From 62b4b76483e171e1e9a04c2226e455d427c4af37 Mon Sep 17 00:00:00 2001
From: Apertis CI <devel@lists.apertis.org>
Date: Wed, 26 Feb 2025 11:25:49 +0000
Subject: [PATCH 1/3] Import Upstream version 2.12.0+dfsg

---
 .commitlintrc.js                              |   19 +-
 .ctags                                        |    4 +
 .cz-adapter.cjs                               |   15 +
 .cz.json                                      |    2 +-
 .editorconfig                                 |    5 +-
 .husky/commit-msg                             |    3 -
 .husky/pre-commit                             |    3 -
 .husky/pre-commit.copyright                   |   72 +-
 .nvmrc                                        |    2 +-
 .readthedocs.yaml                             |    5 +-
 .versionrc.js => .versionrc.cjs               |   10 +-
 Makefile                                      |  535 +-
 bl1/bl1.ld.S                                  |   12 +-
 bl1/bl1.mk                                    |   10 +-
 bl1/bl1_main.c                                |   29 +-
 bl2/bl2.ld.S                                  |    6 +
 bl2/bl2.mk                                    |    8 +-
 bl2/bl2_el3.ld.S                              |    6 +
 bl2/bl2_main.c                                |   11 +-
 bl2u/bl2u.ld.S                                |    6 +
 bl2u/bl2u.mk                                  |    6 +-
 bl2u/bl2u_main.c                              |    5 +-
 bl31/aarch64/runtime_exceptions.S             |   32 +-
 bl31/bl31.ld.S                                |   48 +-
 bl31/bl31.mk                                  |   36 +-
 bl31/bl31_main.c                              |   21 +-
 bl31/bl31_traps.c                             |  215 +-
 bl31/ehf.c                                    |   25 +-
 bl31/interrupt_mgmt.c                         |    2 +-
 bl32/sp_min/aarch32/entrypoint.S              |    5 +-
 bl32/sp_min/sp_min.ld.S                       |    6 +
 bl32/sp_min/sp_min.mk                         |   19 +-
 bl32/sp_min/sp_min_main.c                     |   19 +-
 bl32/sp_min/sp_min_private.h                  |    6 +-
 bl32/tsp/tsp.ld.S                             |    6 +
 bl32/tsp/tsp.mk                               |    9 +-
 bl32/tsp/tsp_common.c                         |    5 +-
 bl32/tsp/tsp_context.c                        |  143 +
 bl32/tsp/tsp_ffa_main.c                       |    5 +-
 bl32/tsp/tsp_main.c                           |   25 +-
 changelog.yaml                                |  198 +-
 common/bl_common.c                            |   35 +-
 common/fdt_fixup.c                            |   19 +
 common/fdt_wrappers.c                         |   15 +-
 common/feat_detect.c                          |  261 +-
 docs/Makefile                                 |   18 +-
 docs/about/contact.rst                        |    7 +-
 docs/about/features.rst                       |    2 +-
 docs/about/maintainers.rst                    |  236 +-
 docs/about/release-information.rst            |   25 +-
 docs/change-log.md                            | 1963 +++-
 docs/components/arm-sip-service.rst           |  357 +-
 .../components/context-management-library.rst |  568 ++
 docs/components/cot-binding.rst               |   70 +-
 docs/components/fconf/index.rst               |    1 +
 docs/components/fconf/tb_fw_bindings.rst      |  159 +
 docs/components/ffa-manifest-binding.rst      |   73 +-
 docs/components/firmware-update.rst           |    2 +-
 .../granule-protection-tables-design.rst      |   93 +-
 docs/components/index.rst                     |    3 +
 .../platform-interrupt-controller-API.rst     |   25 +-
 .../components/realm-management-extension.rst |    2 +-
 docs/components/rmm-el3-comms-spec.rst        |  335 +-
 docs/components/romlib-design.rst             |   19 +-
 docs/components/sdei.rst                      |   46 +-
 docs/components/secure-partition-manager.rst  | 1456 +--
 docs/components/ven-el3-debugfs.rst           |  343 +
 docs/components/ven-el3-service.rst           |   78 +
 docs/conf.py                                  |    6 +-
 docs/design/auth-framework.rst                |    7 +-
 docs/design/cpu-specific-build-macros.rst     |  155 +-
 docs/design/firmware-design.rst               |   59 +-
 docs/design/trusted-board-boot.rst            |  148 +-
 docs/design_documents/cmake_framework.rst     |    8 +-
 docs/design_documents/context_mgmt_rework.rst |    4 +-
 docs/design_documents/index.rst               |    2 +-
 docs/design_documents/measured_boot.rst       |   17 +-
 docs/design_documents/{rss.rst => rse.rst}    |  499 +-
 docs/getting_started/build-internals.rst      |    8 +
 docs/getting_started/build-options.rst        |  337 +-
 docs/getting_started/docs-build.rst           |   25 +-
 docs/getting_started/prerequisites.rst        |  160 +-
 docs/getting_started/rt-svc-writers-guide.rst |   17 +-
 docs/global_substitutions.txt                 |    6 +
 docs/glossary.rst                             |   18 +
 docs/index.rst                                |    4 +-
 docs/license.rst                              |   29 +
 docs/perf/psci-performance-juno.rst           |  339 +-
 docs/perf/psci-performance-n1sdp.rst          |  304 +-
 docs/plat/amd-versal2.rst                     |   87 +
 docs/plat/arm/arm-build-options.rst           |   33 +-
 docs/plat/arm/automotive_rd/index.rst         |   50 +
 docs/plat/arm/fvp/fvp-aemv8-base.rst          |  154 +
 docs/plat/arm/fvp/fvp-build-options.rst       |   51 +
 docs/plat/arm/fvp/fvp-cortex-a32.rst          |   47 +
 docs/plat/arm/fvp/fvp-cortex-a57-a53.rst      |   52 +
 docs/plat/arm/fvp/fvp-foundation.rst          |   42 +
 docs/plat/arm/fvp/fvp-specific-configs.rst    |  209 +
 docs/plat/arm/fvp/fvp-support.rst             |  102 +
 docs/plat/arm/fvp/index.rst                   |  648 +-
 docs/plat/arm/index.rst                       |    3 +-
 docs/plat/arm/juno/index.rst                  |    6 +-
 docs/plat/arm/tc/index.rst                    |   12 +-
 docs/plat/imx8ulp.rst                         |   69 +
 docs/plat/index.rst                           |   22 +-
 docs/plat/mt8195.rst                          |    4 +-
 docs/plat/rockchip.rst                        |    4 +-
 docs/plat/rpi5.rst                            |   78 +
 docs/plat/s32g274a.rst                        |  111 +
 docs/plat/st/stm32mp1.rst                     |   12 +-
 docs/plat/st/stm32mp2.rst                     |   38 +-
 docs/plat/st/stm32mpus.rst                    |    6 +-
 docs/plat/xilinx-versal-net.rst               |   69 +
 docs/plat/xilinx-versal.rst                   |   82 +-
 docs/plat/xilinx-zynqmp.rst                   |   52 +
 docs/porting-guide.rst                        |  205 +-
 docs/process/code-review-guidelines.rst       |    2 +-
 docs/process/coding-guidelines.rst            |    2 -
 docs/process/coding-style.rst                 |   18 +-
 docs/process/commit-style.rst                 |    2 +-
 docs/process/contributing.rst                 |  157 +-
 docs/process/maintenance.rst                  |    4 +-
 docs/process/misra-compliance.csv             |  174 +
 docs/process/security.rst                     |    7 +-
 .../diagrams/context_init_coldboot.png        |  Bin 0 -> 99885 bytes
 .../diagrams/context_init_warmboot.png        |  Bin 0 -> 97092 bytes
 .../diagrams/context_memory_allocation.png    |  Bin 0 -> 204249 bytes
 docs/resources/diagrams/cot-dualroot.jpg      |  Bin 0 -> 134378 bytes
 docs/resources/diagrams/cot-tbbr.jpg          |  Bin 0 -> 131981 bytes
 .../cpu_data_config_context_memory.png        |  Bin 0 -> 680091 bytes
 .../resources/diagrams/percpu-data-struct.png |  Bin 0 -> 207339 bytes
 ...on_flow.puml => rse_attestation_flow.puml} |    2 +-
 .../plantuml/rse_measured_boot_flow.puml      |   79 +
 .../plantuml/rss_measured_boot_flow.puml      |   79 -
 .../{tfa_rss_dfd.puml => tfa_rse_dfd.puml}    |   12 +-
 .../diagrams/root_context_sequence.png        |  Bin 0 -> 210925 bytes
 ...tion_flow.svg => rse_attestation_flow.svg} |    4 +-
 ...ot_flow.svg => rse_measured_boot_flow.svg} |   98 +-
 .../resources/diagrams/secure_sw_stack_sp.png |  Bin 34909 -> 34589 bytes
 .../diagrams/secure_sw_stack_tos.png          |  Bin 34202 -> 34126 bytes
 docs/resources/diagrams/tf-a_attack_tree.png  |  Bin 0 -> 37881 bytes
 .../diagrams/tf-a_data_flow_diagram.png       |  Bin 0 -> 44179 bytes
 .../diagrams/tf-a_system_diagram.png          |  Bin 0 -> 191986 bytes
 docs/security_advisories/index.rst            |    1 +
 .../security-advisory-tfv-10.rst              |    2 +-
 .../security-advisory-tfv-11.rst              |   86 +
 .../security-advisory-tfv-9.rst               |    2 +-
 .../firmware_threat_model/index.rst           |   41 +
 .../threat_model.rst                          |  143 +-
 .../threat_model_arm_cca.rst                  |    4 +-
 .../threat_model_el3_spm.rst                  |    4 +-
 .../threat_model_fvp_r.rst                    |    2 +-
 .../threat_model_fw_update_and_recovery.rst   |  103 +
 .../threat_model_rse_interface.rst}           |   30 +-
 docs/threat_model/index.rst                   |   32 +-
 .../supply_chain_threat_model.rst             |  760 ++
 docs/tools/cot-dt2c.rst                       |  119 +
 docs/tools/index.rst                          |    4 +-
 docs/tools/transfer-list-compiler.rst         |  311 +
 drivers/arm/css/dsu/dsu.c                     |  135 +
 drivers/arm/css/scmi/scmi_common.c            |    9 +-
 drivers/arm/css/scp/css_sds.c                 |   16 +-
 drivers/arm/css/sds/sds.c                     |   85 +-
 drivers/arm/dcc/dcc_console.c                 |   16 +-
 drivers/arm/gic/v3/arm_gicv3_common.c         |   16 +-
 drivers/arm/gic/v3/gic600_multichip.c         |    4 +-
 drivers/arm/gic/v3/gicv3_main.c               |  102 +-
 drivers/arm/mhu/mhu_v3_x.c                    |  475 +
 drivers/arm/mhu/mhu_v3_x.h                    |  226 +
 drivers/arm/mhu/mhu_v3_x_private.h            |  222 +
 drivers/arm/mhu/mhu_wrapper_v2_x.c            |    7 +-
 drivers/arm/mhu/mhu_wrapper_v3_x.c            |  462 +
 .../arm/{rss/rss_comms.c => rse/rse_comms.c}  |   60 +-
 drivers/arm/rse/rse_comms.mk                  |   35 +
 .../rse_comms_protocol.c}                     |   28 +-
 drivers/arm/rse/rse_comms_protocol.h          |   67 +
 drivers/arm/rse/rse_comms_protocol_common.h   |   35 +
 .../rse_comms_protocol_embed.c}               |   25 +-
 .../rse_comms_protocol_embed.h}               |   22 +-
 .../rse_comms_protocol_pointer_access.c}      |   25 +-
 .../rse_comms_protocol_pointer_access.h}      |   18 +-
 drivers/arm/rss/rss_comms.mk                  |   22 -
 drivers/arm/rss/rss_comms_protocol.h          |   67 -
 drivers/arm/smmu/smmu_v3.c                    |   51 +-
 drivers/auth/auth_mod.c                       |   10 +-
 drivers/auth/cca/bl1_cot.c                    |  145 +
 drivers/auth/cca/cot.c                        |  679 --
 drivers/auth/dualroot/bl1_cot.c               |  246 +
 drivers/auth/dualroot/cot.c                   |  962 --
 drivers/auth/mbedtls/mbedtls_common.mk        |   53 +-
 drivers/auth/mbedtls/mbedtls_crypto.c         |   22 +-
 drivers/auth/mbedtls/mbedtls_psa_crypto.c     |  456 +-
 drivers/auth/tbbr/tbbr_cot_bl1.c              |    3 +-
 drivers/auth/tbbr/tbbr_cot_bl2.c              |   18 +-
 drivers/auth/tbbr/tbbr_cot_common.c           |   20 +-
 drivers/cadence/emmc/cdns_sdmmc.c             |  981 +-
 drivers/cadence/nand/cdns_nand.c              |   85 +-
 drivers/clk/clk.c                             |   21 +
 drivers/delay_timer/delay_timer.c             |   24 +-
 drivers/delay_timer/generic_delay_timer.c     |   28 +-
 drivers/fwu/fwu.c                             |  139 +-
 drivers/measured_boot/rse/dice_prot_env.c     |  194 +
 drivers/measured_boot/rse/dice_prot_env.mk    |   29 +
 drivers/measured_boot/rse/qcbor.mk            |   23 +
 .../rse_measured_boot.c}                      |   20 +-
 .../rse_measured_boot.mk}                     |   14 +-
 drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk    |   16 +-
 .../nxp/clk/s32cc/include/s32cc-clk-regs.h    |  115 +
 drivers/nxp/clk/s32cc/include/s32cc-mc-me.h   |   16 +
 drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h  |   14 +
 drivers/nxp/clk/s32cc/mc_me.c                 |  173 +
 drivers/nxp/clk/s32cc/mc_rgm.c                |   84 +
 drivers/nxp/clk/s32cc/s32cc_clk.mk            |   22 +
 drivers/nxp/clk/s32cc/s32cc_clk_drv.c         | 1481 +++
 drivers/nxp/clk/s32cc/s32cc_clk_modules.c     |  257 +
 drivers/nxp/clk/s32cc/s32cc_clk_utils.c       |   65 +
 drivers/nxp/clk/s32cc/s32cc_early_clks.c      |  230 +
 drivers/nxp/console/console.mk                |    7 +-
 drivers/nxp/console/linflex_console.S         |  299 +
 drivers/nxp/ddr/phy-gen2/ddrphy.mk            |    4 +-
 drivers/nxp/drivers.mk                        |    4 +
 drivers/nxp/gpio/nxp_gpio.c                   |    9 +-
 drivers/partition/partition.c                 |  128 +-
 drivers/renesas/common/io/io_rcar.c           |  114 +-
 drivers/renesas/rcar/qos/D3/qos_init_d3.c     |    4 +-
 drivers/renesas/rcar/qos/E3/qos_init_e3_v10.c |    4 +-
 drivers/renesas/rcar/qos/H3/qos_init_h3_v11.c |    4 +-
 drivers/renesas/rcar/qos/H3/qos_init_h3_v20.c |    4 +-
 drivers/renesas/rcar/qos/H3/qos_init_h3_v30.c |    4 +-
 .../renesas/rcar/qos/H3/qos_init_h3n_v30.c    |    4 +-
 drivers/renesas/rcar/qos/M3/qos_init_m3_v10.c |    4 +-
 drivers/renesas/rcar/qos/M3/qos_init_m3_v11.c |    4 +-
 drivers/renesas/rcar/qos/M3/qos_init_m3_v30.c |    4 +-
 .../renesas/rcar/qos/M3N/qos_init_m3n_v10.c   |    4 +-
 drivers/renesas/rcar/qos/V3M/qos_init_v3m.c   |    4 +-
 drivers/rpi3/gpio/rpi3_gpio.c                 |    3 +-
 drivers/rpi3/rng/rpi3_rng.c                   |   15 +-
 drivers/scmi-msg/common.h                     |   10 +-
 drivers/scmi-msg/entry.c                      |    9 +
 drivers/scmi-msg/sensor.c                     |  277 +
 drivers/scmi-msg/sensor.h                     |  125 +
 drivers/st/bsec/bsec2.c                       |  340 +-
 drivers/st/bsec/bsec3.c                       |  533 ++
 drivers/st/clk/clk-stm32-core.c               |   79 +-
 drivers/st/clk/clk-stm32-core.h               |   73 +-
 drivers/st/clk/clk-stm32mp13.c                |  330 +-
 drivers/st/clk/clk-stm32mp2.c                 | 2357 +++++
 drivers/st/clk/stm32mp1_clk.c                 | 1038 ++-
 drivers/st/clk/stm32mp_clkfunc.c              |   50 +-
 drivers/st/crypto/stm32_hash.c                |   10 +-
 .../firmware/include/mnpmusrammsgblock_ddr3.h |  935 ++
 .../firmware/include/mnpmusrammsgblock_ddr4.h | 2203 +++++
 .../include/mnpmusrammsgblock_lpddr4.h        |  925 ++
 .../phyinit/include/ddrphy_csr_all_cdefines.h | 6944 ++++++++++++++
 .../ddr/phy/phyinit/include/ddrphy_phyinit.h  |   37 +
 .../phyinit/include/ddrphy_phyinit_struct.h   |  786 ++
 .../include/ddrphy_phyinit_usercustom.h       |  118 +
 .../ddr/phy/phyinit/include/ddrphy_wrapper.h  |   20 +
 .../src/ddrphy_phyinit_c_initphyconfig.c      | 1141 +++
 .../phy/phyinit/src/ddrphy_phyinit_calcmb.c   |  210 +
 .../phyinit/src/ddrphy_phyinit_d_loadimem.c   |   43 +
 .../phyinit/src/ddrphy_phyinit_f_loaddmem.c   |   70 +
 .../phy/phyinit/src/ddrphy_phyinit_g_execfw.c |   66 +
 .../src/ddrphy_phyinit_i_loadpieimage.c       |  394 +
 .../phyinit/src/ddrphy_phyinit_initstruct.c   |  262 +
 .../src/ddrphy_phyinit_isdbytedisabled.c      |   88 +
 .../src/ddrphy_phyinit_loadpieprodcode.c      |  189 +
 .../phyinit/src/ddrphy_phyinit_mapdrvstren.c  |  282 +
 .../src/ddrphy_phyinit_progcsrskiptrain.c     |  893 ++
 .../phyinit/src/ddrphy_phyinit_reginterface.c |  170 +
 .../src/ddrphy_phyinit_restore_sequence.c     |   78 +
 .../phy/phyinit/src/ddrphy_phyinit_sequence.c |  121 +
 .../phyinit/src/ddrphy_phyinit_softsetmb.c    |  100 +
 .../phyinit/src/ddrphy_phyinit_writeoutmem.c  |   79 +
 ...ddrphy_phyinit_usercustom_custompretrain.c |   90 +
 .../ddrphy_phyinit_usercustom_g_waitfwdone.c  |  183 +
 .../ddrphy_phyinit_usercustom_saveretregs.c   |  399 +
 drivers/st/ddr/stm32mp1_ddr.c                 |   20 +-
 drivers/st/ddr/stm32mp2_ddr.c                 |  479 +
 drivers/st/ddr/stm32mp2_ddr_helpers.c         |  527 ++
 drivers/st/ddr/stm32mp2_ram.c                 |  210 +
 drivers/st/ddr/stm32mp_ddr.c                  |  209 +-
 drivers/st/ddr/stm32mp_ddr_test.c             |   73 +-
 drivers/st/gpio/stm32_gpio.c                  |   77 +-
 drivers/st/i2c/stm32_i2c.c                    |   67 +-
 drivers/st/mmc/stm32_sdmmc2.c                 |    6 +-
 drivers/st/pmic/stm32mp_pmic.c                |  116 +-
 drivers/st/pmic/stm32mp_pmic2.c               |  499 +
 drivers/st/pmic/stpmic2.c                     |  474 +
 drivers/st/regulator/regulator_core.c         |   20 +-
 drivers/st/reset/stm32mp1_reset.c             |   19 +-
 drivers/st/reset/stm32mp2_reset.c             |   76 +
 drivers/ufs/ufs.c                             |    3 +-
 fdts/cca_cot_descriptors.dtsi                 |  269 +
 fdts/dualroot_cot_descriptors.dtsi            |  314 +
 fdts/fvp-base-psci-common.dtsi                |   12 +-
 fdts/fvp-foundation-gicv2-psci.dts            |    4 +-
 fdts/fvp-foundation-gicv3-psci.dts            |    4 +-
 fdts/rd1ae.dts                                |  416 +
 fdts/rtsm_ve-motherboard.dtsi                 |   19 +
 fdts/stm32mp1-cot-descriptors.dtsi            |   18 +-
 fdts/stm32mp131.dtsi                          |   20 +-
 fdts/stm32mp135f-dk.dts                       |   25 +-
 fdts/stm32mp15-fw-config.dtsi                 |   13 +-
 fdts/stm32mp151.dtsi                          |   18 +-
 fdts/stm32mp151a-prtt1a.dts                   |    3 +-
 fdts/stm32mp157a-avenger96.dts                |   85 +-
 fdts/stm32mp157c-ed1.dts                      |   89 +-
 fdts/stm32mp157c-odyssey-som.dtsi             |   89 +-
 fdts/stm32mp15xx-dhcom-som.dtsi               |   91 +-
 fdts/stm32mp15xx-dhcor-som.dtsi               |   90 +-
 fdts/stm32mp15xx-dkx.dtsi                     |   89 +-
 fdts/stm32mp15xx-osd32.dtsi                   |   89 +-
 fdts/stm32mp25-bl2.dtsi                       |   37 +-
 fdts/stm32mp25-bl31.dtsi                      |   13 +
 fdts/stm32mp25-ddr.dtsi                       |  253 +
 ...2mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi |  249 +
 ...32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi |  245 +
 fdts/stm32mp25-fw-config.dtsi                 |   42 +
 fdts/stm32mp25-pinctrl.dtsi                   |   66 +-
 fdts/stm32mp251.dtsi                          |  203 +-
 fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi |   23 +
 fdts/stm32mp257f-ev1-ca35tdcid-rcc.dtsi       |   97 +
 fdts/stm32mp257f-ev1-fw-config.dts            |    7 +
 fdts/stm32mp257f-ev1.dts                      |  162 +-
 ...riptors.dtsi => tbbr_cot_descriptors.dtsi} |   39 +-
 fdts/tc-base.dtsi                             |  683 ++
 fdts/tc-common.dtsi                           |    9 +
 fdts/tc-fpga.dtsi                             |   36 +
 fdts/tc-fvp.dtsi                              |   84 +
 fdts/tc.dts                                   |  599 --
 fdts/tc2.dts                                  |  300 +
 fdts/tc3-4-base.dtsi                          |   84 +
 fdts/tc3.dts                                  |  121 +
 fdts/tc4.dts                                  |   67 +
 include/arch/aarch32/arch.h                   |   38 +-
 include/arch/aarch32/arch_features.h          |  250 +-
 include/arch/aarch32/arch_helpers.h           |   11 +-
 include/arch/aarch32/asm_macros.S             |    9 +
 include/arch/aarch32/el3_common_macros.S      |    8 +-
 include/arch/aarch64/arch.h                   |  272 +-
 include/arch/aarch64/arch_features.h          |  486 +-
 include/arch/aarch64/arch_helpers.h           |  201 +-
 include/arch/aarch64/asm_macros.S             |    8 +
 include/arch/aarch64/el2_common_macros.S      |    6 +-
 include/arch/aarch64/el3_common_macros.S      |  142 +-
 include/bl1/bl1.h                             |    6 +-
 include/bl31/bl31.h                           |    1 -
 include/bl31/interrupt_mgmt.h                 |    4 +-
 include/bl31/sync_handle.h                    |    5 +
 include/bl32/tsp/tsp.h                        |   13 +-
 include/bl32/tsp/tsp_el1_context.h            |   16 +
 include/common/bl_common.h                    |    4 +-
 include/common/build_message.h                |   14 +
 include/common/debug.h                        |    8 +-
 include/common/fdt_wrappers.h                 |    4 +-
 include/common/feat_detect.h                  |    7 +-
 include/common/par.h                          |   30 +
 include/common/sha_common_macros.h            |   19 +
 include/drivers/arm/css/css_mhu_doorbell.h    |    6 +-
 include/drivers/arm/css/dsu.h                 |   42 +
 include/drivers/arm/css/scmi.h                |    4 +-
 include/drivers/arm/css/sds.h                 |   35 +-
 include/drivers/arm/dcc.h                     |    9 +-
 include/drivers/arm/fvp/fvp_cpu_pwr.h         |   25 +
 include/drivers/arm/gicv2.h                   |    2 +-
 include/drivers/arm/gicv3.h                   |    6 +-
 .../drivers/arm/{rss_comms.h => rse_comms.h}  |    8 +-
 .../drivers/auth/mbedtls/mbedtls_config-2.h   |  152 -
 .../drivers/auth/mbedtls/mbedtls_config-3.h   |   33 +-
 .../drivers/auth/mbedtls/psa_mbedtls_config.h |    3 +-
 include/drivers/auth/tbbr_cot_common.h        |    4 +-
 include/drivers/cadence/cdns_nand.h           |    1 +
 include/drivers/cadence/cdns_sdmmc.h          |  327 +-
 include/drivers/clk.h                         |    5 +
 include/drivers/delay_timer.h                 |   25 +-
 include/drivers/fwu/fwu.h                     |    9 +-
 include/drivers/fwu/fwu_metadata.h            |   64 +-
 .../measured_boot/event_log/event_log.h       |   47 +-
 include/drivers/measured_boot/event_log/tcg.h |    7 +-
 include/drivers/measured_boot/metadata.h      |   72 +
 .../drivers/measured_boot/rse/dice_prot_env.h |   50 +
 .../measured_boot/rse/rse_measured_boot.h     |   40 +
 .../measured_boot/rss/rss_measured_boot.h     |   57 -
 include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h |   11 +
 include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h |  106 +
 .../drivers/nxp/clk/s32cc/s32cc-clk-modules.h |  398 +
 .../drivers/nxp/clk/s32cc/s32cc-clk-utils.h   |   23 +
 include/drivers/nxp/console/linflex.h         |   18 +
 include/drivers/nxp/crypto/caam/hash.h        |    4 +-
 include/drivers/partition/partition.h         |   10 +-
 include/drivers/rpi3/mailbox/rpi3_mbox.h      |   18 +-
 include/drivers/st/bsec.h                     |  102 +-
 include/drivers/st/bsec2_reg.h                |   17 +-
 include/drivers/st/bsec3_reg.h                |  103 +
 include/drivers/st/stm32_gpio.h               |   13 +-
 include/drivers/st/stm32_i2c.h                |    3 +-
 include/drivers/st/stm32mp1_clk.h             |    4 +-
 include/drivers/st/stm32mp25_rcc.h            |   30 +-
 include/drivers/st/stm32mp2_clk.h             |   44 +
 include/drivers/st/stm32mp2_ddr.h             |  147 +
 include/drivers/st/stm32mp2_ddr_helpers.h     |   35 +
 include/drivers/st/stm32mp2_ddr_regs.h        |   38 +
 include/drivers/st/stm32mp2_pwr.h             |  478 +
 include/drivers/st/stm32mp2_ram.h             |   13 +
 include/drivers/st/stm32mp_clkfunc.h          |    6 +-
 include/drivers/st/stm32mp_ddr.h              |   21 +-
 include/drivers/st/stm32mp_ddrctrl_regs.h     |   33 +-
 include/drivers/st/stm32mp_pmic.h             |    9 +-
 include/drivers/st/stm32mp_pmic2.h            |   51 +
 include/drivers/st/stm32mp_reset.h            |    7 +-
 include/drivers/st/stm32mp_risab_regs.h       |  271 +
 include/drivers/st/stpmic2.h                  |  307 +
 include/drivers/usb_device.h                  |    3 +-
 include/dt-bindings/clock/stm32mp13-clks.h    |   10 +-
 include/dt-bindings/clock/stm32mp15-clksrc.h  |  660 +-
 include/dt-bindings/clock/stm32mp25-clks.h    |   20 +-
 include/dt-bindings/clock/stm32mp25-clksrc.h  |   15 +-
 include/dt-bindings/gpio/stm32-gpio.h         |   41 +
 include/dt-bindings/reset/stm32mp25-resets.h  |   30 +-
 include/lib/cpus/aarch32/cpu_macros.S         |   63 +-
 include/lib/cpus/aarch64/cortex_a35.h         |    5 +-
 include/lib/cpus/aarch64/cortex_a520.h        |   21 +-
 include/lib/cpus/aarch64/cortex_a710.h        |    7 +-
 include/lib/cpus/aarch64/cortex_a715.h        |   17 +-
 include/lib/cpus/aarch64/cortex_a720.h        |   17 +-
 .../{neoverse_hermes.h => cortex_a720_ae.h}   |   16 +-
 .../{cortex_blackhawk.h => cortex_a725.h}     |   17 +-
 include/lib/cpus/aarch64/cortex_a75.h         |    7 +-
 include/lib/cpus/aarch64/cortex_a78c.h        |    5 +
 include/lib/cpus/aarch64/cortex_arcadia.h     |   24 +
 include/lib/cpus/aarch64/cortex_x2.h          |    7 +-
 include/lib/cpus/aarch64/cortex_x3.h          |   18 +-
 include/lib/cpus/aarch64/cortex_x4.h          |   26 +-
 .../{cortex_chaberton.h => cortex_x925.h}     |   17 +-
 include/lib/cpus/aarch64/cpu_macros.S         |   80 +-
 include/lib/cpus/aarch64/dsu_def.h            |    4 +
 include/lib/cpus/aarch64/neoverse_n3.h        |   24 +
 include/lib/cpus/aarch64/neoverse_poseidon.h  |   27 -
 include/lib/cpus/aarch64/neoverse_v1.h        |    1 +
 include/lib/cpus/aarch64/neoverse_v2.h        |    8 +
 include/lib/cpus/aarch64/neoverse_v3.h        |   28 +
 include/lib/cpus/cpu_ops.h                    |    8 +-
 include/lib/cpus/errata.h                     |   26 +-
 include/lib/debugfs.h                         |   22 +-
 include/lib/dice/dice.h                       |  166 +
 include/lib/el3_runtime/aarch64/context.h     |  476 +-
 include/lib/el3_runtime/context_debug.h       |   19 +
 include/lib/el3_runtime/context_el1.h         |  325 +
 include/lib/el3_runtime/context_el2.h         |  391 +
 include/lib/el3_runtime/context_mgmt.h        |   20 +-
 include/lib/el3_runtime/cpu_data.h            |   23 +-
 include/lib/el3_runtime/simd_ctx.h            |   97 +
 include/lib/extensions/brbe.h                 |    8 +-
 include/lib/extensions/debug_v8p9.h           |   20 +
 include/lib/extensions/fgt2.h                 |   20 +
 include/lib/extensions/mpam.h                 |    4 +-
 include/lib/extensions/spe.h                  |   15 +-
 include/lib/extensions/sve.h                  |    8 +-
 include/lib/extensions/sysreg128.h            |   36 +
 include/lib/extensions/tcr2.h                 |   24 +
 include/lib/extensions/trbe.h                 |   12 +-
 include/lib/extensions/trf.h                  |   24 +-
 include/lib/pmf/pmf.h                         |   31 +-
 include/lib/psa/cca_attestation.h             |   20 +
 include/lib/psa/delegated_attestation.h       |   16 +-
 include/lib/psa/dice_protection_environment.h |  100 +
 include/lib/psa/measured_boot.h               |   23 +-
 include/lib/psa/psa/client.h                  |   20 +-
 include/lib/psa/psa_manifest/sid.h            |   19 +-
 include/lib/psa/rse_crypto_defs.h             |   79 +
 ...{rss_platform_api.h => rse_platform_api.h} |   18 +-
 include/lib/psa/rss_crypto_defs.h             |   58 -
 include/lib/psci/psci_lib.h                   |    3 +-
 include/lib/smccc.h                           |    8 +-
 include/lib/spinlock.h                        |   12 +-
 include/lib/transfer_list.h                   |  115 +-
 include/lib/utils_def.h                       |   30 +-
 include/lib/xlat_tables/xlat_tables_defs.h    |    6 +-
 include/plat/arm/board/common/board_css_def.h |    3 -
 .../plat/arm/board/common/rotpk/rotpk_def.h   |   24 +
 include/plat/arm/board/common/v2m_def.h       |   25 +
 include/plat/arm/common/arm_def.h             |   33 +-
 include/plat/arm/common/arm_sip_svc.h         |   18 +-
 include/plat/arm/common/arm_tzc_dram.ld.S     |    3 +
 include/plat/arm/common/fconf_arm_sp_getter.h |    7 +-
 include/plat/arm/common/plat_arm.h            |   64 +-
 include/plat/arm/css/common/css_def.h         |    7 +-
 include/plat/common/common_def.h              |   35 +-
 include/plat/common/plat_drtm.h               |    6 +-
 include/plat/common/platform.h                |   47 +-
 .../plat/nuvoton/common/npcm845x_arm_def.h    |   16 +-
 include/plat/nuvoton/common/plat_macros.S     |    3 +-
 include/plat/nuvoton/npcm845x/platform_def.h  |    8 +-
 include/services/drtm_svc.h                   |   10 +-
 include/services/ffa_svc.h                    |   22 +-
 .../oem/chromeos/widevine_smc_handlers.h      |   65 +
 include/services/rmm_core_manifest.h          |   55 +-
 include/services/rmm_el3_token_sign.h         |   63 +
 include/services/rmmd_svc.h                   |   48 +-
 include/services/spmd_svc.h                   |    3 +-
 include/services/ven_el3_svc.h                |   32 +
 include/tools_share/cca_oid.h                 |    6 +-
 include/tools_share/tbbr_oid.h                |    8 +-
 lib/aarch64/cache_helpers.S                   |   93 +-
 lib/aarch64/misc_helpers.S                    |   20 +-
 lib/compiler-rt/builtins/assembly.h           |    5 +-
 lib/compiler-rt/builtins/int_lib.h            |   10 +-
 lib/compiler-rt/builtins/int_types.h          |   16 +-
 lib/cpus/aarch32/aem_generic.S                |   10 +-
 lib/cpus/aarch32/cortex_a12.S                 |    4 +-
 lib/cpus/aarch32/cortex_a15.S                 |    4 +-
 lib/cpus/aarch32/cortex_a17.S                 |    4 +-
 lib/cpus/aarch32/cortex_a32.S                 |    4 +-
 lib/cpus/aarch32/cortex_a5.S                  |    4 +-
 lib/cpus/aarch32/cortex_a53.S                 |    4 +-
 lib/cpus/aarch32/cortex_a57.S                 |    4 +-
 lib/cpus/aarch32/cortex_a7.S                  |    4 +-
 lib/cpus/aarch32/cortex_a72.S                 |    4 +-
 lib/cpus/aarch32/cortex_a9.S                  |    4 +-
 lib/cpus/aarch64/a64fx.S                      |    9 -
 lib/cpus/aarch64/aem_generic.S                |   11 +-
 lib/cpus/aarch64/cortex_a35.S                 |    4 +-
 lib/cpus/aarch64/cortex_a510.S                |    4 +-
 lib/cpus/aarch64/cortex_a520.S                |   37 +-
 lib/cpus/aarch64/cortex_a53.S                 |    4 +-
 lib/cpus/aarch64/cortex_a55.S                 |    4 +-
 lib/cpus/aarch64/cortex_a57.S                 |    6 +-
 lib/cpus/aarch64/cortex_a65.S                 |   22 +-
 lib/cpus/aarch64/cortex_a65ae.S               |    4 +-
 lib/cpus/aarch64/cortex_a710.S                |   12 +-
 lib/cpus/aarch64/cortex_a715.S                |   93 +-
 lib/cpus/aarch64/cortex_a72.S                 |    4 +-
 lib/cpus/aarch64/cortex_a720.S                |   38 +-
 .../{neoverse_hermes.S => cortex_a720_ae.S}   |   41 +-
 .../{cortex_blackhawk.S => cortex_a725.S}     |   40 +-
 lib/cpus/aarch64/cortex_a73.S                 |    5 +-
 lib/cpus/aarch64/cortex_a75.S                 |    6 +-
 lib/cpus/aarch64/cortex_a76.S                 |    6 +-
 lib/cpus/aarch64/cortex_a76ae.S               |    4 +-
 lib/cpus/aarch64/cortex_a77.S                 |    5 +-
 lib/cpus/aarch64/cortex_a78.S                 |    6 +-
 lib/cpus/aarch64/cortex_a78_ae.S              |    4 +-
 lib/cpus/aarch64/cortex_a78c.S                |   27 +-
 .../{cortex_chaberton.S => cortex_arcadia.S}  |   40 +-
 lib/cpus/aarch64/cortex_gelas.S               |    6 +-
 lib/cpus/aarch64/cortex_x1.S                  |    2 -
 lib/cpus/aarch64/cortex_x2.S                  |   21 +-
 lib/cpus/aarch64/cortex_x3.S                  |   46 +-
 lib/cpus/aarch64/cortex_x4.S                  |   64 +-
 lib/cpus/aarch64/cortex_x925.S                |   64 +
 lib/cpus/aarch64/cpu_helpers.S                |    4 +-
 lib/cpus/aarch64/denver.S                     |    4 +-
 lib/cpus/aarch64/dsu_helpers.S                |   27 +-
 lib/cpus/aarch64/generic.S                    |    3 +-
 lib/cpus/aarch64/neoverse_e1.S                |    4 +-
 lib/cpus/aarch64/neoverse_n1.S                |    6 +-
 lib/cpus/aarch64/neoverse_n2.S                |   13 +-
 lib/cpus/aarch64/neoverse_n3.S                |   69 +
 lib/cpus/aarch64/neoverse_poseidon.S          |   86 -
 lib/cpus/aarch64/neoverse_v1.S                |   13 +-
 lib/cpus/aarch64/neoverse_v2.S                |   29 +-
 lib/cpus/aarch64/neoverse_v3.S                |   88 +
 lib/cpus/aarch64/nevis.S                      |    4 +-
 lib/cpus/aarch64/qemu_max.S                   |    4 +-
 lib/cpus/aarch64/rainier.S                    |    4 +-
 lib/cpus/aarch64/travis.S                     |    6 +-
 lib/cpus/cpu-ops.mk                           |  148 +-
 lib/cpus/errata_common.c                      |   42 +
 lib/cpus/errata_report.c                      |   68 +-
 lib/el3_runtime/aarch32/context_mgmt.c        |   12 +-
 lib/el3_runtime/aarch64/context.S             |  544 +-
 lib/el3_runtime/aarch64/context_debug.c       |  208 +
 lib/el3_runtime/aarch64/context_mgmt.c        | 1006 +-
 lib/el3_runtime/simd_ctx.c                    |   81 +
 lib/extensions/brbe/brbe.c                    |   18 +-
 lib/extensions/debug/debugv8p9.c              |   26 +
 lib/extensions/fgt/fgt2.c                     |   27 +
 lib/extensions/mpam/mpam.c                    |    8 +-
 lib/extensions/pmuv3/aarch32/pmuv3.c          |    4 -
 lib/extensions/pmuv3/aarch64/pmuv3.c          |   14 +-
 lib/extensions/sme/sme.c                      |    4 +-
 lib/extensions/spe/spe.c                      |   76 +-
 lib/extensions/sysreg128/sysreg128.S          |  139 +
 lib/extensions/tcr/tcr2.c                     |   42 +
 lib/extensions/trbe/trbe.c                    |   33 +-
 lib/extensions/trf/aarch64/trf.c              |   12 +-
 lib/fconf/fconf_cot_getter.c                  |   18 +-
 lib/gpt_rme/gpt_rme.c                         | 1328 ++-
 lib/gpt_rme/gpt_rme.mk                        |   16 +-
 lib/gpt_rme/gpt_rme_private.h                 |  229 +-
 lib/libc/libc.mk                              |   41 +-
 lib/libc/libc_asm.mk                          |   35 +-
 lib/libc/libc_common.mk                       |   42 +
 lib/libc/printf.c                             |   22 +
 lib/libfdt/libfdt.mk                          |   28 +-
 lib/locks/exclusive/aarch64/spinlock.S        |   44 +-
 lib/pmf/pmf_smc.c                             |   16 +-
 lib/psa/cca_attestation.c                     |   66 +
 lib/psa/delegated_attestation.c               |   12 +-
 lib/psa/dice_protection_environment.c         |  370 +
 lib/psa/measured_boot.c                       |   58 +-
 lib/psa/measured_boot_private.h               |    8 +-
 lib/psa/{rss_platform.c => rse_platform.c}    |   26 +-
 lib/psci/aarch64/psci_helpers.S               |    8 +-
 lib/psci/aarch64/runtime_errata.S             |   27 -
 lib/psci/psci_common.c                        |   34 +-
 lib/psci/psci_lib.mk                          |    5 +-
 lib/romlib/Makefile                           |   98 +-
 lib/romlib/romlib_generator.py                |   41 +-
 lib/romlib/templates/wrapper.S                |    5 +-
 lib/romlib/templates/wrapper_bti.S            |    5 +-
 lib/transfer_list/transfer_list.c             |  205 +-
 lib/transfer_list/transfer_list.mk            |    3 +-
 lib/xlat_mpu/aarch64/xlat_mpu_arch.c          |    4 +-
 lib/xlat_tables/aarch64/xlat_tables.c         |    6 +-
 lib/xlat_tables_v2/aarch32/xlat_tables_arch.c |    4 +-
 lib/xlat_tables_v2/aarch64/xlat_tables_arch.c |   19 +-
 lib/xlat_tables_v2/xlat_tables_core.c         |    4 +-
 lib/xlat_tables_v2/xlat_tables_utils.c        |   56 +-
 licenses/LICENSE-APACHE-2.0.txt               |  202 +
 make_helpers/arch_features.mk                 |  145 +-
 make_helpers/build-rules.mk                   |   18 +
 make_helpers/build_env.mk                     |    9 +-
 make_helpers/build_macros.mk                  |  295 +-
 make_helpers/common.mk                        |   17 +
 make_helpers/defaults.mk                      |   55 +-
 make_helpers/march.mk                         |   15 +-
 make_helpers/plat_helpers.mk                  |    4 +
 make_helpers/toolchain.mk                     |  436 +
 make_helpers/toolchains/aarch32.mk            |   39 +
 make_helpers/toolchains/aarch64.mk            |   46 +
 make_helpers/toolchains/host.mk               |   44 +
 make_helpers/toolchains/rk3399-m0.mk          |   31 +
 make_helpers/unix.mk                          |   30 +-
 make_helpers/utilities.mk                     |  129 +
 make_helpers/windows.mk                       |   33 +-
 package-lock.json                             | 8240 ++++++-----------
 package.json                                  |   19 +-
 plat/allwinner/common/include/sunxi_private.h |    8 +
 plat/allwinner/common/sunxi_bl31_setup.c      |    5 +-
 plat/allwinner/common/sunxi_prepare_dtb.c     |    2 +
 plat/allwinner/sun50i_a64/platform.mk         |    4 +
 .../allwinner/sun50i_a64/platform_defaults.mk |    9 +
 plat/allwinner/sun50i_h616/platform.mk        |    5 +-
 plat/allwinner/sun50i_h616/sunxi_h616_dtb.c   |   72 +
 plat/allwinner/sun50i_h616/sunxi_power.c      |  213 +-
 plat/amd/versal2/aarch64/common.c             |  152 +
 plat/amd/versal2/aarch64/helpers.S            |   68 +
 plat/amd/versal2/bl31_setup.c                 |  264 +
 .../versal2/gicv3.c}                          |   72 +-
 plat/amd/versal2/include/def.h                |  188 +
 plat/amd/versal2/include/plat_ipi.h           |   72 +
 plat/amd/versal2/include/plat_macros.S        |  118 +
 plat/amd/versal2/include/plat_pm_common.h     |   25 +
 plat/amd/versal2/include/plat_private.h       |   55 +
 plat/amd/versal2/include/platform_def.h       |  141 +
 plat/amd/versal2/include/scmi.h               |   28 +
 plat/amd/versal2/include/versal2-scmi.h       |  144 +
 plat/amd/versal2/plat_psci.c                  |  241 +
 plat/amd/versal2/plat_topology.c              |   63 +
 plat/amd/versal2/platform.mk                  |  159 +
 plat/amd/versal2/scmi.c                       |  671 ++
 plat/amd/versal2/sip_svc_setup.c              |  117 +
 plat/amd/versal2/soc_ipi.c                    |   73 +
 plat/amd/versal2/tsp/tsp-versal2.mk           |   10 +
 plat/amlogic/axg/platform.mk                  |   11 +-
 plat/amlogic/g12a/platform.mk                 |   11 +-
 plat/amlogic/gxbb/platform.mk                 |    6 +-
 plat/amlogic/gxl/platform.mk                  |   11 +-
 plat/arm/board/a5ds/fdts/a5ds_fw_config.dts   |    5 +-
 plat/arm/board/a5ds/include/platform_def.h    |    5 +-
 plat/arm/board/arm_fpga/fpga_def.h            |    2 +-
 plat/arm/board/arm_fpga/platform.mk           |   29 +-
 .../platform/rd1ae/fdts/rd1ae_fw_config.dts   |   21 +
 .../platform/rd1ae/include/plat_macros.S      |   25 +
 .../platform/rd1ae/include/platform_def.h     |  157 +
 .../platform/rd1ae/include/rd1ae_helpers.S    |   45 +
 .../automotive_rd/platform/rd1ae/platform.mk  |   88 +
 .../rd1ae/rd1ae_bl2_mem_params_desc.c         |   67 +
 .../platform/rd1ae/rd1ae_bl31_setup.c         |   28 +
 .../automotive_rd/platform/rd1ae/rd1ae_err.c  |   22 +
 .../automotive_rd/platform/rd1ae/rd1ae_plat.c |   56 +
 .../automotive_rd/platform/rd1ae/rd1ae_tbb.c  |   34 +
 .../platform/rd1ae/rd1ae_topology.c           |   70 +
 .../arm/board/common/board_arm_trusted_boot.c |   11 +-
 plat/arm/board/common/rotpk/arm_dev_rotpk.S   |   11 +-
 .../swd_rotpk/arm_swd_rotpk_rsa_sha256.bin    |    1 -
 .../common/corstone1000_bl2_mem_params_desc.c |   12 +-
 .../common/corstone1000_helpers.S             |   28 +-
 .../corstone1000/common/corstone1000_plat.c   |    3 +-
 .../corstone1000/common/corstone1000_pm.c     |   58 +-
 .../common/include/platform_def.h             |   60 +-
 plat/arm/board/corstone1000/platform.mk       |   18 +-
 plat/arm/board/fvp/aarch64/fvp_helpers.S      |   19 +-
 plat/arm/board/fvp/aarch64/fvp_lsp_ras_sp.c   |  121 +
 .../board/fvp/fdts/fvp_cactus_sp_manifest.dts |   28 +
 plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi     |   16 +
 plat/arm/board/fvp/fdts/fvp_fw_config.dts     |    5 +-
 .../fvp/fdts/fvp_spmc_el1_optee_manifest.dts  |   22 +
 plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts |   23 +-
 .../fvp/fdts/fvp_spmc_optee_sp_manifest.dts   |   23 +-
 plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts  |   17 +-
 plat/arm/board/fvp/fdts/optee_sp_manifest.dts |   14 +-
 plat/arm/board/fvp/fvp_bl1_measured_boot.c    |   42 +-
 plat/arm/board/fvp/fvp_bl2_measured_boot.c    |   82 +-
 plat/arm/board/fvp/fvp_bl2_setup.c            |   96 +-
 plat/arm/board/fvp/fvp_bl31_setup.c           |   27 +-
 plat/arm/board/fvp/fvp_common.c               |  174 +-
 plat/arm/board/fvp/fvp_common_measured_boot.c |   23 +-
 plat/arm/board/fvp/fvp_cpu_errata.mk          |   61 +-
 plat/arm/board/fvp/fvp_cpu_pwr.c              |   45 +
 plat/arm/board/fvp/fvp_el3_spmc.c             |   15 +-
 plat/arm/board/fvp/fvp_el3_token_sign.c       |   98 +
 plat/arm/board/fvp/fvp_plat_attest_token.c    |  323 +-
 plat/arm/board/fvp/fvp_pm.c                   |   27 +-
 plat/arm/board/fvp/fvp_realm_attest_key.c     |    2 +-
 plat/arm/board/fvp/fvp_topology.c             |    6 +-
 .../arm/board/fvp/include/fvp_pas_def.h       |   12 +-
 plat/arm/board/fvp/include/plat.ld.S          |   30 +-
 plat/arm/board/fvp/include/platform_def.h     |   50 +-
 plat/arm/board/fvp/jmptbl.i                   |    1 -
 plat/arm/board/fvp/platform.mk                |  209 +-
 plat/arm/board/fvp_r/fvp_r_bl1_main.c         |   27 +-
 plat/arm/board/fvp_r/fvp_r_bl1_setup.c        |    4 +-
 plat/arm/board/fvp_r/include/platform_def.h   |   13 +-
 plat/arm/board/fvp_r/platform.mk              |    4 +-
 .../board/fvp_ve/fdts/fvp_ve_fw_config.dts    |    5 +-
 plat/arm/board/fvp_ve/fvp_ve_def.h            |   11 -
 plat/arm/board/fvp_ve/include/platform_def.h  |    5 +-
 plat/arm/board/juno/fdts/juno_fw_config.dts   |    5 +-
 plat/arm/board/juno/include/platform_def.h    |   15 +-
 plat/arm/board/juno/juno_bl1_setup.c          |    7 +-
 plat/arm/board/juno/juno_common.c             |   19 +-
 plat/arm/board/juno/juno_tbbr_cot_bl2.c       |   17 +-
 plat/arm/board/juno/platform.mk               |    4 +-
 .../board/morello/fdts/morello_fw_config.dts  |    5 +-
 plat/arm/board/morello/include/platform_def.h |    9 +-
 plat/arm/board/morello/morello_bl2_setup.c    |    7 +-
 plat/arm/board/morello/morello_bl31_setup.c   |    7 +-
 plat/arm/board/morello/morello_image_load.c   |   14 +-
 plat/arm/board/morello/morello_plat.c         |   17 +-
 plat/arm/board/n1sdp/include/platform_def.h   |    9 +-
 plat/arm/board/n1sdp/n1sdp_bl2_setup.c        |    8 +-
 plat/arm/board/n1sdp/n1sdp_bl31_setup.c       |    7 +-
 plat/arm/board/n1sdp/n1sdp_image_load.c       |    8 +-
 plat/arm/board/n1sdp/n1sdp_plat.c             |   17 +-
 .../common/arch/aarch64/nrd_helper.S}         |   16 +-
 .../common/include/nrd1/nrd_css_def1.h        |   43 +
 .../common/include/nrd1/nrd_css_fw_def1.h     |   92 +
 .../common/include/nrd1/nrd_plat_arm_def1.h   |  249 +
 .../common/include/nrd1/nrd_ros_def1.h        |   35 +
 .../common/include/nrd1/nrd_ros_fw_def1.h     |   63 +
 .../common/include/nrd2/nrd_css_def2.h        |   47 +
 .../common/include/nrd2/nrd_css_fw_def2.h     |  107 +
 .../common/include/nrd2/nrd_plat_arm_def2.h   |  366 +
 .../common/include/nrd2/nrd_ros_def2.h        |   41 +
 .../common/include/nrd2/nrd_ros_fw_def2.h     |   84 +
 .../common/include/nrd3/nrd_css_def3.h        |  268 +
 .../common/include/nrd3/nrd_css_fw_def3.h     |  128 +
 .../common/include/nrd3/nrd_pas_def3.h        |  584 ++
 .../common/include/nrd3/nrd_plat_arm_def3.h   |  784 ++
 .../common/include/nrd3/nrd_ros_def3.h        |   29 +
 .../common/include/nrd3/nrd_ros_fw_def3.h     |   44 +
 .../common/include/nrd_dmc620_tzc_regions.h}  |   12 +-
 .../neoverse_rd/common/include/nrd_plat.h     |   13 +
 .../neoverse_rd/common/include/nrd_ras.h}     |   30 +-
 .../neoverse_rd/common/include/nrd_sdei.h     |   25 +
 .../neoverse_rd/common/include/nrd_variant.h} |   30 +-
 .../neoverse_rd/common}/include/plat_macros.S |    2 +-
 .../neoverse_rd/common/nrd-common.mk}         |   34 +-
 .../board/neoverse_rd/common/nrd_bl1_setup.c  |   19 +
 .../board/neoverse_rd/common/nrd_bl31_setup.c |  259 +
 .../neoverse_rd/common/nrd_image_load.c}      |   30 +-
 .../neoverse_rd/common/nrd_interconnect.c}    |    2 +-
 .../neoverse_rd/common/nrd_plat1.c}           |   61 +-
 .../neoverse_rd/common/nrd_plat2.c}           |   73 +-
 plat/arm/board/neoverse_rd/common/nrd_plat3.c |  102 +
 .../neoverse_rd/common/nrd_topology.c}        |    8 +-
 .../neoverse_rd/common/ras/nrd_ras_common.c}  |   36 +-
 .../neoverse_rd/common/ras/nrd_ras_cpu.c}     |  132 +-
 .../neoverse_rd/common/ras/nrd_ras_sram.c}    |   25 +-
 .../rdn1edge/fdts/rdn1edge_fw_config.dts      |    2 +-
 .../rdn1edge/fdts/rdn1edge_nt_fw_config.dts   |    2 +-
 .../rdn1edge/fdts/rdn1edge_tb_fw_config.dts   |    2 +-
 .../platform/rdn1edge/include/platform_def.h  |   44 +
 .../platform}/rdn1edge/platform.mk            |   38 +-
 .../platform}/rdn1edge/rdn1edge_err.c         |    2 +-
 .../platform}/rdn1edge/rdn1edge_plat.c        |   38 +-
 .../platform}/rdn1edge/rdn1edge_security.c    |    6 +-
 .../platform}/rdn1edge/rdn1edge_topology.c    |   16 +-
 .../rdn1edge/rdn1edge_trusted_boot.c          |    2 +-
 .../platform/rdn2/fdts/rdn2_fw_config.dts}    |   10 +-
 .../platform}/rdn2/fdts/rdn2_nt_fw_config.dts |    2 +-
 .../rdn2/fdts/rdn2_stmm_sel0_manifest.dts     |  147 +
 .../platform}/rdn2/fdts/rdn2_tb_fw_config.dts |    2 +-
 .../platform/rdn2/include/platform_def.h      |   93 +
 .../platform/rdn2/include/rdn2_ras.h          |   14 +
 .../platform}/rdn2/platform.mk                |   82 +-
 .../platform}/rdn2/rdn2_err.c                 |    2 +-
 .../platform}/rdn2/rdn2_plat.c                |   96 +-
 .../platform}/rdn2/rdn2_ras.c                 |   27 +-
 .../platform}/rdn2/rdn2_security.c            |   30 +-
 .../platform}/rdn2/rdn2_topology.c            |   50 +-
 .../platform}/rdn2/rdn2_trusted_boot.c        |    2 +-
 .../platform}/rdv1/fdts/rdv1_fw_config.dts    |    2 +-
 .../platform}/rdv1/fdts/rdv1_nt_fw_config.dts |    2 +-
 .../platform}/rdv1/fdts/rdv1_tb_fw_config.dts |    2 +-
 .../platform}/rdv1/include/platform_def.h     |   30 +-
 .../platform}/rdv1/platform.mk                |   34 +-
 .../platform}/rdv1/rdv1_err.c                 |    2 +-
 .../platform}/rdv1/rdv1_plat.c                |   13 +-
 .../platform}/rdv1/rdv1_security.c            |    2 +-
 .../platform}/rdv1/rdv1_topology.c            |   34 +-
 .../platform}/rdv1/rdv1_trusted_boot.c        |    2 +-
 .../rdv1mc/fdts/rdv1mc_fw_config.dts          |    2 +-
 .../rdv1mc/fdts/rdv1mc_nt_fw_config.dts       |    2 +-
 .../rdv1mc/fdts/rdv1mc_tb_fw_config.dts       |    2 +-
 .../platform}/rdv1mc/include/platform_def.h   |   30 +-
 .../platform}/rdv1mc/platform.mk              |   38 +-
 .../platform}/rdv1mc/rdv1mc_err.c             |    2 +-
 .../platform}/rdv1mc/rdv1mc_plat.c            |   78 +-
 .../platform}/rdv1mc/rdv1mc_security.c        |   24 +-
 .../platform}/rdv1mc/rdv1mc_topology.c        |   53 +-
 .../platform}/rdv1mc/rdv1mc_trusted_boot.c    |    2 +-
 .../platform/rdv3/fdts/rdv3_fw_config.dts}    |    6 +-
 .../platform/rdv3/fdts/rdv3_nt_fw_config.dts} |    5 +-
 .../platform/rdv3/fdts/rdv3_tb_fw_config.dts} |    2 +-
 .../platform/rdv3/include/platform_def.h      |   51 +
 .../platform/rdv3/include/rdv3_mhuv3.h        |   12 +
 .../platform/rdv3/include/rdv3_rse_comms.h    |   12 +
 .../neoverse_rd/platform/rdv3/platform.mk     |  156 +
 .../platform/rdv3/rdv3_bl1_measured_boot.c    |   60 +
 .../platform/rdv3/rdv3_bl2_measured_boot.c    |   69 +
 .../platform/rdv3/rdv3_bl2_setup.c            |   97 +
 .../platform/rdv3/rdv3_bl31_setup.c           |  221 +
 .../neoverse_rd/platform/rdv3/rdv3_common.c   |  183 +
 .../platform/rdv3/rdv3_common_measured_boot.c |   41 +
 .../neoverse_rd/platform/rdv3/rdv3_err.c      |   17 +
 .../neoverse_rd/platform/rdv3/rdv3_mhuv3.c    |   23 +
 .../platform/rdv3/rdv3_plat_attest_token.c    |   35 +
 .../platform/rdv3/rdv3_realm_attest_key.c     |   26 +
 .../neoverse_rd/platform/rdv3/rdv3_security.c |   10 +
 .../neoverse_rd/platform/rdv3/rdv3_topology.c |  100 +
 .../platform/rdv3/rdv3_trusted_boot.c}        |    2 +-
 .../sgi575/fdts/sgi575_fw_config.dts          |    2 +-
 .../sgi575/fdts/sgi575_nt_fw_config.dts       |    2 +-
 .../sgi575/fdts/sgi575_tb_fw_config.dts       |    2 +-
 .../platform/sgi575/include/platform_def.h    |   37 +
 .../platform}/sgi575/platform.mk              |   36 +-
 .../platform}/sgi575/sgi575_err.c             |    2 +-
 .../platform}/sgi575/sgi575_plat.c            |   15 +-
 .../platform}/sgi575/sgi575_security.c        |    6 +-
 .../platform}/sgi575/sgi575_topology.c        |    6 +-
 .../platform}/sgi575/sgi575_trusted_boot.c    |    2 +-
 .../arm/board/rde1edge/include/platform_def.h |   48 -
 plat/arm/board/rde1edge/platform.mk           |   69 -
 plat/arm/board/rde1edge/rde1edge_err.c        |   17 -
 plat/arm/board/rde1edge/rde1edge_plat.c       |   29 -
 plat/arm/board/rde1edge/rde1edge_security.c   |   36 -
 plat/arm/board/rde1edge/rde1edge_topology.c   |   36 -
 .../arm/board/rdn1edge/include/platform_def.h |   54 -
 plat/arm/board/rdn2/include/platform_def.h    |  126 -
 plat/arm/board/rdn2/include/rdn2_ras.h        |   14 -
 plat/arm/board/sgi575/include/platform_def.h  |   49 -
 plat/arm/board/tc/fdts/dice_prot_env.dtsi     |   11 +
 plat/arm/board/tc/fdts/tc_fw_config.dts       |   12 +-
 plat/arm/board/tc/fdts/tc_nt_fw_config.dts    |   13 +
 .../tc/fdts/tc_spmc_common_sp_manifest.dtsi   |   61 +
 ...pmc_manifest.dts => tc_spmc_manifest.dtsi} |   63 +-
 .../tc/fdts/tc_spmc_optee_sp_manifest.dts     |  128 +-
 .../board/tc/fdts/tc_spmc_test_manifest.dts   |   41 +
 .../tc/fdts/tc_spmc_trusty_sp_manifest.dts    |   17 +
 plat/arm/board/tc/fdts/tc_tb_fw_config.dts    |   14 +-
 plat/arm/board/tc/include/platform_def.h      |  211 +-
 plat/arm/board/tc/include/tc_helpers.S        |   44 +-
 plat/arm/board/tc/include/tc_plat.h           |    4 +-
 plat/arm/board/tc/nv_counter_test.c           |   20 +-
 plat/arm/board/tc/plat_def_fip_uuid.h         |   16 +-
 plat/arm/board/tc/plat_tc_mbedtls_config.h    |   25 +-
 plat/arm/board/tc/platform.mk                 |  237 +-
 plat/arm/board/tc/platform_test.mk            |   70 +-
 plat/arm/board/tc/rotpk_test.c                |   16 +-
 ...ss_ap_test_stubs.c => rse_ap_test_stubs.c} |    8 +-
 .../tc/{rss_ap_tests.c => rse_ap_tests.c}     |    6 +-
 ...ss_ap_testsuites.c => rse_ap_testsuites.c} |    2 +-
 ...ss_ap_testsuites.h => rse_ap_testsuites.h} |    6 +-
 plat/arm/board/tc/tc_bl1_dpe.c                |  158 +
 plat/arm/board/tc/tc_bl1_measured_boot.c      |   26 +-
 plat/arm/board/tc/tc_bl1_setup.c              |   19 +
 plat/arm/board/tc/tc_bl2_dpe.c                |  255 +
 plat/arm/board/tc/tc_bl2_measured_boot.c      |   33 +-
 plat/arm/board/tc/tc_bl31_setup.c             |  106 +-
 plat/arm/board/tc/tc_common_dpe.c             |   36 +
 plat/arm/board/tc/tc_common_measured_boot.c   |   12 +-
 plat/arm/board/tc/tc_dpe.h                    |   53 +
 plat/arm/board/tc/tc_plat.c                   |   17 +-
 plat/arm/board/tc/tc_security.c               |    6 +-
 plat/arm/board/tc/tc_topology.c               |   19 +-
 plat/arm/board/tc/tc_trng.c                   |   43 +
 plat/arm/common/arm_bl1_setup.c               |   94 +-
 plat/arm/common/arm_bl2_el3_setup.c           |   41 +-
 plat/arm/common/arm_bl2_setup.c               |  132 +-
 plat/arm/common/arm_bl31_setup.c              |  132 +-
 plat/arm/common/arm_common.c                  |   49 +-
 plat/arm/common/arm_common.mk                 |  107 +-
 plat/arm/common/arm_dyn_cfg.c                 |    4 +-
 plat/arm/common/arm_dyn_cfg_helpers.c         |  147 +-
 plat/arm/common/arm_image_load.c              |   20 +-
 plat/arm/common/arm_io_storage.c              |    1 +
 plat/arm/common/arm_ni.c                      |  167 +
 plat/arm/common/arm_pm.c                      |    6 +-
 plat/arm/common/arm_sip_svc.c                 |   14 +-
 plat/arm/common/arm_transfer_list.c           |   76 +
 plat/arm/common/fconf/arm_fconf_sp.c          |   30 +-
 plat/arm/common/plat_arm_mbedtls_config.h     |   26 +
 plat/arm/common/plat_arm_psa_mbedtls_config.h |   29 +
 plat/arm/common/plat_arm_sip_svc.c            |   82 +-
 plat/arm/common/sp_min/arm_sp_min_setup.c     |    6 +-
 plat/arm/css/common/css_pm.c                  |   13 +-
 .../css/sgi/include/sgi_base_platform_def.h   |  304 -
 plat/arm/css/sgi/include/sgi_plat.h           |   13 -
 plat/arm/css/sgi/include/sgi_sdei.h           |   25 -
 plat/arm/css/sgi/include/sgi_soc_css_def.h    |   47 -
 plat/arm/css/sgi/include/sgi_soc_css_def_v2.h |  207 -
 .../css/sgi/include/sgi_soc_platform_def.h    |   33 -
 .../css/sgi/include/sgi_soc_platform_def_v2.h |   31 -
 plat/arm/css/sgi/sgi_bl31_setup.c             |  136 -
 plat/aspeed/ast2700/include/platform_def.h    |   11 +-
 plat/aspeed/ast2700/include/platform_reg.h    |    4 +
 plat/aspeed/ast2700/plat_bl31_setup.c         |   88 +
 plat/aspeed/ast2700/plat_helpers.S            |    6 -
 plat/brcm/common/brcm_bl31_setup.c            |    4 +-
 plat/common/aarch32/plat_common.c             |   11 +-
 plat/common/aarch64/crash_console_helpers.S   |    4 +-
 plat/common/aarch64/plat_common.c             |   24 +-
 plat/common/plat_bl1_common.c                 |   49 +-
 plat/common/plat_bl_common.c                  |    8 +-
 plat/common/plat_gicv3.c                      |    7 +-
 plat/hisilicon/hikey/hikey_bl31_setup.c       |    6 +-
 plat/hisilicon/hikey/platform.mk              |   14 +-
 plat/hisilicon/hikey960/hikey960_bl31_setup.c |    2 +-
 plat/hisilicon/hikey960/platform.mk           |   14 +-
 plat/hisilicon/poplar/bl31_plat_setup.c       |    7 +-
 plat/hisilicon/poplar/include/hi3798cv200.h   |    4 +
 plat/hisilicon/poplar/plat_pm.c               |   10 +-
 plat/imx/common/imx8_helpers.S                |   47 +-
 plat/imx/common/imx_bl31_common.c             |   23 +
 plat/imx/common/imx_common.c                  |   48 +
 plat/imx/common/imx_sip_handler.c             |   97 +-
 plat/imx/common/imx_sip_svc.c                 |   22 +-
 plat/imx/common/include/imx_plat_common.h     |   16 +
 plat/imx/common/include/imx_sip_svc.h         |   26 +-
 plat/imx/common/include/plat_common.h         |   17 +
 plat/imx/imx7/common/imx7.mk                  |   15 +-
 plat/imx/imx8m/ddr/clock.c                    |    6 +-
 plat/imx/imx8m/imx8m_ccm.c                    |    8 +-
 plat/imx/imx8m/imx8m_measured_boot.c          |   13 +-
 plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c     |   42 +-
 plat/imx/imx8m/imx8mm/include/imx_sec_def.h   |   22 +
 plat/imx/imx8m/imx8mm/include/platform_def.h  |    9 +
 plat/imx/imx8m/imx8mm/platform.mk             |   36 +-
 plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c     |   22 +-
 plat/imx/imx8m/imx8mn/include/imx_sec_def.h   |   19 +
 plat/imx/imx8m/imx8mn/include/platform_def.h  |    9 +
 plat/imx/imx8m/imx8mn/platform.mk             |   17 +-
 plat/imx/imx8m/imx8mp/gpc.c                   |   16 +-
 plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c     |   58 +-
 plat/imx/imx8m/imx8mp/include/imx_sec_def.h   |   35 +
 plat/imx/imx8m/imx8mp/include/platform_def.h  |   10 +
 plat/imx/imx8m/imx8mp/platform.mk             |   30 +-
 plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c     |    8 +-
 plat/imx/imx8m/imx8mq/include/platform_def.h  |    7 +
 plat/imx/imx8m/imx8mq/platform.mk             |   17 +-
 plat/imx/imx8m/imx_rdc.c                      |   69 +-
 plat/imx/imx8m/include/dram.h                 |    8 +-
 plat/imx/imx8m/include/imx8m_csu.h            |    7 +-
 plat/imx/imx8m/include/imx_rdc.h              |    2 +-
 plat/imx/imx8qm/imx8qm_bl31_setup.c           |    7 +-
 plat/imx/imx8qx/imx8qx_bl31_setup.c           |    7 +-
 plat/imx/imx8ulp/apd_context.c                |  657 ++
 plat/imx/imx8ulp/dram.c                       |  798 ++
 plat/imx/imx8ulp/imx8ulp_bl31_setup.c         |  186 +
 plat/imx/imx8ulp/imx8ulp_caam.c               |   18 +
 plat/imx/imx8ulp/imx8ulp_psci.c               |  555 ++
 plat/imx/imx8ulp/include/dram.h               |   13 +
 plat/imx/imx8ulp/include/imx8ulp_caam.h       |   24 +
 plat/imx/imx8ulp/include/platform_def.h       |  124 +
 plat/imx/imx8ulp/include/scmi.h               |  100 +
 plat/imx/imx8ulp/include/scmi_sensor.h        |  139 +
 plat/imx/imx8ulp/include/xrdc.h               |   47 +
 plat/imx/imx8ulp/platform.mk                  |   69 +
 plat/imx/imx8ulp/scmi/scmi.c                  |   69 +
 plat/imx/imx8ulp/scmi/scmi_pd.c               |  371 +
 plat/imx/imx8ulp/scmi/scmi_sensor.c           |   85 +
 plat/imx/imx8ulp/upower/upmu.h                |  279 +
 plat/imx/imx8ulp/upower/upower_api.c          | 3095 +++++++
 plat/imx/imx8ulp/upower/upower_api.h          | 1629 ++++
 plat/imx/imx8ulp/upower/upower_defs.h         |  742 ++
 plat/imx/imx8ulp/upower/upower_hal.c          |  201 +
 plat/imx/imx8ulp/upower/upower_soc_defs.h     | 1154 +++
 plat/imx/imx8ulp/xrdc/xrdc_config.h           |  136 +
 plat/imx/imx8ulp/xrdc/xrdc_core.c             |  327 +
 plat/imx/imx93/imx93_bl31_setup.c             |    9 +-
 plat/imx/imx93/include/platform_def.h         |    3 +
 plat/imx/imx93/platform.mk                    |    4 +-
 plat/intel/soc/agilex/bl2_plat_setup.c        |   35 +-
 plat/intel/soc/agilex/bl31_plat_setup.c       |   86 +-
 .../soc/agilex/include/agilex_clock_manager.h |    1 +
 .../agilex/include/agilex_memory_controller.h |    3 +-
 .../agilex/include/agilex_system_manager.h    |   18 +-
 .../soc/agilex/include/socfpga_plat_def.h     |   71 +-
 plat/intel/soc/agilex/platform.mk             |   39 +-
 .../soc/agilex/soc/agilex_clock_manager.c     |   26 +-
 plat/intel/soc/agilex5/bl2_plat_setup.c       |  115 +-
 plat/intel/soc/agilex5/bl31_plat_setup.c      |   23 +-
 .../intel/soc/agilex5/include/agilex5_cache.h |   13 +
 .../agilex5/include/agilex5_clock_manager.h   |  392 +-
 plat/intel/soc/agilex5/include/agilex5_ddr.h  |   31 +
 .../agilex5/include/agilex5_iossm_mailbox.h   |  155 +
 .../soc/agilex5/include/agilex5_pinmux.h      |   21 +-
 .../agilex5/include/agilex5_power_manager.h   |    5 +-
 .../agilex5/include/agilex5_system_manager.h  |   39 +-
 .../soc/agilex5/include/socfpga_plat_def.h    |   72 +-
 plat/intel/soc/agilex5/platform.mk            |   42 +-
 plat/intel/soc/agilex5/soc/agilex5_cache.S    |  114 +
 .../soc/agilex5/soc/agilex5_clock_manager.c   |  653 +-
 plat/intel/soc/agilex5/soc/agilex5_ddr.c      |  434 +
 .../soc/agilex5/soc/agilex5_iossm_mailbox.c   |  811 ++
 plat/intel/soc/agilex5/soc/agilex5_pinmux.c   |   83 +-
 .../soc/agilex5/soc/agilex5_power_manager.c   |    7 +-
 plat/intel/soc/common/aarch64/plat_helpers.S  |   41 +-
 .../soc/common/aarch64/platform_common.c      |    6 -
 .../soc/common/bl2_plat_mem_params_desc.c     |   18 +
 plat/intel/soc/common/drivers/ccu/ncore_ccu.c |  575 +-
 plat/intel/soc/common/drivers/ccu/ncore_ccu.h |  529 +-
 plat/intel/soc/common/drivers/ddr/ddr.c       |  141 +
 plat/intel/soc/common/drivers/ddr/ddr.h       |   56 +
 plat/intel/soc/common/drivers/nand/nand.c     |   10 +-
 .../soc/common/drivers/qspi/cadence_qspi.c    |   13 +-
 plat/intel/soc/common/drivers/sdmmc/sdmmc.c   |  611 +-
 plat/intel/soc/common/drivers/sdmmc/sdmmc.h   |   13 +-
 plat/intel/soc/common/drivers/wdt/watchdog.h  |    7 +-
 plat/intel/soc/common/include/platform_def.h  |   35 +-
 .../soc/common/include/socfpga_handoff.h      |   37 +-
 .../soc/common/include/socfpga_mailbox.h      |   18 +-
 .../soc/common/include/socfpga_private.h      |   10 +-
 .../common/include/socfpga_reset_manager.h    |    2 +
 plat/intel/soc/common/include/socfpga_ros.h   |   62 +
 .../soc/common/include/socfpga_sip_svc.h      |  154 +-
 .../common/include/socfpga_system_manager.h   |    6 +-
 plat/intel/soc/common/include/socfpga_vab.h   |   48 +-
 plat/intel/soc/common/lib/sha/sha.c           |  253 +
 plat/intel/soc/common/lib/sha/sha.h           |  166 +
 plat/intel/soc/common/sip/socfpga_sip_fcs.c   |  111 +-
 plat/intel/soc/common/soc/socfpga_handoff.c   |   13 +-
 plat/intel/soc/common/soc/socfpga_mailbox.c   |   24 +-
 .../soc/common/soc/socfpga_reset_manager.c    |  693 +-
 .../soc/common/soc/socfpga_system_manager.c   |   31 +
 plat/intel/soc/common/socfpga_delay_timer.c   |    8 +-
 plat/intel/soc/common/socfpga_image_load.c    |    7 +
 plat/intel/soc/common/socfpga_psci.c          |   29 +-
 plat/intel/soc/common/socfpga_ros.c           |  188 +
 plat/intel/soc/common/socfpga_sip_svc.c       |  120 +-
 plat/intel/soc/common/socfpga_storage.c       |   29 +-
 plat/intel/soc/common/socfpga_vab.c           |   93 +-
 plat/intel/soc/n5x/bl31_plat_setup.c          |    2 -
 .../intel/soc/n5x/include/n5x_clock_manager.h |   10 +-
 .../soc/n5x/include/n5x_system_manager.h      |   18 +-
 plat/intel/soc/n5x/include/socfpga_plat_def.h |   68 +-
 plat/intel/soc/n5x/platform.mk                |   27 +-
 plat/intel/soc/n5x/soc/n5x_clock_manager.c    |   20 +-
 plat/intel/soc/stratix10/bl2_plat_setup.c     |    4 +-
 plat/intel/soc/stratix10/bl31_plat_setup.c    |    2 -
 .../soc/stratix10/include/s10_clock_manager.h |    3 +-
 .../stratix10/include/s10_memory_controller.h |    3 +-
 .../stratix10/include/s10_system_manager.h    |   17 +-
 .../soc/stratix10/include/socfpga_plat_def.h  |   56 +-
 plat/intel/soc/stratix10/platform.mk          |   29 +-
 .../soc/stratix10/soc/s10_clock_manager.c     |   62 +-
 .../marvell/armada/a3k/common/a3700_common.mk |  101 +-
 .../armada/a3k/common/cm3_system_reset.c      |  132 +
 .../armada/a3k/common/include/a3700_pm.h      |    2 +
 plat/marvell/armada/a3k/common/plat_pm.c      |    2 +-
 plat/marvell/armada/a8k/common/a8k_common.mk  |   20 +-
 plat/marvell/armada/a8k/common/ble/ble.mk     |    2 +-
 .../armada/common/marvell_bl31_setup.c        |    4 +-
 plat/marvell/armada/common/marvell_common.mk  |   14 +-
 .../build_helpers/mtk_build_helpers.mk        |   21 +-
 plat/mediatek/common/mtk_bl31_setup.c         |    3 +-
 plat/mediatek/common/mtk_smc_handlers.c       |    8 +-
 .../drivers/apusys/apusys_rv/2.0/apusys_rv.c  |   89 -
 .../drivers/apusys/mt8188/apusys_devapc.c     |    7 -
 plat/mediatek/drivers/emi_mpu/emi_mpu.h       |    3 +-
 .../mediatek/drivers/emi_mpu/emi_mpu_common.c |   48 +-
 .../mediatek/drivers/emi_mpu/mt8188/emi_mpu.c |   96 +-
 .../drivers/emi_mpu/mt8188/emi_mpu_priv.h     |   30 +-
 plat/mediatek/drivers/gic600/mt_gic_v3.c      |    8 +-
 .../drivers/iommu/mt8188/mtk_iommu_plat.c     |   18 +-
 .../drivers/iommu/mt8188/mtk_iommu_plat.h     |   15 +-
 plat/mediatek/drivers/iommu/mtk_iommu_priv.h  |   31 +
 plat/mediatek/drivers/iommu/mtk_iommu_smc.c   |   83 +-
 plat/mediatek/drivers/iommu/mtk_iommu_smc.h   |   15 +
 plat/mediatek/drivers/rng/mt8186/rng_plat.c   |  153 +
 plat/mediatek/drivers/rng/mt8186/rng_plat.h   |   30 +
 plat/mediatek/drivers/rng/mt8188/rng_plat.c   |   96 +
 plat/mediatek/drivers/rng/mt8188/rng_plat.h   |   46 +
 plat/mediatek/drivers/rng/rng.c               |   29 +
 plat/mediatek/drivers/rng/rules.mk            |   17 +
 .../{mt8188 => }/include/plat_helpers.h       |    2 +-
 plat/mediatek/mt8186/include/plat_helpers.h   |   12 -
 plat/mediatek/mt8186/include/platform_def.h   |   11 +-
 plat/mediatek/mt8186/platform.mk              |   10 +-
 plat/mediatek/mt8188/include/platform_def.h   |   20 +-
 plat/mediatek/mt8188/plat_config.mk           |    5 +-
 plat/mediatek/mt8188/platform.mk              |    5 +-
 .../mediatek/mt8192/drivers/emi_mpu/emi_mpu.c |   19 +-
 plat/mediatek/mt8192/include/plat_helpers.h   |   12 -
 plat/mediatek/mt8192/include/platform_def.h   |    4 +-
 .../mediatek/mt8195/drivers/emi_mpu/emi_mpu.c |    2 +-
 plat/mediatek/mt8195/include/plat_helpers.h   |   12 -
 plat/mediatek/mt8195/include/platform_def.h   |    7 +-
 plat/nuvoton/common/nuvoton_helpers.S         |    2 +-
 plat/nuvoton/npcm845x/npcm845x_bl31_setup.c   |   33 +-
 plat/nuvoton/npcm845x/platform.mk             |   48 +-
 plat/nvidia/tegra/common/tegra_bl31_setup.c   |    2 +-
 plat/nvidia/tegra/common/tegra_fiq_glue.c     |    4 +-
 plat/nvidia/tegra/platform.mk                 |    4 +-
 .../tegra/soc/t194/plat_psci_handlers.c       |    4 +-
 plat/nxp/common/fip_handler/fuse_fip/fuse.mk  |   12 +-
 plat/nxp/common/tbbr/tbbr.mk                  |   12 +-
 .../s32/s32g274ardb2/include/plat_console.h   |   12 +
 .../s32/s32g274ardb2/include/plat_helpers.h   |   12 +
 .../s32g274ardb2/include/plat_io_storage.h    |   12 +
 .../s32/s32g274ardb2/include/plat_macros.S    |   22 +
 .../s32/s32g274ardb2/include/platform_def.h   |   77 +
 .../s32/s32g274ardb2/include/s32cc-ncore.h    |  102 +
 .../nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c |   80 +
 .../s32/s32g274ardb2/plat_bl2_image_desc.c    |   41 +
 plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c   |   75 +
 plat/nxp/s32/s32g274ardb2/plat_console.c      |   29 +
 plat/nxp/s32/s32g274ardb2/plat_helpers.S      |  129 +
 plat/nxp/s32/s32g274ardb2/plat_io_storage.c   |  135 +
 plat/nxp/s32/s32g274ardb2/platform.mk         |   76 +
 plat/nxp/s32/s32g274ardb2/s32cc_ncore.c       |   99 +
 plat/nxp/s32/s32g274ardb2/s32g2_psci.c        |   20 +
 plat/nxp/s32/s32g274ardb2/s32g2_soc.c         |   52 +
 plat/nxp/soc-lx2160a/ddr_fip.mk               |   22 +-
 plat/nxp/soc-lx2160a/ddr_sb.mk                |    2 +-
 plat/nxp/soc-lx2160a/ddr_tbbr.mk              |    2 -
 plat/qemu/common/common.mk                    |   17 +-
 plat/qemu/common/qemu_bl2_mem_params_desc.c   |   23 +-
 plat/qemu/common/qemu_bl2_setup.c             |  181 +-
 plat/qemu/common/qemu_bl31_setup.c            |   76 +-
 plat/qemu/common/qemu_common.c                |  172 +-
 plat/qemu/common/qemu_io_storage.c            |   17 +-
 plat/qemu/common/qemu_plat_attest_token.c     |  232 +
 plat/qemu/common/qemu_pm.c                    |   17 -
 plat/qemu/common/qemu_realm_attest_key.c      |   36 +
 plat/qemu/common/trp/qemu_trp_setup.c         |   48 +
 plat/qemu/common/trp/trp-qemu-common.mk       |   12 +
 plat/qemu/qemu/include/platform_def.h         |   91 +-
 plat/qemu/qemu/include/qemu_pas_def.h         |  108 +
 plat/qemu/qemu/platform.mk                    |   34 +-
 plat/qemu/qemu/qemu_measured_boot.c           |   23 +-
 plat/qemu/qemu/trp/trp-qemu.mk                |    8 +
 plat/qemu/qemu_sbsa/include/platform_def.h    |   10 +-
 plat/qemu/qemu_sbsa/sbsa_sip_svc.c            |  270 +-
 plat/qti/common/src/aarch64/qti_kryo4_gold.S  |   12 +-
 .../qti/common/src/aarch64/qti_kryo4_silver.S |   13 +-
 plat/qti/common/src/aarch64/qti_kryo6_gold.S  |   12 +-
 .../qti/common/src/aarch64/qti_kryo6_silver.S |   13 +-
 .../qtiseclib/src/qtiseclib_cb_interface.c    |    6 +-
 plat/renesas/common/aarch64/plat_helpers.S    |    7 +-
 plat/renesas/common/aarch64/platform_common.c |   26 +-
 plat/renesas/common/bl2_secure_setting.c      |   98 +-
 plat/renesas/common/include/platform_def.h    |    8 +-
 plat/renesas/common/include/rcar_def.h        |   31 +-
 plat/renesas/common/include/rcar_version.h    |    2 +-
 plat/renesas/rcar/bl2_plat_setup.c            |  287 +-
 plat/renesas/rcar/platform.mk                 |   31 +-
 plat/renesas/rcar/rcar_stack_protector.c      |   36 +
 plat/renesas/rzg/platform.mk                  |   24 +-
 .../rockchip/common/aarch32/platform_common.c |    2 +-
 plat/rockchip/common/aarch64/plat_helpers.S   |   18 +-
 .../rockchip/common/aarch64/platform_common.c |   11 +-
 plat/rockchip/common/bl31_plat_setup.c        |   11 +-
 plat/rockchip/common/include/plat_macros.S    |    6 +-
 .../rockchip/common/include/plat_pm_helpers.h |   51 +
 plat/rockchip/common/include/plat_private.h   |   10 +-
 .../common/include/rockchip_sip_svc.h         |    1 +
 plat/rockchip/common/plat_pm_helpers.c        |  213 +
 plat/rockchip/common/scmi/scmi.c              |   89 +
 plat/rockchip/common/scmi/scmi_clock.c        |  157 +
 plat/rockchip/common/scmi/scmi_clock.h        |   50 +
 plat/rockchip/common/scmi/scmi_rstd.c         |   74 +
 plat/rockchip/common/scmi/scmi_rstd.h         |   45 +
 plat/rockchip/rk3328/platform.mk              |    1 +
 plat/rockchip/rk3399/drivers/m0/Makefile      |   42 +-
 plat/rockchip/rk3399/drivers/pmu/pmu_fw.S     |   21 +
 plat/rockchip/rk3399/drivers/pmu/pmu_fw.c     |   22 -
 plat/rockchip/rk3399/platform.mk              |    9 +-
 .../rk3568/drivers/pmu/plat_pmu_macros.S      |   18 +
 plat/rockchip/rk3568/drivers/pmu/pmu.c        |  543 ++
 plat/rockchip/rk3568/drivers/pmu/pmu.h        |  304 +
 plat/rockchip/rk3568/drivers/soc/soc.c        |  103 +
 plat/rockchip/rk3568/drivers/soc/soc.h        |   63 +
 plat/rockchip/rk3568/include/plat.ld.S        |   36 +
 plat/rockchip/rk3568/include/plat_sip_calls.h |   12 +
 plat/rockchip/rk3568/include/platform_def.h   |  136 +
 plat/rockchip/rk3568/plat_sip_calls.c         |   29 +
 plat/rockchip/rk3568/platform.mk              |   96 +
 plat/rockchip/rk3568/rk3568_def.h             |  104 +
 .../rk3588/drivers/pmu/plat_pmu_macros.S      |   21 +
 plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.c |  555 ++
 plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.h |   23 +
 plat/rockchip/rk3588/drivers/pmu/pmu.c        | 1512 +++
 plat/rockchip/rk3588/drivers/pmu/pmu.h        |  589 ++
 .../rockchip/rk3588/drivers/scmi/rk3588_clk.c | 2463 +++++
 .../rockchip/rk3588/drivers/scmi/rk3588_clk.h |  104 +
 .../rk3588/drivers/scmi/rk3588_rstd.c         |   96 +
 plat/rockchip/rk3588/drivers/secure/secure.c  |  188 +
 plat/rockchip/rk3588/drivers/secure/secure.h  |   54 +
 plat/rockchip/rk3588/drivers/soc/soc.c        |   99 +
 plat/rockchip/rk3588/drivers/soc/soc.h        |  198 +
 plat/rockchip/rk3588/include/plat.ld.S        |   42 +
 plat/rockchip/rk3588/include/plat_sip_calls.h |   12 +
 plat/rockchip/rk3588/include/platform_def.h   |  119 +
 plat/rockchip/rk3588/plat_sip_calls.c         |   32 +
 plat/rockchip/rk3588/platform.mk              |   98 +
 plat/rockchip/rk3588/rk3588_def.h             |  224 +
 .../aarch64/armstub8_header.S                 |    2 +-
 plat/rpi/common/aarch64/plat_helpers.S        |   31 +-
 .../{rpi4 => common}/include/plat_macros.S    |    2 +-
 plat/rpi/common/include/rpi_shared.h          |   18 +-
 plat/rpi/common/rpi3_common.c                 |   24 +-
 plat/rpi/common/rpi3_console_dual.c           |   35 +
 plat/rpi/common/rpi3_console_pl011.c          |   20 +
 plat/rpi/common/rpi3_pm.c                     |   18 +-
 plat/rpi/common/rpi3_topology.c               |   21 +-
 plat/rpi/{rpi4 => common}/rpi4_bl31_setup.c   |  111 +-
 .../rpi4_pci_svc.c => common/rpi_pci_svc.c}   |   95 +-
 plat/rpi/rpi3/include/plat_macros.S           |   20 -
 plat/rpi/rpi3/include/platform_def.h          |    3 +-
 plat/rpi/rpi3/include/rpi_hw.h                |   44 +-
 plat/rpi/rpi3/platform.mk                     |   34 +-
 plat/rpi/rpi3/rpi3_bl1_setup.c                |   13 +-
 plat/rpi/rpi4/include/platform_def.h          |    3 +-
 plat/rpi/rpi4/include/rpi_hw.h                |   51 +-
 plat/rpi/rpi4/platform.mk                     |   16 +-
 plat/rpi/rpi4/rpi4_setup.c                    |  109 +
 plat/rpi/rpi5/include/plat.ld.S               |   23 +
 plat/rpi/rpi5/include/platform_def.h          |  141 +
 plat/rpi/rpi5/include/rpi_hw.h                |   58 +
 plat/rpi/rpi5/platform.mk                     |  115 +
 plat/rpi/rpi5/rpi5_setup.c                    |   12 +
 plat/socionext/synquacer/platform.mk          |   14 +-
 plat/socionext/synquacer/sq_bl31_setup.c      |    2 +-
 plat/socionext/uniphier/platform.mk           |   18 +-
 plat/st/common/bl2_io_storage.c               |  147 +-
 plat/st/common/common.mk                      |   34 +-
 plat/st/common/common_rules.mk                |   44 +-
 .../include/plat_def_fip_uuid.h               |    6 +-
 plat/st/common/include/stm32mp_common.h       |   29 +-
 .../common/include/stm32mp_mbedtls_config-2.h |  119 -
 .../common/include/stm32mp_mbedtls_config-3.h |    3 +-
 plat/st/common/stm32mp_common.c               |   70 +-
 plat/st/common/stm32mp_crypto_lib.c           |    9 +-
 plat/st/common/stm32mp_dt.c                   |    6 +-
 plat/st/common/stm32mp_fconf_io.c             |   33 +-
 plat/st/common/stm32mp_gic.c                  |   21 +-
 plat/st/common/stm32mp_trusted_boot.c         |    8 +-
 plat/st/stm32mp1/bl2_plat_setup.c             |   29 +-
 plat/st/stm32mp1/cert_create_tbbr.mk          |    3 +-
 plat/st/stm32mp1/include/platform_def.h       |   16 +-
 plat/st/stm32mp1/include/stm32mp1_private.h   |   49 +-
 plat/st/stm32mp1/plat_ddr.c                   |  135 +
 plat/st/stm32mp1/platform.mk                  |   44 +-
 plat/st/stm32mp1/services/bsec_svc.c          |   11 +-
 plat/st/stm32mp1/sp_min/sp_min_setup.c        |    7 +-
 plat/st/stm32mp1/stm32mp1_def.h               |   47 +-
 plat/st/stm32mp1/stm32mp1_fip_def.h           |    8 +-
 plat/st/stm32mp1/stm32mp1_pm.c                |   11 +-
 plat/st/stm32mp1/stm32mp1_private.c           |   83 +-
 plat/st/stm32mp1/stm32mp1_syscfg.c            |   24 +-
 plat/st/stm32mp2/aarch64/stm32mp2_helper.S    |   45 +-
 plat/st/stm32mp2/bl2_plat_setup.c             |  372 +-
 plat/st/stm32mp2/bl31_plat_setup.c            |  159 +
 plat/st/stm32mp2/include/boot_api.h           |    2 +-
 plat/st/stm32mp2/include/plat_tbbr_img_def.h  |   55 +
 plat/st/stm32mp2/include/platform_def.h       |   78 +-
 plat/st/stm32mp2/include/stm32mp2_private.h   |   53 +
 plat/st/stm32mp2/plat_bl2_mem_params_desc.c   |  139 +-
 plat/st/stm32mp2/plat_ddr.c                   |  217 +
 plat/st/stm32mp2/platform.mk                  |  187 +-
 plat/st/stm32mp2/stm32mp2_def.h               |  214 +-
 plat/st/stm32mp2/stm32mp2_pm.c                |  124 +
 plat/st/stm32mp2/stm32mp2_private.c           |  334 +
 plat/st/stm32mp2/stm32mp2_syscfg.c            |   31 +
 plat/st/stm32mp2/stm32mp2_topology.c          |   57 +
 plat/st/stm32mp2/stm32mp2_usb_dfu.c           |   21 +
 .../k3/common/drivers/sec_proxy/sec_proxy.c   |    2 +-
 plat/ti/k3/common/drivers/ti_sci/ti_sci.c     |   51 +-
 plat/ti/k3/common/drivers/ti_sci/ti_sci.h     |   50 +-
 .../common/drivers/ti_sci/ti_sci_protocol.h   |   28 +
 plat/ti/k3/common/k3_bl31_setup.c             |   38 +-
 plat/ti/k3/common/k3_psci.c                   |   24 +-
 plat/ti/k3/common/plat_common.mk              |    2 +
 plat/xilinx/common/include/plat_clkfunc.h     |   13 +
 plat/xilinx/common/include/plat_common.h      |   12 +
 plat/xilinx/common/include/plat_console.h     |   24 +-
 plat/xilinx/common/include/plat_fdt.h         |    4 +
 plat/xilinx/common/include/plat_xfer_list.h   |   15 +
 plat/xilinx/common/include/pm_api_sys.h       |   11 +-
 plat/xilinx/common/include/pm_client.h        |    3 +-
 plat/xilinx/common/include/pm_common.h        |    5 +-
 plat/xilinx/common/include/pm_defs.h          |    8 +-
 plat/xilinx/common/include/pm_svc_main.h      |    7 +-
 plat/xilinx/common/ipi.c                      |   10 +-
 .../ipi_mailbox_service/ipi_mailbox_svc.c     |   17 +-
 plat/xilinx/common/plat_clkfunc.c             |   41 +
 plat/xilinx/common/plat_console.c             |  319 +-
 plat/xilinx/common/plat_fdt.c                 |  169 +-
 plat/xilinx/common/plat_startup.c             |    6 +-
 plat/xilinx/common/plat_xfer_list.c           |   50 +
 plat/xilinx/common/pm_service/pm_api_sys.c    |  247 +-
 plat/xilinx/common/pm_service/pm_ipi.c        |   53 +-
 plat/xilinx/common/pm_service/pm_svc_main.c   |  235 +-
 plat/xilinx/common/versal.c                   |    1 +
 plat/xilinx/versal/aarch64/versal_common.c    |   65 +-
 plat/xilinx/versal/bl31_versal_setup.c        |   66 +-
 plat/xilinx/versal/include/plat_macros.S      |    4 +-
 plat/xilinx/versal/include/plat_private.h     |    8 +-
 plat/xilinx/versal/include/platform_def.h     |   20 +-
 plat/xilinx/versal/include/versal_def.h       |   75 +-
 plat/xilinx/versal/plat_psci.c                |   72 +-
 plat/xilinx/versal/platform.mk                |   36 +-
 plat/xilinx/versal/pm_service/pm_client.c     |    5 +-
 plat/xilinx/versal/sip_svc_setup.c            |   27 +-
 plat/xilinx/versal/versal_gicv3.c             |    4 +-
 .../versal_net/aarch64/versal_net_common.c    |   37 +-
 .../versal_net/aarch64/versal_net_helpers.S   |   11 +
 .../xilinx/versal_net/bl31_versal_net_setup.c |   50 +-
 plat/xilinx/versal_net/include/plat_ipi.h     |   26 +-
 plat/xilinx/versal_net/include/plat_macros.S  |    4 +-
 plat/xilinx/versal_net/include/plat_private.h |    1 +
 plat/xilinx/versal_net/include/platform_def.h |   11 +-
 .../versal_net/include/versal_net_def.h       |   51 +-
 plat/xilinx/versal_net/plat_psci.c            |    4 +-
 plat/xilinx/versal_net/plat_psci_pm.c         |   90 +-
 plat/xilinx/versal_net/platform.mk            |   30 +-
 plat/xilinx/versal_net/sip_svc_setup.c        |   11 +-
 plat/xilinx/versal_net/tsp/tsp-versal_net.mk  |    3 -
 plat/xilinx/versal_net/versal_net_ipi.c       |   56 +
 plat/xilinx/zynqmp/aarch64/zynqmp_common.c    |   21 +-
 plat/xilinx/zynqmp/bl31_zynqmp_setup.c        |   13 +-
 plat/xilinx/zynqmp/custom_sip_svc.c           |    8 +
 plat/xilinx/zynqmp/include/plat_private.h     |    4 +-
 plat/xilinx/zynqmp/include/zynqmp_def.h       |   37 +-
 plat/xilinx/zynqmp/plat_psci.c                |   36 +-
 plat/xilinx/zynqmp/plat_topology.c            |    2 +
 plat/xilinx/zynqmp/plat_zynqmp.c              |    2 +-
 plat/xilinx/zynqmp/platform.mk                |   37 +-
 plat/xilinx/zynqmp/pm_service/pm_api_clock.c  |   58 +-
 plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c  |   10 +-
 .../xilinx/zynqmp/pm_service/pm_api_pinctrl.c |   10 +-
 plat/xilinx/zynqmp/pm_service/pm_client.c     |   23 +-
 .../zynqmp/pm_service/zynqmp_pm_api_sys.c     |   43 +-
 .../zynqmp/pm_service/zynqmp_pm_svc_main.c    |   56 +-
 plat/xilinx/zynqmp/sip_svc_setup.c            |    7 +-
 poetry.lock                                   |  995 +-
 pyproject.toml                                |    9 +-
 readme.rst                                    |    2 +-
 services/arm_arch_svc/arm_arch_svc_setup.c    |    4 +-
 services/el3/ven_el3_svc.c                    |   97 +
 services/oem/chromeos/widevine_smc_handlers.c |   98 +
 services/spd/opteed/opteed.mk                 |    8 +
 services/spd/opteed/opteed_common.c           |   15 +-
 services/spd/opteed/opteed_main.c             |  227 +-
 services/spd/opteed/opteed_pm.c               |    4 +-
 services/spd/opteed/opteed_private.h          |    9 +-
 services/spd/pncd/pncd_common.c               |    6 +-
 services/spd/pncd/pncd_main.c                 |    6 +-
 services/spd/tlkd/tlkd.mk                     |    4 +-
 services/spd/trusty/trusty.c                  |   25 +-
 services/spd/tspd/tspd_main.c                 |    7 +-
 services/std_svc/drtm/drtm_main.c             |   20 +-
 services/std_svc/drtm/drtm_main.h             |    9 +-
 services/std_svc/drtm/drtm_remediation.c      |    6 +-
 services/std_svc/errata_abi/cpu_errata_info.h |   39 +-
 services/std_svc/errata_abi/errata_abi_main.c |  522 +-
 services/std_svc/rmmd/rmmd.mk                 |    7 +-
 services/std_svc/rmmd/rmmd_attest.c           |  126 +-
 services/std_svc/rmmd/rmmd_main.c             |   67 +-
 services/std_svc/rmmd/rmmd_private.h          |    7 +-
 services/std_svc/rmmd/trp/trp.mk              |    6 +-
 services/std_svc/rmmd/trp/trp_main.c          |    5 +-
 services/std_svc/sdei/sdei_intr_mgmt.c        |   59 +-
 services/std_svc/sdei/sdei_main.c             |    4 +-
 services/std_svc/spm/el3_spmc/spmc.h          |   12 +-
 services/std_svc/spm/el3_spmc/spmc_main.c     |  401 +-
 services/std_svc/spm/el3_spmc/spmc_pm.c       |   17 +-
 services/std_svc/spm/el3_spmc/spmc_setup.c    |  331 +-
 services/std_svc/spm/spm_mm/spm_mm_main.c     |   23 +-
 services/std_svc/spm/spm_mm/spm_mm_setup.c    |   27 +-
 services/std_svc/spmd/spmd_logical_sp.c       |   14 +-
 services/std_svc/spmd/spmd_main.c             |  141 +-
 services/std_svc/std_svc_setup.c              |    2 +-
 tools/amlogic/Makefile                        |   26 +-
 tools/cert_create/Makefile                    |   32 +-
 tools/cert_create/include/key.h               |   24 +-
 tools/cert_create/src/cca/cot.c               |    4 +-
 tools/cert_create/src/cert.c                  |    3 +-
 tools/cert_create/src/dualroot/cot.c          |    4 +-
 tools/cert_create/src/key.c                   |   42 +-
 tools/cert_create/src/main.c                  |   32 +-
 tools/cert_create/src/tbbr/tbb_key.c          |    4 +-
 .../conventional-changelog-tf-a/package.json  |    2 +-
 tools/cot_dt2c/.gitignore                     |  176 +
 tools/cot_dt2c/cot_dt2c/__init__.py           |   25 +
 tools/cot_dt2c/cot_dt2c/__main__.py           |   10 +
 tools/cot_dt2c/cot_dt2c/cli.py                |   39 +
 tools/cot_dt2c/cot_dt2c/cot_dt2c.py           |   30 +
 tools/cot_dt2c/cot_dt2c/cot_parser.py         |  673 ++
 tools/cot_dt2c/cot_dt2c/dt_validator.py       |  130 +
 tools/cot_dt2c/poetry.lock                    |  334 +
 tools/cot_dt2c/pyproject.toml                 |   63 +
 tools/cot_dt2c/tests/test.dtsi                |   58 +
 tools/cot_dt2c/tests/test2.dtsi               |   69 +
 .../cot_dt2c/tests/test_invalid_bracket.dtsi  |   54 +
 .../tests/test_invalid_missing_attribute.dtsi |  108 +
 .../tests/test_invalid_missing_ctr.dtsi       |   53 +
 .../tests/test_invalid_missing_root.dtsi      |  242 +
 .../tests/test_invalid_undefined_parent.dtsi  |  113 +
 tools/cot_dt2c/tests/test_util.py             |   33 +
 tools/encrypt_fw/Makefile                     |   26 +-
 tools/encrypt_fw/src/main.c                   |    4 +-
 tools/fiptool/Makefile                        |   29 +-
 tools/fiptool/fiptool.c                       |    5 +-
 .../arm/board/juno}/plat_def_uuid_config.c    |    0
 .../arm/board/juno/plat_fiptool.mk            |    4 +-
 .../arm/board/tc/plat_def_uuid_config.c       |   48 +-
 .../st/{stm32mp1 => }/plat_def_uuid_config.c  |    7 +-
 .../st/{stm32mp1 => }/plat_fiptool.mk         |    8 +-
 tools/marvell/doimage/Makefile                |   22 +-
 tools/marvell/doimage/doimage.c               |    2 +-
 tools/memory/memory/mapparser.py              |    4 +-
 tools/memory/memory/memmap.py                 |    4 +-
 .../nxp/cert_create_helper/src/pdef_tbb_key.c |    2 +-
 tools/nxp/create_pbl/Makefile                 |   36 +-
 tools/nxp/create_pbl/pbl_ch2.mk               |   17 +-
 tools/nxp/create_pbl/pbl_ch3.mk               |   18 +-
 tools/renesas/rcar_layout_create/makefile     |   52 +-
 tools/renesas/rcar_layout_create/sa6.c        |    4 +-
 tools/renesas/rzg_layout_create/makefile      |   52 +-
 tools/sptool/Makefile                         |   27 +-
 tools/sptool/sp_mk_generator.py               |   13 +-
 tools/stm32image/Makefile                     |   27 +-
 tools/tlc/.gitignore                          |  176 +
 tools/tlc/assets/images/coverage.svg          |   21 +
 tools/tlc/poetry.lock                         | 1434 +++
 tools/tlc/pyproject.toml                      |  151 +
 tools/tlc/setup.cfg                           |    4 +
 tools/tlc/tests/conftest.py                   |   72 +
 tools/tlc/tests/test_cli.py                   |  476 +
 tools/tlc/tests/test_transfer_list.py         |  234 +
 tools/tlc/tlc/__init__.py                     |   27 +
 tools/tlc/tlc/__main__.py                     |   13 +
 tools/tlc/tlc/cli.py                          |  201 +
 tools/tlc/tlc/te.py                           |   56 +
 tools/tlc/tlc/templates/header.h.j2           |   16 +
 tools/tlc/tlc/tl.py                           |  363 +
 tools/tlc/tox.ini                             |   26 +
 1473 files changed, 117058 insertions(+), 27515 deletions(-)
 create mode 100644 .ctags
 create mode 100644 .cz-adapter.cjs
 rename .versionrc.js => .versionrc.cjs (95%)
 create mode 100644 bl32/tsp/tsp_context.c
 create mode 100644 docs/components/context-management-library.rst
 create mode 100644 docs/components/fconf/tb_fw_bindings.rst
 create mode 100644 docs/components/ven-el3-debugfs.rst
 create mode 100644 docs/components/ven-el3-service.rst
 rename docs/design_documents/{rss.rst => rse.rst} (52%)
 create mode 100644 docs/plat/amd-versal2.rst
 create mode 100644 docs/plat/arm/automotive_rd/index.rst
 create mode 100644 docs/plat/arm/fvp/fvp-aemv8-base.rst
 create mode 100644 docs/plat/arm/fvp/fvp-build-options.rst
 create mode 100644 docs/plat/arm/fvp/fvp-cortex-a32.rst
 create mode 100644 docs/plat/arm/fvp/fvp-cortex-a57-a53.rst
 create mode 100644 docs/plat/arm/fvp/fvp-foundation.rst
 create mode 100644 docs/plat/arm/fvp/fvp-specific-configs.rst
 create mode 100644 docs/plat/arm/fvp/fvp-support.rst
 create mode 100644 docs/plat/imx8ulp.rst
 create mode 100644 docs/plat/rpi5.rst
 create mode 100644 docs/plat/s32g274a.rst
 create mode 100644 docs/process/misra-compliance.csv
 create mode 100644 docs/resources/diagrams/context_init_coldboot.png
 create mode 100644 docs/resources/diagrams/context_init_warmboot.png
 create mode 100644 docs/resources/diagrams/context_memory_allocation.png
 create mode 100644 docs/resources/diagrams/cot-dualroot.jpg
 create mode 100644 docs/resources/diagrams/cot-tbbr.jpg
 create mode 100644 docs/resources/diagrams/cpu_data_config_context_memory.png
 create mode 100644 docs/resources/diagrams/percpu-data-struct.png
 rename docs/resources/diagrams/plantuml/{rss_attestation_flow.puml => rse_attestation_flow.puml} (99%)
 create mode 100644 docs/resources/diagrams/plantuml/rse_measured_boot_flow.puml
 delete mode 100644 docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
 rename docs/resources/diagrams/plantuml/{tfa_rss_dfd.puml => tfa_rse_dfd.puml} (89%)
 create mode 100644 docs/resources/diagrams/root_context_sequence.png
 rename docs/resources/diagrams/{rss_attestation_flow.svg => rse_attestation_flow.svg} (99%)
 rename docs/resources/diagrams/{rss_measured_boot_flow.svg => rse_measured_boot_flow.svg} (90%)
 create mode 100755 docs/resources/diagrams/tf-a_attack_tree.png
 create mode 100755 docs/resources/diagrams/tf-a_data_flow_diagram.png
 create mode 100755 docs/resources/diagrams/tf-a_system_diagram.png
 create mode 100644 docs/security_advisories/security-advisory-tfv-11.rst
 create mode 100644 docs/threat_model/firmware_threat_model/index.rst
 rename docs/threat_model/{ => firmware_threat_model}/threat_model.rst (89%)
 rename docs/threat_model/{ => firmware_threat_model}/threat_model_arm_cca.rst (98%)
 rename docs/threat_model/{ => firmware_threat_model}/threat_model_el3_spm.rst (99%)
 rename docs/threat_model/{ => firmware_threat_model}/threat_model_fvp_r.rst (98%)
 create mode 100644 docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst
 rename docs/threat_model/{threat_model_rss_interface.rst => firmware_threat_model/threat_model_rse_interface.rst} (72%)
 create mode 100644 docs/threat_model/supply_chain_threat_model.rst
 create mode 100644 docs/tools/cot-dt2c.rst
 create mode 100644 docs/tools/transfer-list-compiler.rst
 create mode 100644 drivers/arm/css/dsu/dsu.c
 create mode 100644 drivers/arm/mhu/mhu_v3_x.c
 create mode 100644 drivers/arm/mhu/mhu_v3_x.h
 create mode 100644 drivers/arm/mhu/mhu_v3_x_private.h
 create mode 100644 drivers/arm/mhu/mhu_wrapper_v3_x.c
 rename drivers/arm/{rss/rss_comms.c => rse/rse_comms.c} (71%)
 create mode 100644 drivers/arm/rse/rse_comms.mk
 rename drivers/arm/{rss/rss_comms_protocol.c => rse/rse_comms_protocol.c} (62%)
 create mode 100644 drivers/arm/rse/rse_comms_protocol.h
 create mode 100644 drivers/arm/rse/rse_comms_protocol_common.h
 rename drivers/arm/{rss/rss_comms_protocol_embed.c => rse/rse_comms_protocol_embed.c} (69%)
 rename drivers/arm/{rss/rss_comms_protocol_embed.h => rse/rse_comms_protocol_embed.h} (55%)
 rename drivers/arm/{rss/rss_comms_protocol_pointer_access.c => rse/rse_comms_protocol_pointer_access.c} (58%)
 rename drivers/arm/{rss/rss_comms_protocol_pointer_access.h => rse/rse_comms_protocol_pointer_access.h} (58%)
 delete mode 100644 drivers/arm/rss/rss_comms.mk
 delete mode 100644 drivers/arm/rss/rss_comms_protocol.h
 create mode 100644 drivers/auth/cca/bl1_cot.c
 delete mode 100644 drivers/auth/cca/cot.c
 create mode 100644 drivers/auth/dualroot/bl1_cot.c
 delete mode 100644 drivers/auth/dualroot/cot.c
 create mode 100644 drivers/measured_boot/rse/dice_prot_env.c
 create mode 100644 drivers/measured_boot/rse/dice_prot_env.mk
 create mode 100644 drivers/measured_boot/rse/qcbor.mk
 rename drivers/measured_boot/{rss/rss_measured_boot.c => rse/rse_measured_boot.c} (86%)
 rename drivers/measured_boot/{rss/rss_measured_boot.mk => rse/rse_measured_boot.mk} (65%)
 create mode 100644 drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
 create mode 100644 drivers/nxp/clk/s32cc/include/s32cc-mc-me.h
 create mode 100644 drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
 create mode 100644 drivers/nxp/clk/s32cc/mc_me.c
 create mode 100644 drivers/nxp/clk/s32cc/mc_rgm.c
 create mode 100644 drivers/nxp/clk/s32cc/s32cc_clk.mk
 create mode 100644 drivers/nxp/clk/s32cc/s32cc_clk_drv.c
 create mode 100644 drivers/nxp/clk/s32cc/s32cc_clk_modules.c
 create mode 100644 drivers/nxp/clk/s32cc/s32cc_clk_utils.c
 create mode 100644 drivers/nxp/clk/s32cc/s32cc_early_clks.c
 create mode 100644 drivers/nxp/console/linflex_console.S
 create mode 100644 drivers/scmi-msg/sensor.c
 create mode 100644 drivers/scmi-msg/sensor.h
 create mode 100644 drivers/st/bsec/bsec3.c
 create mode 100644 drivers/st/clk/clk-stm32mp2.c
 create mode 100644 drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr3.h
 create mode 100644 drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr4.h
 create mode 100644 drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_lpddr4.h
 create mode 100644 drivers/st/ddr/phy/phyinit/include/ddrphy_csr_all_cdefines.h
 create mode 100644 drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit.h
 create mode 100644 drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_struct.h
 create mode 100644 drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_usercustom.h
 create mode 100644 drivers/st/ddr/phy/phyinit/include/ddrphy_wrapper.h
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_calcmb.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_d_loadimem.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_f_loaddmem.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_g_execfw.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_i_loadpieimage.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_initstruct.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_isdbytedisabled.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_loadpieprodcode.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_progcsrskiptrain.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_reginterface.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_restore_sequence.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_sequence.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_softsetmb.c
 create mode 100644 drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_writeoutmem.c
 create mode 100644 drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_custompretrain.c
 create mode 100644 drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_g_waitfwdone.c
 create mode 100644 drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_saveretregs.c
 create mode 100644 drivers/st/ddr/stm32mp2_ddr.c
 create mode 100644 drivers/st/ddr/stm32mp2_ddr_helpers.c
 create mode 100644 drivers/st/ddr/stm32mp2_ram.c
 create mode 100644 drivers/st/pmic/stm32mp_pmic2.c
 create mode 100644 drivers/st/pmic/stpmic2.c
 create mode 100644 drivers/st/reset/stm32mp2_reset.c
 create mode 100644 fdts/cca_cot_descriptors.dtsi
 create mode 100644 fdts/dualroot_cot_descriptors.dtsi
 create mode 100644 fdts/rd1ae.dts
 create mode 100644 fdts/stm32mp25-bl31.dtsi
 create mode 100644 fdts/stm32mp25-ddr.dtsi
 create mode 100644 fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi
 create mode 100644 fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
 create mode 100644 fdts/stm32mp25-fw-config.dtsi
 create mode 100644 fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
 create mode 100644 fdts/stm32mp257f-ev1-ca35tdcid-rcc.dtsi
 create mode 100644 fdts/stm32mp257f-ev1-fw-config.dts
 rename fdts/{cot_descriptors.dtsi => tbbr_cot_descriptors.dtsi} (89%)
 create mode 100644 fdts/tc-base.dtsi
 create mode 100644 fdts/tc-common.dtsi
 create mode 100644 fdts/tc-fpga.dtsi
 create mode 100644 fdts/tc-fvp.dtsi
 delete mode 100644 fdts/tc.dts
 create mode 100644 fdts/tc2.dts
 create mode 100644 fdts/tc3-4-base.dtsi
 create mode 100644 fdts/tc3.dts
 create mode 100644 fdts/tc4.dts
 create mode 100644 include/bl32/tsp/tsp_el1_context.h
 create mode 100644 include/common/build_message.h
 create mode 100644 include/common/par.h
 create mode 100644 include/common/sha_common_macros.h
 create mode 100644 include/drivers/arm/css/dsu.h
 create mode 100644 include/drivers/arm/fvp/fvp_cpu_pwr.h
 rename include/drivers/arm/{rss_comms.h => rse_comms.h} (53%)
 delete mode 100644 include/drivers/auth/mbedtls/mbedtls_config-2.h
 create mode 100644 include/drivers/measured_boot/metadata.h
 create mode 100644 include/drivers/measured_boot/rse/dice_prot_env.h
 create mode 100644 include/drivers/measured_boot/rse/rse_measured_boot.h
 delete mode 100644 include/drivers/measured_boot/rss/rss_measured_boot.h
 create mode 100644 include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
 create mode 100644 include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
 create mode 100644 include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
 create mode 100644 include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
 create mode 100644 include/drivers/nxp/console/linflex.h
 create mode 100644 include/drivers/st/bsec3_reg.h
 create mode 100644 include/drivers/st/stm32mp2_clk.h
 create mode 100644 include/drivers/st/stm32mp2_ddr.h
 create mode 100644 include/drivers/st/stm32mp2_ddr_helpers.h
 create mode 100644 include/drivers/st/stm32mp2_ddr_regs.h
 create mode 100644 include/drivers/st/stm32mp2_pwr.h
 create mode 100644 include/drivers/st/stm32mp2_ram.h
 create mode 100644 include/drivers/st/stm32mp_pmic2.h
 create mode 100644 include/drivers/st/stm32mp_risab_regs.h
 create mode 100644 include/drivers/st/stpmic2.h
 create mode 100644 include/dt-bindings/gpio/stm32-gpio.h
 rename include/lib/cpus/aarch64/{neoverse_hermes.h => cortex_a720_ae.h} (57%)
 rename include/lib/cpus/aarch64/{cortex_blackhawk.h => cortex_a725.h} (55%)
 create mode 100644 include/lib/cpus/aarch64/cortex_arcadia.h
 rename include/lib/cpus/aarch64/{cortex_chaberton.h => cortex_x925.h} (55%)
 create mode 100644 include/lib/cpus/aarch64/neoverse_n3.h
 delete mode 100644 include/lib/cpus/aarch64/neoverse_poseidon.h
 create mode 100644 include/lib/cpus/aarch64/neoverse_v3.h
 create mode 100644 include/lib/dice/dice.h
 create mode 100644 include/lib/el3_runtime/context_debug.h
 create mode 100644 include/lib/el3_runtime/context_el1.h
 create mode 100644 include/lib/el3_runtime/context_el2.h
 create mode 100644 include/lib/el3_runtime/simd_ctx.h
 create mode 100644 include/lib/extensions/debug_v8p9.h
 create mode 100644 include/lib/extensions/fgt2.h
 create mode 100644 include/lib/extensions/sysreg128.h
 create mode 100644 include/lib/extensions/tcr2.h
 create mode 100644 include/lib/psa/cca_attestation.h
 create mode 100644 include/lib/psa/dice_protection_environment.h
 create mode 100644 include/lib/psa/rse_crypto_defs.h
 rename include/lib/psa/{rss_platform_api.h => rse_platform_api.h} (74%)
 delete mode 100644 include/lib/psa/rss_crypto_defs.h
 create mode 100644 include/plat/arm/board/common/rotpk/rotpk_def.h
 create mode 100644 include/services/oem/chromeos/widevine_smc_handlers.h
 create mode 100644 include/services/rmm_el3_token_sign.h
 create mode 100644 include/services/ven_el3_svc.h
 rename lib/cpus/aarch64/{neoverse_hermes.S => cortex_a720_ae.S} (52%)
 rename lib/cpus/aarch64/{cortex_blackhawk.S => cortex_a725.S} (51%)
 rename lib/cpus/aarch64/{cortex_chaberton.S => cortex_arcadia.S} (51%)
 create mode 100644 lib/cpus/aarch64/cortex_x925.S
 create mode 100644 lib/cpus/aarch64/neoverse_n3.S
 delete mode 100644 lib/cpus/aarch64/neoverse_poseidon.S
 create mode 100644 lib/cpus/aarch64/neoverse_v3.S
 create mode 100644 lib/cpus/errata_common.c
 create mode 100644 lib/el3_runtime/aarch64/context_debug.c
 create mode 100644 lib/el3_runtime/simd_ctx.c
 create mode 100644 lib/extensions/debug/debugv8p9.c
 create mode 100644 lib/extensions/fgt/fgt2.c
 create mode 100644 lib/extensions/sysreg128/sysreg128.S
 create mode 100644 lib/extensions/tcr/tcr2.c
 create mode 100644 lib/libc/libc_common.mk
 create mode 100644 lib/psa/cca_attestation.c
 create mode 100644 lib/psa/dice_protection_environment.c
 rename lib/psa/{rss_platform.c => rse_platform.c} (59%)
 delete mode 100644 lib/psci/aarch64/runtime_errata.S
 create mode 100644 licenses/LICENSE-APACHE-2.0.txt
 create mode 100644 make_helpers/build-rules.mk
 create mode 100644 make_helpers/common.mk
 create mode 100644 make_helpers/toolchain.mk
 create mode 100644 make_helpers/toolchains/aarch32.mk
 create mode 100644 make_helpers/toolchains/aarch64.mk
 create mode 100644 make_helpers/toolchains/host.mk
 create mode 100644 make_helpers/toolchains/rk3399-m0.mk
 create mode 100644 make_helpers/utilities.mk
 create mode 100644 plat/allwinner/sun50i_a64/platform_defaults.mk
 create mode 100644 plat/allwinner/sun50i_h616/sunxi_h616_dtb.c
 create mode 100644 plat/amd/versal2/aarch64/common.c
 create mode 100644 plat/amd/versal2/aarch64/helpers.S
 create mode 100644 plat/amd/versal2/bl31_setup.c
 rename plat/{xilinx/versal_net/versal_net_gicv3.c => amd/versal2/gicv3.c} (72%)
 create mode 100644 plat/amd/versal2/include/def.h
 create mode 100644 plat/amd/versal2/include/plat_ipi.h
 create mode 100644 plat/amd/versal2/include/plat_macros.S
 create mode 100644 plat/amd/versal2/include/plat_pm_common.h
 create mode 100644 plat/amd/versal2/include/plat_private.h
 create mode 100644 plat/amd/versal2/include/platform_def.h
 create mode 100644 plat/amd/versal2/include/scmi.h
 create mode 100644 plat/amd/versal2/include/versal2-scmi.h
 create mode 100644 plat/amd/versal2/plat_psci.c
 create mode 100644 plat/amd/versal2/plat_topology.c
 create mode 100644 plat/amd/versal2/platform.mk
 create mode 100644 plat/amd/versal2/scmi.c
 create mode 100644 plat/amd/versal2/sip_svc_setup.c
 create mode 100644 plat/amd/versal2/soc_ipi.c
 create mode 100644 plat/amd/versal2/tsp/tsp-versal2.mk
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/include/plat_macros.S
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/include/rd1ae_helpers.S
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_err.c
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_tbb.c
 create mode 100644 plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_topology.c
 delete mode 100644 plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
 create mode 100644 plat/arm/board/fvp/aarch64/fvp_lsp_ras_sp.c
 create mode 100644 plat/arm/board/fvp/fdts/fvp_cactus_sp_manifest.dts
 create mode 100644 plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi
 create mode 100644 plat/arm/board/fvp/fdts/fvp_spmc_el1_optee_manifest.dts
 create mode 100644 plat/arm/board/fvp/fvp_cpu_pwr.c
 create mode 100644 plat/arm/board/fvp/fvp_el3_token_sign.c
 rename include/plat/arm/common/arm_pas_def.h => plat/arm/board/fvp/include/fvp_pas_def.h (95%)
 rename plat/arm/{css/sgi/aarch64/sgi_helper.S => board/neoverse_rd/common/arch/aarch64/nrd_helper.S} (84%)
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_def1.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_fw_def1.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd1/nrd_plat_arm_def1.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_def1.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_fw_def1.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_def2.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_fw_def2.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd2/nrd_plat_arm_def2.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_def2.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_fw_def2.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h
 rename plat/arm/{css/sgi/include/sgi_dmc620_tzc_regions.h => board/neoverse_rd/common/include/nrd_dmc620_tzc_regions.h} (72%)
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd_plat.h
 rename plat/arm/{css/sgi/include/sgi_ras.h => board/neoverse_rd/common/include/nrd_ras.h} (66%)
 create mode 100644 plat/arm/board/neoverse_rd/common/include/nrd_sdei.h
 rename plat/arm/{css/sgi/include/sgi_variant.h => board/neoverse_rd/common/include/nrd_variant.h} (60%)
 rename plat/arm/{css/sgi => board/neoverse_rd/common}/include/plat_macros.S (86%)
 rename plat/arm/{css/sgi/sgi-common.mk => board/neoverse_rd/common/nrd-common.mk} (61%)
 create mode 100644 plat/arm/board/neoverse_rd/common/nrd_bl1_setup.c
 create mode 100644 plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
 rename plat/arm/{css/sgi/sgi_image_load.c => board/neoverse_rd/common/nrd_image_load.c} (84%)
 rename plat/arm/{css/sgi/sgi_interconnect.c => board/neoverse_rd/common/nrd_interconnect.c} (94%)
 rename plat/arm/{css/sgi/sgi_plat.c => board/neoverse_rd/common/nrd_plat1.c} (79%)
 rename plat/arm/{css/sgi/sgi_plat_v2.c => board/neoverse_rd/common/nrd_plat2.c} (73%)
 create mode 100644 plat/arm/board/neoverse_rd/common/nrd_plat3.c
 rename plat/arm/{css/sgi/sgi_topology.c => board/neoverse_rd/common/nrd_topology.c} (78%)
 rename plat/arm/{css/sgi/ras/sgi_ras_common.c => board/neoverse_rd/common/ras/nrd_ras_common.c} (65%)
 rename plat/arm/{css/sgi/ras/sgi_ras_cpu.c => board/neoverse_rd/common/ras/nrd_ras_cpu.c} (57%)
 rename plat/arm/{css/sgi/ras/sgi_ras_sram.c => board/neoverse_rd/common/ras/nrd_ras_sram.c} (81%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn1edge/fdts/rdn1edge_fw_config.dts (86%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn1edge/fdts/rdn1edge_nt_fw_config.dts (86%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn1edge/fdts/rdn1edge_tb_fw_config.dts (89%)
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdn1edge/include/platform_def.h
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn1edge/platform.mk (65%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn1edge/rdn1edge_err.c (71%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn1edge/rdn1edge_plat.c (70%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn1edge/rdn1edge_security.c (85%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn1edge/rdn1edge_topology.c (86%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn1edge/rdn1edge_trusted_boot.c (88%)
 rename plat/arm/board/{rde1edge/fdts/rde1edge_fw_config.dts => neoverse_rd/platform/rdn2/fdts/rdn2_fw_config.dts} (64%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn2/fdts/rdn2_nt_fw_config.dts (90%)
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_stmm_sel0_manifest.dts
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn2/fdts/rdn2_tb_fw_config.dts (89%)
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdn2/include/platform_def.h
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdn2/include/rdn2_ras.h
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn2/platform.mk (50%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn2/rdn2_err.c (71%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn2/rdn2_plat.c (60%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn2/rdn2_ras.c (60%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn2/rdn2_security.c (55%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn2/rdn2_topology.c (77%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdn2/rdn2_trusted_boot.c (88%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/fdts/rdv1_fw_config.dts (83%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/fdts/rdv1_nt_fw_config.dts (83%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/fdts/rdv1_tb_fw_config.dts (89%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/include/platform_def.h (64%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/platform.mk (64%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/rdv1_err.c (71%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/rdv1_plat.c (59%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/rdv1_security.c (82%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/rdv1_topology.c (77%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1/rdv1_trusted_boot.c (88%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/fdts/rdv1mc_fw_config.dts (83%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/fdts/rdv1mc_nt_fw_config.dts (83%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/fdts/rdv1mc_tb_fw_config.dts (89%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/include/platform_def.h (69%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/platform.mk (65%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/rdv1mc_err.c (71%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/rdv1mc_plat.c (54%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/rdv1mc_security.c (63%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/rdv1mc_topology.c (70%)
 rename plat/arm/board/{ => neoverse_rd/platform}/rdv1mc/rdv1mc_trusted_boot.c (88%)
 rename plat/arm/board/{rdn2/fdts/rdn2_fw_config.dts => neoverse_rd/platform/rdv3/fdts/rdv3_fw_config.dts} (71%)
 rename plat/arm/board/{rde1edge/fdts/rde1edge_nt_fw_config.dts => neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts} (78%)
 rename plat/arm/board/{rde1edge/fdts/rde1edge_tb_fw_config.dts => neoverse_rd/platform/rdv3/fdts/rdv3_tb_fw_config.dts} (90%)
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_setup.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_realm_attest_key.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_security.c
 create mode 100644 plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c
 rename plat/arm/board/{rde1edge/rde1edge_trusted_boot.c => neoverse_rd/platform/rdv3/rdv3_trusted_boot.c} (89%)
 rename plat/arm/board/{ => neoverse_rd/platform}/sgi575/fdts/sgi575_fw_config.dts (86%)
 rename plat/arm/board/{ => neoverse_rd/platform}/sgi575/fdts/sgi575_nt_fw_config.dts (86%)
 rename plat/arm/board/{ => neoverse_rd/platform}/sgi575/fdts/sgi575_tb_fw_config.dts (89%)
 create mode 100644 plat/arm/board/neoverse_rd/platform/sgi575/include/platform_def.h
 rename plat/arm/board/{ => neoverse_rd/platform}/sgi575/platform.mk (65%)
 rename plat/arm/board/{ => neoverse_rd/platform}/sgi575/sgi575_err.c (71%)
 rename plat/arm/board/{ => neoverse_rd/platform}/sgi575/sgi575_plat.c (52%)
 rename plat/arm/board/{ => neoverse_rd/platform}/sgi575/sgi575_security.c (85%)
 rename plat/arm/board/{ => neoverse_rd/platform}/sgi575/sgi575_topology.c (89%)
 rename plat/arm/board/{ => neoverse_rd/platform}/sgi575/sgi575_trusted_boot.c (88%)
 delete mode 100644 plat/arm/board/rde1edge/include/platform_def.h
 delete mode 100644 plat/arm/board/rde1edge/platform.mk
 delete mode 100644 plat/arm/board/rde1edge/rde1edge_err.c
 delete mode 100644 plat/arm/board/rde1edge/rde1edge_plat.c
 delete mode 100644 plat/arm/board/rde1edge/rde1edge_security.c
 delete mode 100644 plat/arm/board/rde1edge/rde1edge_topology.c
 delete mode 100644 plat/arm/board/rdn1edge/include/platform_def.h
 delete mode 100644 plat/arm/board/rdn2/include/platform_def.h
 delete mode 100644 plat/arm/board/rdn2/include/rdn2_ras.h
 delete mode 100644 plat/arm/board/sgi575/include/platform_def.h
 create mode 100644 plat/arm/board/tc/fdts/dice_prot_env.dtsi
 create mode 100644 plat/arm/board/tc/fdts/tc_nt_fw_config.dts
 create mode 100644 plat/arm/board/tc/fdts/tc_spmc_common_sp_manifest.dtsi
 rename plat/arm/board/tc/fdts/{tc_spmc_manifest.dts => tc_spmc_manifest.dtsi} (65%)
 create mode 100644 plat/arm/board/tc/fdts/tc_spmc_test_manifest.dts
 create mode 100644 plat/arm/board/tc/fdts/tc_spmc_trusty_sp_manifest.dts
 rename plat/arm/board/tc/{rss_ap_test_stubs.c => rse_ap_test_stubs.c} (92%)
 rename plat/arm/board/tc/{rss_ap_tests.c => rse_ap_tests.c} (94%)
 rename plat/arm/board/tc/{rss_ap_testsuites.c => rse_ap_testsuites.c} (93%)
 rename plat/arm/board/tc/{rss_ap_testsuites.h => rse_ap_testsuites.h} (76%)
 create mode 100644 plat/arm/board/tc/tc_bl1_dpe.c
 create mode 100644 plat/arm/board/tc/tc_bl1_setup.c
 create mode 100644 plat/arm/board/tc/tc_bl2_dpe.c
 create mode 100644 plat/arm/board/tc/tc_common_dpe.c
 create mode 100644 plat/arm/board/tc/tc_dpe.h
 create mode 100644 plat/arm/board/tc/tc_trng.c
 create mode 100644 plat/arm/common/arm_ni.c
 create mode 100644 plat/arm/common/arm_transfer_list.c
 create mode 100644 plat/arm/common/plat_arm_mbedtls_config.h
 create mode 100644 plat/arm/common/plat_arm_psa_mbedtls_config.h
 delete mode 100644 plat/arm/css/sgi/include/sgi_base_platform_def.h
 delete mode 100644 plat/arm/css/sgi/include/sgi_plat.h
 delete mode 100644 plat/arm/css/sgi/include/sgi_sdei.h
 delete mode 100644 plat/arm/css/sgi/include/sgi_soc_css_def.h
 delete mode 100644 plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
 delete mode 100644 plat/arm/css/sgi/include/sgi_soc_platform_def.h
 delete mode 100644 plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
 delete mode 100644 plat/arm/css/sgi/sgi_bl31_setup.c
 create mode 100644 plat/imx/common/imx_bl31_common.c
 create mode 100644 plat/imx/common/imx_common.c
 create mode 100644 plat/imx/common/include/imx_plat_common.h
 create mode 100644 plat/imx/common/include/plat_common.h
 create mode 100644 plat/imx/imx8ulp/apd_context.c
 create mode 100644 plat/imx/imx8ulp/dram.c
 create mode 100644 plat/imx/imx8ulp/imx8ulp_bl31_setup.c
 create mode 100644 plat/imx/imx8ulp/imx8ulp_caam.c
 create mode 100644 plat/imx/imx8ulp/imx8ulp_psci.c
 create mode 100644 plat/imx/imx8ulp/include/dram.h
 create mode 100644 plat/imx/imx8ulp/include/imx8ulp_caam.h
 create mode 100644 plat/imx/imx8ulp/include/platform_def.h
 create mode 100644 plat/imx/imx8ulp/include/scmi.h
 create mode 100644 plat/imx/imx8ulp/include/scmi_sensor.h
 create mode 100644 plat/imx/imx8ulp/include/xrdc.h
 create mode 100644 plat/imx/imx8ulp/platform.mk
 create mode 100644 plat/imx/imx8ulp/scmi/scmi.c
 create mode 100644 plat/imx/imx8ulp/scmi/scmi_pd.c
 create mode 100644 plat/imx/imx8ulp/scmi/scmi_sensor.c
 create mode 100644 plat/imx/imx8ulp/upower/upmu.h
 create mode 100644 plat/imx/imx8ulp/upower/upower_api.c
 create mode 100644 plat/imx/imx8ulp/upower/upower_api.h
 create mode 100644 plat/imx/imx8ulp/upower/upower_defs.h
 create mode 100644 plat/imx/imx8ulp/upower/upower_hal.c
 create mode 100644 plat/imx/imx8ulp/upower/upower_soc_defs.h
 create mode 100644 plat/imx/imx8ulp/xrdc/xrdc_config.h
 create mode 100644 plat/imx/imx8ulp/xrdc/xrdc_core.c
 create mode 100644 plat/intel/soc/agilex5/include/agilex5_cache.h
 create mode 100644 plat/intel/soc/agilex5/include/agilex5_ddr.h
 create mode 100644 plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h
 create mode 100644 plat/intel/soc/agilex5/soc/agilex5_cache.S
 create mode 100644 plat/intel/soc/agilex5/soc/agilex5_ddr.c
 create mode 100644 plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c
 create mode 100644 plat/intel/soc/common/include/socfpga_ros.h
 create mode 100644 plat/intel/soc/common/lib/sha/sha.c
 create mode 100644 plat/intel/soc/common/lib/sha/sha.h
 create mode 100644 plat/intel/soc/common/soc/socfpga_system_manager.c
 create mode 100644 plat/intel/soc/common/socfpga_ros.c
 create mode 100644 plat/mediatek/drivers/iommu/mtk_iommu_smc.h
 create mode 100644 plat/mediatek/drivers/rng/mt8186/rng_plat.c
 create mode 100644 plat/mediatek/drivers/rng/mt8186/rng_plat.h
 create mode 100644 plat/mediatek/drivers/rng/mt8188/rng_plat.c
 create mode 100644 plat/mediatek/drivers/rng/mt8188/rng_plat.h
 create mode 100644 plat/mediatek/drivers/rng/rng.c
 create mode 100644 plat/mediatek/drivers/rng/rules.mk
 rename plat/mediatek/{mt8188 => }/include/plat_helpers.h (71%)
 delete mode 100644 plat/mediatek/mt8186/include/plat_helpers.h
 delete mode 100644 plat/mediatek/mt8192/include/plat_helpers.h
 delete mode 100644 plat/mediatek/mt8195/include/plat_helpers.h
 create mode 100644 plat/nxp/s32/s32g274ardb2/include/plat_console.h
 create mode 100644 plat/nxp/s32/s32g274ardb2/include/plat_helpers.h
 create mode 100644 plat/nxp/s32/s32g274ardb2/include/plat_io_storage.h
 create mode 100644 plat/nxp/s32/s32g274ardb2/include/plat_macros.S
 create mode 100644 plat/nxp/s32/s32g274ardb2/include/platform_def.h
 create mode 100644 plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
 create mode 100644 plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
 create mode 100644 plat/nxp/s32/s32g274ardb2/plat_bl2_image_desc.c
 create mode 100644 plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
 create mode 100644 plat/nxp/s32/s32g274ardb2/plat_console.c
 create mode 100644 plat/nxp/s32/s32g274ardb2/plat_helpers.S
 create mode 100644 plat/nxp/s32/s32g274ardb2/plat_io_storage.c
 create mode 100644 plat/nxp/s32/s32g274ardb2/platform.mk
 create mode 100644 plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
 create mode 100644 plat/nxp/s32/s32g274ardb2/s32g2_psci.c
 create mode 100644 plat/nxp/s32/s32g274ardb2/s32g2_soc.c
 create mode 100644 plat/qemu/common/qemu_plat_attest_token.c
 create mode 100644 plat/qemu/common/qemu_realm_attest_key.c
 create mode 100644 plat/qemu/common/trp/qemu_trp_setup.c
 create mode 100644 plat/qemu/common/trp/trp-qemu-common.mk
 create mode 100644 plat/qemu/qemu/include/qemu_pas_def.h
 create mode 100644 plat/qemu/qemu/trp/trp-qemu.mk
 create mode 100644 plat/renesas/rcar/rcar_stack_protector.c
 create mode 100644 plat/rockchip/common/include/plat_pm_helpers.h
 create mode 100644 plat/rockchip/common/plat_pm_helpers.c
 create mode 100644 plat/rockchip/common/scmi/scmi.c
 create mode 100644 plat/rockchip/common/scmi/scmi_clock.c
 create mode 100644 plat/rockchip/common/scmi/scmi_clock.h
 create mode 100644 plat/rockchip/common/scmi/scmi_rstd.c
 create mode 100644 plat/rockchip/common/scmi/scmi_rstd.h
 create mode 100644 plat/rockchip/rk3399/drivers/pmu/pmu_fw.S
 delete mode 100644 plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
 create mode 100644 plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
 create mode 100644 plat/rockchip/rk3568/drivers/pmu/pmu.c
 create mode 100644 plat/rockchip/rk3568/drivers/pmu/pmu.h
 create mode 100644 plat/rockchip/rk3568/drivers/soc/soc.c
 create mode 100644 plat/rockchip/rk3568/drivers/soc/soc.h
 create mode 100644 plat/rockchip/rk3568/include/plat.ld.S
 create mode 100644 plat/rockchip/rk3568/include/plat_sip_calls.h
 create mode 100644 plat/rockchip/rk3568/include/platform_def.h
 create mode 100644 plat/rockchip/rk3568/plat_sip_calls.c
 create mode 100644 plat/rockchip/rk3568/platform.mk
 create mode 100644 plat/rockchip/rk3568/rk3568_def.h
 create mode 100644 plat/rockchip/rk3588/drivers/pmu/plat_pmu_macros.S
 create mode 100644 plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.c
 create mode 100644 plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.h
 create mode 100644 plat/rockchip/rk3588/drivers/pmu/pmu.c
 create mode 100644 plat/rockchip/rk3588/drivers/pmu/pmu.h
 create mode 100644 plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c
 create mode 100644 plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h
 create mode 100644 plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c
 create mode 100644 plat/rockchip/rk3588/drivers/secure/secure.c
 create mode 100644 plat/rockchip/rk3588/drivers/secure/secure.h
 create mode 100644 plat/rockchip/rk3588/drivers/soc/soc.c
 create mode 100644 plat/rockchip/rk3588/drivers/soc/soc.h
 create mode 100644 plat/rockchip/rk3588/include/plat.ld.S
 create mode 100644 plat/rockchip/rk3588/include/plat_sip_calls.h
 create mode 100644 plat/rockchip/rk3588/include/platform_def.h
 create mode 100644 plat/rockchip/rk3588/plat_sip_calls.c
 create mode 100644 plat/rockchip/rk3588/platform.mk
 create mode 100644 plat/rockchip/rk3588/rk3588_def.h
 rename plat/rpi/{rpi4 => common}/aarch64/armstub8_header.S (89%)
 rename plat/rpi/{rpi4 => common}/include/plat_macros.S (87%)
 create mode 100644 plat/rpi/common/rpi3_console_dual.c
 create mode 100644 plat/rpi/common/rpi3_console_pl011.c
 rename plat/rpi/{rpi4 => common}/rpi4_bl31_setup.c (67%)
 rename plat/rpi/{rpi4/rpi4_pci_svc.c => common/rpi_pci_svc.c} (76%)
 delete mode 100644 plat/rpi/rpi3/include/plat_macros.S
 create mode 100644 plat/rpi/rpi4/rpi4_setup.c
 create mode 100644 plat/rpi/rpi5/include/plat.ld.S
 create mode 100644 plat/rpi/rpi5/include/platform_def.h
 create mode 100644 plat/rpi/rpi5/include/rpi_hw.h
 create mode 100644 plat/rpi/rpi5/platform.mk
 create mode 100644 plat/rpi/rpi5/rpi5_setup.c
 rename plat/st/{stm32mp1 => common}/include/plat_def_fip_uuid.h (59%)
 delete mode 100644 plat/st/common/include/stm32mp_mbedtls_config-2.h
 create mode 100644 plat/st/stm32mp1/plat_ddr.c
 create mode 100644 plat/st/stm32mp2/bl31_plat_setup.c
 create mode 100644 plat/st/stm32mp2/include/plat_tbbr_img_def.h
 create mode 100644 plat/st/stm32mp2/include/stm32mp2_private.h
 create mode 100644 plat/st/stm32mp2/plat_ddr.c
 create mode 100644 plat/st/stm32mp2/stm32mp2_pm.c
 create mode 100644 plat/st/stm32mp2/stm32mp2_private.c
 create mode 100644 plat/st/stm32mp2/stm32mp2_syscfg.c
 create mode 100644 plat/st/stm32mp2/stm32mp2_topology.c
 create mode 100644 plat/st/stm32mp2/stm32mp2_usb_dfu.c
 create mode 100644 plat/xilinx/common/include/plat_clkfunc.h
 create mode 100644 plat/xilinx/common/include/plat_xfer_list.h
 create mode 100644 plat/xilinx/common/plat_clkfunc.c
 create mode 100644 plat/xilinx/common/plat_xfer_list.c
 create mode 100644 services/el3/ven_el3_svc.c
 create mode 100644 services/oem/chromeos/widevine_smc_handlers.c
 create mode 100644 tools/cot_dt2c/.gitignore
 create mode 100644 tools/cot_dt2c/cot_dt2c/__init__.py
 create mode 100644 tools/cot_dt2c/cot_dt2c/__main__.py
 create mode 100644 tools/cot_dt2c/cot_dt2c/cli.py
 create mode 100644 tools/cot_dt2c/cot_dt2c/cot_dt2c.py
 create mode 100644 tools/cot_dt2c/cot_dt2c/cot_parser.py
 create mode 100644 tools/cot_dt2c/cot_dt2c/dt_validator.py
 create mode 100644 tools/cot_dt2c/poetry.lock
 create mode 100644 tools/cot_dt2c/pyproject.toml
 create mode 100644 tools/cot_dt2c/tests/test.dtsi
 create mode 100644 tools/cot_dt2c/tests/test2.dtsi
 create mode 100644 tools/cot_dt2c/tests/test_invalid_bracket.dtsi
 create mode 100644 tools/cot_dt2c/tests/test_invalid_missing_attribute.dtsi
 create mode 100644 tools/cot_dt2c/tests/test_invalid_missing_ctr.dtsi
 create mode 100644 tools/cot_dt2c/tests/test_invalid_missing_root.dtsi
 create mode 100644 tools/cot_dt2c/tests/test_invalid_undefined_parent.dtsi
 create mode 100644 tools/cot_dt2c/tests/test_util.py
 rename {plat/arm/board/juno/fip => tools/fiptool/plat_fiptool/arm/board/juno}/plat_def_uuid_config.c (100%)
 rename tools/fiptool/plat_fiptool/st/{stm32mp1 => }/plat_def_uuid_config.c (71%)
 rename tools/fiptool/plat_fiptool/st/{stm32mp1 => }/plat_fiptool.mk (60%)
 create mode 100644 tools/tlc/.gitignore
 create mode 100644 tools/tlc/assets/images/coverage.svg
 create mode 100644 tools/tlc/poetry.lock
 create mode 100644 tools/tlc/pyproject.toml
 create mode 100644 tools/tlc/setup.cfg
 create mode 100644 tools/tlc/tests/conftest.py
 create mode 100644 tools/tlc/tests/test_cli.py
 create mode 100644 tools/tlc/tests/test_transfer_list.py
 create mode 100644 tools/tlc/tlc/__init__.py
 create mode 100644 tools/tlc/tlc/__main__.py
 create mode 100644 tools/tlc/tlc/cli.py
 create mode 100644 tools/tlc/tlc/te.py
 create mode 100644 tools/tlc/tlc/templates/header.h.j2
 create mode 100644 tools/tlc/tlc/tl.py
 create mode 100644 tools/tlc/tox.ini

diff --git a/.commitlintrc.js b/.commitlintrc.js
index cfafbedc..53e3a635 100644
--- a/.commitlintrc.js
+++ b/.commitlintrc.js
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,10 +8,9 @@
 
 "use strict";
 
-const fs = require("fs");
-const yaml = require("js-yaml");
-
-const { "trailer-exists": trailerExists } = require("@commitlint/rules").default;
+import fs from "fs";
+import rules from "@commitlint/rules";
+import yaml from "js-yaml";
 
 /*
  * The types and scopes accepted by both Commitlint and Commitizen are defined by the changelog
@@ -37,7 +36,7 @@ function getTypes(sections) {
 
 function getScopes(subsections) {
     return subsections.flatMap(subsection => {
-        const scope = subsection.scope ?  [ subsection.scope ] : [];
+        const scope = subsection.scope ? [subsection.scope] : [];
         const subscopes = getScopes(subsection.subsections || []);
 
         return scope.concat(subscopes);
@@ -47,13 +46,13 @@ function getScopes(subsections) {
 const types = getTypes(changelog.sections).sort(); /* Sort alphabetically */
 const scopes = getScopes(changelog.subsections).sort(); /* Sort alphabetically */
 
-module.exports = {
+export default {
     extends: ["@commitlint/config-conventional"],
     plugins: [
         {
             rules: {
-                "signed-off-by-exists": trailerExists,
-                "change-id-exists": trailerExists,
+                "signed-off-by-exists": rules["trailer-exists"],
+                "change-id-exists": rules["trailer-exists"],
             },
         },
     ],
@@ -64,7 +63,7 @@ module.exports = {
         "change-id-exists": [1, "always", "Change-Id:"], /* Warning */
         "signed-off-by-exists": [1, "always", "Signed-off-by:"], /* Warning */
 
-        "type-case": [2, "always", "lower-case" ], /* Error */
+        "type-case": [2, "always", "lower-case"], /* Error */
         "type-enum": [2, "always", types], /* Error */
 
         "scope-case": [2, "always", "lower-case"], /* Error */
diff --git a/.ctags b/.ctags
new file mode 100644
index 00000000..5e608e48
--- /dev/null
+++ b/.ctags
@@ -0,0 +1,4 @@
+--regex-Asm=/^func[ \t]+([a-zA-Z_0-9]+)$/\1/l,function/
+--regex-Asm=/^.*\.macro[ \t]+([a-zA-Z_0-9]+)$/\1/m,macro/
+--regex-Asm=/^vector_entry[ \t]+([a-zA-Z_0-9]+)$/\1/l,function/
+--regex-Asm=/^.equ[ \t]+([a-zA-Z_0-9]+),/\1/l,name/
diff --git a/.cz-adapter.cjs b/.cz-adapter.cjs
new file mode 100644
index 00000000..26aaeb2a
--- /dev/null
+++ b/.cz-adapter.cjs
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * A workaround for:
+ *
+ *     https://github.com/conventional-changelog/commitlint/issues/3949
+ */
+
+exports.prompter = async (inquirerIns, commit) => {
+    ; (await import('@commitlint/cz-commitlint')).prompter(inquirerIns, commit)
+}
diff --git a/.cz.json b/.cz.json
index 556c39f1..969a73b8 100644
--- a/.cz.json
+++ b/.cz.json
@@ -1,3 +1,3 @@
 {
-    "path": "@commitlint/cz-commitlint"
+    "path": "./.cz-adapter.cjs"
 }
diff --git a/.editorconfig b/.editorconfig
index 12f786de..1b29c880 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -70,3 +70,6 @@ indent_style = space
 # [PEP8] Maximum Line Length
 #	"Limit all lines to a maximum of 79 characters."
 max_line_length = 79
+
+[.git/COMMIT_EDITMSG]
+max_line_length = 72
diff --git a/.husky/commit-msg b/.husky/commit-msg
index c1c96002..b5d407b7 100755
--- a/.husky/commit-msg
+++ b/.husky/commit-msg
@@ -1,7 +1,4 @@
 #!/bin/sh
 
-# shellcheck source=./_/husky.sh
-. "$(dirname "$0")/_/husky.sh"
-
 "$(dirname "$0")/commit-msg.gerrit" "$@"
 "$(dirname "$0")/commit-msg.commitlint" "$@"
diff --git a/.husky/pre-commit b/.husky/pre-commit
index afcb1f6d..f438ddbe 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,6 +1,3 @@
 #!/bin/sh
 
-# shellcheck source=./_/husky.sh
-. "$(dirname "$0")/_/husky.sh"
-
 "$(dirname "$0")/pre-commit.copyright" "$@"
diff --git a/.husky/pre-commit.copyright b/.husky/pre-commit.copyright
index a4dfee8e..5f838a68 100755
--- a/.husky/pre-commit.copyright
+++ b/.husky/pre-commit.copyright
@@ -17,10 +17,24 @@ ARM_RGX="\(ARM\|Arm\|arm\)"
 
 exit_code=0
 
+PLATPROV=
+ORG=`echo "$GIT_AUTHOR_EMAIL" | awk -F '[@]' '{ print $2;}'`
+
+case $ORG in
+	amd.com)
+		PLATPROV="Advanced Micro Devices, Inc. All rights reserved."
+		;;
+	*arm.com)
+		PLATPROV="$ARM_RGX"
+		;;
+	*)
+		;;
+esac
+
 function user_warning() {
 	echo -e "Copyright of $RED$FILE$BLANK is out of date/incorrect"
 	echo -e "Updated copyright to"
-	grep -nr "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE"
+	grep -nr "opyright.*$YEAR_RGX.*$PLATPROV" "$FILE"
 	echo
 }
 
@@ -29,31 +43,45 @@ while read -r FILE; do
 	then
 		break
 	fi
-	# Check if correct copyright notice is in file.
-	# To reduce false positives, we assume files with no
-	# copyright notice do not require it.
-	if ! grep "opyright.*$YEAR_NOW.*$ARM_RGX" "$FILE">/dev/null 2>&1
+
+	# Check if copyright header exists for the org
+	if ! grep "opyright.*$YEAR_RGX.*$PLATPROV" "$FILE">/dev/null 2>&1 && [[ $ORG != *arm* ]]
 	then
-		# If it is "from_date - to_date" type of entry - change to_date entry.
-		if grep "opyright.*$YEAR_RGX.*-.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
-		then
-			exit_code=1
-			sed -i "s/\(opyright.*\)$YEAR_RGX\(.*$ARM_RGX\)/\1$(date +"%Y"), Arm/" $FILE
-			user_warning
-		# If it is single "date" type of entry - add the copyright extension to current year.
-		elif grep "opyright.*$YEAR_RGX.*$ARM_RGX" "$FILE" >/dev/null 2>&1
+		echo -e "Copyright header ""$RED""$PLATPROV""$BLANK"" is missing in ""$YELLOW""$FILE""$BLANK"
+	fi
+
+	# Check if the copyright year is updated for the org  and update it
+	if [ ! -z "$PLATPROV" ]
+	then
+		if ! grep "opyright.*$YEAR_NOW.*$PLATPROV" "$FILE">/dev/null 2>&1
 		then
-			exit_code=1
-			sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$ARM_RGX\)/\1-$(date +"%Y"), Arm/" $FILE
-			user_warning
+			# If it is "from_date - to_date" type of entry - change to_date entry.
+			if grep "opyright.*$YEAR_RGX.*-.*$YEAR_RGX.*$PLATPROV" "$FILE" >/dev/null 2>&1
+			then
+				exit_code=1
+				sed -i "s/\(opyright.*\)$YEAR_RGX\(.*$PLATPROV\)/\1$(date +"%Y")\2/" $FILE
+				user_warning
+			# If it is single "date" type of entry - add the copyright extension to current year.
+			elif grep "opyright.*$YEAR_RGX.*$PLATPROV" "$FILE" >/dev/null 2>&1
+			then
+				exit_code=1
+				sed -i "s/\(opyright.*$YEAR_RGX\)\(.*$PLATPROV\)/\1-$(date +"%Y")\2/" $FILE
+				user_warning
+			fi
+
+			# Even if the year is correct - verify that Arm copyright is formatted correctly.
+			if [[ $ORG == *arm* ]]
+			then
+				if grep "opyright.*\(ARM\|arm\)" "$FILE">/dev/null 2>&1
+				then
+					exit_code=1
+					sed -i "s/\(opyright.*\)\(ARM\|arm\)/\1Arm/" $FILE
+					user_warning
+				fi
+			fi
 		fi
-	# Even if the year is correct - verify that Arm copyright is formatted correctly.
-	elif grep "opyright.*\(ARM\|arm\)" "$FILE">/dev/null 2>&1
-	then
-		exit_code=1
-		sed -i "s/\(opyright.*\)\(ARM\|arm\)/\1Arm/" $FILE
-		user_warning
 	fi
+
 done <<< "$FILES"
 
 if [ $exit_code -eq 1 ]
diff --git a/.nvmrc b/.nvmrc
index e0325e5a..ee09fac7 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v16.17.1
+v20.11.1
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 7b6a1f5c..2d1afab8 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -1,4 +1,4 @@
-# Copyright (c) 2023, Arm Limited. All rights reserved
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,9 +19,8 @@ build:
   jobs:
     post_create_environment:
       - pip install poetry=="1.3.2"
-      - poetry config virtualenvs.create false
     post_install:
-      - poetry install --with doc
+      - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with docs
 
 sphinx:
   configuration: docs/conf.py
diff --git a/.versionrc.js b/.versionrc.cjs
similarity index 95%
rename from .versionrc.js
rename to .versionrc.cjs
index c7ee4a22..ac473b09 100644
--- a/.versionrc.js
+++ b/.versionrc.cjs
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -84,9 +84,9 @@ module.exports = {
             "filename": "pyproject.toml",
             "updater": {
                 "readVersion": function (contents) {
-                    const _ver = contents.match(/version\s=.*"(\d)\.(\d)\.(\d)/);
+                    const _ver = contents.match(/version\s=.*"(\d+?)\.(\d+?)\.(\d+?)/);
 
-                    return `${_ver[1]}.${_ver[2]}.${_ver[2]}`;
+                    return `${_ver[1]}.${_ver[2]}.${_ver[3]}`;
                 },
 
                 "writeVersion": function (contents, version) {
@@ -104,9 +104,9 @@ module.exports = {
             "filename": "docs/conf.py",
             "updater": {
                 "readVersion": function (contents) {
-                    const _ver = contents.match(/version\s=.*"(\d)\.(\d)\.(\d)/);
+                    const _ver = contents.match(/version\s=.*"(\d+?)\.(\d+?)\.(\d+?)/);
 
-                    return `${_ver[1]}.${_ver[2]}.${_ver[2]}`;
+                    return `${_ver[1]}.${_ver[2]}.${_ver[3]}`;
                 },
 
                 "writeVersion": function (contents, version) {
diff --git a/Makefile b/Makefile
index 97c3c154..e4a1f311 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,8 +8,9 @@
 # Trusted Firmware Version
 #
 VERSION_MAJOR			:= 2
-VERSION_MINOR			:= 10
-VERSION_PATCH			:= 0	# Only used for LTS releases
+VERSION_MINOR			:= 12
+# VERSION_PATCH is only used for LTS releases
+VERSION_PATCH			:= 0
 VERSION				:= ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
 
 # Default goal is build all images
@@ -23,17 +24,30 @@ MAKEOVERRIDES =
 MAKE_HELPERS_DIRECTORY := make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}build-rules.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 
 ################################################################################
 # Default values for build configurations, and their dependencies
 ################################################################################
 
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
+include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
+
+# To be able to set platform specific defaults
+ifneq ($(PLAT_DEFAULTS_MAKEFILE_FULL),)
+include ${PLAT_DEFAULTS_MAKEFILE_FULL}
+endif
+
+################################################################################
+# Configure the toolchains used to build TF-A and its tools
+################################################################################
+
+include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 # Assertions enabled for DEBUG builds by default
 ENABLE_ASSERTIONS		:= ${DEBUG}
 ENABLE_PMF			:= ${ENABLE_RUNTIME_INSTRUMENTATION}
-PLAT				:= ${DEFAULT_PLAT}
 
 ################################################################################
 # Checkpatch script options
@@ -75,45 +89,8 @@ CHECK_PATHS		:=	${ROOT_DIRS_TO_CHECK}			\
 # Process build options
 ################################################################################
 
-# Verbose flag
-ifeq (${V},0)
-	Q:=@
-	ECHO:=@echo
+ifeq ($(verbose),)
 	CHECKCODE_ARGS	+=	--no-summary --terse
-else
-	Q:=
-	ECHO:=$(ECHO_QUIET)
-endif
-
-ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
-	Q:=@
-	ECHO:=$(ECHO_QUIET)
-endif
-
-export Q ECHO
-
-################################################################################
-# Toolchain
-################################################################################
-
-HOSTCC			:=	gcc
-export HOSTCC
-
-CC			:=	${CROSS_COMPILE}gcc
-CPP			:=	${CROSS_COMPILE}cpp
-AS			:=	${CROSS_COMPILE}gcc
-AR			:=	${CROSS_COMPILE}ar
-LINKER			:=	${CROSS_COMPILE}ld
-OC			:=	${CROSS_COMPILE}objcopy
-OD			:=	${CROSS_COMPILE}objdump
-NM			:=	${CROSS_COMPILE}nm
-PP			:=	${CROSS_COMPILE}gcc -E
-DTC			:=	dtc
-
-# Use ${LD}.bfd instead if it exists (as absolute path or together with $PATH).
-ifneq ($(strip $(wildcard ${LD}.bfd) \
-	$(foreach dir,$(subst :, ,${PATH}),$(wildcard ${dir}/${LINKER}.bfd))),)
-LINKER			:=	${LINKER}.bfd
 endif
 
 ################################################################################
@@ -162,45 +139,20 @@ endif #(ARM_ARCH_MAJOR)
 ################################################################################
 arch-features		=	${ARM_ARCH_FEATURE}
 
-# Set the compiler's architecture feature modifiers
-ifneq ($(arch-features), none)
-	# Strip "none+" from arch-features
-	arch-features	:=	$(subst none+,,$(arch-features))
-	march-directive	:=	$(march-directive)+$(arch-features)
-# Print features
-        $(info Arm Architecture Features specified: $(subst +, ,$(arch-features)))
-endif #(arch-features)
-
-ifneq ($(findstring clang,$(notdir $(CC))),)
-	ifneq ($(findstring armclang,$(notdir $(CC))),)
+ifneq ($(filter %-clang,$($(ARCH)-cc-id)),)
+	ifeq ($($(ARCH)-cc-id),arm-clang)
 		TF_CFLAGS_aarch32	:=	-target arm-arm-none-eabi
 		TF_CFLAGS_aarch64	:=	-target aarch64-arm-none-eabi
-		LD			:=	$(LINKER)
 	else
 		TF_CFLAGS_aarch32	=	$(target32-directive)
 		TF_CFLAGS_aarch64	:=	-target aarch64-elf
-		LD			:=	$(shell $(CC) --print-prog-name ld.lld)
-
-		AR			:=	$(shell $(CC) --print-prog-name llvm-ar)
-		OD			:=	$(shell $(CC) --print-prog-name llvm-objdump)
-		OC			:=	$(shell $(CC) --print-prog-name llvm-objcopy)
 	endif
 
-	CPP		:=	$(CC) -E $(TF_CFLAGS_$(ARCH))
-	PP		:=	$(CC) -E $(TF_CFLAGS_$(ARCH))
-	AS		:=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
-else ifneq ($(findstring gcc,$(notdir $(CC))),)
-	ifeq ($(ENABLE_LTO),1)
-		# Enable LTO only for aarch64
-		ifeq (${ARCH},aarch64)
-			LTO_CFLAGS	=	-flto
-			# Use gcc as a wrapper for the ld, recommended for LTO
-			LINKER		:=	${CROSS_COMPILE}gcc
-		endif
+else ifeq ($($(ARCH)-cc-id),gnu-gcc)
+	# Enable LTO only for aarch64
+	ifeq (${ARCH},aarch64)
+		LTO_CFLAGS	=	$(if $(filter-out 0,$(ENABLE_LTO)),-flto)
 	endif
-	LD			=	$(LINKER)
-else
-	LD			=	$(LINKER)
 endif #(clang)
 
 # Process Debug flag
@@ -235,8 +187,6 @@ endif #(AARCH32_INSTRUCTION_SET)
 TF_CFLAGS_aarch32	+=	-mno-unaligned-access
 TF_CFLAGS_aarch64	+=	-mgeneral-regs-only -mstrict-align
 
-ASFLAGS		+=	$(march-directive)
-
 ##############################################################################
 # WARNINGS Configuration
 ###############################################################################
@@ -299,14 +249,20 @@ else ifeq (${W},3)
 endif #(W)
 
 # Compiler specific warnings
-ifeq ($(findstring clang,$(notdir $(CC))),)
+ifeq ($(filter %-clang,$($(ARCH)-cc-id)),)
 # not using clang
 WARNINGS	+=		-Wunused-but-set-variable -Wmaybe-uninitialized	\
 				-Wpacked-bitfield-compat -Wshift-overflow=2 \
 				-Wlogical-op
 
 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
-TF_CFLAGS		+= 	$(call cc_option, --param=min-pagesize=0)
+TF_CFLAGS_MIN_PAGE_SIZE	:=	$(call cc_option, --param=min-pagesize=0)
+TF_CFLAGS		+=	$(TF_CFLAGS_MIN_PAGE_SIZE)
+
+ifeq ($(HARDEN_SLS), 1)
+        TF_CFLAGS_MHARDEN_SLS	:=      $(call cc_option, -mharden-sls=all)
+        TF_CFLAGS_aarch64	+=      $(TF_CFLAGS_MHARDEN_SLS)
+endif
 
 else
 # using clang
@@ -339,28 +295,31 @@ ifeq (${SANITIZE_UB},trap)
 				-fsanitize-undefined-trap-on-error
 endif #(${SANITIZE_UB},trap)
 
-GCC_V_OUTPUT		:=	$(shell $(CC) -v 2>&1)
+GCC_V_OUTPUT		:=	$(if $($(ARCH)-cc),$(shell $($(ARCH)-cc) -v 2>&1))
 
 TF_LDFLAGS		+=	-z noexecstack
 
 # LD = armlink
-ifneq ($(findstring armlink,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),arm-link)
 	TF_LDFLAGS		+=	--diag_error=warning --lto_level=O1
 	TF_LDFLAGS		+=	--remove --info=unused,unusedsymbols
 	TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
 
 # LD = gcc (used when GCC LTO is enabled)
-else ifneq ($(findstring gcc,$(notdir $(LD))),)
+else ifeq ($($(ARCH)-ld-id),gnu-gcc)
 	# Pass ld options with Wl or Xlinker switches
+	TF_LDFLAGS		+=	$(call ld_option,-Xlinker --no-warn-rwx-segments)
 	TF_LDFLAGS		+=	-Wl,--fatal-warnings -O1
 	TF_LDFLAGS		+=	-Wl,--gc-sections
 
 	TF_LDFLAGS		+=	-Wl,-z,common-page-size=4096 #Configure page size constants
 	TF_LDFLAGS		+=	-Wl,-z,max-page-size=4096
+	TF_LDFLAGS		+=	-Wl,--build-id=none
 
 	ifeq ($(ENABLE_LTO),1)
 		ifeq (${ARCH},aarch64)
 			TF_LDFLAGS	+=	-flto -fuse-linker-plugin
+			TF_LDFLAGS      +=	-flto-partition=one
 		endif
 	endif #(ENABLE_LTO)
 
@@ -384,12 +343,13 @@ else
 
 	TF_LDFLAGS		+=	-z common-page-size=4096 # Configure page size constants
 	TF_LDFLAGS		+=	-z max-page-size=4096
+	TF_LDFLAGS		+=	--build-id=none
 
 # ld.lld doesn't recognize the errata flags,
 # therefore don't add those in that case.
 # ld.lld reports section type mismatch warnings,
 # therefore don't add --fatal-warnings to it.
-	ifeq ($(findstring ld.lld,$(notdir $(LD))),)
+	ifneq ($($(ARCH)-ld-id),llvm-lld)
 		TF_LDFLAGS	+=	$(TF_LDFLAGS_$(ARCH)) --fatal-warnings
 	endif
 
@@ -399,8 +359,8 @@ endif #(LD = armlink)
 # Setup ARCH_MAJOR/MINOR before parsing arch_features.
 ################################################################################
 ifeq (${ENABLE_RME},1)
-	ARM_ARCH_MAJOR := 8
-	ARM_ARCH_MINOR := 6
+	ARM_ARCH_MAJOR := 9
+	ARM_ARCH_MINOR := 2
 endif
 
 ################################################################################
@@ -408,6 +368,15 @@ endif
 ################################################################################
 include lib/compiler-rt/compiler-rt.mk
 
+# Allow overriding the timestamp, for example for reproducible builds, or to
+# synchronize timestamps across multiple projects.
+# This must be set to a C string (including quotes where applicable).
+BUILD_MESSAGE_TIMESTAMP ?= __TIME__", "__DATE__
+
+DEFINES += -DBUILD_MESSAGE_TIMESTAMP='$(BUILD_MESSAGE_TIMESTAMP)'
+DEFINES += -DBUILD_MESSAGE_VERSION_STRING='"$(VERSION_STRING)"'
+DEFINES += -DBUILD_MESSAGE_VERSION='"$(VERSION)"'
+
 BL_COMMON_SOURCES	+=	common/bl_common.c			\
 				common/tf_log.c				\
 				common/${ARCH}/debug.S			\
@@ -421,7 +390,7 @@ BL_COMMON_SOURCES	+=	common/bl_common.c			\
 				plat/common/${ARCH}/platform_helpers.S	\
 				${COMPILER_RT_SRCS}
 
-ifeq ($(notdir $(CC)),armclang)
+ifeq ($($(ARCH)-cc-id),arm-clang)
 	BL_COMMON_SOURCES	+=	lib/${ARCH}/armclang_printf.S
 endif
 
@@ -445,7 +414,6 @@ include common/backtrace/backtrace.mk
 ################################################################################
 # Generic definitions
 ################################################################################
-include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
 
 ifeq (${BUILD_BASE},)
      BUILD_BASE		:=	./build
@@ -481,14 +449,21 @@ ifneq (${SPD},none)
 			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)
 			DTC_CPPFLAGS	+=	-DOPTEE_SP_FW_CONFIG
 		endif
 
+		ifeq ($(findstring trusty_sp,$(ARM_SPMC_MANIFEST_DTS)),trusty_sp)
+			DTC_CPPFLAGS	+=	-DTRUSTY_SP_FW_CONFIG
+		endif
+
 		ifeq ($(TS_SP_FW_CONFIG),1)
-		DTC_CPPFLAGS	+=	-DTS_SP_FW_CONFIG
+			DTC_CPPFLAGS	+=	-DTS_SP_FW_CONFIG
 		endif
 
 		ifneq ($(ARM_BL2_SP_LIST_DTS),)
@@ -602,14 +577,14 @@ include ${MAKE_HELPERS_DIRECTORY}arch_features.mk
 ifeq (${SUPPORT_STACK_MEMTAG},yes)
     ifdef mem_tag_arch_support
         # Check for armclang and clang compilers
-        ifneq ( ,$(filter $(notdir $(CC)),armclang clang))
+        ifneq ($(filter %-clang,$($(ARCH)-cc-id)),)
         # Add "memtag" architecture feature modifier if not specified
             ifeq ( ,$(findstring memtag,$(arch-features)))
                 arch-features	:=	$(arch-features)+memtag
             endif	# memtag
-            ifeq ($(notdir $(CC)),armclang)
+            ifeq ($($(ARCH)-cc-id),arm-clang)
                 TF_CFLAGS	+=	-mmemtag-stack
-            else ifeq ($(notdir $(CC)),clang)
+            else ifeq ($($(ARCH)-cc-id),llvm-clang)
                 TF_CFLAGS	+=	-fsanitize=memtag
             endif	# armclang
         endif
@@ -624,19 +599,11 @@ endif #(SUPPORT_STACK_MEMTAG)
 ################################################################################
 # FEAT_RME
 ifeq (${ENABLE_RME},1)
-	# RME doesn't support BRBE
-	ENABLE_BRBE_FOR_NS := 0
-
 	# RME doesn't support PIE
 	ifneq (${ENABLE_PIE},0)
                 $(error ENABLE_RME does not support PIE)
 	endif
 
-	# RME doesn't support BRBE
-	ifneq (${ENABLE_BRBE_FOR_NS},0)
-                $(error ENABLE_RME does not support BRBE.)
-	endif
-
 	# RME requires AARCH64
 	ifneq (${ARCH},aarch64)
                 $(error ENABLE_RME requires AArch64)
@@ -680,6 +647,13 @@ ifeq (${CTX_INCLUDE_EL2_REGS}, 1)
 	endif
 endif
 
+################################################################################
+# Make 128-Bit sysreg read/writes availabe when FEAT_D128 is enabled.
+################################################################################
+ifneq (${ENABLE_FEAT_D128}, 0)
+        BL_COMMON_SOURCES       +=      lib/extensions/sysreg128/sysreg128.S
+endif
+
 ################################################################################
 # Platform specific Makefile might provide us ARCH_MAJOR/MINOR use that to come
 # up with appropriate march values for compiler.
@@ -687,6 +661,7 @@ endif
 include ${MAKE_HELPERS_DIRECTORY}march.mk
 
 TF_CFLAGS   +=	$(march-directive)
+ASFLAGS		+=	$(march-directive)
 
 # This internal flag is common option which is set to 1 for scenarios
 # when the BL2 is running in EL3 level. This occurs in two scenarios -
@@ -713,8 +688,6 @@ else
 	FFH_SUPPORT := 0
 endif
 
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_PLAT}))
-
 ifeq (${ARM_ARCH_MAJOR},7)
 include make_helpers/armv7-a-cpus.mk
 endif
@@ -722,12 +695,12 @@ endif
 PIE_FOUND		:=	$(findstring --enable-default-pie,${GCC_V_OUTPUT})
 ifneq ($(PIE_FOUND),)
 	TF_CFLAGS	+=	-fno-PIE
-ifneq ($(findstring gcc,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
 	TF_LDFLAGS	+=	-no-pie
 endif
 endif #(PIE_FOUND)
 
-ifneq ($(findstring gcc,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
 	PIE_LDFLAGS	+=	-Wl,-pie -Wl,--no-dynamic-linker
 else
 	PIE_LDFLAGS	+=	-pie --no-dynamic-linker
@@ -929,16 +902,6 @@ ifeq ($(CTX_INCLUDE_PAUTH_REGS),1)
 	endif
 endif #(CTX_INCLUDE_PAUTH_REGS)
 
-ifeq ($(CTX_INCLUDE_MTE_REGS),1)
-	ifneq (${ARCH},aarch64)
-                $(error CTX_INCLUDE_MTE_REGS requires AArch64)
-	endif
-endif #(CTX_INCLUDE_MTE_REGS)
-
-ifeq ($(PSA_FWU_SUPPORT),1)
-        $(info PSA_FWU_SUPPORT is an experimental feature)
-endif #(PSA_FWU_SUPPORT)
-
 ifeq ($(FEATURE_DETECTION),1)
         $(info FEATURE_DETECTION is an experimental feature)
 endif #(FEATURE_DETECTION)
@@ -1006,25 +969,52 @@ ifeq (${ENABLE_SME_FOR_SWD},1)
 	endif
 endif #(ENABLE_SME_FOR_SWD)
 
+# Enabling SVE for SWD requires enabling SVE for NWD due to ENABLE_FEAT
+# mechanism.
 ifeq (${ENABLE_SVE_FOR_SWD},1)
-	ifeq (${ENABLE_SVE_FOR_NS},0)
-                $(error "ENABLE_SVE_FOR_SWD requires ENABLE_SVE_FOR_NS")
-	endif
-endif #(ENABLE_SVE_FOR_SWD)
+    ifeq (${ENABLE_SVE_FOR_NS},0)
+        $(error "ENABLE_SVE_FOR_SWD requires ENABLE_SVE_FOR_NS")
+    endif
+endif
 
-# SVE and SME cannot be used with CTX_INCLUDE_FPREGS since secure manager does
-# its own context management including FPU registers.
-ifeq (${CTX_INCLUDE_FPREGS},1)
-	ifneq (${ENABLE_SME_FOR_NS},0)
-                $(error "ENABLE_SME_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
-	endif
+# Enabling SVE for both the worlds typically requires the context
+# management of SVE registers. The only exception being SPMC at S-EL2.
+ifeq (${ENABLE_SVE_FOR_SWD}, 1)
+    ifneq (${ENABLE_SVE_FOR_NS}, 0)
+        ifeq (${CTX_INCLUDE_SVE_REGS}-$(SPMD_SPM_AT_SEL2),0-0)
+            $(warning "ENABLE_SVE_FOR_SWD and ENABLE_SVE_FOR_NS together require CTX_INCLUDE_SVE_REGS")
+        endif
+    endif
+endif
 
-	ifeq (${ENABLE_SVE_FOR_NS},1)
-		# Warning instead of error due to CI dependency on this
-                $(warning "ENABLE_SVE_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
-                $(warning "Forced ENABLE_SVE_FOR_NS=0")
-		override ENABLE_SVE_FOR_NS	:= 0
-	endif
+# Enabling SVE in either world while enabling CTX_INCLUDE_FPREGS requires
+# CTX_INCLUDE_SVE_REGS to be enabled due to architectural dependency between FP
+# and SVE registers.
+ifeq (${CTX_INCLUDE_FPREGS}, 1)
+    ifneq (${ENABLE_SVE_FOR_NS},0)
+        ifeq (${CTX_INCLUDE_SVE_REGS},0)
+	    # Warning instead of error due to CI dependency on this
+            $(warning "CTX_INCLUDE_FPREGS and ENABLE_SVE_FOR_NS together require CTX_INCLUDE_SVE_REGS")
+            $(warning "Forced ENABLE_SVE_FOR_NS=0")
+	    override ENABLE_SVE_FOR_NS	:= 0
+        endif
+    endif
+endif #(CTX_INCLUDE_FPREGS)
+
+# SVE context management is only required if secure world has access to SVE/FP
+# functionality.
+ifeq (${CTX_INCLUDE_SVE_REGS},1)
+    ifeq (${ENABLE_SVE_FOR_SWD},0)
+        $(error "CTX_INCLUDE_SVE_REGS requires ENABLE_SVE_FOR_SWD to also be enabled")
+    endif
+endif
+
+# SME cannot be used with CTX_INCLUDE_FPREGS since SPM does its own context
+# management including FPU registers.
+ifeq (${CTX_INCLUDE_FPREGS},1)
+    ifneq (${ENABLE_SME_FOR_NS},0)
+        $(error "ENABLE_SME_FOR_NS cannot be used with CTX_INCLUDE_FPREGS")
+    endif
 endif #(CTX_INCLUDE_FPREGS)
 
 ifeq ($(DRTM_SUPPORT),1)
@@ -1041,16 +1031,14 @@ ifeq (${ENABLE_RME},1)
 	endif
 endif
 
-# Determine if FEAT_RNG is supported
-ENABLE_FEAT_RNG		=	$(if $(findstring rng,${arch-features}),1,0)
-
-# Determine if FEAT_SB is supported
-ENABLE_FEAT_SB		=	$(if $(findstring sb,${arch-features}),1,0)
-
 ifeq ($(PSA_CRYPTO),1)
         $(info PSA_CRYPTO is an experimental feature)
 endif
 
+ifeq ($(DICE_PROTECTION_ENVIRONMENT),1)
+        $(info DICE_PROTECTION_ENVIRONMENT is an experimental feature)
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -1163,7 +1151,9 @@ $(eval $(call assert_booleans,\
 	CREATE_KEYS \
 	CTX_INCLUDE_AARCH32_REGS \
 	CTX_INCLUDE_FPREGS \
+	CTX_INCLUDE_SVE_REGS \
 	CTX_INCLUDE_EL2_REGS \
+	CTX_INCLUDE_MPAM_REGS \
 	DEBUG \
 	DYN_DISABLE_AUTH \
 	EL3_EXCEPTION_HANDLING \
@@ -1171,7 +1161,6 @@ $(eval $(call assert_booleans,\
 	ENABLE_AMU_FCONF \
 	AMU_RESTRICT_COUNTERS \
 	ENABLE_ASSERTIONS \
-	ENABLE_FEAT_SB \
 	ENABLE_PIE \
 	ENABLE_PMF \
 	ENABLE_PSCI_STAT \
@@ -1185,13 +1174,15 @@ $(eval $(call assert_booleans,\
 	GENERATE_COT \
 	GICV2_G0_FOR_EL3 \
 	HANDLE_EA_EL3_FIRST_NS \
+	HARDEN_SLS \
 	HW_ASSISTED_COHERENCY \
 	MEASURED_BOOT \
+	DICE_PROTECTION_ENVIRONMENT \
+	RMMD_ENABLE_EL3_TOKEN_SIGN \
 	DRTM_SUPPORT \
 	NS_TIMER_SWITCH \
 	OVERRIDE_LIBC \
 	PL011_GENERIC_UART \
-	PLAT_RSS_NOT_SUPPORTED \
 	PROGRAMMABLE_RESET_ADDRESS \
 	PSCI_EXTENDED_STATE_ID \
 	PSCI_OS_INIT_MODE \
@@ -1200,6 +1191,8 @@ $(eval $(call assert_booleans,\
 	SEPARATE_CODE_AND_RODATA \
 	SEPARATE_BL2_NOLOAD_REGION \
 	SEPARATE_NOBITS_REGION \
+	SEPARATE_RWDATA_REGION \
+	SEPARATE_SIMD_SECTION \
 	SPIN_ON_BL1_EXIT \
 	SPM_MM \
 	SPMC_AT_EL3 \
@@ -1227,6 +1220,7 @@ $(eval $(call assert_booleans,\
 	COT_DESC_IN_DTB \
 	USE_SP804_TIMER \
 	PSA_FWU_SUPPORT \
+	PSA_FWU_METADATA_FW_STORE_DESC \
 	ENABLE_MPMM \
 	ENABLE_MPMM_FCONF \
 	FEATURE_DETECTION \
@@ -1237,6 +1231,9 @@ $(eval $(call assert_booleans,\
 	PSA_CRYPTO	\
 	ENABLE_CONSOLE_GETC \
 	INIT_UNUSED_NS_EL2	\
+	PLATFORM_REPORT_CTX_MEM_USE \
+	EARLY_CONSOLE \
+	PRESERVE_DSU_PMU_REGS \
 )))
 
 # Numeric_Flags
@@ -1246,7 +1243,6 @@ $(eval $(call assert_numerics,\
 	ARM_ARCH_MINOR \
 	BRANCH_PROTECTION \
 	CTX_INCLUDE_PAUTH_REGS \
-	CTX_INCLUDE_MTE_REGS \
 	CTX_INCLUDE_NEVE_REGS \
 	CRYPTO_SUPPORT \
 	DISABLE_MTPMU \
@@ -1257,22 +1253,30 @@ $(eval $(call assert_numerics,\
 	ENABLE_FEAT_AMU \
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_CSV2_2 \
+	ENABLE_FEAT_CSV2_3 \
+	ENABLE_FEAT_DEBUGV8P9 \
 	ENABLE_FEAT_DIT \
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_FGT \
+	ENABLE_FEAT_FGT2 \
 	ENABLE_FEAT_HCX \
+	ENABLE_FEAT_LS64_ACCDATA \
+	ENABLE_FEAT_MTE2 \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_RNG \
 	ENABLE_FEAT_RNG_TRAP \
 	ENABLE_FEAT_SEL2 \
 	ENABLE_FEAT_TCR2 \
+	ENABLE_FEAT_THE \
+	ENABLE_FEAT_SB \
 	ENABLE_FEAT_S2PIE \
 	ENABLE_FEAT_S1PIE \
 	ENABLE_FEAT_S2POE \
 	ENABLE_FEAT_S1POE \
+	ENABLE_FEAT_SCTLR2 \
+	ENABLE_FEAT_D128 \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_VHE \
-	ENABLE_FEAT_MTE_PERM \
 	ENABLE_FEAT_MPAM \
 	ENABLE_RME \
 	ENABLE_SPE_FOR_NS \
@@ -1313,9 +1317,10 @@ $(eval $(call add_defines,\
 	COLD_BOOT_SINGLE_CPU \
 	CTX_INCLUDE_AARCH32_REGS \
 	CTX_INCLUDE_FPREGS \
+	CTX_INCLUDE_SVE_REGS \
 	CTX_INCLUDE_PAUTH_REGS \
+	CTX_INCLUDE_MPAM_REGS \
 	EL3_EXCEPTION_HANDLING \
-	CTX_INCLUDE_MTE_REGS \
 	CTX_INCLUDE_EL2_REGS \
 	CTX_INCLUDE_NEVE_REGS \
 	DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \
@@ -1326,12 +1331,14 @@ $(eval $(call add_defines,\
 	AMU_RESTRICT_COUNTERS \
 	ENABLE_ASSERTIONS \
 	ENABLE_BTI \
+	ENABLE_FEAT_DEBUGV8P9 \
 	ENABLE_FEAT_MPAM \
 	ENABLE_PAUTH \
 	ENABLE_PIE \
 	ENABLE_PMF \
 	ENABLE_PSCI_STAT \
 	ENABLE_RME \
+	RMMD_ENABLE_EL3_TOKEN_SIGN \
 	ENABLE_RUNTIME_INSTRUMENTATION \
 	ENABLE_SME_FOR_NS \
 	ENABLE_SME2_FOR_NS \
@@ -1350,18 +1357,22 @@ $(eval $(call add_defines,\
 	HW_ASSISTED_COHERENCY \
 	LOG_LEVEL \
 	MEASURED_BOOT \
+	DICE_PROTECTION_ENVIRONMENT \
 	DRTM_SUPPORT \
 	NS_TIMER_SWITCH \
 	PL011_GENERIC_UART \
 	PLAT_${PLAT} \
-	PLAT_RSS_NOT_SUPPORTED \
 	PROGRAMMABLE_RESET_ADDRESS \
 	PSCI_EXTENDED_STATE_ID \
 	PSCI_OS_INIT_MODE \
 	RESET_TO_BL31 \
+	RME_GPT_BITLOCK_BLOCK \
+	RME_GPT_MAX_BLOCK \
 	SEPARATE_CODE_AND_RODATA \
 	SEPARATE_BL2_NOLOAD_REGION \
 	SEPARATE_NOBITS_REGION \
+	SEPARATE_RWDATA_REGION \
+	SEPARATE_SIMD_SECTION \
 	RECLAIM_INIT_CODE \
 	SPD_${SPD} \
 	SPIN_ON_BL1_EXIT \
@@ -1399,6 +1410,7 @@ $(eval $(call add_defines,\
 	NR_OF_FW_BANKS \
 	NR_OF_IMAGES_IN_FW_BANK \
 	PSA_FWU_SUPPORT \
+	PSA_FWU_METADATA_FW_STORE_DESC \
 	ENABLE_BRBE_FOR_NS \
 	ENABLE_TRBE_FOR_NS \
 	ENABLE_SYS_REG_TRACE_FOR_NS \
@@ -1407,19 +1419,25 @@ $(eval $(call add_defines,\
 	ENABLE_MPMM \
 	ENABLE_MPMM_FCONF \
 	ENABLE_FEAT_FGT \
+	ENABLE_FEAT_FGT2 \
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_SEL2 \
 	ENABLE_FEAT_VHE \
 	ENABLE_FEAT_CSV2_2 \
+	ENABLE_FEAT_CSV2_3 \
+	ENABLE_FEAT_LS64_ACCDATA \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_TCR2 \
+	ENABLE_FEAT_THE \
 	ENABLE_FEAT_S2PIE \
 	ENABLE_FEAT_S1PIE \
 	ENABLE_FEAT_S2POE \
 	ENABLE_FEAT_S1POE \
+	ENABLE_FEAT_SCTLR2 \
+	ENABLE_FEAT_D128 \
 	ENABLE_FEAT_GCS \
-	ENABLE_FEAT_MTE_PERM \
+	ENABLE_FEAT_MTE2 \
 	FEATURE_DETECTION \
 	TWED_DELAY \
 	ENABLE_FEAT_TWED \
@@ -1430,8 +1448,18 @@ $(eval $(call add_defines,\
 	PSA_CRYPTO	\
 	ENABLE_CONSOLE_GETC \
 	INIT_UNUSED_NS_EL2	\
+	PLATFORM_REPORT_CTX_MEM_USE \
+	EARLY_CONSOLE \
+	PRESERVE_DSU_PMU_REGS \
 )))
 
+ifeq (${PLATFORM_REPORT_CTX_MEM_USE}, 1)
+ifeq (${DEBUG}, 0)
+        $(warning "PLATFORM_REPORT_CTX_MEM_USE can be applied when DEBUG=1 only")
+        override PLATFORM_REPORT_CTX_MEM_USE := 0
+endif
+endif
+
 ifeq (${SANITIZE_UB},trap)
         $(eval $(call add_define,MONITOR_TRAPS))
 endif #(SANITIZE_UB)
@@ -1452,7 +1480,7 @@ ifeq (${DYN_DISABLE_AUTH},1)
         $(eval $(call add_define,DYN_DISABLE_AUTH))
 endif
 
-ifneq ($(findstring armlink,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),arm-link)
         $(eval $(call add_define,USE_ARM_LINK))
 endif
 
@@ -1474,24 +1502,23 @@ endif #(SPD)
 # Build targets
 ################################################################################
 
-.PHONY:	all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip sp fwu_fip certtool dtbs memmap doc enctool
+.PHONY:	all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip sp tl fwu_fip certtool dtbs memmap doc enctool
 .SUFFIXES:
 
 all: msg_start
 
 msg_start:
-	@echo "Building ${PLAT}"
+	$(s)echo "Building ${PLAT}"
 
 ifeq (${ERROR_DEPRECATED},0)
 # Check if deprecated declarations and cpp warnings should be treated as error or not.
-ifneq ($(findstring clang,$(notdir $(CC))),)
+ifneq ($(filter %-clang,$($(ARCH)-cc-id)),)
     CPPFLAGS		+= 	-Wno-error=deprecated-declarations
 else
     CPPFLAGS		+= 	-Wno-error=deprecated-declarations -Wno-error=cpp
 endif
 endif #(!ERROR_DEPRECATED)
 
-$(eval $(call MAKE_LIB_DIRS))
 $(eval $(call MAKE_LIB,c))
 
 # Expand build macros for the different images
@@ -1575,12 +1602,12 @@ endif #(NEED_FDT)
 
 # Add Secure Partition packages
 ifeq (${NEED_SP_PKG},yes)
-$(BUILD_PLAT)/sp_gen.mk : ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT}
-	${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT} ${SP_DTS_LIST_FRAGMENT}
+$(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | $$(@D)/
+	$(q)${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT} ${SP_DTS_LIST_FRAGMENT}
 sp: $(DTBS) $(BUILD_PLAT)/sp_gen.mk $(SP_PKGS)
-	@${ECHO_BLANK_LINE}
-	@echo "Built SP Images successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built SP Images successfully"
+	$(s)echo
 endif #(NEED_SP_PKG)
 
 locate-checkpatch:
@@ -1593,37 +1620,37 @@ endif
 endif #(CHECKPATCH)
 
 clean:
-	@echo "  CLEAN"
+	$(s)echo "  CLEAN"
 	$(call SHELL_REMOVE_DIR,${BUILD_PLAT})
 ifdef UNIX_MK
-	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+	$(q)${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
 else
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
-	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) clean
+	$(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) clean
 endif #(UNIX_MK)
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean
-	${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} clean
+	$(q)${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
 
 realclean distclean:
-	@echo "  REALCLEAN"
+	$(s)echo "  REALCLEAN"
 	$(call SHELL_REMOVE_DIR,${BUILD_BASE})
 	$(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
 ifdef UNIX_MK
-	${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
+	$(q)${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
 else
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
-	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
+	$(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL)) realclean
 endif #(UNIX_MK)
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} realclean
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
-	${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} realclean
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${ENCTOOLPATH} realclean
+	$(q)${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
 
 checkcodebase:		locate-checkpatch
-	@echo "  CHECKING STYLE"
-	@if test -d .git ; then						\
+	$(s)echo "  CHECKING STYLE"
+	$(q)if test -d .git ; then						\
 		git ls-files | grep -E -v 'libfdt|libc|docs|\.rst' |	\
 		while read GIT_FILE ;					\
 		do ${CHECKPATCH} ${CHECKCODE_ARGS} -f $$GIT_FILE ;	\
@@ -1639,63 +1666,62 @@ checkcodebase:		locate-checkpatch
 	fi
 
 checkpatch:		locate-checkpatch
-	@echo "  CHECKING STYLE"
-	@if test -n "${CHECKPATCH_OPTS}"; then				\
+	$(s)echo "  CHECKING STYLE"
+	$(q)if test -n "${CHECKPATCH_OPTS}"; then				\
 		echo "    with ${CHECKPATCH_OPTS} option(s)";		\
 	fi
-	${Q}COMMON_COMMIT=$$(git merge-base HEAD ${BASE_COMMIT});	\
+	$(q)COMMON_COMMIT=$$(git merge-base HEAD ${BASE_COMMIT});	\
 	for commit in `git rev-list --no-merges $$COMMON_COMMIT..HEAD`;	\
 	do								\
 		printf "\n[*] Checking style of '$$commit'\n\n";	\
-		git log --format=email "$$commit~..$$commit"		\
-			-- ${CHECK_PATHS} |				\
-			${CHECKPATCH} ${CHECKPATCH_OPTS} - || true;	\
-		git diff --format=email "$$commit~..$$commit"		\
-			-- ${CHECK_PATHS} |				\
+		( git log --format=email "$$commit~..$$commit"		\
+			-- ${CHECK_PATHS} ;				\
+		  git diff --format=email "$$commit~..$$commit"		\
+			-- ${CHECK_PATHS}; ) |				\
 			${CHECKPATCH}  ${CHECKPATCH_OPTS} - || true;	\
 	done
 
 certtool: ${CRTTOOL}
 
 ${CRTTOOL}: FORCE
-	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${CRTTOOLPATH} all
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} DEBUG=${DEBUG} --no-print-directory -C ${CRTTOOLPATH} all
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 ifneq (${GENERATE_COT},0)
 certificates: ${CRT_DEPS} ${CRTTOOL}
-	${Q}${CRTTOOL} ${CRT_ARGS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@echo "Certificates can be found in ${BUILD_PLAT}"
-	@${ECHO_BLANK_LINE}
+	$(q)${CRTTOOL} ${CRT_ARGS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo "Certificates can be found in ${BUILD_PLAT}"
+	$(s)echo
 endif #(GENERATE_COT)
 
 ${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_FIP_CMD})
-	${Q}${FIPTOOL} create ${FIP_ARGS} $@
-	${Q}${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${FIPTOOL} create ${FIP_ARGS} $@
+	$(q)${FIPTOOL} info $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 ifneq (${GENERATE_COT},0)
 fwu_certificates: ${FWU_CRT_DEPS} ${CRTTOOL}
-	${Q}${CRTTOOL} ${FWU_CRT_ARGS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@echo "FWU certificates can be found in ${BUILD_PLAT}"
-	@${ECHO_BLANK_LINE}
+	$(q)${CRTTOOL} ${FWU_CRT_ARGS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo "FWU certificates can be found in ${BUILD_PLAT}"
+	$(s)echo
 endif #(GENERATE_COT)
 
 ${BUILD_PLAT}/${FWU_FIP_NAME}: ${FWU_FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_FWU_FIP_CMD})
-	${Q}${FIPTOOL} create ${FWU_FIP_ARGS} $@
-	${Q}${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${FIPTOOL} create ${FWU_FIP_ARGS} $@
+	$(q)${FIPTOOL} info $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 fiptool: ${FIPTOOL}
 fip: ${BUILD_PLAT}/${FIP_NAME}
@@ -1703,85 +1729,90 @@ fwu_fip: ${BUILD_PLAT}/${FWU_FIP_NAME}
 
 ${FIPTOOL}: FORCE
 ifdef UNIX_MK
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${FIPTOOLPATH} all
+	$(q)${MAKE} PLAT=${PLAT} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} OPENSSL_DIR=${OPENSSL_DIR} DEBUG=${DEBUG} --no-print-directory -C ${FIPTOOLPATH} all
 else
 # Clear the MAKEFLAGS as we do not want
 # to pass the gnumake flags to nmake.
-	${Q}set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
+	$(q)set MAKEFLAGS= && ${MSVC_NMAKE} /nologo /f ${FIPTOOLPATH}/Makefile.msvc FIPTOOLPATH=$(subst /,\,$(FIPTOOLPATH)) FIPTOOL=$(subst /,\,$(FIPTOOL))
 endif #(UNIX_MK)
 
 romlib.bin: libraries FORCE
-	${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all
+	$(q)${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES=$(call escape-shell,$(INCLUDES)) DEFINES=$(call escape-shell,$(DEFINES)) --no-print-directory -C ${ROMLIBPATH} all
 
 memmap: all
 ifdef UNIX_MK
-	${Q}PYTHONPATH=${CURDIR}/tools/memory \
+	$(q)PYTHONPATH=${CURDIR}/tools/memory \
 		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
 else
-	${Q}set PYTHONPATH=${CURDIR}/tools/memory && \
+	$(q)set PYTHONPATH=${CURDIR}/tools/memory && \
 		${PYTHON} -m memory.memmap -sr ${BUILD_PLAT}
 endif
 
+tl: ${BUILD_PLAT}/tl.bin
+${BUILD_PLAT}/tl.bin: ${HW_CONFIG}
+	$(if $(host-poetry),$(q)poetry -q install)
+	$(q)$(if $(host-poetry),poetry run )tlc create --fdt $< -s ${FW_HANDOFF_SIZE} $@
+
 doc:
-	@echo "  BUILD DOCUMENTATION"
-	${Q}${MAKE} --no-print-directory -C ${DOCS_PATH} html
+	$(s)echo "  BUILD DOCUMENTATION"
+	$(q)${MAKE} --no-print-directory -C ${DOCS_PATH} html
 
 enctool: ${ENCTOOL}
 
 ${ENCTOOL}: FORCE
-	${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} DEBUG=${DEBUG} V=${V} --no-print-directory -C ${ENCTOOLPATH} all
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} DEBUG=${DEBUG} --no-print-directory -C ${ENCTOOLPATH} all
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 cscope:
-	@echo "  CSCOPE"
-	${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
-	${Q}cscope -b -q -k
+	$(s)echo "  CSCOPE"
+	$(q)find ${CURDIR} -name "*.[chsS]" > cscope.files
+	$(q)cscope -b -q -k
 
 help:
-	@echo "usage: ${MAKE} [PLAT=<platform>] [OPTIONS] [TARGET]"
-	@echo ""
-	@echo "PLAT is used to specify which platform you wish to build."
-	@echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
-	@echo ""
-	@echo "platform = ${PLATFORM_LIST}"
-	@echo ""
-	@echo "Please refer to the User Guide for a list of all supported options."
-	@echo "Note that the build system doesn't track dependencies for build "
-	@echo "options. Therefore, if any of the build options are changed "
-	@echo "from a previous build, a clean build must be performed."
-	@echo ""
-	@echo "Supported Targets:"
-	@echo "  all            Build all individual bootloader binaries"
-	@echo "  bl1            Build the BL1 binary"
-	@echo "  bl2            Build the BL2 binary"
-	@echo "  bl2u           Build the BL2U binary"
-	@echo "  bl31           Build the BL31 binary"
-	@echo "  bl32           Build the BL32 binary. If ARCH=aarch32, then "
-	@echo "                 this builds secure payload specified by AARCH32_SP"
-	@echo "  certificates   Build the certificates (requires 'GENERATE_COT=1')"
-	@echo "  fip            Build the Firmware Image Package (FIP)"
-	@echo "  fwu_fip        Build the FWU Firmware Image Package (FIP)"
-	@echo "  checkcodebase  Check the coding style of the entire source tree"
-	@echo "  checkpatch     Check the coding style on changes in the current"
-	@echo "                 branch against BASE_COMMIT (default origin/master)"
-	@echo "  clean          Clean the build for the selected platform"
-	@echo "  cscope         Generate cscope index"
-	@echo "  distclean      Remove all build artifacts for all platforms"
-	@echo "  certtool       Build the Certificate generation tool"
-	@echo "  enctool        Build the Firmware encryption tool"
-	@echo "  fiptool        Build the Firmware Image Package (FIP) creation tool"
-	@echo "  sp             Build the Secure Partition Packages"
-	@echo "  sptool         Build the Secure Partition Package creation tool"
-	@echo "  dtbs           Build the Device Tree Blobs (if required for the platform)"
-	@echo "  memmap         Print the memory map of the built binaries"
-	@echo "  doc            Build html based documentation using Sphinx tool"
-	@echo ""
-	@echo "Note: most build targets require PLAT to be set to a specific platform."
-	@echo ""
-	@echo "example: build all targets for the FVP platform:"
-	@echo "  CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all"
+	$(s)echo "usage: ${MAKE} [PLAT=<platform>] [OPTIONS] [TARGET]"
+	$(s)echo ""
+	$(s)echo "PLAT is used to specify which platform you wish to build."
+	$(s)echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
+	$(s)echo ""
+	$(s)echo "platform = ${PLATFORM_LIST}"
+	$(s)echo ""
+	$(s)echo "Please refer to the User Guide for a list of all supported options."
+	$(s)echo "Note that the build system doesn't track dependencies for build "
+	$(s)echo "options. Therefore, if any of the build options are changed "
+	$(s)echo "from a previous build, a clean build must be performed."
+	$(s)echo ""
+	$(s)echo "Supported Targets:"
+	$(s)echo "  all            Build all individual bootloader binaries"
+	$(s)echo "  bl1            Build the BL1 binary"
+	$(s)echo "  bl2            Build the BL2 binary"
+	$(s)echo "  bl2u           Build the BL2U binary"
+	$(s)echo "  bl31           Build the BL31 binary"
+	$(s)echo "  bl32           Build the BL32 binary. If ARCH=aarch32, then "
+	$(s)echo "                 this builds secure payload specified by AARCH32_SP"
+	$(s)echo "  certificates   Build the certificates (requires 'GENERATE_COT=1')"
+	$(s)echo "  fip            Build the Firmware Image Package (FIP)"
+	$(s)echo "  fwu_fip        Build the FWU Firmware Image Package (FIP)"
+	$(s)echo "  checkcodebase  Check the coding style of the entire source tree"
+	$(s)echo "  checkpatch     Check the coding style on changes in the current"
+	$(s)echo "                 branch against BASE_COMMIT (default origin/master)"
+	$(s)echo "  clean          Clean the build for the selected platform"
+	$(s)echo "  cscope         Generate cscope index"
+	$(s)echo "  distclean      Remove all build artifacts for all platforms"
+	$(s)echo "  certtool       Build the Certificate generation tool"
+	$(s)echo "  enctool        Build the Firmware encryption tool"
+	$(s)echo "  fiptool        Build the Firmware Image Package (FIP) creation tool"
+	$(s)echo "  sp             Build the Secure Partition Packages"
+	$(s)echo "  sptool         Build the Secure Partition Package creation tool"
+	$(s)echo "  dtbs           Build the Device Tree Blobs (if required for the platform)"
+	$(s)echo "  memmap         Print the memory map of the built binaries"
+	$(s)echo "  doc            Build html based documentation using Sphinx tool"
+	$(s)echo ""
+	$(s)echo "Note: most build targets require PLAT to be set to a specific platform."
+	$(s)echo ""
+	$(s)echo "example: build all targets for the FVP platform:"
+	$(s)echo "  CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all"
 
 .PHONY: FORCE
 FORCE:;
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index 49dda855..636aebe2 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,6 +36,9 @@ SECTIONS {
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".text address is not aligned on a page boundary.");
+
         __TEXT_START__ = .;
 
         *bl1_entrypoint.o(.text*)
@@ -80,6 +83,9 @@ SECTIONS {
     } >ROM
 #else /* SEPARATE_CODE_AND_RODATA */
     .ro . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".ro address is not aligned on a page boundary.");
+
         __RO_START__ = .;
 
         *bl1_entrypoint.o(.text*)
@@ -110,6 +116,8 @@ SECTIONS {
     ASSERT(BL1_RW_BASE == ALIGN(PAGE_SIZE),
         "BL1_RW_BASE address is not aligned on a page boundary.")
 
+    __RW_START__ = .;
+
     DATA_SECTION >RAM AT>ROM
 
     __DATA_RAM_START__ = __DATA_START__;
@@ -142,6 +150,8 @@ SECTIONS {
     } >RAM
 #endif /* USE_COHERENT_MEM */
 
+    __RW_END__ = .;
+
     __BL1_RAM_START__ = ADDR(.data);
     __BL1_RAM_END__ = .;
 
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index 53946ab8..a8a00616 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,13 +12,15 @@ BL1_SOURCES		+=	bl1/${ARCH}/bl1_arch_setup.c		\
 				lib/cpus/${ARCH}/cpu_helpers.S		\
 				lib/cpus/errata_report.c		\
 				lib/el3_runtime/${ARCH}/context_mgmt.c	\
+				lib/locks/exclusive/${ARCH}/spinlock.S	\
 				plat/common/plat_bl1_common.c		\
 				plat/common/${ARCH}/platform_up_stack.S \
 				${MBEDTLS_SOURCES}
 
 ifeq (${ARCH},aarch64)
 BL1_SOURCES		+=	lib/cpus/aarch64/dsu_helpers.S		\
-				lib/el3_runtime/aarch64/context.S
+				lib/el3_runtime/aarch64/context.S	\
+				lib/cpus/errata_common.c
 endif
 
 ifeq (${TRUSTED_BOARD_BOOT},1)
@@ -29,9 +31,9 @@ ifeq (${ENABLE_PMF},1)
 BL1_SOURCES		+=	lib/pmf/pmf_main.c
 endif
 
-ifneq ($(findstring gcc,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
         BL1_LDFLAGS	+=	-Wl,--sort-section=alignment
-else ifneq ($(findstring ld,$(notdir $(LD))),)
+else ifneq ($(filter llvm-lld gnu-ld,$($(ARCH)-ld-id)),)
         BL1_LDFLAGS	+=	--sort-section=alignment
 endif
 
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index 6fe55118..2b3a8271 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <arch_helpers.h>
 #include <bl1/bl1.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/crypto_mod.h>
@@ -38,32 +39,14 @@ uint64_t bl1_apiakey[2];
 		BL_TOTAL_IDS, PMF_DUMP_ENABLE)
 #endif
 
-/*******************************************************************************
- * Helper utility to calculate the BL2 memory layout taking into consideration
- * the BL1 RW data assuming that it is at the top of the memory layout.
- ******************************************************************************/
-void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
-			meminfo_t *bl2_mem_layout)
-{
-	assert(bl1_mem_layout != NULL);
-	assert(bl2_mem_layout != NULL);
-
-	/*
-	 * Remove BL1 RW data from the scope of memory visible to BL2.
-	 * This is assuming BL1 RW data is at the top of bl1_mem_layout.
-	 */
-	assert(BL1_RW_BASE > bl1_mem_layout->total_base);
-	bl2_mem_layout->total_base = bl1_mem_layout->total_base;
-	bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base;
-
-	flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t));
-}
-
 /*******************************************************************************
  * Setup function for BL1.
  ******************************************************************************/
 void bl1_setup(void)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup */
 	bl1_early_platform_setup();
 
@@ -94,7 +77,7 @@ void bl1_main(void)
 
 	/* Announce our arrival */
 	NOTICE(FIRMWARE_WELCOME_STR);
-	NOTICE("BL1: %s\n", version_string);
+	NOTICE("BL1: %s\n", build_version_string);
 	NOTICE("BL1: %s\n", build_message);
 
 	INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT);
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index db83a0c5..310e6fe7 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -25,6 +25,9 @@ SECTIONS {
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".text address is not aligned on a page boundary.");
+
         __TEXT_START__ = .;
 
 #if ENABLE_RME
@@ -65,6 +68,9 @@ SECTIONS {
     } >RAM
 #else /* SEPARATE_CODE_AND_RODATA */
     .ro . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".ro address is not aligned on a page boundary.");
+
         __RO_START__ = .;
 
         *bl2_entrypoint.o(.text*)
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
index b70a3fbe..850d8266 100644
--- a/bl2/bl2.mk
+++ b/bl2/bl2.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -15,9 +15,9 @@ ifeq (${ARCH},aarch64)
 BL2_SOURCES		+=	common/aarch64/early_exceptions.S
 endif
 
-ifneq ($(findstring gcc,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
         BL2_LDFLAGS	+=	-Wl,--sort-section=alignment
-else ifneq ($(findstring ld,$(notdir $(LD))),)
+else ifneq ($(filter llvm-lld gnu-ld,$($(ARCH)-ld-id)),)
         BL2_LDFLAGS	+=	--sort-section=alignment
 endif
 
@@ -52,4 +52,4 @@ endif
 
 ifeq (${ENABLE_PMF},1)
 BL2_SOURCES		+=	lib/pmf/pmf_main.c
-endif
\ No newline at end of file
+endif
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 4aa5cb04..811f41e1 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -55,6 +55,9 @@ SECTIONS {
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".text address is not aligned on a page boundary.");
+
         __TEXT_START__ = .;
         __TEXT_RESIDENT_START__ = .;
 
@@ -89,6 +92,9 @@ SECTIONS {
         "Resident part of BL2 has exceeded its limit.")
 #else /* SEPARATE_CODE_AND_RODATA */
     .ro . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".ro address is not aligned on a page boundary.");
+
         __RO_START__ = .;
         __TEXT_RESIDENT_START__ = .;
 
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index 923a554f..f12c1a5e 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 #include <bl1/bl1.h>
 #include <bl2/bl2.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/auth/crypto_mod.h>
@@ -41,6 +42,9 @@
 void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 		   u_register_t arg3)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup */
 	bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3);
 
@@ -63,6 +67,9 @@ void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 	       u_register_t arg3)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup */
 	bl2_early_platform_setup2(arg0, arg1, arg2, arg3);
 
@@ -92,7 +99,7 @@ void bl2_main(void)
 	PMF_CAPTURE_TIMESTAMP(bl_svc, BL2_ENTRY, PMF_CACHE_MAINT);
 #endif
 
-	NOTICE("BL2: %s\n", version_string);
+	NOTICE("BL2: %s\n", build_version_string);
 	NOTICE("BL2: %s\n", build_message);
 
 	/* Perform remaining generic architectural setup in S-EL1 */
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index 7b1a1010..ee6a0206 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -27,6 +27,9 @@ SECTIONS {
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".text address is not aligned on a page boundary.");
+
         __TEXT_START__ = .;
 
         *bl2u_entrypoint.o(.text*)
@@ -60,6 +63,9 @@ SECTIONS {
     } >RAM
 #else /* SEPARATE_CODE_AND_RODATA */
     .ro . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".ro address is not aligned on a page boundary.");
+
         __RO_START__ = .;
 
         *bl2u_entrypoint.o(.text*)
diff --git a/bl2u/bl2u.mk b/bl2u/bl2u.mk
index 9fe20f50..a4051ecc 100644
--- a/bl2u/bl2u.mk
+++ b/bl2u/bl2u.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -14,8 +14,8 @@ endif
 
 BL2U_DEFAULT_LINKER_SCRIPT_SOURCE := bl2u/bl2u.ld.S
 
-ifneq ($(findstring gcc,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
         BL2U_LDFLAGS	+=	-Wl,--sort-section=alignment
-else ifneq ($(findstring ld,$(notdir $(LD))),)
+else ifneq ($(filter llvm-lld gnu-ld,$($(ARCH)-ld-id)),)
         BL2U_LDFLAGS	+=	--sort-section=alignment
 endif
diff --git a/bl2u/bl2u_main.c b/bl2u/bl2u_main.c
index fcb73b9c..cd13defe 100644
--- a/bl2u/bl2u_main.c
+++ b/bl2u/bl2u_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <bl1/bl1.h>
 #include <bl2u/bl2u.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/console.h>
@@ -27,7 +28,7 @@
  ******************************************************************************/
 void bl2u_main(void)
 {
-	NOTICE("BL2U: %s\n", version_string);
+	NOTICE("BL2U: %s\n", build_version_string);
 	NOTICE("BL2U: %s\n", build_message);
 
 #if SCP_BL2U_BASE
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index ed483111..74238056 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -229,7 +229,6 @@ vector_entry sync_exception_aarch64
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch64
 
@@ -237,7 +236,6 @@ vector_entry irq_aarch64
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_interrupt_exception
 end_vector_entry irq_aarch64
 
@@ -245,7 +243,6 @@ vector_entry fiq_aarch64
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b 	handle_interrupt_exception
 end_vector_entry fiq_aarch64
 
@@ -258,7 +255,6 @@ vector_entry serror_aarch64
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_lower_el_async_ea
 #else
 	b	report_unhandled_exception
@@ -279,7 +275,6 @@ vector_entry sync_exception_aarch32
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	handle_sync_exception
 end_vector_entry sync_exception_aarch32
 
@@ -287,7 +282,6 @@ vector_entry irq_aarch32
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_interrupt_exception
 end_vector_entry irq_aarch32
 
@@ -295,7 +289,6 @@ vector_entry fiq_aarch32
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_interrupt_exception
 end_vector_entry fiq_aarch32
 
@@ -308,7 +301,6 @@ vector_entry serror_aarch32
 	save_x30
 	apply_at_speculative_wa
 	sync_and_handle_pending_serror
-	unmask_async_ea
 	b	handle_lower_el_async_ea
 #else
 	b	report_unhandled_exception
@@ -450,7 +442,7 @@ sync_handler64:
 	 *
 	 * handler = (base + off) + (index << log2(size))
 	 */
-	adr	x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
+	adr_l	x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
 	lsl	w10, w15, #RT_SVC_SIZE_LOG2
 	ldr	x15, [x11, w10, uxtw]
 
@@ -476,21 +468,33 @@ sysreg_handler64:
 	bl	handle_sysreg_trap
 	/*
 	 * returns:
-	 *   -1: unhandled trap, panic
+	 *   -1: unhandled trap, UNDEF injection into lower EL
 	 *    0: handled trap, return to the trapping instruction (repeating it)
 	 *    1: handled trap, return to the next instruction
 	 */
 
 	tst	w0, w0
-	b.mi	elx_panic	/* negative return value: panic */
-	b.eq	1f		/* zero: do not change ELR_EL3 */
+	b.mi	2f	/* negative: undefined exception injection */
 
-	/* advance the PC to continue after the instruction */
+	b.eq	1f	/* zero: do not change ELR_EL3 */
+	/* positive: advance the PC to continue after the instruction */
 	ldr	x1, [x19, #CTX_EL3STATE_OFFSET + CTX_ELR_EL3]
 	add	x1, x1, #4
 	str	x1, [x19, #CTX_EL3STATE_OFFSET + CTX_ELR_EL3]
 1:
 	b	el3_exit
+2:
+	/*
+	 * UNDEF injection to lower EL, the support is only provided for lower
+	 * EL in AArch64 mode, for AArch32 mode it will do elx_panic as before.
+	 */
+	mrs	x0, spsr_el3
+	tst	x0, #(SPSR_M_MASK << SPSR_M_SHIFT)
+	b.ne	elx_panic
+	/* Pass context pointer as an argument to inject_undef64 */
+	mov	x0, x19
+	bl	inject_undef64
+	b	el3_exit
 
 smc_unknown:
 	/*
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 773b41d3..867dedb9 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -19,6 +19,12 @@ MEMORY {
 #else /* SEPARATE_NOBITS_REGION */
 #   define NOBITS RAM
 #endif /* SEPARATE_NOBITS_REGION */
+
+#if SEPARATE_RWDATA_REGION
+    RAM_RW (rw): ORIGIN = BL31_RWDATA_BASE, LENGTH = BL31_RWDATA_LIMIT - BL31_RWDATA_BASE
+#else /* SEPARATE_RWDATA_REGION */
+#define RAM_RW RAM
+#endif /* SEPARATE_RWDATA_REGION */
 }
 
 #ifdef PLAT_EXTRA_LD_SCRIPT
@@ -37,6 +43,9 @@ SECTIONS {
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".text is not aligned on a page boundary.");
+
         __TEXT_START__ = .;
 
         *bl31_entrypoint.o(.text*)
@@ -71,6 +80,9 @@ SECTIONS {
     } >RAM
 #else /* SEPARATE_CODE_AND_RODATA */
     .ro . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".ro is not aligned on a page boundary.");
+
         __RO_START__ = .;
 
         *bl31_entrypoint.o(.text*)
@@ -130,10 +142,36 @@ SECTIONS {
     . = LOADADDR(.spm_shim_exceptions) + SIZEOF(.spm_shim_exceptions);
 #endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */
 
-    __RW_START__ = .;
+#if SEPARATE_RWDATA_REGION
+    . = BL31_RWDATA_BASE;
+    ASSERT(BL31_RWDATA_BASE == ALIGN(PAGE_SIZE),
+           "BL31_RWDATA_BASE address is not aligned on a page boundary.")
+
+    /*
+     * Define a linker symbol to mark the start of the RW memory area for this
+     * image.
+     */
+    __RW_START__ = . ;
+
+    DATA_SECTION >RAM_RW AT>RAM
+    __DATA_RAM_START__ = __DATA_START__;
+    __DATA_RAM_END__ = __DATA_END__;
+    __DATA_ROM_START__ = LOADADDR(.data);
+
+    . = ALIGN(PAGE_SIZE);
+    __RW_END__ = .;
+
+    RELA_SECTION >RAM
+#else /* SEPARATE_RWDATA_REGION */
+    /*
+     * Define a linker symbol to mark the start of the RW memory area for this
+     * image.
+     */
+    __RW_START__ = . ;
 
     DATA_SECTION >RAM
     RELA_SECTION >RAM
+#endif /* SEPARATE_RWDATA_REGION */
 
 #ifdef BL31_PROGBITS_LIMIT
     ASSERT(
@@ -145,7 +183,9 @@ SECTIONS {
 #if SEPARATE_NOBITS_REGION
     . = ALIGN(PAGE_SIZE);
 
+#if !SEPARATE_RWDATA_REGION
     __RW_END__ = .;
+#endif /* SEPARATE_RWDATA_REGION */
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
@@ -197,7 +237,13 @@ SECTIONS {
 
     ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
 #else /* SEPARATE_NOBITS_REGION */
+    /*
+     * Define a linker symbol to mark the end of the RW memory area for this
+     * image.
+     */
+#if !SEPARATE_RWDATA_REGION
     __RW_END__ = .;
+#endif /* SEPARATE_RWDATA_REGION */
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index f0776c4e..336ad2be 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -42,23 +42,33 @@ BL31_SOURCES		+=	bl31/bl31_main.c				\
 				bl31/bl31_context_mgmt.c			\
 				bl31/bl31_traps.c				\
 				common/runtime_svc.c				\
+				lib/cpus/errata_common.c			\
 				lib/cpus/aarch64/dsu_helpers.S			\
 				plat/common/aarch64/platform_mp_stack.S		\
 				services/arm_arch_svc/arm_arch_svc_setup.c	\
 				services/std_svc/std_svc_setup.c		\
+				lib/el3_runtime/simd_ctx.c			\
 				${PSCI_LIB_SOURCES}				\
 				${SPMD_SOURCES}					\
 				${SPM_MM_SOURCES}				\
 				${SPMC_SOURCES}					\
 				${SPM_SOURCES}
 
+VENDOR_EL3_SRCS		+=	services/el3/ven_el3_svc.c
+
 ifeq (${ENABLE_PMF}, 1)
-BL31_SOURCES		+=	lib/pmf/pmf_main.c
+BL31_SOURCES		+=	lib/pmf/pmf_main.c				\
+				${VENDOR_EL3_SRCS}
 endif
 
 include lib/debugfs/debugfs.mk
 ifeq (${USE_DEBUGFS},1)
-	BL31_SOURCES	+= $(DEBUGFS_SRCS)
+BL31_SOURCES		+=	${DEBUGFS_SRCS}					\
+				${VENDOR_EL3_SRCS}
+endif
+
+ifeq (${PLATFORM_REPORT_CTX_MEM_USE},1)
+BL31_SOURCES		+=	lib/el3_runtime/aarch64/context_debug.c
 endif
 
 ifeq (${EL3_EXCEPTION_HANDLING},1)
@@ -97,6 +107,14 @@ ifneq (${ENABLE_FEAT_AMU},0)
 BL31_SOURCES		+=	${AMU_SOURCES}
 endif
 
+ifneq (${ENABLE_FEAT_FGT2},0)
+BL31_SOURCES		+=	lib/extensions/fgt/fgt2.c
+endif
+
+ifneq (${ENABLE_FEAT_TCR2},0)
+BL31_SOURCES		+=	lib/extensions/tcr/tcr2.c
+endif
+
 ifeq (${ENABLE_MPMM},1)
 BL31_SOURCES		+=	${MPMM_SOURCES}
 endif
@@ -112,6 +130,10 @@ ifneq (${ENABLE_FEAT_MPAM},0)
 BL31_SOURCES		+=	lib/extensions/mpam/mpam.c
 endif
 
+ifneq (${ENABLE_FEAT_DEBUGV8P9},0)
+BL31_SOURCES		+=	lib/extensions/debug/debugv8p9.c
+endif
+
 ifneq (${ENABLE_TRBE_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/trbe/trbe.c
 endif
@@ -157,11 +179,15 @@ BL31_SOURCES		+=	services/std_svc/drtm/drtm_main.c		\
 				${MBEDTLS_SOURCES}
 endif
 
+ifeq ($(CROS_WIDEVINE_SMC),1)
+BL31_SOURCES		+=	services/oem/chromeos/widevine_smc_handlers.c
+endif
+
 BL31_DEFAULT_LINKER_SCRIPT_SOURCE := bl31/bl31.ld.S
 
-ifneq ($(findstring gcc,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
         BL31_LDFLAGS	+=	-Wl,--sort-section=alignment
-else ifneq ($(findstring ld,$(notdir $(LD))),)
+else ifneq ($(filter llvm-lld gnu-ld,$($(ARCH)-ld-id)),)
         BL31_LDFLAGS	+=	--sort-section=alignment
 endif
 
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 925c6a69..83be0f6f 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,11 +13,13 @@
 #include <bl31/bl31.h>
 #include <bl31/ehf.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <common/feat_detect.h>
 #include <common/runtime_svc.h>
 #include <drivers/console.h>
 #include <lib/bootmarker_capture.h>
+#include <lib/el3_runtime/context_debug.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/pmf/pmf.h>
 #include <lib/runtime_instr.h>
@@ -82,7 +84,7 @@ uintptr_t get_arm_std_svc_args(unsigned int svc_mask)
 /*******************************************************************************
  * Simple function to initialise all BL31 helper libraries.
  ******************************************************************************/
-void __init bl31_lib_init(void)
+static void __init bl31_lib_init(void)
 {
 	cm_init();
 }
@@ -93,6 +95,9 @@ void __init bl31_lib_init(void)
 void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 		u_register_t arg3)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup */
 	bl31_early_platform_setup2(arg0, arg1, arg2, arg3);
 
@@ -106,6 +111,9 @@ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
 	 */
 	assert(is_armv8_3_pauth_present());
 #endif /* CTX_INCLUDE_PAUTH_REGS */
+
+	/* Prints context_memory allocated for all the security states */
+	report_ctx_memory_usage();
 }
 
 /*******************************************************************************
@@ -124,7 +132,7 @@ void bl31_main(void)
 	/* Init per-world context registers for non-secure world */
 	manage_extensions_nonsecure_per_world();
 
-	NOTICE("BL31: %s\n", version_string);
+	NOTICE("BL31: %s\n", build_version_string);
 	NOTICE("BL31: %s\n", build_message);
 
 #if FEATURE_DETECTION
@@ -207,8 +215,6 @@ void bl31_main(void)
 	 */
 	bl31_prepare_next_image_entry();
 
-	console_flush();
-
 	/*
 	 * Perform any platform specific runtime setup prior to cold boot exit
 	 * from BL31
@@ -216,9 +222,12 @@ void bl31_main(void)
 	bl31_plat_runtime_setup();
 
 #if ENABLE_RUNTIME_INSTRUMENTATION
-	PMF_CAPTURE_TIMESTAMP(bl_svc, BL31_EXIT, PMF_CACHE_MAINT);
 	console_flush();
+	PMF_CAPTURE_TIMESTAMP(bl_svc, BL31_EXIT, PMF_CACHE_MAINT);
 #endif
+
+	console_flush();
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*******************************************************************************
diff --git a/bl31/bl31_traps.c b/bl31/bl31_traps.c
index 2cfe14a8..984fdaa4 100644
--- a/bl31/bl31_traps.c
+++ b/bl31/bl31_traps.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -7,8 +7,11 @@
  * Dispatch synchronous system register traps from lower ELs.
  */
 
+#include <arch_features.h>
+#include <arch_helpers.h>
 #include <bl31/sync_handle.h>
 #include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
 
 int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx)
 {
@@ -28,3 +31,213 @@ int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx)
 
 	return TRAP_RET_UNHANDLED;
 }
+
+static bool is_tge_enabled(void)
+{
+	u_register_t hcr_el2 = read_hcr_el2();
+
+	return ((is_feat_vhe_present()) && ((hcr_el2 & HCR_TGE_BIT) != 0U));
+}
+
+/*
+ * This function is to ensure that undef injection does not happen into
+ * non-existent S-EL2. This could happen when trap happens from S-EL{1,0}
+ * and non-secure world is running with TGE bit set, considering EL3 does
+ * not save/restore EL2 registers if only one world has EL2 enabled.
+ * So reading hcr_el2.TGE would give NS world value.
+ */
+static bool is_secure_trap_without_sel2(u_register_t scr)
+{
+	return ((scr & (SCR_NS_BIT | SCR_EEL2_BIT)) == 0);
+}
+
+static unsigned int target_el(unsigned int from_el, u_register_t scr)
+{
+	if (from_el > MODE_EL1) {
+		return from_el;
+	} else if (is_tge_enabled() && !is_secure_trap_without_sel2(scr)) {
+		return MODE_EL2;
+	} else {
+		return MODE_EL1;
+	}
+}
+
+static u_register_t get_elr_el3(u_register_t spsr_el3, u_register_t vbar, unsigned int target_el)
+{
+	unsigned int outgoing_el = GET_EL(spsr_el3);
+	u_register_t elr_el3 = 0;
+
+	if (outgoing_el == target_el) {
+		/*
+		 * Target EL is either EL1 or EL2, lsb can tell us the SPsel
+		 *  Thread mode  : 0
+		 *  Handler mode : 1
+		 */
+		if ((spsr_el3 & (MODE_SP_MASK << MODE_SP_SHIFT)) == MODE_SP_ELX) {
+			elr_el3 = vbar + CURRENT_EL_SPX;
+		} else {
+			elr_el3 = vbar + CURRENT_EL_SP0;
+		}
+	} else {
+		/* Vector address for Lower EL using Aarch64 */
+		elr_el3 = vbar + LOWER_EL_AARCH64;
+	}
+
+	return elr_el3;
+}
+
+/*
+ * Explicitly create all bits of SPSR to get PSTATE at exception return.
+ *
+ * The code is based on "Aarch64.exceptions.takeexception" described in
+ * DDI0602 revision 2023-06.
+ * "https://developer.arm.com/documentation/ddi0602/2023-06/Shared-Pseudocode/
+ * aarch64-exceptions-takeexception"
+ *
+ * NOTE: This piece of code must be reviewed every release to ensure that
+ * we keep up with new ARCH features which introduces a new SPSR bit.
+ *
+ * TF-A 2.12 release review
+ * The latest version available is 2024-09, which has two extra features which
+ * impacts generation of SPSR, since these features are not implemented in TF-A
+ * at the time of release, just log the feature names here to be taken up when
+ * feature support is introduced.
+ *  - FEAT_PAuth_LR (2023 extension)
+ *  - FEAT_UINJ (2024 extension)
+ */
+u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el)
+{
+	u_register_t new_spsr = 0;
+	u_register_t sctlr;
+
+	/* Set M bits for target EL in AArch64 mode, also get sctlr */
+	if (target_el == MODE_EL2) {
+		sctlr = read_sctlr_el2();
+		new_spsr |= (SPSR_M_AARCH64 << SPSR_M_SHIFT) | SPSR_M_EL2H;
+	} else {
+		sctlr = read_sctlr_el1();
+		new_spsr |= (SPSR_M_AARCH64 << SPSR_M_SHIFT) | SPSR_M_EL1H;
+	}
+
+	/* Mask all exceptions, update DAIF bits */
+	new_spsr |= SPSR_DAIF_MASK << SPSR_DAIF_SHIFT;
+
+	/* If FEAT_BTI is present, clear BTYPE bits */
+	new_spsr |= old_spsr & (SPSR_BTYPE_MASK_AARCH64 << SPSR_BTYPE_SHIFT_AARCH64);
+	if (is_feat_bti_present()) {
+		new_spsr &= ~(SPSR_BTYPE_MASK_AARCH64 << SPSR_BTYPE_SHIFT_AARCH64);
+	}
+
+	/* If SSBS is implemented, take the value from SCTLR.DSSBS */
+	new_spsr |= old_spsr & SPSR_SSBS_BIT_AARCH64;
+	if (is_feat_ssbs_present()) {
+		if ((sctlr & SCTLR_DSSBS_BIT) != 0U) {
+			new_spsr |= SPSR_SSBS_BIT_AARCH64;
+		} else {
+			new_spsr &= ~SPSR_SSBS_BIT_AARCH64;
+		}
+	}
+
+	/* If FEAT_NMI is implemented, ALLINT = !(SCTLR.SPINTMASK) */
+	new_spsr |= old_spsr & SPSR_ALLINT_BIT_AARCH64;
+	if (is_feat_nmi_present()) {
+		if ((sctlr & SCTLR_SPINTMASK_BIT) != 0U) {
+			new_spsr &= ~SPSR_ALLINT_BIT_AARCH64;
+		} else {
+			new_spsr |= SPSR_ALLINT_BIT_AARCH64;
+		}
+	}
+
+	/* Clear PSTATE.IL bit explicitly */
+	new_spsr &= ~SPSR_IL_BIT;
+
+	/* Clear PSTATE.SS bit explicitly */
+	new_spsr &= ~SPSR_SS_BIT;
+
+	/* Update PSTATE.PAN bit */
+	new_spsr |= old_spsr & SPSR_PAN_BIT;
+	if (is_feat_pan_present() &&
+	    ((target_el == MODE_EL1) || ((target_el == MODE_EL2) && is_tge_enabled())) &&
+	    ((sctlr & SCTLR_SPAN_BIT) == 0U)) {
+	    new_spsr |= SPSR_PAN_BIT;
+	}
+
+	/* Clear UAO bit if FEAT_UAO is present */
+	new_spsr |= old_spsr & SPSR_UAO_BIT_AARCH64;
+	if (is_feat_uao_present()) {
+		new_spsr &= ~SPSR_UAO_BIT_AARCH64;
+	}
+
+	/* DIT bits are unchanged */
+	new_spsr |= old_spsr & SPSR_DIT_BIT;
+
+	/* If FEAT_MTE2 is implemented mask tag faults by setting TCO bit */
+	new_spsr |= old_spsr & SPSR_TCO_BIT_AARCH64;
+	if (is_feat_mte2_present()) {
+		new_spsr |= SPSR_TCO_BIT_AARCH64;
+	}
+
+	/* NZCV bits are unchanged */
+	new_spsr |= old_spsr & SPSR_NZCV;
+
+	/* If FEAT_EBEP is present set PM bit */
+	new_spsr |= old_spsr & SPSR_PM_BIT_AARCH64;
+	if (is_feat_ebep_present()) {
+		new_spsr |= SPSR_PM_BIT_AARCH64;
+	}
+
+	/* If FEAT_SEBEP is present clear PPEND bit */
+	new_spsr |= old_spsr & SPSR_PPEND_BIT;
+	if (is_feat_sebep_present()) {
+		new_spsr &= ~SPSR_PPEND_BIT;
+	}
+
+	/* If FEAT_GCS is present, update EXLOCK bit */
+	new_spsr |= old_spsr & SPSR_EXLOCK_BIT_AARCH64;
+	if (is_feat_gcs_present()) {
+		u_register_t gcscr;
+		if (target_el == MODE_EL2) {
+			gcscr = read_gcscr_el2();
+		} else {
+			gcscr = read_gcscr_el1();
+		}
+		new_spsr |= (gcscr & GCSCR_EXLOCK_EN_BIT) ? SPSR_EXLOCK_BIT_AARCH64 : 0;
+	}
+
+	return new_spsr;
+}
+
+/*
+ * Handler for injecting Undefined exception to lower EL which is caused by
+ * lower EL accessing system registers of which (old)EL3 firmware is unaware.
+ *
+ * This is a safety net to avoid EL3 panics caused by system register access
+ * that triggers an exception syndrome EC=0x18.
+ */
+void inject_undef64(cpu_context_t *ctx)
+{
+	u_register_t esr = (EC_UNKNOWN << ESR_EC_SHIFT) | ESR_IL_BIT;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t elr_el3 = read_ctx_reg(state, CTX_ELR_EL3);
+	u_register_t old_spsr = read_ctx_reg(state, CTX_SPSR_EL3);
+	u_register_t scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
+	u_register_t new_spsr = 0;
+	unsigned int to_el = target_el(GET_EL(old_spsr), scr_el3);
+
+	if (to_el == MODE_EL2) {
+		write_elr_el2(elr_el3);
+		elr_el3 = get_elr_el3(old_spsr, read_vbar_el2(), to_el);
+		write_esr_el2(esr);
+		write_spsr_el2(old_spsr);
+	} else {
+		write_elr_el1(elr_el3);
+		elr_el3 = get_elr_el3(old_spsr, read_vbar_el1(), to_el);
+		write_esr_el1(esr);
+		write_spsr_el1(old_spsr);
+	}
+
+	new_spsr = create_spsr(old_spsr, to_el);
+
+	write_ctx_reg(state, CTX_SPSR_EL3, new_spsr);
+	write_ctx_reg(state, CTX_ELR_EL3, elr_el3);
+}
diff --git a/bl31/ehf.c b/bl31/ehf.c
index 6f3d9412..3a14635c 100644
--- a/bl31/ehf.c
+++ b/bl31/ehf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -203,10 +203,20 @@ void ehf_deactivate_priority(unsigned int priority)
 	 * one stashed earlier if there are no more to deactivate.
 	 */
 	cur_pri_idx = get_pe_highest_active_idx(pe_data);
-	if (cur_pri_idx == EHF_INVALID_IDX)
+
+#if GIC600_ERRATA_WA_2384374
+	if (cur_pri_idx == EHF_INVALID_IDX) {
+		old_mask = plat_ic_deactivate_priority(pe_data->init_pri_mask);
+	} else {
+		old_mask = plat_ic_deactivate_priority(priority);
+	}
+#else
+	if (cur_pri_idx == EHF_INVALID_IDX) {
 		old_mask = plat_ic_set_priority_mask(pe_data->init_pri_mask);
-	else
+	} else {
 		old_mask = plat_ic_set_priority_mask(priority);
+	}
+#endif
 
 	if (old_mask > priority) {
 		ERROR("Deactivation priority (0x%x) lower than Priority Mask (0x%x)\n",
@@ -478,13 +488,10 @@ void __init ehf_init(void)
 	/* Route EL3 interrupts when in Non-secure. */
 	set_interrupt_rm_flag(flags, NON_SECURE);
 
-	/*
-	 * Route EL3 interrupts when in secure, only when SPMC is not present
-	 * in S-EL2.
-	 */
-#if !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1))
+	/* Route EL3 interrupts only when SPM_MM present in secure. */
+#if SPM_MM
 	set_interrupt_rm_flag(flags, SECURE);
-#endif /* !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)) */
+#endif
 
 	/* Register handler for EL3 interrupts */
 	ret = register_interrupt_type_handler(INTR_TYPE_EL3,
diff --git a/bl31/interrupt_mgmt.c b/bl31/interrupt_mgmt.c
index 68c7f10a..a2b2c068 100644
--- a/bl31/interrupt_mgmt.c
+++ b/bl31/interrupt_mgmt.c
@@ -34,7 +34,7 @@
  *
  *           All other bits are reserved and SBZ.
  ******************************************************************************/
-typedef struct intr_type_desc {
+typedef struct {
 	interrupt_type_handler_t handler;
 	u_register_t scr_el3[2];
 	uint32_t flags;
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index 693dd4b8..ba9d90d4 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -118,8 +118,7 @@ func sp_min_entrypoint
 	mov	r1, r10
 	mov	r2, r11
 	mov	r3, r12
-	bl	sp_min_early_platform_setup2
-	bl	sp_min_plat_arch_setup
+	bl	sp_min_setup
 
 	/* Jump to the main function */
 	bl	sp_min_main
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index dd819733..a2d9b7bf 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -29,6 +29,9 @@ SECTIONS {
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".text address is not aligned on a page boundary.");
+
         __TEXT_START__ = .;
 
         *entrypoint.o(.text*)
@@ -67,6 +70,9 @@ SECTIONS {
     } >RAM
 #else /* SEPARATE_CODE_AND_RODATA */
     .ro . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".ro address is not aligned on a page boundary.");
+
         __RO_START__ = .;
 
         *entrypoint.o(.text*)
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 065468c5..b1f4343f 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -13,16 +13,17 @@ include lib/psci/psci_lib.mk
 
 INCLUDES		+=	-Iinclude/bl32/sp_min
 
-BL32_SOURCES		+=	bl32/sp_min/sp_min_main.c		\
-				bl32/sp_min/aarch32/entrypoint.S	\
-				common/runtime_svc.c			\
-				plat/common/aarch32/plat_sp_min_common.c\
+BL32_SOURCES		+=	bl32/sp_min/sp_min_main.c			\
+				bl32/sp_min/aarch32/entrypoint.S		\
+				common/runtime_svc.c				\
+				plat/common/aarch32/plat_sp_min_common.c	\
 				services/arm_arch_svc/arm_arch_svc_setup.c	\
-				services/std_svc/std_svc_setup.c	\
+				services/std_svc/std_svc_setup.c		\
 				${PSCI_LIB_SOURCES}
 
 ifeq (${ENABLE_PMF}, 1)
-BL32_SOURCES		+=	lib/pmf/pmf_main.c
+BL32_SOURCES		+=	services/el3/ven_el3_svc.c			\
+				lib/pmf/pmf_main.c
 endif
 
 ifneq (${ENABLE_FEAT_AMU},0)
@@ -57,9 +58,9 @@ endif
 
 BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/sp_min/sp_min.ld.S
 
-ifneq ($(findstring gcc,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
         BL32_LDFLAGS	+=	-Wl,--sort-section=alignment
-else ifneq ($(findstring ld,$(notdir $(LD))),)
+else ifneq ($(filter llvm-lld gnu-ld,$($(ARCH)-ld-id)),)
         BL32_LDFLAGS	+=	--sort-section=alignment
 endif
 
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index 26cf2079..a26910cb 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <context.h>
@@ -169,13 +170,27 @@ uintptr_t get_arm_std_svc_args(unsigned int svc_mask)
 	return (uintptr_t)&psci_args;
 }
 
+/******************************************************************************
+ * The SP_MIN setup function. Calls platforms init functions
+ *****************************************************************************/
+void sp_min_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
+		  u_register_t arg3)
+{
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
+	/* Perform early platform-specific setup */
+	sp_min_early_platform_setup2(arg0, arg1, arg2, arg3);
+	sp_min_plat_arch_setup();
+}
+
 /******************************************************************************
  * The SP_MIN main function. Do the platform and PSCI Library setup. Also
  * initialize the runtime service framework.
  *****************************************************************************/
 void sp_min_main(void)
 {
-	NOTICE("SP_MIN: %s\n", version_string);
+	NOTICE("SP_MIN: %s\n", build_version_string);
 	NOTICE("SP_MIN: %s\n", build_message);
 
 	/* Perform the SP_MIN platform setup */
diff --git a/bl32/sp_min/sp_min_private.h b/bl32/sp_min/sp_min_private.h
index 628581a4..9c6b5fb2 100644
--- a/bl32/sp_min/sp_min_private.h
+++ b/bl32/sp_min/sp_min_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,10 @@
 #ifndef SP_MIN_PRIVATE_H
 #define SP_MIN_PRIVATE_H
 
+#include <stdint.h>
+
+void sp_min_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
+		  u_register_t arg3);
 void sp_min_main(void);
 void sp_min_warm_boot(void);
 void sp_min_fiq(void);
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index 22bf11da..5116b20a 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -25,6 +25,9 @@ SECTIONS {
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".text address is not aligned on a page boundary.");
+
         __TEXT_START__ = .;
 
         *tsp_entrypoint.o(.text*)
@@ -51,6 +54,9 @@ SECTIONS {
     } >RAM
 #else /* SEPARATE_CODE_AND_RODATA */
     .ro . : {
+        ASSERT(. == ALIGN(PAGE_SIZE),
+        ".ro address is not aligned on a page boundary.");
+
         __RO_START__ = .;
 
         *tsp_entrypoint.o(.text*)
diff --git a/bl32/tsp/tsp.mk b/bl32/tsp/tsp.mk
index 4c181311..696cdb2c 100644
--- a/bl32/tsp/tsp.mk
+++ b/bl32/tsp/tsp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,7 +7,7 @@
 INCLUDES		+=	-Iinclude/bl32/tsp
 
 ifeq (${SPMC_AT_EL3},1)
-   BL32_SOURCES            +=      bl32/tsp/tsp_ffa_main.c                    \
+   BL32_SOURCES            +=      bl32/tsp/tsp_ffa_main.c		\
 				   bl32/tsp/ffa_helpers.c
 else
    BL32_SOURCES            +=      bl32/tsp/tsp_main.c
@@ -19,14 +19,15 @@ BL32_SOURCES		+=	bl32/tsp/aarch64/tsp_entrypoint.S	\
 				bl32/tsp/tsp_interrupt.c		\
 				bl32/tsp/tsp_timer.c			\
 				bl32/tsp/tsp_common.c			\
+				bl32/tsp/tsp_context.c			\
 				common/aarch64/early_exceptions.S	\
 				lib/locks/exclusive/aarch64/spinlock.S
 
 BL32_DEFAULT_LINKER_SCRIPT_SOURCE := bl32/tsp/tsp.ld.S
 
-ifneq ($(findstring gcc,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
         BL32_LDFLAGS	+=	-Wl,--sort-section=alignment
-else ifneq ($(findstring ld,$(notdir $(LD))),)
+else ifneq ($(filter llvm-lld gnu-ld,$($(ARCH)-ld-id)),)
         BL32_LDFLAGS	+=	--sort-section=alignment
 endif
 
diff --git a/bl32/tsp/tsp_common.c b/bl32/tsp/tsp_common.c
index 908b4ff0..3a6c9d97 100644
--- a/bl32/tsp/tsp_common.c
+++ b/bl32/tsp/tsp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -66,6 +66,9 @@ smc_args_t *set_smc_args(uint64_t arg0,
  ******************************************************************************/
 void tsp_setup(void)
 {
+	/* Enable early console if EARLY_CONSOLE flag is enabled */
+	plat_setup_early_console();
+
 	/* Perform early platform-specific setup. */
 	tsp_early_platform_setup();
 
diff --git a/bl32/tsp/tsp_context.c b/bl32/tsp/tsp_context.c
new file mode 100644
index 00000000..6307f72c
--- /dev/null
+++ b/bl32/tsp/tsp_context.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <bl32/tsp/tsp_el1_context.h>
+#include <common/debug.h>
+
+#define DUMMY_CTX_VALUE		ULL(0xffffffff)
+#define DUMMY_CTX_TCR_VALUE	ULL(0xffff0000)
+#define DUMMY_CTX_TRF_VALUE	ULL(0xf)
+#define DUMMY_CTX_GCS_VALUE	ULL(0xffff0000)
+#define DEFAULT_CTX_VALUE	ULL(0x0)
+
+/**
+ * -------------------------------------------------------
+ * Private Helper functions required to access and modify
+ * EL1 context registers at S-EL1.
+ * -------------------------------------------------------
+ */
+static void modify_el1_common_regs(uint64_t cm_value)
+{
+	/**
+	 * NOTE: Few EL1 registers "SCTLR_EL1, SPSR_EL1, ELR_EL1" are
+	 *       left out consciously as those are important registers for
+	 *       execution in each world and overwriting them with dummy value
+	 *       would cause unintended crash while executing the test.
+	 */
+	write_tcr_el1(cm_value);
+	write_cpacr_el1(cm_value);
+	write_csselr_el1(cm_value);
+	write_esr_el1(cm_value);
+	write_ttbr0_el1(cm_value);
+	write_ttbr1_el1(cm_value);
+	write_mair_el1(cm_value);
+	write_amair_el1(cm_value);
+	write_actlr_el1(cm_value);
+	write_tpidr_el1(cm_value);
+	write_tpidr_el0(cm_value);
+	write_tpidrro_el0(cm_value);
+	write_par_el1(cm_value);
+	write_far_el1(cm_value);
+	write_afsr0_el1(cm_value);
+	write_afsr1_el1(cm_value);
+	write_contextidr_el1(cm_value);
+	write_vbar_el1(cm_value);
+	write_mdccint_el1(cm_value);
+	write_mdscr_el1(cm_value);
+}
+
+static void modify_el1_mte2_regs(uint64_t mte_value)
+{
+	if (is_feat_mte2_supported()) {
+		write_tfsre0_el1(mte_value);
+		write_tfsr_el1(mte_value);
+		write_rgsr_el1(mte_value);
+		write_gcr_el1(mte_value);
+	}
+}
+
+static void modify_el1_ras_regs(uint64_t ras_value)
+{
+	if (is_feat_ras_supported()) {
+		write_disr_el1(ras_value);
+	}
+}
+
+static void modify_el1_s1pie_regs(uint64_t s1pie_value)
+{
+	if (is_feat_s1pie_supported()) {
+		write_pire0_el1(s1pie_value);
+		write_pir_el1(s1pie_value);
+	}
+}
+
+static void modify_el1_s1poe_regs(uint64_t s1poe_value)
+{
+	if (is_feat_s1poe_supported()) {
+		write_por_el1(s1poe_value);
+	}
+}
+
+static void modify_el1_s2poe_regs(uint64_t s2poe_value)
+{
+	if (is_feat_s2poe_supported()) {
+		write_s2por_el1(s2poe_value);
+	}
+}
+
+static void modify_el1_tcr2_regs(uint64_t tcr_value)
+{
+	if (is_feat_tcr2_supported()) {
+		write_tcr2_el1(tcr_value & DUMMY_CTX_TCR_VALUE);
+	}
+}
+
+static void modify_el1_trf_regs(uint64_t trf_value)
+{
+	if (is_feat_trf_supported()) {
+		write_trfcr_el1(trf_value & DUMMY_CTX_TRF_VALUE);
+	}
+}
+
+static void modify_el1_gcs_regs(uint64_t gcs_value)
+{
+	if (is_feat_gcs_supported()) {
+		write_gcscr_el1(gcs_value & DUMMY_CTX_GCS_VALUE);
+		write_gcscre0_el1(gcs_value & DUMMY_CTX_GCS_VALUE);
+		write_gcspr_el1(gcs_value & DUMMY_CTX_GCS_VALUE);
+		write_gcspr_el0(gcs_value & DUMMY_CTX_GCS_VALUE);
+	}
+}
+
+/**
+ * -----------------------------------------------------
+ * Public API, to modify/restore EL1 ctx registers:
+ * -----------------------------------------------------
+ */
+void modify_el1_ctx_regs(const bool modify_option)
+{
+	uint64_t mask;
+
+	if (modify_option == TSP_CORRUPT_EL1_REGS) {
+		VERBOSE("TSP(S-EL1): Corrupt EL1 Registers with Dummy values\n");
+		mask = DUMMY_CTX_VALUE;
+	} else {
+		VERBOSE("TSP(S-EL1): Restore EL1 Registers with Default values\n");
+		mask = DEFAULT_CTX_VALUE;
+	}
+
+	modify_el1_common_regs(mask);
+	modify_el1_mte2_regs(mask);
+	modify_el1_ras_regs(mask);
+	modify_el1_s1pie_regs(mask);
+	modify_el1_s1poe_regs(mask);
+	modify_el1_s2poe_regs(mask);
+	modify_el1_tcr2_regs(mask);
+	modify_el1_trf_regs(mask);
+	modify_el1_gcs_regs(mask);
+}
diff --git a/bl32/tsp/tsp_ffa_main.c b/bl32/tsp/tsp_ffa_main.c
index 1c8c68f0..8273060b 100644
--- a/bl32/tsp/tsp_ffa_main.c
+++ b/bl32/tsp/tsp_ffa_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <arch_helpers.h>
 #include <bl32/tsp/tsp.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include "ffa_helpers.h"
 #include <lib/psci/psci.h>
@@ -554,7 +555,7 @@ uint64_t tsp_main(void)
 {
 	smc_args_t smc_args = {0};
 
-	NOTICE("TSP: %s\n", version_string);
+	NOTICE("TSP: %s\n", build_version_string);
 	NOTICE("TSP: %s\n", build_message);
 	INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE);
 	INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE);
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index 1ab2260a..8c6b2edf 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,9 @@
 #include <arch_features.h>
 #include <arch_helpers.h>
 #include <bl32/tsp/tsp.h>
+#include <bl32/tsp/tsp_el1_context.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <lib/spinlock.h>
 #include <plat/common/platform.h>
@@ -27,7 +29,7 @@
  ******************************************************************************/
 uint64_t tsp_main(void)
 {
-	NOTICE("TSP: %s\n", version_string);
+	NOTICE("TSP: %s\n", build_version_string);
 	NOTICE("TSP: %s\n", build_message);
 	INFO("TSP: Total memory base : 0x%lx\n", (unsigned long) BL32_BASE);
 	INFO("TSP: Total memory size : 0x%lx bytes\n", BL32_TOTAL_SIZE);
@@ -238,13 +240,13 @@ smc_args_t *tsp_smc_handler(uint64_t func,
 	service_arg0 = (uint64_t)service_args;
 	service_arg1 = (uint64_t)(service_args >> 64U);
 
-#if CTX_INCLUDE_MTE_REGS
 	/*
-	 * Write a dummy value to an MTE register, to simulate usage in the
+	 * Write a dummy value to an MTE2 register, to simulate usage in the
 	 * secure world
 	 */
-	write_gcr_el1(0x99);
-#endif
+	if (is_feat_mte2_supported()) {
+		write_gcr_el1(0x99);
+	}
 
 	/* Determine the function to perform based on the function ID */
 	switch (TSP_BARE_FID(func)) {
@@ -277,6 +279,17 @@ smc_args_t *tsp_smc_handler(uint64_t func,
 		/* Toggle the dit bit */
 		write_dit(service_arg0 != 0U ? 0 : DIT_BIT);
 		break;
+	case TSP_MODIFY_EL1_CTX:
+		/*
+		 * Write dummy values to EL1 context registers, to simulate
+		 * their usage in the secure world.
+		 */
+		if (arg1 == TSP_CORRUPT_EL1_REGS) {
+			modify_el1_ctx_regs(TSP_CORRUPT_EL1_REGS);
+		} else {
+			modify_el1_ctx_regs(TSP_RESTORE_EL1_REGS);
+		}
+		break;
 	default:
 		break;
 	}
diff --git a/changelog.yaml b/changelog.yaml
index 1467ab4c..9d1c3a98 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -104,9 +104,15 @@ subsections:
       - title: Extended Translation Control Register (FEAT_TCR2).
         scope: tcr2
 
+      - title: Fine-grained Traps 2 (FEAT_FGT2).
+        scope: fgt2
+
       - title: CPU feature / ID register handling in general
         scope: cpufeat
 
+      - title: Debug Extension (FEAT_Debugv8p9)
+        scope: debugv8p9
+
       - title: Guarded Control Stack (FEAT_GCS)
         scope: gcs
 
@@ -116,8 +122,11 @@ subsections:
       - title: Memory Partitioning and Monitoring (MPAM) Extension (FEAT_MPAM)
         scope: mpam
 
-      - title: Memory Tagging Extension
-        scope: mte
+      - title: Memory Tagging Extension2
+        scope: mte2
+
+        deprecated:
+          - mte
 
       - title: Pointer Authentication Extension
         scope: pauth
@@ -149,11 +158,27 @@ subsections:
       - title: Self-hosted Trace Extensions (FEAT_TRF)
         scope: trf
 
+      - title: DynamIQ Shared Unit (DSU)
+        scope: dsu
+
+      - title: Extension to SCTLR_ELx (FEAT_SCTLR2)
+        scope: sctlr2
+
+        deprecated:
+          - feat_sctlr2
+
+      - title: 128-bit Translation Tables (FEAT_D128)
+        scope: d128
+
+      - title: Translation Hardening Extension (FEAT_THE)
+        scope: the
+
   - title: Platforms
     scope: platforms
 
     deprecated:
       - plat/common
+      - plat
 
     subsections:
       - title: Allwinner
@@ -169,6 +194,9 @@ subsections:
           - plat/arm
 
         subsections:
+          - title: Common
+            scope: common
+
           - title: A5DS
             scope: a5ds
 
@@ -212,25 +240,37 @@ subsections:
           - title: N1SDP
             scope: n1sdp
 
-          - title: RD
-            scope: rd
+          - title: Neoverse-RD
+            scope: neoverse-rd
 
             subsections:
-              - title: RD-N1 Edge
+              - title: SGI-575
+                scope: sgi575
+
+              - title: RD-E1-Edge
+                scope: rde1edge
+
+              - title: RD-N1-Edge
                 scope: rdn1edge
 
+              - title: RD-V1
+                scope: rdv1
+
+              - title: RD-V1-MC
+                scope: rdv1mc
+
               - title: RD-N2
                 scope: rdn2
 
+              - title: RD-V3
+                scope: rdv3
+
                 deprecated:
                   - board/rdn2
-
-          - title: SGI
-            scope: sgi
+                  - rdfremont
 
             deprecated:
-              - plat/sgi
-              - plat/arm/sgi
+              - neoverse
 
           - title: TC
             scope: tc
@@ -248,6 +288,16 @@ subsections:
           - title: Corstone-1000
             scope: corstone-1000
 
+            deprecated:
+              - corstone1000
+
+          - title: Automotive RD
+            scope: automotive_rd
+
+            subsections:
+              - title: RD-1 AE
+                scope: rd1ae
+
       - title: Aspeed
         scope: aspeed
 
@@ -271,6 +321,9 @@ subsections:
           - title: HiKey960
             scope: hikey960
 
+          - title: Poplar
+            scope: poplar
+
       - title: Intel
         scope: intel
 
@@ -413,6 +466,9 @@ subsections:
               - title: i.MX 8
                 scope: imx8
 
+              - title: i.MX 8ULP
+                scope: imx8ulp
+
               - title: i.MX 9
                 scope: imx9
 
@@ -496,6 +552,13 @@ subsections:
                   - title: LS1088AQDS
                     scope: ls1088aqds
 
+          - title: S32G274A
+            scope: s32g274a
+
+            subsections:
+              - title: S32G274ARDB
+                scope: s32g274ardb
+
       - title: QEMU
         scope: qemu
 
@@ -541,6 +604,9 @@ subsections:
           - title: Raspberry Pi 4
             scope: rpi4
 
+          - title: Raspberry Pi 5
+            scope: rpi5
+
       - title: Renesas
         scope: renesas
 
@@ -569,6 +635,12 @@ subsections:
               - rockchip/rk3399
               - rk3399/suspend
 
+          - title: RK3328
+            scope: rk3328
+
+          - title: RK3588
+            scope: rk3588
+
       - title: Socionext
         scope: socionext
 
@@ -602,6 +674,10 @@ subsections:
           - title: STM32MP2
             scope: stm32mp2
 
+            subsections:
+              - title: STM32MP25
+                scope: stm32mp25
+
       - title: Texas Instruments
         scope: ti
 
@@ -630,12 +706,11 @@ subsections:
               - plat/xilinx/versal
               - plat/versal
 
-            subsections:
-             - title: Versal NET
-               scope: versal-net
+          - title: Versal NET
+            scope: versal-net
 
-               deprecated:
-                 - versal_net
+            deprecated:
+              - versal_net
 
           - title: ZynqMP
             scope: zynqmp
@@ -644,6 +719,13 @@ subsections:
               - plat/zynqmp
               - plat/xilinx/zynqmp
 
+      - title: AMD
+        scope: amd
+
+        subsections:
+          - title: Versal Gen 2
+            scope: versal2
+
       - title: Nuvoton
         scope: nuvoton
 
@@ -677,6 +759,9 @@ subsections:
   - title: Services
     scope: services
 
+    deprecated:
+      - std_svc
+
     subsections:
       - title: FF-A
         scope: ff-a
@@ -731,6 +816,31 @@ subsections:
         deprecated:
           - errata_abi
 
+      - title: ChromeOS
+        scope: cros
+
+      - title: Secure Payload Dispatcher
+        scope: spd
+
+        subsections:
+          - title: OP-TEE
+            scope: optee
+
+            deprecated:
+              - lib/optee
+
+          - title: ProvenCore
+            scope: pncd
+
+          - title: Trusted Little Kernel
+            scope: tlkd
+
+          - title: Trusty
+            scope: trusty
+
+          - title: TSP
+            scope: tspd
+
   - title: Libraries
     scope: lib
 
@@ -756,21 +866,21 @@ subsections:
           - title: RAS
             scope: ras
 
+          - title: SIMD
+            scope: simd
+
       - title: FCONF
         scope: fconf
 
       - title: MPMM
         scope: mpmm
 
-      - title: OP-TEE
-        scope: optee
-
-        deprecated:
-          - lib/optee
-
       - title: PSCI
         scope: psci
 
+      - title: ROMlib
+        scope: romlib
+
       - title: GPT
         scope: gpt
 
@@ -795,6 +905,9 @@ subsections:
         deprecated:
           - lib/psa
 
+      - title: DICE Protection Environment
+        scope: dice
+
       - title: Context Management
         scope: context-mgmt
 
@@ -807,6 +920,9 @@ subsections:
       - title: Firmware Handoff
         scope: handoff
 
+      - title: Exception Handling Framework (EHF)
+        scope: ehf
+
   - title: Drivers
 
     subsections:
@@ -832,6 +948,9 @@ subsections:
       - title: Console
         scope: console
 
+      - title: Delay Timer
+        scope: delay-timer
+
       - title: Generic Clock
         scope: clk
 
@@ -937,11 +1056,12 @@ subsections:
             deprecated:
               - drivers/arm/mhu
 
-          - title: RSS
-            scope: rss
+          - title: RSE
+            scope: rse
 
             deprecated:
               - drivers/arm/rss
+              - rss
 
           - title: TZC
             scope: tzc
@@ -1093,6 +1213,9 @@ subsections:
           - title: TRDC
             scope: imx-trdc
 
+          - title: Clock
+            scope: nxp-clk
+
       - title: Renesas
         scope: renesas-drivers
 
@@ -1260,6 +1383,10 @@ subsections:
           - title: STM32MP2
             scope: stm32mp2-fdts
 
+            subsections:
+              - title: STM32MP25
+                scope: stm32mp25-fdts
+
       - title: PIE
         scope: pie
 
@@ -1340,6 +1467,7 @@ subsections:
           - git-hooks
 
   - title: Tools
+    scope: tools
 
     subsections:
       - title: STM32 Image
@@ -1360,12 +1488,34 @@ subsections:
       - title: Certificate Creation Tool
         scope: cert-create
 
+      - title: Firmware Encryption Tool
+        scope: encrypt-fw
+
       - title: Memory Mapping Tool
         scope: memmap
 
         deprecated:
           - cert_create
 
+      - title: Marvell Tools
+        scope: marvell-tools
+
+      - title: Renesas Tools
+        scope: renesas-tools
+
+        subsections:
+          - title: R-Car Layout Tool
+            scope: rcar-layout
+
+          - title: R/ZG Layout Tool
+            scope: rzg-layout
+
+      - title: Transfer List Compiler
+        scope: tlc
+
+      - title: Chain of Trust device tree to C source file
+        scope: cot-dt2c
+
   - title: Dependencies
     scope: deps
 
diff --git a/common/bl_common.c b/common/bl_common.c
index 8fce02fb..2c452aa8 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,7 @@
 #include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/io/io_storage.h>
@@ -149,8 +150,7 @@ exit:
  * of trust.
  */
 static int load_auth_image_recursive(unsigned int image_id,
-				    image_info_t *image_data,
-				    int is_parent_image)
+				    image_info_t *image_data)
 {
 	int rc;
 	unsigned int parent_id;
@@ -158,7 +158,7 @@ static int load_auth_image_recursive(unsigned int image_id,
 	/* Use recursion to authenticate parent images */
 	rc = auth_mod_get_parent_id(image_id, &parent_id);
 	if (rc == 0) {
-		rc = load_auth_image_recursive(parent_id, image_data, 1);
+		rc = load_auth_image_recursive(parent_id, image_data);
 		if (rc != 0) {
 			return rc;
 		}
@@ -192,7 +192,7 @@ static int load_auth_image_internal(unsigned int image_id,
 {
 #if TRUSTED_BOARD_BOOT
 	if (dyn_is_auth_disabled() == 0) {
-		return load_auth_image_recursive(image_id, image_data, 0);
+		return load_auth_image_recursive(image_id, image_data);
 	}
 #endif
 
@@ -210,18 +210,18 @@ int load_auth_image(unsigned int image_id, image_info_t *image_data)
 {
 	int err;
 
-/*
- * All firmware banks should be part of the same non-volatile storage as per
- * PSA FWU specification, hence don't check for any alternate boot source
- * when PSA FWU is enabled.
- */
-#if PSA_FWU_SUPPORT
-	err = load_auth_image_internal(image_id, image_data);
-#else
-	do {
+	if ((plat_try_img_ops == NULL) || (plat_try_img_ops->next_instance == NULL)) {
 		err = load_auth_image_internal(image_id, image_data);
-	} while ((err != 0) && (plat_try_next_boot_source() != 0));
-#endif /* PSA_FWU_SUPPORT */
+	} else {
+		do {
+			err = load_auth_image_internal(image_id, image_data);
+			if (err != 0) {
+				if (plat_try_img_ops->next_instance(image_id) != 0) {
+					return err;
+				}
+			}
+		} while (err != 0);
+	}
 
 	if (err == 0) {
 		/*
@@ -275,6 +275,5 @@ void print_entry_point_info(const entry_point_info_t *ep_info)
  */
 const char *get_version(void)
 {
-	extern const char version[];
-	return version;
+	return build_version;
 }
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index 1bad74fe..59b75435 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -197,6 +197,7 @@ int fdt_add_reserved_memory(void *dtb, const char *node_name,
 			    uintptr_t base, size_t size)
 {
 	int offs = fdt_path_offset(dtb, "/reserved-memory");
+	int node;
 	uint32_t addresses[4];
 	int ac, sc;
 	unsigned int idx = 0;
@@ -213,6 +214,24 @@ int fdt_add_reserved_memory(void *dtb, const char *node_name,
 		fdt_setprop(dtb, offs, "ranges", NULL, 0);
 	}
 
+	/* Check for existing regions */
+	fdt_for_each_subnode(node, dtb, offs) {
+		uintptr_t c_base;
+		size_t c_size;
+		int ret;
+
+		ret = fdt_get_reg_props_by_index(dtb, node, 0, &c_base, &c_size);
+		/* Ignore illegal subnodes */
+		if (ret != 0) {
+			continue;
+		}
+
+		/* existing region entirely contains the new region */
+		if (base >= c_base && (base + size) <= (c_base + c_size)) {
+			return 0;
+		}
+	}
+
 	if (ac > 1) {
 		addresses[idx] = cpu_to_fdt32(HIGH_BITS(base));
 		idx++;
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index 783b660e..b213ffa4 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -88,6 +88,19 @@ int fdt_read_uint64(const void *dtb, int node, const char *prop_name,
 	return 0;
 }
 
+uint64_t fdt_read_uint64_default(const void *dtb, int node,
+				 const char *prop_name, uint64_t dflt_value)
+{
+	uint64_t ret = dflt_value;
+	int err = fdt_read_uint64(dtb, node, prop_name, &ret);
+
+	if (err < 0) {
+		return dflt_value;
+	}
+
+	return ret;
+}
+
 /*
  * Read bytes from a given property of the given node. Any number of
  * bytes of the property can be read. The fdt pointer is updated.
diff --git a/common/feat_detect.c b/common/feat_detect.c
index be22c6ed..8c03ab82 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -70,47 +70,214 @@ static void read_feat_pauth(void)
 #endif
 }
 
-/************************************************
- * Feature : FEAT_MTE (Memory Tagging Extension)
- ***********************************************/
-static void read_feat_mte(void)
+static unsigned int read_feat_rng_trap_id_field(void)
 {
-#if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_ALWAYS)
-	unsigned int mte = get_armv8_5_mte_support();
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT,
+			     ID_AA64PFR1_EL1_RNDR_TRAP_MASK);
+}
 
-	feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE");
-#endif
+static unsigned int read_feat_bti_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_BT_SHIFT,
+			     ID_AA64PFR1_EL1_BT_MASK);
 }
 
-/****************************************************
- * Feature : FEAT_BTI (Branch Target Identification)
- ***************************************************/
-static void read_feat_bti(void)
+static unsigned int read_feat_sb_id_field(void)
 {
-#if (ENABLE_BTI == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_armv8_5_bti_present(), "BTI");
-#endif
+	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT,
+			     ID_AA64ISAR1_SB_MASK);
 }
 
-/**************************************************
- * Feature : FEAT_RME (Realm Management Extension)
- *************************************************/
-static void read_feat_rme(void)
+static unsigned int read_feat_csv2_id_field(void)
 {
-#if (ENABLE_RME == FEAT_STATE_ALWAYS)
-	feat_detect_panic((get_armv9_2_feat_rme_support() !=
-			ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME");
-#endif
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_CSV2_SHIFT,
+			     ID_AA64PFR0_CSV2_MASK);
 }
 
-/******************************************************************
- * Feature : FEAT_RNG_TRAP (Trapping support for RNDR/RNDRRS)
- *****************************************************************/
-static void read_feat_rng_trap(void)
+static unsigned int read_feat_debugv8p9_id_field(void)
 {
-#if (ENABLE_FEAT_RNG_TRAP == FEAT_STATE_ALWAYS)
-	feat_detect_panic(is_feat_rng_trap_present(), "RNG_TRAP");
-#endif
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_DEBUGVER_SHIFT,
+			     ID_AA64DFR0_DEBUGVER_MASK);
+}
+
+static unsigned int read_feat_pmuv3_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER_SHIFT,
+			     ID_AA64DFR0_PMUVER_MASK);
+}
+
+static unsigned int read_feat_vhe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_VHE_SHIFT,
+			     ID_AA64MMFR1_EL1_VHE_MASK);
+}
+
+static unsigned int read_feat_sve_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SVE_SHIFT,
+			     ID_AA64PFR0_SVE_MASK);
+}
+
+static unsigned int read_feat_ras_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_RAS_SHIFT,
+			     ID_AA64PFR0_RAS_MASK);
+}
+
+static unsigned int read_feat_dit_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_DIT_SHIFT,
+			     ID_AA64PFR0_DIT_MASK);
+}
+
+static unsigned int  read_feat_amu_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_AMU_SHIFT,
+			     ID_AA64PFR0_AMU_MASK);
+}
+
+static unsigned int read_feat_mpam_version(void)
+{
+	return (unsigned int)((((read_id_aa64pfr0_el1() >>
+		ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
+			((read_id_aa64pfr1_el1() >>
+		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
+}
+
+static unsigned int read_feat_nv_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr2_el1(), ID_AA64MMFR2_EL1_NV_SHIFT,
+			     ID_AA64MMFR2_EL1_NV_MASK);
+}
+
+static unsigned int read_feat_sel2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SEL2_SHIFT,
+			     ID_AA64PFR0_SEL2_MASK);
+}
+
+static unsigned int read_feat_trf_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEFILT_SHIFT,
+			     ID_AA64DFR0_TRACEFILT_MASK);
+}
+static unsigned int get_armv8_5_mte_support(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_MTE_SHIFT,
+			     ID_AA64PFR1_EL1_MTE_MASK);
+}
+static unsigned int read_feat_rng_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64isar0_el1(), ID_AA64ISAR0_RNDR_SHIFT,
+			     ID_AA64ISAR0_RNDR_MASK);
+}
+static unsigned int read_feat_fgt_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_FGT_SHIFT,
+			     ID_AA64MMFR0_EL1_FGT_MASK);
+}
+static unsigned int read_feat_ecv_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_ECV_SHIFT,
+			     ID_AA64MMFR0_EL1_ECV_MASK);
+}
+static unsigned int read_feat_twed_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_TWED_SHIFT,
+			     ID_AA64MMFR1_EL1_TWED_MASK);
+}
+
+static unsigned int read_feat_hcx_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX_SHIFT,
+			     ID_AA64MMFR1_EL1_HCX_MASK);
+}
+static unsigned int read_feat_ls64_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_LS64_SHIFT,
+			     ID_AA64ISAR1_LS64_MASK);
+}
+static unsigned int read_feat_tcr2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX_SHIFT,
+			     ID_AA64MMFR3_EL1_TCRX_MASK);
+}
+static unsigned int read_feat_s2pie_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE_SHIFT,
+			     ID_AA64MMFR3_EL1_S2PIE_MASK);
+}
+static unsigned int read_feat_s1pie_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE_SHIFT,
+			     ID_AA64MMFR3_EL1_S1PIE_MASK);
+}
+static unsigned int read_feat_s2poe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE_SHIFT,
+			     ID_AA64MMFR3_EL1_S2POE_MASK);
+}
+static unsigned int read_feat_s1poe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE_SHIFT,
+			     ID_AA64MMFR3_EL1_S1POE_MASK);
+}
+static unsigned int read_feat_brbe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_BRBE_SHIFT,
+			     ID_AA64DFR0_BRBE_MASK);
+}
+static unsigned int read_feat_trbe_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEBUFFER_SHIFT,
+			     ID_AA64DFR0_TRACEBUFFER_MASK);
+}
+static unsigned int read_feat_sme_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_SME_SHIFT,
+			     ID_AA64PFR1_EL1_SME_MASK);
+}
+static unsigned int read_feat_gcs_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_GCS_SHIFT,
+			     ID_AA64PFR1_EL1_GCS_MASK);
+}
+
+static unsigned int read_feat_rme_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_FEAT_RME_SHIFT,
+			     ID_AA64PFR0_FEAT_RME_MASK);
+}
+
+static unsigned int read_feat_pan_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_PAN_SHIFT,
+			     ID_AA64MMFR1_EL1_PAN_MASK);
+}
+
+static unsigned int read_feat_mtpmu_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT,
+			     ID_AA64DFR0_MTPMU_MASK);
+
+}
+
+static unsigned int read_feat_the_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_THE_SHIFT,
+			     ID_AA64PFR1_EL1_THE_MASK);
+}
+
+static unsigned int read_feat_sctlr2_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_SCTLR2_SHIFT,
+			     ID_AA64MMFR3_EL1_SCTLR2_MASK);
+}
+
+static unsigned int read_feat_d128_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_D128_SHIFT,
+			     ID_AA64MMFR3_EL1_D128_MASK);
 }
 
 /***********************************************************************************
@@ -151,7 +318,7 @@ void detect_arch_features(void)
 	 * revisions so that we catch them as they come along
 	 */
 	check_feature(FEAT_STATE_ALWAYS, read_feat_pmuv3_id_field(),
-		      "PMUv3", 1, ID_AA64DFR0_PMUVER_PMUV3P7);
+		      "PMUv3", 1, ID_AA64DFR0_PMUVER_PMUV3P8);
 
 	/* v8.1 features */
 	check_feature(ENABLE_FEAT_PAN, read_feat_pan_id_field(), "PAN", 1, 3);
@@ -163,6 +330,7 @@ void detect_arch_features(void)
 	check_feature(ENABLE_FEAT_RAS, read_feat_ras_id_field(), "RAS", 1, 2);
 
 	/* v8.3 features */
+	/* TODO: Pauth yet to convert to tri-state feat detect logic */
 	read_feat_pauth();
 
 	/* v8.4 features */
@@ -179,15 +347,18 @@ void detect_arch_features(void)
 		      "TRF", 1, 1);
 
 	/* v8.5 features */
-	read_feat_mte();
+	check_feature(ENABLE_FEAT_MTE2, get_armv8_5_mte_support(), "MTE2",
+		      MTE_IMPLEMENTED_ELX, MTE_IMPLEMENTED_ASY);
 	check_feature(ENABLE_FEAT_RNG, read_feat_rng_id_field(), "RNG", 1, 1);
-	read_feat_bti();
-	read_feat_rng_trap();
+	check_feature(ENABLE_BTI, read_feat_bti_id_field(), "BTI", 1, 1);
+	check_feature(ENABLE_FEAT_RNG_TRAP, read_feat_rng_trap_id_field(),
+		      "RNG_TRAP", 1, 1);
 
 	/* v8.6 features */
 	check_feature(ENABLE_FEAT_AMUv1p1, read_feat_amu_id_field(),
 		      "AMUv1p1", 2, 2);
-	check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT", 1, 1);
+	check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT", 1, 2);
+	check_feature(ENABLE_FEAT_FGT2, read_feat_fgt_id_field(), "FGT2", 2, 2);
 	check_feature(ENABLE_FEAT_ECV, read_feat_ecv_id_field(), "ECV", 1, 2);
 	check_feature(ENABLE_FEAT_TWED, read_feat_twed_id_field(),
 		      "TWED", 1, 1);
@@ -201,6 +372,7 @@ void detect_arch_features(void)
 
 	/* v8.7 features */
 	check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX", 1, 1);
+	check_feature(ENABLE_FEAT_LS64_ACCDATA, read_feat_ls64_id_field(), "LS64", 1, 3);
 
 	/* v8.9 features */
 	check_feature(ENABLE_FEAT_TCR2, read_feat_tcr2_id_field(),
@@ -213,8 +385,14 @@ void detect_arch_features(void)
 		      "S2POE", 1, 1);
 	check_feature(ENABLE_FEAT_S1POE, read_feat_s1poe_id_field(),
 		      "S1POE", 1, 1);
-	check_feature(ENABLE_FEAT_MTE_PERM, read_feat_mte_perm_id_field(),
-		      "MTE_PERM", 1, 1);
+	check_feature(ENABLE_FEAT_CSV2_3, read_feat_csv2_id_field(),
+		      "CSV2_3", 3, 3);
+	check_feature(ENABLE_FEAT_DEBUGV8P9, read_feat_debugv8p9_id_field(),
+			"DEBUGV8P9", 11, 11);
+	check_feature(ENABLE_FEAT_THE, read_feat_the_id_field(),
+			"THE", 1, 1);
+	check_feature(ENABLE_FEAT_SCTLR2, read_feat_sctlr2_id_field(),
+			"SCTLR2", 1, 1);
 
 	/* v9.0 features */
 	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
@@ -228,10 +406,13 @@ void detect_arch_features(void)
 	check_feature(ENABLE_SME2_FOR_NS, read_feat_sme_id_field(),
 		      "SME2", 2, 2);
 
+	/* v9.3 features */
+	check_feature(ENABLE_FEAT_D128, read_feat_d128_id_field(),
+		      "D128", 1, 1);
+
 	/* v9.4 features */
 	check_feature(ENABLE_FEAT_GCS, read_feat_gcs_id_field(), "GCS", 1, 1);
-
-	read_feat_rme();
+	check_feature(ENABLE_RME, read_feat_rme_id_field(), "RME", 1, 1);
 
 	if (tainted) {
 		panic();
diff --git a/docs/Makefile b/docs/Makefile
index 5bc24db7..68c09581 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,11 +1,13 @@
 #
-# Copyright (c) 2019-2023, ARM Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 # Minimal makefile for Sphinx documentation
 #
 
+include ../make_helpers/common.mk
+
 # You can set these variables from the command line.
 SPHINXOPTS    = -W
 SPHINXBUILD   = sphinx-build
@@ -13,20 +15,14 @@ SPHINXPROJ    = TrustedFirmware-A
 SOURCEDIR     = .
 BUILDDIR      = build
 
-V ?= 0
-ifeq ($(V),0)
-  Q := @
-else
-  Q :=
-endif
-
 # Put it first so that "make" without argument is like "make help".
 help:
-	${Q}$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+	$(q)$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
 .PHONY: help Makefile
 
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
-	${Q}$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+.DEFAULT: Makefile
+	$(if $(host-poetry),$(q)poetry -q install --with=docs)
+	$(q)$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/about/contact.rst b/docs/about/contact.rst
index 4f482bd3..bb73dfe0 100644
--- a/docs/about/contact.rst
+++ b/docs/about/contact.rst
@@ -36,9 +36,8 @@ topic within the community. More details can be found `here`_.
 Issue Tracker
 ^^^^^^^^^^^^^
 
-Bug reports may be filed on the `issue tracker`_ on the TrustedFirmware.org
-website. Using this tracker gives everyone visibility of the known issues in
-TF-A.
+Bug reports may be filed on the `issue tracker`_ on Github. Using this tracker
+gives everyone visibility of the known issues in TF-A.
 
 Arm Licensees
 ^^^^^^^^^^^^^
@@ -46,7 +45,7 @@ Arm Licensees
 Arm licensees have an additional support conduit - they may contact Arm directly
 via their partner managers.
 
-.. _`issue tracker`: https://developer.trustedfirmware.org
+.. _`issue tracker`: https://github.com/TrustedFirmware-A/trusted-firmware-a/issues
 .. _`TF-A development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
 .. _`TF-A-Tests development`: https://lists.trustedfirmware.org/mailman3/lists/tf-a-tests.lists.trustedfirmware.org/
 .. _`summary of all the lists`: https://lists.trustedfirmware.org/mailman3/lists/
diff --git a/docs/about/features.rst b/docs/about/features.rst
index c12509d9..9b7bdf9d 100644
--- a/docs/about/features.rst
+++ b/docs/about/features.rst
@@ -128,7 +128,7 @@ Additionally the following libraries are marked experimental when included
 in a platform:
 
 -  MPU translation library ``lib/xlat_mpu``
--  RSS comms driver ``drivers/arm/rss``
+-  RSE comms driver ``drivers/arm/rse``
 
 Still to come
 -------------
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 4531a03e..03526a62 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -49,12 +49,14 @@ Maintainers
 :|G|: `laurenw-arm`_
 :|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
 :|G|: `madhukar-Arm`_
-:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:|M|: Raghu Krishnamurthy <raghuoss@raghushome.com>
 :|G|: `raghuncstate`_
 :|M|: Manish Badarkhe <manish.badarkhe@arm.com>
 :|G|: `ManishVB-Arm`_
 :|M|: Yann Gautier <yann.gautier@st.com>
 :|G|: `Yann-lms`_
+:|M|: Govindraj Raja <govindraj.raja@arm.com>
+:|G|: `govindraj-arm`_
 
 LTS Maintainers
 ---------------
@@ -63,8 +65,8 @@ LTS Maintainers
 :|G|: `bipinravi-arm`_
 :|M|: Joanna Farley <joanna.farley@arm.com>
 :|G|: `joannafarley-arm`_
-:|M|: Okash Khawaja <okash@google.com>
-:|G|: `bytefire`_
+:|M|: Jidong Sun <jidong@google.com>
+:|G|: `jidongsun`_
 :|M|: Varun Wadekar <vwadekar@nvidia.com>
 :|G|: `vwadekar`_
 :|M|: Yann Gautier <yann.gautier@st.com>
@@ -114,6 +116,8 @@ Secure Partition Manager Core (EL3 FF-A SPMC)
 :|M|: Marc Bonnici <marc.bonnici@arm.com>
 :|G|: `marcbonnici`_
 :|F|: services/std_svc/spm/el3_spmc/\*
+:|F|: include/services/el3_spmc\_\*
+:|F|: include/services/spmc_svc.h
 
 Secure Partition Manager Dispatcher (SPMD)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -121,7 +125,13 @@ Secure Partition Manager Dispatcher (SPMD)
 :|G|: `odeprez`_
 :|M|: Joao Alves <Joao.Alves@arm.com>
 :|G|: `J-Alves`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
 :|F|: services/std_svc/spmd/\*
+:|F|: plat/common/plat_spmd_manifest.c
+:|F|: include/services/ffa_svc.h
+:|F|: include/services/el3_spmd_logical_sp.h
+:|F|: include/services/spmd_svc.h
 
 Exception Handling Framework (EHF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -131,6 +141,16 @@ Exception Handling Framework (EHF)
 :|G|: `manish-pandey-arm`_
 :|F|: bl31/ehf.c
 
+Runtime Exceptions and Interrupt Management
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: bl31/aarch64/
+:|F|: bl31/interrupt_mgmt.c
+:|F|: include/bl31/interrupt_mgmt.h
+
 Realm Management Monitor Dispatcher (RMMD)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
@@ -216,12 +236,14 @@ Power State Coordination Interface (PSCI)
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/psci/
+:|F|: include/lib/psci/
 
 DebugFS
 ^^^^^^^
 :|M|: Olivier Deprez <olivier.deprez@arm.com>
 :|G|: `odeprez`_
 :|F|: lib/debugfs/
+:|F|: include/lib/debugfs.h
 
 Firmware Configuration Framework (FCONF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -232,6 +254,10 @@ Firmware Configuration Framework (FCONF)
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/fconf/
+:|F|: plat/arm/common/fconf/
+:|F|: include/lib/fconf/
+:|F|: include/plat/arm/common/arm_fconf\_\*
+:|F|: include/plat/arm/common/fconf\_\*
 
 Performance Measurement Framework (PMF)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -253,6 +279,7 @@ Arm CPU libraries
 :|M|: Lauren Wehrmeister <Lauren.Wehrmeister@arm.com>
 :|G|: `laurenw-arm`_
 :|F|: lib/cpus/
+:|F|: include/lib/cpus/
 
 Reliability Availability Serviceabilty (RAS) framework
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -337,12 +364,12 @@ Message Handling Unit (MHU) driver
 :|F|: include/drivers/arm/mhu.h
 :|F|: drivers/arm/mhu
 
-Runtime Security Subsystem (RSS) comms driver
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Runtime Security Engine (RSE) comms driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: David Vincze <david.vincze@arm.com>
 :|G|: `davidvincze`_
-:|F|: include/drivers/arm/rss_comms.h
-:|F|: drivers/arm/rss
+:|F|: include/drivers/arm/rse_comms.h
+:|F|: drivers/arm/rse
 
 Libfdt wrappers
 ^^^^^^^^^^^^^^^
@@ -380,6 +407,8 @@ DRTM
 :|M|: Manish Pandey <manish.pandey2@arm.com>
 :|G|: `manish-pandey-arm`_
 :|F|: services/std_svc/drtm
+:|F|: include/plat/common/plat_drtm.h
+:|F|: include/services/drtm_svc.h
 
 PSA Firmware Update
 ^^^^^^^^^^^^^^^^^^^
@@ -433,6 +462,32 @@ Firmware Handoff Library (Transfer List)
 :|F|: lib/transfer_list
 :|F|: include/lib/transfer_list.h
 
+Context Management
+^^^^^^^^^^^^^^^^^^
+:|M|: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
+:|G|: `jayanthchidanand-arm`_
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: bl1/aarch32/bl1_context_mgmt.c
+:|F|: bl1/aarch64/bl1_context_mgmt.c
+:|F|: bl31/bl31_context_mgmt.c
+:|F|: lib/el3_runtime/
+:|F|: include/lib/el3_runtime/
+
+Runtime Services
+^^^^^^^^^^^^^^^^
+:|M|: Manish Pandey <manish.pandey2@arm.com>
+:|G|: `manish-pandey-arm`_
+:|M|: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
+:|G|: `madhukar-Arm`_
+:|F|: services/std_svc/std_svc_setup.c
+:|F|: common/runtime_svc.c
+:|F|: include/common/runtime_svc.h
+:|F|: include/services/arm_arch_svc.h
+:|F|: include/services/std_svc.h
+
 Platform Ports
 ~~~~~~~~~~~~~~
 
@@ -512,8 +567,8 @@ Arm Rich IoT Platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
 :|G|: `abdellatif-elkhlifi`_
-:|M|: Xueliang Zhong <xueliang.zhong@arm.com>
-:|G|: `xueliang-zhong-arm`_
+:|M|: Hugues Kamba Mpiana <hugues.kambampiana@arm.com>
+:|G|: `hugues-kambampiana-arm`_
 :|F|: plat/arm/board/corstone700
 :|F|: plat/arm/board/a5ds
 :|F|: plat/arm/board/corstone1000
@@ -524,13 +579,14 @@ Arm Reference Design platform ports
 :|G|: `thomas-arm`_
 :|M|: Vijayenthiran Subramaniam <vijayenthiran.subramaniam@arm.com>
 :|G|: `vijayenthiran-arm`_
-:|F|: plat/arm/css/sgi/
-:|F|: plat/arm/board/rde1edge/
-:|F|: plat/arm/board/rdn1edge/
-:|F|: plat/arm/board/rdn2/
-:|F|: plat/arm/board/rdv1/
-:|F|: plat/arm/board/rdv1mc/
-:|F|: plat/arm/board/sgi575/
+:|M|: Rohit Mathew <Rohit.Mathew@arm.com>
+:|G|: `rohit-arm`_
+:|F|: plat/arm/board/neoverse_rd/common
+:|F|: plat/arm/board/neoverse_rd/platform/rdn1edge/
+:|F|: plat/arm/board/neoverse_rd/platform/rdn2/
+:|F|: plat/arm/board/neoverse_rd/platform/rdv1/
+:|F|: plat/arm/board/neoverse_rd/platform/rdv1mc/
+:|F|: plat/arm/board/neoverse_rd/platform/sgi575/
 
 Arm Total Compute platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -540,6 +596,16 @@ Arm Total Compute platform port
 :|G|: `rupsin01`_
 :|F|: plat/arm/board/tc
 
+Arm Automotive RD platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Diego Sueiro <diego.sueiro@arm.com>
+:|G|: `diego-sueiro`_
+:|M|: Peter Hoyes <peter.hoyes@arm.com>
+:|G|: `hoyes`_
+:|M|: Divin Raj <divin.raj@arm.com>
+:|G|: `divin-raj`_
+:|F|: plat/arm/board/automotive_rd
+
 Aspeed platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Chia-Wei Wang <chiawei_wang@aspeedtech.com>
@@ -576,8 +642,6 @@ Intel SocFPGA platform ports
 
 MediaTek platform ports
 ^^^^^^^^^^^^^^^^^^^^^^^
-:|M|: Rex-BC Chen <rex-bc.chen@mediatek.com>
-:|G|: `mtk-rex-bc-chen`_
 :|M|: Leon Chen <leon.chen@mediatek.com>
 :|G|: `leon-chen-mtk`_
 :|M|: Jason-CH Chen <jason-ch.chen@mediatek.com>
@@ -605,7 +669,6 @@ Nuvoton npcm845x platform port
 :|M|: Avi Fishman <avi.fishman@nuvoton.com>
 :|G|: `avifishman`_
 :|F|: docs/plat/npcm845x.rst
-:|F|: drivers/nuvoton/
 :|F|: include/drivers/nuvoton/
 :|F|: include/plat/nuvoton/
 :|F|: plat/nuvoton/
@@ -646,6 +709,13 @@ NXP i.MX8M platform port
 :|F|: docs/plat/imx8m.rst
 :|F|: plat/imx/imx8m/
 
+NXP i.MX8ULP platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Jacky Bai <ping.bai@nxp.com>
+:|G|: `JackyBai`_
+:|F|: docs/plat/imx8ulp.rst
+:|F|: plat/imx/imx8ulp/
+
 NXP i.MX9 platform port
 ^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Jacky Bai <ping.bai@nxp.com>
@@ -704,6 +774,16 @@ NXP SoC Part LS1088A and its platform port
 :|F|: plat/nxp/soc-ls1088a/ls1088ardb
 :|F|: plat/nxp/soc-ls1088a/ls1088aqds
 
+NXP SoC Part S32G274A and its platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
+:|G|: `gprocopciucnxp`_
+:|F|: docs/plat/s32g274a.rst
+:|F|: drivers/nxp/clk/s32cc
+:|F|: drivers/nxp/console/linflex_console.S
+:|F|: include/drivers/nxp/console/linflex.h
+:|F|: plat/nxp/s32
+
 QEMU platform port
 ^^^^^^^^^^^^^^^^^^
 :|M|: Jens Wiklander <jens.wiklander@linaro.org>
@@ -790,14 +870,14 @@ RockChip platform port
 :|G|: `rockchip-linux`_
 :|M|: Heiko Stuebner <heiko@sntech.de>
 :|G|: `mmind`_
-:|M|: Julius Werner <jwerner@chromium.org>
-:|G|: `jwerner-chromium`_
 :|F|: plat/rockchip/
 
-STM32MP1 platform port
-^^^^^^^^^^^^^^^^^^^^^^
+STMicroelectronics platform ports
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Yann Gautier <yann.gautier@st.com>
 :|G|: `Yann-lms`_
+:|M|: Maxime Méré <maxime.mere@foss.st.com>
+:|G|: `meremST`_
 :|F|: docs/plat/st/*
 :|F|: docs/plat/stm32mp1.rst
 :|F|: drivers/st/
@@ -805,12 +885,15 @@ STM32MP1 platform port
 :|F|: include/drivers/st/
 :|F|: include/dt-bindings/\*/stm32\*
 :|F|: plat/st/
+:|F|: tools/fiptool/plat_fiptool/st/
 :|F|: tools/stm32image/
 
 Synquacer platform port
 ^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Sumit Garg <sumit.garg@linaro.org>
 :|G|: `b49020`_
+:|M|: Masahisa Kojima <kojima.masahisa@socionext.com>
+:|G|: `masahisak`_
 :|F|: docs/plat/synquacer.rst
 :|F|: plat/socionext/synquacer/
 
@@ -935,7 +1018,7 @@ Threat Model
 :|G|: `sandrine-bailleux-arm`_
 :|M|: Joanna Farley <joanna.farley@arm.com>
 :|G|: `joannafarley-arm`_
-:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:|M|: Raghu Krishnamurthy <raghuoss@raghushome.com>
 :|G|: `raghuncstate`_
 :|M|: Varun Wadekar <vwadekar@nvidia.com>
 :|G|: `vwadekar`_
@@ -947,94 +1030,105 @@ Conventional Changelog Extensions
 :|G|: `CJKay`_
 :|F|: tools/conventional-changelog-tf-a
 
+.. _abdellatif-elkhlifi: https://github.com/abdellatif-elkhlifi
+.. _Akshay-Belsare: https://github.com/Akshay-Belsare
 .. _AlexeiFedorov: https://github.com/AlexeiFedorov
+.. _amit-nagal: https://github.com/amit-nagal
 .. _andersdellien-arm: https://github.com/andersdellien-arm
 .. _Andre-ARM: https://github.com/Andre-ARM
 .. _Anson-Huang: https://github.com/Anson-Huang
+.. _anukou: https://github.com/anukou
+.. _arugan02: https://github.com/arugan02
+.. _arve-android: https://github.com/arve-android
+.. _avifishman: https://github.com/avifishman
+.. _b49020: https://github.com/b49020
+.. _BenjaminLimJL: https://github.com/BenjaminLimJL
 .. _bijucdas: https://github.com/bijucdas
+.. _bipinravi-arm: https://github.com/bipinravi-arm
 .. _bryanodonoghue: https://github.com/bryanodonoghue
-.. _b49020: https://github.com/b49020
+.. _jidongsun: https://github.com/jidongsun
 .. _carlocaione: https://github.com/carlocaione
+.. _chandnich: https://github.com/chandnich
+.. _ChiaweiW: https://github.com/chiaweiw
+.. _CJKay: https://github.com/cjkay
 .. _danh-arm: https://github.com/danh-arm
 .. _davidvincze: https://github.com/davidvincze
+.. _diego-sueiro: https://github.com/diego-sueiro
+.. _divin-raj: https://github.com/divin-raj
 .. _etienne-lms: https://github.com/etienne-lms
 .. _glneo: https://github.com/glneo
+.. _govindraj-arm: https://github.com/govindraj-arm
+.. _gprocopciucnxp: https://github.com/gprocopciucnxp
 .. _grandpaul: https://github.com/grandpaul
+.. _harrisonmutai-arm: https://github.com/harrisonmutai-arm
+.. _hilamirandakuzi1: https://github.com/hilamirandakuzi1
+.. _hoyes: https://github.com/hoyes
 .. _hzhuang1: https://github.com/hzhuang1
+.. _hugues-kambampiana-arm: https://github.com/hugueskamba
 .. _JackyBai: https://github.com/JackyBai
+.. _J-Alves: https://github.com/J-Alves
+.. _jason-ch-chen: https://github.com/jason-ch-chen
+.. _javieralso-arm: https://github.com/javieralso-arm
+.. _jayanthchidanand-arm: https://github.com/jayanthchidanand-arm
 .. _jcorbier: https://github.com/jcorbier
 .. _jenswi-linaro: https://github.com/jenswi-linaro
+.. _JiafeiPan: https://github.com/JiafeiPan
+.. _jimmy-brisson: https://github.com/theotherjimmy
+.. _joannafarley-arm: https://github.com/joannafarley-arm
 .. _jslater8: https://github.com/jslater8
 .. _jwerner-chromium: https://github.com/jwerner-chromium
 .. _kostapr: https://github.com/kostapr
 .. _lachitp: https://github.com/lachitp
+.. _laurenw-arm: https://github.com/laurenw-arm
+.. _leon-chen-mtk: https://github.com/leon-chen-mtk
+.. _linyidi: https://github.com/linyidi
+.. _madhukar-Arm: https://github.com/madhukar-Arm
+.. _manish-pandey-arm: https://github.com/manish-pandey-arm
+.. _ManishVB-Arm: https://github.com/ManishVB-Arm
+.. _marcbonnici: https://github.com/marcbonnici
+.. _marcone: https://github.com/marcone
+.. _mardyk01: https://github.com/mardyk01
 .. _marex: https://github.com/marex
 .. _masahir0y: https://github.com/masahir0y
+.. _masahisak: https://github.com/masahisak
+.. _max-shvetsov: https://github.com/max-shvetsov
+.. _meremST: https://github.com/meremST
 .. _michalsimek: https://github.com/michalsimek
 .. _mmind: https://github.com/mmind
 .. _MrVan: https://github.com/MrVan
-.. _mtk-rex-bc-chen: https://github.com/mtk-rex-bc-chen
-.. _leon-chen-mtk: https://github.com/leon-chen-mtk
-.. _jason-ch-chen: https://github.com/jason-ch-chen
-.. _linyidi: https://github.com/linyidi
+.. _Neal-liu: https://github.com/neal-liu
 .. _niej: https://github.com/niej
+.. _nmenon: https://github.com/nmenon
 .. _npoushin: https://github.com/npoushin
+.. _odeprez: https://github.com/odeprez
+.. _pangupta: https://github.com/pangupta
 .. _prabhakarlad: https://github.com/prabhakarlad
 .. _quic_mkf: https://github.com/quicmkf
+.. _raghuncstate: https://github.com/raghuncstate
+.. _raymo200915: https://github.com/raymo200915
 .. _remi-triplefault: https://github.com/repk
 .. _rockchip-linux: https://github.com/rockchip-linux
+.. _rohit-arm: https://github.com/rohit-arm
+.. _rupsin01: https://github.com/rupsin01
+.. _rutigl: https://github.com/rutigl
 .. _sandrine-bailleux-arm: https://github.com/sandrine-bailleux-arm
 .. _sgorecha: https://github.com/sgorecha
 .. _shawnguo2: https://github.com/shawnguo2
+.. _sieumunt: https://github.com/sieumunt
 .. _smaeul: https://github.com/smaeul
 .. _soby-mathew: https://github.com/soby-mathew
 .. _sreekare: https://github.com/sreekare
 .. _stefanasimion: https://github.com/stefanasimion
 .. _stephan-gh: https://github.com/stephan-gh
-.. _sieumunt: https://github.com/sieumunt
-.. _BenjaminLimJL: https://github.com/BenjaminLimJL
 .. _thomas-arm: https://github.com/thomas-arm
 .. _TonyXie06: https://github.com/TonyXie06
 .. _TravMurav: https://github.com/TravMurav
+.. _uarif1: https://github.com/uarif1
+.. _vijayenthiran-arm: https://github.com/vijayenthiran-arm
+.. _vishnu-banavath: https://github.com/vishnu-banavath
 .. _vwadekar: https://github.com/vwadekar
 .. _Yann-lms: https://github.com/Yann-lms
-.. _manish-pandey-arm: https://github.com/manish-pandey-arm
-.. _mardyk01: https://github.com/mardyk01
-.. _odeprez: https://github.com/odeprez
-.. _bipinravi-arm: https://github.com/bipinravi-arm
-.. _joannafarley-arm: https://github.com/joannafarley-arm
-.. _ManishVB-Arm: https://github.com/ManishVB-Arm
-.. _max-shvetsov: https://github.com/max-shvetsov
-.. _javieralso-arm: https://github.com/javieralso-arm
-.. _laurenw-arm: https://github.com/laurenw-arm
-.. _J-Alves: https://github.com/J-Alves
-.. _madhukar-Arm: https://github.com/madhukar-Arm
-.. _raghuncstate: https://github.com/raghuncstate
-.. _CJKay: https://github.com/cjkay
-.. _nmenon: https://github.com/nmenon
-.. _anukou: https://github.com/anukou
-.. _chandnich: https://github.com/chandnich
-.. _abdellatif-elkhlifi: https://github.com/abdellatif-elkhlifi
-.. _vishnu-banavath: https://github.com/vishnu-banavath
-.. _vijayenthiran-arm: https://github.com/vijayenthiran-arm
-.. _arugan02: https://github.com/arugan02
-.. _uarif1: https://github.com/uarif1
-.. _pangupta: https://github.com/pangupta
-.. _JiafeiPan: https://github.com/JiafeiPan
-.. _arve-android: https://github.com/arve-android
-.. _marcone: https://github.com/marcone
-.. _marcbonnici: https://github.com/marcbonnici
-.. _jayanthchidanand-arm: https://github.com/jayanthchidanand-arm
-.. _bytefire: https://github.com/bytefire
-.. _rupsin01: https://github.com/rupsin01
-.. _jimmy-brisson: https://github.com/theotherjimmy
-.. _ChiaweiW: https://github.com/chiaweiw
-.. _Neal-liu: https://github.com/neal-liu
-.. _amit-nagal: https://github.com/amit-nagal
-.. _Akshay-Belsare: https://github.com/Akshay-Belsare
-.. _hilamirandakuzi1: https://github.com/hilamirandakuzi1
-.. _rutigl: https://github.com/rutigl
-.. _avifishman: https://github.com/avifishman
-.. _xueliang-zhong-arm: https://github.com/xueliang-zhong-arm
-.. _raymo200915: https://github.com/raymo200915
-.. _harrisonmutai-arm: https://github.com/harrisonmutai-arm
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 654d65fd..9d6bbf6a 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -68,6 +68,12 @@ depending on project requirement and partner feedback.
 +-----------------+---------------------------+------------------------------+
 | v2.10           | 4th week of Nov '23       | 2nd week of Nov '23          |
 +-----------------+---------------------------+------------------------------+
+| v2.11           | 4th week of May '24       | 2nd week of May '24          |
++-----------------+---------------------------+------------------------------+
+| v2.12           | 4th week of Nov '24       | 2nd week of Nov '24          |
++-----------------+---------------------------+------------------------------+
+| v2.13           | 4th week of May '25       | 2nd week of May '25          |
++-----------------+---------------------------+------------------------------+
 
 Removal of Deprecated Interfaces
 --------------------------------
@@ -81,9 +87,7 @@ after which it will be removed.
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| Mbedtls-2.x                    |     2.10    |   2.10  | Support for TF-A builds with Mbedtls-2.x will be removed|
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-| STM32MP15_OPTEE_RSV_SHM        |     2.10    |   3.0   | OP-TEE manages its own memory on STM32MP15              |
+|                                |             |         |                                                         |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
 Removal of Deprecated Drivers
@@ -101,6 +105,19 @@ after which it will be removed.
 | None at this time.             |             |         |                                                         |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
+Build Options deprecated/removed
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Populated table provides details about build options that were removed or deprecated.
+
++-----------------------+--------------------------------+
+| Build Option          | Deprecated from TF-A Version   |
++=======================+================================+
+|                       |                                |
++-----------------------+--------------------------------+
+|                       |                                |
++-----------------------+--------------------------------+
+
 --------------
 
-*Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/change-log.md b/docs/change-log.md
index cfc8c564..721e0f32 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -3,6 +3,1958 @@
 This document contains a summary of the new features, changes, fixes and known
 issues in each release of Trusted Firmware-A.
 
+## [2.12.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.11.0..refs/tags/v2.12.0) (2024-11-19)
+
+The threat model for context management and the asymmetric CPU extension support
+feature is not available in the release.
+
+### âš  BREAKING CHANGES
+
+- **Bootloader Images**
+
+  - remove unused plat_try_next_boot_source
+
+    **See:** remove unused plat_try_next_boot_source ([2c303e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c303e393befcd063df60806e5208ff09958d573))
+
+### Resolved Issues
+
+- **Architecture**
+
+  - **Branch Record Buffer Extension (FEAT_BRBE)**
+
+    - allow RME builds with BRBE ([9890eab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9890eab5743629c10a3d7432cdb89b65e11c83b8))
+
+  - **Memory Tagging Extension2**
+
+    - improve ENABLE_FEAT_MTE deprecation warning ([ba65e2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba65e2d1574954cead8b474e692eef608deff4b3))
+    - remove deprecated CTX_INCLUDE_MTE_REGS/FEAT_MTE ([6f2b881](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6f2b8810f6d48bde930d4384df4b6894effcd14f))
+
+- **Platforms**
+
+  - **Allwinner**
+
+    - dtb: check for correct error condition ([7300a4d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7300a4d1676f0c929f6a41810f9bc43d4e5334eb))
+    - enable dtb modifications for CPU idle states to the rich OS ([188a988](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/188a9888e7b541299133a75b7632fdda2584833d))
+    - remove unneeded header inclusion ([8bb8f02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8bb8f02d44d1620de6c410f9091c2dd53814479e))
+
+  - **Arm**
+
+    - **FPGA**
+
+      - avoid stripping kernel trampoline ([8292f24](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8292f240e5d3fc1391cb463d068a69803b72a9e7))
+
+    - **FVP**
+
+      - add DRAM memory regions that linux kernel can share ([18ec9bd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18ec9bdc2d51f0b58d24e4a6520b2922e74e7dd8))
+      - add optee specific mem-size attribute ([75265a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/75265a16c978c75c9737e03101fb4616b0aedf7e))
+      - add secure uart interrupt in device region ([fc3a01a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc3a01aac3a8c4ba2d491e77681567a2727935e3))
+      - enable FEAT_MTE2 ([d081c61](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d081c6116e455732b579304268027b9cd98e50ff))
+      - fix the FF-A optee manifest by adding the boot info node ([bf36351](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bf36351acaa5ecef6243513d68afb083d7aba07e))
+      - update the memory size allocated to optee at EL1 ([4739372](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47393722783c4cc636244388dccd9987ecf97fa9))
+
+    - **Neoverse-RD**
+
+      - **RD-V3**
+
+        - remove NEED_* from RD-V3 makefile ([a3eef39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a3eef39f45d8e82bb306045eaf4a1f3ad37592c7))
+
+    - **TC**
+
+      - add SCP_BL2 to RSE measured boot ([7984154](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/79841546a2782c400751bdc5a4d5f8c0263b3812))
+      - add stubs for soc_css_init functions ([f5ae5dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f5ae5dcd89497d4c5e5187137a8392d4216a5aaa))
+      - correct CPU PMU binding ([7aca660](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7aca660c4e77477d81623df00fc7ffab2700dcb9))
+      - correct NS timer frame ID for TC ([034cc80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/034cc8087b249f87bfd42b99ac8553756274ee5a))
+      - don't enable TZC on TC3 ([8ce29a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ce29a74a44523ce3e56da09a7b64f415c08a20f))
+      - enable MTE2 unconditionally ([be8eaa5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be8eaa5e62d2a916c6521e1d9c17ec4698bbbb27))
+      - fix the MHUv3 interrupt name in DT ([1bf3325](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1bf33251a8fe774674205df9ea0f49d55233820c))
+      - retain NS timer frame ID for TC2 as 0 ([1ba0880](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1ba08807a58d977e2cbf0fec5ec49f29652ff997))
+
+    - **Corstone-1000**
+
+      - fix Makefile error reporting ([09bf366](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/09bf366bef9bcbf10267ec036b8de7b5b35fd58e))
+      - clean cache and disable interrupt before system reset ([335c4f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/335c4f8b301ffe0fd323a25e9995c3e0b1b8aa1d))
+      - include platform header file ([783e5ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/783e5abe94a10c9aa5c7c750ec1590f0529702fa))
+      - pass spsr value explicitly ([32690ba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32690bacb9564263f4ed23e27a1f22ba0a22bc9e))
+      - remove unused NS_SHARED_RAM region ([83c11c0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83c11c0bd119ffe8f2673aa09e17e1432b226415))
+      - update memory layout comments ([d7417ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d7417adc218c1386b30658e83ea8d4f3b7b72697))
+
+  - **Aspeed**
+
+    - **AST2700**
+
+      - fix mpll calculate statement ([aa09622](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aa09622233a891cb04c65a5db816e0dc76110e21))
+
+  - **HiSilicon**
+
+    - **Poplar**
+
+      - shutdown wdt0 before powering off ([88bc65d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88bc65d745c0c29f4d2d9a75abe3ea45a235a719))
+      - use sysctrl module to reset ([c961e68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c961e68e7990eb802d6638bc881afa3b7068e60d))
+
+  - **Intel**
+
+    - add cache invalidation during BL31 initialization ([3c640c1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3c640c124ec02f3f0e6bbc5b6d364a0b851ba1ad))
+    - add in JTAG ID for Linux FCS ([ea906b9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea906b9bb97fa6011ad974838266d5f82efc134d))
+    - add in missing ECC register ([4683946](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4683946015365e1a6e8a7fd8c8c2c72cc6043b02))
+    - add in watchdog for QSPI driver ([6704cba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6704cba25d6386469832fe82e8ec6e0fed79b0ce))
+    - bridge ack timing issue causing fpga config hung ([9a402d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a402d2f0f7e4c62c26903af1482d2f67cfa48c5))
+    - correct macro naming ([815245e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/815245e4deafc375dd62aa26821059a07e7ad2b5))
+    - f2sdram bridge quick write thru failed ([64cf9de](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/64cf9deb770ea7eccd5f92a013b67b492978aea0))
+    - fix bridge enable and disable function ([90f5283](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/90f5283ec052f622285ef35210d4bc452e4b905a))
+    - fix CCU for cache maintenance ([f06fdb1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f06fdb1469e8855e0b711ba86fde98b44f1d7736))
+    - flush L1/L2/L3/Sys cache before HPS cold reset ([7ac7dad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ac7dadb551ee602299aef91043dc4adbd234a3e))
+    - implement soc and lwsoc bridge control for burst speed ([a8d81d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8d81d61e120f2e5958f996cd59ab5219a8a3cce))
+    - refactor SDMMC driver for Altera products ([beba204](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/beba20403e23ab128711c2c8c9d480a3a40b804c))
+    - remove redundant BIT_32 macro ([7985ade](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7985aded701cc715bff2dd247680b9d0d2ffb42c))
+    - software workaround for bridge timeout ([e08039d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e08039d0e2b3ed69bf2b10592006be8008dcb398))
+    - update Agilex5 BL2 init flow and other misc changes ([b3d2850](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b3d28508427225f41d55fa3b10fe4f1f1dfbd238))
+    - update Agilex5 warm reset subroutines ([c1253b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1253b2445d6b57851118fb9cb4ee1eac9e122be))
+    - update all the platforms hand-off data offset value ([1838a39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1838a39a44a058c6fc14e045fabe433c93e609c4))
+    - update CCU configuration for Agilex5 platform ([09330a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/09330a49376306031cf92e26bbd6955ebfe87597))
+    - update mailbox SDM printout message ([569a03c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/569a03c7114f4a5c005a8cf4fa1dcae2b54bec56))
+    - update memcpy to memcpy_s ([e264b55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e264b5573952c72805a14e69e438168c00163e9a))
+    - update outdated code for Linux direct boot ([21a01da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21a01dac879daaded762f2feccccbdf6c07cf451))
+    - update preloaded_bl33_base for legacy product ([f29765f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f29765fd337cc0a405b1ffee945bc6a5db2d7e8b))
+    - update sip smc config addr for agilex5 ([7c72dfa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c72dfac962ce1e1f95be4c974b691d667a8eae4))
+    - update the size with addition 0x8000 0000 base ([9978a3f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9978a3fd8b97f024a28be798494b608f43ef5e79))
+
+  - **Marvell**
+
+    - **Armada**
+
+      - **A3K**
+
+        - reset GIC before resetting via CM3 secure coprocessor ([5993af4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5993af454fca84d1401d12eabc3c714b6b5dd953))
+
+  - **MediaTek**
+
+    - **MT8188**
+
+      - remove BL32 region protection if SPD sets to none ([207c447](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/207c4470492ea5b9554051b9abaf6cc9c1a78f35))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - disable DRAM retention by default on i.MX8MQ ([108146c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/108146ce73573ca761fb2072efef0e0c4e4d50bb))
+
+      - **i.MX 8M**
+
+        - 8mq: enable imx_hab_handler ([af79981](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af799814e2639a03b3453744f06a73e77cb66e86))
+        - ensure domain permissions for the console ([f7434fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f7434fa13507b8879922bcf0c55947e9b9606404))
+
+    - **S32G274A**
+
+      - avoid overwriting const fields ([bf01296](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bf012960d4f1490897b6a243eb89c70d6e03161f))
+      - workaround for ERR051700 erratum ([b47d085](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b47d085a3bc918d51dae48fa7bb13678f3ae14ba))
+
+  - **QEMU**
+
+    - allocate space for GPT bitlock ([e9bcbd7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9bcbd7b2ee43b3abc89f8e505b9fd5689f91aae))
+    - exclude GPT reserve from BL32_MEM_SIZE ([7604288](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7604288577bab9a1ff02fd69e07a803b808bbfae))
+    - fix build error with spmd ([1b1b40a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b1b40a941b62a845e57ca8d2bf754396b1b5dcb))
+    - fix EL3-SPMC data store alignment ([eee52da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eee52dac2c3e6b7c9ac51624c6200d2201e65bc2))
+    - fix L0 GPT page table mapping ([147b1a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/147b1a6f068bc3db73d0f945137054af83c486f5))
+    - remove validate_ns_entrypoint ([e5362e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e5362e29d556df2e4238e798513f670ca3f85aad))
+    - update rmmd_attest_get_platform_token() ([9248ee0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9248ee0cc413a209f93ee330a04890f873fec1ee))
+
+  - **Raspberry Pi**
+
+    - **Raspberry Pi 3**
+
+      - manually populate CNTFRQ reg ([11dff59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11dff5994671bf3ec4f26b7ea930bd4749658aa2))
+      - use correct define for GPIO reg_clr ([9876baf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9876baf180d307fe36ec846c03c05dd8a1b08d53))
+
+  - **Rockchip**
+
+    - add parenthesis for BITS_SHIFT macro ([901e94e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/901e94ed1a0d5e381d857e062c8b8289cfa80a48))
+    - fix "unexpected token" error with clang ([52cdebb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52cdebbcc5d1fffea7af837178a712c8d02bcdde))
+    - xlat: fix compatibility between v1 and v2 ([d43a2e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d43a2e8bf4b4434cf30296cc56fdaf15321e5e8b))
+
+  - **ST**
+
+    - set no-pie option when building ST elf file ([6d26d75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d26d75c374bc9c7aa03d8c745b9f5f9082b18c2))
+    - support device tree DDR sizes higher than 16Gbits for aarch64 ([cd9c92c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd9c92cd16b1beb6199ae7a7c01effb0d49ab448))
+
+    - **STM32MP1**
+
+      - remove unnecessary assert on GPIO_BANK_A value ([5c45768](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5c457689b283437cbf1ba87c48bae9e03a579aa8))
+      - skip OP-TEE header check if image base is NULL ([b452e7a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b452e7a8246533a4923d54cc916bdf805f9543da))
+
+    - **STM32MP2**
+
+      - enable timer earlier in BL31 ([16a659d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/16a659d73a70ce16662c0e2df4097f3496d65f63))
+      - remove mapping of BL2 DT area ([60d0758](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/60d0758411064ac67df22ade6dba460d31d00c81))
+      - set PLAT_MAX_PWR_LVL to one ([747d85e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/747d85ee77d8d8b2e04a4988f98cb2fc426103a3))
+      - use TOOL_ADD_IMG_PAYLOAD for BL31 DT ([f15f1c6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f15f1c6270d50e06eafb4202dd32326d516960f3))
+
+  - **Xilinx**
+
+    - avoid altering function parameters ([b21e287](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b21e2874f81633892e914f7d53b5bf0fe3b41a18))
+    - dcc to support runtime console scope ([238eb54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/238eb542bb746a776de82236dd25b7ae5876b743))
+    - declare unused parameters as void ([d3bb350](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d3bb350c40d202bec31dde04911f1c50d3e71634))
+    - explicitly check operators precedence ([8e9a5a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e9a5a5150c631dec09b9fea610ca3846e0dce9c))
+    - fix comment about MEM_BASE/SIZE ([1e2a5e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1e2a5e2851072803a78a8e998dee1ff4ad5b7f9b))
+    - fix logic to read ipi response ([03fa6f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03fa6f42502a3b6b318a9a73a228a6c751329a8f))
+    - fix OVERRUN coverity violation ([e27b949](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e27b9491f39c4657727d3b1641680a7e5c09a3b4))
+    - handle power down event if SGI not registered ([c3ffa4c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3ffa4c5bae5c2be313faa015bfffdb7b46c4122))
+    - map PMC_GPIO device node to interrupt for wakeup source ([692d32b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/692d32b5733b4520093ac059578b2e6c2429b80d))
+    - modify conditions to have boolean type ([e223037](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e223037525ef7b2e3794733ba417cbb848907dda))
+    - optimize logic to read IPI response ([02943d0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/02943d0d8d05e8a647a72eb11ac9159c6a257aa3))
+    - register for idle callback ([a3b0a34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a3b0a3422c3f2b2718a7f8b337d019f470101d4d))
+    - rename variable to avoid conflict ([aba5bf9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aba5bf901d775ffbf77a5034eb91f3667758a4c1))
+    - warn if reserved memory pre-exists in DT ([729477f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/729477fd86fc7c471fe44f81ed58e94d1656571f))
+
+    - **Versal**
+
+      - add const qualifier ([0f9f557](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0f9f5575cc2c5de913e4222c149146c149378728))
+      - add external declaration ([16c611f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/16c611f8a6f6a6669265fda95115a0ade56078e7))
+      - declare unused parameters as void ([ab9aab3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab9aab38d13a0905804ab5a8480dd31828d5b3ab))
+      - evaluate condition for boolean ([b39c82e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b39c82e9201255f6a396ff9a80cb2c2ec038b588))
+      - explicitly check operators precedence ([0ed8b4b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ed8b4bffc31e52facf27445503ea668e7ba3dc2))
+      - kernel QEMU boot is failing on versal platform ([8e5252f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e5252f3c08d25575fbbcbb8cb4ed3a4b0c9d506))
+      - modify conditions to have boolean type ([1247566](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12475663b53f6e5ffe18343470d653cc092aca48))
+      - remove check for bl32 load address ([4c9ae8a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c9ae8ae1f266f7558c5bcc98491a4fbb69967f5))
+      - variable conflicting with external linkage ([e452826](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e452826ad3aa595f720be2c2500ada2f27d3eaea))
+
+    - **Versal NET**
+
+      - evaluate condition for boolean ([37c46d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/37c46d85d14021fa89186d3221621658410e8720))
+      - declare unused parameters as void ([06f63f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/06f63f4b566c86209fbd13142d6c5453a6fd9c8e))
+      - explicitly check operators precedence ([a4ddd24](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4ddd24f97953b6c8ad6b9dfddc240067807c502))
+      - ignore the unused function return value ([aa6df8e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aa6df8ec32a48d8e57205b6bb93d4bc283d353f2))
+      - modify conditions to have boolean type ([83c3c36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83c3c36b1b2869ade53f36cfd9052e6b6a17797b))
+      - remove check for bl32 load address ([c38ced2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c38ced2d279a40298cab6a4c99b046146c3a1917))
+      - variable conflicting with external linkage ([4d2b4e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d2b4e4dd7ed22a41c0569f9b2b2fd5c419a8261))
+
+    - **ZynqMP**
+
+      - add const qualifier ([bb145c9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb145c9d9b543d9440b3b4fc48b8210df4b35ce9))
+      - add external declaration ([6c08d1d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c08d1df0ccb14fb66ba081bbe57ea17b8b3bb1c))
+      - declare unused parameters as void ([1c43e36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1c43e36ac18aeaa6816a0474655d699909d616b1))
+      - evaluate condition for boolean ([aaf6e76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aaf6e7627e11b1b8616d798975e40d71d1e03c8c))
+      - explicitly check operators precedence ([5b54231](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b542313f8af2373549e71266307b8fbbb8788cd))
+      - handle secure SGI at EL1 for OP-TEE ([f5b2fa9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f5b2fa90e0c0324f31e72429e7a7382f49a25912))
+      - ignore the unused function return value ([355ccf8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/355ccf895e5106d0f7a9b5932f73759277d1ab2a))
+      - modify conditions to have boolean type ([a42e6e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a42e6e44b89fb1be1d3e97e5adc4f7288bb7e69b))
+      - variable conflicting with external linkage ([eda23fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eda23fa5aa065216d9cf86176fbb916b4841c874))
+
+  - **AMD**
+
+    - **Versal Gen 2**
+
+      - add const qualifier ([a0745f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a0745f21aa0c5c869a3788e8f2c590bace11ef0b))
+      - add external declaration ([17a8f41](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/17a8f41e458e662c878fc8549d7a04a49e88abac))
+      - add ufs specific features support ([b9c20e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9c20e5d144347ca28e17df080b7ee9bf0dd9377))
+      - correct the UFS clock rates ([b048601](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b048601eeeeb34fb1e7642d1ed7f18f9a51d6ae9))
+      - declare unused parameters as void ([851df3c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/851df3c8915d5832d9ac1d58dc3420847cacb0a0))
+      - explicitly check operators precedence ([15a9e38](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15a9e381cdfc607e516f86adc118d036ce78aa86))
+      - ospi data integrity cases are failing ([a147362](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a14736268bd5156f657286b535af5d27959dec99))
+      - update check for TRANSFER_LIST macro ([7d09198](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d09198f58cefd10a9ca19305782785632ffa72a))
+      - variable conflicting with external linkage ([ca39fd4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ca39fd46c1ce0203df7f797fa6bd8a4fc5336c38))
+
+  - **Nuvoton**
+
+    - fix MMU mapping settings ([0a1df64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a1df6411734d1793e06e508f27bcf95f01c703f))
+
+- **Services**
+
+  - **RME**
+
+    - **RMMD**
+
+      - continue boot if rmmd_setup fails ([fdd8a24](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fdd8a24b9892fa0e67580dc25f7e7ca0b54c870e))
+      - fail gracefully if RME is not enabled ([eacbef4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eacbef4c643a5ee69828a7004abf0097b3d3f728))
+      - handle RMMD manifest loading failure ([0c70781](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c707813e9e734d9a62d5cdc592e68e245f4f557))
+      - ignore SMC FID when RMM image is not present ([adcd74c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/adcd74ca05fe4d7c3c047c0108cb9f136b67be49))
+      - remove the assert check for RMM_BASE ([8cb9c63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8cb9c635775b2f1c413c28ea8610dc81b6e8928f))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - use write_el1_ctx_timer() macro to set cntkctl_el1 value ([19082c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19082c20d98456d147816d8ebf01f4e6721c7b12))
+
+    - **SPMD**
+
+      - remove spmd_handle_spmc_message ([6c378c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c378c2feffd8826542322e8d2cc53fd7f0d8252))
+
+    - **SPM MM**
+
+      - carve out NS buffer TZC400 region ([1922875](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/192287523350dfdc06b794ae2fbc1827ff69ab72))
+
+  - **DRTM**
+
+    - do cache maintenance before launching DLME ([23378ae](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/23378ae0bdcdaee5764af9ebf5faed7cdb8b2737))
+    - return proper values for DRTM get and set error SMCs ([5e1fa57](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e1fa57459aa27a28bb21be5496fb471350b6046))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - modify the fix for Cortex-A75 erratum 764081 ([7f152ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f152ea6856c7780424ec3e92b181d805a314f43))
+    - workaround for Cortex-A720 erratum 2792132 ([b1bde25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b1bde25ed9b302a2203a928457c91693ed7f91a7))
+    - workaround for Cortex-A720 erratum 2844092 ([1214090](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12140908a52230081f85069f0f0a400ddabf44ef))
+    - workaround for Cortex-X4 erratum 2816013 ([1e4480b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1e4480bb54b0f567688cfbea2119aa703fcbb7b8))
+    - workaround for Cortex-X4 erratum 2897503 ([609d08a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/609d08a86db2ddf09f98105b999d57b8e2eecc8b))
+    - workaround for Cortex-X4 erratum 3076789 ([db7eb68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/db7eb68817dad1a429a2f6518926791c47091b1c))
+    - workaround for Cortex-A520(2938996) and Cortex-X4(2726228) ([4a97ff5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a97ff5111204a18b4f72d1e1cd3d8285f16289d))
+
+  - **EL3 Runtime**
+
+    - correct CASSERT for cpu data size ([483dc2e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/483dc2e43e550cf5d4541a7b164b49edbaa467e6))
+
+  - **PSCI**
+
+    - fix parent parsing in psci_is_last_cpu_to_idle_at_pwrlvl ([01959a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/01959a1656a08dacd1d036d0441165d52bf7563e))
+
+  - **ROMlib**
+
+    - prevent race condition on the build directory ([25cde5f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25cde5f810422867bf03b2c0e8354dcee2493e8a))
+    - wrap indirectly included functions ([d95d56b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d95d56bd2bfc87951f35d2badde9db336c0a6489))
+
+  - **GPT**
+
+    - fix GPT library fill_l1_tbl() function ([d024cce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d024cce376f01652b91ebdef286dceffc9ffb063))
+    - fix RME GPT library bug ([6350aea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6350aea2f186c593ef46737f573de5e4833a9433))
+
+  - **Translation Tables**
+
+    - correct attribute retrieval in a RME enabled system ([e3c0869](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e3c0869f6fbd8008b556738384e3f3a22cf981c3))
+
+  - **Authentication**
+
+    - check the presence of the policy check function ([491832f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/491832fedf979b6b0c00c5c5411780047f106804))
+    - correct RSE_CRYPTO_EXPORT_PUBLIC_KEY_SID ([759994a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/759994aa3b1ad1e54ef3a998d0685108fec6d27c))
+    - remove the bl2 static c file ([ac106f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ac106f208fad311e691b69e116632239c635a81f))
+
+    - **mbedTLS**
+
+      - fix error return code for calc_hash ([885bd91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/885bd91f27fd31d46f33861b94a814fa4537ab5f))
+      - sign verification issue with invalid Key/Signature ([7731465](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7731465252bd82ce97620a327f3b5d8905f8bdb1))
+      - add extra hash config to validate ROTPK ([014975c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/014975cea46261d84a934644be2ad53bbdc0dc79))
+
+    - **mbedTLS-PSA**
+
+      - fix P-384 PSA key signature verification ([12a8e95](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12a8e95303c051dc5671441a6419741db3b0964e))
+
+  - **GUID Partition Tables Support**
+
+    - fix unaligned access in load_mbr_header() ([21a77e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21a77e08921a13ac4adc523a136d829333a854f1))
+
+  - **Arm**
+
+    - **GIC**
+
+      - **GICv3**
+
+        - fix GITS_CTLR.Quiescent bit definition ([2da29d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2da29d2d07cdd8c52a1c1d6f26d7d45ac11ef2be))
+        - incorrect impdef power down sequence ([b1925dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b1925dcfd97a5d77a796bee8164519b4e8254d8c))
+        - wait rwp when gicr_ctrl.enablelpis from 1 to 0 ([66668c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66668c77cb140c3af1a801b8f56b0c0ec65c4c21))
+
+    - **MHU**
+
+      - fix compilation error with ENABLE_ASSERTIONS=0 option ([e2e8a39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2e8a397f88eaedb9d3f16b6b4560eec51aee7e0))
+
+    - **RSE**
+
+      - include lib-psa to resolve build ([654ae70](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/654ae705c35baa1fbd13a0cd8558a64c8454347c))
+
+  - **NXP**
+
+    - **SFP**
+
+      - shift gpio register offsets by 2 ([d30312a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d30312a2dcdbe7aa651f8770d9b00e6ae83baacc))
+
+    - **Clock**
+
+      - broken UART clock initalization ([f8490b8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f8490b85b49c92799a792587658eca4cf36fd4f6))
+      - function parameter should not be modified ([8ee0fc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ee0fc31992538823177e764e4522293ea829957))
+
+  - **ST**
+
+    - **Clock**
+
+      - adapt order of CSS on LSE and HSE ([eca5103](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eca510346d9ae7d14eea53ec01554bbde6cb2e69))
+      - display proper PLL number for STM32MP13 ([039b7d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/039b7d4673e5b39056a6c0c40204aad2b0258581))
+      - do not reconfigure LSE ([f4a2bb9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4a2bb986b43fcb1c0c8c45b5d9a93798f655453))
+
+    - **DDR**
+
+      - fix coverity issue in ddrphyinit ([5dd1d54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5dd1d5447750e1be9377ae8d1c4fce2608a53a63))
+      - move skipddc_dat definition ([13cc1a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/13cc1a506428398cc8cc142015dca10d24840f96))
+
+    - **GPIO**
+
+      - configure each GPIO mux as secure for STM32MP2 ([179a130](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/179a130aea4876c7fc89606c65b55f143724eb38))
+
+- **Miscellaneous**
+
+  - **DT Bindings**
+
+    - update STM32MP2 clock and reset bindings ([8522909](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/85229098ab70dfb65905f9ad7229db6478335a00))
+
+  - **FDTs**
+
+    - reserved memory: detect existing region ([4248806](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42488064e10383247d0c321fe1e7fc13eec0752c))
+
+  - **SDEI**
+
+    - fix a crash when attempting to bind more events than are available ([4096bd6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4096bd66c7af0a5661c7926460f2a2ca4162388d))
+
+- **Documentation**
+
+  - fix CPU type for mt8195 ([65ada75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/65ada7571781317f16240ee3694bd684fd3bdaf5))
+  - fix the example command for doc build ([9db2b05](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9db2b059eb76eaf51af8e434904caf277b998c99))
+  - point poetry readthedocs virtual env ([5383a88](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5383a88b93abead45ab3479536d1b1516d9be3f8))
+  - refactor poetry dependency group ([4a29299](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a29299f2e1640dc9f3136682b914c39930562eb))
+  - replace "ARM-TF" with "TF-A" in diagrams ([c4067a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c4067a9df6e9c478a824bd5b0ac44b84d48c9b40))
+
+- **Build System**
+
+  - correct feature assignment for ARM v8.8 compliance ([94ff1d9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/94ff1d98c95db491137177c2160ef1afe944ff5f))
+  - ensure `$(ROT_KEY)` depends on correct directory rules ([7a95759](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7a95759f935202c1f25df10eb32c67bbd69db3c8))
+  - fix incorrectly-escaped armlink preprocessor definitions ([df52e26](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/df52e2600deef3fff250d337d06f55863d1dfd76))
+  - pass the PLAT option during FIP tool compilation ([40469bf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40469bf977a615400424cdcd78c350b3310ebd2f))
+  - string split into two lines causing error ([4f32179](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f321794ffaacad74258082272163a61f3db8477))
+
+
+- **Tools**
+  - **fiptool**
+
+    - update the fiptool and certtool to fix POSIX build ([ccbfd01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ccbfd01d95b9b35acb3e2ca5f25379ce8fa0ed1c))
+
+- **Dependencies**
+
+  - **checkpatch**
+
+    - detect issues in commit message ([1a72174](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a721748605bc753089bc34c6010aa236c9d0ab7))
+### New Features
+
+- **Architecture**
+
+  - **Fine-grained Traps 2 (FEAT_FGT2).**
+
+    - add support for FEAT_FGT2 ([33e6aaa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33e6aaacf1e8f327b33fe2db1f5e964b0adb41c7))
+
+  - **CPU feature / ID register handling in general**
+
+    - add ENABLE_FEAT_LS64_ACCDATA ([19d52a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19d52a83b755cdf6d9b7defc7eb821eb62e80310))
+    - add new feature state for asymmetric features ([43d1d95](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/43d1d951ddb3b725d372884f314babb6594fcd47))
+    - upgrade PMU to v8 (FEATURE_DETECTION) ([515d2d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/515d2d46a318fa3c4c172491c6408c032e6a6b15))
+
+  - **Debug Extension (FEAT_Debugv8p9)**
+
+    - add support for FEAT_Debugv8p9 ([83271d5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83271d5a5aae06c23c59a32c30a0fe83fb82e79f))
+
+  - **Statistical profiling Extension (FEAT_SPE)**
+
+    - introduce spe_disable() function ([651fe50](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/651fe5073c790647305363a4de05cf050e0851de))
+
+  - **Trace Buffer Extension (FEAT_TRBE)**
+
+    - introduce trbe_disable() function ([b36e975](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b36e975ea374589270fc4010aa247e1e56432bda))
+
+  - **Extension to SCTLR_ELx (FEAT_SCTLR2)**
+
+    - enable FEAT_SCTLR2 for Realm world ([b17fecd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b17fecd6cf23f50346d70ec84f5708c95a2db5f8))
+    - add support for FEAT_SCTLR2 ([4ec4e54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4ec4e545c66cb888bfbedcea4030a234421457d7))
+
+  - **128-bit Translation Tables (FEAT_D128)**
+
+    - add support for FEAT_D128 ([3065513](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/306551362c15c3be7d118b549c7c99290716d5d6))
+
+  - **Translation Hardening Extension (FEAT_THE)**
+
+    - add support for FEAT_THE ([6d0433f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d0433f04045f52856ecb837efc873a5504d9fa2))
+
+- **Platforms**
+
+  - **Allwinner**
+
+    - adjust H616 L2 cache size in DTB ([ee5b26f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ee5b26fd0058d5e696cdf83bf389351eab296bf7))
+    - h616: add I2C PMIC support ([0444589](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/044458981f986b03445185b646bebbea1d90f11f))
+    - h616: add support for AXP313 PMIC ([0385136](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03851367dbd46f73708fa35da2b501489e44afa4))
+    - h616: add support for AXP717 PMIC ([646d06b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/646d06b2378b39b8dfa713b74f936a2b02782e96))
+
+  - **Arm**
+
+    - **Common**
+
+      - add support for loading CONFIG from BL2 ([973e0b7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/973e0b7f2cc9ac64132b2179295c424a88b690ea))
+      - add fw handoff support for RESET_TO_BL31 ([1a0ebff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a0ebff784c11f0b11f203b56eeb3180f994c0b9))
+      - correct the RESET_TO_BL31 x1 handoff arg ([5da68cc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5da68cc477adf0f686eeb9b6c8c53c1104805f24))
+      - load dt before updating entry point ([c1c406a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1c406a4de90b859a2e534304e33331ecd3dcef8))
+      - move HW_CONFIG relocation into BL31 ([fe94a21](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fe94a21a6815fc8623074e7184d87583f2f58940))
+      - remove critical handoff code from assert ([cca1b72](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cca1b72b3bf25dab03d3527c9fbe0f5d368382cc))
+      - makefile invoke CoT dt2c ([0e0fab0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e0fab0ca2190d75dd12b655e043ed8b6053221f))
+      - generate tbbr c file CoT dt2c ([479c833](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/479c833afcfce3afebefdc8eecefea71c09f0bf1))
+      - add COT_DESC_IN_DTB option for Dualroot ([731ac5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/731ac5ea043efb333ea74c8443c10989acce5d94))
+
+    - **FPGA**
+
+      - enable new CPU features ([1920a32](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1920a32b7fd32c22f4cef6d948c1d0be4efce0e5))
+
+    - **FVP**
+
+      - change UART0-1 to NS device region ([cd656a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd656a5612e6f6942fd8fb768b5dd948efbc37ac))
+      - add Cactus partition manifest for EL3 SPMC ([5134623](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/51346236c3f07fd86bf14f4743517ab1d15bd56c))
+      - add cpu power control ([d38c64d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d38c64d2466006104142ae23a673a9cf2b4170e2))
+      - add Dualroot CoT in DTB support ([0af86f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0af86f08ce5c39e3d53ccd9daa77084acef09fa7))
+      - add flash areas for secure partition ([9fb7676](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9fb767630dbb3a54eff17b9b9b83078a7b3e77b7))
+      - add SPM manifest for OP-TEE at S-EL1 without S-EL2/Hafnium ([41d73bf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/41d73bffe1cac198ef1f21149ac64f784f5ae8db))
+      - allow SIMD context to be put in TZC DRAM ([b4c23ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b4c23adf58dce011ce5119cfc79f4312cea855f7))
+      - fdts: add stdout-path to the Foundation FVPs ([2faccab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2faccaba80318b48e7ae738a909a38a989ed3c5e))
+      - replace managed-exit with ns-interrupts-action ([887cec9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/887cec9caedb87f824f8f35adbf058e1e83b250e))
+      - scale SP_MIN max size based on SRAM size ([3b5eca9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b5eca9e7a96f7a6f3c764fb981a3b2bfe67e514))
+      - update FF-A version to v1.1 supported by optee ([4f37e1e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f37e1e8b233a2968dd32708eef0a4a44d093b7a))
+      - remove duplicate jumptable entry ([180a3a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/180a3a9ed3e0ee80f4ed4d02d671a7b0fb28db6d))
+
+    - **Neoverse-RD**
+
+      - add a routine to update NT_FW_CONFIG in BL31 ([c6b27c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c6b27c4916d41db9a8f6be089970fa5f79634f7c))
+      - add CSS definitions for third gen platforms ([6d52713](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d5271346d38ac9899bc2f8c9fe96b32bcef05c8))
+      - add DRAM layout for third gen platforms ([10eb4c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10eb4c4bee31786800a8d61ef54d68d22db97221))
+      - add firmware definitions for third gen platforms ([e517ccf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e517ccf52cf9f2578d980b5340900fafe3e9a6e6))
+      - add MHUv3 channels on third gen multichip platforms ([47348b1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47348b1c53c1000f7b36593aa1641240d0509947))
+      - add MHUv3 doorbell channels on third gen platforms ([46d474f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/46d474fc9fc99b1d8c9e8b66514cc380ec10aa9a))
+      - add multichip pas entries ([c72e9dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c72e9dcdd872f3922eb093afbfded0dd78533cc7))
+      - add pas definitions for third gen platforms ([896e9aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/896e9aa98b5cf25a4b5e9d11a58265fdb43dca1e))
+      - add RoS definitions for third gen platforms ([fad5a20](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fad5a209a03ae7a893b8e93197ed6e795fe370a6))
+      - add scope for RD-Fremont variants ([84973bb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/84973bb3cafeb21f7c706335570fbef41ab62179))
+      - add SRAM layout for third gen platforms ([5a37d68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5a37d68c78b0c1fcd527e2d6fbc40ecf84dc0f15))
+      - allow RESET_TO_BL31 for third gen platforms ([4abcfd8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4abcfd8b2ce2fd8aad9f4de652a11a0b6a28e8dd))
+      - enable RESET_TO_BL31 for RD-V3 ([527fc46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/527fc46541b85371b01dc55e5ebc1ba92c1b6b47))
+
+      - **RD-V3**
+
+        - add DRAM pas entries in pas table for multichip ([6a9cf0e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a9cf0e5aaf6bc97b433e79c74cf4ba435c877b2))
+        - add implementation for GPT setup ([0876c74](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0876c74285377857d34701f9279cc15b60f6ac50))
+        - add support for measured boot at BL1 and BL2 ([6182950](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/61829505d2d40a1b5a3065fda53df7f6b833cdb3))
+        - add support for RD-Fremont ([c0513e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0513e0f8500d8552646f57b2a2e68113c48ad2e))
+        - add support for RD-Fremont-Cfg1 ([6a0cb48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a0cb487fd61e0c583465338bb502833803b8a5a))
+        - add support for RD-Fremont-Cfg2 ([eedb2d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eedb2d820a26300314ac81773fe597938e67698e))
+        - enable AMU if present on the platform ([faf98b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/faf98b3fe24926bd556b175ce07c97a63b058b45))
+        - enable MPAM if present on the platform ([e951985](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9519857d36517624f954b85b7f24f677fdc6765))
+        - enable MTE2 if present on the platform ([f801377](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f80137720cbe08c2de1b130b1a4ba44af037fa1d))
+        - enable SVE for SWD and NS ([7e2736b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e2736b0c1fbe5a41cd815da0b625a90f0142a57))
+        - fetch attestation key and token from RSE ([0e323ec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e323ec5c4e824c113394f87d1c77103471e8123))
+        - helper to initialize rse-comms with AP-RSE MHUv3 ([2a35fcd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2a35fcdd9faa056e182a43ea6e53dc529bfc4186))
+        - initialize GPT on GPC SMMU block ([ba35fac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba35fac174ae4a9d52625e709863b6c565608538))
+        - initialize the rse comms driver ([f546113](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f54611376113d7c0cfdfd0eb89752040deb99aff))
+        - integrate DTS files for RD-Fremont variants ([1b96641](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b966414c1a2a38a931eb4499bc209c37c4f39db))
+        - update Root registers page offset for SMMUv3 ([859355f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/859355f27598da4f9ac76c0d12d1f8db4499e131))
+        - set CTX_INCLUDE_SVE_REGS build flag for RD-V3 variants ([1551834](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/155183432afffa8dad4260b0dc4eeef60a8385cd))
+
+    - **TC**
+
+      - add default SLC policy for the gpu ([bebefe0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bebefe0f33411245325c9a25db4eb9d7cbec69fc))
+      - add device tree binding for SPE ([77080f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77080f6aaf7e1cde46a4d48a9e8eb673119dd3ff))
+      - add device tree binding for TC4 ([3cedc47](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3cedc47b1d4cf46622b4b5413fab01d3224dc872))
+      - add DSU PMU node for tc3 ([d3ae677](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d3ae67771d14e7ffa06793661833654681934d39))
+      - add dts entries for MCN PMU nodes ([1401a42](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1401a42c950751170c5cf14106d1872160d7ecea))
+      - add MHUv3 addresses between RSS and AP ([5ab7a2f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5ab7a2f2eac2b9e398d83ca2a16738f38a18baf6))
+      - add MHUv3 doorbell support on TC3 ([4f65c0b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f65c0beaad1a73e45919eb0b450a86c4f58de27))
+      - add MHUv3 DT binding for TC3 ([6c069e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c069e7168445d5fa1e1a49dbfc269faa65bfa62))
+      - add MHUv3 register addresses for TC4 ([36ffe3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/36ffe3e1be3fe91e2b709b769eb4f17545f6ce04))
+      - add new TC4 RoS definitions ([e9e83e9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9e83e96bb0f7d83dd7e8eae3a3a82f391922bd9))
+      - add NI-Tower PMU node for TC3 ([169eb7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/169eb7daf248e75d40cd72a434aedc70a3d9ebdb))
+      - add PPI partitions in DT binding ([ebc991b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ebc991b3a11a01142d8e4d71263c5a9a5f40db1b))
+      - add system generic timer register definition for TC4 ([d6b6a8b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6b6a8b7cc9fa872f752640a52b9a752fa50e3a8))
+      - add uart node in spmc manifest ([880dcd0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/880dcd0d791288dab34f9e6668f9491796ef687a))
+      - allow TARGET_VERSION=4 ([e8e1b60](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8e1b60820dcba1f2be151d296a8e81de9bed8ba))
+      - bind DPU SMMU on TC4 ([e365479](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e365479d0d89999f815ea71b1511ff7952b479e2))
+      - bind GPU SMMU on TC4 ([11ec5de](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11ec5de6957206c9b1ec84b78cccf4e876688a84))
+      - bind SCMI over MHUv3 for TC3 ([f2596ff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f2596ff1a8c0c3daddcd406a18224fce9af0f1fc))
+      - bind SMMU-600 with the DPU on TC3 FPGA ([4c6960c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c6960ca4040e5628874f48576170b6f8f3904a9))
+      - bind SMMU-700 with DPU on TC3 ([0458d3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0458d3acae25aa98f28bc0e0aa578fdce7ae92fa))
+      - change GIC DT property 'interrupt-cells' to 4 ([1300bbc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1300bbce15308868fefda1be9ee7b4fccedde951))
+      - configure MCN rdalloc and wralloc mode ([bb04d02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb04d0232e8eeb593028aa730618be35d32a4f22))
+      - enable el1 access to DSU PMU registers ([de8b9ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de8b9cedccd652c357aff5311f8d7cb9d663514b))
+      - enable Last-level cache (LLC) ([e1b76cb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e1b76cb06a70b5c3d9b46a71c26e7e889dcee91b))
+      - enable MCN non-secure access to pmu counters on TC3 ([adc91a3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/adc91a3440af73e2799023117764c6e1b1fd26fb))
+      - enable SME and SME2 options for TC4 ([9face21](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9face2123a5925619d54070d0a9e4e628084eff3))
+      - enable trbe errata flags for Cortex-A520 and X4 ([74dc801](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/74dc801d4b284e0b3829ab8ec741e0f2c311a7c2))
+      - make SPE feature asymmetric ([7754b77](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7754b770cff6fb956e0384150c1f84a1a6abc620))
+      - make TCR2 feature asymmetric ([3e8a82a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3e8a82a030735c14eab0d15fa6f65d7c3f90042d))
+      - move flash device to own node ([62269d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62269d47439e34c161f2c4990f9fdc536d82943a))
+      - provide target_locality info of AP FW components ([3201faf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3201faf3563930d90a0eb2fa6fad92f65b01101e))
+      - remove static memory used for fwu ([25a2fe3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/25a2fe3b74689614f73138d130ab0cae14269b51))
+      - setup ni-tower non-secure access for TC3 ([89c58a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89c58a5087f12f0e965ce8fdf946038d5799d07d))
+      - specify MHU version based on platform ([04085d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04085d6eb47b67833d0a5444c92c9856b38459f6))
+      - support full-HD resolution for the FVP model ([dd5bf9c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dd5bf9c5e26ea47988cde76f916495031ecc85c9))
+      - update DT for Drage GPU ([b3a4f8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b3a4f8cfcfad1df90273d0e131c2016068c57f61))
+
+    - **Corstone-1000**
+
+      - add multicore support for fvp ([16f4862](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/16f48623d8d398ec588a958accb037c6debb7f7b))
+
+    - **Automotive RD**
+
+      - **RD-1 AE**
+
+        - add device tree files ([bb7c7e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb7c7e713074e6254955e9e64386493a7ad810f1))
+        - enabling Trusted Board Boot(TBB) for RD-1 AE ([2638496](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2638496965edd80e43af71a5952e7005d1fd3e8c))
+        - introduce Arm RD-1 AE platform ([f661c74](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f661c74b528f3aee6f30a28a82e8c76ab26f35f7))
+        - introduce BL31 for RD-1 AE platform ([daf934c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/daf934ca918057b13fecfe949315e097ca358329))
+
+  - **Aspeed**
+
+    - **AST2700**
+
+      - set up CPU clock frequency by SCU ([e3d1bbd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e3d1bbdb08f643ad54e79c678d9f8cadaf63d4ce))
+
+  - **Intel**
+
+    - add build option for boot source ([ef8b05f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef8b05f559a698cdeca43b3ad287d720f0c22a8a))
+    - add in SHA384 authentication ([cab83c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cab83c34871aa3d20bab81d3fca34c3d746c3db4))
+    - add QSPI get devinfo mailbox cmd ([8fb1b48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8fb1b484ac74f945eb483453b3f7e776c13b7b90))
+    - clock manager PLL configuration for Agilex5 platform ([e60bedd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e60bedd5e134e2ad996a0d21a8170caec12c2dd2))
+    - direct boot from TF-A to Linux for Agilex ([b5c3a3f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b5c3a3fc94b43f273332518024d4955e2c54a995))
+    - enable VAB support for Intel products ([3eb5640](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3eb5640a7d9277eee80b5b31bb30230a374e0fb0))
+    - pinmux and power manager config for Agilex5 platform ([94a546a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/94a546acc4d6e659f64266d93d9e74b0a2b86f4f))
+    - update Agilex5 DDR and IOSSM driver ([ce21a1a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ce21a1a909f2ec98f83c25dd2ed3b7fedd46c46b))
+    - update BL2 platform specific functions ([fa1e92c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fa1e92c6360280447a63422b3844df5abf186577))
+    - update hand-off data to include agilex5 params ([6875d82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6875d823ede6f3668e3c176e97083dea97ab236d))
+
+  - **MediaTek**
+
+    - change log level from INFO to VERBOSE ([5f2f384](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5f2f384890c44756c6b6d946ae675d72bdadc904))
+    - configure DEV_IRQ as G1S interrupt ([240a1ec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/240a1ecd1818e3098d641bd3304acda8b1744809))
+    - move plat_helpers.h to the common folder ([b741293](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b741293f34e394dc544250b3bad39a148e206f6d))
+
+    - **MT8186**
+
+      - add common and MT8186 TRNG driver ([8c1740e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c1740e2f260e662ed13fc04e1702c20b66d459f))
+
+    - **MT8188**
+
+      - add MT8188 TRNG driver ([b88d1f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b88d1f527baa5e2666df465acb85e09a2f8c9f8b))
+      - update SVP region ID and permission ([fc77c69](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc77c69a17c6228c29113c695efc6aac1a8f6b18))
+      - update SVP region ID protection flow ([e66c4ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e66c4ea8ae2c586e648e85370c1f04c0b67bbfcb))
+      - update the memory usage for SCP core0 and core1 ([83112aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83112aa24f408fda256c536b0880df46726db593))
+
+    - **MT8192**
+
+      - update memory protect region ([7587cfd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7587cfdd96029247145d992ac042bf3af0c2f20d))
+
+    - **MT8195**
+
+      - update memory protect region ([4224783](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4224783f8403031fc12c340efdc87e3cda30fb22))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - add helper to take params from BL2 ([7eae1db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7eae1db027149e361c84395a14115324d430aa52))
+
+      - **i.MX 8M**
+
+        - **i.MX 8M Nano**
+
+          - optionally take params from BL2 ([c37a877](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c37a877e563fd3953e3ea0dc29570cbd5e13aa36))
+
+        - **i.MX 8M Mini**
+
+          - optionally take params from BL2 ([11d32b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11d32b33ea3331adf31fac7fe499176a739178b1))
+
+        - **i.MX 8M Plus**
+
+          - optionally take params from BL2 ([3d9fea9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d9fea941a3be346ea5382c69b06d05ca470903a))
+
+      - **i.MX 9**
+
+        - **i.MX93**
+
+          - optionally take params from BL2 ([02d1813](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/02d1813e8701752ec6bb23ad0c1e68be2f4b38e4))
+
+    - **S32G274A**
+
+      - add ncore support ([5071f7c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5071f7c7ee0c1ef1498d71f6ac65e71014044498))
+      - enable BL2 early clocks ([66af542](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66af5425a6c28af7f426a82af4ec7ea4049aa6f2))
+      - enable workaround for ERR051700 ([cc6e9b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc6e9b01900b0f4101e012889b19ff225ff55001))
+      - use s32cc clock driver ([f1e4ac5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1e4ac56b53029e67b2cb626b637a4bfe4904866))
+
+  - **QEMU**
+
+    - **SBSA**
+
+      - handle the information of CPU topology ([c891b4d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c891b4d83578db25d24d2a8e3e7e419e65773ac8))
+
+  - **Raspberry Pi**
+
+    - **Raspberry Pi 5**
+
+      - add PCI SMCCC support ([682607f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/682607fbd775e37fb5631508434dab9e60220c9a))
+
+  - **Renesas**
+
+    - **R-Car**
+
+      - **R-Car 3**
+
+        - populate kaslr-seed in next stage DT ([b9e34d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9e34d14c954a9af21deb70acc4579b4494824fb))
+
+  - **Rockchip**
+
+    - add RK3566/RK3568 Socs support ([9fd9f1d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9fd9f1d024872b440e3906eded28037330b6f422))
+
+    - **RK3588**
+
+      - enable crypto function ([b833bbe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b833bbe6f088e3ee78037515d6c7c5ebb6d9a0cc))
+      - support rk3588 ([e3ec6ff](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e3ec6ff4b24c7daa4dfa82709c23a22829947160))
+      - support SCMI for clock/reset domain ([04150fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04150fee44cc0dec5bbe4cce42e2b626695d6f52))
+
+  - **ST**
+
+    - add FWU with boot from NAND ([795a559](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/795a559bc59887543afa76f05397382befd14fb8))
+    - add stm32mp_is_wakeup_from_standby() ([87cd847](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/87cd847ce5640039068993868d6f853e9035c01a))
+    - manage backup partitions for NAND devices ([ae81d48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae81d48d8366bf2d7e890741bb92262b3d3a1aaa))
+    - manage BL31 FCONF load_info struct ([aa7f6cd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/aa7f6cd8b363fb97efd232991eb9ccedc2316a9d))
+
+    - **STM32MP1**
+
+      - always boot at 650MHz ([f655922](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f65592278869951330325085cf373c3306ccab57))
+      - handle DDR power supplies ([47e6231](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47e62314b6baee0e5647c903b0feeba47f804df0))
+
+      - **STM32MP15**
+
+        - remove OP-TEE shared mem ([8dd2a64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8dd2a64a12b3ee47507aab4fb0294d366a5a5159))
+
+    - **STM32MP2**
+
+      - add BL2 boot first steps ([db77f8b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/db77f8bf227b1ffc6b282408aeccc4737cb1fc78))
+      - add BL31 device tree support ([27dd11d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/27dd11dbf5a7dc3d9894e6bae9630b4e5aa36d59))
+      - add defines for the PWR peripheral ([6add715](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6add715405bd92e5f5ad59da79c3a23031162544))
+      - add fixed regulators support ([c3a7534](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3a7534167b22d6a14fb0ee224bbb7b49478a479))
+      - add fw-config compilation ([5af9369](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5af9369c6ce0beff681ce1548bb5d614c3a6a85e))
+      - add helper to get DDRDBG base address ([2fd7b23](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2fd7b230ee8605d109167e1a6f76d87c7fb132f7))
+      - add minimal support for BL31 ([03020b6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03020b6688b459da84bdb2a3fb58c99916bfd7f7))
+      - add RETRAM map/unmap capability ([52f530d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52f530d3ab9d27db653670511b238d54e212cf0f))
+      - add RISAB registers description ([631c5f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/631c5f86d5438e92e1d64e7dfdab58e92ad3e24f))
+      - boot BL33 at EL1 or EL2 ([c900760](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c900760d47d9fa9833610f5b831712cec1ba2ef2))
+      - disable unsupported features ([128df96](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/128df96579f4837ed9571a1843a5b842de52ed3c))
+      - display CPU info ([381b2a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/381b2a6b02ef5b0245f200b8c2d42a4a58cf88be))
+      - enable DDR driver ([213a08e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/213a08eb422a69bc7c95579fadf076f5af152f49))
+      - enable DDR sub-system clock ([5e0be8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e0be8c0241e5075b34bd5b14df2df9f048715d3))
+      - get chip ID ([154e6e6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/154e6e62fe851b95cd17087a8cdd53bfbb39613b))
+      - handle DDR power supplies ([e2d6e5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2d6e5e21adcf9e41a335c31d5c337c65ad0a133))
+      - improve BL31 size management ([64e5a6d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/64e5a6df4638af5a5c308c9ebd4aee5a839f7e3e))
+      - initialize gic and delay timer in bl31_plat_arch_setup ([77847f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77847f037df3e28ac221396f118e9fd4189b1894))
+      - introduce DDR type compilation flags ([d07e946](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d07e9467d375bd414fefc86dead4a833572a166a))
+      - load FW binaries to DDR ([9a0cad3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a0cad3917e6bb76694e02fd2e099ccb564a6431))
+      - load fw-config file ([a846a23](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a846a23596d97b90f203dc39aeef00c0ccd88b9d))
+      - manage DDR FW via FIP ([ae84525](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae84525f44ddfe8abd66644475899fdc19893481))
+      - print board info ([cdaced3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cdaced366844b80024a8871adcbc94fbe31f6f1b))
+
+  - **Texas Instruments**
+
+    - implement DM_MANAGED suspend ([9b7550f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9b7550f1f0caaa20acb6140211ac298e74894f22))
+
+  - **Xilinx**
+
+    - add feature check function for TF-A specific APIs ([9a0f5d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a0f5d128ac70da64bc33731c4e4b29007692cc3))
+    - add none console ([6d41398](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d41398382430134308a513c027b77ec70b03ae4))
+    - remove PM_IOCTL and PM_QUERY_DATA APIs ([924f8ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/924f8ce2e966d2ffdb2c0f29c72cb3a68d293b45))
+    - update SiP SVC version number ([c26aa08](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c26aa08bee58e81710ee9d884247fdf9b23c0022))
+    - update TF-A to passthrough all PLM commands ([4661c8f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4661c8f508d3ecdb7a258c71a26f489ea1bffc21))
+
+    - **Versal**
+
+      - add DTB console to platform.mk ([d629db2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d629db247648acdb703d841b4d3d303506af6ff0))
+      - add support for QEMU COSIM platform ([db827f9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/db827f99a0132389ab18836b9419406b45ccd11c))
+      - dedicate console for boot and runtime ([d533f58](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d533f58d556e729a5705b9f1aaeac467291dc686))
+      - deprecate build time arg VERSAL_PLATFORM ([09ac1ca](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/09ac1ca27c6497cd1e04e108d4d927500d737991))
+
+    - **Versal NET**
+
+      - add DTB console to platform.mk ([d61ba95](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d61ba95eecf61b660cc5161a7e4fd68948775e39))
+      - dedicate console for boot and runtime ([28ad0e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28ad0e0209ac38711d69384da9f706f43e4cc681))
+      - set lower cluster bus qos value ([c6f6202](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c6f62027afb2e888b0c5f1eccc42c23bab0885ef))
+
+    - **ZynqMP**
+
+      - add DTB console to platform.mk ([09a02ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/09a02ce0bd37585a85f5b3e7f8dd6d7dc82e5f14))
+      - dedicate console for boot and runtime ([4557ab6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4557ab69fe371137d44f8a0ee6bb2129886ab6cd))
+      - enable ENABLE_LTO flag ([19d8756](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19d875677e368e96ca0e96ec59e0c60a092114b4))
+      - move zynqmp platform to xlat tables v2 ([fdda980](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fdda980af4b8c8d59374785681a153afda8f71e2))
+
+  - **AMD**
+
+    - populate handoff from TL ([1fbe81f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1fbe81febd4fc69813188ceefb4cbe95a3410ed9))
+
+    - **Versal Gen 2**
+
+      - add dtb & runtime console ([1196474](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11964742d6557c314b6106a8630a3317666c708f))
+      - add dummy implementation for SCMI PD ([095a20a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/095a20a70ce55a08752214fc9eb46bffe4a44a21))
+      - add support for AMD Versal Gen 2 platform ([c97857d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c97857dba2588ce44dd1d9907797f9f4e952fea7))
+      - implement USB_SET_STATE dummy IOCTL ([282bce1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/282bce19bbdb3a95a5365a0385aecfbfa4293ae6))
+      - support dynamic XLAT tables ([9aa71f4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9aa71f48bcf98c047e920a8c671b8f5c58b57b74))
+
+- **Bootloader Images**
+
+  - add plat handler for image loading ([a03dafe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a03dafe5164fd3ec81915c49f4e50f0f927726ea))
+
+  - **BL32**
+
+    - setup GPT in BL31 in RESET_TO_BL31 boot flow ([1547e5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1547e5e66675ec11bf6dc5958d2d5cff1948cd1f))
+
+- **Services**
+
+  - **RME**
+
+    - **RMMD**
+
+      - el3 token sign during attestation ([6a88ec8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a88ec8b300ca88ba7b6ba8d9626b66a7ee87116))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - support simd context management upon world switch ([59bdcc5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59bdcc58c3948cd24428c0aef7c478128b2a0bde))
+
+    - **SPM MM**
+
+      - switch to simd_ctx_save/restore APIs ([e6e3486](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6e348689a4b25089145abb798fc2b2aabf6f90b))
+
+  - **Secure Payload Dispatcher**
+
+    - **ProvenCore**
+
+      - switch to simd_ctx_save/restore apis ([a9b64ed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a9b64ed969edffe020e2096b5006b27373218ff6))
+
+    - **Trusty**
+
+      - switch to simd_ctx_save/restore apis ([7461025](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/74610259856a1df5ca7b9516e74478bb16490a95))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - add support for arcadia cpu ([8fa5460](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8fa54607088314aa8e3db1da5649276f2544c75a))
+    - add support for cortex-a720ae ([8118078](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8118078b71583e01a486da01f1bf369b4fde3c59))
+    - add sysreg_bitfield_insert_from_gpr macro ([ad8b514](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ad8b51418e3c9e19ddc957424ab19386711ba7ee))
+
+  - **EL3 Runtime**
+
+    - **Context Management**
+      - context switch MDCR_EL3 register ([123002f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/123002f9171384d976d95935b7f566740d69cc68))
+      - introduce EL3/root context ([40e5f7a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40e5f7a58f906beef74587a06f7fc35efe20537d))
+      - add Root-Context documentation([0f3cd51](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0f3cd5150c8f530bb96b84b0ae8129f749835ba3))
+      - enhance the cpu_context memory report ([781e1a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/781e1a44e0cdbd1fd8bbd978a60dcc947eecf29e))
+      - move mpam registers into el2 context ([7d930c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d930c7e599de10bf2418cc93a176122211e7bbb))
+      - convert el1-ctx assembly offset entries to c structure ([42e35d2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42e35d2f8c0ec3b931a0da90cb0111369aecea1f))
+      - add explicit context entries for ERRATA_SPECULATIVE_AT ([59b7c0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59b7c0a03fa8adfc9272f959bd8b4228ddd2607a))
+      - remove el1 context when SPMD_SPM_AT_SEL2=1 ([a0674ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a0674ab08192e2175afe919f929c9985adc32174))
+      - support for asymmetric feature among cores ([2f41c9a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2f41c9a7be46b148d557d3d933547c6e9ad1fd40))
+      - asymmetric feature support for trbe ([721249b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/721249b0c0cce9fbe60175af6ee895e2bb7a6d10))
+      - handle asymmetry for FEAT_TCR2 ([f4303d0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4303d05ead1026ce5f97f83558f15159e7d6476))
+      - handle asymmetry for SPE feature ([188f8c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/188f8c4b6040a35adce6f6c15670f2af436df0c3))
+      - test integrity of el1_ctx registers ([7623e08](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7623e085cb5396054b72f1ea3f02e8c7a34568b5))
+      - keep actlr_el2 value in the init context ([0aa3284](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0aa3284a45ccf4405cda0bb76f6b16a33e87f222))
+
+    - **SIMD**
+
+      - add data struct for simd ctxt management ([841533d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/841533dd5345dfd7ab78effe1544dc72b6ec840d))
+      - add routines to save, restore sve state ([6d5319a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d5319afecf62f931fe03c12f2dbc398e959c7f0))
+      - add rules to rationalize simd ctxt mgmt ([3524d07](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3524d0742e6dd4e8ed9e7a11d8268a9ea2f42c6a))
+      - add sve state to simd ctxt struct ([4242262](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42422622f924b0cf636864e045e38110e97ac126))
+      - introduce simd context helper APIs ([308ebfa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/308ebfa18859c89c8b630c1c130e7002095e875f))
+
+  - **GPT**
+
+    - change the default max GPT block size to 512MB ([01faa99](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/01faa994ceb2635a175f1d299d3b2cd7afd036c0))
+    - add support for large GPT mappings ([ec0088b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ec0088bbab9335c5273e57a84b81adf2201a51db))
+    - configure memory size protected by bitlock ([d766084](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d766084fc48ed83890c63a7ef773b8fff9e4ea86))
+
+  - **C Standard Library**
+
+    - avoid CWE-190 for GENMASK macros ([1f0b6e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f0b6e756a6d1894f7ec8423fac18671b55c51af))
+    - fix MISRA 12.2 violations for BIT32 and BIT64 macros ([0605b7e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0605b7e8af4980d4e26afc6720dcbf2644633c53))
+
+  - **PSA**
+
+    - introduce generic library for CCA attestation ([98d36e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/98d36e5b02f859866da6782a8ad73b0d26d781e8))
+
+  - **Firmware Handoff**
+
+    - fix register convention r1/x1 value on transfer list ([7475815](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7475815f4b3697f6c61868e4ae6680baee8b93e2))
+    - make tl generation flexible ([2329e22](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2329e22b8bec6fdbb1b5531f3d29569519782a63))
+
+- **Drivers**
+
+  - **Generic Clock**
+
+    - add set_parent callback ([a2c6016](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a2c6016f927e4b9a23499005c63f3e46f48ff8a2))
+    - add set_rate callback ([19f9e2e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19f9e2e657918d023c9836f8330a967e97a45d7e))
+
+  - **NXP**
+
+    - add clock skeleton for s32cc ([3a580e9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3a580e9e472a5506da82227e809e0bd472dea1b1))
+    - add Linflex flush callback ([95ac568](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/95ac568b6137ee8d3a53d3ec911a7116c90e8d5d))
+
+    - **Clock**
+
+      - add A53 clock objects ([44e2130](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44e2130ab9948530cd5eb3fbd1d6d8ead6336845))
+      - add ARM PLL enablement ([b5101c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b5101c452e3fefdf4fe13d944372e5ad5d2ea5c4))
+      - add ARM PLL ODIV enablement ([84e8208](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/84e82085a1d59624ab7dc14256a152d6d7dd15f2))
+      - add CGM0 instance ([9dbca85](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9dbca85ddf0c9a7c64e4207b74c25a09fd923aba))
+      - add clock objects for ARM DFS ([44ae54a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44ae54af5cadb499cb72cc0edd71711d7a2d019e))
+      - add clock objects for ARM PLL ([a8be748](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8be748a2821355734f603342b2d2cf7105f6a30))
+      - add dependencies for the XBAR clock ([5692f88](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5692f881f5064f612719a4f6e7aa3a4abb827439))
+      - add DFS module enablement ([4cd04c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4cd04c50eb4de7dfd65f8811331f0ed3f9f4037c))
+      - add FXOSC clock enablement ([8ab3435](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ab34357497b454b2f5e505d06ce9437da7772e4))
+      - add get_parent callback ([96e069c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/96e069cb8ec72b6ac3cac0e7708749cb3fe13abb))
+      - add MC_CGM clock objects ([3fa91a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3fa91a94501ed13587132f6e2aec66a6c054c61e))
+      - add MC_ME utilities ([b8c68ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b8c68ad799523229ed7c0a9d025b22f74ffe9eed))
+      - add minimal set of S32CC clock ids ([086ee20](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/086ee20fe7ccb9dcbf6e9ee1ce529ae98e6cf977))
+      - add objects needed for DDR clock ([4a2ca71](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a2ca718571b3b46cd091cac50c83e9f76c5927b))
+      - add oscillator clock objects ([7c36209](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c36209b29da152cc5e98b6a141fe85d78fca84b))
+      - add partition reset utilities ([11a7c54](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11a7c54072f651512948446e432421ba7ee57469))
+      - add partitions objects ([af3020e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af3020e2ae86b71a87d936bb5e7181393874d708))
+      - add PERIPH PLL enablement ([8653352](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8653352ad72e0f95dfd44f2ef9d1b2406dd8dca5))
+      - add set_parent callback ([12e7a2c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12e7a2cd2f8f535dfd63834ce78e3fc248ff39f2))
+      - enable the A53 clock ([7004f67](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7004f6782e0c9c7c5875b294af049cd022695cbb))
+      - enable the DDR clock ([8a4f840](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8a4f840b1e13b0187b373e014ea314c3dabb122d))
+      - enable the XBAR clock ([b8ad880](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b8ad8800b2b13d40a6ea1e997e6feb573744665b))
+      - enable UART clock ([e4462da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e4462dae81d0674eaf07ad8fa61b25b28a209d0b))
+      - implement set_rate for oscillators ([d937351](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d9373519873b11cf7d9cad57742272c80d8967e7))
+      - refactor clock enablement ([5300040](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5300040bfd0acf0e839a9828a1a5341afc936e36))
+      - set parent for ARM PLL and MC_CGM muxes ([83af450](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83af45042debcaf76f2f898984f1b74dedc477e1))
+      - set rate for clock fixed divider ([65739db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/65739db28bf0c0d5d4daa8735a2935681f835634))
+      - set rate for clock muxes ([64e0c22](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/64e0c2260fa385bdf91d7e3471e10ab251c96644))
+      - set rate for PLL divider objects ([de950ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de950ef04f2bf71924d7ac65e86cfc0cfd97aae3))
+      - set rate for PLL objects ([7ad4e23](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ad4e2312f58606ee74ac7c655a655bd85148582))
+      - setup the DDR PLL ([18c2b13](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18c2b137f84fed5929ee5f21cbec9260670814a2))
+
+  - **ST**
+
+    - **Clock**
+
+      - add function to restore generic timer rate ([bfe8a12](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bfe8a12eea3d51c07570cce65ea7a290db0ab9ce))
+      - add STM32MP2 clock driver ([615f31f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/615f31fe40e5ebf9ecef81eb01abbe52984e093a))
+      - don't gate/ungate an oscillator if it is not wired ([f2aebab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f2aebab8591ef9370159fc9ddf976599bdef6349))
+      - update with new bindings ([ae1e503](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae1e503763c8bc52eba1a38e320539d61ebe2043))
+      - use early traces ([1a25db1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1a25db196d8fb4da379ecea43d0d004470806ee6))
+
+    - **DDR**
+
+      - add STM32MP2 driver ([79629b1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/79629b1a79bd1ee254077d4e76fea05ba73b9bab))
+
+    - **GPIO**
+
+      - add set GPIO config API ([bfa5f61](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bfa5f61b579f9eaeead1278efc5997ddd4b5543a))
+
+    - **ST PMIC**
+
+      - add STPMIC2 driver ([817f42f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/817f42f07ede5ef55dab857cde4e9601e349ad75))
+
+    - **Regulator**
+
+      - add enable ramp-delay ([6897ae8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6897ae8d0f4bba1b147f572306782b1aa6b18666))
+      - support regulator_set_voltage for fixed regulator ([156ed97](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/156ed9724f95643dd749b5ed00a7a4b92bab1c71))
+
+    - **Reset**
+
+      - add stm32mp2_reset driver ([f829d7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f829d7df7e261fb8f68e21dbceab8c77ce65aedd))
+      - add system reset management ([d91d10a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d91d10ab39b29339f1c98d95745ba98476fd7e46))
+
+- **Miscellaneous**
+
+  - **DT Bindings**
+
+    - add missing SPIx bus clocks ([c6d50c9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c6d50c9f933a0e11c419848d30ff018d404c9a42))
+    - describe ST GPIO banks and config ([deb9c86](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/deb9c864eac86b4c7a57ec5bf90d301f7f741bd0))
+    - introduce Dualroot CoT DTB ([703df3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/703df3a3ef4aafe30a3522b80ec305a9833f732d))
+    - new RCC DT bindings ([52b253b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52b253bfa2b1788d30339f75cfe39bce387496f3))
+
+  - **FDT Wrappers**
+
+    - add function to read uint64 with default value ([bc8dfca](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc8dfca64d07185304a5acfe87a039c8a6649a4c))
+
+  - **FDTs**
+
+    - add DDR4 files for STM32MP2 ([178aef6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/178aef6989395f956b0e149b2b33cdfc0ac2e854))
+
+    - **STM32MP1**
+
+      - move RNG1 to CSI to improve random generation ([d594239](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d594239d4ebf2d44521bc30ec4b59b23f08c5a36))
+      - new RCC DT bindings for STM32MP1 ([4391e5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4391e5edea930810e68d087ddeb02d06886d891d))
+      - remove PLL1 settings ([66d7c8b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66d7c8bf8ef12f3424fc6da214f9fc65d4cf82b5))
+      - remove RTC clock configuration ([703a581](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/703a581e2522bffe21b421c98994dc02aed2934c))
+
+    - **STM32MP2**
+
+      - add BL31 info in fw-config ([a370c85](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a370c856f1f7655384f8e06f7fd84ded63838c02))
+      - add clock tree for STM32MP257F-EV1 ([293a4f3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/293a4f3defe95eddaccd671783e4ff855f1d6f8b))
+      - add fw-config file ([513b5cc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/513b5cc83add907f2faa8587e1d24195294c03a5))
+      - add fw-config files for STM32MP257F-EV1 ([83f571e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83f571edb49e35855fa1ab277b3788354d6e707b))
+      - add I2C7 pin muxing ([0a08208](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a0820885d341cc26620c37f6c10ca478955d11f))
+      - add io_policies ([53e8982](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/53e89824aa2b4107a583150d1b14b855f25cd63c))
+      - add memory node ([e34839b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e34839b9a275ec9d8487875fc8ef1949a1c41665))
+      - add SD-card and eMMC support on STM32MP257F-EV1 ([1dafb40](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1dafb409ba94b3b5c8caba08f691c099e5a7433d))
+      - add sdmmc nodes in SoC DT file ([3879761](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3879761fc206d8b3c04f0fb48d811efc267c025f))
+      - add sdmmc pins definition ([6a85f67](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a85f6710fb03474d3724667e806ab7deff84814))
+      - add UART and I2C nodes for STM32MP2 ([c7cfe27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c7cfe27a2412cceef6e1e217798d2f3fc43abded))
+      - describe stpmic2 power supplies ([e974670](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e97467068a2defaea92ec6acaf76b9f416de02a1))
+      - remove pins-are-numbered ([a1a50ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1a50ef1e2f7c5aac89c65b8a7bc67b1f502f21d))
+      - update STM32MP257F-EV1 DT ([f0d6dcb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f0d6dcb2bf5e3d382c908a28d1dc670b4914d366))
+
+      - **STM32MP25**
+
+        - add DDR power supplies ([7323c7f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7323c7f9a30391f14dca7ae0627e1a3ce32b3515))
+        - add DDRCTRL and DDRPHY settings in DDR node ([56ac99a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56ac99a04cac9f29e75153c6bf84e37d2f746f0b))
+
+- **Documentation**
+
+  - add DPE to RSE design doc ([e4582e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e4582e424799c6072e03d1c6244109eb069ac4bd))
+  - add RMM option in build-options.rst ([1b7f51e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b7f51ea1662810dea4112a543f2309fe44fdca6))
+  - add RSE provided mboot backends to the threat model ([3849d27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3849d272e3b1317ad660df37f1501cb11827e600))
+  - add STM32MP2 docs links ([21b6260](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21b6260ec8d83fc9dbbfca22ef3addcf2018da9f))
+  - update mboot threat model ([07c2d18](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07c2d18f4ef6cd1ce61326e0e85d93abe8f2f4ed))
+
+- **Build System**
+
+  - add ability to define platform specific defaults ([1b2fb6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b2fb6adb53de652d3fe69984731a62da122e0da))
+  - add ctags recipes for indexing assembly files ([54b773e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/54b773e18336b2b01b52686799192808b5aa2751))
+
+- **Tools**
+
+  - **Transfer List Compiler**
+
+    - add command gen-header ([9b05c37](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9b05c3739c44418f47c2b50980fe24651a1eed1f))
+    - add host tool for static TL generation ([6ac31f3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6ac31f3e76021fed1951d8b62105e6708123f8e3))
+    - add support for tox ([38487c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/38487c7fd3f337298ceb60657a6bca5f11816b56))
+    - add creating transfer lists from yaml files ([3112099](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/311209934e78b1d7005ae48c95b0d45c08c1c728))
+    - add option to input attr as string of flag names ([4dcbba9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4dcbba98cee2260e4c4f680f6a7fda5a98fdc7d5))
+    - add option to input text instead of tag id number ([792e8e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/792e8e896f81fff3e0d75dca5f633903fa18f55e))
+
+  - **Chain of Trust device tree to C source file**
+
+    - standalone CoT dt2c tool ([4274d6f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4274d6f885f9df1845d5a6a0b4145cd2f289f4bb))
+    - fix various breakages ([73f7b7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/73f7b7ddbe9c86520c47a9ceb9dc95f224aa0bc6))
+    - use processed Device Tree source file as input ([e19977d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e19977d664027bb16324b1b5e1aaa0ca097e637b))
+    - update documentation for cot-dt2c ([b95f398](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b95f398ebd58785f29b96d94d14aec1301f42355))
+
+
+## [2.11.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.10.0..refs/tags/v2.11.0) (2024-05-17)
+
+### âš  BREAKING CHANGES
+
+- **Architecture**
+
+  - **Memory Tagging Extension2**
+
+    - Any platform or downstream code trying to use
+      SCR_EL3.ATA bit(26) will see failures as this is now moved to be
+      used only with FEAT_MTE2 with
+      commit@ef0d0e5478a3f19cbe70a378b9b184036db38fe2
+
+      **See:** remove mte, mte_perm ([c282384](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c282384dbb45b6185b4aba14efebbad110d18e49))
+
+- **Services**
+
+  - **SPM**
+
+    - **SPMD**
+
+      - Given the optimizations made in TF-A SPMD to simplify NS EL1 context
+        management, platform integrators must use SPMC binaries built by
+        picking commits after 2fc6dcfa97e05159f95859fcf68db3031586f8c7 from
+        hafnium repository.
+
+        **See:** skip NS EL1 context save & restore operations ([2d960a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d960a11601be6e7f24c38d84b2a4fdbb52efb9b))
+
+- **Drivers**
+
+  - **Arm**
+
+    - **RSE**
+
+      - remove PLAT_RSS_NOT_SUPPORTED build option
+
+        **See:** remove PLAT_RSS_NOT_SUPPORTED build option ([878354a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/878354a845cbc51c198b879d3d92ed472e21889c))
+
+  - **FWU**
+
+    - add a config flag for including image info in the FWU metadata ([11d05a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/11d05a77295885f27530cf07029ebc2b36f49918))
+    - add a function to obtain an alternate FWU bank to boot ([26aab79](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/26aab79560a2281c4207b01102495459c2bddefc))
+    - add some sanity checks for the FWU metadata ([d2566cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2566cfb896672ea07c31c37e7acd9ef77abc4fb))
+    - document the config flag for including image info in the FWU metadata ([7ae1619](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ae16196cc73a580f298734bb98f2ccb210e3ba9))
+    - migrate FWU metadata structure to version 2 ([a89d58b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a89d58bb204c00db260225859bce0b55aa5e2385))
+
+### New Features
+
+- **Architecture**
+
+  - **CPU feature / ID register handling in general**
+
+    - add cortex-a35 l2 extended control register ([a727d59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a727d59d9c1ef5ecf2f221ce289506da2011dda1))
+    - add feature detection for FEAT_CSV2_3 ([30019d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30019d8698b219d4a642dc59e7178006f59654ff))
+    - added few helper functions ([30f05b4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30f05b4f5db605ddc1a3ca0ae0cbd13ed0e728b6))
+
+  - **DynamIQ Shared Unit (DSU)**
+
+    - save/restore DSU PMU register ([f99a69c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f99a69c386ce5448edfc47eaf146d1a20ac8216e))
+
+  - **Memory Tagging Extension2**
+
+    - add mte2 feat ([8e39788](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e3978899a481484d8c60bf276be503aebd43afb))
+
+- **Platforms**
+
+  - update SZ_* macros ([6d511a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d511a8c31f0d792695566ae75c8f7b08b3b7236))
+
+  - **Arm**
+
+    - add COT_DESC_IN_DTB option for CCA CoT ([b76a43c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b76a43c9382e85969cac896cd4d5d6774d0d1553))
+    - add trusty_sp_fw_config build option ([0686a01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0686a01b0cacb9aab840a5c334409b5739a95a97))
+    - move GPT setup to common BL source ([341df6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/341df6af6eb911ffd175e129f61fc59efcf9fcea))
+    - retrieve GPT related data from platform ([86e4859](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86e4859a05614b40ff3cf38f8bd4efc856c546fe))
+    - support FW handoff b/w BL1 & BL2 ([9c11ed7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c11ed7e3e5536ad1fcb9190560e0368da9c5ab5))
+    - support FW handoff b/w BL2 & BL31 ([a5566f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5566f65fd1be689ca5c63baa1f5b61b40960c8d))
+    - add platform API that gets cluster ID ([e6ae019](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6ae019a84c4d2ad2d2825b32fbcbe304752e3ae))
+
+    - **CSS**
+
+      - initialise generic timer early in the boot ([3447ba1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3447ba1f0405a8590ec31e4b79737efe151c3d5b))
+
+    - **FVP**
+
+      - add CCA CoT in DTB support ([4c79b86](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c79b86ed6a36b572cf9e96f0269eb5dd0b46d5f))
+      - add stdout-path ([8c30a0c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c30a0c7fe0162de0618b26fb34cc91ea582e5f7))
+      - add support for virto-net, virtio-9p and virtio-rng ([51b8b9c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/51b8b9c3c46cec87ebb7b484727c80ff29d73057))
+      - added calls to unprotect/protect memory ([6873088](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6873088c2cd6983025b6777d4c3bde912eade571))
+      - delegate FFH RAS handling to SP ([d07d4d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d07d4d63374b0d155b9281f9fcaf6b44f18117c8))
+      - remove left-over RSS usage ([a1726fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1726fa7ffecdcc8f8f4d09bd0bdc97ef3b72f11))
+
+    - **Neoverse-RD**
+
+      - add scope for RD-V1 ([86a4949](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86a4949fd012a9912c8bf909d14e20657bba2240))
+      - add scope for RD-V1-MC ([6fb16da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6fb16dac6e6672040ec80f85f2f337f52cf3f3d3))
+      - add scope for SGI-575 ([18b5070](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18b50707f7732a8b3deb46d8d011566199711c0b))
+      - disable SPMD_SPM_AT_SEL2 for A75/V1/N1 platforms ([b9c3273](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9c32730e5b7efe5170ed3c0dda7ab9db397c478))
+      - disable SPMD_SPM_AT_SEL2 for N2/V2 platforms ([301c017](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/301c01748ea717d0f2cf3ba1f0a2fe389b6fb155))
+      - enable AMU if supported by the platform ([fed9368](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fed9368529e5bc2c9111ac5a743688166661fd8f))
+      - remove unused SGI_PLAT build-option ([2d32517](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d32517ce64886f154c6d509f80d0fcde05dc498))
+
+      - **SGI-575**
+
+        - remove SGI-575 from deprecated list ([f104eec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f104eecdea209af87de43c62811a0a9456f2838c))
+
+      - **RD-E1-Edge**
+
+        - remove support for RD-E1-Edge ([c69253c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c69253cc3ad3063380c8f905125fe85f6d942d09))
+
+      - **RD-N1-Edge**
+
+        - remove RD-N1-Edge from deprecated list ([78b7939](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/78b793956f3a86a3dd62394c858ae9ee41379b8b))
+
+      - **RD-N2**
+
+        - enable NEOVERSE_Nx_EXTERNAL_LLC flag ([ab2b363](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab2b3632171dd5488952ba3f68693e490857e9dc))
+        - add dts for secure partition ([49df726](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49df7261be44d5199a930c95667edb6b878355d1))
+        - enable AMU if present on the platform ([2cfedfa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2cfedfad9c2c59316adf17d4f0ee561b50a041b6))
+        - enable MTE2 if present on the platform ([3a5b375](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3a5b3753033561cb5d7cd7aace634cc66eab0fa7))
+        - update power message value to 0 ([08f6398](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/08f6398b2b9566812cd110498e3135dfc2e3e494))
+
+    - **TC**
+
+      - add arm_ffa node in dts ([4fc4e9c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fc4e9c969930d83f1144441199301d3b4b34a5a))
+      - add DPE backend to the measured boot framework ([e7f1181](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7f1181f8a7729acb07ebac86944e36932bcd09e))
+      - add DPE context handle node to device tree ([1f47a71](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f47a7133f7fe7fb038aca97fc93533964b2b429))
+      - add dummy TRNG support to be able to boot pVMs ([7be391d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7be391d1ce5683c717fcf2be584f3d294ebc2bf3))
+      - add firmware update secure partition ([d062872](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0628728a627ee11c97839640d404221a74c3a65))
+      - add memory node in the device tree ([5ee4deb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5ee4deb8e69175f57fa51519ef37e3674aa6b9a0))
+      - add PMU entry ([553b06b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/553b06b5d4f7ec8e49796e0ffdf081bf5cf30d53))
+      - add RSS SDS region right after SCMI payload ([6f503e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6f503e0eea23a2663ed5cbfe9b925e1e0d65c236))
+      - add save/restore DSU PMU register support ([b87d7ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b87d7ab13f4b03f872c3c4a3dd7c755baf3a38d3))
+      - add SCMI power domain and IOMMU toggles ([a658b46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a658b46dc74ceaa51d119bd7bd9eccdefb0cc455))
+      - add spmc manifest with trusty sp ([ba197f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba197f5f708fe8e033971c6f4d5b25f6783aaa45))
+      - add TC3 platform definitions ([62320dc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62320dc4fd2c13d9f4b227fe73cad2a79bdba42c))
+      - allow booting from DRAM ([18f754a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18f754a275083ea66823b1c9f39e234cf430140e))
+      - choose the DPU address and irq based on the target ([8e94163](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8e94163ec041f2d7df41c2dfd8625c06655ba08e))
+      - enable gpu/dpu scmi power domain and also gpu perf domain ([127eabe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/127eabeddfc4fb596a1b499fe68ee6f7e5b5b6d5))
+      - factor in FVP/FPGA differences ([1b8ed09](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b8ed0993fc5c04f76d949df7e2851e67040bbf9))
+      - get the parent component provided DPE context_handle ([467bdf2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/467bdf26b64a38cfbfb3bf8ab915eb97eb6b3037))
+      - group components into certificates ([6df8d76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6df8d7647dad5c347d363554d25e590d24eb05e5))
+      - interrupt numbers for `smmu_700` ([2c406dd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c406ddaf700e0f1c80535e309a2245b9e0bee92))
+      - introduce an FPGA subvariant and TC3 CPUs ([a02bb36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a02bb36caa521259ae57a904dedb7fd4e6a51340))
+      - pass the DTB address to BL33 in R0 ([638e4a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/638e4a92d80346b4d46ef2cc5fbb7941d1b7fd31))
+      - provide a mock mbedtls-random generation function ([a877818](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8778185d2fd2b80cee8af7879ecb92be1aa3898))
+      - share DPE context handle with child component ([03d388d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/03d388d8e3eb5c6cce65afba060a16fae83d4d12))
+
+  - **Intel**
+
+    - add in QSPI ECC for Linux ([4d122e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d122e5f199ad1531650ae11de5121057cfc0855))
+    - enable query of fip offset on RSU ([6cbe2c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cbe2c5d19c4af0ba6bbba049962bf55454da8bb))
+    - enable SDMMC frontdoor load for ATF->Linux ([32a87d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32a87d440087e0a71765a61ec341af7cfcfbda97))
+    - increase bl2 size limit ([2d46b2e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d46b2e46189120b6779cd27ec6bd6ec9901f72c))
+    - restructure watchdog ([47ca43b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47ca43bcb4565a992bf527f68e1ff60fc036fd12))
+    - support QSPI ECC Linux for Agilex ([d6ae69c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6ae69c8c69016d05d64752538aad53f319b88a2))
+    - support QSPI ECC Linux for N5X ([6cf16b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cf16b36821b9f2a60ed9abbaa593ef62b8b9f2b))
+    - support QSPI ECC Linux for Stratix10 ([8be16e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8be16e44cf0143e8651090d80bd14194aa78b1f2))
+    - support query of fip offset using RSU ([62be2a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62be2a1ae3efcba0bb8b7ec8ef73b2a0f5a437e3))
+    - support SDM mailbox safe inject seu error for Linux ([fffcb25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fffcb25c3c2171624c582d92173154f570708a9a))
+    - support wipe DDR after calibration ([68bb3e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68bb3e836e93b271f9f1c05787025dd3f04dd788))
+
+  - **MediaTek**
+
+    - remove bl32 flag for mtk_bl ([9c41cc1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c41cc182dd7acf541565ab3df7a4261fb7eaf1b))
+
+    - **MT8188**
+
+      - add secure iommu support ([5fb5ff5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5fb5ff5694c1bcf0ddfc972600b69d7494ca6645))
+      - remove apusys kernel handler usage constraints ([0c77651](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c77651fb47c7ffd4b1b37a74aea77373179ab5d))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - add 3600 MTps DDR PLL rate ([f1bb459](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1bb459c3192eb6b3fc6b9b77658d82227eae2d5))
+        - add defines for csu_sa access security ([81de503](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81de50372c9192098118fc8bddaf086a620add87))
+        - add imx csu_sa enum type defines for imx8m ([2ac4909](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2ac4909a5ec0a50a75cab9bb587fb1b8e592794d))
+        - make bl33 start configurable via PRELOADED_BL33_BASE ([9260a8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9260a8c818aadbf513b2744cad978c18d0f65a8e))
+        - obtain boot image set for imx8mn/mp ([6d2c502](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d2c502afb845e7af94c610ab5a375b868c885ba))
+
+        - **i.MX 8M Mini**
+
+          - restrict peripheral access to secure world ([1156c76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1156c76361c170c83c6b9a9dd7c22aa401a4ce2e))
+          - set and lock almost all peripherals as non-secure ([f4b11e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4b11e59b81af3e485e6992b10b50b362902eee1))
+
+        - **i.MX 8M Plus**
+
+          - restrict peripheral access to secure world ([0324081](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0324081af0105af536992c8ced2caa5a1928010f))
+          - set and lock almost all peripherals as non-secure ([cba7daa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cba7daa10576684670e06d05ff02888a5b4f16bf))
+
+        - **i.MX 8Q**
+
+          - detect console base address during runtime ([52ee817](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52ee8173041c46aafcfa43f004029dddbfa9f9b5))
+
+      - **i.MX 8ULP**
+
+        - add a flag check for the ddr status ([4fafccb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fafccb9a8f7b35406b08743f6d9c9b519b01c61))
+        - add APD power down mode(PD) support in system suspend ([478af8d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/478af8d3c34576793a820733ddba6449c2cf2fac))
+        - add i.MX8ULP basic support ([fcd41e8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fcd41e8692ce8e8fc98d069bc131820cbf83c55c))
+        - add memory region policy ([5fd0642](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5fd06421f8bf9f5b67e73828281534f14f302630))
+        - add OPTEE support ([e7b82a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e7b82a7d2fa1fc3f32724e6836b8f6078d20c103))
+        - add some delay before cmc1 access ([c514d3c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c514d3cfa7640313c4d78674df9d7cbe9227420b))
+        - add system power off support ([891c547](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/891c547e9658c1827559d8da5e3b87de5a2e9f6a))
+        - add the basic support for idle & system suspned ([daa4478](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/daa4478a3cb2f86501c37e5a301cd4d6a6e60ee6))
+        - add the initial XRDC support ([ac5d69b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ac5d69b628736f66f72e99532656105fdc07a3fe))
+        - add trusty support ([e853041](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e853041920b15b77839027ab802d0cd9a08c7c35))
+        - adjust the dram mapped region ([8d50c91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8d50c91b476474cc403c30eb6de6af28cb246e5a))
+        - adjust the voltage when sys dvfs enabled ([416c443](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/416c4433f0047a86165e450e60f93020c561151b))
+        - allocated caam did for the non secure world ([7c5eedc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7c5eedca4c7f176448e6b92eb5c22ee2ea45e70a))
+        - allow RTD to reset APD through MU ([ea1f7a2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea1f7a2e109181f19f5bdeb71533e7dfda753df7))
+        - ddrc switch auto low power and software interface ([ee25e6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ee25e6a51bf20c92471e737ccba98af4a74d1383))
+        - enable 512KB cache after resume on imx8ulp ([bcca70b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcca70b9688c5effa0731f39e2b209071f54be2c))
+        - enable the DDR frequency scaling support ([caee273](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/caee2733ba4e7a09ea656b0be85f150a275cc57c))
+        - give HIFI4 DSP access to more resources ([351976b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/351976bb063cca7866e214a6bda9302f9ab018b3))
+        - not power off LPAV PD when LPAV owner is RTD ([ab787db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ab787dba7726bdf58c15626e5cc9a3525aade8a3))
+        - protect TEE region for secure access only ([ff5e179](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff5e1793b95ed4297deae72cdb665178e6e72e44))
+        - update the upower config for power optimization ([36af80c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/36af80c2b420cb32ff57273eda0d7d0e93b49153))
+        - update XRDC for ELE to access DDR with CA35 DID ([d159c00](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d159c00532afe50686dd92215de9b420d60502f6))
+
+    - **S32G274A**
+
+      - add S32G274ARDB2 board support ([8b81a39](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8b81a39e28a087e1123271a42c04a7ce3b496a58))
+      - enable BL31 stage ([e73c3c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e73c3c3a6cbc1e81de4c9d73a5d713e6b37ae3b2))
+
+  - **QEMU**
+
+    - allow ARM_ARCH_MAJOR/MINOR override ([e769f83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e769f830d3116f49ed82769d9d731c4dca8f6188))
+    - enable FEAT_ECV when present ([1b694c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1b694c77c497cb8272c97417ef1fa4f5f9c869c1))
+    - enable transfer list to BL31/32 ([305825b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/305825b490a77e5b0ee816ea29c53bc6444a1d63))
+    - load and run RMM image ([8ffe0b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ffe0b2edea6b00c9fe7d9ecaeca43c734d3764d))
+    - setup Granule Protection Table ([6cd113f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cd113fe06fdaa67a8457391eb6bcffd295f87fd))
+    - setup memory map for RME ([cd75693](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd75693f5ed303c1366fdff9b392d766848b6b67))
+    - support TRP for RME ([ebe82a3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ebe82a392f06aa0adddf9cc5caa7af8f561b2fb4))
+    - update mapping types for RME ([a5ab1ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5ab1ef7febb2dc931cd8f7fcd76caac04d628cd))
+    - update to manifest v0.3 ([762a1c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/762a1c44b985b71495a90bc3484b576d28c8511a))
+    - use mock attestation functions for RME ([c69e95e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c69e95eed0491b481971b48f5df855402ed5392a))
+
+    - **SBSA**
+
+      - handle CPU information ([42925c1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42925c15bee09162c6dfc8c2204843ffac6201c1))
+      - handle memory information ([8b7dd83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8b7dd8397dd017b61ecda8447e8956a1d9d6d5d3))
+      - mpidr needs to be present ([4fc54c9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4fc54c99d08926c2d42173902c8aaf3862722c84))
+
+  - **Raspberry Pi**
+
+    - add Raspberry Pi 5 support ([f834b64](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f834b64f889c1c4e03e590d44a6a52e3ac79cf42))
+
+  - **Renesas**
+
+    - **R-Car**
+
+      - **R-Car 3**
+
+        - add cache operations to boot process ([7e06b06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e06b06753b12d567b6f48b6e60d6d0a56cf72e5))
+        - change CAM setting to improve bus latency of R-Car Gen3 ([e366f8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e366f8cf3349189daafb7ac2ab74d98931757a60))
+        - change MMU configurations ([5e8c2d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e8c2d8e23ca0760bca7e5b692ee95dd2871ec89))
+        - enable the stack protection ([cfa466a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cfa466ab733ff021771b94b4a98d22bfdd246139))
+        - update IPL and Secure Monitor Rev.4.0.0 ([516a98e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/516a98ef277626aa1858d9a4018d13ab2aeb39e7))
+
+  - **ST**
+
+    - add a function to clear the FWU trial state counter ([6e99fee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6e99fee43efa256bdac3b38864206c94bd9ae3c8))
+    - add logic to boot the platform from an alternate bank ([6166051](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6166051426638087b5433eff1739d26478313dff))
+    - do not directly call BSEC functions in common code ([3007c72](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3007c72844c72e0911721e499dbab37b3eca1cdc))
+    - get the state of the active bank directly ([588b01b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/588b01b5e4726cd4a6d235e9f566a546ef17f631))
+    - use stm32_get_otp_value_from_idx() in BL31 ([189db94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/189db9486ddd949f279faa970bfc1dd9cc0e3623))
+
+    - **STM32MP1**
+
+      - only fuse monotonic counter on closed devices ([d6bb94f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6bb94f3a14ddbcf44c667134ed302eff054954c))
+
+    - **STM32MP2**
+
+      - add BSEC and OTP support ([197ac78](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/197ac780d73c3421c4643e0bc02d112ceffd248f))
+      - add ddr-fw parameter for fiptool ([e494afc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e494afc05f8562455e09b4f131f2699990a744f8))
+      - add plat_my_core_pos ([d1c85da](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d1c85da8ef23a99387823272b03399a07e3a00da))
+      - add STM32MP_USB_PROGRAMMER compilation ([2e905c0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2e905c0682b4e6d2cfdbd42e41f6097b16967ff5))
+      - put back core 1 in wfi after debugger's halt ([2331a34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2331a34f783b29a9a1fe86f5142d0a359cacb259))
+      - use early traces ([47ea303](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47ea303389f6d0ac81617366973ece9d93dc49c9))
+
+  - **Xilinx**
+
+    - add handler for power down req sgi irq ([ade92a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ade92a64e4d2fbb5f246e6ad891465d10e0d9b26))
+    - add new state to identify cpu power down ([5949701](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5949701600c7f3c3a6589d0efd743615156c34b6))
+    - add wrapper to handle cpu power down req ([3dd118c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3dd118cf9d60e1eab97af505eb63a2cdc044d747))
+    - power down all cores on receiving cpu pwrdwn req ([c3280df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3280df1bb95ed09b5d5f91f8977bbe99c6a923b))
+    - request cpu power down from reset ([88ee081](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88ee0816a7429689890659f69b895ac84e48f141))
+    - send SGI to mailbox driver ([9a7f892](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a7f892e29ea81c67f6f6b1342a367234e125b63))
+
+    - **Versal**
+
+      - enable errata management feature ([d766f99](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d766f994d2bd00c538f66e95686fc47b45ccbdb9))
+      - extend platform address space sizes ([663f024](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/663f024f207bddb7b80167e661c094d77955e292))
+
+      - **Versal NET**
+
+        - add bufferless IPI Support ([511e4a4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/511e4a48ccd5e74af338041be238f5df12fffe3e))
+
+    - **ZynqMP**
+
+      - remove unused pm_get_proc_by_node() ([b03ba48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b03ba4801d39da1d5acc7a58d9c7736e57efc099))
+
+- **Bootloader Images**
+
+  - **BL32**
+
+    - create an sp_min_setup function ([a1255c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1255c758593f9f6fb85b70165fad21de7491e1e))
+
+- **Services**
+
+  - **FF-A**
+
+    - update FF-A version to v1.2 ([e830e4c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e830e4cdee3d2238314326ef8c259b35d1c4f167))
+
+  - **RME**
+
+    - build TF-A with ENABLE_RME for Armv9.2 ([7d5fc98](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d5fc98f5483efb942f7cbe4c04bf546a9a8598c))
+    - pass console info via RMM-EL3 ifc ([3290447](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/32904472cc55a4bc9d8181a389ce3419033e0101))
+
+  - **SPM**
+
+    - **EL3 SPMC**
+
+      - add support for FFA_CONSOLE_LOG ([638a6f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/638a6f8e04c543649369374492524f2952f8d6b6))
+      - add support for FFA_MEM_PERM_GET and SET ABIs ([1f6b2b2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f6b2b26535d5254d998239f232d997972d0475b))
+      - add support to handle power mgmt calls for s-el0 sp ([5917379](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59173793f47e27a66c871a0e8237e0f0d462080d))
+      - add support to map S-EL0 SP device regions ([727ab1c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/727ab1c4ab1e5ce1559fa6efec510114ce51fdf8))
+      - add support to map S-EL0 SP memory regions ([83c3da7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83c3da7711a246e04f4d0a64593fc0ab46f08bad))
+      - add support to setup S-EL0 context ([48db2b0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/48db2b0120d1726208ff38a0edf6962f55a988bf))
+      - synchronize access to the s-el0 sp context ([5ed8e25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5ed8e255096bd34d12bc6621e48cf9139bf414b2))
+
+    - **SPMD**
+
+      - add FFA_MSG_SEND_DIR_REQ2 ([cc6047b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc6047b3de52e412988f321723f67077a409e27d))
+      - add FFA_MSG_SEND_DIR_RESP2 ([0651b7b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0651b7beb7e08a01c6e28be61026b053d53308fa))
+      - initialize SCR_EL3.EEL2 bit at RESET ([8815cda](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8815cdaf57806901cfd388b8ee8c7979a8a2fe15))
+      - pass SMCCCv1.3 SVE hint to lower EL ([c925867](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c925867ec1be039abb72a7d65bff1b6a85b3d67a))
+
+  - **DRTM**
+
+    - add ACPI table region size to the DLME header ([5dde96b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5dde96b02490829d023b37931737c2ba2a6ed431))
+    - add additional return codes ([89f5c75](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89f5c753af8e5b8091543e8b1cae4d37e345ed7f))
+    - for TPM features fw hash algorithm should be 16-bits ([c86cfa3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c86cfa35975542d25d2192b81908074195aafe96))
+    - update DRTM version to 1.0 ([9c36b90](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9c36b900f904642f41e201024df584c0eaef9fc5))
+    - update references to DRTM beta0 ([b94d590](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b94d59099f0addb32389952dc6ecf35136a23859))
+    - update return code if secondary PE is not off ([bc9064a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc9064ae5c983aaca56102c2c0d3513ed022fd46))
+
+  - **ChromeOS**
+
+    - add ChromeOS widevine SMC handler ([b22e689](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b22e6898e1493eb00d0f0de6d48655d744264cb6))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - add support for Poseidon V CPU ([b77f55d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b77f55d6c7e51025d6c7ada1b4aa9506a046cf0f))
+    - support to update External LLC presence in Neoverse N3 ([6fbc98b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6fbc98b15d92d881c4fbb74fd1344f0ef3f128ad))
+    - support to update External LLC presence in Neoverse V2 ([6aa5d1b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6aa5d1b3ab7b29c85ffe05942f2991da869e7fed))
+
+  - **EL3 Runtime**
+
+    - introduce UNDEF injection to lower EL ([3c789bf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3c789bfccca548ebcbdafbc7ecb07461d9368bea))
+
+  - **FCONF**
+
+    - support signing-key in root cert node ([04ac0b3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04ac0b3c2711a4cb2f35983e91ff0ee842b52bbd))
+
+  - **OP-TEE**
+
+    - enable transfer list in opteed ([0e8def9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e8def996e73673d3e2c3d755a84e2b759ab3052))
+
+  - **PSCI**
+
+    - add psci_do_manage_extensions API ([160e843](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/160e8434baa48cc19d69913b00d2a643c788caec))
+
+  - **GPT**
+
+    - validate CRC of GPT partition entries ([7a9e9f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7a9e9f6e96a93617abd33ef48734b65ad792ec13))
+
+  - **SMCCC**
+
+    - add vendor specific el3 id ([be5b1e2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be5b1e22346c6d8ce4b0c56604c99f7a9d3676cc))
+    - add vendor-specific el3 service ([de6b79d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de6b79d8b5e15262b328051095e15ad4c67518eb))
+    - add version FID for PMF ([42cbefc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42cbefc72721a9cbf68a70d81cbcb141a2d085f1))
+
+  - **C Standard Library**
+
+    - add printf support for space padding ([0926d2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0926d2df7a5606c2b7c341d51f04a396084c39f2))
+
+  - **Locks**
+
+    - add bitlock ([222f885](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/222f885df38c3abd34ee239a721654155609631b))
+
+  - **DICE Protection Environment (Experimental)**
+
+    - add cert_id argument to dpe_derive_context() ([6a415bd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a415bd1e71ac944c0ac67507b01f251e63361c3))
+    - add client API for DICE Protection Environment ([b03fe8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b03fe8c025f1c8025e70e7289339ecbc6cf83aae))
+    - add DPE driver to measured boot ([0ae9c63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ae9c631eaa32a30df3ff10cb4f0abafccb6c409))
+    - add QCBOR library as a dependency of DPE ([c19977b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c19977be0c3654e12accd51d4aef7059411106a6))
+    - add typedefs from the Open DICE repo ([584052c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/584052c7f80b406666b9597447eeccef4d6deca4))
+
+  - **Context Management**
+
+    - report context memory usage ([bfef8b9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bfef8b908e3a3cc29656c1d30a6b53490c79539b))
+    - add documentation for context management library ([4efd219](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4efd2193621ab7b933f4edfa28888379f3e03cbd))
+
+  - **Firmware Handoff**
+
+    - add additional TE tags ([a312bfb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a312bfb34487774a0e3244266ee45f63af86e2e8))
+    - add support for RESET_TO_BL2 ([f019c80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f019c8013e9c5efeb85eec7792fe901543a5832c))
+    - add TE's for BL1 handoff interface ([0646c9b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0646c9b293a2d8cdfd4626d15395385b5c1c2a6c))
+    - add TL source files to BL1 ([469b1d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/469b1d8412a748819f8c1bf51f695f2cb9f20489))
+    - enhance transfer list library ([40fd755](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40fd755bad9411d1e9e55984107186dde4137635))
+
+- **Drivers**
+
+  - **Authentication**
+
+    - add explicit entries for key OIDs ([2b53106](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2b53106a0e91e0865bf855935de04b24ef1cfa02))
+
+    - **mbedTLS**
+
+      - update config for 3.6.0 ([55aed7d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/55aed7d798f3d48d6aa08d58eb46c4cda318bcfb))
+
+  - **Console**
+
+    - introduce EARLY_CONSOLE ([ae770fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae770fedf459d5643125d29f48659e3e936ebd2d))
+
+  - **FWU**
+
+    - modify the check for getting the FWU bank's state ([56724d0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56724d09c2c55ee2b8486b7c706f5fb9d980df88))
+    - update the URL links for the FWU specification ([e106a78](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e106a78ef00df4c70a1594a89520af07b939cd92))
+
+  - **SCMI**
+
+    - add scmi sensor support ([e63819f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e63819f2bc307e7a42d43151242009f91ceeb06b))
+
+  - **Arm**
+
+    - **SMMU**
+
+      - fix to perform INV_ALL before enabling GPC ([70d849c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70d849c14de99e7320cc381b441af8bfe2a38375))
+      - separate out smmuv3_security_init from smmuv3_init ([a23710b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a23710b4b943a15a418a5d41236b2b57bd071de6))
+
+    - **MHU**
+
+      - add MHUv3 doorbell driver ([bc17476](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc174764f0daa82128bf60163653fc20db9a7e87))
+      - add MHUv3 wrapper APIs for RSS comm driver ([4b4f850](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4b4f8505e7c58ba80a00c47a11f5feaf6d6f44f2))
+      - use compile flag to choose mhu version ([996b3af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/996b3af84cc6aeca90bc0dd3559abffd8bdc0ed7))
+
+    - **RSE**
+
+      - add defines for 'type' range and use them in psa_call() ([002b106](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/002b10604ba0b90ac6e85d445ce2184cab52e39b))
+      - adjust parameter packing to match TF-M changes ([5abcc83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5abcc83991770a2fdbcb57dfc01000c6354da915))
+
+  - **NXP**
+
+    - add Linflex driver ([306946b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/306946b01490cfe0675300412cf738840bd099ef))
+
+  - **ST**
+
+    - **BSEC**
+
+      - add driver for the new IP version BSEC3 ([ae6542f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae6542f6c7ac9224843448424d3a539733bd651b))
+      - use early traces ([cf237f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cf237f8d55255da1aad4f8dccb3110bab6060eba))
+
+    - **Clock**
+
+      - add function to control MCU subsystem ([77b4ca0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77b4ca0b2fd2c35e3bcb516078e1d9e3573172b3))
+
+    - **SDMMC2**
+
+      - set FIFO size to 1024 on STM32MP25 ([d5b4d5d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5b4d5d2e62e57acdcb2dbbcd4fe208bde92dc4c))
+
+- **Miscellaneous**
+
+  - **AArch64**
+
+    - add functions for TLBI RPALOS ([8754cc5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8754cc5d1c1b33d645b321f465bcfe61bc3915d6))
+
+  - **DT Bindings**
+
+    - introduce CCA CoT, rename TBBR ([c4b35ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c4b35cebffb0d034aa7bdba7cfdb65ba93939e35))
+
+  - **FDTs**
+
+    - **STM32MP2**
+
+      - add board ID OTP in STM32MP257F-EV1 ([88528f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/88528f55771fdc0a94b2ddd7f49f495a83044a24))
+      - add OTP nodes in STM32MP251 SoC DT file ([c238a46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c238a46a76660cbfa9ed40da4b1d0e5d477c3dd7))
+
+  - **Security**
+
+    - add support for SLS mitigation ([538516f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/538516f5d3db6e2c30dfa9f0b82859389f529e78))
+
+- **Documentation**
+
+  - update maintainer list for neoverse_rd ([2d7902d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d7902d9bf0bafceee9f571225862c476de0cdce))
+
+- **Build System**
+
+  - check that .text section starts at page boundary ([3d6edc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d6edc325c52082ab63ffd003c55a4ed875a52c5))
+  - redirect stdin to nul during toolchain detection ([b9014f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9014f858d1fd963a466228ec15572b0892a8490))
+
+- **Tools**
+
+  - **Memory Mapping Tool**
+
+    - add RELA section display ([a6462e0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a6462e05cf1cd55da44002cdede04053a928cf0a))
+
+### Resolved Issues
+
+- **Architecture**
+
+  - **Memory Tagging Extension2**
+
+    - remove CTX_INCLUDE_MTE_REGS usage ([30788a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/30788a8455779b70aebd38d53afc8aa19d776c6c))
+    - use ATA bit with FEAT_MTE2 ([ef0d0e5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef0d0e5478a3f19cbe70a378b9b184036db38fe2))
+
+  - **Performance Monitors Extension (FEAT_PMUv3)**
+
+    - fix breakage on ARMv7 CPUs with SP_min as BL32 ([e6f8fc7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e6f8fc7437f6b9483ea0463315809d7ff6d5c0ec))
+
+  - **Statistical profiling Extension (FEAT_SPE)**
+
+    - invoke spe_disable during power domain off/suspend ([777f1f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/777f1f6897b57fe98c70d17c0d318aab3b86e119))
+
+- **Platforms**
+
+  - **Arm**
+
+    - move console flush/switch in common function ([6bdc856](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6bdc856bc9135db420196683501b4f201b30ae3a))
+    - only expose `arm_bl2_dyn_cfg_init` to BL2 ([3b48ca1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b48ca17f350d8b0999e89e8d9215993701e16a0))
+
+    - **FVP**
+
+      - added ranges for linux ([b7491c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7491c77d7ad2991b8c7c01f0311ebb3b0eca397))
+      - don't check MPIDRs with the power controller in BL1 ([6d8546f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d8546f9fc49a03a817b15b20a9d62fadda74b9c))
+      - permit enabling SME for SPD=spmd ([0b0fd0b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0b0fd0b47616b706e2f07c6da548cdc913fecd17))
+
+    - **FPGA**
+
+      - halve number of PEs per core ([70b9204](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70b9204e6f98f1ec4f0529e8c1c88e8ece490d22))
+
+    - **Neoverse-RD**
+
+      - **SGI**
+
+        - align to misra rule for braces ([cacee06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cacee0605684a75bbe8783c74fddba97b9abcffa))
+        - apply workarounds for N2 CPU erratum ([7934b68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7934b68af6b446783823a114f25c3be06244c0e4))
+        - increase BL31 carveout size ([0737bd3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0737bd33faba5c9e6a0e98969e015430e2782332))
+        - reduce cper buffer carveout size ([f10d3e4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f10d3e4953741eb3be1f9e4c09e7420554a0f050))
+        - update spi_id max for sgi multichip platforms ([89d8577](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/89d857780c50bddf94db26f158c008b4cc846edf))
+
+      - **RD-N1-Edge**
+
+        - update RD-N1-Edge's changelog title ([d239ede](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d239edea5644657ac72458cc13e3ce6bb5754ff8))
+
+      - **RD-N2**
+
+        - populate TOS_CONFIG only when SPMC_AT_EL3 is enabled ([10dcffe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10dcffedb36a658cf8a3389fbdeb499d4e7e4446))
+
+    - **TC**
+
+      - correct interrupts ([d2e44e7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2e44e7d71863e3b302b5e72c8262bb0f3964fe6))
+      - do not enable MPMM and Aux AMU counters always ([fc42f84](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc42f84560d33c53b248e14913bbd6a69a8d310a))
+      - do not use r0 for HW_CONFIG ([a5a966b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5a966b12d9fe51a337db3204e7463ad95ba99c6))
+      - enable FEAT_MTE2 ([154eb0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/154eb0a22fa0a88d1f46e3674e3979626a83e063))
+      - guard PSA crypto headers under TF-M test-suite define ([d2ce6aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2ce6aa066ce1539908726de0d94a59c16634c4a))
+      - increase BL2 maximum size limit ([19258a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/19258a5839cae9a81fb7256fbea34ff118220161))
+      - increase stack size when TRUSTED_BOARD_BOOT=0 ([44ddee6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/44ddee6f0a993ed5b3409e6626c0c70b7ed7d7a2))
+      - missing device regions in spmc manifest ([5e47112](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5e4711208db622ff6150e69c87962b506742a544))
+      - remove timer interrupt from G1S ([9bf31a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9bf31a59d187f6537066f05677972d9767e96c82))
+
+  - **Intel**
+
+    - add HPS remapper to remap base address for SDM ([b727664](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b727664e0dcf62be39552521c451ecde02091917))
+    - bl31 overwrite OCRAM configuration ([cfbac59](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cfbac59590056e6b639aed56a1da480cd46f6f3e))
+    - fix hardcoded mpu frequency ticks ([150d2be](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/150d2be0d2d440011c91c9bf8013a1ab602b464c))
+    - read QSPI bank buffer data in bytes ([2f17ac0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2f17ac01adf28edb90a5ec8f446be1be76971b5c))
+    - revert back to use L4 clock ([d0e400b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0e400b3c626be647b9a20bc4f4869e20cc15dde))
+    - revert sys counter to 400MHz ([460692a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/460692afb5b934720b69c410e3b02c540a3b1ddf))
+    - temporarily workaround for Zephyr SMP ([68820f6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68820f642191cef67df38516ef1c2ed1411c579f))
+    - update DDR range checking for Agilex5 ([f4aaa9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f4aaa9fd6e6b4edd03976680b94e1c24aa582a68))
+    - update fcs crypto init code to check for mode ([b0f4478](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0f447897d3e2ddd72b291cb450165f4d220663e))
+    - update fcs functions to check ddr range ([e8a3454](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8a3454cb74a9b55c0cb678d47a8553ece660439))
+    - update from INFO to VERBOSE when print debug message ([56c8d02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/56c8d022b00ba212f3e21dcfab20c14f3a44eec4))
+    - update HPS bridges for Agilex5 SoC FPGA ([2973054](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2973054d9b4ba4fbcad7e04303ce8e0838b2f2b3))
+    - update individual return result for hps and fpga bridges ([82752c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/82752c412362607549068d1c10cf7688f309d249))
+    - update nand driver to match GHRD design ([a773f41](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a773f4121b3064fba24631e980c6226f23378e06))
+    - update stream id to non-secure for SDM ([8fbd307](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8fbd3073cacfc7a23efdfda4eecfaf6607515306))
+    - update system counter back to 400MHz ([a72f86a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a72f86ac4208e2aae5da83229cdd9ac97f651e36))
+
+  - **NXP**
+
+    - **i.MX**
+
+      - **i.MX 8M**
+
+        - align 3200 MTps rate with U-Boot ([060fe63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/060fe63337097c6cadea76ef5d2d383f0d90ef01))
+        - fix CSU_SA_REG to work with all sa registers ([c13016b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c13016bac6a6960acbbfb3e0176e1894a7e9fa3a))
+        - handle 3734 in addition to 3733 and 3732 MTps rates ([cb60a87](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cb60a876efc156c87afcd5ec53b9cf356f30211d))
+
+        - **i.MX 8M Plus**
+
+          - uncondtionally enable only the USB power domain ([ae6ce19](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae6ce196df5b932f38c543cd8c6d8d86ee600009))
+
+      - **i.MX 8ULP**
+
+        - add sw workaround for csi/hotplug test hang ([e1d5c3c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e1d5c3c8f435424394367e2ff19240b1b8a3073c))
+        - fix suspend/resume issue when DBD owner is s400 only ([68f132b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68f132b88bb24277ee34d5c3c94d16c26d7d4545))
+        - increase the mmap region num ([047d7d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/047d7d1ba2fc84d8377156f7f45d2d69c3cb5f84))
+
+  - **QEMU**
+
+    - disable FEAT_SB ([59bdb42](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59bdb426d300a6350334523a8dbc3fa6ae9f3bfc))
+    - increase max FIP size ([f465ac2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f465ac221001f82bed907be356917675645d92eb))
+
+  - **Raspberry Pi**
+
+    - consider MT when calculating core index from MPIDR ([6744d07](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6744d07d9475adb49352fa57aa72fce17a95d757))
+
+  - **Renesas**
+
+    - **R-Car**
+
+      - fix implicit rule invocations in tools ([e068a7c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e068a7ca860f35a171f608d55fb8a2a00ebd7561))
+
+      - **R-Car 3**
+
+        - change RAM protection configurations ([e9afde1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e9afde1a2e311df0197a8e9102ef535382aef228))
+        - fix load address range check ([4f7e0fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4f7e0fa38fdb6a25b07afafff492985bcc4e63a0))
+
+  - **Rockchip**
+
+    - add support for building with LTO enabled ([e5e9ccd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e5e9ccdb0c070d3066e7d778e5e2b563acd7ba98))
+    - fix documentation in how build bl31 in AARCH64 ([6611e81](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6611e81e14ed4aa16844e3865fd8a9f6fa99a074))
+
+    - **RK3328**
+
+      - apply ERRATA_A53_1530924 erratum ([dd2c888](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dd2c888606dcdd638354c6345e08d4415d9d09fd))
+
+  - **ST**
+
+    - **STM32MP2**
+
+      - add missing include ([cb0d6b5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cb0d6b5b5f7530335eac3c387bbb82d86608b0ea))
+      - correct early/crash console init ([4da462d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4da462dcdc2e435c8b732f3ceff4c94ca28b4c43))
+
+  - **Texas Instruments**
+
+    - do not stop non-secure timer on world switch ([d2e1f6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2e1f6a8811e52505556f7b91156499d82488751))
+
+    - **K3**
+
+      - increment while reading trail bytes ([0bdaf5c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0bdaf5c804f852fe21f6172e436524157c9f6919))
+
+  - **Xilinx**
+
+    - add console_flush() before shutdown ([7ec53af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ec53afaade308b35f546480990dbc9304e06e7d))
+    - add FIT image check in DT console ([e2d9dfe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e2d9dfe2bffe4fde28f2714058c8c882ea90102a))
+    - add FIT image check in prepare_dtb ([046e130](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/046e1304721e8bbf3d304dac22aa290bcbb0d10c))
+    - check proc variable before use ([652c1ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/652c1ab1526877d3505218f87ea96e6a9b2ccc11))
+    - deprecate SiP service count query ([6a80c20](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a80c20eff74054c28273b42f3fe8e1a8fc5add4))
+    - fix sending sgi to linux ([427e46d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/427e46ddea1e528d4c57b1d8215482055bd79c3e))
+    - follow MISRA-C standards for condition check ([655e62a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/655e62aa5bede7ace8f8c6df571707aca9d6e14f))
+    - rename macros to align with ARM ([7995319](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/79953190bc856ac3f47281029a80e5129bb4437d))
+    - update correct return types ([8eb6a1d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8eb6a1da1229b8f0bff33293cbb86ce20d09259d))
+
+    - **Versal**
+
+      - initialize cntfrq_el0 register ([f000744](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f000744e0f501c89fb2240b47e91c261e3082249))
+
+      - **Versal NET**
+
+        - setup counter frequency ([07625d9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07625d9dd42d81c0e15f101fc0b6efa1c784b6f4))
+        - use arm common GIC handlers ([b225926](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b2259261815961042d2a994401929bc76a0d3ee9))
+
+    - **ZynqMP**
+
+      - resolve null pointer dereferencing ([20fa9fc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/20fa9fc82334c67834eb22e20a3f4a07bcbe069d))
+
+  - **Nuvoton**
+
+    - gfx frame buffer memory corruption during secondary boot ([ae2b4a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae2b4a5494f9b4985fc2434e543ab0921e3b5a34))
+    - prevent changing clock frequency ([fe8cc55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fe8cc55a0cb5e47a0c0e28b147ee3e8dfdae07b2))
+
+- **Bootloader Images**
+
+  - **BL1**
+
+    - add missing `__RW_{START,END}__` symbols ([d701b48](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d701b48eef4bb4b4b13ce5ef4091a37047e49a0b))
+    - add missing spinlock dependency ([e40b563](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e40b563e87fd4ff58474a289909a1827c8d2bca7))
+
+  - **BL2**
+
+    - make BL2 SRAM footprint flexible ([e0e03a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0e03a8d8b7eac45606812d1f2a9685b51e44515))
+
+- **Services**
+
+  - **FF-A**
+
+    - add NS memory node to fvp_spmc_optee_sp manifest ([92bba3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/92bba3e711a21f2d31842bee64a1bd87e4b65414))
+
+  - **RME**
+
+    - **RMMD**
+
+      - avoid TRP when external RMM is defined ([57bc3c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/57bc3c40560285e6029742b7360f8a0d0ac2346c))
+      - fix bug, raised by coverity, when zeroing manifest struct ([83a4e8e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83a4e8e0c69c64219e4d9de6c7f51fb10e3adc5a))
+
+  - **SPM**
+
+    - add device-regions used in tf-a-tests ([45716e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/45716e377ecb30c17aa3b375ce1e232d15492b9c))
+    - not defining load-address in SP config ([04e7f80](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04e7f80823e8a083138dd25963a5509bacd93257))
+    - reduce verbosity on passing tf-a-tests ([29872eb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/29872eb330201334fcb8e418b7dc7ae8ff0dc192))
+    - silence warning in sp_mk_generator ([6a3225e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a3225e2277df18e5c3aceb6173579cccefece51))
+
+    - **EL3 SPMC**
+
+      - add datastore linker script markers ([ba33528](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ba33528a00bb83f5562918131cb37574fc287193))
+      - fix dangling pointer in FFA_CONSOLE_LOG ([83129bc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/83129bcd8e75f1ffbfc9a3bae3d60749b1d22fe3))
+
+    - **SPMD**
+
+      - register group0 handler only if supported ([fca5f0e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fca5f0ebe5c2b5cf1c9d5096db6001a60ff7e089))
+      - skip NS EL1 context save & restore operations ([2d960a1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d960a11601be6e7f24c38d84b2a4fdbb52efb9b))
+
+- **Libraries**
+
+  - **CPU Support**
+
+    - workaround for Cortex-A520 erratum 2630792 ([f03bfc3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f03bfc304599540d859c4a07ac85d1bd9ae2c4f0))
+    - workaround for Cortex-A520 erratum 2858100 ([34db353](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/34db3531ba085f111274b3b8e18476c4a392c245))
+    - workaround for Cortex-A710 erratum 2778471 ([c9508d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c9508d6a1062ec3de4baaa3bd79ceed13eb972ad))
+    - workaround for Cortex-A715 erratum 2331818 ([53b3cd2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/53b3cd2532dbdb794ddfedcc8a3985d2404eb6f7))
+    - workaround for Cortex-A715 erratum 2344187 ([33c665a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33c665ae955fe5f5ae255f56ef6cdf073a9f601f))
+    - workaround for Cortex-A715 erratum 2413290 ([15a0461](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15a04615bb6834d93ab0077b89726dc17e3ba8b0))
+    - workaround for Cortex-A715 erratum 2420947 ([1f73247](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f732471320cee7b4f355ecff7dcfab7018e48ae))
+    - workaround for Cortex-A715 erratum 2429384 ([262dc9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/262dc9f76086970dab3dc43815890bed0ea29c79))
+    - workaround for Cortex-A715 erratum 2561034 ([6a6b282](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6a6b282378340dc61cf088ff5a06770cf68f44d8))
+    - workaround for Cortex-A715 erratum 2728106 ([10134e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10134e3556ca61e670017e681eb637889b1bd4f8))
+    - workaround for Cortex-A720 erratum 2926083 ([152f4cf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/152f4cfa16bc3d2786f598390450af38f4b2d0be))
+    - workaround for Cortex-A720 erratum 2940794 ([7385213](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7385213e602465d27530015a9b28ebc36a77b1c1))
+    - workaround for Cortex-A78C erratum 2683027 ([68cac6a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68cac6a0f273dbe4f44563b467c996fafef07016))
+    - workaround for Cortex-A78C erratum 2743232 ([81d4094](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81d4094d637871ff34ddd7c2e2b3e842915f30f5))
+    - workaround for Cortex-X2 erratum 2778471 ([b01a93d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b01a93d7789a794ef0635e0a7b0e7e53cc8519e5))
+    - workaround for Cortex-X3 erratum 2266875 ([a65c5ba](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a65c5ba351178e6119299fa935a3576453cf900b))
+    - workaround for Cortex-X3 erratum 2302506 ([3f9df2c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3f9df2c6ad053172c5dab74cd12d82a5b2c93c34))
+    - workaround for Cortex-X3 erratum 2372204 ([7f69a40](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f69a40697c3cc64e3fc553f6b50c72b97238dc9))
+    - workaround for Cortex X3 erratum 2641945 ([c1aa3fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1aa3fa5555250dfbcae99fb6944ad24c4ee6a0b))
+    - workaround for Cortex X3 erratum 2743088 ([f43e9f5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f43e9f57dc37a806bcd5e25a46b9f9bb1f365a64))
+    - workaround for Cortex-X3 erratum 2779509 ([355ce0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/355ce0a43abc1559b072b9cd9905f5194a6f0b86))
+    - workaround for Cortex-X4 erratum 2701112 ([cc41b56](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc41b56f41af14b00ce9f5c802e2f883786cef38))
+    - workaround for Cortex-X4 erratum 2740089 ([c833ca6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c833ca66a6fecbc54e038164e466be677559ec4e))
+    - workaround for Cortex-X4 erratum 2763018 ([4731211](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47312115dea140dd7ba26cf0512856a41f3e3067))
+    - workaround for Neoverse V1 erratum 2348377 ([71ed917](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/71ed91733140c82a392161c81869fcadb445c01a))
+    - workaround for Neoverse V2 erratum 2618597 ([c0f8ce5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0f8ce5379a77e61e89d91e225784801e5bbd3e0))
+    - workaround for Neoverse V2 erratum 2662553 ([912c409](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/912c4090fff207b445dde4bff72cc9b6e057e8b7))
+    - workaround for Neoverse V2 erratum 3099206 ([8815cda](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8815cdaf57806901cfd388b8ee8c7979a8a2fe15))
+    - add Cortex-A520 definitions ([ae19093](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae19093f2aa6dd95cc7819accb0d05c0ebe4eeb3))
+    - workaround for Cortex-A715 erratum 2413290 re-factored with ENABLE_SPE_FOR_NS=1 ([bd2f7d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bd2f7d325826f75acd729d4ee2719fd6130a7c5e))
+    - fix a defect in Cortex-A715 erratum 2561034 ([57ab6d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/57ab6d897656f71d229268d80e41b26e62179400))
+    - add erratum 2701951 to Cortex-X3's list ([106c428](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/106c4283a564e4f37976ebc7dd8bc7d35f6592e4))
+    - update status of Cortex-X3 erratum 2615812 ([f589a2a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f589a2a5f1b032ff3a09a419e49db0b97ccd8595))
+    - fix incorrect AMU trap settings for N2 CPU ([54b86d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/54b86d47eb05f09330df57519b7d04b9968890e5))
+    - correct variant name for default Poseidon CPU ([61a2968](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/61a29682c66d0437806f81fb8ab0e3ff321dfe04))
+    - check for SCU before accessing DSU ([5b5562b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b5562b2e5855f949f1fc0579d7aff15e6b274ef))
+
+  - **EL3 Runtime**
+
+    - **Context Management**
+
+      - add more feature registers to EL1 context mgmt ([d6c76e6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6c76e6c65429326e7572e10f521dd9108a3a1e3))
+      - add more system registers to EL1 context mgmt ([ed9bb82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ed9bb824e4a3815e60acaa69ed66796279f4afbf))
+      - hide `cm_init_context_by_index` from BL1 ([a6b3643](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a6b3643c2a1a95146e93c8b6f07c2e491a1230d6))
+      - remove ENABLE_FEAT_MTE usage ([a796d5a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a796d5aa11b25622841cd2283630ff9348eed699))
+      - save guarded control stack registers ([6aae3ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6aae3acfd0d48e49e2367e6cd883dda7dca974c8))
+      - update gic el2 sysregs save/restore mechanism ([937d6fd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/937d6fdb70cd24602fd2638a5dbd5c46d32559c1))
+      - couple el2 registers with dependent feature flags ([d6af234](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d6af23443179f6d2239c7f5f190f0d8828bd68cf))
+      - move EL1 save/restore routines into C ([59f8882](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/59f8882b44845ab865e354eeda8ce653f5d5fcf3))
+
+  - **FCONF**
+
+    - boot fails using ARM_ARCH_MINOR=8 ([0c86a84](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c86a846d9149ee5af7e1ee4bb185c532ed9d0f8))
+
+  - **OP-TEE**
+
+    - set interrupt handler before kernel boot ([0ec69a5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ec69a5bfbfcdf4566db8e96adaf29ad847d3d58))
+
+  - **PSCI**
+
+    - fix parent_idx in psci_validate_state_coordination ([412d92f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/412d92fdfd28d2f850a48e5f0aee95faa894a556))
+    - mask the Last in Level nibble in StateId ([0a9c244](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a9c244b05ef2d2d4b946ba81bb9b9584b479b48))
+
+  - **GPT**
+
+    - declare gpt_tlbi_by_pa_ll() ([832e4ed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/832e4ed520d5ed7e64249fe98c1ffb4550db5eca))
+    - unify logging messages ([b99926e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b99926ef7b287738c4b4a87ee7ab4eaed1e4038f))
+    - use DC CIGDPAPA when MTE2 is implemented ([62d6465](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62d64652134ca1d3ea68da65ea9e4ae136f6c44e))
+
+  - **C Standard Library**
+
+    - add memcpy_s source file to libc_asm mk ([99db13b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99db13bfaa5b11345730937c2e0e56cb670c01a5))
+    - memset inclusion to libc makefiles ([84eb3ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/84eb3ef6c9f596e968b4f9b83a3a01deda2a8a9d))
+
+  - **PSA**
+
+    - fix static check failure ([bc0ff02](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc0ff02cbb046388eff1a95efd0043757d6ac317))
+
+  - **Context Management**
+
+    - align the memory address of EL2 context registers ([8c56a78](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8c56a78894ddc69167bc093fe19f173feced720c))
+
+  - **Firmware Handoff**
+
+    - correct representation of tag_id ([d594ace](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d594ace68d4fa62cf2f1d5d13503b737b85924e5))
+
+  - **Exception Handling Framework (EHF)**
+
+    - restrict secure world FIQ routing model to SPM_MM ([7671008](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7671008fcfc826dbc3166ff1bdbb9cd7fbc7f68b))
+
+  - **SMCCC**
+
+    - correctly find pmf version ([62865b4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/62865b4ee455806e37a9c5bd52255b8c09cf1a1a))
+
+- **Drivers**
+
+  - **Measured Boot**
+
+    - add missing image identifier string ([a8a09e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8a09e3141354b159e7699d7c9c325bdd817b1f5))
+
+  - **SCMI**
+
+    - induce a delay in monitoring SCMI channel status ([af1ac2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/af1ac2d7db47717bc69afd69b56f398aa34b2fb6))
+
+  - **Arm**
+
+    - **GIC**
+
+      - **GICv3**
+
+        - **GIC-600**
+
+          - workaround for Part 1 of GIC600 erratum 2384374 ([24a4a0a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/24a4a0a5ec25e179f2e567a6e13a9b5c87db1b81))
+
+      - **GICv2**
+
+        - fix SGIR_NSATT bitshift ([eef240c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/eef240cfdedcc59f09dd5cd942448c5dcecc75d6))
+
+    - **MHU**
+
+      - use MHUv2 if PLAT_MHU_VERSION undefined ([c34dd06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c34dd06a843d71cdba2fa1c3c9067f6f130a0c73))
+      - provide only the usable size of memory ([5cd1084](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5cd10848be4f6ac19daa66803c3d512e3eea4266))
+
+    - **RSE**
+
+      - fix bound check during protocol selection ([f754bd4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f754bd466749a9338561f991bfb85140dd034e03))
+
+  - **Renesas**
+
+    - **R-Car3**
+
+      - add integer overflow check ([ef38fb1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef38fb1f5a5f2bdb897158e4244a1eddd2396eeb))
+      - add integer overflow check ([93b8952](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/93b8952eefa14141c142070a71fc017736c8910c))
+      - check "rcar_image_number" variable before use ([b469880](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b469880e3b6b26849c3d43d3fe88a755a25249bc))
+      - check for length underflow ([9778b27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9778b270e29bac3e16f57f9557098c45858c05de))
+      - check loaded NS image area ([ae4860b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ae4860b0f5c283aeca4def1449f0293ef22ff508))
+
+  - **USB**
+
+    - add missing include ([f84f21f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f84f21fa8d17662dcdc6b0b8b0caca4a45cd9ccd))
+
+- **Miscellaneous**
+
+    - **TBBR**
+
+      - move rotpk definitions out of arm_def.h ([0f0fd49](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0f0fd499dedd799e19279f0aa1f4f686085a944a))
+
+    - code coverage optimization fix ([152ad11](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/152ad112d73402523302f3cb252aee0efc145736))
+    - fix MISRA defects ([c42d0d8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c42d0d8754ae8818a7e7a63e873ca7699a7f102b))
+    - static checks on spmc dts ([c35299d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c35299d6b4e8b2757e47dc4c5a3b2e0836f89a7d))
+
+- **Documentation**
+
+  - revise the description of REGISTER_CRYPTO_LIB ([5710229](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5710229f9e837f28e4bafee6b51e828f901bf3f1))
+  - typo in the romlib design ([3b57ae2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b57ae23e0891e44d5b648575b80cbad4fc10405))
+
+- **Build System**
+
+  - add forgotten BL_LDFLAGS to lto command line ([49ba1df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49ba1df52204e721f06a6da76ef0f8692ce1b2f8))
+  - don't generate build-id ([304ad94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/304ad94b34c2117823169a199558e7484139caa1))
+  - don't rely on that gcc-ar is in the same directory as gcc ([7ef0b83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ef0b8377fa7fb3697dda5adfa44dafd7e14150f))
+  - enforce single partition for LTO build ([31f80ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/31f80efeefaee2c59db50a46cabe2b5fdf20e4ae))
+  - march handling with arch-features ([7275ac2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7275ac2af86277e2442ef4b0fee6c35cbe830056))
+  - move comment for VERSION_PATCH ([c25d1cc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c25d1ccf1e205b2781ecd0de91e91d35e57b79bc))
+  - mute sp_mk_generator from build log ([fbd32ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fbd32ac081c421929728f454427b7839235d2075))
+  - properly manage versions in .versionrc.js ([7f74030](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f74030b89136a1673e2a949564403709bc48f5d))
+  - wrap toolchain paths in double quotes ([4731c00](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4731c00bb60915c0d4b29c082a752e9925a244b4))
+
+- **Tools**
+
+  - **Certificate Creation Tool**
+
+    - add guardrails around brainpool usage ([c0c280d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0c280dfda7322dcaebb5c6341c0880bdf524e13))
+    - use a salt length equal to digest length for RSA-PSS ([e639ad2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e639ad23c8c7a1b320af9ebd519420ae7d431531))
+
+  - **Memory Mapping Tool**
+
+    - fix footprint free space calculation ([9e72d01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9e72d01ed29c350dfc0567c59bc482901211634b))
+    - fix memory map dump when SEPARATE_CODE_AND_RODATA=0 ([6dc8ee6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6dc8ee61ffeee8ea5aafdbef3121fa4e82b57932))
+
+  - **Marvell Tools**
+
+    - include mbedtls/version.h before use ([8eb4efe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8eb4efe70bd5b03917e2063ab8ff5646de88922a))
+
 ## [2.10.0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.9.0..refs/tags/v2.10.0) (2023-11-21)
 
 ### âš  BREAKING CHANGES
@@ -2667,11 +4619,11 @@ issues in each release of Trusted Firmware-A.
       - route GIC IPI interrupts during setup ([04cc91b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04cc91b43c1d10fcba563e18f06336987e6e3a24))
       - use only one space for indentation ([dee5885](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dee588591328b96d9b9ef908869c8b42bd2632f2))
 
-      - **Versal NET**
+    - **Versal NET**
 
-        - Enable a78 errata workarounds ([bcc6e4a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcc6e4a02a88056b9c45ff28f405e09444433528))
-        - add default values for silicon ([faa22d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/faa22d48d9929d57975b84ab76cb595afdcf57f4))
-        - use api_id directly without FUNCID_MASK ([b0eb6d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0eb6d124b1764264778d17b1519bfe62b7b9337))
+      - Enable a78 errata workarounds ([bcc6e4a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bcc6e4a02a88056b9c45ff28f405e09444433528))
+      - add default values for silicon ([faa22d4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/faa22d48d9929d57975b84ab76cb595afdcf57f4))
+      - use api_id directly without FUNCID_MASK ([b0eb6d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b0eb6d124b1764264778d17b1519bfe62b7b9337))
 
     - **ZynqMP**
 
@@ -4642,6 +6594,7 @@ issues in each release of Trusted Firmware-A.
       - bump BL2 stack size ([d22f1d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d22f1d358731f0f55f2f392fa587f0fa8d315aa5))
       - provide boot files via semihosting ([749d0fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/749d0fa80d1c7ca30b4092a381a06deeeaf1747f))
       - OP-TEE SP manifest per latest SPMC changes ([b7bc51a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7bc51a7a747bf40d219b2041e5b3ce56737a71b))
+      - mock support for CCA NV ctr ([7423e5e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7423e5e893179d37061a67f8eafda24e649a79ea))
 
     - **FVP-R**
 
@@ -8839,7 +10792,7 @@ releases of TF-A.
 
 ______________________________________________________________________
 
-*Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
 
 [mbed tls releases]: https://tls.mbed.org/tech-updates/releases
 [pr#1002]: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193
diff --git a/docs/components/arm-sip-service.rst b/docs/components/arm-sip-service.rst
index b51a94dc..74a40a3f 100644
--- a/docs/components/arm-sip-service.rst
+++ b/docs/components/arm-sip-service.rst
@@ -15,19 +15,20 @@ services:
 
 The Arm SiP implementation offers the following services:
 
--  Performance Measurement Framework (PMF)
 -  Execution State Switching service
--  DebugFS interface
 
 Source definitions for Arm SiP service are located in the ``arm_sip_svc.h`` header
 file.
 
-Performance Measurement Framework (PMF)
----------------------------------------
++----------------------------+----------------------------+---------------------------------------+
+| ARM_SIP_SVC_VERSION_MAJOR  | ARM_SIP_SVC_VERSION_MINOR  | Changes                               |
++============================+============================+=======================================+
+|                          1 |                          0 | Move DebugFS and PMF to the new vendor|
+|                            |                            | specific FID range. The old FID range |
+|                            |                            | for these services are deprecated     |
++----------------------------+----------------------------+---------------------------------------+
 
-The :ref:`Performance Measurement Framework <firmware_design_pmf>`
-allows callers to retrieve timestamps captured at various paths in TF-A
-execution.
+*Table 1: Showing different versions of arm-sip-service and changes done with each version*
 
 Execution State Switching service
 ---------------------------------
@@ -88,348 +89,8 @@ Instead, execution starts at the supplied entry point, with the CPU registers 0
 and 1 populated with the supplied *Cookie hi* and *Cookie lo* values,
 respectively.
 
-DebugFS interface
------------------
-
-The optional DebugFS interface is accessed through an SMC SiP service. Refer
-to the component documentation for details.
-
-String parameters are passed through a shared buffer using a specific union:
-
-.. code:: c
-
-    union debugfs_parms {
-        struct {
-            char fname[MAX_PATH_LEN];
-        } open;
-
-        struct mount {
-            char srv[MAX_PATH_LEN];
-            char where[MAX_PATH_LEN];
-            char spec[MAX_PATH_LEN];
-        } mount;
-
-        struct {
-            char path[MAX_PATH_LEN];
-            dir_t dir;
-        } stat;
-
-        struct {
-            char oldpath[MAX_PATH_LEN];
-            char newpath[MAX_PATH_LEN];
-        } bind;
-    };
-
-Format of the dir_t structure as such:
-
-.. code:: c
-
-    typedef struct {
-        char		name[NAMELEN];
-        long		length;
-        unsigned char	mode;
-        unsigned char	index;
-        unsigned char	dev;
-        qid_t		qid;
-    } dir_t;
-
-
-* Identifiers
-
-======================== =============================================
-SMC_OK                   0
-SMC_UNK                  -1
-DEBUGFS_E_INVALID_PARAMS -2
-======================== =============================================
-
-======================== =============================================
-MOUNT                    0
-CREATE                   1
-OPEN                     2
-CLOSE                    3
-READ                     4
-WRITE                    5
-SEEK                     6
-BIND                     7
-STAT                     8
-INIT                     10
-VERSION                  11
-======================== =============================================
-
-MOUNT
-~~~~~
-
-Description
-^^^^^^^^^^^
-This operation mounts a blob of data pointed to by path stored in `src`, at
-filesystem location pointed to by path stored in `where`, using driver pointed
-to by path in `spec`.
-
-Parameters
-^^^^^^^^^^
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``MOUNT``
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if mount operation failed
-=============== ==========================================================
-
-OPEN
-~~~~
-
-Description
-^^^^^^^^^^^
-This operation opens the file path pointed to by `fname`.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``OPEN``
-uint32_t mode
-======== ============================================================
-
-mode can be one of:
-
-.. code:: c
-
-    enum mode {
-        O_READ   = 1 << 0,
-        O_WRITE  = 1 << 1,
-        O_RDWR   = 1 << 2,
-        O_BIND   = 1 << 3,
-        O_DIR    = 1 << 4,
-        O_STAT   = 1 << 5
-    };
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if open operation failed
-
-uint32_t        w1: file descriptor id on success.
-=============== ==========================================================
-
-CLOSE
-~~~~~
-
-Description
-^^^^^^^^^^^
-
-This operation closes a file described by a file descriptor obtained by a
-previous call to OPEN.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``CLOSE``
-uint32_t File descriptor id returned by OPEN
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if close operation failed
-=============== ==========================================================
-
-READ
-~~~~
-
-Description
-^^^^^^^^^^^
-
-This operation reads a number of bytes from a file descriptor obtained by
-a previous call to OPEN.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``READ``
-uint32_t File descriptor id returned by OPEN
-uint32_t Number of bytes to read
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-On success, the read data is retrieved from the shared buffer after the
-operation.
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if read operation failed
-
-uint32_t        w1: number of bytes read on success.
-=============== ==========================================================
-
-SEEK
-~~~~
-
-Description
-^^^^^^^^^^^
-
-Move file pointer for file described by given `file descriptor` of given
-`offset` related to `whence`.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``SEEK``
-uint32_t File descriptor id returned by OPEN
-sint32_t offset in the file relative to whence
-uint32_t whence
-======== ============================================================
-
-whence can be one of:
-
-========= ============================================================
-KSEEK_SET 0
-KSEEK_CUR 1
-KSEEK_END 2
-========= ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if seek operation failed
-=============== ==========================================================
-
-BIND
-~~~~
-
-Description
-^^^^^^^^^^^
-
-Create a link from `oldpath` to `newpath`.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``BIND``
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if bind operation failed
-=============== ==========================================================
-
-STAT
-~~~~
-
-Description
-^^^^^^^^^^^
-
-Perform a stat operation on provided file `name` and returns the directory
-entry statistics into `dir`.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``STAT``
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ==========================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if stat operation failed
-=============== ==========================================================
-
-INIT
-~~~~
-
-Description
-^^^^^^^^^^^
-Initial call to setup the shared exchange buffer. Notice if successful once,
-subsequent calls fail after a first initialization. The caller maps the same
-page frame in its virtual space and uses this buffer to exchange string
-parameters with filesystem primitives.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``INIT``
-uint64_t Physical address of the shared buffer.
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ======================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == DEBUGFS_E_INVALID_PARAMS if already initialized,
-                or internal error occurred.
-=============== ======================================================
-
-VERSION
-~~~~~~~
-
-Description
-^^^^^^^^^^^
-Returns the debugfs interface version if implemented in TF-A.
-
-Parameters
-^^^^^^^^^^
-
-======== ============================================================
-uint32_t FunctionID (0x82000030 / 0xC2000030)
-uint32_t ``VERSION``
-======== ============================================================
-
-Return values
-^^^^^^^^^^^^^
-
-=============== ======================================================
-int32_t         w0 == SMC_OK on success
-
-                w0 == SMC_UNK if interface is not implemented
-
-uint32_t        w1: On success, debugfs interface version, 32 bits
-                value with major version number in upper 16 bits and
-                minor version in lower 16 bits.
-=============== ======================================================
-
-* CREATE(1) and WRITE (5) command identifiers are unimplemented and
-  return `SMC_UNK`.
-
 --------------
 
-*Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
diff --git a/docs/components/context-management-library.rst b/docs/components/context-management-library.rst
new file mode 100644
index 00000000..6a76ada3
--- /dev/null
+++ b/docs/components/context-management-library.rst
@@ -0,0 +1,568 @@
+Context Management Library
+**************************
+
+This document provides an overview of the Context Management library implementation
+in Trusted Firmware-A (TF-A). It enumerates and describes the APIs implemented
+and their accessibility from other components at EL3.
+
+Overview
+========
+
+Arm TrustZone architecture facilitates hardware-enforced isolation between
+software running in various security states (Secure/Non-Secure/Realm).
+The general-purpose registers, most of the system registers and vector registers
+are not banked per world. When moving between the security states it is the
+responsibility of the secure monitor software (BL31(AArch64) / BL32(Aarch32))
+in TF-A, not the hardware, to save and restore register state.
+Refer to `Trustzone for AArch64`_ for more details.
+
+EL3 Runtime Firmware, also termed as secure monitor firmware, is integrated
+with a context management library to handle the context of the CPU, managing the
+saving and restoring of register states across the worlds.
+
+TF-A Context
+============
+
+In TF-A, the context is represented as a data structure used by the EL3 firmware
+to preserve the state of the CPU at the next lower exception level (EL) in a given
+security state and save enough EL3 metadata to be able to return to that exception
+level and security state. The memory for the context data structures are allocated
+in BSS section of EL3 firmware.
+
+In a trusted system at any instance, a given CPU could be executing in one of the
+security states (Non-Secure, Secure, Realm). Each world must have its
+configuration of system registers independent of other security states to access
+and execute any of the architectural features.
+
+If the CPU switches across security states (for example: from Non-secure to Secure
+or vice versa), the register contents, especially the ones that are not banked
+(EL2/EL1, vector, general-purpose registers), will be overwritten, as the software
+running in either state has the privileges to access them. Additionally, some of
+the architectural features enabled in the former security state will be unconditionally
+accessible in the latter security state as well. This can be a major concern when
+dealing with security-specific bits, as they need to be explicitly enabled or
+disabled in each state to prevent data leakage across the worlds.
+
+In general, an ideal trusted system should have Secure world-specific configurations
+that are not influenced by Normal World operations. Therefore, for each CPU, we
+need to maintain world-specific context to ensure that register entries from one
+world do not leak or impact the execution of the CPU in other worlds.
+This will help ensure the integrity and security of the system, preventing any
+unauthorized access or data corruption between the different security states.
+
+Design
+======
+
+The Context Management library in TF-A is designed to cover all the requirements
+for maintaining world-specific context essential for a trusted system.
+This includes implementing CPU context initialization and management routines,
+as well as other helper APIs that are required by dispatcher components in EL3
+firmware, which are collectively referred to as CPU Context Management.
+The APIs and their usecases are listed in detail under the :ref:`Library APIs`
+section.
+
+Originally, the Context Management library in TF-A was designed to cater for a
+two-world system, comprising of Non-Secure and Secure Worlds. In this case, the
+EL3 Firmware is assumed to be running in Secure World.
+With introduction of Realm Management Extension (RME), from Armv9.2 a system
+can have four distinct worlds (Non-Secure, Secure, Realm, Root).
+RME isolates EL3 from all other Security states and moves it into its own security
+state called root. EL3 firmware now runs at Root World and thereby is
+trusted from software in Non-secure, Secure, and Realm states.
+Refer to `Security States with RME`_ for more details.
+
+Key principles followed in designing the context management library :
+
+1. **EL3 should only initialize immediate used lower EL**
+
+Context Management library running at EL3 should only initialize and monitor the
+immediate used lower EL. This implies that, when S-EL2 is present in the system,
+EL3 should initialise and monitor S-EL2 registers only. S-EL1 registers should
+not be the concern of EL3 while S-EL2 is in place. In systems where S-EL2 is
+absent, S-EL1 registers should be initialised from EL3.
+
+2. **Decentralized model for context management**
+
+Each world (Non-Secure, Secure, and Realm) should have their separate component
+in EL3 responsible for their respective world context management.
+Both the Secure and Realm world have associated dispatcher components in EL3
+firmware to allow management of the respective worlds. For the Non-Secure world,
+PSCI Library (BL31)/context management library provides routines to help
+initialize the Non-Secure world context.
+
+3. **Flexibility for Dispatchers to select desired feature set to save and restore**
+
+Each feature is supported with a helper function ``is_feature_supported(void)``,
+to detect its presence at runtime. This helps dispatchers to select the desired
+feature set, and thereby save and restore the configuration associated with them.
+
+4. **Dynamic discovery of Feature enablement by EL3**
+
+TF-A supports four states for feature enablement at EL3, to make them available
+for lower exception levels.
+
+.. code:: c
+
+	#define FEAT_STATE_DISABLED     	0
+	#define FEAT_STATE_ENABLED      	1
+	#define FEAT_STATE_CHECK        	2
+	#define FEAT_STATE_CHECK_ASYMMETRIC	3
+
+A pattern is established for feature enablement behavior.
+Each feature must support the 3 possible values with rigid semantics.
+
+- **FEAT_STATE_DISABLED** - all code relating to this feature is always skipped.
+  Firmware is unaware of this feature.
+
+- **FEAT_STATE_ALWAYS** - all code relating to this feature is always executed.
+  Firmware expects this feature to be present in hardware.
+
+- **FEAT_STATE_CHECK** - same as ``FEAT_STATE_ALWAYS`` except that the feature's
+  existence will be checked at runtime. Default on dynamic platforms (example: FVP).
+
+- **FEAT_STATE_CHECK_ASYMMETRIC** - same as ``FEAT_STATE_CHECK`` except that the feature's
+  existence is asymmetric across cores, which requires the feature existence is checked
+  during warmboot path also. Note that only limited number of features can be asymmetric.
+
+ .. note::
+   Only limited number of features can be ``FEAT_STATE_CHECK_ASYMMETRIC`` this is due to
+   the fact that Operating systems are designed for SMP systems.
+   There are no clear guidelines what kind of mismatch is allowed but following pointers
+   can help making a decision
+
+    - All mandatory features must be symmetric.
+    - Any feature that impacts the generation of page tables must be symmetric.
+    - Any feature access which does not trap to EL3 should be symmetric.
+    - Features related with profiling, debug and trace could be asymmetric
+    - Migration of vCPU/tasks between CPUs should not cause an error
+
+    Whenever there is asymmetric feature support is added for a feature TF-A need to add
+    feature specific code in context management code.
+
+ .. note::
+   ``FEAT_RAS`` is an exception here, as it impacts the execution of EL3 and
+   it is essential to know its presence at compile time. Refer to ``ENABLE_FEAT``
+   macro under :ref:`Build Options` section for more details.
+
+Code Structure
+==============
+
+`lib/el3_runtime/(aarch32/aarch64)`_ - Context library code directory.
+
+Source Files
+~~~~~~~~~~~~
+
+#. ``context_mgmt.c`` : consists of core functions that setup, save and restore
+   context for different security states alongside high level feature enablement
+   APIs for individual worlds.
+
+#. ``cpu_data_array.c`` : contains per_cpu_data structure instantiation.
+
+#. ``context.S`` : consists of functions that save and restore some of the context
+   structure members in assembly code.
+
+#. ``cpu_data.S`` : consists of helper functions to initialise per_cpu_data pointers.
+
+#. ``el3_common_macros.S`` : consists of macros to facilitate actions to be performed
+   during cold and warmboot and el3 registers initialisation in assembly code.
+
+Header Files
+~~~~~~~~~~~~
+
+#. ``context_mgmt.h`` :  contains the public interface to Context Management Library.
+
+#. ``context.h`` : contains the helper macros and definitions for context entries.
+
+#. ``cpu_data.h`` : contains the public interface to Per CPU data structure.
+
+#. ``context_debug.h`` : contains public interface to report context memory
+   utilisation across the security states.
+
+#. ``context_el2.h`` : internal header consisting of helper macros to access EL2
+   context entries. Used by ``context.h``.
+
+Apart from these files, we have some context related source files under ``BL1``
+and ``BL31`` directory. ``bl1_context_mgmt.c`` ``bl31_context_mgmt.c``
+
+Bootloader Images utilizing Context Management Library
+======================================================
+
++-------------------------------------------+-----------------------------+
+|   Bootloader                              | Context Management Library  |
++-------------------------------------------+-----------------------------+
+|   BL1                                     |       Yes                   |
++-------------------------------------------+-----------------------------+
+|   BL2                                     |       No                    |
++-------------------------------------------+-----------------------------+
+|   BL31 (Aarch64- EL3runtime firmware)     |       Yes                   |
++-------------------------------------------+-----------------------------+
+|   BL32 (Aarch32- EL3runtime firmware)     |       Yes                   |
++-------------------------------------------+-----------------------------+
+
+CPU Data Structure
+==================
+For a given system, depending on the CPU count, the platform statically
+allocates memory for the CPU data structure.
+
+.. code:: c
+
+	/* The per_cpu_ptr_cache_t space allocation */
+	cpu_data_t percpu_data[PLATFORM_CORE_COUNT];
+
+This CPU data structure has a member element with an array of pointers to hold
+the Non-Secure, Realm and Secure security state context structures as listed below.
+
+.. code:: c
+
+	typedef struct cpu_data {
+	#ifdef __aarch64__
+	void *cpu_context[CPU_DATA_CONTEXT_NUM];
+	#endif
+
+	....
+	....
+
+	}cpu_data_t;
+
+|CPU Data Structure|
+
+At runtime, ``cpu_context[CPU_DATA_CONTEXT_NUM]`` array will be intitialised with
+the Secure, Non-Secure and Realm context structure addresses to ensure proper
+handling of the register state.
+See :ref:`Library APIs` section for more details.
+
+CPU Context and Memory allocation
+=================================
+
+CPU Context
+~~~~~~~~~~~
+The members of the context structure used by the EL3 firmware to preserve the
+state of CPU across exception levels for a given security state are listed below.
+
+.. code:: c
+
+	typedef struct cpu_context {
+	gp_regs_t gpregs_ctx;
+	el3_state_t el3state_ctx;
+
+	cve_2018_3639_t cve_2018_3639_ctx;
+
+	#if ERRATA_SPECULATIVE_AT
+	errata_speculative_at_t errata_speculative_at_ctx;
+	#endif
+
+	#if CTX_INCLUDE_PAUTH_REGS
+	pauth_t pauth_ctx;
+	#endif
+
+	#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
+	el2_sysregs_t el2_sysregs_ctx;
+	#else
+	el1_sysregs_t el1_sysregs_ctx;
+	#endif
+	} cpu_context_t;
+
+Context Memory Allocation
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+CPUs maintain their context per world. The individual context memory allocation
+for each CPU per world is allocated by the world-specific dispatcher components
+at compile time as shown below.
+
+|Context memory allocation|
+
+NS-Context Memory
+~~~~~~~~~~~~~~~~~
+It's important to note that the Normal world doesn't possess the dispatcher
+component found in the Secure and Realm worlds. Instead, the PSCI library at EL3
+handles memory allocation for ``Non-Secure`` world context for all CPUs.
+
+.. code:: c
+
+	static cpu_context_t psci_ns_context[PLATFORM_CORE_COUNT];
+
+Secure-Context Memory
+~~~~~~~~~~~~~~~~~~~~~
+Secure World dispatcher (such as SPMD) at EL3 allocates the memory for ``Secure``
+world context of all CPUs.
+
+.. code:: c
+
+	static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
+
+Realm-Context Memory
+~~~~~~~~~~~~~~~~~~~~
+Realm World dispatcher (RMMD) at EL3 allocates the memory for ``Realm`` world
+context of all CPUs.
+
+.. code:: c
+
+	rmmd_rmm_context_t rmm_context[PLATFORM_CORE_COUNT];
+
+To summarize, the world-specific context structures are synchronized with
+per-CPU data structures, which means that each CPU will have an array of pointers
+to individual worlds. The figure below illustrates the same.
+
+|CPU Context Memory Configuration|
+
+Context Setup/Initialization
+============================
+
+The CPU has been assigned context structures for every security state, which include
+Non-Secure, Secure and Realm. It is crucial to initialize each of these structures
+during the bootup of every CPU before they enter any security state for the
+first time. This section explains the specifics of how the initialization of
+every CPU context takes place during both cold and warm boot paths.
+
+Context Setup during Cold boot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The cold boot path is mainly executed by the primary CPU, other than essential
+CPU initialization executed by all CPUs. After executing BL1 and BL2, the Primary
+CPU jumps to the BL31 image for runtime services initialization.
+During this process, the per_cpu_data structure gets initialized with statically
+allocated world-specific context memory.
+
+Later in the cold boot sequence, the BL31 image at EL3 checks for the presence
+of a Secure world image at S-EL2. If detected, it invokes the secure context
+initialization sequence under SPMD. Additionally, based on RME enablement,
+the Realm context gets initialized from the RMMD at EL3. Finally, before exiting
+to the normal world, the Non-Secure context gets initialized via the context
+management library. At this stage, all Primary CPU contexts are initialized
+and the CPU exits EL3 to enter the Normal world.
+
+|Context Init ColdBoot|
+
+.. note::
+   The figure above illustrates a scenario on FVP for one of the build
+   configurations with TFTF component at NS-EL2.
+
+Context Setup during Warmboot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+During a warm boot sequence, the primary CPU is responsible for powering on the
+secondary CPUs. Refer to :ref:`CPU Reset` and :ref:`Firmware Design` sections for
+more details on the warm boot.
+
+|Context Init WarmBoot|
+
+The primary CPU initializes the Non-Secure context for the secondary CPU while
+restoring re-entry information for the Non-Secure world.
+It initialises via ``cm_init_context_by_index(target_idx, ep )``.
+
+``psci_warmboot_entrypoint()`` is the warm boot entrypoint procedure.
+During the warm bootup process, secondary CPUs have their secure context
+initialized through SPMD at EL3. Upon successful SP initialization, the SPD
+power management operations become shared with the PSCI library. During this
+process, the SPMD duly registers its handlers with the PSCI library.
+
+.. code:: c
+
+	file: psci_common.c
+	const spd_pm_ops_t *psci_spd_pm;
+
+	file: spmd_pm.c
+	const spd_pm_ops_t spmd_pm = {
+	.svc_on_finish = spmd_cpu_on_finish_handler,
+	.svc_off = spmd_cpu_off_handler
+	}
+
+Secondary CPUs during their bootup in the ``psci_cpu_on_finish()`` routine get
+their secure context initialised via the registered SPMD handler
+``spmd_cpu_on_finish_handler()`` at EL3.
+The figure above illustrates the same with reference of Primary CPU running at
+NS-EL2.
+
+.. _Library APIs:
+
+Library APIs
+============
+
+The public APIs and types can be found in ``include/lib/el3_runtime/context_management.h``
+and this section is intended to provide additional details and clarifications.
+
+Context Initialization for Individual Worlds
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The library implements high level APIs for the CPUs in setting up their individual
+context for each world (Non-Secure, Secure and Realm).
+
+.. c:function::	static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep);
+
+This function is responsible for the general context initialization that applies
+to all worlds. It will be invoked first, before calling the individual
+world-specific context setup APIs.
+
+.. c:function::	static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *ep);
+.. c:function::	static void setup_realm_context(cpu_context_t *ctx, const struct entry_point_info *ep);
+.. c:function::	static void setup_secure_context(cpu_context_t *ctx, const struct entry_point_info *ep);
+
+Depending on the security state that the CPU needs to enter, the respective
+world-specific context setup handlers listed above will be invoked once per-CPU
+to set up the context for their execution.
+
+.. c:function::	void cm_manage_extensions_el3(void)
+
+This function initializes all EL3 registers whose values do not change during the
+lifetime of EL3 runtime firmware. It is invoked from each CPU via the cold boot
+path ``bl31_main()`` and in the WarmBoot entry path ``void psci_warmboot_entrypoint()``.
+
+Runtime Save and Restore of Registers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+EL1 Registers
+-------------
+
+.. c:function::	void cm_el1_sysregs_context_save(uint32_t security_state);
+.. c:function::	void cm_el1_sysregs_context_restore(uint32_t security_state);
+
+These functions are utilized by the world-specific dispatcher components running
+at EL3 to facilitate the saving and restoration of the EL1 system registers
+during a world switch.
+
+EL2 Registers
+-------------
+
+.. c:function::	void cm_el2_sysregs_context_save(uint32_t security_state);
+.. c:function::	void cm_el2_sysregs_context_restore(uint32_t security_state);
+
+These functions are utilized by the world-specific dispatcher components running
+at EL3 to facilitate the saving and restoration of the EL2 system registers
+during a world switch.
+
+Pauth Registers
+---------------
+
+Pointer Authentication feature is enabled by default for Non-Secure world and
+disabled for Secure and Realm worlds. In this case, we don't need to explicitly
+save and restore the Pauth registers during world switch.
+However, ``CTX_INCLUDE_PAUTH_REGS`` flag is explicitly used to enable Pauth for
+lower exception levels of Secure and Realm worlds. In this scenario, we save the
+general purpose and Pauth registers while we enter EL3 from lower ELs via
+``prepare_el3_entry`` and restore them back while we exit EL3 to lower ELs
+via ``el3_exit``.
+
+.. code:: c
+
+	.macro save_gp_pmcr_pauth_regs
+	func restore_gp_pmcr_pauth_regs
+
+Feature Enablement for Individual Worlds
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function::	static void manage_extensions_nonsecure(cpu_context_t *ctx);
+.. c:function::	static void manage_extensions_secure(cpu_context_t *ctx);
+.. c:function::	static void manage_extensions_realm(cpu_context_t *ctx)
+
+Functions that allow the enabling and disabling of architectural features for
+each security state. These functions are invoked from the top-level setup APIs
+during context initialization.
+
+Further, a pattern is established for feature enablement code (AArch64).
+Each feature implements following APIs as applicable:
+Note: (``xxx`` is the name of the feature in the APIs)
+
+- ``is_feat_xxx_supported()`` and ``is_feat_xxx_present()`` - mandatory for all features.
+
+- ``xxx_enable(cpu_context * )`` and ``xxx_disable(cpu_context * )`` - optional
+  functions to enable the feature for the passed context only. To be called in
+  the respective world's setup_context to select behaviour.
+
+- ``xxx_init_el3()`` - optional function to enable the feature in-place in any EL3
+  registers that are never context switched. The values they write must never
+  change, otherwise the functions mentioned in previous point should be used.
+  Invoked from ``cm_manage_extensions_el3()``.
+
+- ``xxx_init_el2_unused()`` - optional function to enable the feature in-place
+  in any EL2 registers that are necessary for execution in EL1 with no EL2 present.
+
+The above mentioned rules, followed for ``FEAT_SME`` is shown below:
+
+.. code:: c
+
+	void sme_enable(cpu_context_t *context);
+	void sme_init_el3(void);
+	void sme_init_el2_unused(void);
+	void sme_disable(cpu_context_t *context);
+
+Per-world Context
+=================
+
+Apart from the CPU context structure, we have another structure to manage some
+of the EL3 system registers whose values are identical across all the CPUs
+referred to as ``per_world_context_t``.
+The Per-world context structure is intended for managing EL3 system registers with
+identical values across all CPUs, requiring only a singular context entry for each
+individual world. This structure operates independently of the CPU context
+structure and is intended to manage specific EL3 registers.
+
+.. code-block:: c
+
+	typedef struct per_world_context {
+		uint64_t ctx_cptr_el3;
+		uint64_t ctx_zcr_el3;
+		uint64_t ctx_mpam3_el3;
+	} per_world_context_t;
+
+These functions facilitate the activation of architectural extensions that possess
+identical values across all cores for the individual Non-secure, Secure, and
+Realm worlds.
+
+Root-Context (EL3-Execution-Context)
+====================================
+
+EL3/Root Context is the execution environment while the CPU is running at EL3.
+
+Previously, while the CPU is in execution at EL3, the system registers persist
+with the values of the incoming world. This implies that if the CPU is entering
+EL3 from NS world, the EL1 and EL2 system registers which might be modified in
+lower exception levels NS(EL2/EL1) will carry forward those values to EL3.
+Further the EL3 registers also hold on to the values configured for Non-secure
+world, written during the previous ERET from EL3 to NS(EL2/EL1).
+Same policy is followed with respect to other worlds (Secure/Realm) depending on
+the system configuration.
+
+The firmware at EL3 has traditionally operated within the context of the incoming
+world (Secure/Non-Secure/Realm). This becomes problematic in scenarios where the
+EL3/Root world must explicitly use architectural features that depend on system
+registers configured for lower exception levels.
+A good example of this is the PAuth regs. The Root world would need to program
+its own PAuth Keys while executing in EL3 and this needs to be restored in entry
+to EL3 from any world.
+Therefore, Root world should maintain its own distinct settings to access
+features for its own execution at EL3.
+
+Register values which are currently known to be of importance during EL3 execution,
+is referred to as the EL3/Root context.
+This includes ( MDCR_EL3.SDD, SCR_EL3.{EA, SIF}, PMCR_EL0.DP, PSTATE.DIT)
+EL3 Context ensures, CPU executes under fixed EL3 system register settings
+which is not affected by settings of other worlds.
+
+Root Context needs to be setup as early as possible before we try and access/modify
+architectural features at EL3. Its a simple restore operation ``setup_el3_execution_context``
+that overwrites the selected bits listed above. EL3 never changes its mind about
+what those values should be, sets it as required for EL3. Henceforth, a Root
+context save operation is not required.
+
+The figure below illustrates the same with NS-world as a reference while entering
+EL3.
+
+|Root Context Sequence|
+
+.. code:: c
+
+	# EL3/Root_Context routine
+	.macro setup_el3_execution_context
+
+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.*
+
+.. |Context Memory Allocation| image:: ../resources/diagrams/context_memory_allocation.png
+.. |CPU Context Memory Configuration| image:: ../resources/diagrams/cpu_data_config_context_memory.png
+.. |CPU Data Structure| image:: ../resources/diagrams/percpu-data-struct.png
+.. |Context Init ColdBoot| image:: ../resources/diagrams/context_init_coldboot.png
+.. |Context Init WarmBoot| image:: ../resources/diagrams/context_init_warmboot.png
+.. |Root Context Sequence| image:: ../resources/diagrams/root_context_sequence.png
+.. _Trustzone for AArch64: https://developer.arm.com/documentation/102418/0101/TrustZone-in-the-processor/Switching-between-Security-states
+.. _Security States with RME: https://developer.arm.com/documentation/den0126/0100/Security-states
+.. _lib/el3_runtime/(aarch32/aarch64): https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/lib/el3_runtime
diff --git a/docs/components/cot-binding.rst b/docs/components/cot-binding.rst
index 4f8c8b72..5d9acdff 100644
--- a/docs/components/cot-binding.rst
+++ b/docs/components/cot-binding.rst
@@ -67,14 +67,16 @@ Manifests and Certificate node bindings definition
         - signing-key
                 Usage:
 
-                This property is used to refer public key node present in
-                parent certificate node and it is required property for all
-                non-root certificates which are authenticated using public-key
-                present in parent certificate.
+                For non-root certificates, this property is used to refer
+                public key node present in parent certificate node and it is
+                required property for all non-root certificates which are
+                authenticated using public-key present in parent certificate.
 
-                This property is not required for root-certificates
-                as root-certificates are validated using root of trust
-                public key provided by platform.
+                This property is not required for all root-certificates. If
+                omitted, the root certificate will be validated using the
+                default platform ROTPK. If instead the root certificate needs
+                validating using a different ROTPK, the signing-key property
+                should provide a reference to the ROTPK node to use.
 
                 Value type: <phandle>
 
@@ -106,7 +108,7 @@ Manifests and Certificate node bindings definition
                      Usage:
 
                      This property provides the Object ID of public key
-                     provided in the certificate which the help of which
+                     provided in the certificate with the help of which
                      public key information can be extracted.
 
                      Value type: <string>
@@ -120,7 +122,7 @@ Manifests and Certificate node bindings definition
                      Usage:
 
                      This property provides the Object ID of hash provided in
-                     the certificate which the help of which hash information
+                     the certificate with the help of which hash information
                      can be extracted.
 
                      Value type: <string>
@@ -136,7 +138,7 @@ Example:
          trusted-key-cert: trusted-key-cert {
             root-certificate;
             image-id = <TRUSTED_KEY_CERT_ID>;
-            antirollback-counter = <&trusted_nv_counter>;
+            antirollback-counter = <&trusted_nv_ctr>;
 
             trusted-world-pk: trusted-world-pk {
                oid = TRUSTED_WORLD_PK_OID;
@@ -150,7 +152,7 @@ Example:
             image-id = <SCP_FW_KEY_CERT_ID>;
             parent = <&trusted-key-cert>;
             signing-key = <&trusted_world_pk>;
-            antirollback-counter = <&trusted_nv_counter>;
+            antirollback-counter = <&trusted_nv_ctr>;
 
             scp_fw_content_pk: scp_fw_content_pk {
                oid = SCP_FW_CONTENT_CERT_PK_OID;
@@ -310,23 +312,63 @@ Below is non-volatile counters example for ARM platform
         #address-cells = <1>;
         #size-cells = <0>;
 
-        trusted-nv-counter: trusted_nv_counter {
+        trusted_nv_ctr: trusted_nv_ctr {
            id  = <TRUSTED_NV_CTR_ID>;
            reg = <TFW_NVCTR_BASE>;
            oid = TRUSTED_FW_NVCOUNTER_OID;
         };
 
-        non_trusted_nv_counter: non_trusted_nv_counter {
+        non_trusted_nv_ctr: non_trusted_nv_ctr {
            id  = <NON_TRUSTED_NV_CTR_ID>;
            reg = <NTFW_CTR_BASE>;
            oid = NON_TRUSTED_FW_NVCOUNTER_OID;
         };
    };
 
+rot_keys node binding definition
+---------------------------------
+
+- rot_keys node
+        Description: Contains root-of-trust keys for the root certificates.
+
+        SUBNODES
+            - Description:
+
+              Root of trust key information present in the root certificates
+              are shown by these nodes.
+
+            - rot key node
+                  Description: Provide ROT key information in the certificate.
+
+                  PROPERTIES
+
+                  - oid
+                     Usage:
+
+                     This property provides the Object ID of ROT key provided
+                     in the certificate.
+
+                     Value type: <string>
+
+Example:
+Below is rot_keys example for CCA platform
+
+.. code:: c
+
+   rot_keys {
+        swd_rot_pk: swd_rot_pk {
+           oid = SWD_ROT_PK_OID;
+        };
+
+        prot_pk: prot_pk {
+           oid = PROT_PK_OID;
+        };
+   };
+
 Future update to chain of trust binding
 ---------------------------------------
 
 This binding document needs to be revisited to generalise some terminologies
 which are currently specific to X.509 certificates for e.g. Object IDs.
 
-*Copyright (c) 2020, Arm Limited. All rights reserved.*
+*Copyright (c) 2020-2024, Arm Limited. All rights reserved.*
diff --git a/docs/components/fconf/index.rst b/docs/components/fconf/index.rst
index 029f324d..b8b4519e 100644
--- a/docs/components/fconf/index.rst
+++ b/docs/components/fconf/index.rst
@@ -147,3 +147,4 @@ Properties binding information
   fconf_properties
   amu-bindings
   mpmm-bindings
+  tb_fw_bindings
diff --git a/docs/components/fconf/tb_fw_bindings.rst b/docs/components/fconf/tb_fw_bindings.rst
new file mode 100644
index 00000000..aee3b8da
--- /dev/null
+++ b/docs/components/fconf/tb_fw_bindings.rst
@@ -0,0 +1,159 @@
+Trusted Boot Firmware Configuration bindings
+============================================
+
+This document defines the nodes and properties used to define the Trusted-Boot
+firmware configuration. Platform owners are advised to define shared bindings
+here. If a binding does not generalize, they should be documented
+alongside platform documentation. There is no guarantee of backward
+compatibility with the nodes and properties outlined in this context.
+
+Trusted Boot Firmware Configuration
+-----------------------------------
+
+- compatible [mandatory]
+   - value type: <string>
+   - Should be the string ``"<plat>,tb_fw"``, where ``<plat>`` is the name of the
+     platform (i.e. ``"arm,tb_fw"``).
+
+- disable_auth [mandatory]
+   - value type: <u32>
+   - Flag used to dynamically disable authentication for development purposes.
+     Has two possible values: 0 or 1. Setting the flag to 1 disables
+     authentication.
+
+- mbedtls_heap_addr [mandatory]
+   - value type: <u64>
+   - Base address of the dynamically allocated Mbed TLS heap. This is given as a placeholder.
+
+- mbedtls_heap_size [mandatory]
+   - value type: <u32>
+   - Size of the Mbed TLS heap.
+
+IO FIP Handles
+--------------
+
+- compatible [mandatory]
+   - value type: <string>
+   - Should be the string ``"<plat>,io-fip-handle"``, where ``<plat>`` is the name of the
+     platform (i.e. ``"arm,io-fip-handle"``).
+
+- scp_bl2_uuid [mandatory]
+   - value type: <string>
+   - SCP Firmware SCP_BL2 UUID
+
+- bl31_uuid [mandatory]
+   - value type: <string>
+   - EL3 Runtime Firmware BL31 UUID
+
+- bl32_uuid [mandatory]
+   - value type: <string>
+   - Secure Payload BL32 (Trusted OS) UUID
+
+- bl32_extra1_uuid [mandatory]
+   - value type: <string>
+   - Secure Payload BL32_EXTRA1 (Trusted OS Extra1) UUID
+
+- bl32_extra2_uuid [mandatory]
+   - value type: <string>
+   - Secure Payload BL32_EXTRA2 (Trusted OS Extra2) UUID
+
+- bl33_uuid [mandatory]
+   - value type: <string>
+   - Non-Trusted Firmware BL33 UUID
+
+- hw_cfg_uuid [mandatory]
+   - value type: <string>
+   - HW_CONFIG (e.g. Kernel DT) UUID
+
+- soc_fw_cfg_uuid [mandatory]
+   - value type: <string>
+   - SOC Firmware Configuration SOC_FW_CONFIG UUID
+
+- tos_fw_cfg_uuid [mandatory]
+   - value type: <string>
+   - Trusted OS Firmware Configuration TOS_FW_CONFIG UUID
+
+- nt_fw_cfg_uuid [mandatory]
+   - value type: <string>
+   - Non-Trusted Firmware Configuration NT_FW_CONFIG UUID
+
+- cca_cert_uuid [optional]
+   - value type: <string>
+   - CCA Content Certificate UUID
+
+- core_swd_cert_uuid [optional]
+   - value type: <string>
+   - Core SWD Key Certificate UUID
+
+- plat_cert_uuid [optional]
+   - value type: <string>
+   - Core SWD Key Certificate UUID
+
+- t_key_cert_uuid [optional]
+   - value type: <string>
+   - Trusted Key Certificate UUID
+
+- scp_fw_key_uuid [optional]
+   - value type: <string>
+   - SCP Firmware Key UUID
+
+- soc_fw_key_uuid [optional]
+   - value type: <string>
+   - SOC Firmware Key UUID
+
+- tos_fw_key_cert_uuid [optional]
+   - value type: <string>
+   - TOS Firmware Key UUID
+
+- nt_fw_key_cert_uuid [optional]
+   - value type: <string>
+   - Non-Trusted Firmware Key UUID
+
+- scp_fw_content_cert_uuid [optional]
+   - value type: <string>
+   - SCP Firmware Content Certificate UUID
+
+- soc_fw_content_cert_uuid [optional]
+   - value type: <string>
+   - SOC Firmware Content Certificate UUID
+
+- tos_fw_content_cert_uuid [optional]
+   - value type: <string>
+   - TOS Firmware Content Certificate UUID
+
+- nt_fw_content_cert_uuid [optional]
+   - value type: <string>
+   - Non-Trusted Firmware Content Certificate UUID
+
+- plat_sp_content_cert_uuid [optional]
+   - value type: <string>
+   - Platform Secure Partition Content Certificate UUID
+
+
+Secure Partitions
+-----------------
+
+- compatible [mandatory]
+   - value type: <string>
+   - Should be the string ``"<plat>,sp"``, where ``<plat>`` is the name of the
+     platform (i.e. ``"arm,sp"``).
+
+- uuid [mandatory]
+   - value type: <string>
+   - A string identifying the UUID of the service implemented by this partition.
+     The UUID format is described in RFC 4122.
+
+- load-address [mandatory]
+   - value type: <u32>
+   - Physical base address of the partition in memory. Absence of this field
+     indicates that the partition is position independent and can be loaded at
+     any address chosen at boot time.
+
+- owner [optional]
+   - value type: <string>
+   - A string property representing the name of the owner of the secure
+     partition, which may be the silicon or platform provider.
+
+--------------
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst
index ee322ac6..2b6382b3 100644
--- a/docs/components/ffa-manifest-binding.rst
+++ b/docs/components/ffa-manifest-binding.rst
@@ -1,5 +1,5 @@
 FF-A manifest binding to device tree
-========================================
+====================================
 
 This document defines the nodes and properties used to define a partition,
 according to the FF-A specification.
@@ -82,7 +82,7 @@ Partition Properties
      the partition. Absence of this field indicates that the entry point is at
      offset 0x0 from the base of the partition's binary.
 
-- xlat-granule [mandatory]
+- xlat-granule
    - value type: <u32>
    - Translation granule used with the partition:
 
@@ -91,10 +91,10 @@ Partition Properties
       - 0x2: 64k
 
 - boot-order
-   - value type: <u16>
+   - value type: <u32>
    - A unique number amongst all partitions that specifies if this partition
      must be booted before others. The partition with the smaller number will be
-     booted first.
+     booted first. Highest vlue allowed for this field is 0xFFFF.
 
 - rx-tx-buffer
    - value type: "memory-regions" node
@@ -103,13 +103,15 @@ Partition Properties
      The "compatible" must be the string "arm,ffa-manifest-rx_tx-buffer".
 
 - messaging-method [mandatory]
-   - value type: <u8>
+   - value type: <u32>
    - Specifies which messaging methods are supported by the partition, set bit
      means the feature is supported, clear bit - not supported:
 
-      - Bit[0]: partition can receive direct requests if set
-      - Bit[1]: partition can send direct requests if set
+      - Bit[0]: partition can receive direct requests via FFA_MSG_SEND_DIRECT_REQ ABI if set
+      - Bit[1]: partition can send direct requests via FFA_MSG_SEND_DIRECT_REQ ABI if set
       - Bit[2]: partition can send and receive indirect messages
+      - Bit[9]: partition can receive direct requests via FFA_MSG_SEND_DIRECT_REQ2 ABI if set
+      - Bit[10]: partition can send direct requests via FFA_MSG_SEND_DIRECT_REQ2 ABI if set
 
 - managed-exit
    - value type: <empty>
@@ -117,6 +119,11 @@ Partition Properties
    - This field is deprecated in favor of ns-interrupts-action field in the FF-A
      v1.1 EAC0 spec.
 
+- managed-exit-virq
+   - value type: <empty>
+   - Indicates if the partition needs managed exit, if supported, to be signaled
+     through vIRQ signal.
+
 - ns-interrupts-action [mandatory]
    - value type: <u32>
    - Specifies the action that the SPMC must take in response to a Non-secure
@@ -157,11 +164,6 @@ Partition Properties
      the FF-A boot information blob to be passed in the specified general purpose
      register.
 
-- stream-endpoint-ids
-   - value type: <prop-encoded-array>
-   - List of <u32> tuples, identifying the IDs this partition is acting as
-     proxy for.
-
 - power-management-messages
    - value type: <u32>
    - Specifies which power management messages a partition subscribes to.
@@ -172,6 +174,17 @@ Partition Properties
       - Bit[1]: CPU_SUSPEND
       - Bit[2]: CPU_SUSPEND_RESUME
 
+- vm-availability-messages
+   - value type: <u32>
+   - Specifies which VM availability messages a partition subscribes to. A set
+     bit means the partition should be informed of the event, clear bit - should
+     not be informed of event:
+
+      - Bit[0]: VM created
+      - Bit[1]: VM destroyed
+
+.. _memory_region_node:
+
 Memory Regions
 --------------
 
@@ -209,6 +222,33 @@ Memory Regions
      then communicate the region properties (including the base address chosen
      by the partition manager) to the partition.
 
+- load-address-relative-offset
+   - value type: <u64>
+   - Offset relative to the load address of the partition.
+     When this is provided in the partition manifest, it should be added to the
+     load address to get the base address of the region. The secure partition
+     manifest can have either "base-address" or "load-address-relative-offset".
+     It cannot have both.
+
+- stream-ids
+   - value type: <prop-encoded-array>
+   - List of IDs belonging to a DMA capable peripheral device that has access to
+     the memory region represented by current node.
+   - Each ID must have been declared in exactly one device region node.
+
+- smmu-id
+   - value type: <u32>
+   - Identifies the SMMU IP that enforces the access control for the DMA device
+     that owns the above stream-ids.
+
+- stream-ids-access-permissions
+   - value type: <prop-encoded-array>
+   - List of attributes representing the instruction and data access permissions
+     used by the DMA device streams to access the memory region represented by
+     current node.
+
+.. _device_region_node:
+
 Device Regions
 --------------
 
@@ -251,11 +291,10 @@ Device Regions
 
 - stream-ids
    - value type: <prop-encoded-array>
-   - A list of (id, mem-manage) pair, where:
-
-      - id: A unique <u32> value amongst all devices assigned to the partition.
+   - List of IDs where an ID is a unique <u32> value amongst all devices assigned
+     to the partition.
 
-- interrupts [mandatory]
+- interrupts
    - value type: <prop-encoded-array>
    - A list of (id, attributes) pair describing the device interrupts, where:
 
@@ -306,4 +345,4 @@ Device Regions
 
 --------------
 
-*Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/firmware-update.rst b/docs/components/firmware-update.rst
index 1ba1e1c6..eda78525 100644
--- a/docs/components/firmware-update.rst
+++ b/docs/components/firmware-update.rst
@@ -494,4 +494,4 @@ This is only allowed if the image is not being executed.
 .. _Universally Unique Identifier: https://tools.ietf.org/rfc/rfc4122.txt
 .. |Flow Diagram| image:: ../resources/diagrams/fwu_flow.png
 .. |FWU state machine| image:: ../resources/diagrams/fwu_states.png
-.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/latest/
diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst
index 07637dd5..78d2f12a 100644
--- a/docs/components/granule-protection-tables-design.rst
+++ b/docs/components/granule-protection-tables-design.rst
@@ -1,17 +1,17 @@
 Granule Protection Tables Library
 =================================
 
-This document describes the design of the granule protection tables (GPT)
+This document describes the design of the Granule Protection Tables (GPT)
 library used by Trusted Firmware-A (TF-A). This library provides the APIs needed
 to initialize the GPTs based on a data structure containing information about
 the systems memory layout, configure the system registers to enable granule
 protection checks based on these tables, and transition granules between
 different PAS (physical address spaces) at runtime.
 
-Arm CCA adds two new security states for a total of four: root, realm, secure, and
-non-secure. In addition to new security states, corresponding physical address
-spaces have been added to control memory access for each state. The PAS access
-allowed to each security state can be seen in the table below.
+Arm CCA adds two new security states for a total of four: root, realm, secure,
+and non-secure. In addition to new security states, corresponding physical
+address spaces have been added to control memory access for each state. The PAS
+access allowed to each security state can be seen in the table below.
 
 .. list-table:: Security states and PAS access rights
    :widths: 25 25 25 25 25
@@ -45,12 +45,15 @@ allowed to each security state can be seen in the table below.
 
 The GPT can function as either a 1 level or 2 level lookup depending on how a
 PAS region is configured. The first step is the level 0 table, each entry in the
-level 0 table controls access to a relatively large region in memory (block
+level 0 table controls access to a relatively large region in memory (GPT Block
 descriptor), and the entire region can belong to a single PAS when a one step
-mapping is used, or a level 0 entry can link to a level 1 table where relatively
-small regions (granules) of memory can be assigned to different PAS with a 2
-step mapping. The type of mapping used for each PAS is determined by the user
-when setting up the configuration structure.
+mapping is used. Level 0 entry can also link to a level 1 table (GPT Table
+descriptor) with a 2 step mapping. To change PAS of a region dynamically, the
+region must be mapped in Level 1 table.
+
+The Level 1 tables entries with the same PAS can be combined to form a
+contiguous block entry using GPT Contiguous descriptor. More details about this
+is explained in the following section.
 
 Design Concepts and Interfaces
 ------------------------------
@@ -73,18 +76,23 @@ coded in the firmware.
 GPT setup is split into two parts: table creation and runtime initialization. In
 the table creation step, a data structure containing information about the
 desired PAS regions is passed into the library which validates the mappings,
-creates the tables in memory, and enables granule protection checks. In the
+creates the tables in memory, and enables granule protection checks. It also
+allocates memory for fine-grained locks adjacent to the L0 tables. In the
 runtime initialization step, the runtime firmware locates the existing tables in
 memory using the GPT register configuration and saves important data to a
 structure used by the granule transition service which will be covered more
 below.
 
 In the reference implementation for FVP models, you can find an example of PAS
-region definitions in the file ``include/plat/arm/common/arm_pas_def.h``. Table
-creation API calls can be found in ``plat/arm/common/arm_bl2_setup.c`` and
+region definitions in the file ``plat/arm/board/fvp/include/fvp_pas_def.h``.
+Table creation API calls can be found in ``plat/arm/common/arm_common.c`` and
 runtime initialization API calls can be seen in
 ``plat/arm/common/arm_bl31_setup.c``.
 
+During the table creation time, the GPT lib opportunistically fuses contiguous
+GPT L1 entries having the same PAS. The maximum size of
+supported contiguous blocks is defined by ``RME_GPT_MAX_BLOCK`` build option.
+
 Defining PAS regions
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -115,8 +123,13 @@ Level 0 and Level 1 Tables
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The GPT initialization APIs require memory to be passed in for the tables to be
-constructed, ``gpt_init_l0_tables`` takes a memory address and size for building
-the level 0 tables and ``gpt_init_pas_l1_tables`` takes an address and size for
+constructed. The ``gpt_init_l0_tables`` API takes a memory address and size for
+building the level 0 tables and also memory for allocating the fine-grained bitlock
+data structure. The amount of memory needed for bitlock structure is controlled via
+``RME_GPT_BITLOCK_BLOCK`` config which defines the block size for each bit of the
+the bitlock.
+
+The ``gpt_init_pas_l1_tables`` API takes an address and size for
 building the level 1 tables which are linked from level 0 descriptors. The
 tables should have PAS type ``GPT_GPI_ROOT`` and a typical system might place
 its level 0 table in SRAM and its level 1 table(s) in DRAM.
@@ -124,12 +137,28 @@ its level 0 table in SRAM and its level 1 table(s) in DRAM.
 Granule Transition Service
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The Granule Transition Service allows memory mapped with GPT_MAP_REGION_GRANULE
-ownership to be changed using SMC calls. Non-secure granules can be transitioned
-to either realm or secure space, and realm and secure granules can be
-transitioned back to non-secure. This library only allows memory mapped as
-granules to be transitioned, memory mapped as blocks have their GPIs fixed after
-table creation.
+The Granule Transition Service allows memory mapped with
+``GPT_MAP_REGION_GRANULE`` ownership to be changed using SMC calls. Non-secure
+granules can be transitioned to either realm or secure space, and realm and
+secure granules can be transitioned back to non-secure. This library only
+allows Level 1 entries to be transitioned. The lib may either shatter
+contiguous blocks or fuse adjacent GPT entries to form a contiguous block
+opportunistically. Depending on the maximum block size, the fuse operation may
+propogate to higher block sizes as allowed by RME Architecture. Thus a higher
+maximum block size may have a higher runtime cost due to software operations
+that need to be performed for fuse to bigger block sizes. This cost may
+be offset by better TLB performance due to the higher block size and platforms
+need to make the trade-off decision based on their particular workload.
+
+Locking Scheme
+~~~~~~~~~~~~~~
+
+During Granule Transition access to L1 tables is controlled by a lock to ensure
+that no more than one CPU is allowed to make changes at any given time.
+The granularity of the lock is defined by ``RME_GPT_BITLOCK_BLOCK`` build option
+which defines the size of the memory block protected by one bit of ``bitlock``
+structure. Setting this option to 0 chooses a single spinlock for all GPT L1
+table entries.
 
 Library APIs
 ------------
@@ -196,7 +225,9 @@ The L0 table memory has some constraints that must be taken into account.
   is greater. L0 table size is the total protected space (PPS) divided by the
   size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor
   (8 bytes). ((PPS / L0GPTSZ) * 8)
-* The L0 memory size must be greater than or equal to the table size.
+* The L0 memory size must be greater than the table size and have enough space
+  to allocate array of ``bitlock`` structures at the end of L0 table if
+  required (``RME_GPT_BITLOCK_BLOCK`` is not 0).
 * The L0 memory must fall within a PAS of type GPT_GPI_ROOT.
 
 The L1 memory also has some constraints.
@@ -223,6 +254,24 @@ Substitute values to get this: ((0x100000000 / 0x40000000) * 8)
 And solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0
 tables must be aligned to 4096 bytes.
 
+Sample calculation for bitlock array size
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Let PGS=GPCCR_PPS_256TB and RME_GPT_BITLOCK_BLOCK=1
+
+The size of bit lock array in bits is the total protected space (PPS) divided
+by the size of memory block per bit. The size of memory block
+is ``RME_GPT_BITLOCK_BLOCK`` (number of 512MB blocks per bit) times
+512MB (0x20000000). This is then divided by the number of bits in ``bitlock``
+structure (8) to get the size of bit array in bytes.
+
+In other words, we can find the total size of ``bitlock`` array
+in bytes with PPS / (RME_GPT_BITLOCK_BLOCK * 0x20000000 *  8).
+
+Substitute values to get this: 0x1000000000000 / (1 * 0x20000000 * 8)
+
+And solve to get 0x10000 bytes.
+
 Sample calculation for L1 table size and alignment
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/components/index.rst b/docs/components/index.rst
index 30d80fcd..36970260 100644
--- a/docs/components/index.rst
+++ b/docs/components/index.rst
@@ -26,3 +26,6 @@ Components
    realm-management-extension
    rmm-el3-comms-spec
    granule-protection-tables-design
+   ven-el3-service
+   ven-el3-debugfs
+   context-management-library
diff --git a/docs/components/platform-interrupt-controller-API.rst b/docs/components/platform-interrupt-controller-API.rst
index 4de39d1e..8cd4bae9 100644
--- a/docs/components/platform-interrupt-controller-API.rst
+++ b/docs/components/platform-interrupt-controller-API.rst
@@ -282,9 +282,28 @@ may be signalled to the PE. The API should return the current priority value
 that it's overwriting.
 
 In case of Arm standard platforms using GIC, the implementation of the API
-inserts to order memory updates before updating mask, then writes to the GIC
-*Priority Mask Register*, and make sure memory updates are visible before
-potential trigger due to mask update.
+inserts barriers to order memory updates before updating mask,
+then writes to the GIC *Priority Mask Register*, and make sure memory updates
+are visible before potential trigger due to mask update.
+
+Function: unsigned int plat_ic_deactivate_priority(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : unsigned int
+    Return   : int
+
+This API performs the operations of plat_ic_set_priority_mask along with
+calling the errata workaround gicv3_apply_errata_wa_2384374(). This is
+performed when priority mask is restored to it's older value. This API returns
+the current priority value that it's overwriting.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+inserts barriers to order memory updates before updating mask, then writes
+to the GIC *Priority Mask Register*, and make sure memory updates
+are visible before potential trigger due to mask update, and
+applies 2384374 GIC errata workaround to process pending interrupt packets.
 
 .. _plat_ic_get_interrupt_id:
 
diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst
index f228e6b5..39186b42 100644
--- a/docs/components/realm-management-extension.rst
+++ b/docs/components/realm-management-extension.rst
@@ -237,7 +237,7 @@ Use the following command to run the tests on FVP.
  -C bp.ve_sysregs.exit_on_shutdown=1                            \
  -C cache_state_modelled=1                                      \
  -C bp.dram_size=4                                              \
- -C bp.secure_memory=1                                          \
+ -C bp.secure_memory=0                                          \
  -C pci.pci_smmuv3.mmu.SMMU_ROOT_IDR0=3                         \
  -C pci.pci_smmuv3.mmu.SMMU_ROOT_IIDR=0x43B                     \
  -C pci.pci_smmuv3.mmu.root_register_page_offset=0x20000        \
diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst
index 009ac28c..79e1d2cd 100644
--- a/docs/components/rmm-el3-comms-spec.rst
+++ b/docs/components/rmm-el3-comms-spec.rst
@@ -52,8 +52,8 @@ are explained below:
   - ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
     consistency with the versioning schemes used in other parts of RMM.
 
-This document specifies the 0.2 version of Boot Interface ABI and RMM-EL3
-services specification and the 0.2 version of the Boot Manifest.
+This document specifies the 0.4 version of Boot Interface ABI and RMM-EL3
+services specification and the 0.3 version of the Boot Manifest.
 
 .. _rmm_el3_boot_interface:
 
@@ -159,8 +159,8 @@ as per the following table:
    ``E_RMM_BOOT_SUCCESS``,Boot successful,0
    ``E_RMM_BOOT_ERR_UNKNOWN``,Unknown error,-1
    ``E_RMM_BOOT_VERSION_NOT_VALID``,Boot Interface version reported by EL3 is not supported by RMM,-2
-   ``E_RMM_BOOT_CPUS_OUT_OF_RAGE``,Number of CPUs reported by EL3 larger than maximum supported by RMM,-3
-   ``E_RMM_BOOT_CPU_ID_OUT_OF_RAGE``,Current CPU Id is higher or equal than the number of CPUs supported by RMM,-4
+   ``E_RMM_BOOT_CPUS_OUT_OF_RANGE``,Number of CPUs reported by EL3 larger than maximum supported by RMM,-3
+   ``E_RMM_BOOT_CPU_ID_OUT_OF_RANGE``,Current CPU Id is higher or equal than the number of CPUs supported by RMM,-4
    ``E_RMM_BOOT_INVALID_SHARED_BUFFER``,Invalid pointer to shared memory area,-5
    ``E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED``,Version reported by the Boot Manifest not supported by RMM,-6
    ``E_RMM_BOOT_MANIFEST_DATA_ERROR``,Error parsing core Boot Manifest,-7
@@ -182,17 +182,20 @@ platform information.
 
 This Boot Manifest is versioned independently of the Boot Interface, to help
 evolve the former independent of the latter.
-The current version for the Boot Manifest is ``v0.2`` and the rules explained
+The current version for the Boot Manifest is ``v0.3`` and the rules explained
 in :ref:`rmm_el3_ifc_versioning` apply on this version as well.
 
-The Boot Manifest v0.2 has the following fields:
+The Boot Manifest v0.3 has the following fields:
 
-   - version : Version of the Manifest (v0.2)
+   - version : Version of the Manifest (v0.3)
    - plat_data : Pointer to the platform specific data and not specified by this
      document. These data are optional and can be NULL.
    - plat_dram : Structure encoding the NS DRAM information on the platform. This
-     field is also optional and platform can choose to zero out this structure if
+     field is optional and platform can choose to zero out this structure if
      RMM does not need EL3 to send this information during the boot.
+   - plat_console : Structure encoding the list of consoles for RMM use on the
+     platform. This field is optional and platform can choose to not populate
+     the console list if this is not needed by the RMM for this platform.
 
 For the current version of the Boot Manifest, the core manifest contains a pointer
 to the platform data. EL3 must ensure that the whole Boot Manifest, including
@@ -235,6 +238,7 @@ error condition as described in the following table:
    ``E_RMM_BAD_PAS``,Incorrect PAS,-3
    ``E_RMM_NOMEM``,Not enough memory to perform an operation,-4
    ``E_RMM_INVAL``,The value of an argument was invalid,-5
+   ``E_RMM_AGAIN``,The resource is busy. Try again.,-6
 
 If multiple failure conditions are detected in an RMM to EL3 command, then EL3
 is allowed to return an error code corresponding to any of the failure
@@ -255,6 +259,8 @@ implemented by EL3 Firmware.
    0xC40001B1,``RMM_GTSI_UNDELEGATE``
    0xC40001B2,``RMM_ATTEST_GET_REALM_KEY``
    0xC40001B3,``RMM_ATTEST_GET_PLAT_TOKEN``
+   0xC40001B4,``RMM_EL3_FEATURES``
+   0xC40001B5,``RMM_EL3_TOKEN_SIGN``
 
 RMM_RMI_REQ_COMPLETE command
 ============================
@@ -439,7 +445,21 @@ Supported ECC Curves
 RMM_ATTEST_GET_PLAT_TOKEN command
 =================================
 
-Retrieve the Platform Token from EL3.
+Retrieve the Platform Token from EL3. If the entire token does not fit in the
+buffer, EL3 returns a hunk of the token (via ``tokenHunkSize`` parameter) and
+indicates the remaining bytes that are pending retrieval (via ``remainingSize``
+parameter). The challenge object for the platform token must be populated in
+the buffer for the first call of this command and the size of the object is
+indicated by ``c_size`` parameter. Subsequent calls to retrieve remaining hunks of
+the token must be made with ``c_size`` as 0.
+
+If ``c_size`` is not 0, this command could cause regeneration of platform token
+and will return token hunk corresponding to beginning of the token.
+
+It is valid for the calls of this command to return ``E_RMM_AGAIN`` error,
+which is an indication to the caller to retry this command again. Depending on the
+platform, this mechanism can be used to implement queuing to HES, if HES is
+involved in platform token generation.
 
 FID
 ---
@@ -454,9 +474,9 @@ Input values
    :widths: 1 1 1 1 5
 
    fid,x0,[63:0],UInt64,Command FID
-   buf_pa,x1,[63:0],Address,PA of the platform attestation token. The challenge object is passed in this buffer. The PA must belong to the shared buffer
+   buf_pa,x1,[63:0],Address,"PA of the platform attestation token. The challenge object must be passed in this buffer for the first call of this command. Any subsequent calls, if required to retrieve the full token, should not have this object. The PA must belong to the shared buffer."
    buf_size,x2,[63:0],Size,Size in bytes of the platform attestation token buffer. ``bufPa + bufSize`` must lie within the shared buffer
-   c_size,x3,[63:0],Size,Size in bytes of the challenge object. It corresponds to the size of one of the defined SHA algorithms
+   c_size,x3,[63:0],Size,"Size in bytes of the challenge object. It corresponds to the size of one of the defined SHA algorithms. Any subsequent calls, if required to retrieve the full token, should set this size to 0."
 
 Output values
 -------------
@@ -466,7 +486,8 @@ Output values
    :widths: 1 1 1 1 5
 
    Result,x0,[63:0],Error Code,Command return status
-   tokenSize,x1,[63:0],Size,Size of the platform token
+   tokenHunkSize,x1,[63:0],Size,Size of the platform token hunk retrieved
+   remainingSize,x2,[63:0],Size,Remaining bytes of the token that are pending retrieval
 
 Failure conditions
 ------------------
@@ -478,12 +499,178 @@ a failure. The errors are ordered by condition check.
    :header: "ID", "Condition"
    :widths: 1 5
 
+   ``E_RMM_AGAIN``,Resource for Platform token retrieval is busy. Try again.
    ``E_RMM_BAD_ADDR``,``PA`` is outside the shared buffer
    ``E_RMM_INVAL``,``PA + BSize`` is outside the shared buffer
-   ``E_RMM_INVAL``,``CSize`` does not represent the size of a supported SHA algorithm
+   ``E_RMM_INVAL``,``CSize`` does not represent the size of a supported SHA algorithm for the first call to this command
+   ``E_RMM_INVAL``,``CSize`` is not 0 for subsequent calls to retrieve remaining hunks of the token
    ``E_RMM_UNK``,An unknown error occurred whilst processing the command
    ``E_RMM_OK``,No errors detected
 
+RMM_EL3_FEATURES command
+========================
+
+This command provides a mechanism to discover features and ABIs supported by the
+RMM-EL3 interface, for a given version. This command is helpful when there are
+platform specific optional RMM-EL3 interfaces and features exposed by vendor
+specific EL3 firmware, and a generic RMM that can modify its behavior based on
+discovery of EL3 features.
+
+The features can be discovered by specifying the feature register index that
+has fields defined to indicate presence or absence of features and other
+relevant information. The feature register index is specified in the
+``feat_reg_idx`` parameter. Each feature register is a 64 bit register.
+
+This command is available from v0.4 of the RMM-EL3 interface.
+
+The following is the register definition for feature register index 0 for
+v0.4 of the interface:
+
+RMM-EL3 Feature Resister 0
+--------------------------
+
+.. code-block:: none
+
+    63      32      31      16       15      8       7       1       0
+    +-------+-------+-------+-------+-------+-------+-------+-------+
+    |       |       |       |       |       |       |       |       |
+    |       |       |       |       |       |       |       |       |
+    +-------+-------+-------+-------+-------+-------+-------+-------+
+                                                             ^
+                                                             |
+                                                 RMMD_EL3_TOKEN_SIGN
+
+**Bit Fields:**
+
+- **Bit 0**: `RMMD_EL3_TOKEN_SIGN`
+    - When set to 1, the `RMMD_EL3_TOKEN_SIGN` feature is enabled.
+    - When cleared (0), the feature is disabled.
+- **Bits [1:63]**: Reserved (must be zero)
+
+FID
+---
+
+``0xC40001B4``
+
+
+Input values
+------------
+
+.. csv-table:: Input values for RMM_EL3_FEATURES
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   fid,x0,[63:0],UInt64,Command FID
+   feat_reg_idx,x1,[63:0],UInt64, "Feature register index. For v0.4, a value of 0 is the only
+   acceptable value"
+
+
+Output values
+-------------
+
+.. csv-table:: Output values for RMM_EL3_FEATURES
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   Result,x0,[63:0],Error Code,Command return status
+   feat_reg,x1,[63:0],Value,Value of the register as defined above
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table:: Failure conditions for RMM_EL3_FEATURES
+   :header: "ID", "Condition"
+   :widths: 1 5
+
+   ``E_RMM_INVAL``,``feat_reg_idx`` is out of valid range
+   ``E_RMM_UNK``,"if the SMC is not present, if interface version is <0.4"
+   ``E_RMM_OK``,No errors detected
+
+RMM_EL3_TOKEN_SIGN command
+==========================
+
+This command is an optional command that can be discovered using the RMM_EL3_FEATURES command.
+This command is used to send requests related to realm attestation token signing requests to EL3.
+The command supports 3 opcodes:
+
+   - RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP
+   - RMM_EL3_TOKEN_SIGN_PULL_RESP_OP
+   - RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+
+The above opcodes can be used to send realm attestation token signing requests to EL3 and get their
+response, so that the realm attestation token can be constructed.
+
+This command is useful when the RMM may not have access to the private portion of the realm
+attestation key and needs signing services from EL3 or CCA HES, or other platform specific
+mechanisms to perform signing.
+
+The RMM-EL3 interface for this command is modeled as two separate queues, one for signing requests
+and one for retrieving the signed responses. It is possible that the queue in EL3 is full or EL3 is busy and
+unable to service the RMM requests, in which case the RMM is expected to retry the push operation
+for requests and pop operation for responses.
+
+FID
+---
+
+``0xC40001B5``
+
+Input values
+------------
+
+.. csv-table:: Input values for RMM_EL3_TOKEN_SIGN
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   fid,x0,[63:0],UInt64,Command FID
+   opcode,x1,[63:0],UInt64,"
+   Opcode that is one of:
+
+    - RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP: 0x1 -
+      Opcode to push a token signing request to EL3 using struct el3_token_sign_request as described above
+    - RMM_EL3_TOKEN_SIGN_PULL_RESP_OP: 0x2 -
+      Opcode to pull a token signing response from EL3 using struct el3_token_sign_response as described above
+    - RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP: 0x3 -
+      Opcode to get the realm attestation public key
+
+   "
+   buf_pa,x2,[63:0],Address,"PA where the request structure is stored for the opcode RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP, the response structure needs to be populated for the opcode RMM_EL3_TOKEN_SIGN_PULL_RESP_OP, or where the public key must be populated for the opcode RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP. The PA must belong to the RMM-EL3 shared buffer"
+   buf_size,x3,[63:0],Size,Size in bytes of the input buffer in ``buf_pa``. ``buf_pa + buf_size`` must lie within the shared buffer
+   ecc_curve,x4,[63:0],Enum,Type of the elliptic curve to which the requested attestation key belongs to. See :ref:`ecc_curves`. This parameter is valid on for the opcode RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+
+Output values
+-------------
+
+.. csv-table:: Output values for RMM_EL3_TOKEN_SIGN
+   :header: "Name", "Register", "Field", "Type", "Description"
+   :widths: 1 1 1 1 5
+
+   Result,x0,[63:0],Error Code,Command return status. Valid for all opcodes listed in input values
+   retval1,x1,[63:0],Value, "If opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP, then returns length of
+   public key returned. Otherwise, reserved"
+
+
+Failure conditions
+------------------
+
+The table below shows all the possible error codes returned in ``Result`` upon
+a failure. The errors are ordered by condition check.
+
+.. csv-table:: Failure conditions for RMM_EL3_TOKEN_SIGN
+   :header: "ID", "Condition"
+   :widths: 1 5
+
+   ``E_RMM_INVAL``,"if opcode is invalid or buffer address and length passed to the EL3 are not in valid range
+   corresponding to the RMM-EL3 shared buffer, or if the curve used for opcode
+   RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP is not the ECC P384 curve"
+   ``E_RMM_UNK``,"if the SMC is not present, if interface version is <0.4"
+   ``E_RMM_AGAIN``,"For opcode RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP, if the request is not queued since
+   the EL3 queue is full, or if the response is not ready yet, for other opcodes"
+   ``E_RMM_OK``,No errors detected
+
+
 RMM-EL3 world switch register save restore convention
 _____________________________________________________
 
@@ -533,23 +720,25 @@ _____
 RMM-EL3 Boot Manifest structure
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The RMM-EL3 Boot Manifest v0.2 structure contains platform boot information passed
-from EL3 to RMM. The size of the Boot Manifest is 40 bytes.
+The RMM-EL3 Boot Manifest v0.3 structure contains platform boot information passed
+from EL3 to RMM. The size of the Boot Manifest is 64 bytes.
 
 The members of the RMM-EL3 Boot Manifest structure are shown in the following
 table:
 
-+-----------+--------+----------------+----------------------------------------+
-|   Name    | Offset |     Type       |               Description              |
-+===========+========+================+========================================+
-| version   |   0    |   uint32_t     | Boot Manifest version                  |
-+-----------+--------+----------------+----------------------------------------+
-| padding   |   4    |   uint32_t     | Reserved, set to 0                     |
-+-----------+--------+----------------+----------------------------------------+
-| plat_data |   8    |   uintptr_t    | Pointer to Platform Data section       |
-+-----------+--------+----------------+----------------------------------------+
-| plat_dram |   16   | ns_dram_info   | NS DRAM Layout Info structure          |
-+-----------+--------+----------------+----------------------------------------+
++--------------+--------+----------------+----------------------------------------+
+|   Name       | Offset |     Type       |               Description              |
++==============+========+================+========================================+
+| version      |   0    |   uint32_t     | Boot Manifest version                  |
++--------------+--------+----------------+----------------------------------------+
+| padding      |   4    |   uint32_t     | Reserved, set to 0                     |
++--------------+--------+----------------+----------------------------------------+
+| plat_data    |   8    |   uintptr_t    | Pointer to Platform Data section       |
++--------------+--------+----------------+----------------------------------------+
+| plat_dram    |   16   | ns_dram_info   | NS DRAM Layout Info structure          |
++--------------+--------+----------------+----------------------------------------+
+| plat_console |   40   | console_list   | List of consoles available to RMM      |
++--------------+--------+----------------+----------------------------------------+
 
 .. _ns_dram_info_struct:
 
@@ -587,5 +776,99 @@ NS DRAM Bank structure contains information about each Non-secure DRAM bank:
 |   size    |   8    |   uint64_t     | Size of bank in bytes                  |
 +-----------+--------+----------------+----------------------------------------+
 
+.. _console_list_struct:
+
+Console List structure
+~~~~~~~~~~~~~~~~~~~~~~
+
+Console List structure contains information about the available consoles for RMM.
+The members of this structure are shown in the table below:
+
++--------------+--------+----------------+----------------------------------------+
+|   Name       | Offset |     Type       |               Description              |
++==============+========+================+========================================+
+| num_consoles |   0    |   uint64_t     | Number of consoles                     |
++--------------+--------+----------------+----------------------------------------+
+| consoles     |   8    | console_info * | Pointer to 'console_info'[] array      |
++--------------+--------+----------------+----------------------------------------+
+| checksum     |   16   |   uint64_t     | Checksum                               |
++--------------+--------+----------------+----------------------------------------+
 
+Checksum is calculated as two's complement sum of 'num_consoles', 'consoles'
+pointer and the consoles array pointed by it.
+
+.. _console_info_struct:
+
+Console Info structure
+~~~~~~~~~~~~~~~~~~~~~~
 
+Console Info structure contains information about each Console available to RMM.
+
++-----------+--------+---------------+----------------------------------------+
+|   Name    | Offset |     Type      |               Description              |
++===========+========+===============+========================================+
+| base      |   0    |   uintptr_t   | Console Base address                   |
++-----------+--------+---------------+----------------------------------------+
+| map_pages |   8    |   uint64_t    | Num of pages to map for console MMIO   |
++-----------+--------+---------------+----------------------------------------+
+| name      |   16   |   char[]      | Name of console                        |
++-----------+--------+---------------+----------------------------------------+
+| clk_in_hz |   24   |   uint64_t    | UART clock (in hz) for console         |
++-----------+--------+---------------+----------------------------------------+
+| baud_rate |   32   |   uint64_t    | Baud rate                              |
++-----------+--------+---------------+----------------------------------------+
+| flags     |   40   |   uint64_t    | Additional flags (RES0)                |
++-----------+--------+---------------+----------------------------------------+
+
+.. _el3_token_sign_request_struct:
+
+EL3 Token Sign Request structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This structure represents a realm attestation toekn signing request.
+
++-------------+--------+---------------+-----------------------------------------+
+|   Name      | Offset |     Type      |               Description               |
++=============+========+===============+=========================================+
+| sig_alg_id  |   0    |   uint32_t    | Algorithm idenfier for the sign request.|
+|             |        |               | - 0x0: ECC SECP384R1 (ECDSA)            |
+|             |        |               | - Other values reserved                 |
++-------------+--------+---------------+-----------------------------------------+
+| rec_granule |   8    |   uint64_t    | Identifier used by RMM to associate     |
+|             |        |               | a signing request to a realm. Must not  |
+|             |        |               | be interpreted or modified.             |
++-------------+--------+---------------+-----------------------------------------+
+| req_ticket  |   16   |   uint64_t    | Value used by RMM to associate request  |
+|             |        |               | and responses. Must not be interpreted  |
+|             |        |               | or modified.                            |
++-------------+--------+---------------+-----------------------------------------+
+| hash_alg_id |   24   |   uint32_t    | Hash algorithm for data in `hash_buf`   |
+|             |        |               | - 0x1: SHA2-384                         |
+|             |        |               | - All other values reserved.            |
++-------------+--------+---------------+-----------------------------------------+
+| hash_buf    |   32   |   uint8_t[]   | TBS (to-be-signed) Hash of length       |
+|             |        |               | defined by hash algorithm `hash_alg_id` |
++-------------+--------+---------------+-----------------------------------------+
+
+.. _el3_token_sign_response_struct:
+
+EL3 Token Sign Response structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This structure represents a realm attestation token signing response.
+
++---------------+--------+---------------+-----------------------------------------+
+|   Name        | Offset |     Type      |               Description               |
++===============+========+===============+=========================================+
+| rec_granule   |   0    |   uint64_t    | Identifier used by RMM to associate     |
+|               |        |               | a signing request to a realm. Must not  |
+|               |        |               | be interpreted or modified.             |
++---------------+--------+---------------+-----------------------------------------+
+| req_ticket    |   8    |   uint64_t    | Value used by RMM to associate request  |
+|               |        |               | and responses. Must not be interpreted  |
+|               |        |               | or modified.                            |
++---------------+--------+---------------+-----------------------------------------+
+| sig_len       |   16   |   uint16_t    | Length of the `signature_buf` field     |
++---------------+--------+---------------+-----------------------------------------+
+| signature_buf |   18   |   uint8_t[]   | Signature                               |
++---------------+--------+---------------+-----------------------------------------+
diff --git a/docs/components/romlib-design.rst b/docs/components/romlib-design.rst
index d34b3cc5..c0f3ed34 100644
--- a/docs/components/romlib-design.rst
+++ b/docs/components/romlib-design.rst
@@ -71,13 +71,22 @@ image(s) is replaced with the wrapper function.
 The "library at ROM" contains a necessary init function that initialises the
 global variables defined by the functions inside "library at ROM".
 
+Wrapper functions are specified at the link stage of compilation and cannot
+interpose uppon functions within the same translation unit. For example, if
+function ``fn_a`` calls ``fn_b`` within translation unit ``functions.c`` and
+the romlib jump table includes an entry for ``fn_b``, ``fn_a`` will include
+a reference to ``fn_b``'s original program text instead of the wrapper. Thus
+the jumptable author must take care to include public entry points into
+translation units to avoid paying the program text cost twice, once in the
+original executable and once in romlib.
+
 Script
 ~~~~~~
 
-There is a ``romlib_generate.py`` Python script that generates the necessary
+There is a ``romlib_generator.py`` Python script that generates the necessary
 files for the "library at ROM" to work. It implements multiple functions:
 
-1. ``romlib_generate.py gentbl [args]`` - Generates the jump table by parsing
+1. ``romlib_generator.py gentbl [args]`` - Generates the jump table by parsing
    the index file.
 
 2. ``romlib_generator.py genvar [args]`` - Generates the jump table global
@@ -86,17 +95,17 @@ files for the "library at ROM" to work. It implements multiple functions:
 
 3. ``romlib_generator.py genwrappers [args]`` - Generates a wrapper function for
    each entry in the index file except for the ones that contain the keyword
-   ``patch``. The generated wrapper file is called ``<fn_name>.s``.
+   ``patch``. The generated wrapper file is called ``wrappers.s``.
 
 4. ``romlib_generator.py pre [args]`` - Preprocesses the index file which means
    it resolves all the include commands in the file recursively. It can also
    generate a dependency file of the included index files which can be directly
    used in makefiles.
 
-Each ``romlib_generate.py`` function has its own manual which is accessible by
+Each ``romlib_generator.py`` function has its own manual which is accessible by
 runing ``romlib_generator.py [function] --help``.
 
-``romlib_generate.py`` requires Python 3 environment.
+``romlib_generator.py`` requires Python 3 environment.
 
 
 Patching of functions in library at ROM
diff --git a/docs/components/sdei.rst b/docs/components/sdei.rst
index 60259c83..309375f9 100644
--- a/docs/components/sdei.rst
+++ b/docs/components/sdei.rst
@@ -354,7 +354,51 @@ implemented in assembly, following a similar pattern as below:
 
 --------------
 
-*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
+Security Considerations
+-----------------------
+
+SDEI introduces concept of providing software based non-maskable interrupts to
+Hypervisor/OS. In doing so, it modifies the priority scheme defined by Interrupt
+controllers and relies on Non-Secure clients, Hypervisor or OS, to create/manage
+high priority events.
+
+Considering a Non-secure client is involved in SDEI state management, there exists
+some security considerations which needs to be taken care of in both client and EL3
+when using SDEI. Few of them are mentioned below.
+
+Bound events
+~~~~~~~~~~~~
+
+A bound event is an SDEI event that corresponds to a client interrupt.
+The binding of event is done using ``SDEI_INTERRUPT_BIND`` SMC call to associate
+an SDEI event with a client interrupt. There is a possibility that a rogue
+client can request an invalid interrupt to be bound. This may potentially
+cause out-of-bound memory read.
+
+Even though TF-A implementation has checks to ensure that interrupt ID passed
+by client is architecturally valid, Non-secure client should also ensure the
+validity of interrupts.
+
+Recurring events
+~~~~~~~~~~~~~~~~
+
+For a given event source, if the events are generated continuously, then NS client
+may be unusable. To mitigate against this, the Non-secure client must have
+mechanism in place to remove such interrupt source from the system.
+
+One of the examples is a memory region which continuously generates RAS errors.
+This may result in unusable Non-secure client.
+
+Dispatched events
+~~~~~~~~~~~~~~~~~
+
+For a dispatched event, it is the client's responsibility to ensure that the
+handling finishes in finite time and notify the dispatcher through
+``SDEI_EVENT_COMPLETE`` or ``SDEI_EVENT_COMPLETE_AND_RESUME``. If the client
+fails to complete the event handling, it might result in ``UNPREDICTABLE`` behavior
+in the client and potentially end up in unusable PE.
+
+*Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. rubric:: Footnotes
 
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index 5d3adec8..a181204b 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -9,43 +9,13 @@ Secure Partition Manager
 Acronyms
 ========
 
-+--------+--------------------------------------+
-| CoT    | Chain of Trust                       |
-+--------+--------------------------------------+
-| DMA    | Direct Memory Access                 |
-+--------+--------------------------------------+
-| DTB    | Device Tree Blob                     |
 +--------+--------------------------------------+
 | DTS    | Device Tree Source                   |
 +--------+--------------------------------------+
-| EC     | Execution Context                    |
-+--------+--------------------------------------+
-| FIP    | Firmware Image Package               |
-+--------+--------------------------------------+
 | FF-A   | Firmware Framework for Arm A-profile |
 +--------+--------------------------------------+
-| IPA    | Intermediate Physical Address        |
-+--------+--------------------------------------+
-| JOP    | Jump-Oriented Programming            |
-+--------+--------------------------------------+
 | NWd    | Normal World                         |
 +--------+--------------------------------------+
-| ODM    | Original Design Manufacturer         |
-+--------+--------------------------------------+
-| OEM    | Original Equipment Manufacturer      |
-+--------+--------------------------------------+
-| PA     | Physical Address                     |
-+--------+--------------------------------------+
-| PE     | Processing Element                   |
-+--------+--------------------------------------+
-| PM     | Power Management                     |
-+--------+--------------------------------------+
-| PVM    | Primary VM                           |
-+--------+--------------------------------------+
-| ROP    | Return-Oriented Programming          |
-+--------+--------------------------------------+
-| SMMU   | System Memory Management Unit        |
-+--------+--------------------------------------+
 | SP     | Secure Partition                     |
 +--------+--------------------------------------+
 | SPD    | Secure Payload Dispatcher            |
@@ -56,16 +26,8 @@ Acronyms
 +--------+--------------------------------------+
 | SPMD   | SPM Dispatcher                       |
 +--------+--------------------------------------+
-| SiP    | Silicon Provider                     |
-+--------+--------------------------------------+
 | SWd    | Secure World                         |
 +--------+--------------------------------------+
-| TLV    | Tag-Length-Value                     |
-+--------+--------------------------------------+
-| TOS    | Trusted Operating System             |
-+--------+--------------------------------------+
-| VM     | Virtual Machine                      |
-+--------+--------------------------------------+
 
 Foreword
 ========
@@ -74,34 +36,14 @@ Three implementations of a Secure Partition Manager co-exist in the TF-A
 codebase:
 
 #. S-EL2 SPMC based on the FF-A specification `[1]`_, enabling virtualization in
-   the secure world, managing multiple S-EL1 or S-EL0 partitions.
+   the secure world, managing multiple S-EL1 or S-EL0 partitions `[5]`_.
 #. EL3 SPMC based on the FF-A specification, managing a single S-EL1 partition
-   without virtualization in the secure world.
+   without virtualization in the secure world `[6]`_.
 #. EL3 SPM based on the MM specification, legacy implementation managing a
    single S-EL0 partition `[2]`_.
 
 These implementations differ in their respective SW architecture and only one
-can be selected at build time. This document:
-
-- describes the implementation from bullet 1. when the SPMC resides at S-EL2.
-- is not an architecture specification and it might provide assumptions
-  on sections mandated as implementation-defined in the specification.
-- covers the implications to TF-A used as a bootloader, and Hafnium used as a
-  reference code base for an S-EL2/SPMC secure firmware on platforms
-  implementing the FEAT_SEL2 architecture extension.
-
-Terminology
------------
-
-- The term Hypervisor refers to the NS-EL2 component managing Virtual Machines
-  (or partitions) in the normal world.
-- The term SPMC refers to the S-EL2 component managing secure partitions in
-  the secure world when the FEAT_SEL2 architecture extension is implemented.
-- Alternatively, SPMC can refer to an S-EL1 component, itself being a secure
-  partition and implementing the FF-A ABI on platforms not implementing the
-  FEAT_SEL2 architecture extension.
-- The term VM refers to a normal world Virtual Machine managed by an Hypervisor.
-- The term SP refers to a secure world "Virtual Machine" managed by an SPMC.
+can be selected at build time.
 
 Support for legacy platforms
 ----------------------------
@@ -123,16 +65,6 @@ TF-A supports both cases:
 - S-EL2 SPMC for platforms implementing the FEAT_SEL2 architecture
   extension. The SPMD relays the FF-A protocol from EL3 to S-EL2.
 
-Sample reference stack
-======================
-
-The following diagram illustrates a possible configuration when the
-FEAT_SEL2 architecture extension is implemented, showing the SPMD
-and SPMC, one or multiple secure partitions, with an optional
-Hypervisor:
-
-.. image:: ../resources/diagrams/ff-a-spm-sel2.png
-
 TF-A build options
 ==================
 
@@ -147,16 +79,15 @@ SPMC located at S-EL1, S-EL2 or EL3:
   level to being at S-EL2. It defaults to enabled (value 1) when
   SPD=spmd is chosen.
 - **SPMC_AT_EL3**: this option adjusts the SPMC exception level to being
-  at EL3.
-- If neither ``SPMD_SPM_AT_SEL2`` or ``SPMC_AT_EL3`` are enabled the SPMC
-  exception level is set to S-EL1.
+  at EL3. If neither ``SPMD_SPM_AT_SEL2`` or ``SPMC_AT_EL3`` are enabled the
+  SPMC exception level is set to S-EL1.
   ``SPMD_SPM_AT_SEL2`` is enabled. The context save/restore routine
   and exhaustive list of registers is visible at `[4]`_.
 - **SPMC_AT_EL3_SEL0_SP**: this option enables the support to load SEL0 SP
   when SPMC at EL3 support is enabled.
 - **SP_LAYOUT_FILE**: this option specifies a text description file
   providing paths to SP binary images and manifests in DTS format
-  (see `Describing secure partitions`_). It
+  (see `[3]`_). It
   is required when ``SPMD_SPM_AT_SEL2`` is enabled hence when multiple
   secure partitions are to be loaded by BL2 on behalf of the SPMC.
 
@@ -179,7 +110,7 @@ Notes:
 - Only Arm's FVP platform is supported to use with the TF-A reference software
   stack.
 - When ``SPMD_SPM_AT_SEL2=1``, the reference software stack assumes enablement
-  of FEAT_PAuth, FEAT_BTI and FEAT_MTE architecture extensions.
+  of FEAT_PAuth, FEAT_BTI and FEAT_MTE2 architecture extensions.
 - ``(*) CTX_INCLUDE_EL2_REGS``, this flag is |TF-A| internal and informational
   in this table. When set, it provides the generic support for saving/restoring
   EL2 registers required when S-EL2 firmware is present.
@@ -215,7 +146,7 @@ implemented and the SPMC is located at S-EL2:
     ARM_ARCH_MINOR=5 \
     BRANCH_PROTECTION=1 \
     CTX_INCLUDE_PAUTH_REGS=1 \
-    CTX_INCLUDE_MTE_REGS=1 \
+    ENABLE_FEAT_MTE2=1 \
     BL32=<path-to-hafnium-binary> \
     BL33=<path-to-bl33-binary> \
     SP_LAYOUT_FILE=sp_layout.json \
@@ -233,7 +164,7 @@ implemented, the SPMC is located at S-EL2, and enabling secure boot:
     ARM_ARCH_MINOR=5 \
     BRANCH_PROTECTION=1 \
     CTX_INCLUDE_PAUTH_REGS=1 \
-    CTX_INCLUDE_MTE_REGS=1 \
+    ENABLE_FEAT_MTE2=1 \
     BL32=<path-to-hafnium-binary> \
     BL33=<path-to-bl33-binary> \
     SP_LAYOUT_FILE=sp_layout.json \
@@ -275,1358 +206,28 @@ enabled:
     PLAT=fvp \
     all fip
 
-FVP model invocation
-====================
-
-The FVP command line needs the following options to exercise the S-EL2 SPMC:
-
-+---------------------------------------------------+------------------------------------+
-| - cluster0.has_arm_v8-5=1                         | Implements FEAT_SEL2, FEAT_PAuth,  |
-| - cluster1.has_arm_v8-5=1                         | and FEAT_BTI.                      |
-+---------------------------------------------------+------------------------------------+
-| - pci.pci_smmuv3.mmu.SMMU_AIDR=2                  | Parameters required for the        |
-| - pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B         | SMMUv3.2 modeling.                 |
-| - pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002         |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714             |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0472         |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002       |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_S_IDR2=0                |                                    |
-| - pci.pci_smmuv3.mmu.SMMU_S_IDR3=0                |                                    |
-+---------------------------------------------------+------------------------------------+
-| - cluster0.has_branch_target_exception=1          | Implements FEAT_BTI.               |
-| - cluster1.has_branch_target_exception=1          |                                    |
-+---------------------------------------------------+------------------------------------+
-| - cluster0.has_pointer_authentication=2           | Implements FEAT_PAuth              |
-| - cluster1.has_pointer_authentication=2           |                                    |
-+---------------------------------------------------+------------------------------------+
-| - cluster0.memory_tagging_support_level=2         | Implements FEAT_MTE2               |
-| - cluster1.memory_tagging_support_level=2         |                                    |
-| - bp.dram_metadata.is_enabled=1                   |                                    |
-+---------------------------------------------------+------------------------------------+
-
-Sample FVP command line invocation:
-
-.. code:: shell
-
-    <path-to-fvp-model>/FVP_Base_RevC-2xAEMvA -C pctl.startup=0.0.0.0 \
-    -C cluster0.NUM_CORES=4 -C cluster1.NUM_CORES=4 -C bp.secure_memory=1 \
-    -C bp.secureflashloader.fname=trusted-firmware-a/build/fvp/debug/bl1.bin \
-    -C bp.flashloader0.fname=trusted-firmware-a/build/fvp/debug/fip.bin \
-    -C bp.pl011_uart0.out_file=fvp-uart0.log -C bp.pl011_uart1.out_file=fvp-uart1.log \
-    -C bp.pl011_uart2.out_file=fvp-uart2.log \
-    -C cluster0.has_arm_v8-5=1 -C cluster1.has_arm_v8-5=1 \
-    -C cluster0.has_pointer_authentication=2 -C cluster1.has_pointer_authentication=2 \
-    -C cluster0.has_branch_target_exception=1 -C cluster1.has_branch_target_exception=1 \
-    -C cluster0.memory_tagging_support_level=2 -C cluster1.memory_tagging_support_level=2 \
-    -C bp.dram_metadata.is_enabled=1 \
-    -C pci.pci_smmuv3.mmu.SMMU_AIDR=2 -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B \
-    -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002 -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714 \
-    -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0472 -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002 \
-    -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0 -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0
-
 Boot process
 ============
 
-Loading Hafnium and secure partitions in the secure world
----------------------------------------------------------
-
-TF-A BL2 is the bootlader for the SPMC and SPs in the secure world.
-
-SPs may be signed by different parties (SiP, OEM/ODM, TOS vendor, etc.).
-Thus they are supplied as distinct signed entities within the FIP flash
-image. The FIP image itself is not signed hence this provides the ability
-to upgrade SPs in the field.
-
-Booting through TF-A
---------------------
-
-SP manifests
-~~~~~~~~~~~~
-
-An SP manifest describes SP attributes as defined in `[1]`_
-(partition manifest at virtual FF-A instance) in DTS format. It is
-represented as a single file associated with the SP. A sample is
-provided by `[5]`_. A binding document is provided by `[6]`_.
-
-Secure Partition packages
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Secure partitions are bundled as independent package files consisting
-of:
-
-- a header
-- a DTB
-- an image payload
-
-The header starts with a magic value and offset values to SP DTB and
-image payload. Each SP package is loaded independently by BL2 loader
-and verified for authenticity and integrity.
-
-The SP package identified by its UUID (matching FF-A uuid property) is
-inserted as a single entry into the FIP at end of the TF-A build flow
-as shown:
-
-.. code:: shell
-
-    Trusted Boot Firmware BL2: offset=0x1F0, size=0x8AE1, cmdline="--tb-fw"
-    EL3 Runtime Firmware BL31: offset=0x8CD1, size=0x13000, cmdline="--soc-fw"
-    Secure Payload BL32 (Trusted OS): offset=0x1BCD1, size=0x15270, cmdline="--tos-fw"
-    Non-Trusted Firmware BL33: offset=0x30F41, size=0x92E0, cmdline="--nt-fw"
-    HW_CONFIG: offset=0x3A221, size=0x2348, cmdline="--hw-config"
-    TB_FW_CONFIG: offset=0x3C569, size=0x37A, cmdline="--tb-fw-config"
-    SOC_FW_CONFIG: offset=0x3C8E3, size=0x48, cmdline="--soc-fw-config"
-    TOS_FW_CONFIG: offset=0x3C92B, size=0x427, cmdline="--tos-fw-config"
-    NT_FW_CONFIG: offset=0x3CD52, size=0x48, cmdline="--nt-fw-config"
-    B4B5671E-4A90-4FE1-B81F-FB13DAE1DACB: offset=0x3CD9A, size=0xC168, cmdline="--blob"
-    D1582309-F023-47B9-827C-4464F5578FC8: offset=0x48F02, size=0xC168, cmdline="--blob"
-
-.. uml:: ../resources/diagrams/plantuml/fip-secure-partitions.puml
-
-Describing secure partitions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A json-formatted description file is passed to the build flow specifying paths
-to the SP binary image and associated DTS partition manifest file. The latter
-is processed by the dtc compiler to generate a DTB fed into the SP package.
-Optionally, the partition's json description can contain offsets for both
-the image and partition manifest within the SP package. Both offsets need to be
-4KB aligned, because it is the translation granule supported by Hafnium SPMC.
-These fields can be leveraged to support SPs with S1 translation granules that
-differ from 4KB, and to configure the regions allocated within the SP package,
-as well as to comply with the requirements for the implementation of the boot
-information protocol (see `Passing boot data to the SP`_ for more details). In
-case the offsets are absent in their json node, they default to 0x1000 and
-0x4000 for the manifest offset and image offset respectively.
-This file also specifies the SP owner (as an optional field) identifying the
-signing domain in case of dual root CoT.
-The SP owner can either be the silicon or the platform provider. The
-corresponding "owner" field value can either take the value of "SiP" or "Plat".
-In absence of "owner" field, it defaults to "SiP" owner.
-The UUID of the partition can be specified as a field in the description file or
-if it does not exist there the UUID is extracted from the DTS partition
-manifest.
-
-.. code:: shell
-
-    {
-        "tee1" : {
-            "image": "tee1.bin",
-             "pm": "tee1.dts",
-             "owner": "SiP",
-             "uuid": "1b1820fe-48f7-4175-8999-d51da00b7c9f"
-        },
-
-        "tee2" : {
-            "image": "tee2.bin",
-            "pm": "tee2.dts",
-            "owner": "Plat"
-        },
-
-        "tee3" : {
-            "image": {
-                "file": "tee3.bin",
-                "offset":"0x2000"
-             },
-            "pm": {
-                "file": "tee3.dts",
-                "offset":"0x6000"
-             },
-            "owner": "Plat"
-        },
-    }
-
-SPMC manifest
-~~~~~~~~~~~~~
-
-This manifest contains the SPMC *attribute* node consumed by the SPMD at boot
-time. It implements `[1]`_ (SP manifest at physical FF-A instance) and serves
-two different cases:
-
-- The SPMC resides at S-EL1: the SPMC manifest is used by the SPMD to setup a
-  SP that co-resides with the SPMC and executes at S-EL1 or Secure Supervisor
-  mode.
-- The SPMC resides at S-EL2: the SPMC manifest is used by the SPMD to setup
-  the environment required by the SPMC to run at S-EL2. SPs run at S-EL1 or
-  S-EL0.
-
-.. code:: shell
-
-    attribute {
-        spmc_id = <0x8000>;
-        maj_ver = <0x1>;
-        min_ver = <0x1>;
-        exec_state = <0x0>;
-        load_address = <0x0 0x6000000>;
-        entrypoint = <0x0 0x6000000>;
-        binary_size = <0x60000>;
-    };
-
-- *spmc_id* defines the endpoint ID value that SPMC can query through
-  ``FFA_ID_GET``.
-- *maj_ver/min_ver*. SPMD checks provided version versus its internal
-  version and aborts if not matching.
-- *exec_state* defines the SPMC execution state (AArch64 or AArch32).
-  Notice Hafnium used as a SPMC only supports AArch64.
-- *load_address* and *binary_size* are mostly used to verify secondary
-  entry points fit into the loaded binary image.
-- *entrypoint* defines the cold boot primary core entry point used by
-  SPMD (currently matches ``BL32_BASE``) to enter the SPMC.
-
-Other nodes in the manifest are consumed by Hafnium in the secure world.
-A sample can be found at `[7]`_:
-
-- The *hypervisor* node describes SPs. *is_ffa_partition* boolean attribute
-  indicates a FF-A compliant SP. The *load_address* field specifies the load
-  address at which BL2 loaded the SP package.
-- *cpus* node provide the platform topology and allows MPIDR to VMPIDR mapping.
-  Note the primary core is declared first, then secondary cores are declared
-  in reverse order.
-- The *memory* nodes provide platform information on the ranges of memory
-  available for use by SPs at runtime. These ranges relate to either
-  secure or non-secure memory, depending on the *device_type* field.
-  If the field specifies "memory" the range is secure, else if it specifies
-  "ns-memory" the memory is non-secure. The system integrator must exclude
-  the memory used by other components that are not SPs, such as the monitor,
-  or the SPMC itself, the OS Kernel/Hypervisor, or other NWd VMs. The SPMC
-  limits the SP's address space such that they do not access memory outside
-  of those ranges.
+The boot process involving SPMC is highly dependent on the SPMC implementation.
+It is recommended to refer to corresponding SPMC documentation for further
+details. Some aspects of boot process are described here in the greater interest
+of the project.
 
 SPMC boot
-~~~~~~~~~
+---------
 
-The SPMC is loaded by BL2 as the BL32 image.
+When SPMC resides at a lower EL i.e., S-EL1 or S-EL2, it is loaded by BL2 as the
+BL32 image. The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image `[7]`_.
 
-The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image `[9]`_.
-
-BL2 passes the SPMC manifest address to BL31 through a register.
-
-At boot time, the SPMD in BL31 runs from the primary core, initializes the core
-contexts and launches the SPMC (BL32) passing the following information through
-registers:
+BL2 passes the SPMC manifest address to BL31 through a register. At boot time,
+the SPMD in BL31 runs from the primary core, initializes the core contexts and
+launches the SPMC (BL32) passing the following information through registers:
 
 - X0 holds the ``TOS_FW_CONFIG`` physical address (or SPMC manifest blob).
 - X1 holds the ``HW_CONFIG`` physical address.
 - X4 holds the currently running core linear id.
 
-Loading of SPs
-~~~~~~~~~~~~~~
-
-At boot time, BL2 loads SPs sequentially in addition to the SPMC as depicted
-below:
-
-.. uml:: ../resources/diagrams/plantuml/bl2-loading-sp.puml
-
-Note this boot flow is an implementation sample on Arm's FVP platform.
-Platforms not using TF-A's *Firmware CONFiguration* framework would adjust to a
-different boot flow. The flow restricts to a maximum of 8 secure partitions.
-
-Secure boot
-~~~~~~~~~~~
-
-The SP content certificate is inserted as a separate FIP item so that BL2 loads SPMC,
-SPMC manifest, secure partitions and verifies them for authenticity and integrity.
-Refer to TBBR specification `[3]`_.
-
-The multiple-signing domain feature (in current state dual signing domain `[8]`_) allows
-the use of two root keys namely S-ROTPK and NS-ROTPK:
-
-- SPMC (BL32) and SPMC manifest are signed by the SiP using the S-ROTPK.
-- BL33 may be signed by the OEM using NS-ROTPK.
-- An SP may be signed either by SiP (using S-ROTPK) or by OEM (using NS-ROTPK).
-- A maximum of 4 partitions can be signed with the S-ROTPK key and 4 partitions
-  signed with the NS-ROTPK key.
-
-Also refer to `Describing secure partitions`_ and `TF-A build options`_ sections.
-
-Hafnium in the secure world
-===========================
-
-General considerations
-----------------------
-
-Build platform for the secure world
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In the Hafnium reference implementation specific code parts are only relevant to
-the secure world. Such portions are isolated in architecture specific files
-and/or enclosed by a ``SECURE_WORLD`` macro.
-
-Secure partitions scheduling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The FF-A specification `[1]`_ provides two ways to relinquinsh CPU time to
-secure partitions. For this a VM (Hypervisor or OS kernel), or SP invokes one of:
-
-- the FFA_MSG_SEND_DIRECT_REQ interface.
-- the FFA_RUN interface.
-
-Additionally a secure interrupt can pre-empt the normal world execution and give
-CPU cycles by transitioning to EL3 and S-EL2.
-
-Platform topology
-~~~~~~~~~~~~~~~~~
-
-The *execution-ctx-count* SP manifest field can take the value of one or the
-total number of PEs. The FF-A specification `[1]`_  recommends the
-following SP types:
-
-- Pinned MP SPs: an execution context matches a physical PE. MP SPs must
-  implement the same number of ECs as the number of PEs in the platform.
-- Migratable UP SPs: a single execution context can run and be migrated on any
-  physical PE. Such SP declares a single EC in its SP manifest. An UP SP can
-  receive a direct message request originating from any physical core targeting
-  the single execution context.
-
-Parsing SP partition manifests
-------------------------------
-
-Hafnium consumes SP manifests as defined in `[1]`_ and `SP manifests`_.
-Note the current implementation may not implement all optional fields.
-
-The SP manifest may contain memory and device regions nodes. In case of
-an S-EL2 SPMC:
-
-- Memory regions are mapped in the SP EL1&0 Stage-2 translation regime at
-  load time (or EL1&0 Stage-1 for an S-EL1 SPMC). A memory region node can
-  specify RX/TX buffer regions in which case it is not necessary for an SP
-  to explicitly invoke the ``FFA_RXTX_MAP`` interface. The memory referred
-  shall be contained within the memory ranges defined in SPMC manifest. The
-  NS bit in the attributes field should be consistent with the security
-  state of the range that it relates to. I.e. non-secure memory shall be
-  part of a non-secure memory range, and secure memory shall be contained
-  in a secure memory range of a given platform.
-- Device regions are mapped in the SP EL1&0 Stage-2 translation regime (or
-  EL1&0 Stage-1 for an S-EL1 SPMC) as peripherals and possibly allocate
-  additional resources (e.g. interrupts).
-
-For the S-EL2 SPMC, base addresses for memory and device region nodes are IPAs
-provided the SPMC identity maps IPAs to PAs within SP EL1&0 Stage-2 translation
-regime.
-
-Note: in the current implementation both VTTBR_EL2 and VSTTBR_EL2 point to the
-same set of page tables. It is still open whether two sets of page tables shall
-be provided per SP. The memory region node as defined in the specification
-provides a memory security attribute hinting to map either to the secure or
-non-secure EL1&0 Stage-2 table if it exists.
-
-Passing boot data to the SP
----------------------------
-
-In `[1]`_ , the section  "Boot information protocol" defines a method for passing
-data to the SPs at boot time. It specifies the format for the boot information
-descriptor and boot information header structures, which describe the data to be
-exchanged between SPMC and SP.
-The specification also defines the types of data that can be passed.
-The aggregate of both the boot info structures and the data itself is designated
-the boot information blob, and is passed to a Partition as a contiguous memory
-region.
-
-Currently, the SPM implementation supports the FDT type which is used to pass the
-partition's DTB manifest.
-
-The region for the boot information blob is allocated through the SP package.
-
-.. image:: ../resources/diagrams/partition-package.png
-
-To adjust the space allocated for the boot information blob, the json description
-of the SP (see section `Describing secure partitions`_) shall be updated to contain
-the manifest offset. If no offset is provided the manifest offset defaults to 0x1000,
-which is the page size in the Hafnium SPMC.
-
-The configuration of the boot protocol is done in the SPs manifest. As defined by
-the specification, the manifest field 'gp-register-num' configures the GP register
-which shall be used to pass the address to the partitions boot information blob when
-booting the partition.
-In addition, the Hafnium SPMC implementation requires the boot information arguments
-to be listed in a designated DT node:
-
-.. code:: shell
-
-  boot-info {
-      compatible = "arm,ffa-manifest-boot-info";
-      ffa_manifest;
-  };
-
-The whole secure partition package image (see `Secure Partition packages`_) is
-mapped to the SP secure EL1&0 Stage-2 translation regime. As such, the SP can
-retrieve the address for the boot information blob in the designated GP register,
-process the boot information header and descriptors, access its own manifest
-DTB blob and extract its partition manifest properties.
-
-SP Boot order
--------------
-
-SP manifests provide an optional boot order attribute meant to resolve
-dependencies such as an SP providing a service required to properly boot
-another SP. SPMC boots the SPs in accordance to the boot order attribute,
-lowest to the highest value. If the boot order attribute is absent from the FF-A
-manifest, the SP is treated as if it had the highest boot order value
-(i.e. lowest booting priority).
-
-It is possible for an SP to call into another SP through a direct request
-provided the latter SP has already been booted.
-
-Boot phases
------------
-
-Primary core boot-up
-~~~~~~~~~~~~~~~~~~~~
-
-Upon boot-up, BL31 hands over to the SPMC (BL32) on the primary boot physical
-core. The SPMC performs its platform initializations and registers the SPMC
-secondary physical core entry point physical address by the use of the
-`FFA_SECONDARY_EP_REGISTER`_ interface (SMC invocation from the SPMC to the SPMD
-at secure physical FF-A instance).
-
-The SPMC then creates secure partitions based on SP packages and manifests. Each
-secure partition is launched in sequence (`SP Boot order`_) on their "primary"
-execution context. If the primary boot physical core linear id is N, an MP SP is
-started using EC[N] on PE[N] (see `Platform topology`_). If the partition is a
-UP SP, it is started using its unique EC0 on PE[N].
-
-The SP primary EC (or the EC used when the partition is booted as described
-above):
-
-- Performs the overall SP boot time initialization, and in case of a MP SP,
-  prepares the SP environment for other execution contexts.
-- In the case of a MP SP, it invokes the FFA_SECONDARY_EP_REGISTER at secure
-  virtual FF-A instance (SMC invocation from SP to SPMC) to provide the IPA
-  entry point for other execution contexts.
-- Exits through ``FFA_MSG_WAIT`` to indicate successful initialization or
-  ``FFA_ERROR`` in case of failure.
-
-Secondary cores boot-up
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Once the system is started and NWd brought up, a secondary physical core is
-woken up by the ``PSCI_CPU_ON`` service invocation. The TF-A SPD hook mechanism
-calls into the SPMD on the newly woken up physical core. Then the SPMC is
-entered at the secondary physical core entry point.
-
-In the current implementation, the first SP is resumed on the coresponding EC
-(the virtual CPU which matches the physical core). The implication is that the
-first SP must be a MP SP.
-
-In a linux based system, once secure and normal worlds are booted but prior to
-a NWd FF-A driver has been loaded:
-
-- The first SP has initialized all its ECs in response to primary core boot up
-  (at system initialization) and secondary core boot up (as a result of linux
-  invoking PSCI_CPU_ON for all secondary cores).
-- Other SPs have their first execution context initialized as a result of secure
-  world initialization on the primary boot core. Other ECs for those SPs have to
-  be run first through ffa_run to complete their initialization (which results
-  in the EC completing with FFA_MSG_WAIT).
-
-Refer to `Power management`_ for further details.
-
-Notifications
--------------
-
-The FF-A v1.1 specification `[1]`_ defines notifications as an asynchronous
-communication mechanism with non-blocking semantics. It allows for one FF-A
-endpoint to signal another for service provision, without hindering its current
-progress.
-
-Hafnium currently supports 64 notifications. The IDs of each notification define
-a position in a 64-bit bitmap.
-
-The signaling of notifications can interchangeably happen between NWd and SWd
-FF-A endpoints.
-
-The SPMC is in charge of managing notifications from SPs to SPs, from SPs to
-VMs, and from VMs to SPs. An hypervisor component would only manage
-notifications from VMs to VMs. Given the SPMC has no visibility of the endpoints
-deployed in NWd, the Hypervisor or OS kernel must invoke the interface
-FFA_NOTIFICATION_BITMAP_CREATE to allocate the notifications bitmap per FF-A
-endpoint in the NWd that supports it.
-
-A sender can signal notifications once the receiver has provided it with
-permissions. Permissions are provided by invoking the interface
-FFA_NOTIFICATION_BIND.
-
-Notifications are signaled by invoking FFA_NOTIFICATION_SET. Henceforth
-they are considered to be in a pending sate. The receiver can retrieve its
-pending notifications invoking FFA_NOTIFICATION_GET, which, from that moment,
-are considered to be handled.
-
-Per the FF-A v1.1 spec, each FF-A endpoint must be associated with a scheduler
-that is in charge of donating CPU cycles for notifications handling. The
-FF-A driver calls FFA_NOTIFICATION_INFO_GET to retrieve the information about
-which FF-A endpoints have pending notifications. The receiver scheduler is
-called and informed by the FF-A driver, and it should allocate CPU cycles to the
-receiver.
-
-There are two types of notifications supported:
-
-- Global, which are targeted to a FF-A endpoint and can be handled within any of
-  its execution contexts, as determined by the scheduler of the system.
-- Per-vCPU, which are targeted to a FF-A endpoint and to be handled within a
-  a specific execution context, as determined by the sender.
-
-The type of a notification is set when invoking FFA_NOTIFICATION_BIND to give
-permissions to the sender.
-
-Notification signaling resorts to two interrupts:
-
-- Schedule Receiver Interrupt: non-secure physical interrupt to be handled by
-  the FF-A driver within the receiver scheduler. At initialization the SPMC
-  donates a SGI ID chosen from the secure SGI IDs range and configures it as
-  non-secure. The SPMC triggers this SGI on the currently running core when
-  there are pending notifications, and the respective receivers need CPU cycles
-  to handle them.
-- Notifications Pending Interrupt: virtual interrupt to be handled by the
-  receiver of the notification. Set when there are pending notifications for the
-  given secure partition. The NPI is pended when the NWd relinquishes CPU cycles
-  to an SP.
-
-The notifications receipt support is enabled in the partition FF-A manifest.
-
-Mandatory interfaces
---------------------
-
-The following interfaces are exposed to SPs:
-
--  ``FFA_VERSION``
--  ``FFA_FEATURES``
--  ``FFA_RX_RELEASE``
--  ``FFA_RXTX_MAP``
--  ``FFA_RXTX_UNMAP``
--  ``FFA_PARTITION_INFO_GET``
--  ``FFA_ID_GET``
--  ``FFA_MSG_WAIT``
--  ``FFA_MSG_SEND_DIRECT_REQ``
--  ``FFA_MSG_SEND_DIRECT_RESP``
--  ``FFA_MEM_DONATE``
--  ``FFA_MEM_LEND``
--  ``FFA_MEM_SHARE``
--  ``FFA_MEM_RETRIEVE_REQ``
--  ``FFA_MEM_RETRIEVE_RESP``
--  ``FFA_MEM_RELINQUISH``
--  ``FFA_MEM_FRAG_RX``
--  ``FFA_MEM_FRAG_TX``
--  ``FFA_MEM_RECLAIM``
--  ``FFA_RUN``
-
-As part of the FF-A v1.1 support, the following interfaces were added:
-
- - ``FFA_NOTIFICATION_BITMAP_CREATE``
- - ``FFA_NOTIFICATION_BITMAP_DESTROY``
- - ``FFA_NOTIFICATION_BIND``
- - ``FFA_NOTIFICATION_UNBIND``
- - ``FFA_NOTIFICATION_SET``
- - ``FFA_NOTIFICATION_GET``
- - ``FFA_NOTIFICATION_INFO_GET``
- - ``FFA_SPM_ID_GET``
- - ``FFA_SECONDARY_EP_REGISTER``
- - ``FFA_MEM_PERM_GET``
- - ``FFA_MEM_PERM_SET``
- - ``FFA_MSG_SEND2``
- - ``FFA_RX_ACQUIRE``
-
-FFA_VERSION
-~~~~~~~~~~~
-
-``FFA_VERSION`` requires a *requested_version* parameter from the caller.
-The returned value depends on the caller:
-
-- Hypervisor or OS kernel in NS-EL1/EL2: the SPMD returns the SPMC version
-  specified in the SPMC manifest.
-- SP: the SPMC returns its own implemented version.
-- SPMC at S-EL1/S-EL2: the SPMD returns its own implemented version.
-
-FFA_FEATURES
-~~~~~~~~~~~~
-
-FF-A features supported by the SPMC may be discovered by secure partitions at
-boot (that is prior to NWd is booted) or run-time.
-
-The SPMC calling FFA_FEATURES at secure physical FF-A instance always get
-FFA_SUCCESS from the SPMD.
-
-The request made by an Hypervisor or OS kernel is forwarded to the SPMC and
-the response relayed back to the NWd.
-
-FFA_RXTX_MAP/FFA_RXTX_UNMAP
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When invoked from a secure partition FFA_RXTX_MAP maps the provided send and
-receive buffers described by their IPAs to the SP EL1&0 Stage-2 translation
-regime as secure buffers in the MMU descriptors.
-
-When invoked from the Hypervisor or OS kernel, the buffers are mapped into the
-SPMC EL2 Stage-1 translation regime and marked as NS buffers in the MMU
-descriptors. The provided addresses may be owned by a VM in the normal world,
-which is expected to receive messages from the secure world. The SPMC will in
-this case allocate internal state structures to facilitate RX buffer access
-synchronization (through FFA_RX_ACQUIRE interface), and to permit SPs to send
-messages.
-
-The FFA_RXTX_UNMAP unmaps the RX/TX pair from the translation regime of the
-caller, either it being the Hypervisor or OS kernel, as well as a secure
-partition.
-
-FFA_PARTITION_INFO_GET
-~~~~~~~~~~~~~~~~~~~~~~
-
-Partition info get call can originate:
-
-- from SP to SPMC
-- from Hypervisor or OS kernel to SPMC. The request is relayed by the SPMD.
-
-FFA_ID_GET
-~~~~~~~~~~
-
-The FF-A id space is split into a non-secure space and secure space:
-
-- FF-A ID with bit 15 clear relates to VMs.
-- FF-A ID with bit 15 set related to SPs.
-- FF-A IDs 0, 0xffff, 0x8000 are assigned respectively to the Hypervisor, SPMD
-  and SPMC.
-
-The SPMD returns:
-
-- The default zero value on invocation from the Hypervisor.
-- The ``spmc_id`` value specified in the SPMC manifest on invocation from
-  the SPMC (see `SPMC manifest`_)
-
-This convention helps the SPMC to determine the origin and destination worlds in
-an FF-A ABI invocation. In particular the SPMC shall filter unauthorized
-transactions in its world switch routine. It must not be permitted for a VM to
-use a secure FF-A ID as origin world by spoofing:
-
-- A VM-to-SP direct request/response shall set the origin world to be non-secure
-  (FF-A ID bit 15 clear) and destination world to be secure (FF-A ID bit 15
-  set).
-- Similarly, an SP-to-SP direct request/response shall set the FF-A ID bit 15
-  for both origin and destination IDs.
-
-An incoming direct message request arriving at SPMD from NWd is forwarded to
-SPMC without a specific check. The SPMC is resumed through eret and "knows" the
-message is coming from normal world in this specific code path. Thus the origin
-endpoint ID must be checked by SPMC for being a normal world ID.
-
-An SP sending a direct message request must have bit 15 set in its origin
-endpoint ID and this can be checked by the SPMC when the SP invokes the ABI.
-
-The SPMC shall reject the direct message if the claimed world in origin endpoint
-ID is not consistent:
-
--  It is either forwarded by SPMD and thus origin endpoint ID must be a "normal
-   world ID",
--  or initiated by an SP and thus origin endpoint ID must be a "secure world ID".
-
-
-FFA_MSG_SEND_DIRECT_REQ/FFA_MSG_SEND_DIRECT_RESP
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is a mandatory interface for secure partitions consisting in direct request
-and responses with the following rules:
-
-- An SP can send a direct request to another SP.
-- An SP can receive a direct request from another SP.
-- An SP can send a direct response to another SP.
-- An SP cannot send a direct request to an Hypervisor or OS kernel.
-- An Hypervisor or OS kernel can send a direct request to an SP.
-- An SP can send a direct response to an Hypervisor or OS kernel.
-
-FFA_NOTIFICATION_BITMAP_CREATE/FFA_NOTIFICATION_BITMAP_DESTROY
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The secure partitions notifications bitmap are statically allocated by the SPMC.
-Hence, this interface is not to be issued by secure partitions.
-
-At initialization, the SPMC is not aware of VMs/partitions deployed in the
-normal world. Hence, the Hypervisor or OS kernel must use both ABIs for SPMC
-to be prepared to handle notifications for the provided VM ID.
-
-FFA_NOTIFICATION_BIND/FFA_NOTIFICATION_UNBIND
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Pair of interfaces to manage permissions to signal notifications. Prior to
-handling notifications, an FF-A endpoint must allow a given sender to signal a
-bitmap of notifications.
-
-If the receiver doesn't have notification support enabled in its FF-A manifest,
-it won't be able to bind notifications, hence forbidding it to receive any
-notifications.
-
-FFA_NOTIFICATION_SET/FFA_NOTIFICATION_GET
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-FFA_NOTIFICATION_GET retrieves all pending global notifications and
-per-vCPU notifications targeted to the current vCPU.
-
-Hafnium maintains a global count of pending notifications which gets incremented
-and decremented when handling FFA_NOTIFICATION_SET and FFA_NOTIFICATION_GET
-respectively. A delayed SRI is triggered if the counter is non-zero when the
-SPMC returns to normal world.
-
-FFA_NOTIFICATION_INFO_GET
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Hafnium maintains a global count of pending notifications whose information
-has been retrieved by this interface. The count is incremented and decremented
-when handling FFA_NOTIFICATION_INFO_GET and FFA_NOTIFICATION_GET respectively.
-It also tracks notifications whose information has been retrieved individually,
-such that it avoids duplicating returned information for subsequent calls to
-FFA_NOTIFICATION_INFO_GET. For each notification, this state information is
-reset when receiver called FFA_NOTIFICATION_GET to retrieve them.
-
-FFA_SPM_ID_GET
-~~~~~~~~~~~~~~
-
-Returns the FF-A ID allocated to an SPM component which can be one of SPMD
-or SPMC.
-
-At initialization, the SPMC queries the SPMD for the SPMC ID, using the
-FFA_ID_GET interface, and records it. The SPMC can also query the SPMD ID using
-the FFA_SPM_ID_GET interface at the secure physical FF-A instance.
-
-Secure partitions call this interface at the virtual FF-A instance, to which
-the SPMC returns the priorly retrieved SPMC ID.
-
-The Hypervisor or OS kernel can issue the FFA_SPM_ID_GET call handled by the
-SPMD, which returns the SPMC ID.
-
-FFA_SECONDARY_EP_REGISTER
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When the SPMC boots, all secure partitions are initialized on their primary
-Execution Context.
-
-The FFA_SECONDARY_EP_REGISTER interface is to be used by a secure partition
-from its first execution context, to provide the entry point address for
-secondary execution contexts.
-
-A secondary EC is first resumed either upon invocation of PSCI_CPU_ON from
-the NWd or by invocation of FFA_RUN.
-
-FFA_RX_ACQUIRE/FFA_RX_RELEASE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The RX buffers can be used to pass information to an FF-A endpoint in the
-following scenarios:
-
- - When it was targetted by a FFA_MSG_SEND2 invokation from another endpoint.
- - Return the result of calling ``FFA_PARTITION_INFO_GET``.
- - In a memory share operation, as part of the ``FFA_MEM_RETRIEVE_RESP``,
-   with the memory descriptor of the shared memory.
-
-If a normal world VM is expected to exchange messages with secure world,
-its RX/TX buffer addresses are forwarded to the SPMC via FFA_RXTX_MAP ABI,
-and are from this moment owned by the SPMC.
-The hypervisor must call the FFA_RX_ACQUIRE interface before attempting
-to use the RX buffer, in any of the aforementioned scenarios. A successful
-call to FFA_RX_ACQUIRE transfers ownership of RX buffer to hypervisor, such
-that it can be safely used.
-
-The FFA_RX_RELEASE interface is used after the FF-A endpoint is done with
-processing the data received in its RX buffer. If the RX buffer has been
-acquired by the hypervisor, the FFA_RX_RELEASE call must be forwarded to
-the SPMC to reestablish SPMC's RX ownership.
-
-An attempt from an SP to send a message to a normal world VM whose RX buffer
-was acquired by the hypervisor fails with error code FFA_BUSY, to preserve
-the RX buffer integrity.
-The operation could then be conducted after FFA_RX_RELEASE.
-
-FFA_MSG_SEND2
-~~~~~~~~~~~~~
-
-Hafnium copies a message from the sender TX buffer into receiver's RX buffer.
-For messages from SPs to VMs, operation is only possible if the SPMC owns
-the receiver's RX buffer.
-
-Both receiver and sender need to enable support for indirect messaging,
-in their respective partition manifest. The discovery of support
-of such feature can be done via FFA_PARTITION_INFO_GET.
-
-On a successful message send, Hafnium pends an RX buffer full framework
-notification for the receiver, to inform it about a message in the RX buffer.
-
-The handling of framework notifications is similar to that of
-global notifications. Binding of these is not necessary, as these are
-reserved to be used by the hypervisor or SPMC.
-
-SPMC-SPMD direct requests/responses
------------------------------------
-
-Implementation-defined FF-A IDs are allocated to the SPMC and SPMD.
-Using those IDs in source/destination fields of a direct request/response
-permits SPMD to SPMC communication and either way.
-
-- SPMC to SPMD direct request/response uses SMC conduit.
-- SPMD to SPMC direct request/response uses ERET conduit.
-
-This is used in particular to convey power management messages.
-
-Memory Sharing
---------------
-
-Hafnium implements the following memory sharing interfaces:
-
- - ``FFA_MEM_SHARE`` - for shared access between lender and borrower.
- - ``FFA_MEM_LEND`` - borrower to obtain exclusive access, though lender
-   retains ownership of the memory.
- - ``FFA_MEM_DONATE`` - lender permanently relinquishes ownership of memory
-   to the borrower.
-
-The ``FFA_MEM_RETRIEVE_REQ`` interface is for the borrower to request the
-memory to be mapped into its address space: for S-EL1 partitions the SPM updates
-their stage 2 translation regime; for S-EL0 partitions the SPM updates their
-stage 1 translation regime. On a successful call, the SPMC responds back with
-``FFA_MEM_RETRIEVE_RESP``.
-
-The ``FFA_MEM_RELINQUISH`` interface is for when the borrower is done with using
-a memory region.
-
-The ``FFA_MEM_RECLAIM`` interface is for the owner of the memory to reestablish
-its ownership and exclusive access to the memory shared.
-
-The memory transaction descriptors are transmitted via RX/TX buffers. In
-situations where the size of the memory transaction descriptor exceeds the
-size of the RX/TX buffers, Hafnium provides support for fragmented transmission
-of the full transaction descriptor. The ``FFA_MEM_FRAG_RX`` and ``FFA_MEM_FRAG_TX``
-interfaces are for receiving and transmitting the next fragment, respectively.
-
-If lender and borrower(s) are SPs, all memory sharing operations are supported.
-
-Hafnium also supports memory sharing operations between the normal world and the
-secure world. If there is an SP involved, the SPMC allocates data to track the
-state of the operation.
-
-The SPMC is also the designated allocator for the memory handle. The hypervisor
-or OS kernel has the possibility to rely on the SPMC to maintain the state
-of the operation, thus saving memory.
-A lender SP can only donate NS memory to a borrower from the normal world.
-
-The SPMC supports the hypervisor retrieve request, as defined by the FF-A
-v1.1 EAC0 specification, in section 16.4.3. The intent is to aid with operations
-that the hypervisor must do for a VM retriever. For example, when handling
-an FFA_MEM_RECLAIM, if the hypervisor relies on SPMC to keep the state
-of the operation, the hypervisor retrieve request can be used to obtain
-that state information, do the necessary validations, and update stage 2
-memory translation.
-
-Hafnium also supports memory lend and share targetting multiple borrowers.
-This is the case for a lender SP to multiple SPs, and for a lender VM to
-multiple endpoints (from both secure world and normal world). If there is
-at least one borrower VM, the hypervisor is in charge of managing its
-stage 2 translation on a successful memory retrieve.
-The semantics of ``FFA_MEM_DONATE`` implies ownership transmission,
-which should target only one partition.
-
-The memory share interfaces are backwards compatible with memory transaction
-descriptors from FF-A v1.0. These get translated to FF-A v1.1 descriptors for
-Hafnium's internal processing of the operation. If the FF-A version of a
-borrower is v1.0, Hafnium provides FF-A v1.0 compliant memory transaction
-descriptors on memory retrieve response.
-
-PE MMU configuration
---------------------
-
-With secure virtualization enabled (``HCR_EL2.VM = 1``) and for S-EL1
-partitions, two IPA spaces (secure and non-secure) are output from the
-secure EL1&0 Stage-1 translation.
-The EL1&0 Stage-2 translation hardware is fed by:
-
-- A secure IPA when the SP EL1&0 Stage-1 MMU is disabled.
-- One of secure or non-secure IPA when the secure EL1&0 Stage-1 MMU is enabled.
-
-``VTCR_EL2`` and ``VSTCR_EL2`` provide configuration bits for controlling the
-NS/S IPA translations. The following controls are set up:
-``VSTCR_EL2.SW = 0`` , ``VSTCR_EL2.SA = 0``, ``VTCR_EL2.NSW = 0``,
-``VTCR_EL2.NSA = 1``:
-
-- Stage-2 translations for the NS IPA space access the NS PA space.
-- Stage-2 translation table walks for the NS IPA space are to the secure PA space.
-
-Secure and non-secure IPA regions (rooted to by ``VTTBR_EL2`` and ``VSTTBR_EL2``)
-use the same set of Stage-2 page tables within a SP.
-
-The ``VTCR_EL2/VSTCR_EL2/VTTBR_EL2/VSTTBR_EL2`` virtual address space
-configuration is made part of a vCPU context.
-
-For S-EL0 partitions with VHE enabled, a single secure EL2&0 Stage-1 translation
-regime is used for both Hafnium and the partition.
-
-Schedule modes and SP Call chains
----------------------------------
-
-An SP execution context is said to be in SPMC scheduled mode if CPU cycles are
-allocated to it by SPMC. Correspondingly, an SP execution context is said to be
-in Normal world scheduled mode if CPU cycles are allocated by the normal world.
-
-A call chain represents all SPs in a sequence of invocations of a direct message
-request. When execution on a PE is in the secure state, only a single call chain
-that runs in the Normal World scheduled mode can exist. FF-A v1.1 spec allows
-any number of call chains to run in the SPMC scheduled mode but the Hafnium
-SPMC restricts the number of call chains in SPMC scheduled mode to only one for
-keeping the implementation simple.
-
-Partition runtime models
-------------------------
-
-The runtime model of an endpoint describes the transitions permitted for an
-execution context between various states. These are the four partition runtime
-models supported (refer to `[1]`_ section 7):
-
-  - RTM_FFA_RUN: runtime model presented to an execution context that is
-    allocated CPU cycles through FFA_RUN interface.
-  - RTM_FFA_DIR_REQ: runtime model presented to an execution context that is
-    allocated CPU cycles through FFA_MSG_SEND_DIRECT_REQ interface.
-  - RTM_SEC_INTERRUPT: runtime model presented to an execution context that is
-    allocated CPU cycles by SPMC to handle a secure interrupt.
-  - RTM_SP_INIT: runtime model presented to an execution context that is
-    allocated CPU cycles by SPMC to initialize its state.
-
-If an endpoint execution context attempts to make an invalid transition or a
-valid transition that could lead to a loop in the call chain, SPMC denies the
-transition with the help of above runtime models.
-
-Interrupt management
---------------------
-
-GIC ownership
-~~~~~~~~~~~~~
-
-The SPMC owns the GIC configuration. Secure and non-secure interrupts are
-trapped at S-EL2. The SPMC manages interrupt resources and allocates interrupt
-IDs based on SP manifests. The SPMC acknowledges physical interrupts and injects
-virtual interrupts by setting the use of vIRQ/vFIQ bits before resuming a SP.
-
-Abbreviations:
-
-  - NS-Int: A non-secure physical interrupt. It requires a switch to the normal
-    world to be handled if it triggers while execution is in secure world.
-  - Other S-Int: A secure physical interrupt targeted to an SP different from
-    the one that is currently running.
-  - Self S-Int: A secure physical interrupt targeted to the SP that is currently
-    running.
-
-Non-secure interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This section documents the actions supported in SPMC in response to a non-secure
-interrupt as per the guidance provided by FF-A v1.1 EAC0 specification.
-An SP specifies one of the following actions in its partition manifest:
-
-  - Non-secure interrupt is signaled.
-  - Non-secure interrupt is signaled after a managed exit.
-  - Non-secure interrupt is queued.
-
-An SP execution context in a call chain could specify a less permissive action
-than subsequent SP execution contexts in the same call chain. The less
-permissive action takes precedence over the more permissive actions specified
-by the subsequent execution contexts. Please refer to FF-A v1.1 EAC0 section
-8.3.1 for further explanation.
-
-Secure interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This section documents the support implemented for secure interrupt handling in
-SPMC as per the guidance provided by FF-A v1.1 EAC0 specification.
-The following assumptions are made about the system configuration:
-
-  - In the current implementation, S-EL1 SPs are expected to use the para
-    virtualized ABIs for interrupt management rather than accessing the virtual
-    GIC interface.
-  - Unless explicitly stated otherwise, this support is applicable only for
-    S-EL1 SPs managed by SPMC.
-  - Secure interrupts are configured as G1S or G0 interrupts.
-  - All physical interrupts are routed to SPMC when running a secure partition
-    execution context.
-  - All endpoints with multiple execution contexts have their contexts pinned
-    to corresponding CPUs. Hence, a secure virtual interrupt cannot be signaled
-    to a target vCPU that is currently running or blocked on a different
-    physical CPU.
-
-A physical secure interrupt could trigger while CPU is executing in normal world
-or secure world.
-The action of SPMC for a secure interrupt depends on: the state of the target
-execution context of the SP that is responsible for handling the interrupt;
-whether the interrupt triggered while execution was in normal world or secure
-world.
-
-Secure interrupt signaling mechanisms
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Signaling refers to the mechanisms used by SPMC to indicate to the SP execution
-context that it has a pending virtual interrupt and to further run the SP
-execution context, such that it can handle the virtual interrupt. SPMC uses
-either the FFA_INTERRUPT interface with ERET conduit or vIRQ signal for signaling
-to S-EL1 SPs. When normal world execution is preempted by a secure interrupt,
-the SPMD uses the FFA_INTERRUPT ABI with ERET conduit to signal interrupt to SPMC
-running in S-EL2.
-
-+-----------+---------+---------------+---------------------------------------+
-| SP State  | Conduit | Interface and | Description                           |
-|           |         | parameters    |                                       |
-+-----------+---------+---------------+---------------------------------------+
-| WAITING   | ERET,   | FFA_INTERRUPT,| SPMC signals to SP the ID of pending  |
-|           | vIRQ    | Interrupt ID  | interrupt. It pends vIRQ signal and   |
-|           |         |               | resumes execution context of SP       |
-|           |         |               | through ERET.                         |
-+-----------+---------+---------------+---------------------------------------+
-| BLOCKED   | ERET,   | FFA_INTERRUPT | SPMC signals to SP that an interrupt  |
-|           | vIRQ    |               | is pending. It pends vIRQ signal and  |
-|           |         |               | resumes execution context of SP       |
-|           |         |               | through ERET.                         |
-+-----------+---------+---------------+---------------------------------------+
-| PREEMPTED | vIRQ    | NA            | SPMC pends the vIRQ signal but does   |
-|           |         |               | not resume execution context of SP.   |
-+-----------+---------+---------------+---------------------------------------+
-| RUNNING   | ERET,   | NA            | SPMC pends the vIRQ signal and resumes|
-|           | vIRQ    |               | execution context of SP through ERET. |
-+-----------+---------+---------------+---------------------------------------+
-
-Secure interrupt completion mechanisms
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A SP signals secure interrupt handling completion to the SPMC through the
-following mechanisms:
-
-  - ``FFA_MSG_WAIT`` ABI if it was in WAITING state.
-  - ``FFA_RUN`` ABI if its was in BLOCKED state.
-
-This is a remnant of SPMC implementation based on the FF-A v1.0 specification.
-In the current implementation, S-EL1 SPs use the para-virtualized HVC interface
-implemented by SPMC to perform priority drop and interrupt deactivation (SPMC
-configures EOImode = 0, i.e. priority drop and deactivation are done together).
-The SPMC performs checks to deny the state transition upon invocation of
-either FFA_MSG_WAIT or FFA_RUN interface if the SP didn't perform the
-deactivation of the secure virtual interrupt.
-
-If the current SP execution context was preempted by a secure interrupt to be
-handled by execution context of target SP, SPMC resumes current SP after signal
-completion by target SP execution context.
-
-Actions for a secure interrupt triggered while execution is in normal world
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------------------+----------+-----------------------------------------------+
-| State of target   | Action   | Description                                   |
-| execution context |          |                                               |
-+-------------------+----------+-----------------------------------------------+
-| WAITING           | Signaled | This starts a new call chain in SPMC scheduled|
-|                   |          | mode.                                         |
-+-------------------+----------+-----------------------------------------------+
-| PREEMPTED         | Queued   | The target execution must have been preempted |
-|                   |          | by a non-secure interrupt. SPMC queues the    |
-|                   |          | secure virtual interrupt now. It is signaled  |
-|                   |          | when the target execution context next enters |
-|                   |          | the RUNNING state.                            |
-+-------------------+----------+-----------------------------------------------+
-| BLOCKED, RUNNING  | NA       | The target execution context is blocked or    |
-|                   |          | running on a different CPU. This is not       |
-|                   |          | supported by current SPMC implementation and  |
-|                   |          | execution hits panic.                         |
-+-------------------+----------+-----------------------------------------------+
-
-If normal world execution was preempted by a secure interrupt, SPMC uses
-FFA_NORMAL_WORLD_RESUME ABI to indicate completion of secure interrupt handling
-and further returns execution to normal world.
-
-The following figure describes interrupt handling flow when a secure interrupt
-triggers while execution is in normal world:
-
-.. image:: ../resources/diagrams/ffa-secure-interrupt-handling-nwd.png
-
-A brief description of the events:
-
-  - 1) Secure interrupt triggers while normal world is running.
-  - 2) FIQ gets trapped to EL3.
-  - 3) SPMD signals secure interrupt to SPMC at S-EL2 using FFA_INTERRUPT ABI.
-  - 4) SPMC identifies target vCPU of SP and injects virtual interrupt (pends
-       vIRQ).
-  - 5) Assuming SP1 vCPU is in WAITING state, SPMC signals virtual interrupt
-       using FFA_INTERRUPT with interrupt id as an argument and resumes the SP1
-       vCPU using ERET in SPMC scheduled mode.
-  - 6) Execution traps to vIRQ handler in SP1 provided that the virtual
-       interrupt is not masked i.e., PSTATE.I = 0
-  - 7) SP1 queries for the pending virtual interrupt id using a paravirtualized
-       HVC call. SPMC clears the pending virtual interrupt state management
-       and returns the pending virtual interrupt id.
-  - 8) SP1 services the virtual interrupt and invokes the paravirtualized
-       de-activation HVC call. SPMC de-activates the physical interrupt,
-       clears the fields tracking the secure interrupt and resumes SP1 vCPU.
-  - 9) SP1 performs secure interrupt completion through FFA_MSG_WAIT ABI.
-  - 10) SPMC returns control to EL3 using FFA_NORMAL_WORLD_RESUME.
-  - 11) EL3 resumes normal world execution.
-
-Actions for a secure interrupt triggered while execution is in secure world
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------------------+----------+------------------------------------------------+
-| State of target   | Action   | Description                                    |
-| execution context |          |                                                |
-+-------------------+----------+------------------------------------------------+
-| WAITING           | Signaled | This starts a new call chain in SPMC scheduled |
-|                   |          | mode.                                          |
-+-------------------+----------+------------------------------------------------+
-| PREEMPTED by Self | Signaled | The target execution context reenters the      |
-| S-Int             |          | RUNNING state to handle the secure virtual     |
-|                   |          | interrupt.                                     |
-+-------------------+----------+------------------------------------------------+
-| PREEMPTED by      | Queued   | SPMC queues the secure virtual interrupt now.  |
-| NS-Int            |          | It is signaled when the target execution       |
-|                   |          | context next enters the RUNNING state.         |
-+-------------------+----------+------------------------------------------------+
-| BLOCKED           | Signaled | Both preempted and target execution contexts   |
-|                   |          | must have been part of the Normal world        |
-|                   |          | scheduled call chain. Refer scenario 1 of      |
-|                   |          | Table 8.4 in the FF-A v1.1 EAC0 spec.          |
-+-------------------+----------+------------------------------------------------+
-| RUNNING           | NA       | The target execution context is running on a   |
-|                   |          | different CPU. This scenario is not supported  |
-|                   |          | by current SPMC implementation and execution   |
-|                   |          | hits panic.                                    |
-+-------------------+----------+------------------------------------------------+
-
-The following figure describes interrupt handling flow when a secure interrupt
-triggers while execution is in secure world. We assume OS kernel sends a direct
-request message to SP1. Further, SP1 sends a direct request message to SP2. SP1
-enters BLOCKED state and SPMC resumes SP2.
-
-.. image:: ../resources/diagrams/ffa-secure-interrupt-handling-swd.png
-
-A brief description of the events:
-
-  - 1) Secure interrupt triggers while SP2 is running.
-  - 2) SP2 gets preempted and execution traps to SPMC as IRQ.
-  - 3) SPMC finds the target vCPU of secure partition responsible for handling
-       this secure interrupt. In this scenario, it is SP1.
-  - 4) SPMC pends vIRQ for SP1 and signals through FFA_INTERRUPT interface.
-       SPMC further resumes SP1 through ERET conduit. Note that SP1 remains in
-       Normal world schedule mode.
-  - 6) Execution traps to vIRQ handler in SP1 provided that the virtual
-       interrupt is not masked i.e., PSTATE.I = 0
-  - 7) SP1 queries for the pending virtual interrupt id using a paravirtualized
-       HVC call. SPMC clears the pending virtual interrupt state management
-       and returns the pending virtual interrupt id.
-  - 8) SP1 services the virtual interrupt and invokes the paravirtualized
-       de-activation HVC call. SPMC de-activates the physical interrupt and
-       clears the fields tracking the secure interrupt and resumes SP1 vCPU.
-  - 9) Since SP1 direct request completed with FFA_INTERRUPT, it resumes the
-       direct request to SP2 by invoking FFA_RUN.
-  - 9) SPMC resumes the pre-empted vCPU of SP2.
-
-EL3 interrupt handling
-~~~~~~~~~~~~~~~~~~~~~~
-
-In GICv3 based systems, EL3 interrupts are configured as Group0 secure
-interrupts. Execution traps to SPMC when a Group0 interrupt triggers while an
-SP is running. Further, SPMC running at S-EL2 uses FFA_EL3_INTR_HANDLE ABI to
-request EL3 platform firmware to handle a pending Group0 interrupt.
-Similarly, SPMD registers a handler with interrupt management framework to
-delegate handling of Group0 interrupt to the platform if the interrupt triggers
-in normal world.
-
- - Platform hook
-
-   - plat_spmd_handle_group0_interrupt
-
-     SPMD provides platform hook to handle Group0 secure interrupts. In the
-     current design, SPMD expects the platform not to delegate handling to the
-     NWd (such as through SDEI) while processing Group0 interrupts.
-
-Power management
-----------------
-
-In platforms with or without secure virtualization:
-
-- The NWd owns the platform PM policy.
-- The Hypervisor or OS kernel is the component initiating PSCI service calls.
-- The EL3 PSCI library is in charge of the PM coordination and control
-  (eventually writing to platform registers).
-- While coordinating PM events, the PSCI library calls backs into the Secure
-  Payload Dispatcher for events the latter has statically registered to.
-
-When using the SPMD as a Secure Payload Dispatcher:
-
-- A power management event is relayed through the SPD hook to the SPMC.
-- In the current implementation only cpu on (svc_on_finish) and cpu off
-  (svc_off) hooks are registered.
-- The behavior for the cpu on event is described in `Secondary cores boot-up`_.
-  The SPMC is entered through its secondary physical core entry point.
-- The cpu off event occurs when the NWd calls PSCI_CPU_OFF. The PM event is
-  signaled to the SPMC through a power management framework message.
-  It consists in a SPMD-to-SPMC direct request/response (`SPMC-SPMD direct
-  requests/responses`_) conveying the event details and SPMC response.
-  The SPMD performs a synchronous entry into the SPMC. The SPMC is entered and
-  updates its internal state to reflect the physical core is being turned off.
-  In the current implementation no SP is resumed as a consequence. This behavior
-  ensures a minimal support for CPU hotplug e.g. when initiated by the NWd linux
-  userspace.
-
-Arm architecture extensions for security hardening
-==================================================
-
-Hafnium supports the following architecture extensions for security hardening:
-
-- Pointer authentication (FEAT_PAuth): the extension permits detection of forged
-  pointers used by ROP type of attacks through the signing of the pointer
-  value. Hafnium is built with the compiler branch protection option to permit
-  generation of a pointer authentication code for return addresses (pointer
-  authentication for instructions). The APIA key is used while Hafnium runs.
-  A random key is generated at boot time and restored upon entry into Hafnium
-  at run-time. APIA and other keys (APIB, APDA, APDB, APGA) are saved/restored
-  in vCPU contexts permitting to enable pointer authentication in VMs/SPs.
-- Branch Target Identification (FEAT_BTI): the extension permits detection of
-  unexpected indirect branches used by JOP type of attacks. Hafnium is built
-  with the compiler branch protection option, inserting land pads at function
-  prologues that are reached by indirect branch instructions (BR/BLR).
-  Hafnium code pages are marked as guarded in the EL2 Stage-1 MMU descriptors
-  such that an indirect branch must always target a landpad. A fault is
-  triggered otherwise. VMs/SPs can (independently) mark their code pages as
-  guarded in the EL1&0 Stage-1 translation regime.
-- Memory Tagging Extension (FEAT_MTE): the option permits detection of out of
-  bound memory array accesses or re-use of an already freed memory region.
-  Hafnium enables the compiler option permitting to leverage MTE stack tagging
-  applied to core stacks. Core stacks are marked as normal tagged memory in the
-  EL2 Stage-1 translation regime. A synchronous data abort is generated upon tag
-  check failure on load/stores. A random seed is generated at boot time and
-  restored upon entry into Hafnium. MTE system registers are saved/restored in
-  vCPU contexts permitting MTE usage from VMs/SPs.
-
-SMMUv3 support in Hafnium
-=========================
-
-An SMMU is analogous to an MMU in a CPU. It performs address translations for
-Direct Memory Access (DMA) requests from system I/O devices.
-The responsibilities of an SMMU include:
-
--  Translation: Incoming DMA requests are translated from bus address space to
-   system physical address space using translation tables compliant to
-   Armv8/Armv7 VMSA descriptor format.
--  Protection: An I/O device can be prohibited from read, write access to a
-   memory region or allowed.
--  Isolation: Traffic from each individial device can be independently managed.
-   The devices are differentiated from each other using unique translation
-   tables.
-
-The following diagram illustrates a typical SMMU IP integrated in a SoC with
-several I/O devices along with Interconnect and Memory system.
-
-.. image:: ../resources/diagrams/MMU-600.png
-
-SMMU has several versions including SMMUv1, SMMUv2 and SMMUv3. Hafnium provides
-support for SMMUv3 driver in both normal and secure world. A brief introduction
-of SMMUv3 functionality and the corresponding software support in Hafnium is
-provided here.
-
-SMMUv3 features
----------------
-
--  SMMUv3 provides Stage1, Stage2 translation as well as nested (Stage1 + Stage2)
-   translation support. It can either bypass or abort incoming translations as
-   well.
--  Traffic (memory transactions) from each upstream I/O peripheral device,
-   referred to as Stream, can be independently managed using a combination of
-   several memory based configuration structures. This allows the SMMUv3 to
-   support a large number of streams with each stream assigned to a unique
-   translation context.
--  Support for Armv8.1 VMSA where the SMMU shares the translation tables with
-   a Processing Element. AArch32(LPAE) and AArch64 translation table format
-   are supported by SMMUv3.
--  SMMUv3 offers non-secure stream support with secure stream support being
-   optional. Logically, SMMUv3 behaves as if there is an indepdendent SMMU
-   instance for secure and non-secure stream support.
--  It also supports sub-streams to differentiate traffic from a virtualized
-   peripheral associated with a VM/SP.
--  Additionally, SMMUv3.2 provides support for PEs implementing Armv8.4-A
-   extensions. Consequently, SPM depends on Secure EL2 support in SMMUv3.2
-   for providing Secure Stage2 translation support to upstream peripheral
-   devices.
-
-SMMUv3 Programming Interfaces
------------------------------
-
-SMMUv3 has three software interfaces that are used by the Hafnium driver to
-configure the behaviour of SMMUv3 and manage the streams.
-
--  Memory based data strutures that provide unique translation context for
-   each stream.
--  Memory based circular buffers for command queue and event queue.
--  A large number of SMMU configuration registers that are memory mapped during
-   boot time by Hafnium driver. Except a few registers, all configuration
-   registers have independent secure and non-secure versions to configure the
-   behaviour of SMMUv3 for translation of secure and non-secure streams
-   respectively.
-
-Peripheral device manifest
---------------------------
-
-Currently, SMMUv3 driver in Hafnium only supports dependent peripheral devices.
-These devices are dependent on PE endpoint to initiate and receive memory
-management transactions on their behalf. The acccess to the MMIO regions of
-any such device is assigned to the endpoint during boot. Moreover, SMMUv3 driver
-uses the same stage 2 translations for the device as those used by partition
-manager on behalf of the PE endpoint. This ensures that the peripheral device
-has the same visibility of the physical address space as the endpoint. The
-device node of the corresponding partition manifest (refer to `[1]`_ section 3.2
-) must specify these additional properties for each peripheral device in the
-system :
-
--  smmu-id: This field helps to identify the SMMU instance that this device is
-   upstream of.
--  stream-ids: List of stream IDs assigned to this device.
-
-.. code:: shell
-
-    smmuv3-testengine {
-        base-address = <0x00000000 0x2bfe0000>;
-        pages-count = <32>;
-        attributes = <0x3>;
-        smmu-id = <0>;
-        stream-ids = <0x0 0x1>;
-        interrupts = <0x2 0x3>, <0x4 0x5>;
-        exclusive-access;
-    };
-
-SMMUv3 driver limitations
--------------------------
-
-The primary design goal for the Hafnium SMMU driver is to support secure
-streams.
-
--  Currently, the driver only supports Stage2 translations. No support for
-   Stage1 or nested translations.
--  Supports only AArch64 translation format.
--  No support for features such as PCI Express (PASIDs, ATS, PRI), MSI, RAS,
-   Fault handling, Performance Monitor Extensions, Event Handling, MPAM.
--  No support for independent peripheral devices.
-
-S-EL0 Partition support
-=======================
-The SPMC (Hafnium) has limited capability to run S-EL0 FF-A partitions using
-FEAT_VHE (mandatory with ARMv8.1 in non-secure state, and in secure world
-with ARMv8.4 and FEAT_SEL2).
-
-S-EL0 partitions are useful for simple partitions that don't require full
-Trusted OS functionality. It is also useful to reduce jitter and cycle
-stealing from normal world since they are more lightweight than VMs.
-
-S-EL0 partitions are presented, loaded and initialized the same as S-EL1 VMs by
-the SPMC. They are differentiated primarily by the 'exception-level' property
-and the 'execution-ctx-count' property in the SP manifest. They are host apps
-under the single EL2&0 Stage-1 translation regime controlled by the SPMC and
-call into the SPMC through SVCs as opposed to HVCs and SMCs. These partitions
-can use FF-A defined services (FFA_MEM_PERM_*) to update or change permissions
-for memory regions.
-
-S-EL0 partitions are required by the FF-A specification to be UP endpoints,
-capable of migrating, and the SPMC enforces this requirement. The SPMC allows
-a S-EL0 partition to accept a direct message from secure world and normal world,
-and generate direct responses to them.
-All S-EL0 partitions must use AArch64. AArch32 S-EL0 partitions are not supported.
-
-Memory sharing, indirect messaging, and notifications functionality with S-EL0
-partitions is supported.
-
-Interrupt handling is not supported with S-EL0 partitions and is work in
-progress.
 
 References
 ==========
@@ -1641,8 +242,7 @@ References
 
 .. _[3]:
 
-[3] `Trusted Boot Board Requirements
-Client <https://developer.arm.com/documentation/den0006/d/>`__
+[3] https://hafnium.readthedocs.io/en/latest/secure-partition-manager/secure-partition-manager.html#secure-partitions-layout-file
 
 .. _[4]:
 
@@ -1650,24 +250,16 @@ Client <https://developer.arm.com/documentation/den0006/d/>`__
 
 .. _[5]:
 
-[5] https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/spm/cactus/plat/arm/fvp/fdts/cactus.dts
+[5] https://hafnium.readthedocs.io/en/latest/secure-partition-manager/index.html
 
 .. _[6]:
 
-[6] https://trustedfirmware-a.readthedocs.io/en/latest/components/ffa-manifest-binding.html
+[6] :ref:`EL3 Secure Partition Manager<EL3 Secure Partition Manager>`
 
 .. _[7]:
 
-[7] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
-
-.. _[8]:
-
-[8] https://lists.trustedfirmware.org/archives/list/tf-a@lists.trustedfirmware.org/thread/CFQFGU6H2D5GZYMUYGTGUSXIU3OYZP6U/
-
-.. _[9]:
-
-[9] https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#dynamic-configuration-during-cold-boot
+[7] https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#dynamic-configuration-during-cold-boot
 
 --------------
 
-*Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/ven-el3-debugfs.rst b/docs/components/ven-el3-debugfs.rst
new file mode 100644
index 00000000..8629d701
--- /dev/null
+++ b/docs/components/ven-el3-debugfs.rst
@@ -0,0 +1,343 @@
+DebugFS interface
+=================
+
+The optional DebugFS interface is accessed through a Vendor specific EL3 service. Refer
+to the component documentation for details.
+
+String parameters are passed through a shared buffer using a specific union:
+
+.. code:: c
+
+    union debugfs_parms {
+        struct {
+            char fname[MAX_PATH_LEN];
+        } open;
+
+        struct mount {
+            char srv[MAX_PATH_LEN];
+            char where[MAX_PATH_LEN];
+            char spec[MAX_PATH_LEN];
+        } mount;
+
+        struct {
+            char path[MAX_PATH_LEN];
+            dir_t dir;
+        } stat;
+
+        struct {
+            char oldpath[MAX_PATH_LEN];
+            char newpath[MAX_PATH_LEN];
+        } bind;
+    };
+
+Format of the dir_t structure as such:
+
+.. code:: c
+
+    typedef struct {
+        char		name[NAMELEN];
+        long		length;
+        unsigned char	mode;
+        unsigned char	index;
+        unsigned char	dev;
+        qid_t		qid;
+    } dir_t;
+
+
+* Identifiers
+
+======================== =============================================
+SMC_OK                   0
+SMC_UNK                  -1
+DEBUGFS_E_INVALID_PARAMS -2
+======================== =============================================
+
+======================== =============================================
+MOUNT                    0
+CREATE                   1
+OPEN                     2
+CLOSE                    3
+READ                     4
+WRITE                    5
+SEEK                     6
+BIND                     7
+STAT                     8
+INIT                     10
+VERSION                  11
+======================== =============================================
+
+MOUNT
+~~~~~
+
+Description
+^^^^^^^^^^^
+This operation mounts a blob of data pointed to by path stored in `src`, at
+filesystem location pointed to by path stored in `where`, using driver pointed
+to by path in `spec`.
+
+Parameters
+^^^^^^^^^^
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``MOUNT``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if mount operation failed
+=============== ==========================================================
+
+OPEN
+~~~~
+
+Description
+^^^^^^^^^^^
+This operation opens the file path pointed to by `fname`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``OPEN``
+uint32_t mode
+======== ============================================================
+
+mode can be one of:
+
+.. code:: c
+
+    enum mode {
+        O_READ   = 1 << 0,
+        O_WRITE  = 1 << 1,
+        O_RDWR   = 1 << 2,
+        O_BIND   = 1 << 3,
+        O_DIR    = 1 << 4,
+        O_STAT   = 1 << 5
+    };
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if open operation failed
+
+uint32_t        w1: file descriptor id on success.
+=============== ==========================================================
+
+CLOSE
+~~~~~
+
+Description
+^^^^^^^^^^^
+
+This operation closes a file described by a file descriptor obtained by a
+previous call to OPEN.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``CLOSE``
+uint32_t File descriptor id returned by OPEN
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if close operation failed
+=============== ==========================================================
+
+READ
+~~~~
+
+Description
+^^^^^^^^^^^
+
+This operation reads a number of bytes from a file descriptor obtained by
+a previous call to OPEN.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``READ``
+uint32_t File descriptor id returned by OPEN
+uint32_t Number of bytes to read
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+On success, the read data is retrieved from the shared buffer after the
+operation.
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if read operation failed
+
+uint32_t        w1: number of bytes read on success.
+=============== ==========================================================
+
+SEEK
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Move file pointer for file described by given `file descriptor` of given
+`offset` related to `whence`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``SEEK``
+uint32_t File descriptor id returned by OPEN
+sint32_t offset in the file relative to whence
+uint32_t whence
+======== ============================================================
+
+whence can be one of:
+
+========= ============================================================
+KSEEK_SET 0
+KSEEK_CUR 1
+KSEEK_END 2
+========= ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if seek operation failed
+=============== ==========================================================
+
+BIND
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Create a link from `oldpath` to `newpath`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``BIND``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if bind operation failed
+=============== ==========================================================
+
+STAT
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Perform a stat operation on provided file `name` and returns the directory
+entry statistics into `dir`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``STAT``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if stat operation failed
+=============== ==========================================================
+
+INIT
+~~~~
+
+Description
+^^^^^^^^^^^
+Initial call to setup the shared exchange buffer. Notice if successful once,
+subsequent calls fail after a first initialization. The caller maps the same
+page frame in its virtual space and uses this buffer to exchange string
+parameters with filesystem primitives.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``INIT``
+uint64_t Physical address of the shared buffer.
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ======================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if already initialized,
+                or internal error occurred.
+=============== ======================================================
+
+VERSION
+~~~~~~~
+
+Description
+^^^^^^^^^^^
+Returns the debugfs interface version if implemented in TF-A.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x87000010 / 0xC7000010)
+uint32_t ``VERSION``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ======================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == SMC_UNK if interface is not implemented
+
+uint32_t        w1: On success, debugfs interface version, 32 bits
+                value with major version number in upper 16 bits and
+                minor version in lower 16 bits.
+=============== ======================================================
+
+* CREATE(1) and WRITE (5) command identifiers are unimplemented and
+  return `SMC_UNK`.
+
+--------------
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/ven-el3-service.rst b/docs/components/ven-el3-service.rst
new file mode 100644
index 00000000..13449ba6
--- /dev/null
+++ b/docs/components/ven-el3-service.rst
@@ -0,0 +1,78 @@
+Vendor Specific EL3 Monitor Service Calls
+=========================================
+
+This document enumerates and describes the Vendor Specific EL3 Monitor Service
+Calls.
+
+These are Service Calls defined by the vendor of the EL3 Monitor.
+They are accessed via ``SMC`` ("SMC calls") instruction executed from Exception
+Levels below EL3. SMC calls for Vendor Specific EL3 Monitor Services:
+
+-  Follow `SMC Calling Convention`_;
+-  Use SMC function IDs that fall in the vendor-specific EL3 range, which are
+
++---------------------------+--------------------------------------------------+
+| SMC Function Identifier   | Service Type                                     |
++===========================+==================================================+
+| 0x87000000 - 0x8700FFFF   | SMC32: Vendor Specific EL3 Monitor Service Calls |
++---------------------------+--------------------------------------------------+
+| 0xC7000000 - 0xC700FFFF   | SMC64: Vendor Specific EL3 Monitor Service Calls |
++---------------------------+--------------------------------------------------+
+
+Vendor-specific EL3 monitor services are as follows:
+
++-----------------------------------+-----------------------+---------------------------------------------+
+| SMC Function Identifier           | Service Type          | FID's Usage                                 |
++===================================+=======================+=============================================+
+| 0x87000010 - 0x8700001F (SMC32)   | DebugFS Interface     | | 0 - 11 are in use.                        |
++-----------------------------------+                       | | 12 - 15 are reserved for future expansion.|
+| 0xC7000010 - 0xC700001F (SMC64)   |                       |                                             |
++-----------------------------------+-----------------------+---------------------------------------------+
+| 0x87000020 - 0x8700002F (SMC32)   | Performance           | | 0,1 is in use.                            |
++-----------------------------------+ Measurement Framework | | 2 - 15 are reserved for future expansion. |
+| 0xC7000020 - 0xC700002F (SMC64)   | (PMF)                 |                                             |
++-----------------------------------+-----------------------+---------------------------------------------+
+| 0x87000030 - 0x8700FFFF (SMC32)   | Reserved              | | reserved for future expansion             |
++-----------------------------------+                       |                                             |
+| 0xC7000030 - 0xC700FFFF (SMC64)   |                       |                                             |
++-----------------------------------+-----------------------+---------------------------------------------+
+
+Source definitions for vendor-specific EL3 Monitor Service Calls used by TF-A are located in
+the ``ven_el3_svc.h`` header file.
+
++----------------------------+----------------------------+--------------------------------+
+| VEN_EL3_SVC_VERSION_MAJOR  | VEN_EL3_SVC_VERSION_MINOR  | Changes                        |
++============================+============================+================================+
+|                          1 |                          0 | Added Debugfs and PMF services.|
++----------------------------+----------------------------+--------------------------------+
+
+*Table 1: Showing different versions of Vendor-specific service and changes done with each version*
+
+Each sub service will have its own version, one FID allocated for sub service version.
+
+Some ground rules when one should update top level version.
+ - VEN_EL3_SVC_VERSION_MAJOR is incremented when any of the sub service version discovery
+   FID changes or the FID that was allocated for discovery changes. So any breaking subfeature
+   discovery changes will lead to major version update.
+ - VEN_EL3_SVC_VERSION_MINOR is incremented when we add a new FID or a new sub service.
+   For example adding an new monitor service at 0x30, Debugfs starts at 0x10 and PMF
+   starts at 0x20 next one will start at 0x30, this will need a update to minor version.
+
+Performance Measurement Framework (PMF)
+---------------------------------------
+
+The :ref:`Performance Measurement Framework <firmware_design_pmf>`
+allows callers to retrieve timestamps captured at various paths in TF-A
+execution.
+
+DebugFS interface
+-----------------
+
+The optional DebugFS interface is accessed through Vendor specific EL3 service. Refer
+to :ref:`DebugFS interface` documentation for further details and usage.
+
+--------------
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
+
+.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
diff --git a/docs/conf.py b/docs/conf.py
index d4e54239..3a7264fd 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -14,8 +14,8 @@
 
 project = "Trusted Firmware-A"
 author = "Trusted Firmware-A contributors"
-version = "2.10.0"
-release = "2.10.0"
+version = "2.12.0"
+release = "2.12.0"
 
 # -- General configuration ---------------------------------------------------
 
diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst
index 597f955e..6dc2245c 100644
--- a/docs/design/auth-framework.rst
+++ b/docs/design/auth-framework.rst
@@ -254,8 +254,8 @@ These functions are registered in the CM using the macro:
     REGISTER_CRYPTO_LIB(_name,
                         _init,
                         _verify_signature,
-                        _calc_hash,
                         _verify_hash,
+                        _calc_hash,
                         _auth_decrypt,
                         _convert_pk);
 
@@ -505,11 +505,12 @@ uses this information to:
 
     typedef enum {
         AUTH_PARAM_NONE,
-        AUTH_PARAM_RAW_DATA,        /* Raw image data */
+        AUTH_PARAM_RAW_DATA,    /* Raw image data */
         AUTH_PARAM_SIG,         /* The image signature */
         AUTH_PARAM_SIG_ALG,     /* The image signature algorithm */
         AUTH_PARAM_HASH,        /* A hash (including the algorithm) */
         AUTH_PARAM_PUB_KEY,     /* A public key */
+        AUTH_PARAM_NV_CTR,      /* A non-volatile counter */
     } auth_param_type_t;
 
 The AM defines the following structure to identify an authentication parameter
@@ -1018,4 +1019,4 @@ The mbedTLS library algorithm support is configured by both the
 
 *Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.*
 
-.. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index d03daf89..fda43dc9 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -384,11 +384,19 @@ For Cortex-A78C, the following errata build flags are defined :
   Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
   erratum is still open.
 
+- ``ERRATA_A78C_2683027`` : This applies errata 2683027 workaround to
+  Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
+  erratum is still open.
+
 - ``ERRATA_A78C_2712575`` : This applies erratum 2712575 workaround to
   Cortex-A78C CPU, this erratum affects system configurations that do not use
   an ARM interconnect IP. This needs to be enabled for revisions r0p1 and r0p2
   and is still open.
 
+- ``ERRATA_A78C_2743232`` : This applies erratum 2743232 workaround to
+  Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2.
+  This erratum is still open.
+
 - ``ERRATA_A78C_2772121`` : This applies errata 2772121 workaround to
   Cortex-A78C CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2.
   This erratum is still open.
@@ -501,6 +509,10 @@ For Neoverse V1, the following errata build flags are defined :
    CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 and r1p2 of
    the CPU.
 
+-  ``ERRATA_V1_2348377``: This applies errata 2348377 workaroud to Neoverse-V1
+   CPU. This needs to be enabled for revisions r0p0, r1p0 and r1p1 of the CPU.
+   It has been fixed in r1p2.
+
 -  ``ERRATA_V1_2372203``: This applies errata 2372203 workaround to Neoverse-V1
    CPU. This needs to be enabled for revisions r0p0, r1p0 and r1p1 of the CPU.
    It is still open.
@@ -528,6 +540,14 @@ For Neoverse V2, the following errata build flags are defined :
    CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is still
    open.
 
+-  ``ERRATA_V2_2618597``: This applies errata 2618597 workaround to Neoverse-V2
+   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in
+   r0p2.
+
+-  ``ERRATA_V2_2662553``: This applies errata 2662553 workaround to Neoverse-V2
+   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in
+   r0p2.
+
 -  ``ERRATA_V2_2719103``: This applies errata 2719103 workaround to Neoverse-V2
    CPU, this affects system configurations that do not use and ARM interconnect
    IP. This needs to be enabled for revisions r0p0 and r0p1. It has been fixed
@@ -620,6 +640,10 @@ For Cortex-A710, the following errata build flags are defined :
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
    r2p1 of the CPU and is still open.
 
+-  ``ERRATA_A710_2778471``: This applies errata 2778471 workaround to Cortex-A710
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
+   CPU and is still open.
+
 For Neoverse N2, the following errata build flags are defined :
 
 -  ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2
@@ -741,24 +765,87 @@ For Cortex-X2, the following errata build flags are defined :
    CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
    CPU and is still open.
 
+-  ``ERRATA_X2_2778471``: This applies errata 2778471 workaround to Cortex-X2
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
+   CPU and it is still open.
+
 For Cortex-X3, the following errata build flags are defined :
 
 - ``ERRATA_X3_2070301``: This applies errata 2070301 workaround to the Cortex-X3
   CPU. This needs to be enabled only for revisions r0p0, r1p0, r1p1 and r1p2 of
   the CPU and is still open.
 
+- ``ERRATA_X3_2266875``: This applies errata 2266875 workaround to the Cortex-X3
+  CPU. This needs to be enabled only for revisions r0p0 and r1p0 of the CPU, it
+  is fixed in r1p1.
+
+- ``ERRATA_X3_2302506``: This applies errata 2302506 workaround to the Cortex-X3
+  CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1, it is
+  fixed in r1p2.
+
 - ``ERRATA_X3_2313909``: This applies errata 2313909 workaround to
   Cortex-X3 CPU. This needs to be enabled only for revisions r0p0 and r1p0
   of the CPU, it is fixed in r1p1.
 
+- ``ERRATA_X3_2372204``: This applies errata 2372204 workaround to
+  Cortex-X3 CPU. This needs to be enabled only for revisions r0p0 and r1p0
+  of the CPU, it is fixed in r1p1.
+
 - ``ERRATA_X3_2615812``: This applies errata 2615812 workaround to Cortex-X3
   CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1 of the
-  CPU, it is still open.
+  CPU, it is fixed in r1p2.
+
+- ``ERRATA_X3_2641945``: This applies errata 2641945 workaround to Cortex-X3
+  CPU. This needs to be enabled only for revisions r0p0 and r1p0 of the CPU.
+  It is fixed in r1p1.
+
+- ``ERRATA_X3_2701951``: This applies erratum 2701951 workaround to Cortex-X3
+  CPU and affects system configurations that do not use an ARM interconnect
+  IP. This needs to be applied to revisions r0p0, r1p0 and r1p1. It is fixed
+  in r1p2.
 
 - ``ERRATA_X3_2742421``: This applies errata 2742421 workaround to
   Cortex-X3 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
   r1p1. It is fixed in r1p2.
 
+- ``ERRATA_X3_2743088``: This applies errata 2743088 workaround to Cortex-X3
+  CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1. It is
+  fixed in r1p2.
+
+- ``ERRATA_X3_2779509``: This applies errata 2779509 workaround to Cortex-X3
+  CPU. This needs to be enabled only for revisions r0p0, r1p0 and r1p1 of the
+  CPU. It is fixed in r1p2.
+
+For Cortex-X4, the following errata build flags are defined :
+
+- ``ERRATA_X4_2701112``: This applies erratum 2701112 workaround to Cortex-X4
+  CPU and affects system configurations that do not use an Arm interconnect IP.
+  This needs to be enabled for revisions r0p0 and is fixed in r0p1.
+  The workaround for this erratum is not implemented in EL3, but the flag can
+  be enabled/disabled at the platform level. The flag is used when the errata ABI
+  feature is enabled and can assist the Kernel in the process of
+  mitigation of the erratum.
+
+- ``ERRATA_X4_2726228``: This applies erratum 2726228 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in
+  r0p2.
+
+-  ``ERRATA_X4_2740089``: This applies errata 2740089 workaround to Cortex-X4
+   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed
+   in r0p2.
+
+- ``ERRATA_X4_2763018``: This applies errata 2763018 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
+- ``ERRATA_X4_2816013``: This applies errata 2816013 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
+- ``ERRATA_X4_2897503``: This applies errata 2897503 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
+- ``ERRATA_X4_3076789``: This applies errata 3076789 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
 For Cortex-A510, the following errata build flags are defined :
 
 -  ``ERRATA_A510_1922240``: This applies errata 1922240 workaround to
@@ -812,12 +899,68 @@ For Cortex-A510, the following errata build flags are defined :
    Cortex-A510 CPU. This needs to be applied to revision r0p0, r0p1, r0p2,
    r0p3, r1p0, r1p1 and r1p2. It is fixed in r1p3.
 
+For Cortex-A520, the following errata build flags are defined :
+
+-  ``ERRATA_A520_2630792``: This applies errata 2630792 workaround to
+   Cortex-A520 CPU. This needs to applied for revisions r0p0, r0p1 of the
+   CPU and is still open.
+
+-  ``ERRATA_A520_2858100``: This applies errata 2858100 workaround to
+   Cortex-A520 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is still open.
+
+-  ``ERRATA_A520_2938996``: This applies errata 2938996 workaround to
+   Cortex-A520 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
+
 For Cortex-A715, the following errata build flags are defined :
 
--  ``ERRATA_A715_2701951``: This applies erratum 2701951 workaround to Cortex-A715
-   CPU and affects system configurations that do not use an ARM interconnect
-   IP. This needs to be applied to revisions r0p0, r1p0 and r1p1. It is fixed
-   in r1p2.
+-  ``ERRATA_A715_2331818``: This applies errata 2331818 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0 and r1p0.
+   It is fixed in r1p1.
+
+- ``ERRATA_A715_2344187``: This applies errata 2344187 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0 and r1p0. It is
+   fixed in r1p1.
+
+-  ``ERRATA_A715_2413290``: This applies errata 2413290 workaround to
+   Cortex-A715 CPU. This needs to be enabled only for revision r1p0 and
+   when SPE(Statistical profiling extension)=True. The errata is fixed
+   in r1p1.
+
+-  ``ERRATA_A715_2420947``: This applies errata 2420947 workaround to
+   Cortex-A715 CPU. This needs to be enabled only for revision r1p0.
+   It is fixed in r1p1.
+
+-  ``ERRATA_A715_2429384``: This applies errata 2429384 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revision r1p0. There is no
+   workaround for revision r0p0. It is fixed in r1p1.
+
+-  ``ERRATA_A715_2561034``: This applies errata 2561034 workaround to
+   Cortex-A715 CPU. This needs to be enabled only for revision r1p0.
+   It is fixed in r1p1.
+
+-  ``ERRATA_A715_2728106``: This applies errata 2728106 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0
+   and r1p1. It is fixed in r1p2.
+
+For Cortex-A720, the following errata build flags are defined :
+
+-  ``ERRATA_A720_2792132``: This applies errata 2792132 workaround to
+   Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
+
+-  ``ERRATA_A720_2844092``: This applies errata 2844092 workaround to
+   Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
+
+-  ``ERRATA_A720_2926083``: This applies errata 2926083 workaround to
+   Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
+
+-  ``ERRATA_A720_2940794``: This applies errata 2940794 workaround to
+   Cortex-A720 CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   It is fixed in r0p2.
 
 DSU Errata Workarounds
 ----------------------
@@ -904,7 +1047,7 @@ GIC Errata Workarounds
 
 --------------
 
-*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
 .. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 3fce3939..2ba54ea8 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -645,6 +645,35 @@ on entry, these should be enabled during ``bl31_plat_arch_setup()``.
 Data structures used in the BL31 cold boot interface
 ''''''''''''''''''''''''''''''''''''''''''''''''''''
 
+In the cold boot flow, ``entry_point_info`` is used to represent the execution
+state of an image; that is, the state of general purpose registers, PC, and
+SPSR.
+
+There are two variants of this structure, for AArch64:
+
+.. code:: c
+
+   typedef struct entry_point_info {
+        param_header_t h;
+        uintptr_t pc;
+        uint32_t spsr;
+
+        aapcs64_params_t args;
+   }
+
+and, AArch32:
+
+.. code:: c
+
+   typedef struct entry_point_info {
+      param_header_t h;
+      uintptr_t pc;
+      uint32_t spsr;
+
+      uintptr_t lr_svc;
+      aapcs32_params_t args;
+   } entry_point_info_t;
+
 These structures are designed to support compatibility and independent
 evolution of the structures and the firmware images. For example, a version of
 BL31 that can interpret the BL3x image information from different versions of
@@ -662,13 +691,17 @@ BL31 to detect which information is present and respond appropriately. The
         uint8_t type;       /* type of the structure */
         uint8_t version;    /* version of this structure */
         uint16_t size;      /* size of this structure in bytes */
-        uint32_t attr;      /* attributes: unused bits SBZ */
+        uint32_t attr;      /* attributes */
     } param_header_t;
 
-The structures using this format are ``entry_point_info``, ``image_info`` and
-``bl31_params``. The code that allocates and populates these structures must set
-the header fields appropriately, and the ``SET_PARAM_HEAD()`` a macro is defined
-to simplify this action.
+In `entry_point_info`, Bits 0 and 5 of ``attr`` field are used to encode the
+security state; in other words, whether the image is to be executed in Secure,
+Non-Secure, or Realm mode.
+
+Other structures using this format are ``image_info`` and ``bl31_params``. The
+code that allocates and populates these structures must set the header fields
+appropriately, the ``SET_PARAM_HEAD()`` macro is defined to simplify this
+action.
 
 Required CPU state for BL31 Warm boot initialization
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -2767,13 +2800,11 @@ Armv8.5-A
 -  Branch Target Identification feature is selected by ``BRANCH_PROTECTION``
    option set to 1. This option defaults to 0.
 
--  Memory Tagging Extension feature is unconditionally enabled for both worlds
-   (at EL0 and S-EL0) if it is only supported at EL0. If instead it is
-   implemented at all ELs, it is unconditionally enabled for only the normal
-   world. To enable it for the secure world as well, the build option
-   ``CTX_INCLUDE_MTE_REGS`` is required. If the hardware does not implement
-   MTE support at all, it is always disabled, no matter what build options
-   are used.
+-  Memory Tagging Extension feature has few variants but not all of them require
+   enablement from EL3 to be used at lower EL. e.g. Memory tagging only at
+   EL0(MTE) does not require EL3 configuration however memory tagging at
+   EL2/EL1 (MTE2) does require EL3 enablement and we need to set this option
+   ``ENABLE_FEAT_MTE2`` to 1. This option defaults to 0.
 
 Armv7-A
 ~~~~~~~
@@ -2860,13 +2891,13 @@ kernel at boot time. These can be found in the ``fdts`` directory.
 
 --------------
 
-*Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _SMCCC: https://developer.arm.com/docs/den0028/latest
 .. _PSCI: https://developer.arm.com/documentation/den0022/latest/
 .. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest
 .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
-.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest
 .. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture
 .. _AArch64 exception vector table: https://developer.arm.com/documentation/100933/0100/AArch64-exception-vector-table
 
diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst
index fed202ad..f10d2e72 100644
--- a/docs/design/trusted-board-boot.rst
+++ b/docs/design/trusted-board-boot.rst
@@ -1,24 +1,45 @@
 Trusted Board Boot
 ==================
 
-The Trusted Board Boot (TBB) feature prevents malicious firmware from running on
-the platform by authenticating all firmware images up to and including the
-normal world bootloader. It does this by establishing a Chain of Trust using
+The `Trusted Board Boot` (TBB) feature prevents malicious firmware from running
+on the platform by authenticating all firmware images up to and including the
+normal world bootloader. It does this by establishing a `Chain of Trust` using
 Public-Key-Cryptography Standards (PKCS).
 
 This document describes the design of Trusted Firmware-A (TF-A) TBB, which is an
 implementation of the `Trusted Board Boot Requirements (TBBR)`_ specification,
-Arm DEN0006D. It should be used in conjunction with the
-:ref:`Firmware Update (FWU)` design document, which implements a specific aspect
-of the TBBR.
+Arm DEN0006D. It should be used in conjunction with the :ref:`Firmware Update
+(FWU)` design document, which implements a specific aspect of the TBBR.
 
 Chain of Trust
 --------------
 
-A Chain of Trust (CoT) starts with a set of implicitly trusted components. On
-the Arm development platforms, these components are:
+A Chain of Trust (CoT) starts with a set of implicitly trusted components, which
+are used to establish trust in the next layer of components, and so on, in a
+`chained` manner.
 
--  A SHA-256 hash of the Root of Trust Public Key (ROTPK). It is stored in the
+The chain of trust depends on several factors, including:
+
+-  The set of firmware images in use on this platform.
+   Typically, most platforms share a common set of firmware images (BL1, BL2,
+   BL31, BL33) but extra platform-specific images might be required.
+
+-  The key provisioning scheme: which keys need to programmed into the device
+   and at which stage during the platform's manufacturing lifecycle.
+
+-  The key ownership model: who owns which key.
+
+As these vary across platforms, chains of trust also vary across
+platforms. Although each platform is free to define its own CoT based on its
+needs, TF-A provides a set of "default" CoTs fitting some typical trust models,
+which platforms may reuse. The rest of this section presents general concepts
+which apply to all these default CoTs.
+
+The implicitly trusted components forming the trust anchor are:
+
+-  A Root of Trust Public Key (ROTPK), or a hash of it.
+
+   On Arm development platforms, a SHA-256 hash of the ROTPK is stored in the
    trusted root-key storage registers. Alternatively, a development ROTPK might
    be used and its hash embedded into the BL1 and BL2 images (only for
    development purposes).
@@ -31,11 +52,11 @@ images. The certificates follow the `X.509 v3`_ standard. This standard
 enables adding custom extensions to the certificates, which are used to store
 essential information to establish the CoT.
 
-In the TBB CoT all certificates are self-signed. There is no need for a
-Certificate Authority (CA) because the CoT is not established by verifying the
-validity of a certificate's issuer but by the content of the certificate
-extensions. To sign the certificates, different signature schemes are available,
-please refer to the :ref:`Build Options` for more details.
+All certificates are self-signed. There is no need for a Certificate Authority
+(CA) because the CoT is not established by verifying the validity of a
+certificate's issuer but by the content of the certificate extensions. To sign
+the certificates, different signature schemes are available, please refer to the
+:ref:`Build Options` for more details.
 
 The certificates are categorised as "Key" and "Content" certificates. Key
 certificates are used to verify public keys which have been used to sign content
@@ -43,27 +64,40 @@ certificates. Content certificates are used to store the hash of a boot loader
 image. An image can be authenticated by calculating its hash and matching it
 with the hash extracted from the content certificate. Various hash algorithms
 are supported to calculate all hashes, please refer to the :ref:`Build Options`
-for more details.. The public keys and hashes are included as non-standard
+for more details. The public keys and hashes are included as non-standard
 extension fields in the `X.509 v3`_ certificates.
 
-The keys used to establish the CoT are:
+The next sections now present specificities of each default CoT provided in
+TF-A.
+
+Default CoT #1: TBBR
+~~~~~~~~~~~~~~~~~~~~
+
+The `TBBR` CoT is named after the specification it follows to the letter.
+
+In the TBBR CoT, all firmware binaries and certificates are (directly or
+indirectly) linked to the Root of Trust Public Key (ROTPK). Typically, the same
+vendor owns the ROTPK, the Trusted key and the Non-Trusted Key. Thus, this vendor
+is involved in signing every BL3x Key Certificate.
+
+The keys used to establish this CoT are:
 
 -  **Root of trust key**
 
-   The private part of this key is used to sign the BL2 content certificate and
-   the trusted key certificate. The public part is the ROTPK.
+   The private part of this key is used to sign the trusted boot firmware
+   certificate and the trusted key certificate. The public part is the ROTPK.
 
 -  **Trusted world key**
 
    The private part is used to sign the key certificates corresponding to the
    secure world images (SCP_BL2, BL31 and BL32). The public part is stored in
-   one of the extension fields in the trusted world certificate.
+   one of the extension fields in the trusted key certificate.
 
 -  **Non-trusted world key**
 
    The private part is used to sign the key certificate corresponding to the
-   non secure world image (BL33). The public part is stored in one of the
-   extension fields in the trusted world certificate.
+   non-secure world image (BL33). The public part is stored in one of the
+   extension fields in the trusted key certificate.
 
 -  **BL3X keys**
 
@@ -82,10 +116,11 @@ The following images are included in the CoT:
 
 The following certificates are used to authenticate the images.
 
--  **BL2 content certificate**
+-  **Trusted boot firmware certificate**
 
-   It is self-signed with the private part of the ROT key. It contains a hash
-   of the BL2 image.
+   It is self-signed with the private part of the ROT key. It contains a hash of
+   the BL2 image and hashes of various firmware configuration files
+   (TB_FW_CONFIG, HW_CONFIG, FW_CONFIG).
 
 -  **Trusted key certificate**
 
@@ -93,45 +128,82 @@ The following certificates are used to authenticate the images.
    public part of the trusted world key and the public part of the non-trusted
    world key.
 
--  **SCP_BL2 key certificate**
+-  **SCP firmware key certificate**
 
    It is self-signed with the trusted world key. It contains the public part of
    the SCP_BL2 key.
 
--  **SCP_BL2 content certificate**
+-  **SCP firmware content certificate**
 
    It is self-signed with the SCP_BL2 key. It contains a hash of the SCP_BL2
    image.
 
--  **BL31 key certificate**
+-  **SoC firmware key certificate**
 
    It is self-signed with the trusted world key. It contains the public part of
    the BL31 key.
 
--  **BL31 content certificate**
+-  **SoC firmware content certificate**
 
-   It is self-signed with the BL31 key. It contains a hash of the BL31 image.
+   It is self-signed with the BL31 key. It contains hashes of the BL31 image and
+   its configuration file (SOC_FW_CONFIG).
 
--  **BL32 key certificate**
+-  **Trusted OS key certificate**
 
    It is self-signed with the trusted world key. It contains the public part of
    the BL32 key.
 
--  **BL32 content certificate**
+-  **Trusted OS content certificate**
 
-   It is self-signed with the BL32 key. It contains a hash of the BL32 image.
+   It is self-signed with the BL32 key. It contains hashes of the BL32 image(s)
+   and its configuration file(s) (TOS_FW_CONFIG).
 
--  **BL33 key certificate**
+-  **Non-trusted firmware key certificate**
 
    It is self-signed with the non-trusted world key. It contains the public
    part of the BL33 key.
 
--  **BL33 content certificate**
+-  **Non-trusted firmware content certificate**
+
+   It is self-signed with the BL33 key. It contains hashes of the BL33 image and
+   its configuration file (NT_FW_CONFIG).
+
+The SCP firmware and Trusted OS certificates are optional, but they must be
+present if the corresponding SCP_BL2 or BL32 images are present.
+
+The following diagram summarizes the part of the TBBR CoT enforced by BL2. Some
+images (SCP, debug certificates, secure partitions, configuration files) are not
+shown here for conciseness:
+
+.. image:: ../resources/diagrams/cot-tbbr.jpg
+
+Default CoT #2: Dualroot
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The `dualroot` CoT is targeted at systems where the Normal World firmware is
+owned by a different entity than the Secure World Firmware, and those 2 entities
+do not wish to share any keys or have any dependency between each other when it
+comes to signing their respective images. It establishes 2 separate signing
+domains, each with its own Root of Trust key. In that sense, this CoT has 2
+roots of trust, hence the `dualroot` name.
+
+Although the dualroot CoT reuses some of the TBBR CoT components and concepts,
+it differs on the BL33 image's chain of trust, which is rooted into a new key,
+called `Platform ROTPK`, or `PROTPK` for short.
+
+The following diagram summarizes the part of the dualroot CoT enforced by
+BL2. Some images (SCP, debug certificates, secure partitions, configuration
+files) are not shown here for conciseness:
+
+.. image:: ../resources/diagrams/cot-dualroot.jpg
 
-   It is self-signed with the BL33 key. It contains a hash of the BL33 image.
+Default CoT #3: CCA
+~~~~~~~~~~~~~~~~~~~
 
-The SCP_BL2 and BL32 certificates are optional, but they must be present if the
-corresponding SCP_BL2 or BL32 images are present.
+This CoT is targeted at Arm CCA systems. The Arm CCA security model recommends
+making supply chains for the Arm CCA firmware, the secure world firmware and the
+platform owner firmware, independent. Hence, this CoT has 3 roots of trust, one
+for each supply chain.
 
 Trusted Board Boot Sequence
 ---------------------------
@@ -261,4 +333,4 @@ Instructions for building and using the tool can be found in the
 *Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.*
 
 .. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt
-.. _Trusted Board Boot Requirements (TBBR): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _Trusted Board Boot Requirements (TBBR): https://developer.arm.com/docs/den0006/latest
diff --git a/docs/design_documents/cmake_framework.rst b/docs/design_documents/cmake_framework.rst
index d88942e8..f946b2e0 100644
--- a/docs/design_documents/cmake_framework.rst
+++ b/docs/design_documents/cmake_framework.rst
@@ -11,11 +11,7 @@ TF-A CMake buildsystem
 Abstract
 --------
 This document presents a proposal for a new buildsystem for TF-A using CMake,
-and as part of this a reusable CMake framework for embedded projects. For a
-summary about the proposal, please see the `Phabricator wiki page
-<https://developer.trustedfirmware.org/w/tf_a/cmake-buildsystem-proposal/>`_. As
-mentioned there, the proposal consists of two phases. The subject of this
-document is the first phase only.
+and as part of this a reusable CMake framework for embedded projects.
 
 Introduction
 ------------
@@ -162,4 +158,4 @@ the settings group, we can use it for conditionally adding source files. E.g.
 
 --------------
 
-*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design_documents/context_mgmt_rework.rst b/docs/design_documents/context_mgmt_rework.rst
index 59f9d4ea..b086e3c8 100644
--- a/docs/design_documents/context_mgmt_rework.rst
+++ b/docs/design_documents/context_mgmt_rework.rst
@@ -4,7 +4,7 @@ Enhance Context Management library for EL3 firmware
 :Authors: Soby Mathew & Zelalem Aweke
 :Organization: Arm Limited
 :Contact: Soby Mathew <soby.mathew@arm.com> & Zelalem Aweke <zelalem.aweke@arm.com>
-:Status: RFC
+:Status: Implementation is ongoing. Refer to :ref:`Context Management Library` for more details.
 
 .. contents:: Table of Contents
 
@@ -194,4 +194,4 @@ improvements which are thought to have negligible impact on EL3 performance.
 
 --------------
 
-*Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst
index ecc68b23..ac982e09 100644
--- a/docs/design_documents/index.rst
+++ b/docs/design_documents/index.rst
@@ -9,7 +9,7 @@ Design Documents
    context_mgmt_rework
    measured_boot_poc
    drtm_poc
-   rss
+   rse
    psci_osi_mode
    measured_boot
 
diff --git a/docs/design_documents/measured_boot.rst b/docs/design_documents/measured_boot.rst
index c4e52135..005903ed 100644
--- a/docs/design_documents/measured_boot.rst
+++ b/docs/design_documents/measured_boot.rst
@@ -91,10 +91,10 @@ The Measured Boot implementation in TF-A supports:
    and the variable length crypto agile structure called TCG_PCR_EVENT2. Event
    Log driver implemented in TF-A covers later part.
 
-#. RSS
+#. |RSE|
 
-   It is one of physical backend to extend the measurements. Please refer this
-   document :ref:`Runtime Security Subsystem (RSS)` for more details.
+   It is one of the physical backends to extend the measurements. Please refer
+   this document :ref:`Runtime Security Engine (RSE)` for more details.
 
 Platform Interface
 ------------------
@@ -121,7 +121,7 @@ Responsibilities of these platform interfaces are -
       void bl2_plat_mboot_init(void);
 
    Initialise all Measured Boot backends supported by the platform
-   (e.g. Event Log buffer, RSS). As these functions do not return any value,
+   (e.g. Event Log buffer, |RSE|). As these functions do not return any value,
    the platform should deal with error management, such as logging the error
    somewhere, or panicking the system if this is considered a fatal error.
 
@@ -147,8 +147,9 @@ Responsibilities of these platform interfaces are -
 
      - If it is Event Log backend, then record the measurement in TCG Event Log
        format.
-     - If it is a secure crypto-processor (like RSS), then extend the designated
-       PCR (or slot) with the given measurement.
+     - If it is a secure crypto-processor (like |RSE|), then extend the
+       designated PCR (or store it in secure on-chip memory) with the given
+       measurement.
    - This function must return 0 on success, a signed integer error code
      otherwise.
    - On the Arm FVP port, this function measures the given image and then
@@ -222,8 +223,8 @@ Responsibilities of these platform interfaces are -
    - Public key data size is passed as the third argument to this function.
    - This function must return 0 on success, a signed integer error code
      otherwise.
-   - In FVP platform, this function is used to calculate the hash of the given
-     key and forward this hash to RSS alongside the measurement of the image
+   - In TC2 platform, this function is used to calculate the hash of the given
+     key and forward this hash to |RSE| alongside the measurement of the image
      which the key signs.
 
 --------------
diff --git a/docs/design_documents/rss.rst b/docs/design_documents/rse.rst
similarity index 52%
rename from docs/design_documents/rss.rst
rename to docs/design_documents/rse.rst
index 18d54368..dd110ca8 100644
--- a/docs/design_documents/rss.rst
+++ b/docs/design_documents/rse.rst
@@ -1,45 +1,45 @@
-Runtime Security Subsystem (RSS)
-================================
+Runtime Security Engine (RSE)
+=============================
 
-This document focuses on the relationship between the Runtime Security Subsystem
-(RSS) and the application processor (AP). According to the ARM reference design
-the RSS is an independent core next to the AP and the SCP on the same die. It
+This document focuses on the relationship between the Runtime Security Engine
+(RSE) and the application processor (AP). According to the ARM reference design
+the RSE is an independent core next to the AP and the SCP on the same die. It
 provides fundamental security guarantees and runtime services for the rest of
 the system (e.g.: trusted boot, measured boot, platform attestation,
 key management, and key derivation).
 
-At power up RSS boots first from its private ROM code. It validates and loads
+At power up RSE boots first from its private ROM code. It validates and loads
 its own images and the initial images of SCP and AP. When AP and SCP are
 released from reset and their initial code is loaded then they continue their
-own boot process, which is the same as on non-RSS systems. Please refer to the
-``RSS documentation`` [1]_ for more details about the RSS boot flow.
+own boot process, which is the same as on non-RSE systems. Please refer to the
+``RSE documentation`` [1]_ for more details about the RSE boot flow.
 
-The last stage of the RSS firmware is a persistent, runtime component. Much
+The last stage of the RSE firmware is a persistent, runtime component. Much
 like AP_BL31, this is a passive entity which has no periodical task to do and
-just waits for external requests from other subsystems. RSS and other
-subsystems can communicate with each other over message exchange. RSS waits
+just waits for external requests from other subsystems. RSE and other
+subsystems can communicate with each other over message exchange. RSE waits
 in idle for the incoming request, handles them, and sends a response then goes
 back to idle.
 
-RSS communication layer
+RSE communication layer
 -----------------------
 
-The communication between RSS and other subsystems are primarily relying on the
-Message Handling Unit (MHU) module. The number of MHU interfaces between RSS
+The communication between RSE and other subsystems are primarily relying on the
+Message Handling Unit (MHU) module. The number of MHU interfaces between RSE
 and other cores is IMPDEF. Besides MHU other modules also could take part in
-the communication. RSS is capable of mapping the AP memory to its address space.
-Thereby either RSS core itself or a DMA engine if it is present, can move the
-data between memory belonging to RSS or AP. In this way, a bigger amount of data
+the communication. RSE is capable of mapping the AP memory to its address space.
+Thereby either RSE core itself or a DMA engine if it is present, can move the
+data between memory belonging to RSE or AP. In this way, a bigger amount of data
 can be transferred in a short time.
 
 The MHU comes in pairs. There is a sender and receiver side. They are connected
 to each other. An MHU interface consists of two pairs of MHUs, one sender and
 one receiver on both sides. Bidirectional communication is possible over an
-interface. One pair provides message sending from AP to RSS and the other pair
-from RSS to AP. The sender and receiver are connected via channels. There is an
+interface. One pair provides message sending from AP to RSE and the other pair
+from RSE to AP. The sender and receiver are connected via channels. There is an
 IMPDEF number of channels (e.g: 4-16) between a sender and a receiver module.
 
-The RSS communication layer provides two ways for message exchange:
+The RSE communication layer provides two ways for message exchange:
 
 - ``Embedded messaging``: The full message, including header and payload, are
   exchanged over the MHU channels. A channel is capable of delivering a single
@@ -55,16 +55,16 @@ The RSS communication layer provides two ways for message exchange:
 - ``Pointer-access messaging``: The message header and the payload are
   separated and they are conveyed in different ways. The header is sent
   over the channels, similar to the embedded messaging but the payload is
-  copied over by RSS core (or by DMA) between the sender and the receiver. This
+  copied over by RSE core (or by DMA) between the sender and the receiver. This
   could be useful in the case of long messages because transaction time is less
-  compared to the embedded messaging mode. Small payloads are copied by the RSS
+  compared to the embedded messaging mode. Small payloads are copied by the RSE
   core because setting up DMA would require more CPU cycles. The payload is
-  either copied into an internal buffer or directly read-written by RSS. Actual
-  behavior depends on RSS setup, whether the partition supports memory-mapped
+  either copied into an internal buffer or directly read-written by RSE. Actual
+  behavior depends on RSE setup, whether the partition supports memory-mapped
   ``iovec``. Therefore, the sender must handle both cases and prevent access to
-  the memory, where payload data lives, while the RSS handles the request.
+  the memory, where payload data lives, while the RSE handles the request.
 
-The RSS communication layer supports both ways of messaging in parallel. It is
+The RSE communication layer supports both ways of messaging in parallel. It is
 decided at runtime based on the message size which way to transfer the message.
 
 .. code-block:: bash
@@ -93,25 +93,25 @@ decided at runtime based on the message size which way to transfer the message.
              V                           |            | |      V           V
     +----------------------------------------------+  | |  +-------------------+
     |                                              |--+-+  |                   |
-    |                  RSS                         |       |      SRAM         |
+    |                  RSE                         |       |      SRAM         |
     |                                              |       |                   |
     +----------------------------------------------+       +-------------------+
 
 .. Note::
 
-    The RSS communication layer is not prepared for concurrent execution. The
+    The RSE communication layer is not prepared for concurrent execution. The
     current use case only requires message exchange during the boot phase. In
     the boot phase, only a single core is running and the rest of the cores are
     in reset.
 
 Message structure
 ^^^^^^^^^^^^^^^^^
-A description of the message format can be found in the ``RSS communication
+A description of the message format can be found in the ``RSE communication
 design`` [2]_ document.
 
 Source files
 ^^^^^^^^^^^^
-- RSS comms:  ``drivers/arm/rss``
+- RSE comms:  ``drivers/arm/rse``
 - MHU driver: ``drivers/arm/mhu``
 
 
@@ -119,29 +119,34 @@ API for communication over MHU
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 The API is defined in these header files:
 
-- ``include/drivers/arm/rss_comms.h``
+- ``include/drivers/arm/rse_comms.h``
 - ``include/drivers/arm/mhu.h``
 
-RSS provided runtime services
+RSE provided runtime services
 -----------------------------
 
-RSS provides the following runtime services:
+RSE provides the following runtime services:
 
 - ``Measured boot``: Securely store the firmware measurements which were
   computed during the boot process and the associated metadata (image
   description, measurement algorithm, etc.). More info on measured boot service
-  in RSS can be found in the ``measured_boot_integration_guide`` [3]_ .
+  in RSE can be found in the ``measured_boot_integration_guide`` [3]_ .
 - ``Delegated attestation``: Query the platform attestation token and derive a
   delegated attestation key. More info on the delegated attestation service
-  in RSS can be found in the ``delegated_attestation_integration_guide`` [4]_ .
+  in RSE can be found in the ``delegated_attestation_integration_guide`` [4]_ .
 - ``OTP assets management``: Public keys used by AP during the trusted boot
-  process can be requested from RSS. Furthermore, AP can request RSS to
+  process can be requested from RSE. Furthermore, AP can request RSE to
   increase a non-volatile counter. Please refer to the
-  ``RSS key management`` [5]_ document for more details.
+  ``RSE key management`` [5]_ document for more details.
+- ``DICE Protection Environment``: Securely store the firmware measurements
+  which were computed during the boot process and the associated metadata. It is
+  also capable of representing the boot measurements in the form of a
+  certificate chain, which is queriable. Please refer to the
+  ``DICE Protection Environment (DPE)`` [8]_ document for more details.
 
 Runtime service API
 ^^^^^^^^^^^^^^^^^^^
-The RSS provided runtime services implement a PSA aligned API. The parameter
+The RSE provided runtime services implement a PSA aligned API. The parameter
 encoding follows the PSA client protocol described in the
 ``Firmware Framework for M`` [6]_ document in chapter 4.4. The implementation is
 restricted to the static handle use case therefore only the ``psa_call`` API is
@@ -168,7 +173,7 @@ Software and API layers
          |                               |
          V                               V
     +------------------------------------------------+
-    |         RSS communication protocol             |
+    |         RSE communication protocol             |
     +------------------------------------------------+
          |                     ^
          | mhu_send_data()     | mhu_receive_data()
@@ -188,7 +193,7 @@ Software and API layers
                          |
                          V
     +------------------------------------------------+
-    |             MHU HW on RSS side                 |
+    |             MHU HW on RSE side                 |
     +------------------------------------------------+
              |                        ^
              | IRQ                    | Register access
@@ -204,17 +209,17 @@ Software and API layers
     +---------------+       +------------------------+
 
 
-RSS based Measured Boot
+RSE based Measured Boot
 -----------------------
 
 Measured Boot is the process of cryptographically measuring (computing the hash
 value of a binary) the code and critical data used at boot time. The
 measurement must be stored in a tamper-resistant way, so the security state
-of the device can be attested later to an external party. RSS provides a runtime
+of the device can be attested later to an external party. RSE provides a runtime
 service which is meant to store measurements and associated metadata alongside.
 
 Data is stored in internal SRAM which is only accessible by the secure runtime
-firmware of RSS. Data is stored in so-called measurement slots. A platform has
+firmware of RSE. Data is stored in so-called measurement slots. A platform has
 IMPDEF number of measurement slots. The measurement storage follows extend
 semantics. This means that measurements are not stored directly (as it was
 taken) instead they contribute to the current value of the measurement slot.
@@ -236,7 +241,7 @@ Defined here:
 .. code-block:: c
 
     psa_status_t
-    rss_measured_boot_extend_measurement(uint8_t        index,
+    rse_measured_boot_extend_measurement(uint8_t        index,
                                          const uint8_t *signer_id,
                                          size_t         signer_id_size,
                                          const uint8_t *version,
@@ -291,27 +296,27 @@ multiple times:
 .. Note::
 
     Extending multiple measurements in the same slot leads to some metadata
-    information loss. Since RSS is not constrained on special HW resources to
+    information loss. Since RSE is not constrained on special HW resources to
     store the measurements and metadata, therefore it is worth considering to
     store all of them one by one in distinct slots. However, they are one-by-one
     included in the platform attestation token. So, the number of distinct
     firmware image measurements has an impact on the size of the attestation
     token.
 
-The allocation of the measurement slot among RSS, Root and Realm worlds is
+The allocation of the measurement slot among RSE, Root and Realm worlds is
 platform dependent. The platform must provide an allocation of the measurement
 slot at build time. An example can be found in
 ``tf-a/plat/arm/board/tc/tc_bl1_measured_boot.c``
 Furthermore, the memory, which holds the metadata is also statically allocated
-in RSS memory. Some of the fields have a static value (measurement algorithm),
+in RSE memory. Some of the fields have a static value (measurement algorithm),
 and some of the values have a dynamic value (measurement value) which is updated
 by the bootloaders when the firmware image is loaded and measured. The metadata
 structure is defined in
-``include/drivers/measured_boot/rss/rss_measured_boot.h``.
+``include/drivers/measured_boot/rse/rse_measured_boot.h``.
 
 .. code-block:: c
 
-    struct rss_mboot_metadata {
+    struct rse_mboot_metadata {
             unsigned int id;
             uint8_t slot;
             uint8_t signer_id[SIGNER_ID_MAX_SIZE];
@@ -328,24 +333,24 @@ Signer-ID API
 ^^^^^^^^^^^^^
 
 This function calculates the hash of a public key (signer-ID) using the
-``Measurement algorithm`` and stores it in the ``rss_mboot_metadata`` field
+``Measurement algorithm`` and stores it in the ``rse_mboot_metadata`` field
 named ``signer_id``.
 Prior to calling this function, the caller must ensure that the ``signer_id``
 field points to the zero-filled buffer.
 
 Defined here:
 
-- ``include/drivers/measured_boot/rss/rss_measured_boot.h``
+- ``include/drivers/measured_boot/rse/rse_measured_boot.h``
 
 .. code-block:: c
 
-   int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
+   int rse_mboot_set_signer_id(struct rse_mboot_metadata *metadata_ptr,
                                const void *pk_oid,
                                const void *pk_ptr,
                                size_t pk_len)
 
 
-- First parameter is the pointer to the ``rss_mboot_metadata`` structure.
+- First parameter is the pointer to the ``rse_mboot_metadata`` structure.
 - Second parameter is the pointer to the key-OID of the public key.
 - Third parameter is the pointer to the public key buffer.
 - Fourth parameter is the size of public key buffer.
@@ -355,16 +360,14 @@ Defined here:
 Build time config options
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- ``MEASURED_BOOT``: Enable measured boot. It depends on the platform
-  implementation whether RSS or TPM (or both) backend based measured boot is
-  enabled.
-- ``MBOOT_RSS_HASH_ALG``: Determine the hash algorithm to measure the images.
+- ``MEASURED_BOOT``: Enable measured boot.
+- ``MBOOT_RSE_HASH_ALG``: Determine the hash algorithm to measure the images.
   The default value is sha-256.
 
 Measured boot flow
 ^^^^^^^^^^^^^^^^^^
 
-.. figure:: ../resources/diagrams/rss_measured_boot_flow.svg
+.. figure:: ../resources/diagrams/rse_measured_boot_flow.svg
   :align: center
 
 Sample console log
@@ -425,17 +428,13 @@ The detailed description of the delegated attestation service can be found in
 the ``Delegated Attestation Service Integration Guide`` [4]_ document.
 
 In the CCA use case, the Realm Management Monitor (RMM) relies on the delegated
-attestation service of the RSS to get a realm attestation key and the CCA
+attestation service of the RSE to get a realm attestation key and the CCA
 platform token. BL31 does not use the service for its own purpose, only calls
-it on behalf of RMM. The access to MHU interface and thereby to RSS is
+it on behalf of RMM. The access to MHU interface and thereby to RSE is
 restricted to BL31 only. Therefore, RMM does not have direct access, all calls
 need to go through BL31. The RMM dispatcher module of the BL31 is responsible
 for delivering the calls between the two parties.
 
-.. Note::
-     Currently the connection between the RMM dispatcher and the PSA/RSS layer
-     is not yet implemented. RMM dispatcher just returns hard coded data.
-
 Delegated Attestation API
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 Defined here:
@@ -445,7 +444,7 @@ Defined here:
 .. code-block:: c
 
     psa_status_t
-    rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+    rse_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
                                            uint32_t  key_bits,
                                            uint8_t  *key_buf,
                                            size_t    key_buf_size,
@@ -453,7 +452,7 @@ Defined here:
                                            uint32_t  hash_algo);
 
     psa_status_t
-    rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+    rse_delegated_attest_get_token(const uint8_t *dak_pub_hash,
                                    size_t         dak_pub_hash_size,
                                    uint8_t       *token_buf,
                                    size_t         token_buf_size,
@@ -462,7 +461,7 @@ Defined here:
 Attestation flow
 ^^^^^^^^^^^^^^^^
 
-.. figure:: ../resources/diagrams/rss_attestation_flow.svg
+.. figure:: ../resources/diagrams/rse_attestation_flow.svg
   :align: center
 
 Sample attestation token
@@ -482,74 +481,101 @@ Binary format:
     INFO:    Get platform token start
     INFO:    Get platform token succeeds, len: 1086
     INFO:    Platform attestation token:
-    INFO:            d2 84 44 a1 01 38 22 a0 59 03 d1 a9 0a 58 20 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-    INFO:            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19
-    INFO:            01 00 58 21 01 cb 8c 79 f7 a0 0a 6c ce 12 66 f8
-    INFO:            64 45 48 42 0e c5 10 bf 84 ee 22 18 b9 8f 11 04
-    INFO:            c7 22 31 9d fb 19 09 5c 58 20 aa aa aa aa aa aa
-    INFO:            aa aa bb bb bb bb bb bb bb bb cc cc cc cc cc cc
-    INFO:            cc cc dd dd dd dd dd dd dd dd 19 09 5b 19 30 00
-    INFO:            19 09 5f 89 a4 05 58 20 bf e6 d8 6f 88 26 f4 ff
-    INFO:            97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d a2 6a
-    INFO:            df 34 c3 29 48 9a dc 38 04 67 31 2e 36 2e 30 2b
-    INFO:            30 01 64 52 54 5f 30 02 58 20 90 27 f2 46 ab 31
-    INFO:            85 36 46 c4 d7 c6 60 ed 31 0d 3c f0 14 de f0 6c
-    INFO:            24 0b de b6 7a 84 fc 3f 5b b7 a4 05 58 20 b3 60
-    INFO:            ca f5 c9 8c 6b 94 2a 48 82 fa 9d 48 23 ef b1 66
-    INFO:            a9 ef 6a 6e 4a a3 7c 19 19 ed 1f cc c0 49 04 67
-    INFO:            30 2e 30 2e 30 2b 30 01 64 52 54 5f 31 02 58 20
-    INFO:            52 13 15 d4 9d b2 cf 54 e4 99 37 44 40 68 f0 70
-    INFO:            7d 73 64 ae f7 08 14 b0 f7 82 ad c6 17 db a3 91
-    INFO:            a4 05 58 20 bf e6 d8 6f 88 26 f4 ff 97 fb 96 c4
-    INFO:            e6 fb c4 99 3e 46 19 fc 56 5d a2 6a df 34 c3 29
-    INFO:            48 9a dc 38 04 67 31 2e 35 2e 30 2b 30 01 64 52
-    INFO:            54 5f 32 02 58 20 8e 5d 64 7e 6f 6c c6 6f d4 4f
-    INFO:            54 b6 06 e5 47 9a cc 1b f3 7f ce 87 38 49 c5 92
-    INFO:            d8 2f 85 2e 85 42 a4 05 58 20 bf e6 d8 6f 88 26
-    INFO:            f4 ff 97 fb 96 c4 e6 fb c4 99 3e 46 19 fc 56 5d
-    INFO:            a2 6a df 34 c3 29 48 9a dc 38 04 67 31 2e 35 2e
-    INFO:            30 2b 30 01 60 02 58 20 b8 01 65 a7 78 8b c6 59
-    INFO:            42 8d 33 10 85 d1 49 0a dc 9e c3 ee df 85 1b d2
-    INFO:            f0 73 73 6a 0c 07 11 b8 a4 05 58 20 b0 f3 82 09
-    INFO:            12 97 d8 3a 37 7a 72 47 1b ec 32 73 e9 92 32 e2
-    INFO:            49 59 f6 5e 8b 4a 4a 46 d8 22 9a da 04 60 01 6a
-    INFO:            46 57 5f 43 4f 4e 46 49 47 00 02 58 20 21 9e a0
-    INFO:            13 82 e6 d7 97 5a 11 13 a3 5f 45 39 68 b1 d9 a3
-    INFO:            ea 6a ab 84 23 3b 8c 06 16 98 20 ba b9 a4 05 58
-    INFO:            20 b0 f3 82 09 12 97 d8 3a 37 7a 72 47 1b ec 32
-    INFO:            73 e9 92 32 e2 49 59 f6 5e 8b 4a 4a 46 d8 22 9a
-    INFO:            da 04 60 01 6d 54 42 5f 46 57 5f 43 4f 4e 46 49
-    INFO:            47 00 02 58 20 41 39 f6 c2 10 84 53 c5 17 ae 9a
-    INFO:            e5 be c1 20 7b cc 24 24 f3 9d 20 a8 fb c7 b3 10
-    INFO:            e3 ee af 1b 05 a4 05 58 20 b0 f3 82 09 12 97 d8
-    INFO:            3a 37 7a 72 47 1b ec 32 73 e9 92 32 e2 49 59 f6
-    INFO:            5e 8b 4a 4a 46 d8 22 9a da 04 60 01 65 42 4c 5f
-    INFO:            32 00 02 58 20 5c 96 20 e1 e3 3b 0f 2c eb c1 8e
-    INFO:            1a 02 a6 65 86 dd 34 97 a7 4c 98 13 bf 74 14 45
-    INFO:            2d 30 28 05 c3 a4 05 58 20 b0 f3 82 09 12 97 d8
-    INFO:            3a 37 7a 72 47 1b ec 32 73 e9 92 32 e2 49 59 f6
-    INFO:            5e 8b 4a 4a 46 d8 22 9a da 04 60 01 6e 53 45 43
-    INFO:            55 52 45 5f 52 54 5f 45 4c 33 00 02 58 20 f6 fb
-    INFO:            62 99 a5 0c df db 02 0b 72 5b 1c 0b 63 6e 94 ee
-    INFO:            66 50 56 3a 29 9c cb 38 f0 ec 59 99 d4 2e a4 05
-    INFO:            58 20 b0 f3 82 09 12 97 d8 3a 37 7a 72 47 1b ec
-    INFO:            32 73 e9 92 32 e2 49 59 f6 5e 8b 4a 4a 46 d8 22
-    INFO:            9a da 04 60 01 6a 48 57 5f 43 4f 4e 46 49 47 00
-    INFO:            02 58 20 98 5d 87 21 84 06 33 9d c3 1f 91 f5 68
-    INFO:            8d a0 5a f0 d7 7e 20 51 ce 3b f2 a5 c3 05 2e 3c
-    INFO:            8b 52 31 19 01 09 78 1c 68 74 74 70 3a 2f 2f 61
-    INFO:            72 6d 2e 63 6f 6d 2f 43 43 41 2d 53 53 44 2f 31
-    INFO:            2e 30 2e 30 19 09 62 71 6e 6f 74 2d 68 61 73 68
-    INFO:            2d 65 78 74 65 6e 64 65 64 19 09 61 44 ef be ad
-    INFO:            de 19 09 60 77 77 77 77 2e 74 72 75 73 74 65 64
-    INFO:            66 69 72 6d 77 61 72 65 2e 6f 72 67 58 60 29 4e
-    INFO:            4a d3 98 1e 3b 70 9f b6 66 ed 47 33 0e 99 f0 b1
-    INFO:            c3 f2 bc b2 1d b0 ae 90 0c c4 82 ff a2 6f ae 45
-    INFO:            f6 87 09 4a 09 21 77 ec 36 1c 53 b8 a7 9b 8e f7
-    INFO:            27 eb 7a 09 da 6f fb bf cb fd b3 e5 e9 36 91 b1
-    INFO:            92 13 c1 30 16 b4 5c 49 5e c0 c1 b9 01 5c 88 2c
-    INFO:            f8 2f 3e a4 a2 6d e4 9d 31 6a 06 f7 a7 73
+    INFO:            d2 84 44 a1 01 38 22 a0 59 05 81 a9 19 01 09 78
+    INFO:            23 74 61 67 3a 61 72 6d 2e 63 6f 6d 2c 32 30 32
+    INFO:            33 3a 63 63 61 5f 70 6c 61 74 66 6f 72 6d 23 31
+    INFO:            2e 30 2e 30 0a 58 20 0d 22 e0 8a 98 46 90 58 48
+    INFO:            63 18 28 34 89 bd b3 6f 09 db ef eb 18 64 df 43
+    INFO:            3f a6 e5 4e a2 d7 11 19 09 5c 58 20 7f 45 4c 46
+    INFO:            02 01 01 00 00 00 00 00 00 00 00 00 03 00 3e 00
+    INFO:            01 00 00 00 50 58 00 00 00 00 00 00 19 01 00 58
+    INFO:            21 01 07 06 05 04 03 02 01 00 0f 0e 0d 0c 0b 0a
+    INFO:            09 08 17 16 15 14 13 12 11 10 1f 1e 1d 1c 1b 1a
+    INFO:            19 18 19 09 61 44 cf cf cf cf 19 09 5b 19 30 03
+    INFO:            19 09 62 67 73 68 61 2d 32 35 36 19 09 60 78 3a
+    INFO:            68 74 74 70 73 3a 2f 2f 76 65 72 61 69 73 6f 6e
+    INFO:            2e 65 78 61 6d 70 6c 65 2f 2e 77 65 6c 6c 2d 6b
+    INFO:            6e 6f 77 6e 2f 76 65 72 61 69 73 6f 6e 2f 76 65
+    INFO:            72 69 66 69 63 61 74 69 6f 6e 19 09 5f 8d a4 01
+    INFO:            69 52 53 45 5f 42 4c 31 5f 32 05 58 20 53 78 79
+    INFO:            63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c
+    INFO:            3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20
+    INFO:            9a 27 1f 2a 91 6b 0b 6e e6 ce cb 24 26 f0 b3 20
+    INFO:            6e f0 74 57 8b e5 5d 9b c9 4f 6f 3f e3 ab 86 aa
+    INFO:            06 67 73 68 61 2d 32 35 36 a4 01 67 52 53 45 5f
+    INFO:            42 4c 32 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 53 c2 34 e5 e8 47 2b
+    INFO:            6a c5 1c 1a e1 ca b3 fe 06 fa d0 53 be b8 eb fd
+    INFO:            89 77 b0 10 65 5b fd d3 c3 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 65 52 53 45 5f 53 05 58 20 53 78 79
+    INFO:            63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c
+    INFO:            3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20
+    INFO:            11 21 cf cc d5 91 3f 0a 63 fe c4 0a 6f fd 44 ea
+    INFO:            64 f9 dc 13 5c 66 63 4b a0 01 d1 0b cf 43 02 a2
+    INFO:            06 67 73 68 61 2d 32 35 36 a4 01 66 41 50 5f 42
+    INFO:            4c 31 05 58 20 53 78 79 63 07 53 5d f3 ec 8d 8b
+    INFO:            15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38 c0
+    INFO:            fa 97 3f 7a a3 02 58 20 15 71 b5 ec 78 bd 68 51
+    INFO:            2b f7 83 0b b6 a2 a4 4b 20 47 c7 df 57 bc e7 9e
+    INFO:            b8 a1 c0 e5 be a0 a5 01 06 67 73 68 61 2d 32 35
+    INFO:            36 a4 01 66 41 50 5f 42 4c 32 05 58 20 53 78 79
+    INFO:            63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c
+    INFO:            3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20
+    INFO:            10 15 9b af 26 2b 43 a9 2d 95 db 59 da e1 f7 2c
+    INFO:            64 51 27 30 16 61 e0 a3 ce 4e 38 b2 95 a9 7c 58
+    INFO:            06 67 73 68 61 2d 32 35 36 a4 01 67 53 43 50 5f
+    INFO:            42 4c 31 05 58 20 53 78 79 63 07 53 5d f3 ec 8d
+    INFO:            8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38
+    INFO:            c0 fa 97 3f 7a a3 02 58 20 10 12 2e 85 6b 3f cd
+    INFO:            49 f0 63 63 63 17 47 61 49 cb 73 0a 1a a1 cf aa
+    INFO:            d8 18 55 2b 72 f5 6d 6f 68 06 67 73 68 61 2d 32
+    INFO:            35 36 a4 01 67 53 43 50 5f 42 4c 32 05 58 20 f1
+    INFO:            4b 49 87 90 4b cb 58 14 e4 45 9a 05 7e d4 d2 0f
+    INFO:            58 a6 33 15 22 88 a7 61 21 4d cd 28 78 0b 56 02
+    INFO:            58 20 aa 67 a1 69 b0 bb a2 17 aa 0a a8 8a 65 34
+    INFO:            69 20 c8 4c 42 44 7c 36 ba 5f 7e a6 5f 42 2c 1f
+    INFO:            e5 d8 06 67 73 68 61 2d 32 35 36 a4 01 67 41 50
+    INFO:            5f 42 4c 33 31 05 58 20 53 78 79 63 07 53 5d f3
+    INFO:            ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3
+    INFO:            22 38 c0 fa 97 3f 7a a3 02 58 20 2e 6d 31 a5 98
+    INFO:            3a 91 25 1b fa e5 ae fa 1c 0a 19 d8 ba 3c f6 01
+    INFO:            d0 e8 a7 06 b4 cf a9 66 1a 6b 8a 06 67 73 68 61
+    INFO:            2d 32 35 36 a4 01 63 52 4d 4d 05 58 20 53 78 79
+    INFO:            63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56 41 41 9c
+    INFO:            3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3 02 58 20
+    INFO:            a1 fb 50 e6 c8 6f ae 16 79 ef 33 51 29 6f d6 71
+    INFO:            34 11 a0 8c f8 dd 17 90 a4 fd 05 fa e8 68 81 64
+    INFO:            06 67 73 68 61 2d 32 35 36 a4 01 69 48 57 5f 43
+    INFO:            4f 4e 46 49 47 05 58 20 53 78 79 63 07 53 5d f3
+    INFO:            ec 8d 8b 15 a2 e2 dc 56 41 41 9c 3d 30 60 cf e3
+    INFO:            22 38 c0 fa 97 3f 7a a3 02 58 20 1a 25 24 02 97
+    INFO:            2f 60 57 fa 53 cc 17 2b 52 b9 ff ca 69 8e 18 31
+    INFO:            1f ac d0 f3 b0 6e ca ae f7 9e 17 06 67 73 68 61
+    INFO:            2d 32 35 36 a4 01 69 46 57 5f 43 4f 4e 46 49 47
+    INFO:            05 58 20 53 78 79 63 07 53 5d f3 ec 8d 8b 15 a2
+    INFO:            e2 dc 56 41 41 9c 3d 30 60 cf e3 22 38 c0 fa 97
+    INFO:            3f 7a a3 02 58 20 9a 92 ad bc 0c ee 38 ef 65 8c
+    INFO:            71 ce 1b 1b f8 c6 56 68 f1 66 bf b2 13 64 4c 89
+    INFO:            5c cb 1a d0 7a 25 06 67 73 68 61 2d 32 35 36 a4
+    INFO:            01 6c 54 42 5f 46 57 5f 43 4f 4e 46 49 47 05 58
+    INFO:            20 53 78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc
+    INFO:            56 41 41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a
+    INFO:            a3 02 58 20 23 89 03 18 0c c1 04 ec 2c 5d 8b 3f
+    INFO:            20 c5 bc 61 b3 89 ec 0a 96 7d f8 cc 20 8c dc 7c
+    INFO:            d4 54 17 4f 06 67 73 68 61 2d 32 35 36 a4 01 6d
+    INFO:            53 4f 43 5f 46 57 5f 43 4f 4e 46 49 47 05 58 20
+    INFO:            53 78 79 63 07 53 5d f3 ec 8d 8b 15 a2 e2 dc 56
+    INFO:            41 41 9c 3d 30 60 cf e3 22 38 c0 fa 97 3f 7a a3
+    INFO:            02 58 20 e6 c2 1e 8d 26 0f e7 18 82 de bd b3 39
+    INFO:            d2 40 2a 2c a7 64 85 29 bc 23 03 f4 86 49 bc e0
+    INFO:            38 00 17 06 67 73 68 61 2d 32 35 36 58 60 31 d0
+    INFO:            4d 52 cc de 95 2c 1e 32 cb a1 81 88 5a 40 b8 cc
+    INFO:            38 e0 52 8c 1e 89 58 98 07 64 2a a5 e3 f2 bc 37
+    INFO:            f9 53 74 50 6b ff 4d 2e 4b e7 06 3c 4d 72 41 92
+    INFO:            70 c7 22 e8 d4 d9 3e e8 b6 c9 fa ce 3b 43 c9 76
+    INFO:            1a 49 94 1a b6 f3 8f fd ff 49 6a d4 63 b4 cb fa
+    INFO:            11 d8 3e 23 e3 1f 7f 62 32 9d e3 0c 1c c8
     INFO:    DELEGATED ATTEST TEST END
 
 JSON format:
@@ -557,93 +583,174 @@ JSON format:
 .. code-block:: JSON
 
     {
-        "CCA_PLATFORM_CHALLENGE": "b'0000000000000000000000000000000000000000000000000000000000000000'",
-        "CCA_PLATFORM_INSTANCE_ID": "b'01CB8C79F7A00A6CCE1266F8644548420EC510BF84EE2218B98F1104C722319DFB'",
-        "CCA_PLATFORM_IMPLEMENTATION_ID": "b'AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD'",
-        "CCA_PLATFORM_LIFECYCLE": "secured_3000",
+        "CCA_ATTESTATION_PROFILE": "tag:arm.com,2023:cca_platform#1.0.0",
+        "CCA_PLATFORM_CHALLENGE": "b'0D22E08A98469058486318283489BDB36F09DBEFEB1864DF433FA6E54EA2D711'",
+        "CCA_PLATFORM_IMPLEMENTATION_ID": "b'7F454C4602010100000000000000000003003E00010000005058000000000000'",
+        "CCA_PLATFORM_INSTANCE_ID": "b'0107060504030201000F0E0D0C0B0A090817161514131211101F1E1D1C1B1A1918'",
+        "CCA_PLATFORM_CONFIG": "b'CFCFCFCF'",
+        "CCA_PLATFORM_LIFECYCLE": "secured_3003",
+        "CCA_PLATFORM_HASH_ALGO_ID": "sha-256",
+        "CCA_PLATFORM_VERIFICATION_SERVICE": "https://veraison.example/.well-known/veraison/verification",
         "CCA_PLATFORM_SW_COMPONENTS": [
             {
-                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
-                "SW_COMPONENT_VERSION": "1.6.0+0",
-                "SW_COMPONENT_TYPE": "RT_0",
-                "MEASUREMENT_VALUE": "b'9027F246AB31853646C4D7C660ED310D3CF014DEF06C240BDEB67A84FC3F5BB7'"
+                "SW_COMPONENT_TYPE": "RSE_BL1_2",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'9A271F2A916B0B6EE6CECB2426F0B3206EF074578BE55D9BC94F6F3FE3AB86AA'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "RSE_BL2",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'53C234E5E8472B6AC51C1AE1CAB3FE06FAD053BEB8EBFD8977B010655BFDD3C3'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'B360CAF5C98C6B942A4882FA9D4823EFB166A9EF6A6E4AA37C1919ED1FCCC049'",
-                "SW_COMPONENT_VERSION": "0.0.0+0",
-                "SW_COMPONENT_TYPE": "RT_1",
-                "MEASUREMENT_VALUE": "b'521315D49DB2CF54E49937444068F0707D7364AEF70814B0F782ADC617DBA391'"
+                "SW_COMPONENT_TYPE": "RSE_S",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'1121CFCCD5913F0A63FEC40A6FFD44EA64F9DC135C66634BA001D10BCF4302A2'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
-                "SW_COMPONENT_VERSION": "1.5.0+0",
-                "SW_COMPONENT_TYPE": "RT_2",
-                "MEASUREMENT_VALUE": "b'8E5D647E6F6CC66FD44F54B606E5479ACC1BF37FCE873849C592D82F852E8542'"
+                "SW_COMPONENT_TYPE": "AP_BL1",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'1571B5EC78BD68512BF7830BB6A2A44B2047C7DF57BCE79EB8A1C0E5BEA0A501'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'BFE6D86F8826F4FF97FB96C4E6FBC4993E4619FC565DA26ADF34C329489ADC38'",
-                "SW_COMPONENT_VERSION": "1.5.0+0",
-                "SW_COMPONENT_TYPE": "",
-                "MEASUREMENT_VALUE": "b'B80165A7788BC659428D331085D1490ADC9EC3EEDF851BD2F073736A0C0711B8'"
+                "SW_COMPONENT_TYPE": "AP_BL2",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'10159BAF262B43A92D95DB59DAE1F72C645127301661E0A3CE4E38B295A97C58'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "FW_CONFIG\u0000",
-                "MEASUREMENT_VALUE": "b'219EA01382E6D7975A1113A35F453968B1D9A3EA6AAB84233B8C06169820BAB9'"
+                "SW_COMPONENT_TYPE": "SCP_BL1",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'10122E856B3FCD49F063636317476149CB730A1AA1CFAAD818552B72F56D6F68'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "TB_FW_CONFIG\u0000",
-                "MEASUREMENT_VALUE": "b'4139F6C2108453C517AE9AE5BEC1207BCC2424F39D20A8FBC7B310E3EEAF1B05'"
+                "SW_COMPONENT_TYPE": "SCP_BL2",
+                "SIGNER_ID": "b'F14B4987904BCB5814E4459A057ED4D20F58A633152288A761214DCD28780B56'",
+                "MEASUREMENT_VALUE": "b'AA67A169B0BBA217AA0AA88A65346920C84C42447C36BA5F7EA65F422C1FE5D8'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "BL_2\u0000",
-                "MEASUREMENT_VALUE": "b'5C9620E1E33B0F2CEBC18E1A02A66586DD3497A74C9813BF7414452D302805C3'"
+                "SW_COMPONENT_TYPE": "AP_BL31",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'2E6D31A5983A91251BFAE5AEFA1C0A19D8BA3CF601D0E8A706B4CFA9661A6B8A'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "SECURE_RT_EL3\u0000",
-                "MEASUREMENT_VALUE": "b'F6FB6299A50CDFDB020B725B1C0B636E94EE6650563A299CCB38F0EC5999D42E'"
+                "SW_COMPONENT_TYPE": "RMM",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'A1FB50E6C86FAE1679EF3351296FD6713411A08CF8DD1790A4FD05FAE8688164'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             },
             {
-                "SIGNER_ID": "b'b0f382091297d83a377a72471bec3273e99232e24959f65e8b4a4a46d8229ada'",
-                "SW_COMPONENT_VERSION": "",
-                "SW_COMPONENT_TYPE": "HW_CONFIG\u0000",
-                "MEASUREMENT_VALUE": "b'985D87218406339DC31F91F5688DA05AF0D77E2051CE3BF2A5C3052E3C8B5231'"
+                "SW_COMPONENT_TYPE": "HW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'1A252402972F6057FA53CC172B52B9FFCA698E18311FACD0F3B06ECAAEF79E17'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "FW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'9A92ADBC0CEE38EF658C71CE1B1BF8C65668F166BFB213644C895CCB1AD07A25'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "TB_FW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'238903180CC104EC2C5D8B3F20C5BC61B389EC0A967DF8CC208CDC7CD454174F'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
+            },
+            {
+                "SW_COMPONENT_TYPE": "SOC_FW_CONFIG",
+                "SIGNER_ID": "b'5378796307535DF3EC8D8B15A2E2DC5641419C3D3060CFE32238C0FA973F7AA3'",
+                "MEASUREMENT_VALUE": "b'E6C21E8D260FE71882DEBDB339D2402A2CA7648529BC2303F48649BCE0380017'",
+                "CCA_SW_COMPONENT_HASH_ID": "sha-256"
             }
-        ],
-        "CCA_ATTESTATION_PROFILE": "http://arm.com/CCA-SSD/1.0.0",
-        "CCA_PLATFORM_HASH_ALGO_ID": "not-hash-extended",
-        "CCA_PLATFORM_CONFIG": "b'EFBEADDE'",
-        "CCA_PLATFORM_VERIFICATION_SERVICE": "www.trustedfirmware.org"
+        ]
     }
 
-RSS OTP Assets Management
+RSE based DICE Protection Environment
+-------------------------------------
+
+The ``DICE Protection Environment (DPE)`` [8]_ service makes it possible to
+execute |DICE| commands within an isolated execution environment. It provides
+clients with an interface to send DICE commands, encoded as CBOR objects,
+that act on opaque context handles. The |DPE| service performs |DICE|
+derivations and certification on its internal contexts, without exposing the
+|DICE| secrets (private keys and CDIs) outside of the isolated execution
+environment.
+
+|DPE| API
+^^^^^^^^^
+
+Defined here:
+
+- ``include/lib/psa/dice_protection_environment.h``
+
+.. code-block:: c
+
+    dpe_error_t
+    dpe_derive_context(int      context_handle,
+                       uint32_t cert_id,
+                       bool     retain_parent_context,
+                       bool     allow_new_context_to_derive,
+                       bool     create_certificate,
+                       const DiceInputValues *dice_inputs,
+                       int32_t  target_locality,
+                       bool     return_certificate,
+                       bool     allow_new_context_to_export,
+                       bool     export_cdi,
+                       int     *new_context_handle,
+                       int     *new_parent_context_handle,
+                       uint8_t *new_certificate_buf,
+                       size_t   new_certificate_buf_size,
+                       size_t  *new_certificate_actual_size,
+                       uint8_t *exported_cdi_buf,
+                       size_t   exported_cdi_buf_size,
+                       size_t  *exported_cdi_actual_size);
+
+Build time config options
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``MEASURED_BOOT``: Enable measured boot.
+- ``DICE_PROTECTION_ENVIRONMENT``: Boolean flag to specify the measured boot
+  backend when |RSE| based ``MEASURED_BOOT`` is enabled. The default value is
+  ``0``. When set to ``1`` then measurements and additional metadata collected
+  during the measured boot process are sent to the |DPE| for storage and
+  processing.
+- ``DPE_ALG_ID``: Determine the hash algorithm to measure the images. The
+  default value is sha-256.
+
+Example certificate chain
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``plat/arm/board/tc/tc_dpe.h``
+
+RSE OTP Assets Management
 -------------------------
 
-RSS provides access for AP to assets in OTP, which include keys for image
+RSE provides access for AP to assets in OTP, which include keys for image
 signature verification and non-volatile counters for anti-rollback protection.
 
 Non-Volatile Counter API
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
-AP/RSS interface for retrieving and incrementing non-volatile counters API is
+AP/RSE interface for retrieving and incrementing non-volatile counters API is
 as follows.
 
 Defined here:
 
-- ``include/lib/psa/rss_platform_api.h``
+- ``include/lib/psa/rse_platform_api.h``
 
 .. code-block:: c
 
-    psa_status_t rss_platform_nv_counter_increment(uint32_t counter_id)
+    psa_status_t rse_platform_nv_counter_increment(uint32_t counter_id)
 
-    psa_status_t rss_platform_nv_counter_read(uint32_t counter_id,
+    psa_status_t rse_platform_nv_counter_read(uint32_t counter_id,
             uint32_t size, uint8_t *val)
 
 Through this service, we can read/increment any of the 3 non-volatile
@@ -656,15 +763,15 @@ counters used on an Arm CCA platform:
 Public Key API
 ^^^^^^^^^^^^^^
 
-AP/RSS interface for reading the ROTPK is as follows.
+AP/RSE interface for reading the ROTPK is as follows.
 
 Defined here:
 
-- ``include/lib/psa/rss_platform_api.h``
+- ``include/lib/psa/rse_platform_api.h``
 
 .. code-block:: c
 
-    psa_status_t rss_platform_key_read(enum rss_key_id_builtin_t key,
+    psa_status_t rse_platform_key_read(enum rse_key_id_builtin_t key,
             uint8_t *data, size_t data_size, size_t *data_length)
 
 Through this service, we can read any of the 3 ROTPKs used on an
@@ -677,14 +784,16 @@ Arm CCA platform:
 References
 ----------
 
-.. [1] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/readme.html
-.. [2] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_comms.html
-.. [3] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/measured_boot/measured_boot_integration_guide.rst
-.. [4] https://git.trustedfirmware.org/TF-M/tf-m-extras.git/tree/partitions/delegated_attestation/delegated_attest_integration_guide.rst
-.. [5] https://tf-m-user-guide.trustedfirmware.org/platform/arm/rss/rss_key_management.html
+.. [1] https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/index.html
+.. [2] https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_comms.html
+.. [3] https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/measured_boot_integration_guide.html
+.. [4] https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/delegated_attestation/delegated_attest_integration_guide.html
+.. [5] https://trustedfirmware-m.readthedocs.io/en/latest/platform/arm/rse/rse_key_management.html
 .. [6] https://developer.arm.com/-/media/Files/pdf/PlatformSecurityArchitecture/Architect/DEN0063-PSA_Firmware_Framework-1.0.0-2.pdf?revision=2d1429fa-4b5b-461a-a60e-4ef3d8f7f4b4&hash=3BFD6F3E687F324672F18E5BE9F08EDC48087C93
 .. [7] https://developer.arm.com/documentation/DEN0096/A_a/?lang=en
+.. [8] https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/dice_protection_environment/dice_protection_environment.html
 
 --------------
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
+*Copyright (c) 2024, Linaro Limited. All rights reserved.*
diff --git a/docs/getting_started/build-internals.rst b/docs/getting_started/build-internals.rst
index 390c3671..c43f4e98 100644
--- a/docs/getting_started/build-internals.rst
+++ b/docs/getting_started/build-internals.rst
@@ -19,3 +19,11 @@ depends on certain options to be enabled or disabled.
   ``HANDLE_EA_EL3_FIRST_NS`` is set. Currently only NS world routes EA to EL3 but
   in future when Secure/Realm wants to use FFH then they can introduce new macros
   which will enable this option implicitly.
+
+-  ``OPTEE_SP_FW_CONFIG``: DTC build flag to include OP-TEE as SP in
+   tb_fw_config device tree. This flag is defined only when
+   ``ARM_SPMC_MANIFEST_DTS`` manifest file name contains pattern optee_sp.
+
+-  ``TRUSTY_SP_FW_CONFIG``: DTC build flag to include Trusty as SP in
+   tb_fw_config device tree. This flag is defined only when
+   ``ARM_SPMC_MANIFEST_DTS`` manifest file name contains pattern trusty_sp.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 80baf9cd..ab0b94d5 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -23,8 +23,9 @@ Common build options
    is expected to contain a makefile called ``<aarch32_sp-value>.mk``.
 
 -  ``AMU_RESTRICT_COUNTERS``: Register reads to the group 1 counters will return
-   zero at all but the highest implemented exception level.  Reads from the
-   memory mapped view are unaffected by this control.
+   zero at all but the highest implemented exception level. External
+   memory-mapped debug accesses are unaffected by this control.
+   The default value is 1 for all platforms.
 
 -  ``ARCH`` : Choose the target build architecture for TF-A. It can take either
    ``aarch64`` or ``aarch32`` as values. By default, it is defined to
@@ -98,6 +99,10 @@ Common build options
    file that contains the BL32 private key in PEM format or a PKCS11 URI. If
    ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key.
 
+-  ``RMM``: This is an optional build option used when ``ENABLE_RME`` is set.
+   It specifies the path to RMM binary for the ``fip`` target. If the RMM option
+   is not specified, TF-A builds the TRP to load and run at R-EL2.
+
 -  ``BL33``: Path to BL33 image in the host file system. This is mandatory for
    ``fip`` target in case TF-A BL2 is used.
 
@@ -180,26 +185,32 @@ Common build options
    registers to be included when saving and restoring the CPU context. Default
    is 0.
 
--  ``CTX_INCLUDE_MTE_REGS``: Numeric value to include Memory Tagging Extension
-   registers in cpu context. This must be enabled, if the platform wants to use
-   this feature in the Secure world and MTE is enabled at ELX. This flag can
-   take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
-   Default value is 0.
+-  ``CTX_INCLUDE_MPAM_REGS``: Boolean option that, when set to 1, will cause the
+   Memory System Resource Partitioning and Monitoring (MPAM)
+   registers to be included when saving and restoring the CPU context.
+   Default is '0'.
 
 -  ``CTX_INCLUDE_NEVE_REGS``: Numeric value, when set will cause the Armv8.4-NV
    registers to be saved/restored when entering/exiting an EL2 execution
    context. This flag can take values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. Default value is 0.
+   ``ENABLE_FEAT`` mechanism. Default value is 0.
 
 -  ``CTX_INCLUDE_PAUTH_REGS``: Numeric value to enable the Pointer
    Authentication for Secure world. This will cause the ARMv8.3-PAuth registers
    to be included when saving and restoring the CPU context as part of world
-   switch. This flag can take values 0 to 2, to align with ``FEATURE_DETECTION``
+   switch. This flag can take values 0 to 2, to align with ``ENABLE_FEAT``
    mechanism. Default value is 0.
 
    Note that Pointer Authentication is enabled for Non-secure world irrespective
    of the value of this flag if the CPU supports it.
 
+-  ``CTX_INCLUDE_SVE_REGS``: Boolean option that, when set to 1, will cause the
+   SVE registers to be included when saving and restoring the CPU context. Note
+   that this build option requires ``ENABLE_SVE_FOR_SWD`` to be enabled. In
+   general, it is recommended to perform SVE context management in lower ELs
+   and skip in EL3 due to the additional cost of maintaining large data
+   structures to track the SVE state. Hence, the default value is 0.
+
 -  ``DEBUG``: Chooses between a debug and release build. It can take either 0
    (release) or 1 (debug) as values. 0 is the default.
 
@@ -215,7 +226,7 @@ Common build options
 
 -  ``DISABLE_MTPMU``: Numeric option to disable ``FEAT_MTPMU`` (Multi Threaded
    PMU). ``FEAT_MTPMU`` is an optional feature available on Armv8.6 onwards.
-   This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
+   This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. Default is ``0``.
 
 -  ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted
@@ -231,6 +242,13 @@ Common build options
    contributions are still expected to build with ``W=0`` and ``E=1`` (the
    default).
 
+-  ``EARLY_CONSOLE``: This option is used to enable early traces before default
+   console is properly setup. It introduces EARLY_* traces macros, that will
+   use the non-EARLY traces macros if the flag is enabled, or do nothing
+   otherwise. To use this feature, platforms will have to create the function
+   plat_setup_early_console().
+   Default is 0 (disabled)
+
 -  ``EL3_PAYLOAD_BASE``: This option enables booting an EL3 payload instead of
    the normal boot flow. It must specify the entry point address of the EL3
    payload. Please refer to the "Booting an EL3 payload" section for more
@@ -262,9 +280,35 @@ Common build options
    builds, but this behaviour can be overridden in each platform's Makefile or
    in the build command line.
 
+-  ``ENABLE_FEAT``
+   The Arm architecture defines several architecture extension features,
+   named FEAT_xxx in the architecure manual. Some of those features require
+   setup code in higher exception levels, other features might be used by TF-A
+   code itself.
+   Most of the feature flags defined in the TF-A build system permit to take
+   the values 0, 1 or 2, with the following meaning:
+
+   ::
+
+     ENABLE_FEAT_* = 0: Feature is disabled statically at compile time.
+     ENABLE_FEAT_* = 1: Feature is enabled unconditionally at compile time.
+     ENABLE_FEAT_* = 2: Feature is enabled, but checked at runtime.
+
+   When setting the flag to 0, the feature is disabled during compilation,
+   and the compiler's optimisation stage and the linker will try to remove
+   as much of this code as possible.
+   If it is defined to 1, the code will use the feature unconditionally, so the
+   CPU is expected to support that feature. The FEATURE_DETECTION debug
+   feature, if enabled, will verify this.
+   If the feature flag is set to 2, support for the feature will be compiled
+   in, but its existence will be checked at runtime, so it works on CPUs with
+   or without the feature. This is mostly useful for platforms which either
+   support multiple different CPUs, or where the CPU is configured at runtime,
+   like in emulators.
+
 -  ``ENABLE_FEAT_AMU``: Numeric value to enable Activity Monitor Unit
    extensions. This flag can take the values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. This is an optional architectural feature
+   ``ENABLE_FEAT`` mechanism. This is an optional architectural feature
    available on v8.4 onwards. Some v8.2 implementations also implement an AMU
    and this option can be used to enable this feature on those systems as well.
    This flag can take the values 0 to 2, the default is 0.
@@ -272,65 +316,83 @@ Common build options
 -  ``ENABLE_FEAT_AMUv1p1``: Numeric value to enable the ``FEAT_AMUv1p1``
    extension. ``FEAT_AMUv1p1`` is an optional feature available on Arm v8.6
    onwards. This flag can take the values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+   ``ENABLE_FEAT`` mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_CSV2_2``: Numeric value to enable the ``FEAT_CSV2_2``
    extension. It allows access to the SCXTNUM_EL2 (Software Context Number)
    register during EL2 context save/restore operations. ``FEAT_CSV2_2`` is an
    optional feature available on Arm v8.0 onwards. This flag can take values
-   0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+   0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``.
 
+-  ``ENABLE_FEAT_CSV2_3``: Numeric value to enable support for ``FEAT_CSV2_3``
+   extension. This feature is supported in AArch64 state only and is an optional
+   feature available in Arm v8.0 implementations.
+   ``FEAT_CSV2_3`` implies the implementation of ``FEAT_CSV2_2``.
+   The flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
+- ``ENABLE_FEAT_DEBUGV8P9``: Numeric value to enable ``FEAT_DEBUGV8P9``
+   extension which allows the ability to implement more than 16 breakpoints
+   and/or watchpoints. This feature is mandatory from v8.9 and is optional
+   from v8.8. This flag can take the values of 0 to 2, to align with the
+   ``ENABLE_FEAT`` mechanism. Default value is ``0``.
+
 -  ``ENABLE_FEAT_DIT``: Numeric value to enable ``FEAT_DIT`` (Data Independent
    Timing) extension. It allows setting the ``DIT`` bit of PSTATE in EL3.
    ``FEAT_DIT`` is a mandatory  architectural feature and is enabled from v8.4
    and upwards. This flag can take the values 0 to 2, to align  with the
-   ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+   ``ENABLE_FEAT`` mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_ECV``: Numeric value to enable support for the Enhanced Counter
    Virtualization feature, allowing for access to the CNTPOFF_EL2 (Counter-timer
    Physical Offset register) during EL2 to EL3 context save/restore operations.
    Its a mandatory architectural feature and is enabled from v8.6 and upwards.
-   This flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps)
    feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained
    Read Trap Register) during EL2 to EL3 context save/restore operations.
    Its a mandatory architectural feature and is enabled from v8.6 and upwards.
-   This flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_FGT2``: Numeric value to enable support for FGT2
+   (Fine Grain Traps 2) feature allowing for access to Fine-grained trap 2 registers
+   during  EL2 to EL3 context save/restore operations.
+   Its an optional architectural feature and is available from v8.8 and upwards.
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_HCX``: Numeric value to set the bit SCR_EL3.HXEn in EL3 to
    allow access to HCRX_EL2 (extended hypervisor control register) from EL2 as
    well as adding HCRX_EL2 to the EL2 context save/restore operations. Its a
    mandatory architectural feature and is enabled from v8.7 and upwards. This
-   flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
--  ``ENABLE_FEAT_MTE_PERM``: Numeric value to enable support for
-   ``FEAT_MTE_PERM``, which introduces Allocation tag access permission to
-   memory region attributes. ``FEAT_MTE_PERM`` is a optional architectural
-   feature available from v8.9 and upwards.  This flag can take the values 0 to
-   2, to align  with the ``FEATURE_DETECTION`` mechanism. Default value is
-   ``0``.
+-  ``ENABLE_FEAT_MTE2``: Numeric value to enable Memory Tagging Extension2
+   if the platform wants to use this feature and MTE2 is enabled at ELX.
+   This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_PAN``: Numeric value to enable the ``FEAT_PAN`` (Privileged
    Access Never) extension. ``FEAT_PAN`` adds a bit to PSTATE, generating a
    permission fault for any privileged data access from EL1/EL2 to virtual
    memory address, accessible at EL0, provided (HCR_EL2.E2H=1). It is a
    mandatory architectural feature and is enabled from v8.1 and upwards. This
-   flag can take values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   flag can take values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_RNG``: Numeric value to enable the ``FEAT_RNG`` extension.
    ``FEAT_RNG`` is an optional feature available on Arm v8.5 onwards. This
-   flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+   flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_RNG_TRAP``: Numeric value to enable the ``FEAT_RNG_TRAP``
    extension. This feature is only supported in AArch64 state. This flag can
-   take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+   take values 0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``. ``FEAT_RNG_TRAP`` is an optional feature from
    Armv8.5 onwards.
 
@@ -342,13 +404,13 @@ Common build options
 
 -  ``ENABLE_FEAT_SEL2``: Numeric value to enable the ``FEAT_SEL2`` (Secure EL2)
    extension. ``FEAT_SEL2`` is a mandatory feature available on Arm v8.4.
-   This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
+   This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. Default is ``0``.
 
 -  ``ENABLE_FEAT_TWED``: Numeric value to enable the ``FEAT_TWED`` (Delayed
    trapping of WFE Instruction) extension. ``FEAT_TWED`` is a optional feature
    available on Arm v8.6. This flag can take values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. Default is ``0``.
+   ``ENABLE_FEAT`` mechanism. Default is ``0``.
 
     When ``ENABLE_FEAT_TWED`` is set to ``1``, WFE instruction trapping gets
     delayed by the amount of value in ``TWED_DELAY``.
@@ -357,42 +419,67 @@ Common build options
    Host Extensions) extension. It allows access to CONTEXTIDR_EL2 register
    during EL2 context save/restore operations.``FEAT_VHE`` is a mandatory
    architectural feature and is enabled from v8.1 and upwards. It can take
-   values 0 to 2, to align  with the ``FEATURE_DETECTION`` mechanism.
+   values 0 to 2, to align  with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``.
 
 -  ``ENABLE_FEAT_TCR2``: Numeric value to set the bit SCR_EL3.ENTCR2 in EL3 to
    allow access to TCR2_EL2 (extended translation control) from EL2 as
    well as adding TCR2_EL2 to the EL2 context save/restore operations. Its a
    mandatory architectural feature and is enabled from v8.9 and upwards. This
-   flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_S2PIE``: Numeric value to enable support for FEAT_S2PIE
    at EL2 and below, and context switch relevant registers.  This flag
-   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_S1PIE``: Numeric value to enable support for FEAT_S1PIE
    at EL2 and below, and context switch relevant registers.  This flag
-   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_S2POE``: Numeric value to enable support for FEAT_S2POE
    at EL2 and below, and context switch relevant registers.  This flag
-   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_S1POE``: Numeric value to enable support for FEAT_S1POE
    at EL2 and below, and context switch relevant registers.  This flag
-   can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_GCS``: Numeric value to set the bit SCR_EL3.GCSEn in EL3 to
    allow use of Guarded Control Stack from EL2 as well as adding the GCS
    registers to the EL2 context save/restore operations. This flag can take
-   the values 0 to 2, to align  with the ``FEATURE_DETECTION`` mechanism.
+   the values 0 to 2, to align  with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``.
 
+-  ``ENABLE_FEAT_THE``: Numeric value to enable support for FEAT_THE
+   (Translation Hardening Extension) at EL2 and below, setting the bit
+   SCR_EL3.RCWMASKEn in EL3 to allow access to RCWMASK_EL1 and RCWSMASK_EL1
+   registers and context switch them.
+   Its an optional architectural feature and is available from v8.8 and upwards.
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_SCTLR2``: Numeric value to enable support for FEAT_SCTLR2
+   (Extension to SCTLR_ELx) at EL2 and below, setting the bit
+   SCR_EL3.SCTLR2En in EL3 to allow access to SCTLR2_ELx registers and
+   context switch them. This feature is OPTIONAL from Armv8.0 implementations
+   and mandatory in Armv8.9 implementations.
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_D128``: Numeric value to enable support for FEAT_D128
+   at EL2 and below, setting the bit SCT_EL3.D128En in EL3 to allow access to
+   128 bit version of system registers like PAR_EL1, TTBR0_EL1, TTBR1_EL1,
+   TTBR0_EL2, TTBR1_EL2, TTBR0_EL12, TTBR1_EL12 , VTTBR_EL2, RCWMASK_EL1, and
+   RCWSMASK_EL1. Its an optional architectural feature and is available from
+   9.3 and upwards.
+   This flag can take the values 0 to 2, to align  with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
    support in GCC for TF-A. This option is currently only supported for
    AArch64. Default is 0.
@@ -403,7 +490,7 @@ Common build options
    various ELs can assign themselves to desired partition to control their
    performance aspects.
 
-   This flag can take values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   This flag can take values 0 to 2, to align  with the ``ENABLE_FEAT``
    mechanism. When this option is set to ``1`` or ``2``, EL3 allows lower ELs to
    access their own MPAM registers without trapping into EL3. This option
    doesn't make use of partitioning in EL3, however. Platform initialisation
@@ -412,6 +499,11 @@ Common build options
    The flag is automatically disabled when the target
    architecture is AArch32.
 
+-  ``ENABLE_FEAT_LS64_ACCDATA``: Numeric value to enable access and save and
+   restore the ACCDATA_EL1 system register, at EL2 and below. This flag can
+   take the values 0 to 2, to align  with the ``ENABLE_FEAT`` mechanism.
+   Default value is ``0``.
+
 -  ``ENABLE_MPMM``: Boolean option to enable support for the Maximum Power
    Mitigation Mechanism supported by certain Arm cores, which allows the SoC
    firmware to detect and limit high activity events to assist in SoC processor
@@ -444,27 +536,32 @@ Common build options
 
 -  ``ENABLE_SPE_FOR_NS`` : Numeric value to enable Statistical Profiling
    extensions. This is an optional architectural feature for AArch64.
-   This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+   This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. The default is 2 but is automatically disabled when the target
    architecture is AArch32.
 
 -  ``ENABLE_SVE_FOR_NS``: Numeric value to enable Scalable Vector Extension
    (SVE) for the Non-secure world only. SVE is an optional architectural feature
-   for AArch64. Note that when SVE is enabled for the Non-secure world, access
-   to SIMD and floating-point functionality from the Secure world is disabled by
-   default and controlled with ENABLE_SVE_FOR_SWD.
-   This is to avoid corruption of the Non-secure world data in the Z-registers
-   which are aliased by the SIMD and FP registers. The build option is not
-   compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
-   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS``
-   enabled.  This flag can take the values 0 to 2, to align with the
-   ``FEATURE_DETECTION`` mechanism. At this time, this build option cannot be
-   used on systems that have SPM_MM enabled. The default is 1.
-
--  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world.
-   SVE is an optional architectural feature for AArch64. Note that this option
-   requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it is
-   automatically disabled when the target architecture is AArch32.
+   for AArch64. This flag can take the values 0 to 2, to align with the
+   ``ENABLE_FEAT`` mechanism. At this time, this build option cannot be used on
+   systems that have SPM_MM enabled. The default value is 2.
+
+   Note that when SVE is enabled for the Non-secure world, access
+   to SVE, SIMD and floating-point functionality from the Secure world is
+   independently controlled by build option ``ENABLE_SVE_FOR_SWD``. When enabling
+   ``CTX_INCLUDE_FPREGS`` and ``ENABLE_SVE_FOR_NS`` together, it is mandatory to
+   enable ``CTX_INCLUDE_SVE_REGS``. This is to avoid corruption of the Non-secure
+   world data in the Z-registers which are aliased by the SIMD and FP registers.
+
+-  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE and FPU/SIMD functionality
+   for the Secure world. SVE is an optional architectural feature for AArch64.
+   The default is 0 and it is automatically disabled when the target architecture
+   is AArch32.
+
+   .. note::
+      This build flag requires ``ENABLE_SVE_FOR_NS`` to be enabled. When enabling
+      ``ENABLE_SVE_FOR_SWD``, a developer must carefully consider whether
+      ``CTX_INCLUDE_SVE_REGS`` is also needed.
 
 -  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
    checks in GCC. Allowed values are "all", "strong", "default" and "none". The
@@ -671,6 +768,19 @@ Common build options
 
       MARCH_DIRECTIVE := -march=armv8.5-a
 
+-  ``HARDEN_SLS``: used to pass -mharden-sls=all from the TF-A build
+   options to the compiler currently supporting only of the options.
+   GCC documentation:
+   https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html#index-mharden-sls
+
+   An example usage:
+
+   .. code:: make
+
+      HARDEN_SLS := 1
+
+   This option defaults to 0.
+
 -  ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
    specifies a file that contains the Non-Trusted World private key in PEM
    format or a PKCS11 URI. If ``SAVE_KEYS=1``, only a file is accepted and it
@@ -685,10 +795,6 @@ Common build options
    1 (do save and restore). 0 is the default. An SPD may set this to 1 if it
    wants the timer registers to be saved and restored.
 
--  ``OPTEE_SP_FW_CONFIG``: DTC build flag to include OP-TEE as SP in
-   tb_fw_config device tree. This flag is defined only when
-   ``ARM_SPMC_MANIFEST_DTS`` manifest file name contains pattern optee_sp.
-
 -  ``OVERRIDE_LIBC``: This option allows platforms to override the default libc
    for the BL image. It can be either 0 (include) or 1 (remove). The default
    value is 0.
@@ -704,12 +810,22 @@ Common build options
    platform makefile named ``platform.mk``. For example, to build TF-A for the
    Arm Juno board, select PLAT=juno.
 
+-  ``PLATFORM_REPORT_CTX_MEM_USE``: Reports the context memory allocated for
+   each core as well as the global context. The data includes the memory used
+   by each world and each privileged exception level. This build option is
+   applicable only for ``ARCH=aarch64`` builds. The default value is 0.
+
 -  ``PRELOADED_BL33_BASE``: This option enables booting a preloaded BL33 image
    instead of the normal boot flow. When defined, it must specify the entry
    point address for the preloaded BL33 image. This option is incompatible with
    ``EL3_PAYLOAD_BASE``. If both are defined, ``EL3_PAYLOAD_BASE`` has priority
    over ``PRELOADED_BL33_BASE``.
 
+-  ``PRESERVE_DSU_PMU_REGS``: This options when enabled allows the platform to
+   save/restore the DynamIQ Shared Unit's(DSU) Performance Monitoring Unit(PMU)
+   registers when the cluster goes through a power cycle. This is disabled by
+   default and platforms that require this feature have to enable them.
+
 -  ``PROGRAMMABLE_RESET_ADDRESS``: This option indicates whether the reset
    vector address can be programmed or is fixed on the platform. It can take
    either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a
@@ -749,6 +865,21 @@ Common build options
    instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
    entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
 
+-  ``RME_GPT_BITLOCK_BLOCK``: This defines the block size (in number of 512MB
+-  blocks) covered by a single bit of the bitlock structure during RME GPT
+-  operations. The lower the block size, the better opportunity for
+-  parallelising GPT operations but at the cost of more bits being needed
+-  for the bitlock structure. This numeric parameter can take the values
+-  from 0 to 512 and must be a power of 2. The value of 0 is special and
+-  and it chooses a single spinlock for all GPT L1 table entries. Default
+-  value is 1 which corresponds to block size of 512MB per bit of bitlock
+-  structure.
+
+-  ``RME_GPT_MAX_BLOCK``: Numeric value in MB to define the maximum size of
+   supported contiguous blocks in GPT Library. This parameter can take the
+   values 0, 2, 32 and 512. Setting this value to 0 disables use of Contigious
+   descriptors. Default value is 512.
+
 -  ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a
    file that contains the ROT private key in PEM format or a PKCS11 URI and
    enforces public key hash generation. If ``SAVE_KEYS=1``, only a file is
@@ -796,6 +927,11 @@ Common build options
    flag is disabled by default and NOLOAD sections are placed in RAM immediately
    following the loaded firmware image.
 
+-  ``SEPARATE_SIMD_SECTION``: Setting this option to ``1`` allows the SIMD context
+    data structures to be put in a dedicated memory region as decided by platform
+    integrator. Default value is ``0`` which means the SIMD context is put in BSS
+    section of EL3 firmware.
+
 -  ``SMC_PCI_SUPPORT``: This option allows platforms to handle PCI configuration
    access requests via a standard SMCCC defined in `DEN0115`_. When combined with
    UEFI+ACPI this can provide a certain amount of OS forward compatibility
@@ -1056,31 +1192,26 @@ Common build options
 - ``ENABLE_BRBE_FOR_NS``: Numeric value to enable access to the branch record
   buffer registers from NS ELs when FEAT_BRBE is implemented. BRBE is an
   optional architectural feature for AArch64. This flag can take the values
-  0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. The default is 0
+  0 to 2, to align with the ``ENABLE_FEAT`` mechanism. The default is 0
   and it is automatically disabled when the target architecture is AArch32.
 
 - ``ENABLE_TRBE_FOR_NS``: Numeric value to enable access of trace buffer
   control registers from NS ELs, NS-EL2 or NS-EL1(when NS-EL2 is implemented
   but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural
   feature for AArch64. This flag can take the values  0 to 2, to align with the
-  ``FEATURE_DETECTION`` mechanism. The default is 0 and it is automatically
+  ``ENABLE_FEAT`` mechanism. The default is 0 and it is automatically
   disabled when the target architecture is AArch32.
 
 - ``ENABLE_SYS_REG_TRACE_FOR_NS``: Numeric value to enable trace system
   registers access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented
   but unused). This feature is available if trace unit such as ETMv4.x, and
   ETE(extending ETM feature) is implemented. This flag can take the values
-  0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. The default is 0.
+  0 to 2, to align with the ``ENABLE_FEAT`` mechanism. The default is 0.
 
 - ``ENABLE_TRF_FOR_NS``: Numeric value to enable trace filter control registers
   access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused),
   if FEAT_TRF is implemented. This flag can take the values 0 to 2, to align
-  with the ``FEATURE_DETECTION`` mechanism. This flag is disabled by default.
-
-- ``PLAT_RSS_NOT_SUPPORTED``: Boolean option to enable the usage of the PSA
-  APIs on platforms that doesn't support RSS (providing Arm CCA HES
-  functionalities). When enabled (``1``), a mocked version of the APIs are used.
-  The default value is 0.
+  with the ``ENABLE_FEAT`` mechanism. This flag is disabled by default.
 
 - ``CONDITIONAL_CMO``: Boolean option to enable call to platform-defined routine
   ``plat_can_cmo`` which will return zero if cache management operations should
@@ -1199,6 +1330,13 @@ Experimental build options
 Common build options
 ~~~~~~~~~~~~~~~~~~~~
 
+-  ``DICE_PROTECTION_ENVIRONMENT``: Boolean flag to specify the measured boot
+   backend when ``MEASURED_BOOT`` is enabled. The default value is ``0``. When
+   set to ``1`` then measurements and additional metadata collected during the
+   measured boot process are sent to the DICE Protection Environment for storage
+   and processing. A certificate chain, which represents the boot state of the
+   device, can be queried from the DPE.
+
 -  ``DRTM_SUPPORT``: Boolean flag to enable support for Dynamic Root of Trust
    for Measurement (DRTM). This feature has trust dependency on BL31 for taking
    the measurements and recording them as per `PSA DRTM specification`_. For
@@ -1208,7 +1346,14 @@ Common build options
 
 -  ``ENABLE_RME``: Numeric value to enable support for the ARMv9 Realm
    Management Extension. This flag can take the values 0 to 2, to align with
-   the ``FEATURE_DETECTION`` mechanism. Default value is 0.
+   the ``ENABLE_FEAT`` mechanism. Default value is 0.
+
+-  ``RMMD_ENABLE_EL3_TOKEN_SIGN``: Numeric value to enable support for singing
+   realm attestation token signing requests in EL3. This flag can take the
+   values 0 and 1. The default value is ``0``. When set to ``1``, this option
+   enables additional RMMD SMCs to push and pop requests for signing to
+   EL3 along with platform hooks that must be implemented to service those
+   requests and responses.
 
 -  ``ENABLE_SME_FOR_NS``: Numeric value to enable Scalable Matrix Extension
    (SME), SVE, and FPU/SIMD for the non-secure world only. These features share
@@ -1218,7 +1363,7 @@ Common build options
    superset of SVE. SME is an optional architectural feature for AArch64.
    At this time, this build option cannot be used on systems that have
    SPD=spmd/SPM_MM and atempting to build with this option will fail.
-   This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+   This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
    mechanism. Default is 0.
 
 -  ``ENABLE_SME2_FOR_NS``: Numeric value to enable Scalable Matrix Extension
@@ -1226,7 +1371,7 @@ Common build options
    architectural feature for AArch64.
    This should be set along with ENABLE_SME_FOR_NS=1, if not, the default SME
    accesses will still be trapped. This flag can take the values 0 to 2, to
-   align with the ``FEATURE_DETECTION`` mechanism. Default is 0.
+   align with the ``ENABLE_FEAT`` mechanism. Default is 0.
 
 -  ``ENABLE_SME_FOR_SWD``: Boolean option to enable the Scalable Matrix
    Extension for secure world. Used along with SVE and FPU/SIMD.
@@ -1240,41 +1385,16 @@ Common build options
    must not be used if ``SPMC_AT_EL3`` is enabled.
 
 -  ``FEATURE_DETECTION``: Boolean option to enable the architectural features
-   detection mechanism. It detects whether the Architectural features enabled
-   through feature specific build flags are supported by the PE or not by
-   validating them either at boot phase or at runtime based on the value
-   possessed by the feature flag (0 to 2) and report error messages at an early
-   stage. This flag will also enable errata ordering checking for ``DEBUG``
-   builds.
-
-   This prevents and benefits us from EL3 runtime exceptions during context save
-   and restore routines guarded by these build flags. Henceforth validating them
-   before their usage provides more control on the actions taken under them.
-
-   The mechanism permits the build flags to take values 0, 1 or 2 and
-   evaluates them accordingly.
-
-   Lets consider ``ENABLE_FEAT_HCX``, build flag for ``FEAT_HCX`` as an example:
-
-   ::
-
-     ENABLE_FEAT_HCX = 0: Feature disabled statically at compile time.
-     ENABLE_FEAT_HCX = 1: Feature Enabled and the flag is validated at boottime.
-     ENABLE_FEAT_HCX = 2: Feature Enabled and the flag is validated at runtime.
-
-   In the above example, if the feature build flag, ``ENABLE_FEAT_HCX`` set to
-   0, feature is disabled statically during compilation. If it is defined as 1,
-   feature is validated, wherein FEAT_HCX is detected at boot time. In case not
-   implemented by the PE, a hard panic is generated. Finally, if the flag is set
-   to 2, feature is validated at runtime.
+   verification mechanism. This is a debug feature that compares the
+   architectural features enabled through the feature specific build flags
+   (ENABLE_FEAT_xxx) with the features actually available on the CPU running,
+   and reports any discrepancies.
+   This flag will also enable errata ordering checking for ``DEBUG`` builds.
 
-   Note that the entire implementation is divided into two phases, wherein as
-   as part of phase-1 we are supporting the values 0,1. Value 2 is currently not
-   supported and is planned to be handled explicilty in phase-2 implementation.
-
-   ``FEATURE_DETECTION`` macro is disabled by default. Platforms can explicitly
-   make use of this by mechanism, by enabling it to validate whether they have
-   set their build flags properly at an early phase.
+   It is expected that this feature is only used for flexible platforms like
+   software emulators, or for hardware platforms at bringup time, to verify
+   that the configured feature set matches the CPU.
+   The ``FEATURE_DETECTION`` macro is disabled by default.
 
 -  ``PSA_CRYPTO``: Boolean option for enabling MbedTLS PSA crypto APIs support.
    The platform will use PSA compliant Crypto APIs during authentication and
@@ -1314,12 +1434,21 @@ Firmware update options
    This flag is used in defining the firmware update metadata structure. This
    flag is by default set to '1'.
 
+- ``PSA_FWU_METADATA_FW_STORE_DESC``: To be enabled when the FWU
+   metadata contains image description. The default value is 1.
+
+   The version 2 of the FWU metadata allows for an opaque metadata
+   structure where a platform can choose to not include the firmware
+   store description in the metadata structure. This option indicates
+   if the firmware store description, which provides information on
+   the updatable images is part of the structure.
+
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
 
 .. _DEN0115: https://developer.arm.com/docs/den0115/latest
-.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/latest/
 .. _PSA DRTM specification: https://developer.arm.com/documentation/den0113/a
 .. _GCC: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
 .. _Clang: https://clang.llvm.org/docs/DiagnosticsReference.html
diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst
index 50fff575..54e29dd5 100644
--- a/docs/getting_started/docs-build.rst
+++ b/docs/getting_started/docs-build.rst
@@ -37,25 +37,8 @@ Ubuntu):
 Building rendered documentation
 -------------------------------
 
-To install Python dependencies using Poetry:
-
-.. code:: shell
-
-    poetry install
-
-Poetry will create a new virtual environment and install all dependencies listed
-in ``pyproject.toml``. You can get information about this environment, such as
-its location and the Python version, with the command:
-
-.. code:: shell
-
-    poetry env info
-
-If you have already sourced a virtual environment, Poetry will respect this and
-install dependencies there.
-
-Once all dependencies are installed, the documentation can be compiled into
-HTML-formatted pages from the project root directory by running:
+The documentation can be compiled into HTML-formatted pages from the project
+root directory by running:
 
 .. code:: shell
 
@@ -129,7 +112,7 @@ from project root directory
         bash -c 'cd /tf-a &&
             apt-get update && apt-get install -y curl plantuml &&
             curl -sSL https://install.python-poetry.org | python3 - &&
-            ~/.local/bin/poetry install && ~/.local/bin/poetry run make doc'
+            ~/.local/bin/poetry run make doc'
 
 The above command fetches the ``sphinxdoc/sphinx`` container from `docker
 hub`_, launches the container, installs documentation requirements and finally
@@ -138,7 +121,7 @@ build process will be placed in: ``docs/build/html``.
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
 
 .. _Sphinx: http://www.sphinx-doc.org/en/master/
 .. _Poetry: https://python-poetry.org/docs/
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 573abdfe..c414b1f2 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -8,33 +8,53 @@ It may possible to build |TF-A| with combinations of software packages that are
 different from those listed below, however only the software described in this
 document can be officially supported.
 
-Build Host
-----------
+Getting the TF-A Source
+-----------------------
 
-|TF-A| can be built using either a Linux or a Windows machine as the build host.
+Source code for |TF-A| is maintained in a Git repository hosted on
+`TrustedFirmware.org`_. To clone this repository from the server, run the following
+in your shell:
 
-A relatively recent Linux distribution is recommended for building |TF-A|. We
-have performed tests using Ubuntu 22.04 LTS (64-bit) but other distributions
-should also work fine as a base, provided that the necessary tools and libraries
-can be installed.
+.. code:: shell
 
-.. _prerequisites_toolchain:
+    git clone "https://review.trustedfirmware.org/TF-A/trusted-firmware-a"
 
-Toolchain
----------
 
-|TF-A| can be built with any of the following *cross-compiler* toolchains that
-target the Armv7-A or Armv8-A architectures:
+Requirements
+------------
+
+======================== =====================
+        Program          Min supported version
+======================== =====================
+Arm Compiler             6.18
+Arm GNU Compiler         13.3
+Clang/LLVM               18.1.8
+Device Tree Compiler     1.6.1
+GNU make                 3.81
+mbed TLS\ [#f1]_         3.6.1
+Node.js [#f2]_           16
+OpenSSL                  1.0.0
+Poetry                   1.3.2
+QCBOR\ [#f3]_            1.2
+Sphinx\ [#f2]_           5.3.0
+======================== =====================
+
+.. [#f1] Required for Trusted Board Boot and Measured Boot.
+.. [#f2] Required only for building TF-A documentation.
+.. [#f3] Required only when enabling DICE Protection Environment support.
 
-- TF-A has been tested with version 12.3.Rel1 (gcc 12.3) from the `Arm Developer website`_
+Toolchain
+^^^^^^^^^
 
-   You will need the targets ``arm-none-eabi`` and ``aarch64-none-elf`` for
-   AArch32 and AArch64 builds respectively.
+|TF-A| can be compiled using any cross-compiler toolchain specified in the
+preceding table that target Armv7-A or Armv8-A. For AArch32 and
+AArch64 builds, the respective targets required are ``arm-none-eabi`` and
+``aarch64-none-elf``.
 
-- Clang == 14.0.0
-- Arm Compiler == 6.18
+Testing has been performed with version 13.3.Rel1 (gcc 13.3) of the Arm
+GNU compiler, which can be installed from the `Arm Developer website`_.
 
-In addition, a native compiler is required to build the supporting tools.
+In addition, a native compiler is required to build supporting tools.
 
 .. note::
    Versions greater than the ones specified are likely but not guaranteed to
@@ -42,78 +62,69 @@ In addition, a native compiler is required to build the supporting tools.
    which may be older than the version expected by the compiler. Fixes and bug
    reports are always welcome.
 
-.. note::
-   The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
-   Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain.
-
 .. note::
    For instructions on how to select the cross compiler refer to
    :ref:`Performing an Initial Build`.
 
-.. _prerequisites_software_and_libraries:
-
-Software and Libraries
-----------------------
-
-The following tools are required to obtain and build |TF-A|:
-
-- An appropriate toolchain (see :ref:`prerequisites_toolchain`)
-- GNU Make
-- Git
+OpenSSL
+^^^^^^^
 
-The following libraries must be available to build one or more components or
-supporting tools:
+OpenSSL is required to build the cert_create, encrypt_fw, and fiptool tools.
 
-- OpenSSL >= 1.1.1 (v3.0.0 to v3.0.6 highly discouraged due to security issues)
+If using OpenSSL 3, older Linux versions may require it to be built from
+source code, as it may not be available in the default package repositories.
+Please refer to the OpenSSL project documentation for more information.
 
-   Required to build the cert_create, encrypt_fw, and fiptool tools.
+.. warning::
+    Versions 1.0.x and from v3.0.0 up to v3.0.6 are strongly advised against due
+    to concerns regarding security vulnerabilities!
 
-   .. note::
+Device Tree Compiler (DTC)
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-    If using OpenSSL 3, older Linux versions may require it to be built from
-    source code, as it may not be available in the default package repositories.
-    Please refer to the OpenSSL project documentation for more information.
+Needed if you want to rebuild the provided Flattened Device Tree (FDT)
+source files (``.dts`` files). DTC is available for Linux through the package
+repositories of most distributions.
 
-The following libraries are required for Trusted Board Boot and Measured Boot
-support:
+Arm Development Studio (`Arm-DS`_)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- mbed TLS == 3.4.1 (tag: ``mbedtls-3.4.1``)
+The standard software package used for debugging software on Arm development
+platforms and |FVP| models.
 
-These tools are optional:
+Node.js
+^^^^^^^
 
-- Device Tree Compiler (DTC) >= 1.4.7
+Highly recommended, and necessary in order to install and use the packaged
+Git hooks and helper tools. Without these tools you will need to rely on the
+CI for feedback on commit message conformance.
 
-   Needed if you want to rebuild the provided Flattened Device Tree (FDT)
-   source files (``.dts`` files). DTC is available for Linux through the package
-   repositories of most distributions.
+Poetry
+^^^^^^
 
-- Arm `Development Studio (Arm-DS)`_
+Required for managing Python dependencies, this will allow you to reliably
+reproduce a Python environment to build documentation and run some of the
+integrated Python tools. Most importantly, it ensures your system environment
+will not be affected by dependencies in the Python scripts.
 
-   The standard software package used for debugging software on Arm development
-   platforms and |FVP| models.
+For installation instructions, see the `official Poetry documentation`_.
 
-- Node.js >= 16
-
-   Highly recommended, and necessary in order to install and use the packaged
-   Git hooks and helper tools. Without these tools you will need to rely on the
-   CI for feedback on commit message conformance.
+.. _prerequisites_software_and_libraries:
 
-- Poetry >= 1.3.2
+Package Installation (Linux)
+----------------------------
 
-   Required for managing Python dependencies, this will allow you to reliably
-   reproduce a Python environment to build documentation and run analysis tools.
-   Most importantly, it ensures your system environment will not be affected by
-   dependencies in the Python scripts.
+|TF-A| can be compiled on both Linux and Windows-based machines.
+However, we strongly recommend using a UNIX-compatible build environment.
 
-Package Installation (Linux)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Testing is performed using Ubuntu 22.04 LTS (64-bit), but other distributions
+should also work, provided the necessary tools and libraries are installed.
 
-If you are using the recommended Ubuntu distribution then you can install the
-required packages with the following command:
+The following are steps to install the required packages:
 
 .. code:: shell
 
-    sudo apt install build-essential git
+    sudo apt install build-essential
 
 The optional packages can be installed using:
 
@@ -142,17 +153,6 @@ instructions in :ref:`Performing an Initial Build`.
 
 .. _prerequisites_get_source:
 
-Getting the TF-A Source
------------------------
-
-Source code for |TF-A| is maintained in a Git repository hosted on
-TrustedFirmware.org. To clone this repository from the server, run the following
-in your shell:
-
-.. code:: shell
-
-    git clone "https://review.trustedfirmware.org/TF-A/trusted-firmware-a"
-
 Additional Steps for Contributors
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -184,11 +184,13 @@ documentation, available `here <https://git-scm.com/docs/githooks>`_.
 
 --------------
 
-*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
 
 .. _Arm Developer website: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
 .. _Gerrit Code Review: https://www.gerritcodereview.com/
 .. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes
 .. _Linaro instructions: https://community.arm.com/dev-platforms/w/docs/304/arm-reference-platforms-deliverables
-.. _Development Studio (Arm-DS): https://developer.arm.com/Tools%20and%20Software/Arm%20Development%20Studio
+.. _Arm-DS: https://developer.arm.com/Tools%20and%20Software/Arm%20Development%20Studio
 .. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
+.. _TrustedFirmware.org: https://www.trustedfirmware.org/
+.. _official Poetry documentation: https://python-poetry.org/docs/#installation
diff --git a/docs/getting_started/rt-svc-writers-guide.rst b/docs/getting_started/rt-svc-writers-guide.rst
index fe645588..4d4ec22f 100644
--- a/docs/getting_started/rt-svc-writers-guide.rst
+++ b/docs/getting_started/rt-svc-writers-guide.rst
@@ -49,8 +49,11 @@ legacy 32-bit software that predates the `SMCCC`_.
     Fast        1      CPU Service calls
     Fast        2      SiP Service calls
     Fast        3      OEM Service calls
-    Fast        4      Standard Service calls
-    Fast       5-47    Reserved for future use
+    Fast        4      Standard Secure Service calls
+    Fast        5      Standard Hypervisor Service Calls
+    Fast        6      Vendor Specific Hypervisor Service Calls
+    Fast        7      Vendor Specific EL3 Monitor Calls
+    Fast       8-47    Reserved for future use
     Fast      48-49    Trusted Application calls
     Fast      50-63    Trusted OS calls
 
@@ -312,9 +315,17 @@ TODO: Provide details of the additional work required to implement a SPD and
 the BL31 support for these services. Or a reference to the document that will
 provide this information....
 
+Additional References:
+----------------------
+
+#. :ref:`ARM SiP Services <arm sip services>`
+#. :ref:`Vendor Specific EL3 Monitor Service Calls`
+
 --------------
 
-*Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _SMCCC: https://developer.arm.com/docs/den0028/latest
 .. _PSCI: https://developer.arm.com/documentation/den0022/latest/
+.. _ARM SiP Services: arm-sip-service.rst
+.. _Vendor Specific EL3 Monitor Service Calls: ven-el3-service.rst
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 80012e7b..23a91cdc 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -8,6 +8,8 @@
 .. |COT| replace:: :term:`COT`
 .. |CSS| replace:: :term:`CSS`
 .. |CVE| replace:: :term:`CVE`
+.. |DICE| replace:: :term:`DICE`
+.. |DPE| replace:: :term:`DPE`
 .. |DTB| replace:: :term:`DTB`
 .. |DS-5| replace:: :term:`DS-5`
 .. |DSU| replace:: :term:`DSU`
@@ -21,6 +23,7 @@
 .. |FVP| replace:: :term:`FVP`
 .. |FWU| replace:: :term:`FWU`
 .. |GIC| replace:: :term:`GIC`
+.. |HES| replace:: :term:`HES`
 .. |ISA| replace:: :term:`ISA`
 .. |Linaro| replace:: :term:`Linaro`
 .. |MMU| replace:: :term:`MMU`
@@ -31,12 +34,14 @@
 .. |OEN| replace:: :term:`OEN`
 .. |OP-TEE| replace:: :term:`OP-TEE`
 .. |OTE| replace:: :term:`OTE`
+.. |PCR| replace:: :term:`PCR`
 .. |PDD| replace:: :term:`PDD`
 .. |PAUTH| replace:: :term:`PAUTH`
 .. |PMF| replace:: :term:`PMF`
 .. |PSCI| replace:: :term:`PSCI`
 .. |RAS| replace:: :term:`RAS`
 .. |ROT| replace:: :term:`ROT`
+.. |RSE| replace:: :term:`RSE`
 .. |SCMI| replace:: :term:`SCMI`
 .. |SCP| replace:: :term:`SCP`
 .. |SDEI| replace:: :term:`SDEI`
@@ -55,6 +60,7 @@
 .. |SVE| replace:: :term:`SVE`
 .. |TBB| replace:: :term:`TBB`
 .. |TBBR| replace:: :term:`TBBR`
+.. |TCB| replace:: :term:`TCB`
 .. |TCG| replace:: :term:`TCG`
 .. |TEE| replace:: :term:`TEE`
 .. |TF-A| replace:: :term:`TF-A`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 58b7d999..f19897c7 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -40,6 +40,9 @@ You can find additional definitions in the `Arm Glossary`_.
       Common Vulnerabilities and Exposures. A CVE document is commonly used to
       describe a publicly-known security vulnerability.
 
+   DICE
+      Device Identifier Composition Engine
+
    DCE
       DRTM Configuration Environment
 
@@ -52,6 +55,9 @@ You can find additional definitions in the `Arm Glossary`_.
    DRTM
       Dynamic Root of Trust for Measurement
 
+   DPE
+      DICE Protection Environment
+
    DS-5
       Arm Development Studio 5
 
@@ -94,6 +100,9 @@ You can find additional definitions in the `Arm Glossary`_.
    GIC
       Generic Interrupt Controller
 
+   HES
+      Arm CCA Hardware Enforced Security
+
    ISA
       Instruction Set Architecture
 
@@ -130,6 +139,9 @@ You can find additional definitions in the `Arm Glossary`_.
    OTE
       Open-source Trusted Execution Environment
 
+   PCR
+      Platform Configuration Register
+
    PDD
       Platform Design Document
 
@@ -142,6 +154,9 @@ You can find additional definitions in the `Arm Glossary`_.
    PSA
       Platform Security Architecture
 
+   PSR
+     Platform Security Requirements
+
    PSCI
       Power State Coordination Interface
 
@@ -153,6 +168,9 @@ You can find additional definitions in the `Arm Glossary`_.
    ROT
       Root of Trust
 
+   RSE
+      Runtime Security Engine
+
    SCMI
       System Control and Management Interface
 
diff --git a/docs/index.rst b/docs/index.rst
index a7a59935..c05c0a50 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -91,8 +91,8 @@ have previously been raised against the software.
 .. _Armv7-A and Armv8-A: https://developer.arm.com/products/architecture/a-profile
 .. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php
 .. _Power State Coordination Interface (PSCI): https://developer.arm.com/documentation/den0022/latest/
-.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT): https://developer.arm.com/docs/den0006/latest
 .. _System Control and Management Interface (SCMI): http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
 .. _Software Delegated Exception Interface (SDEI): http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
 .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
-.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
+.. _PSA FW update specification: https://developer.arm.com/documentation/den0118/latest/
diff --git a/docs/license.rst b/docs/license.rst
index 80f11186..9e0298b7 100644
--- a/docs/license.rst
+++ b/docs/license.rst
@@ -85,6 +85,35 @@ license text is included in those source files.
 
    See the original `Linux MIT license`_.
 
+-  Some source files originating from the `Open Profile for DICE`_ project.
+   These files are licensed under the Apache License, Version 2.0, which is a
+   permissive license compatible with BSD-3-Clause. Any contributions to this
+   code must also be made under the terms of `Apache License 2.0`_.
+   These files are:
+
+   -  ``include/lib/dice/dice.h``
+
+-  Some source files originating from the `pydevicetree`_ project.
+   These files are licensed under the Apache License, Version 2.0, which is a
+   permissive license compatible with BSD-3-Clause. Any contributions to this
+   code must also be made under the terms of `Apache License 2.0`_.
+   These files are:
+
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/__init__.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/directive.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/helpers.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/node.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/property.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/ast/reference.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/source/__init__.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/source/grammar.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/source/parser.py``
+   -  ``tools/cot_dt2c/cot_dt2c/pydevicetree/__init__.py``
+
+
 .. _FreeBSD: http://www.freebsd.org
 .. _Linux MIT license: https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/MIT
 .. _SCC: http://www.simple-cc.org/
+.. _Open Profile for DICE: https://pigweed.googlesource.com/open-dice/
+.. _Apache License 2.0: https://www.apache.org/licenses/LICENSE-2.0.txt
+.. _pydevicetree: https://pypi.org/project/pydevicetree/
diff --git a/docs/perf/psci-performance-juno.rst b/docs/perf/psci-performance-juno.rst
index bab10862..9640a242 100644
--- a/docs/perf/psci-performance-juno.rst
+++ b/docs/perf/psci-performance-juno.rst
@@ -31,8 +31,8 @@ timestamps, which runs at 50MHz on Juno.
 
 The following source trees and binaries were used:
 
-- TF-A [`v2.9-rc0`_]
-- TFTF [`v2.9-rc0`_]
+- `TF-A v2.12-rc0`_
+- `TFTF v2.12-rc0`_
 
 Please see the Runtime Instrumentation :ref:`Testing Methodology
 <Runtime Instrumentation Methodology>`
@@ -73,156 +73,158 @@ Results
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.9)
-
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   104.58  | 241.20 |     5.26    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   384.24  | 22.50  |    138.76   |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   244.56  | 22.18  |     5.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   670.56  | 18.58  |     4.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   809.36  | 269.28 |     4.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   984.96  | 219.70 |    79.62    |
-    +---------+------+-----------+--------+-------------+
+        parallel (v2.12)
+
+    +---------+------+-------------------+------------------+--------------------+
+    | Cluster | Core |     Powerdown     |      Wakeup      |    Cache Flush     |
+    +---------+------+-------------------+------------------+--------------------+
+    |    0    |  0   |  244.52 (-65.43%) | 26.92 (-32.60%)  |   5.54 (-96.70%)   |
+    +---------+------+-------------------+------------------+--------------------+
+    |    0    |  1   | 526.18 (+105.12%) |      416.1       | 138.52 (+2011.59%) |
+    +---------+------+-------------------+------------------+--------------------+
+    |    1    |  0   |       104.34      | 27.02 (-94.62%)  |        5.32        |
+    +---------+------+-------------------+------------------+--------------------+
+    |    1    |  1   |       384.98      | 23.06 (-85.40%)  |        4.48        |
+    +---------+------+-------------------+------------------+--------------------+
+    |    1    |  2   |  812.44 (+45.94%) |      126.78      |        4.54        |
+    +---------+------+-------------------+------------------+--------------------+
+    |    1    |  3   |       986.84      | 77.22 (+176.58%) |       79.76        |
+    +---------+------+-------------------+------------------+--------------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.10)
-
-    +---------+------+-------------------+--------+-------------+
-    | Cluster | Core |     Powerdown     | Wakeup | Cache Flush |
-    +---------+------+-------------------+--------+-------------+
-    |    0    |  0   | 242.66 (+132.03%) | 245.1  |     5.4     |
-    +---------+------+-------------------+--------+-------------+
-    |    0    |  1   |  522.08 (+35.87%) | 26.24  |    138.32   |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  0   |  104.36 (-57.33%) |  27.1  |     5.32    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  1   |  382.56 (-42.95%) | 23.34  |     4.42    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  2   |       807.74      | 271.54 |     4.64    |
-    +---------+------+-------------------+--------+-------------+
-    |    1    |  3   |       981.36      | 221.8  |    79.48    |
-    +---------+------+-------------------+--------+-------------+
+        parallel (v2.11)
+
+    +---------+------+-------------------+--------------------+-------------+
+    | Cluster | Core |     Powerdown     |       Wakeup       | Cache Flush |
+    +---------+------+-------------------+--------------------+-------------+
+    |    0    |  0   |  112.98 (-53.44%) |  26.16 (-89.33%)   |     5.48    |
+    +---------+------+-------------------+--------------------+-------------+
+    |    0    |  1   |       411.18      | 438.88 (+1572.56%) |    138.54   |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  0   | 261.82 (+150.88%) | 474.06 (+1649.30%) |     5.6     |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  1   |  714.76 (+86.84%) |       26.44        |     4.48    |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  2   |       862.66      |  149.34 (-45.00%)  |     4.38    |
+    +---------+------+-------------------+--------------------+-------------+
+    |    1    |  3   |      1045.12      |  98.12 (-55.76%)   |    79.74    |
+    +---------+------+-------------------+--------------------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.9)
-
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   236.56  | 23.24  |    138.18   |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   236.86  | 23.28  |    138.10   |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   281.04  | 22.80  |    77.24    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.28  | 18.52  |     4.54    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.12  | 18.78  |     4.50    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   100.36  | 18.94  |     4.44    |
-    +---------+------+-----------+--------+-------------+
+        serial (v2.12)
+
+    +---------+------+-----------+-----------------+-------------+
+    | Cluster | Core | Powerdown |      Wakeup     | Cache Flush |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  0   |   236.36  | 27.94 (-31.52%) |    138.0    |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  1   |   236.58  | 27.86 (-31.72%) |    138.2    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  0   |   280.68  |      27.02      |     77.6    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  1   |   101.4   |      22.52      |     4.42    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  2   |   100.92  |      22.68      |     4.4     |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  3   |   100.96  |      22.54      |     4.38    |
+    +---------+------+-----------+-----------------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.10)
+        serial (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   236.84  |  27.1  |    138.36   |
+    |    0    |  0   |   244.42  | 27.42  |    138.12   |
     +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   236.96  |  27.1  |    138.32   |
+    |    0    |  1   |   245.02  | 27.34  |    138.08   |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   280.06  | 26.94  |     77.5    |
+    |    1    |  0   |   297.66  |  26.2  |    77.68    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.76  | 23.42  |     4.36    |
+    |    1    |  1   |   108.02  | 21.94  |     4.52    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.02  | 23.42  |     4.44    |
+    |    1    |  2   |   107.48  | 21.88  |     4.46    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   100.08  |  23.2  |     4.4     |
+    |    1    |  3   |   107.52  | 21.86  |     4.46    |
     +---------+------+-----------+--------+-------------+
 
 ``CPU_SUSPEND`` to power level 0
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.9)
-
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   662.34  | 15.22  |     8.08    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   802.00  | 15.50  |     8.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   385.22  | 15.74  |     7.88    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   106.16  | 16.06  |     7.44    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   524.38  | 15.64  |     7.34    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   246.00  | 15.78  |     7.72    |
-    +---------+------+-----------+--------+-------------+
+        parallel (v2.12)
+
+    +--------------------------------------------------------------------+
+    |                  test_rt_instr_cpu_susp_parallel                   |
+    +---------+------+-------------------+-----------------+-------------+
+    | Cluster | Core |     Powerdown     |      Wakeup     | Cache Flush |
+    +---------+------+-------------------+-----------------+-------------+
+    |    0    |  0   |       663.12      | 19.66 (-39.21%) |     8.26    |
+    +---------+------+-------------------+-----------------+-------------+
+    |    0    |  1   |       804.18      | 19.24 (-40.65%) |     8.1     |
+    +---------+------+-------------------+-----------------+-------------+
+    |    1    |  0   |  105.58 (-58.80%) |      19.68      |     7.42    |
+    +---------+------+-------------------+-----------------+-------------+
+    |    1    |  1   |  245.02 (-39.67%) |       19.8      |     6.82    |
+    +---------+------+-------------------+-----------------+-------------+
+    |    1    |  2   |  383.82 (-30.83%) |      18.84      |     7.06    |
+    +---------+------+-------------------+-----------------+-------------+
+    |    1    |  3   | 523.36 (+391.23%) |       19.0      |     7.3     |
+    +---------+------+-------------------+-----------------+-------------+
 
 .. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.10)
+        parallel (v2.11)
 
     +---------+------+-------------------+--------+-------------+
     | Cluster | Core |     Powerdown     | Wakeup | Cache Flush |
     +---------+------+-------------------+--------+-------------+
-    |    0    |  0   |       801.04      | 18.66  |     8.22    |
+    |    0    |  0   |       704.46      | 19.28  |     7.86    |
     +---------+------+-------------------+--------+-------------+
-    |    0    |  1   |       661.28      | 19.08  |     7.88    |
+    |    0    |  1   |       853.66      | 18.78  |     7.82    |
     +---------+------+-------------------+--------+-------------+
-    |    1    |  0   |  105.9 (-72.51%)  |  20.3  |     7.58    |
+    |    1    |  0   | 556.52 (+425.51%) | 19.06  |     7.82    |
     +---------+------+-------------------+--------+-------------+
-    |    1    |  1   | 383.58 (+261.32%) |  20.4  |     7.42    |
+    |    1    |  1   |  113.28 (-70.47%) | 19.28  |     7.48    |
     +---------+------+-------------------+--------+-------------+
-    |    1    |  2   |       523.52      |  20.1  |     7.74    |
+    |    1    |  2   |  260.62 (-50.22%) |  19.8  |     7.26    |
     +---------+------+-------------------+--------+-------------+
-    |    1    |  3   |       244.5       | 20.16  |     7.56    |
+    |    1    |  3   |  408.16 (+66.94%) | 19.82  |     7.38    |
     +---------+------+-------------------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.12)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   99.80   | 15.94  |     5.42    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   99.76   | 15.80  |     5.24    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   278.26  | 16.16  |     4.58    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   96.88   | 16.00  |     4.52    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   96.80   | 16.12  |     4.54    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   96.88   | 16.12  |     4.54    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+-----------+-----------------+-------------+
+    | Cluster | Core | Powerdown |      Wakeup     | Cache Flush |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  0   |   100.04  | 20.32 (-38.50%) |     5.62    |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  1   |   99.78   |  20.6 (-36.10%) |     5.42    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  0   |   278.28  |      19.52      |     4.32    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  1   |    97.3   |      19.44      |     4.26    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  2   |   97.56   |      19.52      |     4.32    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  3   |   97.52   |      19.46      |     4.26    |
+    +---------+------+-----------+-----------------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.10)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   99.84   | 18.86  |     5.54    |
+    |    0    |  0   |   106.78  |  19.2  |     5.32    |
     +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   100.2   | 18.82  |     5.66    |
+    |    0    |  1   |   107.44  | 19.64  |     5.44    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   278.12  | 20.56  |     4.48    |
+    |    1    |  0   |   295.82  | 19.14  |     4.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   96.68   | 20.62  |     4.3     |
+    |    1    |  1   |   104.34  | 19.18  |     4.28    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   96.94   | 20.14  |     4.42    |
+    |    1    |  2   |   103.96  | 19.34  |     4.4     |
     +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   96.68   | 20.46  |     4.32    |
+    |    1    |  3   |   104.32  | 19.18  |     4.34    |
     +---------+------+-----------+--------+-------------+
 
 ``CPU_OFF`` on all non-lead CPUs
@@ -231,82 +233,80 @@ Results
 ``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
 core to the deepest power level.
 
-.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.9)
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.12)
 
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   235.76  | 26.14  |    137.80   |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   235.40  | 25.72  |    137.62   |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   174.70  | 22.40  |    77.26    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.92  | 24.04  |     4.52    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.68  | 22.44  |     4.36    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   101.36  | 22.70  |     4.52    |
-    +---------+------+-----------+--------+-------------+
+    +---------+------+-----------+-----------------+-------------+
+    | Cluster | Core | Powerdown |      Wakeup     | Cache Flush |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  0   |   236.3   | 30.88 (-29.30%) |    137.76   |
+    +---------+------+-----------+-----------------+-------------+
+    |    0    |  1   |   236.66  |  30.5 (-29.23%) |    138.02   |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  0   |   175.9   |       27.0      |    77.86    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  1   |   100.96  |      27.56      |     4.26    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  2   |   101.04  |      26.48      |     4.38    |
+    +---------+------+-----------+-----------------+-------------+
+    |    1    |  3   |   101.08  |      26.74      |     4.4     |
+    +---------+------+-----------+-----------------+-------------+
 
-.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.10)
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.11)
 
-    +---------------------------------------------------+
-    |       test_rt_instr_cpu_off_serial (latest)       |
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   236.04  | 30.02  |    137.9    |
+    |    0    |  0   |   243.62  | 29.84  |    137.66   |
     +---------+------+-----------+--------+-------------+
-    |    0    |  1   |   235.38  |  29.7  |    137.72   |
+    |    0    |  1   |   243.88  | 29.54  |    137.8    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   175.18  | 26.96  |    77.26    |
+    |    1    |  0   |   183.26  | 26.22  |    77.76    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  1   |   100.56  | 28.34  |     4.32    |
+    |    1    |  1   |   107.64  | 26.74  |     4.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  2   |   100.38  | 26.82  |     4.3     |
+    |    1    |  2   |   107.52  |  25.9  |     4.32    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  3   |   100.86  | 26.98  |     4.42    |
+    |    1    |  3   |   107.74  |  25.8  |     4.34    |
     +---------+------+-----------+--------+-------------+
 
 ``CPU_VERSION`` in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.9)
-
-    +-------------+--------+-------------+
-    |   Cluster   |  Core  |   Latency   |
-    +-------------+--------+-------------+
-    |      0      |   0    |     1.48    |
-    +-------------+--------+-------------+
-    |      0      |   1    |     1.04    |
-    +-------------+--------+-------------+
-    |      1      |   0    |     0.56    |
-    +-------------+--------+-------------+
-    |      1      |   1    |     0.92    |
-    +-------------+--------+-------------+
-    |      1      |   2    |     0.96    |
-    +-------------+--------+-------------+
-    |      1      |   3    |     0.96    |
-    +-------------+--------+-------------+
-
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.10)
-
-    +-------------+--------+----------------------+
-    |   Cluster   |  Core  |       Latency        |
-    +-------------+--------+----------------------+
-    |      0      |   0    |    1.1 (-25.68%)     |
-    +-------------+--------+----------------------+
-    |      0      |   1    |         1.06         |
-    +-------------+--------+----------------------+
-    |      1      |   0    |         0.58         |
-    +-------------+--------+----------------------+
-    |      1      |   1    |         0.88         |
-    +-------------+--------+----------------------+
-    |      1      |   2    |         0.92         |
-    +-------------+--------+----------------------+
-    |      1      |   3    |         0.9          |
-    +-------------+--------+----------------------+
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.12)
+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +-------------+--------+--------------+
+    |      0      |   0    |     1.0      |
+    +-------------+--------+--------------+
+    |      0      |   1    |     1.02     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.52     |
+    +-------------+--------+--------------+
+    |      1      |   1    |     0.94     |
+    +-------------+--------+--------------+
+    |      1      |   2    |     0.94     |
+    +-------------+--------+--------------+
+    |      1      |   3    |     0.92     |
+    +-------------+--------+--------------+
+
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (2.11)
+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +-------------+--------+--------------+
+    |      0      |   0    |     1.26     |
+    +-------------+--------+--------------+
+    |      0      |   1    |     0.96     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.54     |
+    +-------------+--------+--------------+
+    |      1      |   1    |     0.94     |
+    +-------------+--------+--------------+
+    |      1      |   2    |     0.92     |
+    +-------------+--------+--------------+
+    |      1      |   3    |     1.02     |
+    +-------------+--------+--------------+
 
 Annotated Historic Results
 --------------------------
@@ -526,8 +526,9 @@ effects, given that these measurements are at the nano-second level.
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _Juno R1 platform: https://developer.arm.com/documentation/100122/latest/
 .. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d
-.. _v2.9-rc0: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?h=v2.9-rc0
+.. _TF-A v2.12-rc0: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?h=v2.12-rc0
+.. _TFTF v2.12-rc0: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/tree/?h=v2.12-rc0
diff --git a/docs/perf/psci-performance-n1sdp.rst b/docs/perf/psci-performance-n1sdp.rst
index fd3c9c94..178d8e64 100644
--- a/docs/perf/psci-performance-n1sdp.rst
+++ b/docs/perf/psci-performance-n1sdp.rst
@@ -6,8 +6,8 @@ contains an SoC consisting of two dual-core Arm N1 clusters.
 
 The following source trees and binaries were used:
 
-- TF-A [`v2.9-rc0-16-g666aec401`_]
-- TFTF [`v2.9-rc0`_]
+- `TF-A v2.12-rc0`_
+- `TFTF v2.12-rc0`_
 - SCP/MCP `Prebuilt Images`_
 
 Please see the Runtime Instrumentation :ref:`Testing Methodology
@@ -92,206 +92,192 @@ Results
 ``CPU_SUSPEND`` to deepest power level
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in parallel (v2.12)
+
+    +---------+------+----------------+--------+----------------+
+    | Cluster | Core |   Powerdown    | Wakeup |  Cache Flush   |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   |      2.58      | 24.14  | 0.28 (-69.57%) |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   | 4.24 (-32.27%) |  40.1  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   |      3.58      | 35.54  |      0.28      |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   |      3.28      | 42.36  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in parallel (v2.11)
+
+    +---------+------+----------------+--------+----------------+
+    | Cluster | Core |   Powerdown    | Wakeup |  Cache Flush   |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   | 3.0 (+41.51%)  | 23.14  | 1.2 (+185.71%) |
+    +---------+------+----------------+--------+----------------+
+    |    0    |  0   |      4.6       | 35.86  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   | 3.68 (+33.33%) | 33.36  |      0.3       |
+    +---------+------+----------------+--------+----------------+
+    |    1    |  0   | 3.7 (+40.15%)  |  38.1  |      0.28      |
+    +---------+------+----------------+--------+----------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in serial (v2.12)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    2.80   | 10.08  |     0.80    |
+    |    0    |  0   |    1.9    |  23.8  |     0.36    |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    4.14   | 15.92  |     0.16    |
+    |    0    |  0   |    2.26   | 23.86  |     0.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    3.68   | 12.96  |     0.16    |
+    |    1    |  0   |    2.02   |  23.4  |     0.36    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    3.36   | 18.58  |     0.18    |
+    |    1    |  0   |    2.24   | 23.84  |     0.36    |
     +---------+------+-----------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        parallel (v2.10)
-
-    +---------+------+----------------+------------------+-----------------+
-    | Cluster | Core |   Powerdown    |      Wakeup      |   Cache Flush   |
-    +---------+------+----------------+------------------+-----------------+
-    |    0    |  0   |      2.12      | 23.94 (+137.50%) |  0.42 (-47.50%) |
-    +---------+------+----------------+------------------+-----------------+
-    |    0    |  0   |      3.52      | 42.08 (+164.32%) |  0.26 (+62.50%) |
-    +---------+------+----------------+------------------+-----------------+
-    |    1    |  0   | 2.76 (-25.00%) | 38.3 (+195.52%)  |  0.26 (+62.50%) |
-    +---------+------+----------------+------------------+-----------------+
-    |    1    |  0   |      2.64      | 44.56 (+139.83%) | 0.36 (+100.00%) |
-    +---------+------+----------------+------------------+-----------------+
-
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.9)
+.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in serial (v2.11)
 
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.86   |  9.92  |     0.32    |
+    |    0    |  0   |    1.7    | 22.46  |     0.3     |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    2.70   | 10.48  |     0.36    |
+    |    0    |  0   |    2.28   |  22.5  |     0.3     |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.78   |  9.72  |     0.16    |
+    |    1    |  0   |    2.14   |  21.5  |     0.32    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.94   | 10.44  |     0.16    |
+    |    1    |  0   |    2.24   | 22.66  |     0.3     |
     +---------+------+-----------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to deepest power level in
-        serial (v2.10)
-
-    +---------+------+-----------+------------------+----------------+
-    | Cluster | Core | Powerdown |      Wakeup      |  Cache Flush   |
-    +---------+------+-----------+------------------+----------------+
-    |    0    |  0   |    1.74   | 23.7 (+138.91%)  |      0.3       |
-    +---------+------+-----------+------------------+----------------+
-    |    0    |  0   |    2.08   | 23.96 (+128.63%) | 0.26 (-27.78%) |
-    +---------+------+-----------+------------------+----------------+
-    |    1    |  0   |    1.9    | 23.62 (+143.00%) | 0.28 (+75.00%) |
-    +---------+------+-----------+------------------+----------------+
-    |    1    |  0   |    2.06   | 23.92 (+129.12%) | 0.26 (+62.50%) |
-    +---------+------+-----------+------------------+----------------+
-
 ``CPU_SUSPEND`` to power level 0
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.9)
-
-    +---------------------------------------------------+
-    |          test_rt_instr_cpu_susp_parallel          |
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    0.88   | 12.32  |     0.26    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    2.12   | 14.62  |     0.26    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.86   | 14.14  |     0.16    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.92   |  9.44  |     0.18    |
-    +---------+------+-----------+--------+-------------+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in parallel (v2.12)
+
+    +---------+------+-----------+--------+----------------+
+    | Cluster | Core | Powerdown | Wakeup |  Cache Flush   |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    1.46   |  31.7  |      0.32      |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    2.06   |  35.5  | 0.48 (+60.00%) |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |    1.96   |  35.7  |      0.32      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |    2.08   | 23.38  |      0.28      |
+    +---------+------+-----------+--------+----------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in parallel (v2.11)
+
+    +---------+------+----------------+--------+-------------+
+    | Cluster | Core |   Powerdown    | Wakeup | Cache Flush |
+    +---------+------+----------------+--------+-------------+
+    |    0    |  0   | 0.94 (-37.33%) | 30.36  |     0.3     |
+    +---------+------+----------------+--------+-------------+
+    |    0    |  0   |      2.12      | 33.12  |     0.28    |
+    +---------+------+----------------+--------+-------------+
+    |    1    |  0   |      2.08      | 32.56  |     0.3     |
+    +---------+------+----------------+--------+-------------+
+    |    1    |  0   |      2.14      | 21.92  |     0.28    |
+    +---------+------+----------------+--------+-------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.12)
+
+    +---------+------+-----------+--------+----------------+
+    | Cluster | Core | Powerdown | Wakeup |  Cache Flush   |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    1.66   | 23.22  |      0.36      |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    2.58   | 23.72  | 0.78 (+85.71%) |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |    2.02   | 23.84  |      0.38      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |    2.16   | 23.92  |      0.34      |
+    +---------+------+-----------+--------+----------------+
+
+.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.11)
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in
-        parallel (v2.10)
-
-    +---------+------+---------------+------------------+----------------+
-    | Cluster | Core |   Powerdown   |      Wakeup      |  Cache Flush   |
-    +---------+------+---------------+------------------+----------------+
-    |    0    |  0   | 1.5 (+70.45%) | 35.02 (+184.25%) |      0.24      |
-    +---------+------+---------------+------------------+----------------+
-    |    0    |  0   |      1.92     | 38.12 (+160.74%) |      0.28      |
-    +---------+------+---------------+------------------+----------------+
-    |    1    |  0   |      1.88     | 38.1 (+169.45%)  | 0.26 (+62.50%) |
-    +---------+------+---------------+------------------+----------------+
-    |    1    |  0   |      2.04     | 23.1 (+144.70%)  |      0.24      |
-    +---------+------+---------------+------------------+----------------+
-
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.9)
-
-    +---------------------------------------------------+
-    |           test_rt_instr_cpu_susp_serial           |
     +---------+------+-----------+--------+-------------+
     | Cluster | Core | Powerdown | Wakeup | Cache Flush |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.52   |  9.40  |     0.30    |
+    |    0    |  0   |    1.64   | 21.88  |     0.34    |
     +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.92   |  9.80  |     0.18    |
+    |    0    |  0   |    2.42   | 21.76  |     0.34    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    2.20   |  9.60  |     0.14    |
+    |    1    |  0   |    2.02   | 21.14  |     0.32    |
     +---------+------+-----------+--------+-------------+
-    |    1    |  0   |    1.82   |  9.78  |     0.18    |
+    |    1    |  0   |    2.18   |  22.3  |     0.34    |
     +---------+------+-----------+--------+-------------+
 
-.. table:: ``CPU_SUSPEND`` latencies (µs) to power level 0 in serial (v2.10)
-
-    +---------+------+-----------+------------------+-----------------+
-    | Cluster | Core | Powerdown |      Wakeup      |   Cache Flush   |
-    +---------+------+-----------+------------------+-----------------+
-    |    0    |  0   |    1.52   | 23.08 (+145.53%) |       0.3       |
-    +---------+------+-----------+------------------+-----------------+
-    |    0    |  0   |    1.98   | 23.68 (+141.63%) |  0.28 (+55.56%) |
-    +---------+------+-----------+------------------+-----------------+
-    |    1    |  0   |    1.84   | 23.86 (+148.54%) | 0.28 (+100.00%) |
-    +---------+------+-----------+------------------+-----------------+
-    |    1    |  0   |    1.98   | 23.68 (+142.13%) |  0.28 (+55.56%) |
-    +---------+------+-----------+------------------+-----------------+
-
 ``CPU_OFF`` on all non-lead CPUs
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ``CPU_OFF`` on all non-lead CPUs in sequence then, ``CPU_SUSPEND`` on the lead
 core to the deepest power level.
 
-.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.9)
-
-    +---------+------+-----------+--------+-------------+
-    | Cluster | Core | Powerdown | Wakeup | Cache Flush |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |    1.84   |  9.94  |     0.32    |
-    +---------+------+-----------+--------+-------------+
-    |    0    |  0   |   14.20   | 13.10  |     0.50    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   13.88   | 12.36  |     0.42    |
-    +---------+------+-----------+--------+-------------+
-    |    1    |  0   |   14.40   | 13.26  |     0.52    |
-    +---------+------+-----------+--------+-------------+
-
-.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.10)
-
-    +---------+------+-----------+------------------+----------------+
-    | Cluster | Core | Powerdown |      Wakeup      |  Cache Flush   |
-    +---------+------+-----------+------------------+----------------+
-    |    0    |  0   |    1.78   | 23.7 (+138.43%)  |      0.3       |
-    +---------+------+-----------+------------------+----------------+
-    |    0    |  0   |   13.96   | 31.16 (+137.86%) | 0.34 (-32.00%) |
-    +---------+------+-----------+------------------+----------------+
-    |    1    |  0   |   13.54   | 30.24 (+144.66%) | 0.26 (-38.10%) |
-    +---------+------+-----------+------------------+----------------+
-    |    1    |  0   |   14.46   | 31.12 (+134.69%) | 0.7 (+34.62%)  |
-    +---------+------+-----------+------------------+----------------+
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.12)
+
+    +---------+------+-----------+--------+----------------+
+    | Cluster | Core | Powerdown | Wakeup |  Cache Flush   |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    1.84   | 23.82  |      0.36      |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |   14.18   | 31.78  | 0.56 (+86.67%) |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   13.64   | 30.54  |      0.36      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   14.18   | 31.82  |      0.68      |
+    +---------+------+-----------+--------+----------------+
+
+.. table:: ``CPU_OFF`` latencies (µs) on all non-lead CPUs (v2.11)
+
+    +---------+------+-----------+--------+----------------+
+    | Cluster | Core | Powerdown | Wakeup |  Cache Flush   |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |    1.96   | 22.44  |      0.38      |
+    +---------+------+-----------+--------+----------------+
+    |    0    |  0   |   13.76   | 30.34  |      0.26      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   13.46   | 28.28  |      0.24      |
+    +---------+------+-----------+--------+----------------+
+    |    1    |  0   |   13.84   | 30.06  | 0.28 (-60.00%) |
+    +---------+------+-----------+--------+----------------+
 
 ``CPU_VERSION`` in parallel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.9)
-
-    +------------------------------------+
-    | test_rt_instr_psci_version_parallel|
-    +-------------+--------+-------------+
-    |   Cluster   |  Core  |   Latency   |
-    +-------------+--------+-------------+
-    |      0      |   0    |     0.08    |
-    +-------------+--------+-------------+
-    |      0      |   0    |     0.26    |
-    +-------------+--------+-------------+
-    |      1      |   0    |     0.20    |
-    +-------------+--------+-------------+
-    |      1      |   0    |     0.26    |
-    +-------------+--------+-------------+
-
-.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.10)
-
-    +----------------------------------------------+
-    | test_rt_instr_psci_version_parallel (latest) |
-    +-------------+--------+-----------------------+
-    |   Cluster   |  Core  |        Latency        |
-    +-------------+--------+-----------------------+
-    |      0      |   0    |     0.14 (+75.00%)    |
-    +-------------+--------+-----------------------+
-    |      0      |   0    |          0.22         |
-    +-------------+--------+-----------------------+
-    |      1      |   0    |          0.2          |
-    +-------------+--------+-----------------------+
-    |      1      |   0    |          0.26         |
-    +-------------+--------+-----------------------+
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.12)
+
+    +----------+------+-------------------+
+    | Cluster  | Core |      Latency      |
+    +----------+------+-------------------+
+    |    0     |  0   |        0.14       |
+    +----------+------+-------------------+
+    |    0     |  0   |   0.2 (-28.57%)   |
+    +----------+------+-------------------+
+    |    1     |  0   |        0.2        |
+    +----------+------+-------------------+
+    |    1     |  0   |        0.26       |
+    +----------+------+-------------------+
+
+.. table:: ``CPU_VERSION`` latency (µs) in parallel on all cores (v2.11)
+
+    +-------------+--------+--------------+
+    |   Cluster   |  Core  |   Latency    |
+    +-------------+--------+--------------+
+    |      0      |   0    |     0.12     |
+    +-------------+--------+--------------+
+    |      0      |   0    |     0.24     |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.2      |
+    +-------------+--------+--------------+
+    |      1      |   0    |     0.26     |
+    +-------------+--------+--------------+
 
 --------------
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
 
-.. _v2.9-rc0-16-g666aec401: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/v2.9-rc0-16-g666aec401
-.. _v2.9-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/tf-a-tests/+/refs/tags/v2.9-rc0
+.. _TF-A v2.12-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/tags/v2.12-rc0
+.. _TFTF v2.12-rc0: https://review.trustedfirmware.org/plugins/gitiles/TF-A/tf-a-tests/+/refs/tags/v2.12-rc0
 .. _user guide: https://gitlab.arm.com/arm-reference-solutions/arm-reference-solutions-docs/-/blob/master/docs/n1sdp/user-guide.rst
-.. _Prebuilt Images:  https://downloads.trustedfirmware.org/tf-a/css_scp_2.11.0/n1sdp/release/
+.. _Prebuilt Images:  https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/n1sdp/release/
 .. _N1SDP: https://developer.arm.com/documentation/101489/latest
diff --git a/docs/plat/amd-versal2.rst b/docs/plat/amd-versal2.rst
new file mode 100644
index 00000000..876ab3c7
--- /dev/null
+++ b/docs/plat/amd-versal2.rst
@@ -0,0 +1,87 @@
+AMD Versal Gen 2
+================
+
+Trusted Firmware-A implements the EL3 firmware layer for AMD Versal Gen 2.
+The platform only uses the runtime part of TF-A as AMD Versal Gen 2 already
+has a BootROM (BL1) and PMC FW (BL2).
+
+BL31 is TF-A.
+BL32 is an optional Secure Payload.
+BL33 is the non-secure world software (U-Boot, Linux etc).
+
+To build:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 bl31
+```
+
+To build TF-A for JTAG DCC console:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 CONSOLE=dcc bl31
+```
+
+To build TF-A with Errata management interface
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 bl31 ERRATA_ABI_SUPPORT=1
+```
+
+To build TF-A with IPI CRC check:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal2 bl31 IPI_CRC_CHECK=1
+```
+
+AMD Versal Gen 2 platform specific build options
+-------------------------------------------------
+
+*   `MEM_BASE`: Specifies the base address of the bl31 binary.
+*   `MEM_SIZE`: Specifies the size of the memory region of the bl31 binary.
+*   `BL32_MEM_BASE`: Specifies the base address of the bl32 binary.
+*   `BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary.
+
+*   `CONSOLE`: Select the console driver. Options:
+    -   `pl011`, `pl011_0`: ARM pl011 UART 0 (default)
+    -   `pl011_1`         : ARM pl011 UART 1
+    -   `dcc`             : JTAG Debug Communication Channel(DCC)
+
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+------------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+-------------------------------------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+------------------
+
++---------------------------+---------------------------------------------------------------------------+
+| SMC Function Identifier   |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
index 3301067e..afbb1576 100644
--- a/docs/plat/arm/arm-build-options.rst
+++ b/docs/plat/arm/arm-build-options.rst
@@ -16,6 +16,12 @@ Arm Platform Build Options
    should match the frame used by the Non-Secure image (normally the Linux
    kernel). Default is true (access to the frame is allowed).
 
+-  ``ARM_FW_CONFIG_LOAD_ENABLE``: Boolean option to enable the loading of
+   FW_CONFIG device trees from the Firmware Image Package (FIP). When enabled,
+   BL2 calls the platform specific function `arm_bl2_el3_plat_config_load`.
+   This function is responsible for loading, parsing, and validating the
+   FW_CONFIG device trees from the FIP. The option depends on RESET_TO_BL2.
+
 -  ``ARM_DISABLE_TRUSTED_WDOG``: boolean option to disable the Trusted Watchdog.
    By default, Arm platforms use a watchdog to trigger a system reset in case
    an error is encountered during the boot process (for example, when an image
@@ -121,17 +127,6 @@ Arm CSS Platform-Specific Build Options
    management operations and for SCP RAM Firmware transfer. If this option
    is set to 1, then SCMI/SDS drivers will be used. Default is 0.
 
- - ``CSS_SGI_CHIP_COUNT``: Configures the number of chips on a SGI/RD platform
-   which supports multi-chip operation. If ``CSS_SGI_CHIP_COUNT`` is set to any
-   valid value greater than 1, the platform code performs required configuration
-   to support multi-chip operation.
-
-- ``CSS_SGI_PLATFORM_VARIANT``: Selects the variant of a SGI/RD platform. A
-    particular SGI/RD platform may have multiple variants which may differ in
-    core count, cluster count or other peripherals. This build option is used
-    to select the appropriate platform variant for the build. The range of
-    valid values is platform specific.
-
 - ``CSS_SYSTEM_GRACEFUL_RESET``: Build option to enable graceful powerdown of
    CPU core on reset. This build option can be used on CSS platforms that
    require all the CPUs to execute the CPU specific power down sequence to
@@ -152,8 +147,22 @@ Arm Juno Build Options
    AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
    images.
 
+Arm Neoverse RD Platform Build Options
+--------------------------------------
+
+ - ``NRD_CHIP_COUNT``: Configures the number of chips on a Neoverse RD platform
+   which supports multi-chip operation. If ``NRD_CHIP_COUNT`` is set to any
+   valid value greater than 1, the platform code performs required configuration
+   to support multi-chip operation.
+
+- ``NRD_PLATFORM_VARIANT``: Selects the variant of a Neoverse RD platform. A
+  particular Neoverse RD platform may have multiple variants which may differ in
+  core count, cluster count or other peripherals. This build option is used to
+  select the appropriate platform variant for the build. The range of valid
+  values is platform specific.
+
 --------------
 
 .. |FIP in a GPT image| image:: ../../resources/diagrams/FIP_in_a_GPT_image.png
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/automotive_rd/index.rst b/docs/plat/arm/automotive_rd/index.rst
new file mode 100644
index 00000000..d0db6ac5
--- /dev/null
+++ b/docs/plat/arm/automotive_rd/index.rst
@@ -0,0 +1,50 @@
+RD-1 AE (Kronos) Platform
+=========================
+
+Some of the features of the RD-1 AE platform referenced in TF-A include:
+
+- Neoverse-V3AE, Arm9.2-A application processor (64-bit mode)
+- A GICv4-compatible GIC-720AE
+
+Further information on RD1-AE is available at `rd1ae`_
+
+Boot Sequence
+-------------
+
+BL2 –> BL31 –> BL33
+
+The boot process starts from RSE (Runtime Security Engine) that loads the BL2 image
+and signals the System Control Processor (SCP) to power up the Application Processor (AP).
+The AP then runs BL2, which loads the rest of the images, including the runtime firmware
+BL31, and proceeds to execute it. Finally, it passes control to the non-secure world
+BL33 (u-boot).
+
+BL2 performs the actions described in the `Trusted Board Boot (TBB)`_ document.
+
+Build Procedure (TF-A only)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+-  Obtain `Arm toolchain`_ and set the CROSS_COMPILE environment variable to
+   point to the toolchain folder.
+
+-  Build TF-A:
+
+   .. code:: shell
+
+      make \
+      PLAT=rd1ae \
+      MBEDTLS_DIR=<mbedtls_dir> \
+      ARCH=aarch64 \
+      CREATE_KEYS=1 \
+      GENERATE_COT=1 \
+      TRUSTED_BOARD_BOOT=1 \
+      COT=tbbr \
+      ARM_ROTPK_LOCATION=devel_rsa \
+      ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
+      BL33=<path to u-boot binary> \
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
+
+.. _Arm Toolchain: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
+.. _rd1ae: https://developer.arm.com/Tools%20and%20Software/Arm%20Reference%20Design-1%20AE
+.. _Trusted Board Boot (TBB): https://trustedfirmware-a.readthedocs.io/en/latest/design/trusted-board-boot.html
diff --git a/docs/plat/arm/fvp/fvp-aemv8-base.rst b/docs/plat/arm/fvp/fvp-aemv8-base.rst
new file mode 100644
index 00000000..6dd35e53
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-aemv8-base.rst
@@ -0,0 +1,154 @@
+Running on the AEMv8 Base FVP
+=============================
+
+AArch64 with reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_RevC-2xAEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+.. note::
+   The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires
+   a specific DTS for all the CPUs to be loaded.
+
+AArch32 with reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.CONFIG64=0                                 \
+    -C cluster0.cpu1.CONFIG64=0                                 \
+    -C cluster0.cpu2.CONFIG64=0                                 \
+    -C cluster0.cpu3.CONFIG64=0                                 \
+    -C cluster1.cpu0.CONFIG64=0                                 \
+    -C cluster1.cpu1.CONFIG64=0                                 \
+    -C cluster1.cpu2.CONFIG64=0                                 \
+    -C cluster1.cpu3.CONFIG64=0                                 \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+AArch64 with reset to BL31 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_RevC-2xAEMv8A                             \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cluster0.NUM_CORES=4                                      \
+    -C cluster1.NUM_CORES=4                                      \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.RVBAR=0x04010000                            \
+    -C cluster0.cpu1.RVBAR=0x04010000                            \
+    -C cluster0.cpu2.RVBAR=0x04010000                            \
+    -C cluster0.cpu3.RVBAR=0x04010000                            \
+    -C cluster1.cpu0.RVBAR=0x04010000                            \
+    -C cluster1.cpu1.RVBAR=0x04010000                            \
+    -C cluster1.cpu2.RVBAR=0x04010000                            \
+    -C cluster1.cpu3.RVBAR=0x04010000                            \
+    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Notes:
+
+-  Position Independent Executable (PIE) support is enabled in this
+   config allowing BL31 to be loaded at any valid address for execution.
+
+-  Since a FIP is not loaded when using BL31 as reset entrypoint, the
+   ``--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>``
+   parameter is needed to load the individual bootloader images in memory.
+   BL32 image is only needed if BL31 has been built to expect a Secure-EL1
+   Payload. For the same reason, the FDT needs to be compiled from the DT source
+   and loaded via the ``--data cluster0.cpu0="<path-to>/<fdt>"@0x82000000``
+   parameter.
+
+-  The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
+   specific DTS for all the CPUs to be loaded.
+
+-  The ``-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>`` parameter, where
+   X and Y are the cluster and CPU numbers respectively, is used to set the
+   reset vector for each core.
+
+-  Changing the default value of ``ARM_TSP_RAM_LOCATION`` will also require
+   changing the value of
+   ``--data="<path-to><bl32-binary>"@<base-address-of-bl32>`` to the new value of
+   ``BL32_BASE``.
+
+AArch32 with reset to SP_MIN entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                             \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cluster0.NUM_CORES=4                                      \
+    -C cluster1.NUM_CORES=4                                      \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.CONFIG64=0                                  \
+    -C cluster0.cpu1.CONFIG64=0                                  \
+    -C cluster0.cpu2.CONFIG64=0                                  \
+    -C cluster0.cpu3.CONFIG64=0                                  \
+    -C cluster1.cpu0.CONFIG64=0                                  \
+    -C cluster1.cpu1.CONFIG64=0                                  \
+    -C cluster1.cpu2.CONFIG64=0                                  \
+    -C cluster1.cpu3.CONFIG64=0                                  \
+    -C cluster0.cpu0.RVBAR=0x04002000                            \
+    -C cluster0.cpu1.RVBAR=0x04002000                            \
+    -C cluster0.cpu2.RVBAR=0x04002000                            \
+    -C cluster0.cpu3.RVBAR=0x04002000                            \
+    -C cluster1.cpu0.RVBAR=0x04002000                            \
+    -C cluster1.cpu1.RVBAR=0x04002000                            \
+    -C cluster1.cpu2.RVBAR=0x04002000                            \
+    -C cluster1.cpu3.RVBAR=0x04002000                            \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+.. note::
+   Position Independent Executable (PIE) support is enabled in this
+   config allowing SP_MIN to be loaded at any valid address for execution.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-build-options.rst b/docs/plat/arm/fvp/fvp-build-options.rst
new file mode 100644
index 00000000..b0359fa9
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-build-options.rst
@@ -0,0 +1,51 @@
+.. _build_options_arm_fvp_platform:
+
+Arm FVP Platform Specific Build Options
+---------------------------------------
+
+-  ``FVP_CLUSTER_COUNT`` : Configures the cluster count to be used to
+   build the topology tree within TF-A. By default TF-A is configured for dual
+   cluster topology and this option can be used to override the default value.
+
+-  ``FVP_INTERCONNECT_DRIVER``: Selects the interconnect driver to be built. The
+   default interconnect driver depends on the value of ``FVP_CLUSTER_COUNT`` as
+   explained in the options below:
+
+   -  ``FVP_CCI`` : The CCI driver is selected. This is the default
+      if 0 < ``FVP_CLUSTER_COUNT`` <= 2.
+   -  ``FVP_CCN`` : The CCN driver is selected. This is the default
+      if ``FVP_CLUSTER_COUNT`` > 2.
+
+-  ``FVP_MAX_CPUS_PER_CLUSTER``: Sets the maximum number of CPUs implemented in
+   a single cluster.  This option defaults to 4.
+
+-  ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
+   in the system. This option defaults to 1. Note that the build option
+   ``ARM_PLAT_MT`` doesn't have any effect on FVP platforms.
+
+-  ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
+
+   -  ``FVP_GICV2`` : The GICv2 only driver is selected
+   -  ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
+
+-  ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled
+   to DTB and packaged in FIP as the HW_CONFIG. See :ref:`Firmware Design` for
+   details on HW_CONFIG. By default, this is initialized to a sensible DTS
+   file in ``fdts/`` folder depending on other build options. But some cases,
+   like shifted affinity format for MPIDR, cannot be detected at build time
+   and this option is needed to specify the appropriate DTS file.
+
+-  ``FVP_HW_CONFIG`` : Specify the path to the HW_CONFIG blob to be packaged in
+   FIP. See :ref:`Firmware Design` for details on HW_CONFIG. This option is
+   similar to the ``FVP_HW_CONFIG_DTS`` option, but it directly specifies the
+   HW_CONFIG blob instead of the DTS file. This option is useful to override
+   the default HW_CONFIG selected by the build system.
+
+-  ``FVP_GICR_REGION_PROTECTION``: Mark the redistributor pages of
+   inactive/fused CPU cores as read-only. The default value of this option
+   is ``0``, which means the redistributor pages of all CPU cores are marked
+   as read and write.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-cortex-a32.rst b/docs/plat/arm/fvp/fvp-cortex-a32.rst
new file mode 100644
index 00000000..df17eed6
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-cortex-a32.rst
@@ -0,0 +1,47 @@
+Running on the Cortex-A32 Base FVP (AArch32)
+============================================
+
+With reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A32x4                             \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+With reset to SP_MIN entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A32x4                             \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.RVBARADDR=0x04002000                       \
+    -C cluster0.cpu1.RVBARADDR=0x04002000                       \
+    -C cluster0.cpu2.RVBARADDR=0x04002000                       \
+    -C cluster0.cpu3.RVBARADDR=0x04002000                       \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000   \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000   \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-cortex-a57-a53.rst b/docs/plat/arm/fvp/fvp-cortex-a57-a53.rst
new file mode 100644
index 00000000..8f541140
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-cortex-a57-a53.rst
@@ -0,0 +1,52 @@
+Running on the Cortex-A57-A53 Base FVP
+======================================
+
+With reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
+boot Linux with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A57x4-A53x4                       \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+With reset to BL31 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
+boot Linux with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A57x4-A53x4                        \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.RVBARADDR=0x04010000                        \
+    -C cluster0.cpu1.RVBARADDR=0x04010000                        \
+    -C cluster0.cpu2.RVBARADDR=0x04010000                        \
+    -C cluster0.cpu3.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu0.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu1.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu2.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu3.RVBARADDR=0x04010000                        \
+    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-foundation.rst b/docs/plat/arm/fvp/fvp-foundation.rst
new file mode 100644
index 00000000..dd6f9dce
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-foundation.rst
@@ -0,0 +1,42 @@
+Running on the Foundation FVP
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``Foundation_Platform`` parameters should be used to boot Linux with
+4 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/Foundation_Platform                   \
+    --cores=4                                       \
+    --arm-v8.0                                      \
+    --secure-memory                                 \
+    --visualization                                 \
+    --gicv3                                         \
+    --data="<path-to>/<bl1-binary>"@0x0             \
+    --data="<path-to>/<FIP-binary>"@0x08000000      \
+    --data="<path-to>/<kernel-binary>"@0x80080000   \
+    --data="<path-to>/<ramdisk-binary>"@0x84000000
+
+Notes:
+
+-  BL1 is loaded at the start of the Trusted ROM.
+-  The Firmware Image Package is loaded at the start of NOR FLASH0.
+-  The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
+   is specified via the ``load-address`` property in the ``hw-config`` node of
+   `FW_CONFIG for FVP`_.
+-  The default use-case for the Foundation FVP is to use the ``--gicv3`` option
+   and enable the GICv3 device in the model. Note that without this option,
+   the Foundation FVP defaults to legacy (Versatile Express) memory map which
+   is not supported by TF-A.
+-  In order for TF-A to run correctly on the Foundation FVP, the architecture
+   versions must match. The Foundation FVP defaults to the highest v8.x
+   version it supports but the default build for TF-A is for v8.0. To avoid
+   issues either start the Foundation FVP to use v8.0 architecture using the
+   ``--arm-v8.0`` option, or build TF-A with an appropriate value for
+   ``ARM_ARCH_MINOR``.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
+
+.. _FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_fw_config.dts
diff --git a/docs/plat/arm/fvp/fvp-specific-configs.rst b/docs/plat/arm/fvp/fvp-specific-configs.rst
new file mode 100644
index 00000000..63b3c31c
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-specific-configs.rst
@@ -0,0 +1,209 @@
+Booting Firmware Update images
+------------------------------
+
+When Firmware Update (FWU) is enabled there are at least 2 new images
+that have to be loaded, the Non-Secure FWU ROM (NS-BL1U), and the
+FWU FIP.
+
+The additional fip images must be loaded with:
+
+::
+
+    --data cluster0.cpu0="<path_to>/ns_bl1u.bin"@0x0beb8000	[ns_bl1u_base_address]
+    --data cluster0.cpu0="<path_to>/fwu_fip.bin"@0x08400000	[ns_bl2u_base_address]
+
+The address ns_bl1u_base_address is the value of NS_BL1U_BASE.
+In the same way, the address ns_bl2u_base_address is the value of
+NS_BL2U_BASE.
+
+Booting an EL3 payload
+----------------------
+
+The EL3 payloads boot flow requires the CPU's mailbox to be cleared at reset for
+the secondary CPUs holding pen to work properly. Unfortunately, its reset value
+is undefined on the FVP platform and the FVP platform code doesn't clear it.
+Therefore, one must modify the way the model is normally invoked in order to
+clear the mailbox at start-up.
+
+One way to do that is to create an 8-byte file containing all zero bytes using
+the following command:
+
+.. code:: shell
+
+    dd if=/dev/zero of=mailbox.dat bs=1 count=8
+
+and pre-load it into the FVP memory at the mailbox address (i.e. ``0x04000000``)
+using the following model parameters:
+
+::
+
+    --data cluster0.cpu0=mailbox.dat@0x04000000   [Base FVPs]
+    --data=mailbox.dat@0x04000000                 [Foundation FVP]
+
+To provide the model with the EL3 payload image, the following methods may be
+used:
+
+#. If the EL3 payload is able to execute in place, it may be programmed into
+   flash memory. On Base Cortex and AEM FVPs, the following model parameter
+   loads it at the base address of the NOR FLASH1 (the NOR FLASH0 is already
+   used for the FIP):
+
+   ::
+
+       -C bp.flashloader1.fname="<path-to>/<el3-payload>"
+
+   On Foundation FVP, there is no flash loader component and the EL3 payload
+   may be programmed anywhere in flash using method 3 below.
+
+#. When using the ``SPIN_ON_BL1_EXIT=1`` loading method, the following DS-5
+   command may be used to load the EL3 payload ELF image over JTAG:
+
+   ::
+
+       load <path-to>/el3-payload.elf
+
+#. The EL3 payload may be pre-loaded in volatile memory using the following
+   model parameters:
+
+   ::
+
+       --data cluster0.cpu0="<path-to>/el3-payload>"@address   [Base FVPs]
+       --data="<path-to>/<el3-payload>"@address                [Foundation FVP]
+
+   The address provided to the FVP must match the ``EL3_PAYLOAD_BASE`` address
+   used when building TF-A.
+
+Booting a preloaded kernel image (Base FVP)
+-------------------------------------------
+
+The following example uses a simplified boot flow by directly jumping from the
+TF-A to the Linux kernel, which will use a ramdisk as filesystem. This can be
+useful if both the kernel and the device tree blob (DTB) are already present in
+memory (like in FVP).
+
+For example, if the kernel is loaded at ``0x80080000`` and the DTB is loaded at
+address ``0x82000000``, the firmware can be built like this:
+
+.. code:: shell
+
+    CROSS_COMPILE=aarch64-none-elf-  \
+    make PLAT=fvp DEBUG=1             \
+    RESET_TO_BL31=1                   \
+    ARM_LINUX_KERNEL_AS_BL33=1        \
+    PRELOADED_BL33_BASE=0x80080000    \
+    ARM_PRELOADED_DTB_BASE=0x82000000 \
+    all fip
+
+Now, it is needed to modify the DTB so that the kernel knows the address of the
+ramdisk. The following script generates a patched DTB from the provided one,
+assuming that the ramdisk is loaded at address ``0x84000000``. Note that this
+script assumes that the user is using a ramdisk image prepared for U-Boot, like
+the ones provided by Linaro. If using a ramdisk without this header,the ``0x40``
+offset in ``INITRD_START`` has to be removed.
+
+.. code:: bash
+
+    #!/bin/bash
+
+    # Path to the input DTB
+    KERNEL_DTB=<path-to>/<fdt>
+    # Path to the output DTB
+    PATCHED_KERNEL_DTB=<path-to>/<patched-fdt>
+    # Base address of the ramdisk
+    INITRD_BASE=0x84000000
+    # Path to the ramdisk
+    INITRD=<path-to>/<ramdisk.img>
+
+    # Skip uboot header (64 bytes)
+    INITRD_START=$(printf "0x%x" $((${INITRD_BASE} + 0x40)) )
+    INITRD_SIZE=$(stat -Lc %s ${INITRD})
+    INITRD_END=$(printf "0x%x" $((${INITRD_BASE} + ${INITRD_SIZE})) )
+
+    CHOSEN_NODE=$(echo                                        \
+    "/ {                                                      \
+            chosen {                                          \
+                    linux,initrd-start = <${INITRD_START}>;   \
+                    linux,initrd-end = <${INITRD_END}>;       \
+            };                                                \
+    };")
+
+    echo $(dtc -O dts -I dtb ${KERNEL_DTB}) ${CHOSEN_NODE} |  \
+            dtc -O dtb -o ${PATCHED_KERNEL_DTB} -
+
+And the FVP binary can be run with the following command:
+
+.. code:: shell
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.RVBAR=0x04001000                           \
+    -C cluster0.cpu1.RVBAR=0x04001000                           \
+    -C cluster0.cpu2.RVBAR=0x04001000                           \
+    -C cluster0.cpu3.RVBAR=0x04001000                           \
+    -C cluster1.cpu0.RVBAR=0x04001000                           \
+    -C cluster1.cpu1.RVBAR=0x04001000                           \
+    -C cluster1.cpu2.RVBAR=0x04001000                           \
+    -C cluster1.cpu3.RVBAR=0x04001000                           \
+    --data cluster0.cpu0="<path-to>/bl31.bin"@0x04001000        \
+    --data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000   \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
+
+Obtaining the Flattened Device Trees
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Depending on the FVP configuration and Linux configuration used, different
+FDT files are required. FDT source files for the Foundation and Base FVPs can
+be found in the TF-A source directory under ``fdts/``. The Foundation FVP has
+a subset of the Base FVP components. For example, the Foundation FVP lacks
+CLCD and MMC support, and has only one CPU cluster.
+
+.. note::
+   It is not recommended to use the FDTs built along the kernel because not
+   all FDTs are available from there.
+
+The dynamic configuration capability is enabled in the firmware for FVPs.
+This means that the firmware can authenticate and load the FDT if present in
+FIP. A default FDT is packaged into FIP during the build based on
+the build configuration. This can be overridden by using the ``FVP_HW_CONFIG``
+or ``FVP_HW_CONFIG_DTS`` build options (refer to
+:ref:`build_options_arm_fvp_platform` for details on the options).
+
+-  ``fvp-base-gicv2-psci.dts``
+
+   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
+   without shifted affinities and with Base memory map configuration.
+
+-  ``fvp-base-gicv3-psci.dts``
+
+   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
+   without shifted affinities and with Base memory map configuration and
+   Linux GICv3 support.
+
+-  ``fvp-base-gicv3-psci-1t.dts``
+
+   For use with models such as the AEMv8-RevC Base FVP with shifted affinities,
+   single threaded CPUs, Base memory map configuration and Linux GICv3 support.
+
+-  ``fvp-base-gicv3-psci-dynamiq.dts``
+
+   For use with models as the Cortex-A55-A75 Base FVPs with shifted affinities,
+   single cluster, single threaded CPUs, Base memory map configuration and Linux
+   GICv3 support.
+
+-  ``fvp-foundation-gicv2-psci.dts``
+
+   For use with Foundation FVP with Base memory map configuration.
+
+-  ``fvp-foundation-gicv3-psci.dts``
+
+   (Default) For use with Foundation FVP with Base memory map configuration
+   and Linux GICv3 support.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/fvp-support.rst b/docs/plat/arm/fvp/fvp-support.rst
new file mode 100644
index 00000000..ad76cf16
--- /dev/null
+++ b/docs/plat/arm/fvp/fvp-support.rst
@@ -0,0 +1,102 @@
+Fixed Virtual Platform (FVP) Support
+------------------------------------
+
+This section lists the supported Arm |FVP| platforms. Please refer to the FVP
+documentation for a detailed description of the model parameter options.
+
+The latest version of the AArch64 build of TF-A has been tested on the following
+Arm FVPs without shifted affinities, and that do not support threaded CPU cores
+(64-bit host machine only).
+
+.. note::
+   The FVP models used are Version 11.26 Build 11, unless otherwise stated.
+
+-  ``FVP_Base_AEMvA-AEMvA``
+-  ``FVP_Base_RevC-2xAEMvA``
+-  ``FVP_Base_Cortex-A32x4``
+-  ``FVP_Base_Cortex-A35x4``
+-  ``FVP_Base_Cortex-A53x4``
+-  ``FVP_Base_Cortex-A55``
+-  ``FVP_Base_Cortex-A57x1-A53x1``
+-  ``FVP_Base_Cortex-A57x2-A53x4``
+-  ``FVP_Base_Cortex-A57x4``
+-  ``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-A73x4-A53x4``
+-  ``FVP_Base_Cortex-A75``
+-  ``FVP_Base_Cortex-A76``
+-  ``FVP_Base_Cortex-A76AE``
+-  ``FVP_Base_Cortex-A77``
+-  ``FVP_Base_Cortex-A78``
+-  ``FVP_Base_Cortex-A78AE``
+-  ``FVP_Base_Cortex-A78C``
+-  ``FVP_Base_Cortex-X2``
+-  ``FVP_Base_Neoverse-E1`` (Version 11.24/24)
+-  ``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)
+
+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
+CPU cores (64-bit host machine only).
+
+-  ``FVP_Base_AEMvA``
+-  ``FVP_Base_AEMvA-AEMvA``
+-  ``FVP_Base_Cortex-A32x4``
+
+.. note::
+   The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities, which
+   is not compatible with legacy GIC configurations. Therefore this FVP does not
+   support these legacy GIC configurations.
+
+The *Foundation* and *Base* FVPs can be downloaded free of charge. See the `Arm
+FVP website`_. The Cortex-A models listed above are also available to download
+from `Arm's website`_.
+
+.. note::
+   The build numbers quoted above are those reported by launching the FVP
+   with the ``--version`` parameter.
+
+.. note::
+   Linaro provides a ramdisk image in prebuilt FVP configurations and full
+   file systems that can be downloaded separately. To run an FVP with a virtio
+   file system image an additional FVP configuration option
+   ``-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>`` can be
+   used.
+
+.. note::
+   The software will not work on Version 1.0 of the Foundation FVP.
+   The commands below would report an ``unhandled argument`` error in this case.
+
+.. note::
+   FVPs can be launched with ``--cadi-server`` option such that a
+   CADI-compliant debugger (for example, Arm DS-5) can connect to and control
+   its execution.
+
+.. warning::
+   Since FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
+   the internal synchronisation timings changed compared to older versions of
+   the models. The models can be launched with ``-Q 100`` option if they are
+   required to match the run time characteristics of the older versions.
+
+All the above platforms have been tested with `Linaro Release 20.01`_.
+
+--------------
+
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
+
+.. _Arm's website: `FVP models`_
+.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
+.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
+.. _Arm FVP website: https://developer.arm.com/products/system-design/fixed-virtual-platforms
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index 700020f5..088beec5 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -1,639 +1,31 @@
 Arm Fixed Virtual Platforms (FVP)
 =================================
 
-Fixed Virtual Platform (FVP) Support
-------------------------------------
+Arm |FVP|\s are complete simulations of an Arm system, including processor,
+memory and peripherals. They enable software development without the need for
+real hardware.
 
-This section lists the supported Arm |FVP| platforms. Please refer to the FVP
-documentation for a detailed description of the model parameter options.
+There exists many types of FVPs. This page provides details on how to build and
+run TF-A on some of these FVPs.
 
-The latest version of the AArch64 build of TF-A has been tested on the following
-Arm FVPs without shifted affinities, and that do not support threaded CPU cores
-(64-bit host machine only).
+Please also refer to the TF-A CI scripts under the `model/`_ directory for an
+exhaustive list of |FVP|\s which TF-A is regularly tested on as part of our
+continuous integration strategy.
 
-.. note::
-   The FVP models used are Version 11.22 Build 14, unless otherwise stated.
+.. toctree::
+  :maxdepth: 1
+  :caption: Contents
 
--  ``Foundation_Platform``
--  ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502`` (Version 11.17/21)
--  ``FVP_Base_AEMv8A-GIC600AE`` (Version 11.17/21)
--  ``FVP_Base_AEMvA``
--  ``FVP_Base_AEMvA-AEMvA``
--  ``FVP_Base_Cortex-A32x4`` (Version 11.12/38)
--  ``FVP_Base_Cortex-A35x4``
--  ``FVP_Base_Cortex-A53x4``
--  ``FVP_Base_Cortex-A55``
--  ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
--  ``FVP_Base_Cortex-A55x4+Cortex-A76x2``
--  ``FVP_Base_Cortex-A57x1-A53x1``
--  ``FVP_Base_Cortex-A57x2-A53x4``
--  ``FVP_Base_Cortex-A57x4``
--  ``FVP_Base_Cortex-A57x4-A53x4``
--  ``FVP_Base_Cortex-A65``
--  ``FVP_Base_Cortex-A65AE``
--  ``FVP_Base_Cortex-A710x4`` (Version 11.17/21)
--  ``FVP_Base_Cortex-A72x4``
--  ``FVP_Base_Cortex-A72x4-A53x4``
--  ``FVP_Base_Cortex-A73x4``
--  ``FVP_Base_Cortex-A73x4-A53x4``
--  ``FVP_Base_Cortex-A75``
--  ``FVP_Base_Cortex-A76``
--  ``FVP_Base_Cortex-A76AE``
--  ``FVP_Base_Cortex-A77``
--  ``FVP_Base_Cortex-A78``
--  ``FVP_Base_Cortex-A78AE``
--  ``FVP_Base_Cortex-A78C``
--  ``FVP_Base_Cortex-X2x4`` (Version 11.17/21)
--  ``FVP_Base_Neoverse-E1``
--  ``FVP_Base_Neoverse-N1``
--  ``FVP_Base_Neoverse-V1``
--  ``FVP_Base_RevC-2xAEMvA``
--  ``FVP_BaseR_AEMv8R``
--  ``FVP_Morello`` (Version 0.11/33)
--  ``FVP_RD_V1``
--  ``FVP_TC1``
--  ``FVP_TC2`` (Version 11.20/24)
-
-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
-CPU cores (64-bit host machine only).
-
--  ``FVP_Base_AEMvA``
--  ``FVP_Base_AEMvA-AEMvA``
--  ``FVP_Base_Cortex-A32x4``
-
-.. note::
-   The ``FVP_Base_RevC-2xAEMvA`` FVP only supports shifted affinities, which
-   is not compatible with legacy GIC configurations. Therefore this FVP does not
-   support these legacy GIC configurations.
-
-The *Foundation* and *Base* FVPs can be downloaded free of charge. See the `Arm
-FVP website`_. The Cortex-A models listed above are also available to download
-from `Arm's website`_.
-
-.. note::
-   The build numbers quoted above are those reported by launching the FVP
-   with the ``--version`` parameter.
-
-.. note::
-   Linaro provides a ramdisk image in prebuilt FVP configurations and full
-   file systems that can be downloaded separately. To run an FVP with a virtio
-   file system image an additional FVP configuration option
-   ``-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>`` can be
-   used.
-
-.. note::
-   The software will not work on Version 1.0 of the Foundation FVP.
-   The commands below would report an ``unhandled argument`` error in this case.
-
-.. note::
-   FVPs can be launched with ``--cadi-server`` option such that a
-   CADI-compliant debugger (for example, Arm DS-5) can connect to and control
-   its execution.
-
-.. warning::
-   Since FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
-   the internal synchronisation timings changed compared to older versions of
-   the models. The models can be launched with ``-Q 100`` option if they are
-   required to match the run time characteristics of the older versions.
-
-All the above platforms have been tested with `Linaro Release 20.01`_.
-
-.. _build_options_arm_fvp_platform:
-
-Arm FVP Platform Specific Build Options
----------------------------------------
-
--  ``FVP_CLUSTER_COUNT`` : Configures the cluster count to be used to
-   build the topology tree within TF-A. By default TF-A is configured for dual
-   cluster topology and this option can be used to override the default value.
-
--  ``FVP_INTERCONNECT_DRIVER``: Selects the interconnect driver to be built. The
-   default interconnect driver depends on the value of ``FVP_CLUSTER_COUNT`` as
-   explained in the options below:
-
-   -  ``FVP_CCI`` : The CCI driver is selected. This is the default
-      if 0 < ``FVP_CLUSTER_COUNT`` <= 2.
-   -  ``FVP_CCN`` : The CCN driver is selected. This is the default
-      if ``FVP_CLUSTER_COUNT`` > 2.
-
--  ``FVP_MAX_CPUS_PER_CLUSTER``: Sets the maximum number of CPUs implemented in
-   a single cluster.  This option defaults to 4.
-
--  ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
-   in the system. This option defaults to 1. Note that the build option
-   ``ARM_PLAT_MT`` doesn't have any effect on FVP platforms.
-
--  ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
-
-   -  ``FVP_GICV2`` : The GICv2 only driver is selected
-   -  ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
-
--  ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled
-   to DTB and packaged in FIP as the HW_CONFIG. See :ref:`Firmware Design` for
-   details on HW_CONFIG. By default, this is initialized to a sensible DTS
-   file in ``fdts/`` folder depending on other build options. But some cases,
-   like shifted affinity format for MPIDR, cannot be detected at build time
-   and this option is needed to specify the appropriate DTS file.
-
--  ``FVP_HW_CONFIG`` : Specify the path to the HW_CONFIG blob to be packaged in
-   FIP. See :ref:`Firmware Design` for details on HW_CONFIG. This option is
-   similar to the ``FVP_HW_CONFIG_DTS`` option, but it directly specifies the
-   HW_CONFIG blob instead of the DTS file. This option is useful to override
-   the default HW_CONFIG selected by the build system.
-
--  ``FVP_GICR_REGION_PROTECTION``: Mark the redistributor pages of
-   inactive/fused CPU cores as read-only. The default value of this option
-   is ``0``, which means the redistributor pages of all CPU cores are marked
-   as read and write.
-
-Booting Firmware Update images
-------------------------------
-
-When Firmware Update (FWU) is enabled there are at least 2 new images
-that have to be loaded, the Non-Secure FWU ROM (NS-BL1U), and the
-FWU FIP.
-
-The additional fip images must be loaded with:
-
-::
-
-    --data cluster0.cpu0="<path_to>/ns_bl1u.bin"@0x0beb8000	[ns_bl1u_base_address]
-    --data cluster0.cpu0="<path_to>/fwu_fip.bin"@0x08400000	[ns_bl2u_base_address]
-
-The address ns_bl1u_base_address is the value of NS_BL1U_BASE.
-In the same way, the address ns_bl2u_base_address is the value of
-NS_BL2U_BASE.
-
-Booting an EL3 payload
-----------------------
-
-The EL3 payloads boot flow requires the CPU's mailbox to be cleared at reset for
-the secondary CPUs holding pen to work properly. Unfortunately, its reset value
-is undefined on the FVP platform and the FVP platform code doesn't clear it.
-Therefore, one must modify the way the model is normally invoked in order to
-clear the mailbox at start-up.
-
-One way to do that is to create an 8-byte file containing all zero bytes using
-the following command:
-
-.. code:: shell
-
-    dd if=/dev/zero of=mailbox.dat bs=1 count=8
-
-and pre-load it into the FVP memory at the mailbox address (i.e. ``0x04000000``)
-using the following model parameters:
-
-::
-
-    --data cluster0.cpu0=mailbox.dat@0x04000000   [Base FVPs]
-    --data=mailbox.dat@0x04000000                 [Foundation FVP]
-
-To provide the model with the EL3 payload image, the following methods may be
-used:
-
-#. If the EL3 payload is able to execute in place, it may be programmed into
-   flash memory. On Base Cortex and AEM FVPs, the following model parameter
-   loads it at the base address of the NOR FLASH1 (the NOR FLASH0 is already
-   used for the FIP):
-
-   ::
-
-       -C bp.flashloader1.fname="<path-to>/<el3-payload>"
-
-   On Foundation FVP, there is no flash loader component and the EL3 payload
-   may be programmed anywhere in flash using method 3 below.
-
-#. When using the ``SPIN_ON_BL1_EXIT=1`` loading method, the following DS-5
-   command may be used to load the EL3 payload ELF image over JTAG:
-
-   ::
-
-       load <path-to>/el3-payload.elf
-
-#. The EL3 payload may be pre-loaded in volatile memory using the following
-   model parameters:
-
-   ::
-
-       --data cluster0.cpu0="<path-to>/el3-payload>"@address   [Base FVPs]
-       --data="<path-to>/<el3-payload>"@address                [Foundation FVP]
-
-   The address provided to the FVP must match the ``EL3_PAYLOAD_BASE`` address
-   used when building TF-A.
-
-Booting a preloaded kernel image (Base FVP)
--------------------------------------------
-
-The following example uses a simplified boot flow by directly jumping from the
-TF-A to the Linux kernel, which will use a ramdisk as filesystem. This can be
-useful if both the kernel and the device tree blob (DTB) are already present in
-memory (like in FVP).
-
-For example, if the kernel is loaded at ``0x80080000`` and the DTB is loaded at
-address ``0x82000000``, the firmware can be built like this:
-
-.. code:: shell
-
-    CROSS_COMPILE=aarch64-none-elf-  \
-    make PLAT=fvp DEBUG=1             \
-    RESET_TO_BL31=1                   \
-    ARM_LINUX_KERNEL_AS_BL33=1        \
-    PRELOADED_BL33_BASE=0x80080000    \
-    ARM_PRELOADED_DTB_BASE=0x82000000 \
-    all fip
-
-Now, it is needed to modify the DTB so that the kernel knows the address of the
-ramdisk. The following script generates a patched DTB from the provided one,
-assuming that the ramdisk is loaded at address ``0x84000000``. Note that this
-script assumes that the user is using a ramdisk image prepared for U-Boot, like
-the ones provided by Linaro. If using a ramdisk without this header,the ``0x40``
-offset in ``INITRD_START`` has to be removed.
-
-.. code:: bash
-
-    #!/bin/bash
-
-    # Path to the input DTB
-    KERNEL_DTB=<path-to>/<fdt>
-    # Path to the output DTB
-    PATCHED_KERNEL_DTB=<path-to>/<patched-fdt>
-    # Base address of the ramdisk
-    INITRD_BASE=0x84000000
-    # Path to the ramdisk
-    INITRD=<path-to>/<ramdisk.img>
-
-    # Skip uboot header (64 bytes)
-    INITRD_START=$(printf "0x%x" $((${INITRD_BASE} + 0x40)) )
-    INITRD_SIZE=$(stat -Lc %s ${INITRD})
-    INITRD_END=$(printf "0x%x" $((${INITRD_BASE} + ${INITRD_SIZE})) )
-
-    CHOSEN_NODE=$(echo                                        \
-    "/ {                                                      \
-            chosen {                                          \
-                    linux,initrd-start = <${INITRD_START}>;   \
-                    linux,initrd-end = <${INITRD_END}>;       \
-            };                                                \
-    };")
-
-    echo $(dtc -O dts -I dtb ${KERNEL_DTB}) ${CHOSEN_NODE} |  \
-            dtc -O dtb -o ${PATCHED_KERNEL_DTB} -
-
-And the FVP binary can be run with the following command:
-
-.. code:: shell
-
-    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C cluster0.NUM_CORES=4                                     \
-    -C cluster1.NUM_CORES=4                                     \
-    -C cache_state_modelled=1                                   \
-    -C cluster0.cpu0.RVBAR=0x04001000                           \
-    -C cluster0.cpu1.RVBAR=0x04001000                           \
-    -C cluster0.cpu2.RVBAR=0x04001000                           \
-    -C cluster0.cpu3.RVBAR=0x04001000                           \
-    -C cluster1.cpu0.RVBAR=0x04001000                           \
-    -C cluster1.cpu1.RVBAR=0x04001000                           \
-    -C cluster1.cpu2.RVBAR=0x04001000                           \
-    -C cluster1.cpu3.RVBAR=0x04001000                           \
-    --data cluster0.cpu0="<path-to>/bl31.bin"@0x04001000        \
-    --data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000   \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
-
-Obtaining the Flattened Device Trees
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Depending on the FVP configuration and Linux configuration used, different
-FDT files are required. FDT source files for the Foundation and Base FVPs can
-be found in the TF-A source directory under ``fdts/``. The Foundation FVP has
-a subset of the Base FVP components. For example, the Foundation FVP lacks
-CLCD and MMC support, and has only one CPU cluster.
-
-.. note::
-   It is not recommended to use the FDTs built along the kernel because not
-   all FDTs are available from there.
-
-The dynamic configuration capability is enabled in the firmware for FVPs.
-This means that the firmware can authenticate and load the FDT if present in
-FIP. A default FDT is packaged into FIP during the build based on
-the build configuration. This can be overridden by using the ``FVP_HW_CONFIG``
-or ``FVP_HW_CONFIG_DTS`` build options (refer to
-:ref:`build_options_arm_fvp_platform` for details on the options).
-
--  ``fvp-base-gicv2-psci.dts``
-
-   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
-   without shifted affinities and with Base memory map configuration.
-
--  ``fvp-base-gicv3-psci.dts``
-
-   For use with models such as the Cortex-A57-A53 or Cortex-A32 Base FVPs
-   without shifted affinities and with Base memory map configuration and
-   Linux GICv3 support.
-
--  ``fvp-base-gicv3-psci-1t.dts``
-
-   For use with models such as the AEMv8-RevC Base FVP with shifted affinities,
-   single threaded CPUs, Base memory map configuration and Linux GICv3 support.
-
--  ``fvp-base-gicv3-psci-dynamiq.dts``
-
-   For use with models as the Cortex-A55-A75 Base FVPs with shifted affinities,
-   single cluster, single threaded CPUs, Base memory map configuration and Linux
-   GICv3 support.
-
--  ``fvp-foundation-gicv2-psci.dts``
-
-   For use with Foundation FVP with Base memory map configuration.
-
--  ``fvp-foundation-gicv3-psci.dts``
-
-   (Default) For use with Foundation FVP with Base memory map configuration
-   and Linux GICv3 support.
-
-
-Running on the Foundation FVP with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``Foundation_Platform`` parameters should be used to boot Linux with
-4 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/Foundation_Platform                   \
-    --cores=4                                       \
-    --arm-v8.0                                      \
-    --secure-memory                                 \
-    --visualization                                 \
-    --gicv3                                         \
-    --data="<path-to>/<bl1-binary>"@0x0             \
-    --data="<path-to>/<FIP-binary>"@0x08000000      \
-    --data="<path-to>/<kernel-binary>"@0x80080000   \
-    --data="<path-to>/<ramdisk-binary>"@0x84000000
-
-Notes:
-
--  BL1 is loaded at the start of the Trusted ROM.
--  The Firmware Image Package is loaded at the start of NOR FLASH0.
--  The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
-   is specified via the ``load-address`` property in the ``hw-config`` node of
-   `FW_CONFIG for FVP`_.
--  The default use-case for the Foundation FVP is to use the ``--gicv3`` option
-   and enable the GICv3 device in the model. Note that without this option,
-   the Foundation FVP defaults to legacy (Versatile Express) memory map which
-   is not supported by TF-A.
--  In order for TF-A to run correctly on the Foundation FVP, the architecture
-   versions must match. The Foundation FVP defaults to the highest v8.x
-   version it supports but the default build for TF-A is for v8.0. To avoid
-   issues either start the Foundation FVP to use v8.0 architecture using the
-   ``--arm-v8.0`` option, or build TF-A with an appropriate value for
-   ``ARM_ARCH_MINOR``.
-
-Running on the AEMv8 Base FVP with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_RevC-2xAEMv8A                            \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cluster0.NUM_CORES=4                                     \
-    -C cluster1.NUM_CORES=4                                     \
-    -C cache_state_modelled=1                                   \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-.. note::
-   The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires
-   a specific DTS for all the CPUs to be loaded.
-
-Running on the AEMv8 Base FVP (AArch32) with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cluster0.NUM_CORES=4                                     \
-    -C cluster1.NUM_CORES=4                                     \
-    -C cache_state_modelled=1                                   \
-    -C cluster0.cpu0.CONFIG64=0                                 \
-    -C cluster0.cpu1.CONFIG64=0                                 \
-    -C cluster0.cpu2.CONFIG64=0                                 \
-    -C cluster0.cpu3.CONFIG64=0                                 \
-    -C cluster1.cpu0.CONFIG64=0                                 \
-    -C cluster1.cpu1.CONFIG64=0                                 \
-    -C cluster1.cpu2.CONFIG64=0                                 \
-    -C cluster1.cpu3.CONFIG64=0                                 \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
-boot Linux with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A57x4-A53x4                       \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cache_state_modelled=1                                   \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A32 Base FVP (AArch32) with reset to BL1 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
-boot Linux with 4 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A32x4                             \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cache_state_modelled=1                                   \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-
-Running on the AEMv8 Base FVP with reset to BL31 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_RevC-2xAEMv8A                             \
-    -C pctl.startup=0.0.0.0                                      \
-    -C bp.secure_memory=1                                        \
-    -C bp.tzc_400.diagnostics=1                                  \
-    -C cluster0.NUM_CORES=4                                      \
-    -C cluster1.NUM_CORES=4                                      \
-    -C cache_state_modelled=1                                    \
-    -C cluster0.cpu0.RVBAR=0x04010000                            \
-    -C cluster0.cpu1.RVBAR=0x04010000                            \
-    -C cluster0.cpu2.RVBAR=0x04010000                            \
-    -C cluster0.cpu3.RVBAR=0x04010000                            \
-    -C cluster1.cpu0.RVBAR=0x04010000                            \
-    -C cluster1.cpu1.RVBAR=0x04010000                            \
-    -C cluster1.cpu2.RVBAR=0x04010000                            \
-    -C cluster1.cpu3.RVBAR=0x04010000                            \
-    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Notes:
-
--  Position Independent Executable (PIE) support is enabled in this
-   config allowing BL31 to be loaded at any valid address for execution.
-
--  Since a FIP is not loaded when using BL31 as reset entrypoint, the
-   ``--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>``
-   parameter is needed to load the individual bootloader images in memory.
-   BL32 image is only needed if BL31 has been built to expect a Secure-EL1
-   Payload. For the same reason, the FDT needs to be compiled from the DT source
-   and loaded via the ``--data cluster0.cpu0="<path-to>/<fdt>"@0x82000000``
-   parameter.
-
--  The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
-   specific DTS for all the CPUs to be loaded.
-
--  The ``-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>`` parameter, where
-   X and Y are the cluster and CPU numbers respectively, is used to set the
-   reset vector for each core.
-
--  Changing the default value of ``ARM_TSP_RAM_LOCATION`` will also require
-   changing the value of
-   ``--data="<path-to><bl32-binary>"@<base-address-of-bl32>`` to the new value of
-   ``BL32_BASE``.
-
-
-Running on the AEMv8 Base FVP (AArch32) with reset to SP_MIN entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_AEMv8A-AEMv8A                             \
-    -C pctl.startup=0.0.0.0                                      \
-    -C bp.secure_memory=1                                        \
-    -C bp.tzc_400.diagnostics=1                                  \
-    -C cluster0.NUM_CORES=4                                      \
-    -C cluster1.NUM_CORES=4                                      \
-    -C cache_state_modelled=1                                    \
-    -C cluster0.cpu0.CONFIG64=0                                  \
-    -C cluster0.cpu1.CONFIG64=0                                  \
-    -C cluster0.cpu2.CONFIG64=0                                  \
-    -C cluster0.cpu3.CONFIG64=0                                  \
-    -C cluster1.cpu0.CONFIG64=0                                  \
-    -C cluster1.cpu1.CONFIG64=0                                  \
-    -C cluster1.cpu2.CONFIG64=0                                  \
-    -C cluster1.cpu3.CONFIG64=0                                  \
-    -C cluster0.cpu0.RVBAR=0x04002000                            \
-    -C cluster0.cpu1.RVBAR=0x04002000                            \
-    -C cluster0.cpu2.RVBAR=0x04002000                            \
-    -C cluster0.cpu3.RVBAR=0x04002000                            \
-    -C cluster1.cpu0.RVBAR=0x04002000                            \
-    -C cluster1.cpu1.RVBAR=0x04002000                            \
-    -C cluster1.cpu2.RVBAR=0x04002000                            \
-    -C cluster1.cpu3.RVBAR=0x04002000                            \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000    \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-.. note::
-   Position Independent Executable (PIE) support is enabled in this
-   config allowing SP_MIN to be loaded at any valid address for execution.
-
-Running on the Cortex-A57-A53 Base FVP with reset to BL31 entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
-boot Linux with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A57x4-A53x4                        \
-    -C pctl.startup=0.0.0.0                                      \
-    -C bp.secure_memory=1                                        \
-    -C bp.tzc_400.diagnostics=1                                  \
-    -C cache_state_modelled=1                                    \
-    -C cluster0.cpu0.RVBARADDR=0x04010000                        \
-    -C cluster0.cpu1.RVBARADDR=0x04010000                        \
-    -C cluster0.cpu2.RVBARADDR=0x04010000                        \
-    -C cluster0.cpu3.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu0.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu1.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu2.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu3.RVBARADDR=0x04010000                        \
-    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A32 Base FVP (AArch32) with reset to SP_MIN entrypoint
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
-boot Linux with 4 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A32x4                             \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cache_state_modelled=1                                   \
-    -C cluster0.cpu0.RVBARADDR=0x04002000                       \
-    -C cluster0.cpu1.RVBARADDR=0x04002000                       \
-    -C cluster0.cpu2.RVBARADDR=0x04002000                       \
-    -C cluster0.cpu3.RVBARADDR=0x04002000                       \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000   \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000   \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+  fvp-support
+  fvp-build-options
+  fvp-foundation
+  fvp-aemv8-base
+  fvp-cortex-a57-a53
+  fvp-cortex-a32
+  fvp-specific-configs
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
 
-.. _FW_CONFIG for FVP: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/arm/board/fvp/fdts/fvp_fw_config.dts
-.. _Arm's website: `FVP models`_
-.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
-.. _Linaro Release 20.01: http://releases.linaro.org/members/arm/platforms/20.01
-.. _Arm FVP website: https://developer.arm.com/products/system-design/fixed-virtual-platforms
+.. _model/: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/model
diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst
index 2f685222..35c0c598 100644
--- a/docs/plat/arm/index.rst
+++ b/docs/plat/arm/index.rst
@@ -14,6 +14,7 @@ Arm Development Platforms
    arm-build-options
    morello/index
    corstone1000/index
+   automotive_rd/index
 
 This chapter holds documentation related to Arm's development platforms,
 including both software models (FVPs) and hardware development boards
@@ -21,4 +22,4 @@ such as Juno.
 
 --------------
 
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index 5320a3b3..1e376960 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -56,7 +56,7 @@ installed.
 
 #. Obtain SCP binaries (Juno)
 
-   This version of TF-A is tested with SCP version 2.12.0 on Juno. You can
+   This version of TF-A is tested with SCP version 2.15.0 on Juno. You can
    download pre-built SCP binaries (``scp_bl1.bin`` and ``scp_bl2.bin``)
    from `TF-A downloads page`_. Alternatively, you can `build
    the binaries from source`_.
@@ -241,11 +241,11 @@ configure it.
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
 
 .. _Linaro release software stack: http://releases.linaro.org/members/arm/platforms/
 .. _Juno platform software user guide: https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/juno/user-guide.rst
-.. _TF-A downloads page: https://downloads.trustedfirmware.org/tf-a/css_scp_2.12.0/juno/
+.. _TF-A downloads page: https://downloads.trustedfirmware.org/tf-a/css_scp_2.15.0/juno/
 .. _build the binaries from source: https://github.com/ARM-software/SCP-firmware/blob/master/user_guide.md#scp-firmware-user-guide
 .. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
 .. _Juno Getting Started Guide: https://developer.arm.com/documentation/den0928/f/?lang=en
diff --git a/docs/plat/arm/tc/index.rst b/docs/plat/arm/tc/index.rst
index 9469e9ad..467738cd 100644
--- a/docs/plat/arm/tc/index.rst
+++ b/docs/plat/arm/tc/index.rst
@@ -13,13 +13,15 @@ Some of the features of TC platform referenced in TF-A include:
 - SCMI
 - MHUv2
 
-Currently, the main difference between TC0 (TARGET_PLATFORM=0), TC1
-(TARGET_PLATFORM=1), TC2 (TARGET_PLATFORM=2) platforms w.r.t to TF-A
-is the CPUs supported as below:
+The TF-A build is specified by the option `TARGET_PLATFORM` which represents
+the Total Compute platform number. The platforms support the CPU variants
+listed as below:
 
 -  TC0 has support for Cortex A510, Cortex A710 and Cortex X2. (Note TC0 is now deprecated)
 -  TC1 has support for Cortex A510, Cortex A715 and Cortex X3. (Note TC1 is now deprecated)
--  TC2 has support for Cortex A520, Cortex A720 and Cortex x4.
+-  TC2 has support for Cortex A520, Cortex A720 and Cortex x4. (Note TC2 is now deprecated)
+-  TC3 has support for Cortex A520, Cortex A725 and Cortex x925.
+
 
 Boot Sequence
 -------------
@@ -43,7 +45,7 @@ Build Procedure (TF-A only)
    .. code:: shell
 
       make PLAT=tc BL33=<path_to_uboot.bin> \
-      SCP_BL2=<path_to_scp_ramfw.bin> TARGET_PLATFORM={0,1,2} all fip
+      SCP_BL2=<path_to_scp_ramfw.bin> TARGET_PLATFORM={3} all fip
 
    Enable TBBR by adding the following options to the make command:
 
diff --git a/docs/plat/imx8ulp.rst b/docs/plat/imx8ulp.rst
new file mode 100644
index 00000000..b6b13e26
--- /dev/null
+++ b/docs/plat/imx8ulp.rst
@@ -0,0 +1,69 @@
+NXP i.MX 8ULP
+==================
+
+i.MX 8ULP is part of the ULP family with emphasis on extreme low-power techniques
+using the 28 nm fully depleted silicon on insulator process. Like i.MX 7ULP,
+i.MX 8ULP continues to be based on asymmetric architecture.
+
+The i.MX 8ULP family of processors features NXP’s advanced implementation of the
+dual Arm Cortex-A35 cores alongside an Arm Cortex-M33. This combined architecture
+enables the device to run a rich operating system (such as Linux) on the Cortex-A35
+core and an RTOS (such as FreeRTOS) on the Cortex-M33 core. It also includes a Cadence
+Tensilica Fusion DSP for low-power audio and a HiFi4 DSP for advanced audio and machine
+learning applications.
+
+The design enables clean separation between two processing domains, where each has
+separate power, clocking and peripheral islands, but the bus fabric of each domain
+is tightly integrated for efficient communication. The part is streamlined to minimize
+pin count, enabling small packages and simple system integration. This microprocessor
+is intended for applications where efficiency and simple system integration is important.
+`i.MX8ULP Applications Processors`_.
+
+Boot Sequence
+-------------
+
+BootROM --> SPL --> BL31 --> BL33(u-boot) --> Linux kernel
+
+How to build
+------------
+
+Build Procedure
+~~~~~~~~~~~~~~~
+
+-  Prepare AARCH64 toolchain.
+
+- Get the ELE FW image from NXP linux SDK package
+
+-  Build SPL and u-boot firstly, and get binary images: u-boot-spl.bin,
+   u-boot.bin and dtb
+
+-  Build TF-A
+
+   Build bl31:
+
+   .. code:: shell
+
+       CROSS_COMPILE=aarch64-linux-gnu- make PLAT=<Target_SoC> bl31
+
+   Target_SoC should be "imx8ulp" for i.MX8ULP SoC.
+
+Deploy TF-A Images
+~~~~~~~~~~~~~~~~~~
+
+TF-A binary(bl31.bin), u-boot-spl.bin u-boot.bin, ELE FW image are combined
+together to generate a binary file called flash.bin, the imx-mkimage tool is
+used to generate flash.bin, and flash.bin needs to be flashed into SD card
+with certain offset for BOOT ROM.
+
+Reference Documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Details on how to prepare, generate & deploy the boot image be found in following documents:
+
+- i.MX Linux User's Guide
+  `link <https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX>`__
+- i.MX Linux Reference Manual
+  `link <https://www.nxp.com/design/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX>`__
+
+.. _i.MX8ULP Applications Processors: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/i-mx-applications-processors/i-mx-8-applications-processors/i-mx-8ulp-applications-processor-family:i.MX8ULP
+
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index b1ccaa51..a8e0c8dc 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -7,6 +7,7 @@ Platform Ports
    :hidden:
 
    allwinner
+   amd-versal2
    arm/index
    ast2700
    meson-axg
@@ -27,7 +28,9 @@ Platform Ports
    warp7
    imx8
    imx8m
+   imx8ulp
    imx9
+   s32g274a
    npcm845x
    nxp/index
    poplar
@@ -37,6 +40,7 @@ Platform Ports
    qti-msm8916
    rpi3
    rpi4
+   rpi5
    rcar-gen3
    rz-g2
    rockchip
@@ -59,7 +63,6 @@ documentation associated with them.
 
    - Arm Neoverse N1 System Development Platform (N1SDP)
    - Arm Neoverse Reference Design N1 Edge (RD-N1-Edge) FVP
-   - Arm Neoverse Reference Design E1 Edge (RD-E1-Edge) FVP
    - Arm SGI-575
    - MediaTek MT8173 SoCs
 
@@ -69,21 +72,10 @@ Deprecated platforms
 +----------------+----------------+--------------------+--------------------+
 |    Platform    |     Vendor     | Deprecated version |  Deleted version   |
 +================+================+====================+====================+
-|    sgm775      |      Arm       |        2.5         |       2.7          |
-+----------------+----------------+--------------------+--------------------+
-|    mt6795      |      MTK       |        2.5         |       2.7          |
-+----------------+----------------+--------------------+--------------------+
-|    sgi575      |      Arm       |        2.8         |       TBD          |
-+----------------+----------------+--------------------+--------------------+
-|    rdn1edge    |      Arm       |        2.8         |       TBD          |
-+----------------+----------------+--------------------+--------------------+
-|    tc0         |      Arm       |        2.8         |       2.10         |
-+----------------+----------------+--------------------+--------------------+
-|    tc1         |      Arm       |        2.10        |       TBD          |
-+----------------+----------------+--------------------+--------------------+
-|    rde1edge    |      Arm       |        2.9         |       3.0          |
+|      TC2       |      Arm       |        2.12        |         TBD        |
+|                |                |                    |                    |
 +----------------+----------------+--------------------+--------------------+
 
 --------------
 
-*Copyright (c) 2019-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2024, Arm Limited. All rights reserved.*
diff --git a/docs/plat/mt8195.rst b/docs/plat/mt8195.rst
index b2aeea20..9810f9e4 100644
--- a/docs/plat/mt8195.rst
+++ b/docs/plat/mt8195.rst
@@ -2,8 +2,8 @@ MediaTek 8195
 =============
 
 MediaTek 8195 (MT8195) is a 64-bit ARM SoC introduced by MediaTek in 2021.
-The chip incorporates eight cores - four Cortex-A55 little cores and Cortex-A76.
-Cortex-A76 can operate at up to 2.2 GHz.
+The chip incorporates eight cores - four Cortex-A55 little cores and Cortex-A78.
+Cortex-A78 can operate at up to 2.6 GHz.
 Cortex-A55 can operate at up to 2.0 GHz.
 
 Boot Sequence
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
index b7c43fbe..384cd73d 100644
--- a/docs/plat/rockchip.rst
+++ b/docs/plat/rockchip.rst
@@ -10,6 +10,8 @@ This includes right now:
 -  rk3328: Quad-Core Cortex-A53
 -  rk3368: Octa-Core Cortex-A53
 -  rk3399: Hexa-Core Cortex-A53/A72
+-  rk3566/rk3568: Quad-Core Cortex-A55
+-  rk3588: Octa-Core Cortex-A55/A76
 
 
 Boot Sequence
@@ -35,7 +37,7 @@ these images need to get build from the TF-A repository.
 
 For AARCH64 architectures the build command looks like
 
-    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399 bl32
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399 bl31
 
 while AARCH32 needs a slightly different command
 
diff --git a/docs/plat/rpi5.rst b/docs/plat/rpi5.rst
new file mode 100644
index 00000000..f2e1b9f2
--- /dev/null
+++ b/docs/plat/rpi5.rst
@@ -0,0 +1,78 @@
+Raspberry Pi 5
+==============
+
+The `Raspberry Pi 5`_ is a single-board computer that contains four
+Arm Cortex-A76 cores.
+
+This port is a minimal BL31 implementation capable of booting 64-bit EL2
+payloads such as Linux and EDK2.
+
+**IMPORTANT NOTE**: This port isn't secure. All of the memory used is DRAM,
+which is available from both the Non-secure and Secure worlds. The SoC does
+not seem to feature a secure memory controller of any kind, so portions of
+DRAM can't be protected properly from the Non-secure world.
+
+Build
+------------------
+
+To build this platform, run:
+
+.. code:: shell
+
+    CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi5 DEBUG=1
+
+The firmware will be generated at ``build/rpi5/debug/bl31.bin``.
+
+The following build options are supported:
+
+- ``RPI3_DIRECT_LINUX_BOOT``: Enabled by default. Allows direct boot of the Linux
+  kernel from the firmware.
+
+- ``PRELOADED_BL33_BASE``: Used to specify the fixed address of a BL33 binary
+  that has been preloaded by earlier boot stages (VPU). Useful for bundling
+  BL31 and BL33 in the same ``armstub`` image (e.g. TF-A + EDK2).
+
+- ``RPI3_PRELOADED_DTB_BASE``: This option allows to specify the fixed address of
+  a DTB in memory. Can only be used if ``device_tree_address=`` is present in
+  config.txt.
+
+- ``RPI3_RUNTIME_UART``: Indicates whether TF-A should use the debug UART for
+  runtime messages or not. ``-1`` (default) disables the option, any other value
+  enables it.
+
+Usage
+------------------
+
+Copy the firmware binary to the first FAT32 partition of a supported boot media
+(SD, USB) and append ``armstub=bl31.bin`` to config.txt, or just rename the
+file to ``armstub8-2712.bin``.
+
+No other config options or files are required by the firmware alone, this will
+depend on the payload you intend to run.
+
+For Linux, you must also place an appropriate DTB and kernel in the boot
+partition. This has been validated with a copy of Raspberry Pi OS.
+
+The VPU will preload a BL33 AArch64 image named either ``kernel_2712.img`` or
+``kernel8.img``, which can be overridden by adding a ``kernel=filename`` option
+to config.txt.
+
+Kernel and DTB load addresses are also chosen by the VPU and can be changed with
+``kernel_address=`` and ``device_tree_address=`` in config.txt. If TF-A was built
+with ``PRELOADED_BL33_BASE`` or ``RPI3_PRELOADED_DTB_BASE``, setting those config
+options may be necessary.
+
+By default, all boot stages print messages to the dedicated UART debug port.
+Configuration is ``115200 8n1``.
+
+Design
+------------------
+
+This port is largely based on the RPi 4 one.
+
+The boot process is essentially the same, the only notable difference being that
+all VPU blobs have been moved into EEPROM (former start4.elf & fixup4.dat). There's
+also a custom BL31 TF-A armstub included for PSCI, which can be replaced with this
+port.
+
+.. _Raspberry Pi 5: https://www.raspberrypi.com/products/raspberry-pi-5/
diff --git a/docs/plat/s32g274a.rst b/docs/plat/s32g274a.rst
new file mode 100644
index 00000000..d3f31cab
--- /dev/null
+++ b/docs/plat/s32g274a.rst
@@ -0,0 +1,111 @@
+NXP S32G274A
+============
+
+S32G2 is an NXP vehicle network processor combining ASIL D safety, hardware
+security, high-performance real-time and application processing and network
+acceleration. S32G2 supports the needs of new vehicle architectures:
+service-oriented gateways, domain controllers, zonal processors, safety
+processors and more. It is equipped with 4 Cortex-A53 cores operating at
+1.0GHz.
+
+The TF-A includes support for one single S32G2-based board called S32G274ARDB2.
+The S32G-VNP-RDB2 is a compact, highly optimized and integrated board
+engineering for vehicle service-oriented gateway (SoG), domain control
+applications, high-performance processing, safety and security applications.
+More details about this board can be found at `s32g274ardb2`_.
+
+Boot Flow
+---------
+
+::
+
+   BootROM -> BL2 (SRAM) -> BL31 (SRAM) -> BL33 (DDR - TODO)
+
+.. warning::
+   This boot flow is a preliminary version that will serve as a foundation for
+   upcoming S32G2 contributions. The execution will hang after the BL31 stage
+   due to U-Boot being deployed in SRAM instead of DDR. This issue will be
+   resolved with the addition of the DDR driver.
+
+Code Locations
+--------------
+
+- Downstream TF-A:
+  `link: <https://github.com/nxp-auto-linux/arm-trusted-firmware>`__
+
+- Downstream U-Boot:
+  `link <https://github.com/nxp-auto-linux/u-boot>`__
+
+- Downstream Linux:
+  `link <https://github.com/nxp-auto-linux/linux>`__
+
+How to build
+------------
+
+The port currently available on the S32G274ARDB2 platform is in its initial
+stage. This means that important drivers like DDR and storage are not yet
+available. Consequently, the boot process depends on BootROM to load all TF-A
+stages in SRAM. To create a bootable image, the script below should be used.
+This script makes use of the ``mkimage`` tool, which is part of the U-Boot drop
+for S32G274A SoCs.
+
+.. code:: bash
+
+        #!/bin/bash -xe
+        TF_A="${TF_A:-`pwd`}"
+        UBOOT="${UBOOT:-${TF_A}/../u-boot}"
+        DEBUG="${DEBUG:-1}"
+
+        FIP_BASE="0x34100000"
+
+        if [ "${DEBUG}" -eq "1" ]; then
+                BUILD="debug"
+        else
+                BUILD="release"
+        fi
+
+        BOOT_IMAGE="build/s32g274ardb2/${BUILD}/BOOT_IMAGE.bin"
+        BL2_BIN="build/s32g274ardb2/${BUILD}/bl2.bin"
+        FIP_BIN="build/s32g274ardb2/${BUILD}/fip.bin"
+
+        # Generate bl2, bl31 and fip image
+        make -C "${TF_A}" -j9 'PLAT=s32g274ardb2' \
+                BL33="${UBOOT}/u-boot-nodtb.bin" DEBUG="${DEBUG}" clean
+        make -C "${TF_A}" -j9 'PLAT=s32g274ardb2' \
+                BL33="${UBOOT}/u-boot-nodtb.bin" DEBUG="${DEBUG}" bl2
+        make -C "${TF_A}" -j9 'PLAT=s32g274ardb2' \
+                BL33="${UBOOT}/u-boot-nodtb.bin" DEBUG="${DEBUG}" fip
+
+        # Extract BL2 entry
+        BL2_START="0x$(poetry run memory -p s32g274ardb2 -b debug -f | \
+                                grep BL2 | awk -F'|' '{print $3}' | xargs)"
+        # BL2 bin file size in bytes
+        BL2_SIZE="$(stat -c "%s" "${BL2_BIN}")"
+
+        # Pack bl2.bin and fip.bin by ensuring that the FIP image will start at FIP_BASE
+        cp -vf "${BL2_BIN}" "${BOOT_IMAGE}"
+        dd if="${FIP_BIN}" of="${BOOT_IMAGE}" seek="$((FIP_BASE - BL2_START))" bs=1
+
+        # Build a bootable image by appending the IVT
+        "${UBOOT}/tools/mkimage" \
+                -a "${BL2_START}" \
+                -e "${BL2_START}" \
+                -T s32ccimage \
+                -n "${UBOOT}/u-boot-s32.cfgout" \
+                -d "${BOOT_IMAGE}" \
+                fip.s32
+
+SoC Errata Workarounds
+----------------------
+
+The S32G274A port of the TF-A includes compilation flags that can be used to
+control the workaround for the SoC. These flags are used similarly to how the
+:ref:`arm_cpu_macros_errata_workarounds` are used. The list of workarounds
+includes the following switches:
+
+-  ``ERRATA_S32_051700``: This applies erratum ERR051700 workaround to
+   SoCs part of the S32 Common Chassis family, and therefore it needs to
+   be enabled for the S32G and S32R devices.
+
+.. _s32g2: https://www.nxp.com/products/processors-and-microcontrollers/s32-automotive-platform/s32g-vehicle-network-processors/s32g2-processors-for-vehicle-networking:S32G2
+.. _s32g274ardb2: https://www.nxp.com/design/design-center/designs/s32g2-vehicle-networking-reference-design:S32G-VNP-RDB2
diff --git a/docs/plat/st/stm32mp1.rst b/docs/plat/st/stm32mp1.rst
index b6e4b0d8..39a43eeb 100644
--- a/docs/plat/st/stm32mp1.rst
+++ b/docs/plat/st/stm32mp1.rst
@@ -115,8 +115,9 @@ ______
     make stm32mp15_trusted_defconfig
     make DEVICE_TREE=stm32mp157c-ev1 all
 
-OP-TEE (optional)
-_________________
+OP-TEE (recommended)
+____________________
+OP-TEE is the default BL32 supported for STMicroelectronics platforms.
 
 .. code:: bash
 
@@ -125,9 +126,10 @@ _________________
         CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts
 
 
-TF-A BL32 (SP_min)
-__________________
+TF-A BL32 (SP_min) (not recommended)
+____________________________________
 If you choose not to use OP-TEE, you can use TF-A SP_min.
+This is not the recommended BL32 to use, and will have very limited support.
 To build TF-A BL32, and its device tree file:
 
 .. code:: bash
@@ -217,4 +219,4 @@ __________________
 .. _STM32MP1 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp1-series.html
 .. _STM32MP1 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP15_microprocessor#Part_number_codification
 
-*Copyright (c) 2023, STMicroelectronics - All Rights Reserved*
+*Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/docs/plat/st/stm32mp2.rst b/docs/plat/st/stm32mp2.rst
index 43e131d7..87bb6a53 100644
--- a/docs/plat/st/stm32mp2.rst
+++ b/docs/plat/st/stm32mp2.rst
@@ -4,6 +4,8 @@ STM32MP2
 STM32MP2 is a microprocessor designed by STMicroelectronics
 based on Arm Cortex-A35.
 
+More information can be found on `STM32MP2 Series`_ page.
+
 For TF-A common configuration of STM32 MPUs, please check
 :ref:`STM32 MPUs` page.
 
@@ -19,11 +21,13 @@ The STM32MP25 series is available in 4 different lines which are pin-to-pin comp
 
 Each line comes with a security option (cryptography & secure boot) and a Cortex-A frequency option:
 
-- A      Basic + Cortex-A35 @ 1GHz
-- C      Secure Boot + HW Crypto + Cortex-A35 @ 1GHz
+- A      Basic + Cortex-A35 @ 1.2GHz
+- C      Secure Boot + HW Crypto + Cortex-A35 @ 1.2GHz
 - D      Basic + Cortex-A35 @ 1.5GHz
 - F      Secure Boot + HW Crypto + Cortex-A35 @ 1.5GHz
 
+The `STM32MP2 part number codification`_ page gives more information about part numbers.
+
 Memory mapping
 --------------
 
@@ -81,7 +85,8 @@ To compile the correct DDR driver, one flag must be set among:
 
 Boot with FIP
 ~~~~~~~~~~~~~
-You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) before building FIP binary.
+You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) and retrieve
+DDR PHY firmware before building FIP binary.
 
 U-Boot
 ______
@@ -102,9 +107,24 @@ ______
         ARCH=arm PLATFORM=stm32mp2 \
         CFG_EMBED_DTB_SOURCE_FILE=stm32mp257f-ev1.dts
 
-TF-A BL2 & BL31
-_______________
-To build TF-A BL2 with its STM32 header and BL31 for SD-card boot:
+DDR PHY firmware
+________________
+DDR PHY firmware files may not be delivered inside TF-A repository, especially
+if you build directly from trustedfirmware.org repository. It then needs to be
+retrieved from `STMicroelectronics DDR PHY github`_.
+
+You can either clone the repository to the default directory:
+
+.. code:: bash
+
+    git clone https://github.com/STMicroelectronics/stm32-ddr-phy-binary.git drivers/st/ddr/phy/firmware/bin
+
+Or clone it somewhere else, and add ``STM32MP_DDR_FW_PATH=`` in your make command
+line when building FIP.
+
+TF-A BL2
+________
+To build TF-A BL2 with its STM32 header for SD-card boot:
 
 .. code:: bash
 
@@ -130,4 +150,8 @@ ___
         BL32_EXTRA1=<optee_directory>/tee-pager_v2.bin
         fip
 
-*Copyright (c) 2023, STMicroelectronics - All Rights Reserved*
+.. _STM32MP2 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp2-series.html
+.. _STM32MP2 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP25_microprocessor#Part_number_codification
+.. _STMicroelectronics DDR PHY github: https://github.com/STMicroelectronics/stm32-ddr-phy-binary
+
+*Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/docs/plat/st/stm32mpus.rst b/docs/plat/st/stm32mpus.rst
index 931dd57f..7b471127 100644
--- a/docs/plat/st/stm32mpus.rst
+++ b/docs/plat/st/stm32mpus.rst
@@ -45,6 +45,8 @@ Serial boot devices:
 - ``STM32MP_UART_PROGRAMMER``
 - ``STM32MP_USB_PROGRAMMER``
 
+Only one storage or serial device should be selected in the build command line,
+to save space and not overflow SYSRAM size, or else the platform won't build or boot.
 
 Other configuration flags:
 
@@ -52,8 +54,6 @@ Other configuration flags:
   | Default: stm32mp157c-ev1.dtb
 - | ``DWL_BUFFER_BASE``: the 'serial boot' load address of FIP,
   | default location (end of the first 128MB) is used when absent
-- | ``STM32MP_EARLY_CONSOLE``: to enable early traces before clock driver is setup.
-  | Default: 0 (disabled)
 - | ``STM32MP_RECONFIGURE_CONSOLE``: to re-configure crash console (especially after BL2).
   | Default: 0 (disabled)
 - | ``STM32MP_UART_BAUDRATE``: to select UART baud rate.
@@ -75,4 +75,4 @@ Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition
 
 --------------
 
-*Copyright (c) 2023, STMicroelectronics - All Rights Reserved*
+*Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 1db7695b..d22a46d1 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -40,3 +40,72 @@ Xilinx Versal NET platform specific build options
 *   `TFA_NO_PM` : Platform Management support.
     -    0 : Enable Platform Management (Default)
     -    1 : Disable Platform Management
+
+*   `CPU_PWRDWN_SGI`: Select the SGI for triggering CPU power down request to
+                      secondary cores on receiving power down callback from
+                      firmware. Options:
+
+    -   `0`   : SGI 0
+    -   `1`   : SGI 1
+    -   `2`   : SGI 2
+    -   `3`   : SGI 3
+    -   `4`   : SGI 4
+    -   `5`   : SGI 5
+    -   `6`   : SGI 6 (Default)
+    -   `7`   : SGI 7
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+-----------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+------------------------------+------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------------------------------------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges for SiP SVC version 0.1
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+PM SMC call ranges for SiP SVC version 0.2
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000FFF                | Fast SMC64 SiP Service call used for pass-through of AMD-Xilinx Platform  |
+|                           | Management APIs to firmware                                               |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000A00-0xc2000AFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
+|                           | specific TF-A APIs                                                        |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index b71776d2..7185d910 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -14,11 +14,6 @@ To build:
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31
 ```
 
-To build ATF for different platform (supported are "silicon"(default) and "versal_virt")
-```bash
-make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal VERSAL_PLATFORM=versal_virt bl31
-```
-
 To build bl32 TSP you have to rebuild bl31 too
 ```bash
 make CROSS_COMPILE=aarch64-none-elf- PLAT=versal SPD=tspd RESET_TO_BL31=1 bl31 bl32
@@ -29,6 +24,11 @@ To build TF-A for JTAG DCC console
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31 VERSAL_CONSOLE=dcc
 ```
 
+To build TF-A with Errata management interface
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31 ERRATA_ABI_SUPPORT=1
+```
+
 To build TF-A with Straight-Line Speculation(SLS)
 ```bash
 make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31 HARDEN_SLS_ALL=1
@@ -46,10 +46,18 @@ Xilinx Versal platform specific build options
     -   `pl011`, `pl011_0`: ARM pl011 UART 0
     -   `pl011_1`         : ARM pl011 UART 1
 
-*   `VERSAL_PLATFORM`: Select the platform. Options:
-    -   `versal_virt`	: Versal Virtual platform
-    -   `spp_itr6`	: SPP ITR6
-    -   `emu_itr6`	: EMU ITR6
+*   `CPU_PWRDWN_SGI`: Select the SGI for triggering CPU power down request to
+                      secondary cores on receiving power down callback from
+                      firmware. Options:
+
+    -   `0`   : SGI 0
+    -   `1`   : SGI 1
+    -   `2`   : SGI 2
+    -   `3`   : SGI 3
+    -   `4`   : SGI 4
+    -   `5`   : SGI 5
+    -   `6`   : SGI 6 (Default)
+    -   `7`   : SGI 7
 
 # PLM->TF-A Parameter Passing
 ------------------------------
@@ -58,3 +66,59 @@ uses that data to hand off to the loaded images. The address of the handoff
 data structure is passed in the ```PMC_GLOBAL_GLOB_GEN_STORAGE4``` register.
 The register is free to be used by other software once the TF-A is bringing up
 further firmware images.
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+----------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+-------------------------------------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges for SiP SVC version 0.1
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+PM SMC call ranges for SiP SVC version 0.2
+--------------------------------------------------------
+
++---------------------------+---------------------------------------------------------------------------+
+|   SMC Function Identifier |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000FFF                | Fast SMC64 SiP Service call used for pass-through of AMD-Xilinx Platform  |
+|                           | Management APIs to firmware                                               |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000A00-0xc2000AFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
+|                           | specific TF-A APIs                                                        |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst
index 4fe0d2f8..c8ba27f6 100644
--- a/docs/plat/xilinx-zynqmp.rst
+++ b/docs/plat/xilinx-zynqmp.rst
@@ -166,3 +166,55 @@ Custom package makefile fragment inclusion in TF-A build
 - TF-A build command:
   make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1
   bl31 CUSTOM_PKG_PATH=<...>
+
+Reference DEN0028E SMC calling convention
+------------------------------------------
+
+Allocated subranges of Function Identifier to SIP services
+------------------------------------------------------------
+
++-----------------------+-------------------------------------------------------+
+|    SMC Function       | Identifier Service type                               |
++-----------------------+-------------------------------------------------------+
+| 0xC2000000-0xC200FFFF | Fast SMC64 SiP Service Calls as per SMCCC Section 6.1 |
++-----------------------+-------------------------------------------------------+
+
+IPI SMC call ranges
+-------------------
+
++---------------------------+-----------------------------------------------------------+
+| SMC Function Identifier   | Service type                                              |
++---------------------------+-----------------------------------------------------------+
+| 0xc2001000-0xc2001FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx IPI |
++---------------------------+-----------------------------------------------------------+
+
+PM SMC call ranges
+------------------
+
++---------------------------+---------------------------------------------------------------------------+
+| SMC Function Identifier   |  Service type                                                             |
++---------------------------+---------------------------------------------------------------------------+
+| 0xc2000000-0xc2000FFF     | Fast SMC64 SiP Service call range used for AMD-Xilinx Platform Management |
++---------------------------+---------------------------------------------------------------------------+
+
+SMC function IDs for SiP Service queries
+----------------------------------------
+
++--------------+--------------+--------------+
+|  Service     | Call UID     | Revision     |
++--------------+--------------+--------------+
+|  SiP Service | 0x8200_FF01  | 0x8200_FF03  |
++--------------+--------------+--------------+
+
+Call UID Query – Returns a unique identifier of the service provider.
+
+Revision Query – Returns revision details of the service implementor.
+
+CUSTOM SIP service support
+--------------------------
+
++-------------+------------+------------+
+| Service     | 32-bit     | 64-bit     |
++-------------+------------+------------+
+| SiP Service | 0x82002000 | 0xC2002000 |
++-------------+------------+------------+
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 7c66d111..5cb20fd9 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -256,10 +256,10 @@ likely to be suitable for all platform ports.
 
    Defines the maximum address in secure RAM that the BL31 image can occupy.
 
--  **#define : PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE**
+-  **#define : PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE**
 
-   Defines the maximum message size between AP and RSS. Need to define if
-   platform supports RSS.
+   Defines the maximum message size between AP and RSE. Need to define if
+   platform supports RSE.
 
 For every image, the platform must define individual identifiers that will be
 used by BL1 or BL2 to load the corresponding image into memory from non-volatile
@@ -1518,6 +1518,40 @@ When CONDITIONAL_CMO flag is enabled:
 - The function must not clobber x1, x2 and x3. It's also not safe to rely on
   stack. Otherwise obey AAPCS.
 
+Struct: plat_try_images_ops [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This optional structure holds platform hooks for alternative images load.
+It has to be defined in platform code and registered by calling
+plat_setup_try_img_ops() function, passing it the address of the
+plat_try_images_ops struct.
+
+Function : plat_setup_try_img_ops [optional]
+............................................
+
+::
+
+    Argument : const struct plat_try_images_ops *
+    Return   : void
+
+This optional function is called to register platform try images ops, given
+as argument.
+
+Function : plat_try_images_ops.next_instance [optional]
+.......................................................
+
+::
+
+    Argument : unsigned int image_id
+    Return   : int
+
+This optional function tries to load images from alternative places.
+In case PSA FWU is not used, it can be any instance or media. If PSA FWU is
+used, it is mandatory that the backup image is on the same media.
+This is required for MTD devices like NAND.
+The argument is the ID of the image for which we are looking for an alternative
+place. It returns 0 in case of success and a negative errno value otherwise.
+
 Modifications specific to a Boot Loader stage
 ---------------------------------------------
 
@@ -1607,9 +1641,6 @@ This function executes with the MMU and data caches enabled. It is responsible
 for performing any remaining platform-specific setup that can occur after the
 MMU and data cache have been enabled.
 
-if support for multiple boot sources is required, it initializes the boot
-sequence used by plat_try_next_boot_source().
-
 In Arm standard platforms, this function initializes the storage abstraction
 layer used to load the next bootloader image.
 
@@ -1712,6 +1743,18 @@ This function can be used by the platforms to update/use image information
 corresponding to ``image_id``. This function is invoked in BL1, both in cold
 boot and FWU code path, before loading the image.
 
+Function : bl1_plat_calc_bl2_layout() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : const meminfo_t *bl1_mem_layout, meminfo_t *bl2_mem_layout
+    Return   : void
+
+This utility function calculates the memory layout of BL2, representing it in a
+`meminfo_t` structure. The default implementation derives this layout from the
+positioning of BL1’s RW data at the top of the memory layout.
+
 Function : bl1_plat_handle_post_image_load() [optional]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1880,25 +1923,7 @@ Function : bl2_plat_preload_setup [optional]
 
 This optional function performs any BL2 platform initialization
 required before image loading, that is not done later in
-bl2_platform_setup(). Specifically, if support for multiple
-boot sources is required, it initializes the boot sequence used by
-plat_try_next_boot_source().
-
-Function : plat_try_next_boot_source() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
-    Argument : void
-    Return   : int
-
-This optional function passes to the next boot source in the redundancy
-sequence.
-
-This function moves the current boot redundancy source to the next
-element in the boot sequence. If there are no more boot sources then it
-must return 0, otherwise it must return 1. The default implementation
-of this always returns 0.
+bl2_platform_setup().
 
 Boot Loader Stage 2 (BL2) at EL3
 --------------------------------
@@ -2223,26 +2248,35 @@ Function : plat_rmmd_get_cca_attest_token() [mandatory when ENABLE_RME == 1]
 
 ::
 
-    Argument : uintptr_t, size_t *, uintptr_t, size_t
+    Argument : uintptr_t, size_t *, uintptr_t, size_t, size_t *
     Return   : int
 
-This function returns the Platform attestation token.
+This function returns the Platform attestation token. If the full token does
+not fit in the buffer, the function will return a hunk of the token and
+indicate how many bytes were copied and how many are pending. Multiple calls
+to this function may be needed to retrieve the entire token.
 
 The parameters of the function are:
 
     arg0 - A pointer to the buffer where the Platform token should be copied by
-           this function. The buffer must be big enough to hold the Platform
-           token.
+           this function. If the platform token does not completely fit in the
+           buffer, the function may return a piece of the token only.
 
-    arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
-           function returns the platform token length in this parameter.
+    arg1 - Contains the size (in bytes) of the buffer passed in arg0. In
+           addition, this parameter is used by the function to return the size
+           of the platform token length hunk copied to the buffer.
 
     arg2 - A pointer to the buffer where the challenge object is stored.
 
     arg3 - The length of the challenge object in bytes. Possible values are 32,
-           48 and 64.
+           48 and 64. This argument must be zero for subsequent calls to
+           retrieve the remaining hunks of the token.
 
-The function returns 0 on success, -EINVAL on failure.
+    arg4 - Returns the remaining length of the token (in bytes) that is yet to
+           be returned in further calls.
+
+The function returns 0 on success, -EINVAL on failure and -EAGAIN if the
+resource associated with the platform token retrieval is busy.
 
 Function : plat_rmmd_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2295,6 +2329,98 @@ RMM image and stores it in the area specified by manifest.
 
 When ENABLE_RME is disabled, this function is not used.
 
+Function : plat_rmmd_el3_token_sign_push_req() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Arguments : const struct el3_token_sign_request *req
+    Return    : int
+
+Queue realm attestation token signing request from the RMM in EL3. The interface between
+the RMM and EL3 is modeled as a queue but the underlying implementation may be different,
+so long as the semantics of queuing and the error codes are used as defined below.
+
+See :ref:`el3_token_sign_request_struct` for definition of the request structure.
+
+Optional interface from the RMM-EL3 interface v0.4 onwards.
+
+The parameters of the functions are:
+      arg0: Pointer to the token sign request to be pushed to EL3.
+      The structure must be located in the RMM-EL3 shared
+      memory buffer and must be locked before use.
+
+Return codes:
+        - E_RMM_OK	On Success.
+        - E_RMM_INVAL   If the arguments are invalid.
+        - E_RMM_AGAIN   Indicates that the request was not queued since the
+	  queue in EL3 is full. This may also be returned for any reason
+	  or situation in the system, that prevents accepting the request
+	  from the RMM.
+        - E_RMM_UNK     If the SMC is not implemented or if interface
+	  version is < 0.4.
+
+Function : plat_rmmd_el3_token_sign_pull_resp() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Arguments : struct el3_token_sign_response *resp
+    Return    : int
+
+Populate the attestation signing response in the ``resp`` parameter. The interface between
+the RMM and EL3 is modeled as a queue for responses but the underlying implementation may
+be different, so long as the semantics of queuing and the error codes are used as defined
+below.
+
+See :ref:`el3_token_sign_response_struct` for definition of the response structure.
+
+Optional interface from the RMM-EL3 interface v0.4 onwards.
+
+The parameters of the functions are:
+          resp: Pointer to the token sign response to get from EL3.
+	  The structure must be located in the RMM-EL3 shared
+	  memory buffer and must be locked before use.
+
+Return:
+        - E_RMM_OK      On Success.
+        - E_RMM_INVAL   If the arguments are invalid.
+        - E_RMM_AGAIN   Indicates that a response is not ready yet.
+        - E_RMM_UNK     If the SMC is not implemented or if interface
+	  version is < 0.4.
+
+Function : plat_rmmd_el3_token_sign_get_rak_pub() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uintptr_t, size_t *, unsigned int
+    Return   : int
+
+This function returns the public portion of the realm attestation key which will be used to
+sign Realm attestation token. Typically, with delegated attestation, the private key is
+returned, however, there may be platforms where the private key bits are better protected
+in a platform specific manner such that the private key is not exposed. In such cases,
+the RMM will only cache the public key and forward any requests such as signing, that
+uses the private key to EL3. The API currently only supports P-384 ECC curve key.
+
+This is an optional interface from the RMM-EL3 interface v0.4 onwards.
+
+The parameters of the function are:
+
+    arg0 - A pointer to the buffer where the public key should be copied
+    by this function. The buffer must be big enough to hold the
+    attestation key.
+
+    arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
+    function returns the attestation key length in this parameter.
+
+    arg2 - The type of the elliptic curve to which the requested attestation key
+    belongs.
+
+The function returns E_RMM_OK on success, RMM_E_INVAL if arguments are invalid and
+E_RMM_UNK if the SMC is not implemented or if interface version is < 0.4.
+
 Function : bl31_plat_enable_mmu [optional]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -3274,6 +3400,17 @@ This API is used by the crash reporting mechanism to force write of all buffered
 data on the designated crash console. It should only use general purpose
 registers x0 through x5 to do its work.
 
+Function : plat_setup_early_console [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : void
+    Return   : void
+
+This API is used to setup the early console, it is required only if the flag
+``EARLY_CONSOLE`` is enabled.
+
 .. _External Abort handling and RAS Support:
 
 External Abort handling and RAS Support
@@ -3560,7 +3697,7 @@ to :ref:`Measured Boot Design` for more details.
 
 --------------
 
-*Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
 
 .. _PSCI: https://developer.arm.com/documentation/den0022/latest/
 .. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
diff --git a/docs/process/code-review-guidelines.rst b/docs/process/code-review-guidelines.rst
index bd428113..5e9a6678 100644
--- a/docs/process/code-review-guidelines.rst
+++ b/docs/process/code-review-guidelines.rst
@@ -242,4 +242,4 @@ concerns, questions, or any other type of blocking comment, they should set
 
 *Copyright (c) 2020-2023, Arm Limited. All rights reserved.*
 
-.. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
+.. _Project Maintenance Process: https://trusted-firmware-docs.readthedocs.io/en/latest/generic_processes/project_maintenance_process.html
diff --git a/docs/process/coding-guidelines.rst b/docs/process/coding-guidelines.rst
index 97303905..0f207a62 100644
--- a/docs/process/coding-guidelines.rst
+++ b/docs/process/coding-guidelines.rst
@@ -520,5 +520,3 @@ comply with.
 .. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
 .. _`EditorConfig`: http://editorconfig.org/
 .. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
-.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
-.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods
diff --git a/docs/process/coding-style.rst b/docs/process/coding-style.rst
index 483780b3..4f1976f9 100644
--- a/docs/process/coding-style.rst
+++ b/docs/process/coding-style.rst
@@ -47,13 +47,13 @@ missing extensions are rarely used, however, and should not pose a problem.
 MISRA Compliance
 ----------------
 
-TF-A attempts to comply with the `MISRA C:2012 Guidelines`_. Coverity
-Static Analysis is used to regularly generate a report of current MISRA defects
-and to prevent the addition of new ones.
+TF-A attempts to comply with the `MISRA C:2012 Guidelines`_. `ECLAIR` static
+analysis is used to regularly generate a report of current MISRA defects and to
+prevent the addition of new ones.
 
-It is not possible for the project to follow all MISRA guidelines. We maintain
-`a spreadsheet`_ that lists all rules and directives and whether we aim to
-comply with them or not. A rationale is given for each deviation.
+It is not possible for the project to follow all MISRA guidelines. Table 1
+below lists all rules and directives and whether we aim to comply with them or
+not. A rationale is given for each deviation.
 
 .. note::
    Enforcing a rule does not mean that the codebase is free of defects
@@ -63,6 +63,9 @@ comply with them or not. A rationale is given for each deviation.
    Third-party libraries are not considered in our MISRA analysis and we do not
    intend to modify them to make them MISRA compliant.
 
+.. csv-table:: Table 1: MISRA compliance in TF-A code base
+   :file: misra-compliance.csv
+
 Indentation
 -----------
 
@@ -487,5 +490,4 @@ Existing typedefs will be retained for compatibility.
 *Copyright (c) 2020-2023, Arm Limited. All rights reserved.*
 
 .. _`Linux kernel coding style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
-.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
-.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods
+.. _`MISRA C:2012 Guidelines`: https://en.wikipedia.org/wiki/MISRA_C#MISRA_C:2012
diff --git a/docs/process/commit-style.rst b/docs/process/commit-style.rst
index d7e937be..c287599e 100644
--- a/docs/process/commit-style.rst
+++ b/docs/process/commit-style.rst
@@ -149,5 +149,5 @@ More details may be found in the `Gerrit Change-Ids documentation`_.
 .. _Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0
 .. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html
 .. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html
-.. _issue: https://developer.trustedfirmware.org/project/board/1/
+.. _issue: https://github.com/TrustedFirmware-A/trusted-firmware-a/issues
 .. _quick summary: https://www.conventionalcommits.org/en/v1.0.0/#summary
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index ef9ebd38..11bec7e4 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -4,11 +4,15 @@ Contributor's Guide
 Getting Started
 ===============
 
--  Make sure you have a Github account and you are logged on both
-   `developer.trustedfirmware.org`_ and `review.trustedfirmware.org`_.
+-  Make sure you have a Github account and you are logged on to
+   `review.trustedfirmware.org`_.
+
+   Also make sure that you have registered your full name and email address in
+   your `review.trustedfirmware.org`_ profile. Otherwise, the Gerrit server
+   might reject patches you attempt to post for review.
 
 -  If you plan to contribute a major piece of work, it is usually a good idea to
-   start a discussion around it on the mailing list. This gives everyone
+   start a discussion around it on the `TF-A mailing list`_. This gives everyone
    visibility of what is coming up, you might learn that somebody else is
    already working on something similar or the community might be able to
    provide some early input to help shaping the design of the feature.
@@ -17,16 +21,16 @@ Getting Started
    it explicitly in the email thread and ensure that the changes that include
    Third Party IP are made in a separate patch (or patch series).
 
--  Clone `Trusted Firmware-A`_ on your own machine as described in
+-  Clone the Trusted Firmware-A source code on your own machine as described in
    :ref:`prerequisites_get_source`.
 
--  Create a local topic branch based on the `Trusted Firmware-A`_ ``master``
+-  Create a local topic branch based on the Trusted Firmware-A ``master``
    branch.
 
 Making Changes
 ==============
 
--  Ensure commits adhere to the the project's :ref:`Commit Style`.
+-  Ensure commits adhere to the project's :ref:`Commit Style`.
 
 -  Make commits of logical units. See these general `Git guidelines`_ for
    contributing to a project.
@@ -93,13 +97,21 @@ Making Changes
 Submitting Changes
 ==================
 
--  Submit your changes for review at https://review.trustedfirmware.org
-   targeting the ``integration`` branch.
+.. note::
+   Please follow the `How to Contribute Code`_ section of the OpenCI
+   documentation for general instructions on setting up Gerrit and posting
+   patches there. The rest of this section provides details about patch
+   submission rules specifically for the TF-A project.
+
+-  Submit your changes for review using the ``git review`` command.
 
--  Add reviewers for your patch:
+   This will automatically rebase them onto the upstream ``integration`` branch,
+   as required by TF-A's patch submission process.
 
-   -  At least one code owner for each module modified by the patch. See the list
-      of modules and their :ref:`code owners`.
+-  From the Gerrit web UI, add reviewers for your patch:
+
+   -  At least one code owner for each module modified by the patch. See the
+      list of modules and their :ref:`code owners`.
 
    -  At least one maintainer. See the list of :ref:`maintainers`.
 
@@ -167,26 +179,54 @@ Submitting Changes
 Add CI Configurations
 =====================
 
--  TF-A uses Jenkins tool for Continuous Integration and testing activities.
-   Various CI Jobs are deployed which run tests on every patch before being
-   merged. So each of your patches go through a series of checks before they
-   get merged on to the master branch. Kindly ensure, that everytime you add
-   new files under your platform, they are covered under the following two sections:
+TF-A uses Jenkins for Continuous Integration and testing activities. Various CI
+jobs are deployed to run tests on every patch before being merged. Each of your
+patches go through a series of checks before they get merged on to the master
+branch. Kindly ensure that every time you add new files under your platform,
+they are covered by the following two sections.
 
 Coverity Scan
 -------------
 
--  ``Coverity Scan analysis`` is one of the tests we perform on our source code
-   at regular intervals. We maintain a build script ``tf-cov-make`` which contains the
-   build configurations of various platforms in order to cover the entire source
-   code being analysed by Coverity.
+The TF-A project makes use of `Coverity Scan` for static analysis, a service
+offered by Synopsys for open-source projects. This tool is able to find defects
+and vulnerabilities in a code base, such as dereferences of NULL pointers, use
+of uninitialized data, control flow issues and many other things.
+
+The TF-A source code is submitted daily to this service for analysis. Results of
+the latest and previous scans, as well as the complete list of defects it
+detected, are accessible online from
+https://scan.coverity.com/projects/arm-software-arm-trusted-firmware.
+
+The `tf-a-ci-scripts repository`_ contains scripts to run the Coverity Scan
+tools on the integration branch of the TF-A code base and make them available on
+https://scan.coverity.com. These scripts get executed daily by the
+`tf-a-coverity Jenkins job`_.
+
+In order to maintain a high level of coverage, including on newly introduced
+code, it is important to maintain the appropriate TF-A CI scripts. Details of
+when to update these scripts and how to do so follow.
+
+We maintain a build script - ``tf-cov-make`` - which contains the build
+configurations of various platforms in order to cover the entire source code
+being analysed by Coverity.
 
--  When you submit your patches for review containing new source files, please
-   ensure to include them for the ``Coverity Scan analysis`` by adding the
-   respective build configurations in the ``tf-cov-make`` build script.
+When you submit your patches for review, and if they contain new source files,
+`TF-A CI static checks job`_ might report that these files are not covered. In
+this case, the job's console output will show the following error message::
 
--  In this section you find the details on how to append your new build
-   configurations for Coverity scan analysis illustrated with examples:
+   ****** Newly added files detection check for Coverity Scan analysis on patch(es) ******
+
+   Result : FAILURE
+
+   New source files have been identified in your patch..
+   some/dir/file.c
+
+   please ensure to include them for the ``Coverity Scan analysis`` by adding
+   the respective build configurations in the ``tf-cov-make`` build script.
+
+In this section you find the details on how to append your new build
+configurations for Coverity scan analysis illustrated with examples:
 
 #. We maintain a separate repository named `tf-a-ci-scripts repository`_
    for placing all the test scripts which will be executed by the CI Jobs.
@@ -194,9 +234,9 @@ Coverity Scan
 #. In this repository, ``tf-cov-make`` script is located at
    ``tf-a-ci-scripts/script/tf-coverity/tf-cov-make``
 
-#. Edit `tf-cov-make`_ script by appending all the possible build configurations with
-   the specific ``build-flags`` relevant to your platform, so that newly added
-   source files get built and analysed by Coverity.
+#. Edit the `tf-cov-make`_ script by appending all the possible build
+   configurations with the specific build flags relevant to your platform, so
+   that newly added source files get built and analysed by Coverity.
 
 #. For better understanding follow the below specified examples listed in the
    ``tf-cov-make`` script.
@@ -220,45 +260,44 @@ Coverity Scan
     make PLAT=hikey960 $(common_flags) ${TBB_OPTIONS} all
     make PLAT=poplar $(common_flags) all
 
--  In this case for ``Hikey`` boards additional ``build-flags`` has been included
-   along with the ``commom_flags`` to cover most of the files relevant to it.
+-  In this case for ``Hikey`` boards additional build flags have been included
+   along with the ``common_flags`` to cover most of the files relevant to it.
 
 -  Similar to this you can still find many other different build configurations
    of various other platforms listed in the ``tf-cov-make`` script. Kindly refer
    them and append your build configurations respectively.
 
-Test Build Configuration (``tf-l1-build-plat``)
------------------------------------------------
-
--  Coverity Scan analysis, runs on a daily basis and will not be triggered for
-   every individual trusted-firmware patch.
+Test Build Configurations
+-------------------------
 
--  Considering this, we have other distinguished CI jobs which run a set of test
-   configurations on every patch, before they are being passed to ``Coverity scan analysis``.
+We have CI jobs which run a set of test configurations on every TF-A patch
+before they get merged upstream.
 
--  ``tf-l1-build-plat`` is the test group, which holds the test configurations
-   to build all the platforms. So be kind enough to verify that your newly added
-   files are built as part of one of the existing platform configurations present
-   in ``tf-l1-build-plat`` test group.
+At the bare minimum, TF-A code should build without any errors for every
+supported platform - and every feature of this platform. To make sure this is
+the case, we maintain a set of build tests. ``tf-l1-build-plat`` is the test
+group which holds all build tests for all platforms. So be kind enough to
+verify that your newly added files are covered by such a build test.
 
--  In this section you find the details on how to add the appropriate files,
-   needed to build your newly introduced platform as part of ``tf-l1-build-plat``
-   test group, illustrated with an example:
+If this is not the case, please follow the instructions below to add the
+appropriate files. We will illustrate this with an example for the ``Hikey``
+platform.
 
--  Lets consider ``Hikey`` platform:
-   In the `tf-a-ci-scripts repository`_ we need to add a build configuration file ``hikey-default``
-   under tf_config folder, ``tf_config/hikey-default`` listing all the build parameters
-   relevant to it.
+-  In the `tf-a-ci-scripts repository`_ we need to add a build configuration file
+   ``hikey-default`` under ``tf_config/`` folder. ``tf_config/hikey-default``
+   must list all the build parameters relevant to it.
 
 .. code:: shell
 
-   #Hikey Build Parameters
+   # Hikey Build Parameters
    CROSS_COMPILE=aarch64-none-elf-
    PLAT=hikey
 
--  Further a test-configuration file ``hikey-default:nil`` need to be added under the
-   test group, ``tf-l1-build-plat`` located at ``tf-a-ci-scripts/group/tf-l1-build-plat``,
-   to allow the platform to be built as part of this group.
+-  Further another file, ``hikey-default:nil``, needs to be added under
+   ``group/tf-l1-build-plat/`` folder to allow the platform to be built as part
+   of this test group. ``group/tf-l1-build-plat/hikey-default:nil`` file just
+   needs to exist but does not contain anything meaningful, apart from a
+   mandatory copyright notice:
 
 .. code:: shell
 
@@ -268,7 +307,11 @@ Test Build Configuration (``tf-l1-build-plat``)
    # SPDX-License-Identifier: BSD-3-Clause
    #
 
--  As illustrated above, you need to add the similar files supporting your platform.
+-  As illustrated above, you need to add similar files supporting your platform.
+
+For a more elaborate explanation of the TF-A CI scripts internals, including how
+to add more complex tests beyond a simple build test, please refer to the `TF-A
+CI scripts overview`_ section of the OpenCI documentation.
 
 Binary Components
 =================
@@ -289,11 +332,9 @@ Binary Components
 
 --------------
 
-*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.*
 
-.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
 .. _review.trustedfirmware.org: https://review.trustedfirmware.org
-.. _Trusted Firmware-A: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
 .. _Git guidelines: http://git-scm.com/book/ch5-2.html
 .. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html
 .. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io
@@ -302,3 +343,7 @@ Binary Components
 .. _TF-A mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
 .. _tf-a-ci-scripts repository: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/
 .. _tf-cov-make: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/script/tf-coverity/tf-cov-make
+.. _How to Contribute Code: https://tf-ci-users-guide.readthedocs.io/en/latest/#how-to-contribute-code
+.. _TF-A CI scripts overview: https://tf-ci-users-guide.readthedocs.io/en/latest/#tf-a-ci-scripts-overview
+.. _tf-a-coverity Jenkins job: https://ci.trustedfirmware.org/job/tf-a-coverity/
+.. _TF-A CI static checks job: https://ci.trustedfirmware.org/job/tf-a-static-checks/
diff --git a/docs/process/maintenance.rst b/docs/process/maintenance.rst
index 45aada26..5ee435e8 100644
--- a/docs/process/maintenance.rst
+++ b/docs/process/maintenance.rst
@@ -51,5 +51,5 @@ To put an individual's name up for election,
    and update the list of maintainers on the :ref:`Project
    Maintenance<maintainers>` page.
 
-.. _trustedfirmware.org Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
-.. _here: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/#how-to-become-a-maintainer
+.. _trustedfirmware.org Project Maintenance Process: https://trusted-firmware-docs.readthedocs.io/en/latest/generic_processes/project_maintenance_process.html
+.. _here: https://trusted-firmware-docs.readthedocs.io/en/latest/generic_processes/project_maintenance_process.html#how-to-become-a-maintainer
diff --git a/docs/process/misra-compliance.csv b/docs/process/misra-compliance.csv
new file mode 100644
index 00000000..7b029301
--- /dev/null
+++ b/docs/process/misra-compliance.csv
@@ -0,0 +1,174 @@
+Seq,Dir / Rule,Number,Source,Category,Checker Enabled,Enforced,Comments
+1,D,1.1,MISRA C 2012,Required,N/A,Yes,
+2,D,2.1,MISRA C 2012,Required,N/A,Yes,
+3,D,3.1,MISRA C 2012,Required,N/A,No,It can’t be done retroactively.
+4,D,4.1,MISRA C 2012,Required,N/A,Yes,
+5,D,4.2,MISRA C 2012,Advisory,N/A,Yes,
+6,D,4.3,MISRA C 2012,Required,Yes,Yes,
+7,D,4.4,MISRA C 2012,Advisory,Yes,Yes,
+8,D,4.5,MISRA C 2012,Advisory,Yes,Yes,
+9,D,4.6,MISRA C 2012,Advisory,No,No,We use a mix of both. It would be too disruptive for the project to change.
+10,D,4.7,MISRA C 2012,Required,Yes,Yes,
+11,D,4.8,MISRA C 2012,Advisory,No,No,Fixing all instances would involve invasive changes to the codebase for no good reason.
+12,D,4.9,MISRA C 2012,Advisory,No,No,"We mustn’t introduce new macros unless strictly needed, but this affects assert(), INFO(), etc. It creates too much noise in the report for little gain."
+13,D,4.10,MISRA C 2012,Required,Yes,Yes,
+14,D,4.11,MISRA C 2012,Required,Yes,Yes,
+15,D,4.12,MISRA C 2012,Required,Yes,Yes,
+16,D,4.13,MISRA C 2012,Advisory,Yes,Yes,
+17,D,4.14,MISRA C 2012 AMD-1,Required,Yes,Yes,
+18,R,1.1,MISRA C 2012,Required,Yes,Yes,
+19,R,1.2,MISRA C 2012,Advisory,Yes,Optional,It bans __attribute__(())  and similar helpers.
+20,R,1.3,MISRA C 2012,Required,N/A,Yes,
+21,R,2.1,MISRA C 2012,Required,Yes,Yes,
+22,R,2.2,MISRA C 2012,Required,Yes,Yes,
+23,R,2.3,MISRA C 2012,Advisory,Yes,Optional,It prevents the usage of CASSERT().
+24,R,2.4,MISRA C 2012,Advisory,No,No,Header files may use enumerations instead of defines to group sets of values.
+25,R,2.5,MISRA C 2012,Advisory,No,No,We define many headers with macros that are unused in the project but may be used by non-upstream code or may be desirable for completeness.
+26,R,2.6,MISRA C 2012,Advisory,Yes,Yes,
+27,R,2.7,MISRA C 2012,Advisory,No,No,Doesn't allow for simple implementations of porting functions that don't require all parameters.
+28,R,3.1,MISRA C 2012,Required,Yes,Yes,
+29,R,3.2,MISRA C 2012,Required,Yes,Yes,
+30,R,4.1,MISRA C 2012,Required,Yes,Yes,
+31,R,4.2,MISRA C 2012,Advisory,Yes,Yes,
+32,R,5.1,MISRA C 2012,Required,No,No,We use weak symbols that prevent us from complying with this rule.
+33,R,5.2,MISRA C 2012,Required,Yes,Yes,
+34,R,5.3,MISRA C 2012,Required,Yes,Yes,
+35,R,5.4,MISRA C 2012,Required,Yes,Yes,
+36,R,5.5,MISRA C 2012,Required,Yes,Yes,
+37,R,5.6,MISRA C 2012,Required,Yes,Yes,
+38,R,5.7,MISRA C 2012,Required,Yes,Optional,Fixing all existing defects is problematic because of compatibility issues.
+39,R,5.8,MISRA C 2012,Required,No,No,We use weak symbols that prevent us from complying with this rule.
+40,R,5.9,MISRA C 2012,Advisory,Yes,Yes,
+41,R,6.1,MISRA C 2012,Required,Yes,Yes,
+42,R,6.2,MISRA C 2012,Required,Yes,Yes,
+43,R,7.1,MISRA C 2012,Required,Yes,Yes,
+44,R,7.2,MISRA C 2012,Required,Yes,Yes,
+45,R,7.3,MISRA C 2012,Required,Yes,Yes,
+46,R,7.4,MISRA C 2012,Required,Yes,Yes,
+47,R,8.1,MISRA C 2012,Required,Yes,Yes,
+48,R,8.2,MISRA C 2012,Required,Yes,Yes,
+49,R,8.3,MISRA C 2012,Required,Yes,Yes,
+50,R,8.4,MISRA C 2012,Required,Yes,Yes,
+51,R,8.5,MISRA C 2012,Required,Yes,Yes,
+52,R,8.6,MISRA C 2012,Required,No,No,We use weak symbols that prevent us from complying with this rule.
+53,R,8.7,MISRA C 2012,Advisory,No,No,"Bans pattern of declaring funcs in private header that are used/defined in separate translation units, which seems over the top."
+54,R,8.8,MISRA C 2012,Required,Yes,Yes,
+55,R,8.9,MISRA C 2012,Advisory,Yes,Yes,
+56,R,8.10,MISRA C 2012,Required,Yes,Yes,
+57,R,8.11,MISRA C 2012,Advisory,Yes,Optional,This may not be possible in some interfaces.
+58,R,8.12,MISRA C 2012,Required,Yes,Yes,
+59,R,8.13,MISRA C 2012,Advisory,Yes,Optional,The benefits of fixing existing code aren’t worth the effort.
+60,R,8.14,MISRA C 2012,Required,Yes,Yes,
+61,R,9.1,MISRA C 2012,Mandatory,Yes,Yes,
+62,R,9.2,MISRA C 2012,Required,Yes,Yes,
+63,R,9.3,MISRA C 2012,Required,Yes,Yes,
+64,R,9.4,MISRA C 2012,Required,Yes,Yes,
+65,R,9.5,MISRA C 2012,Required,Yes,Yes,
+66,R,10.1,MISRA C 2012,Required,Yes,Optional,Fixing existing code may be counter-productive and introduce bugs.
+67,R,10.2,MISRA C 2012,Required,Yes,Yes,
+68,R,10.3,MISRA C 2012,Required,Yes,Optional,Fixing existing code may be counter-productive and introduce bugs.
+69,R,10.4,MISRA C 2012,Required,Yes,Optional,Fixing existing code may be counter-productive and introduce bugs.
+70,R,10.5,MISRA C 2012,Advisory,Yes,Yes,
+71,R,10.6,MISRA C 2012,Required,Yes,Yes,
+72,R,10.7,MISRA C 2012,Required,Yes,Yes,
+73,R,10.8,MISRA C 2012,Required,Yes,Yes,
+74,R,11.1,MISRA C 2012,Required,Yes,Yes,
+75,R,11.2,MISRA C 2012,Required,Yes,Yes,
+76,R,11.3,MISRA C 2012,Required,Yes,Yes,
+77,R,11.4,MISRA C 2012,Advisory,No,No,This would be invasive for TF (e.g. in exported linker script macros). Also bans conversion from uintptr_t.
+78,R,11.5,MISRA C 2012,Advisory,No,No,"This seems to preclude the pattern of using void * in interfaces to hide the real object, which we use extensively."
+79,R,11.6,MISRA C 2012,Required,Yes,Optional,This is needed in several cases.
+80,R,11.7,MISRA C 2012,Required,Yes,Yes,
+81,R,11.8,MISRA C 2012,Required,Yes,Yes,
+82,R,11.9,MISRA C 2012,Required,Yes,Yes,
+83,R,12.1,MISRA C 2012,Advisory,Yes,Yes,
+84,R,12.2,MISRA C 2012,Required,Yes,Yes,"This rule is fine, but there are lots of false positives in Coverity."
+85,R,12.3,MISRA C 2012,Advisory,Yes,Yes,
+86,R,12.4,MISRA C 2012,Advisory,Yes,Yes,
+87,R,12.5,MISRA C 2012 AMD-1,Mandatory,Yes,Yes,
+88,R,13.1,MISRA C 2012,Required,Yes,Yes,
+89,R,13.2,MISRA C 2012,Required,Yes,Yes,
+90,R,13.3,MISRA C 2012,Advisory,Yes,Yes,
+91,R,13.4,MISRA C 2012,Advisory,Yes,Yes,
+92,R,13.5,MISRA C 2012,Required,Yes,Yes,
+93,R,13.6,MISRA C 2012,Mandatory,Yes,Yes,
+94,R,14.1,MISRA C 2012,Required,Yes,Yes,
+95,R,14.2,MISRA C 2012,Required,Yes,Yes,
+96,R,14.3,MISRA C 2012,Required,Yes,Yes,
+97,R,14.4,MISRA C 2012,Required,Yes,Yes,
+98,R,15.1,MISRA C 2012,Advisory,No,No,In some cases goto may be useful for readability.
+99,R,15.2,MISRA C 2012,Required,Yes,Yes,
+100,R,15.3,MISRA C 2012,Required,Yes,Yes,
+101,R,15.4,MISRA C 2012,Advisory,Yes,Yes,
+102,R,15.5,MISRA C 2012,Advisory,No,No,This has no real value. It may make code less understandable than before.
+103,R,15.6,MISRA C 2012,Required,No,No,This directly contradicts the Linux style guidelines and would require many changes. We would have to remove that rule from checkpatch.
+104,R,15.7,MISRA C 2012,Required,Yes,Yes,
+105,R,16.1,MISRA C 2012,Required,No,No,Cannot comply with this unless we comply with 16.3
+106,R,16.2,MISRA C 2012,Required,Yes,Yes,
+107,R,16.3,MISRA C 2012,Required,No,No,Returns within switch statements and fall-throughs can improve readability.
+108,R,16.4,MISRA C 2012,Required,Yes,Yes,
+109,R,16.5,MISRA C 2012,Required,Yes,Yes,
+110,R,16.6,MISRA C 2012,Required,Yes,Yes,
+111,R,16.7,MISRA C 2012,Required,Yes,Yes,
+112,R,17.1,MISRA C 2012,Required,No,No,This is needed for printf.
+113,R,17.2,MISRA C 2012,Required,Yes,Yes,Bans recursion. We consider it acceptable if the max depth is known.
+114,R,17.3,MISRA C 2012,Mandatory,Yes,Yes,
+115,R,17.4,MISRA C 2012,Mandatory,Yes,Yes,
+116,R,17.5,MISRA C 2012,Advisory,Yes,Yes,
+117,R,17.6,MISRA C 2012,Mandatory,Yes,Yes,
+118,R,17.7,MISRA C 2012,Required,Yes,Optional,In some cases it doesn’t add any value to the code (like with memset() or printf()).
+119,R,17.8,MISRA C 2012,Advisory,Yes,Optional,It would make some one-line functions grow in size for no reason.
+120,R,18.1,MISRA C 2012,Required,Yes,Yes,
+121,R,18.2,MISRA C 2012,Required,Yes,Yes,
+122,R,18.3,MISRA C 2012,Required,Yes,Yes,
+123,R,18.4,MISRA C 2012,Advisory,Yes,Yes,
+124,R,18.5,MISRA C 2012,Advisory,Yes,Yes,
+125,R,18.6,MISRA C 2012,Required,Yes,Yes,
+126,R,18.7,MISRA C 2012,Required,Yes,Yes,
+127,R,18.8,MISRA C 2012,Required,Yes,Yes,
+128,R,19.1,MISRA C 2012,Mandatory,Yes,Yes,
+129,R,19.2,MISRA C 2012,Advisory,Yes,Optional,"Unions can be useful. We almost don’t use them, so it’s ok."
+130,R,20.1,MISRA C 2012,Advisory,Yes,Optional,In some files we have assembly-compatible includes followed by assembly-compatible definitions followed by C includes and C declarations. This is done to not have #ifdef in the include list.
+131,R,20.2,MISRA C 2012,Required,Yes,Yes,
+132,R,20.3,MISRA C 2012,Required,Yes,Yes,
+133,R,20.4,MISRA C 2012,Required,Yes,Yes,
+134,R,20.5,MISRA C 2012,Advisory,Yes,Yes,
+135,R,20.6,MISRA C 2012,Required,Yes,Yes,
+136,R,20.7,MISRA C 2012,Required,Yes,Yes,
+137,R,20.8,MISRA C 2012,Required,Yes,Optional,We need a new configuration system to fix all defects.
+138,R,20.9,MISRA C 2012,Required,Yes,Optional,"We use a mix of #if and #ifdef for boolean macros, which may raise some failures here. We should consistently use one or the other"
+139,R,20.10,MISRA C 2012,Advisory,Yes,Optional,"It’s good to avoid them, but they are sometimes needed."
+140,R,20.11,MISRA C 2012,Required,Yes,Yes,
+141,R,20.12,MISRA C 2012,Required,Yes,Yes,
+142,R,20.13,MISRA C 2012,Required,Yes,Yes,
+143,R,20.14,MISRA C 2012,Required,Yes,Yes,
+144,R,21.1,MISRA C 2012,Required,Yes,Yes,
+145,R,21.2,MISRA C 2012,Required,Yes,Yes,
+146,R,21.3,MISRA C 2012,Required,Yes,Yes,
+147,R,21.4,MISRA C 2012,Required,Yes,Yes,
+148,R,21.5,MISRA C 2012,Required,Yes,Yes,
+149,R,21.6,MISRA C 2012,Required,No,No,This bans printf.
+150,R,21.7,MISRA C 2012,Required,Yes,Yes,
+151,R,21.8,MISRA C 2012,Required,Yes,Yes,
+152,R,21.9,MISRA C 2012,Required,Yes,Yes,
+153,R,21.10,MISRA C 2012,Required,Yes,Yes,
+154,R,21.11,MISRA C 2012,Required,Yes,Yes,
+155,R,21.12,MISRA C 2012,Advisory,Yes,Yes,
+156,R,21.13,MISRA C 2012 AMD-1,Mandatory,Yes,Yes,
+157,R,21.14,MISRA C 2012 AMD-1,Required,Yes,Yes,
+158,R,21.15,MISRA C 2012 AMD-1,Required,Yes,Yes,
+159,R,21.16,MISRA C 2012 AMD-1,Required,Yes,Yes,
+160,R,21.17,MISRA C 2012 AMD-1,Mandatory,Yes,Yes,
+161,R,21.18,MISRA C 2012 AMD-1,Mandatory,Yes,Yes,
+162,R,21.19,MISRA C 2012 AMD-1,Mandatory,Yes,Yes,
+163,R,21.20,MISRA C 2012 AMD-1,Mandatory,Yes,Yes,
+164,R,22.1,MISRA C 2012,Required,Yes,Yes,
+165,R,22.2,MISRA C 2012,Mandatory,Yes,Yes,
+166,R,22.3,MISRA C 2012,Required,Yes,Yes,
+167,R,22.4,MISRA C 2012,Mandatory,Yes,Yes,
+168,R,22.5,MISRA C 2012,Mandatory,Yes,Yes,
+169,R,22.6,MISRA C 2012,Mandatory,Yes,Yes,
+170,R,22.7,MISRA C 2012 AMD-1,Required,Yes,Yes,
+171,R,22.8,MISRA C 2012 AMD-1,Required,Yes,Yes,
+172,R,22.9,MISRA C 2012 AMD-1,Required,Yes,Yes,
+173,R,22.10,MISRA C 2012 AMD-1,Required,Yes,Yes,
diff --git a/docs/process/security.rst b/docs/process/security.rst
index c6429ad5..1e7ac2ec 100644
--- a/docs/process/security.rst
+++ b/docs/process/security.rst
@@ -73,8 +73,10 @@ Security Advisories
 |  |TFV-10| | Incorrect validation of X.509 certificate extensions can result  |
 |           | in an out-of-bounds read                                         |
 +-----------+------------------------------------------------------------------+
+|  |TFV-11| |  A Malformed SDEI SMC can cause out of bound memory read         |
++-----------+------------------------------------------------------------------+
 
-.. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
+.. _issue tracker: https://github.com/TrustedFirmware-A/trusted-firmware-a/issues
 .. _mailing list: https://lists.trustedfirmware.org/mailman3/lists/tf-a.lists.trustedfirmware.org/
 
 .. |TFV-1| replace:: :ref:`Advisory TFV-1 (CVE-2016-10319)`
@@ -87,8 +89,9 @@ Security Advisories
 .. |TFV-8| replace:: :ref:`Advisory TFV-8 (CVE-2018-19440)`
 .. |TFV-9| replace:: :ref:`Advisory TFV-9 (CVE-2022-23960)`
 .. |TFV-10| replace:: :ref:`Advisory TFV-10 (CVE-2022-47630)`
+.. |TFV-11| replace:: :ref:`Advisory TFV-11 (CVE-2023-49100)`
 
-.. _TrustedFirmware.org security incident process: https://developer.trustedfirmware.org/w/collaboration/security_center/
+.. _TrustedFirmware.org security incident process: https://trusted-firmware-docs.readthedocs.io/en/latest/security_center/
 
 --------------
 
diff --git a/docs/resources/diagrams/context_init_coldboot.png b/docs/resources/diagrams/context_init_coldboot.png
new file mode 100644
index 0000000000000000000000000000000000000000..85606e451d9421da947fa1aa2c46a66d7b5e8dc4
GIT binary patch
literal 99885
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

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/context_init_warmboot.png b/docs/resources/diagrams/context_init_warmboot.png
new file mode 100644
index 0000000000000000000000000000000000000000..19f11e35a05f1e1abd9fd336774338dae99beb32
GIT binary patch
literal 97092
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
MtMaBq+Bo3<0OeG@<NyEw

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/context_memory_allocation.png b/docs/resources/diagrams/context_memory_allocation.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2e6a8e5c98e5d06203933a643754ab42843c4d7
GIT binary patch
literal 204249
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%0AyJ6;@r!lhF6i*?-%)u?oMdN
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

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/cot-dualroot.jpg b/docs/resources/diagrams/cot-dualroot.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..c56392eb64e08288e1782427cbfa679a66dad707
GIT binary patch
literal 134378
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
AQvd(}

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/cot-tbbr.jpg b/docs/resources/diagrams/cot-tbbr.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7ecd69d011c01e50eda823bea189c07c62ab02a8
GIT binary patch
literal 131981
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%0ACU3MUJw)WUz>@$(@r>
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

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/cpu_data_config_context_memory.png b/docs/resources/diagrams/cpu_data_config_context_memory.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e64dddf453739b448c0eae771a2dab9eb422857
GIT binary patch
literal 680091
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%0AAPeKz+6{G
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
YMQ?@^5)^-b4E(1ouO^ps-N5Vr0Q^gd@Bjb+

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/percpu-data-struct.png b/docs/resources/diagrams/percpu-data-struct.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8977d53dc2881b546f5e010276ac3396edd29d3
GIT binary patch
literal 207339
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
NIccRcnNkKf{vY9dR~G;P

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/plantuml/rss_attestation_flow.puml b/docs/resources/diagrams/plantuml/rse_attestation_flow.puml
similarity index 99%
rename from docs/resources/diagrams/plantuml/rss_attestation_flow.puml
rename to docs/resources/diagrams/plantuml/rse_attestation_flow.puml
index aca5c01f..9d7d7802 100644
--- a/docs/resources/diagrams/plantuml/rss_attestation_flow.puml
+++ b/docs/resources/diagrams/plantuml/rse_attestation_flow.puml
@@ -5,7 +5,7 @@ box AP
 participant RMM
 participant BL31
 endbox
-box RSS
+box RSE
 participant DelegAttest
 participant InitAttest
 participant MeasuredBoot
diff --git a/docs/resources/diagrams/plantuml/rse_measured_boot_flow.puml b/docs/resources/diagrams/plantuml/rse_measured_boot_flow.puml
new file mode 100644
index 00000000..97af5627
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/rse_measured_boot_flow.puml
@@ -0,0 +1,79 @@
+@startuml
+skinparam ParticipantPadding 10
+skinparam BoxPadding 10
+box RSE
+participant RSE_BL1_1
+participant RSE_BL1_2
+participant RSE_BL2
+participant RSE_S
+endbox
+box SCP
+participant SCP_BL1
+endbox
+box AP
+participant AP_BL1
+participant AP_BL2
+participant AP_BL31
+endbox
+
+== RSE Boot phase ==
+-> RSE_BL1_1: Reset
+Rnote over RSE_BL1_1: ROM code, XIP
+Rnote over RSE_BL1_2: OTP code, XIP
+Rnote over RSE_BL2, AP_BL31: Stored in flash, loaded and executed in RAM
+activate RSE_BL1_1 #Green
+RSE_BL1_1 -->> RSE_BL1_2: Validate, measure
+Rnote over RSE_BL1_1: BL1_2 measurement\n\ saved to a shared buffer
+RSE_BL1_1 -> RSE_BL1_2: Pass execution
+deactivate RSE_BL1_1
+activate RSE_BL1_2 #Green
+RSE_BL1_2 -->> RSE_BL2: Validate, measure, load
+Rnote over RSE_BL1_2: RSE_BL2 measurement\n\ saved to a shared buffer
+RSE_BL1_2 -> RSE_BL2: Pass execution
+deactivate RSE_BL1_2
+activate RSE_BL2 #Green
+RSE_BL2 -->> RSE_S: Validate, measure, load
+RSE_BL2 -->> SCP_BL1: Validate, measure, load
+Rnote over RSE_BL2: RSE_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer
+RSE_BL2 -> SCP_BL1: Release from reset
+activate SCP_BL1 #Green
+Rnote over RSE_BL2, SCP_BL1: MHU init between RSE and SCP
+Rnote over SCP_BL1: Configure memory
+Rnote over RSE_BL2: Waits for SCP
+SCP_BL1 --> RSE_BL2: Done
+RSE_BL2 -->> AP_BL1: Validate, measure, load
+Rnote over RSE_BL2: AP_BL1 measurement\n\ saved to a shared buffer
+RSE_BL2 -> AP_BL1: Release from reset
+activate AP_BL1 #Green
+RSE_BL2 -> RSE_S: Pass execution
+deactivate RSE_BL2
+activate RSE_S #Green
+Rnote over RSE_S: Measurements read from\n\ shared buffer and saved by\n\
+Measured Boot service to\n\ measurement slots.
+
+== RSE Runtime / AP Boot phase ==
+Rnote over RSE_S, AP_BL1: MHU init between RSE and AP
+Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG
+AP_BL1 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+AP_BL1 -->> AP_BL2: Validate, measure,load
+AP_BL1 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+AP_BL1 -> AP_BL2: Pass execution
+deactivate AP_BL1
+activate AP_BL2 #Green
+Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG
+AP_BL2 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+AP_BL2 -->> AP_BL31: Validate, measure,load
+Rnote over AP_BL2: Measure and load:\n\ BL31
+AP_BL2 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+Rnote over AP_BL2: Measure and load:\n\ RMM
+AP_BL2 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
+AP_BL2 -> AP_BL31: Pass execution
+deactivate AP_BL2
+activate AP_BL31 #Green
+== RSE / AP Runtime ==
+@enduml
diff --git a/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml b/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
deleted file mode 100644
index 1aeb1a9f..00000000
--- a/docs/resources/diagrams/plantuml/rss_measured_boot_flow.puml
+++ /dev/null
@@ -1,79 +0,0 @@
-@startuml
-skinparam ParticipantPadding 10
-skinparam BoxPadding 10
-box RSS
-participant RSS_BL1_1
-participant RSS_BL1_2
-participant RSS_BL2
-participant RSS_S
-endbox
-box SCP
-participant SCP_BL1
-endbox
-box AP
-participant AP_BL1
-participant AP_BL2
-participant AP_BL31
-endbox
-
-== RSS Boot phase ==
--> RSS_BL1_1: Reset
-Rnote over RSS_BL1_1: ROM code, XIP
-Rnote over RSS_BL1_2: OTP code, XIP
-Rnote over RSS_BL2, AP_BL31: Stored in flash, loaded and executed in RAM
-activate RSS_BL1_1 #Green
-RSS_BL1_1 -->> RSS_BL1_2: Validate, measure
-Rnote over RSS_BL1_1: BL1_2 measurement\n\ saved to a shared buffer
-RSS_BL1_1 -> RSS_BL1_2: Pass execution
-deactivate RSS_BL1_1
-activate RSS_BL1_2 #Green
-RSS_BL1_2 -->> RSS_BL2: Validate, measure, load
-Rnote over RSS_BL1_2: RSS_BL2 measurement\n\ saved to a shared buffer
-RSS_BL1_2 -> RSS_BL2: Pass execution
-deactivate RSS_BL1_2
-activate RSS_BL2 #Green
-RSS_BL2 -->> RSS_S: Validate, measure, load
-RSS_BL2 -->> SCP_BL1: Validate, measure, load
-Rnote over RSS_BL2: RSS_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer
-RSS_BL2 -> SCP_BL1: Release from reset
-activate SCP_BL1 #Green
-Rnote over RSS_BL2, SCP_BL1: MHU init between RSS and SCP
-Rnote over SCP_BL1: Configure memory
-Rnote over RSS_BL2: Waits for SCP
-SCP_BL1 --> RSS_BL2: Done
-RSS_BL2 -->> AP_BL1: Validate, measure, load
-Rnote over RSS_BL2: AP_BL1 measurement\n\ saved to a shared buffer
-RSS_BL2 -> AP_BL1: Release from reset
-activate AP_BL1 #Green
-RSS_BL2 -> RSS_S: Pass execution
-deactivate RSS_BL2
-activate RSS_S #Green
-Rnote over RSS_S: Measurements read from\n\ shared buffer and saved by\n\
-Measured Boot service to\n\ measurement slots.
-
-== RSS Runtime / AP Boot phase ==
-Rnote over RSS_S, AP_BL1: MHU init between RSS and AP
-Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG
-AP_BL1 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-AP_BL1 -->> AP_BL2: Validate, measure,load
-AP_BL1 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-AP_BL1 -> AP_BL2: Pass execution
-deactivate AP_BL1
-activate AP_BL2 #Green
-Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG
-AP_BL2 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-AP_BL2 -->> AP_BL31: Validate, measure,load
-Rnote over AP_BL2: Measure and load:\n\ BL31
-AP_BL2 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-Rnote over AP_BL2: Measure and load:\n\ RMM
-AP_BL2 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
-AP_BL2 -> AP_BL31: Pass execution
-deactivate AP_BL2
-activate AP_BL31 #Green
-== RSS / AP Runtime ==
-@enduml
diff --git a/docs/resources/diagrams/plantuml/tfa_rss_dfd.puml b/docs/resources/diagrams/plantuml/tfa_rse_dfd.puml
similarity index 89%
rename from docs/resources/diagrams/plantuml/tfa_rss_dfd.puml
rename to docs/resources/diagrams/plantuml/tfa_rse_dfd.puml
index a7e0ce57..68a80bfd 100644
--- a/docs/resources/diagrams/plantuml/tfa_rss_dfd.puml
+++ b/docs/resources/diagrams/plantuml/tfa_rse_dfd.puml
@@ -5,7 +5,7 @@
  '/
 
 /'
-TF-A Data Flow Diagram including RSS
+TF-A Data Flow Diagram including RSE
 '/
 
 @startuml
@@ -54,12 +54,12 @@ digraph tfa_dfd {
             bl31 [label="TF-A Runtime\n(BL31)" fillcolor="#ddffb3"]
         }
 
-        # RSS cluster
-        subgraph cluster_rss{
-            label ="RSS";
+        # RSE cluster
+        subgraph cluster_rse{
+            label ="RSE";
             graph [style=filled color="#000000" fillcolor="#faf9cd"]
 
-            rss [label="Runtime Security\n\ Subsystem\n\ (RSS)" fillcolor="#ddffb3"]
+            rse [label="Runtime Security\n\ Subsystem\n\ (RSE)" fillcolor="#ddffb3"]
         }
     }
 
@@ -70,7 +70,7 @@ digraph tfa_dfd {
     sec -> bl2 [dir="both" lhead=cluster_tfa label="DF4"]
     nsec -> bl1 [dir="both" lhead=cluster_tfa, label="DF5"]
     bl2 ->  tzc [dir="both" ltail=cluster_tfa lhead=cluster_ip label="DF6" minlen=1]
-    bl31 -> rss [dir="both" ltail=cluster_tfa lhead=cluster_rss label="DF7" minlen=1]
+    bl31 -> rse [dir="both" ltail=cluster_tfa lhead=cluster_rse label="DF7" minlen=1]
 
 }
 
diff --git a/docs/resources/diagrams/root_context_sequence.png b/docs/resources/diagrams/root_context_sequence.png
new file mode 100644
index 0000000000000000000000000000000000000000..67783f138cc64f799e09450ef372f8a6d40b14ef
GIT binary patch
literal 210925
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%0A9!z3SGB7*@5`<SxY=<xu
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

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/rss_attestation_flow.svg b/docs/resources/diagrams/rse_attestation_flow.svg
similarity index 99%
rename from docs/resources/diagrams/rss_attestation_flow.svg
rename to docs/resources/diagrams/rse_attestation_flow.svg
index 3728c6fb..7257576c 100644
--- a/docs/resources/diagrams/rss_attestation_flow.svg
+++ b/docs/resources/diagrams/rse_attestation_flow.svg
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1087px" preserveAspectRatio="none" style="width:900px;height:1087px;background:#FFFFFF;" version="1.1" viewBox="0 0 900 1087" width="900px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="261.5" x="44" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="164.75" y="18.0669">AP</text><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="502" x="364" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="601" y="18.0669">RSS</text><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="82" x2="82" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="266.5" x2="266.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="426" x2="426" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="553.5" x2="553.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="705" x2="705" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="822" x2="822" y1="56.4297" y2="1046.875"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="45.1279">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="1065.8701">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="45.1279">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="1065.8701">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="45.1279">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="1065.8701">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="45.1279">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="1065.8701">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="45.1279">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="1065.8701">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="45.1279">Crypto</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="1065.8701">Crypto</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="893" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="144" x="374.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="125" x="380.5" y="92.4966">RMM Boot phase</text><polygon fill="#181818" points="255,141.8281,265,145.8281,255,149.8281,259,145.8281" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="145.8281" y2="145.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="89" y="125.6294">get_realm_key(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="121" y="140.7622">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="195" y="140.7622">, ...)</text><polygon fill="#181818" points="414,170.9609,424,174.9609,414,178.9609,418,174.9609" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="174.9609" y2="174.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="274" y="169.895">get_delegated_key</text><polygon fill="#181818" points="693,200.0938,703,204.0938,693,208.0938,697,204.0938" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="699" y1="204.0938" y2="204.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="433" y="199.0278">read_measurement</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="167" x="342" y="217.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="95" x="346" y="233.1606">Compute input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="110" x="346" y="248.2935">for key derivation</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="159" x="346" y="263.4263">(hash of measurements)</text><polygon fill="#181818" points="810.5,292.625,820.5,296.625,810.5,300.625,814.5,296.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="816.5" y1="296.625" y2="296.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="68" x="433" y="291.5591">derive_key</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="150" x="351" y="309.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="355" y="325.6919">Compute public key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="60" x="355" y="340.8247">hash with</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="419" y="340.8247">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="4" x="493" y="340.8247">.</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="132" x="756" y="357.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="124" x="760" y="373.9575">Seed is provisioned</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="760" y="389.0903">in the factory.</text><polygon fill="#181818" points="278,418.2891,268,422.2891,278,426.2891,274,422.2891" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="422.2891" y2="422.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="284" y="417.2231">get_delegated_key</text><polygon fill="#181818" points="93,447.4219,83,451.4219,93,455.4219,89,451.4219" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="451.4219" y2="451.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="94" x="99" y="446.356">get_realm_key</text><rect fill="#FEFFDD" height="129" style="stroke:#181818;stroke-width:0.5;" width="154" x="5" y="464.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="102" x="9" y="480.4888">Only private key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="9" y="495.6216">is returned. Public</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="9" y="510.7544">key and its hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="9" y="525.8872">must be computed.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="541.02">Public key is included</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="9" y="556.1528">in the realm token.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="9" y="571.2856">Its hash is the input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="146" x="9" y="586.4185">for get_platform_token</text><polygon fill="#181818" points="255,630.75,265,634.75,255,638.75,259,634.75" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="634.75" y2="634.75"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="130" x="89" y="614.5513">get_platform_token(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="121" y="629.6841">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="225" y="629.6841">, ...)</text><polygon fill="#181818" points="414,659.8828,424,663.8828,414,667.8828,418,663.8828" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="663.8828" y2="663.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="274" y="658.8169">get_delegated_token</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="155" x="348" y="676.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="39" x="352" y="692.9497">Check</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="395" y="692.9497">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="352" y="708.0825">against derived key.</text><polygon fill="#181818" points="542,737.2813,552,741.2813,542,745.2813,546,741.2813" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="548" y1="741.2813" y2="741.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="433" y="736.2153">get_initial_token</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="181" x="463" y="754.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="168" x="467" y="770.3481">Create the token including</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="21" x="467" y="785.481">the</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="492" y="785.481">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="40" x="600" y="785.481">as the</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="467" y="800.6138">challenge claim</text><polygon fill="#181818" points="693,829.8125,703,833.8125,693,837.8125,697,833.8125" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="699" y1="833.8125" y2="833.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="561" y="828.7466">read_measurement</text><polygon fill="#181818" points="810.5,858.9453,820.5,862.9453,810.5,866.9453,814.5,862.9453" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="816.5" y1="862.9453" y2="862.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="69" x="561" y="857.8794">sign_token</text><polygon fill="#181818" points="437,888.0781,427,892.0781,437,896.0781,433,892.0781" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="431" x2="553" y1="892.0781" y2="892.0781"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="443" y="887.0122">get_initial_token</text><polygon fill="#181818" points="278,917.2109,268,921.2109,278,925.2109,274,921.2109" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="921.2109" y2="921.2109"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="284" y="916.145">get_delegated_token</text><polygon fill="#181818" points="93,946.3438,83,950.3438,93,954.3438,89,950.3438" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="950.3438" y2="950.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="99" y="945.2778">get_platform_token</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="116" x="24" y="963.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="108" x="28" y="979.4106">Platform token is</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="28" y="994.5435">cached. It is not</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="98" x="28" y="1009.6763">changing within</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="90" x="28" y="1024.8091">a power cycle.</text><!--MD5=[84fabec568a656165bea957fac178b53]
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1087px" preserveAspectRatio="none" style="width:900px;height:1087px;background:#FFFFFF;" version="1.1" viewBox="0 0 900 1087" width="900px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="261.5" x="44" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="164.75" y="18.0669">AP</text><rect fill="#DDDDDD" height="1075.1719" style="stroke:#181818;stroke-width:0.5;" width="502" x="364" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="601" y="18.0669">RSE</text><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="82" x2="82" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="266.5" x2="266.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="426" x2="426" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="553.5" x2="553.5" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="705" x2="705" y1="56.4297" y2="1046.875"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="822" x2="822" y1="56.4297" y2="1046.875"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="45.1279">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="48" x="58" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="34" x="65" y="1065.8701">RMM</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="45.1279">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="49" x="242.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="35" x="249.5" y="1065.8701">BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="45.1279">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="96" x="378" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="82" x="385" y="1065.8701">DelegAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="45.1279">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="516.5" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="523.5" y="1065.8701">InitAttest</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="45.1279">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="647" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="102" x="654" y="1065.8701">MeasuredBoot</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="45.1279">Crypto</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="59" x="793" y="1045.875"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="45" x="800" y="1065.8701">Crypto</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="893" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="893" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="144" x="374.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="125" x="380.5" y="92.4966">RMM Boot phase</text><polygon fill="#181818" points="255,141.8281,265,145.8281,255,149.8281,259,145.8281" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="145.8281" y2="145.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="89" y="125.6294">get_realm_key(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="121" y="140.7622">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="195" y="140.7622">, ...)</text><polygon fill="#181818" points="414,170.9609,424,174.9609,414,178.9609,418,174.9609" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="174.9609" y2="174.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="274" y="169.895">get_delegated_key</text><polygon fill="#181818" points="693,200.0938,703,204.0938,693,208.0938,697,204.0938" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="699" y1="204.0938" y2="204.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="433" y="199.0278">read_measurement</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="167" x="342" y="217.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="95" x="346" y="233.1606">Compute input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="110" x="346" y="248.2935">for key derivation</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="159" x="346" y="263.4263">(hash of measurements)</text><polygon fill="#181818" points="810.5,292.625,820.5,296.625,810.5,300.625,814.5,296.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="816.5" y1="296.625" y2="296.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="68" x="433" y="291.5591">derive_key</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="150" x="351" y="309.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="355" y="325.6919">Compute public key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="60" x="355" y="340.8247">hash with</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="74" x="419" y="340.8247">hash_algo</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="4" x="493" y="340.8247">.</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="132" x="756" y="357.8906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="124" x="760" y="373.9575">Seed is provisioned</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="760" y="389.0903">in the factory.</text><polygon fill="#181818" points="278,418.2891,268,422.2891,278,426.2891,274,422.2891" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="422.2891" y2="422.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="284" y="417.2231">get_delegated_key</text><polygon fill="#181818" points="93,447.4219,83,451.4219,93,455.4219,89,451.4219" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="451.4219" y2="451.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="94" x="99" y="446.356">get_realm_key</text><rect fill="#FEFFDD" height="129" style="stroke:#181818;stroke-width:0.5;" width="154" x="5" y="464.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="102" x="9" y="480.4888">Only private key</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="9" y="495.6216">is returned. Public</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="9" y="510.7544">key and its hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="126" x="9" y="525.8872">must be computed.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="541.02">Public key is included</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="9" y="556.1528">in the realm token.</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="9" y="571.2856">Its hash is the input</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="146" x="9" y="586.4185">for get_platform_token</text><polygon fill="#181818" points="255,630.75,265,634.75,255,638.75,259,634.75" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="82" x2="261" y1="634.75" y2="634.75"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="130" x="89" y="614.5513">get_platform_token(</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="121" y="629.6841">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="25" x="225" y="629.6841">, ...)</text><polygon fill="#181818" points="414,659.8828,424,663.8828,414,667.8828,418,663.8828" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="267" x2="420" y1="663.8828" y2="663.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="274" y="658.8169">get_delegated_token</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="155" x="348" y="676.8828"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="39" x="352" y="692.9497">Check</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="395" y="692.9497">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="352" y="708.0825">against derived key.</text><polygon fill="#181818" points="542,737.2813,552,741.2813,542,745.2813,546,741.2813" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="426" x2="548" y1="741.2813" y2="741.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="433" y="736.2153">get_initial_token</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="181" x="463" y="754.2813"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="168" x="467" y="770.3481">Create the token including</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="21" x="467" y="785.481">the</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="104" x="492" y="785.481">pub_key_hash</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="40" x="600" y="785.481">as the</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="99" x="467" y="800.6138">challenge claim</text><polygon fill="#181818" points="693,829.8125,703,833.8125,693,837.8125,697,833.8125" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="699" y1="833.8125" y2="833.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="127" x="561" y="828.7466">read_measurement</text><polygon fill="#181818" points="810.5,858.9453,820.5,862.9453,810.5,866.9453,814.5,862.9453" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="554" x2="816.5" y1="862.9453" y2="862.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="69" x="561" y="857.8794">sign_token</text><polygon fill="#181818" points="437,888.0781,427,892.0781,437,896.0781,433,892.0781" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="431" x2="553" y1="892.0781" y2="892.0781"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="104" x="443" y="887.0122">get_initial_token</text><polygon fill="#181818" points="278,917.2109,268,921.2109,278,925.2109,274,921.2109" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="272" x2="425" y1="921.2109" y2="921.2109"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="135" x="284" y="916.145">get_delegated_token</text><polygon fill="#181818" points="93,946.3438,83,950.3438,93,954.3438,89,950.3438" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="87" x2="266" y1="950.3438" y2="950.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="125" x="99" y="945.2778">get_platform_token</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="116" x="24" y="963.3438"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="108" x="28" y="979.4106">Platform token is</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="28" y="994.5435">cached. It is not</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="98" x="28" y="1009.6763">changing within</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="90" x="28" y="1024.8091">a power cycle.</text><!--MD5=[84fabec568a656165bea957fac178b53]
 @startuml
 skinparam ParticipantPadding 10
 skinparam BoxPadding 10
@@ -6,7 +6,7 @@ box AP
 participant RMM
 participant BL31
 endbox
-box RSS
+box RSE
 participant DelegAttest
 participant InitAttest
 participant MeasuredBoot
diff --git a/docs/resources/diagrams/rss_measured_boot_flow.svg b/docs/resources/diagrams/rse_measured_boot_flow.svg
similarity index 90%
rename from docs/resources/diagrams/rss_measured_boot_flow.svg
rename to docs/resources/diagrams/rse_measured_boot_flow.svg
index f5bf3113..0ccfbc2d 100644
--- a/docs/resources/diagrams/rss_measured_boot_flow.svg
+++ b/docs/resources/diagrams/rse_measured_boot_flow.svg
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1826px" preserveAspectRatio="none" style="width:1254px;height:1826px;background:#FFFFFF;" version="1.1" viewBox="0 0 1254 1826" width="1254px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="610.5" x="27" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="318.25" y="18.0669">RSS</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="103" x="659.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="29" x="696.5" y="18.0669">SCP</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="451.5" x="784.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="1000.25" y="18.0669">AP</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="86" x2="86" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="232" x2="232" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="413" x2="413" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="594.5" x2="594.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="710.5" x2="710.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="830.5" x2="830.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1007.5" x2="1007.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1185" x2="1185" y1="56.4297" y2="1785.7969"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="45.1279">RSS_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="1804.792">RSS_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="45.1279">RSS_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="1804.792">RSS_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="45.1279">RSS_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="1804.792">RSS_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="45.1279">RSS_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="1804.792">RSS_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="45.1279">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="1804.792">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="45.1279">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="1804.792">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="45.1279">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="1804.792">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="45.1279">AP_BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="1804.792">AP_BL31</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="136" x="555.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="117" x="561.5" y="92.4966">RSS Boot phase</text><polygon fill="#181818" points="69.5,126.6953,79.5,130.6953,69.5,134.6953,73.5,130.6953" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="0" x2="75.5" y1="130.6953" y2="130.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="36" x="7" y="125.6294">Reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="99" x="37" y="143.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="91" x="41" y="159.7622">ROM code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="95" x="185" y="176.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="87" x="189" y="192.895">OTP code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="861" x="368" y="209.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="281" x="658" y="226.0278">Stored in flash, loaded and executed in RAM</text><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="255.2266"/><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="263.2266"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="91.5" x2="231.5" y1="259.2266" y2="259.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="117" x="98.5" y="254.1606">Validate, measure</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="5" y="272.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="288.2935">BL1_2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="9" y="303.4263">saved to a shared buffer</text><polygon fill="#181818" points="215.5,332.625,225.5,336.625,215.5,340.625,219.5,336.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="86.5" x2="221.5" y1="336.625" y2="336.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="93.5" y="331.5591">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="361.7578"/><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="369.7578"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="237.5" x2="412.5" y1="365.7578" y2="365.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="244.5" y="360.6919">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="150" y="378.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="154" y="394.8247">RSS_BL2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="154" y="409.9575">saved to a shared buffer</text><polygon fill="#181818" points="396.5,439.1563,406.5,443.1563,396.5,447.1563,400.5,443.1563" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="232.5" x2="402.5" y1="443.1563" y2="443.1563"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="239.5" y="438.0903">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="468.2891"/><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="476.2891"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="593.5" y1="472.2891" y2="472.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="467.2231">Validate, measure, load</text><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="497.4219"/><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="505.4219"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="710" y1="501.4219" y2="501.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="496.356">Validate, measure, load</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="148" x="339" y="514.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="131" x="343" y="530.4888">RSS_S and SCP_BL1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="140" x="343" y="545.6216">measurements saved</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="343" y="560.7544">to a shared buffer</text><polygon fill="#181818" points="694,589.9531,704,593.9531,694,597.9531,698,593.9531" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="700" y1="593.9531" y2="593.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="588.8872">Release from reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="387" x="368" y="606.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="200" x="461.75" y="623.02">MHU init between RSS and SCP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="127" x="647" y="640.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="119" x="651" y="656.1528">Configure memory</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="93" x="367" y="673.2188"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="85" x="371" y="689.2856">Waits for SCP</text><polygon fill="#181818" points="429.5,718.4844,419.5,722.4844,429.5,726.4844,425.5,722.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="423.5" x2="705" y1="722.4844" y2="722.4844"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="34" x="435.5" y="717.4185">Done</text><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="747.6172"/><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="755.6172"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="830" y1="751.6172" y2="751.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="746.5513">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="331" y="764.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="143" x="335" y="780.6841">AP_BL1 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="335" y="795.8169">saved to a shared buffer</text><polygon fill="#181818" points="814,825.0156,824,829.0156,814,833.0156,818,829.0156" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="820" y1="829.0156" y2="829.0156"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="823.9497">Release from reset</text><polygon fill="#181818" points="577.5,854.1484,587.5,858.1484,577.5,862.1484,581.5,858.1484" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="413.5" x2="583.5" y1="858.1484" y2="858.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="420.5" y="853.0825">Pass execution</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="182" x="503" y="871.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="887.2153">Measurements read from</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="174" x="507" y="902.3481">shared buffer and saved by</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="917.481">Measured Boot service to</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="129" x="507" y="932.6138">measurement slots.</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="965.2461" y2="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="968.2461" y2="968.2461"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="237" x="505" y="954.6797"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="218" x="511" y="970.7466">RSS Runtime / AP Boot phase</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="313" x="556" y="992.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="191" x="617" y="1008.8794">MHU init between RSS and AP</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="126" x="768" y="1025.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="772" y="1042.0122">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="74" x="772" y="1057.145">FW_CONFIG</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="97" x="772" y="1072.2778">TB_FW_CONFIG</text><polygon fill="#181818" points="610.5,1101.4766,600.5,1105.4766,610.5,1109.4766,606.5,1105.4766" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1105.4766" y2="1105.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1100.4106">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1118.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1134.5435">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1149.6763">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1178.875"/><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1186.875"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="836" x2="1007" y1="1182.875" y2="1182.875"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="843" y="1177.8091">Validate, measure,load</text><polygon fill="#181818" points="610.5,1208.0078,600.5,1212.0078,610.5,1216.0078,606.5,1212.0078" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1212.0078" y2="1212.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1206.9419">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1225.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1241.0747">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1256.2075">store measurement</text><polygon fill="#181818" points="991,1285.4063,1001,1289.4063,991,1293.4063,995,1289.4063" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="831" x2="997" y1="1289.4063" y2="1289.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="838" y="1284.3403">Pass execution</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1302.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1318.4731">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="77" x="949" y="1333.606">HW_CONFIG</text><polygon fill="#181818" points="610.5,1362.8047,600.5,1366.8047,610.5,1370.8047,606.5,1366.8047" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1366.8047" y2="1366.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1361.7388">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1379.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1395.8716">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1411.0044">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1440.2031"/><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1448.2031"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="1013" x2="1184" y1="1444.2031" y2="1444.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="1020" y="1439.1372">Validate, measure,load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1457.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1473.27">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="32" x="949" y="1488.4028">BL31</text><polygon fill="#181818" points="610.5,1517.6016,600.5,1521.6016,610.5,1525.6016,606.5,1521.6016" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1521.6016" y2="1521.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1516.5356">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1534.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1550.6685">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1565.8013">store measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1582.8672"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1598.9341">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="30" x="949" y="1614.0669">RMM</text><polygon fill="#181818" points="610.5,1643.2656,600.5,1647.2656,610.5,1651.2656,606.5,1647.2656" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1647.2656" y2="1647.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1642.1997">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1660.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1676.3325">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1691.4653">store measurement</text><polygon fill="#181818" points="1168,1720.6641,1178,1724.6641,1168,1728.6641,1172,1724.6641" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="1008" x2="1174" y1="1724.6641" y2="1724.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="1015" y="1719.5981">Pass execution</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1753.2305" y2="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1756.2305" y2="1756.2305"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="148" x="549.5" y="1742.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="129" x="555.5" y="1758.731">RSS / AP Runtime</text><!--MD5=[e3f0ee259d2a4aa9c2a97ff856de0312]
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="1826px" preserveAspectRatio="none" style="width:1254px;height:1826px;background:#FFFFFF;" version="1.1" viewBox="0 0 1254 1826" width="1254px" zoomAndPan="magnify"><defs/><g><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="610.5" x="27" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="28" x="318.25" y="18.0669">RSE</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="103" x="659.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="29" x="696.5" y="18.0669">SCP</text><rect fill="#DDDDDD" height="1814.0938" style="stroke:#181818;stroke-width:0.5;" width="451.5" x="784.5" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="20" x="1000.25" y="18.0669">AP</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="86" x2="86" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="232" x2="232" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="413" x2="413" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="594.5" x2="594.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="710.5" x2="710.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="830.5" x2="830.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1007.5" x2="1007.5" y1="56.4297" y2="1785.7969"/><line style="stroke:#181818;stroke-width:0.5;stroke-dasharray:5.0,5.0;" x1="1185" x2="1185" y1="56.4297" y2="1785.7969"/><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="45.1279">RSE_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="41" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="48" y="1804.792">RSE_BL1_1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="45.1279">RSE_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="91" x="187" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="77" x="194" y="1804.792">RSE_BL1_2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="45.1279">RSE_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="376" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="383" y="1804.792">RSE_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="45.1279">RSE_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="58" x="565.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="572.5" y="1804.792">RSE_S</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="45.1279">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="75" x="673.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="61" x="680.5" y="1804.792">SCP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="45.1279">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="798.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="805.5" y="1804.792">AP_BL1</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="45.1279">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="65" x="975.5" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="51" x="982.5" y="1804.792">AP_BL2</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="45.1279">AP_BL31</text><rect fill="#E2E2F0" height="30.2969" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="74" x="1148" y="1784.7969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="1155" y="1804.792">AP_BL31</text><rect fill="#008000" height="205.9297" style="stroke:#181818;stroke-width:1.0;" width="10" x="81.5" y="130.6953"/><rect fill="#008000" height="106.5313" style="stroke:#181818;stroke-width:1.0;" width="10" x="227.5" y="336.625"/><rect fill="#008000" height="414.9922" style="stroke:#181818;stroke-width:1.0;" width="10" x="408.5" y="443.1563"/><rect fill="#008000" height="918.6484" style="stroke:#181818;stroke-width:1.0;" width="10" x="589.5" y="858.1484"/><rect fill="#008000" height="1182.8438" style="stroke:#181818;stroke-width:1.0;" width="10" x="706" y="593.9531"/><rect fill="#008000" height="460.3906" style="stroke:#181818;stroke-width:1.0;" width="10" x="826" y="829.0156"/><rect fill="#008000" height="435.2578" style="stroke:#181818;stroke-width:1.0;" width="10" x="1003" y="1289.4063"/><rect fill="#008000" height="52.1328" style="stroke:#181818;stroke-width:1.0;" width="10" x="1180" y="1724.6641"/><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="86.9961" y2="86.9961"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="89.9961" y2="89.9961"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="136" x="555.5" y="76.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="117" x="561.5" y="92.4966">RSE Boot phase</text><polygon fill="#181818" points="69.5,126.6953,79.5,130.6953,69.5,134.6953,73.5,130.6953" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="0" x2="75.5" y1="130.6953" y2="130.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="36" x="7" y="125.6294">Reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="99" x="37" y="143.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="91" x="41" y="159.7622">ROM code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="95" x="185" y="176.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="87" x="189" y="192.895">OTP code, XIP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="861" x="368" y="209.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="281" x="658" y="226.0278">Stored in flash, loaded and executed in RAM</text><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="255.2266"/><line style="stroke:#181818;stroke-width:1.0;" x1="230.5" x2="220.5" y1="259.2266" y2="263.2266"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="91.5" x2="231.5" y1="259.2266" y2="259.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="117" x="98.5" y="254.1606">Validate, measure</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="5" y="272.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="134" x="9" y="288.2935">BL1_2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="9" y="303.4263">saved to a shared buffer</text><polygon fill="#181818" points="215.5,332.625,225.5,336.625,215.5,340.625,219.5,336.625" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="86.5" x2="221.5" y1="336.625" y2="336.625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="93.5" y="331.5591">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="361.7578"/><line style="stroke:#181818;stroke-width:1.0;" x1="411.5" x2="401.5" y1="365.7578" y2="369.7578"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="237.5" x2="412.5" y1="365.7578" y2="365.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="244.5" y="360.6919">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="150" y="378.7578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="154" y="394.8247">RSE_BL2 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="154" y="409.9575">saved to a shared buffer</text><polygon fill="#181818" points="396.5,439.1563,406.5,443.1563,396.5,447.1563,400.5,443.1563" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="232.5" x2="402.5" y1="443.1563" y2="443.1563"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="239.5" y="438.0903">Pass execution</text><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="468.2891"/><line style="stroke:#181818;stroke-width:1.0;" x1="592.5" x2="582.5" y1="472.2891" y2="476.2891"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="593.5" y1="472.2891" y2="472.2891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="467.2231">Validate, measure, load</text><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="497.4219"/><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="699" y1="501.4219" y2="505.4219"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="710" y1="501.4219" y2="501.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="496.356">Validate, measure, load</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="148" x="339" y="514.4219"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="131" x="343" y="530.4888">RSE_S and SCP_BL1</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="140" x="343" y="545.6216">measurements saved</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="114" x="343" y="560.7544">to a shared buffer</text><polygon fill="#181818" points="694,589.9531,704,593.9531,694,597.9531,698,593.9531" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="700" y1="593.9531" y2="593.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="588.8872">Release from reset</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="387" x="368" y="606.9531"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="200" x="461.75" y="623.02">MHU init between RSE and SCP</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="127" x="647" y="640.0859"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="119" x="651" y="656.1528">Configure memory</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="93" x="367" y="673.2188"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="85" x="371" y="689.2856">Waits for SCP</text><polygon fill="#181818" points="429.5,718.4844,419.5,722.4844,429.5,726.4844,425.5,722.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="423.5" x2="705" y1="722.4844" y2="722.4844"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="34" x="435.5" y="717.4185">Done</text><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="747.6172"/><line style="stroke:#181818;stroke-width:1.0;" x1="829" x2="819" y1="751.6172" y2="755.6172"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="418.5" x2="830" y1="751.6172" y2="751.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="152" x="425.5" y="746.5513">Validate, measure, load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="164" x="331" y="764.6172"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="143" x="335" y="780.6841">AP_BL1 measurement</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="335" y="795.8169">saved to a shared buffer</text><polygon fill="#181818" points="814,825.0156,824,829.0156,814,833.0156,818,829.0156" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="418.5" x2="820" y1="829.0156" y2="829.0156"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="121" x="425.5" y="823.9497">Release from reset</text><polygon fill="#181818" points="577.5,854.1484,587.5,858.1484,577.5,862.1484,581.5,858.1484" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="413.5" x2="583.5" y1="858.1484" y2="858.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="420.5" y="853.0825">Pass execution</text><rect fill="#FEFFDD" height="68" style="stroke:#181818;stroke-width:0.5;" width="182" x="503" y="871.1484"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="887.2153">Measurements read from</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="174" x="507" y="902.3481">shared buffer and saved by</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="507" y="917.481">Measured Boot service to</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="129" x="507" y="932.6138">measurement slots.</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="965.2461" y2="965.2461"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="968.2461" y2="968.2461"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="237" x="505" y="954.6797"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="218" x="511" y="970.7466">RSE Runtime / AP Boot phase</text><rect fill="#FEFFDD" height="23" style="stroke:#181818;stroke-width:0.5;" width="313" x="556" y="992.8125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="191" x="617" y="1008.8794">MHU init between RSE and AP</text><rect fill="#FEFFDD" height="53" style="stroke:#181818;stroke-width:0.5;" width="126" x="768" y="1025.9453"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="772" y="1042.0122">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="74" x="772" y="1057.145">FW_CONFIG</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="97" x="772" y="1072.2778">TB_FW_CONFIG</text><polygon fill="#181818" points="610.5,1101.4766,600.5,1105.4766,610.5,1109.4766,606.5,1105.4766" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1105.4766" y2="1105.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1100.4106">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1118.4766"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1134.5435">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1149.6763">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1178.875"/><line style="stroke:#181818;stroke-width:1.0;" x1="1006" x2="996" y1="1182.875" y2="1186.875"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="836" x2="1007" y1="1182.875" y2="1182.875"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="843" y="1177.8091">Validate, measure,load</text><polygon fill="#181818" points="610.5,1208.0078,600.5,1212.0078,610.5,1216.0078,606.5,1212.0078" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="825" y1="1212.0078" y2="1212.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1206.9419">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1225.0078"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1241.0747">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1256.2075">store measurement</text><polygon fill="#181818" points="991,1285.4063,1001,1289.4063,991,1293.4063,995,1289.4063" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="831" x2="997" y1="1289.4063" y2="1289.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="838" y="1284.3403">Pass execution</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1302.4063"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1318.4731">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="77" x="949" y="1333.606">HW_CONFIG</text><polygon fill="#181818" points="610.5,1362.8047,600.5,1366.8047,610.5,1370.8047,606.5,1366.8047" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1366.8047" y2="1366.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1361.7388">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1379.8047"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1395.8716">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1411.0044">store measurement</text><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1440.2031"/><line style="stroke:#181818;stroke-width:1.0;" x1="1183" x2="1173" y1="1444.2031" y2="1448.2031"/><line style="stroke:#181818;stroke-width:1.0;stroke-dasharray:2.0,2.0;" x1="1013" x2="1184" y1="1444.2031" y2="1444.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="148" x="1020" y="1439.1372">Validate, measure,load</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1457.2031"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1473.27">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="32" x="949" y="1488.4028">BL31</text><polygon fill="#181818" points="610.5,1517.6016,600.5,1521.6016,610.5,1525.6016,606.5,1521.6016" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1521.6016" y2="1521.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1516.5356">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1534.6016"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1550.6685">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1565.8013">store measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="126" x="945" y="1582.8672"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="118" x="949" y="1598.9341">Measure and load:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="30" x="949" y="1614.0669">RMM</text><polygon fill="#181818" points="610.5,1643.2656,600.5,1647.2656,610.5,1651.2656,606.5,1647.2656" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="604.5" x2="1002" y1="1647.2656" y2="1647.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="139" x="616.5" y="1642.1997">Extend measurement</text><rect fill="#FEFFDD" height="38" style="stroke:#181818;stroke-width:0.5;" width="136" x="526" y="1660.2656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="101" x="530" y="1676.3325">Measured Boot:</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="128" x="530" y="1691.4653">store measurement</text><polygon fill="#181818" points="1168,1720.6641,1178,1724.6641,1168,1728.6641,1172,1724.6641" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="1008" x2="1174" y1="1724.6641" y2="1724.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="96" x="1015" y="1719.5981">Pass execution</text><rect fill="#EEEEEE" height="3" style="stroke:#EEEEEE;stroke-width:1.0;" width="1247" x="0" y="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1753.2305" y2="1753.2305"/><line style="stroke:#000000;stroke-width:1.0;" x1="0" x2="1247" y1="1756.2305" y2="1756.2305"/><rect fill="#EEEEEE" height="23.1328" style="stroke:#000000;stroke-width:2.0;" width="148" x="549.5" y="1742.6641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacing" textLength="129" x="555.5" y="1758.731">RSE / AP Runtime</text><!--MD5=[e3f0ee259d2a4aa9c2a97ff856de0312]
 @startuml
 skinparam ParticipantPadding 10
 skinparam BoxPadding 10
-box RSS
-participant RSS_BL1_1
-participant RSS_BL1_2
-participant RSS_BL2
-participant RSS_S
+box RSE
+participant RSE_BL1_1
+participant RSE_BL1_2
+participant RSE_BL2
+participant RSE_S
 endbox
 box SCP
 participant SCP_BL1
@@ -17,65 +17,65 @@ participant AP_BL2
 participant AP_BL31
 endbox
 
-== RSS Boot phase ==
--> RSS_BL1_1: Reset
-Rnote over RSS_BL1_1: ROM code, XIP
-Rnote over RSS_BL1_2: OTP code, XIP
-Rnote over RSS_BL2, AP_BL31: Stored in flash, loaded and executed in RAM
-activate RSS_BL1_1 #Green
-RSS_BL1_1 - ->> RSS_BL1_2: Validate, measure
-Rnote over RSS_BL1_1: BL1_2 measurement\n\ saved to a shared buffer
-RSS_BL1_1 -> RSS_BL1_2: Pass execution
-deactivate RSS_BL1_1
-activate RSS_BL1_2 #Green
-RSS_BL1_2 - ->> RSS_BL2: Validate, measure, load
-Rnote over RSS_BL1_2: RSS_BL2 measurement\n\ saved to a shared buffer
-RSS_BL1_2 -> RSS_BL2: Pass execution
-deactivate RSS_BL1_2
-activate RSS_BL2 #Green
-RSS_BL2 - ->> RSS_S: Validate, measure, load
-RSS_BL2 - ->> SCP_BL1: Validate, measure, load
-Rnote over RSS_BL2: RSS_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer
-RSS_BL2 -> SCP_BL1: Release from reset
+== RSE Boot phase ==
+-> RSE_BL1_1: Reset
+Rnote over RSE_BL1_1: ROM code, XIP
+Rnote over RSE_BL1_2: OTP code, XIP
+Rnote over RSE_BL2, AP_BL31: Stored in flash, loaded and executed in RAM
+activate RSE_BL1_1 #Green
+RSE_BL1_1 - ->> RSE_BL1_2: Validate, measure
+Rnote over RSE_BL1_1: BL1_2 measurement\n\ saved to a shared buffer
+RSE_BL1_1 -> RSE_BL1_2: Pass execution
+deactivate RSE_BL1_1
+activate RSE_BL1_2 #Green
+RSE_BL1_2 - ->> RSE_BL2: Validate, measure, load
+Rnote over RSE_BL1_2: RSE_BL2 measurement\n\ saved to a shared buffer
+RSE_BL1_2 -> RSE_BL2: Pass execution
+deactivate RSE_BL1_2
+activate RSE_BL2 #Green
+RSE_BL2 - ->> RSE_S: Validate, measure, load
+RSE_BL2 - ->> SCP_BL1: Validate, measure, load
+Rnote over RSE_BL2: RSE_S and SCP_BL1\n\ measurements saved\n\ to a shared buffer
+RSE_BL2 -> SCP_BL1: Release from reset
 activate SCP_BL1 #Green
-Rnote over RSS_BL2, SCP_BL1: MHU init between RSS and SCP
+Rnote over RSE_BL2, SCP_BL1: MHU init between RSE and SCP
 Rnote over SCP_BL1: Configure memory
-Rnote over RSS_BL2: Waits for SCP
-SCP_BL1 - -> RSS_BL2: Done
-RSS_BL2 - ->> AP_BL1: Validate, measure, load
-Rnote over RSS_BL2: AP_BL1 measurement\n\ saved to a shared buffer
-RSS_BL2 -> AP_BL1: Release from reset
+Rnote over RSE_BL2: Waits for SCP
+SCP_BL1 - -> RSE_BL2: Done
+RSE_BL2 - ->> AP_BL1: Validate, measure, load
+Rnote over RSE_BL2: AP_BL1 measurement\n\ saved to a shared buffer
+RSE_BL2 -> AP_BL1: Release from reset
 activate AP_BL1 #Green
-RSS_BL2 -> RSS_S: Pass execution
-deactivate RSS_BL2
-activate RSS_S #Green
-Rnote over RSS_S: Measurements read from\n\ shared buffer and saved by\nMeasured Boot service to\n\ measurement slots.
+RSE_BL2 -> RSE_S: Pass execution
+deactivate RSE_BL2
+activate RSE_S #Green
+Rnote over RSE_S: Measurements read from\n\ shared buffer and saved by\nMeasured Boot service to\n\ measurement slots.
 
-== RSS Runtime / AP Boot phase ==
-Rnote over RSS_S, AP_BL1: MHU init between RSS and AP
+== RSE Runtime / AP Boot phase ==
+Rnote over RSE_S, AP_BL1: MHU init between RSE and AP
 Rnote over AP_BL1: Measure and load:\n\ FW_CONFIG\n\ TB_FW_CONFIG
-AP_BL1 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL1 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
 AP_BL1 - ->> AP_BL2: Validate, measure,load
-AP_BL1 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL1 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
 AP_BL1 -> AP_BL2: Pass execution
 deactivate AP_BL1
 activate AP_BL2 #Green
 Rnote over AP_BL2: Measure and load:\n\ HW_CONFIG
-AP_BL2 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL2 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
 AP_BL2 - ->> AP_BL31: Validate, measure,load
 Rnote over AP_BL2: Measure and load:\n\ BL31
-AP_BL2 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL2 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
 Rnote over AP_BL2: Measure and load:\n\ RMM
-AP_BL2 -> RSS_S: Extend measurement
-Rnote over RSS_S: Measured Boot:\n\ store measurement
+AP_BL2 -> RSE_S: Extend measurement
+Rnote over RSE_S: Measured Boot:\n\ store measurement
 AP_BL2 -> AP_BL31: Pass execution
 deactivate AP_BL2
 activate AP_BL31 #Green
-== RSS / AP Runtime ==
+== RSE / AP Runtime ==
 @enduml
 
 PlantUML version 1.2022.7(Mon Aug 22 19:01:30 CEST 2022)
diff --git a/docs/resources/diagrams/secure_sw_stack_sp.png b/docs/resources/diagrams/secure_sw_stack_sp.png
index 5cb2ca7a2c7b22955691bf1ef5f19b2e7fe14ec1..dc18cb4755c4237133a97546cbde65d14ac1c4e8 100644
GIT binary patch
literal 34589
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
B&y@fG

literal 34909
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

diff --git a/docs/resources/diagrams/secure_sw_stack_tos.png b/docs/resources/diagrams/secure_sw_stack_tos.png
index 1f2d55506a5b4677d89b37159b1a6a00ed759d26..2b42019fdc4db9ad60cd0affd2cd4786f3c5215d 100644
GIT binary patch
literal 34126
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

literal 34202
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
A1^@s6

diff --git a/docs/resources/diagrams/tf-a_attack_tree.png b/docs/resources/diagrams/tf-a_attack_tree.png
new file mode 100755
index 0000000000000000000000000000000000000000..0ade8e897556f15c876243cbdc1b61e1de7c156b
GIT binary patch
literal 37881
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

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/tf-a_data_flow_diagram.png b/docs/resources/diagrams/tf-a_data_flow_diagram.png
new file mode 100755
index 0000000000000000000000000000000000000000..f65da012785ad9609873e58c45830db2724758f2
GIT binary patch
literal 44179
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

literal 0
HcmV?d00001

diff --git a/docs/resources/diagrams/tf-a_system_diagram.png b/docs/resources/diagrams/tf-a_system_diagram.png
new file mode 100755
index 0000000000000000000000000000000000000000..f9bb9e95bbfd4e27cd5b2b2f24346c83cf2de022
GIT binary patch
literal 191986
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%0A!F
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%0D~xfeZZO`+sJB
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

literal 0
HcmV?d00001

diff --git a/docs/security_advisories/index.rst b/docs/security_advisories/index.rst
index c9b0f781..ad555467 100644
--- a/docs/security_advisories/index.rst
+++ b/docs/security_advisories/index.rst
@@ -15,3 +15,4 @@ Security Advisories
    security-advisory-tfv-8.rst
    security-advisory-tfv-9.rst
    security-advisory-tfv-10.rst
+   security-advisory-tfv-11.rst
diff --git a/docs/security_advisories/security-advisory-tfv-10.rst b/docs/security_advisories/security-advisory-tfv-10.rst
index 91dba074..f53bae13 100644
--- a/docs/security_advisories/security-advisory-tfv-10.rst
+++ b/docs/security_advisories/security-advisory-tfv-10.rst
@@ -98,7 +98,7 @@ All standard chains of trust provided in TF-A source tree (that is, under
 ``drivers/auth/``) require that the certificate's signature has already been
 validated prior to calling ``get_ext()``, or any function that calls ``get_ext()``.
 Platforms taking their chain of trust from a dynamic configuration file (such as
-``fdts/cot_descriptors.dtsi``) are also safe, as signature verification will
+``fdts/tbbr_cot_descriptors.dtsi``) are also safe, as signature verification will
 always be done prior to any calls to ``get_ext()`` or ``auth_nvctr()`` in this
 case, no matter the order of the properties in the file.  Therefore, it is not
 possible to exploit this vulnerability pre-authentication in upstream TF-A.
diff --git a/docs/security_advisories/security-advisory-tfv-11.rst b/docs/security_advisories/security-advisory-tfv-11.rst
new file mode 100644
index 00000000..b5063f09
--- /dev/null
+++ b/docs/security_advisories/security-advisory-tfv-11.rst
@@ -0,0 +1,86 @@
+Advisory TFV-11 (CVE-2023-49100)
+================================
+
++----------------+-------------------------------------------------------------+
+| Title          | A Malformed SDEI SMC can cause out of bound memory read.    |
++================+=============================================================+
+| CVE ID         | `CVE-2023-49100`_                                           |
++----------------+-------------------------------------------------------------+
+| Date           | Reported on 12 Oct 2023                                     |
++----------------+-------------------------------------------------------------+
+| Versions       | TF-A releases v1.5 to v2.9                                  |
+| Affected       | LTS releases  lts-v2.8.0 to lts-v2.8.11                     |
++----------------+-------------------------------------------------------------+
+| Configurations | Platforms with SDEI support                                 |
+| Affected       |                                                             |
++----------------+-------------------------------------------------------------+
+| Impact         | Denial of Service (secure world panic)                      |
++----------------+-------------------------------------------------------------+
+| Fix Version    | `a7eff3477`_ "fix(sdei): ensure that interrupt ID is valid" |
++----------------+-------------------------------------------------------------+
+| Credit         | Christian Lindenmeier `@_chli_`_                            |
+|                | Marcel Busch `@0ddc0de`_                                    |
+|                | `IT Security Infrastructures Lab`_                          |
++----------------+-------------------------------------------------------------+
+
+This security advisory describes a vulnerability in the SDEI services, where a
+rogue Non-secure caller invoking a SDEI_INTERRUPT_BIND SMC call with an invalid
+interrupt ID causes out of bound memory read.
+
+SDEI_INTERRUPT_BIND is used to bind any physical interrupt into a normal
+priority SDEI event. The interrupt can be a private peripheral interrupt
+(PPI) or a shared peripheral interrupt (SPI).
+Refer to SDEI_INTERRUPT_BIND in the `SDEI Specification`_ for further details.
+
+The vulnerability exists when the SDEI client passes an interrupt ID which
+is not implemented by the GIC. This will result in a data abort exception
+or a EL3 panic depending on the GIC version used in the system.
+
+- **GICv2 systems:**
+
+.. code:: c
+
+  Call stack:
+        sdei_interrupt_bind(interrupt ID)
+         -> plat_ic_get_interrupt_type(interrupt ID)
+           -> gicv2_get_interrupt_group(interrupt ID)
+             -> gicd_get_igroupr(distributor base, interrupt ID)
+               -> gicd_read_igroupr(distributor base, interrupt ID).
+
+  gicd_read_igroupr() will eventually do a MMIO read to an unimplemented IGROUPR
+  register. Which may cause a data abort or an access to a random EL3 memory region.
+
+- **GICv3 systems:**
+
+.. code:: c
+
+   Call stack:
+        sdei_interrupt_bind(interrupt ID)
+          -> plat_ic_get_interrupt_type(interrupt ID)
+            -> gicv3_get_interrupt_group(interrupt ID, core ID)
+              -> is_sgi_ppi(interrupt ID)
+
+   is_sgi_ppi() will end up in an EL3 panic on encountering an invalid interrupt ID.
+
+The vulnerability is fixed by ensuring that the Interrupt ID provided by the
+SDEI client is a valid PPI or SPI, otherwise return an error code indicating
+that the parameter is invalid.
+
+.. code:: c
+
+   /* Bind an SDEI event to an interrupt */
+   static int sdei_interrupt_bind(unsigned int intr_num)
+   {
+        sdei_ev_map_t *map;
+        bool retry = true, shared_mapping;
+
+        /* Interrupt must be either PPI or SPI */
+        if (!(plat_ic_is_ppi(intr_num) || plat_ic_is_spi(intr_num)))
+              return SDEI_EINVAL;
+
+.. _CVE-2023-49100: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-49100
+.. _a7eff3477: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=a7eff3477dcf3624c74f5217419b1a27b7ebd2aa
+.. _IT Security Infrastructures Lab: https://www.cs1.tf.fau.de/
+.. _SDEI Specification: https://developer.arm.com/documentation/den0054/latest/
+.. _@_chli_: https://twitter.com/_chli_
+.. _@0ddc0de: https://twitter.com/0ddc0de
diff --git a/docs/security_advisories/security-advisory-tfv-9.rst b/docs/security_advisories/security-advisory-tfv-9.rst
index 762801d7..014221e3 100644
--- a/docs/security_advisories/security-advisory-tfv-9.rst
+++ b/docs/security_advisories/security-advisory-tfv-9.rst
@@ -87,7 +87,7 @@ revisions of Cortex-A73 and Cortex-A75 that implements FEAT_CSV2).
 +----------------------+
 | Neoverse-V2          |
 +----------------------+
-| Neoverse-Poseidon    |
+| Neoverse-V3          |
 +----------------------+
 
 For all other cores impacted by Spectre-BHB, some of which that do not implement
diff --git a/docs/threat_model/firmware_threat_model/index.rst b/docs/threat_model/firmware_threat_model/index.rst
new file mode 100644
index 00000000..ce1752fd
--- /dev/null
+++ b/docs/threat_model/firmware_threat_model/index.rst
@@ -0,0 +1,41 @@
+TF-A Firmware Threat Model
+==========================
+
+As the TF-A codebase is highly configurable to allow tailoring it best for each
+platform's needs, providing a holistic threat model covering all of its features
+is not necessarily the best approach. Instead, we provide a collection of
+documents which, together, form the project's threat model. These are
+articulated around a core document, called the :ref:`Generic Threat Model`,
+which focuses on the most common configuration we expect to see. The other
+documents typically focus on specific features not covered in the core document.
+
+As the TF-A codebase evolves and new features get added, these threat model
+documents will be updated and extended in parallel to reflect at best the
+current status of the code from a security standpoint.
+
+   .. note::
+
+      Although our aim is eventually to provide threat model material for all
+      features within the project, we have not reached that point yet. We expect
+      to gradually fill these gaps over time.
+
+Each of these documents give a description of the target of evaluation using a
+data flow diagram, as well as a list of threats we have identified using the
+`STRIDE threat modeling technique`_ and corresponding mitigations.
+
+.. toctree::
+   :maxdepth: 1
+   :caption: Contents
+
+   threat_model
+   threat_model_el3_spm
+   threat_model_fvp_r
+   threat_model_rse_interface
+   threat_model_arm_cca
+   threat_model_fw_update_and_recovery
+
+--------------
+
+*Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.*
+
+.. _STRIDE threat modeling technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/firmware_threat_model/threat_model.rst
similarity index 89%
rename from docs/threat_model/threat_model.rst
rename to docs/threat_model/firmware_threat_model/threat_model.rst
index 0da25585..ae0219ee 100644
--- a/docs/threat_model/threat_model.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model.rst
@@ -42,6 +42,8 @@ assumptions:
 - No experimental features are enabled. We do not consider threats that may come
   from them.
 
+- The platform's hardware complies with the `PSR specification`_, defining the
+  bare-minimum security prerequisites for System-on-Chips (SoC).
 
 Data Flow Diagram
 =================
@@ -53,7 +55,7 @@ is given on Table 1. On the diagram, the red broken lines indicate
 trust boundaries. Components outside of the broken lines
 are considered untrusted by TF-A.
 
-.. uml:: ../resources/diagrams/plantuml/tfa_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/tfa_dfd.puml
   :caption: Figure 1: TF-A Data Flow Diagram
 
 .. table:: Table 1: TF-A Data Flow Diagram Description
@@ -161,6 +163,15 @@ in scope of this threat model.
   ion beam (FIB) workstation or decapsulate the chip using chemicals) is
   considered out-of-scope.
 
+  Certain non-invasive physical attacks that do not need modifications to the
+  chip, notably those like Power Analysis Attacks, are out-of-scope. Power
+  analysis side-channel attacks represent a category of security threats that
+  capitalize on information leakage through a device's power consumption during
+  its normal operation. These attacks leverage the correlation between a
+  device's power usage and its internal data processing activities. This
+  correlation provides attackers with the means to extract sensitive
+  information, including cryptographic keys.
+
 Threat Types
 ============
 
@@ -612,6 +623,62 @@ General Threats for All Firmware Images
 |                        |   UART interface(s).                                |
 +------------------------+-----------------------------------------------------+
 
++------------------------+-----------------------------------------------------+
+| ID                     | 16                                                  |
++========================+=====================================================+
+| Threat                 | | **An attacker could analyse the timing behaviour  |
+|                        |     of implemented methods in the system to infer   |
+|                        |     sensitive information.**                        |
+|                        |                                                     |
+|                        | | A timing side-channel attack is a type of attack  |
+|                        |   that exploits variations in the time it takes a   |
+|                        |   system to perform different operations. This      |
+|                        |   form of attack focuses on analyzing the time-     |
+|                        |   related information leakage that occurs during    |
+|                        |   the execution of cryptographic algorithms or      |
+|                        |   other security-sensitive processes. By observing  |
+|                        |   these timing differences, an attacker can gain    |
+|                        |   insights into the internal workings of a system   |
+|                        |   and potentially extract sensitive information.    |
+|                        |   Sensitive information that, when revealed even    |
+|                        |   partially, could heighten the susceptibility to   |
+|                        |   traditional attacks like brute-force attacks.     |
++------------------------+-----------------------------------------------------+
+| Diagram Elements       | DF2                                                 |
++------------------------+-----------------------------------------------------+
+| Affected TF-A          | BL1, BL2, BL31                                      |
+| Components             |                                                     |
++------------------------+-----------------------------------------------------+
+| Assets                 | Sensitive Data                                      |
++------------------------+-----------------------------------------------------+
+| Threat Agent           | AppDebug                                            |
++------------------------+-----------------------------------------------------+
+| Threat Type            | Information Disclosure                              |
++------------------------+------------------+----------------+-----------------+
+| Application            | Server           | IoT            | Mobile          |
++------------------------+------------------+----------------+-----------------+
+| Impact                 | Critical (5)     | Critical (5)   | Critical (5)    |
++------------------------+------------------+----------------+-----------------+
+| Likelihood             | Critical (5)     | Critical (5)   | Critical (5)    |
++------------------------+------------------+----------------+-----------------+
+| Total Risk Rating      | Critical (25)    | Critical (25)  | Critical (25)   |
++------------------------+------------------+----------------+-----------------+
+| Mitigations            | |  Ensure that the execution time of critical       |
+|                        |    operations is constant and independent of        |
+|                        |    secret data. This prevents attackers from        |
+|                        |    exploiting timing differences to infer           |
+|                        |    information about sensitive data.                |
+|                        |                                                     |
+|                        | |  Introduce random delays/timing jitter or dummy   |
+|                        |    operations to make the timing behavior of program|
+|                        |    execution less predictable. This can disrupt the |
+|                        |    correlation between the execution time and       |
+|                        |    sensitive data.                                  |
+|                        |                                                     |
++------------------------+-----------------------------------------------------+
+| Mitigations            | |  Not implemented                                  |
+| implemented?           |                                                     |
++------------------------+-----------------------------------------------------+
 
 .. _Boot Firmware Threats:
 
@@ -825,28 +892,65 @@ nonetheless once execution has reached the runtime EL3 firmware.
 
 .. topic:: Measured Boot Threats (or lack of)
 
- In the current Measured Boot design, BL1, BL2, and BL31, as well as the
- secure world components, form the |SRTM|. Measurement data is currently
- considered an asset to be protected against attack, and this is achieved
- by storing them in the Secure Memory.
- Beyond the measurements stored inside the TCG-compliant Event Log buffer,
- there are no other assets to protect or threats to defend against that
- could compromise |TF-A| execution environment's security.
+ In the current Measured Boot design the following components form the |TCB|:
+
+   - BL1, BL2, BL31
+   - Secure world components
+   - RMM (if RME extension is implemented)
+   - The configuration data of the above components
+
+ Across various Measured Boot backends, the data recorded during the flow as
+ well as the criticality of this data can vary. In most cases, these attributes
+ are considered valuable assets and are protected against potential attacks:
+
+   - Image measurement: the digest value of a component produced by a hash
+     function.
+   - Signer-id: the digest value of the image verification publiy key. The
+     verification public key is part of the image metadata.
+
+ In addition to these, other metadata attributes (image version, hash algorithm
+ identifier, etc) could be recorded during the Measured Boot process. But these
+ are not critical data.
+
+ In this context, an attack means modifying the measurement data (image or
+ public key hash) or recording arbitrary data as valid measurements.
+
+ The current Measured Boot design consists of two main parts. A frontend, which
+ is responsible for taking the measurements, and a backend which is responsible
+ for storing them. |TF-A| makes it possible to integrate various backends. Some
+ of these are implemented by the |TF-A| projects, while others are part of
+ different projects, and |TF-A| provides an integration layer.
+
+   - TCG-compliant Event Log: Implemented by |TF-A|. Measurements are stored in
+     the Event Log which is located on the secure on-chip memory of the AP. The
+     address of the Event Log buffer is handed off between boot stages and new
+     measurements are appended to the Event Log. A limitation of the current
+     Measured Boot implementation in |TF-A| is that it does not extend the
+     measurements into a |PCR| of a Discrete |TPM|, where measurements would
+     be securely stored and protected against tampering.
+   - `CCA Measured Boot`_: Implemented by |TF-M|. Measurements are stored in
+     |HES| secure on-chip memory. |HES| implements protection against tampering
+     its on-chip memory. |HES| interface is available for BL1 and BL2.
+   - `DICE Protection Environment`_ (DPE): Implemented by |TF-M|. Measurements
+     are stored in |RSE| secure on-chip memory. |RSE| implements protection
+     against tampering its on-chip memory. DPE provides additional protection
+     against unauthorized access by malicious actors through the use of one-time
+     context handles and the identification of the client's target locality
+     (location of the client).
+
+ Beyond the measurements (image digest and signer-id) there are no other assets
+ to protect or threats to defend against that could compromise |TF-A| execution
+ environment's security.
 
  There are general security assets and threats associated with remote/delegated
  attestation. However, these are outside the |TF-A| security boundary and
  should be dealt with by the appropriate agent in the platform/system.
  Since current Measured Boot design does not use local attestation, there would
- be no further assets to protect(like unsealed keys).
-
- A limitation of the current Measured Boot design is that it is dependent upon
- Secure Boot as implementation of Measured Boot does not extend measurements
- into a discrete |TPM|, where they would be securely stored and protected
- against tampering. This implies that if Secure-Boot is compromised, Measured
- Boot may also be compromised.
+ be no further assets to protect (like unsealed keys).
 
- Platforms must carefully evaluate the security of the default implementation
- since the |SRTM| includes all secure world components.
+ System integrators must carefully evaluate the security requirement and
+ capabilities of their platform and choose an appropriate Measured Boot
+ solution.
 
 
 .. _Runtime Firmware Threats:
@@ -1088,7 +1192,7 @@ Threats to be Mitigated by an External Agent Outside of TF-A
 
 --------------
 
-*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
 
 
 .. _STRIDE threat analysis technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
@@ -1101,3 +1205,6 @@ Threats to be Mitigated by an External Agent Outside of TF-A
 .. _Secure Development Guidelines: https://trustedfirmware-a.readthedocs.io/en/latest/process/security-hardening.html#secure-development-guidelines
 .. _Trusted Firmware-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
 .. _OP-TEE Dispatcher: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/spd/optee-dispatcher.rst
+.. _PSR Specification: https://developer.arm.com/documentation/den0106/0100
+.. _CCA Measured Boot: https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/measured_boot_integration_guide.html
+.. _DICE Protection Environment: https://trustedfirmware-m.readthedocs.io/projects/tf-m-extras/en/latest/partitions/dice_protection_environment/dice_protection_environment.html
diff --git a/docs/threat_model/threat_model_arm_cca.rst b/docs/threat_model/firmware_threat_model/threat_model_arm_cca.rst
similarity index 98%
rename from docs/threat_model/threat_model_arm_cca.rst
rename to docs/threat_model/firmware_threat_model/threat_model_arm_cca.rst
index fbf3327b..af38ea3c 100644
--- a/docs/threat_model/threat_model_arm_cca.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_arm_cca.rst
@@ -86,7 +86,7 @@ with TF-A. A description of each diagram element is given on Table 1. On the
 diagram, the red broken lines indicate trust boundaries. Components outside of
 the broken lines are considered untrusted by TF-A.
 
-.. uml:: ../resources/diagrams/plantuml/tfa_arm_cca_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/tfa_arm_cca_dfd.puml
   :caption: Figure 1: Data Flow Diagram
 
 .. table:: Table 1: Data Flow Diagram Description
@@ -220,6 +220,6 @@ of this threat model. Only deltas are pointed out.
   | 14 |     Yes     |                                                       |
   +----+-------------+-------------------------------------------------------+
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
 
 .. _Arm CCA Security Model: https://developer.arm.com/documentation/DEN0096/A_a
diff --git a/docs/threat_model/threat_model_el3_spm.rst b/docs/threat_model/firmware_threat_model/threat_model_el3_spm.rst
similarity index 99%
rename from docs/threat_model/threat_model_el3_spm.rst
rename to docs/threat_model/firmware_threat_model/threat_model_el3_spm.rst
index 8adf3dfd..a2d67985 100644
--- a/docs/threat_model/threat_model_el3_spm.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_el3_spm.rst
@@ -37,7 +37,7 @@ red broken lines indicate trust boundaries.
 
 Components outside of the broken lines are considered untrusted.
 
-.. uml:: ../resources/diagrams/plantuml/el3_spm_dfd.puml
+.. uml:: ../../resources/diagrams/plantuml/el3_spm_dfd.puml
   :caption: Figure 1: EL3 SPMC Data Flow Diagram
 
 .. table:: Table 1: EL3 SPMC Data Flow Diagram Description
@@ -644,7 +644,7 @@ element of the data flow diagram.
 
 ---------------
 
-*Copyright (c) 2022-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2022-2024, Arm Limited. All rights reserved.*
 
 .. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest
 .. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases
diff --git a/docs/threat_model/threat_model_fvp_r.rst b/docs/threat_model/firmware_threat_model/threat_model_fvp_r.rst
similarity index 98%
rename from docs/threat_model/threat_model_fvp_r.rst
rename to docs/threat_model/firmware_threat_model/threat_model_fvp_r.rst
index 725eeed9..0b71bf07 100644
--- a/docs/threat_model/threat_model_fvp_r.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_fvp_r.rst
@@ -96,4 +96,4 @@ implementation:
 
 --------------
 
-*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst b/docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst
new file mode 100644
index 00000000..7b55c746
--- /dev/null
+++ b/docs/threat_model/firmware_threat_model/threat_model_fw_update_and_recovery.rst
@@ -0,0 +1,103 @@
+Threat Model for TF-A with PSA FWU or TBBR FWU support
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduction
+************
+
+This document provides a threat model of TF-A firmware for platforms with
+the feature PSA firmware update or TBBR firmware update or both enabled.
+To understand the design of the firmware update refer
+:ref:`Firmware Update (FWU)`.
+
+Although it is a separate document, it references the :ref:`Generic Threat
+Model` in a number of places, as some of the contents are applicable to this
+threat model.
+
+Target of Evaluation
+********************
+
+In this threat model, the target of evaluation is the Trusted Firmware for
+A-class Processors (TF-A) when PSA FWU support is enabled or TBBR FWU mode
+is enabled. This includes the boot ROM (BL1), the trusted boot firmware (BL2).
+
+Threat Assessment
+*****************
+
+For this section, please reference the Threat Assessment under the
+:ref:`Generic Threat Model`. Here only the differences are highlighted.
+
+PSA FWU
+*******
+
+Threats to be Mitigated by the Boot Firmware
+--------------------------------------------
+
+The following table analyses the :ref:`Boot Firmware Threats` in the context
+of this threat model. Only additional details are pointed out.
+
++----+-------------+-------------------------------------------------------+
+| ID | Applicable? | Comments                                              |
++====+=============+=======================================================+
+| 01 |     Yes     | | Attacker can use arbitrary images to update the     |
+|    |             |   system.                                             |
++----+-------------+-------------------------------------------------------+
+| 02 |     Yes     | | Attacker tries to update the system with the        |
+|    |             |   vulnerable/older firmware.                          |
++----+-------------+-------------------------------------------------------+
+| 03 |     Yes     |                                                       |
++----+-------------+-------------------------------------------------------+
+| 04 |     Yes     |                                                       |
++----+-------------+-------------------------------------------------------+
+
+
+Threats to be mitigated by platform design
+------------------------------------------
+
+PSA FWU is driven by metadata stored in non-volatile storage. This metadata
+is not cryptographically signed. Also, depending on the hardware design,
+it may be stored in untrusted storage, which makes it possible for software
+outside of TF-A security boundary or for a physical attacker to modify it
+in order to change the behaviour of the FWU process.
+
+Below we provide some possible FWU metadata corruption scenarios:
+
+1. The FWU metadata includes the firmware bank for booting; the attacker
+   tries to modify it to prevent the execution of the updated firmware.
+2. The FWU metadata features a field indicating the firmware's status, either
+   in trial run or accepted run. The attacker tries to manipulate this field,
+   ensuring the updated firmware consistently runs in trial mode, with the
+   intention of preventing the anti-rollback update.
+
+By design, no software mitigations exist to prevent this. The safeguarding
+of FWU metadata relies on the platform's hardware design to mitigate potential
+attacks on it, if this is a concern in the platform's threat model.
+For example, FWU metadata may be stored in secure storage under exclusive
+access from secure software, protecting it from physical, unauthenticated
+accesses and from non-secure software accesses.
+
+TBBR FWU - Firmware Recovery
+****************************
+
+Threats to be Mitigated by the Boot Firmware
+--------------------------------------------
+
+The following table analyses the :ref:`Boot Firmware Threats` in the context
+of this threat model. Only additional details are pointed out.
+
++----+-------------+-------------------------------------------------------+
+| ID | Applicable? | Comments                                              |
++====+=============+=======================================================+
+| 01 |     Yes     | | Attacker can use arbitrary images to recover the    |
+|    |             |   system.                                             |
++----+-------------+-------------------------------------------------------+
+| 02 |     Yes     | | Attacker tries to recover the system with the       |
+|    |             |   vulnerable/older firmware.                          |
++----+-------------+-------------------------------------------------------+
+| 03 |     Yes     |                                                       |
++----+-------------+-------------------------------------------------------+
+| 04 |     Yes     |                                                       |
++----+-------------+-------------------------------------------------------+
+
+--------------
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/threat_model_rss_interface.rst b/docs/threat_model/firmware_threat_model/threat_model_rse_interface.rst
similarity index 72%
rename from docs/threat_model/threat_model_rss_interface.rst
rename to docs/threat_model/firmware_threat_model/threat_model_rse_interface.rst
index 4bceb631..3b391c14 100644
--- a/docs/threat_model/threat_model_rss_interface.rst
+++ b/docs/threat_model/firmware_threat_model/threat_model_rse_interface.rst
@@ -1,41 +1,41 @@
-Threat Model for RSS - AP interface
+Threat Model for RSE - AP interface
 ***********************************
 
 ************
 Introduction
 ************
 This document is an extension for the general TF-A threat-model. It considers
-those platforms where a Runtime Security Subsystem (RSS) is included in the SoC
+those platforms where a Runtime Security Engine (RSE) is included in the SoC
 next to the Application Processor (AP).
 
 ********************
 Target of Evaluation
 ********************
-The scope of this threat model only includes the interface between the RSS and
+The scope of this threat model only includes the interface between the RSE and
 AP. Otherwise, the TF-A :ref:`Generic Threat Model` document is applicable for
-the AP core. The threat model for the RSS firmware will be provided by the RSS
+the AP core. The threat model for the RSE firmware will be provided by the RSE
 firmware project in the future.
 
 
 Data Flow Diagram
 =================
 This diagram is different only from the general TF-A data flow diagram in that
-it includes the RSS and highlights the interface between the AP and the RSS
-cores. The interface description only focuses on the AP-RSS interface the rest
+it includes the RSE and highlights the interface between the AP and the RSE
+cores. The interface description only focuses on the AP-RSE interface the rest
 is the same as in the general TF-A threat-model document.
 
-.. uml:: ../resources/diagrams/plantuml/tfa_rss_dfd.puml
-  :caption: Figure 1: TF-A Data Flow Diagram including RSS
+.. uml:: ../../resources/diagrams/plantuml/tfa_rse_dfd.puml
+  :caption: Figure 1: TF-A Data Flow Diagram including RSE
 
-.. table:: Table 1: TF-A - RSS data flow diagram
+.. table:: Table 1: TF-A - RSE data flow diagram
 
   +-----------------+--------------------------------------------------------+
   | Diagram Element | Description                                            |
   +=================+========================================================+
-  |       DF7       | | Boot images interact with RSS over a communication   |
+  |       DF7       | | Boot images interact with RSE over a communication   |
   |                 |   channel to record boot measurements and get image    |
   |                 |   verification keys. At runtime, BL31 obtains the      |
-  |                 |   realm world attestation signing key from RSS.        |
+  |                 |   realm world attestation signing key from RSE.        |
   +-----------------+--------------------------------------------------------+
 
 Threat Assessment
@@ -44,16 +44,16 @@ For this section, please reference the Threat Assessment under the general TF-A
 threat-model document, :ref:`Generic Threat Model`. All the threats listed there
 are applicable for the AP core, here only the differences are highlighted.
 
-    - ID 11: The access to the communication interface between AP and RSS is
+    - ID 11: The access to the communication interface between AP and RSE is
       allowed only for firmware running at EL3. Accidentally exposing this
-      interface to NSCode can allow malicious code to interact with RSS and
+      interface to NSCode can allow malicious code to interact with RSE and
       gain access to sensitive data.
     - ID 13: Relevant in the context of the realm attestation key, which can be
-      retrieved by BL31 through DF7. The RSS communication protocol layer
+      retrieved by BL31 through DF7. The RSE communication protocol layer
       mitigates against this by clearing its internal buffer when reply is
       received. The caller of the API must do the same if data is not needed
       anymore.
 
 --------------
 
-*Copyright (c) 2022, Arm Limited. All rights reserved.*
\ No newline at end of file
+*Copyright (c) 2022-2024, Arm Limited. All rights reserved.*
diff --git a/docs/threat_model/index.rst b/docs/threat_model/index.rst
index e22378b0..446e610d 100644
--- a/docs/threat_model/index.rst
+++ b/docs/threat_model/index.rst
@@ -4,40 +4,14 @@ Threat Model
 Threat modeling is an important part of Secure Development Lifecycle (SDL)
 that helps us identify potential threats and mitigations affecting a system.
 
-As the TF-A codebase is highly configurable to allow tailoring it best for each
-platform's needs, providing a holistic threat model covering all of its features
-is not necessarily the best approach. Instead, we provide a collection of
-documents which, together, form the project's threat model. These are
-articulated around a core document, called the :ref:`Generic Threat Model`,
-which focuses on the most common configuration we expect to see. The other
-documents typically focus on specific features not covered in the core document.
-
-As the TF-A codebase evolves and new features get added, these threat model
-documents will be updated and extended in parallel to reflect at best the
-current status of the code from a security standpoint.
-
-   .. note::
-
-      Although our aim is eventually to provide threat model material for all
-      features within the project, we have not reached that point yet. We expect
-      to gradually fill these gaps over time.
-
-Each of these documents give a description of the target of evaluation using a
-data flow diagram, as well as a list of threats we have identified using the
-`STRIDE threat modeling technique`_ and corresponding mitigations.
 
 .. toctree::
    :maxdepth: 1
    :caption: Contents
 
-   threat_model
-   threat_model_el3_spm
-   threat_model_fvp_r
-   threat_model_rss_interface
-   threat_model_arm_cca
+   firmware_threat_model/index
+   supply_chain_threat_model
 
 --------------
 
-*Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.*
-
-.. _STRIDE threat modeling technique: https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats#stride-model
+*Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/threat_model/supply_chain_threat_model.rst b/docs/threat_model/supply_chain_threat_model.rst
new file mode 100644
index 00000000..a0fed5c8
--- /dev/null
+++ b/docs/threat_model/supply_chain_threat_model.rst
@@ -0,0 +1,760 @@
+TF-A Supply Chain Threat Model
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduction
+************
+
+Software supply chain attacks aim to inject malicious code into a software
+product. There are several ways a malicious code can be injected into a
+software product (open-source project). These include:
+
+- Malicious code commits: This attack directly injects code into a project
+  repository. This can happen for example through developer/maintainer
+  credential hijacks, or malicious external contributors.
+
+- Malicious dependencies:  In this case malicious code is introduced into a
+  project through other piece of code or packages the project depends on. This
+  can happen through for example typosquatting attack where an attacker creates
+  a malicious package with a very similar name to a popular package and hosts
+  it on popular package repositories.
+
+- Malicious toolchains:  This involves malicious code introduced by compromised
+  resources used throughout the development and/or build process such as
+  compilers and IDEs.
+
+This document provides analysis of software supply chain attack threats for the
+TF-A project.
+
+TF-A Overview
+*************
+
+Figure 1 shows the different software components surrounding the TF-A project.
+A brief description of each component is provided below.
+
+TF-A Repository
+===============
+
+The TF-A repository contains generic and platform code contributed by TF-A
+contributors as well as libraries imported from other open-source projects,
+referred to as internal dependencies on Figure 1. These libraries include:
+
+- *libfdt*: libfdt is a utility library for reading and manipulating Device
+  Tree Binary (DTB) files. It is part of the Device Tree Compiler (DTC)
+  toolchain [1]_. DTC is used as part of the build process on the host machine
+  to build DTB files. libfdt is used to parse the DTB files at boot time.
+
+- *zlib*: zlib is a data compression library imported from [2]_.
+
+- *compiler-rt*: This is a collection of runtime libraries from the LLVM
+  compiler infrastructure project [3]_. We import the builtins library which
+  provides low-level, target-specific compiler builtins from compiler-rt.
+
+The TF-A repository also includes source code for host tools that supplement
+the TF-A build process. These tools include:
+
+- *fiptool*: This tool is used to create a Firmware Image Package (FIP) which
+  allows for packing bootloader images into a single archive that can be
+  loaded by TF-A from non-volatile platform storage.
+
+- *cert_create*: This tool is used to generate certificates for binary images.
+
+- *encrypt_fw*: This tool takes the plain firmware image as input and generates
+  the encrypted firmware image which can then be passed as input to the fiptool
+  utility for creating the FIP.
+
+- *sptool*: This tool is used to build the secure partition packages.
+
+|TF-A System Diagram|
+*Figure 1: TF-A System Diagram*
+
+External Dependencies
+=====================
+
+These are software components that are not part of the TF-A repository but are
+required to build TF-A binaries and host tools.
+
+- *Mbed TLS Library*: This is a cryptography library from trustedfirmware.org
+  (tf.org). It is required to build TF-A binaries where cryptography features
+  are needed, such as Trusted Board Boot (TBB).
+
+- *OpenSSL Library*: This is another cryptography library used by TF-A host
+  tools: fiptool, cert_create, and encrypt_fw.
+
+The following table lists TF-A dependencies including the sources of the
+dependencies.
+
+.. table:: Table 1: TF-A Dependencies
+
+  +-------------+------------------------+------------------------------------+
+  | Dependency  | Location of Dependency | Original Source                    |
+  +=============+========================+====================================+
+  | libfdt      | Local copy             | [1]_                               |
+  +-------------+------------------------+------------------------------------+
+  | zlib        | Local copy             | [2]_                               |
+  +-------------+------------------------+------------------------------------+
+  | compiler-rt | Local copy             | [3]_                               |
+  +-------------+------------------------+------------------------------------+
+  | Mbed TLS    | External               | [4]_                               |
+  +-------------+------------------------+------------------------------------+
+  | OpenSSL     | External               | [5]_                               |
+  +-------------+------------------------+------------------------------------+
+
+Supplementary Binaries
+======================
+
+These are binaries used to test TF-A based systems. Below is a brief
+description of each component and where they are sourced from.
+
+- *SCP-firmware*: For our tests, we use SCP-firmware binaries supplied by the
+  Arm SCP team built from the source from the GitHub repository [6]_.
+
+- *OP-TEE*: Trusted Execution Environment (TEE) from tf.org that runs as
+  Secure EL1. We use OP-TEE built from source or binaries supplied with Arm
+  Reference Platforms depending on the test configuration.
+
+- *EDK2 UEFI*: Normal world bootloader from the EDK2 project [7]_. We use EDK2
+  UEFI binaries hosted on tf.org servers for testing [8]_.
+
+Other software components used to test TF-A include U-Boot, Linux kernel, RSE,
+MCP, and file systems, all sourced from the Arm Reference Platforms teams.
+
+TF-A Toolchain
+==============
+
+The TF-A project uses several tools to build, analyze and test the TF-A source
+code.
+
+Node.js Tools
+-------------
+
+These are optional quality assurance and developer utility tools that are
+installed through the use of the Node.js package manager. They are pinned to
+specific versions described by the package.json file in the root of the TF-A
+repository, and their dependencies are downloaded from the internet at the
+point of installation. These tools may be installed locally on the developer
+machine and are installed within a Docker container in certain CI jobs. At
+present, these are:
+
+- Commitlint
+
+- Commitizen
+
+- Husky
+
+Infrastructure
+==============
+
+TF-A uses trustedfirmware.org (tf.org) and Arm infrastructures to host the
+source code, review code and run tests. Appendix A provides a security analysis
+of tf.org infrastructure.
+
+TF-A Data Flow
+**************
+
+Figure 2 below shows the data flow diagram for TF-A. The broken red lines
+indicate trust boundaries.
+
+|TF-A Data Flow Diagram|
+*Figure 2: TF-A Data Flow Diagram*
+
+Attack Tree
+***********
+
+|TF-A Attack Tree|
+*Figure 3: TF-A Attack Tree*
+
+Threat Assessment and Mitigations
+*********************************
+
+Impact and Likelihood Ratings
+=============================
+
+  +--------+------------------------------+-----------------------------------+
+  | Rating | Impact                       | Likelihood                        |
+  +========+==============================+===================================+
+  | HIGH   | Major impact to entire       | Threat is relatively easy to      |
+  |        | organization or single line  | exploit by an attacker with       |
+  |        | of business if exploited.    | little effort and skill.          |
+  +--------+------------------------------+-----------------------------------+
+  | MEDIUM | Noticeable impact to line of | An expert attacker could exploit  |
+  |        | business if exploited.       | the threat without much           |
+  |        |                              | difficulty.                       |
+  +--------+------------------------------+-----------------------------------+
+  | LOW    | Minor damage if exploited or | Exploiting the threat would       |
+  |        | could be used in conjunction | require considerable effort and   |
+  |        | with other vulnerabilities   | resources.                        |
+  |        | to perform a more serious    |                                   |
+  |        | attack.                      |                                   |
+  +--------+------------------------------+-----------------------------------+
+
+Threats and Mitigations
+=======================
+
+Threat naming convention key
+
+- SC – Supply Chain
+
+- SRC – Source
+
+- DEP – Dependency
+
+- TOOL – Toolchain
+
+- REPO – Repository
+
+- MAIN – Maintainer
+
+- CONT – Contributor
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-SRC-MAIN-01                                                |
+  +=============+=============================================================+
+  | Description | An attacker can submit and merge malicious code by posing   |
+  |             | as a maintainer after compromising maintainers’             |
+  |             | credentials.                                                |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | MEDIUM                                                      |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | In the TF-A code review process all submitted changes     |
+  | impact      |   undergo review by a code owner and a maintainer. If the   |
+  |             |   change is accepted, it will be merged (integrated) into   |
+  |             |   an integration branch by a maintainer. A maintainer has   |
+  |             |   the right to give a code owner review, a maintainer       |
+  |             |   review and merge the submitted change.                    |
+  |             |                                                             |
+  |             | | tf.org users (including maintainers) are authenticated    |
+  |             |   through GitHub. The likelihood of a credential compromise |
+  |             |   depends on multiple factors. The authentication mechanism |
+  |             |   of GitHub is strong if the recommended best practices are |
+  |             |   followed [9]_ making credential compromise unlikely.      |
+  |             |   GitHub (therefore tf.org) allows logins with two-factor   |
+  |             |   authentication, requiring both a password and access to   |
+  |             |   the user's authentication code. Depending on the strength |
+  |             |   of the password and factors such as whether the           |
+  |             |   maintainer reuses passwords across services, the          |
+  |             |   likelihood of a compromise can be higher.                 |
+  |             |                                                             |
+  |             | | If an attacker manages to compromise a maintainer’s       |
+  |             |   credentials, posing as the maintainer, they can in theory |
+  |             |   submit a malicious change (as a maintainer or as a        |
+  |             |   contributor), give all the necessary reviews and merge    |
+  |             |   the change.                                               |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | | - Enforce best practices recommended by GitHub [9]_       |
+  |             |                                                             |
+  |             | | - Not allowing a committer to both self-review and merge  |
+  |             |     patches they have submitted. To achieve the commit the  |
+  |             |     attacker would be required to compromise at least two   |
+  |             |     credentials (reviewers and maintainer).                 |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | We have not disallowed self-review/merge of patches         |
+  | implemented?|                                                             |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-SRC-MAIN-02                                                |
+  +=============+=============================================================+
+  | Description | An attacker can submit and merge malicious code after       |
+  |             | becoming a maintainer through social engineering            |
+  |             | techniques.                                                 |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | According to the TF project maintenance process [10]_,    |
+  | impact      |   maintainers of TF-A are selected by their peers based on  |
+  |             |   merit. Some of the criteria of becoming a maintainer      |
+  |             |   include being an active member of the project for a       |
+  |             |   minimum duration and contributing a substantial number of |
+  |             |   non-trivial and high-quality patches. However, there are  |
+  |             |   some weaknesses in the process:                           |
+  |             |                                                             |
+  |             | | - There is no structured mechanism to establish trust     |
+  |             |     with a maintainer other than the recommendations by     |
+  |             |     peers                                                   |
+  |             | | - There is no continuous monitoring of the status of a    |
+  |             |     maintainer (e.g. maintainer can move from one           |
+  |             |     organization to another)                                |
+  |             |                                                             |
+  |             | | To perform such an attack, in addition to becoming a      |
+  |             |   maintainer, an attacker also must deal with all           |
+  |             |   restrictions put on maintainers.                          |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | | - Structured mechanism to establish trust with            |
+  |             |     maintainers                                             |
+  |             |                                                             |
+  |             | | - Not allowing a committer to both self-review and merge  |
+  |             |     patches they have submitted. To achieve the commit the  |
+  |             |     attacker would be required to compromise at least two   |
+  |             |     credentials (reviewers and maintainer).                 |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | There is a structured mechanism to establish trust with     |
+  | implemented?| maintainers, but self-review/merge of patches is not        |
+  |             | disallowed                                                  |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-SRC-CONT-01                                                |
+  +=============+=============================================================+
+  | Description | An attacker can submit malicious code patch as a            |
+  |             | contributor.                                                |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | TF-A accepts external contributions to both the generic   |
+  | impact      |   and platform code. Unlike maintainers, contributors do    |
+  |             |   not have maintainer review or merging privileges,         |
+  |             |   therefore the likelihood of injecting malicious code as a |
+  |             |   contributor is lower. However, even though unlikely, it   |
+  |             |   is still possible for a malicious commit to go unnoticed  |
+  |             |   through the code review and verification processes.       |
+  |             |                                                             |
+  |             | | If successful, the impact can range from low to high      |
+  |             |   depending on the injected code. For example, an attacker  |
+  |             |   can potentially deliberately insert a memory corruption   |
+  |             |   vulnerability that is hard to notice on code review and   |
+  |             |   will not be detected by the verification process. This    |
+  |             |   vulnerability by itself may have a low impact but can     |
+  |             |   have a major impact if used in combination with other     |
+  |             |   vulnerabilities.                                          |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Code review and verification                              |
+  | Mitigations | - Static analysis to try to pick up issues that typically   |
+  |             |   end in some form of attack vector                         |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, contributions go through the thorough review,          |
+  | implemented?| verification, and static analysis process automated through |
+  |             | CI                                                          |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-DEP-01                                                     |
+  +=============+=============================================================+
+  | Description | An attacker can inject malicious code into TF-A internal    |
+  |             | dependencies.                                               |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | TF-A has two types of dependencies: those that are copied |
+  | impact      |   into the TF-A repository and shipped as part of TF-A code |
+  |             |   (referred to as *internal dependencies* here) and those   |
+  |             |   that are downloaded from external repositories and used   |
+  |             |   when building TF-A (referred to as                        |
+  |             |   *external dependencies* here).                            |
+  |             |                                                             |
+  |             | | Currently TF-A has three internal dependencies: *libfdt*  |
+  |             |   [1]_, *zlib* [2]_ and *compiler-rt* [3]_ libraries. These |
+  |             |   libraries are periodically updated by copying them from   |
+  |             |   their source repositories. Although unlikely, it is       |
+  |             |   possible for a contributor to copy the libraries from the |
+  |             |   wrong (and potentially malicious) repositories. For       |
+  |             |   example, there are already multiple forks of *libfdt*     |
+  |             |   (DTC) on GitHub. In addition to this, the official        |
+  |             |   repositories are not immune to threats described above    |
+  |             |   (TFA-SC-SRC-MAIN-01, TFA-SC-SRC-MAIN-02 and               |
+  |             |   TFA-SC-SRC-CONT-01).                                      |
+  |             |                                                             |
+  |             | | The likelihood of an attack on TF-A through internal      |
+  |             |   dependencies is lower than external dependencies for the  |
+  |             |   following reasons:                                        |
+  |             |                                                             |
+  |             | | - Internal dependencies go through the normal code review |
+  |             |     process during upgrade                                  |
+  |             | | - Once upgraded internal dependencies stay unchanged      |
+  |             |     until the next upgrade. The upgrade window is typically |
+  |             |     long (for example *libfdt* has only changed 4 times     |
+  |             |     over the past 4 years). This reduces the window of      |
+  |             |     opportunity for an attacker to inject malicious code    |
+  |             |     into the dependencies                                   |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Explicitly document versions and official sources of      |
+  | Mitigations |   dependencies                                              |
+  |             | - Keep a copy of a pinned version of the source code inside |
+  |             |   the TF-A tree so that the risk of getting malicious code  |
+  |             |   from dependencies only arises when we upgrade them        |
+  |             | - Monitor alerts for vulnerable dependencies from GitHub    |
+  |             |   [11]_                                                     |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, we explicitly document versions and official sources   |
+  | implemented?| of dependencies, keep a copy of pinned versions of the      |
+  |             | source code, and monitor alerts for vulnerable dependencies |
+  |             | for Python and Node.js, but we aren't able to do this for C |
+  |             | dependencies                                                |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-DEP-02                                                     |
+  +=============+=============================================================+
+  | Description | An attacker can inject malicious code into TF-A external    |
+  |             | dependencies.                                               |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | MEDIUM                                                      |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | Unlike internal dependencies, external dependencies are   |
+  | impact      |   downloaded from external repositories by end-users.       |
+  |             |   Although the TF-A documentation provides information      |
+  |             |   about the versions of dependencies used for testing and   |
+  |             |   links to repositories, it is up to the end-user to decide |
+  |             |   where to get the dependencies from. As such, the          |
+  |             |   likelihood of an attack through an external dependency is |
+  |             |   higher compared to an internal dependency.                |
+  |             |                                                             |
+  |             | | The impact of an attack ranges from low to critical       |
+  |             |   depending on which dependency and what part of the        |
+  |             |   dependency is affected. For example, a malicious code     |
+  |             |   that affects the signature verification functions in      |
+  |             |   MbedTLS is considered critical as it can be used to       |
+  |             |   bypass the TBB process of TF-A.                           |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Explicitly document versions and official sources of      |
+  | Mitigations |   dependencies                                              |
+  |             | - Provide scripts and build options to automatically fetch  |
+  |             |   the latest stable release of external dependencies        |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | We explicitly document versions and official sources of     |
+  | implemented?| dependencies, but do not yet provide scripts and build      |
+  |             | options to automatically fetch the latest stable release of |
+  |             | external dependencies                                       |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-REPO-01                                                    |
+  +=============+=============================================================+
+  | Description | An attacker can upload malicious versions of TF-A by        |
+  |             | compromising credentials of administrator accounts on       |
+  |             | tf.org or GitHub.                                           |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | This attack is like TFA-SC-SRC-MAIN-01, but the           |
+  | impact      |   likelihood and impact of the two attacks are different.   |
+  |             |                                                             |
+  |             | | The likelihood of compromising administrator credentials  |
+  |             |   is lower than that of a maintainer’s (assuming both use   |
+  |             |   authentication methods of similar strength) as there are  |
+  |             |   smaller number of administrators than maintainers. On the |
+  |             |   other hand, the impact is higher since an administrator   |
+  |             |   has more privileges than a maintainer:                    |
+  |             |                                                             |
+  |             | | - An administrator can upload a malicious TF-A            |
+  |             |     contribution unnoticed by other reviewers               |
+  |             |   - An administrator can potentially rewrite the history of |
+  |             |     the repository to evade detection                       |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | Strong authentication (Follow best practices recommended by |
+  | Mitigations | GitHub [9]_)                                                |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, strong authentication is implemented through           |
+  | implemented?| recommended best practices                                  |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-REPO-02                                                    |
+  +=============+=============================================================+
+  | Description | An attacker can upload malicious versions of TF-A after     |
+  |             | getting write access to the repository by exploiting a      |
+  |             | vulnerability on tf.org or GitHub.                          |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | There are no reports of someone exploiting a              |
+  | impact      |   vulnerability on GitHub or tf.org to upload malicious     |
+  |             |   contributions. However, there are examples of             |
+  |             |   vulnerabilities that allowed arbitrary code execution on  |
+  |             |   popular hosting services [12]_. Such vulnerabilities can  |
+  |             |   potentially be used to upload malicious packages. In      |
+  |             |   addition to being hard to exploit, vulnerabilities on     |
+  |             |   popular hosting sites such as GitHub are typically        |
+  |             |   detected quickly, making the window of opportunity for    |
+  |             |   such attack small.                                        |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Monitor alerts of any vulnerabilities that might affect   |
+  | Mitigations |   TF-A repository                                           |
+  |             | - Ensure tf.org is up to date with latest security patches  |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, alerts of vulnerabilities are monitored and tf.org is  |
+  | implemented?| ensured to be up to date with the latest security patches   |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-REPO-03                                                    |
+  +=============+=============================================================+
+  | Description | An attacker can host a malicious version of TF-A on an      |
+  |             | attacker-controlled repository, and trick end-users into    |
+  |             | downloading from that repository.                           |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | MEDIUM                                                      |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | It is not difficult for an attacker to create a website   |
+  | impact      |   with a similar domain name and look as tf.org (website    |
+  |             |   spoofing) and host a malicious TF-A source repository.    |
+  |             |   Similarly, an attacker can create a mirror of the TF-A    |
+  |             |   repository on GitHub with malicious code in it. However,  |
+  |             |   for this attack to succeed the attacker needs to trick    |
+  |             |   the end-user into using the attacker-controlled           |
+  |             |   repositories.                                             |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Users should carefully check the URL of the website       |
+  | Mitigations |   before visiting it and the URL of the repository before   |
+  |             |   checking it out                                           |
+  |             | - Accept reports of spoofing attacks on tf.org and          |
+  |             |   broadcast a warning to partners                           |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | We accept reports of spoofing attacks on tf.org and will    |
+  | implemented?| broadcast a warning to partners                             |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-TOOL-01                                                    |
+  +=============+=============================================================+
+  | Description | Malicious code can be injected at build time through        |
+  |             | malicious tools.                                            |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | End-users of TF-A use make (or cmake), compilers and      |
+  | impact      |   linkers (armgcc, armclang or LLVM) to build TF-A          |
+  |             |   binaries. Although TF-A documentation specifies versions  |
+  |             |   and official sources of tools used to build TF-A, users   |
+  |             |   can potentially be tricked into using unofficial,         |
+  |             |   malicious toolchains. Similar attacks have been used in   |
+  |             |   the past to inject malicious code into final products     |
+  |             |   [13]_.                                                    |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Explicitly document versions and official sources of      |
+  | Mitigations |   toolchains                                                |
+  |             | - Provide scripts to automatically fetch the latest stable  |
+  |             |   release of toolchains                                     |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | We explicitly document versions and official sources of     |
+  | implemented?| toolchains, but have not yet provided scripts to            |
+  |             | automatically fetch the latest stable release of toolchains |
+  +-------------+-------------------------------------------------------------+
+
+  +---------------------------------------------------------------------------+
+  | Threat: TFA-SC-TOOL-02                                                    |
+  +=============+=============================================================+
+  | Description | Malicious code can be executed by developer’s tools at      |
+  |             | installation time through malicious Node.js dependencies.   |
+  +-------------+-------------------------------------------------------------+
+  | Impact      | HIGH                                                        |
+  +-------------+-------------------------------------------------------------+
+  | Likelihood  | LOW                                                         |
+  +-------------+-------------------------------------------------------------+
+  | Threat and  | | Users of the Node.js tools, including the CI, may be      |
+  | impact      |   exposed to malicious dependencies that have been missed   |
+  |             |   by the Node.js dependency auditor. Users of these tools   |
+  |             |   could potentially be executing malicious code when using  |
+  |             |   these tools, which could potentially allow a malicious    |
+  |             |   actor to make silent modifications to the repository or   |
+  |             |   enable retrieval of user credentials.                     |
+  |             |                                                             |
+  |             | | If successful, the impact can range from low to high      |
+  |             |   depending on the user's credentials. If the user is an    |
+  |             |   administrator, this could imply TFA-SC-REPO-01.           |
+  +-------------+-------------------------------------------------------------+
+  | Proposed    | - Limit Node.js tools to a minimal set of trusted packages  |
+  | Mitigations | - Pin Node.js packages to known versions                    |
+  |             | - Update dependencies for which Node.js’s auditor reports   |
+  |             |   known CVEs                                                |
+  |             | - Execute Node.js tools in the CI only from within a        |
+  |             |   trusted container                                         |
+  +-------------+-------------------------------------------------------------+
+  | Mitigations | Yes, Node.js tools are limited to a minimal set of trusted  |
+  | implemented?| packages, packages are pinned to known versions,            |
+  |             | dependencies are updated when there are known CVEs          |
+  |             | reported, and Node.js tools are only executed within a      |
+  |             | trusted container in CI                                     |
+  +-------------+-------------------------------------------------------------+
+
+Appendix A
+**********
+
+Summary of trustedfirmware.org security:
+
+.. table:: Table 2: Security information of  trustedfirmware.org
+
+  +------------+--------------------+--------------------+--------------------+
+  | Software/  | Source and         | Credential and     | Security incident  |
+  | System     | integrity          | permission         | response plan      |
+  |            |                    | management         |                    |
+  +============+====================+====================+====================+
+  | Jenkins    | - Jenkins is built | - Use oauth from   | - Monitor CVE’s    |
+  | (including |   using Dockerfile |   Github only      |   and update       |
+  | plugins)   |   which is based   | - The password     |   Jenkins LTS on a |
+  |            |   on the official  |   strength follows |   monthly cycle    |
+  |            |   Jenkins docker   |   Github policy    | - Keep plugins up- |
+  |            |   image            | - Do not enforce   |   to-date. But it  |
+  |            | - Jenkins plugins  |   using two-factor |   is up to the     |
+  |            |   are built using  |   authentication   |   plugin owner to  |
+  |            |   the official     | - Jenkins uses     |   maintain said    |
+  |            |   install-         |   matrix auth      |   plugin           |
+  |            |   plugins.sh       |   which allows     |                    |
+  |            |                    |   users to manage  |                    |
+  |            |                    |   "job" level ACL  |                    |
+  |            |                    |   using Jenkins    |                    |
+  |            |                    |   Job Builder      |                    |
+  |            |                    | - No API token     |                    |
+  |            |                    |   enabled          |                    |
+  |            |                    | - Jenkins uses the |                    |
+  |            |                    |   inbuilt          |                    |
+  |            |                    |   credential store |                    |
+  |            |                    |   where we store   |                    |
+  |            |                    |   credentials for  |                    |
+  |            |                    |   LAVA, Jenkins    |                    |
+  |            |                    |   Job Builder,     |                    |
+  |            |                    |   DockerHub, AWS   |                    |
+  |            |                    |   and Gerrit       |                    |
+  |            |                    |   tokens. The      |                    |
+  |            |                    |   credentials are  |                    |
+  |            |                    |   stored as a      |                    |
+  |            |                    |   secret in        |                    |
+  |            |                    |   Jenkins          |                    |
+  |            |                    |   credential       |                    |
+  |            |                    |   store. These     |                    |
+  |            |                    |   credentials      |                    |
+  |            |                    |   can be accessed  |                    |
+  |            |                    |   via a Jenkins    |                    |
+  |            |                    |   job, but someone |                    |
+  |            |                    |   would have to    |                    |
+  |            |                    |   push a Jenkins   |                    |
+  |            |                    |   Job through a    |                    |
+  |            |                    |   Gerrit review to |                    |
+  |            |                    |   do this. Gerrit  |                    |
+  |            |                    |   maintains the    |                    |
+  |            |                    |   ACL for this and |                    |
+  |            |                    |   only admins and  |                    |
+  |            |                    |   project approver |                    |
+  |            |                    |   can +2 a review. |                    |
+  +------------+--------------------+--------------------+--------------------+
+  | Gerrit     | - Gerrit package   | - Use oauth from   | - Keep plugins up- |
+  | (including |   is installed     |   Github only      |   to-date. But it  |
+  | plugins)   |   from Linaro top  | - The password     |   is up to the     |
+  |            |   level role,      |   strength follows |   plugin owner to  |
+  |            |   which has a      |   Github policy    |   maintain said    |
+  |            |   md5sum check     | - Do not enforce   |   plugin           |
+  |            | - Gerrit Plugins   |   using two-factor |                    |
+  |            |   are installed    |   authentication   |                    |
+  |            |   from Ansible     | - Gerrit has ACL   |                    |
+  |            |   playbook, from   |   setup within the |                    |
+  |            |   the official     |   UI per-project   |                    |
+  |            |   Gerrit CI. The   |   level            |                    |
+  |            |   plugins are      | - No API token     |                    |
+  |            |   downloaded from  |   enabled          |                    |
+  |            |   https://gerrit-  | - A ci-bot-user    |                    |
+  |            |   ci.gerritforge.  |   created for      |                    |
+  |            |   com/             |   getting comments |                    |
+  |            | - Do not check     |   from Jenkins     |                    |
+  |            |   md5sum for every |                    |                    |
+  |            |   plugin           |                    |                    |
+  +------------+--------------------+--------------------+--------------------+
+  | Git        | - Package is from  | - All credentials  | - Monitor all      |
+  |            |   Linaro OBS (Open |   use GitHub. So   |   CVE's and apply  |
+  |            |   Build Service)   |   password         |   them immediately |
+  |            |   with a couple of |   strength etc are |   and keep servers |
+  |            |   “Linaro          |   based on GitHub  |   up-to-date       |
+  |            |   modifications”.  |   policy           |   monthly          |
+  |            |   (reference:      |                    | - The security     |
+  |            |   Ansible playbook |                    |   incident         |
+  |            |   and cgit repo)   |                    |   response plan is |
+  |            | - No special       |                    |   working in       |
+  |            |   integrity check  |                    |   progress         |
+  +------------+--------------------+--------------------+--------------------+
+  | Mailman    | - Installed from   | - It has           | - Plan to monitor  |
+  |            |   Ubuntu-          |   administrator    |   the CVE’s but no |
+  |            |   distributed      |   passwords for    |   timetable at the |
+  |            |   package          |   the various      |   moment           |
+  |            | - No special       |   mailing lists    |                    |
+  |            |   integrity check  | - The password     |                    |
+  |            |   (reply on APT    |   strength is not  |                    |
+  |            |   security)        |   specified        |                    |
+  +------------+--------------------+--------------------+--------------------+
+  | Website    | The website is     | There are no       | - The websites     |
+  |            | built on the IT    | credentials        |   themselves are   |
+  |            | Services' CI/CD    | associated with    |   static files     |
+  |            | server,            | the website        |   hosted on AWS S3 |
+  |            | bamboo.linaro.org, | itself. Any        |   and cached by    |
+  |            | from a Jekyll git  | permissions        |   AWS CloudFront   |
+  |            | repository stored  | required by bamboo | - The software     |
+  |            | on GitHub          | to carry out its   |   used to build    |
+  |            |                    | tasks are provided |   the website is   |
+  |            |                    | through AWS        |   all open source  |
+  |            |                    | instance role      |   and Linaro       |
+  |            |                    | permissions        |   occasionally     |
+  |            |                    |                    |   gets reports     |
+  |            |                    |                    |   from GitHub when |
+  |            |                    |                    |   an issue is      |
+  |            |                    |                    |   detected. Apply  |
+  |            |                    |                    |   a fix if it is   |
+  |            |                    |                    |   available. This  |
+  |            |                    |                    |   includes any     |
+  |            |                    |                    |   Javascript       |
+  |            |                    |                    |   frameworks that  |
+  |            |                    |                    |   might be used    |
+  |            |                    |                    |   within the web   |
+  |            |                    |                    |   pages            |
+  +------------+--------------------+--------------------+--------------------+
+  | ReadTheDocs| - One webhook ID   | - One TF-A account | - Keep database    |
+  |            |   per project is   |   with password    |   access list up   |
+  |            |   used by TF CI    |   stored in        |   to date          |
+  |            |   for building     |   engineering      | - Monitor security |
+  |            |   documentation    |   password         |   advisories       |
+  |            |   hosted by        |   database is used |                    |
+  |            |   ReadTheDocs      |   to manage        |                    |
+  |            | - Secret token     |   documentation    |                    |
+  |            |   supplied as part | - Access request   |                    |
+  |            |   of the webhook   |   is required      |                    |
+  |            |   post build       |   for database     |                    |
+  |            | - Updated content  |   access           |                    |
+  |            |   goes live        | - Token for        |                    |
+  |            |   automatically    |   Jenkins webhook  |                    |
+  |            |                    |   for CI uses      |                    |
+  |            |                    |   secret           |                    |
+  |            |                    |   credential       |                    |
+  |            |                    |   storage in       |                    |
+  |            |                    |   internal Jenkins |                    |
+  |            |                    |   and viewable     |                    |
+  |            |                    |   only through     |                    |
+  |            |                    |   ReadTheDocs      |                    |
+  |            |                    |   admin page       |                    |
+  +------------+--------------------+--------------------+--------------------+
+
+References
+**********
+
+.. [1] https://git.kernel.org/pub/scm/utils/dtc/dtc.git
+.. [2] http://zlib.net/
+.. [3] https://compiler-rt.llvm.org/
+.. [4] https://tls.mbed.org/
+.. [5] https://www.openssl.org/
+.. [6] https://github.com/ARM-software/SCP-firmware
+.. [7] https://github.com/tianocore/edk2
+.. [8] https://downloads.trustedfirmware.org/tf-a/
+.. [9] https://docs.github.com/en/github/authenticating-to-github/creating-a-strong-password
+.. [10] https://trustedfirmware-a.readthedocs.io/en/latest/process/maintenance.html#how-to-become-a-maintainer
+.. [11] https://docs.github.com/en/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies
+.. [12] "Backstabber’s Knife Collection: A Review of Open Source Software Supply Chain Attacks"
+.. [13] https://www.wired.com/story/supply-chain-hackers-videogames-asus-ccleaner/
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
+
+.. |TF-A System Diagram| image:: ../resources/diagrams/tf-a_system_diagram.png
+.. |TF-A Data Flow Diagram| image:: ../resources/diagrams/tf-a_data_flow_diagram.png
+.. |TF-A Attack Tree| image:: ../resources/diagrams/tf-a_attack_tree.png
diff --git a/docs/tools/cot-dt2c.rst b/docs/tools/cot-dt2c.rst
new file mode 100644
index 00000000..e8bb1ace
--- /dev/null
+++ b/docs/tools/cot-dt2c.rst
@@ -0,0 +1,119 @@
+TF-A CoT dt2c Tool
+==================
+
+This tool is used to automatically generate the corresponding c file for a
+CoT DT file. Since currently TF-A support two type of CoT file: static c file
+and CoT DT binding. This is error prone and hard to maintain, therefore this
+tool can generate the c file for the platform that does not support CoT DT
+binding, given the CoT DT file so the c file can be deprecated.
+
+Prerequisites
+~~~~~~~~~~~~~
+
+#. Python (3.8 or later)
+#. `Poetry`_ Python package manager
+
+Getting Started
+~~~~~~~~~~~~~~~
+
+``cot-dt2c`` is installed by default with TF-A's poetry environment. All of it's
+dependencies are listed in `tools/cot_dt2c/pyproject.toml`_.
+
+``cot-dt2c`` requires a standard DTS file without #ifdef, macros, or other
+preprocessor directives. Therefore, you need to provide a preprocessed device
+tree source(DTS) as input to the tool.
+
+#. Usage of the tool
+
+    .. code::
+
+        cot-dt2c
+
+    This command will output the following as usage for this command
+
+    .. code-block:: text
+
+        Usage: cot-dt2c [OPTIONS] COMMAND [ARGS]...
+
+        Options:
+        --version  Show the version and exit.
+        --help     Show this message and exit.
+
+        Commands:
+        convert-to-c
+        validate-cot
+        visualize-cot
+        validate-dt
+
+Convert CoT descriptors to C file
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To convert the CoT descriptors
+
+This command is for the platform that does not use CoT DT parser,
+which can generate the C file given the CoT descriptors. Before
+the conversion to C file, the tool will do an implicit checks on
+the validity of the CoT DT file.
+
+.. code::
+
+    cot-dt2c convert-to-c [INPUT DTS PATH] [OUTPUT C PATH]
+    cot-dt2c convert-to-c fdts/tbbr_cot_descriptors.dtsi test.c
+
+
+Validate CoT descriptors
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To validate the certificate
+
+The tests folder in the tool folder provides some bad-example of the
+DT file, and the tool will print out "not a valid CoT DT file" on console.
+
+The command will check the format of the CoT file
+
+#. The open bracket
+#. The open ifdef macro
+#. The missing mandatory attribute
+#. Malformed DT file (cert missing parent, missing root certs. etc.)
+
+Currently the validation is specifically for checking the CoT DT file
+
+.. code::
+
+    cot-dt2c validate-cot [INPUT DTS PATH]
+    cot-dt2c validate-cot fdts/tbbr_cot_descriptors.dtsi
+
+
+Visualize CoT descriptors
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This command create a HTML to visualize the relationship between
+the certificates and the image of a CoT DT file.
+
+.. code::
+
+    cot-dt2c visualize-cot [INPUT DTS PATH]
+    cot-dt2c visualize-cot fdts/tbbr_cot_descriptors.dtsi
+
+
+Validate Other DT files
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The command will transform the dtsi/dts file into a more standard
+dtsi/dts file inside /tmp folder that can be used as input to dt-schema
+for further validation. Currently the tool will perform some basic validation
+for the file (syntax) and dt-schema can be used for advance checks. dt-schema
+is not installed along with the tool.
+
+.. code::
+
+    cot-dt2c validate-dt [INPUT DTS PATH or INPUT DTS folder]
+    cot-dt2c validate-dt fdts/
+    cot-dt2c validate-dt fdts/fvp-bsae-gicv3.dtsi
+
+--------------
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
+
+.. _tools/cot_dt2c/pyproject.toml: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/integration/tools/cot_dt2c/pyproject.toml
+.. _Poetry: https://python-poetry.org/docs/
diff --git a/docs/tools/index.rst b/docs/tools/index.rst
index 2dee2c07..c0e214a9 100644
--- a/docs/tools/index.rst
+++ b/docs/tools/index.rst
@@ -6,7 +6,9 @@ Tools
    :caption: Contents
 
    memory-layout-tool
+   transfer-list-compiler
+   cot-dt2c
 
 --------------
 
-*Copyright (c) 2023, Arm Limited. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited. All rights reserved.*
diff --git a/docs/tools/transfer-list-compiler.rst b/docs/tools/transfer-list-compiler.rst
new file mode 100644
index 00000000..fa660dc6
--- /dev/null
+++ b/docs/tools/transfer-list-compiler.rst
@@ -0,0 +1,311 @@
+Transfer List Compiler
+======================
+
+The Transfer List Compiler (tlc) is a host tool used by TF-A to generate transfer
+lists compliant with the v0.9 of the `Firmware Handoff specification`_. It enables
+developers to statically generate transfer list blobs containing any number of
+transfer entries.
+
+Getting Started
+~~~~~~~~~~~~~~~
+
+``tlc`` is installed by default with TF-A's poetry environment. All of it's
+dependencies are listed in `tools/tlc/pyproject.toml`_.
+
+To install ``tlc`` seperately, run the following command:
+
+.. code::
+
+    make -C tools/tlc install
+
+Creating a Transfer List
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+To create an empty TL, you can use the ``create`` command.
+
+.. code::
+
+    tlc create tl.bin
+
+This commands generates a binary blob representing an empty TL, shown in the
+hexdump below.
+
+.. code::
+
+    $ hexdump tl.bin | head
+    0000000 b10b 4a0f 01a6 0318 0018 0000 1000 0000
+    0000010 0001 0000 0000 0000
+
+A common use-case this tool supports is the addition of TE's via the option
+``--entry``. This takes as input the tag ID and path to a binary blob to be
+included in the transfer list. The snippet below shows how to include an FDT in
+the TL.
+
+.. code::
+
+    tlc create --entry 1 fdt.dtb tl.bin
+
+Alternatively, addition of a device tree is supported through the option
+``--fdt``. This has the same effect as passing the device tree and it's tag ID
+through the ``--entry`` option.
+
+.. code::
+
+    tlc create --fdt fdt.dtb tl.bin
+
+.. note::
+
+    ``tlc`` makes no effort to verify the contents of a binary blob against the
+    provided tag ID. It only checks that the tags provided as input are within
+    range and that there is sufficient memory to include their TE's.
+
+You can also create a TL from a YAML config file.
+
+.. code ::
+
+    tlc create --from-yaml config.yaml tl.bin
+
+Printing the contents of a TL
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Support is provided for dumping the contents of a TL via the ``info`` command.
+This prints the header of the TL and all included TE's.
+
+.. code::
+
+    $ tlc info tl.bin
+    signature  0x4a0fb10b
+    checksum   0xe1
+    version    0x1
+    hdr_size   0x18
+    alignment  0x3
+    size       0x2a6f
+    total_size 0x4e20
+    flags      0x1
+    ----
+    id         0x1
+    data_size  0x2a47
+    hdr_size   0x8
+    offset     0x18
+    ----
+    id         0x0
+    data_size  0x0
+    hdr_size   0x8
+    offset     0x2a68
+
+The example above shows the dump produced by ``tlc`` for a 20Kb TL containing a
+device tree (tag_id=1) and a NULL entry (tag_id=0).
+
+Modifying the contents of an existing TL
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`tlc` supports removal of one or more entries from a TL through the ``remove``
+command. It takes as argument the filename, and one or more tag ID's, passed
+through the ``--tags`` option.  It produces a valid TL blob without those
+entries.
+
+
+For example, using the same blob as in the section above, we can remove the FDT
+TE with the command.
+
+.. code::
+
+    $ tlc remove --tags 1 tl.bin
+
+Using the ``info`` command, shows the the TE has been remove:
+
+.. code::
+
+    $ tlc info tl.bin
+
+    signature  0x4a0fb10b
+    checksum   0x38
+    version    0x1
+    hdr_size   0x18
+    alignment  0x3
+    size       0x20
+    total_size 0x4e20
+    flags      0x1
+    ----
+    id         0x0
+    data_size  0x0
+    hdr_size   0x8
+    offset     0x18
+
+Note that more than one entry can be removed at a time. The ``--tags`` option
+accepts multiple tag ID's.
+
+Conversely, TE's can be added to an existing TL. This is achieved through the
+`add` command.
+
+.. code::
+
+    $ tlc add --entry 1 fdt.dtb tl.bin
+
+
+The result of this modification is shown below:
+
+.. code::
+
+    $ tlc info tl.bin
+
+    signature  0x4a0fb10b
+    checksum   0xe1
+    version    0x1
+    hdr_size   0x18
+    alignment  0x3
+    size       0x2a6f
+    total_size 0x4e20
+    flags      0x1
+    ----
+    id         0x0
+    data_size  0x0
+    hdr_size   0x8
+    offset     0x18
+    ----
+    id         0x1
+    data_size  0x2a47
+    hdr_size   0x8
+    offset     0x20
+
+Unpacking a Transfer List
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Given a transfer list, ``tlc`` also provides a mechanism for extracting TE data.
+Running the command ``unpack``, yields binary files containing data from all the TE's.
+
+.. code::
+
+    $ tlc create --size 20000 --fdt build/fvp/debug/fdts/fvp-base-gicv3-psci.dtb tl.bin
+    $ tlc unpack tl.bin
+    $ file te_1.bin
+    te_1.bin: Device Tree Blob version 17, size=10823, boot CPU=0, string block size=851, DT structure block size=9900
+
+Validate a Transfer List
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+``tlc validate`` provides a quick and simple mechanism for checking wether the TL
+is compliant with version of the specification supported by the tool. It
+performs the following checks:
+
+#. Validates the signature.
+#. Ensures that the specified version is greater than or equal to the tool’s current version.
+#. Verifies alignment criteria for all TE’s.
+
+YAML Config File Format
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Example YAML config file:
+
+.. code::
+
+    execution_state: aarch32
+    has_checksum: true
+    max_size: 4096
+    entries:
+            - tag_id: 258  # entry point info
+              ep_info:
+                      args:
+                              - 67112968
+                              - 67112960
+                              - 0
+                              - 0
+                              - 0
+                              - 0
+                              - 0
+                              - 0
+                      h:
+                              attr: 8
+                              type: 1
+                              version: 2
+                      pc: 67239936
+                      spsr: 467
+            - tag_id: 3  # memory layout
+              addr: 8
+              size: 8
+            - tag_id: 1,  # fdt
+              blob_file_path: "fdt.bin",
+
+`max_size` defaults to `0x1000`, `execution_state` defaults to `aarch64`, and `has_checksum`
+defaults to `true`.
+
+The fields of the YAML file should match the fields in the specification for the transfer list. You
+don't need to give the hdr_size or data_size fields. For example, a memory layout entry would have
+an entry like:
+
+.. code::
+
+    tag_id: 3
+    addr: 8
+    size: 8
+
+You can input blob files by giving paths to the current working directory. You can do this for any
+TE type. For example, an FDT layout would have an entry like:
+
+.. code::
+
+    tag_id: 1,
+    blob_file_path: "fdt.bin",
+
+You can input C-types by giving its fields. For example, an entry point
+info entry would have an entry like:
+
+.. code::
+
+    tag_id: 258
+    ep_info:
+            args:
+                    - 67112968
+                    - 67112960
+                    - 0
+                    - 0
+            h:
+                    attr: 8
+                    type: 1
+                    version: 2
+            lr_svc: 0
+            pc: 67239936
+            spsr: 467
+
+You can give the name of the tag instead of the tag id number. The valid tag names are in the
+`transfer_entry_formats` dict in `tools/tlc/tlc/tl.py`_. Some examples are:
+
+* empty
+* fdt
+* hob_block
+* hob_list
+
+You can input the attr field of entry_point_info as a string of flag
+names separated by `|`. The names are taken from ep_info_exp.h in TF-A.
+For example:
+
+.. code::
+
+    has_checksum: true
+    max_size: 4096
+    entries:
+    - tag_id: 0x102
+      ep_info:
+        args:
+        - 67112976
+        - 67112960
+        - 0
+        - 0
+        - 0
+        - 0
+        - 0
+        - 0
+        h:
+          attr: EP_NON_SECURE | EP_ST_ENABLE
+          type: 1
+          version: 2
+        pc: 67239936
+        spsr: 965
+
+--------------
+
+*Copyright (c) 2024, Arm Limited. All rights reserved.*
+
+.. _Firmware Handoff specification: https://github.com/FirmwareHandoff/firmware_handoff/
+.. _tools/tlc/pyproject.toml: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/master/tools/tlc/pyproject.toml
+.. _tools/tlc/tlc/tl.py: https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/refs/heads/master/tools/tlc/tlc/tl.py
diff --git a/drivers/arm/css/dsu/dsu.c b/drivers/arm/css/dsu/dsu.c
new file mode 100644
index 00000000..f0e8df12
--- /dev/null
+++ b/drivers/arm/css/dsu/dsu.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/css/dsu.h>
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+/*
+ * Context structure that saves the state of DSU PMU registers
+ */
+cluster_pmu_state_t cluster_pmu_context[PLAT_ARM_CLUSTER_COUNT];
+
+/****************************************************************************
+ * This function, save_dsu_pmu_state, is designed to save the
+ * current state of the Performance Monitoring Unit (PMU) for a cluster.
+ *
+ * The function performs the following operations:
+ * 1. Saves the current values of several PMU registers
+ *    (CLUSTERPMCR_EL1, CLUSTERPMCNTENSET_EL1, CLUSTERPMCCNTR_EL1,
+ *    CLUSTERPMOVSSET_EL1, and CLUSTERPMSELR_EL1) into the cluster_pmu_state
+ *    structure.
+ *
+ * 2. Disables the PMU event counting by
+ *    clearing the E bit in the clusterpmcr_el1 register.
+ *
+ * 3. Iterates over the available PMU counters as
+ *    determined by the read_cluster_eventctr_num() function.
+ *    For each counter, it:
+ *    a. Selects the counter by writing its index to CLUSTERPMSELR_EL1.
+ *    b. Reads the current counter value (event count) and
+ *       the event type being counted from CLUSTERPMXEVCNTR_EL1 and
+ *       CLUSTERPMXEVTYPER_EL1 registers, respectively.
+ *
+ * This function is useful for preserving the DynamIQ Shared Unit's (DSU)
+ * PMU registers over a power cycle.
+ ***************************************************************************/
+
+void save_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_state)
+{
+	unsigned int idx = 0U;
+	unsigned int cluster_eventctr_num = read_cluster_eventctr_num();
+
+	assert(cluster_pmu_state != 0);
+
+	save_pmu_reg(cluster_pmu_state, clusterpmcr);
+
+	write_clusterpmcr(cluster_pmu_state->clusterpmcr &
+			~(CLUSTERPMCR_E_BIT));
+
+	save_pmu_reg(cluster_pmu_state, clusterpmcntenset);
+
+	save_pmu_reg(cluster_pmu_state, clusterpmccntr);
+
+	save_pmu_reg(cluster_pmu_state, clusterpmovsset);
+
+	save_pmu_reg(cluster_pmu_state, clusterpmselr);
+
+	for (idx = 0U ; idx < cluster_eventctr_num ; idx++) {
+		write_clusterpmselr(idx);
+		cluster_pmu_state->counter_val[idx] = read_clusterpmxevcntr();
+		cluster_pmu_state->counter_type[idx] = read_clusterpmxevtyper();
+	}
+}
+
+void cluster_off_dsu_pmu_context_save(void)
+{
+	unsigned int cluster_pos;
+
+	cluster_pos = (unsigned int) plat_cluster_id_by_mpidr(read_mpidr_el1());
+
+	save_dsu_pmu_state(&cluster_pmu_context[cluster_pos]);
+}
+
+/*****************************************************************************
+ * This function, restore_dsu_pmu_state, restores the state of the
+ * Performance Monitoring Unit (PMU) from a previously saved state.
+ *
+ * The function performs the following operations:
+ * 1. Restores the CLUSTERPMCR_EL1 register with the
+ *    saved value from the cluster_pmu_state structure.
+ * 2. Iterates over the available PMU counters as determined
+ *    by the read_cluster_eventctr_num() function. For each counter, it:
+ *    a. Selects the counter by writing its index to CLUSTERPMSELR_EL1.
+ *    b. Restores the counter value (event count) and the event type to
+ *       CLUSTERPMXEVCNTR_EL1 and CLUSTERPMXEVTYPER_EL1 registers, respectively
+ * 3. Restores several other PMU registers (CLUSTERPMSELR_EL1,
+ *    CLUSTERPMOVSCLR_EL1, CLUSTERPMOVSSET_EL1, CLUSTERPMCCNTR_EL1,
+ *    and CLUSTERPMCNTENSET_EL1) with their saved values.
+ *
+ *****************************************************************************/
+void restore_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_state)
+{
+	unsigned int idx = 0U;
+	unsigned int cluster_eventctr_num = read_cluster_eventctr_num();
+
+	assert(cluster_pmu_state != 0);
+
+	for (idx = 0U ; idx < cluster_eventctr_num ; idx++) {
+		write_clusterpmselr(idx);
+		write_clusterpmxevcntr(cluster_pmu_state->counter_val[idx]);
+		write_clusterpmxevtyper(cluster_pmu_state->counter_type[idx]);
+	}
+
+	restore_pmu_reg(cluster_pmu_state, clusterpmselr);
+
+	write_clusterpmovsclr(~(uint32_t)cluster_pmu_state->clusterpmovsset);
+
+	restore_pmu_reg(cluster_pmu_state, clusterpmovsset);
+
+	restore_pmu_reg(cluster_pmu_state, clusterpmccntr);
+
+	restore_pmu_reg(cluster_pmu_state, clusterpmcntenset);
+
+	write_clusterpmcr(cluster_pmu_state->clusterpmcr);
+}
+
+void cluster_on_dsu_pmu_context_restore(void)
+{
+	unsigned int cluster_pos;
+
+	cluster_pos = (unsigned int) plat_cluster_id_by_mpidr(read_mpidr_el1());
+
+	restore_dsu_pmu_state(&cluster_pmu_context[cluster_pos]);
+}
+
diff --git a/drivers/arm/css/scmi/scmi_common.c b/drivers/arm/css/scmi/scmi_common.c
index ec749fb5..ca855fe7 100644
--- a/drivers/arm/css/scmi/scmi_common.c
+++ b/drivers/arm/css/scmi/scmi_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/arm/css/scmi.h>
+#include <drivers/delay_timer.h>
 
 #include "scmi_private.h"
 
@@ -60,8 +61,10 @@ void scmi_send_sync_command(scmi_channel_t *ch)
 	dmbsy();
 
 	/* Wait for channel to be free */
-	while (!SCMI_IS_CHANNEL_FREE(mbx_mem->status))
-		;
+	while (!SCMI_IS_CHANNEL_FREE(mbx_mem->status)) {
+		if (ch->info->delay != 0)
+			udelay(ch->info->delay);
+	}
 
 	/*
 	 * Ensure that any read to the SCMI payload area is done after reading
diff --git a/drivers/arm/css/scp/css_sds.c b/drivers/arm/css/scp/css_sds.c
index e42ee10d..d9965c67 100644
--- a/drivers/arm/css/scp/css_sds.c
+++ b/drivers/arm/css/scp/css_sds.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,7 @@ int css_scp_boot_image_xfer(void *image, unsigned int image_size)
 	int ret;
 	unsigned int image_offset, image_flags;
 
-	ret = sds_init();
+	ret = sds_init(SDS_SCP_AP_REGION_ID);
 	if (ret != SDS_OK) {
 		ERROR("SCP SDS initialization failed\n");
 		panic();
@@ -28,13 +28,15 @@ int css_scp_boot_image_xfer(void *image, unsigned int image_size)
 
 	VERBOSE("Writing SCP image metadata\n");
 	image_offset = (uintptr_t) image - ARM_TRUSTED_SRAM_BASE;
-	ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_ADDR_OFFSET,
+	ret = sds_struct_write(SDS_SCP_AP_REGION_ID,
+			SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_ADDR_OFFSET,
 			&image_offset, SDS_SCP_IMG_ADDR_SIZE,
 			SDS_ACCESS_MODE_NON_CACHED);
 	if (ret != SDS_OK)
 		goto sds_fail;
 
-	ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_SIZE_OFFSET,
+	ret = sds_struct_write(SDS_SCP_AP_REGION_ID,
+			SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_SIZE_OFFSET,
 			&image_size, SDS_SCP_IMG_SIZE_SIZE,
 			SDS_ACCESS_MODE_NON_CACHED);
 	if (ret != SDS_OK)
@@ -42,7 +44,8 @@ int css_scp_boot_image_xfer(void *image, unsigned int image_size)
 
 	VERBOSE("Marking SCP image metadata as valid\n");
 	image_flags = SDS_SCP_IMG_VALID_FLAG_BIT;
-	ret = sds_struct_write(SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_FLAG_OFFSET,
+	ret = sds_struct_write(SDS_SCP_AP_REGION_ID,
+			SDS_SCP_IMG_STRUCT_ID, SDS_SCP_IMG_FLAG_OFFSET,
 			&image_flags, SDS_SCP_IMG_FLAG_SIZE,
 			SDS_ACCESS_MODE_NON_CACHED);
 	if (ret != SDS_OK)
@@ -68,7 +71,8 @@ int css_scp_boot_ready(void)
 
 	/* Wait for the SCP RAM Firmware to complete its initialization process */
 	while (retry > 0) {
-		ret = sds_struct_read(SDS_FEATURE_AVAIL_STRUCT_ID, 0,
+		ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+				SDS_FEATURE_AVAIL_STRUCT_ID, 0,
 				&scp_feature_availability_flags,
 				SDS_FEATURE_AVAIL_SIZE,
 				SDS_ACCESS_MODE_NON_CACHED);
diff --git a/drivers/arm/css/sds/sds.c b/drivers/arm/css/sds/sds.c
index 1fb196c7..91f0a27a 100644
--- a/drivers/arm/css/sds/sds.c
+++ b/drivers/arm/css/sds/sds.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,40 +15,39 @@
 
 #include "sds_private.h"
 
-/*
- * Variables used to track and maintain the state of the memory region reserved
- * for usage by the SDS framework.
- */
+/* Array of SDS memory region descriptions */
+static sds_region_desc_t *sds_regions;
 
-/* Pointer to the base of the SDS memory region */
-static uintptr_t sds_mem_base;
-
-/* Size of the SDS memory region in bytes */
-static size_t sds_mem_size;
+/* Total count of SDS memory regions */
+static unsigned int sds_region_cnt;
 
 /*
  * Perform some non-exhaustive tests to determine whether any of the fields
  * within a Structure Header contain obviously invalid data.
  * Returns SDS_OK on success, SDS_ERR_FAIL on error.
  */
-static int sds_struct_is_valid(uintptr_t header)
+static int sds_struct_is_valid(unsigned int region_id, uintptr_t header)
 {
 	size_t struct_size = GET_SDS_HEADER_STRUCT_SIZE(header);
 
 	/* Zero is not a valid identifier */
-	if (GET_SDS_HEADER_ID(header) == 0)
+	if (GET_SDS_HEADER_ID(header) == 0) {
 		return SDS_ERR_FAIL;
+	}
 
 	/* Check SDS Schema version */
-	if (GET_SDS_HEADER_VERSION(header) == SDS_REGION_SCH_VERSION)
+	if (GET_SDS_HEADER_VERSION(header) == SDS_REGION_SCH_VERSION) {
 		return SDS_ERR_FAIL;
+	}
 
 	/* The SDS Structure sizes have to be multiple of 8 */
-	if ((struct_size == 0) || ((struct_size % 8) != 0))
+	if ((struct_size == 0) || ((struct_size % 8) != 0)) {
 		return SDS_ERR_FAIL;
+	}
 
-	if (struct_size > sds_mem_size)
+	if (struct_size > sds_regions[region_id].size) {
 		return SDS_ERR_FAIL;
+	}
 
 	return SDS_OK;
 }
@@ -57,10 +56,11 @@ static int sds_struct_is_valid(uintptr_t header)
  * Validate the SDS structure headers.
  * Returns SDS_OK on success, SDS_ERR_FAIL on error.
  */
-static int validate_sds_struct_headers(void)
+static int validate_sds_struct_headers(unsigned int region_id)
 {
 	unsigned int i, structure_count;
 	uintptr_t header;
+	uintptr_t sds_mem_base = sds_regions[region_id].base;
 
 	structure_count = GET_SDS_REGION_STRUCTURE_COUNT(sds_mem_base);
 
@@ -71,7 +71,7 @@ static int validate_sds_struct_headers(void)
 
 	/* Iterate over structure headers and validate each one */
 	for (i = 0; i < structure_count; i++) {
-		if (sds_struct_is_valid(header) != SDS_OK) {
+		if (sds_struct_is_valid(region_id, header) != SDS_OK) {
 			WARN("SDS: Invalid structure header detected\n");
 			return SDS_ERR_FAIL;
 		}
@@ -84,10 +84,12 @@ static int validate_sds_struct_headers(void)
  * Get the structure header pointer corresponding to the structure ID.
  * Returns SDS_OK on success, SDS_ERR_STRUCT_NOT_FOUND on error.
  */
-static int get_struct_header(uint32_t structure_id, struct_header_t **header)
+static int get_struct_header(unsigned int region_id, uint32_t structure_id,
+			struct_header_t **header)
 {
 	unsigned int i, structure_count;
 	uintptr_t current_header;
+	uintptr_t sds_mem_base = sds_regions[region_id].base;
 
 	assert(header);
 
@@ -116,12 +118,14 @@ static int get_struct_header(uint32_t structure_id, struct_header_t **header)
  * Returns SDS_OK if structure header exists else SDS_ERR_STRUCT_NOT_FOUND
  * if not found.
  */
-int sds_struct_exists(unsigned int structure_id)
+int sds_struct_exists(unsigned int region_id, unsigned int structure_id)
 {
 	struct_header_t *header = NULL;
 	int ret;
 
-	ret = get_struct_header(structure_id, &header);
+	assert(region_id < sds_region_cnt);
+
+	ret = get_struct_header(region_id, structure_id, &header);
 	if (ret == SDS_OK) {
 		assert(header);
 	}
@@ -136,18 +140,21 @@ int sds_struct_exists(unsigned int structure_id)
  * The `data` is the pointer to store the read data of size specified by `size`.
  * Returns SDS_OK on success or corresponding error codes on failure.
  */
-int sds_struct_read(uint32_t structure_id, unsigned int fld_off,
-		void *data, size_t size, sds_access_mode_t mode)
+int sds_struct_read(unsigned int region_id, uint32_t structure_id,
+		unsigned int fld_off, void *data, size_t size,
+		sds_access_mode_t mode)
 {
 	int status;
 	uintptr_t field_base;
 	struct_header_t *header = NULL;
 
+	assert(region_id < sds_region_cnt);
+
 	if (!data)
 		return SDS_ERR_INVALID_PARAMS;
 
 	/* Check if a structure with this ID exists */
-	status = get_struct_header(structure_id, &header);
+	status = get_struct_header(region_id, structure_id, &header);
 	if (status != SDS_OK)
 		return status;
 
@@ -182,18 +189,21 @@ int sds_struct_read(uint32_t structure_id, unsigned int fld_off,
  * The `data` is the pointer to data of size specified by `size`.
  * Returns SDS_OK on success or corresponding error codes on failure.
  */
-int sds_struct_write(uint32_t structure_id, unsigned int fld_off,
-		void *data, size_t size, sds_access_mode_t mode)
+int sds_struct_write(unsigned int region_id, uint32_t structure_id,
+		unsigned int fld_off, void *data, size_t size,
+		sds_access_mode_t mode)
 {
 	int status;
 	uintptr_t field_base;
 	struct_header_t *header = NULL;
 
+	assert(region_id < sds_region_cnt);
+
 	if (!data)
 		return SDS_ERR_INVALID_PARAMS;
 
 	/* Check if a structure with this ID exists */
-	status = get_struct_header(structure_id, &header);
+	status = get_struct_header(region_id, structure_id, &header);
 	if (status != SDS_OK)
 		return status;
 
@@ -226,15 +236,21 @@ int sds_struct_write(uint32_t structure_id, unsigned int fld_off,
 
 /*
  * Initialize the SDS driver. Also verifies the SDS version and sanity of
- * the SDS structure headers.
+ * the SDS structure headers in the given SDS region.
  * Returns SDS_OK on success, SDS_ERR_FAIL on error.
  */
-int sds_init(void)
+int sds_init(unsigned int region_id)
 {
-	sds_mem_base = (uintptr_t)PLAT_ARM_SDS_MEM_BASE;
+	if (sds_regions == NULL) {
+		sds_regions = plat_sds_get_regions(&sds_region_cnt);
+	}
+
+	assert(region_id < sds_region_cnt);
+
+	uintptr_t sds_mem_base = sds_regions[region_id].base;
 
 	if (!IS_SDS_REGION_VALID(sds_mem_base)) {
-		WARN("SDS: No valid SDS Memory Region found\n");
+		VERBOSE("SDS: No valid SDS Memory Region found\n");
 		return SDS_ERR_FAIL;
 	}
 
@@ -244,15 +260,16 @@ int sds_init(void)
 		return SDS_ERR_FAIL;
 	}
 
-	sds_mem_size = GET_SDS_REGION_SIZE(sds_mem_base);
-	if (sds_mem_size > PLAT_ARM_SDS_MEM_SIZE_MAX) {
+	sds_regions[region_id].size = GET_SDS_REGION_SIZE(sds_mem_base);
+	if (sds_regions[region_id].size > PLAT_ARM_SDS_MEM_SIZE_MAX) {
 		WARN("SDS: SDS Memory Region exceeds size limit\n");
 		return SDS_ERR_FAIL;
 	}
 
-	INFO("SDS: Detected SDS Memory Region (%zu bytes)\n", sds_mem_size);
+	INFO("SDS: Detected SDS Memory Region (%zu bytes)\n",
+		sds_regions[region_id].size);
 
-	if (validate_sds_struct_headers() != SDS_OK)
+	if (validate_sds_struct_headers(region_id) != SDS_OK)
 		return SDS_ERR_FAIL;
 
 	return SDS_OK;
diff --git a/drivers/arm/dcc/dcc_console.c b/drivers/arm/dcc/dcc_console.c
index 19c3450b..841c1fde 100644
--- a/drivers/arm/dcc/dcc_console.c
+++ b/drivers/arm/dcc/dcc_console.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2015-2021, Xilinx Inc.
+ * Copyright (c) 2015-2022, Xilinx Inc.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  * Written by Michal Simek.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -45,7 +46,7 @@
 #define TIMEOUT_COUNT_US	U(0x10624)
 
 struct dcc_console {
-	struct console console;
+	console_t console;
 };
 
 static inline uint32_t __dcc_getstatus(void)
@@ -147,13 +148,14 @@ static struct dcc_console dcc_console = {
 	},
 };
 
-int console_dcc_register(void)
+int console_dcc_register(console_t *console)
 {
-	return console_register(&dcc_console.console);
+	memcpy(console, &dcc_console.console, sizeof(console_t));
+	return console_register(console);
 }
 
-void console_dcc_unregister(void)
+void console_dcc_unregister(console_t *console)
 {
-	dcc_console_flush(&dcc_console.console);
-	(void)console_unregister(&dcc_console.console);
+	dcc_console_flush(console);
+	(void)console_unregister(console);
 }
diff --git a/drivers/arm/gic/v3/arm_gicv3_common.c b/drivers/arm/gic/v3/arm_gicv3_common.c
index 44898928..cc82ddb1 100644
--- a/drivers/arm/gic/v3/arm_gicv3_common.c
+++ b/drivers/arm/gic/v3/arm_gicv3_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,10 +28,13 @@
 void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num)
 {
 	uintptr_t gicr_base = 0;
+	unsigned int typer_reg;
 
 	assert(gicv3_driver_data);
 	assert(gicv3_driver_data->rdistif_base_addrs);
+	assert(gicv3_driver_data->gicd_base != 0U);
 
+	typer_reg = gicd_read_typer(gicv3_driver_data->gicd_base);
 	/*
 	 * The GICR_WAKER.Sleep bit should be set only when both
 	 * GICR_WAKER.ChildrenAsleep and GICR_WAKER.ProcessorSleep are set on
@@ -60,9 +63,14 @@ void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num)
 	 */
 	gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_SL_BIT);
 
-	/* Wait until the GICR_WAKER.Quiescent bit is set */
-	while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT))
-		;
+	/*
+	 * If LPIs are supported, wait until the GICR_WAKER.Quiescent bit is
+	 * set.
+	 */
+	if ((typer_reg & TYPER_LPIS) != 0U) {
+		while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT))
+			;
+	}
 }
 
 /*
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
index a4786bb8..5e44aa95 100644
--- a/drivers/arm/gic/v3/gic600_multichip.c
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2022-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -75,7 +75,7 @@ static void set_gicd_dchipr_rt_owner(uintptr_t base, unsigned int rt_owner)
 		panic();
 	}
 
-	/* Poll till PUP is zero before intiating write */
+	/* Poll till PUP is zero before initiating write */
 	gicd_dchipr_wait_for_power_update_progress(base);
 
 	write_gicd_dchipr(base, read_gicd_dchipr(base) |
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 3c995171..2be19db7 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -34,8 +34,8 @@ static spinlock_t gic_lock;
 #pragma weak gicv3_rdistif_off
 #pragma weak gicv3_rdistif_on
 
-/* Check interrupt ID for SGI/(E)PPI and (E)SPIs */
-static bool is_sgi_ppi(unsigned int id);
+/* Check for valid SGI/PPI or SPI interrupt ID */
+static bool is_valid_interrupt(unsigned int id);
 
 /*
  * Helper macros to save and restore GICR and GICD registers
@@ -447,8 +447,12 @@ unsigned int gicv3_get_interrupt_group(unsigned int id, unsigned int proc_num)
 		return INTR_GROUP1NS;
 	}
 
+	if (!is_valid_interrupt(id)) {
+		panic();
+	}
+
 	/* Check interrupt ID */
-	if (is_sgi_ppi(id)) {
+	if (IS_SGI_PPI(id)) {
 		/* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */
 		assert(gicv3_driver_data->rdistif_base_addrs != NULL);
 		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
@@ -682,6 +686,8 @@ void gicv3_rdistif_init_restore(unsigned int proc_num,
 	gicr_write_ctlr(gicr_base,
 			rdist_ctx->gicr_ctlr & ~(GICR_CTLR_EN_LPIS_BIT));
 
+	gicr_wait_for_pending_write(gicr_base);
+
 	/* Restore registers' content */
 	gicr_write_propbaser(gicr_base, rdist_ctx->gicr_propbaser);
 	gicr_write_pendbaser(gicr_base, rdist_ctx->gicr_pendbaser);
@@ -942,8 +948,11 @@ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
 	assert(proc_num < gicv3_driver_data->rdistif_num);
 	assert(gicv3_driver_data->rdistif_base_addrs != NULL);
 
+	if (!is_valid_interrupt(id)) {
+		panic();
+	}
 	/* Check interrupt ID */
-	if (is_sgi_ppi(id)) {
+	if (IS_SGI_PPI(id)) {
 		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
 		return gicr_get_isactiver(
 			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
@@ -973,9 +982,11 @@ void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num)
 	 * interrupt trigger are observed before enabling interrupt.
 	 */
 	dsbishst();
-
+	if (!is_valid_interrupt(id)) {
+		panic();
+	}
 	/* Check interrupt ID */
-	if (is_sgi_ppi(id)) {
+	if (IS_SGI_PPI(id)) {
 		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
 		gicr_set_isenabler(
 			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
@@ -1004,9 +1015,11 @@ void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num)
 	 * Disable interrupt, and ensure that any shared variable updates
 	 * depending on out of band interrupt trigger are observed afterwards.
 	 */
-
+	if (!is_valid_interrupt(id)) {
+		panic();
+	}
 	/* Check interrupt ID */
-	if (is_sgi_ppi(id)) {
+	if (IS_SGI_PPI(id)) {
 		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
 		gicr_set_icenabler(
 			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
@@ -1041,8 +1054,11 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
 	assert(proc_num < gicv3_driver_data->rdistif_num);
 	assert(gicv3_driver_data->rdistif_base_addrs != NULL);
 
+	if (!is_valid_interrupt(id)) {
+		panic();
+	}
 	/* Check interrupt ID */
-	if (is_sgi_ppi(id)) {
+	if (IS_SGI_PPI(id)) {
 		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
 		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
 		gicr_set_ipriorityr(gicr_base, id, priority);
@@ -1088,8 +1104,11 @@ void gicv3_set_interrupt_group(unsigned int id, unsigned int proc_num,
 		break;
 	}
 
+	if (!is_valid_interrupt(id)) {
+		panic();
+	}
 	/* Check interrupt ID */
-	if (is_sgi_ppi(id)) {
+	if (IS_SGI_PPI(id)) {
 		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
 		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
 
@@ -1228,12 +1247,14 @@ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num)
 	 * Clear pending interrupt, and ensure that any shared variable updates
 	 * depending on out of band interrupt trigger are observed afterwards.
 	 */
-
+	if (!is_valid_interrupt(id)) {
+		panic();
+	}
 	/* Check interrupt ID */
-	if (is_sgi_ppi(id)) {
+	if (IS_SGI_PPI(id)) {
 		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
 		gicr_set_icpendr(
-			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
+		gicv3_driver_data->rdistif_base_addrs[proc_num], id);
 	} else {
 		/* For SPIs: 32-1019 and ESPIs: 4096-5119 */
 		gicd_base = gicv3_get_multichip_base(id, gicv3_driver_data->gicd_base);
@@ -1263,8 +1284,12 @@ void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num)
 	 */
 	dsbishst();
 
+	if (!is_valid_interrupt(id)) {
+		panic();
+	}
+
 	/* Check interrupt ID */
-	if (is_sgi_ppi(id)) {
+	if (IS_SGI_PPI(id)) {
 		/* For SGIs: 0-15, PPIs: 16-31 and EPPIs: 1056-1119 */
 		gicr_set_ispendr(
 			gicv3_driver_data->rdistif_base_addrs[proc_num], id);
@@ -1297,6 +1322,31 @@ unsigned int gicv3_set_pmr(unsigned int mask)
 	return old_mask;
 }
 
+/*******************************************************************************
+ * This function restores the PMR register to old value and also triggers
+ * gicv3_apply_errata_wa_2384374() that flushes the GIC buffer allowing any
+ * pending interrupts to processed. Returns the original PMR.
+ ******************************************************************************/
+unsigned int gicv3_deactivate_priority(unsigned int mask)
+{
+
+	unsigned int old_mask, proc_num;
+	uintptr_t gicr_base;
+
+	old_mask = gicv3_set_pmr(mask);
+
+	proc_num = plat_my_core_pos();
+	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+	assert(gicr_base != 0UL);
+
+	/* Add DSB to ensure visibility of System register writes */
+	dsb();
+
+	gicv3_apply_errata_wa_2384374(gicr_base);
+
+	return old_mask;
+}
+
 /*******************************************************************************
  * This function delegates the responsibility of discovering the corresponding
  * Redistributor frames to each CPU itself. It is a modified version of
@@ -1371,21 +1421,19 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame)
 }
 
 /******************************************************************************
- * This function checks the interrupt ID and returns true for SGIs and (E)PPIs
- * and false for (E)SPIs IDs.
+ * This function checks the interrupt ID and returns true for SGIs, (E)PPIs
+ * and (E)SPIs IDs. Any interrupt ID outside the range is invalid and returns
+ * false.
  *****************************************************************************/
-static bool is_sgi_ppi(unsigned int id)
+static bool is_valid_interrupt(unsigned int id)
 {
-	/* SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119 */
-	if (IS_SGI_PPI(id)) {
+	/* Valid interrupts:
+	 * SGIs: 0-15, PPIs: 16-31, EPPIs: 1056-1119
+	 * SPIs: 32-1019, ESPIs: 4096-5119
+	 */
+	if ((IS_SGI_PPI(id)) || (IS_SPI(id))) {
 		return true;
 	}
 
-	/* SPIs: 32-1019, ESPIs: 4096-5119 */
-	if (IS_SPI(id)) {
-		return false;
-	}
-
-	assert(false);
-	panic();
+	return false;
 }
diff --git a/drivers/arm/mhu/mhu_v3_x.c b/drivers/arm/mhu/mhu_v3_x.c
new file mode 100644
index 00000000..118c608e
--- /dev/null
+++ b/drivers/arm/mhu/mhu_v3_x.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "mhu_v3_x.h"
+
+#include "mhu_v3_x_private.h"
+
+/*
+ * Get the device base from the device struct. Return an error if the dev is
+ * invalid.
+ */
+static enum mhu_v3_x_error_t get_dev_base(const struct mhu_v3_x_dev_t *dev,
+	 union _mhu_v3_x_frame_t **base)
+{
+	if (dev == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Ensure driver has been initialized */
+	if (dev->is_initialized == false) {
+		return MHU_V_3_X_ERR_NOT_INIT;
+	}
+
+	*base = (union _mhu_v3_x_frame_t *)dev->base;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_driver_init(struct mhu_v3_x_dev_t *dev)
+{
+	uint32_t aidr = 0;
+	uint8_t mhu_major_rev;
+	union _mhu_v3_x_frame_t *p_mhu;
+
+	if (dev == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Return if already initialized */
+	if (dev->is_initialized == true) {
+		return MHU_V_3_X_ERR_NONE;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	/* Read revision from MHU hardware */
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		aidr = p_mhu->pbx_frame.pbx_ctrl_page.pbx_aidr;
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		aidr = p_mhu->mbx_frame.mbx_ctrl_page.mbx_aidr;
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	/* Read the MHU Architecture Major Revision */
+	mhu_major_rev =
+		((aidr & MHU_ARCH_MAJOR_REV_MASK) >> MHU_ARCH_MAJOR_REV_OFF);
+
+	/* Return error if the MHU major revision is not 3 */
+	if (mhu_major_rev != MHU_MAJOR_REV_V3) {
+		/* Unsupported MHU version */
+		return MHU_V_3_X_ERR_UNSUPPORTED_VERSION;
+	}
+
+	/* Read the MHU Architecture Minor Revision */
+	dev->subversion =
+		((aidr & MHU_ARCH_MINOR_REV_MASK) >> MHU_ARCH_MINOR_REV_MASK);
+
+	/* Return error if the MHU minor revision is not 0 */
+	if (dev->subversion != MHU_MINOR_REV_3_0) {
+		/* Unsupported subversion */
+		return MHU_V_3_X_ERR_UNSUPPORTED_VERSION;
+	}
+
+	/* Initialize the Postbox/Mailbox to remain in operational state */
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		p_mhu->pbx_frame.pbx_ctrl_page.pbx_ctrl |= MHU_V3_OP_REQ;
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		p_mhu->mbx_frame.mbx_ctrl_page.mbx_ctrl |= MHU_V3_OP_REQ;
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	dev->is_initialized = true;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_get_num_channel_implemented(
+	 const struct mhu_v3_x_dev_t *dev,
+	 enum mhu_v3_x_channel_type_t ch_type, uint8_t *num_ch)
+{
+	enum mhu_v3_x_error_t status;
+	union _mhu_v3_x_frame_t *p_mhu;
+
+	if (num_ch == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only doorbell channel is supported */
+	if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	/* Read the number of channels implemented in the MHU */
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		*num_ch = (p_mhu->pbx_frame.pbx_ctrl_page.pbx_dbch_cfg0 + 1);
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		*num_ch = (p_mhu->mbx_frame.mbx_ctrl_page.mbx_dbch_cfg0 + 1);
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_clear(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only MBX can clear the Doorbell channel */
+	if (dev->frame != MHU_V3_X_MBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+	mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+		&(p_mhu->mbx_frame.mdbcw_page);
+
+	/* Clear the bits in the doorbell channel */
+	mdbcw_reg[channel].mdbcw_clr |= flags;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_write(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only PBX can set the Doorbell channel value */
+	if (dev->frame != MHU_V3_X_PBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
+		&(p_mhu->pbx_frame.pdbcw_page);
+
+	/* Write the value to the doorbell channel */
+	pdbcw_reg[channel].pdbcw_set |= flags;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_read(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t *flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	enum mhu_v3_x_error_t status;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+
+	if (flags == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
+			&(p_mhu->pbx_frame.pdbcw_page);
+
+		/* Read the value from Postbox Doorbell status register */
+		*flags = pdbcw_reg[channel].pdbcw_st;
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+			&(p_mhu->mbx_frame.mdbcw_page);
+
+		/* Read the value from Mailbox Doorbell status register */
+		*flags = mdbcw_reg[channel].mdbcw_st;
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_set(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 uint32_t flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Doorbell channel mask is not applicable for PBX */
+	if (dev->frame != MHU_V3_X_MBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+		&(p_mhu->mbx_frame.mdbcw_page);
+
+	/* Set the Doorbell channel mask */
+	mdbcw_reg[channel].mdbcw_msk_set |= flags;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_clear(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 uint32_t flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Doorbell channel mask is not applicable for PBX */
+	if (dev->frame != MHU_V3_X_MBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+		&(p_mhu->mbx_frame.mdbcw_page);
+
+	/* Clear the Doorbell channel mask */
+	mdbcw_reg[channel].mdbcw_msk_clr = flags;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_get(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 uint32_t *flags)
+{
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+	enum mhu_v3_x_error_t status;
+
+	if (flags == NULL) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Doorbell channel mask is not applicable for PBX */
+	if (dev->frame != MHU_V3_X_MBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+		&(p_mhu->mbx_frame.mdbcw_page);
+
+	/* Save the Doorbell channel mask status */
+	*flags = mdbcw_reg[channel].mdbcw_msk_st;
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_enable(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type)
+{
+	enum mhu_v3_x_error_t status;
+
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only doorbell channel is supported */
+	if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
+			&(p_mhu->pbx_frame.pdbcw_page);
+
+		/*
+		 * Enable this doorbell channel to generate interrupts for
+		 * transfer acknowledge events.
+		 */
+		pdbcw_reg[channel].pdbcw_int_en = MHU_V3_X_PDBCW_INT_X_TFR_ACK;
+
+		/*
+		 * Enable this doorbell channel to contribute to the PBX
+		 * combined interrupt.
+		 */
+		pdbcw_reg[channel].pdbcw_ctrl = MHU_V3_X_PDBCW_CTRL_PBX_COMB_EN;
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+			&(p_mhu->mbx_frame.mdbcw_page);
+
+		/*
+		 * Enable this doorbell channel to contribute to the MBX
+		 * combined interrupt.
+		 */
+		mdbcw_reg[channel].mdbcw_ctrl = MHU_V3_X_MDBCW_CTRL_MBX_COMB_EN;
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_disable(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type)
+{
+	enum mhu_v3_x_error_t status;
+
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+	struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only doorbell channel is supported */
+	if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+
+	if (dev->frame == MHU_V3_X_PBX_FRAME) {
+		pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
+			&(p_mhu->pbx_frame.pdbcw_page);
+
+		/* Clear channel transfer acknowledge event interrupt */
+		pdbcw_reg[channel].pdbcw_int_clr = MHU_V3_X_PDBCW_INT_X_TFR_ACK;
+
+		/* Disable channel transfer acknowledge event interrupt */
+		pdbcw_reg[channel].pdbcw_int_en &=
+			~(MHU_V3_X_PDBCW_INT_X_TFR_ACK);
+
+		/*
+		 * Disable this doorbell channel from contributing to the PBX
+		 * combined interrupt.
+		 */
+		pdbcw_reg[channel].pdbcw_ctrl &=
+			~(MHU_V3_X_PDBCW_CTRL_PBX_COMB_EN);
+	} else if (dev->frame == MHU_V3_X_MBX_FRAME) {
+		mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
+			&(p_mhu->mbx_frame.mdbcw_page);
+
+		/*
+		 * Disable this doorbell channel from contributing to the MBX
+		 * combined interrupt.
+		 */
+		mdbcw_reg[channel].mdbcw_ctrl &=
+			~(MHU_V3_X_MDBCW_CTRL_MBX_COMB_EN);
+	} else {
+		/* Only PBX and MBX frames are supported. */
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	return MHU_V_3_X_ERR_NONE;
+}
+
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_clear(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type)
+{
+	enum mhu_v3_x_error_t status;
+	union _mhu_v3_x_frame_t *p_mhu;
+	struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
+
+	/* Get dev->base if it is valid or return an error if dev is not */
+	status = get_dev_base(dev, &p_mhu);
+	if (status != MHU_V_3_X_ERR_NONE) {
+		return status;
+	}
+
+	/* Only doorbell channel is supported */
+	if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
+		return MHU_V_3_X_ERR_UNSUPPORTED;
+	}
+
+	/*
+	 * Only postbox doorbell channel transfer acknowledge interrupt can be
+	 * cleared manually.
+	 *
+	 * To clear MBX interrupt the unmasked status must be cleared using
+	 * mhu_v3_x_doorbell_clear.
+	 */
+	if (dev->frame != MHU_V3_X_PBX_FRAME) {
+		return MHU_V_3_X_ERR_INVALID_PARAM;
+	}
+
+	p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
+	pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)&(
+			p_mhu->pbx_frame.pdbcw_page);
+
+	/* Clear channel transfer acknowledge event interrupt */
+	pdbcw_reg[channel].pdbcw_int_clr |= 0x1;
+
+	return MHU_V_3_X_ERR_NONE;
+}
diff --git a/drivers/arm/mhu/mhu_v3_x.h b/drivers/arm/mhu/mhu_v3_x.h
new file mode 100644
index 00000000..a3a19503
--- /dev/null
+++ b/drivers/arm/mhu/mhu_v3_x.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MHU_V3_X_H
+#define MHU_V3_X_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/* MHU Architecture Major Revision 3 */
+#define MHU_MAJOR_REV_V3 U(0x2)
+/* MHU Architecture Minor Revision 0 */
+#define MHU_MINOR_REV_3_0 U(0x0)
+
+/* MHU Architecture Major Revision offset */
+#define MHU_ARCH_MAJOR_REV_OFF U(0x4)
+/* MHU Architecture Major Revision mask */
+#define MHU_ARCH_MAJOR_REV_MASK (U(0xf) << MHU_ARCH_MAJOR_REV_OFF)
+
+/* MHU Architecture Minor Revision offset */
+#define MHU_ARCH_MINOR_REV_OFF U(0x0)
+/* MHU Architecture Minor Revision mask */
+#define MHU_ARCH_MINOR_REV_MASK (U(0xf) << MHU_ARCH_MINOR_REV_OFF)
+
+/* MHUv3 PBX/MBX Operational Request offset */
+#define MHU_V3_OP_REQ_OFF U(0)
+/* MHUv3 PBX/MBX Operational Request */
+#define MHU_V3_OP_REQ (U(1) << MHU_V3_OP_REQ_OFF)
+
+/**
+ * MHUv3 error enumeration types
+ */
+enum mhu_v3_x_error_t {
+	/* No error */
+	MHU_V_3_X_ERR_NONE,
+	/* MHU driver not initialized */
+	MHU_V_3_X_ERR_NOT_INIT,
+	/* MHU driver alreary initialized */
+	MHU_V_3_X_ERR_ALREADY_INIT,
+	/* MHU Revision not supported error */
+	MHU_V_3_X_ERR_UNSUPPORTED_VERSION,
+	/* Operation not supported */
+	MHU_V_3_X_ERR_UNSUPPORTED,
+	/* Invalid parameter */
+	MHU_V_3_X_ERR_INVALID_PARAM,
+	/* General MHU driver error */
+	MHU_V_3_X_ERR_GENERAL,
+};
+
+/**
+ * MHUv3 channel types
+ */
+enum mhu_v3_x_channel_type_t {
+	/* Doorbell channel */
+	MHU_V3_X_CHANNEL_TYPE_DBCH,
+	/* Channel type count */
+	MHU_V3_X_CHANNEL_TYPE_COUNT,
+};
+
+/**
+ * MHUv3 frame types
+ */
+enum mhu_v3_x_frame_t {
+	/* MHUv3 postbox frame */
+	MHU_V3_X_PBX_FRAME,
+	/* MHUv3 mailbox frame */
+	MHU_V3_X_MBX_FRAME,
+};
+
+/**
+ * MHUv3 device structure
+ */
+struct mhu_v3_x_dev_t {
+	/* Base address of the MHUv3 frame */
+	uintptr_t base;
+	/* Type of the MHUv3 frame */
+	enum mhu_v3_x_frame_t frame;
+	/* Minor revision of the MHUv3 */
+	uint32_t subversion;
+	/* Flag to indicate if the MHUv3 is initialized */
+	bool is_initialized;
+};
+
+/**
+ * Initializes the MHUv3
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_driver_init(struct mhu_v3_x_dev_t *dev);
+
+/**
+ * Returns the number of channels implemented
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * ch_type	MHU channel type mhu_v3_x_channel_type_t
+ * num_ch	Pointer to the variable that will store the value
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_get_num_channel_implemented(
+	 const struct mhu_v3_x_dev_t *dev, enum mhu_v3_x_channel_type_t ch_type,
+	 uint8_t *num_ch);
+
+/**
+ * Clear flags from a doorbell channel
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Flags to be cleared from the channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_clear(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t flags);
+
+/**
+ * Write flags to a doorbell channel
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Flags to be written to the channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_write(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t flags);
+
+/**
+ * Read value from a doorbell channel
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Pointer to the variable that will store the flags read from the
+ *		channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_read(const struct mhu_v3_x_dev_t *dev,
+	 const uint32_t channel, uint32_t *flags);
+
+/**
+ * Set bits in a doorbell channel mask which is used to disable interrupts for
+ * received flags corresponding to the mask
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Flags to set mask bits in this doorbell channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_set(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 uint32_t flags);
+
+/**
+ * Clear bits in a doorbell channel mask which is used to disable interrupts
+ * for received flags corresponding to the mask
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Flags to clear mask bits in this doorbell channel
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_clear(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel, uint32_t flags);
+
+/**
+ * Get the mask of a doorbell channel which is used to disable interrupts for
+ * received flags corresponding to the mask
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * flags	Pointer to the variable that will store the flags read from the
+ *		mask value
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_get(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel, uint32_t *flags);
+
+/**
+ * Enable the channel interrupt
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * ch_type	MHU channel type mhu_v3_x_channel_type_t
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_enable(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type);
+
+/**
+ * Disable the channel interrupt
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * ch_type	MHU channel type mhu_v3_x_channel_type_t
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_disable(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type);
+
+/**
+ * Clear the channel interrupt
+ *
+ * dev		MHU device struct mhu_v3_x_dev_t
+ * channel	Doorbell channel number
+ * ch_type	MHU channel type mhu_v3_x_channel_type_t
+ *
+ * Returns mhu_v3_x_error_t error code
+ */
+enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_clear(
+	 const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
+	 enum mhu_v3_x_channel_type_t ch_type);
+
+#endif /* MHU_V3_X_H */
diff --git a/drivers/arm/mhu/mhu_v3_x_private.h b/drivers/arm/mhu/mhu_v3_x_private.h
new file mode 100644
index 00000000..9594a2a8
--- /dev/null
+++ b/drivers/arm/mhu/mhu_v3_x_private.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MHU_V3_X_PRIVATE_H
+#define MHU_V3_X_PRIVATE_H
+
+#include <stdint.h>
+
+/* Flag for PDBCW Interrupt Transfer Acknowledgment  */
+#define MHU_V3_X_PDBCW_INT_X_TFR_ACK 0x1
+
+/* Flag for PDBCW CTRL Postbox combined interrupts enable */
+#define MHU_V3_X_PDBCW_CTRL_PBX_COMB_EN 0x1
+
+/* Flag for MDBCW CTRL Mailbox combined interrupts enable */
+#define MHU_V3_X_MDBCW_CTRL_MBX_COMB_EN 0x1
+
+/**
+ * Postbox control page structure
+ */
+struct _mhu_v3_x_pbx_ctrl_reg_t {
+	/* Offset: 0x000 (R/ ) Postbox Block Identifier */
+	const volatile uint32_t pbx_blk_id;
+	/* Offset: 0x004 (R/ ) Reserved */
+	const volatile uint8_t reserved_0[0x10 - 0x04];
+	/* Offset: 0x010 (R/ ) Postbox Feature Support 0 */
+	const volatile uint32_t pbx_feat_spt0;
+	/* Offset: 0x014 (R/ ) Postbox Feature Support 1 */
+	const volatile uint32_t pbx_feat_spt1;
+	/* Offset: 0x018 (R/ ) Reserved */
+	const volatile uint8_t reserved_1[0x20 - 0x18];
+	/* Offset: 0x020 (R/ ) Postbox Doorbell Channel Configuration 0 */
+	const volatile uint32_t pbx_dbch_cfg0;
+	/* Offset: 0x024 (R/ ) Reserved */
+	const volatile uint8_t reserved_2[0x30 - 0x24];
+	/* Offset: 0x030 (R/ ) Postbox FIFO Channel Configuration 0 */
+	const volatile uint32_t pbx_ffch_cfg0;
+	/* Offset: 0x034 (R/ ) Reserved */
+	const volatile uint8_t reserved_3[0x40 - 0x34];
+	/* Offset: 0x040 (R/ ) Postbox Fast Channel Configuration 0 */
+	const volatile uint32_t pbx_fch_cfg0;
+	/* Offset: 0x044 (R/ ) Reserved */
+	const volatile uint8_t reserved_4[0x100 - 0x44];
+	/* Offset: 0x100 (R/W) Postbox control */
+	volatile uint32_t pbx_ctrl;
+	/* Offset: 0x164 (R/ ) Reserved */
+	const volatile uint8_t reserved_5[0x400 - 0x104];
+	/*
+	 * Offset: 0x400 (R/ ) Postbox Doorbell Channel Interrupt Status n,
+	 * where n is 0 - 3.
+	 */
+	const volatile uint32_t pbx_dbch_int_st[4];
+	/*
+	 * Offset: 0x410 (R/ ) Postbox FIFO Channel <n> Interrupt Status n,
+	 * where n is 0 - 1.
+	 */
+	const volatile uint32_t pbx_ffch_int_st[2];
+	/* Offset: 0x418 (R/ ) Reserved */
+	const uint8_t reserved_6[0xFC8 - 0x418];
+	/* Offset: 0xFC8 (R/ ) Postbox Implementer Identification Register */
+	const volatile uint32_t pbx_iidr;
+	/* Offset: 0xFCC (R/ ) Postbox Architecture Identification Register */
+	const volatile uint32_t pbx_aidr;
+	/*
+	 * Offset: 0xFD0 (R/ ) Postbox Implementation Defined Identification
+	 * Register n, where n is 0 - 11.
+	 */
+	const volatile uint32_t impl_def_id[12];
+};
+
+/**
+ * Postbox doorbell channel window page structure
+ */
+struct _mhu_v3_x_pdbcw_reg_t {
+	/* Offset: 0x000 (R/ ) Postbox Doorbell Channel Window Status */
+	const volatile uint32_t pdbcw_st;
+	/* Offset: 0x004 (R/ ) Reserved */
+	const uint8_t reserved_0[0xC - 0x4];
+	/* Offset: 0x00C ( /W) Postbox Doorbell Channel Window Set */
+	volatile uint32_t pdbcw_set;
+	/*
+	 * Offset: 0x010 (R/ ) Postbox Doorbell Channel Window Interrupt Status
+	 */
+	const volatile uint32_t pdbcw_int_st;
+	/*
+	 * Offset: 0x014 ( /W) Postbox Doorbell Channel Window Interrupt Clear
+	 */
+	volatile uint32_t pdbcw_int_clr;
+	/*
+	 * Offset: 0x018 (R/W) Postbox Doorbell Channel Window Interrupt Enable
+	 */
+	volatile uint32_t pdbcw_int_en;
+	/* Offset: 0x01C (R/W) Postbox Doorbell Channel Window Control */
+	volatile uint32_t pdbcw_ctrl;
+};
+
+/**
+ * Postbox structure
+ */
+struct _mhu_v3_x_pbx {
+	/* Postbox Control */
+	struct _mhu_v3_x_pbx_ctrl_reg_t pbx_ctrl_page;
+	/* Postbox Doorbell Channel Window */
+	struct _mhu_v3_x_pdbcw_reg_t pdbcw_page;
+};
+
+/**
+ * Mailbox control page structure
+ */
+struct _mhu_v3_x_mbx_ctrl_reg_t {
+	/* Offset: 0x000 (R/ ) Mailbox Block Identifier */
+	const volatile uint32_t mbx_blk_id;
+	/* Offset: 0x004 (R/ ) Reserved */
+	const volatile uint8_t reserved_0[0x10 - 0x04];
+	/* Offset: 0x010 (R/ ) Mailbox Feature Support 0 */
+	const volatile uint32_t mbx_feat_spt0;
+	/* Offset: 0x014 (R/ ) Mailbox Feature Support 1 */
+	const volatile uint32_t mbx_feat_spt1;
+	/* Offset: 0x018 (R/ ) Reserved */
+	const volatile uint8_t reserved_1[0x20 - 0x18];
+	/* Offset: 0x020 (R/ ) Mailbox Doorbell Channel Configuration 0 */
+	const volatile uint32_t mbx_dbch_cfg0;
+	/* Offset: 0x024 (R/ ) Reserved */
+	const volatile uint8_t reserved_2[0x30 - 0x24];
+	/* Offset: 0x030 (R/ ) Mailbox FIFO Channel Configuration 0 */
+	const volatile uint32_t mbx_ffch_cfg0;
+	/* Offset: 0x034 (R/ ) Reserved */
+	const volatile uint8_t reserved_4[0x40 - 0x34];
+	/* Offset: 0x040 (R/ ) Mailbox Fast Channel Configuration 0 */
+	const volatile uint32_t mbx_fch_cfg0;
+	/* Offset: 0x044 (R/ ) Reserved */
+	const volatile uint8_t reserved_5[0x100 - 0x44];
+	/* Offset: 0x100 (R/W) Mailbox control */
+	volatile uint32_t mbx_ctrl;
+	/* Offset: 0x104 (R/ ) Reserved */
+	const volatile uint8_t reserved_6[0x140 - 0x104];
+	/* Offset: 0x140 (R/W) Mailbox Fast Channel control */
+	volatile uint32_t mbx_fch_ctrl;
+	/* Offset: 0x144 (R/W) Mailbox Fast Channel Group Interrupt Enable */
+	volatile uint32_t mbx_fcg_int_en;
+	/* Offset: 0x148 (R/ ) Reserved */
+	const volatile uint8_t reserved_7[0x400 - 0x148];
+	/*
+	 * Offset: 0x400 (R/ ) Mailbox Doorbell Channel Interrupt Status n,
+	 * where n = 0 - 3.
+	 */
+	const volatile uint32_t mbx_dbch_int_st[4];
+	/*
+	 * Offset: 0x410 (R/ ) Mailbox FIFO Channel Interrupt Status n, where
+	 * n = 0 - 1.
+	 */
+	const volatile uint32_t mbx_ffch_int_st[2];
+	/* Offset: 0x418 (R/ ) Reserved */
+	const volatile uint8_t reserved_8[0x470 - 0x418];
+	/* Offset: 0x470 (R/ ) Mailbox Fast Channel Group Interrupt Status */
+	const volatile uint32_t mbx_fcg_int_st;
+	/* Offset: 0x474 (R/ ) Reserved */
+	const volatile uint8_t reserved_9[0x480 - 0x474];
+	/*
+	 * Offset: 0x480 (R/ ) Mailbox Fast Channel Group <n> Interrupt Status,
+	 * where n = 0 - 31.
+	 */
+	const volatile uint32_t mbx_fch_grp_int_st[32];
+	/* Offset: 0x500 (R/ ) Reserved */
+	const volatile uint8_t reserved_10[0xFC8 - 0x500];
+	/* Offset: 0xFC8 (R/ ) Mailbox Implementer Identification Register */
+	const volatile uint32_t mbx_iidr;
+	/* Offset: 0xFCC (R/ ) Mailbox Architecture Identification Register */
+	const volatile uint32_t mbx_aidr;
+	/*
+	 * Offset: 0xFD0 (R/ ) Mailbox Implementation Defined Identification
+	 * Register n, where n is 0 - 11.
+	 */
+	const volatile uint32_t impl_def_id[12];
+};
+
+/**
+ * Mailbox doorbell channel window page structure
+ */
+struct _mhu_v3_x_mdbcw_reg_t {
+	/* Offset: 0x000 (R/ ) Mailbox Doorbell Channel Window Status */
+	const volatile uint32_t mdbcw_st;
+	/* Offset: 0x004 (R/ ) Mailbox Doorbell Channel Window Status Masked */
+	const volatile uint32_t mdbcw_st_msk;
+	/* Offset: 0x008 ( /W) Mailbox Doorbell Channel Window Clear */
+	volatile uint32_t mdbcw_clr;
+	/* Offset: 0x00C (R/ ) Reserved */
+	const volatile uint8_t reserved_0[0x10 - 0x0C];
+	/* Offset: 0x010 (R/ ) Mailbox Doorbell Channel Window Mask Status */
+	const volatile uint32_t mdbcw_msk_st;
+	/* Offset: 0x014 ( /W) Mailbox Doorbell Channel Window Mask Set */
+	volatile uint32_t mdbcw_msk_set;
+	/* Offset: 0x018 ( /W) Mailbox Doorbell Channel Window Mask Clear */
+	volatile uint32_t mdbcw_msk_clr;
+	/* Offset: 0x01C (R/W) Mailbox Doorbell Channel Window Control */
+	volatile uint32_t mdbcw_ctrl;
+};
+
+/**
+ * Mailbox structure
+ */
+struct _mhu_v3_x_mbx {
+	/* Mailbox control */
+	struct _mhu_v3_x_mbx_ctrl_reg_t mbx_ctrl_page;
+	/* Mailbox Doorbell Channel Window */
+	struct _mhu_v3_x_mdbcw_reg_t mdbcw_page;
+};
+
+/**
+ * MHUv3 frame type
+ */
+union _mhu_v3_x_frame_t {
+	/* Postbox Frame */
+	struct _mhu_v3_x_pbx pbx_frame;
+	/* Mailbox Frame */
+	struct _mhu_v3_x_mbx mbx_frame;
+};
+
+#endif /* MHU_V3_X_PRIVATE_H */
diff --git a/drivers/arm/mhu/mhu_wrapper_v2_x.c b/drivers/arm/mhu/mhu_wrapper_v2_x.c
index 60de1d38..54a58812 100644
--- a/drivers/arm/mhu/mhu_wrapper_v2_x.c
+++ b/drivers/arm/mhu/mhu_wrapper_v2_x.c
@@ -308,5 +308,10 @@ size_t mhu_get_max_message_size(void)
 
 	assert(num_channels != 0);
 
-	return num_channels * sizeof(uint32_t);
+	/*
+	 * Returns only usable size of memory. As one channel is specifically
+	 * used to inform about the size of payload, discard it from avialable
+	 * memory size.
+	 */
+	return (num_channels - 1) * sizeof(uint32_t);
 }
diff --git a/drivers/arm/mhu/mhu_wrapper_v3_x.c b/drivers/arm/mhu/mhu_wrapper_v3_x.c
new file mode 100644
index 00000000..3efd7017
--- /dev/null
+++ b/drivers/arm/mhu/mhu_wrapper_v3_x.c
@@ -0,0 +1,462 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <drivers/arm/mhu.h>
+
+#include "mhu_v3_x.h"
+
+#define MHU_NOTIFY_VALUE	U(1234)
+
+#ifndef ALIGN_UP
+#define ALIGN_UP(num, align)	(((num) + ((align) - 1)) & ~((align) - 1))
+#endif
+
+/*
+ * MHUv3 Wrapper utility macros
+ */
+#define IS_ALIGNED(val, align)	(val == ALIGN_UP(val, align))
+
+/*
+ * MHU devices for host:
+ * HSE: Host to Secure Enclave (sender device)
+ * SEH: Secure Enclave to Host (receiver device)
+ */
+struct mhu_v3_x_dev_t mhu_hse_dev = {0, MHU_V3_X_PBX_FRAME};
+struct mhu_v3_x_dev_t mhu_seh_dev = {0, MHU_V3_X_MBX_FRAME};
+
+/* MHUv3 driver error to MHUv3 wrapper error mapping */
+static enum mhu_error_t error_mapping_to_mhu_error_t(enum mhu_v3_x_error_t err)
+{
+	switch (err) {
+	case MHU_V_3_X_ERR_NONE:
+		return MHU_ERR_NONE;
+
+	case MHU_V_3_X_ERR_NOT_INIT:
+		return MHU_ERR_NOT_INIT;
+
+	case MHU_V_3_X_ERR_UNSUPPORTED_VERSION:
+		return MHU_ERR_UNSUPPORTED_VERSION;
+
+	case MHU_V_3_X_ERR_UNSUPPORTED:
+		return MHU_ERR_UNSUPPORTED;
+
+	case MHU_V_3_X_ERR_INVALID_PARAM:
+		return MHU_ERR_INVALID_ARG;
+
+	default:
+		return MHU_ERR_GENERAL;
+	}
+}
+
+static enum mhu_error_t signal_and_wait_for_clear(
+	void *mhu_sender_dev, uint32_t value)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint8_t num_channels;
+	uint32_t read_val;
+
+	dev = (struct mhu_v3_x_dev_t *)mhu_sender_dev;
+
+	if ((dev == NULL) || (dev->base == 0)) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Wait for any pending acknowledgment from transmitter side */
+	do {
+		err = mhu_v3_x_doorbell_read(dev, num_channels - 1, &read_val);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	} while ((read_val & value) == value);
+
+	/* Use the last channel to notify that a transfer is ready */
+	err = mhu_v3_x_doorbell_write(dev, num_channels - 1, value);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Wait until receiver side acknowledges the transfer */
+	do {
+		err = mhu_v3_x_doorbell_read(dev, num_channels - 1, &read_val);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	} while ((read_val & value) == value);
+
+	return error_mapping_to_mhu_error_t(MHU_V_3_X_ERR_NONE);
+}
+
+static enum mhu_error_t wait_for_signal(
+	void *mhu_receiver_dev, uint32_t value)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint32_t read_val;
+	uint8_t num_channels;
+
+	dev = (struct mhu_v3_x_dev_t *)mhu_receiver_dev;
+
+	if ((dev == NULL) || (dev->base == 0)) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	do {
+		err = mhu_v3_x_doorbell_read(dev, num_channels - 1, &read_val);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	} while (read_val != value);
+
+	return error_mapping_to_mhu_error_t(err);
+}
+
+static enum mhu_error_t clear_and_wait_for_signal(
+	void *mhu_receiver_dev, uint32_t value)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint8_t num_channels;
+
+	dev = (struct mhu_v3_x_dev_t *)mhu_receiver_dev;
+
+	if ((dev == NULL) || (dev->base == 0)) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Clear all channels */
+	for (int i = 0; i < num_channels; i++) {
+		err = mhu_v3_x_doorbell_clear(dev, i, UINT32_MAX);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	}
+
+	return wait_for_signal(mhu_receiver_dev, value);
+}
+
+static enum mhu_error_t validate_buffer_params(uintptr_t buf_addr)
+{
+	if ((buf_addr == 0) || (!IS_ALIGNED(buf_addr, sizeof(uint32_t)))) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	return MHU_ERR_NONE;
+}
+
+enum mhu_error_t mhu_init_sender(uintptr_t mhu_sender_base)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint8_t num_ch;
+	uint32_t ch;
+
+	assert(mhu_sender_base != (uintptr_t)NULL);
+
+	mhu_hse_dev.base = mhu_sender_base;
+	dev = (struct mhu_v3_x_dev_t *)&mhu_hse_dev;
+
+	/* Initialize MHUv3 */
+	err = mhu_v3_x_driver_init(dev);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Read the number of doorbell channels implemented in the MHU */
+	err = mhu_v3_x_get_num_channel_implemented(
+		dev, MHU_V3_X_CHANNEL_TYPE_DBCH, &num_ch);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	} else if (num_ch < 2) {
+		/* This wrapper requires at least two channels implemented */
+		return MHU_ERR_UNSUPPORTED;
+	}
+
+	/*
+	 * The sender polls the postbox doorbell channel window status register
+	 * to get notified about successful transfer. So, disable the doorbell
+	 * channel's contribution to postbox combined interrupt.
+	 *
+	 * Also, clear and disable the postbox doorbell channel transfer
+	 * acknowledge interrupt.
+	 */
+	for (ch = 0; ch < num_ch; ch++) {
+		err = mhu_v3_x_channel_interrupt_disable(
+			dev, ch, MHU_V3_X_CHANNEL_TYPE_DBCH);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	}
+
+	return MHU_ERR_NONE;
+}
+
+enum mhu_error_t mhu_init_receiver(uintptr_t mhu_receiver_base)
+{
+	enum mhu_v3_x_error_t err;
+	struct mhu_v3_x_dev_t *dev;
+	uint32_t ch;
+	uint8_t num_ch;
+
+	assert(mhu_receiver_base != (uintptr_t)NULL);
+
+	mhu_seh_dev.base = mhu_receiver_base;
+	dev = (struct mhu_v3_x_dev_t *)&mhu_seh_dev;
+
+	/* Initialize MHUv3 */
+	err = mhu_v3_x_driver_init(dev);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/* Read the number of doorbell channels implemented in the MHU */
+	err = mhu_v3_x_get_num_channel_implemented(
+		dev, MHU_V3_X_CHANNEL_TYPE_DBCH, &num_ch);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	} else if (num_ch < 2) {
+		/* This wrapper requires at least two channels implemented */
+		return MHU_ERR_UNSUPPORTED;
+	}
+
+	/* Mask all channels except the notifying channel */
+	for (ch = 0; ch < (num_ch - 1); ch++) {
+		/* Mask interrupts on channels used for data */
+		err = mhu_v3_x_doorbell_mask_set(dev, ch, UINT32_MAX);
+		if (err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(err);
+		}
+	}
+
+	/* Unmask doorbell notification channel interrupt */
+	err = mhu_v3_x_doorbell_mask_clear(dev, (num_ch - 1), UINT32_MAX);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	/*
+	 * Enable the doorbell channel's contribution to mailbox combined
+	 * interrupt.
+	 */
+	err = mhu_v3_x_channel_interrupt_enable(dev, (num_ch - 1),
+			MHU_V3_X_CHANNEL_TYPE_DBCH);
+	if (err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(err);
+	}
+
+	return MHU_ERR_NONE;
+}
+
+/*
+ * Public function. See mhu.h
+ *
+ * The basic steps of transferring a message:
+ * 1. Send the size of the payload on Channel 0. It is the very first Bytes of
+ *    the transfer. Continue with Channel 1.
+ * 2. Send the payload, writing the channels one after the other (4 Bytes
+ *    each). The last available channel is reserved for controlling the
+ *    transfer. When the last channel is reached or no more data is left, STOP.
+ * 3. Notify the receiver using the last channel and wait for acknowledge. If
+ *    there is still data to transfer, jump to step 2. Otherwise, proceed.
+ *
+ */
+enum mhu_error_t mhu_send_data(const uint8_t *send_buffer, size_t size)
+{
+	enum mhu_error_t mhu_err;
+	enum mhu_v3_x_error_t mhu_v3_err;
+	uint8_t num_channels;
+	uint8_t chan;
+	uint32_t *buffer;
+	struct mhu_v3_x_dev_t *dev;
+
+	if (size == 0) {
+		return MHU_ERR_NONE;
+	}
+
+	dev = (struct mhu_v3_x_dev_t *)&mhu_hse_dev;
+	chan = 0;
+
+	if ((dev == NULL) || (dev->base == 0)) {
+		return MHU_ERR_INVALID_ARG;
+	}
+
+	mhu_err = validate_buffer_params((uintptr_t)send_buffer);
+	if (mhu_err != MHU_ERR_NONE) {
+		return mhu_err;
+	}
+
+	mhu_v3_err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(mhu_v3_err);
+	}
+
+	/* First send the size of the actual message. */
+	mhu_v3_err = mhu_v3_x_doorbell_write(dev, chan, (uint32_t)size);
+	if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(mhu_v3_err);
+	}
+	chan++;
+
+	buffer = (uint32_t *)send_buffer;
+	for (size_t i = 0; i < size; i += 4) {
+		mhu_v3_err = mhu_v3_x_doorbell_write(dev, chan, *buffer++);
+		if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(mhu_v3_err);
+		}
+
+		if (++chan == (num_channels - 1)) {
+			/* Use the last channel to notify transfer complete */
+			mhu_err = signal_and_wait_for_clear(
+				dev, MHU_NOTIFY_VALUE);
+			if (mhu_err != MHU_ERR_NONE) {
+				return mhu_err;
+			}
+			chan = 0;
+		}
+	}
+
+	if (chan != 0) {
+		/* Use the last channel to notify transfer complete */
+		mhu_err = signal_and_wait_for_clear(dev, MHU_NOTIFY_VALUE);
+		if (mhu_err != MHU_ERR_NONE) {
+			return mhu_err;
+		}
+	}
+
+	return MHU_ERR_NONE;
+}
+
+/*
+ * Public function. See mhu.h
+ *
+ * The basic steps of receiving a message:
+ * 1. Read the size of the payload from Channel 0. It is the very first
+ *    4 Bytes of the transfer. Continue with Channel 1.
+ * 2. Receive the payload, read the channels one after the other
+ *    (4 Bytes each). The last available channel is reserved for controlling
+ *    the transfer.
+ *    When the last channel is reached clear all the channels
+ *    (also sending an acknowledge on the last channel).
+ * 3. If there is still data to receive wait for a notification on the last
+ *    channel and jump to step 2 as soon as it arrived. Otherwise, proceed.
+ *
+ */
+enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size)
+{
+	enum mhu_error_t mhu_err;
+	enum mhu_v3_x_error_t mhu_v3_err;
+	uint32_t msg_len;
+	uint8_t num_channels;
+	uint8_t chan;
+	uint32_t *buffer;
+	struct mhu_v3_x_dev_t *dev;
+
+	dev = (struct mhu_v3_x_dev_t *)&mhu_seh_dev;
+	chan = 0;
+
+	mhu_err = validate_buffer_params((uintptr_t)receive_buffer);
+	if (mhu_err != MHU_ERR_NONE) {
+		return mhu_err;
+	}
+
+	mhu_v3_err = mhu_v3_x_get_num_channel_implemented(dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+	if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(mhu_v3_err);
+	}
+
+	/* Busy wait for incoming reply */
+	mhu_err = wait_for_signal(dev, MHU_NOTIFY_VALUE);
+	if (mhu_err != MHU_ERR_NONE) {
+		return mhu_err;
+	}
+
+	/* The first word is the length of the actual message. */
+	mhu_v3_err = mhu_v3_x_doorbell_read(dev, chan, &msg_len);
+	if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+		return error_mapping_to_mhu_error_t(mhu_v3_err);
+	}
+	chan++;
+
+	if (*size < msg_len) {
+		/* Message buffer too small */
+		*size = msg_len;
+		return MHU_ERR_BUFFER_TOO_SMALL;
+	}
+
+	buffer = (uint32_t *)receive_buffer;
+	for (size_t i = 0; i < msg_len; i += 4) {
+		mhu_v3_err = mhu_v3_x_doorbell_read(dev, chan, buffer++);
+		if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(mhu_v3_err);
+		}
+
+		/* Only wait for next transfer if still missing data. */
+		if (++chan == (num_channels - 1) && (msg_len - i) > 4) {
+			/* Busy wait for next transfer */
+			mhu_err = clear_and_wait_for_signal(
+				dev, MHU_NOTIFY_VALUE);
+			if (mhu_err != MHU_ERR_NONE) {
+				return mhu_err;
+			}
+			chan = 0;
+		}
+	}
+
+	/* Clear all channels */
+	for (uint8_t i = U(0); i < num_channels; i++) {
+		mhu_v3_err = mhu_v3_x_doorbell_clear(dev, i, UINT32_MAX);
+		if (mhu_v3_err != MHU_V_3_X_ERR_NONE) {
+			return error_mapping_to_mhu_error_t(mhu_v3_err);
+		}
+	}
+
+	*size = msg_len;
+
+	return MHU_ERR_NONE;
+}
+
+size_t mhu_get_max_message_size(void)
+{
+	enum mhu_v3_x_error_t err __maybe_unused;
+	uint8_t num_channels;
+
+	err = mhu_v3_x_get_num_channel_implemented(&mhu_seh_dev,
+			MHU_V3_X_CHANNEL_TYPE_DBCH, &num_channels);
+
+	assert(err == MHU_V_3_X_ERR_NONE);
+	assert(num_channels != U(0));
+	/*
+	 * Returns only usable size of memory. As one channel is specifically
+	 * used to inform about the size of payload, discard it from available
+	 * memory size.
+	 */
+	return (num_channels - 1) * sizeof(uint32_t);
+}
diff --git a/drivers/arm/rss/rss_comms.c b/drivers/arm/rse/rse_comms.c
similarity index 71%
rename from drivers/arm/rss/rss_comms.c
rename to drivers/arm/rse/rse_comms.c
index 4622af98..cfc5a83c 100644
--- a/drivers/arm/rss/rss_comms.c
+++ b/drivers/arm/rse/rse_comms.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,16 +9,16 @@
 
 #include <common/debug.h>
 #include <drivers/arm/mhu.h>
-#include <drivers/arm/rss_comms.h>
+#include <drivers/arm/rse_comms.h>
 #include <psa/client.h>
-#include <rss_comms_protocol.h>
+#include <rse_comms_protocol.h>
 
 /* Union as message space and reply space are never used at the same time, and this saves space as
  * we can overlap them.
  */
-union __packed __attribute__((aligned(4))) rss_comms_io_buffer_t {
-	struct serialized_rss_comms_msg_t msg;
-	struct serialized_rss_comms_reply_t reply;
+union __packed __attribute__((aligned(4))) rse_comms_io_buffer_t {
+	struct serialized_rse_comms_msg_t msg;
+	struct serialized_rse_comms_reply_t reply;
 };
 
 static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
@@ -40,13 +40,13 @@ static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
 
 	comms_mhu_msg_size = mhu_get_max_message_size();
 
-	comms_embed_msg_min_size = sizeof(struct serialized_rss_comms_header_t) +
-				   sizeof(struct rss_embed_msg_t) -
-				   PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
+	comms_embed_msg_min_size = sizeof(struct serialized_rse_comms_header_t) +
+				   sizeof(struct rse_embed_msg_t) -
+				   PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
 
-	comms_embed_reply_min_size = sizeof(struct serialized_rss_comms_header_t) +
-				     sizeof(struct rss_embed_reply_t) -
-				     PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
+	comms_embed_reply_min_size = sizeof(struct serialized_rse_comms_header_t) +
+				     sizeof(struct rse_embed_reply_t) -
+				     PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
 
 	/* Use embed if we can pack into one message and reply, else use
 	 * pointer_access. The underlying MHU transport protocol uses a
@@ -59,11 +59,13 @@ static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
 	 * messages due to ATU configuration costs to allow access to the
 	 * pointers.
 	 */
-	if ((comms_embed_msg_min_size + in_size_total > comms_mhu_msg_size - sizeof(uint32_t))
-	 || (comms_embed_reply_min_size + out_size_total > comms_mhu_msg_size) - sizeof(uint32_t)) {
-		return RSS_COMMS_PROTOCOL_POINTER_ACCESS;
+	if ((comms_embed_msg_min_size + in_size_total >
+	     comms_mhu_msg_size - sizeof(uint32_t)) ||
+	    (comms_embed_reply_min_size + out_size_total >
+	     comms_mhu_msg_size - sizeof(uint32_t))) {
+		return RSE_COMMS_PROTOCOL_POINTER_ACCESS;
 	} else {
-		return RSS_COMMS_PROTOCOL_EMBED;
+		return RSE_COMMS_PROTOCOL_EMBED;
 	}
 }
 
@@ -73,7 +75,7 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
 	/* Declared statically to avoid using huge amounts of stack space. Maybe revisit if
 	 * functions not being reentrant becomes a problem.
 	 */
-	static union rss_comms_io_buffer_t io_buf;
+	static union rse_comms_io_buffer_t io_buf;
 	enum mhu_error_t err;
 	psa_status_t status;
 	static uint8_t seq_num = 1U;
@@ -82,8 +84,8 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
 	psa_status_t return_val;
 	size_t idx;
 
-	if (type > INT16_MAX || type < INT16_MIN || in_len > PSA_MAX_IOVEC
-	    || out_len > PSA_MAX_IOVEC) {
+	if (type > PSA_CALL_TYPE_MAX || type < PSA_CALL_TYPE_MIN ||
+	    in_len > PSA_MAX_IOVEC   || out_len > PSA_MAX_IOVEC) {
 		return PSA_ERROR_INVALID_ARGUMENT;
 	}
 
@@ -92,13 +94,13 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
 	io_buf.msg.header.client_id = 1U,
 	io_buf.msg.header.protocol_ver = select_protocol_version(in_vec, in_len, out_vec, out_len);
 
-	status = rss_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec,
+	status = rse_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec,
 					    out_len, &io_buf.msg, &msg_size);
 	if (status != PSA_SUCCESS) {
 		return status;
 	}
 
-	VERBOSE("[RSS-COMMS] Sending message\n");
+	VERBOSE("[RSE-COMMS] Sending message\n");
 	VERBOSE("protocol_ver=%u\n", io_buf.msg.header.protocol_ver);
 	VERBOSE("seq_num=%u\n", io_buf.msg.header.seq_num);
 	VERBOSE("client_id=%u\n", io_buf.msg.header.client_id);
@@ -115,7 +117,7 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
 #if DEBUG
 	/*
 	 * Poisoning the message buffer (with a known pattern).
-	 * Helps in detecting hypothetical RSS communication bugs.
+	 * Helps in detecting hypothetical RSE communication bugs.
 	 */
 	memset(&io_buf.msg, 0xA5, msg_size);
 #endif
@@ -125,12 +127,12 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
 		return PSA_ERROR_COMMUNICATION_FAILURE;
 	}
 
-	VERBOSE("[RSS-COMMS] Received reply\n");
+	VERBOSE("[RSE-COMMS] Received reply\n");
 	VERBOSE("protocol_ver=%u\n", io_buf.reply.header.protocol_ver);
 	VERBOSE("seq_num=%u\n", io_buf.reply.header.seq_num);
 	VERBOSE("client_id=%u\n", io_buf.reply.header.client_id);
 
-	status = rss_protocol_deserialize_reply(out_vec, out_len, &return_val,
+	status = rse_protocol_deserialize_reply(out_vec, out_len, &return_val,
 						&io_buf.reply, reply_size);
 	if (status != PSA_SUCCESS) {
 		return status;
@@ -150,16 +152,16 @@ psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec
 	return return_val;
 }
 
-int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base)
+int rse_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base)
 {
 	enum mhu_error_t err;
 
 	err = mhu_init_sender(mhu_sender_base);
 	if (err != MHU_ERR_NONE) {
 		if (err == MHU_ERR_ALREADY_INIT) {
-			INFO("[RSS-COMMS] Host to RSS MHU driver already initialized\n");
+			INFO("[RSE-COMMS] Host to RSE MHU driver already initialized\n");
 		} else {
-			ERROR("[RSS-COMMS] Host to RSS MHU driver initialization failed: %d\n", err);
+			ERROR("[RSE-COMMS] Host to RSE MHU driver initialization failed: %d\n", err);
 			return -1;
 		}
 	}
@@ -167,9 +169,9 @@ int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base)
 	err = mhu_init_receiver(mhu_receiver_base);
 	if (err != MHU_ERR_NONE) {
 		if (err == MHU_ERR_ALREADY_INIT) {
-			INFO("[RSS-COMMS] RSS to Host MHU driver already initialized\n");
+			INFO("[RSE-COMMS] RSE to Host MHU driver already initialized\n");
 		} else {
-			ERROR("[RSS-COMMS] RSS to Host MHU driver initialization failed: %d\n", err);
+			ERROR("[RSE-COMMS] RSE to Host MHU driver initialization failed: %d\n", err);
 			return -1;
 		}
 	}
diff --git a/drivers/arm/rse/rse_comms.mk b/drivers/arm/rse/rse_comms.mk
new file mode 100644
index 00000000..3b87fe23
--- /dev/null
+++ b/drivers/arm/rse/rse_comms.mk
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+$(warning "RSE driver is an experimental feature")
+
+RSE_COMMS_SOURCES	:=	$(addprefix drivers/arm/rse/,			\
+					rse_comms.c				\
+					rse_comms_protocol.c			\
+					rse_comms_protocol_embed.c		\
+					rse_comms_protocol_pointer_access.c	\
+				)
+
+# Default to MHUv2 if PLAT_MHU_VERSION undefined
+PLAT_MHU_VERSION ?= 2
+
+ifeq (${PLAT_MHU_VERSION}, 3)
+RSE_COMMS_SOURCES	+=	$(addprefix drivers/arm/mhu/,			\
+					mhu_v3_x.c				\
+					mhu_wrapper_v3_x.c			\
+				)
+else ifeq (${PLAT_MHU_VERSION}, 2)
+RSE_COMMS_SOURCES	+=	$(addprefix drivers/arm/mhu/,			\
+					mhu_v2_x.c				\
+					mhu_wrapper_v2_x.c			\
+				)
+else
+$(error Unsupported MHU version)
+endif
+
+PLAT_INCLUDES		+=	-Idrivers/arm/rse		\
+				-Idrivers/arm/mhu		\
+				-Iinclude/lib/psa
diff --git a/drivers/arm/rss/rss_comms_protocol.c b/drivers/arm/rse/rse_comms_protocol.c
similarity index 62%
rename from drivers/arm/rss/rss_comms_protocol.c
rename to drivers/arm/rse/rse_comms_protocol.c
index a1b1b58c..3eb7eaa5 100644
--- a/drivers/arm/rss/rss_comms_protocol.c
+++ b/drivers/arm/rse/rse_comms_protocol.c
@@ -7,15 +7,15 @@
 #include <assert.h>
 
 #include <common/debug.h>
-#include "rss_comms_protocol.h"
+#include "rse_comms_protocol.h"
 
-psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_serialize_msg(psa_handle_t handle,
 					int16_t type,
 					const psa_invec *in_vec,
 					uint8_t in_len,
 					const psa_outvec *out_vec,
 					uint8_t out_len,
-					struct serialized_rss_comms_msg_t *msg,
+					struct serialized_rse_comms_msg_t *msg,
 					size_t *msg_len)
 {
 	psa_status_t status;
@@ -25,15 +25,15 @@ psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
 	assert(in_vec != NULL);
 
 	switch (msg->header.protocol_ver) {
-	case RSS_COMMS_PROTOCOL_EMBED:
-		status = rss_protocol_embed_serialize_msg(handle, type, in_vec, in_len, out_vec,
+	case RSE_COMMS_PROTOCOL_EMBED:
+		status = rse_protocol_embed_serialize_msg(handle, type, in_vec, in_len, out_vec,
 							  out_len, &msg->msg.embed, msg_len);
 		if (status != PSA_SUCCESS) {
 			return status;
 		}
 		break;
-	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
-		status = rss_protocol_pointer_access_serialize_msg(handle, type, in_vec, in_len,
+	case RSE_COMMS_PROTOCOL_POINTER_ACCESS:
+		status = rse_protocol_pointer_access_serialize_msg(handle, type, in_vec, in_len,
 								   out_vec, out_len,
 								   &msg->msg.pointer_access,
 								   msg_len);
@@ -45,26 +45,26 @@ psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
 		return PSA_ERROR_NOT_SUPPORTED;
 	}
 
-	*msg_len += sizeof(struct serialized_rss_comms_header_t);
+	*msg_len += sizeof(struct serialized_rse_comms_header_t);
 
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_deserialize_reply(psa_outvec *out_vec,
+psa_status_t rse_protocol_deserialize_reply(psa_outvec *out_vec,
 					    uint8_t out_len,
 					    psa_status_t *return_val,
-					    const struct serialized_rss_comms_reply_t *reply,
+					    const struct serialized_rse_comms_reply_t *reply,
 					    size_t reply_size)
 {
 	assert(reply != NULL);
 	assert(return_val != NULL);
 
 	switch (reply->header.protocol_ver) {
-	case RSS_COMMS_PROTOCOL_EMBED:
-		return rss_protocol_embed_deserialize_reply(out_vec, out_len, return_val,
+	case RSE_COMMS_PROTOCOL_EMBED:
+		return rse_protocol_embed_deserialize_reply(out_vec, out_len, return_val,
 							    &reply->reply.embed, reply_size);
-	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
-		return rss_protocol_pointer_access_deserialize_reply(out_vec, out_len, return_val,
+	case RSE_COMMS_PROTOCOL_POINTER_ACCESS:
+		return rse_protocol_pointer_access_deserialize_reply(out_vec, out_len, return_val,
 								     &reply->reply.pointer_access,
 								     reply_size);
 	default:
diff --git a/drivers/arm/rse/rse_comms_protocol.h b/drivers/arm/rse/rse_comms_protocol.h
new file mode 100644
index 00000000..24f39657
--- /dev/null
+++ b/drivers/arm/rse/rse_comms_protocol.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSE_COMMS_PROTOCOL_H__
+#define __RSE_COMMS_PROTOCOL_H__
+
+#include <cdefs.h>
+#include <stdint.h>
+
+#include <psa/client.h>
+#include "rse_comms_protocol_embed.h"
+#include "rse_comms_protocol_pointer_access.h"
+
+enum rse_comms_protocol_version_t {
+	RSE_COMMS_PROTOCOL_EMBED = 0,
+	RSE_COMMS_PROTOCOL_POINTER_ACCESS = 1,
+};
+
+struct __packed serialized_rse_comms_header_t {
+	uint8_t protocol_ver;
+	uint8_t seq_num;
+	uint16_t client_id;
+};
+
+/* MHU message passed from Host to RSE to deliver a PSA client call */
+struct __packed serialized_rse_comms_msg_t {
+	struct serialized_rse_comms_header_t header;
+	union __packed {
+		struct rse_embed_msg_t embed;
+		struct rse_pointer_access_msg_t pointer_access;
+	} msg;
+};
+
+/* MHU reply message to hold the PSA client reply result returned by RSE */
+struct __packed serialized_rse_comms_reply_t {
+	struct serialized_rse_comms_header_t header;
+	union __packed {
+		struct rse_embed_reply_t embed;
+		struct rse_pointer_access_reply_t pointer_access;
+	} reply;
+};
+
+/* in_len and out_len are uint8_ts, therefore if there are more than 255 iovecs
+ * an error may occur.
+ */
+CASSERT(PSA_MAX_IOVEC <= UINT8_MAX, assert_rse_comms_max_iovec_too_large);
+
+psa_status_t rse_protocol_serialize_msg(psa_handle_t handle,
+					int16_t type,
+					const psa_invec *in_vec,
+					uint8_t in_len,
+					const psa_outvec *out_vec,
+					uint8_t out_len,
+					struct serialized_rse_comms_msg_t *msg,
+					size_t *msg_len);
+
+psa_status_t rse_protocol_deserialize_reply(psa_outvec *out_vec,
+					    uint8_t out_len,
+					    psa_status_t *return_val,
+					    const struct serialized_rse_comms_reply_t *reply,
+					    size_t reply_size);
+
+#endif /* __RSE_COMMS_PROTOCOL_H__ */
diff --git a/drivers/arm/rse/rse_comms_protocol_common.h b/drivers/arm/rse/rse_comms_protocol_common.h
new file mode 100644
index 00000000..235ea92f
--- /dev/null
+++ b/drivers/arm/rse/rse_comms_protocol_common.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*
+ * Packing scheme of the control parameter
+ *
+ *  31           30-28   27    26-24  23-20   19     18-16   15-0
+ * +------------+-----+------+-------+-----+-------+-------+------+
+ * |            |     |      | invec |     |       | outvec| type |
+ * | Res        | Res | Res  | number| Res | Res   | number|      |
+ * +------------+-----+------+-------+-----+-------+-------+------+
+ *
+ * Res: Reserved.
+ */
+
+#ifndef RSE_COMMS_PROTOCOL_COMMON
+#define RSE_COMMS_PROTOCOL_COMMON
+
+#define TYPE_OFFSET	(0U)
+#define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
+#define IN_LEN_OFFSET	(24U)
+#define IN_LEN_MASK	(0x7UL << IN_LEN_OFFSET)
+#define OUT_LEN_OFFSET	(16U)
+#define OUT_LEN_MASK	(0x7UL << OUT_LEN_OFFSET)
+
+#define PARAM_PACK(type, in_len, out_len)			   \
+	(((((uint32_t)(type)) << TYPE_OFFSET) & TYPE_MASK)	 | \
+	 ((((uint32_t)(in_len)) << IN_LEN_OFFSET) & IN_LEN_MASK) | \
+	 ((((uint32_t)(out_len)) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
+
+#endif /* RSE_COMMS_PROTOCOL_COMMON */
diff --git a/drivers/arm/rss/rss_comms_protocol_embed.c b/drivers/arm/rse/rse_comms_protocol_embed.c
similarity index 69%
rename from drivers/arm/rss/rss_comms_protocol_embed.c
rename to drivers/arm/rse/rse_comms_protocol_embed.c
index c453258f..d425257d 100644
--- a/drivers/arm/rss/rss_comms_protocol_embed.c
+++ b/drivers/arm/rse/rse_comms_protocol_embed.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -9,27 +9,16 @@
 #include <string.h>
 
 #include <common/debug.h>
-#include "rss_comms_protocol_embed.h"
+#include "rse_comms_protocol_common.h"
+#include "rse_comms_protocol_embed.h"
 
-#define TYPE_OFFSET	(16U)
-#define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
-#define IN_LEN_OFFSET	(8U)
-#define IN_LEN_MASK	(0xFFUL << IN_LEN_OFFSET)
-#define OUT_LEN_OFFSET	(0U)
-#define OUT_LEN_MASK	(0xFFUL << OUT_LEN_OFFSET)
-
-#define PARAM_PACK(type, in_len, out_len)			  \
-	(((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK)	| \
-	 ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK)	| \
-	 ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
-
-psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_embed_serialize_msg(psa_handle_t handle,
 					      int16_t type,
 					      const psa_invec *in_vec,
 					      uint8_t in_len,
 					      const psa_outvec *out_vec,
 					      uint8_t out_len,
-					      struct rss_embed_msg_t *msg,
+					      struct rse_embed_msg_t *msg,
 					      size_t *msg_len)
 {
 	uint32_t payload_size = 0;
@@ -66,10 +55,10 @@ psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_embed_deserialize_reply(psa_outvec *out_vec,
+psa_status_t rse_protocol_embed_deserialize_reply(psa_outvec *out_vec,
 						  uint8_t out_len,
 						  psa_status_t *return_val,
-						  const struct rss_embed_reply_t *reply,
+						  const struct rse_embed_reply_t *reply,
 						  size_t reply_size)
 {
 	uint32_t payload_offset = 0;
diff --git a/drivers/arm/rss/rss_comms_protocol_embed.h b/drivers/arm/rse/rse_comms_protocol_embed.h
similarity index 55%
rename from drivers/arm/rss/rss_comms_protocol_embed.h
rename to drivers/arm/rse/rse_comms_protocol_embed.h
index c81c7954..165978d4 100644
--- a/drivers/arm/rss/rss_comms_protocol_embed.h
+++ b/drivers/arm/rse/rse_comms_protocol_embed.h
@@ -5,8 +5,8 @@
  *
  */
 
-#ifndef __RSS_COMMS_PROTOCOL_EMBED_H__
-#define __RSS_COMMS_PROTOCOL_EMBED_H__
+#ifndef __RSE_COMMS_PROTOCOL_EMBED_H__
+#define __RSE_COMMS_PROTOCOL_EMBED_H__
 
 #include <cdefs.h>
 
@@ -16,32 +16,32 @@
 
 
 
-struct __packed rss_embed_msg_t {
+struct __packed rse_embed_msg_t {
 	psa_handle_t handle;
 	uint32_t ctrl_param; /* type, in_len, out_len */
 	uint16_t io_size[PSA_MAX_IOVEC];
-	uint8_t trailer[PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE];
+	uint8_t trailer[PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE];
 };
 
-struct __packed rss_embed_reply_t {
+struct __packed rse_embed_reply_t {
 	int32_t return_val;
 	uint16_t out_size[PSA_MAX_IOVEC];
-	uint8_t trailer[PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE];
+	uint8_t trailer[PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE];
 };
 
-psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_embed_serialize_msg(psa_handle_t handle,
 					      int16_t type,
 					      const psa_invec *in_vec,
 					      uint8_t in_len,
 					      const psa_outvec *out_vec,
 					      uint8_t out_len,
-					      struct rss_embed_msg_t *msg,
+					      struct rse_embed_msg_t *msg,
 					      size_t *msg_len);
 
-psa_status_t rss_protocol_embed_deserialize_reply(psa_outvec *out_vec,
+psa_status_t rse_protocol_embed_deserialize_reply(psa_outvec *out_vec,
 						  uint8_t out_len,
 						  psa_status_t *return_val,
-						  const struct rss_embed_reply_t *reply,
+						  const struct rse_embed_reply_t *reply,
 						  size_t reply_size);
 
-#endif /* __RSS_COMMS_PROTOCOL_EMBED_H__ */
+#endif /* __RSE_COMMS_PROTOCOL_EMBED_H__ */
diff --git a/drivers/arm/rss/rss_comms_protocol_pointer_access.c b/drivers/arm/rse/rse_comms_protocol_pointer_access.c
similarity index 58%
rename from drivers/arm/rss/rss_comms_protocol_pointer_access.c
rename to drivers/arm/rse/rse_comms_protocol_pointer_access.c
index 5007b9de..63524ebe 100644
--- a/drivers/arm/rss/rss_comms_protocol_pointer_access.c
+++ b/drivers/arm/rse/rse_comms_protocol_pointer_access.c
@@ -1,32 +1,21 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
 #include <assert.h>
 
-#include "rss_comms_protocol_pointer_access.h"
+#include "rse_comms_protocol_common.h"
+#include "rse_comms_protocol_pointer_access.h"
 
-#define TYPE_OFFSET	(16U)
-#define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
-#define IN_LEN_OFFSET	(8U)
-#define IN_LEN_MASK	(0xFFUL << IN_LEN_OFFSET)
-#define OUT_LEN_OFFSET	(0U)
-#define OUT_LEN_MASK	(0xFFUL << OUT_LEN_OFFSET)
-
-#define PARAM_PACK(type, in_len, out_len)			  \
-	(((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK)	| \
-	 ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK)	| \
-	 ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
-
-psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_pointer_access_serialize_msg(psa_handle_t handle,
 						       int16_t type,
 						       const psa_invec *in_vec,
 						       uint8_t in_len,
 						       const psa_outvec *out_vec,
 						       uint8_t out_len,
-						       struct rss_pointer_access_msg_t *msg,
+						       struct rse_pointer_access_msg_t *msg,
 						       size_t *msg_len)
 {
 	unsigned int i;
@@ -53,10 +42,10 @@ psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
+psa_status_t rse_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
 							   uint8_t out_len,
 							   psa_status_t *return_val,
-							   const struct rss_pointer_access_reply_t *reply,
+							   const struct rse_pointer_access_reply_t *reply,
 							   size_t reply_size)
 {
 	unsigned int i;
diff --git a/drivers/arm/rss/rss_comms_protocol_pointer_access.h b/drivers/arm/rse/rse_comms_protocol_pointer_access.h
similarity index 58%
rename from drivers/arm/rss/rss_comms_protocol_pointer_access.h
rename to drivers/arm/rse/rse_comms_protocol_pointer_access.h
index a4d054bd..e5935f3f 100644
--- a/drivers/arm/rss/rss_comms_protocol_pointer_access.h
+++ b/drivers/arm/rse/rse_comms_protocol_pointer_access.h
@@ -5,38 +5,38 @@
  *
  */
 
-#ifndef __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
-#define __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
+#ifndef __RSE_COMMS_PROTOCOL_POINTER_ACCESS_H__
+#define __RSE_COMMS_PROTOCOL_POINTER_ACCESS_H__
 
 #include <cdefs.h>
 
 #include <psa/client.h>
 
-struct __packed rss_pointer_access_msg_t {
+struct __packed rse_pointer_access_msg_t {
 	psa_handle_t handle;
 	uint32_t ctrl_param;
 	uint32_t io_sizes[PSA_MAX_IOVEC];
 	uint64_t host_ptrs[PSA_MAX_IOVEC];
 };
 
-struct __packed rss_pointer_access_reply_t {
+struct __packed rse_pointer_access_reply_t {
 	int32_t return_val;
 	uint32_t out_sizes[PSA_MAX_IOVEC];
 };
 
-psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_pointer_access_serialize_msg(psa_handle_t handle,
 						       int16_t type,
 						       const psa_invec *in_vec,
 						       uint8_t in_len,
 						       const psa_outvec *out_vec,
 						       uint8_t out_len,
-						       struct rss_pointer_access_msg_t *msg,
+						       struct rse_pointer_access_msg_t *msg,
 						       size_t *msg_len);
 
-psa_status_t rss_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
+psa_status_t rse_protocol_pointer_access_deserialize_reply(psa_outvec *out_vec,
 							   uint8_t out_len,
 							   psa_status_t *return_val,
-							   const struct rss_pointer_access_reply_t *reply,
+							   const struct rse_pointer_access_reply_t *reply,
 							   size_t reply_size);
 
-#endif /* __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__ */
+#endif /* __RSE_COMMS_PROTOCOL_POINTER_ACCESS_H__ */
diff --git a/drivers/arm/rss/rss_comms.mk b/drivers/arm/rss/rss_comms.mk
deleted file mode 100644
index c1c994b6..00000000
--- a/drivers/arm/rss/rss_comms.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2022, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-$(warning "RSS driver is an experimental feature")
-
-RSS_COMMS_SOURCES	:=	$(addprefix drivers/arm/rss/,			\
-					rss_comms.c				\
-					rss_comms_protocol.c			\
-					rss_comms_protocol_embed.c		\
-					rss_comms_protocol_pointer_access.c	\
-				)
-
-RSS_COMMS_SOURCES	+=	$(addprefix drivers/arm/mhu/,			\
-					mhu_v2_x.c				\
-					mhu_wrapper_v2_x.c			\
-				)
-
-PLAT_INCLUDES		+=	-Idrivers/arm/rss		\
-				-Idrivers/arm/mhu
diff --git a/drivers/arm/rss/rss_comms_protocol.h b/drivers/arm/rss/rss_comms_protocol.h
deleted file mode 100644
index 9a38057c..00000000
--- a/drivers/arm/rss/rss_comms_protocol.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __RSS_COMMS_PROTOCOL_H__
-#define __RSS_COMMS_PROTOCOL_H__
-
-#include <cdefs.h>
-#include <stdint.h>
-
-#include <psa/client.h>
-#include "rss_comms_protocol_embed.h"
-#include "rss_comms_protocol_pointer_access.h"
-
-enum rss_comms_protocol_version_t {
-	RSS_COMMS_PROTOCOL_EMBED = 0,
-	RSS_COMMS_PROTOCOL_POINTER_ACCESS = 1,
-};
-
-struct __packed serialized_rss_comms_header_t {
-	uint8_t protocol_ver;
-	uint8_t seq_num;
-	uint16_t client_id;
-};
-
-/* MHU message passed from Host to RSS to deliver a PSA client call */
-struct __packed serialized_rss_comms_msg_t {
-	struct serialized_rss_comms_header_t header;
-	union __packed {
-		struct rss_embed_msg_t embed;
-		struct rss_pointer_access_msg_t pointer_access;
-	} msg;
-};
-
-/* MHU reply message to hold the PSA client reply result returned by RSS */
-struct __packed serialized_rss_comms_reply_t {
-	struct serialized_rss_comms_header_t header;
-	union __packed {
-		struct rss_embed_reply_t embed;
-		struct rss_pointer_access_reply_t pointer_access;
-	} reply;
-};
-
-/* in_len and out_len are uint8_ts, therefore if there are more than 255 iovecs
- * an error may occur.
- */
-CASSERT(PSA_MAX_IOVEC <= UINT8_MAX, assert_rss_comms_max_iovec_too_large);
-
-psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
-					int16_t type,
-					const psa_invec *in_vec,
-					uint8_t in_len,
-					const psa_outvec *out_vec,
-					uint8_t out_len,
-					struct serialized_rss_comms_msg_t *msg,
-					size_t *msg_len);
-
-psa_status_t rss_protocol_deserialize_reply(psa_outvec *out_vec,
-					    uint8_t out_len,
-					    psa_status_t *return_val,
-					    const struct serialized_rss_comms_reply_t *reply,
-					    size_t reply_size);
-
-#endif /* __RSS_COMMS_PROTOCOL_H__ */
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index 6c6f978d..ef04c4d6 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -69,20 +69,35 @@ int __init smmuv3_security_init(uintptr_t smmu_base)
 	return smmuv3_poll(smmu_base + SMMU_S_GBPA, SMMU_S_GBPA_UPDATE, 0U);
 }
 
-/*
- * Initialize the SMMU by invalidating all secure caches and TLBs.
- * Abort all incoming transactions in order to implement a default
- * deny policy on reset
- */
+/* Initialize the SMMU by invalidating all secure caches and TLBs. */
 int __init smmuv3_init(uintptr_t smmu_base)
 {
-	/* Abort all incoming transactions */
-	if (smmuv3_security_init(smmu_base) != 0)
+	/*
+	 * Initiate invalidation of secure caches and TLBs if the SMMU
+	 * supports secure state. If not, it's implementation defined
+	 * as to how SMMU_S_INIT register is accessed.
+	 * As per Arm SMMUv3 specification the SMMU_S_INIT register in a SMMU
+	 * with RME implementation has following properties:
+	 * a) all SMMU registers that are specified to be accessible only in
+	 *    the Secure physical address space are additionally accessible in
+	 *    Root physical address space.
+	 * b) as GPT information is permitted to be cached in a TLB, the
+	 *    SMMU_S_INIT.INV_ALL operation also invalidates all GPT information
+	 *    cached in TLBs.
+	 * Additionally, it is Root firmware’s responsibility to write to
+	 * INV_ALL before enabling SMMU_ROOT_CR0.{ACCESSEN,GPCEN}.
+	 */
+	mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
+
+	/* Wait for global invalidation operation to finish */
+	if (smmuv3_poll(smmu_base + SMMU_S_INIT,
+			SMMU_S_INIT_INV_ALL, 0U) != 0) {
 		return -1;
+	}
 
 #if ENABLE_RME
 
-	if (get_armv9_2_feat_rme_support() != 0U) {
+	if (is_feat_rme_present()) {
 		if ((mmio_read_32(smmu_base + SMMU_ROOT_IDR0) &
 				  SMMU_ROOT_IDR0_ROOT_IMPL) == 0U) {
 			WARN("Skip SMMU GPC configuration.\n");
@@ -137,23 +152,7 @@ int __init smmuv3_init(uintptr_t smmu_base)
 
 #endif /* ENABLE_RME */
 
-	/*
-	 * Initiate invalidation of secure caches and TLBs if the SMMU
-	 * supports secure state. If not, it's implementation defined
-	 * as to how SMMU_S_INIT register is accessed.
-	 * Arm SMMU Arch RME supplement, section 3.4: all SMMU registers
-	 * specified to be accessible only in secure physical address space are
-	 * additionally accessible in root physical address space in an SMMU
-	 * with RME.
-	 * Section 3.3: as GPT information is permitted to be cached in a TLB,
-	 * the SMMU_S_INIT.INV_ALL mechanism also invalidates GPT information
-	 * cached in TLBs.
-	 */
-	mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
-
-	/* Wait for global invalidation operation to finish */
-	return smmuv3_poll(smmu_base + SMMU_S_INIT,
-				SMMU_S_INIT_INV_ALL, 0U);
+	return 0;
 }
 
 int smmuv3_ns_set_abort_all(uintptr_t smmu_base)
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 608866c8..8c5ff9d1 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -328,7 +328,6 @@ static int auth_nvctr(const auth_method_param_nv_ctr_t *param,
 	unsigned int data_len, len, i;
 	unsigned int plat_nv_ctr;
 	int rc;
-	bool is_trial_run = false;
 
 	/* Get the counter value from current image. The AM expects the IPM
 	 * to return the counter value as a DER encoded integer */
@@ -388,9 +387,14 @@ static int auth_nvctr(const auth_method_param_nv_ctr_t *param,
 		return 1;
 	} else if (*cert_nv_ctr > plat_nv_ctr) {
 #if PSA_FWU_SUPPORT && IMAGE_BL2
-		is_trial_run = fwu_is_trial_run_state();
+		if (fwu_get_active_bank_state() == FWU_BANK_STATE_ACCEPTED) {
+			*need_nv_ctr_upgrade = true;
+		} else {
+			*need_nv_ctr_upgrade = false;
+		}
+#else
+		*need_nv_ctr_upgrade = true;
 #endif /* PSA_FWU_SUPPORT && IMAGE_BL2 */
-		*need_nv_ctr_upgrade = !is_trial_run;
 	}
 
 	return 0;
diff --git a/drivers/auth/cca/bl1_cot.c b/drivers/auth/cca/bl1_cot.c
new file mode 100644
index 00000000..43cb18a9
--- /dev/null
+++ b/drivers/auth/cca/bl1_cot.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <mbedtls/version.h>
+
+#include <common/tbbr/cot_def.h>
+#include <drivers/auth/auth_mod.h>
+#include <platform_def.h>
+#include <tools_share/cca_oid.h>
+
+/*
+ * Allocate static buffers to store the authentication parameters extracted from
+ * the certificates.
+ */
+static unsigned char fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
+
+/*
+ * Parameter type descriptors.
+ */
+static auth_param_type_desc_t cca_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, CCA_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, 0);
+static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG, 0);
+static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG_ALG, 0);
+static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_RAW_DATA, 0);
+
+static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
+static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
+
+/* CCA Content Certificate */
+static const auth_img_desc_t cca_content_cert = {
+	.img_id = CCA_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &cca_nv_ctr,
+				.plat_nv_ctr = &cca_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tb_fw_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tb_fw_config_hash,
+			.data = {
+				.ptr = (void *)tb_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &fw_config_hash,
+			.data = {
+				.ptr = (void *)fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t bl2_image = {
+	.img_id = BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t tb_fw_config = {
+	.img_id = TB_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_config_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t fw_config = {
+	.img_id = FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &cca_content_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &fw_config_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t * const cot_desc[] = {
+	[CCA_CONTENT_CERT_ID]			=	&cca_content_cert,
+	[BL2_IMAGE_ID]				=	&bl2_image,
+	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
+	[FW_CONFIG_ID]				=	&fw_config,
+};
+
+REGISTER_COT(cot_desc);
diff --git a/drivers/auth/cca/cot.c b/drivers/auth/cca/cot.c
deleted file mode 100644
index 2a036045..00000000
--- a/drivers/auth/cca/cot.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-
-#include <mbedtls/version.h>
-
-#include <common/tbbr/cot_def.h>
-#include <drivers/auth/auth_mod.h>
-#include <tools_share/cca_oid.h>
-
-#include <platform_def.h>
-
-/*
- * Allocate static buffers to store the authentication parameters extracted from
- * the certificates.
- */
-static unsigned char fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char hw_config_hash_buf[HASH_DER_LEN];
-static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
-static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char rmm_hash_buf[HASH_DER_LEN];
-
-#ifdef IMAGE_BL2
-static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
-#if defined(SPD_spmd)
-static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
-#endif /* SPD_spmd */
-
-static unsigned char core_swd_pk_buf[PK_DER_LEN];
-static unsigned char plat_pk_buf[PK_DER_LEN];
-#endif /* IMAGE_BL2 */
-
-/*
- * Parameter type descriptors.
- */
-static auth_param_type_desc_t cca_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, CCA_FW_NVCOUNTER_OID);
-static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, 0);
-static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG, 0);
-static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG_ALG, 0);
-static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_RAW_DATA, 0);
-
-static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
-static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
-static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
-static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t rmm_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, RMM_HASH_OID);
-
-#ifdef IMAGE_BL2
-static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
-static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
-
-static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, PROT_PK_OID);
-static auth_param_type_desc_t swd_rot_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, SWD_ROT_PK_OID);
-static auth_param_type_desc_t core_swd_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, CORE_SWD_PK_OID);
-static auth_param_type_desc_t plat_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, PLAT_PK_OID);
-
-static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
-static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
-static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
-#if defined(SPD_spmd)
-static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
-static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
-static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
-static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
-static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
-static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
-static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
-static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
-#endif /* SPD_spmd */
-#endif /* IMAGE_BL2 */
-
-/* CCA Content Certificate */
-static const auth_img_desc_t cca_content_cert = {
-	.img_id = CCA_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &cca_nv_ctr,
-				.plat_nv_ctr = &cca_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tb_fw_hash,
-			.data = {
-				.ptr = (void *)tb_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &tb_fw_config_hash,
-			.data = {
-				.ptr = (void *)tb_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &fw_config_hash,
-			.data = {
-				.ptr = (void *)fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &hw_config_hash,
-			.data = {
-				.ptr = (void *)hw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[4] = {
-			.type_desc = &soc_fw_hash,
-			.data = {
-				.ptr = (void *)soc_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[5] = {
-			.type_desc = &soc_fw_config_hash,
-			.data = {
-				.ptr = (void *)soc_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[6] = {
-			.type_desc = &rmm_hash,
-			.data = {
-				.ptr = (void *)rmm_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-#ifdef IMAGE_BL1
-static const auth_img_desc_t bl2_image = {
-	.img_id = BL2_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tb_fw_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t tb_fw_config = {
-	.img_id = TB_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tb_fw_config_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t fw_config = {
-	.img_id = FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &fw_config_hash
-			}
-		}
-	}
-};
-#endif /* IMAGE_BL1 */
-
-#ifdef IMAGE_BL2
-/* HW Config */
-static const auth_img_desc_t hw_config = {
-	.img_id = HW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &hw_config_hash
-			}
-		}
-	}
-};
-
-/* BL31 */
-static const auth_img_desc_t bl31_image = {
-	.img_id = BL31_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &soc_fw_hash
-			}
-		}
-	}
-};
-
-/* BL31 Config */
-static const auth_img_desc_t soc_fw_config = {
-	.img_id = SOC_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &soc_fw_config_hash
-			}
-		}
-	}
-};
-
-/* RMM */
-static const auth_img_desc_t rmm_image = {
-	.img_id = RMM_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &cca_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &rmm_hash
-			}
-		}
-	}
-};
-
-/* Core SWD Key Certificate */
-static const auth_img_desc_t core_swd_key_cert = {
-	.img_id = CORE_SWD_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL, /* SWD ROOT CERT */
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &swd_rot_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &core_swd_pk,
-			.data = {
-				.ptr = (void *)core_swd_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-/* SPMC Content Certificate */
-static const auth_img_desc_t trusted_os_fw_content_cert = {
-	.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &core_swd_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &core_swd_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tos_fw_hash,
-			.data = {
-				.ptr = (void *)tos_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &tos_fw_config_hash,
-			.data = {
-				.ptr = (void *)tos_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-/* SPMC */
-static const auth_img_desc_t bl32_image = {
-	.img_id = BL32_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_hash
-			}
-		}
-	}
-};
-
-/* SPM Config */
-static const auth_img_desc_t tos_fw_config = {
-	.img_id = TOS_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_config_hash
-			}
-		}
-	}
-};
-
-/* Platform Key Certificate */
-static const auth_img_desc_t plat_key_cert = {
-	.img_id = PLAT_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL, /* PLATFORM ROOT CERT */
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &prot_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &plat_pk,
-			.data = {
-				.ptr = (void *)plat_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-/* Non-Trusted Firmware */
-static const auth_img_desc_t non_trusted_fw_content_cert = {
-	.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &plat_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &plat_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &nt_world_bl_hash,
-			.data = {
-				.ptr = (void *)nt_world_bl_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &nt_fw_config_hash,
-			.data = {
-				.ptr = (void *)nt_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl33_image = {
-	.img_id = BL33_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &non_trusted_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &nt_world_bl_hash
-			}
-		}
-	}
-};
-
-/* NT FW Config */
-static const auth_img_desc_t nt_fw_config = {
-	.img_id = NT_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &non_trusted_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &nt_fw_config_hash
-			}
-		}
-	}
-};
-
-/*
- * Secure Partitions
- */
-#if defined(SPD_spmd)
-static const auth_img_desc_t sip_sp_content_cert = {
-	.img_id = SIP_SP_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &core_swd_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &core_swd_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &sp_pkg1_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[0],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &sp_pkg2_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[1],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &sp_pkg3_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[2],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &sp_pkg4_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[3],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-DEFINE_SIP_SP_PKG(1);
-DEFINE_SIP_SP_PKG(2);
-DEFINE_SIP_SP_PKG(3);
-DEFINE_SIP_SP_PKG(4);
-
-static const auth_img_desc_t plat_sp_content_cert = {
-	.img_id = PLAT_SP_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &plat_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &plat_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &sp_pkg5_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[4],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &sp_pkg6_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[5],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &sp_pkg7_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[6],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &sp_pkg8_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[7],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-DEFINE_PLAT_SP_PKG(5);
-DEFINE_PLAT_SP_PKG(6);
-DEFINE_PLAT_SP_PKG(7);
-DEFINE_PLAT_SP_PKG(8);
-#endif /* SPD_spmd */
-#endif /* IMAGE_BL2 */
-/*
- * Chain of trust definition
- */
-#ifdef IMAGE_BL1
-static const auth_img_desc_t * const cot_desc[] = {
-	[CCA_CONTENT_CERT_ID]			=	&cca_content_cert,
-	[BL2_IMAGE_ID]				=	&bl2_image,
-	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
-	[FW_CONFIG_ID]				=	&fw_config,
-};
-#else /* IMAGE_BL2 */
-static const auth_img_desc_t * const cot_desc[] = {
-	[CCA_CONTENT_CERT_ID]			=	&cca_content_cert,
-	[HW_CONFIG_ID]				=	&hw_config,
-	[BL31_IMAGE_ID]				=	&bl31_image,
-	[SOC_FW_CONFIG_ID]			=	&soc_fw_config,
-	[RMM_IMAGE_ID]				=	&rmm_image,
-	[CORE_SWD_KEY_CERT_ID]			=	&core_swd_key_cert,
-	[TRUSTED_OS_FW_CONTENT_CERT_ID]		=	&trusted_os_fw_content_cert,
-	[BL32_IMAGE_ID]				=	&bl32_image,
-	[TOS_FW_CONFIG_ID]			=	&tos_fw_config,
-	[PLAT_KEY_CERT_ID]			=	&plat_key_cert,
-	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
-	[BL33_IMAGE_ID]				=	&bl33_image,
-	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
-#if defined(SPD_spmd)
-	[SIP_SP_CONTENT_CERT_ID]		=	&sip_sp_content_cert,
-	[PLAT_SP_CONTENT_CERT_ID]		=	&plat_sp_content_cert,
-	[SP_PKG1_ID]				=	&sp_pkg1,
-	[SP_PKG2_ID]				=	&sp_pkg2,
-	[SP_PKG3_ID]				=	&sp_pkg3,
-	[SP_PKG4_ID]				=	&sp_pkg4,
-	[SP_PKG5_ID]				=	&sp_pkg5,
-	[SP_PKG6_ID]				=	&sp_pkg6,
-	[SP_PKG7_ID]				=	&sp_pkg7,
-	[SP_PKG8_ID]				=       &sp_pkg8,
-#endif
-};
-#endif /* IMAGE_BL1 */
-
-/* Register the CoT in the authentication module */
-REGISTER_COT(cot_desc);
diff --git a/drivers/auth/dualroot/bl1_cot.c b/drivers/auth/dualroot/bl1_cot.c
new file mode 100644
index 00000000..a5481709
--- /dev/null
+++ b/drivers/auth/dualroot/bl1_cot.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <mbedtls/version.h>
+
+#include <common/tbbr/cot_def.h>
+#include <drivers/auth/auth_mod.h>
+#include <platform_def.h>
+#include <tools_share/dualroot_oid.h>
+
+/*
+ * Allocate static buffers to store the authentication parameters extracted from
+ * the certificates.
+ */
+static unsigned char fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
+static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
+static unsigned char scp_fw_hash_buf[HASH_DER_LEN];
+static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
+
+/*
+ * Parameter type descriptors.
+ */
+static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
+static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_PUB_KEY, 0);
+static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG, 0);
+static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_SIG_ALG, 0);
+static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_RAW_DATA, 0);
+
+static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
+static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
+static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
+static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, FWU_HASH_OID);
+
+static const auth_img_desc_t trusted_boot_fw_cert = {
+	.img_id = TRUSTED_BOOT_FW_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &tb_fw_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &tb_fw_config_hash,
+			.data = {
+				.ptr = (void *)tb_fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &fw_config_hash,
+			.data = {
+				.ptr = (void *)fw_config_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t bl2_image = {
+	.img_id = BL2_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_hash
+			}
+		}
+	}
+};
+
+/* TB FW Config */
+static const auth_img_desc_t tb_fw_config = {
+	.img_id = TB_FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &tb_fw_config_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t fw_config = {
+	.img_id = FW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &fw_config_hash
+			}
+		}
+	}
+};
+
+/* FWU auth descriptor */
+static const auth_img_desc_t fwu_cert = {
+	.img_id = FWU_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = NULL,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &subject_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &scp_bl2u_hash,
+			.data = {
+				.ptr = (void *)scp_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &bl2u_hash,
+			.data = {
+				.ptr = (void *)tb_fw_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &ns_bl2u_hash,
+			.data = {
+				.ptr = (void *)nt_world_bl_hash_buf,
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+/* SCP_BL2U */
+static const auth_img_desc_t scp_bl2u_image = {
+	.img_id = SCP_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &scp_bl2u_hash
+			}
+		}
+	}
+};
+
+/* BL2U */
+static const auth_img_desc_t bl2u_image = {
+	.img_id = BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &bl2u_hash
+			}
+		}
+	}
+};
+
+/* NS_BL2U */
+static const auth_img_desc_t ns_bl2u_image = {
+	.img_id = NS_BL2U_IMAGE_ID,
+	.img_type = IMG_RAW,
+	.parent = &fwu_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &ns_bl2u_hash
+			}
+		}
+	}
+};
+
+static const auth_img_desc_t * const cot_desc[] = {
+	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
+	[BL2_IMAGE_ID]				=	&bl2_image,
+	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
+	[FW_CONFIG_ID]				=	&fw_config,
+	[FWU_CERT_ID]				=	&fwu_cert,
+	[SCP_BL2U_IMAGE_ID]			=	&scp_bl2u_image,
+	[BL2U_IMAGE_ID]				=	&bl2u_image,
+	[NS_BL2U_IMAGE_ID]			=	&ns_bl2u_image
+};
+
+REGISTER_COT(cot_desc);
diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c
deleted file mode 100644
index c89930c1..00000000
--- a/drivers/auth/dualroot/cot.c
+++ /dev/null
@@ -1,962 +0,0 @@
-/*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-
-#include <mbedtls/version.h>
-
-#include <common/tbbr/cot_def.h>
-#include <drivers/auth/auth_mod.h>
-
-#include <tools_share/dualroot_oid.h>
-
-#include <platform_def.h>
-
-/*
- * Allocate static buffers to store the authentication parameters extracted from
- * the certificates.
- */
-static unsigned char fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char hw_config_hash_buf[HASH_DER_LEN];
-static unsigned char scp_fw_hash_buf[HASH_DER_LEN];
-static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
-
-#ifdef IMAGE_BL2
-static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN];
-static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
-static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
-#if defined(SPD_spmd)
-static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
-#endif /* SPD_spmd */
-
-static unsigned char trusted_world_pk_buf[PK_DER_LEN];
-static unsigned char content_pk_buf[PK_DER_LEN];
-#endif
-
-/*
- * Parameter type descriptors.
- */
-static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
-static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, 0);
-static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG, 0);
-static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_SIG_ALG, 0);
-static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_RAW_DATA, 0);
-
-static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
-static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
-static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
-#ifdef IMAGE_BL1
-static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
-static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, FWU_HASH_OID);
-#endif /* IMAGE_BL1 */
-
-#ifdef IMAGE_BL2
-static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
-
-static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
-static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID);
-static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID);
-static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID);
-static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_PUB_KEY, PROT_PK_OID);
-
-static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SCP_FW_HASH_OID);
-static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
-static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
-static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID);
-static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_OID);
-static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
-static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
-#if defined(SPD_spmd)
-static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
-static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
-static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
-static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
-static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
-static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
-static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
-static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
-		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
-#endif /* SPD_spmd */
-#endif /* IMAGE_BL2 */
-
-
-/* BL2 */
-static const auth_img_desc_t trusted_boot_fw_cert = {
-	.img_id = TRUSTED_BOOT_FW_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tb_fw_hash,
-			.data = {
-				.ptr = (void *)tb_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &tb_fw_config_hash,
-			.data = {
-				.ptr = (void *)tb_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &hw_config_hash,
-			.data = {
-				.ptr = (void *)hw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &fw_config_hash,
-			.data = {
-				.ptr = (void *)fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-#ifdef IMAGE_BL1
-static const auth_img_desc_t bl2_image = {
-	.img_id = BL2_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tb_fw_hash
-			}
-		}
-	}
-};
-#endif /* IMAGE_BL1 */
-
-/* HW Config */
-static const auth_img_desc_t hw_config = {
-	.img_id = HW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &hw_config_hash
-			}
-		}
-	}
-};
-
-/* TB FW Config */
-#ifdef IMAGE_BL1
-static const auth_img_desc_t tb_fw_config = {
-	.img_id = TB_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tb_fw_config_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t fw_config = {
-	.img_id = FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &fw_config_hash
-			}
-		}
-	}
-};
-
-#endif /* IMAGE_BL1 */
-
-#ifdef IMAGE_BL2
-/* Trusted key certificate */
-static const auth_img_desc_t trusted_key_cert = {
-	.img_id = TRUSTED_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &trusted_world_pk,
-			.data = {
-				.ptr = (void *)trusted_world_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		},
-	}
-};
-
-/* SCP Firmware */
-static const auth_img_desc_t scp_fw_key_cert = {
-	.img_id = SCP_FW_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &trusted_world_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &scp_fw_content_pk,
-			.data = {
-				.ptr = (void *)content_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t scp_fw_content_cert = {
-	.img_id = SCP_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &scp_fw_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &scp_fw_content_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &scp_fw_hash,
-			.data = {
-				.ptr = (void *)scp_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t scp_bl2_image = {
-	.img_id = SCP_BL2_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &scp_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &scp_fw_hash
-			}
-		}
-	}
-};
-
-/* SoC Firmware */
-static const auth_img_desc_t soc_fw_key_cert = {
-	.img_id = SOC_FW_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &trusted_world_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &soc_fw_content_pk,
-			.data = {
-				.ptr = (void *)content_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t soc_fw_content_cert = {
-	.img_id = SOC_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &soc_fw_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &soc_fw_content_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &soc_fw_hash,
-			.data = {
-				.ptr = (void *)soc_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &soc_fw_config_hash,
-			.data = {
-				.ptr = (void *)soc_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl31_image = {
-	.img_id = BL31_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &soc_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &soc_fw_hash
-			}
-		}
-	}
-};
-
-/* SOC FW Config */
-static const auth_img_desc_t soc_fw_config = {
-	.img_id = SOC_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &soc_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &soc_fw_config_hash
-			}
-		}
-	}
-};
-
-/* Trusted OS Firmware */
-static const auth_img_desc_t trusted_os_fw_key_cert = {
-	.img_id = TRUSTED_OS_FW_KEY_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &trusted_world_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tos_fw_content_pk,
-			.data = {
-				.ptr = (void *)content_pk_buf,
-				.len = (unsigned int)PK_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t trusted_os_fw_content_cert = {
-	.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_os_fw_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &tos_fw_content_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &tos_fw_hash,
-			.data = {
-				.ptr = (void *)tos_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &tos_fw_extra1_hash,
-			.data = {
-				.ptr = (void *)tos_fw_extra1_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &tos_fw_extra2_hash,
-			.data = {
-				.ptr = (void *)tos_fw_extra2_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &tos_fw_config_hash,
-			.data = {
-				.ptr = (void *)tos_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl32_image = {
-	.img_id = BL32_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl32_extra1_image = {
-	.img_id = BL32_EXTRA1_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_extra1_hash
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl32_extra2_image = {
-	.img_id = BL32_EXTRA2_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_extra2_hash
-			}
-		}
-	}
-};
-
-/* TOS FW Config */
-static const auth_img_desc_t tos_fw_config = {
-	.img_id = TOS_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_os_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &tos_fw_config_hash
-			}
-		}
-	}
-};
-
-/* Non-Trusted Firmware */
-static const auth_img_desc_t non_trusted_fw_content_cert = {
-	.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL, /* Root certificate.  */
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &prot_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &nt_world_bl_hash,
-			.data = {
-				.ptr = (void *)nt_world_bl_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &nt_fw_config_hash,
-			.data = {
-				.ptr = (void *)nt_fw_config_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-static const auth_img_desc_t bl33_image = {
-	.img_id = BL33_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &non_trusted_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &nt_world_bl_hash
-			}
-		}
-	}
-};
-
-/* NT FW Config */
-static const auth_img_desc_t nt_fw_config = {
-	.img_id = NT_FW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &non_trusted_fw_content_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &nt_fw_config_hash
-			}
-		}
-	}
-};
-
-/*
- * Secure Partitions
- */
-#if defined(SPD_spmd)
-static const auth_img_desc_t sip_sp_content_cert = {
-	.img_id = SIP_SP_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = &trusted_key_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &trusted_world_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &trusted_nv_ctr,
-				.plat_nv_ctr = &trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &sp_pkg1_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[0],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &sp_pkg2_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[1],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &sp_pkg3_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[2],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &sp_pkg4_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[3],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-DEFINE_SIP_SP_PKG(1);
-DEFINE_SIP_SP_PKG(2);
-DEFINE_SIP_SP_PKG(3);
-DEFINE_SIP_SP_PKG(4);
-
-static const auth_img_desc_t plat_sp_content_cert = {
-	.img_id = PLAT_SP_CONTENT_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &prot_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		},
-		[1] = {
-			.type = AUTH_METHOD_NV_CTR,
-			.param.nv_ctr = {
-				.cert_nv_ctr = &non_trusted_nv_ctr,
-				.plat_nv_ctr = &non_trusted_nv_ctr
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &sp_pkg5_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[4],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &sp_pkg6_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[5],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &sp_pkg7_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[6],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[3] = {
-			.type_desc = &sp_pkg8_hash,
-			.data = {
-				.ptr = (void *)sp_pkg_hash_buf[7],
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-DEFINE_PLAT_SP_PKG(5);
-DEFINE_PLAT_SP_PKG(6);
-DEFINE_PLAT_SP_PKG(7);
-DEFINE_PLAT_SP_PKG(8);
-#endif /* SPD_spmd */
-
-#else  /* IMAGE_BL2 */
-
-/* FWU auth descriptor */
-static const auth_img_desc_t fwu_cert = {
-	.img_id = FWU_CERT_ID,
-	.img_type = IMG_CERT,
-	.parent = NULL,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_SIG,
-			.param.sig = {
-				.pk = &subject_pk,
-				.sig = &sig,
-				.alg = &sig_alg,
-				.data = &raw_data
-			}
-		}
-	},
-	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
-		[0] = {
-			.type_desc = &scp_bl2u_hash,
-			.data = {
-				.ptr = (void *)scp_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[1] = {
-			.type_desc = &bl2u_hash,
-			.data = {
-				.ptr = (void *)tb_fw_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		},
-		[2] = {
-			.type_desc = &ns_bl2u_hash,
-			.data = {
-				.ptr = (void *)nt_world_bl_hash_buf,
-				.len = (unsigned int)HASH_DER_LEN
-			}
-		}
-	}
-};
-
-/* SCP_BL2U */
-static const auth_img_desc_t scp_bl2u_image = {
-	.img_id = SCP_BL2U_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &fwu_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &scp_bl2u_hash
-			}
-		}
-	}
-};
-
-/* BL2U */
-static const auth_img_desc_t bl2u_image = {
-	.img_id = BL2U_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &fwu_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &bl2u_hash
-			}
-		}
-	}
-};
-
-/* NS_BL2U */
-static const auth_img_desc_t ns_bl2u_image = {
-	.img_id = NS_BL2U_IMAGE_ID,
-	.img_type = IMG_RAW,
-	.parent = &fwu_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &ns_bl2u_hash
-			}
-		}
-	}
-};
-#endif /* IMAGE_BL2 */
-
-/*
- * Chain of trust definition
- */
-#ifdef IMAGE_BL1
-static const auth_img_desc_t * const cot_desc[] = {
-	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
-	[BL2_IMAGE_ID]				=	&bl2_image,
-	[HW_CONFIG_ID]				=	&hw_config,
-	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
-	[FW_CONFIG_ID]				=	&fw_config,
-	[FWU_CERT_ID]				=	&fwu_cert,
-	[SCP_BL2U_IMAGE_ID]			=	&scp_bl2u_image,
-	[BL2U_IMAGE_ID]				=	&bl2u_image,
-	[NS_BL2U_IMAGE_ID]			=	&ns_bl2u_image
-};
-#else /* IMAGE_BL2 */
-static const auth_img_desc_t * const cot_desc[] = {
-	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
-	[HW_CONFIG_ID]				=	&hw_config,
-	[TRUSTED_KEY_CERT_ID]			=	&trusted_key_cert,
-	[SCP_FW_KEY_CERT_ID]			=	&scp_fw_key_cert,
-	[SCP_FW_CONTENT_CERT_ID]		=	&scp_fw_content_cert,
-	[SCP_BL2_IMAGE_ID]			=	&scp_bl2_image,
-	[SOC_FW_KEY_CERT_ID]			=	&soc_fw_key_cert,
-	[SOC_FW_CONTENT_CERT_ID]		=	&soc_fw_content_cert,
-	[BL31_IMAGE_ID]				=	&bl31_image,
-	[SOC_FW_CONFIG_ID]			=	&soc_fw_config,
-	[TRUSTED_OS_FW_KEY_CERT_ID]		=	&trusted_os_fw_key_cert,
-	[TRUSTED_OS_FW_CONTENT_CERT_ID]		=	&trusted_os_fw_content_cert,
-	[BL32_IMAGE_ID]				=	&bl32_image,
-	[BL32_EXTRA1_IMAGE_ID]			=	&bl32_extra1_image,
-	[BL32_EXTRA2_IMAGE_ID]			=	&bl32_extra2_image,
-	[TOS_FW_CONFIG_ID]			=	&tos_fw_config,
-	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
-	[BL33_IMAGE_ID]				=	&bl33_image,
-	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
-#if defined(SPD_spmd)
-	[SIP_SP_CONTENT_CERT_ID]		=	&sip_sp_content_cert,
-	[PLAT_SP_CONTENT_CERT_ID]		=	&plat_sp_content_cert,
-	[SP_PKG1_ID]				=	&sp_pkg1,
-	[SP_PKG2_ID]				=	&sp_pkg2,
-	[SP_PKG3_ID]				=	&sp_pkg3,
-	[SP_PKG4_ID]				=	&sp_pkg4,
-	[SP_PKG5_ID]				=	&sp_pkg5,
-	[SP_PKG6_ID]				=	&sp_pkg6,
-	[SP_PKG7_ID]				=	&sp_pkg7,
-	[SP_PKG8_ID]				=       &sp_pkg8,
-#endif
-};
-#endif
-
-/* Register the CoT in the authentication module */
-REGISTER_COT(cot_desc);
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index a2c64303..765491e9 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,16 +19,15 @@ MBEDTLS_MAJOR=$(shell grep -hP "define MBEDTLS_VERSION_MAJOR" ${MBEDTLS_DIR}/inc
 MBEDTLS_MINOR=$(shell grep -hP "define MBEDTLS_VERSION_MINOR" ${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
 $(info MBEDTLS_VERSION_MAJOR is [${MBEDTLS_MAJOR}] MBEDTLS_VERSION_MINOR is [${MBEDTLS_MINOR}])
 
+ifneq (${MBEDTLS_MAJOR}, 3)
+  $(error Error: TF-A only supports MbedTLS versions > 3.x)
+endif
+
 # Specify mbed TLS configuration file
-ifeq (${MBEDTLS_MAJOR}, 2)
-        $(info Deprecation Notice: Please migrate to Mbedtls version 3.x (refer to TF-A documentation for the exact version number))
-	MBEDTLS_CONFIG_FILE             ?=	"<drivers/auth/mbedtls/mbedtls_config-2.h>"
-else ifeq (${MBEDTLS_MAJOR}, 3)
-	ifeq (${PSA_CRYPTO},1)
-		MBEDTLS_CONFIG_FILE     ?=      "<drivers/auth/mbedtls/psa_mbedtls_config.h>"
-	else
-		MBEDTLS_CONFIG_FILE	?=	"<drivers/auth/mbedtls/mbedtls_config-3.h>"
-	endif
+ifeq (${PSA_CRYPTO},1)
+  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/psa_mbedtls_config.h>"
+else
+  MBEDTLS_CONFIG_FILE    ?=    "<drivers/auth/mbedtls/mbedtls_config-3.h>"
 endif
 
 $(eval $(call add_define,MBEDTLS_CONFIG_FILE))
@@ -47,9 +46,11 @@ LIBMBEDTLS_SRCS		+= $(addprefix ${MBEDTLS_DIR}/library/,		\
 					platform.c 			\
 					platform_util.c			\
 					bignum.c			\
+					bignum_core.c			\
 					gcm.c 				\
 					md.c				\
 					pk.c 				\
+					pk_ecc.c 			\
 					pk_wrap.c 			\
 					pkparse.c 			\
 					pkwrite.c 			\
@@ -59,38 +60,22 @@ LIBMBEDTLS_SRCS		+= $(addprefix ${MBEDTLS_DIR}/library/,		\
 					ecp_curves.c			\
 					ecp.c				\
 					rsa.c				\
+					rsa_alt_helpers.c		\
 					x509.c 				\
 					x509_crt.c 			\
 					)
 
-ifeq (${MBEDTLS_MAJOR}, 2)
-	LIBMBEDTLS_SRCS +=  $(addprefix ${MBEDTLS_DIR}/library/,	\
-						rsa_internal.c		\
-						)
-else ifeq (${MBEDTLS_MAJOR}, 3)
-	LIBMBEDTLS_SRCS +=  $(addprefix ${MBEDTLS_DIR}/library/,	\
-						bignum_core.c		\
-						rsa_alt_helpers.c	\
-						hash_info.c		\
-						)
-
-	# Currently on Mbedtls-3 there is outstanding bug due to usage
-	# of redundant declaration[1], So disable redundant-decls
-	# compilation flag to avoid compilation error when compiling with
-	# Mbedtls-3.
-	# [1]: https://github.com/Mbed-TLS/mbedtls/issues/6910
-	LIBMBEDTLS_CFLAGS += -Wno-error=redundant-decls
-endif
-
 ifeq (${PSA_CRYPTO},1)
 LIBMBEDTLS_SRCS         += $(addprefix ${MBEDTLS_DIR}/library/,    	\
 					psa_crypto.c                   	\
 					psa_crypto_client.c            	\
-					psa_crypto_driver_wrappers.c   	\
 					psa_crypto_hash.c              	\
 					psa_crypto_rsa.c               	\
 					psa_crypto_ecp.c               	\
 					psa_crypto_slot_management.c   	\
+					psa_crypto_aead.c               \
+					psa_crypto_cipher.c             \
+					psa_util.c			\
 					)
 endif
 
@@ -134,6 +119,14 @@ else
     TF_MBEDTLS_HASH_ALG_ID	:=	TF_MBEDTLS_SHA256
 endif
 
+ifeq (${MBOOT_EL_HASH_ALG}, sha256)
+    $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA256))
+else ifeq (${MBOOT_EL_HASH_ALG}, sha384)
+    $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA384))
+else ifeq (${MBOOT_EL_HASH_ALG}, sha512)
+    $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
+endif
+
 ifeq (${TF_MBEDTLS_KEY_ALG},ecdsa)
     TF_MBEDTLS_KEY_ALG_ID	:=	TF_MBEDTLS_ECDSA
 else ifeq (${TF_MBEDTLS_KEY_ALG},rsa)
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index 230cec9d..8fe426bb 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -65,6 +65,18 @@ static void init(void)
 
 #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
 CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
+
+
+/*
+ * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
+ * advised that it's better to copy out the declaration than it would be to
+ * update to 3.5.2, where this function is exposed.
+ */
+int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
+			     const mbedtls_x509_buf *sig_params,
+			     mbedtls_md_type_t *md_alg,
+			     mbedtls_pk_type_t *pk_alg,
+			     void **sig_opts);
 /*
  * Verify a signature.
  *
@@ -263,6 +275,7 @@ static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
 		     unsigned char output[CRYPTO_MD_MAX_SIZE])
 {
 	const mbedtls_md_info_t *md_info;
+	int rc;
 
 	md_info = mbedtls_md_info_from_type(md_type(md_algo));
 	if (md_info == NULL) {
@@ -274,7 +287,12 @@ static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
 	 * 'output' hash buffer pointer considering its size is always
 	 * bigger than or equal to MBEDTLS_MD_MAX_SIZE.
 	 */
-	return mbedtls_md(md_info, data_ptr, data_len, output);
+	rc = mbedtls_md(md_info, data_ptr, data_len, output);
+	if (rc != 0) {
+		return CRYPTO_ERR_HASH;
+	}
+
+	return CRYPTO_SUCCESS;
 }
 #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
 	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
diff --git a/drivers/auth/mbedtls/mbedtls_psa_crypto.c b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
index 5891acf3..0e4b57e2 100644
--- a/drivers/auth/mbedtls/mbedtls_psa_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,12 +9,11 @@
 #include <string.h>
 
 /* mbed TLS headers */
-#include <mbedtls/gcm.h>
 #include <mbedtls/md.h>
 #include <mbedtls/memory_buffer_alloc.h>
 #include <mbedtls/oid.h>
 #include <mbedtls/platform.h>
-#include <mbedtls/version.h>
+#include <mbedtls/psa_util.h>
 #include <mbedtls/x509.h>
 #include <psa/crypto.h>
 #include <psa/crypto_platform.h>
@@ -28,8 +27,10 @@
 
 #define LIB_NAME		"mbed TLS PSA"
 
-/* Maximum length of R_S pair in the ECDSA signature in bytes */
-#define MAX_ECDSA_R_S_PAIR_LEN	64U
+/* Minimum required size for a buffer containing a raw EC signature when using
+ * a maximum curve size of 384 bits.
+ * This is calculated as 2 * (384 / 8). */
+#define ECDSA_SIG_BUFFER_SIZE	96U
 
 /* Size of ASN.1 length and tag in bytes*/
 #define SIZE_OF_ASN1_LEN	1U
@@ -49,16 +50,6 @@ CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
 	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 	*/
 
-static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(
-						mbedtls_md_type_t md_type)
-{
-	assert((md_type == MBEDTLS_MD_SHA256) ||
-	       (md_type == MBEDTLS_MD_SHA384) ||
-	       (md_type == MBEDTLS_MD_SHA512));
-
-	return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) (md_type + 0x5);
-}
-
 /*
  * AlgorithmIdentifier  ::=  SEQUENCE  {
  *     algorithm               OBJECT IDENTIFIER,
@@ -113,184 +104,82 @@ static void init(void)
 #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
 CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 
-static void construct_psa_key_alg_and_type(mbedtls_pk_type_t pk_alg,
-					   mbedtls_md_type_t md_alg,
-					   psa_ecc_family_t psa_ecc_family,
-					   psa_algorithm_t *psa_alg,
-					   psa_key_type_t *psa_key_type)
-{
-	psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
-
-	switch (pk_alg) {
-	case MBEDTLS_PK_RSASSA_PSS:
-		*psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
-		*psa_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY;
-		break;
-	case MBEDTLS_PK_ECDSA:
-		*psa_alg = PSA_ALG_ECDSA(psa_md_alg);
-		*psa_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_ecc_family);
-		break;
-	default:
-		*psa_alg = PSA_ALG_NONE;
-		*psa_key_type = PSA_KEY_TYPE_NONE;
-		break;
-	}
-}
-
-
-#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
-TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
-
 /*
- * This is a helper function to detect padding byte (if the MSB bit of the
- * first data byte is set to 1, for example 0x80) and on detection, ignore the
- * padded byte(0x00) and increase the buffer pointer beyond padded byte and
- * decrease the length of the buffer by 1.
- *
- * On Success returns 0, error otherwise.
- **/
-static inline int ignore_asn1_int_padding_byte(unsigned char **buf_start,
-					       size_t *buf_len)
-{
-	unsigned char *local_buf = *buf_start;
-
-	/* Check for negative number */
-	if ((local_buf[0] & 0x80U) != 0U) {
-		return -1;
-	}
-
-	if ((local_buf[0] == 0U) && (local_buf[1] > 0x7FU) &&
-	    (*buf_len > 1U)) {
-		*buf_start = &local_buf[1];
-		(*buf_len)--;
-	}
-
-	return 0;
-}
+ * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
+ * advised that it's better to copy out the declaration than it would be to
+ * update to 3.5.2, where this function is exposed.
+ */
+int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
+			     const mbedtls_x509_buf *sig_params,
+			     mbedtls_md_type_t *md_alg,
+			     mbedtls_pk_type_t *pk_alg,
+			     void **sig_opts);
 
 /*
- * This is a helper function that gets a pointer to the encoded ECDSA publicKey
- * and its length (as per RFC5280) and returns corresponding decoded publicKey
- * and its length. As well, it retrieves the family of ECC key in the PSA
- * format.
- *
- * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
- * otherwise success(0).
- **/
-static int get_ecdsa_pkinfo_from_asn1(unsigned char **pk_start,
-				      unsigned int *pk_len,
-				      psa_ecc_family_t *psa_ecc_family)
+ * This is a helper function which parses a SignatureAlgorithm OID.
+ * It extracts the pk algorithm and constructs a psa_algorithm_t object
+ * to be used by PSA calls.
+ */
+static int construct_psa_alg(void *sig_alg, unsigned int sig_alg_len,
+			     mbedtls_pk_type_t *pk_alg, psa_algorithm_t *psa_alg)
 {
-	mbedtls_asn1_buf alg_oid, alg_params;
-	mbedtls_ecp_group_id grp_id;
 	int rc;
-	unsigned char *pk_end;
-	size_t len;
-	size_t curve_bits;
-	unsigned char *pk_ptr = *pk_start;
+	mbedtls_md_type_t md_alg;
+	void *sig_opts = NULL;
+	mbedtls_asn1_buf sig_alg_oid, params;
+	unsigned char *p = (unsigned char *) sig_alg;
+	unsigned char *end = (unsigned char *) sig_alg + sig_alg_len;
 
-	pk_end = pk_ptr + *pk_len;
-	rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len,
-				  MBEDTLS_ASN1_CONSTRUCTED |
-				  MBEDTLS_ASN1_SEQUENCE);
+	rc = mbedtls_asn1_get_alg(&p, end, &sig_alg_oid, &params);
 	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end;
 	}
 
-	pk_end = pk_ptr + len;
-	rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params);
+	rc = mbedtls_x509_get_sig_alg(&sig_alg_oid, &params, &md_alg, pk_alg, &sig_opts);
 	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end;
 	}
 
-	if (alg_params.tag == MBEDTLS_ASN1_OID) {
-		if (mbedtls_oid_get_ec_grp(&alg_params, &grp_id) != 0) {
-			return CRYPTO_ERR_SIGNATURE;
-		}
-		*psa_ecc_family = mbedtls_ecc_group_to_psa(grp_id,
-							   &curve_bits);
-	} else {
-		return CRYPTO_ERR_SIGNATURE;
-	}
+	psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
 
-	pk_end = pk_ptr + len - (alg_oid.len + alg_params.len +
-		 2 * (SIZE_OF_ASN1_LEN + SIZE_OF_ASN1_TAG));
-	rc = mbedtls_asn1_get_bitstring_null(&pk_ptr, pk_end, &len);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
+	switch (*pk_alg) {
+	case MBEDTLS_PK_RSASSA_PSS:
+		*psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
+		rc = CRYPTO_SUCCESS;
+		break;
+	case MBEDTLS_PK_ECDSA:
+		*psa_alg = PSA_ALG_ECDSA(psa_md_alg);
+		rc = CRYPTO_SUCCESS;
+		break;
+	default:
+		*psa_alg = PSA_ALG_NONE;
+		rc = CRYPTO_ERR_SIGNATURE;
+		break;
 	}
 
-	*pk_start = pk_ptr;
-	*pk_len = len;
-
+end:
+	mbedtls_free(sig_opts);
 	return rc;
 }
 
 /*
- * Ecdsa-Sig-Value  ::=  SEQUENCE  {
- *   r     INTEGER,
- *   s     INTEGER
- * }
- *
- * This helper function that gets a pointer to the encoded ECDSA signature and
- * its length (as per RFC5280) and returns corresponding decoded signature
- * (R_S pair) and its size.
- *
- * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
- * otherwise success(0).
- **/
-static int get_ecdsa_signature_from_asn1(unsigned char *sig_ptr,
-					 size_t *sig_len,
-					 unsigned char *r_s_pair)
+ * Helper functions for mbedtls PK contexts.
+ */
+static void initialize_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
 {
-	int rc;
-	unsigned char *sig_end;
-	size_t len, r_len, s_len;
-
-	sig_end = sig_ptr + *sig_len;
-	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &len,
-				  MBEDTLS_ASN1_CONSTRUCTED |
-				  MBEDTLS_ASN1_SEQUENCE);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	sig_end = sig_ptr + len;
-	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &r_len,
-				  MBEDTLS_ASN1_INTEGER);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	if (ignore_asn1_int_padding_byte(&sig_ptr, &r_len) != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
-
-	(void)memcpy((void *)&r_s_pair[0], (const void *)sig_ptr, r_len);
-
-	sig_ptr = sig_ptr + r_len;
-	sig_end = sig_ptr + len - (r_len + (SIZE_OF_ASN1_LEN +
-		  SIZE_OF_ASN1_TAG));
-	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &s_len,
-				  MBEDTLS_ASN1_INTEGER);
-	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
-	}
+	mbedtls_pk_init(pk);
+	*pk_initialized = true;
+}
 
-	if (ignore_asn1_int_padding_byte(&sig_ptr, &s_len) != 0) {
-		return CRYPTO_ERR_SIGNATURE;
+static void cleanup_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
+{
+	if (*pk_initialized) {
+		mbedtls_pk_free(pk);
+		*pk_initialized = false;
 	}
-
-	(void)memcpy((void *)&r_s_pair[r_len], (const void *)sig_ptr, s_len);
-
-	*sig_len = s_len + r_len;
-
-	return 0;
 }
-#endif /*
-	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
-	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
-	**/
 
 /*
  * Verify a signature.
@@ -303,125 +192,99 @@ static int verify_signature(void *data_ptr, unsigned int data_len,
 			    void *sig_alg, unsigned int sig_alg_len,
 			    void *pk_ptr, unsigned int pk_len)
 {
-	mbedtls_asn1_buf sig_oid, sig_params;
-	mbedtls_asn1_buf signature;
-	mbedtls_md_type_t md_alg;
-	mbedtls_pk_type_t pk_alg;
-	int rc;
-	void *sig_opts = NULL;
 	unsigned char *p, *end;
+	mbedtls_pk_context pk;
+	bool pk_initialized = false;
+	int rc = CRYPTO_ERR_SIGNATURE;
+	psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED;
+	psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT;
+	psa_key_id_t psa_key_id;
+	mbedtls_pk_type_t pk_alg;
+	psa_algorithm_t psa_alg;
+	__unused unsigned char reformatted_sig[ECDSA_SIG_BUFFER_SIZE] = {0};
 	unsigned char *local_sig_ptr;
 	size_t local_sig_len;
-	psa_ecc_family_t psa_ecc_family = 0U;
-	__unused unsigned char reformatted_sig[MAX_ECDSA_R_S_PAIR_LEN] = {0};
 
-	/* construct PSA key algo and type */
-	psa_status_t status = PSA_SUCCESS;
-	psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT;
-	psa_key_id_t psa_key_id = PSA_KEY_ID_NULL;
-	psa_key_type_t psa_key_type;
-	psa_algorithm_t psa_alg;
+	/* Load the key into the PSA key store. */
+	initialize_pk_context(&pk, &pk_initialized);
 
-	/* Get pointers to signature OID and parameters */
-	p = (unsigned char *)sig_alg;
-	end = (unsigned char *)(p + sig_alg_len);
-	rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params);
+	p = (unsigned char *) pk_ptr;
+	end = p + pk_len;
+	rc = mbedtls_pk_parse_subpubkey(&p, end, &pk);
 	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end2;
 	}
 
-	/* Get the actual signature algorithm (MD + PK) */
-	rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts);
+	rc = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_MESSAGE, &psa_key_attr);
 	if (rc != 0) {
-		return CRYPTO_ERR_SIGNATURE;
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end2;
 	}
 
-	/* Get the signature (bitstring) */
-	p = (unsigned char *)sig_ptr;
-	end = (unsigned char *)(p + sig_len);
-	signature.tag = *p;
-	rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len);
-	if ((rc != 0) || ((size_t)(end - p) != signature.len)) {
+	rc = construct_psa_alg(sig_alg, sig_alg_len, &pk_alg, &psa_alg);
+	if (rc != CRYPTO_SUCCESS) {
+		goto end2;
+	}
+	psa_set_key_algorithm(&psa_key_attr, psa_alg);
+
+	rc = mbedtls_pk_import_into_psa(&pk, &psa_key_attr, &psa_key_id);
+	if (rc != 0) {
 		rc = CRYPTO_ERR_SIGNATURE;
 		goto end2;
 	}
 
+	/* Optimize mbedtls heap usage by freeing the pk context now.  */
+	cleanup_pk_context(&pk, &pk_initialized);
+
+	/* Extract the signature from sig_ptr. */
+	p = (unsigned char *) sig_ptr;
+	end = p + sig_len;
+	rc = mbedtls_asn1_get_bitstring_null(&p, end, &local_sig_len);
+	if (rc != 0) {
+		rc = CRYPTO_ERR_SIGNATURE;
+		goto end1;
+	}
 	local_sig_ptr = p;
-	local_sig_len = signature.len;
 
 #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
 TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
 	if (pk_alg == MBEDTLS_PK_ECDSA) {
-		rc = get_ecdsa_signature_from_asn1(local_sig_ptr,
-						   &local_sig_len,
-						   reformatted_sig);
-		if (rc != 0) {
-			goto end2;
-		}
+		/* Convert the DER ASN.1 signature to raw format. */
+		size_t key_bits = psa_get_key_bits(&psa_key_attr);
 
-		local_sig_ptr = reformatted_sig;
-
-		rc = get_ecdsa_pkinfo_from_asn1((unsigned char **)&pk_ptr,
-						&pk_len,
-						&psa_ecc_family);
+		rc = mbedtls_ecdsa_der_to_raw(key_bits, p, local_sig_len,
+					      reformatted_sig, ECDSA_SIG_BUFFER_SIZE,
+					      &local_sig_len);
 		if (rc != 0) {
-			goto end2;
+			rc = CRYPTO_ERR_SIGNATURE;
+			goto end1;
 		}
+		local_sig_ptr = reformatted_sig;
 	}
 #endif /*
 	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
 	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
 	**/
 
-	/* Convert this pk_alg and md_alg to PSA key type and key algorithm */
-	construct_psa_key_alg_and_type(pk_alg, md_alg, psa_ecc_family,
-				       &psa_alg, &psa_key_type);
-
-
-	if ((psa_alg == PSA_ALG_NONE) || (psa_key_type == PSA_KEY_TYPE_NONE)) {
-		rc = CRYPTO_ERR_SIGNATURE;
-		goto end2;
-	}
-
-	/* filled-in key_attributes */
-	psa_set_key_algorithm(&psa_key_attr, psa_alg);
-	psa_set_key_type(&psa_key_attr, psa_key_type);
-	psa_set_key_usage_flags(&psa_key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
-
-	/* Get the key_id using import API */
-	status = psa_import_key(&psa_key_attr,
-				pk_ptr,
-				(size_t)pk_len,
-				&psa_key_id);
-
-	if (status != PSA_SUCCESS) {
-		rc = CRYPTO_ERR_SIGNATURE;
-		goto end2;
-	}
-
-	/*
-	 * Hash calculation and Signature verification of the given data payload
-	 * is wrapped under the psa_verify_message function.
-	 */
-	status = psa_verify_message(psa_key_id, psa_alg,
+	/* Verify the signature. */
+	psa_status = psa_verify_message(psa_key_id, psa_alg,
 				    data_ptr, data_len,
 				    local_sig_ptr, local_sig_len);
-
-	if (status != PSA_SUCCESS) {
+	if (psa_status == PSA_SUCCESS) {
+		/* The signature has been successfully verified. */
+		rc = CRYPTO_SUCCESS;
+	} else {
 		rc = CRYPTO_ERR_SIGNATURE;
-		goto end1;
 	}
 
-	/* Signature verification success */
-	rc = CRYPTO_SUCCESS;
-
 end1:
-	/*
-	 * Destroy the key if it is created successfully
-	 */
+	/* Destroy the key from the PSA subsystem. */
 	psa_destroy_key(psa_key_id);
 end2:
-	mbedtls_free(sig_opts);
+	/* Free the pk context, if it is initialized. */
+	cleanup_pk_context(&pk, &pk_initialized);
+
 	return rc;
 }
 
@@ -570,78 +433,61 @@ static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
 			   unsigned int iv_len, const void *tag,
 			   unsigned int tag_len)
 {
-	mbedtls_gcm_context ctx;
-	mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
+	mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
+	psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
 	unsigned char buf[DEC_OP_BUF_SIZE];
-	unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE];
 	unsigned char *pt = data_ptr;
 	size_t dec_len;
-	int diff, i, rc;
-	size_t output_length __unused;
+	size_t output_length;
 
-	mbedtls_gcm_init(&ctx);
+	/* Load the key into the PSA key store. */
+	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
+	psa_set_key_algorithm(&attributes, PSA_ALG_GCM);
+	psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
 
-	rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8);
-	if (rc != 0) {
-		rc = CRYPTO_ERR_DECRYPTION;
-		goto exit_gcm;
+	psa_status = psa_import_key(&attributes, key, key_len, &key_id);
+	if (psa_status != PSA_SUCCESS) {
+		return CRYPTO_ERR_DECRYPTION;
 	}
 
-#if (MBEDTLS_VERSION_MAJOR < 3)
-	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0);
-#else
-	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len);
-#endif
-	if (rc != 0) {
-		rc = CRYPTO_ERR_DECRYPTION;
-		goto exit_gcm;
+	/* Perform the decryption. */
+	psa_status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_GCM);
+	if (psa_status != PSA_SUCCESS) {
+		goto err;
+	}
+
+	psa_status = psa_aead_set_nonce(&operation, iv, iv_len);
+	if (psa_status != PSA_SUCCESS) {
+		goto err;
 	}
 
 	while (len > 0) {
 		dec_len = MIN(sizeof(buf), len);
 
-#if (MBEDTLS_VERSION_MAJOR < 3)
-		rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf);
-#else
-		rc = mbedtls_gcm_update(&ctx, pt, dec_len, buf, sizeof(buf), &output_length);
-#endif
-
-		if (rc != 0) {
-			rc = CRYPTO_ERR_DECRYPTION;
-			goto exit_gcm;
+		psa_status = psa_aead_update(&operation, pt, dec_len, buf,
+					     sizeof(buf), &output_length);
+		if (psa_status != PSA_SUCCESS) {
+			goto err;
 		}
 
-		memcpy(pt, buf, dec_len);
-		pt += dec_len;
+		memcpy(pt, buf, output_length);
+		pt += output_length;
 		len -= dec_len;
 	}
 
-#if (MBEDTLS_VERSION_MAJOR < 3)
-	rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf));
-#else
-	rc = mbedtls_gcm_finish(&ctx, NULL, 0, &output_length, tag_buf, sizeof(tag_buf));
-#endif
-
-	if (rc != 0) {
-		rc = CRYPTO_ERR_DECRYPTION;
-		goto exit_gcm;
+	/* Verify the tag. */
+	psa_status = psa_aead_verify(&operation, NULL, 0, &output_length, tag, tag_len);
+	if (psa_status == PSA_SUCCESS) {
+		psa_destroy_key(key_id);
+		return CRYPTO_SUCCESS;
 	}
 
-	/* Check tag in "constant-time" */
-	for (diff = 0, i = 0; i < tag_len; i++)
-		diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i];
-
-	if (diff != 0) {
-		rc = CRYPTO_ERR_DECRYPTION;
-		goto exit_gcm;
-	}
-
-	/* GCM decryption success */
-	rc = CRYPTO_SUCCESS;
-
-exit_gcm:
-	mbedtls_gcm_free(&ctx);
-	return rc;
+err:
+	psa_aead_abort(&operation);
+	psa_destroy_key(key_id);
+	return CRYPTO_ERR_DECRYPTION;
 }
 
 /*
diff --git a/drivers/auth/tbbr/tbbr_cot_bl1.c b/drivers/auth/tbbr/tbbr_cot_bl1.c
index 21942b49..8bab6e87 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl1.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl1.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -173,7 +173,6 @@ static const auth_img_desc_t fw_config = {
 static const auth_img_desc_t * const cot_desc[] = {
 	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
 	[BL2_IMAGE_ID]				=	&bl2_image,
-	[HW_CONFIG_ID]				=	&hw_config,
 	[TB_FW_CONFIG_ID]			=	&tb_fw_config,
 	[FW_CONFIG_ID]				=	&fw_config,
 	[FWU_CERT_ID]				=	&fwu_cert,
diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c
index ce2aa7e2..8dccaece 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl2.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -84,6 +84,22 @@ static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
 #endif /* SPD_spmd */
 
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
+			}
+		}
+	}
+};
+
 /*
  * Trusted key certificate
  */
diff --git a/drivers/auth/tbbr/tbbr_cot_common.c b/drivers/auth/tbbr/tbbr_cot_common.c
index 8c372488..619b241c 100644
--- a/drivers/auth/tbbr/tbbr_cot_common.c
+++ b/drivers/auth/tbbr/tbbr_cot_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,7 +52,7 @@ auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
 	AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
 auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
 	AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
-static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
+auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
 	AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
 
 /* trusted_boot_fw_cert */
@@ -109,19 +109,3 @@ const auth_img_desc_t trusted_boot_fw_cert = {
 		}
 	}
 };
-
-/* HW Config */
-const auth_img_desc_t hw_config = {
-	.img_id = HW_CONFIG_ID,
-	.img_type = IMG_RAW,
-	.parent = &trusted_boot_fw_cert,
-	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
-		[0] = {
-			.type = AUTH_METHOD_HASH,
-			.param.hash = {
-				.data = &raw_data,
-				.hash = &hw_config_hash
-			}
-		}
-	}
-};
diff --git a/drivers/cadence/emmc/cdns_sdmmc.c b/drivers/cadence/emmc/cdns_sdmmc.c
index d2cd4d6a..892d3330 100644
--- a/drivers/cadence/emmc/cdns_sdmmc.c
+++ b/drivers/cadence/emmc/cdns_sdmmc.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,35 +19,6 @@
 #include <lib/mmio.h>
 #include <lib/utils.h>
 
-/* Card busy and present */
-#define CARD_BUSY					1
-#define CARD_NOT_BUSY					0
-
-/* 500 ms delay to read the RINST register */
-#define DELAY_MS_SRS_READ				500
-#define DELAY_RES					10
-
-/* SRS12 error mask */
-#define SRS12_ERR_MASK					0xFFFF8000
-
-/* Check DV dfi_init val=0 */
-#define IO_MASK_END_DATA				0x0
-
-/* Check DV dfi_init val=2; DDR Mode */
-#define IO_MASK_END_DATA_DDR				0x2
-#define IO_MASK_START_DATA				0x0
-#define DATA_SELECT_OE_END_DATA				0x1
-
-#define TIMEOUT						100000
-
-/* General define */
-#define SDHC_REG_MASK					UINT_MAX
-#define SD_HOST_BLOCK_SIZE				0x200
-#define DTCVVAL_DEFAULT_VAL				0xE
-#define CDMMC_DMA_MAX_BUFFER_SIZE			64*1024
-#define CDNSMMC_ADDRESS_MASK				U(0x0f)
-#define CONFIG_CDNS_DESC_COUNT				8
-
 void cdns_init(void);
 int cdns_send_cmd(struct mmc_cmd *cmd);
 int cdns_set_ios(unsigned int clk, unsigned int width);
@@ -62,7 +34,8 @@ const struct mmc_ops cdns_sdmmc_ops = {
 	.read			= cdns_read,
 	.write			= cdns_write,
 };
-
+void sd_host_adma_prepare(struct cdns_idmac_desc *desc_ptr, uintptr_t buf,
+			  size_t size);
 struct cdns_sdmmc_params cdns_params;
 struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
 struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
@@ -92,42 +65,19 @@ int cdns_wait_ics(uint16_t timeout, uint32_t cdn_srs_res)
 	return 0;
 }
 
-int cdns_busy(void)
-{
-	unsigned int data;
-
-	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS09);
-	return (data & STATUS_DATA_BUSY) ? CARD_BUSY : CARD_NOT_BUSY;
-}
-
-int cdns_vol_reset(void)
-{
-	/* Reset embedded card */
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
-	udelay(250);
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
-	udelay(500);
-
-	/* Turn on supply voltage */
-	/* BVS = 7, BP = 1, BP2 only in UHS2 mode */
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
-	udelay(250);
-	return 0;
-}
-
 void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
-	struct cdns_sdmmc_sdhc *sdhc_reg)
+			struct cdns_sdmmc_sdhc *sdhc_reg)
 {
 	/* Values are taken by the reference of cadence IP documents */
 	combo_phy_reg->cp_clk_wr_delay = 0;
 	combo_phy_reg->cp_clk_wrdqs_delay = 0;
-	combo_phy_reg->cp_data_select_oe_end = 0;
+	combo_phy_reg->cp_data_select_oe_end = 1;
 	combo_phy_reg->cp_dll_bypass_mode = 1;
 	combo_phy_reg->cp_dll_locked_mode = 0;
-	combo_phy_reg->cp_dll_start_point = 0;
+	combo_phy_reg->cp_dll_start_point = 254;
 	combo_phy_reg->cp_gate_cfg_always_on = 1;
 	combo_phy_reg->cp_io_mask_always_on = 0;
-	combo_phy_reg->cp_io_mask_end = 0;
+	combo_phy_reg->cp_io_mask_end = 5;
 	combo_phy_reg->cp_io_mask_start = 0;
 	combo_phy_reg->cp_rd_del_sel = 52;
 	combo_phy_reg->cp_read_dqs_cmd_delay = 0;
@@ -142,38 +92,58 @@ void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
 
 	sdhc_reg->sdhc_extended_rd_mode = 1;
 	sdhc_reg->sdhc_extended_wr_mode = 1;
-	sdhc_reg->sdhc_hcsdclkadj = 0;
+	sdhc_reg->sdhc_hcsdclkadj = 3;
 	sdhc_reg->sdhc_idelay_val = 0;
 	sdhc_reg->sdhc_rdcmd_en = 1;
 	sdhc_reg->sdhc_rddata_en = 1;
-	sdhc_reg->sdhc_rw_compensate = 9;
+	sdhc_reg->sdhc_rw_compensate = 10;
 	sdhc_reg->sdhc_sdcfsh = 0;
-	sdhc_reg->sdhc_sdcfsl = 1;
+	sdhc_reg->sdhc_sdcfsl = 0;
 	sdhc_reg->sdhc_wrcmd0_dly = 1;
 	sdhc_reg->sdhc_wrcmd0_sdclk_dly = 0;
 	sdhc_reg->sdhc_wrcmd1_dly = 0;
 	sdhc_reg->sdhc_wrcmd1_sdclk_dly = 0;
-	sdhc_reg->sdhc_wrdata0_dly = 1;
+	sdhc_reg->sdhc_wrdata0_dly = 0;
 	sdhc_reg->sdhc_wrdata0_sdclk_dly = 0;
 	sdhc_reg->sdhc_wrdata1_dly = 0;
 	sdhc_reg->sdhc_wrdata1_sdclk_dly = 0;
 }
 
-static int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
-	struct cdns_sdmmc_sdhc *sdhc_reg)
+int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+				struct cdns_sdmmc_sdhc *sdhc_reg)
 {
 	uint32_t value = 0;
 	int ret = 0;
+	uint32_t timeout = 0;
+
+	/* HRS00 - Software Reset */
+	mmio_write_32((cdns_params.reg_base + SDHC_CDNS_HRS00), SDHC_CDNS_HRS00_SWR);
+
+	/* Waiting for SDHC_CDNS_HRS00_SWR reset */
+	timeout = TIMEOUT;
+	do {
+		udelay(250);
+		if (--timeout <= 0) {
+			NOTICE(" SDHC Software Reset failed!!!\n");
+			panic();
+		}
+	} while (((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS00) &
+		SDHC_CDNS_HRS00_SWR) == 1));
+
+	/* Step 1, switch on DLL_RESET */
+	value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
+	value &= ~SDHC_PHY_SW_RESET;
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value);
 
 	/* program PHY_DQS_TIMING_REG */
 	value = (CP_USE_EXT_LPBK_DQS(combo_phy_reg->cp_use_ext_lpbk_dqs)) |
 		(CP_USE_LPBK_DQS(combo_phy_reg->cp_use_lpbk_dqs)) |
 		(CP_USE_PHONY_DQS(combo_phy_reg->cp_use_phony_dqs)) |
 		(CP_USE_PHONY_DQS_CMD(combo_phy_reg->cp_use_phony_dqs_cmd));
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_DQS_TIMING_REG, MMC_REG_BASE +
-			SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+					COMBO_PHY_REG + PHY_DQS_TIMING_REG,
+					cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
 		return ret;
 	}
 
@@ -183,73 +153,90 @@ static int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
 		(CP_RD_DEL_SEL(combo_phy_reg->cp_rd_del_sel)) |
 		(CP_UNDERRUN_SUPPRESS(combo_phy_reg->cp_underrun_suppress)) |
 		(CP_GATE_CFG_ALWAYS_ON(combo_phy_reg->cp_gate_cfg_always_on));
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG, MMC_REG_BASE +
-			SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
-		return ret;
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+				 COMBO_PHY_REG + PHY_GATE_LPBK_CTRL_REG,
+				 cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
+		return -ret;
 	}
 
 	/* program PHY_DLL_MASTER_CTRL_REG */
-	value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode))
-			| (CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point));
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG, MMC_REG_BASE
-			+ SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
+	value = (CP_DLL_BYPASS_MODE(combo_phy_reg->cp_dll_bypass_mode)) | (2 << 20) |
+		(CP_DLL_START_POINT(combo_phy_reg->cp_dll_start_point));
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+					COMBO_PHY_REG + PHY_DLL_MASTER_CTRL_REG,
+					cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
 		return ret;
 	}
 
 	/* program PHY_DLL_SLAVE_CTRL_REG */
-	value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay))
-		| (CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay))
-		| (CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay))
-		| (CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay));
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG, MMC_REG_BASE
-			+ SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
+	value = (CP_READ_DQS_CMD_DELAY(combo_phy_reg->cp_read_dqs_cmd_delay)) |
+		(CP_CLK_WRDQS_DELAY(combo_phy_reg->cp_clk_wrdqs_delay)) |
+		(CP_CLK_WR_DELAY(combo_phy_reg->cp_clk_wr_delay)) |
+		(CP_READ_DQS_DELAY(combo_phy_reg->cp_read_dqs_delay));
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+					COMBO_PHY_REG + PHY_DLL_SLAVE_CTRL_REG,
+					cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
 		return ret;
 	}
 
 	/* program PHY_CTRL_REG */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS04, COMBO_PHY_REG
-			+ PHY_CTRL_REG);
-	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS05);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS04, COMBO_PHY_REG + PHY_CTRL_REG);
+	value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS05);
 
 	/* phony_dqs_timing=0 */
 	value &= ~(CP_PHONY_DQS_TIMING_MASK << CP_PHONY_DQS_TIMING_SHIFT);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS05, value);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS05, value);
 
 	/* switch off DLL_RESET */
 	do {
-		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+		value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
 		value |= SDHC_PHY_SW_RESET;
-		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
-		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value);
+		value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
 	/* polling PHY_INIT_COMPLETE */
 	} while ((value & SDHC_PHY_INIT_COMPLETE) != SDHC_PHY_INIT_COMPLETE);
 
 	/* program PHY_DQ_TIMING_REG */
-	combo_phy_reg->cp_io_mask_end = 0U;
-	value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on))
-		| (CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end))
-		| (CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start))
-		| (CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end));
-
-	ret = cdns_sdmmc_write_phy_reg(MMC_REG_BASE + SDHC_CDNS_HRS04,
-			COMBO_PHY_REG + PHY_DQ_TIMING_REG, MMC_REG_BASE
-			+ SDHC_CDNS_HRS05, value);
-	if (ret != 0) {
+	value = (CP_IO_MASK_ALWAYS_ON(combo_phy_reg->cp_io_mask_always_on)) |
+		(CP_IO_MASK_END(combo_phy_reg->cp_io_mask_end)) |
+		(CP_IO_MASK_START(combo_phy_reg->cp_io_mask_start)) |
+		(CP_DATA_SELECT_OE_END(combo_phy_reg->cp_data_select_oe_end));
+
+	ret = cdns_sdmmc_write_phy_reg(cdns_params.reg_base + SDHC_CDNS_HRS04,
+				 COMBO_PHY_REG + PHY_DQ_TIMING_REG,
+				 cdns_params.reg_base + SDHC_CDNS_HRS05, value);
+	if (ret != 0U) {
 		return ret;
 	}
+
+	value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
+	value |= (HRS_09_EXTENDED_RD_MODE | HRS_09_EXTENDED_WR_MODE |
+		HRS_09_RDCMD_EN | HRS_09_RDDATA_EN);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09, value);
+
+	value = 0;
+	value = SDHC_HCSDCLKADJ(HRS_10_HCSDCLKADJ_VAL);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS10, value);
+
+	value = 0;
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS16, value);
+
+	value = (10 << 16);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS07, value);
+
 	return 0;
 }
 
 int cdns_read(int lba, uintptr_t buf, size_t size)
 {
-	inv_dcache_range(buf, size);
+	return 0;
+}
 
+int cdns_write(int lba, uintptr_t buf, size_t size)
+{
 	return 0;
 }
 
@@ -260,120 +247,79 @@ void cdns_init(void)
 
 int cdns_prepare(int dma_start_addr, uintptr_t dma_buff, size_t size)
 {
-	data_cmd = true;
-	struct cdns_idmac_desc *desc;
-	uint32_t desc_cnt, i;
-	uint64_t desc_base;
-
+	struct cdns_idmac_desc *cdns_desc_data;
 	assert(((dma_buff & CDNSMMC_ADDRESS_MASK) == 0) &&
-			(cdns_params.desc_size > 0) &&
-			((MMC_REG_BASE & MMC_BLOCK_MASK) == 0) &&
-			((cdns_params.desc_base & MMC_BLOCK_MASK) == 0) &&
-			((cdns_params.desc_size & MMC_BLOCK_MASK) == 0));
-
-	flush_dcache_range(dma_buff, size);
-
-	desc_cnt = (size + (CDMMC_DMA_MAX_BUFFER_SIZE) - 1) / (CDMMC_DMA_MAX_BUFFER_SIZE);
-	assert(desc_cnt * sizeof(struct cdns_idmac_desc) < cdns_params.desc_size);
+	 (cdns_params.desc_size > 0));
 
-	if (desc_cnt > CONFIG_CDNS_DESC_COUNT) {
-		ERROR("Requested data transfer length %ld is greater than configured length %d",
-				size, (CONFIG_CDNS_DESC_COUNT * CDMMC_DMA_MAX_BUFFER_SIZE));
-		return -EINVAL;
-	}
-
-	desc = (struct cdns_idmac_desc *)cdns_params.desc_base;
-	desc_base = (uint64_t)desc;
-	i = 0;
-
-	while ((i + 1) < desc_cnt) {
-		desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;
-		desc->reserved = 0;
-		desc->len = MAX_64KB_PAGE;
-		desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
-#if CONFIG_DMA_ADDR_T_64BIT == 1
-		desc->addr_hi = (dma_buff >> 32) & 0xffffffff;
-#endif
-		size -= CDMMC_DMA_MAX_BUFFER_SIZE;
-		desc++;
-		i++;
-	}
+	cdns_desc_data = (struct cdns_idmac_desc *)cdns_params.desc_base;
+	sd_host_adma_prepare(cdns_desc_data, dma_buff, size);
 
-	desc->attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA |
-			ADMA_DESC_ATTR_END;
-	desc->reserved = 0;
-	desc->len = size;
-#if CONFIG_DMA_ADDR_T_64BIT == 1
-	desc->addr_lo = (dma_buff & UINT_MAX) + (CDMMC_DMA_MAX_BUFFER_SIZE * i);
-	desc->addr_hi = (dma_buff >> 32) & UINT_MAX;
-#else
-	desc->addr_lo = (dma_buff & UINT_MAX);
-#endif
-
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS22, (uint32_t)desc_base);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS23, (uint32_t)(desc_base >> 32));
-	flush_dcache_range(cdns_params.desc_base,
-				desc_cnt * CDMMC_DMA_MAX_BUFFER_SIZE);
-
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS01,
-			((512 << BLOCK_SIZE) | ((size/512) << BLK_COUNT_CT) | SDMA_BUF));
 	return 0;
 }
 
-static void cdns_host_set_clk(int clk)
+void cdns_host_set_clk(uint32_t clk)
 {
 	uint32_t ret = 0;
 	uint32_t sdclkfsval = 0;
-	uint32_t dtcvval = DTCVVAL_DEFAULT_VAL;
+	uint32_t dtcvval = 0xE;
 
-	sdclkfsval = (cdns_params.clk_rate / 2000) / clk;
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
-			(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
+	sdclkfsval = (SD_HOST_CLK / 2) / clk;
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, 0);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11,
+			(dtcvval << SDMMC_CDN_DTCV) | (sdclkfsval << SDMMC_CDN_SDCLKFS) |
+			(1 << SDMMC_CDN_ICE));
 
-	ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
-	if (ret != 0U) {
-		ERROR("Waiting SDMMC_CDN_ICS timeout");
+	ret = cdns_wait_ics(5000, cdns_params.reg_base + SDHC_CDNS_SRS11);
+	if (ret != 0) {
+		ERROR("Waiting ICS timeout");
 	}
-
 	/* Enable DLL reset */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &
-			~SDHC_DLL_RESET_MASK);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+		mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) & ~0x00000001);
 	/* Set extended_wr_mode */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, (mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09)
-			& SDHC_EXTENDED_WR_MODE_MASK) | (1 << EXTENDED_WR_MODE));
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+		(mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) & 0xFFFFFFF7) |
+			(1 << EXTENDED_WR_MODE));
 	/* Release DLL reset */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) | 1);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+		mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) | PHY_SW_RESET_EN);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_HRS09,
+		mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) | RDCMD_EN);
 
 	do {
-		mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
-	} while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
-
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
-	(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
+		mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09);
+	} while (~mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS09) &
+		(PHY_INIT_COMPLETE_BIT));
+
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
+			(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) |
+			(1 << SDMMC_CDN_SDCE));
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS13, 0xFFFFFFFF);
 }
 
 int cdns_set_ios(unsigned int clk, unsigned int width)
 {
+	uint32_t _status = 0;
 
+	_status = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
 	switch (width) {
 	case MMC_BUS_WIDTH_1:
-		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), LEDC_OFF);
+		_status &= ~(BIT4);
 		break;
+
 	case MMC_BUS_WIDTH_4:
-		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), DTW_4BIT);
+		_status |= BIT4;
 		break;
+
 	case MMC_BUS_WIDTH_8:
-		mmio_write_32((MMC_REG_BASE + SDHC_CDNS_SRS10), EDTW_8BIT);
+		_status |= BIT8;
 		break;
+
 	default:
 		assert(0);
 		break;
 	}
+	mmio_write_32((cdns_params.reg_base + SDHC_CDNS_SRS10), _status);
 	cdns_host_set_clk(clk);
 
 	return 0;
@@ -388,6 +334,7 @@ int cdns_sdmmc_write_sd_host_reg(uint32_t addr, uint32_t data)
 	value |= data;
 	mmio_write_32(addr, value);
 	value = mmio_read_32(addr);
+
 	if (value != data) {
 		ERROR("SD host address is not set properly\n");
 		return -ENXIO;
@@ -396,429 +343,403 @@ int cdns_sdmmc_write_sd_host_reg(uint32_t addr, uint32_t data)
 	return 0;
 }
 
-int cdns_write(int lba, uintptr_t buf, size_t size)
-{
-	return 0;
-}
 
-static int cdns_init_hrs_io(struct cdns_sdmmc_combo_phy *combo_phy_reg,
-	struct cdns_sdmmc_sdhc *sdhc_reg)
+
+void sd_host_oper_mode(enum sd_opr_modes opr_mode)
 {
-	uint32_t value = 0;
-	int ret = 0;
 
-	/* program HRS09, register 42 */
-	value = (SDHC_RDDATA_EN(sdhc_reg->sdhc_rddata_en))
-		| (SDHC_RDCMD_EN(sdhc_reg->sdhc_rdcmd_en))
-		| (SDHC_EXTENDED_WR_MODE(sdhc_reg->sdhc_extended_wr_mode))
-		| (SDHC_EXTENDED_RD_MODE(sdhc_reg->sdhc_extended_rd_mode));
-	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
-	if (ret != 0) {
-		ERROR("Program HRS09 failed");
-		return ret;
-	}
+	uint32_t reg = 0;
 
-	/* program HRS10, register 43 */
-	value = (SDHC_HCSDCLKADJ(sdhc_reg->sdhc_hcsdclkadj));
-	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS10, value);
-	if (ret != 0) {
-		ERROR("Program HRS10 failed");
-		return ret;
-	}
+	switch (opr_mode) {
+	case SD_HOST_OPR_MODE_HV4E_0_SDMA_32:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
 
-	/* program HRS16, register 48 */
-	value = (SDHC_WRDATA1_SDCLK_DLY(sdhc_reg->sdhc_wrdata1_sdclk_dly))
-		| (SDHC_WRDATA0_SDCLK_DLY(sdhc_reg->sdhc_wrdata0_sdclk_dly))
-		| (SDHC_WRCMD1_SDCLK_DLY(sdhc_reg->sdhc_wrcmd1_sdclk_dly))
-		| (SDHC_WRCMD0_SDCLK_DLY(sdhc_reg->sdhc_wrcmd0_sdclk_dly))
-		| (SDHC_WRDATA1_DLY(sdhc_reg->sdhc_wrdata1_dly))
-		| (SDHC_WRDATA0_DLY(sdhc_reg->sdhc_wrdata0_dly))
-		| (SDHC_WRCMD1_DLY(sdhc_reg->sdhc_wrcmd1_dly))
-		| (SDHC_WRCMD0_DLY(sdhc_reg->sdhc_wrcmd0_dly));
-	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS16, value);
-	if (ret != 0) {
-		ERROR("Program HRS16 failed");
-		return ret;
-	}
+	case SD_HOST_OPR_MODE_HV4E_1_SDMA_32:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		reg |= (HV4E);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
 
-	/* program HRS07, register 40 */
-	value = (SDHC_RW_COMPENSATE(sdhc_reg->sdhc_rw_compensate))
-		| (SDHC_IDELAY_VAL(sdhc_reg->sdhc_idelay_val));
-	ret = cdns_sdmmc_write_sd_host_reg(MMC_REG_BASE + SDHC_CDNS_HRS07, value);
-	if (ret != 0) {
-		ERROR("Program HRS07 failed");
-		return ret;
-	}
+	case SD_HOST_OPR_MODE_HV4E_1_SDMA_64:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg |= (HV4E | BIT_AD_64);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+
+	case SD_HOST_OPR_MODE_HV4E_0_ADMA_32:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		reg |= DMA_SEL_BIT_2;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
 
-	return ret;
+	case SD_HOST_OPR_MODE_HV4E_0_ADMA_64:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		reg |= DMA_SEL_BIT_3;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		reg |= BIT_AD_64;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+
+	case SD_HOST_OPR_MODE_HV4E_1_ADMA_32:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		reg |= DMA_SEL_BIT_2;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg &= ~(HV4E | BIT_AD_64);
+		reg |= HV4E;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+
+	case SD_HOST_OPR_MODE_HV4E_1_ADMA_64:
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+		reg &= ~(DMA_SEL_BIT);
+		reg |= DMA_SEL_BIT_2;
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg);
+		reg = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS15);
+		reg |= (HV4E | BIT_AD_64);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS15, reg);
+		break;
+	}
 }
 
-static int cdns_hc_set_clk(struct cdns_sdmmc_params *cdn_sdmmc_dev_mode_params)
+void card_reset(bool power_enable)
 {
-	uint32_t ret = 0;
-	uint32_t dtcvval, sdclkfsval;
-
-	dtcvval = DTC_VAL;
-	sdclkfsval = 0;
-
-	if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_DS) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR12) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR_BC)) {
-		sdclkfsval = 4;
-	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_HS) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR25) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_DDR50) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_SDR)) {
-		sdclkfsval = 2;
-	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR50) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_DDR) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS400es)) {
-		sdclkfsval = 1;
-	} else if ((cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == SD_UHS_SDR104) ||
-		(cdn_sdmmc_dev_mode_params->cdn_sdmmc_dev_mode == EMMC_HS200)) {
-		sdclkfsval = 0;
-	}
+	uint32_t reg_value = 0;
 
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, 0);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
-		(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE));
-	ret = cdns_wait_ics(5000, MMC_REG_BASE + SDHC_CDNS_SRS11);
-	if (ret != 0U) {
-		ERROR("Waiting SDMMC_CDN_ICS timeout");
-		return ret;
+	/* Reading SRS10 value before writing */
+	reg_value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
+
+	if (power_enable == true) {
+		reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+		reg_value = ((1 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
+	} else {
+		reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP));
 	}
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value);
+}
 
-	/* Enable DLL reset */
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09), mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) & ~SDHC_DLL_RESET_MASK);
-	/* Set extended_wr_mode */
-	mmio_write_32((MMC_REG_BASE + SDHC_CDNS_HRS09),
-	(mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) &	SDHC_EXTENDED_WR_MODE_MASK) |
-			(1 << EXTENDED_WR_MODE));
-	/* Release DLL reset */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) | 1);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, mmio_read_32(MMC_REG_BASE
-			+ SDHC_CDNS_HRS09) | (3 << RDCMD_EN));
-	do {
-		mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
-	} while (~mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09) & (1 << 1));
+void high_speed_enable(bool mode)
+{
 
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (dtcvval << SDMMC_CDN_DTCV) |
-		(sdclkfsval << SDMMC_CDN_SDCLKFS) | (1 << SDMMC_CDN_ICE) | (1 << SDMMC_CDN_SDCE));
+	uint32_t reg_value = 0;
+	/* Reading SRS10 value before writing */
+	reg_value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10);
 
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS13, UINT_MAX);
-	return 0;
+	if (mode == true) {
+		reg_value |= HS_EN;
+	} else {
+		reg_value &= ~HS_EN;
+	}
+
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value);
 }
 
 int cdns_reset(void)
 {
-	uint32_t data = 0;
+	volatile uint32_t data = 0;
 	uint32_t count = 0;
-	uint32_t value = 0;
-
-	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
-	value &= ~(0xFFFF);
-	value |= 0x0;
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, value);
-	udelay(500);
 
 	/* Software reset */
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS00, 1);
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, SRS11_SRFA);
 	/* Wait status command response ready */
 	do {
-		data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS00);
+		data = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_HRS00);
 		count++;
-		if (count >= 5000) {
+		if (count >= CDNS_TIMEOUT) {
 			return -ETIMEDOUT;
 		}
-	/* Wait for HRS00.SWR */
-	} while ((data & 1) == 1);
-
-	/* Step 1, switch on DLL_RESET */
-	value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_HRS09);
-	value &= ~SDHC_PHY_SW_RESET;
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_HRS09, value);
+	/* Wait for SRS11 */
+	} while (((SRS11_SRFA_CHK(data)) & 1) == 1);
 
 	return 0;
 }
 
+void sdmmc_host_init(bool uhs2_enable)
+{
+	uint32_t timeout;
+
+	/* SRS11 - Host Control  default value set */
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS11, 0x0);
+
+	/* Waiting for detect card */
+	timeout = TIMEOUT;
+	do {
+		udelay(250);
+		if (--timeout <= 0) {
+			NOTICE(" SDHC Card Detecion failed!!!\n");
+			panic();
+		}
+	} while (((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09) & CHECK_CARD) == 0));
+
+	/* UHS2 Host setting */
+	if (uhs2_enable == true) {
+	/** need to implement*/
+	}
+
+	/* Card reset */
+
+	card_reset(1);
+	udelay(2500);
+	card_reset(0);
+	udelay(2500);
+	card_reset(1);
+	udelay(2500);
+
+	/* Enable Interrupt Flags*/
+	mmio_write_32((cdns_params.reg_base + SDHC_CDNS_SRS13), ~0);
+	high_speed_enable(true);
+}
+
 int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg,
-struct cdns_sdmmc_sdhc *mmc_sdhc_reg)
+		      struct cdns_sdmmc_sdhc *mmc_sdhc_reg)
 {
 	int ret = 0;
 
 	ret = cdns_reset();
-	if (ret != 0) {
+	if (ret != 0U) {
 		ERROR("Program phy reg init failed");
 		return ret;
 	}
 
 	ret = cdns_program_phy_reg(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
-	if (ret != 0) {
+	if (ret != 0U) {
 		ERROR("Program phy reg init failed");
 		return ret;
 	}
+	sdmmc_host_init(0);
+	cdns_host_set_clk(100000);
 
-	ret = cdns_init_hrs_io(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
-	if (ret != 0) {
-		ERROR("Program init for HRS reg is failed");
-		return ret;
-	}
-
-	ret = cdns_sd_card_detect();
-	if (ret != 0) {
-		ERROR("SD card does not detect");
-		return ret;
-	}
-
-	ret = cdns_vol_reset();
-	if (ret != 0) {
-		ERROR("eMMC card reset failed");
-		return ret;
-	}
-
-	ret = cdns_hc_set_clk(&cdns_params);
-	if (ret != 0) {
-		ERROR("hc set clk failed");
-		return ret;
-	}
+	sd_host_oper_mode(SD_HOST_OPR_MODE_HV4E_0_ADMA_64);
 
 	return 0;
 }
 
-void cdns_srs10_value_toggle(uint8_t write_val, uint8_t prev_val)
-{
-	uint32_t data_op = 0U;
-
-	data_op = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, (data_op & (prev_val << 0)));
-	mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS10);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS10, data_op | (write_val << 0));
-}
-
-void cdns_srs11_srs15_config(uint32_t srs11_val, uint32_t srs15_val)
-{
-	uint32_t data = 0U;
-
-	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS11);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS11, (data | srs11_val));
-	data = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS15);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS15, (data | srs15_val));
-}
-
 int cdns_send_cmd(struct mmc_cmd *cmd)
 {
-	uint32_t op = 0, ret = 0;
-	uint8_t write_value = 0, prev_val = 0;
-	uint32_t value;
-	int32_t timeout;
-	uint32_t cmd_indx;
-	uint32_t status = 0, srs15_val = 0, srs11_val = 0;
+	uint32_t cmd_flags = 0;
+	uint32_t timeout = 0;
 	uint32_t status_check = 0;
+	uint32_t mode = 0;
+	uint32_t status;
 
 	assert(cmd);
-	cmd_indx = (cmd->cmd_idx) << COM_IDX;
-
-	if (data_cmd) {
-		switch (cmd->cmd_idx) {
-		case SD_SWITCH:
-			op = DATA_PRESENT;
-			write_value = ADMA2_32 | DT_WIDTH;
-			prev_val = ADMA2_32 | DT_WIDTH;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			srs15_val = BIT_AD_64 | HV4E | V18SE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		case SD_WRITE_SINGLE_BLOCK:
-		case SD_READ_SINGLE_BLOCK:
-			op = DATA_PRESENT;
-			write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
-			prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
-			break;
-
-		case SD_WRITE_MULTIPLE_BLOCK:
-		case SD_READ_MULTIPLE_BLOCK:
-			op = DATA_PRESENT | AUTO_CMD_EN | MULTI_BLK_READ;
-			write_value = ADMA2_32 | HS_EN | DT_WIDTH | LEDC;
-			prev_val = ADMA2_32 | HS_EN | DT_WIDTH;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = PVE | BIT_AD_64 | HV4E | SDR104_MODE | V18SE;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS00, SAAR);
-			break;
-
-		case SD_APP_SEND_SCR:
-			op = DATA_PRESENT;
-			write_value = ADMA2_32 | LEDC;
-			prev_val = LEDC;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = BIT_AD_64 | HV4E | V18SE;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		case SD_SEND_IF_COND:
-			op = DATA_PRESENT | CMD_IDX_CHK_ENABLE;
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = HV4E;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		default:
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			op = 0;
-			break;
-		}
-	} else {
-		switch (cmd->cmd_idx) {
-		case SD_GO_IDLE_STATE:
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = HV4E;
-			srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		case SD_ALL_SEND_CID:
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = HV4E | V18SE;
-			srs11_val = SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		case SD_SEND_IF_COND:
-			op = CMD_IDX_CHK_ENABLE;
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			srs15_val = HV4E;
-			srs11_val = READ_CLK | SDMMC_CDN_ICE | SDMMC_CDN_ICS | SDMMC_CDN_SDCE;
-			cdns_srs11_srs15_config(srs11_val, srs15_val);
-			break;
-
-		case SD_STOP_TRANSMISSION:
-			op = CMD_STOP_ABORT_CMD;
-			break;
-
-		case SD_SEND_STATUS:
-			break;
-
-		case 1:
-			cmd->cmd_arg = 0;
-			break;
-
-		case SD_SELECT_CARD:
-			op = MULTI_BLK_READ;
-			break;
-
-		case SD_APP_CMD:
-		default:
-			write_value = LEDC;
-			prev_val = 0x0;
-			cdns_srs10_value_toggle(write_value, prev_val);
-			op = 0;
-			break;
-		}
-	}
-
-	switch (cmd->resp_type) {
-	case MMC_RESPONSE_NONE:
-		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN;
-		break;
-
-	case MMC_RESPONSE_R2:
-		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
-			RES_TYPE_SEL_136 | CMD_CHECK_RESP_CRC;
-		break;
 
-	case MMC_RESPONSE_R3:
-		op |= CMD_READ | MULTI_BLK_READ | DMA_ENABLED | BLK_CNT_EN |
-			RES_TYPE_SEL_48;
-		break;
+	cmd_flags = CDNS_HOST_CMD_INHIBIT | CDNS_HOST_DATA_INHIBIT;
 
-	case MMC_RESPONSE_R1:
-		if ((cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK) || (cmd->cmd_idx
-			== SD_WRITE_MULTIPLE_BLOCK)) {
-			op |= DMA_ENABLED | BLK_CNT_EN | RES_TYPE_SEL_48
-			| CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
-		} else {
-			op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | RES_TYPE_SEL_48
-			| CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
-		}
-		break;
-
-	default:
-		op |= DMA_ENABLED | BLK_CNT_EN | CMD_READ | MULTI_BLK_READ |
-			RES_TYPE_SEL_48 | CMD_CHECK_RESP_CRC | CMD_IDX_CHK_ENABLE;
-		break;
+	if ((cmd->cmd_idx == SD_STOP_TRANSMISSION) && (!data_cmd)) {
+		cmd_flags &= ~CDNS_HOST_DATA_INHIBIT;
 	}
 
 	timeout = TIMEOUT;
 	do {
 		udelay(100);
-		ret = cdns_busy();
 		if (--timeout <= 0) {
 			udelay(50);
+			NOTICE("Timeout occur data and cmd line %x\n",
+			 mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09));
 			panic();
 		}
-	} while (ret);
+	} while ((mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09) & (cmd_flags)));
+
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, 0xFFFFFFFF);
+	cmd_flags = 0;
+	cmd_flags = (cmd->cmd_idx) << COM_IDX;
+
+	if ((cmd->resp_type & MMC_RSP_136) != 0) {
+		cmd_flags |= RES_TYPE_SEL_136;
+	} else if (((cmd->resp_type & MMC_RSP_48) != 0) &&
+			((cmd->resp_type & MMC_RSP_BUSY) != 0)) {
+		cmd_flags |= RES_TYPE_SEL_48_B;
+	} else if ((cmd->resp_type & MMC_RSP_48) != 0) {
+		cmd_flags |= RES_TYPE_SEL_48;
+	} else {
+		cmd_flags &= ~RES_TYPE_SEL_NO;
+	}
 
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS12, UINT_MAX);
+	if ((cmd->resp_type & MMC_RSP_CRC) != 0) {
+		cmd_flags |= CMD_CHECK_RESP_CRC;
+	}
 
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS02, cmd->cmd_arg);
-	mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS14, 0x00000000);
-	if (cmd_indx == 1)
-		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, SDHC_CDNS_SRS03_VALUE);
-	else
-		mmio_write_32(MMC_REG_BASE + SDHC_CDNS_SRS03, op | cmd_indx);
+	if ((cmd->resp_type & MMC_RSP_CMD_IDX) != 0) {
+		cmd_flags |= CMD_IDX_CHK_ENABLE;
+	}
 
-	timeout = TIMEOUT;
-	do {
-		udelay(500);
-		value = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS12);
-	} while (((value & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0));
+	if ((cmd->cmd_idx == MMC_ACMD(51)) || (cmd->cmd_idx == MMC_CMD(17)) ||
+		(cmd->cmd_idx == MMC_CMD(18)) || (cmd->cmd_idx == MMC_CMD(24)) ||
+		(cmd->cmd_idx == MMC_CMD(25))) {
+		mmio_write_8((cdns_params.reg_base + DTCV_OFFSET), DTCV_VAL);
+		cmd_flags |= DATA_PRESENT;
+		mode |= BLK_CNT_EN;
+
+		mode |= (DMA_ENABLED);
+		if ((cmd->cmd_idx == SD_WRITE_MULTIPLE_BLOCK) ||
+		(cmd->cmd_idx == SD_READ_MULTIPLE_BLOCK)) {
+			mode |= (MULTI_BLK_READ);
+		} else {
+			mode &= ~(MULTI_BLK_READ);
+		}
+		if ((cmd->cmd_idx == SD_WRITE_MULTIPLE_BLOCK) ||
+		(cmd->cmd_idx == SD_WRITE_SINGLE_BLOCK)) {
+			mode &= ~CMD_READ;
+		} else {
+			mode |= CMD_READ;
+		}
+		mmio_write_16(cdns_params.reg_base + SDHC_CDNS_SRS03, mode);
+
+	} else {
+		mmio_write_8((cdns_params.reg_base + DTCV_OFFSET), DTCV_VAL);
+	}
+
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS02, cmd->cmd_arg);
+	mmio_write_16((cdns_params.reg_base + CICE_OFFSET),
+		SDHCI_MAKE_CMD(cmd->cmd_idx, cmd_flags));
 
 	timeout = TIMEOUT;
 
-	if (data_cmd) {
-		data_cmd = false;
-		do {
-			udelay(250);
-		} while (((value & TRAN_COMP) == 0) && (timeout-- > 0));
-	}
+	do {
+		udelay(CDNS_TIMEOUT);
+		status = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12);
+	} while (((status & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0));
 
-	status_check = value & SRS12_ERR_MASK;
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, (SRS_12_CC_EN));
+	status_check = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12) & 0xffff8000;
 	if (status_check != 0U) {
-		ERROR("SD host controller send command failed, SRS12 = %x", status);
+		timeout = TIMEOUT;
+		ERROR("SD host controller send command failed, SRS12 = %x", status_check);
 		return -1;
 	}
 
-	if ((op & RES_TYPE_SEL_48) || (op & RES_TYPE_SEL_136)) {
-		cmd->resp_data[0] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS04);
-		if (op & RES_TYPE_SEL_136) {
-			cmd->resp_data[1] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS05);
-			cmd->resp_data[2] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS06);
-			cmd->resp_data[3] = mmio_read_32(MMC_REG_BASE + SDHC_CDNS_SRS07);
+	if (!((cmd_flags & RES_TYPE_SEL_NO) == 0)) {
+		cmd->resp_data[0] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS04);
+		if ((cmd_flags & RES_TYPE_SEL_NO) == RES_TYPE_SEL_136) {
+			cmd->resp_data[1] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS05);
+			cmd->resp_data[2] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS06);
+			cmd->resp_data[3] = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS07);
+			/* 136-bit: RTS=01b, Response field R[127:8] - RESP3[23:0],
+			 * RESP2[31:0], RESP1[31:0], RESP0[31:0]
+			 * Subsystem expects 128 bits response but cadence SDHC sends
+			 * 120 bits response from R[127:8]. Bits manupulation to address
+			 * the correct responses for the 136 bit response type.
+			 */
+			cmd->resp_data[3] = ((cmd->resp_data[3] << 8) |
+						((cmd->resp_data[2] >> 24) &
+						CDNS_CSD_BYTE_MASK));
+			cmd->resp_data[2] = ((cmd->resp_data[2] << 8) |
+						((cmd->resp_data[1] >> 24) &
+						CDNS_CSD_BYTE_MASK));
+			cmd->resp_data[1] = ((cmd->resp_data[1] << 8) |
+						((cmd->resp_data[0] >> 24) &
+						CDNS_CSD_BYTE_MASK));
+			cmd->resp_data[0] = (cmd->resp_data[0] << 8);
 		}
 	}
 
+	mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, (SRS_12_CC_EN));
+
 	return 0;
 }
+
+void sd_host_adma_prepare(struct cdns_idmac_desc *desc_ptr, uint64_t buf,
+			  size_t size)
+{
+	uint32_t full_desc_cnt = 0;
+	uint32_t non_full_desc_cnt = 0;
+	uint64_t desc_address;
+	uint32_t block_count;
+	uint32_t transfer_block_size;
+
+	full_desc_cnt = (size / PAGE_BUFFER_LEN);
+	non_full_desc_cnt = (size % PAGE_BUFFER_LEN);
+	for (int i = 0; i < full_desc_cnt; i++) {
+		desc_ptr->attr = (ADMA_DESC_TRANSFER_DATA | ADMA_DESC_ATTR_VALID);
+		desc_ptr->len = 0; // 0 means 64kb page size it will take
+		desc_ptr->addr_lo = 0;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+		desc_ptr->addr_hi = (uint32_t)((buf >> 32) & 0xffffffff);
+#endif
+		if (non_full_desc_cnt == 0) {
+			desc_ptr->attr |= (ADMA_DESC_ATTR_END);
+		}
+	buf += PAGE_BUFFER_LEN;
+	}
+
+	if (non_full_desc_cnt != 0) {
+		desc_ptr->attr =
+		(ADMA_DESC_TRANSFER_DATA | ADMA_DESC_ATTR_END | ADMA_DESC_ATTR_VALID);
+		desc_ptr->addr_lo = buf & 0xffffffff;
+		desc_ptr->len = size;
+#if CONFIG_DMA_ADDR_T_64BIT == 1
+		desc_ptr->addr_hi = (uint32_t)((buf >> 32) & 0xffffffff);
+#endif
+		desc_address = (uint64_t)desc_ptr;
+		if (size > MMC_MAX_BLOCK_LEN) {
+			transfer_block_size = MMC_MAX_BLOCK_LEN;
+		} else {
+			transfer_block_size = size;
+		}
+
+		block_count = (size / transfer_block_size);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS01,
+				((transfer_block_size << BLOCK_SIZE) | SDMA_BUF |
+				(block_count << BLK_COUNT_CT)));
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS22,
+				(uint32_t)desc_address & 0xFFFFFFFF);
+		mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS23,
+				(uint32_t)(desc_address >> 32 & 0xFFFFFFFF));
+	}
+}
+
+int cdns_mmc_init(struct cdns_sdmmc_params *params,
+		  struct mmc_device_info *info)
+{
+
+	int result = 0;
+
+	assert((params != NULL) &&
+		((params->reg_base & MMC_BLOCK_MASK) == 0) &&
+		((params->desc_size & MMC_BLOCK_MASK) == 0) &&
+		((params->reg_pinmux & MMC_BLOCK_MASK) == 0) &&
+		((params->reg_phy & MMC_BLOCK_MASK) == 0) &&
+		(params->desc_size > 0) &&
+		(params->clk_rate > 0) &&
+		((params->bus_width == MMC_BUS_WIDTH_1) ||
+		(params->bus_width == MMC_BUS_WIDTH_4) ||
+		(params->bus_width == MMC_BUS_WIDTH_8)));
+
+	memcpy(&cdns_params, params, sizeof(struct cdns_sdmmc_params));
+
+	cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
+	if (result < 0) {
+		return result;
+	}
+
+	cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
+	cdns_params.cdn_sdmmc_dev_mode = SD_DS;
+
+	result = mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width,
+			params->flags, info);
+
+	return result;
+}
diff --git a/drivers/cadence/nand/cdns_nand.c b/drivers/cadence/nand/cdns_nand.c
index 5a662626..20147d07 100644
--- a/drivers/cadence/nand/cdns_nand.c
+++ b/drivers/cadence/nand/cdns_nand.c
@@ -20,8 +20,12 @@
 /* NAND flash device information struct */
 static cnf_dev_info_t dev_info;
 
-/* Scratch buffers for read and write operations */
-static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+/*
+ * Scratch buffers for read and write operations
+ * DMA transfer of Cadence NAND expects data 8 bytes aligned
+ * to be written to register
+ */
+static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE] __aligned(8);
 
 /* Wait for controller to be in idle state */
 static inline void cdns_nand_wait_idle(void)
@@ -111,7 +115,8 @@ int cdns_nand_reset(uint8_t thread_id)
 	cdns_nand_wait_thread_ready(thread_id);
 
 	/* Select memory */
-	mmio_write_32(CNF_CMDREG(CMD_REG4), (CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+	mmio_write_32(CNF_CMDREG(CMD_REG4),
+			(CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
 
 	/* Issue reset command */
 	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
@@ -150,21 +155,19 @@ static void cdns_nand_set_opr_mode(uint8_t opr_mode)
 
 		/* Async mode timing settings */
 		mmio_write_32(CNF_MINICTRL(ASYNC_TOGGLE_TIMINGS),
-								(2 << CNF_ASYNC_TIMINGS_TRH) |
-								(4 << CNF_ASYNC_TIMINGS_TRP) |
-								(2 << CNF_ASYNC_TIMINGS_TWH) |
-								(4 << CNF_ASYNC_TIMINGS_TWP));
+				(2 << CNF_ASYNC_TIMINGS_TRH) |
+				(4 << CNF_ASYNC_TIMINGS_TRP) |
+				(2 << CNF_ASYNC_TIMINGS_TWH) |
+				(4 << CNF_ASYNC_TIMINGS_TWP));
 
 		/* Set extended read and write mode */
 		reg |= (1 << CNF_DLL_PHY_EXT_RD_MODE);
 		reg |= (1 << CNF_DLL_PHY_EXT_WR_MODE);
 
 		/* Set operation work mode in common settings */
-		uint32_t data = mmio_read_32(CNF_MINICTRL(CMN_SETTINGS));
-
-		data |= (CNF_OPR_WORK_MODE_SDR << CNF_CMN_SETTINGS_OPR);
-		mmio_write_32(CNF_MINICTRL(CMN_SETTINGS), data);
-
+		mmio_clrsetbits_32(CNF_MINICTRL(CMN_SETTINGS),
+				CNF_CMN_SETTINGS_OPR_MASK,
+				CNF_OPR_WORK_MODE_SDR);
 	} else if (opr_mode == CNF_OPR_WORK_MODE_NVDDR) {
 		; /* ToDo: add DDR mode settings also once available on SIMICS */
 	} else {
@@ -189,13 +192,13 @@ static void cdns_nand_transfer_config(void)
 
 	/* DMA burst select */
 	mmio_write_32(CNF_CTRLCFG(DMA_SETTINGS),
-					(CNF_DMA_BURST_SIZE_MAX << CNF_DMA_SETTINGS_BURST) |
-					(1 << CNF_DMA_SETTINGS_OTE));
+			(CNF_DMA_BURST_SIZE_MAX << CNF_DMA_SETTINGS_BURST) |
+			(1 << CNF_DMA_SETTINGS_OTE));
 
 	/* Enable pre-fetching for 1K */
 	mmio_write_32(CNF_CTRLCFG(FIFO_TLEVEL),
-					(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_POS) |
-					(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_DMA_SIZE));
+			(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_POS) |
+			(CNF_DMA_PREFETCH_SIZE << CNF_FIFO_TLEVEL_DMA_SIZE));
 
 	/* Select access type */
 	mmio_write_32(CNF_CTRLCFG(MULTIPLANE_CFG), 0);
@@ -235,12 +238,13 @@ static int cdns_nand_update_dev_info(void)
 
 	/* Calculate block size and total device size */
 	dev_info.block_size = (dev_info.npages_per_block * dev_info.page_size);
-	dev_info.total_size = (dev_info.block_size * dev_info.nblocks_per_lun *
-							dev_info.nluns);
+	dev_info.total_size = ((unsigned long long)dev_info.block_size *
+				(unsigned long long)dev_info.nblocks_per_lun *
+				dev_info.nluns);
 
-	VERBOSE("CNF params: page %d, spare %d, block %d, total %lld\n",
-				dev_info.page_size, dev_info.spare_size,
-				dev_info.block_size, dev_info.total_size);
+	VERBOSE("CNF params: page_size %d, spare_size %d, block_size %u, total_size %llu\n",
+		dev_info.page_size, dev_info.spare_size,
+		dev_info.block_size, dev_info.total_size);
 
 	return 0;
 }
@@ -323,25 +327,44 @@ int cdns_nand_init_mtd(unsigned long long *size, unsigned int *erase_size)
 	return 0;
 }
 
+static uint32_t cdns_nand_get_row_address(uint32_t page, uint32_t block)
+{
+	uint32_t row_address = 0U;
+	uint32_t req_bits = 0U;
+
+	/* The device info is not populated yet. */
+	if (dev_info.npages_per_block == 0U)
+		return 0;
+
+	for (uint32_t i = 0U; i < sizeof(uint32_t) * 8; i++) {
+		if ((1U << i) & dev_info.npages_per_block)
+			req_bits = i;
+	}
+
+	row_address = ((page & GENMASK_32((req_bits - 1), 0)) |
+			(block << req_bits));
+
+	return row_address;
+}
+
 /* NAND Flash page read */
 static int cdns_nand_read_page(uint32_t block, uint32_t page, uintptr_t buffer)
 {
+
 	/* Wait for thread to be ready */
 	cdns_nand_wait_thread_ready(CNF_DEF_TRD);
 
 	/* Select device */
 	mmio_write_32(CNF_CMDREG(CMD_REG4),
-					(CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
+			(CNF_DEF_DEVICE << CNF_CMDREG4_MEM));
 
 	/* Set host memory address for DMA transfers */
-	mmio_write_32(CNF_CMDREG(CMD_REG2), (buffer & 0xFFFF));
-	mmio_write_32(CNF_CMDREG(CMD_REG3), ((buffer >> 32) & 0xFFFF));
+	mmio_write_32(CNF_CMDREG(CMD_REG2), (buffer & UINT32_MAX));
+	mmio_write_32(CNF_CMDREG(CMD_REG3), ((buffer >> 32) & UINT32_MAX));
 
 	/* Set row address */
-	uint32_t row_address = 0U;
-
-	row_address |= ((page & 0x3F) | (block << 6));
-	mmio_write_32(CNF_CMDREG(CMD_REG1), row_address);
+	mmio_write_32(CNF_CMDREG(CMD_REG1),
+			cdns_nand_get_row_address(page, block));
 
 	/* Page read command */
 	uint32_t reg = (CNF_WORK_MODE_PIO << CNF_CMDREG0_CT);
@@ -375,8 +398,8 @@ int cdns_nand_read(unsigned int offset, uintptr_t buffer, size_t length,
 	uint32_t page = 0U;
 	int result = 0;
 
-	VERBOSE("CNF: block %u-%u, page_start %u, len %zu, offset %u\n",
-				block, end_block, page_start, length, offset);
+	INFO("CNF: %s: block %u-%u, page_start %u, len %zu, offset %u\n",
+		__func__, block, end_block, page_start, length, offset);
 
 	if ((offset >= dev_info.total_size) ||
 		(offset + length-1 >= dev_info.total_size) ||
@@ -392,7 +415,7 @@ int cdns_nand_read(unsigned int offset, uintptr_t buffer, size_t length,
 			if ((start_offset != 0U) || (length < dev_info.page_size)) {
 				/* Partial page read */
 				result = cdns_nand_read_page(block, page,
-				(uintptr_t)scratch_buff);
+							(uintptr_t)scratch_buff);
 				if (result != 0) {
 					return result;
 				}
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 4cbc0f70..3e87efcb 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -34,6 +34,20 @@ unsigned long clk_get_rate(unsigned long id)
 	return ops->get_rate(id);
 }
 
+int clk_set_rate(unsigned long id, unsigned long rate, unsigned long *orate)
+{
+	unsigned long lrate;
+
+	assert((ops != NULL) && (ops->set_rate != NULL));
+
+	if (orate != NULL) {
+		return ops->set_rate(id, rate, orate);
+	}
+
+	/* In case the caller is not interested in the output rate */
+	return ops->set_rate(id, rate, &lrate);
+}
+
 int clk_get_parent(unsigned long id)
 {
 	assert((ops != NULL) && (ops->get_parent != NULL));
@@ -41,6 +55,13 @@ int clk_get_parent(unsigned long id)
 	return ops->get_parent(id);
 }
 
+int clk_set_parent(unsigned long id, unsigned long parent_id)
+{
+	assert((ops != NULL) && (ops->set_parent != NULL));
+
+	return ops->set_parent(id, parent_id);
+}
+
 bool clk_is_enabled(unsigned long id)
 {
 	assert((ops != NULL) && (ops->is_enabled != NULL));
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c
index a3fd7bfe..bdbbbf6a 100644
--- a/drivers/delay_timer/delay_timer.c
+++ b/drivers/delay_timer/delay_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,3 +80,25 @@ void timer_init(const timer_ops_t *ops_ptr)
 
 	timer_ops = ops_ptr;
 }
+
+/***********************************************************
+ * Initialize the timer in us
+ ***********************************************************/
+uint64_t timeout_init_us(uint32_t usec)
+{
+	assert(timer_ops != NULL);
+	assert(timer_ops->timeout_init_us != NULL);
+
+	return timer_ops->timeout_init_us(usec);
+}
+
+/***********************************************************
+ * check the given timeout elapsed or not.
+ ***********************************************************/
+bool timeout_elapsed(uint64_t cnt)
+{
+	assert(timer_ops != NULL);
+	assert(timer_ops->timeout_elapsed != NULL);
+
+	return timer_ops->timeout_elapsed(cnt);
+}
diff --git a/drivers/delay_timer/generic_delay_timer.c b/drivers/delay_timer/generic_delay_timer.c
index ca522e05..0407e385 100644
--- a/drivers/delay_timer/generic_delay_timer.c
+++ b/drivers/delay_timer/generic_delay_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -18,7 +18,26 @@
 
 static timer_ops_t ops;
 
-static uint32_t get_timer_value(void)
+static uint64_t timeout_cnt_us2cnt(uint32_t us)
+{
+	return ((uint64_t)us * (uint64_t)read_cntfrq_el0()) / 1000000ULL;
+}
+
+static uint64_t generic_delay_timeout_init_us(uint32_t us)
+{
+	uint64_t cnt = timeout_cnt_us2cnt(us);
+
+	cnt += read_cntpct_el0();
+
+	return cnt;
+}
+
+static bool generic_delay_timeout_elapsed(uint64_t expire_cnt)
+{
+	return read_cntpct_el0() > expire_cnt;
+}
+
+static uint32_t generic_delay_get_timer_value(void)
 {
 	/*
 	 * Generic delay timer implementation expects the timer to be a down
@@ -31,9 +50,11 @@ static uint32_t get_timer_value(void)
 
 void generic_delay_timer_init_args(uint32_t mult, uint32_t div)
 {
-	ops.get_timer_value	= get_timer_value;
+	ops.get_timer_value	= generic_delay_get_timer_value;
 	ops.clk_mult		= mult;
 	ops.clk_div		= div;
+	ops.timeout_init_us	= generic_delay_timeout_init_us;
+	ops.timeout_elapsed	= generic_delay_timeout_elapsed;
 
 	timer_init(&ops);
 
@@ -59,4 +80,3 @@ void generic_delay_timer_init(void)
 
 	generic_delay_timer_init_args(mult, div);
 }
-
diff --git a/drivers/fwu/fwu.c b/drivers/fwu/fwu.c
index ff432be8..b6f06e0a 100644
--- a/drivers/fwu/fwu.c
+++ b/drivers/fwu/fwu.c
@@ -24,6 +24,17 @@
 CASSERT((offsetof(struct fwu_metadata, crc_32) == 0),
 	crc_32_must_be_first_member_of_structure);
 
+/*
+ * Ensure that the NR_OF_FW_BANKS selected by the platform is not
+ * zero and not greater than the maximum number of banks allowed
+ * by the specification.
+ */
+CASSERT((NR_OF_FW_BANKS > 0) && (NR_OF_FW_BANKS <= NR_OF_MAX_FW_BANKS),
+	assert_fwu_num_banks_invalid_value);
+
+#define FWU_METADATA_VERSION		2U
+#define FWU_FW_STORE_DESC_OFFSET	0x20U
+
 static struct fwu_metadata metadata;
 static bool is_metadata_initialized __unused;
 
@@ -51,16 +62,54 @@ static int fwu_metadata_crc_check(void)
 /*******************************************************************************
  * Check the sanity of FWU metadata.
  *
- * return -1 on error, otherwise 0
+ * return -EINVAL on error, otherwise 0
  ******************************************************************************/
 static int fwu_metadata_sanity_check(void)
 {
-	/* ToDo: add more conditions for sanity check */
-	if ((metadata.active_index >= NR_OF_FW_BANKS) ||
-	    (metadata.previous_active_index >= NR_OF_FW_BANKS)) {
-		return -1;
+	if (metadata.version != FWU_METADATA_VERSION) {
+		WARN("Incorrect FWU Metadata version of %u\n",
+		     metadata.version);
+		return -EINVAL;
+	}
+
+	if (metadata.active_index >= NR_OF_FW_BANKS) {
+		WARN("Active Index value(%u) greater than the configured value(%d)",
+		     metadata.active_index, NR_OF_FW_BANKS);
+		return -EINVAL;
+	}
+
+	if (metadata.previous_active_index >= NR_OF_FW_BANKS) {
+		WARN("Previous Active Index value(%u) greater than the configured value(%d)",
+		     metadata.previous_active_index, NR_OF_FW_BANKS);
+		return -EINVAL;
 	}
 
+#if PSA_FWU_METADATA_FW_STORE_DESC
+	if (metadata.fw_desc.num_banks != NR_OF_FW_BANKS) {
+		WARN("Number of Banks(%u) in FWU Metadata different from the configured value(%d)",
+		     metadata.fw_desc.num_banks, NR_OF_FW_BANKS);
+		return -EINVAL;
+	}
+
+	if (metadata.fw_desc.num_images != NR_OF_IMAGES_IN_FW_BANK) {
+		WARN("Number of Images(%u) in FWU Metadata different from the configured value(%d)",
+		     metadata.fw_desc.num_images, NR_OF_IMAGES_IN_FW_BANK);
+		return -EINVAL;
+	}
+
+	if (metadata.desc_offset != FWU_FW_STORE_DESC_OFFSET) {
+		WARN("Descriptor Offset(0x%x) in the FWU Metadata not equal to 0x20\n",
+		     metadata.desc_offset);
+		return -EINVAL;
+	}
+#else
+	if (metadata.desc_offset != 0U) {
+		WARN("Descriptor offset has non zero value of 0x%x\n",
+		     metadata.desc_offset);
+		return -EINVAL;
+	}
+#endif
+
 	return 0;
 }
 
@@ -133,28 +182,80 @@ exit:
 }
 
 /*******************************************************************************
- * The system runs in the trial run state if any of the images in the active
- * firmware bank has not been accepted yet.
+ * Check for an alternate bank for the platform to boot from. This function will
+ * mostly be called whenever the count of the number of times a platform boots
+ * in the Trial State exceeds a pre-set limit.
+ * The function first checks if the platform can boot from the previously active
+ * bank. If not, it tries to find another bank in the accepted state.
+ * And finally, if both the checks fail, as a last resort, it tries to find
+ * a valid bank.
  *
- * Returns true if the system is running in the trial state.
+ * Returns the index of a bank to boot, else returns invalid index
+ * INVALID_BOOT_IDX.
  ******************************************************************************/
-bool fwu_is_trial_run_state(void)
+uint32_t fwu_get_alternate_boot_bank(void)
 {
-	bool trial_run = false;
+	uint32_t i;
 
-	assert(is_metadata_initialized);
+	/* First check if the previously active bank can be used */
+	if (metadata.bank_state[metadata.previous_active_index] ==
+	    FWU_BANK_STATE_ACCEPTED) {
+		return metadata.previous_active_index;
+	}
+
+	/* Now check for any other bank in the accepted state */
+	for (i = 0U; i < NR_OF_FW_BANKS; i++) {
+		if (i == metadata.active_index ||
+		    i == metadata.previous_active_index) {
+			continue;
+		}
+
+		if (metadata.bank_state[i] == FWU_BANK_STATE_ACCEPTED) {
+			return i;
+		}
+	}
+
+	/*
+	 * No accepted bank found. Now try booting from a valid bank.
+	 * Give priority to the previous active bank.
+	 */
+	if (metadata.bank_state[metadata.previous_active_index] ==
+	    FWU_BANK_STATE_VALID) {
+		return metadata.previous_active_index;
+	}
 
-	for (unsigned int i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
-		struct fwu_image_entry *entry = &metadata.img_entry[i];
-		struct fwu_image_properties *img_props =
-			&entry->img_props[metadata.active_index];
-		if (img_props->accepted == 0) {
-			trial_run = true;
-			break;
+	for (i = 0U; i < NR_OF_FW_BANKS; i++) {
+		if (i == metadata.active_index ||
+		    i == metadata.previous_active_index) {
+			continue;
+		}
+
+		if (metadata.bank_state[i] == FWU_BANK_STATE_VALID) {
+			return i;
 		}
 	}
 
-	return trial_run;
+	return INVALID_BOOT_IDX;
+}
+
+/*******************************************************************************
+ * The platform can be in one of Valid, Invalid or Accepted states.
+ *
+ * Invalid - One or more images in the bank are corrupted, or partially
+ *           overwritten. The bank is not to be used for booting.
+ *
+ * Valid - All images of the bank are valid but at least one image has not
+ *         been accepted. This implies that the platform is in Trial State.
+ *
+ * Accepted - All images of the bank are valid and accepted.
+ *
+ * Returns the state of the current active bank
+ ******************************************************************************/
+uint32_t fwu_get_active_bank_state(void)
+{
+	assert(is_metadata_initialized);
+
+	return metadata.bank_state[metadata.active_index];
 }
 
 const struct fwu_metadata *fwu_get_metadata(void)
diff --git a/drivers/measured_boot/rse/dice_prot_env.c b/drivers/measured_boot/rse/dice_prot_env.c
new file mode 100644
index 00000000..dad30b2c
--- /dev/null
+++ b/drivers/measured_boot/rse/dice_prot_env.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <psa/crypto_types.h>
+#include <psa/crypto_values.h>
+
+#include <common/debug.h>
+#include <drivers/auth/crypto_mod.h>
+#include <drivers/measured_boot/rse/dice_prot_env.h>
+#include <lib/cassert.h>
+#include <lib/psa/dice_protection_environment.h>
+
+#include <platform_def.h>
+
+#define DPE_ALG_SHA512 0
+#define DPE_ALG_SHA384 1
+#define DPE_ALG_SHA256 2
+
+#if DPE_ALG_ID == DPE_ALG_SHA512
+#define	CRYPTO_MD_ID		CRYPTO_MD_SHA512
+#define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_512
+#elif DPE_ALG_ID == DPE_ALG_SHA384
+#define	CRYPTO_MD_ID		CRYPTO_MD_SHA384
+#define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_384
+#elif DPE_ALG_ID == DPE_ALG_SHA256
+#define	CRYPTO_MD_ID		CRYPTO_MD_SHA256
+#define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_256
+#else
+#  error Invalid DPE hash algorithm.
+#endif /* DPE_ALG_ID */
+
+/* Ensure that computed hash values fits into the DiceInputValues structure */
+CASSERT(DICE_HASH_SIZE >= DPE_DIGEST_SIZE,
+	assert_digest_size_bigger_than_allocated_buffer);
+
+static int initial_context_handle;
+
+static void map_metadata_to_dice_inputs(struct dpe_metadata *metadata,
+					DiceInputValues  *dice_inputs)
+{
+	/* Hash of the content certificate signing key (public part) */
+	memcpy(dice_inputs->authority_hash, metadata->signer_id,
+	       DPE_DIGEST_SIZE);
+
+	/* SW type string identifier */
+	assert(metadata->sw_type_size < DICE_CODE_DESCRIPTOR_MAX_SIZE);
+	dice_inputs->code_descriptor = metadata->sw_type;
+	dice_inputs->code_descriptor_size = metadata->sw_type_size;
+}
+
+void dpe_init(struct dpe_metadata *metadata)
+{
+	assert(metadata != NULL);
+
+	/* Init the non-const members of the metadata structure */
+	while (metadata->id != DPE_INVALID_ID) {
+		/* Terminating 0 character is not needed due to CBOR encoding */
+		metadata->sw_type_size =
+			strlen((const char *)&metadata->sw_type);
+		metadata++;
+	}
+
+	plat_dpe_get_context_handle(&initial_context_handle);
+}
+
+int dpe_measure_and_record(struct dpe_metadata *metadata,
+			   uintptr_t data_base, uint32_t data_size,
+			   uint32_t data_id)
+{
+	static int current_context_handle;
+	DiceInputValues dice_inputs = { 0 };
+	int new_parent_context_handle;
+	int new_context_handle;
+	dpe_error_t ret;
+	int rc;
+
+	assert(metadata != NULL);
+
+	/* Get the metadata associated with this image. */
+	while ((metadata->id != DPE_INVALID_ID) && (metadata->id != data_id)) {
+		metadata++;
+	}
+
+	/* If image is not present in metadata array then skip */
+	if (metadata->id == DPE_INVALID_ID) {
+		return 0;
+	}
+
+	/* Calculate hash */
+	rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
+				  (void *)data_base, data_size,
+				   dice_inputs.code_hash);
+	if (rc != 0) {
+		return rc;
+	}
+
+	map_metadata_to_dice_inputs(metadata, &dice_inputs);
+
+	/* Only at the first call */
+	if (current_context_handle == 0) {
+		current_context_handle = initial_context_handle;
+	}
+
+	VERBOSE("Calling dpe_derive_context, image_id: %d\n", metadata->id);
+	ret = dpe_derive_context(current_context_handle,
+				 metadata->cert_id,
+				 metadata->retain_parent_context,
+				 metadata->allow_new_context_to_derive,
+				 metadata->create_certificate,
+				 &dice_inputs,
+				 metadata->target_locality,
+				 false, /* return_certificate */
+				 true, /* allow_new_context_to_export */
+				 false, /* export_cdi */
+				 &new_context_handle,
+				 &new_parent_context_handle,
+				 NULL, 0, NULL,  /* new_certificate_* */
+				 NULL, 0, NULL); /* exported_cdi_* */
+	if (ret == DPE_NO_ERROR) {
+		current_context_handle = new_parent_context_handle;
+		if (metadata->allow_new_context_to_derive == true) {
+			/* Share new_context_handle with child component:
+			 * e.g: BL2, BL33.
+			 */
+			VERBOSE("Share new_context_handle with child: 0x%x\n",
+				new_context_handle);
+			plat_dpe_share_context_handle(&new_context_handle,
+						      &new_parent_context_handle);
+		}
+	} else {
+		ERROR("dpe_derive_context failed: %d\n", ret);
+	}
+
+	return (ret == DPE_NO_ERROR) ? 0 : -1;
+}
+
+int dpe_set_signer_id(struct dpe_metadata *metadata,
+		      const void *pk_oid,
+		      const void *pk_ptr,
+		      size_t pk_len)
+{
+	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
+	int rc;
+	bool hash_calc_done = false;
+
+	assert(metadata != NULL);
+
+	/*
+	 * Do an exhaustive search over the platform metadata to find
+	 * all images whose key OID matches the one passed in argument.
+	 *
+	 * Note that it is not an error if do not get any matches.
+	 * The platform may decide not to measure all of the images
+	 * in the system.
+	 */
+	while (metadata->id != DPE_INVALID_ID) {
+		/* Get the metadata associated with this key-oid */
+		if (metadata->pk_oid == pk_oid) {
+			if (hash_calc_done == false) {
+				/* Calculate public key hash */
+				rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
+							  (void *)pk_ptr,
+							  pk_len, hash_data);
+				if (rc != 0) {
+					return rc;
+				}
+
+				hash_calc_done = true;
+			}
+
+			/*
+			 * Fill the signer-ID field with the newly/already
+			 * computed hash of the public key and update its
+			 * signer ID size field with compile-time decided
+			 * digest size.
+			 */
+			(void)memcpy(metadata->signer_id,
+				     hash_data,
+				     DPE_DIGEST_SIZE);
+			metadata->signer_id_size = DPE_DIGEST_SIZE;
+		}
+
+		metadata++;
+	}
+
+	return 0;
+}
diff --git a/drivers/measured_boot/rse/dice_prot_env.mk b/drivers/measured_boot/rse/dice_prot_env.mk
new file mode 100644
index 00000000..7c833076
--- /dev/null
+++ b/drivers/measured_boot/rse/dice_prot_env.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Hash algorithm for DICE Protection Environment
+# SHA-256 (or stronger) is required.
+DPE_HASH_ALG	:=	sha256
+
+ifeq (${DPE_HASH_ALG}, sha512)
+    DPE_ALG_ID		:=	DPE_ALG_SHA512
+    DPE_DIGEST_SIZE	:=	64U
+else ifeq (${DPE_HASH_ALG}, sha384)
+    DPE_ALG_ID		:=	DPE_ALG_SHA384
+    DPE_DIGEST_SIZE	:=	48U
+else
+    DPE_ALG_ID		:=	DPE_ALG_SHA256
+    DPE_DIGEST_SIZE	:=	32U
+endif #DPE_HASH_ALG
+
+# Set definitions for DICE Protection Environment
+$(eval $(call add_defines,\
+    $(sort \
+        DPE_ALG_ID \
+        DPE_DIGEST_SIZE \
+)))
+
+DPE_SOURCES	+=	drivers/measured_boot/rse/dice_prot_env.c
diff --git a/drivers/measured_boot/rse/qcbor.mk b/drivers/measured_boot/rse/qcbor.mk
new file mode 100644
index 00000000..2146e5d2
--- /dev/null
+++ b/drivers/measured_boot/rse/qcbor.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# TF-A was tested with v1.2 version of QCBOR
+
+ifeq (${QCBOR_DIR},)
+        $(error Error: QCBOR_DIR not set)
+endif
+
+QCBOR_SOURCES	+=	${QCBOR_DIR}/src/qcbor_encode.c \
+			${QCBOR_DIR}/src/qcbor_decode.c \
+			${QCBOR_DIR}/src/UsefulBuf.c
+
+QCBOR_INCLUDES	+=	${QCBOR_DIR}/inc
+
+# Floating point numbers are not used, so disable the support.
+# This reduces the library size as well.
+$(eval $(call add_define,QCBOR_DISABLE_FLOAT_HW_USE))
+$(eval $(call add_define,USEFULBUF_DISABLE_ALL_FLOAT))
+$(eval $(call add_define,QCBOR_DISABLE_PREFERRED_FLOAT))
diff --git a/drivers/measured_boot/rss/rss_measured_boot.c b/drivers/measured_boot/rse/rse_measured_boot.c
similarity index 86%
rename from drivers/measured_boot/rss/rss_measured_boot.c
rename to drivers/measured_boot/rse/rse_measured_boot.c
index 258aa8d4..5337c3de 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.c
+++ b/drivers/measured_boot/rse/rse_measured_boot.c
@@ -9,7 +9,7 @@
 
 #include <common/debug.h>
 #include <drivers/auth/crypto_mod.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
 #include <lib/psa/measured_boot.h>
 #include <psa/crypto_types.h>
 #include <psa/crypto_values.h>
@@ -46,12 +46,12 @@ static bool null_arr(const uint8_t *signer_id, size_t signer_id_size)
 #endif /* ENABLE_ASSERTIONS */
 
 /* Functions' declarations */
-void rss_measured_boot_init(struct rss_mboot_metadata *metadata_ptr)
+void rse_measured_boot_init(struct rse_mboot_metadata *metadata_ptr)
 {
 	assert(metadata_ptr != NULL);
 
 	/* Init the non-const members of the metadata structure */
-	while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
+	while (metadata_ptr->id != RSE_MBOOT_INVALID_ID) {
 		assert(null_arr(metadata_ptr->signer_id, MBOOT_DIGEST_SIZE));
 		metadata_ptr->sw_type_size =
 			strlen((const char *)&metadata_ptr->sw_type) + 1;
@@ -59,7 +59,7 @@ void rss_measured_boot_init(struct rss_mboot_metadata *metadata_ptr)
 	}
 }
 
-int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
+int rse_mboot_measure_and_record(struct rse_mboot_metadata *metadata_ptr,
 				 uintptr_t data_base, uint32_t data_size,
 				 uint32_t data_id)
 {
@@ -70,13 +70,13 @@ int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
 	assert(metadata_ptr != NULL);
 
 	/* Get the metadata associated with this image. */
-	while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) &&
+	while ((metadata_ptr->id != RSE_MBOOT_INVALID_ID) &&
 		(metadata_ptr->id != data_id)) {
 		metadata_ptr++;
 	}
 
 	/* If image is not present in metadata array then skip */
-	if (metadata_ptr->id == RSS_MBOOT_INVALID_ID) {
+	if (metadata_ptr->id == RSE_MBOOT_INVALID_ID) {
 		return 0;
 	}
 
@@ -87,7 +87,7 @@ int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
 		return rc;
 	}
 
-	ret = rss_measured_boot_extend_measurement(
+	ret = rse_measured_boot_extend_measurement(
 						metadata_ptr->slot,
 						metadata_ptr->signer_id,
 						metadata_ptr->signer_id_size,
@@ -106,7 +106,7 @@ int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
 	return 0;
 }
 
-int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
+int rse_mboot_set_signer_id(struct rse_mboot_metadata *metadata_ptr,
 			    const void *pk_oid,
 			    const void *pk_ptr,
 			    size_t pk_len)
@@ -125,10 +125,10 @@ int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
 	 * The platform may decide not to measure all of the images
 	 * in the system.
 	 */
-	while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
+	while (metadata_ptr->id != RSE_MBOOT_INVALID_ID) {
 		/* Get the metadata associated with this key-oid */
 		if (metadata_ptr->pk_oid == pk_oid) {
-			if (!hash_calc_done) {
+			if (hash_calc_done == false) {
 				/* Calculate public key hash */
 				rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
 							  (void *)pk_ptr,
diff --git a/drivers/measured_boot/rss/rss_measured_boot.mk b/drivers/measured_boot/rse/rse_measured_boot.mk
similarity index 65%
rename from drivers/measured_boot/rss/rss_measured_boot.mk
rename to drivers/measured_boot/rse/rse_measured_boot.mk
index 18ee8361..1bd971f3 100644
--- a/drivers/measured_boot/rss/rss_measured_boot.mk
+++ b/drivers/measured_boot/rse/rse_measured_boot.mk
@@ -6,27 +6,27 @@
 
 # Hash algorithm for measured boot
 # SHA-256 (or stronger) is required.
-MBOOT_RSS_HASH_ALG		:=	sha256
+MBOOT_RSE_HASH_ALG		:=	sha256
 
-ifeq (${MBOOT_RSS_HASH_ALG}, sha512)
+ifeq (${MBOOT_RSE_HASH_ALG}, sha512)
     MBOOT_ALG_ID		:=	MBOOT_ALG_SHA512
     MBOOT_DIGEST_SIZE		:=	64U
-else ifeq (${MBOOT_RSS_HASH_ALG}, sha384)
+else ifeq (${MBOOT_RSE_HASH_ALG}, sha384)
     MBOOT_ALG_ID		:=	MBOOT_ALG_SHA384
     MBOOT_DIGEST_SIZE		:=	48U
 else
     MBOOT_ALG_ID		:=	MBOOT_ALG_SHA256
     MBOOT_DIGEST_SIZE		:=	32U
-endif #MBOOT_RSS_HASH_ALG
+endif #MBOOT_RSE_HASH_ALG
 
 # Set definitions for Measured Boot driver.
 $(eval $(call add_defines,\
     $(sort \
         MBOOT_ALG_ID \
         MBOOT_DIGEST_SIZE \
-        MBOOT_RSS_BACKEND \
+        MBOOT_RSE_BACKEND \
 )))
 
-MEASURED_BOOT_SRC_DIR	:= drivers/measured_boot/rss/
+MEASURED_BOOT_SRC_DIR	:= drivers/measured_boot/rse/
 
-MEASURED_BOOT_SOURCES	+= ${MEASURED_BOOT_SRC_DIR}rss_measured_boot.c
+MEASURED_BOOT_SOURCES	+= ${MEASURED_BOOT_SRC_DIR}rse_measured_boot.c
diff --git a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
index 1af51f80..12e22e94 100644
--- a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
+++ b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk
@@ -26,8 +26,8 @@ endif
 # CST_BL31
 define CST_BL31_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${BL31_INPUT_FILE}
 endef
 
@@ -36,8 +36,8 @@ CST_BL31_SUFFIX := .cst
 # CST_BL32
 define CST_BL32_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${BL32_INPUT_FILE}
 endef
 
@@ -46,8 +46,8 @@ CST_BL32_SUFFIX := .cst
 # CST_BL33
 define CST_BL33_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${BL33_INPUT_FILE}
 endef
 
@@ -56,8 +56,8 @@ CST_BL33_SUFFIX := .cst
 # CST_SCP_BL2
 define CST_SCP_BL2_RULE
 $(1): $(2)
-	@echo " Generating CSF Header for $$@ $$<"
-	$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
+	$(s)echo " Generating CSF Header for $$@ $$<"
+	$(q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
 					--app $(2) ${FUSE_INPUT_FILE}
 endef
 
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
new file mode 100644
index 00000000..e54d5813
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/include/s32cc-clk-regs.h
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2020-2021, 2023-2024 NXP
+ */
+#ifndef S32CC_CLK_REGS_H
+#define S32CC_CLK_REGS_H
+
+#include <lib/utils_def.h>
+
+#define FXOSC_BASE_ADDR			(0x40050000UL)
+#define ARMPLL_BASE_ADDR		(0x40038000UL)
+#define PERIPHPLL_BASE_ADDR		(0x4003C000UL)
+#define ARM_DFS_BASE_ADDR		(0x40054000UL)
+#define CGM0_BASE_ADDR			(0x40030000UL)
+#define CGM1_BASE_ADDR			(0x40034000UL)
+#define DDRPLL_BASE_ADDR		(0x40044000UL)
+#define MC_ME_BASE_ADDR			(0x40088000UL)
+#define MC_RGM_BASE_ADDR		(0x40078000UL)
+#define RDC_BASE_ADDR			(0x40080000UL)
+#define MC_CGM5_BASE_ADDR		(0x40068000UL)
+
+/* FXOSC */
+#define FXOSC_CTRL(FXOSC)		((FXOSC) + 0x0UL)
+#define FXOSC_CTRL_OSC_BYP		BIT_32(31U)
+#define FXOSC_CTRL_COMP_EN		BIT_32(24U)
+#define FXOSC_CTRL_EOCV_OFFSET		16U
+#define FXOSC_CTRL_EOCV_MASK		GENMASK_32(23U, FXOSC_CTRL_EOCV_OFFSET)
+#define FXOSC_CTRL_EOCV(VAL)		(FXOSC_CTRL_EOCV_MASK & \
+					 ((uint32_t)(VAL) << FXOSC_CTRL_EOCV_OFFSET))
+#define FXOSC_CTRL_GM_SEL_OFFSET	4U
+#define FXOSC_CTRL_GM_SEL_MASK		GENMASK_32(7U, FXOSC_CTRL_GM_SEL_OFFSET)
+#define FXOSC_CTRL_GM_SEL(VAL)		(FXOSC_CTRL_GM_SEL_MASK & \
+					 ((uint32_t)(VAL) << FXOSC_CTRL_GM_SEL_OFFSET))
+#define FXOSC_CTRL_OSCON		BIT_32(0U)
+
+#define FXOSC_STAT(FXOSC)		((FXOSC) + 0x4UL)
+#define FXOSC_STAT_OSC_STAT		BIT_32(31U)
+
+/* PLL */
+#define PLLDIG_PLLCR(PLL)		((PLL) + 0x0UL)
+#define PLLDIG_PLLCR_PLLPD		BIT_32(31U)
+
+#define PLLDIG_PLLSR(PLL)		((PLL) + 0x4UL)
+#define PLLDIG_PLLSR_LOCK		BIT_32(2U)
+
+#define PLLDIG_PLLDV(PLL)		((PLL) + 0x8UL)
+#define PLLDIG_PLLDV_RDIV_OFFSET	12U
+#define PLLDIG_PLLDV_RDIV_MASK		GENMASK_32(14U, PLLDIG_PLLDV_RDIV_OFFSET)
+#define PLLDIG_PLLDV_RDIV_SET(VAL)	(PLLDIG_PLLDV_RDIV_MASK & \
+					((VAL) << PLLDIG_PLLDV_RDIV_OFFSET))
+#define PLLDIG_PLLDV_MFI_MASK		GENMASK_32(7U, 0U)
+#define PLLDIG_PLLDV_MFI(DIV)		(PLLDIG_PLLDV_MFI_MASK & (DIV))
+
+#define PLLDIG_PLLFD(PLL)		((PLL) + 0x10UL)
+#define PLLDIG_PLLFD_SMDEN		BIT_32(30U)
+#define PLLDIG_PLLFD_MFN_MASK		GENMASK_32(14U, 0U)
+#define PLLDIG_PLLFD_MFN_SET(VAL)	(PLLDIG_PLLFD_MFN_MASK & (VAL))
+
+#define PLLDIG_PLLCLKMUX(PLL)		((PLL) + 0x20UL)
+
+#define PLLDIG_PLLODIV(PLL, N)		((PLL) + 0x80UL + ((N) * 0x4UL))
+#define PLLDIG_PLLODIV_DE		BIT_32(31U)
+#define PLLDIG_PLLODIV_DIV_OFFSET	16U
+#define PLLDIG_PLLODIV_DIV_MASK		GENMASK_32(23U, PLLDIG_PLLODIV_DIV_OFFSET)
+#define PLLDIG_PLLODIV_DIV(VAL)		(((VAL) & PLLDIG_PLLODIV_DIV_MASK) >> \
+					 PLLDIG_PLLODIV_DIV_OFFSET)
+#define PLLDIG_PLLODIV_DIV_SET(VAL)	(PLLDIG_PLLODIV_DIV_MASK & ((VAL) << \
+					 PLLDIG_PLLODIV_DIV_OFFSET))
+
+/* MMC_CGM */
+#define CGM_MUXn_CSC(CGM_ADDR, MUX)	((CGM_ADDR) + 0x300UL + ((MUX) * 0x40UL))
+#define MC_CGM_MUXn_CSC_SELCTL_OFFSET	24U
+#define MC_CGM_MUXn_CSC_SELCTL_MASK	GENMASK_32(29U, MC_CGM_MUXn_CSC_SELCTL_OFFSET)
+#define MC_CGM_MUXn_CSC_SELCTL(val)	(MC_CGM_MUXn_CSC_SELCTL_MASK & ((val) \
+					 << MC_CGM_MUXn_CSC_SELCTL_OFFSET))
+#define MC_CGM_MUXn_CSC_CLK_SW		BIT_32(2U)
+#define MC_CGM_MUXn_CSC_SAFE_SW		BIT_32(3U)
+
+#define CGM_MUXn_CSS(CGM_ADDR, MUX)	((CGM_ADDR) + 0x304UL + ((MUX) * 0x40UL))
+#define MC_CGM_MUXn_CSS_SELSTAT_OFFSET	24U
+#define MC_CGM_MUXn_CSS_SELSTAT_MASK	GENMASK_32(29U, MC_CGM_MUXn_CSS_SELSTAT_OFFSET)
+#define MC_CGM_MUXn_CSS_SELSTAT(css)	((MC_CGM_MUXn_CSS_SELSTAT_MASK & (css))\
+					 >> MC_CGM_MUXn_CSS_SELSTAT_OFFSET)
+#define MC_CGM_MUXn_CSS_SWTRG(css)	((MC_CGM_MUXn_CSS_SWTRG_MASK & (css)) \
+					 >> MC_CGM_MUXn_CSS_SWTRG_OFFSET)
+#define MC_CGM_MUXn_CSS_SWTRG_OFFSET	17U
+#define MC_CGM_MUXn_CSS_SWTRG_MASK	GENMASK_32(19U, MC_CGM_MUXn_CSS_SWTRG_OFFSET)
+#define MC_CGM_MUXn_CSS_SWTRG_SUCCESS	0x1U
+#define MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK	0x4U
+#define MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK_INACTIVE	0x5U
+#define MC_CGM_MUXn_CSS_SWIP		BIT_32(16U)
+#define MC_CGM_MUXn_CSS_SAFE_SW		BIT_32(3U)
+
+/* DFS */
+#define DFS_PORTSR(DFS_ADDR)		((DFS_ADDR) + 0xCUL)
+#define DFS_PORTOLSR(DFS_ADDR)		((DFS_ADDR) + 0x10UL)
+#define DFS_PORTOLSR_LOL(N)		(BIT_32(N) & GENMASK_32(5U, 0U))
+#define DFS_PORTRESET(DFS_ADDR)		((DFS_ADDR) + 0x14UL)
+#define DFS_PORTRESET_MASK		GENMASK_32(5U, 0U)
+#define DFS_PORTRESET_SET(VAL)		(((VAL) & DFS_PORTRESET_MASK))
+
+#define DFS_CTL(DFS_ADDR)		((DFS_ADDR) + 0x18UL)
+#define DFS_CTL_RESET			BIT_32(1U)
+
+#define DFS_DVPORTn(DFS_ADDR, PORT)	((DFS_ADDR) + 0x1CUL + ((PORT) * 0x4UL))
+#define DFS_DVPORTn_MFI_MASK		GENMASK_32(15U, 8U)
+#define DFS_DVPORTn_MFI_SHIFT		8U
+#define DFS_DVPORTn_MFN_MASK		GENMASK_32(7U, 0U)
+#define DFS_DVPORTn_MFN_SHIFT		0U
+#define DFS_DVPORTn_MFI(MFI)		(((MFI) & DFS_DVPORTn_MFI_MASK) >> DFS_DVPORTn_MFI_SHIFT)
+#define DFS_DVPORTn_MFN(MFN)		(((MFN) & DFS_DVPORTn_MFN_MASK) >> DFS_DVPORTn_MFN_SHIFT)
+#define DFS_DVPORTn_MFI_SET(VAL)	(((VAL) << DFS_DVPORTn_MFI_SHIFT) & DFS_DVPORTn_MFI_MASK)
+#define DFS_DVPORTn_MFN_SET(VAL)	(((VAL) << DFS_DVPORTn_MFN_SHIFT) & DFS_DVPORTn_MFN_MASK)
+
+#endif /* S32CC_CLK_REGS_H */
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-mc-me.h b/drivers/nxp/clk/s32cc/include/s32cc-mc-me.h
new file mode 100644
index 00000000..8249fc55
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/include/s32cc-mc-me.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2020-2021, 2023-2024 NXP
+ */
+#ifndef S32CC_MC_ME_H
+#define S32CC_MC_ME_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+int mc_me_enable_partition(uintptr_t mc_me, uintptr_t mc_rgm, uintptr_t rdc,
+			   uint32_t part);
+void mc_me_enable_part_cofb(uintptr_t mc_me, uint32_t partition_n, uint32_t block,
+			    bool check_status);
+
+#endif /* S32CC_MC_ME_H */
diff --git a/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h b/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
new file mode 100644
index 00000000..d6234daf
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/include/s32cc-mc-rgm.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2020-2021, 2023-2024 NXP
+ */
+#ifndef S32CC_MC_RGM_H
+#define S32CC_MC_RGM_H
+
+#include <stdint.h>
+
+void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value);
+void mc_rgm_release_part(uintptr_t rgm, uint32_t part);
+void mc_rgm_wait_part_deassert(uintptr_t rgm, uint32_t part);
+
+#endif /* MC_RGM_H */
diff --git a/drivers/nxp/clk/s32cc/mc_me.c b/drivers/nxp/clk/s32cc/mc_me.c
new file mode 100644
index 00000000..04d04253
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/mc_me.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <s32cc-mc-me.h>
+#include <s32cc-mc-rgm.h>
+
+#define MC_ME_MAX_PARTITIONS		(4U)
+
+#define MC_ME_CTL_KEY(MC_ME)		((MC_ME) + 0x0UL)
+#define MC_ME_CTL_KEY_KEY		(0x5AF0U)
+#define MC_ME_CTL_KEY_INVERTEDKEY	(0xA50FU)
+
+#define MC_ME_PRTN_N(MC_ME, PART)	((MC_ME) + 0x100UL + ((PART) * 0x200UL))
+#define MC_ME_PRTN_N_PCONF(MC_ME, PART)	(MC_ME_PRTN_N(MC_ME, PART))
+#define MC_ME_PRTN_N_PCE		BIT_32(0)
+#define MC_ME_PRTN_N_OSSE		BIT_32(2)
+#define MC_ME_PRTN_N_PUPD(MC_ME, PART)	(MC_ME_PRTN_N(MC_ME, PART) + 0x4UL)
+#define MC_ME_PRTN_N_PCUD		BIT_32(0)
+#define MC_ME_PRTN_N_OSSUD		BIT_32(2)
+#define MC_ME_PRTN_N_STAT(MC_ME, PART)	(MC_ME_PRTN_N(MC_ME, PART) + 0x8UL)
+#define MC_ME_PRTN_N_PCS		BIT_32(0)
+#define MC_ME_PRTN_N_COFB0_STAT(MC_ME, PART) \
+					(MC_ME_PRTN_N(MC_ME, PART) + 0x10UL)
+#define MC_ME_PRTN_N_COFB0_CLKEN(MC_ME, PART) \
+					(MC_ME_PRTN_N(MC_ME, PART) + 0x30UL)
+#define MC_ME_PRTN_N_REQ(PART)		BIT_32(PART)
+
+#define RDC_RD_CTRL(RDC, PART)		((RDC) + ((PART) * 0x4UL))
+#define RDC_CTRL_UNLOCK			BIT_32(31)
+#define RDC_RD_INTERCONNECT_DISABLE	BIT_32(3)
+
+#define RDC_RD_N_STATUS(RDC, PART)	((RDC) + ((PART) * 0x4UL) + 0x80UL)
+#define RDC_RD_INTERCONNECT_DISABLE_STAT \
+					BIT_32(4)
+
+static bool is_interconnect_disabled(uintptr_t rdc, uint32_t part)
+{
+	return ((mmio_read_32(RDC_RD_N_STATUS(rdc, part)) &
+		  RDC_RD_INTERCONNECT_DISABLE_STAT) != 0U);
+}
+
+static void enable_interconnect(uintptr_t rdc, uint32_t part)
+{
+	/* Unlock RDC register write */
+	mmio_setbits_32(RDC_RD_CTRL(rdc, part), RDC_CTRL_UNLOCK);
+
+	/* Clear corresponding RDC_RD_INTERCONNECT bit */
+	mmio_clrbits_32(RDC_RD_CTRL(rdc, part), RDC_RD_INTERCONNECT_DISABLE);
+
+	/* Wait until the interface gets enabled */
+	while (is_interconnect_disabled(rdc, part)) {
+	}
+
+	/* Lock RDC register write */
+	mmio_clrbits_32(RDC_RD_CTRL(rdc, part), RDC_CTRL_UNLOCK);
+}
+
+static int mc_me_check_partition_nb_valid(uint32_t part)
+{
+	if (part >= MC_ME_MAX_PARTITIONS) {
+		ERROR("Invalid partition %" PRIu32 "\n", part);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void part_pconf_write_pce(uintptr_t mc_me, uint32_t pce_bit,
+				 uint32_t part)
+{
+	mmio_clrsetbits_32(MC_ME_PRTN_N_PCONF(mc_me, part), MC_ME_PRTN_N_PCE,
+			   pce_bit & MC_ME_PRTN_N_PCE);
+}
+
+static void mc_me_apply_hw_changes(uintptr_t mc_me)
+{
+	mmio_write_32(MC_ME_CTL_KEY(mc_me), MC_ME_CTL_KEY_KEY);
+	mmio_write_32(MC_ME_CTL_KEY(mc_me), MC_ME_CTL_KEY_INVERTEDKEY);
+}
+
+static void part_pupd_update_and_wait(uintptr_t mc_me, uint32_t part,
+				      uint32_t mask)
+{
+	uint32_t pconf, stat;
+
+	mmio_setbits_32(MC_ME_PRTN_N_PUPD(mc_me, part), mask);
+
+	mc_me_apply_hw_changes(mc_me);
+
+	/* wait for the updates to apply */
+	pconf = mmio_read_32(MC_ME_PRTN_N_PCONF(mc_me, part));
+	do {
+		stat = mmio_read_32(MC_ME_PRTN_N_STAT(mc_me, part));
+	} while ((stat & mask) != (pconf & mask));
+}
+
+static void part_pconf_write_osse(uintptr_t mc_me, uint32_t osse_bit,
+				  uint32_t part)
+{
+	mmio_clrsetbits_32(MC_ME_PRTN_N_PCONF(mc_me, part), MC_ME_PRTN_N_OSSE,
+			   (osse_bit & MC_ME_PRTN_N_OSSE));
+}
+
+int mc_me_enable_partition(uintptr_t mc_me, uintptr_t mc_rgm, uintptr_t rdc,
+			   uint32_t part)
+{
+	uint32_t part_stat;
+	int ret;
+
+	/* Partition 0 is already enabled by BootROM */
+	if (part == 0U) {
+		return 0;
+	}
+
+	ret = mc_me_check_partition_nb_valid(part);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Enable a partition only if it's disabled */
+	part_stat = mmio_read_32(MC_ME_PRTN_N_STAT(mc_me, part));
+	if ((MC_ME_PRTN_N_PCS & part_stat) != 0U) {
+		return 0;
+	}
+
+	part_pconf_write_pce(mc_me, MC_ME_PRTN_N_PCE, part);
+	part_pupd_update_and_wait(mc_me, part, MC_ME_PRTN_N_PCUD);
+
+	enable_interconnect(rdc, part);
+
+	/* Release partition reset */
+	mc_rgm_release_part(mc_rgm, part);
+
+	/* Clear OSSE bit */
+	part_pconf_write_osse(mc_me, 0, part);
+
+	part_pupd_update_and_wait(mc_me, part, MC_ME_PRTN_N_OSSUD);
+
+	mc_rgm_wait_part_deassert(mc_rgm, part);
+
+	return 0;
+}
+
+void mc_me_enable_part_cofb(uintptr_t mc_me, uint32_t partition_n, uint32_t block,
+			    bool check_status)
+{
+	uint32_t block_mask = MC_ME_PRTN_N_REQ(block);
+	uintptr_t cofb_stat_addr;
+
+	mmio_setbits_32(MC_ME_PRTN_N_COFB0_CLKEN(mc_me, partition_n),
+			block_mask);
+
+	mmio_setbits_32(MC_ME_PRTN_N_PCONF(mc_me, partition_n),
+			MC_ME_PRTN_N_PCE);
+
+	part_pupd_update_and_wait(mc_me, partition_n, MC_ME_PRTN_N_PCUD);
+
+	cofb_stat_addr = MC_ME_PRTN_N_COFB0_STAT(mc_me, partition_n);
+	if (check_status) {
+		while ((mmio_read_32(cofb_stat_addr) & block_mask) == 0U) {
+		}
+	}
+}
diff --git a/drivers/nxp/clk/s32cc/mc_rgm.c b/drivers/nxp/clk/s32cc/mc_rgm.c
new file mode 100644
index 00000000..c66b0139
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/mc_rgm.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2023-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <s32cc-mc-rgm.h>
+
+#define MC_RGM_PRST(RGM, PER)		((RGM) + 0x40UL + ((PER) * 0x8UL))
+#define MC_RGM_PRST_PERIPH_N_RST(PER)	BIT_32(PER)
+#define MC_RGM_PSTAT(RGM, PER)		((RGM) + 0x140UL + ((PER) * 0x8UL))
+#define MC_RGM_PSTAT_PERIPH(PER)	BIT_32(PER)
+
+/*  ERR051700
+ *  Releasing more than one Software Resettable Domain (SRD)
+ *  from reset simultaneously, by clearing the corresponding
+ *  peripheral MC_RGM_PRSTn[PERIPH_x_RST] reset control may
+ *  cause a false setting of the Fault Collection and
+ *  Control Unit (FCCU) Non-Critical Fault (NCF) flag
+ *  corresponding to a Memory-Test-Repair (MTR) Error
+ */
+#if (ERRATA_S32_051700 == 1)
+void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
+{
+	uint32_t current_bit_checked, i;
+	uint32_t current_regs, mask;
+	int bit_index;
+
+	current_regs = mmio_read_32(MC_RGM_PRST(rgm, part));
+	/* Create a mask with all changed bits */
+	mask = current_regs ^ value;
+
+	while (mask != 0U) {
+		bit_index = __builtin_ffs(mask);
+		if (bit_index < 1) {
+			break;
+		}
+
+		i = (uint32_t)bit_index - 1U;
+		current_bit_checked = BIT_32(i);
+
+		/* Check if we assert or de-assert.
+		 * Also wait for completion.
+		 */
+		if ((value & current_bit_checked) != 0U) {
+			mmio_setbits_32(MC_RGM_PRST(rgm, part),
+					current_bit_checked);
+			while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
+				 current_bit_checked) == 0U)
+				;
+		} else {
+			mmio_clrbits_32(MC_RGM_PRST(rgm, part),
+					current_bit_checked);
+			while ((mmio_read_32(MC_RGM_PRST(rgm, part)) &
+					    current_bit_checked) != 0U)
+				;
+		}
+
+		mask &= ~current_bit_checked;
+	}
+}
+#else /* ERRATA_S32_051700 */
+void mc_rgm_periph_reset(uintptr_t rgm, uint32_t part, uint32_t value)
+{
+	mmio_write_32(MC_RGM_PRST(rgm, part), value);
+}
+#endif /* ERRATA_S32_051700 */
+
+void mc_rgm_release_part(uintptr_t rgm, uint32_t part)
+{
+	uint32_t reg;
+
+	reg = mmio_read_32(MC_RGM_PRST(rgm, part));
+	reg &= ~MC_RGM_PRST_PERIPH_N_RST(0);
+	mc_rgm_periph_reset(rgm, part, reg);
+}
+
+void mc_rgm_wait_part_deassert(uintptr_t rgm, uint32_t part)
+{
+	while ((mmio_read_32(MC_RGM_PSTAT(rgm, part)) &
+		MC_RGM_PSTAT_PERIPH(0)) != 0U) {
+	}
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk.mk b/drivers/nxp/clk/s32cc/s32cc_clk.mk
new file mode 100644
index 00000000..602179e3
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk.mk
@@ -0,0 +1,22 @@
+#
+# Copyright 2024 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES		+= \
+	-I${PLAT_DRIVERS_INCLUDE_PATH}/clk/s32cc \
+	-I${PLAT_DRIVERS_PATH}/clk/s32cc/include \
+
+CLK_SOURCES		:= \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/mc_rgm.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/mc_me.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_drv.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_modules.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk_utils.c \
+	${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_early_clks.c \
+	drivers/clk/clk.c \
+
+ifeq (${BL_COMM_CLK_NEEDED},yes)
+BL2_SOURCES		+= ${CLK_SOURCES}
+endif
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
new file mode 100644
index 00000000..9b576075
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c
@@ -0,0 +1,1481 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+#include <common/debug.h>
+#include <drivers/clk.h>
+#include <lib/mmio.h>
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-modules.h>
+#include <s32cc-clk-regs.h>
+#include <s32cc-clk-utils.h>
+#include <s32cc-mc-me.h>
+
+#define MAX_STACK_DEPTH		(40U)
+
+/* This is used for floating-point precision calculations. */
+#define FP_PRECISION		(100000000UL)
+
+struct s32cc_clk_drv {
+	uintptr_t fxosc_base;
+	uintptr_t armpll_base;
+	uintptr_t periphpll_base;
+	uintptr_t armdfs_base;
+	uintptr_t cgm0_base;
+	uintptr_t cgm1_base;
+	uintptr_t cgm5_base;
+	uintptr_t ddrpll_base;
+	uintptr_t mc_me;
+	uintptr_t mc_rgm;
+	uintptr_t rdc;
+};
+
+static int update_stack_depth(unsigned int *depth)
+{
+	if (*depth == 0U) {
+		return -ENOMEM;
+	}
+
+	(*depth)--;
+	return 0;
+}
+
+static struct s32cc_clk_drv *get_drv(void)
+{
+	static struct s32cc_clk_drv driver = {
+		.fxosc_base = FXOSC_BASE_ADDR,
+		.armpll_base = ARMPLL_BASE_ADDR,
+		.periphpll_base = PERIPHPLL_BASE_ADDR,
+		.armdfs_base = ARM_DFS_BASE_ADDR,
+		.cgm0_base = CGM0_BASE_ADDR,
+		.cgm1_base = CGM1_BASE_ADDR,
+		.cgm5_base = MC_CGM5_BASE_ADDR,
+		.ddrpll_base = DDRPLL_BASE_ADDR,
+		.mc_me = MC_ME_BASE_ADDR,
+		.mc_rgm = MC_RGM_BASE_ADDR,
+		.rdc = RDC_BASE_ADDR,
+	};
+
+	return &driver;
+}
+
+static int enable_module(struct s32cc_clk_obj *module,
+			 const struct s32cc_clk_drv *drv,
+			 unsigned int depth);
+
+static struct s32cc_clk_obj *get_clk_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_clk *clk = s32cc_obj2clk(module);
+
+	if (clk->module != NULL) {
+		return clk->module;
+	}
+
+	if (clk->pclock != NULL) {
+		return &clk->pclock->desc;
+	}
+
+	return NULL;
+}
+
+static int get_base_addr(enum s32cc_clk_source id, const struct s32cc_clk_drv *drv,
+			 uintptr_t *base)
+{
+	int ret = 0;
+
+	switch (id) {
+	case S32CC_FXOSC:
+		*base = drv->fxosc_base;
+		break;
+	case S32CC_ARM_PLL:
+		*base = drv->armpll_base;
+		break;
+	case S32CC_PERIPH_PLL:
+		*base = drv->periphpll_base;
+		break;
+	case S32CC_DDR_PLL:
+		*base = drv->ddrpll_base;
+		break;
+	case S32CC_ARM_DFS:
+		*base = drv->armdfs_base;
+		break;
+	case S32CC_CGM0:
+		*base = drv->cgm0_base;
+		break;
+	case S32CC_CGM1:
+		*base = drv->cgm1_base;
+		break;
+	case S32CC_CGM5:
+		*base = drv->cgm5_base;
+		break;
+	case S32CC_FIRC:
+		break;
+	case S32CC_SIRC:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ret != 0) {
+		ERROR("Unknown clock source id: %u\n", id);
+	}
+
+	return ret;
+}
+
+static void enable_fxosc(const struct s32cc_clk_drv *drv)
+{
+	uintptr_t fxosc_base = drv->fxosc_base;
+	uint32_t ctrl;
+
+	ctrl = mmio_read_32(FXOSC_CTRL(fxosc_base));
+	if ((ctrl & FXOSC_CTRL_OSCON) != U(0)) {
+		return;
+	}
+
+	ctrl = FXOSC_CTRL_COMP_EN;
+	ctrl &= ~FXOSC_CTRL_OSC_BYP;
+	ctrl |= FXOSC_CTRL_EOCV(0x1);
+	ctrl |= FXOSC_CTRL_GM_SEL(0x7);
+	mmio_write_32(FXOSC_CTRL(fxosc_base), ctrl);
+
+	/* Switch ON the crystal oscillator. */
+	mmio_setbits_32(FXOSC_CTRL(fxosc_base), FXOSC_CTRL_OSCON);
+
+	/* Wait until the clock is stable. */
+	while ((mmio_read_32(FXOSC_STAT(fxosc_base)) & FXOSC_STAT_OSC_STAT) == U(0)) {
+	}
+}
+
+static int enable_osc(struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int depth)
+{
+	const struct s32cc_osc *osc = s32cc_obj2osc(module);
+	unsigned int ldepth = depth;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	switch (osc->source) {
+	case S32CC_FXOSC:
+		enable_fxosc(drv);
+		break;
+	/* FIRC and SIRC oscillators are enabled by default */
+	case S32CC_FIRC:
+		break;
+	case S32CC_SIRC:
+		break;
+	default:
+		ERROR("Invalid oscillator %d\n", osc->source);
+		ret = -EINVAL;
+		break;
+	};
+
+	return ret;
+}
+
+static struct s32cc_clk_obj *get_pll_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_pll *pll = s32cc_obj2pll(module);
+
+	if (pll->source == NULL) {
+		ERROR("Failed to identify PLL's parent\n");
+	}
+
+	return pll->source;
+}
+
+static int get_pll_mfi_mfn(unsigned long pll_vco, unsigned long ref_freq,
+			   uint32_t *mfi, uint32_t *mfn)
+
+{
+	unsigned long vco;
+	unsigned long mfn64;
+
+	/* FRAC-N mode */
+	*mfi = (uint32_t)(pll_vco / ref_freq);
+
+	/* MFN formula : (double)(pll_vco % ref_freq) / ref_freq * 18432.0 */
+	mfn64 = pll_vco % ref_freq;
+	mfn64 *= FP_PRECISION;
+	mfn64 /= ref_freq;
+	mfn64 *= 18432UL;
+	mfn64 /= FP_PRECISION;
+
+	if (mfn64 > UINT32_MAX) {
+		return -EINVAL;
+	}
+
+	*mfn = (uint32_t)mfn64;
+
+	vco = ((unsigned long)*mfn * FP_PRECISION) / 18432UL;
+	vco += (unsigned long)*mfi * FP_PRECISION;
+	vco *= ref_freq;
+	vco /= FP_PRECISION;
+
+	if (vco != pll_vco) {
+		ERROR("Failed to find MFI and MFN settings for PLL freq %lu. Nearest freq = %lu\n",
+		      pll_vco, vco);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct s32cc_clkmux *get_pll_mux(const struct s32cc_pll *pll)
+{
+	const struct s32cc_clk_obj *source = pll->source;
+	const struct s32cc_clk *clk;
+
+	if (source == NULL) {
+		ERROR("Failed to identify PLL's parent\n");
+		return NULL;
+	}
+
+	if (source->type != s32cc_clk_t) {
+		ERROR("The parent of the PLL isn't a clock\n");
+		return NULL;
+	}
+
+	clk = s32cc_obj2clk(source);
+
+	if (clk->module == NULL) {
+		ERROR("The clock isn't connected to a module\n");
+		return NULL;
+	}
+
+	source = clk->module;
+
+	if ((source->type != s32cc_clkmux_t) &&
+	    (source->type != s32cc_shared_clkmux_t)) {
+		ERROR("The parent of the PLL isn't a MUX\n");
+		return NULL;
+	}
+
+	return s32cc_obj2clkmux(source);
+}
+
+static void disable_odiv(uintptr_t pll_addr, uint32_t div_index)
+{
+	mmio_clrbits_32(PLLDIG_PLLODIV(pll_addr, div_index), PLLDIG_PLLODIV_DE);
+}
+
+static void enable_odiv(uintptr_t pll_addr, uint32_t div_index)
+{
+	mmio_setbits_32(PLLDIG_PLLODIV(pll_addr, div_index), PLLDIG_PLLODIV_DE);
+}
+
+static void disable_odivs(uintptr_t pll_addr, uint32_t ndivs)
+{
+	uint32_t i;
+
+	for (i = 0; i < ndivs; i++) {
+		disable_odiv(pll_addr, i);
+	}
+}
+
+static void enable_pll_hw(uintptr_t pll_addr)
+{
+	/* Enable the PLL. */
+	mmio_write_32(PLLDIG_PLLCR(pll_addr), 0x0);
+
+	/* Poll until PLL acquires lock. */
+	while ((mmio_read_32(PLLDIG_PLLSR(pll_addr)) & PLLDIG_PLLSR_LOCK) == 0U) {
+	}
+}
+
+static void disable_pll_hw(uintptr_t pll_addr)
+{
+	mmio_write_32(PLLDIG_PLLCR(pll_addr), PLLDIG_PLLCR_PLLPD);
+}
+
+static int program_pll(const struct s32cc_pll *pll, uintptr_t pll_addr,
+		       const struct s32cc_clk_drv *drv, uint32_t sclk_id,
+		       unsigned long sclk_freq)
+{
+	uint32_t rdiv = 1, mfi, mfn;
+	int ret;
+
+	ret = get_pll_mfi_mfn(pll->vco_freq, sclk_freq, &mfi, &mfn);
+	if (ret != 0) {
+		return -EINVAL;
+	}
+
+	/* Disable ODIVs*/
+	disable_odivs(pll_addr, pll->ndividers);
+
+	/* Disable PLL */
+	disable_pll_hw(pll_addr);
+
+	/* Program PLLCLKMUX */
+	mmio_write_32(PLLDIG_PLLCLKMUX(pll_addr), sclk_id);
+
+	/* Program VCO */
+	mmio_clrsetbits_32(PLLDIG_PLLDV(pll_addr),
+			   PLLDIG_PLLDV_RDIV_MASK | PLLDIG_PLLDV_MFI_MASK,
+			   PLLDIG_PLLDV_RDIV_SET(rdiv) | PLLDIG_PLLDV_MFI(mfi));
+
+	mmio_write_32(PLLDIG_PLLFD(pll_addr),
+		      PLLDIG_PLLFD_MFN_SET(mfn) | PLLDIG_PLLFD_SMDEN);
+
+	enable_pll_hw(pll_addr);
+
+	return ret;
+}
+
+static int enable_pll(struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int depth)
+{
+	const struct s32cc_pll *pll = s32cc_obj2pll(module);
+	const struct s32cc_clkmux *mux;
+	uintptr_t pll_addr = UL(0x0);
+	unsigned int ldepth = depth;
+	unsigned long sclk_freq;
+	uint32_t sclk_id;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	mux = get_pll_mux(pll);
+	if (mux == NULL) {
+		return -EINVAL;
+	}
+
+	if (pll->instance != mux->module) {
+		ERROR("MUX type is not in sync with PLL ID\n");
+		return -EINVAL;
+	}
+
+	ret = get_base_addr(pll->instance, drv, &pll_addr);
+	if (ret != 0) {
+		ERROR("Failed to detect PLL instance\n");
+		return ret;
+	}
+
+	switch (mux->source_id) {
+	case S32CC_CLK_FIRC:
+		sclk_freq = 48U * MHZ;
+		sclk_id = 0;
+		break;
+	case S32CC_CLK_FXOSC:
+		sclk_freq = 40U * MHZ;
+		sclk_id = 1;
+		break;
+	default:
+		ERROR("Invalid source selection for PLL 0x%lx\n",
+		      pll_addr);
+		return -EINVAL;
+	};
+
+	return program_pll(pll, pll_addr, drv, sclk_id, sclk_freq);
+}
+
+static inline struct s32cc_pll *get_div_pll(const struct s32cc_pll_out_div *pdiv)
+{
+	const struct s32cc_clk_obj *parent;
+
+	parent = pdiv->parent;
+	if (parent == NULL) {
+		ERROR("Failed to identify PLL divider's parent\n");
+		return NULL;
+	}
+
+	if (parent->type != s32cc_pll_t) {
+		ERROR("The parent of the divider is not a PLL instance\n");
+		return NULL;
+	}
+
+	return s32cc_obj2pll(parent);
+}
+
+static void config_pll_out_div(uintptr_t pll_addr, uint32_t div_index, uint32_t dc)
+{
+	uint32_t pllodiv;
+	uint32_t pdiv;
+
+	pllodiv = mmio_read_32(PLLDIG_PLLODIV(pll_addr, div_index));
+	pdiv = PLLDIG_PLLODIV_DIV(pllodiv);
+
+	if (((pdiv + 1U) == dc) && ((pllodiv & PLLDIG_PLLODIV_DE) != 0U)) {
+		return;
+	}
+
+	if ((pllodiv & PLLDIG_PLLODIV_DE) != 0U) {
+		disable_odiv(pll_addr, div_index);
+	}
+
+	pllodiv = PLLDIG_PLLODIV_DIV_SET(dc - 1U);
+	mmio_write_32(PLLDIG_PLLODIV(pll_addr, div_index), pllodiv);
+
+	enable_odiv(pll_addr, div_index);
+}
+
+static struct s32cc_clk_obj *get_pll_div_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module);
+
+	if (pdiv->parent == NULL) {
+		ERROR("Failed to identify PLL DIV's parent\n");
+	}
+
+	return pdiv->parent;
+}
+
+static int enable_pll_div(struct s32cc_clk_obj *module,
+			  const struct s32cc_clk_drv *drv,
+			  unsigned int depth)
+{
+	const struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module);
+	uintptr_t pll_addr = 0x0ULL;
+	unsigned int ldepth = depth;
+	const struct s32cc_pll *pll;
+	uint32_t dc;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	pll = get_div_pll(pdiv);
+	if (pll == NULL) {
+		ERROR("The parent of the PLL DIV is invalid\n");
+		return 0;
+	}
+
+	ret = get_base_addr(pll->instance, drv, &pll_addr);
+	if (ret != 0) {
+		ERROR("Failed to detect PLL instance\n");
+		return -EINVAL;
+	}
+
+	dc = (uint32_t)(pll->vco_freq / pdiv->freq);
+
+	config_pll_out_div(pll_addr, pdiv->index, dc);
+
+	return 0;
+}
+
+static int cgm_mux_clk_config(uintptr_t cgm_addr, uint32_t mux, uint32_t source,
+			      bool safe_clk)
+{
+	uint32_t css, csc;
+
+	css = mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux));
+
+	/* Already configured */
+	if ((MC_CGM_MUXn_CSS_SELSTAT(css) == source) &&
+	    (MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SUCCESS) &&
+	    ((css & MC_CGM_MUXn_CSS_SWIP) == 0U) && !safe_clk) {
+		return 0;
+	}
+
+	/* Ongoing clock switch? */
+	while ((mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux)) &
+		MC_CGM_MUXn_CSS_SWIP) != 0U) {
+	}
+
+	csc = mmio_read_32(CGM_MUXn_CSC(cgm_addr, mux));
+
+	/* Clear previous source. */
+	csc &= ~(MC_CGM_MUXn_CSC_SELCTL_MASK);
+
+	if (!safe_clk) {
+		/* Select the clock source and trigger the clock switch. */
+		csc |= MC_CGM_MUXn_CSC_SELCTL(source) | MC_CGM_MUXn_CSC_CLK_SW;
+	} else {
+		/* Switch to safe clock */
+		csc |= MC_CGM_MUXn_CSC_SAFE_SW;
+	}
+
+	mmio_write_32(CGM_MUXn_CSC(cgm_addr, mux), csc);
+
+	/* Wait for configuration bit to auto-clear. */
+	while ((mmio_read_32(CGM_MUXn_CSC(cgm_addr, mux)) &
+		MC_CGM_MUXn_CSC_CLK_SW) != 0U) {
+	}
+
+	/* Is the clock switch completed? */
+	while ((mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux)) &
+		MC_CGM_MUXn_CSS_SWIP) != 0U) {
+	}
+
+	/*
+	 * Check if the switch succeeded.
+	 * Check switch trigger cause and the source.
+	 */
+	css = mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux));
+	if (!safe_clk) {
+		if ((MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SUCCESS) &&
+		    (MC_CGM_MUXn_CSS_SELSTAT(css) == source)) {
+			return 0;
+		}
+
+		ERROR("Failed to change the source of mux %" PRIu32 " to %" PRIu32 " (CGM=%lu)\n",
+		      mux, source, cgm_addr);
+	} else {
+		if (((MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK) ||
+		     (MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK_INACTIVE)) &&
+		     ((MC_CGM_MUXn_CSS_SAFE_SW & css) != 0U)) {
+			return 0;
+		}
+
+		ERROR("The switch of mux %" PRIu32 " (CGM=%lu) to safe clock failed\n",
+		      mux, cgm_addr);
+	}
+
+	return -EINVAL;
+}
+
+static int enable_cgm_mux(const struct s32cc_clkmux *mux,
+			  const struct s32cc_clk_drv *drv)
+{
+	uintptr_t cgm_addr = UL(0x0);
+	uint32_t mux_hw_clk;
+	int ret;
+
+	ret = get_base_addr(mux->module, drv, &cgm_addr);
+	if (ret != 0) {
+		return ret;
+	}
+
+	mux_hw_clk = (uint32_t)S32CC_CLK_ID(mux->source_id);
+
+	return cgm_mux_clk_config(cgm_addr, mux->index,
+				  mux_hw_clk, false);
+}
+
+static struct s32cc_clk_obj *get_mux_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_clkmux *mux = s32cc_obj2clkmux(module);
+	struct s32cc_clk *clk;
+
+	if (mux == NULL) {
+		return NULL;
+	}
+
+	clk = s32cc_get_arch_clk(mux->source_id);
+	if (clk == NULL) {
+		ERROR("Invalid parent (%lu) for mux %" PRIu8 "\n",
+		      mux->source_id, mux->index);
+		return NULL;
+	}
+
+	return &clk->desc;
+}
+
+static int enable_mux(struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int depth)
+{
+	const struct s32cc_clkmux *mux = s32cc_obj2clkmux(module);
+	unsigned int ldepth = depth;
+	const struct s32cc_clk *clk;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (mux == NULL) {
+		return -EINVAL;
+	}
+
+	clk = s32cc_get_arch_clk(mux->source_id);
+	if (clk == NULL) {
+		ERROR("Invalid parent (%lu) for mux %" PRIu8 "\n",
+		      mux->source_id, mux->index);
+		return -EINVAL;
+	}
+
+	switch (mux->module) {
+	/* PLL mux will be enabled by PLL setup */
+	case S32CC_ARM_PLL:
+	case S32CC_PERIPH_PLL:
+	case S32CC_DDR_PLL:
+		break;
+	case S32CC_CGM1:
+		ret = enable_cgm_mux(mux, drv);
+		break;
+	case S32CC_CGM0:
+		ret = enable_cgm_mux(mux, drv);
+		break;
+	case S32CC_CGM5:
+		ret = enable_cgm_mux(mux, drv);
+		break;
+	default:
+		ERROR("Unknown mux parent type: %d\n", mux->module);
+		ret = -EINVAL;
+		break;
+	};
+
+	return ret;
+}
+
+static struct s32cc_clk_obj *get_dfs_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_dfs *dfs = s32cc_obj2dfs(module);
+
+	if (dfs->parent == NULL) {
+		ERROR("Failed to identify DFS's parent\n");
+	}
+
+	return dfs->parent;
+}
+
+static int enable_dfs(struct s32cc_clk_obj *module,
+		      const struct s32cc_clk_drv *drv,
+		      unsigned int depth)
+{
+	unsigned int ldepth = depth;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct s32cc_dfs *get_div_dfs(const struct s32cc_dfs_div *dfs_div)
+{
+	const struct s32cc_clk_obj *parent = dfs_div->parent;
+
+	if (parent->type != s32cc_dfs_t) {
+		ERROR("DFS DIV doesn't have a DFS as parent\n");
+		return NULL;
+	}
+
+	return s32cc_obj2dfs(parent);
+}
+
+static struct s32cc_pll *dfsdiv2pll(const struct s32cc_dfs_div *dfs_div)
+{
+	const struct s32cc_clk_obj *parent;
+	const struct s32cc_dfs *dfs;
+
+	dfs = get_div_dfs(dfs_div);
+	if (dfs == NULL) {
+		return NULL;
+	}
+
+	parent = dfs->parent;
+	if (parent->type != s32cc_pll_t) {
+		return NULL;
+	}
+
+	return s32cc_obj2pll(parent);
+}
+
+static int get_dfs_mfi_mfn(unsigned long dfs_freq, const struct s32cc_dfs_div *dfs_div,
+			   uint32_t *mfi, uint32_t *mfn)
+{
+	uint64_t factor64, tmp64, ofreq;
+	uint32_t factor32;
+
+	unsigned long in = dfs_freq;
+	unsigned long out = dfs_div->freq;
+
+	/**
+	 * factor = (IN / OUT) / 2
+	 * MFI = integer(factor)
+	 * MFN = (factor - MFI) * 36
+	 */
+	factor64 = ((((uint64_t)in) * FP_PRECISION) / ((uint64_t)out)) / 2ULL;
+	tmp64 = factor64 / FP_PRECISION;
+	if (tmp64 > UINT32_MAX) {
+		return -EINVAL;
+	}
+
+	factor32 = (uint32_t)tmp64;
+	*mfi = factor32;
+
+	tmp64 = ((factor64 - ((uint64_t)*mfi * FP_PRECISION)) * 36UL) / FP_PRECISION;
+	if (tmp64 > UINT32_MAX) {
+		return -EINVAL;
+	}
+
+	*mfn = (uint32_t)tmp64;
+
+	/* div_freq = in / (2 * (*mfi + *mfn / 36.0)) */
+	factor64 = (((uint64_t)*mfn) * FP_PRECISION) / 36ULL;
+	factor64 += ((uint64_t)*mfi) * FP_PRECISION;
+	factor64 *= 2ULL;
+	ofreq = (((uint64_t)in) * FP_PRECISION) / factor64;
+
+	if (ofreq != dfs_div->freq) {
+		ERROR("Failed to find MFI and MFN settings for DFS DIV freq %lu\n",
+		      dfs_div->freq);
+		ERROR("Nearest freq = %" PRIx64 "\n", ofreq);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int init_dfs_port(uintptr_t dfs_addr, uint32_t port,
+			 uint32_t mfi, uint32_t mfn)
+{
+	uint32_t portsr, portolsr;
+	uint32_t mask, old_mfi, old_mfn;
+	uint32_t dvport;
+	bool init_dfs;
+
+	dvport = mmio_read_32(DFS_DVPORTn(dfs_addr, port));
+
+	old_mfi = DFS_DVPORTn_MFI(dvport);
+	old_mfn = DFS_DVPORTn_MFN(dvport);
+
+	portsr = mmio_read_32(DFS_PORTSR(dfs_addr));
+	portolsr = mmio_read_32(DFS_PORTOLSR(dfs_addr));
+
+	/* Skip configuration if it's not needed */
+	if (((portsr & BIT_32(port)) != 0U) &&
+	    ((portolsr & BIT_32(port)) == 0U) &&
+	    (mfi == old_mfi) && (mfn == old_mfn)) {
+		return 0;
+	}
+
+	init_dfs = (portsr == 0U);
+
+	if (init_dfs) {
+		mask = DFS_PORTRESET_MASK;
+	} else {
+		mask = DFS_PORTRESET_SET(BIT_32(port));
+	}
+
+	mmio_write_32(DFS_PORTOLSR(dfs_addr), mask);
+	mmio_write_32(DFS_PORTRESET(dfs_addr), mask);
+
+	while ((mmio_read_32(DFS_PORTSR(dfs_addr)) & mask) != 0U) {
+	}
+
+	if (init_dfs) {
+		mmio_write_32(DFS_CTL(dfs_addr), DFS_CTL_RESET);
+	}
+
+	mmio_write_32(DFS_DVPORTn(dfs_addr, port),
+		      DFS_DVPORTn_MFI_SET(mfi) | DFS_DVPORTn_MFN_SET(mfn));
+
+	if (init_dfs) {
+		/* DFS clk enable programming */
+		mmio_clrbits_32(DFS_CTL(dfs_addr), DFS_CTL_RESET);
+	}
+
+	mmio_clrbits_32(DFS_PORTRESET(dfs_addr), BIT_32(port));
+
+	while ((mmio_read_32(DFS_PORTSR(dfs_addr)) & BIT_32(port)) != BIT_32(port)) {
+	}
+
+	portolsr = mmio_read_32(DFS_PORTOLSR(dfs_addr));
+	if ((portolsr & DFS_PORTOLSR_LOL(port)) != 0U) {
+		ERROR("Failed to lock DFS divider\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct s32cc_clk_obj *
+get_dfs_div_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module);
+
+	if (dfs_div->parent == NULL) {
+		ERROR("Failed to identify DFS divider's parent\n");
+	}
+
+	return dfs_div->parent;
+}
+
+static int enable_dfs_div(struct s32cc_clk_obj *module,
+			  const struct s32cc_clk_drv *drv,
+			  unsigned int depth)
+{
+	const struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module);
+	unsigned int ldepth = depth;
+	const struct s32cc_pll *pll;
+	const struct s32cc_dfs *dfs;
+	uintptr_t dfs_addr = 0UL;
+	uint32_t mfi, mfn;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	dfs = get_div_dfs(dfs_div);
+	if (dfs == NULL) {
+		return -EINVAL;
+	}
+
+	pll = dfsdiv2pll(dfs_div);
+	if (pll == NULL) {
+		ERROR("Failed to identify DFS divider's parent\n");
+		return -EINVAL;
+	}
+
+	ret = get_base_addr(dfs->instance, drv, &dfs_addr);
+	if ((ret != 0) || (dfs_addr == 0UL)) {
+		return -EINVAL;
+	}
+
+	ret = get_dfs_mfi_mfn(pll->vco_freq, dfs_div, &mfi, &mfn);
+	if (ret != 0) {
+		return -EINVAL;
+	}
+
+	return init_dfs_port(dfs_addr, dfs_div->index, mfi, mfn);
+}
+
+typedef int (*enable_clk_t)(struct s32cc_clk_obj *module,
+			    const struct s32cc_clk_drv *drv,
+			    unsigned int depth);
+
+static int enable_part(struct s32cc_clk_obj *module,
+		       const struct s32cc_clk_drv *drv,
+		       unsigned int depth)
+{
+	const struct s32cc_part *part = s32cc_obj2part(module);
+	uint32_t part_no = part->partition_id;
+
+	if ((drv->mc_me == 0UL) || (drv->mc_rgm == 0UL) || (drv->rdc == 0UL)) {
+		return -EINVAL;
+	}
+
+	return mc_me_enable_partition(drv->mc_me, drv->mc_rgm, drv->rdc, part_no);
+}
+
+static int enable_part_block(struct s32cc_clk_obj *module,
+			     const struct s32cc_clk_drv *drv,
+			     unsigned int depth)
+{
+	const struct s32cc_part_block *block = s32cc_obj2partblock(module);
+	const struct s32cc_part *part = block->part;
+	uint32_t part_no = part->partition_id;
+	unsigned int ldepth = depth;
+	uint32_t cofb;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((block->block >= s32cc_part_block0) &&
+	    (block->block <= s32cc_part_block15)) {
+		cofb = (uint32_t)block->block - (uint32_t)s32cc_part_block0;
+		mc_me_enable_part_cofb(drv->mc_me, part_no, cofb, block->status);
+	} else {
+		ERROR("Unknown partition block type: %d\n", block->block);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct s32cc_clk_obj *
+get_part_block_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_part_block *block = s32cc_obj2partblock(module);
+
+	return &block->part->desc;
+}
+
+static int enable_module_with_refcount(struct s32cc_clk_obj *module,
+				       const struct s32cc_clk_drv *drv,
+				       unsigned int depth);
+
+static int enable_part_block_link(struct s32cc_clk_obj *module,
+				  const struct s32cc_clk_drv *drv,
+				  unsigned int depth)
+{
+	const struct s32cc_part_block_link *link = s32cc_obj2partblocklink(module);
+	struct s32cc_part_block *block = link->block;
+	unsigned int ldepth = depth;
+	int ret;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Move the enablement algorithm to partition tree */
+	return enable_module_with_refcount(&block->desc, drv, ldepth);
+}
+
+static struct s32cc_clk_obj *
+get_part_block_link_parent(const struct s32cc_clk_obj *module)
+{
+	const struct s32cc_part_block_link *link = s32cc_obj2partblocklink(module);
+
+	return link->parent;
+}
+
+static int no_enable(struct s32cc_clk_obj *module,
+		     const struct s32cc_clk_drv *drv,
+		     unsigned int depth)
+{
+	return 0;
+}
+
+static int exec_cb_with_refcount(enable_clk_t en_cb, struct s32cc_clk_obj *mod,
+				 const struct s32cc_clk_drv *drv, bool leaf_node,
+				 unsigned int depth)
+{
+	unsigned int ldepth = depth;
+	int ret = 0;
+
+	if (mod == NULL) {
+		return 0;
+	}
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Refcount will be updated as part of the recursivity */
+	if (leaf_node) {
+		return en_cb(mod, drv, ldepth);
+	}
+
+	if (mod->refcount == 0U) {
+		ret = en_cb(mod, drv, ldepth);
+	}
+
+	if (ret == 0) {
+		mod->refcount++;
+	}
+
+	return ret;
+}
+
+static struct s32cc_clk_obj *get_module_parent(const struct s32cc_clk_obj *module);
+
+static int enable_module(struct s32cc_clk_obj *module,
+			 const struct s32cc_clk_drv *drv,
+			 unsigned int depth)
+{
+	struct s32cc_clk_obj *parent = get_module_parent(module);
+	static const enable_clk_t enable_clbs[12] = {
+		[s32cc_clk_t] = no_enable,
+		[s32cc_osc_t] = enable_osc,
+		[s32cc_pll_t] = enable_pll,
+		[s32cc_pll_out_div_t] = enable_pll_div,
+		[s32cc_clkmux_t] = enable_mux,
+		[s32cc_shared_clkmux_t] = enable_mux,
+		[s32cc_dfs_t] = enable_dfs,
+		[s32cc_dfs_div_t] = enable_dfs_div,
+		[s32cc_part_t] = enable_part,
+		[s32cc_part_block_t] = enable_part_block,
+		[s32cc_part_block_link_t] = enable_part_block_link,
+	};
+	unsigned int ldepth = depth;
+	uint32_t index;
+	int ret = 0;
+
+	ret = update_stack_depth(&ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (drv == NULL) {
+		return -EINVAL;
+	}
+
+	index = (uint32_t)module->type;
+
+	if (index >= ARRAY_SIZE(enable_clbs)) {
+		ERROR("Undefined module type: %d\n", module->type);
+		return -EINVAL;
+	}
+
+	if (enable_clbs[index] == NULL) {
+		ERROR("Undefined callback for the clock type: %d\n",
+		      module->type);
+		return -EINVAL;
+	}
+
+	parent = get_module_parent(module);
+
+	ret = exec_cb_with_refcount(enable_module, parent, drv,
+				    false, ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = exec_cb_with_refcount(enable_clbs[index], module, drv,
+				    true, ldepth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_module_with_refcount(struct s32cc_clk_obj *module,
+				       const struct s32cc_clk_drv *drv,
+				       unsigned int depth)
+{
+	return exec_cb_with_refcount(enable_module, module, drv, false, depth);
+}
+
+static int s32cc_clk_enable(unsigned long id)
+{
+	const struct s32cc_clk_drv *drv = get_drv();
+	unsigned int depth = MAX_STACK_DEPTH;
+	struct s32cc_clk *clk;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	return enable_module_with_refcount(&clk->desc, drv, depth);
+}
+
+static void s32cc_clk_disable(unsigned long id)
+{
+}
+
+static bool s32cc_clk_is_enabled(unsigned long id)
+{
+	return false;
+}
+
+static unsigned long s32cc_clk_get_rate(unsigned long id)
+{
+	return 0;
+}
+
+static int set_module_rate(const struct s32cc_clk_obj *module,
+			   unsigned long rate, unsigned long *orate,
+			   unsigned int *depth);
+
+static int set_osc_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_osc *osc = s32cc_obj2osc(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((osc->freq != 0UL) && (rate != osc->freq)) {
+		ERROR("Already initialized oscillator. freq = %lu\n",
+		      osc->freq);
+		return -EINVAL;
+	}
+
+	osc->freq = rate;
+	*orate = osc->freq;
+
+	return 0;
+}
+
+static int set_clk_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	const struct s32cc_clk *clk = s32cc_obj2clk(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((clk->min_freq != 0UL) && (clk->max_freq != 0UL) &&
+	    ((rate < clk->min_freq) || (rate > clk->max_freq))) {
+		ERROR("%lu frequency is out of the allowed range: [%lu:%lu]\n",
+		      rate, clk->min_freq, clk->max_freq);
+		return -EINVAL;
+	}
+
+	if (clk->module != NULL) {
+		return set_module_rate(clk->module, rate, orate, depth);
+	}
+
+	if (clk->pclock != NULL) {
+		return set_clk_freq(&clk->pclock->desc, rate, orate, depth);
+	}
+
+	return -EINVAL;
+}
+
+static int set_pll_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_pll *pll = s32cc_obj2pll(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((pll->vco_freq != 0UL) && (pll->vco_freq != rate)) {
+		ERROR("PLL frequency was already set\n");
+		return -EINVAL;
+	}
+
+	pll->vco_freq = rate;
+	*orate = pll->vco_freq;
+
+	return 0;
+}
+
+static int set_pll_div_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			    unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module);
+	const struct s32cc_pll *pll;
+	unsigned long prate, dc;
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (pdiv->parent == NULL) {
+		ERROR("Failed to identify PLL divider's parent\n");
+		return -EINVAL;
+	}
+
+	pll = s32cc_obj2pll(pdiv->parent);
+	if (pll == NULL) {
+		ERROR("The parent of the PLL DIV is invalid\n");
+		return -EINVAL;
+	}
+
+	prate = pll->vco_freq;
+
+	/**
+	 * The PLL is not initialized yet, so let's take a risk
+	 * and accept the proposed rate.
+	 */
+	if (prate == 0UL) {
+		pdiv->freq = rate;
+		*orate = rate;
+		return 0;
+	}
+
+	/* Decline in case the rate cannot fit PLL's requirements. */
+	dc = prate / rate;
+	if ((prate / dc) != rate) {
+		return -EINVAL;
+	}
+
+	pdiv->freq = rate;
+	*orate = pdiv->freq;
+
+	return 0;
+}
+
+static int set_fixed_div_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			      unsigned long *orate, unsigned int *depth)
+{
+	const struct s32cc_fixed_div *fdiv = s32cc_obj2fixeddiv(module);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (fdiv->parent == NULL) {
+		ERROR("The divider doesn't have a valid parent\b");
+		return -EINVAL;
+	}
+
+	ret = set_module_rate(fdiv->parent, rate * fdiv->rate_div, orate, depth);
+
+	/* Update the output rate based on the parent's rate */
+	*orate /= fdiv->rate_div;
+
+	return ret;
+}
+
+static int set_mux_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			unsigned long *orate, unsigned int *depth)
+{
+	const struct s32cc_clkmux *mux = s32cc_obj2clkmux(module);
+	const struct s32cc_clk *clk = s32cc_get_arch_clk(mux->source_id);
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (clk == NULL) {
+		ERROR("Mux (id:%" PRIu8 ") without a valid source (%lu)\n",
+		      mux->index, mux->source_id);
+		return -EINVAL;
+	}
+
+	return set_module_rate(&clk->desc, rate, orate, depth);
+}
+
+static int set_dfs_div_freq(const struct s32cc_clk_obj *module, unsigned long rate,
+			    unsigned long *orate, unsigned int *depth)
+{
+	struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module);
+	const struct s32cc_dfs *dfs;
+	int ret;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (dfs_div->parent == NULL) {
+		ERROR("Failed to identify DFS divider's parent\n");
+		return -EINVAL;
+	}
+
+	/* Sanity check */
+	dfs = s32cc_obj2dfs(dfs_div->parent);
+	if (dfs->parent == NULL) {
+		ERROR("Failed to identify DFS's parent\n");
+		return -EINVAL;
+	}
+
+	if ((dfs_div->freq != 0U) && (dfs_div->freq != rate)) {
+		ERROR("DFS DIV frequency was already set to %lu\n",
+		      dfs_div->freq);
+		return -EINVAL;
+	}
+
+	dfs_div->freq = rate;
+	*orate = rate;
+
+	return ret;
+}
+
+static int set_module_rate(const struct s32cc_clk_obj *module,
+			   unsigned long rate, unsigned long *orate,
+			   unsigned int *depth)
+{
+	int ret = 0;
+
+	ret = update_stack_depth(depth);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = -EINVAL;
+
+	switch (module->type) {
+	case s32cc_clk_t:
+		ret = set_clk_freq(module, rate, orate, depth);
+		break;
+	case s32cc_osc_t:
+		ret = set_osc_freq(module, rate, orate, depth);
+		break;
+	case s32cc_pll_t:
+		ret = set_pll_freq(module, rate, orate, depth);
+		break;
+	case s32cc_pll_out_div_t:
+		ret = set_pll_div_freq(module, rate, orate, depth);
+		break;
+	case s32cc_fixed_div_t:
+		ret = set_fixed_div_freq(module, rate, orate, depth);
+		break;
+	case s32cc_clkmux_t:
+		ret = set_mux_freq(module, rate, orate, depth);
+		break;
+	case s32cc_shared_clkmux_t:
+		ret = set_mux_freq(module, rate, orate, depth);
+		break;
+	case s32cc_dfs_t:
+		ERROR("Setting the frequency of a DFS is not allowed!");
+		break;
+	case s32cc_dfs_div_t:
+		ret = set_dfs_div_freq(module, rate, orate, depth);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int s32cc_clk_set_rate(unsigned long id, unsigned long rate,
+			      unsigned long *orate)
+{
+	unsigned int depth = MAX_STACK_DEPTH;
+	const struct s32cc_clk *clk;
+	int ret;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	ret = set_module_rate(&clk->desc, rate, orate, &depth);
+	if (ret != 0) {
+		ERROR("Failed to set frequency (%lu MHz) for clock %lu\n",
+		      rate, id);
+	}
+
+	return ret;
+}
+
+static struct s32cc_clk_obj *get_no_parent(const struct s32cc_clk_obj *module)
+{
+	return NULL;
+}
+
+typedef struct s32cc_clk_obj *(*get_parent_clb_t)(const struct s32cc_clk_obj *clk_obj);
+
+static struct s32cc_clk_obj *get_module_parent(const struct s32cc_clk_obj *module)
+{
+	static const get_parent_clb_t parents_clbs[12] = {
+		[s32cc_clk_t] = get_clk_parent,
+		[s32cc_osc_t] = get_no_parent,
+		[s32cc_pll_t] = get_pll_parent,
+		[s32cc_pll_out_div_t] = get_pll_div_parent,
+		[s32cc_clkmux_t] = get_mux_parent,
+		[s32cc_shared_clkmux_t] = get_mux_parent,
+		[s32cc_dfs_t] = get_dfs_parent,
+		[s32cc_dfs_div_t] = get_dfs_div_parent,
+		[s32cc_part_t] = get_no_parent,
+		[s32cc_part_block_t] = get_part_block_parent,
+		[s32cc_part_block_link_t] = get_part_block_link_parent,
+	};
+	uint32_t index;
+
+	if (module == NULL) {
+		return NULL;
+	}
+
+	index = (uint32_t)module->type;
+
+	if (index >= ARRAY_SIZE(parents_clbs)) {
+		ERROR("Undefined module type: %d\n", module->type);
+		return NULL;
+	}
+
+	if (parents_clbs[index] == NULL) {
+		ERROR("Undefined parent getter for type: %d\n", module->type);
+		return NULL;
+	}
+
+	return parents_clbs[index](module);
+}
+
+static int s32cc_clk_get_parent(unsigned long id)
+{
+	struct s32cc_clk *parent_clk;
+	const struct s32cc_clk_obj *parent;
+	const struct s32cc_clk *clk;
+	unsigned long parent_id;
+	int ret;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	parent = get_module_parent(clk->module);
+	if (parent == NULL) {
+		return -EINVAL;
+	}
+
+	parent_clk = s32cc_obj2clk(parent);
+	if (parent_clk == NULL) {
+		return -EINVAL;
+	}
+
+	ret = s32cc_get_clk_id(parent_clk, &parent_id);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (parent_id > (unsigned long)INT_MAX) {
+		return -E2BIG;
+	}
+
+	return (int)parent_id;
+}
+
+static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id)
+{
+	const struct s32cc_clk *parent;
+	const struct s32cc_clk *clk;
+	bool valid_source = false;
+	struct s32cc_clkmux *mux;
+	uint8_t i;
+
+	clk = s32cc_get_arch_clk(id);
+	if (clk == NULL) {
+		return -EINVAL;
+	}
+
+	parent = s32cc_get_arch_clk(parent_id);
+	if (parent == NULL) {
+		return -EINVAL;
+	}
+
+	if (!is_s32cc_clk_mux(clk)) {
+		ERROR("Clock %lu is not a mux\n", id);
+		return -EINVAL;
+	}
+
+	mux = s32cc_clk2mux(clk);
+	if (mux == NULL) {
+		ERROR("Failed to cast clock %lu to clock mux\n", id);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < mux->nclks; i++) {
+		if (mux->clkids[i] == parent_id) {
+			valid_source = true;
+			break;
+		}
+	}
+
+	if (!valid_source) {
+		ERROR("Clock %lu is not a valid clock for mux %lu\n",
+		      parent_id, id);
+		return -EINVAL;
+	}
+
+	mux->source_id = parent_id;
+
+	return 0;
+}
+
+void s32cc_clk_register_drv(void)
+{
+	static const struct clk_ops s32cc_clk_ops = {
+		.enable		= s32cc_clk_enable,
+		.disable	= s32cc_clk_disable,
+		.is_enabled	= s32cc_clk_is_enabled,
+		.get_rate	= s32cc_clk_get_rate,
+		.set_rate	= s32cc_clk_set_rate,
+		.get_parent	= s32cc_clk_get_parent,
+		.set_parent	= s32cc_clk_set_parent,
+	};
+
+	clk_register(&s32cc_clk_ops);
+}
+
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_modules.c b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
new file mode 100644
index 00000000..71055abc
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_modules.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2020-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-modules.h>
+#include <s32cc-clk-utils.h>
+
+#define S32CC_A53_MIN_FREQ	(48UL * MHZ)
+#define S32CC_A53_MAX_FREQ	(1000UL * MHZ)
+
+/* Partitions */
+static struct s32cc_part part0 = S32CC_PART(0);
+
+/* Oscillators */
+static struct s32cc_osc fxosc =
+	S32CC_OSC_INIT(S32CC_FXOSC);
+static struct s32cc_clk fxosc_clk =
+	S32CC_MODULE_CLK(fxosc);
+
+static struct s32cc_osc firc =
+	S32CC_OSC_INIT(S32CC_FIRC);
+static struct s32cc_clk firc_clk =
+	S32CC_MODULE_CLK(firc);
+
+static struct s32cc_osc sirc =
+	S32CC_OSC_INIT(S32CC_SIRC);
+static struct s32cc_clk sirc_clk =
+	S32CC_MODULE_CLK(sirc);
+
+/* ARM PLL */
+static struct s32cc_clkmux arm_pll_mux =
+	S32CC_CLKMUX_INIT(S32CC_ARM_PLL, 0, 2,
+			  S32CC_CLK_FIRC,
+			  S32CC_CLK_FXOSC, 0, 0, 0);
+static struct s32cc_clk arm_pll_mux_clk =
+	S32CC_MODULE_CLK(arm_pll_mux);
+static struct s32cc_pll armpll =
+	S32CC_PLL_INIT(arm_pll_mux_clk, S32CC_ARM_PLL, 2);
+static struct s32cc_clk arm_pll_vco_clk =
+	S32CC_FREQ_MODULE_CLK(armpll, 1400 * MHZ, 2000 * MHZ);
+
+static struct s32cc_pll_out_div arm_pll_phi0_div =
+	S32CC_PLL_OUT_DIV_INIT(armpll, 0);
+static struct s32cc_clk arm_pll_phi0_clk =
+	S32CC_FREQ_MODULE_CLK(arm_pll_phi0_div, 0, GHZ);
+
+/* ARM DFS */
+static struct s32cc_dfs armdfs =
+	S32CC_DFS_INIT(armpll, S32CC_ARM_DFS);
+static struct s32cc_dfs_div arm_dfs1_div =
+	S32CC_DFS_DIV_INIT(armdfs, 0);
+static struct s32cc_clk arm_dfs1_clk =
+	S32CC_FREQ_MODULE_CLK(arm_dfs1_div, 0, 800 * MHZ);
+
+/* MC_CGM0 */
+static struct s32cc_clkmux cgm0_mux0 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM0, 0, 2,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_ARM_PLL_DFS1, 0, 0, 0);
+static struct s32cc_clk cgm0_mux0_clk = S32CC_MODULE_CLK(cgm0_mux0);
+
+static struct s32cc_clkmux cgm0_mux8 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM0, 8, 3,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_PERIPH_PLL_PHI3,
+				 S32CC_CLK_FXOSC, 0, 0);
+static struct s32cc_clk cgm0_mux8_clk = S32CC_MODULE_CLK(cgm0_mux8);
+
+/* XBAR */
+static struct s32cc_clk xbar_2x_clk =
+	S32CC_CHILD_CLK(cgm0_mux0_clk, 48 * MHZ, 800 * MHZ);
+static struct s32cc_fixed_div xbar_div2 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 2);
+static struct s32cc_clk xbar_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div2, 24 * MHZ, 400 * MHZ);
+static struct s32cc_fixed_div xbar_div4 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 4);
+static struct s32cc_clk xbar_div2_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div4, 12 * MHZ, 200 * MHZ);
+static struct s32cc_fixed_div xbar_div6 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 6);
+static struct s32cc_clk xbar_div3_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div6, 8 * MHZ, 133333333);
+static struct s32cc_fixed_div xbar_div8 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 8);
+static struct s32cc_clk xbar_div4_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div8, 6 * MHZ, 100 * MHZ);
+static struct s32cc_fixed_div xbar_div12 =
+	S32CC_FIXED_DIV_INIT(cgm0_mux0_clk, 12);
+static struct s32cc_clk xbar_div6_clk =
+	S32CC_FREQ_MODULE_CLK(xbar_div12, 4 * MHZ, 66666666);
+
+/* Linflex */
+static struct s32cc_clk linflex_baud_clk =
+	S32CC_CHILD_CLK(cgm0_mux8_clk, 19200, 133333333);
+static struct s32cc_fixed_div linflex_div =
+	S32CC_FIXED_DIV_INIT(linflex_baud_clk, 2);
+static struct s32cc_clk linflex_clk =
+	S32CC_FREQ_MODULE_CLK(linflex_div, 9600, 66666666);
+
+/* MC_CGM1 */
+static struct s32cc_clkmux cgm1_mux0 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM1, 0, 3,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_ARM_PLL_PHI0,
+				 S32CC_CLK_ARM_PLL_DFS2, 0, 0);
+static struct s32cc_clk cgm1_mux0_clk = S32CC_MODULE_CLK(cgm1_mux0);
+
+/* A53_CORE */
+static struct s32cc_clk a53_core_clk =
+	S32CC_FREQ_MODULE_CLK(cgm1_mux0_clk, S32CC_A53_MIN_FREQ,
+			      S32CC_A53_MAX_FREQ);
+/* A53_CORE_DIV2 */
+static struct s32cc_fixed_div a53_core_div2 =
+		S32CC_FIXED_DIV_INIT(cgm1_mux0_clk, 2);
+static struct s32cc_clk a53_core_div2_clk =
+	S32CC_FREQ_MODULE_CLK(a53_core_div2, S32CC_A53_MIN_FREQ / 2,
+			      S32CC_A53_MAX_FREQ / 2);
+/* A53_CORE_DIV10 */
+static struct s32cc_fixed_div a53_core_div10 =
+	S32CC_FIXED_DIV_INIT(cgm1_mux0_clk, 10);
+static struct s32cc_clk a53_core_div10_clk =
+	S32CC_FREQ_MODULE_CLK(a53_core_div10, S32CC_A53_MIN_FREQ / 10,
+			      S32CC_A53_MAX_FREQ / 10);
+
+/* PERIPH PLL */
+static struct s32cc_clkmux periph_pll_mux =
+	S32CC_CLKMUX_INIT(S32CC_PERIPH_PLL, 0, 2,
+			  S32CC_CLK_FIRC,
+			  S32CC_CLK_FXOSC, 0, 0, 0);
+static struct s32cc_clk periph_pll_mux_clk =
+	S32CC_MODULE_CLK(periph_pll_mux);
+static struct s32cc_pll periphpll =
+	S32CC_PLL_INIT(periph_pll_mux_clk, S32CC_PERIPH_PLL, 2);
+static struct s32cc_clk periph_pll_vco_clk =
+	S32CC_FREQ_MODULE_CLK(periphpll, 1300 * MHZ, 2 * GHZ);
+
+static struct s32cc_pll_out_div periph_pll_phi3_div =
+	S32CC_PLL_OUT_DIV_INIT(periphpll, 3);
+static struct s32cc_clk periph_pll_phi3_clk =
+	S32CC_FREQ_MODULE_CLK(periph_pll_phi3_div, 0, 133333333);
+
+/* DDR PLL */
+static struct s32cc_clkmux ddr_pll_mux =
+	S32CC_CLKMUX_INIT(S32CC_DDR_PLL, 0, 2,
+			  S32CC_CLK_FIRC,
+			  S32CC_CLK_FXOSC, 0, 0, 0);
+static struct s32cc_clk ddr_pll_mux_clk =
+	S32CC_MODULE_CLK(ddr_pll_mux);
+static struct s32cc_pll ddrpll =
+	S32CC_PLL_INIT(ddr_pll_mux_clk, S32CC_DDR_PLL, 1);
+static struct s32cc_clk ddr_pll_vco_clk =
+	S32CC_FREQ_MODULE_CLK(ddrpll, 1300 * MHZ, 1600 * MHZ);
+
+static struct s32cc_pll_out_div ddr_pll_phi0_div =
+	S32CC_PLL_OUT_DIV_INIT(ddrpll, 0);
+static struct s32cc_clk ddr_pll_phi0_clk =
+	S32CC_FREQ_MODULE_CLK(ddr_pll_phi0_div, 0, 800 * MHZ);
+
+/* MC_CGM5 */
+static struct s32cc_clkmux cgm5_mux0 =
+	S32CC_SHARED_CLKMUX_INIT(S32CC_CGM5, 0, 2,
+				 S32CC_CLK_FIRC,
+				 S32CC_CLK_DDR_PLL_PHI0,
+				 0, 0, 0);
+static struct s32cc_clk cgm5_mux0_clk = S32CC_MODULE_CLK(cgm5_mux0);
+
+/* DDR clock */
+static struct s32cc_part_block part0_block1 =
+	S32CC_PART_BLOCK(&part0, s32cc_part_block1);
+static struct s32cc_part_block_link ddr_block_link =
+	S32CC_PART_BLOCK_LINK(cgm5_mux0_clk, &part0_block1);
+static struct s32cc_clk ddr_clk =
+	S32CC_FREQ_MODULE_CLK(ddr_block_link, 0, 800 * MHZ);
+
+static struct s32cc_clk *s32cc_hw_clk_list[37] = {
+	/* Oscillators */
+	[S32CC_CLK_ID(S32CC_CLK_FIRC)] = &firc_clk,
+	[S32CC_CLK_ID(S32CC_CLK_SIRC)] = &sirc_clk,
+	[S32CC_CLK_ID(S32CC_CLK_FXOSC)] = &fxosc_clk,
+	/* ARM PLL */
+	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_PHI0)] = &arm_pll_phi0_clk,
+	/* ARM DFS */
+	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_DFS1)] = &arm_dfs1_clk,
+	/* PERIPH PLL */
+	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_PHI3)] = &periph_pll_phi3_clk,
+	/* DDR PLL */
+	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_PHI0)] = &ddr_pll_phi0_clk,
+};
+
+static struct s32cc_clk_array s32cc_hw_clocks = {
+	.type_mask = S32CC_CLK_TYPE(S32CC_CLK_FIRC),
+	.clks = &s32cc_hw_clk_list[0],
+	.n_clks = ARRAY_SIZE(s32cc_hw_clk_list),
+};
+
+static struct s32cc_clk *s32cc_arch_clk_list[22] = {
+	/* ARM PLL */
+	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_MUX)] = &arm_pll_mux_clk,
+	[S32CC_CLK_ID(S32CC_CLK_ARM_PLL_VCO)] = &arm_pll_vco_clk,
+	/* PERIPH PLL */
+	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_MUX)] = &periph_pll_mux_clk,
+	[S32CC_CLK_ID(S32CC_CLK_PERIPH_PLL_VCO)] = &periph_pll_vco_clk,
+	/* MC_CGM0 */
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX0)] = &cgm0_mux0_clk,
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM0_MUX8)] = &cgm0_mux8_clk,
+	/* XBAR */
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_2X)] = &xbar_2x_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR)] = &xbar_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV2)] = &xbar_div2_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV3)] = &xbar_div3_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV4)] = &xbar_div4_clk,
+	[S32CC_CLK_ID(S32CC_CLK_XBAR_DIV6)] = &xbar_div6_clk,
+	/* MC_CGM1 */
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM1_MUX0)] = &cgm1_mux0_clk,
+	/* A53 */
+	[S32CC_CLK_ID(S32CC_CLK_A53_CORE)] = &a53_core_clk,
+	[S32CC_CLK_ID(S32CC_CLK_A53_CORE_DIV2)] = &a53_core_div2_clk,
+	[S32CC_CLK_ID(S32CC_CLK_A53_CORE_DIV10)] = &a53_core_div10_clk,
+	/* Linflex */
+	[S32CC_CLK_ID(S32CC_CLK_LINFLEX)] = &linflex_clk,
+	[S32CC_CLK_ID(S32CC_CLK_LINFLEX_BAUD)] = &linflex_baud_clk,
+	/* DDR PLL */
+	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_MUX)] = &ddr_pll_mux_clk,
+	[S32CC_CLK_ID(S32CC_CLK_DDR_PLL_VCO)] = &ddr_pll_vco_clk,
+	/* MC_CGM5 */
+	[S32CC_CLK_ID(S32CC_CLK_MC_CGM5_MUX0)] = &cgm5_mux0_clk,
+	/* DDR */
+	[S32CC_CLK_ID(S32CC_CLK_DDR)] = &ddr_clk,
+};
+
+static struct s32cc_clk_array s32cc_arch_clocks = {
+	.type_mask = S32CC_CLK_TYPE(S32CC_CLK_ARM_PLL_MUX),
+	.clks = &s32cc_arch_clk_list[0],
+	.n_clks = ARRAY_SIZE(s32cc_arch_clk_list),
+};
+
+static const struct s32cc_clk_array *s32cc_clk_table[2] = {
+	&s32cc_hw_clocks,
+	&s32cc_arch_clocks,
+};
+
+struct s32cc_clk *s32cc_get_arch_clk(unsigned long id)
+{
+	return s32cc_get_clk_from_table(s32cc_clk_table,
+					ARRAY_SIZE(s32cc_clk_table),
+					id);
+}
+
+int s32cc_get_clk_id(const struct s32cc_clk *clk, unsigned long *id)
+{
+	return s32cc_get_id_from_table(s32cc_clk_table,
+				       ARRAY_SIZE(s32cc_clk_table),
+				       clk, id);
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_utils.c b/drivers/nxp/clk/s32cc/s32cc_clk_utils.c
new file mode 100644
index 00000000..0e75054e
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_clk_utils.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-utils.h>
+
+static struct s32cc_clk *s32cc_clk_get_from_array(const struct s32cc_clk_array *arr,
+						  unsigned long clk_id)
+{
+	unsigned long type, id;
+
+	type = S32CC_CLK_TYPE(clk_id);
+
+	if (type != arr->type_mask) {
+		return NULL;
+	}
+
+	id = S32CC_CLK_ID(clk_id);
+
+	if (id >= arr->n_clks) {
+		return NULL;
+	}
+
+	return arr->clks[id];
+}
+
+struct s32cc_clk *s32cc_get_clk_from_table(const struct s32cc_clk_array *const *clk_arr,
+					   size_t size,
+					   unsigned long clk_id)
+{
+	struct s32cc_clk *clk;
+	size_t i;
+
+	for (i = 0; i < size; i++) {
+		clk = s32cc_clk_get_from_array(clk_arr[i], clk_id);
+		if (clk != NULL) {
+			return clk;
+		}
+	}
+
+	return NULL;
+}
+
+int s32cc_get_id_from_table(const struct s32cc_clk_array *const *clk_arr,
+			    size_t size, const struct s32cc_clk *clk,
+			    unsigned long *clk_index)
+{
+	size_t i, j;
+
+	for (i = 0; i < size; i++) {
+		for (j = 0; j < clk_arr[i]->n_clks; j++) {
+			if (clk_arr[i]->clks[j] != clk) {
+				continue;
+			}
+
+			*clk_index = S32CC_CLK(clk_arr[i]->type_mask, j);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
new file mode 100644
index 00000000..02b9df93
--- /dev/null
+++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <drivers/clk.h>
+#include <platform_def.h>
+#include <s32cc-clk-drv.h>
+#include <s32cc-clk-ids.h>
+#include <s32cc-clk-utils.h>
+
+#define S32CC_FXOSC_FREQ		(40U * MHZ)
+#define S32CC_ARM_PLL_VCO_FREQ		(2U * GHZ)
+#define S32CC_ARM_PLL_PHI0_FREQ		(1U * GHZ)
+#define S32CC_A53_FREQ			(1U * GHZ)
+#define S32CC_XBAR_2X_FREQ		(800U * MHZ)
+#define S32CC_PERIPH_PLL_VCO_FREQ	(2U * GHZ)
+#define S32CC_PERIPH_PLL_PHI3_FREQ	UART_CLOCK_HZ
+#define S32CC_DDR_PLL_VCO_FREQ		(1600U * MHZ)
+#define S32CC_DDR_PLL_PHI0_FREQ		(800U * MHZ)
+
+static int setup_fxosc(void)
+{
+	int ret;
+
+	ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int setup_arm_pll(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_ARM_PLL_VCO, S32CC_ARM_PLL_VCO_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_ARM_PLL_PHI0, S32CC_ARM_PLL_PHI0_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int setup_periph_pll(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_a53_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_A53_CORE);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_xbar_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_XBAR_2X);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_uart_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX8, S32CC_CLK_PERIPH_PLL_PHI3);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_LINFLEX_BAUD);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int setup_ddr_pll(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+static int enable_ddr_clk(void)
+{
+	int ret;
+
+	ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_enable(S32CC_CLK_DDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
+
+int s32cc_init_early_clks(void)
+{
+	int ret;
+
+	s32cc_clk_register_drv();
+
+	ret = setup_fxosc();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = setup_arm_pll();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_a53_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_xbar_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = setup_periph_pll();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_uart_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = setup_ddr_pll();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = enable_ddr_clk();
+	if (ret != 0) {
+		return ret;
+	}
+
+	return ret;
+}
diff --git a/drivers/nxp/console/console.mk b/drivers/nxp/console/console.mk
index 6174650d..5f3c6e34 100644
--- a/drivers/nxp/console/console.mk
+++ b/drivers/nxp/console/console.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2021 NXP
+# Copyright 2021-2024 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -27,9 +27,14 @@ else
 ifeq ($(CONSOLE), PL011)
 CONSOLE_SOURCES		:=	drivers/arm/pl011/aarch64/pl011_console.S	\
 				${PLAT_DRIVERS_PATH}/console/console_pl011.c
+else
+ifeq ($(CONSOLE), LINFLEX)
+CONSOLE_SOURCES		:=	${PLAT_DRIVERS_PATH}/console/linflex_console.S
 else
 	$(error -> CONSOLE not set!)
 endif
+
+endif
 endif
 
 ifeq (${BL_COMM_CONSOLE_NEEDED},yes)
diff --git a/drivers/nxp/console/linflex_console.S b/drivers/nxp/console/linflex_console.S
new file mode 100644
index 00000000..d8c10ef3
--- /dev/null
+++ b/drivers/nxp/console/linflex_console.S
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/libc/errno.h>
+
+#include <asm_macros.S>
+#include <console_macros.S>
+#include <lib/utils_def.h>
+
+#define LDIV_MULTIPLIER		U(16)
+
+#define LINFLEX_LINCR1		(0x0)
+#define LINCR1_INIT		BIT_32(0)
+#define LINCR1_MME		BIT_32(4)
+
+#define LINFLEX_LINSR		(0x8)
+#define LINSR_LINS_INITMODE	(0x00001000)
+#define LINSR_LINS_RX_TX_MODE	(0x00008000)
+#define LINSR_LINS_MASK		(0x0000F000)
+
+#define LINFLEX_UARTCR		(0x10)
+#define UARTCR_ROSE		BIT_32(23)
+
+#define LINFLEX_UARTSR		(0x14)
+#define LINFLEX_LINIBRR		(0x28)
+#define LINFLEX_LINFBRR		(0x24)
+#define LINFLEX_BDRL		(0x38)
+#define LINFLEX_UARTPTO		(0x50)
+
+#define UARTCR_UART		BIT_32(0)
+#define UARTCR_WL0		BIT_32(1)
+#define UARTCR_PC0		BIT_32(3)
+#define UARTCR_TXEN		BIT_32(4)
+#define UARTCR_RXEN		BIT_32(5)
+#define UARTCR_PC1		BIT_32(6)
+#define UARTCR_TFBM		BIT_32(8)
+#define UARTCR_RFBM		BIT_32(9)
+#define UARTCR_OSR_SHIFT	U(24)
+#define UARTCR_OSR_WIDTH	U(4)
+
+#define UARTSR_DTF		BIT_32(1)
+
+/*
+ * "core" functions are low-level implementations that do not require
+ * writable memory and are thus safe to call in BL1 crash context.
+ */
+.globl console_linflex_core_init
+.globl console_linflex_core_putc
+.globl console_linflex_core_flush
+
+.globl console_linflex_register
+.globl console_linflex_putc
+.globl console_linflex_flush
+
+/**
+ * uint32_t get_ldiv_mult(uintptr_t baseaddr, uint32_t clock,
+ *                        uint32_t baud, console_t *console,);
+ *
+ * Clobber list : x0 - x6
+ * Out x4: LDIV multiplier
+ */
+func get_ldiv_mult
+	ldr	w4, [x0, LINFLEX_UARTCR]
+	mov	w5, w4
+
+	/* Prepare choices in w5 and w6 */
+	ubfx	x5, x5, #UARTCR_OSR_SHIFT, #UARTCR_OSR_WIDTH
+	mov	w6, #LDIV_MULTIPLIER
+
+	and	w4, w4, #UARTCR_ROSE
+	cmp	w4, #0x0
+	csel	w4, w5, w6, ne
+	ret
+endfunc get_ldiv_mult
+
+/*
+ * void linflex_set_brg(uintptr_t baseaddr, uint32_t clock
+ *                      uint32_t baud, console_t *console);
+ *
+ * Clobber list : x0 - x7, x13
+ */
+func linflex_set_brg
+	mov	x13, x30
+	bl	get_ldiv_mult
+	mov	x30, x13
+
+	/* (x4) dividr = baudrate * ldiv_mult */
+	mul	x4, x4, x2
+	/* (x5) divisr = clock rate */
+	mov	x5, x1
+	/* (x6) ibr = divisr / dividr */
+	udiv	x6, x5, x4
+	/* (x7) fbr = divisr % dividr */
+	msub	x7, x6, x4, x5
+	/* fbr *= 16 / dividr */
+	lsl	x7, x7, #4
+	udiv	x7, x7, x4
+	/* fbr &= 0xf */
+	and	w7, w7, #0xf
+	str	w6, [x0, LINFLEX_LINIBRR]
+	str	w7, [x0, LINFLEX_LINFBRR]
+	ret
+endfunc linflex_set_brg
+
+/**
+ * int console_linflex_core_init(uintptr_t baseaddr, uint32_t clock,
+ *                               uint32_t baud);
+ *
+ * In:  x0 - Linflex base address
+ *      x1 - clock frequency
+ *      x2 - baudrate
+ * Out: x0 - 1 on success, 0 on error
+ * Clobber list : x0 - x7, x13 - x14
+ */
+func console_linflex_core_init
+	/* Set master mode and init mode */
+	mov	w4, #(LINCR1_INIT)
+	str	w4, [x0, LINFLEX_LINCR1]
+	mov	w4, #(LINCR1_MME | LINCR1_INIT)
+	str	w4, [x0, LINFLEX_LINCR1]
+
+	/* wait for init mode entry */
+wait_init_entry:
+	ldr	w4, [x0, LINFLEX_LINSR]
+	and	w4, w4, #LINSR_LINS_MASK
+	cmp	w4, #LINSR_LINS_INITMODE
+	b.ne	wait_init_entry
+
+	/* Set UART bit */
+	mov	w4, #UARTCR_UART
+	str	w4, [x0, LINFLEX_UARTCR]
+
+	mov	x14, x30
+	bl	linflex_set_brg
+	mov	x30, x14
+
+	/* Set preset timeout register value. */
+	mov	w4, #0xf
+	str	w4, [x0, LINFLEX_UARTPTO]
+
+	/* 8-bit data, no parity, Tx/Rx enabled, UART mode */
+	mov	w4, #(UARTCR_PC1 | UARTCR_RXEN | UARTCR_TXEN | UARTCR_PC0 | \
+		      UARTCR_WL0 | UARTCR_UART | UARTCR_RFBM | UARTCR_TFBM)
+	str	w4, [x0, LINFLEX_UARTCR]
+
+	/* End init mode */
+	ldr	w4, [x0, LINFLEX_LINCR1]
+	bic	w4, w4, #LINCR1_INIT
+	str	w4, [x0, LINFLEX_LINCR1]
+	ret
+endfunc console_linflex_core_init
+
+/**
+ * int console_linflex_register(uintptr_t baseaddr, uint32_t clock,
+ *                              uint32_t clock, uint32_t baud);
+ *
+ * Function to initialize and register the console.
+ * The caller needs to pass an empty console_linflex_t
+ * structure in which *MUST* be allocated in
+ * persistent memory (e.g. a global or static local
+ * variable, *NOT* on the stack).
+ * In:  x0 - Linflex base address
+ *      x1 - clock frequency
+ *      x2 - baudrate
+ *      x3 - pointer to empty console_t structure
+ * Out: x0 - 1 on success, 0 on error
+ * Clobber list : x0 - x7, x13 - x15
+ */
+func console_linflex_register
+	mov	x15, x30
+	bl	console_linflex_core_init
+	mov	x30, x15
+
+	/* Populate the base address */
+	str	x0, [x3, #CONSOLE_T_BASE]
+
+	mov	x0, x3
+	finish_console_register linflex, putc=1, getc=0, flush=1
+endfunc console_linflex_register
+
+/**
+ * int console_linflex_core_flush(uintptr_t baseaddr);
+ *
+ * Loop while the TX fifo is not empty, depending on the selected UART mode.
+ *
+ * In:  x0 - Linflex base address
+ * Clobber list : x0 - x1
+ */
+func console_linflex_core_flush
+wait_rx_tx:
+	ldr	w1, [x0, LINFLEX_LINSR]
+	and	w1, w1, #LINSR_LINS_MASK
+	cmp	w1, #LINSR_LINS_RX_TX_MODE
+	b.eq	wait_rx_tx
+
+	mov	x0, #0
+	ret
+endfunc console_linflex_core_flush
+
+/**
+ * int console_linflex_core_putc(int c, uintptr_t baseaddr);
+
+ * Out: w0 - printed character on success, < 0 on error.
+ * Clobber list : x0 - x3
+ */
+func console_linflex_core_putc
+	cbz	x1, putc_error
+
+	cmp	w0, #'\n'
+	b.ne	print_char
+
+	/* Print '\r\n' for each '\n' */
+	mov	x0, #'\r'
+	mov	x14, x30
+	bl	console_linflex_core_putc
+	mov	x30, x14
+	mov	x0, #'\n'
+
+print_char:
+	ldr	w2, [x1, LINFLEX_UARTCR]
+	and	w2, w2, #UARTCR_TFBM
+	cmp	w2, #0x0
+	b.eq	buffer_mode
+
+fifo_mode:
+	/* UART is in FIFO mode */
+	ldr	w2, [x1, LINFLEX_UARTSR]
+	and	w2, w2, #UARTSR_DTF
+	cmp	w2, #0
+	b.ne	fifo_mode
+
+	strb	w0, [x1, LINFLEX_BDRL]
+	b	no_error
+
+buffer_mode:
+	strb	w0, [x1, LINFLEX_BDRL]
+
+buffer_loop:
+	ldr	w2, [x1, LINFLEX_UARTSR]
+	and	w3, w2, #UARTSR_DTF
+	cmp	w3, #0
+	b.eq	buffer_loop
+
+	/**
+	 * In Buffer Mode the DTFTFF bit of UARTSR register
+	 * has to be set in software
+	 */
+	mov	w2, #UARTSR_DTF
+	str	w2, [x1, LINFLEX_UARTSR]
+
+no_error:
+	mov	x0, #0
+	ret
+
+putc_error:
+	mov	x0, #-EINVAL
+	ret
+endfunc console_linflex_core_putc
+
+/**
+ * int console_linflex_putc(int c, console_t *console);
+ *
+ * Function to output a character over the console. It
+ * returns the character printed on success or -EINVAL on error.
+ * In : w0 - character to be printed
+ *      x1 - pointer to console_t struct
+ * Out: w0 - printed character on success, < 0 on error.
+ * Clobber list : x0 - x3, x15
+ */
+func console_linflex_putc
+	cbz	x1, putc_error
+	ldr	x1, [x1, #CONSOLE_T_BASE]
+
+	b	console_linflex_core_putc
+puct_error:
+	mov	x0, #-EINVAL
+	ret
+endfunc console_linflex_putc
+
+/**
+ * int console_linflex_flush(console_t *console);
+ *
+ * Function to wait for the TX FIFO to be cleared.
+ * In : x0 - pointer to console_t struct
+ * Out: x0 - return -1 on error else return 0.
+ * Clobber list : x0 - x1
+ */
+func console_linflex_flush
+	cbz	x0, flush_error
+	ldr	x0, [x0, #CONSOLE_T_BASE]
+
+	b	console_linflex_core_flush
+flush_error:
+	mov	x0, #-EINVAL
+	ret
+endfunc console_linflex_flush
diff --git a/drivers/nxp/ddr/phy-gen2/ddrphy.mk b/drivers/nxp/ddr/phy-gen2/ddrphy.mk
index ba5c7742..a09a278a 100644
--- a/drivers/nxp/ddr/phy-gen2/ddrphy.mk
+++ b/drivers/nxp/ddr/phy-gen2/ddrphy.mk
@@ -12,9 +12,9 @@ DDR_PHY_C  =
 DDR_PHY_H  =
 
 $(DDR_PHY_C): $(DDR_PHY_H) $(COMMON_HDRS) src
-	@cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
+	$(q)cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
 
 $(DDR_PHY_H): src
-	@cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
+	$(q)cp -r "$(DDR_PHY_PATH)/$@" "$(SRC_DIR)/$@"
 
 #------------------------------------------------
diff --git a/drivers/nxp/drivers.mk b/drivers/nxp/drivers.mk
index d77e9854..761571d3 100644
--- a/drivers/nxp/drivers.mk
+++ b/drivers/nxp/drivers.mk
@@ -97,3 +97,7 @@ endif
 ifeq (${IFC_NAND_NEEDED},yes)
 include ${PLAT_DRIVERS_PATH}/ifc/nand/ifc_nand.mk
 endif
+
+ifeq (${CLK_NEEDED},yes)
+include ${PLAT_DRIVERS_PATH}/clk/s32cc/s32cc_clk.mk
+endif
diff --git a/drivers/nxp/gpio/nxp_gpio.c b/drivers/nxp/gpio/nxp_gpio.c
index 28c9db97..b477b796 100644
--- a/drivers/nxp/gpio/nxp_gpio.c
+++ b/drivers/nxp/gpio/nxp_gpio.c
@@ -28,8 +28,8 @@ int set_gpio_bit(uint32_t *gpio_base_addr,
 		ERROR("GPIO is not initialized.\n");
 		return GPIO_FAILURE;
 	}
-
-	gpdir = gpio_base_addr + GPDIR_REG_OFFSET;
+	/* Divide by 4 since we're operating on 32-bit pointer addresses. */
+	gpdir = gpio_base_addr + (GPDIR_REG_OFFSET >> 2);
 	gpdat = gpio_base_addr + (GPDAT_REG_OFFSET >> 2);
 
 	/*
@@ -67,8 +67,9 @@ int clr_gpio_bit(uint32_t *gpio_base_addr, uint32_t bit_num)
 		return GPIO_FAILURE;
 	}
 
-	gpdir = gpio_base_addr + GPDIR_REG_OFFSET;
-	gpdat = gpio_base_addr + GPDAT_REG_OFFSET;
+	/* Divide by 4 since we're operating on 32-bit pointer addresses. */
+	gpdir = gpio_base_addr + (GPDIR_REG_OFFSET >> 2);
+	gpdat = gpio_base_addr + (GPDAT_REG_OFFSET >> 2);
 
 	/*
 	 * Reset the corresponding bit in direction and data register
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index c60820df..c4f74935 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,7 +50,7 @@ static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry)
 {
 	size_t bytes_read;
 	int result;
-	mbr_entry_t *tmp;
+	mbr_entry_t tmp;
 
 	assert(mbr_entry != NULL);
 	/* MBR partition table is in LBA0. */
@@ -73,19 +73,19 @@ static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry)
 		return -ENOENT;
 	}
 
-	tmp = (mbr_entry_t *)(&mbr_sector[MBR_PRIMARY_ENTRY_OFFSET]);
+	memcpy(&tmp, mbr_sector + MBR_PRIMARY_ENTRY_OFFSET, sizeof(tmp));
 
-	if (tmp->first_lba != 1) {
+	if (tmp.first_lba != 1) {
 		VERBOSE("MBR header may have an invalid first LBA\n");
 		return -EINVAL;
 	}
 
-	if ((tmp->sector_nums == 0) || (tmp->sector_nums == UINT32_MAX)) {
+	if ((tmp.sector_nums == 0) || (tmp.sector_nums == UINT32_MAX)) {
 		VERBOSE("MBR header entry has an invalid number of sectors\n");
 		return -EINVAL;
 	}
 
-	memcpy(mbr_entry, tmp, sizeof(mbr_entry_t));
+	memcpy(mbr_entry, &tmp, sizeof(mbr_entry_t));
 	return 0;
 }
 
@@ -94,9 +94,8 @@ static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry)
  * If partition numbers could be found, check & update it.
  */
 static int load_gpt_header(uintptr_t image_handle, size_t header_offset,
-			   unsigned long long *part_lba)
+			   gpt_header_t *header)
 {
-	gpt_header_t header;
 	size_t bytes_read;
 	int result;
 	uint32_t header_crc, calc_crc;
@@ -107,7 +106,7 @@ static int load_gpt_header(uintptr_t image_handle, size_t header_offset,
 			header_offset);
 		return result;
 	}
-	result = io_read(image_handle, (uintptr_t)&header,
+	result = io_read(image_handle, (uintptr_t)header,
 			 sizeof(gpt_header_t), &bytes_read);
 	if ((result != 0) || (sizeof(gpt_header_t) != bytes_read)) {
 		VERBOSE("GPT header read error(%i) or read mismatch occurred,"
@@ -115,8 +114,8 @@ static int load_gpt_header(uintptr_t image_handle, size_t header_offset,
 			sizeof(gpt_header_t), bytes_read);
 		return result;
 	}
-	if (memcmp(header.signature, GPT_SIGNATURE,
-			   sizeof(header.signature)) != 0) {
+	if (memcmp(header->signature, GPT_SIGNATURE,
+			   sizeof(header->signature)) != 0) {
 		VERBOSE("GPT header signature failure\n");
 		return -EINVAL;
 	}
@@ -126,25 +125,24 @@ static int load_gpt_header(uintptr_t image_handle, size_t header_offset,
 	 * computed by setting this field to 0, and computing the
 	 * 32-bit CRC for HeaderSize bytes.
 	 */
-	header_crc = header.header_crc;
-	header.header_crc = 0U;
+	header_crc = header->header_crc;
+	header->header_crc = 0U;
 
-	calc_crc = tf_crc32(0U, (uint8_t *)&header, sizeof(gpt_header_t));
+	calc_crc = tf_crc32(0U, (uint8_t *)header, sizeof(gpt_header_t));
 	if (header_crc != calc_crc) {
 		ERROR("Invalid GPT Header CRC: Expected 0x%x but got 0x%x.\n",
 		      header_crc, calc_crc);
 		return -EINVAL;
 	}
 
-	header.header_crc = header_crc;
+	header->header_crc = header_crc;
 
 	/* partition numbers can't exceed PLAT_PARTITION_MAX_ENTRIES */
-	list.entry_count = header.list_num;
+	list.entry_count = header->list_num;
 	if (list.entry_count > PLAT_PARTITION_MAX_ENTRIES) {
 		list.entry_count = PLAT_PARTITION_MAX_ENTRIES;
 	}
 
-	*part_lba = header.part_lba;
 	return 0;
 }
 
@@ -192,11 +190,11 @@ static int load_mbr_entry(uintptr_t image_handle, mbr_entry_t *mbr_entry,
 static int load_mbr_entries(uintptr_t image_handle)
 {
 	mbr_entry_t mbr_entry;
-	int i;
+	unsigned int i;
 
 	list.entry_count = MBR_PRIMARY_ENTRY_NUMBER;
 
-	for (i = 0; i < list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		load_mbr_entry(image_handle, &mbr_entry, i);
 		list.list[i].start = mbr_entry.first_lba * 512;
 		list.list[i].length = mbr_entry.sector_nums * 512;
@@ -231,12 +229,13 @@ static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry)
  * Retrieve each entry in the partition table, parse the data from each
  * entry and store them in the list of partition table entries.
  */
-static int load_partition_gpt(uintptr_t image_handle,
-			      unsigned long long part_lba)
+static int load_partition_gpt(uintptr_t image_handle, gpt_header_t header)
 {
-	const signed long long gpt_entry_offset = LBA(part_lba);
+	const signed long long gpt_entry_offset = LBA(header.part_lba);
 	gpt_entry_t entry;
-	int result, i;
+	int result;
+	unsigned int i;
+	uint32_t calc_crc = 0U;
 
 	result = io_seek(image_handle, IO_SEEK_SET, gpt_entry_offset);
 	if (result != 0) {
@@ -245,23 +244,36 @@ static int load_partition_gpt(uintptr_t image_handle,
 		return result;
 	}
 
-	for (i = 0; i < list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		result = load_gpt_entry(image_handle, &entry);
 		if (result != 0) {
-			VERBOSE("Failed to load gpt entry data(%i) error is (%i)\n",
+			VERBOSE("Failed to load gpt entry data(%u) error is (%i)\n",
 				i, result);
 			return result;
 		}
 
 		result = parse_gpt_entry(&entry, &list.list[i]);
 		if (result != 0) {
+			result = io_seek(image_handle, IO_SEEK_SET,
+					(gpt_entry_offset + (i * sizeof(gpt_entry_t))));
+			if (result != 0) {
+				VERBOSE("Failed to seek (%i)\n", result);
+				return result;
+			}
 			break;
 		}
+
+		/*
+		 * Calculate CRC of Partition entry array to compare with CRC
+		 * value in header
+		 */
+		calc_crc = tf_crc32(calc_crc, (uint8_t *)&entry, sizeof(gpt_entry_t));
 	}
 	if (i == 0) {
 		VERBOSE("No Valid GPT Entries found\n");
 		return -EINVAL;
 	}
+
 	/*
 	 * Only records the valid partition number that is loaded from
 	 * partition table.
@@ -269,6 +281,29 @@ static int load_partition_gpt(uintptr_t image_handle,
 	list.entry_count = i;
 	dump_entries(list.entry_count);
 
+	/*
+	 * If there are less valid entries than the possible number of entries
+	 * from the header, continue to load the partition entry table to
+	 * calculate the full CRC in order to check against the partition CRC
+	 * from the header for validation.
+	 */
+	for (; i < header.list_num; i++) {
+		result = load_gpt_entry(image_handle, &entry);
+		if (result != 0) {
+			VERBOSE("Failed to load gpt entry data(%u) error is (%i)\n",
+				i, result);
+			return result;
+		}
+
+		calc_crc = tf_crc32(calc_crc, (uint8_t *)&entry, sizeof(gpt_entry_t));
+	}
+
+	if (header.part_crc != calc_crc) {
+		ERROR("Invalid GPT Partition Array Entry CRC: Expected 0x%x"
+				" but got 0x%x.\n", header.part_crc, calc_crc);
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
@@ -279,7 +314,7 @@ static int load_partition_gpt(uintptr_t image_handle,
 static int load_backup_gpt(unsigned int image_id, unsigned int sector_nums)
 {
 	int result;
-	unsigned long long part_lba = 0;
+	gpt_header_t header;
 	size_t gpt_header_offset;
 	uintptr_t dev_handle, image_spec, image_handle;
 	io_block_spec_t *block_spec;
@@ -316,8 +351,8 @@ static int load_backup_gpt(unsigned int image_id, unsigned int sector_nums)
 	INFO("Trying to retrieve back-up GPT header\n");
 	/* Last block is backup-GPT header, after the end of GPT entries */
 	gpt_header_offset = LBA(part_num_entries);
-	result = load_gpt_header(image_handle, gpt_header_offset, &part_lba);
-	if ((result != 0) || (part_lba == 0)) {
+	result = load_gpt_header(image_handle, gpt_header_offset, &header);
+	if ((result != 0) || (header.part_lba == 0)) {
 		ERROR("Failed to retrieve Backup GPT header,"
 		      "Partition maybe corrupted\n");
 		goto out;
@@ -327,7 +362,8 @@ static int load_backup_gpt(unsigned int image_id, unsigned int sector_nums)
 	 * Note we mapped last 33 blocks(LBA-33), first block here starts with
 	 * entries while last block was header.
 	 */
-	result = load_partition_gpt(image_handle, 0);
+	header.part_lba = 0;
+	result = load_partition_gpt(image_handle, header);
 
 out:
 	io_close(image_handle);
@@ -342,19 +378,19 @@ out:
 static int load_primary_gpt(uintptr_t image_handle, unsigned int first_lba)
 {
 	int result;
-	unsigned long long part_lba;
 	size_t gpt_header_offset;
+	gpt_header_t header;
 
 	/* Try to load Primary GPT header from LBA1 */
 	gpt_header_offset = LBA(first_lba);
-	result = load_gpt_header(image_handle, gpt_header_offset, &part_lba);
-	if ((result != 0) || (part_lba == 0)) {
+	result = load_gpt_header(image_handle, gpt_header_offset, &header);
+	if ((result != 0) || (header.part_lba == 0)) {
 		VERBOSE("Failed to retrieve Primary GPT header,"
 			"trying to retrieve back-up GPT header\n");
 		return result;
 	}
 
-	return load_partition_gpt(image_handle, part_lba);
+	return load_partition_gpt(image_handle, header);
 }
 
 /*
@@ -405,9 +441,9 @@ out:
  */
 const partition_entry_t *get_partition_entry(const char *name)
 {
-	int i;
+	unsigned int i;
 
-	for (i = 0; i < list.entry_count; i++) {
+	for (i = 0U; i < list.entry_count; i++) {
 		if (strcmp(name, list.list[i].name) == 0) {
 			return &list.list[i];
 		}
@@ -416,14 +452,15 @@ const partition_entry_t *get_partition_entry(const char *name)
 }
 
 /*
- * Try retrieving a partition table entry based on the GUID.
+ * Try retrieving a partition table entry based on the partition type GUID.
  */
-const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_uuid)
+const partition_entry_t *get_partition_entry_by_type(
+	const struct efi_guid *type_guid)
 {
-	int i;
+	unsigned int i;
 
-	for (i = 0; i < list.entry_count; i++) {
-		if (guidcmp(type_uuid, &list.list[i].type_guid) == 0) {
+	for (i = 0U; i < list.entry_count; i++) {
+		if (guidcmp(type_guid, &list.list[i].type_guid) == 0) {
 			return &list.list[i];
 		}
 	}
@@ -432,14 +469,15 @@ const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_uuid)
 }
 
 /*
- * Try retrieving a partition table entry based on the UUID.
+ * Try retrieving a partition table entry based on the unique partition GUID.
  */
-const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid)
+const partition_entry_t *get_partition_entry_by_guid(
+	const struct efi_guid *part_guid)
 {
-	int i;
+	unsigned int i;
 
-	for (i = 0; i < list.entry_count; i++) {
-		if (guidcmp(part_uuid, &list.list[i].part_guid) == 0) {
+	for (i = 0U; i < list.entry_count; i++) {
+		if (guidcmp(part_guid, &list.list[i].part_guid) == 0) {
 			return &list.list[i];
 		}
 	}
diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c
index 45ef386a..66662c11 100644
--- a/drivers/renesas/common/io/io_rcar.c
+++ b/drivers/renesas/common/io/io_rcar.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -84,6 +84,29 @@ typedef struct {
 #define RCAR_COUNT_LOAD_BL33		(2U)
 #define RCAR_COUNT_LOAD_BL33X		(3U)
 
+#define CHECK_IMAGE_AREA_CNT (7U)
+#define BOOT_BL2_ADDR (0xE6304000U)
+#define BOOT_BL2_LENGTH (0x19000U)
+
+typedef struct {
+	uintptr_t dest;
+	uintptr_t length;
+} addr_loaded_t;
+
+static addr_loaded_t addr_loaded[CHECK_IMAGE_AREA_CNT] = {
+	[0] = {BOOT_BL2_ADDR, BOOT_BL2_LENGTH},
+	[1] = {BL31_BASE, RCAR_TRUSTED_SRAM_SIZE},
+#ifndef SPD_NONE
+	[2] = {BL32_BASE, BL32_SIZE}
+#endif
+};
+
+#ifndef SPD_NONE
+static uint32_t addr_loaded_cnt = 3;
+#else
+static uint32_t addr_loaded_cnt = 2;
+#endif
+
 static const plat_rcar_name_offset_t name_offset[] = {
 	{BL31_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(0, 0, 0)},
 
@@ -244,8 +267,16 @@ void rcar_read_certificate(uint64_t cert, uint32_t *len, uintptr_t *dst)
 			dstl = cert + RCAR_CERT_INFO_DST_OFFSET;
 			break;
 		}
+		val = mmio_read_32(size);
+		if (val > (UINT32_MAX / 4)) {
+			ERROR("BL2: %s[%d] uint32 overflow!\n",
+				__func__, __LINE__);
+			*dst = 0;
+			*len = 0;
+			return;
+		}
 
-		*len = mmio_read_32(size) * 4U;
+		*len = val * 4U;
 		dsth = dstl + 4U;
 		*dst = ((uintptr_t) mmio_read_32(dsth) << 32) +
 		    ((uintptr_t) mmio_read_32(dstl));
@@ -253,7 +284,14 @@ void rcar_read_certificate(uint64_t cert, uint32_t *len, uintptr_t *dst)
 	}
 
 	size = cert + RCAR_CERT_INFO_SIZE_OFFSET;
-	*len = mmio_read_32(size) * 4U;
+	val = mmio_read_32(size);
+	if (val > (UINT32_MAX / 4)) {
+		ERROR("BL2: %s[%d] uint32 overflow!\n", __func__, __LINE__);
+		*dst = 0;
+		*len = 0;
+		return;
+	}
+	*len = val * 4U;
 	dstl = cert + RCAR_CERT_INFO_DST_OFFSET;
 	dsth = dstl + 4U;
 	*dst = ((uintptr_t) mmio_read_32(dsth) << 32) +
@@ -266,17 +304,18 @@ static int32_t check_load_area(uintptr_t dst, uintptr_t len)
 	uintptr_t dram_start, dram_end;
 	uintptr_t prot_start, prot_end;
 	int32_t result = IO_SUCCESS;
+	int n;
 
-	dram_start = legacy ? DRAM1_BASE : DRAM_40BIT_BASE;
+	dram_start = legacy ? DRAM1_NS_BASE : DRAM_40BIT_BASE;
 
-	dram_end = legacy ? DRAM1_BASE + DRAM1_SIZE :
+	dram_end = legacy ? DRAM1_NS_BASE + DRAM1_NS_SIZE :
 	    DRAM_40BIT_BASE + DRAM_40BIT_SIZE;
 
 	prot_start = legacy ? DRAM_PROTECTED_BASE : DRAM_40BIT_PROTECTED_BASE;
 
 	prot_end = prot_start + DRAM_PROTECTED_SIZE;
 
-	if (dst < dram_start || dst > dram_end - len) {
+	if (dst < dram_start || len > dram_end || dst > dram_end - len) {
 		ERROR("BL2: dst address is on the protected area.\n");
 		result = IO_FAIL;
 		goto done;
@@ -286,12 +325,54 @@ static int32_t check_load_area(uintptr_t dst, uintptr_t len)
 	if (dst >= prot_start && dst < prot_end) {
 		ERROR("BL2: dst address is on the protected area.\n");
 		result = IO_FAIL;
+		goto done;
+	}
+
+	if (len > prot_start || (dst < prot_start && dst > prot_start - len)) {
+		ERROR("BL2: %s[%d] loaded data is on the protected area.\n",
+			__func__, __LINE__);
+		result = IO_FAIL;
+		goto done;
 	}
 
-	if (dst < prot_start && dst > prot_start - len) {
-		ERROR("BL2: loaded data is on the protected area.\n");
+	if (addr_loaded_cnt >= CHECK_IMAGE_AREA_CNT) {
+		ERROR("BL2: max loadable non secure images reached\n");
 		result = IO_FAIL;
+		goto done;
+	}
+
+	addr_loaded[addr_loaded_cnt].dest = dst;
+	addr_loaded[addr_loaded_cnt].length = len;
+	for (n = 0; n < addr_loaded_cnt; n++) {
+		/*
+		 * Check if next image invades a previous loaded image
+		 *
+		 * IMAGE n: area from previous image:	dest| IMAGE n |length
+		 * IMAGE n+1: area from next image:	dst | IMAGE n |len
+		 *
+		 * 1. check:
+		 *      | IMAGE n |
+		 *        | IMAGE n+1 |
+		 * 2. check:
+		 *      | IMAGE n |
+		 *  | IMAGE n+1 |
+		 * 3. check:
+		 *      | IMAGE n |
+		 *  |    IMAGE n+1    |
+		 */
+		if (((dst >= addr_loaded[n].dest) &&
+		     (dst <= addr_loaded[n].dest + addr_loaded[n].length)) ||
+		    ((dst + len >= addr_loaded[n].dest) &&
+		     (dst + len <= addr_loaded[n].dest + addr_loaded[n].length)) ||
+		    ((dst <= addr_loaded[n].dest) &&
+		     (dst + len >= addr_loaded[n].dest + addr_loaded[n].length))) {
+			ERROR("BL2: next image overlap a previous image area.\n");
+			result = IO_FAIL;
+			goto done;
+		}
 	}
+	addr_loaded_cnt++;
+
 done:
 	if (result == IO_FAIL) {
 		ERROR("BL2: Out of range : dst=0x%lx len=0x%lx\n", dst, len);
@@ -435,17 +516,17 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name)
 #endif
 
 	rcar_image_number = header[0];
-	for (i = 0; i < rcar_image_number + 2; i++) {
-		rcar_image_header[i] = header[i * 2 + 1];
-		rcar_image_header_prttn[i] = header[i * 2 + 2];
-	}
-
 	if (rcar_image_number == 0 || rcar_image_number > RCAR_MAX_BL3X_IMAGE) {
 		WARN("Firmware Image Package header check failed.\n");
 		rc = IO_FAIL;
 		goto error;
 	}
 
+	for (i = 0; i < rcar_image_number + 2; i++) {
+		rcar_image_header[i] = header[i * 2 + 1];
+		rcar_image_header_prttn[i] = header[i * 2 + 2];
+	}
+
 	rc = io_seek(handle, IO_SEEK_SET, offset + RCAR_SECTOR6_CERT_OFFSET);
 	if (rc != IO_SUCCESS) {
 		WARN("Firmware Image Package header failed to seek cert\n");
@@ -517,13 +598,6 @@ static int32_t rcar_file_open(io_dev_info_t *info, const uintptr_t file_spec,
 
 	rcar_read_certificate((uint64_t) cert, &len, &dst);
 
-	/* Baylibre: HACK */
-	if (spec->offset == BL31_IMAGE_ID && len < RCAR_TRUSTED_SRAM_SIZE) {
-		WARN("%s,%s\n", "r-car ignoring the BL31 size from certificate",
-		     "using RCAR_TRUSTED_SRAM_SIZE instead");
-		len = RCAR_TRUSTED_SRAM_SIZE;
-	}
-
 	current_file.partition = partition;
 	current_file.no_load = noload;
 	current_file.offset = offset;
diff --git a/drivers/renesas/rcar/qos/D3/qos_init_d3.c b/drivers/renesas/rcar/qos/D3/qos_init_d3.c
index b96e822f..8e1ebcb4 100644
--- a/drivers/renesas/rcar/qos/D3/qos_init_d3.c
+++ b/drivers/renesas/rcar/qos/D3/qos_init_d3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,7 +18,7 @@
 
 struct rcar_gen3_dbsc_qos_settings d3_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
 	{ DBSC_DBSCHSZ0, 0x00000001 },
diff --git a/drivers/renesas/rcar/qos/E3/qos_init_e3_v10.c b/drivers/renesas/rcar/qos/E3/qos_init_e3_v10.c
index 6f4c66cb..1931dd1b 100644
--- a/drivers/renesas/rcar/qos/E3/qos_init_e3_v10.c
+++ b/drivers/renesas/rcar/qos/E3/qos_init_e3_v10.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,7 +28,7 @@
 
 struct rcar_gen3_dbsc_qos_settings e3_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
 	{ DBSC_DBSCHSZ0, 0x00000001 },
diff --git a/drivers/renesas/rcar/qos/H3/qos_init_h3_v11.c b/drivers/renesas/rcar/qos/H3/qos_init_h3_v11.c
index 329bcb82..6d933131 100644
--- a/drivers/renesas/rcar/qos/H3/qos_init_h3_v11.c
+++ b/drivers/renesas/rcar/qos/H3/qos_init_h3_v11.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,7 +21,7 @@
 struct rcar_gen3_dbsc_qos_settings h3_v11_qos[] = {
 	/* BUFCAM settings */
 	/* DBSC_DBCAM0CNF0 not set */
-	{ DBSC_DBCAM0CNF1, 0x00044218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	/* DBSC_DBCAM0CNF3 not set */
 	{ DBSC_DBSCHCNT0, 0x080F0037 },
diff --git a/drivers/renesas/rcar/qos/H3/qos_init_h3_v20.c b/drivers/renesas/rcar/qos/H3/qos_init_h3_v20.c
index c20ab086..f44da872 100644
--- a/drivers/renesas/rcar/qos/H3/qos_init_h3_v20.c
+++ b/drivers/renesas/rcar/qos/H3/qos_init_h3_v20.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -63,7 +63,7 @@
 
 struct rcar_gen3_dbsc_qos_settings h3_v20_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218U },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4U },
 	{ DBSC_DBCAM0CNF3, 0x00000000U },
 	{ DBSC_DBSCHCNT0, 0x000F0037U },
diff --git a/drivers/renesas/rcar/qos/H3/qos_init_h3_v30.c b/drivers/renesas/rcar/qos/H3/qos_init_h3_v30.c
index 1fe6182b..867d9e07 100644
--- a/drivers/renesas/rcar/qos/H3/qos_init_h3_v30.c
+++ b/drivers/renesas/rcar/qos/H3/qos_init_h3_v30.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,7 +62,7 @@
 
 struct rcar_gen3_dbsc_qos_settings h3_v30_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218U },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4U },
 	{ DBSC_DBCAM0CNF3, 0x00000000U },
 	{ DBSC_DBSCHCNT0, 0x000F0037U },
diff --git a/drivers/renesas/rcar/qos/H3/qos_init_h3n_v30.c b/drivers/renesas/rcar/qos/H3/qos_init_h3n_v30.c
index f1ee41b9..d758dbf5 100644
--- a/drivers/renesas/rcar/qos/H3/qos_init_h3n_v30.c
+++ b/drivers/renesas/rcar/qos/H3/qos_init_h3n_v30.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,7 +62,7 @@
 
 struct rcar_gen3_dbsc_qos_settings h3n_v30_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218U },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4U },
 	{ DBSC_DBCAM0CNF3, 0x00000000U },
 	{ DBSC_DBSCHCNT0, 0x000F0037U },
diff --git a/drivers/renesas/rcar/qos/M3/qos_init_m3_v10.c b/drivers/renesas/rcar/qos/M3/qos_init_m3_v10.c
index a8264cb2..d096d012 100644
--- a/drivers/renesas/rcar/qos/M3/qos_init_m3_v10.c
+++ b/drivers/renesas/rcar/qos/M3/qos_init_m3_v10.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,7 +19,7 @@
 struct rcar_gen3_dbsc_qos_settings m3_v10_qos[] = {
 	/* BUFCAM settings */
 	/* DBSC_DBCAM0CNF0 not set */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBCAM0CNF3, 0x00000000 },
 	{ DBSC_DBSCHCNT0, 0x080F0037 },
diff --git a/drivers/renesas/rcar/qos/M3/qos_init_m3_v11.c b/drivers/renesas/rcar/qos/M3/qos_init_m3_v11.c
index 22fd83a9..640fe803 100644
--- a/drivers/renesas/rcar/qos/M3/qos_init_m3_v11.c
+++ b/drivers/renesas/rcar/qos/M3/qos_init_m3_v11.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2017-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,7 +62,7 @@
 
 struct rcar_gen3_dbsc_qos_settings m3_v11_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBCAM0CNF3, 0x00000000 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
diff --git a/drivers/renesas/rcar/qos/M3/qos_init_m3_v30.c b/drivers/renesas/rcar/qos/M3/qos_init_m3_v30.c
index 43d21d71..f5ca4b66 100644
--- a/drivers/renesas/rcar/qos/M3/qos_init_m3_v30.c
+++ b/drivers/renesas/rcar/qos/M3/qos_init_m3_v30.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2019-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,7 +62,7 @@
 
 struct rcar_gen3_dbsc_qos_settings m3_v30_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBCAM0CNF3, 0x00000000 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
diff --git a/drivers/renesas/rcar/qos/M3N/qos_init_m3n_v10.c b/drivers/renesas/rcar/qos/M3N/qos_init_m3n_v10.c
index 446340bb..95c6ac9a 100644
--- a/drivers/renesas/rcar/qos/M3N/qos_init_m3n_v10.c
+++ b/drivers/renesas/rcar/qos/M3N/qos_init_m3n_v10.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2017-2024, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -60,7 +60,7 @@
 
 struct rcar_gen3_dbsc_qos_settings m3n_v10_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00043218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBSCHCNT0, 0x000F0037 },
 	{ DBSC_DBSCHSZ0, 0x00000001 },
diff --git a/drivers/renesas/rcar/qos/V3M/qos_init_v3m.c b/drivers/renesas/rcar/qos/V3M/qos_init_v3m.c
index 076876cc..4e1734cd 100644
--- a/drivers/renesas/rcar/qos/V3M/qos_init_v3m.c
+++ b/drivers/renesas/rcar/qos/V3M/qos_init_v3m.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, Renesas Electronics Corporation
+ * Copyright (c) 2015-2024, Renesas Electronics Corporation
  * All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -19,7 +19,7 @@
 
 struct rcar_gen3_dbsc_qos_settings v3m_qos[] = {
 	/* BUFCAM settings */
-	{ DBSC_DBCAM0CNF1, 0x00044218 },
+	{ DBSC_DBCAM0CNF1, 0x00048218U },
 	{ DBSC_DBCAM0CNF2, 0x000000F4 },
 	{ DBSC_DBSCHCNT0, 0x080F003F },
 	{ DBSC_DBSCHCNT1, 0x00001010 },
diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c
index 55a8832c..460afe17 100644
--- a/drivers/rpi3/gpio/rpi3_gpio.c
+++ b/drivers/rpi3/gpio/rpi3_gpio.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019, Linaro Limited
  * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -120,7 +121,7 @@ static void rpi3_gpio_set_value(int gpio, int value)
 	int regN = gpio / 32;
 	int shift = gpio % 32;
 	uintptr_t reg_set = reg_base + RPI3_GPIO_GPSET(regN);
-	uintptr_t reg_clr = reg_base + RPI3_GPIO_GPSET(regN);
+	uintptr_t reg_clr = reg_base + RPI3_GPIO_GPCLR(regN);
 
 	switch (value) {
 	case GPIO_LEVEL_LOW:
diff --git a/drivers/rpi3/rng/rpi3_rng.c b/drivers/rpi3/rng/rpi3_rng.c
index b6bf0052..16733e15 100644
--- a/drivers/rpi3/rng/rpi3_rng.c
+++ b/drivers/rpi3/rng/rpi3_rng.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,19 @@
 
 #include <rpi_hw.h>
 
+#define RPI3_RNG_CTRL_OFFSET		ULL(0x00000000)
+#define RPI3_RNG_STATUS_OFFSET		ULL(0x00000004)
+#define RPI3_RNG_DATA_OFFSET		ULL(0x00000008)
+#define RPI3_RNG_INT_MASK_OFFSET	ULL(0x00000010)
+/* Enable/disable RNG */
+#define RPI3_RNG_CTRL_ENABLE		U(0x1)
+#define RPI3_RNG_CTRL_DISABLE		U(0x0)
+/* Number of currently available words */
+#define RPI3_RNG_STATUS_NUM_WORDS_SHIFT	U(24)
+#define RPI3_RNG_STATUS_NUM_WORDS_MASK	U(0xFF)
+/* Value to mask interrupts caused by the RNG */
+#define RPI3_RNG_INT_MASK_DISABLE	U(0x1)
+
 /* Initial amount of values to discard */
 #define RNG_WARMUP_COUNT	U(0x40000)
 
diff --git a/drivers/scmi-msg/common.h b/drivers/scmi-msg/common.h
index 62f3087d..6b186d07 100644
--- a/drivers/scmi-msg/common.h
+++ b/drivers/scmi-msg/common.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause */
 /*
- * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2020, Linaro Limited
  */
 #ifndef SCMI_MSG_COMMON_H
@@ -15,6 +15,7 @@
 #include "clock.h"
 #include "power_domain.h"
 #include "reset_domain.h"
+#include "sensor.h"
 
 #define SCMI_VERSION			0x20000U
 #define SCMI_IMPL_VERSION		0U
@@ -118,6 +119,13 @@ scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg);
  */
 scmi_msg_handler_t scmi_msg_get_pd_handler(struct scmi_msg *msg);
 
+/*
+ * scmi_msg_get_sensor_handler - Return a handler for a sensor message
+ * @msg - message to process
+ * Return a function handler for the message or NULL
+ */
+scmi_msg_handler_t scmi_msg_get_sensor_handler(struct scmi_msg *msg);
+
 /*
  * Process Read, process and write response for input SCMI message
  *
diff --git a/drivers/scmi-msg/entry.c b/drivers/scmi-msg/entry.c
index 399115c6..5ac68e1e 100644
--- a/drivers/scmi-msg/entry.c
+++ b/drivers/scmi-msg/entry.c
@@ -15,6 +15,7 @@
 #pragma weak scmi_msg_get_rstd_handler
 #pragma weak scmi_msg_get_pd_handler
 #pragma weak scmi_msg_get_voltage_handler
+#pragma weak scmi_msg_get_sensor_handler
 
 scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg __unused)
 {
@@ -36,6 +37,11 @@ scmi_msg_handler_t scmi_msg_get_voltage_handler(struct scmi_msg *msg __unused)
 	return NULL;
 }
 
+scmi_msg_handler_t scmi_msg_get_sensor_handler(struct scmi_msg *msg __unused)
+{
+	return NULL;
+}
+
 void scmi_status_response(struct scmi_msg *msg, int32_t status)
 {
 	assert(msg->out && msg->out_size >= sizeof(int32_t));
@@ -75,6 +81,9 @@ void scmi_process_message(struct scmi_msg *msg)
 	case SCMI_PROTOCOL_ID_POWER_DOMAIN:
 		handler = scmi_msg_get_pd_handler(msg);
 		break;
+	case SCMI_PROTOCOL_ID_SENSOR:
+		handler = scmi_msg_get_sensor_handler(msg);
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/scmi-msg/sensor.c b/drivers/scmi-msg/sensor.c
new file mode 100644
index 00000000..a47018d8
--- /dev/null
+++ b/drivers/scmi-msg/sensor.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright 2021-2024 NXP
+ */
+
+#include <cdefs.h>
+#include <string.h>
+
+#include "common.h"
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+#include <lib/utils_def.h>
+
+static bool message_id_is_supported(size_t message_id);
+
+uint16_t plat_scmi_sensor_count(unsigned int agent_id __unused)
+{
+	if (sensor_ops.sensor_count != NULL) {
+		return sensor_ops.sensor_count(agent_id);
+	}
+
+	return 0U;
+}
+
+uint8_t plat_scmi_sensor_max_requests(unsigned int agent_id __unused)
+{
+	if (sensor_ops.sensor_max_request != NULL) {
+		return sensor_ops.sensor_max_request(agent_id);
+	}
+
+	return 0U;
+}
+
+uint32_t plat_scmi_sensor_reg(unsigned int agent_id __unused,
+			      unsigned int *addr)
+{
+	if (sensor_ops.get_sensor_req != NULL) {
+		return sensor_ops.get_sensor_req(agent_id, addr);
+	}
+
+	return 0U;
+}
+
+int32_t plat_scmi_sensor_reading_get(uint32_t agent_id __unused,
+				     uint16_t sensor_id __unused,
+				     uint32_t *val __unused)
+{
+	if (sensor_ops.sensor_reading_get != NULL) {
+		return sensor_ops.sensor_reading_get(agent_id, sensor_id, val);
+	}
+
+	return 0;
+}
+
+uint32_t plat_scmi_sensor_description_get(uint32_t agent_id __unused,
+					  uint16_t desc_index __unused,
+					  struct scmi_sensor_desc *desc __unused)
+{
+	if (sensor_ops.sensor_description_get != NULL) {
+		return sensor_ops.sensor_description_get(agent_id, desc_index, desc);
+	}
+
+	return 0U;
+}
+
+uint32_t plat_scmi_sensor_update_interval(uint32_t agent_id __unused,
+					  uint16_t sensor_id __unused)
+{
+	if (sensor_ops.sensor_update_interval != NULL) {
+		return sensor_ops.sensor_update_interval(agent_id, sensor_id);
+	}
+
+	return 0U;
+}
+
+uint32_t plat_scmi_sensor_state(uint32_t agent_id __unused,
+				uint16_t sensor_id __unused)
+{
+	if (sensor_ops.sensor_state != NULL) {
+		return sensor_ops.sensor_state(agent_id, sensor_id);
+	}
+
+	return 0U;
+}
+
+uint32_t plat_scmi_sensor_timestamped(uint32_t agent_id __unused,
+				      uint16_t sensor_id __unused)
+{
+	if (sensor_ops.sensor_timestamped != NULL) {
+		return sensor_ops.sensor_timestamped(agent_id, sensor_id);
+	}
+
+	return 0U;
+}
+
+static void report_version(struct scmi_msg *msg)
+{
+	struct scmi_protocol_version_p2a return_values = {
+		.status = SCMI_SUCCESS,
+		.version = SCMI_PROTOCOL_VERSION_SENSOR,
+	};
+
+	if (msg->in_size != 0U) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void report_attributes(struct scmi_msg *msg)
+{
+	unsigned int addr[2];
+	unsigned int len;
+
+	struct scmi_protocol_attributes_p2a_sensor return_values = {
+		.status = SCMI_SUCCESS,
+	};
+
+	if (msg->in_size != 0U) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	return_values.num_sensors = plat_scmi_sensor_count(msg->agent_id);
+	return_values.max_reqs = plat_scmi_sensor_max_requests(msg->agent_id);
+	len = plat_scmi_sensor_reg(msg->agent_id, addr);
+	if (len != 0U) {
+		return_values.sensor_reg_low = addr[0];
+		return_values.sensor_reg_high = addr[1];
+		return_values.sensor_reg_len = len;
+	}
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void report_message_attributes(struct scmi_msg *msg)
+{
+	struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in;
+	struct scmi_protocol_message_attributes_p2a return_values = {
+		.status = SCMI_SUCCESS,
+		/* For this protocol, attributes shall be zero */
+		.attributes = 0U,
+	};
+
+	if (msg->in_size != sizeof(*in_args)) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	if (!message_id_is_supported(in_args->message_id)) {
+		scmi_status_response(msg, SCMI_NOT_FOUND);
+		return;
+	}
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void scmi_sensor_description_get(struct scmi_msg *msg)
+{
+	const struct scmi_sensor_description_get_a2p *in_args = (void *)msg->in;
+	struct scmi_sensor_description_get_p2a return_values = {
+		.status = SCMI_SUCCESS,
+	};
+	struct scmi_sensor_desc desc;
+	unsigned int desc_index = 0U;
+	unsigned int num_sensor_flags;
+
+	if (msg->in_size != sizeof(*in_args)) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	desc_index = SPECULATION_SAFE_VALUE(in_args->desc_index);
+
+	num_sensor_flags = plat_scmi_sensor_description_get(msg->agent_id, desc_index,
+							    &desc);
+	return_values.num_sensor_flags = num_sensor_flags;
+
+	memcpy(msg->out, &return_values, sizeof(return_values));
+	memcpy(msg->out + sizeof(return_values), &desc, sizeof(desc));
+	msg->out_size_out = sizeof(return_values) + sizeof(struct scmi_sensor_desc);
+}
+
+static void scmi_sensor_config_get(struct scmi_msg *msg)
+{
+	const struct scmi_sensor_config_get_a2p *in_args = (void *)msg->in;
+	struct scmi_sensor_config_get_p2a return_values = {
+		.status = SCMI_SUCCESS,
+	};
+	unsigned int sensor_id = 0U;
+	uint32_t update_interval, state, timestamped;
+
+	if (msg->in_size != sizeof(*in_args)) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	sensor_id = SPECULATION_SAFE_VALUE(in_args->sensor_id);
+
+	if (sensor_id >= plat_scmi_sensor_count(msg->agent_id)) {
+		scmi_status_response(msg, SCMI_INVALID_PARAMETERS);
+		return;
+	}
+
+	update_interval = plat_scmi_sensor_update_interval(msg->agent_id, sensor_id);
+	state = plat_scmi_sensor_state(msg->agent_id, sensor_id);
+	timestamped = plat_scmi_sensor_timestamped(msg->agent_id, sensor_id);
+	return_values.sensor_config = (update_interval << 11) | (timestamped << 1) | state;
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void scmi_sensor_reading_get(struct scmi_msg *msg)
+{
+	const struct scmi_sensor_reading_get_a2p *in_args = (void *)msg->in;
+	struct scmi_sensor_reading_get_p2a return_values = {
+		.status = SCMI_SUCCESS,
+	};
+	unsigned int sensor_id = 0U;
+	int32_t ret;
+
+	if (msg->in_size != sizeof(*in_args)) {
+		scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
+		return;
+	}
+
+	sensor_id = SPECULATION_SAFE_VALUE(in_args->sensor_id);
+
+	if (sensor_id >= plat_scmi_sensor_count(msg->agent_id)) {
+		scmi_status_response(msg, SCMI_INVALID_PARAMETERS);
+		return;
+	}
+
+	ret = plat_scmi_sensor_reading_get(msg->agent_id, sensor_id,
+					  (uint32_t *)&return_values.val);
+	if (ret) {
+		scmi_status_response(msg, SCMI_HARDWARE_ERROR);
+		return;
+	}
+
+	scmi_write_response(msg, &return_values, sizeof(return_values));
+}
+
+static void scmi_sensor_list_update_intervals(struct scmi_msg *msg)
+{
+	/* TODO */
+	scmi_status_response(msg, SCMI_NOT_SUPPORTED);
+}
+
+static const scmi_msg_handler_t scmi_sensor_handler_table[SCMI_SENSOR_MAX] = {
+	[SCMI_PROTOCOL_VERSION] = report_version,
+	[SCMI_PROTOCOL_ATTRIBUTES] = report_attributes,
+	[SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes,
+	[SCMI_SENSOR_DESCRIPTION_GET] = scmi_sensor_description_get,
+	[SCMI_SENSOR_CONFIG_GET] = scmi_sensor_config_get,
+	[SCMI_SENSOR_LIST_UPDATE_INTERVALS] = scmi_sensor_list_update_intervals,
+	[SCMI_SENSOR_READING_GET] = scmi_sensor_reading_get,
+};
+
+static bool message_id_is_supported(size_t message_id)
+{
+	return scmi_sensor_handler_table[message_id] != NULL;
+}
+
+scmi_msg_handler_t scmi_msg_get_sensor_handler(struct scmi_msg *msg)
+{
+	unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id);
+
+	if (!message_id_is_supported(message_id)) {
+		VERBOSE("pd handle not found %u\n", msg->message_id);
+		return NULL;
+	}
+
+	return scmi_sensor_handler_table[message_id];
+}
diff --git a/drivers/scmi-msg/sensor.h b/drivers/scmi-msg/sensor.h
new file mode 100644
index 00000000..28cbb1ed
--- /dev/null
+++ b/drivers/scmi-msg/sensor.h
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2023-2024 NXP
+ */
+
+#ifndef SCMI_MSG_SENSOR_H
+#define SCMI_MSG_SENSOR_H
+
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+
+#define SCMI_PROTOCOL_VERSION_SENSOR	0x20000U
+
+/*
+ * Identifiers of the SCMI SENSOR Protocol commands
+ */
+enum scmi_sensor_command_id {
+	SCMI_SENSOR_DESCRIPTION_GET = 0x003,
+	SCMI_SENSOR_TRIP_POINT_NOTIFY = 0x004,
+	SCMI_SENSOR_TRIP_POINT_CONFIG = 0x005,
+	SCMI_SENSOR_READING_GET = 0x006,
+	SCMI_SENSOR_AXIS_DESCRIPTION_GET = 0x007,
+	SCMI_SENSOR_LIST_UPDATE_INTERVALS = 0x008,
+	SCMI_SENSOR_CONFIG_GET = 0x009,
+	SCMI_SENSOR_CONFIG_SET = 0x00A,
+	SCMI_SENSOR_CONTINUOUS_UPDATE_NOTIFY = 0x00B,
+	SCMI_SENSOR_MAX = 0x00C,
+};
+
+/* Protocol attributes */
+struct scmi_protocol_attributes_p2a_sensor {
+	int32_t status;
+	int16_t num_sensors;
+	uint8_t max_reqs;
+	uint8_t res;
+	uint32_t sensor_reg_low;
+	uint32_t sensor_reg_high;
+	uint32_t sensor_reg_len;
+};
+
+#define SCMI_SENSOR_NAME_LENGTH_MAX	16U
+
+struct scmi_sensor_desc {
+	uint32_t id;
+	uint32_t attr_low;
+	uint32_t attr_high;
+	uint8_t name[SCMI_SENSOR_NAME_LENGTH_MAX];
+	uint32_t power;
+	uint32_t resolution;
+	int32_t min_range_low;
+	int32_t min_range_high;
+	int32_t max_range_low;
+	int32_t max_range_high;
+};
+
+struct scmi_sensor_description_get_a2p {
+	uint32_t desc_index;
+};
+
+struct scmi_sensor_description_get_p2a {
+	int32_t status;
+	uint32_t num_sensor_flags;
+};
+
+struct scmi_sensor_config_get_a2p {
+	uint32_t sensor_id;
+};
+
+struct scmi_sensor_config_get_p2a {
+	int32_t status;
+	uint32_t sensor_config;
+};
+
+/*
+ * Sensor Reading Get
+ */
+struct scmi_sensor_reading_get_a2p {
+	uint32_t sensor_id;
+	uint32_t flags;
+};
+
+struct scmi_sensor_val {
+	uint32_t value_low;
+	uint32_t value_high;
+	uint32_t timestap_low;
+	uint32_t timestap_high;
+};
+
+struct scmi_sensor_reading_get_p2a {
+	int32_t status;
+	struct scmi_sensor_val val;
+};
+
+typedef struct {
+	uint16_t (*sensor_count)(unsigned int agent_id);
+	uint8_t (*sensor_max_request)(unsigned int agent_id);
+	uint32_t (*get_sensor_req)(unsigned int agent_id, unsigned int *addr);
+	int32_t (*sensor_reading_get)(uint32_t agent_id, uint16_t sensor_id,
+				      uint32_t *val);
+	uint32_t (*sensor_description_get)(unsigned int agent_id, uint16_t sensor_id,
+					  struct scmi_sensor_desc *desc);
+	uint32_t (*sensor_update_interval)(uint32_t agent_id, uint16_t sensor_id);
+	uint32_t (*sensor_state)(uint32_t agent_id, uint16_t sensor_id);
+	uint16_t (*sensor_timestamped)(uint32_t agent_id, uint16_t sensor_id);
+} plat_scmi_sensor_ops_t;
+
+#define REGISTER_SCMI_SENSOR_OPS(_sensor_count, _sensor_max_request, \
+				 _get_sensor_req, _sensor_reading_get, \
+				 _sensor_description_get, _sensor_update_interval, \
+				 _sensor_state, _sensor_timestamped) \
+	const plat_scmi_sensor_ops_t sensor_ops = { \
+		.sensor_count = _sensor_count, \
+		.sensor_max_request = _sensor_max_request, \
+		.get_sensor_req = _get_sensor_req, \
+		.sensor_reading_get = _sensor_reading_get, \
+		.sensor_description_get = _sensor_description_get, \
+		.sensor_update_interval = _sensor_update_interval, \
+		.sensor_state = _sensor_state, \
+		.sensor_timestamped = _sensor_timestamped, \
+	}
+
+extern const plat_scmi_sensor_ops_t sensor_ops;
+
+#endif /* SCMI_MSG_SENSOR_H */
diff --git a/drivers/st/bsec/bsec2.c b/drivers/st/bsec/bsec2.c
index 68d3a5b8..db07d1c5 100644
--- a/drivers/st/bsec/bsec2.c
+++ b/drivers/st/bsec/bsec2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,15 +21,26 @@
 #define BSEC_IP_VERSION_2_0	U(0x20)
 #define BSEC_IP_ID_2		U(0x100032)
 
+/*
+ * IP configuration
+ */
+#define BSEC_OTP_MASK			GENMASK(4, 0)
+#define BSEC_OTP_BANK_SHIFT		5
+#define BSEC_TIMEOUT_VALUE		U(0xFFFF)
+
 #define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT)
 
-static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused;
+static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __maybe_unused;
 
+static uint32_t bsec_shadow_register(uint32_t otp);
 static uint32_t bsec_power_safmem(bool power);
+static uint32_t bsec_get_version(void);
+static uint32_t bsec_get_id(void);
+static uint32_t bsec_get_status(void);
+static uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value);
 
 /* BSEC access protection */
 static spinlock_t bsec_spinlock;
-static uintptr_t bsec_base;
 
 static void bsec_lock(void)
 {
@@ -47,7 +58,7 @@ static void bsec_unlock(void)
 
 static bool is_otp_invalid_mode(void)
 {
-	bool ret = ((bsec_get_status() & BSEC_MODE_INVALID) == BSEC_MODE_INVALID);
+	bool ret = ((bsec_get_status() & BSEC_OTP_STATUS_INVALID) == BSEC_OTP_STATUS_INVALID);
 
 	if (ret) {
 		ERROR("OTP mode is OTP-INVALID\n");
@@ -155,15 +166,17 @@ static void bsec_late_init(void)
 	struct dt_node_info bsec_info;
 
 	if (fdt_get_address(&fdt) == 0) {
+		EARLY_ERROR("%s: DT not found\n", __func__);
 		panic();
 	}
 
 	node = bsec_get_dt_node(&bsec_info);
 	if (node < 0) {
+		EARLY_ERROR("%s: BSEC node not found\n", __func__);
 		panic();
 	}
 
-	assert(bsec_base == bsec_info.base);
+	assert(bsec_info.base == BSEC_BASE);
 
 	bsec_dt_otp_nsec_access(fdt, node);
 }
@@ -177,6 +190,11 @@ static uint32_t otp_bank_offset(uint32_t otp)
 	       sizeof(uint32_t);
 }
 
+static uint32_t otp_bit_mask(uint32_t otp)
+{
+	return BIT(otp & BSEC_OTP_MASK);
+}
+
 /*
  * bsec_check_error: check BSEC error status.
  * otp: OTP number.
@@ -186,10 +204,10 @@ static uint32_t otp_bank_offset(uint32_t otp)
  */
 static uint32_t bsec_check_error(uint32_t otp, bool check_disturbed)
 {
-	uint32_t bit = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bit = otp_bit_mask(otp);
 	uint32_t bank = otp_bank_offset(otp);
 
-	if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) {
+	if ((mmio_read_32(BSEC_BASE + BSEC_ERROR_OFF + bank) & bit) != 0U) {
 		return BSEC_ERROR;
 	}
 
@@ -197,7 +215,7 @@ static uint32_t bsec_check_error(uint32_t otp, bool check_disturbed)
 		return BSEC_OK;
 	}
 
-	if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
+	if ((mmio_read_32(BSEC_BASE + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
 		return BSEC_DISTURBED;
 	}
 
@@ -210,15 +228,21 @@ static uint32_t bsec_check_error(uint32_t otp, bool check_disturbed)
  */
 uint32_t bsec_probe(void)
 {
-	bsec_base = BSEC_BASE;
+	uint32_t version;
+	uint32_t id;
 
 	if (is_otp_invalid_mode()) {
+		EARLY_ERROR("%s: otp_invalid_mod\n", __func__);
 		return BSEC_ERROR;
 	}
 
-	if ((((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_1_1) &&
-	     ((bsec_get_version() & BSEC_IPVR_MSK) != BSEC_IP_VERSION_2_0)) ||
-	    (bsec_get_id() != BSEC_IP_ID_2)) {
+	version = bsec_get_version();
+	id = bsec_get_id();
+
+	if (((version != BSEC_IP_VERSION_1_1) &&
+	     (version != BSEC_IP_VERSION_2_0)) ||
+	    (id != BSEC_IP_ID_2)) {
+		EARLY_ERROR("%s: version = 0x%x, id = 0x%x\n", __func__, version, id);
 		panic();
 	}
 
@@ -228,103 +252,12 @@ uint32_t bsec_probe(void)
 	return BSEC_OK;
 }
 
-/*
- * bsec_get_base: return BSEC base address.
- */
-uint32_t bsec_get_base(void)
-{
-	return bsec_base;
-}
-
-/*
- * bsec_set_config: enable and configure BSEC.
- * cfg: pointer to param structure used to set register.
- * return value: BSEC_OK if no error.
- */
-uint32_t bsec_set_config(struct bsec_config *cfg)
-{
-	uint32_t value;
-	uint32_t result;
-
-	if (is_otp_invalid_mode()) {
-		return BSEC_ERROR;
-	}
-
-	value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) &
-						BSEC_CONF_FRQ_MASK) |
-		 (((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) &
-						BSEC_CONF_PRG_WIDTH_MASK) |
-		 (((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) &
-						BSEC_CONF_TREAD_MASK));
-
-	bsec_lock();
-
-	mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value);
-
-	bsec_unlock();
-
-	result = bsec_power_safmem((bool)cfg->power &
-				   BSEC_CONF_POWER_UP_MASK);
-	if (result != BSEC_OK) {
-		return result;
-	}
-
-	value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) &
-						UPPER_OTP_LOCK_MASK) |
-		 (((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) &
-						DENREG_LOCK_MASK) |
-		 (((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) &
-						GPLOCK_LOCK_MASK));
-
-	bsec_lock();
-
-	mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value);
-
-	bsec_unlock();
-
-	return BSEC_OK;
-}
-
-/*
- * bsec_get_config: return config parameters set in BSEC registers.
- * cfg: config param return.
- * return value: BSEC_OK if no error.
- */
-uint32_t bsec_get_config(struct bsec_config *cfg)
-{
-	uint32_t value;
-
-	if (cfg == NULL) {
-		return BSEC_INVALID_PARAM;
-	}
-
-	value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
-	cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >>
-						BSEC_CONF_POWER_UP_SHIFT);
-	cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >>
-						BSEC_CONF_FRQ_SHIFT);
-	cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >>
-						BSEC_CONF_PRG_WIDTH_SHIFT);
-	cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >>
-						BSEC_CONF_TREAD_SHIFT);
-
-	value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF);
-	cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >>
-						UPPER_OTP_LOCK_SHIFT);
-	cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >>
-						DENREG_LOCK_SHIFT);
-	cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >>
-						GPLOCK_LOCK_SHIFT);
-
-	return BSEC_OK;
-}
-
 /*
  * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
  * otp: OTP number.
  * return value: BSEC_OK if no error.
  */
-uint32_t bsec_shadow_register(uint32_t otp)
+static uint32_t bsec_shadow_register(uint32_t otp)
 {
 	uint32_t result;
 	bool value;
@@ -345,7 +278,7 @@ uint32_t bsec_shadow_register(uint32_t otp)
 			otp);
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) {
 		result = bsec_power_safmem(true);
 
 		if (result != BSEC_OK) {
@@ -357,9 +290,9 @@ uint32_t bsec_shadow_register(uint32_t otp)
 
 	bsec_lock();
 
-	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
 
-	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+	while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) {
 		;
 	}
 
@@ -392,7 +325,7 @@ uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
 		return BSEC_INVALID_PARAM;
 	}
 
-	*val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF +
+	*val = mmio_read_32(BSEC_BASE + BSEC_OTP_DATA_OFF +
 			    (otp * sizeof(uint32_t)));
 
 	return BSEC_OK;
@@ -427,7 +360,7 @@ uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
 	/* Ensure integrity of each register access sequence */
 	bsec_lock();
 
-	mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF +
+	mmio_write_32(BSEC_BASE + BSEC_OTP_DATA_OFF +
 		      (otp * sizeof(uint32_t)), val);
 
 	bsec_unlock();
@@ -470,12 +403,11 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
 		return BSEC_PROG_FAIL;
 	}
 
-	if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) &
-	     BIT(BSEC_LOCK_PROGRAM)) != 0U) {
+	if ((mmio_read_32(BSEC_BASE + BSEC_OTP_LOCK_OFF) & GPLOCK_LOCK_MASK) != 0U) {
 		WARN("BSEC: GPLOCK activated, prog will be ignored\n");
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) {
 		result = bsec_power_safmem(true);
 
 		if (result != BSEC_OK) {
@@ -487,15 +419,15 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
 
 	bsec_lock();
 
-	mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_WRDATA_OFF, val);
 
-	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
 
-	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+	while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) {
 		;
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PROGFAIL) != 0U) {
 		result = BSEC_PROG_FAIL;
 	} else {
 		result = bsec_check_error(otp, true);
@@ -517,6 +449,7 @@ uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
  * otp: OTP number.
  * return value: BSEC_OK if no error.
  */
+#if defined(IMAGE_BL32)
 uint32_t bsec_permanent_lock_otp(uint32_t otp)
 {
 	uint32_t result;
@@ -532,7 +465,7 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp)
 		return BSEC_INVALID_PARAM;
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) {
 		result = bsec_power_safmem(true);
 
 		if (result != BSEC_OK) {
@@ -554,16 +487,16 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp)
 
 	bsec_lock();
 
-	mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_WRDATA_OFF, data);
 
-	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF,
+	mmio_write_32(BSEC_BASE + BSEC_OTP_CTRL_OFF,
 		      addr | BSEC_WRITE | BSEC_LOCK);
 
-	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+	while ((bsec_get_status() & BSEC_OTP_STATUS_BUSY) != 0U) {
 		;
 	}
 
-	if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+	if ((bsec_get_status() & BSEC_OTP_STATUS_PROGFAIL) != 0U) {
 		result = BSEC_PROG_FAIL;
 	} else {
 		result = bsec_check_error(otp, false);
@@ -579,30 +512,14 @@ uint32_t bsec_permanent_lock_otp(uint32_t otp)
 
 	return result;
 }
-
-/*
- * bsec_write_debug_conf: write value in debug feature.
- *	to enable/disable debug service.
- * val: value to write.
- * return value: none.
- */
-void bsec_write_debug_conf(uint32_t val)
-{
-	if (is_otp_invalid_mode()) {
-		return;
-	}
-
-	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_DEN_OFF, val & BSEC_DEN_ALL_MSK);
-	bsec_unlock();
-}
+#endif
 
 /*
  * bsec_read_debug_conf: return debug configuration register value.
  */
 uint32_t bsec_read_debug_conf(void)
 {
-	return mmio_read_32(bsec_base + BSEC_DEN_OFF);
+	return mmio_read_32(BSEC_BASE + BSEC_DEN_OFF);
 }
 
 /*
@@ -618,59 +535,35 @@ void bsec_write_scratch(uint32_t val)
 	}
 
 	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_SCRATCH_OFF, val);
+	mmio_write_32(BSEC_BASE + BSEC_SCRATCH_OFF, val);
 	bsec_unlock();
 #else
 	mmio_write_32(BSEC_BASE + BSEC_SCRATCH_OFF, val);
 #endif
 }
 
-/*
- * bsec_read_scratch: return scratch register value.
- */
-uint32_t bsec_read_scratch(void)
-{
-	return mmio_read_32(bsec_base + BSEC_SCRATCH_OFF);
-}
-
 /*
  * bsec_get_status: return status register value.
  */
-uint32_t bsec_get_status(void)
-{
-	return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF);
-}
-
-/*
- * bsec_get_hw_conf: return hardware configuration register value.
- */
-uint32_t bsec_get_hw_conf(void)
+static uint32_t bsec_get_status(void)
 {
-	return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF);
+	return mmio_read_32(BSEC_BASE + BSEC_OTP_STATUS_OFF);
 }
 
 /*
  * bsec_get_version: return BSEC version register value.
  */
-uint32_t bsec_get_version(void)
+static uint32_t bsec_get_version(void)
 {
-	return mmio_read_32(bsec_base + BSEC_IPVR_OFF);
+	return mmio_read_32(BSEC_BASE + BSEC_IPVR_OFF) & BSEC_IPVR_MSK;
 }
 
 /*
  * bsec_get_id: return BSEC ID register value.
  */
-uint32_t bsec_get_id(void)
+static uint32_t bsec_get_id(void)
 {
-	return mmio_read_32(bsec_base + BSEC_IP_ID_OFF);
-}
-
-/*
- * bsec_get_magic_id: return BSEC magic number register value.
- */
-uint32_t bsec_get_magic_id(void)
-{
-	return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF);
+	return mmio_read_32(BSEC_BASE + BSEC_IP_ID_OFF);
 }
 
 /*
@@ -681,7 +574,7 @@ uint32_t bsec_get_magic_id(void)
 uint32_t bsec_set_sr_lock(uint32_t otp)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 
 	if (is_otp_invalid_mode()) {
 		return BSEC_ERROR;
@@ -692,7 +585,7 @@ uint32_t bsec_set_sr_lock(uint32_t otp)
 	}
 
 	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, otp_mask);
+	mmio_write_32(BSEC_BASE + BSEC_SRLOCK_OFF + bank, otp_mask);
 	bsec_unlock();
 
 	return BSEC_OK;
@@ -707,14 +600,14 @@ uint32_t bsec_set_sr_lock(uint32_t otp)
 uint32_t bsec_read_sr_lock(uint32_t otp, bool *value)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 	uint32_t bank_value;
 
 	if (otp > STM32MP1_OTP_MAX_ID) {
 		return BSEC_INVALID_PARAM;
 	}
 
-	bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_SRLOCK_OFF + bank);
 
 	*value = ((bank_value & otp_mask) != 0U);
 
@@ -729,7 +622,7 @@ uint32_t bsec_read_sr_lock(uint32_t otp, bool *value)
 uint32_t bsec_set_sw_lock(uint32_t otp)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 
 	if (is_otp_invalid_mode()) {
 		return BSEC_ERROR;
@@ -740,7 +633,7 @@ uint32_t bsec_set_sw_lock(uint32_t otp)
 	}
 
 	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, otp_mask);
+	mmio_write_32(BSEC_BASE + BSEC_SWLOCK_OFF + bank, otp_mask);
 	bsec_unlock();
 
 	return BSEC_OK;
@@ -762,7 +655,7 @@ uint32_t bsec_read_sw_lock(uint32_t otp, bool *value)
 		return BSEC_INVALID_PARAM;
 	}
 
-	bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_SWLOCK_OFF + bank);
 
 	*value = ((bank_value & otp_mask) != 0U);
 
@@ -777,7 +670,7 @@ uint32_t bsec_read_sw_lock(uint32_t otp, bool *value)
 uint32_t bsec_set_sp_lock(uint32_t otp)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 
 	if (is_otp_invalid_mode()) {
 		return BSEC_ERROR;
@@ -788,7 +681,7 @@ uint32_t bsec_set_sp_lock(uint32_t otp)
 	}
 
 	bsec_lock();
-	mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, otp_mask);
+	mmio_write_32(BSEC_BASE + BSEC_SPLOCK_OFF + bank, otp_mask);
 	bsec_unlock();
 
 	return BSEC_OK;
@@ -810,7 +703,7 @@ uint32_t bsec_read_sp_lock(uint32_t otp, bool *value)
 		return BSEC_INVALID_PARAM;
 	}
 
-	bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_SPLOCK_OFF + bank);
 
 	*value = ((bank_value & otp_mask) != 0U);
 
@@ -823,53 +716,23 @@ uint32_t bsec_read_sp_lock(uint32_t otp, bool *value)
  * value: read value (true or false).
  * return value: BSEC_OK if no error.
  */
-uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value)
+static uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value)
 {
 	uint32_t bank = otp_bank_offset(otp);
-	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t otp_mask = otp_bit_mask(otp);
 	uint32_t bank_value;
 
 	if (otp > STM32MP1_OTP_MAX_ID) {
 		return BSEC_INVALID_PARAM;
 	}
 
-	bank_value = mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank);
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_WRLOCK_OFF + bank);
 
 	*value = ((bank_value & otp_mask) != 0U);
 
 	return BSEC_OK;
 }
 
-/*
- * bsec_otp_lock: Lock Upper OTP or Global Programming or Debug Enable.
- * service: Service to lock, see header file.
- * return value: BSEC_OK if no error.
- */
-uint32_t bsec_otp_lock(uint32_t service)
-{
-	uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF;
-
-	if (is_otp_invalid_mode()) {
-		return BSEC_ERROR;
-	}
-
-	switch (service) {
-	case BSEC_LOCK_UPPER_OTP:
-		mmio_write_32(reg, BIT(BSEC_LOCK_UPPER_OTP));
-		break;
-	case BSEC_LOCK_DEBUG:
-		mmio_write_32(reg, BIT(BSEC_LOCK_DEBUG));
-		break;
-	case BSEC_LOCK_PROGRAM:
-		mmio_write_32(reg, BIT(BSEC_LOCK_PROGRAM));
-		break;
-	default:
-		return BSEC_INVALID_PARAM;
-	}
-
-	return BSEC_OK;
-}
-
 /*
  * bsec_power_safmem: Activate or deactivate SAFMEM power.
  * power: true to power up, false to power down.
@@ -882,7 +745,7 @@ static uint32_t bsec_power_safmem(bool power)
 
 	bsec_lock();
 
-	register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+	register_val = mmio_read_32(BSEC_BASE + BSEC_OTP_CONF_OFF);
 
 	if (power) {
 		register_val |= BSEC_CONF_POWER_UP_MASK;
@@ -890,15 +753,15 @@ static uint32_t bsec_power_safmem(bool power)
 		register_val &= ~BSEC_CONF_POWER_UP_MASK;
 	}
 
-	mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val);
+	mmio_write_32(BSEC_BASE + BSEC_OTP_CONF_OFF, register_val);
 
 	if (power) {
-		while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) &&
+		while (((bsec_get_status() & BSEC_OTP_STATUS_PWRON) == 0U) &&
 		       (timeout != 0U)) {
 			timeout--;
 		}
 	} else {
-		while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) &&
+		while (((bsec_get_status() & BSEC_OTP_STATUS_PWRON) != 0U) &&
 		       (timeout != 0U)) {
 			timeout--;
 		}
@@ -915,28 +778,29 @@ static uint32_t bsec_power_safmem(bool power)
 
 /*
  * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value.
- * otp_value: read value.
- * word: OTP number.
+ * val: read value.
+ * otp: OTP number.
  * return value: BSEC_OK if no error.
  */
-uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word)
+uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp)
 {
 	uint32_t result;
 
-	result = bsec_shadow_register(word);
+	result = bsec_shadow_register(otp);
 	if (result != BSEC_OK) {
-		ERROR("BSEC: %u Shadowing Error %u\n", word, result);
+		ERROR("BSEC: %u Shadowing Error %u\n", otp, result);
 		return result;
 	}
 
-	result = bsec_read_otp(otp_value, word);
+	result = bsec_read_otp(val, otp);
 	if (result != BSEC_OK) {
-		ERROR("BSEC: %u Read Error %u\n", word, result);
+		ERROR("BSEC: %u Read Error %u\n", otp, result);
 	}
 
 	return result;
 }
 
+#if defined(IMAGE_BL32)
 /*
  * bsec_check_nsec_access_rights: check non-secure access rights to target OTP.
  * otp: OTP number.
@@ -944,7 +808,6 @@ uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word)
  */
 uint32_t bsec_check_nsec_access_rights(uint32_t otp)
 {
-#if defined(IMAGE_BL32)
 	if (otp > STM32MP1_OTP_MAX_ID) {
 		return BSEC_INVALID_PARAM;
 	}
@@ -954,8 +817,33 @@ uint32_t bsec_check_nsec_access_rights(uint32_t otp)
 			return BSEC_ERROR;
 		}
 	}
-#endif
 
 	return BSEC_OK;
 }
+#endif
+
+uint32_t bsec_get_secure_state(void)
+{
+	uint32_t status = bsec_get_status();
+	uint32_t result = BSEC_STATE_INVALID;
+	uint32_t otp_enc_id __maybe_unused;
+	uint32_t otp_bit_len __maybe_unused;
+	int res __maybe_unused;
 
+	if ((status & BSEC_OTP_STATUS_INVALID) != 0U) {
+		result = BSEC_STATE_INVALID;
+	} else {
+		if ((status & BSEC_OTP_STATUS_SECURE) != 0U) {
+			if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
+				result = BSEC_STATE_SEC_CLOSED;
+			} else {
+				result = BSEC_STATE_SEC_OPEN;
+			}
+		} else {
+			/* OTP modes OPEN1 and OPEN2 are not supported */
+			result = BSEC_STATE_INVALID;
+		}
+	}
+
+	return result;
+}
diff --git a/drivers/st/bsec/bsec3.c b/drivers/st/bsec/bsec3.c
new file mode 100644
index 00000000..3fdaf16f
--- /dev/null
+++ b/drivers/st/bsec/bsec3.c
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+#include <drivers/st/bsec3_reg.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#define BSEC_IP_VERSION_1_0	U(0x10)
+#define BSEC_IP_ID_3		U(0x100033)
+
+#define MAX_NB_TRIES		U(3)
+
+/*
+ * IP configuration
+ */
+#define BSEC_OTP_MASK			GENMASK_32(4, 0)
+#define BSEC_OTP_BANK_SHIFT		U(5)
+#define BSEC_TIMEOUT_VALUE		U(0x800000) /* ~7sec @1.2GHz */
+
+/* Magic use to indicated valid SHADOW = 'B' 'S' 'E' 'C' */
+#define BSEC_MAGIC			U(0x42534543)
+
+#define OTP_MAX_SIZE			(STM32MP2_OTP_MAX_ID + U(1))
+
+struct bsec_shadow {
+	uint32_t magic;
+	uint32_t state;
+	uint32_t value[OTP_MAX_SIZE];
+	uint32_t status[OTP_MAX_SIZE];
+};
+
+static uint32_t otp_bank(uint32_t otp)
+{
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return (otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT;
+}
+
+static uint32_t otp_bit_mask(uint32_t otp)
+{
+	return BIT(otp & BSEC_OTP_MASK);
+}
+
+/*
+ * bsec_get_status: return status register value.
+ */
+static uint32_t bsec_get_status(void)
+{
+	return mmio_read_32(BSEC_BASE + BSEC_OTPSR);
+}
+
+/*
+ * bsec_get_version: return BSEC version.
+ */
+static uint32_t bsec_get_version(void)
+{
+	return mmio_read_32(BSEC_BASE + BSEC_VERR) & BSEC_VERR_MASK;
+}
+
+/*
+ * bsec_get_id: return BSEC ID.
+ */
+static uint32_t bsec_get_id(void)
+{
+	return mmio_read_32(BSEC_BASE + BSEC_IPIDR);
+}
+
+static bool is_fuse_shadowed(uint32_t otp)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+	uint32_t bank_value;
+
+	bank_value = mmio_read_32(BSEC_BASE + BSEC_SFSR(bank));
+
+	if ((bank_value & otp_mask) != 0U) {
+		return true;
+	}
+
+	return false;
+}
+
+static void poll_otp_status_busy(void)
+{
+	uint32_t timeout = BSEC_TIMEOUT_VALUE;
+
+	while (((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) && (timeout != 0U)) {
+		timeout--;
+	}
+
+	if ((bsec_get_status() & BSEC_OTPSR_BUSY) != 0U) {
+		ERROR("BSEC timeout\n");
+		panic();
+	}
+}
+
+static uint32_t check_read_error(uint32_t otp)
+{
+	uint32_t status = bsec_get_status();
+
+	if ((status & BSEC_OTPSR_SECF) != 0U) {
+		VERBOSE("BSEC read %u single error correction detected\n", otp);
+	}
+
+	if ((status & BSEC_OTPSR_PPLF) != 0U) {
+		VERBOSE("BSEC read %u permanent programming lock detected.\n", otp);
+	}
+
+	if ((status & BSEC_OTPSR_PPLMF) != 0U) {
+		ERROR("BSEC read %u error 0x%x\n", otp, status);
+		return BSEC_ERROR;
+	}
+
+	if ((status & (BSEC_OTPSR_DISTURBF | BSEC_OTPSR_DEDF | BSEC_OTPSR_AMEF)) != 0U) {
+		ERROR("BSEC read %u error 0x%x with invalid FVR\n", otp, status);
+		return BSEC_RETRY;
+	}
+
+	return BSEC_OK;
+}
+
+static uint32_t check_program_error(uint32_t otp)
+{
+	uint32_t status = bsec_get_status();
+
+	if ((status & BSEC_OTPSR_PROGFAIL) != 0U) {
+		ERROR("BSEC program %u error 0x%x\n", otp, status);
+		return BSEC_RETRY;
+	}
+
+	return BSEC_OK;
+}
+
+static void check_reset_error(void)
+{
+	uint32_t status = bsec_get_status();
+
+	/* check initial status reporting */
+	if ((status & BSEC_OTPSR_BUSY) != 0U) {
+		VERBOSE("BSEC reset and busy when OTPSR read\n");
+	}
+	if ((status & BSEC_OTPSR_HIDEUP) != 0U) {
+		VERBOSE("BSEC upper fuse are not accessible (HIDEUP)\n");
+	}
+	if ((status & BSEC_OTPSR_OTPSEC) != 0U) {
+		VERBOSE("BSEC reset single error correction detected\n");
+	}
+	if ((status & BSEC_OTPSR_OTPNVIR) == 0U) {
+		VERBOSE("BSEC reset first fuse word 0 is detected zero\n");
+	}
+	if ((status & BSEC_OTPSR_OTPERR) != 0U) {
+		ERROR("BSEC reset critical error 0x%x\n", status);
+		panic();
+	}
+	if ((status & BSEC_OTPSR_FUSEOK) != BSEC_OTPSR_FUSEOK) {
+		ERROR("BSEC reset critical error 0x%x\n", status);
+		panic();
+	}
+}
+
+static bool is_bsec_write_locked(void)
+{
+	return (mmio_read_32(BSEC_BASE + BSEC_LOCKR) & BSEC_LOCKR_GWLOCK_MASK) != 0U;
+}
+
+/*
+ * bsec_probe: initialize BSEC driver.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_probe(void)
+{
+	uint32_t version = bsec_get_version();
+	uint32_t id = bsec_get_id();
+
+	if ((version != BSEC_IP_VERSION_1_0) || (id != BSEC_IP_ID_3)) {
+		EARLY_ERROR("%s: version = 0x%x, id = 0x%x\n", __func__, version, id);
+		panic();
+	}
+
+	check_reset_error();
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+static uint32_t bsec_shadow_register(uint32_t otp)
+{
+	uint32_t result;
+	uint32_t i;
+	bool value;
+
+	result = bsec_read_sr_lock(otp, &value);
+	if (result != BSEC_OK) {
+		WARN("BSEC: %u Sticky-read bit read Error %u\n", otp, result);
+	} else if (value) {
+		VERBOSE("BSEC: OTP %u is locked and will not be refreshed\n", otp);
+	}
+
+	for (i = 0U; i < MAX_NB_TRIES; i++) {
+		mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp);
+
+		poll_otp_status_busy();
+
+		result = check_read_error(otp);
+		if (result != BSEC_RETRY) {
+			break;
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_write_otp: write a value in shadow OTP.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
+{
+	bool state;
+	uint32_t result;
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	if (!is_fuse_shadowed(otp)) {
+		return BSEC_ERROR;
+	}
+
+	if (is_bsec_write_locked()) {
+		return BSEC_WRITE_LOCKED;
+	}
+
+	result = bsec_read_sw_lock(otp, &state);
+	if (result != BSEC_OK) {
+		WARN("Shadow register is SW locked\n");
+		return result;
+	}
+
+	mmio_write_32(BSEC_BASE + BSEC_FVR(otp), val);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_program_otp: program a bit in SAFMEM after the prog.
+ *	The OTP data is not refreshed.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
+{
+	uint32_t result;
+	uint32_t i;
+	bool value;
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	if (is_bsec_write_locked() == true) {
+		return BSEC_WRITE_LOCKED;
+	}
+
+	result = bsec_read_sp_lock(otp, &value);
+	if (result != BSEC_OK) {
+		WARN("BSEC: %u Sticky-prog bit read Error %u\n", otp, result);
+	} else if (value) {
+		WARN("BSEC: OTP locked, prog will be ignored\n");
+		return BSEC_WRITE_LOCKED;
+	}
+
+	mmio_write_32(BSEC_BASE + BSEC_WDR, val);
+
+	for (i = 0U; i < MAX_NB_TRIES; i++) {
+		mmio_write_32(BSEC_BASE + BSEC_OTPCR, otp | BSEC_OTPCR_PROG);
+
+		poll_otp_status_busy();
+
+		result = check_program_error(otp);
+		if (result != BSEC_RETRY) {
+			break;
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_read_debug_conf: read debug configuration.
+ */
+uint32_t bsec_read_debug_conf(void)
+{
+	return mmio_read_32(BSEC_BASE + BSEC_DENR);
+}
+
+static uint32_t bsec_lock_register_set(uint32_t offset, uint32_t mask)
+{
+	uint32_t value = mmio_read_32(BSEC_BASE + offset);
+
+	/* The lock is already set */
+	if ((value & mask) != 0U) {
+		return BSEC_OK;
+	}
+
+	if (is_bsec_write_locked()) {
+		return BSEC_WRITE_LOCKED;
+	}
+
+	value |= mask;
+
+	mmio_write_32(BSEC_BASE + offset, value);
+
+	return BSEC_OK;
+}
+
+static bool bsec_lock_register_get(uint32_t offset, uint32_t mask)
+{
+	uint32_t value = mmio_read_32(BSEC_BASE + offset);
+
+	return (value & mask) != 0U;
+}
+
+/*
+ * bsec_set_sr_lock: set shadow-read lock.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_sr_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return bsec_lock_register_set(BSEC_SRLOCK(bank), otp_mask);
+}
+
+/*
+ * bsec_read_sr_lock: read shadow-read lock.
+ * otp: OTP number.
+ * value: read value (true or false).
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_sr_lock(uint32_t otp, bool *value)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	assert(value != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	*value = bsec_lock_register_get(BSEC_SRLOCK(bank), otp_mask);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_set_sw_lock: set shadow-write lock.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_sw_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return bsec_lock_register_set(BSEC_SWLOCK(bank), otp_mask);
+}
+
+/*
+ * bsec_read_sw_lock: read shadow-write lock.
+ * otp: OTP number.
+ * value: read value (true or false).
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_sw_lock(uint32_t otp, bool *value)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	assert(value != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	*value = bsec_lock_register_get(BSEC_SWLOCK(bank), otp_mask);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_set_sp_lock: set shadow-program lock.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_sp_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return bsec_lock_register_set(BSEC_SPLOCK(bank), otp_mask);
+}
+
+/*
+ * bsec_read_sp_lock: read shadow-program lock.
+ * otp: OTP number.
+ * value: read value (true or false).
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_sp_lock(uint32_t otp, bool *value)
+{
+	uint32_t bank = otp_bank(otp);
+	uint32_t otp_mask = otp_bit_mask(otp);
+
+	assert(value != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	*value = bsec_lock_register_get(BSEC_SPLOCK(bank), otp_mask);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_get_secure_state: read state in BSEC status register.
+ * return: secure state
+ */
+uint32_t bsec_get_secure_state(void)
+{
+	uint32_t state = BSEC_STATE_INVALID;
+	uint32_t status = bsec_get_status();
+	uint32_t bsec_sr = mmio_read_32(BSEC_BASE + BSEC_SR);
+
+	if ((status & BSEC_OTPSR_FUSEOK) == BSEC_OTPSR_FUSEOK) {
+		/* NVSTATE is only valid if FUSEOK */
+		uint32_t nvstates = (bsec_sr & BSEC_SR_NVSTATE_MASK) >> BSEC_SR_NVSTATE_SHIFT;
+
+		if (nvstates == BSEC_SR_NVSTATE_OPEN) {
+			state = BSEC_STATE_SEC_OPEN;
+		} else if (nvstates == BSEC_SR_NVSTATE_CLOSED) {
+			state = BSEC_STATE_SEC_CLOSED;
+		} else {
+			VERBOSE("%s nvstates = %u\n", __func__, nvstates);
+		}
+	}
+
+	return state;
+}
+
+/*
+ * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp)
+{
+	assert(val != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	*val = 0U;
+
+	if (is_bsec_write_locked()) {
+		return BSEC_WRITE_LOCKED;
+	}
+
+	if (!is_fuse_shadowed(otp)) {
+		uint32_t result = bsec_shadow_register(otp);
+
+		if (result != BSEC_OK) {
+			ERROR("BSEC: %u Shadowing Error %u\n", otp, result);
+			return result;
+		}
+	}
+
+	*val = mmio_read_32(BSEC_BASE + BSEC_FVR(otp));
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_read_otp: read an OTP data value.
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
+{
+	assert(val != NULL);
+	if (otp > STM32MP2_OTP_MAX_ID) {
+		panic();
+	}
+
+	return bsec_shadow_read_otp(val, otp);
+}
diff --git a/drivers/st/clk/clk-stm32-core.c b/drivers/st/clk/clk-stm32-core.c
index 9fe8c8cc..6787d504 100644
--- a/drivers/st/clk/clk-stm32-core.c
+++ b/drivers/st/clk/clk-stm32-core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -28,7 +28,7 @@ struct stm32_clk_priv *clk_stm32_get_priv(void)
 	return stm32_clock_data;
 }
 
-static void stm32mp1_clk_lock(struct spinlock *lock)
+static void _clk_lock(struct spinlock *lock)
 {
 	if (stm32mp_lock_available()) {
 		/* Assume interrupts are masked */
@@ -36,21 +36,21 @@ static void stm32mp1_clk_lock(struct spinlock *lock)
 	}
 }
 
-static void stm32mp1_clk_unlock(struct spinlock *lock)
+static void _clk_unlock(struct spinlock *lock)
 {
 	if (stm32mp_lock_available()) {
 		spin_unlock(lock);
 	}
 }
 
-void stm32mp1_clk_rcc_regs_lock(void)
+void clk_stm32_rcc_regs_lock(void)
 {
-	stm32mp1_clk_lock(&reg_lock);
+	_clk_lock(&reg_lock);
 }
 
-void stm32mp1_clk_rcc_regs_unlock(void)
+void clk_stm32_rcc_regs_unlock(void)
 {
-	stm32mp1_clk_unlock(&reg_lock);
+	_clk_unlock(&reg_lock);
 }
 
 #define TIMEOUT_US_1S	U(1000000)
@@ -224,6 +224,15 @@ const struct clk_stm32 *_clk_get(struct stm32_clk_priv *priv, int id)
 	return NULL;
 }
 
+static const struct stm32_clk_ops *_clk_get_ops(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+
+	assert(clk->ops != NO_OPS);
+
+	return priv->ops_array[clk->ops];
+}
+
 #define clk_div_mask(_width) GENMASK(((_width) - 1U), 0U)
 
 static unsigned int _get_table_div(const struct clk_div_table *table,
@@ -377,7 +386,7 @@ int _clk_stm32_set_parent_by_index(struct stm32_clk_priv *priv, int clk, int sel
 
 int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int clk_id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, clk_id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, clk_id);
 	const struct parent_cfg *parent;
 	uint16_t mux_id;
 	int sel;
@@ -394,8 +403,8 @@ int _clk_stm32_get_parent(struct stm32_clk_priv *priv, int clk_id)
 	mux_id &= MUX_PARENT_MASK;
 	parent = &priv->parents[mux_id];
 
-	if (clk->ops->get_parent != NULL) {
-		sel = clk->ops->get_parent(priv, clk_id);
+	if (ops->get_parent != NULL) {
+		sel = ops->get_parent(priv, clk_id);
 	} else {
 		sel = clk_mux_get_parent(priv, mux_id);
 	}
@@ -464,7 +473,7 @@ int clk_get_index(struct stm32_clk_priv *priv, unsigned long binding_id)
 
 unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 	int parent;
 
 	if ((unsigned int)id >= priv->num) {
@@ -476,14 +485,14 @@ unsigned long _clk_stm32_get_rate(struct stm32_clk_priv *priv, int id)
 		return 0UL;
 	}
 
-	if (clk->ops->recalc_rate != NULL) {
+	if (ops->recalc_rate != NULL) {
 		unsigned long prate = 0UL;
 
 		if (parent != CLK_IS_ROOT) {
 			prate = _clk_stm32_get_rate(priv, parent);
 		}
 
-		return clk->ops->recalc_rate(priv, id, prate);
+		return ops->recalc_rate(priv, id, prate);
 	}
 
 	if (parent == CLK_IS_ROOT) {
@@ -520,10 +529,10 @@ bool _stm32_clk_is_flags(struct stm32_clk_priv *priv, int id, uint8_t flag)
 
 int clk_stm32_enable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 
-	if (clk->ops->enable != NULL) {
-		clk->ops->enable(priv, id);
+	if (ops->enable != NULL) {
+		ops->enable(priv, id);
 	}
 
 	return 0;
@@ -550,7 +559,7 @@ static int _clk_stm32_enable_core(struct stm32_clk_priv *priv, int id)
 
 	priv->gate_refcounts[id]++;
 
-	if (priv->gate_refcounts[id] == UINT_MAX) {
+	if (priv->gate_refcounts[id] == UINT8_MAX) {
 		ERROR("%s: %d max enable count !", __func__, id);
 		panic();
 	}
@@ -562,19 +571,19 @@ int _clk_stm32_enable(struct stm32_clk_priv *priv, int id)
 {
 	int ret;
 
-	stm32mp1_clk_lock(&refcount_lock);
+	_clk_lock(&refcount_lock);
 	ret = _clk_stm32_enable_core(priv, id);
-	stm32mp1_clk_unlock(&refcount_lock);
+	_clk_unlock(&refcount_lock);
 
 	return ret;
 }
 
 void clk_stm32_disable_call_ops(struct stm32_clk_priv *priv, uint16_t id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 
-	if (clk->ops->disable != NULL) {
-		clk->ops->disable(priv, id);
+	if (ops->disable != NULL) {
+		ops->disable(priv, id);
 	}
 }
 
@@ -610,19 +619,19 @@ static void _clk_stm32_disable_core(struct stm32_clk_priv *priv, int id)
 
 void _clk_stm32_disable(struct stm32_clk_priv *priv, int id)
 {
-	stm32mp1_clk_lock(&refcount_lock);
+	_clk_lock(&refcount_lock);
 
 	_clk_stm32_disable_core(priv, id);
 
-	stm32mp1_clk_unlock(&refcount_lock);
+	_clk_unlock(&refcount_lock);
 }
 
 bool _clk_stm32_is_enabled(struct stm32_clk_priv *priv, int id)
 {
-	const struct clk_stm32 *clk = _clk_get(priv, id);
+	const struct stm32_clk_ops *ops = _clk_get_ops(priv, id);
 
-	if (clk->ops->is_enabled != NULL) {
-		return clk->ops->is_enabled(priv, id);
+	if (ops->is_enabled != NULL) {
+		return ops->is_enabled(priv, id);
 	}
 
 	return priv->gate_refcounts[id];
@@ -957,6 +966,10 @@ int clk_stm32_osc_gate_enable(struct stm32_clk_priv *priv, int id)
 {
 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
 
+	if (osc_data->frequency == 0UL) {
+		return 0;
+	}
+
 	_clk_stm32_gate_enable(priv, osc_data->gate_id);
 
 	if (_clk_stm32_gate_wait_ready(priv, osc_data->gate_rdy_id, true) != 0U) {
@@ -971,6 +984,10 @@ void clk_stm32_osc_gate_disable(struct stm32_clk_priv *priv, int id)
 {
 	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, id);
 
+	if (osc_data->frequency == 0UL) {
+		return;
+	}
+
 	_clk_stm32_gate_disable(priv, osc_data->gate_id);
 
 	if (_clk_stm32_gate_wait_ready(priv, osc_data->gate_rdy_id, false) != 0U) {
@@ -1073,12 +1090,10 @@ int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base)
 	priv->base = base;
 
 	for (i = 0U; i < priv->num; i++) {
-		const struct clk_stm32 *clk = _clk_get(priv, i);
-
-		assert(clk->ops != NULL);
+		const struct stm32_clk_ops *ops = _clk_get_ops(priv, i);
 
-		if (clk->ops->init != NULL) {
-			clk->ops->init(priv, i);
+		if (ops->init != NULL) {
+			ops->init(priv, i);
 		}
 	}
 
diff --git a/drivers/st/clk/clk-stm32-core.h b/drivers/st/clk/clk-stm32-core.h
index 8bfb5134..bfb5f119 100644
--- a/drivers/st/clk/clk-stm32-core.h
+++ b/drivers/st/clk/clk-stm32-core.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -21,23 +21,23 @@ struct gate_cfg {
 };
 
 struct clk_div_table {
-	unsigned int val;
-	unsigned int div;
+	uint16_t val;
+	uint16_t div;
 };
 
 struct div_cfg {
+	const struct clk_div_table *table;
 	uint16_t offset;
 	uint8_t shift;
 	uint8_t width;
 	uint8_t flags;
 	uint8_t bitrdy;
-	const struct clk_div_table *table;
 };
 
 struct parent_cfg {
-	uint8_t num_parents;
 	const uint16_t *id_parents;
 	struct mux_cfg *mux;
+	uint8_t num_parents;
 };
 
 struct stm32_clk_priv;
@@ -56,9 +56,9 @@ struct stm32_clk_ops {
 struct clk_stm32 {
 	uint16_t binding;
 	uint16_t parent;
+	uint8_t ops;
 	uint8_t flags;
 	void *clock_cfg;
-	const struct stm32_clk_ops *ops;
 };
 
 struct stm32_clk_priv {
@@ -73,8 +73,9 @@ struct stm32_clk_priv {
 	const uint32_t nb_div;
 	struct clk_oscillator_data *osci_data;
 	const uint32_t nb_osci_data;
-	uint32_t *gate_refcounts;
+	uint8_t *gate_refcounts;
 	void *pdata;
+	const struct stm32_clk_ops **ops_array;
 };
 
 struct stm32_clk_bypass {
@@ -97,18 +98,14 @@ struct stm32_clk_drive {
 
 struct clk_oscillator_data {
 	const char *name;
-	uint16_t id_clk;
-	unsigned long frequency;
-	uint16_t gate_id;
-	uint16_t gate_rdy_id;
 	struct stm32_clk_bypass *bypass;
 	struct stm32_clk_css *css;
 	struct stm32_clk_drive *drive;
-};
+	unsigned long frequency;
+	uint16_t id_clk;
+	uint16_t gate_id;
+	uint16_t gate_rdy_id;
 
-struct clk_fixed_rate {
-	const char *name;
-	unsigned long fixed_rate;
 };
 
 struct clk_gate_cfg {
@@ -144,6 +141,9 @@ struct clk_gate_cfg {
 #define MASK_WIDTH_SHIFT(_width, _shift) \
 	GENMASK(((_width) + (_shift) - 1U), (_shift))
 
+void clk_stm32_rcc_regs_lock(void);
+void clk_stm32_rcc_regs_unlock(void);
+
 int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base);
 void clk_stm32_enable_critical_clocks(void);
 
@@ -218,7 +218,7 @@ void clk_stm32_display_clock_info(void);
 #endif
 
 struct clk_stm32_div_cfg {
-	int id;
+	uint8_t id;
 };
 
 #define STM32_DIV(idx, _binding, _parent, _flags, _div_id) \
@@ -229,11 +229,11 @@ struct clk_stm32_div_cfg {
 		.clock_cfg	= &(struct clk_stm32_div_cfg){\
 			.id	= (_div_id),\
 		},\
-		.ops		= &clk_stm32_divider_ops,\
+		.ops		= STM32_DIVIDER_OPS,\
 	}
 
 struct clk_stm32_gate_cfg {
-	int id;
+	uint8_t id;
 };
 
 #define STM32_GATE(idx, _binding, _parent, _flags, _gate_id) \
@@ -244,12 +244,12 @@ struct clk_stm32_gate_cfg {
 		.clock_cfg	= &(struct clk_stm32_gate_cfg){\
 			.id	= (_gate_id),\
 		},\
-		.ops		= &clk_stm32_gate_ops,\
+		.ops		= STM32_GATE_OPS,\
 	}
 
 struct fixed_factor_cfg {
-	unsigned int mult;
-	unsigned int div;
+	uint8_t mult;
+	uint8_t div;
 };
 
 unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
@@ -263,7 +263,7 @@ unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
 			.mult	= (_mult),\
 			.div	= (_div),\
 		},\
-		.ops		= &clk_fixed_factor_ops,\
+		.ops		= FIXED_FACTOR_OPS,\
 	}
 
 #define GATE(idx, _binding, _parent, _flags, _offset, _bit_idx) \
@@ -275,7 +275,7 @@ unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
 			.offset		= (_offset),\
 			.bit_idx	= (_bit_idx),\
 		},\
-		.ops		= &clk_gate_ops,\
+		.ops		= GATE_OPS,\
 	}
 
 #define STM32_MUX(idx, _binding, _mux_id, _flags) \
@@ -284,7 +284,7 @@ unsigned long fixed_factor_recalc_rate(struct stm32_clk_priv *priv,
 		.parent		= (MUX(_mux_id)),\
 		.flags		= (_flags),\
 		.clock_cfg	= NULL,\
-		.ops		= (&clk_mux_ops),\
+		.ops		= STM32_MUX_OPS\
 	}
 
 struct clk_timer_cfg {
@@ -301,7 +301,7 @@ struct clk_timer_cfg {
 			.apbdiv = (_apbdiv),\
 			.timpre = (_timpre),\
 		},\
-		.ops		= &clk_timer_ops,\
+		.ops		= STM32_TIMER_OPS,\
 	}
 
 struct clk_stm32_fixed_rate_cfg {
@@ -315,7 +315,7 @@ struct clk_stm32_fixed_rate_cfg {
 		.clock_cfg	= &(struct clk_stm32_fixed_rate_cfg){\
 			.rate	= (_rate),\
 		},\
-		.ops		= &clk_stm32_fixed_rate_ops,\
+		.ops		= STM32_FIXED_RATE_OPS,\
 	}
 
 #define BYPASS(_offset, _bit_byp, _bit_digbyp) &(struct stm32_clk_bypass){\
@@ -355,7 +355,7 @@ int clk_stm32_osc_gate_enable(struct stm32_clk_priv *priv, int id);
 void clk_stm32_osc_gate_disable(struct stm32_clk_priv *priv, int id);
 
 struct stm32_osc_cfg {
-	int osc_id;
+	uint8_t osc_id;
 };
 
 #define CLK_OSC(idx, _idx, _parent, _osc_id) \
@@ -366,7 +366,7 @@ struct stm32_osc_cfg {
 		.clock_cfg	= &(struct stm32_osc_cfg){\
 			.osc_id = (_osc_id),\
 		},\
-		.ops		= &clk_stm32_osc_ops,\
+		.ops		= STM32_OSC_OPS,\
 	}
 
 #define CLK_OSC_FIXED(idx, _idx, _parent, _osc_id) \
@@ -377,7 +377,7 @@ struct stm32_osc_cfg {
 		.clock_cfg	= &(struct stm32_osc_cfg){\
 			.osc_id	= (_osc_id),\
 		},\
-		.ops		= &clk_stm32_osc_nogate_ops,\
+		.ops		= STM32_OSC_NOGATE_OPS,\
 	}
 
 extern const struct stm32_clk_ops clk_mux_ops;
@@ -390,4 +390,19 @@ extern const struct stm32_clk_ops clk_stm32_fixed_rate_ops;
 extern const struct stm32_clk_ops clk_stm32_osc_ops;
 extern const struct stm32_clk_ops clk_stm32_osc_nogate_ops;
 
+enum {
+	NO_OPS,
+	FIXED_FACTOR_OPS,
+	GATE_OPS,
+	STM32_MUX_OPS,
+	STM32_DIVIDER_OPS,
+	STM32_GATE_OPS,
+	STM32_TIMER_OPS,
+	STM32_FIXED_RATE_OPS,
+	STM32_OSC_OPS,
+	STM32_OSC_NOGATE_OPS,
+
+	STM32_LAST_OPS
+};
+
 #endif /* CLK_STM32_CORE_H */
diff --git a/drivers/st/clk/clk-stm32mp13.c b/drivers/st/clk/clk-stm32mp13.c
index 01d17640..fd620492 100644
--- a/drivers/st/clk/clk-stm32mp13.c
+++ b/drivers/st/clk/clk-stm32mp13.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -186,65 +186,7 @@ enum stm32_clock {
 	_MCE,
 	_FMC_K,
 	_QSPI_K,
-#if defined(IMAGE_BL32)
-	_LTDC,
-	_DMA1,
-	_DMA2,
-	_MDMA,
-	_ETH1MAC,
-	_USBH,
-	_TIM2,
-	_TIM3,
-	_TIM4,
-	_TIM5,
-	_TIM6,
-	_TIM7,
-	_LPTIM1_K,
-	_SPI2_K,
-	_SPI3_K,
-	_SPDIF_K,
-	_TIM1,
-	_TIM8,
-	_SPI1_K,
-	_SAI1_K,
-	_SAI2_K,
-	_DFSDM,
-	_FDCAN_K,
-	_TIM13,
-	_TIM14,
-	_TIM16,
-	_TIM17,
-	_SPI4_K,
-	_SPI5_K,
-	_I2C1_K,
-	_I2C2_K,
-	_ADFSDM,
-	_LPTIM2_K,
-	_LPTIM3_K,
-	_LPTIM4_K,
-	_LPTIM5_K,
-	_VREF,
-	_DTS,
-	_PMBCTRL,
-	_HDP,
-	_STGENRO,
-	_DCMIPP_K,
-	_DMAMUX1,
-	_DMAMUX2,
-	_DMA3,
-	_ADC1_K,
-	_ADC2_K,
-	_TSC,
-	_AXIMC,
-	_ETH1CK,
-	_ETH1TX,
-	_ETH1RX,
-	_CRC1,
-	_ETH2CK,
-	_ETH2TX,
-	_ETH2RX,
-	_ETH2MAC,
-#endif
+
 	CK_LAST
 };
 
@@ -947,7 +889,7 @@ static bool pll4_bootrom;
 #endif
 
 /* RCC clock device driver private */
-static unsigned int refcounts_mp13[CK_LAST];
+static uint8_t refcounts_mp13[CK_LAST];
 
 static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx);
 
@@ -1007,6 +949,11 @@ static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv)
 		return;
 	}
 
+	/* Do not reconfigure LSE if already enabled */
+	if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) {
+		return;
+	}
+
 	clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass);
 
 	clk_oscillator_set_drive(priv, _CK_LSE, drive);
@@ -1027,8 +974,8 @@ static int stm32mp1_set_hsidiv(uint8_t hsidiv)
 	timeout = timeout_init_us(HSIDIV_TIMEOUT);
 	while ((mmio_read_32(address) & RCC_OCRDYR_HSIDIVRDY) == 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("HSIDIV failed @ 0x%lx: 0x%x\n",
-			      address, mmio_read_32(address));
+			EARLY_ERROR("HSIDIV failed @ 0x%lx: 0x%x\n",
+				    address, mmio_read_32(address));
 			return -ETIMEDOUT;
 		}
 	}
@@ -1050,7 +997,7 @@ static int stm32mp1_hsidiv(unsigned long hsifreq)
 	}
 
 	if (hsidiv == 4U) {
-		ERROR("Invalid clk-hsi frequency\n");
+		EARLY_ERROR("Invalid clk-hsi frequency\n");
 		return -EINVAL;
 	}
 
@@ -1292,7 +1239,7 @@ static void clk_stm32_pll_config_vco(struct stm32_clk_priv *priv,
 	uint32_t value = 0;
 
 	if (clk_stm32_pll_compute_cfgr1(priv, pll, vco, &value) != 0) {
-		ERROR("Invalid Vref clock !\n");
+		EARLY_ERROR("Invalid Vref clock !\n");
 		panic();
 	}
 
@@ -1352,6 +1299,123 @@ static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx)
 	return &pdata->pll[pll_idx];
 }
 
+/* Define characteristic for PLL1 : PLL_2000 */
+#define POST_DIVM_MIN	8000000U
+#define POST_DIVM_MAX	16000000U
+#define DIVM_MIN	0U
+#define DIVM_MAX	63U
+#define DIVN_MIN	24U
+#define DIVN_MAX	99U
+#define DIVP_MIN	0U
+#define DIVP_MAX	127U
+#define FRAC_MAX	8192U
+#define VCO_MIN		992000000U
+#define VCO_MAX		2000000000U
+
+static int clk_compute_pll1_settings(uint32_t freq_khz)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	struct stm32_pll_dt_cfg *pll1 = clk_stm32_pll_get_pdata(_PLL1);
+	struct stm32_pll_dt_cfg *pll2 = clk_stm32_pll_get_pdata(_PLL2);
+	unsigned long long best_diff = ULLONG_MAX;
+	unsigned int divm;
+	unsigned long input_freq = 0UL;
+	uint32_t src =  pll2->vco.src;
+
+	/* PLL1 share the same clock source than PLL2 */
+	switch (src) {
+	case CLK_PLL12_HSI:
+		input_freq = _clk_stm32_get_rate(priv, _CK_HSI);
+		break;
+	case CLK_PLL12_HSE:
+		input_freq = _clk_stm32_get_rate(priv, _CK_HSE);
+		break;
+	default:
+		break;
+	}
+
+	if (input_freq == 0UL) {
+		panic();
+	}
+
+	/* Following parameters have always the same value */
+	pll1->output.output[PLL_CFG_Q] = 0U;
+	pll1->output.output[PLL_CFG_R] = 0U;
+
+	for (divm = (DIVM_MAX + 1U); divm != DIVM_MIN; divm--) {
+		unsigned long post_divm = input_freq / divm;
+		unsigned int divp;
+
+		if ((post_divm < POST_DIVM_MIN) || (post_divm > POST_DIVM_MAX)) {
+			continue;
+		}
+
+		for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
+			unsigned long long output_freq = freq_khz * 1000ULL;
+			unsigned long long freq;
+			unsigned long long divn;
+			unsigned long long frac;
+			unsigned int i;
+
+			freq = output_freq * divm * (divp + 1U);
+
+			divn = (freq / input_freq) - 1U;
+			if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) {
+				continue;
+			}
+
+			frac = ((freq * FRAC_MAX) / input_freq) - ((divn + 1U) * FRAC_MAX);
+
+			/* 2 loops to refine the fractional part */
+			for (i = 2U; i != 0U; i--) {
+				unsigned long long diff;
+				unsigned long long vco;
+
+				if (frac > FRAC_MAX) {
+					break;
+				}
+
+				vco = (post_divm * (divn + 1U)) + ((post_divm * frac) / FRAC_MAX);
+
+				if ((vco < (VCO_MIN / 2U)) || (vco > (VCO_MAX / 2U))) {
+					frac++;
+					continue;
+				}
+
+				freq = vco / (divp + 1U);
+				if (output_freq < freq) {
+					diff = freq - output_freq;
+				} else {
+					diff = output_freq - freq;
+				}
+
+				if (diff < best_diff)  {
+					pll1->vco.src = src;
+					pll1->vco.status = RCC_PLLNCR_DIVPEN | RCC_PLLNCR_PLLON;
+					pll1->vco.div_mn[PLL_CFG_M] = divm - 1U;
+					pll1->vco.div_mn[PLL_CFG_N] = (uint32_t)divn;
+					pll1->vco.frac = (uint32_t)frac;
+					pll1->output.output[PLL_CFG_P] = divp;
+
+					if (diff == 0U) {
+						return 0;
+					}
+
+					best_diff = diff;
+				}
+
+				frac++;
+			}
+		}
+	}
+
+	if (best_diff == ULLONG_MAX) {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
 {
 	uintptr_t pll_base = priv->base + pll->reg_pllxcr;
@@ -1388,8 +1452,8 @@ static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv,
 	/* Wait PLL lock */
 	while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) == 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("%d clock start failed @ 0x%x: 0x%x\n",
-			      pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
+			ERROR("PLL%d start failed @ 0x%x: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base));
 			return -EINVAL;
 		}
 	}
@@ -1406,8 +1470,8 @@ static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv,
 	/* Wait PLL lock */
 	while ((mmio_read_32(pll_base) & RCC_PLLNCR_PLLRDY) != 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("%d clock stop failed @ 0x%x: 0x%x\n",
-			      pll->clk_id, pll->reg_pllxcr, mmio_read_32(pll_base));
+			ERROR("PLL%d stop failed @ 0x%x: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcr, mmio_read_32(pll_base));
 			return -EINVAL;
 		}
 	}
@@ -1629,7 +1693,7 @@ static const struct stm32_clk_pll *clk_st32_pll_data(unsigned int idx)
 }
 
 struct stm32_pll_cfg {
-	int pll_id;
+	uint8_t pll_id;
 };
 
 static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv,  int id,
@@ -1711,12 +1775,12 @@ static const struct stm32_clk_ops clk_stm32_pll_ops = {
 	.clock_cfg	= &(struct stm32_pll_cfg) {\
 		.pll_id = _pll_id,\
 	},\
-	.ops = &clk_stm32_pll_ops,\
+	.ops = STM32_PLL_OPS,\
 }
 
 struct clk_stm32_composite_cfg {
-	int gate_id;
-	int div_id;
+	uint8_t gate_id;
+	uint8_t div_id;
 };
 
 static unsigned long clk_stm32_composite_recalc_rate(struct stm32_clk_priv *priv,
@@ -1768,9 +1832,32 @@ static const struct stm32_clk_ops clk_stm32_composite_ops = {
 		.gate_id	= (_gate_id),\
 		.div_id	= (_div_id),\
 	},\
-	.ops = &clk_stm32_composite_ops,\
+	.ops = STM32_COMPOSITE_OPS,\
 }
 
+enum {
+	STM32_PLL_OPS = STM32_LAST_OPS,
+	STM32_COMPOSITE_OPS,
+
+	MP13_LAST_OPS
+};
+
+static const struct stm32_clk_ops *ops_array_mp13[MP13_LAST_OPS] = {
+	[NO_OPS] =  NULL,
+	[FIXED_FACTOR_OPS] = &clk_fixed_factor_ops,
+	[GATE_OPS] = &clk_gate_ops,
+	[STM32_MUX_OPS] = &clk_mux_ops,
+	[STM32_DIVIDER_OPS] = &clk_stm32_divider_ops,
+	[STM32_GATE_OPS] = &clk_stm32_gate_ops,
+	[STM32_TIMER_OPS] = &clk_timer_ops,
+	[STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops,
+	[STM32_OSC_OPS] = &clk_stm32_osc_ops,
+	[STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops,
+
+	[STM32_PLL_OPS] = &clk_stm32_pll_ops,
+	[STM32_COMPOSITE_OPS] = &clk_stm32_composite_ops
+};
+
 static const struct clk_stm32 stm32mp13_clk[CK_LAST] = {
 	/* ROOT CLOCKS */
 	CLK_FIXED_RATE(_CK_OFF, _NO_ID, 0),
@@ -1882,7 +1969,6 @@ static const struct clk_stm32 stm32mp13_clk[CK_LAST] = {
 	STM32_GATE(_SDMMC2_K, SDMMC2_K, MUX(MUX_SDMMC2), 0, GATE_SDMMC2),
 	STM32_GATE(_DBGCK, CK_DBG, _CKAXI, 0, GATE_DBGCK),
 
-/* TODO: CHECK CLOCK FOR BL2/BL32 AND IF ONLY FOR TEST OR NOT */
 	STM32_GATE(_USART3_K, USART3_K, MUX(MUX_UART35), 0, GATE_USART3),
 	STM32_GATE(_UART4_K, UART4_K, MUX(MUX_UART4), 0, GATE_UART4),
 	STM32_GATE(_UART5_K, UART5_K, MUX(MUX_UART35), 0, GATE_UART5),
@@ -1896,61 +1982,6 @@ static const struct clk_stm32 stm32mp13_clk[CK_LAST] = {
 	STM32_COMPOSITE(_MCO1_K, CK_MCO1, MUX(MUX_MCO1), 0, GATE_MCO1, DIV_MCO1),
 	STM32_COMPOSITE(_MCO2_K, CK_MCO2, MUX(MUX_MCO2), 0, GATE_MCO2, DIV_MCO2),
 	STM32_COMPOSITE(_TRACECK, CK_TRACE, _CKAXI, 0, GATE_TRACECK, DIV_TRACE),
-
-#if defined(IMAGE_BL32)
-	STM32_GATE(_TIM2, TIM2_K, _CKTIMG1, 0, GATE_TIM2),
-	STM32_GATE(_TIM3, TIM3_K, _CKTIMG1, 0, GATE_TIM3),
-	STM32_GATE(_TIM4, TIM4_K, _CKTIMG1, 0, GATE_TIM4),
-	STM32_GATE(_TIM5, TIM5_K, _CKTIMG1, 0, GATE_TIM5),
-	STM32_GATE(_TIM6, TIM6_K, _CKTIMG1, 0, GATE_TIM6),
-	STM32_GATE(_TIM7, TIM7_K, _CKTIMG1, 0, GATE_TIM7),
-	STM32_GATE(_TIM13, TIM13_K, _CKTIMG3, 0, GATE_TIM13),
-	STM32_GATE(_TIM14, TIM14_K, _CKTIMG3, 0, GATE_TIM14),
-	STM32_GATE(_LPTIM1_K, LPTIM1_K, MUX(MUX_LPTIM1), 0, GATE_LPTIM1),
-	STM32_GATE(_SPI2_K, SPI2_K, MUX(MUX_SPI23), 0, GATE_SPI2),
-	STM32_GATE(_SPI3_K, SPI3_K, MUX(MUX_SPI23), 0, GATE_SPI3),
-	STM32_GATE(_SPDIF_K, SPDIF_K, MUX(MUX_SPDIF), 0, GATE_SPDIF),
-	STM32_GATE(_TIM1, TIM1_K, _CKTIMG2, 0, GATE_TIM1),
-	STM32_GATE(_TIM8, TIM8_K, _CKTIMG2, 0, GATE_TIM8),
-	STM32_GATE(_TIM16, TIM16_K, _CKTIMG3, 0, GATE_TIM16),
-	STM32_GATE(_TIM17, TIM17_K, _CKTIMG3, 0, GATE_TIM17),
-	STM32_GATE(_SPI1_K, SPI1_K, MUX(MUX_SPI1), 0, GATE_SPI1),
-	STM32_GATE(_SPI4_K, SPI4_K, MUX(MUX_SPI4), 0, GATE_SPI4),
-	STM32_GATE(_SPI5_K, SPI5_K, MUX(MUX_SPI5), 0, GATE_SPI5),
-	STM32_GATE(_SAI1_K, SAI1_K, MUX(MUX_SAI1), 0, GATE_SAI1),
-	STM32_GATE(_SAI2_K, SAI2_K, MUX(MUX_SAI2), 0, GATE_SAI2),
-	STM32_GATE(_DFSDM, DFSDM_K, MUX(MUX_SAI1), 0, GATE_DFSDM),
-	STM32_GATE(_FDCAN_K, FDCAN_K, MUX(MUX_FDCAN), 0, GATE_FDCAN),
-	STM32_GATE(_USBH, USBH, _CKAXI, 0, GATE_USBH),
-	STM32_GATE(_I2C1_K, I2C1_K, MUX(MUX_I2C12), 0, GATE_I2C1),
-	STM32_GATE(_I2C2_K, I2C2_K, MUX(MUX_I2C12), 0, GATE_I2C2),
-	STM32_GATE(_ADFSDM, ADFSDM_K, MUX(MUX_SAI1), 0, GATE_ADFSDM),
-	STM32_GATE(_LPTIM2_K, LPTIM2_K, MUX(MUX_LPTIM2), 0, GATE_LPTIM2),
-	STM32_GATE(_LPTIM3_K, LPTIM3_K, MUX(MUX_LPTIM3), 0, GATE_LPTIM3),
-	STM32_GATE(_LPTIM4_K, LPTIM4_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM4),
-	STM32_GATE(_LPTIM5_K, LPTIM5_K, MUX(MUX_LPTIM45), 0, GATE_LPTIM5),
-	STM32_GATE(_VREF, VREF, _PCLK3, 0, GATE_VREF),
-	STM32_GATE(_DTS, TMPSENS, _PCLK3, 0, GATE_DTS),
-	STM32_GATE(_PMBCTRL, PMBCTRL, _PCLK3, 0, GATE_HDP),
-	STM32_GATE(_HDP, HDP, _PCLK3, 0, GATE_PMBCTRL),
-	STM32_GATE(_STGENRO, STGENRO, _PCLK4, 0, GATE_DCMIPP),
-	STM32_GATE(_DCMIPP_K, DCMIPP_K, MUX(MUX_DCMIPP), 0, GATE_DCMIPP),
-	STM32_GATE(_DMAMUX1, DMAMUX1, _CKAXI, 0, GATE_DMAMUX1),
-	STM32_GATE(_DMAMUX2, DMAMUX2, _CKAXI, 0, GATE_DMAMUX2),
-	STM32_GATE(_DMA3, DMA3, _CKAXI, 0, GATE_DMAMUX2),
-	STM32_GATE(_ADC1_K, ADC1_K, MUX(MUX_ADC1), 0, GATE_ADC1),
-	STM32_GATE(_ADC2_K, ADC2_K, MUX(MUX_ADC2), 0, GATE_ADC2),
-	STM32_GATE(_TSC, TSC, _CKAXI, 0, GATE_TSC),
-	STM32_GATE(_AXIMC, AXIMC, _CKAXI, 0, GATE_AXIMC),
-	STM32_GATE(_CRC1, CRC1, _CKAXI, 0, GATE_ETH1TX),
-	STM32_GATE(_ETH1CK, ETH1CK_K, MUX(MUX_ETH1), 0, GATE_ETH1CK),
-	STM32_GATE(_ETH1TX, ETH1TX, _CKAXI, 0, GATE_ETH1TX),
-	STM32_GATE(_ETH1RX, ETH1RX, _CKAXI, 0, GATE_ETH1RX),
-	STM32_GATE(_ETH2CK, ETH2CK_K, MUX(MUX_ETH2), 0, GATE_ETH2CK),
-	STM32_GATE(_ETH2TX, ETH2TX, _CKAXI, 0, GATE_ETH2TX),
-	STM32_GATE(_ETH2RX, ETH2RX, _CKAXI, 0, GATE_ETH2RX),
-	STM32_GATE(_ETH2MAC, ETH2MAC, _CKAXI, 0, GATE_ETH2MAC),
-#endif
 };
 
 static struct stm32_pll_dt_cfg mp13_pll[_PLL_NB];
@@ -1986,6 +2017,7 @@ static struct stm32_clk_priv stm32mp13_clock_data = {
 	.nb_osci_data	= ARRAY_SIZE(stm32mp13_osc_data),
 	.gate_refcounts	= refcounts_mp13,
 	.pdata		= &stm32mp13_clock_pdata,
+	.ops_array	= ops_array_mp13,
 };
 
 static int stm32mp1_init_clock_tree(void)
@@ -2072,8 +2104,6 @@ static int stm32mp1_init_clock_tree(void)
 	return 0;
 }
 
-#define LSEDRV_MEDIUM_HIGH 2
-
 static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name,
 					  struct stm32_osci_dt_cfg *osci)
 {
@@ -2241,7 +2271,8 @@ static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_pla
 {
 	size_t i = 0U;
 
-	for (i = _PLL1; i < pdata->npll; i++) {
+	/* PLL1 is not configurable with device tree */
+	for (i = _PLL2; i < pdata->npll; i++) {
 		struct stm32_pll_dt_cfg *pll = &pdata->pll[i];
 		char name[RCC_PLL_NAME_SIZE];
 		int subnode = 0;
@@ -2301,32 +2332,47 @@ static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
 	return 0;
 }
 
-int stm32mp1_clk_init(void)
+void stm32mp1_clk_rcc_regs_lock(void)
 {
-	return 0;
+	clk_stm32_rcc_regs_lock();
 }
 
-int stm32mp1_clk_probe(void)
+void stm32mp1_clk_rcc_regs_unlock(void)
+{
+	clk_stm32_rcc_regs_unlock();
+}
+
+int stm32mp1_clk_init(void)
 {
-	uintptr_t base = RCC_BASE;
 	int ret;
 
-	ret = stm32_clk_parse_fdt(&stm32mp13_clock_pdata);
+	/* compute the PLL1 settings, not read in device tree */
+	ret = clk_compute_pll1_settings(PLL1_NOMINAL_FREQ_IN_KHZ);
 	if (ret != 0) {
 		return ret;
 	}
 
-	ret = clk_stm32_init(&stm32mp13_clock_data, base);
+	ret = stm32mp1_init_clock_tree();
 	if (ret != 0) {
 		return ret;
 	}
 
-	ret = stm32mp1_init_clock_tree();
+	clk_stm32_enable_critical_clocks();
+
+	return 0;
+}
+
+int stm32mp1_clk_probe(void)
+{
+	uintptr_t base = RCC_BASE;
+	int ret;
+
+	ret = stm32_clk_parse_fdt(&stm32mp13_clock_pdata);
 	if (ret != 0) {
 		return ret;
 	}
 
-	clk_stm32_enable_critical_clocks();
+	ret = clk_stm32_init(&stm32mp13_clock_data, base);
 
-	return 0;
+	return ret;
 }
diff --git a/drivers/st/clk/clk-stm32mp2.c b/drivers/st/clk/clk-stm32mp2.c
new file mode 100644
index 00000000..12839f1a
--- /dev/null
+++ b/drivers/st/clk/clk-stm32mp2.c
@@ -0,0 +1,2357 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include "clk-stm32-core.h"
+#include <common/fdt_wrappers.h>
+#include <drivers/clk.h>
+#include <drivers/delay_timer.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/st/stm32mp2_clk.h>
+#include <drivers/st/stm32mp_clkfunc.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+struct stm32_osci_dt_cfg {
+	unsigned long freq;
+	uint32_t drive;
+	bool bypass;
+	bool digbyp;
+	bool css;
+};
+
+struct stm32_pll_dt_cfg {
+	uint32_t src;
+	uint32_t frac;
+	uint32_t cfg[PLLCFG_NB];
+	uint32_t csg[PLLCSG_NB];
+	bool csg_enabled;
+	bool enabled;
+};
+
+struct stm32_clk_platdata {
+	uintptr_t rcc_base;
+	uint32_t nosci;
+	struct stm32_osci_dt_cfg *osci;
+	uint32_t npll;
+	struct stm32_pll_dt_cfg *pll;
+	uint32_t nflexgen;
+	uint32_t *flexgen;
+	uint32_t nbusclk;
+	uint32_t *busclk;
+	uint32_t nkernelclk;
+	uint32_t *kernelclk;
+};
+
+/* A35 Sub-System which manages its own PLL (PLL1) */
+#define A35_SS_CHGCLKREQ	0x0000
+#define A35_SS_PLL_FREQ1	0x0080
+#define A35_SS_PLL_FREQ2	0x0090
+#define A35_SS_PLL_ENABLE	0x00a0
+
+#define A35_SS_CHGCLKREQ_ARM_CHGCLKREQ		BIT(0)
+#define A35_SS_CHGCLKREQ_ARM_CHGCLKACK		BIT(1)
+
+#define A35_SS_PLL_FREQ1_FBDIV_MASK		GENMASK(11, 0)
+#define A35_SS_PLL_FREQ1_FBDIV_SHIFT		0
+#define A35_SS_PLL_FREQ1_REFDIV_MASK		GENMASK(21, 16)
+#define A35_SS_PLL_FREQ1_REFDIV_SHIFT		16
+
+#define A35_SS_PLL_FREQ2_POSTDIV1_MASK		GENMASK(2, 0)
+#define A35_SS_PLL_FREQ2_POSTDIV1_SHIFT		0
+#define A35_SS_PLL_FREQ2_POSTDIV2_MASK		GENMASK(5, 3)
+#define A35_SS_PLL_FREQ2_POSTDIV2_SHIFT		3
+
+#define A35_SS_PLL_ENABLE_PD			BIT(0)
+#define A35_SS_PLL_ENABLE_LOCKP			BIT(1)
+#define A35_SS_PLL_ENABLE_NRESET_SWPLL_FF	BIT(2)
+
+#define TIMEOUT_US_200MS	U(200000)
+#define TIMEOUT_US_1S		U(1000000)
+
+#define PLLRDY_TIMEOUT		TIMEOUT_US_200MS
+#define CLKSRC_TIMEOUT		TIMEOUT_US_200MS
+#define CLKDIV_TIMEOUT		TIMEOUT_US_200MS
+#define OSCRDY_TIMEOUT		TIMEOUT_US_1S
+
+/* PLL minimal frequencies for clock sources */
+#define PLL_REFCLK_MIN			UL(5000000)
+#define PLL_FRAC_REFCLK_MIN		UL(10000000)
+
+#define XBAR_CHANNEL_NB			64
+
+/* Warning, should be start to 1 */
+enum clock {
+	_CK_0_MHZ,
+
+	/* ROOT CLOCKS */
+	_CK_HSI,
+	_CK_HSE,
+	_CK_MSI,
+	_CK_LSI,
+	_CK_LSE,
+	_I2SCKIN,
+	_SPDIFSYMB,
+	_CK_PLL1,
+	_CK_PLL2,
+	_CK_PLL3,
+	_CK_PLL4,
+	_CK_PLL5,
+	_CK_PLL6,
+	_CK_PLL7,
+	_CK_PLL8,
+	_CK_HSE_RTC,
+	_CK_RTCCK,
+	_CK_ICN_HS_MCU,
+	_CK_ICN_SDMMC,
+	_CK_ICN_DDR,
+	_CK_ICN_HSL,
+	_CK_ICN_NIC,
+	_CK_ICN_LS_MCU,
+	_CK_FLEXGEN_07,
+	_CK_FLEXGEN_08,
+	_CK_FLEXGEN_09,
+	_CK_FLEXGEN_10,
+	_CK_FLEXGEN_11,
+	_CK_FLEXGEN_12,
+	_CK_FLEXGEN_13,
+	_CK_FLEXGEN_14,
+	_CK_FLEXGEN_15,
+	_CK_FLEXGEN_16,
+	_CK_FLEXGEN_17,
+	_CK_FLEXGEN_18,
+	_CK_FLEXGEN_19,
+	_CK_FLEXGEN_20,
+	_CK_FLEXGEN_21,
+	_CK_FLEXGEN_22,
+	_CK_FLEXGEN_23,
+	_CK_FLEXGEN_24,
+	_CK_FLEXGEN_25,
+	_CK_FLEXGEN_26,
+	_CK_FLEXGEN_27,
+	_CK_FLEXGEN_28,
+	_CK_FLEXGEN_29,
+	_CK_FLEXGEN_30,
+	_CK_FLEXGEN_31,
+	_CK_FLEXGEN_32,
+	_CK_FLEXGEN_33,
+	_CK_FLEXGEN_34,
+	_CK_FLEXGEN_35,
+	_CK_FLEXGEN_36,
+	_CK_FLEXGEN_37,
+	_CK_FLEXGEN_38,
+	_CK_FLEXGEN_39,
+	_CK_FLEXGEN_40,
+	_CK_FLEXGEN_41,
+	_CK_FLEXGEN_42,
+	_CK_FLEXGEN_43,
+	_CK_FLEXGEN_44,
+	_CK_FLEXGEN_45,
+	_CK_FLEXGEN_46,
+	_CK_FLEXGEN_47,
+	_CK_FLEXGEN_48,
+	_CK_FLEXGEN_49,
+	_CK_FLEXGEN_50,
+	_CK_FLEXGEN_51,
+	_CK_FLEXGEN_52,
+	_CK_FLEXGEN_53,
+	_CK_FLEXGEN_54,
+	_CK_FLEXGEN_55,
+	_CK_FLEXGEN_56,
+	_CK_FLEXGEN_57,
+	_CK_FLEXGEN_58,
+	_CK_FLEXGEN_59,
+	_CK_FLEXGEN_60,
+	_CK_FLEXGEN_61,
+	_CK_FLEXGEN_62,
+	_CK_FLEXGEN_63,
+	_CK_ICN_APB1,
+	_CK_ICN_APB2,
+	_CK_ICN_APB3,
+	_CK_ICN_APB4,
+	_CK_ICN_APBDBG,
+	_CK_BKPSRAM,
+	_CK_BSEC,
+	_CK_CRC,
+	_CK_CRYP1,
+	_CK_CRYP2,
+	_CK_DDR,
+	_CK_DDRCAPB,
+	_CK_DDRCP,
+	_CK_DDRPHYC,
+	_CK_FMC,
+	_CK_GPIOA,
+	_CK_GPIOB,
+	_CK_GPIOC,
+	_CK_GPIOD,
+	_CK_GPIOE,
+	_CK_GPIOF,
+	_CK_GPIOG,
+	_CK_GPIOH,
+	_CK_GPIOI,
+	_CK_GPIOJ,
+	_CK_GPIOK,
+	_CK_GPIOZ,
+	_CK_HASH,
+	_CK_I2C1,
+	_CK_I2C2,
+	_CK_I2C3,
+	_CK_I2C4,
+	_CK_I2C5,
+	_CK_I2C6,
+	_CK_I2C7,
+	_CK_I2C8,
+	_CK_IWDG1,
+	_CK_IWDG2,
+	_CK_OSPI1,
+	_CK_OSPI2,
+	_CK_OSPIIOM,
+	_CK_PKA,
+	_CK_RETRAM,
+	_CK_RNG,
+	_CK_RTC,
+	_CK_SAES,
+	_CK_SDMMC1,
+	_CK_SDMMC2,
+	_CK_SRAM1,
+	_CK_SRAM2,
+	_CK_STGEN,
+	_CK_SYSCPU1,
+	_CK_SYSRAM,
+	_CK_UART4,
+	_CK_UART5,
+	_CK_UART7,
+	_CK_UART8,
+	_CK_UART9,
+	_CK_USART1,
+	_CK_USART2,
+	_CK_USART3,
+	_CK_USART6,
+	_CK_USB2EHCI,
+	_CK_USB2OHCI,
+	_CK_USB2PHY1,
+	_CK_USB2PHY2,
+	_CK_USB3DR,
+	_CK_USB3PCIEPHY,
+	_CK_USBTC,
+
+	CK_LAST
+};
+
+static const uint16_t muxsel_src[] = {
+	_CK_HSI, _CK_HSE, _CK_MSI, _CK_0_MHZ
+};
+
+static const uint16_t xbarsel_src[] = {
+	_CK_PLL4, _CK_PLL5, _CK_PLL6, _CK_PLL7, _CK_PLL8,
+	_CK_HSI, _CK_HSE, _CK_MSI, _CK_HSI, _CK_HSE, _CK_MSI,
+	_SPDIFSYMB, _I2SCKIN, _CK_LSI, _CK_LSE
+};
+
+static const uint16_t rtc_src[] = {
+	_CK_0_MHZ, _CK_LSE, _CK_LSI, _CK_HSE_RTC
+};
+
+static const uint16_t usb2phy1_src[] = {
+	_CK_FLEXGEN_57, _CK_HSE
+};
+
+static const uint16_t usb2phy2_src[] = {
+	_CK_FLEXGEN_58, _CK_HSE
+};
+
+static const uint16_t usb3pciphy_src[] = {
+	_CK_FLEXGEN_34, _CK_HSE
+};
+
+static const uint16_t d3per_src[] = {
+	_CK_MSI, _CK_LSI, _CK_LSE
+};
+
+#define MUX_CONF(id, src, _offset, _shift, _witdh)[id] = {\
+	.id_parents	= src,\
+	.num_parents	= ARRAY_SIZE(src),\
+	.mux		= &(struct mux_cfg) {\
+		.offset	= (_offset),\
+		.shift	= (_shift),\
+		.width	= (_witdh),\
+		.bitrdy = UINT8_MAX,\
+	},\
+}
+
+static const struct parent_cfg parent_mp25[] = {
+	MUX_CONF(MUX_MUXSEL0, muxsel_src, RCC_MUXSELCFGR, 0, 2),
+	MUX_CONF(MUX_MUXSEL1, muxsel_src, RCC_MUXSELCFGR, 4, 2),
+	MUX_CONF(MUX_MUXSEL2, muxsel_src, RCC_MUXSELCFGR, 8, 2),
+	MUX_CONF(MUX_MUXSEL3, muxsel_src, RCC_MUXSELCFGR, 12, 2),
+	MUX_CONF(MUX_MUXSEL4, muxsel_src, RCC_MUXSELCFGR, 16, 2),
+	MUX_CONF(MUX_MUXSEL5, muxsel_src, RCC_MUXSELCFGR, 20, 2),
+	MUX_CONF(MUX_MUXSEL6, muxsel_src, RCC_MUXSELCFGR, 24, 2),
+	MUX_CONF(MUX_MUXSEL7, muxsel_src, RCC_MUXSELCFGR, 28, 2),
+	MUX_CONF(MUX_XBARSEL, xbarsel_src, RCC_XBAR0CFGR, 0, 4),
+	MUX_CONF(MUX_RTC, rtc_src, RCC_BDCR, 16, 2),
+	MUX_CONF(MUX_USB2PHY1, usb2phy1_src, RCC_USB2PHY1CFGR, 15, 1),
+	MUX_CONF(MUX_USB2PHY2, usb2phy2_src, RCC_USB2PHY2CFGR, 15, 1),
+	MUX_CONF(MUX_USB3PCIEPHY, usb3pciphy_src, RCC_USB3PCIEPHYCFGR, 15, 1),
+	MUX_CONF(MUX_D3PER, d3per_src, RCC_D3DCR, 16, 2),
+};
+
+/* GATES */
+enum enum_gate_cfg {
+	GATE_ZERO, /* reserved for no gate */
+	GATE_LSE,
+	GATE_RTCCK,
+	GATE_LSI,
+	GATE_HSI,
+	GATE_MSI,
+	GATE_HSE,
+	GATE_LSI_RDY,
+	GATE_MSI_RDY,
+	GATE_LSE_RDY,
+	GATE_HSE_RDY,
+	GATE_HSI_RDY,
+	GATE_SYSRAM,
+	GATE_RETRAM,
+	GATE_SRAM1,
+	GATE_SRAM2,
+
+	GATE_DDRPHYC,
+	GATE_SYSCPU1,
+	GATE_CRC,
+	GATE_OSPIIOM,
+	GATE_BKPSRAM,
+	GATE_HASH,
+	GATE_RNG,
+	GATE_CRYP1,
+	GATE_CRYP2,
+	GATE_SAES,
+	GATE_PKA,
+
+	GATE_GPIOA,
+	GATE_GPIOB,
+	GATE_GPIOC,
+	GATE_GPIOD,
+	GATE_GPIOE,
+	GATE_GPIOF,
+	GATE_GPIOG,
+	GATE_GPIOH,
+	GATE_GPIOI,
+	GATE_GPIOJ,
+	GATE_GPIOK,
+	GATE_GPIOZ,
+	GATE_RTC,
+
+	GATE_DDRCP,
+
+	/* WARNING 2 CLOCKS FOR ONE GATE */
+	GATE_USB2OHCI,
+	GATE_USB2EHCI,
+
+	GATE_USB3DR,
+
+	GATE_BSEC,
+	GATE_IWDG1,
+	GATE_IWDG2,
+
+	GATE_DDRCAPB,
+	GATE_DDR,
+
+	GATE_USART2,
+	GATE_UART4,
+	GATE_USART3,
+	GATE_UART5,
+	GATE_I2C1,
+	GATE_I2C2,
+	GATE_I2C3,
+	GATE_I2C5,
+	GATE_I2C4,
+	GATE_I2C6,
+	GATE_I2C7,
+	GATE_USART1,
+	GATE_USART6,
+	GATE_UART7,
+	GATE_UART8,
+	GATE_UART9,
+	GATE_STGEN,
+	GATE_USB3PCIEPHY,
+	GATE_USBTC,
+	GATE_I2C8,
+	GATE_OSPI1,
+	GATE_OSPI2,
+	GATE_FMC,
+	GATE_SDMMC1,
+	GATE_SDMMC2,
+	GATE_USB2PHY1,
+	GATE_USB2PHY2,
+	LAST_GATE
+};
+
+#define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\
+	.offset		= (_offset),\
+	.bit_idx	= (_bit_idx),\
+	.set_clr	= (_offset_clr),\
+}
+
+static const struct gate_cfg gates_mp25[LAST_GATE] = {
+	GATE_CFG(GATE_LSE,		RCC_BDCR,		0,	0),
+	GATE_CFG(GATE_LSI,		RCC_BDCR,		9,	0),
+	GATE_CFG(GATE_RTCCK,		RCC_BDCR,		20,	0),
+	GATE_CFG(GATE_HSI,		RCC_OCENSETR,		0,	1),
+	GATE_CFG(GATE_HSE,		RCC_OCENSETR,		8,	1),
+	GATE_CFG(GATE_MSI,		RCC_D3DCR,		0,	0),
+
+	GATE_CFG(GATE_LSI_RDY,		RCC_BDCR,		10,	0),
+	GATE_CFG(GATE_LSE_RDY,		RCC_BDCR,		2,	0),
+	GATE_CFG(GATE_MSI_RDY,		RCC_D3DCR,		2,	0),
+	GATE_CFG(GATE_HSE_RDY,		RCC_OCRDYR,		8,	0),
+	GATE_CFG(GATE_HSI_RDY,		RCC_OCRDYR,		0,	0),
+	GATE_CFG(GATE_SYSRAM,		RCC_SYSRAMCFGR,		1,	0),
+	GATE_CFG(GATE_RETRAM,		RCC_RETRAMCFGR,		1,	0),
+	GATE_CFG(GATE_SRAM1,		RCC_SRAM1CFGR,		1,	0),
+	GATE_CFG(GATE_SRAM2,		RCC_SRAM2CFGR,		1,	0),
+	GATE_CFG(GATE_DDRPHYC,		RCC_DDRPHYCAPBCFGR,	1,	0),
+	GATE_CFG(GATE_SYSCPU1,		RCC_SYSCPU1CFGR,	1,	0),
+	GATE_CFG(GATE_CRC,		RCC_CRCCFGR,		1,	0),
+	GATE_CFG(GATE_OSPIIOM,		RCC_OSPIIOMCFGR,	1,	0),
+	GATE_CFG(GATE_BKPSRAM,		RCC_BKPSRAMCFGR,	1,	0),
+	GATE_CFG(GATE_HASH,		RCC_HASHCFGR,		1,	0),
+	GATE_CFG(GATE_RNG,		RCC_RNGCFGR,		1,	0),
+	GATE_CFG(GATE_CRYP1,		RCC_CRYP1CFGR,		1,	0),
+	GATE_CFG(GATE_CRYP2,		RCC_CRYP2CFGR,		1,	0),
+	GATE_CFG(GATE_SAES,		RCC_SAESCFGR,		1,	0),
+	GATE_CFG(GATE_PKA,		RCC_PKACFGR,		1,	0),
+	GATE_CFG(GATE_GPIOA,		RCC_GPIOACFGR,		1,	0),
+	GATE_CFG(GATE_GPIOB,		RCC_GPIOBCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOC,		RCC_GPIOCCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOD,		RCC_GPIODCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOE,		RCC_GPIOECFGR,		1,	0),
+	GATE_CFG(GATE_GPIOF,		RCC_GPIOFCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOG,		RCC_GPIOGCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOH,		RCC_GPIOHCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOI,		RCC_GPIOICFGR,		1,	0),
+	GATE_CFG(GATE_GPIOJ,		RCC_GPIOJCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOK,		RCC_GPIOKCFGR,		1,	0),
+	GATE_CFG(GATE_GPIOZ,		RCC_GPIOZCFGR,		1,	0),
+	GATE_CFG(GATE_RTC,		RCC_RTCCFGR,		1,	0),
+	GATE_CFG(GATE_DDRCP,		RCC_DDRCPCFGR,		1,	0),
+
+	/* WARNING 2 CLOCKS FOR ONE GATE */
+	GATE_CFG(GATE_USB2OHCI,		RCC_USB2CFGR,		1,	0),
+	GATE_CFG(GATE_USB2EHCI,		RCC_USB2CFGR,		1,	0),
+	GATE_CFG(GATE_USB3DR,		RCC_USB3DRCFGR,		1,	0),
+	GATE_CFG(GATE_BSEC,		RCC_BSECCFGR,		1,	0),
+	GATE_CFG(GATE_IWDG1,		RCC_IWDG1CFGR,		1,	0),
+	GATE_CFG(GATE_IWDG2,		RCC_IWDG2CFGR,		1,	0),
+	GATE_CFG(GATE_DDRCAPB,		RCC_DDRCAPBCFGR,	1,	0),
+	GATE_CFG(GATE_DDR,		RCC_DDRCFGR,		1,	0),
+	GATE_CFG(GATE_USART2,		RCC_USART2CFGR,		1,	0),
+	GATE_CFG(GATE_UART4,		RCC_UART4CFGR,		1,	0),
+	GATE_CFG(GATE_USART3,		RCC_USART3CFGR,		1,	0),
+	GATE_CFG(GATE_UART5,		RCC_UART5CFGR,		1,	0),
+	GATE_CFG(GATE_I2C1,		RCC_I2C1CFGR,		1,	0),
+	GATE_CFG(GATE_I2C2,		RCC_I2C2CFGR,		1,	0),
+	GATE_CFG(GATE_I2C3,		RCC_I2C3CFGR,		1,	0),
+	GATE_CFG(GATE_I2C5,		RCC_I2C5CFGR,		1,	0),
+	GATE_CFG(GATE_I2C4,		RCC_I2C4CFGR,		1,	0),
+	GATE_CFG(GATE_I2C6,		RCC_I2C6CFGR,		1,	0),
+	GATE_CFG(GATE_I2C7,		RCC_I2C7CFGR,		1,	0),
+	GATE_CFG(GATE_USART1,		RCC_USART1CFGR,		1,	0),
+	GATE_CFG(GATE_USART6,		RCC_USART6CFGR,		1,	0),
+	GATE_CFG(GATE_UART7,		RCC_UART7CFGR,		1,	0),
+	GATE_CFG(GATE_UART8,		RCC_UART8CFGR,		1,	0),
+	GATE_CFG(GATE_UART9,		RCC_UART9CFGR,		1,	0),
+	GATE_CFG(GATE_STGEN,		RCC_STGENCFGR,		1,	0),
+	GATE_CFG(GATE_USB3PCIEPHY,	RCC_USB3PCIEPHYCFGR,	1,	0),
+	GATE_CFG(GATE_USBTC,		RCC_USBTCCFGR,		1,	0),
+	GATE_CFG(GATE_I2C8,		RCC_I2C8CFGR,		1,	0),
+	GATE_CFG(GATE_OSPI1,		RCC_OSPI1CFGR,		1,	0),
+	GATE_CFG(GATE_OSPI2,		RCC_OSPI2CFGR,		1,	0),
+	GATE_CFG(GATE_FMC,		RCC_FMCCFGR,		1,	0),
+	GATE_CFG(GATE_SDMMC1,		RCC_SDMMC1CFGR,		1,	0),
+	GATE_CFG(GATE_SDMMC2,		RCC_SDMMC2CFGR,		1,	0),
+	GATE_CFG(GATE_USB2PHY1,		RCC_USB2PHY1CFGR,	1,	0),
+	GATE_CFG(GATE_USB2PHY2,		RCC_USB2PHY2CFGR,	1,	0),
+};
+
+static const struct clk_div_table apb_div_table[] = {
+	{ 0, 1 },  { 1, 2 },  { 2, 4 },  { 3, 8 }, { 4, 16 },
+	{ 5, 16 }, { 6, 16 }, { 7, 16 }, { 0 },
+};
+
+#undef DIV_CFG
+#define DIV_CFG(id, _offset, _shift, _width, _flags, _table, _bitrdy)[id] = {\
+		.offset	= _offset,\
+		.shift	= _shift,\
+		.width	= _width,\
+		.flags	= _flags,\
+		.table	= _table,\
+		.bitrdy	= _bitrdy,\
+}
+
+static const struct div_cfg dividers_mp25[] = {
+	DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_APBDBG, RCC_APBDBGDIVR, 0, 3, 0, apb_div_table, 31),
+	DIV_CFG(DIV_LSMCU, RCC_LSMCUDIVR, 0, 1, 0, NULL, 31),
+	DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, 0),
+};
+
+enum stm32_osc {
+	OSC_HSI,
+	OSC_HSE,
+	OSC_MSI,
+	OSC_LSI,
+	OSC_LSE,
+	OSC_I2SCKIN,
+	OSC_SPDIFSYMB,
+	NB_OSCILLATOR
+};
+
+static struct clk_oscillator_data stm32mp25_osc_data[] = {
+	OSCILLATOR(OSC_HSI, _CK_HSI, "clk-hsi", GATE_HSI, GATE_HSI_RDY,
+		   NULL, NULL, NULL),
+
+	OSCILLATOR(OSC_LSI, _CK_LSI, "clk-lsi", GATE_LSI, GATE_LSI_RDY,
+		   NULL, NULL, NULL),
+
+	OSCILLATOR(OSC_MSI, _CK_MSI, "clk-msi", GATE_MSI, GATE_MSI_RDY,
+		   NULL, NULL, NULL),
+
+	OSCILLATOR(OSC_HSE, _CK_HSE, "clk-hse", GATE_HSE, GATE_HSE_RDY,
+		   BYPASS(RCC_OCENSETR, 10, 7),
+		   CSS(RCC_OCENSETR, 11),
+		   NULL),
+
+	OSCILLATOR(OSC_LSE, _CK_LSE, "clk-lse", GATE_LSE, GATE_LSE_RDY,
+		   BYPASS(RCC_BDCR, 1, 3),
+		   CSS(RCC_BDCR, 8),
+		   DRIVE(RCC_BDCR, 4, 2, 2)),
+
+	OSCILLATOR(OSC_I2SCKIN, _I2SCKIN, "i2s_ckin", NO_GATE, NO_GATE,
+		   NULL, NULL, NULL),
+
+	OSCILLATOR(OSC_SPDIFSYMB, _SPDIFSYMB, "spdif_symb", NO_GATE, NO_GATE,
+		   NULL, NULL, NULL),
+};
+
+#ifdef IMAGE_BL2
+static const char *clk_stm32_get_oscillator_name(enum stm32_osc id)
+{
+	if (id < NB_OSCILLATOR) {
+		return stm32mp25_osc_data[id].name;
+	}
+
+	return NULL;
+}
+#endif
+
+enum pll_id {
+	_PLL1,
+	_PLL2,
+	_PLL3,
+	_PLL4,
+	_PLL5,
+	_PLL6,
+	_PLL7,
+	_PLL8,
+	_PLL_NB
+};
+
+/* PLL configuration registers offsets from RCC_PLLxCFGR1 */
+#define RCC_OFFSET_PLLXCFGR1		0x00
+#define RCC_OFFSET_PLLXCFGR2		0x04
+#define RCC_OFFSET_PLLXCFGR3		0x08
+#define RCC_OFFSET_PLLXCFGR4		0x0C
+#define RCC_OFFSET_PLLXCFGR5		0x10
+#define RCC_OFFSET_PLLXCFGR6		0x18
+#define RCC_OFFSET_PLLXCFGR7		0x1C
+
+struct stm32_clk_pll {
+	uint16_t clk_id;
+	uint16_t reg_pllxcfgr1;
+};
+
+#define CLK_PLL_CFG(_idx, _clk_id, _reg)\
+	[(_idx)] = {\
+		.clk_id = (_clk_id),\
+		.reg_pllxcfgr1 = (_reg),\
+	}
+
+static const struct stm32_clk_pll stm32mp25_clk_pll[_PLL_NB] = {
+	CLK_PLL_CFG(_PLL1, _CK_PLL1, A35_SS_CHGCLKREQ),
+	CLK_PLL_CFG(_PLL2, _CK_PLL2, RCC_PLL2CFGR1),
+	CLK_PLL_CFG(_PLL3, _CK_PLL3, RCC_PLL3CFGR1),
+	CLK_PLL_CFG(_PLL4, _CK_PLL4, RCC_PLL4CFGR1),
+	CLK_PLL_CFG(_PLL5, _CK_PLL5, RCC_PLL5CFGR1),
+	CLK_PLL_CFG(_PLL6, _CK_PLL6, RCC_PLL6CFGR1),
+	CLK_PLL_CFG(_PLL7, _CK_PLL7, RCC_PLL7CFGR1),
+	CLK_PLL_CFG(_PLL8, _CK_PLL8, RCC_PLL8CFGR1),
+};
+
+static const struct stm32_clk_pll *clk_stm32_pll_data(unsigned int idx)
+{
+	return &stm32mp25_clk_pll[idx];
+}
+
+static unsigned long clk_get_pll_fvco(struct stm32_clk_priv *priv,
+				      const struct stm32_clk_pll *pll,
+				      unsigned long prate)
+{
+	unsigned long refclk, fvco;
+	uint32_t fracin, fbdiv, refdiv;
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2;
+	uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3;
+
+	refclk = prate;
+
+	fracin = mmio_read_32(pllxcfgr3) & RCC_PLLxCFGR3_FRACIN_MASK;
+	fbdiv = (mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FBDIV_MASK) >>
+		RCC_PLLxCFGR2_FBDIV_SHIFT;
+	refdiv = mmio_read_32(pllxcfgr2) & RCC_PLLxCFGR2_FREFDIV_MASK;
+
+	if (fracin != 0U) {
+		uint64_t numerator, denominator;
+
+		numerator = ((uint64_t)fbdiv << 24) + fracin;
+		numerator = refclk * numerator;
+		denominator = (uint64_t)refdiv << 24;
+		fvco = (unsigned long)(numerator / denominator);
+	} else {
+		fvco = (unsigned long)(refclk * fbdiv / refdiv);
+	}
+
+	return fvco;
+}
+
+struct stm32_pll_cfg {
+	uint16_t pll_id;
+};
+
+static bool _clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+
+	return ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLEN) != 0U);
+}
+
+static void _clk_stm32_pll_set_on(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+
+	mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN);
+}
+
+static void _clk_stm32_pll_set_off(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+
+	/* Stop PLL */
+	mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN);
+}
+
+static int _clk_stm32_pll_wait_ready_on(struct stm32_clk_priv *priv,
+					const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
+
+	/* Wait PLL lock */
+	while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			ERROR("PLL%d start failed @ 0x%x: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pll->reg_pllxcfgr1,
+			      mmio_read_32(pllxcfgr1));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int _clk_stm32_pll_wait_ready_off(struct stm32_clk_priv *priv,
+					 const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
+
+	/* Wait PLL stopped */
+	while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_PLLRDY) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			ERROR("PLL%d stop failed @ 0x%lx: 0x%x\n",
+			      pll->clk_id - _CK_PLL1 + 1, pllxcfgr1, mmio_read_32(pllxcfgr1));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int _clk_stm32_pll_enable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	if (_clk_stm32_pll_is_enabled(priv, pll)) {
+		return 0;
+	}
+
+	_clk_stm32_pll_set_on(priv, pll);
+
+	return _clk_stm32_pll_wait_ready_on(priv, pll);
+}
+
+static void _clk_stm32_pll_disable(struct stm32_clk_priv *priv, const struct stm32_clk_pll *pll)
+{
+	if (!_clk_stm32_pll_is_enabled(priv, pll)) {
+		return;
+	}
+
+	_clk_stm32_pll_set_off(priv, pll);
+
+	_clk_stm32_pll_wait_ready_off(priv, pll);
+}
+
+static bool clk_stm32_pll_is_enabled(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
+
+	return _clk_stm32_pll_is_enabled(priv, pll);
+}
+
+static int clk_stm32_pll_enable(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
+
+	return _clk_stm32_pll_enable(priv, pll);
+}
+
+static void clk_stm32_pll_disable(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
+
+	_clk_stm32_pll_disable(priv, pll);
+}
+
+static unsigned long clk_stm32_pll_recalc_rate(struct stm32_clk_priv *priv, int id,
+					       unsigned long prate)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_pll_cfg *pll_cfg = clk->clock_cfg;
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_cfg->pll_id);
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4;
+	uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6;
+	uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7;
+	unsigned long dfout;
+	uint32_t postdiv1, postdiv2;
+
+	postdiv1 = mmio_read_32(pllxcfgr6) & RCC_PLLxCFGR6_POSTDIV1_MASK;
+	postdiv2 = mmio_read_32(pllxcfgr7) & RCC_PLLxCFGR7_POSTDIV2_MASK;
+
+	if ((mmio_read_32(pllxcfgr4) & RCC_PLLxCFGR4_BYPASS) != 0U) {
+		dfout = prate;
+	} else {
+		if ((postdiv1 == 0U) || (postdiv2 == 0U)) {
+			dfout = prate;
+		} else {
+			dfout = clk_get_pll_fvco(priv, pll, prate) / (postdiv1 * postdiv2);
+		}
+	}
+
+	return dfout;
+}
+
+static const struct stm32_clk_ops clk_stm32_pll_ops = {
+	.recalc_rate	= clk_stm32_pll_recalc_rate,
+	.enable		= clk_stm32_pll_enable,
+	.disable	= clk_stm32_pll_disable,
+	.is_enabled	= clk_stm32_pll_is_enabled,
+};
+
+#define CLK_PLL(idx, _idx, _parent, _pll_id, _flags)[idx] = {\
+	.binding	= _idx,\
+	.parent		= _parent,\
+	.flags		= (_flags),\
+	.clock_cfg	= &(struct stm32_pll_cfg) {\
+		.pll_id	= _pll_id,\
+	},\
+	.ops		= STM32_PLL_OPS,\
+}
+
+static unsigned long clk_get_pll1_fvco(unsigned long refclk)
+{
+	uintptr_t pll_freq1_reg = A35SSC_BASE + A35_SS_PLL_FREQ1;
+	uint32_t reg, fbdiv, refdiv;
+
+	reg = mmio_read_32(pll_freq1_reg);
+
+	fbdiv = (reg & A35_SS_PLL_FREQ1_FBDIV_MASK) >> A35_SS_PLL_FREQ1_FBDIV_SHIFT;
+	refdiv = (reg & A35_SS_PLL_FREQ1_REFDIV_MASK) >> A35_SS_PLL_FREQ1_REFDIV_SHIFT;
+
+	return (unsigned long)(refclk * fbdiv / refdiv);
+}
+
+static unsigned long clk_stm32_pll1_recalc_rate(struct stm32_clk_priv *priv,
+						int id, unsigned long prate)
+{
+	uintptr_t pll_freq2_reg = A35SSC_BASE + A35_SS_PLL_FREQ2;
+	uint32_t postdiv1, postdiv2;
+	unsigned long dfout;
+
+	postdiv1 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV1_MASK) >>
+		   A35_SS_PLL_FREQ2_POSTDIV1_SHIFT;
+	postdiv2 = (mmio_read_32(pll_freq2_reg) & A35_SS_PLL_FREQ2_POSTDIV2_MASK) >>
+		   A35_SS_PLL_FREQ2_POSTDIV2_SHIFT;
+
+	if ((postdiv1 == 0U) || (postdiv2 == 0U)) {
+		dfout = prate;
+	} else {
+		dfout = clk_get_pll1_fvco(prate) / (postdiv1 * postdiv2);
+	}
+
+	return dfout;
+}
+
+static const struct stm32_clk_ops clk_stm32_pll1_ops = {
+	.recalc_rate = clk_stm32_pll1_recalc_rate,
+};
+
+#define CLK_PLL1(idx, _idx, _parent, _pll_id, _flags)[idx] = {\
+	.binding	= _idx,\
+	.parent		= _parent,\
+	.flags		= (_flags),\
+	.clock_cfg	= &(struct stm32_pll_cfg) {\
+		.pll_id	= _pll_id,\
+	},\
+	.ops		= STM32_PLL1_OPS,\
+}
+
+struct stm32_clk_flexgen_cfg {
+	uint8_t id;
+};
+
+static unsigned long clk_flexgen_recalc(struct stm32_clk_priv *priv, int idx,
+					unsigned long prate)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, idx);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uintptr_t rcc_base = priv->base;
+	uint32_t prediv, findiv;
+	uint8_t channel = cfg->id;
+	unsigned long freq = prate;
+
+	prediv = mmio_read_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel)) &
+		RCC_PREDIVxCFGR_PREDIVx_MASK;
+	findiv = mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) &
+		RCC_FINDIVxCFGR_FINDIVx_MASK;
+
+	if (freq == 0UL) {
+		return 0U;
+	}
+
+	switch (prediv) {
+	case 0x0:
+	case 0x1:
+	case 0x3:
+	case 0x3FF:
+		break;
+
+	default:
+		ERROR("Unsupported PREDIV value (%x)\n", prediv);
+		panic();
+		break;
+	}
+
+	freq /= (prediv + 1U);
+	freq /= (findiv + 1U);
+
+	return freq;
+}
+
+static int clk_flexgen_get_parent(struct stm32_clk_priv *priv, int idx)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, idx);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uint32_t sel;
+	uint32_t address;
+	uintptr_t rcc_base = priv->base;
+
+	address = RCC_XBAR0CFGR + (cfg->id * 4);
+
+	sel = mmio_read_32(rcc_base + address) & RCC_XBARxCFGR_XBARxSEL_MASK;
+
+	return sel;
+}
+
+static int clk_flexgen_gate_enable(struct stm32_clk_priv *priv, int idx)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, idx);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uintptr_t rcc_base = priv->base;
+	uint8_t channel = cfg->id;
+
+	mmio_setbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel),
+			RCC_FINDIVxCFGR_FINDIVxEN);
+
+	return 0;
+}
+
+static void clk_flexgen_gate_disable(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uintptr_t rcc_base = priv->base;
+	uint8_t channel = cfg->id;
+
+	mmio_clrbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel),
+			RCC_FINDIVxCFGR_FINDIVxEN);
+}
+
+static bool clk_flexgen_gate_is_enabled(struct stm32_clk_priv *priv, int id)
+{
+	const struct clk_stm32 *clk = _clk_get(priv, id);
+	struct stm32_clk_flexgen_cfg *cfg = clk->clock_cfg;
+	uintptr_t rcc_base = priv->base;
+	uint8_t channel = cfg->id;
+
+	return !!(mmio_read_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel)) &
+		RCC_FINDIVxCFGR_FINDIVxEN);
+}
+
+static const struct stm32_clk_ops clk_stm32_flexgen_ops = {
+	.recalc_rate = clk_flexgen_recalc,
+	.get_parent = clk_flexgen_get_parent,
+	.enable = clk_flexgen_gate_enable,
+	.disable = clk_flexgen_gate_disable,
+	.is_enabled = clk_flexgen_gate_is_enabled,
+};
+
+#define FLEXGEN(idx, _idx, _flags, _id)[idx] = {\
+	.binding = _idx,\
+	.parent =  MUX(MUX_XBARSEL),\
+	.flags = (_flags),\
+	.clock_cfg	= &(struct stm32_clk_flexgen_cfg) {\
+		.id	= _id,\
+	},\
+	.ops = STM32_FLEXGEN_OPS,\
+}
+
+#define RCC_0_MHZ	UL(0)
+#define RCC_4_MHZ	UL(4000000)
+#define RCC_16_MHZ	UL(16000000)
+
+#ifdef IMAGE_BL2
+static int clk_stm32_osc_msi_set_rate(struct stm32_clk_priv *priv, int id, unsigned long rate,
+				      unsigned long prate)
+{
+	uintptr_t address = priv->base + RCC_BDCR;
+	uint32_t mask = RCC_BDCR_MSIFREQSEL;
+	int ret = -1;
+
+	switch (rate) {
+	case RCC_4_MHZ:
+		mmio_clrbits_32(address, mask);
+		ret = 0;
+		break;
+
+	case RCC_16_MHZ:
+		mmio_setbits_32(address, mask);
+		ret = 0;
+		break;
+
+	default:
+		break;
+	}
+
+	return ret;
+}
+#endif /* IMAGE_BL2 */
+
+static unsigned long clk_stm32_osc_msi_recalc_rate(struct stm32_clk_priv *priv,
+						   int id __unused,
+						   unsigned long prate __unused)
+{
+	uintptr_t address = priv->base + RCC_BDCR;
+
+	if ((mmio_read_32(address) & RCC_BDCR_MSIFREQSEL) == 0U) {
+		return RCC_4_MHZ;
+	} else {
+		return RCC_16_MHZ;
+	}
+}
+
+static const struct stm32_clk_ops clk_stm32_osc_msi_ops = {
+	.recalc_rate	= clk_stm32_osc_msi_recalc_rate,
+	.is_enabled	= clk_stm32_osc_gate_is_enabled,
+	.enable		= clk_stm32_osc_gate_enable,
+	.disable	= clk_stm32_osc_gate_disable,
+	.init		= clk_stm32_osc_init,
+};
+
+#define CLK_OSC_MSI(idx, _idx, _parent, _osc_id) \
+	[(idx)] = (struct clk_stm32){ \
+		.binding	= (_idx),\
+		.parent		= (_parent),\
+		.flags		= CLK_IS_CRITICAL,\
+		.clock_cfg	= &(struct stm32_osc_cfg){\
+			.osc_id = (_osc_id),\
+		},\
+		.ops		= STM32_OSC_MSI_OPS,\
+	}
+
+static const struct stm32_clk_ops clk_stm32_rtc_ops = {
+	.enable = clk_stm32_gate_enable,
+	.disable = clk_stm32_gate_disable,
+	.is_enabled = clk_stm32_gate_is_enabled,
+};
+
+#define CLK_RTC(idx, _binding, _parent, _flags, _gate_id)[idx] = {\
+	.binding = (_binding),\
+	.parent =  (_parent),\
+	.flags = (_flags),\
+	.clock_cfg	= &(struct clk_stm32_gate_cfg) {\
+		.id	= (_gate_id),\
+	},\
+	.ops = STM32_RTC_OPS,\
+}
+
+enum {
+	STM32_PLL_OPS = STM32_LAST_OPS,
+	STM32_PLL1_OPS,
+	STM32_FLEXGEN_OPS,
+	STM32_OSC_MSI_OPS,
+	STM32_RTC_OPS,
+
+	MP25_LAST_OPS
+};
+
+static const struct stm32_clk_ops *ops_array_mp25[MP25_LAST_OPS] = {
+	[NO_OPS] =  NULL,
+	[FIXED_FACTOR_OPS] = &clk_fixed_factor_ops,
+	[GATE_OPS] = &clk_gate_ops,
+	[STM32_MUX_OPS] = &clk_mux_ops,
+	[STM32_DIVIDER_OPS] = &clk_stm32_divider_ops,
+	[STM32_GATE_OPS] = &clk_stm32_gate_ops,
+	[STM32_TIMER_OPS] = &clk_timer_ops,
+	[STM32_FIXED_RATE_OPS] = &clk_stm32_fixed_rate_ops,
+	[STM32_OSC_OPS] = &clk_stm32_osc_ops,
+	[STM32_OSC_NOGATE_OPS] = &clk_stm32_osc_nogate_ops,
+
+	[STM32_PLL_OPS] = &clk_stm32_pll_ops,
+	[STM32_PLL1_OPS] = &clk_stm32_pll1_ops,
+	[STM32_FLEXGEN_OPS] = &clk_stm32_flexgen_ops,
+	[STM32_OSC_MSI_OPS] = &clk_stm32_osc_msi_ops,
+	[STM32_RTC_OPS] = &clk_stm32_rtc_ops
+};
+
+static const struct clk_stm32 stm32mp25_clk[CK_LAST] = {
+	CLK_FIXED_RATE(_CK_0_MHZ, _NO_ID, RCC_0_MHZ),
+
+	/* ROOT CLOCKS */
+	CLK_OSC(_CK_HSE, HSE_CK, CLK_IS_ROOT, OSC_HSE),
+	CLK_OSC(_CK_LSE, LSE_CK, CLK_IS_ROOT, OSC_LSE),
+	CLK_OSC(_CK_HSI, HSI_CK, CLK_IS_ROOT, OSC_HSI),
+	CLK_OSC(_CK_LSI, LSI_CK, CLK_IS_ROOT, OSC_LSI),
+	CLK_OSC_MSI(_CK_MSI, MSI_CK, CLK_IS_ROOT, OSC_MSI),
+
+	CLK_OSC_FIXED(_I2SCKIN, _NO_ID, CLK_IS_ROOT, OSC_I2SCKIN),
+	CLK_OSC_FIXED(_SPDIFSYMB, _NO_ID, CLK_IS_ROOT, OSC_SPDIFSYMB),
+
+	STM32_DIV(_CK_HSE_RTC, _NO_ID, _CK_HSE, 0, DIV_RTC),
+
+	CLK_RTC(_CK_RTCCK, RTC_CK, MUX(MUX_RTC), 0, GATE_RTCCK),
+
+	CLK_PLL1(_CK_PLL1, PLL1_CK, MUX(MUX_MUXSEL5), _PLL1, 0),
+
+	CLK_PLL(_CK_PLL2, PLL2_CK, MUX(MUX_MUXSEL6), _PLL2, 0),
+	CLK_PLL(_CK_PLL3, PLL3_CK, MUX(MUX_MUXSEL7), _PLL3, 0),
+	CLK_PLL(_CK_PLL4, PLL4_CK, MUX(MUX_MUXSEL0), _PLL4, 0),
+	CLK_PLL(_CK_PLL5, PLL5_CK, MUX(MUX_MUXSEL1), _PLL5, 0),
+	CLK_PLL(_CK_PLL6, PLL6_CK, MUX(MUX_MUXSEL2), _PLL6, 0),
+	CLK_PLL(_CK_PLL7, PLL7_CK, MUX(MUX_MUXSEL3), _PLL7, 0),
+	CLK_PLL(_CK_PLL8, PLL8_CK, MUX(MUX_MUXSEL4), _PLL8, 0),
+
+	FLEXGEN(_CK_ICN_HS_MCU,	CK_ICN_HS_MCU, CLK_IS_CRITICAL, 0),
+	FLEXGEN(_CK_ICN_SDMMC, CK_ICN_SDMMC, CLK_IS_CRITICAL, 1),
+	FLEXGEN(_CK_ICN_DDR, CK_ICN_DDR, CLK_IS_CRITICAL, 2),
+	FLEXGEN(_CK_ICN_HSL, CK_ICN_HSL, CLK_IS_CRITICAL, 4),
+	FLEXGEN(_CK_ICN_NIC, CK_ICN_NIC, CLK_IS_CRITICAL, 5),
+
+	STM32_DIV(_CK_ICN_LS_MCU, CK_ICN_LS_MCU, _CK_ICN_HS_MCU, 0, DIV_LSMCU),
+
+	FLEXGEN(_CK_FLEXGEN_07, CK_FLEXGEN_07, 0, 7),
+	FLEXGEN(_CK_FLEXGEN_08, CK_FLEXGEN_08, 0, 8),
+	FLEXGEN(_CK_FLEXGEN_09, CK_FLEXGEN_09, 0, 9),
+	FLEXGEN(_CK_FLEXGEN_10, CK_FLEXGEN_10, 0, 10),
+	FLEXGEN(_CK_FLEXGEN_11, CK_FLEXGEN_11, 0, 11),
+	FLEXGEN(_CK_FLEXGEN_12, CK_FLEXGEN_12, 0, 12),
+	FLEXGEN(_CK_FLEXGEN_13, CK_FLEXGEN_13, 0, 13),
+	FLEXGEN(_CK_FLEXGEN_14, CK_FLEXGEN_14, 0, 14),
+	FLEXGEN(_CK_FLEXGEN_15, CK_FLEXGEN_15, 0, 15),
+	FLEXGEN(_CK_FLEXGEN_16, CK_FLEXGEN_16, 0, 16),
+	FLEXGEN(_CK_FLEXGEN_17, CK_FLEXGEN_17, 0, 17),
+	FLEXGEN(_CK_FLEXGEN_18, CK_FLEXGEN_18, 0, 18),
+	FLEXGEN(_CK_FLEXGEN_19, CK_FLEXGEN_19, 0, 19),
+	FLEXGEN(_CK_FLEXGEN_20, CK_FLEXGEN_20, 0, 20),
+	FLEXGEN(_CK_FLEXGEN_21, CK_FLEXGEN_21, 0, 21),
+	FLEXGEN(_CK_FLEXGEN_22, CK_FLEXGEN_22, 0, 22),
+	FLEXGEN(_CK_FLEXGEN_23, CK_FLEXGEN_23, 0, 23),
+	FLEXGEN(_CK_FLEXGEN_24, CK_FLEXGEN_24, 0, 24),
+	FLEXGEN(_CK_FLEXGEN_25, CK_FLEXGEN_25, 0, 25),
+	FLEXGEN(_CK_FLEXGEN_26, CK_FLEXGEN_26, 0, 26),
+	FLEXGEN(_CK_FLEXGEN_27, CK_FLEXGEN_27, 0, 27),
+	FLEXGEN(_CK_FLEXGEN_28, CK_FLEXGEN_28, 0, 28),
+	FLEXGEN(_CK_FLEXGEN_29, CK_FLEXGEN_29, 0, 29),
+	FLEXGEN(_CK_FLEXGEN_30, CK_FLEXGEN_30, 0, 30),
+	FLEXGEN(_CK_FLEXGEN_31, CK_FLEXGEN_31, 0, 31),
+	FLEXGEN(_CK_FLEXGEN_32, CK_FLEXGEN_32, 0, 32),
+	FLEXGEN(_CK_FLEXGEN_33, CK_FLEXGEN_33, 0, 33),
+	FLEXGEN(_CK_FLEXGEN_34, CK_FLEXGEN_34, 0, 34),
+	FLEXGEN(_CK_FLEXGEN_35, CK_FLEXGEN_35, 0, 35),
+	FLEXGEN(_CK_FLEXGEN_36, CK_FLEXGEN_36, 0, 36),
+	FLEXGEN(_CK_FLEXGEN_37, CK_FLEXGEN_37, 0, 37),
+	FLEXGEN(_CK_FLEXGEN_38, CK_FLEXGEN_38, 0, 38),
+	FLEXGEN(_CK_FLEXGEN_39, CK_FLEXGEN_39, 0, 39),
+	FLEXGEN(_CK_FLEXGEN_40, CK_FLEXGEN_40, 0, 40),
+	FLEXGEN(_CK_FLEXGEN_41, CK_FLEXGEN_41, 0, 41),
+	FLEXGEN(_CK_FLEXGEN_42, CK_FLEXGEN_42, 0, 42),
+	FLEXGEN(_CK_FLEXGEN_43, CK_FLEXGEN_43, 0, 43),
+	FLEXGEN(_CK_FLEXGEN_44, CK_FLEXGEN_44, 0, 44),
+	FLEXGEN(_CK_FLEXGEN_45, CK_FLEXGEN_45, 0, 45),
+	FLEXGEN(_CK_FLEXGEN_46, CK_FLEXGEN_46, 0, 46),
+	FLEXGEN(_CK_FLEXGEN_47, CK_FLEXGEN_47, 0, 47),
+	FLEXGEN(_CK_FLEXGEN_48, CK_FLEXGEN_48, 0, 48),
+	FLEXGEN(_CK_FLEXGEN_49, CK_FLEXGEN_49, 0, 49),
+	FLEXGEN(_CK_FLEXGEN_50, CK_FLEXGEN_50, 0, 50),
+	FLEXGEN(_CK_FLEXGEN_51, CK_FLEXGEN_51, 0, 51),
+	FLEXGEN(_CK_FLEXGEN_52, CK_FLEXGEN_52, 0, 52),
+	FLEXGEN(_CK_FLEXGEN_53, CK_FLEXGEN_53, 0, 53),
+	FLEXGEN(_CK_FLEXGEN_54, CK_FLEXGEN_54, 0, 54),
+	FLEXGEN(_CK_FLEXGEN_55, CK_FLEXGEN_55, 0, 55),
+	FLEXGEN(_CK_FLEXGEN_56, CK_FLEXGEN_56, 0, 56),
+	FLEXGEN(_CK_FLEXGEN_57, CK_FLEXGEN_57, 0, 57),
+	FLEXGEN(_CK_FLEXGEN_58, CK_FLEXGEN_58, 0, 58),
+	FLEXGEN(_CK_FLEXGEN_59, CK_FLEXGEN_59, 0, 59),
+	FLEXGEN(_CK_FLEXGEN_60, CK_FLEXGEN_60, 0, 60),
+	FLEXGEN(_CK_FLEXGEN_61, CK_FLEXGEN_61, 0, 61),
+	FLEXGEN(_CK_FLEXGEN_62, CK_FLEXGEN_62, 0, 62),
+	FLEXGEN(_CK_FLEXGEN_63, CK_FLEXGEN_63, 0, 63),
+
+	STM32_DIV(_CK_ICN_APB1, CK_ICN_APB1, _CK_ICN_LS_MCU, 0, DIV_APB1),
+	STM32_DIV(_CK_ICN_APB2, CK_ICN_APB2, _CK_ICN_LS_MCU, 0, DIV_APB2),
+	STM32_DIV(_CK_ICN_APB3, CK_ICN_APB3, _CK_ICN_LS_MCU, 0, DIV_APB3),
+	STM32_DIV(_CK_ICN_APB4, CK_ICN_APB4, _CK_ICN_LS_MCU, 0, DIV_APB4),
+	STM32_DIV(_CK_ICN_APBDBG, CK_ICN_APBDBG, _CK_ICN_LS_MCU, 0, DIV_APBDBG),
+
+	/* KERNEL CLOCK */
+	STM32_GATE(_CK_SYSRAM, CK_BUS_SYSRAM, _CK_ICN_HS_MCU, 0, GATE_SYSRAM),
+	STM32_GATE(_CK_RETRAM, CK_BUS_RETRAM, _CK_ICN_HS_MCU, 0, GATE_RETRAM),
+	STM32_GATE(_CK_SRAM1, CK_BUS_SRAM1, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM1),
+	STM32_GATE(_CK_SRAM2, CK_BUS_SRAM2, _CK_ICN_HS_MCU, CLK_IS_CRITICAL, GATE_SRAM2),
+
+	STM32_GATE(_CK_DDRPHYC, CK_BUS_DDRPHYC, _CK_ICN_LS_MCU, 0, GATE_DDRPHYC),
+	STM32_GATE(_CK_SYSCPU1, CK_BUS_SYSCPU1, _CK_ICN_LS_MCU, 0, GATE_SYSCPU1),
+	STM32_GATE(_CK_CRC, CK_BUS_CRC, _CK_ICN_LS_MCU, 0, GATE_CRC),
+	STM32_GATE(_CK_OSPIIOM, CK_BUS_OSPIIOM, _CK_ICN_LS_MCU, 0, GATE_OSPIIOM),
+	STM32_GATE(_CK_BKPSRAM, CK_BUS_BKPSRAM, _CK_ICN_LS_MCU, 0, GATE_BKPSRAM),
+	STM32_GATE(_CK_HASH, CK_BUS_HASH, _CK_ICN_LS_MCU, 0, GATE_HASH),
+	STM32_GATE(_CK_RNG, CK_BUS_RNG, _CK_ICN_LS_MCU, 0, GATE_RNG),
+	STM32_GATE(_CK_CRYP1, CK_BUS_CRYP1, _CK_ICN_LS_MCU, 0, GATE_CRYP1),
+	STM32_GATE(_CK_CRYP2, CK_BUS_CRYP2, _CK_ICN_LS_MCU, 0, GATE_CRYP2),
+	STM32_GATE(_CK_SAES, CK_BUS_SAES, _CK_ICN_LS_MCU, 0, GATE_SAES),
+	STM32_GATE(_CK_PKA, CK_BUS_PKA, _CK_ICN_LS_MCU, 0, GATE_PKA),
+
+	STM32_GATE(_CK_GPIOA, CK_BUS_GPIOA, _CK_ICN_LS_MCU, 0, GATE_GPIOA),
+	STM32_GATE(_CK_GPIOB, CK_BUS_GPIOB, _CK_ICN_LS_MCU, 0, GATE_GPIOB),
+	STM32_GATE(_CK_GPIOC, CK_BUS_GPIOC, _CK_ICN_LS_MCU, 0, GATE_GPIOC),
+	STM32_GATE(_CK_GPIOD, CK_BUS_GPIOD, _CK_ICN_LS_MCU, 0, GATE_GPIOD),
+	STM32_GATE(_CK_GPIOE, CK_BUS_GPIOE, _CK_ICN_LS_MCU, 0, GATE_GPIOE),
+	STM32_GATE(_CK_GPIOF, CK_BUS_GPIOF, _CK_ICN_LS_MCU, 0, GATE_GPIOF),
+	STM32_GATE(_CK_GPIOG, CK_BUS_GPIOG, _CK_ICN_LS_MCU, 0, GATE_GPIOG),
+	STM32_GATE(_CK_GPIOH, CK_BUS_GPIOH, _CK_ICN_LS_MCU, 0, GATE_GPIOH),
+	STM32_GATE(_CK_GPIOI, CK_BUS_GPIOI, _CK_ICN_LS_MCU, 0, GATE_GPIOI),
+	STM32_GATE(_CK_GPIOJ, CK_BUS_GPIOJ, _CK_ICN_LS_MCU, 0, GATE_GPIOJ),
+	STM32_GATE(_CK_GPIOK, CK_BUS_GPIOK, _CK_ICN_LS_MCU, 0, GATE_GPIOK),
+	STM32_GATE(_CK_GPIOZ, CK_BUS_GPIOZ, _CK_ICN_LS_MCU, 0, GATE_GPIOZ),
+	STM32_GATE(_CK_RTC, CK_BUS_RTC, _CK_ICN_LS_MCU, 0, GATE_RTC),
+
+	STM32_GATE(_CK_DDRCP, CK_BUS_DDR, _CK_ICN_DDR, 0, GATE_DDRCP),
+
+	/* WARNING 2 CLOCKS FOR ONE GATE */
+	STM32_GATE(_CK_USB2OHCI, CK_BUS_USB2OHCI, _CK_ICN_HSL, 0, GATE_USB2OHCI),
+	STM32_GATE(_CK_USB2EHCI, CK_BUS_USB2EHCI, _CK_ICN_HSL, 0, GATE_USB2EHCI),
+
+	STM32_GATE(_CK_USB3DR, CK_BUS_USB3DR, _CK_ICN_HSL, 0, GATE_USB3DR),
+
+	STM32_GATE(_CK_BSEC, CK_BUS_BSEC, _CK_ICN_APB3, 0, GATE_BSEC),
+	STM32_GATE(_CK_IWDG1, CK_BUS_IWDG1, _CK_ICN_APB3, 0, GATE_IWDG1),
+	STM32_GATE(_CK_IWDG2, CK_BUS_IWDG2, _CK_ICN_APB3, 0, GATE_IWDG2),
+
+	STM32_GATE(_CK_DDRCAPB, CK_BUS_DDRC, _CK_ICN_APB4, 0, GATE_DDRCAPB),
+	STM32_GATE(_CK_DDR, CK_BUS_DDRCFG, _CK_ICN_APB4, 0, GATE_DDR),
+
+	STM32_GATE(_CK_USART2, CK_KER_USART2, _CK_FLEXGEN_08, 0, GATE_USART2),
+	STM32_GATE(_CK_UART4, CK_KER_UART4, _CK_FLEXGEN_08, 0, GATE_UART4),
+	STM32_GATE(_CK_USART3, CK_KER_USART3, _CK_FLEXGEN_09, 0, GATE_USART3),
+	STM32_GATE(_CK_UART5, CK_KER_UART5, _CK_FLEXGEN_09, 0, GATE_UART5),
+	STM32_GATE(_CK_I2C1, CK_KER_I2C1, _CK_FLEXGEN_12, 0, GATE_I2C1),
+	STM32_GATE(_CK_I2C2, CK_KER_I2C2, _CK_FLEXGEN_12, 0, GATE_I2C2),
+	STM32_GATE(_CK_I2C3, CK_KER_I2C3, _CK_FLEXGEN_13, 0, GATE_I2C3),
+	STM32_GATE(_CK_I2C5, CK_KER_I2C5, _CK_FLEXGEN_13, 0, GATE_I2C5),
+	STM32_GATE(_CK_I2C4, CK_KER_I2C4, _CK_FLEXGEN_14, 0, GATE_I2C4),
+	STM32_GATE(_CK_I2C6, CK_KER_I2C6, _CK_FLEXGEN_14, 0, GATE_I2C6),
+	STM32_GATE(_CK_I2C7, CK_KER_I2C7, _CK_FLEXGEN_15, 0, GATE_I2C7),
+	STM32_GATE(_CK_USART1, CK_KER_USART1, _CK_FLEXGEN_19, 0, GATE_USART1),
+	STM32_GATE(_CK_USART6, CK_KER_USART6, _CK_FLEXGEN_20, 0, GATE_USART6),
+	STM32_GATE(_CK_UART7, CK_KER_UART7, _CK_FLEXGEN_21, 0, GATE_UART7),
+	STM32_GATE(_CK_UART8, CK_KER_UART8, _CK_FLEXGEN_21, 0, GATE_UART8),
+	STM32_GATE(_CK_UART9, CK_KER_UART9, _CK_FLEXGEN_22, 0, GATE_UART9),
+	STM32_GATE(_CK_STGEN, CK_KER_STGEN, _CK_FLEXGEN_33, 0, GATE_STGEN),
+	STM32_GATE(_CK_USB3PCIEPHY, CK_KER_USB3PCIEPHY, _CK_FLEXGEN_34, 0, GATE_USB3PCIEPHY),
+	STM32_GATE(_CK_USBTC, CK_KER_USBTC, _CK_FLEXGEN_35, 0, GATE_USBTC),
+	STM32_GATE(_CK_I2C8, CK_KER_I2C8, _CK_FLEXGEN_38, 0, GATE_I2C8),
+	STM32_GATE(_CK_OSPI1, CK_KER_OSPI1, _CK_FLEXGEN_48, 0, GATE_OSPI1),
+	STM32_GATE(_CK_OSPI2, CK_KER_OSPI2, _CK_FLEXGEN_49, 0, GATE_OSPI2),
+	STM32_GATE(_CK_FMC, CK_KER_FMC, _CK_FLEXGEN_50, 0, GATE_FMC),
+	STM32_GATE(_CK_SDMMC1, CK_KER_SDMMC1, _CK_FLEXGEN_51, 0, GATE_SDMMC1),
+	STM32_GATE(_CK_SDMMC2, CK_KER_SDMMC2, _CK_FLEXGEN_52, 0, GATE_SDMMC2),
+	STM32_GATE(_CK_USB2PHY1, CK_KER_USB2PHY1, _CK_FLEXGEN_57, 0, GATE_USB2PHY1),
+	STM32_GATE(_CK_USB2PHY2, CK_KER_USB2PHY2, _CK_FLEXGEN_58, 0, GATE_USB2PHY2),
+};
+
+enum clksrc_id {
+	CLKSRC_CA35SS,
+	CLKSRC_PLL1,
+	CLKSRC_PLL2,
+	CLKSRC_PLL3,
+	CLKSRC_PLL4,
+	CLKSRC_PLL5,
+	CLKSRC_PLL6,
+	CLKSRC_PLL7,
+	CLKSRC_PLL8,
+	CLKSRC_XBAR_CHANNEL0,
+	CLKSRC_XBAR_CHANNEL1,
+	CLKSRC_XBAR_CHANNEL2,
+	CLKSRC_XBAR_CHANNEL3,
+	CLKSRC_XBAR_CHANNEL4,
+	CLKSRC_XBAR_CHANNEL5,
+	CLKSRC_XBAR_CHANNEL6,
+	CLKSRC_XBAR_CHANNEL7,
+	CLKSRC_XBAR_CHANNEL8,
+	CLKSRC_XBAR_CHANNEL9,
+	CLKSRC_XBAR_CHANNEL10,
+	CLKSRC_XBAR_CHANNEL11,
+	CLKSRC_XBAR_CHANNEL12,
+	CLKSRC_XBAR_CHANNEL13,
+	CLKSRC_XBAR_CHANNEL14,
+	CLKSRC_XBAR_CHANNEL15,
+	CLKSRC_XBAR_CHANNEL16,
+	CLKSRC_XBAR_CHANNEL17,
+	CLKSRC_XBAR_CHANNEL18,
+	CLKSRC_XBAR_CHANNEL19,
+	CLKSRC_XBAR_CHANNEL20,
+	CLKSRC_XBAR_CHANNEL21,
+	CLKSRC_XBAR_CHANNEL22,
+	CLKSRC_XBAR_CHANNEL23,
+	CLKSRC_XBAR_CHANNEL24,
+	CLKSRC_XBAR_CHANNEL25,
+	CLKSRC_XBAR_CHANNEL26,
+	CLKSRC_XBAR_CHANNEL27,
+	CLKSRC_XBAR_CHANNEL28,
+	CLKSRC_XBAR_CHANNEL29,
+	CLKSRC_XBAR_CHANNEL30,
+	CLKSRC_XBAR_CHANNEL31,
+	CLKSRC_XBAR_CHANNEL32,
+	CLKSRC_XBAR_CHANNEL33,
+	CLKSRC_XBAR_CHANNEL34,
+	CLKSRC_XBAR_CHANNEL35,
+	CLKSRC_XBAR_CHANNEL36,
+	CLKSRC_XBAR_CHANNEL37,
+	CLKSRC_XBAR_CHANNEL38,
+	CLKSRC_XBAR_CHANNEL39,
+	CLKSRC_XBAR_CHANNEL40,
+	CLKSRC_XBAR_CHANNEL41,
+	CLKSRC_XBAR_CHANNEL42,
+	CLKSRC_XBAR_CHANNEL43,
+	CLKSRC_XBAR_CHANNEL44,
+	CLKSRC_XBAR_CHANNEL45,
+	CLKSRC_XBAR_CHANNEL46,
+	CLKSRC_XBAR_CHANNEL47,
+	CLKSRC_XBAR_CHANNEL48,
+	CLKSRC_XBAR_CHANNEL49,
+	CLKSRC_XBAR_CHANNEL50,
+	CLKSRC_XBAR_CHANNEL51,
+	CLKSRC_XBAR_CHANNEL52,
+	CLKSRC_XBAR_CHANNEL53,
+	CLKSRC_XBAR_CHANNEL54,
+	CLKSRC_XBAR_CHANNEL55,
+	CLKSRC_XBAR_CHANNEL56,
+	CLKSRC_XBAR_CHANNEL57,
+	CLKSRC_XBAR_CHANNEL58,
+	CLKSRC_XBAR_CHANNEL59,
+	CLKSRC_XBAR_CHANNEL60,
+	CLKSRC_XBAR_CHANNEL61,
+	CLKSRC_XBAR_CHANNEL62,
+	CLKSRC_XBAR_CHANNEL63,
+	CLKSRC_RTC,
+	CLKSRC_MCO1,
+	CLKSRC_MCO2,
+	CLKSRC_NB
+};
+
+static void stm32mp2_a35_ss_on_hsi(void)
+{
+	uintptr_t a35_ss_address = A35SSC_BASE;
+	uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ;
+	uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE;
+	uint64_t timeout;
+
+	if ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) ==
+	    A35_SS_CHGCLKREQ_ARM_CHGCLKACK) {
+		/* Nothing to do, clock source is already set on bypass clock */
+		return;
+	}
+
+	mmio_setbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ);
+
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+	while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) !=
+	       A35_SS_CHGCLKREQ_ARM_CHGCLKACK) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("Cannot switch A35 to bypass clock\n");
+			panic();
+		}
+	}
+
+	mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF);
+}
+
+#ifdef IMAGE_BL2
+static void stm32mp2_clk_muxsel_on_hsi(struct stm32_clk_priv *priv)
+{
+	mmio_clrbits_32(priv->base + RCC_MUXSELCFGR,
+			RCC_MUXSELCFGR_MUXSEL0_MASK |
+			RCC_MUXSELCFGR_MUXSEL1_MASK |
+			RCC_MUXSELCFGR_MUXSEL2_MASK |
+			RCC_MUXSELCFGR_MUXSEL3_MASK |
+			RCC_MUXSELCFGR_MUXSEL4_MASK |
+			RCC_MUXSELCFGR_MUXSEL5_MASK |
+			RCC_MUXSELCFGR_MUXSEL6_MASK |
+			RCC_MUXSELCFGR_MUXSEL7_MASK);
+}
+
+static void stm32mp2_clk_xbar_on_hsi(struct stm32_clk_priv *priv)
+{
+	uintptr_t xbar0cfgr = priv->base + RCC_XBAR0CFGR;
+	uint32_t i;
+
+	for (i = 0; i < XBAR_CHANNEL_NB; i++) {
+		mmio_clrsetbits_32(xbar0cfgr + (0x4 * i),
+				   RCC_XBAR0CFGR_XBAR0SEL_MASK,
+				   XBAR_SRC_HSI);
+	}
+}
+
+static int stm32mp2_a35_pll1_start(void)
+{
+	uintptr_t a35_ss_address = A35SSC_BASE;
+	uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE;
+	uintptr_t chgclkreq_reg = a35_ss_address + A35_SS_CHGCLKREQ;
+	uint64_t timeout = timeout_init_us(PLLRDY_TIMEOUT);
+
+	mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD);
+
+	/* Wait PLL lock */
+	while ((mmio_read_32(pll_enable_reg) & A35_SS_PLL_ENABLE_LOCKP) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("PLL1 start failed @ 0x%lx: 0x%x\n",
+				    pll_enable_reg, mmio_read_32(pll_enable_reg));
+			return -ETIMEDOUT;
+		}
+	}
+
+	/* De-assert reset on PLL output clock path */
+	mmio_setbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_NRESET_SWPLL_FF);
+
+	/* Switch CPU clock to PLL clock */
+	mmio_clrbits_32(chgclkreq_reg, A35_SS_CHGCLKREQ_ARM_CHGCLKREQ);
+
+	/* Wait for clock change acknowledge */
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+	while ((mmio_read_32(chgclkreq_reg) & A35_SS_CHGCLKREQ_ARM_CHGCLKACK) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("CA35SS switch to PLL1 failed @ 0x%lx: 0x%x\n",
+				    chgclkreq_reg, mmio_read_32(chgclkreq_reg));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void stm32mp2_a35_pll1_config(uint32_t fbdiv, uint32_t refdiv, uint32_t postdiv1,
+				     uint32_t postdiv2)
+{
+	uintptr_t a35_ss_address = A35SSC_BASE;
+	uintptr_t pll_freq1_reg = a35_ss_address + A35_SS_PLL_FREQ1;
+	uintptr_t pll_freq2_reg = a35_ss_address + A35_SS_PLL_FREQ2;
+
+	mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_REFDIV_MASK,
+			   (refdiv << A35_SS_PLL_FREQ1_REFDIV_SHIFT) &
+			   A35_SS_PLL_FREQ1_REFDIV_MASK);
+
+	mmio_clrsetbits_32(pll_freq1_reg, A35_SS_PLL_FREQ1_FBDIV_MASK,
+			   (fbdiv << A35_SS_PLL_FREQ1_FBDIV_SHIFT) &
+			   A35_SS_PLL_FREQ1_FBDIV_MASK);
+
+	mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV1_MASK,
+			   (postdiv1 << A35_SS_PLL_FREQ2_POSTDIV1_SHIFT) &
+			   A35_SS_PLL_FREQ2_POSTDIV1_MASK);
+
+	mmio_clrsetbits_32(pll_freq2_reg, A35_SS_PLL_FREQ2_POSTDIV2_MASK,
+			   (postdiv2 << A35_SS_PLL_FREQ2_POSTDIV2_SHIFT) &
+			   A35_SS_PLL_FREQ2_POSTDIV2_MASK);
+}
+
+static int clk_stm32_pll_config_output(struct stm32_clk_priv *priv,
+				       const struct stm32_clk_pll *pll,
+				       uint32_t *pllcfg,
+				       uint32_t fracv)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uintptr_t pllxcfgr2 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR2;
+	uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3;
+	uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4;
+	uintptr_t pllxcfgr6 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR6;
+	uintptr_t pllxcfgr7 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR7;
+	unsigned long refclk;
+
+	refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id);
+
+	if (fracv == 0U) {
+		/* PLL in integer mode */
+
+		/*
+		 * No need to check max clock, as oscillator reference clocks
+		 * will always be less than 1.2GHz
+		 */
+		if (refclk < PLL_REFCLK_MIN) {
+			panic();
+		}
+
+		mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK);
+		mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN);
+		mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN);
+		mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS);
+		mmio_setbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST);
+	} else {
+		/* PLL in frac mode */
+
+		/*
+		 * No need to check max clock, as oscillator reference clocks
+		 * will always be less than 1.2GHz
+		 */
+		if (refclk < PLL_FRAC_REFCLK_MIN) {
+			panic();
+		}
+
+		mmio_clrsetbits_32(pllxcfgr3, RCC_PLLxCFGR3_FRACIN_MASK,
+				   fracv & RCC_PLLxCFGR3_FRACIN_MASK);
+		mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS);
+		mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN);
+	}
+
+	assert(pllcfg[REFDIV] != 0U);
+
+	mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FBDIV_MASK,
+			   (pllcfg[FBDIV] << RCC_PLLxCFGR2_FBDIV_SHIFT) &
+			   RCC_PLLxCFGR2_FBDIV_MASK);
+	mmio_clrsetbits_32(pllxcfgr2, RCC_PLLxCFGR2_FREFDIV_MASK,
+			   pllcfg[REFDIV] & RCC_PLLxCFGR2_FREFDIV_MASK);
+	mmio_clrsetbits_32(pllxcfgr6, RCC_PLLxCFGR6_POSTDIV1_MASK,
+			   pllcfg[POSTDIV1] & RCC_PLLxCFGR6_POSTDIV1_MASK);
+	mmio_clrsetbits_32(pllxcfgr7, RCC_PLLxCFGR7_POSTDIV2_MASK,
+			   pllcfg[POSTDIV2] & RCC_PLLxCFGR7_POSTDIV2_MASK);
+
+	if ((pllcfg[POSTDIV1] == 0U) || (pllcfg[POSTDIV2] == 0U)) {
+		/* Bypass mode */
+		mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS);
+		mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN);
+	} else {
+		mmio_clrbits_32(pllxcfgr4, RCC_PLLxCFGR4_BYPASS);
+		mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_FOUTPOSTDIVEN);
+	}
+
+	return 0;
+}
+
+static void clk_stm32_pll_config_csg(struct stm32_clk_priv *priv,
+				     const struct stm32_clk_pll *pll,
+				     uint32_t *csg)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uintptr_t pllxcfgr3 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR3;
+	uintptr_t pllxcfgr4 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR4;
+	uintptr_t pllxcfgr5 = pllxcfgr1 + RCC_OFFSET_PLLXCFGR5;
+
+
+	mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_DIVVAL_MASK,
+			   csg[DIVVAL] & RCC_PLLxCFGR5_DIVVAL_MASK);
+	mmio_clrsetbits_32(pllxcfgr5, RCC_PLLxCFGR5_SPREAD_MASK,
+			   (csg[SPREAD] << RCC_PLLxCFGR5_SPREAD_SHIFT) &
+			   RCC_PLLxCFGR5_SPREAD_MASK);
+
+	if (csg[DOWNSPREAD] != 0) {
+		mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD);
+	} else {
+		mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_DOWNSPREAD);
+	}
+
+	mmio_clrbits_32(pllxcfgr3, RCC_PLLxCFGR3_SSCGDIS);
+
+	mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_PLLEN);
+	udelay(1);
+
+	mmio_setbits_32(pllxcfgr4, RCC_PLLxCFGR4_DSMEN);
+	mmio_setbits_32(pllxcfgr3, RCC_PLLxCFGR3_DACEN);
+}
+
+static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data);
+
+static inline struct stm32_pll_dt_cfg *clk_stm32_pll_get_pdata(int pll_idx)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	struct stm32_clk_platdata *pdata = priv->pdata;
+
+	return  &pdata->pll[pll_idx];
+}
+
+static int _clk_stm32_pll1_init(struct stm32_clk_priv *priv, int pll_idx,
+				struct stm32_pll_dt_cfg *pll_conf)
+{
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx);
+	unsigned long refclk;
+	int ret = 0;
+
+	stm32mp2_a35_ss_on_hsi();
+
+	ret = stm32_clk_configure_mux(priv, pll_conf->src);
+	if (ret != 0) {
+		panic();
+	}
+
+	refclk = _clk_stm32_get_parent_rate(priv, pll->clk_id);
+
+	/*
+	 * No need to check max clock, as oscillator reference clocks will
+	 * always be less than 1.2 GHz
+	 */
+	if (refclk < PLL_REFCLK_MIN) {
+		EARLY_ERROR("%s: %d\n", __func__, __LINE__);
+		panic();
+	}
+
+	stm32mp2_a35_pll1_config(pll_conf->cfg[FBDIV], pll_conf->cfg[REFDIV],
+				 pll_conf->cfg[POSTDIV1], pll_conf->cfg[POSTDIV2]);
+
+	ret = stm32mp2_a35_pll1_start();
+	if (ret != 0) {
+		panic();
+	}
+
+	return 0;
+}
+
+static int clk_stm32_pll_wait_mux_ready(struct stm32_clk_priv *priv,
+					const struct stm32_clk_pll *pll)
+{
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	uint64_t timeout = timeout_init_us(CLKSRC_TIMEOUT);
+
+	while ((mmio_read_32(pllxcfgr1) & RCC_PLLxCFGR1_CKREFST) !=
+	       RCC_PLLxCFGR1_CKREFST) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("PLL%d ref clock not started\n", pll->clk_id - _CK_PLL1 + 1);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int _clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx,
+			       struct stm32_pll_dt_cfg *pll_conf)
+{
+	const struct stm32_clk_pll *pll = clk_stm32_pll_data(pll_idx);
+	uintptr_t pllxcfgr1 = priv->base + pll->reg_pllxcfgr1;
+	bool spread_spectrum = false;
+	int ret = 0;
+
+	_clk_stm32_pll_disable(priv, pll);
+
+	ret = stm32_clk_configure_mux(priv, pll_conf->src);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = clk_stm32_pll_wait_mux_ready(priv, pll);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = clk_stm32_pll_config_output(priv, pll, pll_conf->cfg, pll_conf->frac);
+	if (ret != 0) {
+		panic();
+	}
+
+	if (pll_conf->csg_enabled) {
+		clk_stm32_pll_config_csg(priv, pll, pll_conf->csg);
+		spread_spectrum = true;
+	}
+
+	_clk_stm32_pll_enable(priv, pll);
+
+	if (spread_spectrum) {
+		mmio_clrbits_32(pllxcfgr1, RCC_PLLxCFGR1_SSMODRST);
+	}
+
+	return 0;
+}
+
+static int clk_stm32_pll_init(struct stm32_clk_priv *priv, int pll_idx)
+{
+	struct stm32_pll_dt_cfg *pll_conf = clk_stm32_pll_get_pdata(pll_idx);
+
+	if (pll_conf->enabled) {
+		if (pll_idx == _PLL1) {
+			return _clk_stm32_pll1_init(priv, pll_idx, pll_conf);
+		} else  {
+			return _clk_stm32_pll_init(priv, pll_idx, pll_conf);
+		}
+	}
+
+	return 0;
+}
+
+static int stm32mp2_clk_pll_configure(struct stm32_clk_priv *priv)
+{
+	enum pll_id i;
+	int err;
+
+	for (i = _PLL1; i < _PLL_NB; i++) {
+		err = clk_stm32_pll_init(priv, i);
+		if (err) {
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int wait_predivsr(uint16_t channel)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	uintptr_t rcc_base = priv->base;
+	uintptr_t previvsr;
+	uint32_t channel_bit;
+	uint64_t timeout;
+
+	if (channel < __WORD_BIT) {
+		previvsr = rcc_base + RCC_PREDIVSR1;
+		channel_bit = BIT(channel);
+	} else {
+		previvsr = rcc_base + RCC_PREDIVSR2;
+		channel_bit = BIT(channel - __WORD_BIT);
+	}
+
+	timeout = timeout_init_us(CLKDIV_TIMEOUT);
+	while ((mmio_read_32(previvsr) & channel_bit) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("Pre divider status: %x\n",
+			      mmio_read_32(previvsr));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int wait_findivsr(uint16_t channel)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	uintptr_t rcc_base = priv->base;
+	uintptr_t finvivsr;
+	uint32_t channel_bit;
+	uint64_t timeout;
+
+	if (channel < __WORD_BIT) {
+		finvivsr = rcc_base + RCC_FINDIVSR1;
+		channel_bit = BIT(channel);
+	} else {
+		finvivsr = rcc_base + RCC_FINDIVSR2;
+		channel_bit = BIT(channel - __WORD_BIT);
+	}
+
+	timeout = timeout_init_us(CLKDIV_TIMEOUT);
+	while ((mmio_read_32(finvivsr) & channel_bit) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("Final divider status: %x\n",
+			      mmio_read_32(finvivsr));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int wait_xbar_sts(uint16_t channel)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	uintptr_t rcc_base = priv->base;
+	uintptr_t xbar_cfgr = rcc_base + RCC_XBAR0CFGR + (0x4U * channel);
+	uint64_t timeout;
+
+	timeout = timeout_init_us(CLKDIV_TIMEOUT);
+	while ((mmio_read_32(xbar_cfgr) & RCC_XBAR0CFGR_XBAR0STS) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			EARLY_ERROR("XBAR%uCFGR: %x\n", channel,
+			      mmio_read_32(xbar_cfgr));
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void flexclkgen_config_channel(uint16_t channel, unsigned int clk_src,
+				      unsigned int prediv, unsigned int findiv)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	uintptr_t rcc_base = priv->base;
+
+	if (wait_predivsr(channel) != 0) {
+		panic();
+	}
+
+	mmio_clrsetbits_32(rcc_base + RCC_PREDIV0CFGR + (0x4U * channel),
+			   RCC_PREDIV0CFGR_PREDIV0_MASK,
+			   prediv);
+
+	if (wait_predivsr(channel) != 0) {
+		panic();
+	}
+
+	if (wait_findivsr(channel) != 0) {
+		panic();
+	}
+
+	mmio_clrsetbits_32(rcc_base + RCC_FINDIV0CFGR + (0x4U * channel),
+			   RCC_FINDIV0CFGR_FINDIV0_MASK,
+			   findiv);
+
+	if (wait_findivsr(channel) != 0) {
+		panic();
+	}
+
+	if (wait_xbar_sts(channel) != 0) {
+		panic();
+	}
+
+	mmio_clrsetbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel),
+			   RCC_XBARxCFGR_XBARxSEL_MASK,
+			   clk_src);
+	mmio_setbits_32(rcc_base + RCC_XBAR0CFGR + (0x4U * channel),
+			RCC_XBARxCFGR_XBARxEN);
+
+	if (wait_xbar_sts(channel) != 0) {
+		panic();
+	}
+}
+
+static int stm32mp2_clk_flexgen_configure(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	uint32_t i;
+
+	for (i = 0U; i < pdata->nflexgen; i++) {
+		uint32_t val = pdata->flexgen[i];
+		uint32_t cmd, cmd_data;
+		unsigned int channel, clk_src, pdiv, fdiv;
+
+		cmd = (val & CMD_MASK) >> CMD_SHIFT;
+		cmd_data = val & ~CMD_MASK;
+
+		if (cmd != CMD_FLEXGEN) {
+			continue;
+		}
+
+		channel = (cmd_data & FLEX_ID_MASK) >> FLEX_ID_SHIFT;
+		clk_src = (cmd_data & FLEX_SEL_MASK) >> FLEX_SEL_SHIFT;
+		pdiv = (cmd_data & FLEX_PDIV_MASK) >> FLEX_PDIV_SHIFT;
+		fdiv = (cmd_data & FLEX_FDIV_MASK) >> FLEX_FDIV_SHIFT;
+
+		switch (channel) {
+		case 33U: /* STGEN */
+			break;
+
+		default:
+			flexclkgen_config_channel(channel, clk_src, pdiv, fdiv);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static void stm32_enable_oscillator_hse(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_HSE];
+	bool digbyp =  osci->digbyp;
+	bool bypass = osci->bypass;
+	bool css = osci->css;
+
+	if (_clk_stm32_get_rate(priv, _CK_HSE) == 0U) {
+		return;
+	}
+
+	clk_oscillator_set_bypass(priv, _CK_HSE, digbyp, bypass);
+
+	_clk_stm32_enable(priv, _CK_HSE);
+
+	clk_oscillator_set_css(priv, _CK_HSE, css);
+}
+
+static void stm32_enable_oscillator_lse(struct stm32_clk_priv *priv)
+{
+	struct clk_oscillator_data *osc_data = clk_oscillator_get_data(priv, _CK_LSE);
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_LSE];
+	bool digbyp =  osci->digbyp;
+	bool bypass = osci->bypass;
+	uint8_t drive = osci->drive;
+
+	if (_clk_stm32_get_rate(priv, _CK_LSE) == 0U) {
+		return;
+	}
+
+	/* Do not reconfigure LSE if already enabled */
+	if (_clk_stm32_gate_is_enabled(priv, osc_data->gate_id)) {
+		return;
+	}
+
+	clk_oscillator_set_bypass(priv, _CK_LSE, digbyp, bypass);
+
+	clk_oscillator_set_drive(priv, _CK_LSE, drive);
+
+	_clk_stm32_gate_enable(priv, osc_data->gate_id);
+}
+
+static int stm32mp2_clk_switch_to_hsi(struct stm32_clk_priv *priv)
+{
+	stm32mp2_a35_ss_on_hsi();
+	stm32mp2_clk_muxsel_on_hsi(priv);
+	stm32mp2_clk_xbar_on_hsi(priv);
+
+	return 0;
+}
+
+static int stm32_clk_oscillators_wait_lse_ready(struct stm32_clk_priv *priv)
+{
+	int ret = 0;
+
+	if (_clk_stm32_get_rate(priv, _CK_LSE) != 0U) {
+		ret = clk_oscillator_wait_ready_on(priv, _CK_LSE);
+	}
+
+	return ret;
+}
+
+static void stm32_enable_oscillator_msi(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_osci_dt_cfg *osci = &pdata->osci[OSC_MSI];
+	int err;
+
+	err = clk_stm32_osc_msi_set_rate(priv, _CK_MSI, osci->freq, 0);
+	if (err != 0) {
+		EARLY_ERROR("Invalid rate %lu MHz for MSI ! (4 or 16 only)\n",
+			    osci->freq / 1000000U);
+		panic();
+	}
+
+	_clk_stm32_enable(priv, _CK_MSI);
+}
+
+static void stm32_clk_oscillators_enable(struct stm32_clk_priv *priv)
+{
+	stm32_enable_oscillator_hse(priv);
+	stm32_enable_oscillator_lse(priv);
+	stm32_enable_oscillator_msi(priv);
+	_clk_stm32_enable(priv, _CK_LSI);
+}
+
+static int stm32_clk_configure_div(struct stm32_clk_priv *priv, uint32_t data)
+{
+	int div_id = (data & DIV_ID_MASK) >> DIV_ID_SHIFT;
+	int div_n = (data & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
+
+	return clk_stm32_set_div(priv, div_id, div_n);
+}
+
+static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t data)
+{
+	int mux_id = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
+	int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
+
+	return clk_mux_set_parent(priv, mux_id, sel);
+}
+
+static int stm32_clk_configure_clk_get_binding_id(struct stm32_clk_priv *priv, uint32_t data)
+{
+	unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT;
+
+	return clk_get_index(priv, binding_id);
+}
+
+static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data)
+{
+	int sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
+	bool enable = ((data & CLK_ON_MASK) >> CLK_ON_SHIFT) != 0U;
+	int clk_id = 0;
+	int ret = 0;
+
+	clk_id = stm32_clk_configure_clk_get_binding_id(priv, data);
+	if (clk_id < 0) {
+		return clk_id;
+	}
+
+	if (sel != CLK_NOMUX) {
+		ret = _clk_stm32_set_parent_by_index(priv, clk_id, sel);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	if (enable) {
+		clk_stm32_enable_call_ops(priv, clk_id);
+	} else {
+		clk_stm32_disable_call_ops(priv, clk_id);
+	}
+
+	return 0;
+}
+
+static int stm32_clk_configure(struct stm32_clk_priv *priv, uint32_t val)
+{
+	uint32_t cmd = (val & CMD_MASK) >> CMD_SHIFT;
+	uint32_t cmd_data = val & ~CMD_MASK;
+	int ret = -1;
+
+	switch (cmd) {
+	case CMD_DIV:
+		ret = stm32_clk_configure_div(priv, cmd_data);
+		break;
+
+	case CMD_MUX:
+		ret = stm32_clk_configure_mux(priv, cmd_data);
+		break;
+
+	case CMD_CLK:
+		ret = stm32_clk_configure_clk(priv, cmd_data);
+		break;
+
+	default:
+		EARLY_ERROR("%s: cmd unknown ! : 0x%x\n", __func__, val);
+		break;
+	}
+
+	return ret;
+}
+
+static int stm32_clk_bus_configure(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	uint32_t i;
+
+	for (i = 0; i < pdata->nbusclk; i++) {
+		int ret;
+
+		ret = stm32_clk_configure(priv, pdata->busclk[i]);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_kernel_configure(struct stm32_clk_priv *priv)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	uint32_t i;
+
+	for (i = 0U; i < pdata->nkernelclk; i++) {
+		int ret;
+
+		ret = stm32_clk_configure(priv, pdata->kernelclk[i]);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32mp2_init_clock_tree(void)
+{
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	int ret;
+
+	/* Set timer with STGEN without changing its clock source */
+	stm32mp_stgen_restore_rate();
+	generic_delay_timer_init();
+
+	stm32_clk_oscillators_enable(priv);
+
+	/* Come back to HSI */
+	ret = stm32mp2_clk_switch_to_hsi(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = stm32mp2_clk_pll_configure(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	/* Wait LSE ready before to use it */
+	ret = stm32_clk_oscillators_wait_lse_ready(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = stm32mp2_clk_flexgen_configure(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = stm32_clk_bus_configure(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	ret = stm32_clk_kernel_configure(priv);
+	if (ret != 0) {
+		panic();
+	}
+
+	return 0;
+}
+
+static int clk_stm32_parse_oscillator_fdt(void *fdt, int node, const char *name,
+					  struct stm32_osci_dt_cfg *osci)
+{
+	int subnode = 0;
+
+	/* Default value oscillator not found, freq=0 */
+	osci->freq = 0;
+
+	fdt_for_each_subnode(subnode, fdt, node) {
+		const char *cchar = NULL;
+		const fdt32_t *cuint = NULL;
+		int ret = 0;
+
+		cchar = fdt_get_name(fdt, subnode, &ret);
+		if (cchar == NULL) {
+			return ret;
+		}
+
+		if (strncmp(cchar, name, (size_t)ret) ||
+		    fdt_get_status(subnode) == DT_DISABLED) {
+			continue;
+		}
+
+		cuint = fdt_getprop(fdt, subnode, "clock-frequency", &ret);
+		if (cuint == NULL) {
+			return ret;
+		}
+
+		osci->freq = fdt32_to_cpu(*cuint);
+
+		if (fdt_getprop(fdt, subnode, "st,bypass", NULL) != NULL) {
+			osci->bypass = true;
+		}
+
+		if (fdt_getprop(fdt, subnode, "st,digbypass", NULL) != NULL) {
+			osci->digbyp = true;
+		}
+
+		if (fdt_getprop(fdt, subnode, "st,css", NULL) != NULL) {
+			osci->css = true;
+		}
+
+		osci->drive = fdt_read_uint32_default(fdt, subnode, "st,drive", LSEDRV_MEDIUM_HIGH);
+
+		return 0;
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt_all_oscillator(void *fdt, struct stm32_clk_platdata *pdata)
+{
+	int fdt_err = 0;
+	uint32_t i = 0;
+	int node = 0;
+
+	node = fdt_path_offset(fdt, "/clocks");
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	for (i = 0; i < pdata->nosci; i++) {
+		const char *name = NULL;
+
+		name = clk_stm32_get_oscillator_name((enum stm32_osc)i);
+		if (name == NULL) {
+			continue;
+		}
+
+		fdt_err = clk_stm32_parse_oscillator_fdt(fdt, node, name, &pdata->osci[i]);
+		if (fdt_err < 0) {
+			panic();
+		}
+	}
+
+	return 0;
+}
+
+static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	const fdt32_t *cuint = NULL;
+	int subnode_pll = 0;
+	uint32_t val = 0;
+	int err = 0;
+
+	cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
+	if (!cuint) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+	if (subnode_pll < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	err = fdt_read_uint32_array(fdt, subnode_pll, "cfg", (int)PLLCFG_NB, pll->cfg);
+	if (err != 0) {
+		return err;
+	}
+
+	err = fdt_read_uint32_array(fdt, subnode_pll, "csg", (int)PLLCSG_NB, pll->csg);
+
+	pll->csg_enabled = (err == 0);
+
+	if (err == -FDT_ERR_NOTFOUND) {
+		err = 0;
+	}
+
+	if (err != 0) {
+		return err;
+	}
+
+	pll->enabled = true;
+
+	pll->frac = fdt_read_uint32_default(fdt, subnode_pll, "frac", 0);
+
+	pll->src = UINT32_MAX;
+
+	err = fdt_read_uint32(fdt, subnode_pll, "src", &val);
+	if  (err == 0) {
+		pll->src = val;
+	}
+
+	return 0;
+}
+
+#define RCC_PLL_NAME_SIZE 12
+
+static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata)
+{
+	unsigned int i = 0;
+
+	for (i = _PLL1; i < pdata->npll; i++) {
+		struct stm32_pll_dt_cfg *pll = pdata->pll + i;
+		char name[RCC_PLL_NAME_SIZE];
+		int subnode = 0;
+		int err = 0;
+
+		snprintf(name, sizeof(name), "st,pll-%u", i + 1);
+
+		subnode = fdt_subnode_offset(fdt, node, name);
+		if (!fdt_check_node(subnode)) {
+			continue;
+		}
+
+		err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
+		if (err != 0) {
+			panic();
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
+{
+	void *fdt = NULL;
+	int node;
+	int err;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	if (node < 0) {
+		panic();
+	}
+
+	err = stm32_clk_parse_fdt_all_oscillator(fdt, pdata);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,busclk", pdata->busclk, &pdata->nbusclk);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,flexgen", pdata->flexgen,
+					  &pdata->nflexgen);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,kerclk", pdata->kernelclk,
+					  &pdata->nkernelclk);
+	if (err != 0) {
+		return err;
+	}
+
+	return 0;
+}
+#endif /* IMAGE_BL2 */
+
+static struct stm32_osci_dt_cfg mp25_osci[NB_OSCILLATOR];
+
+static struct stm32_pll_dt_cfg mp25_pll[_PLL_NB];
+
+#define DT_FLEXGEN_CLK_MAX	64
+static uint32_t mp25_flexgen[DT_FLEXGEN_CLK_MAX];
+
+#define DT_BUS_CLK_MAX		6
+static uint32_t mp25_busclk[DT_BUS_CLK_MAX];
+
+#define DT_KERNEL_CLK_MAX	20
+static uint32_t mp25_kernelclk[DT_KERNEL_CLK_MAX];
+
+static struct stm32_clk_platdata stm32mp25_pdata = {
+	.osci = mp25_osci,
+	.nosci = NB_OSCILLATOR,
+	.pll = mp25_pll,
+	.npll = _PLL_NB,
+	.flexgen = mp25_flexgen,
+	.nflexgen = DT_FLEXGEN_CLK_MAX,
+	.busclk	= mp25_busclk,
+	.nbusclk = DT_BUS_CLK_MAX,
+	.kernelclk = mp25_kernelclk,
+	.nkernelclk = DT_KERNEL_CLK_MAX,
+};
+
+static uint8_t refcounts_mp25[CK_LAST];
+
+static struct stm32_clk_priv stm32mp25_clock_data = {
+	.base		= RCC_BASE,
+	.num		= ARRAY_SIZE(stm32mp25_clk),
+	.clks		= stm32mp25_clk,
+	.parents	= parent_mp25,
+	.nb_parents	= ARRAY_SIZE(parent_mp25),
+	.gates		= gates_mp25,
+	.nb_gates	= ARRAY_SIZE(gates_mp25),
+	.div		= dividers_mp25,
+	.nb_div		= ARRAY_SIZE(dividers_mp25),
+	.osci_data	= stm32mp25_osc_data,
+	.nb_osci_data	= ARRAY_SIZE(stm32mp25_osc_data),
+	.gate_refcounts	= refcounts_mp25,
+	.pdata		= &stm32mp25_pdata,
+	.ops_array	= ops_array_mp25,
+};
+
+int stm32mp2_clk_init(void)
+{
+	uintptr_t base = RCC_BASE;
+	int ret;
+
+#ifdef IMAGE_BL2
+	ret = stm32_clk_parse_fdt(&stm32mp25_pdata);
+	if (ret != 0) {
+		return ret;
+	}
+#endif
+
+	ret = clk_stm32_init(&stm32mp25_clock_data, base);
+	if (ret != 0) {
+		return ret;
+	}
+
+#ifdef IMAGE_BL2
+	ret = stm32mp2_init_clock_tree();
+	if (ret != 0) {
+		return ret;
+	}
+
+	clk_stm32_enable_critical_clocks();
+#endif
+
+	return 0;
+}
+
+int stm32mp2_pll1_disable(void)
+{
+#ifdef IMAGE_BL2
+	return -EPERM;
+#else
+	uintptr_t a35_ss_address = A35SSC_BASE;
+	uintptr_t pll_enable_reg = a35_ss_address + A35_SS_PLL_ENABLE;
+
+	stm32mp2_a35_ss_on_hsi();
+
+	mmio_clrbits_32(pll_enable_reg, A35_SS_PLL_ENABLE_PD);
+
+	return 0;
+#endif
+}
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index c9c3c5f9..3d352afb 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -27,6 +27,71 @@
 
 #include <platform_def.h>
 
+enum stm32mp1_pllcfg {
+	PLLCFG_M,
+	PLLCFG_N,
+	PLL_DIV_MN_NB,
+	PLLCFG_P = PLL_DIV_MN_NB,
+	PLLCFG_Q,
+	PLLCFG_R,
+	PLLCFG_O,
+	PLLCFG_NB
+};
+
+#define PLL_DIV_MN_NB	2
+#define PLL_DIV_PQR_NB	3
+
+enum stm32mp1_pllcsg {
+	PLLCSG_MOD_PER,
+	PLLCSG_INC_STEP,
+	PLLCSG_SSCG_MODE,
+	PLLCSG_NB
+};
+
+struct stm32_pll_dt_cfg {
+	bool status;
+	uint32_t src;
+	uint32_t cfg[PLLCFG_NB];
+	uint32_t frac;
+	bool csg_enabled;
+	uint32_t csg[PLLCSG_NB];
+};
+
+struct stm32_clk_platdata {
+	uint32_t npll;
+	struct stm32_pll_dt_cfg *pll;
+	uint32_t nclksrc;
+	uint32_t *clksrc;
+	uint32_t nclkdiv;
+	uint32_t *clkdiv;
+	bool lse_css;
+};
+
+struct stm32_clk_priv {
+	uintptr_t base;
+	const struct mux_cfg *parents;
+	const uint32_t nb_parents;
+	const struct div_cfg *div;
+	const uint32_t nb_div;
+	void *pdata;
+};
+
+static struct stm32_clk_priv *stm32_clock_data;
+
+static struct stm32_clk_priv *clk_stm32_get_priv(void)
+{
+	return stm32_clock_data;
+}
+
+static int clk_stm32_init(struct stm32_clk_priv *priv, uintptr_t base)
+{
+	stm32_clock_data = priv;
+
+	priv->base = base;
+
+	return 0;
+}
+
 #define MAX_HSI_HZ		64000000
 #define USB_PHY_48_MHZ		48000000
 
@@ -39,6 +104,199 @@
 #define HSIDIV_TIMEOUT		TIMEOUT_US_200MS
 #define OSCRDY_TIMEOUT		TIMEOUT_US_1S
 
+struct mux_cfg {
+	uint16_t offset;
+	uint8_t shift;
+	uint8_t width;
+	uint8_t bitrdy;
+};
+
+struct div_cfg {
+	uint16_t offset;
+	uint8_t shift;
+	uint8_t width;
+	uint8_t bitrdy;
+};
+
+#define DIV_NO_BIT_RDY UINT8_MAX
+
+#define DIV_CFG(_id, _offset, _shift, _width,  _bitrdy)\
+	[(_id)] = {\
+		.offset	= (_offset),\
+		.shift	= (_shift),\
+		.width	= (_width),\
+		.bitrdy	= (_bitrdy),\
+	}
+
+static const struct div_cfg dividers_mp15[] = {
+	DIV_CFG(DIV_MPU, RCC_MPCKDIVR, 0, 4, 31),
+	DIV_CFG(DIV_AXI, RCC_AXIDIVR, 0, 3, 31),
+	DIV_CFG(DIV_MCU, RCC_MCUDIVR, 0, 4, 31),
+	DIV_CFG(DIV_APB1, RCC_APB1DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB2, RCC_APB2DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB3, RCC_APB3DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB4, RCC_APB4DIVR, 0, 3, 31),
+	DIV_CFG(DIV_APB5, RCC_APB5DIVR, 0, 3, 31),
+	DIV_CFG(DIV_RTC, RCC_RTCDIVR, 0, 6, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_MCO2, RCC_MCO2CFGR, 4, 4, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_TRACE, RCC_DBGCFGR, 0, 3, DIV_NO_BIT_RDY),
+	DIV_CFG(DIV_ETHPTP, RCC_ETHCKSELR, 4, 4, DIV_NO_BIT_RDY),
+};
+
+/*
+ * MUX CONFIG
+ */
+
+#define MUX_NO_BIT_RDY		UINT8_MAX
+
+#define MUXRDY_CFG(_id, _offset, _shift, _width,  _bitrdy)\
+	[(_id)] = {\
+		.offset	= (_offset),\
+		.shift	= (_shift),\
+		.width	= (_width),\
+		.bitrdy = (_bitrdy),\
+	}
+
+#define MUX_CFG(_id, _offset, _shift, _width)\
+	MUXRDY_CFG(_id, _offset, _shift, _width,  MUX_NO_BIT_RDY)
+
+static const struct mux_cfg parent_mp15[MUX_NB] = {
+	MUX_CFG(MUX_PLL12,	RCC_RCK12SELR, 0, 2),
+	MUX_CFG(MUX_PLL3,	RCC_RCK3SELR, 0, 2),
+	MUX_CFG(MUX_PLL4,	RCC_RCK4SELR, 0, 2),
+	MUX_CFG(MUX_CKPER,	RCC_CPERCKSELR, 0, 2),
+	MUXRDY_CFG(MUX_MPU,	RCC_MPCKSELR, 0, 2, 31),
+	MUXRDY_CFG(MUX_AXI,	RCC_ASSCKSELR, 0, 3, 31),
+	MUXRDY_CFG(MUX_MCU,	RCC_MSSCKSELR, 0, 2, 31),
+	MUX_CFG(MUX_RTC,	RCC_BDCR, 16, 2),
+	MUX_CFG(MUX_SDMMC12,	RCC_SDMMC12CKSELR, 0, 3),
+	MUX_CFG(MUX_SPI2S23,	RCC_SPI2S23CKSELR, 0, 3),
+	MUX_CFG(MUX_SPI45,	RCC_SPI45CKSELR, 0, 3),
+	MUX_CFG(MUX_I2C12,	RCC_I2C12CKSELR, 0, 3),
+	MUX_CFG(MUX_I2C35,	RCC_I2C35CKSELR, 0, 3),
+	MUX_CFG(MUX_LPTIM23,	RCC_LPTIM23CKSELR, 0, 3),
+	MUX_CFG(MUX_LPTIM45,	RCC_LPTIM45CKSELR, 0, 3),
+	MUX_CFG(MUX_UART24,	RCC_UART24CKSELR, 0, 3),
+	MUX_CFG(MUX_UART35,	RCC_UART35CKSELR, 0, 3),
+	MUX_CFG(MUX_UART78,	RCC_UART78CKSELR, 0, 3),
+	MUX_CFG(MUX_SAI1,	RCC_SAI1CKSELR, 0, 3),
+	MUX_CFG(MUX_ETH,	RCC_ETHCKSELR, 0, 2),
+	MUX_CFG(MUX_I2C46,	RCC_I2C46CKSELR, 0, 3),
+	MUX_CFG(MUX_RNG2,	RCC_RNG2CKSELR, 0, 2),
+	MUX_CFG(MUX_SDMMC3,	RCC_SDMMC3CKSELR, 0, 3),
+	MUX_CFG(MUX_FMC,	RCC_FMCCKSELR, 0, 2),
+	MUX_CFG(MUX_QSPI,	RCC_QSPICKSELR, 0, 2),
+	MUX_CFG(MUX_USBPHY,	RCC_USBCKSELR, 0, 2),
+	MUX_CFG(MUX_USBO,	RCC_USBCKSELR, 4, 1),
+	MUX_CFG(MUX_SPDIF,	RCC_SPDIFCKSELR, 0, 2),
+	MUX_CFG(MUX_SPI2S1,	RCC_SPI2S1CKSELR, 0, 3),
+	MUX_CFG(MUX_CEC,	RCC_CECCKSELR, 0, 2),
+	MUX_CFG(MUX_LPTIM1,	RCC_LPTIM1CKSELR, 0, 3),
+	MUX_CFG(MUX_UART6,	RCC_UART6CKSELR, 0, 3),
+	MUX_CFG(MUX_FDCAN,	RCC_FDCANCKSELR, 0, 2),
+	MUX_CFG(MUX_SAI2,	RCC_SAI2CKSELR, 0, 3),
+	MUX_CFG(MUX_SAI3,	RCC_SAI3CKSELR, 0, 3),
+	MUX_CFG(MUX_SAI4,	RCC_SAI4CKSELR, 0, 3),
+	MUX_CFG(MUX_ADC,	RCC_ADCCKSELR, 0, 2),
+	MUX_CFG(MUX_DSI,	RCC_DSICKSELR, 0, 1),
+	MUX_CFG(MUX_RNG1,	RCC_RNG1CKSELR, 0, 2),
+	MUX_CFG(MUX_STGEN,	RCC_STGENCKSELR, 0, 2),
+	MUX_CFG(MUX_UART1,	RCC_UART1CKSELR, 0, 3),
+	MUX_CFG(MUX_SPI6,	RCC_SPI6CKSELR, 0, 3),
+	MUX_CFG(MUX_MCO1,	RCC_MCO1CFGR, 0, 3),
+	MUX_CFG(MUX_MCO2,	RCC_MCO2CFGR, 0, 3),
+};
+
+#define MASK_WIDTH_SHIFT(_width, _shift) \
+	GENMASK(((_width) + (_shift) - 1U), (_shift))
+
+int clk_mux_get_parent(struct stm32_clk_priv *priv, uint32_t mux_id)
+{
+	const struct mux_cfg *mux;
+	uint32_t mask;
+
+	if (mux_id >= priv->nb_parents) {
+		panic();
+	}
+
+	mux = &priv->parents[mux_id];
+
+	mask = MASK_WIDTH_SHIFT(mux->width, mux->shift);
+
+	return (mmio_read_32(priv->base + mux->offset) & mask) >> mux->shift;
+}
+
+static int clk_mux_set_parent(struct stm32_clk_priv *priv, uint16_t pid, uint8_t sel)
+{
+	const struct mux_cfg *mux = &priv->parents[pid];
+	uintptr_t address = priv->base + mux->offset;
+	uint32_t mask;
+	uint64_t timeout;
+
+	mask = MASK_WIDTH_SHIFT(mux->width, mux->shift);
+
+	mmio_clrsetbits_32(address, mask, (sel << mux->shift) & mask);
+
+	if (mux->bitrdy == MUX_NO_BIT_RDY) {
+		return 0;
+	}
+
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+
+	mask = BIT(mux->bitrdy);
+
+	while ((mmio_read_32(address) & mask) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_configure_mux(struct stm32_clk_priv *priv, uint32_t val)
+{
+	uint32_t data = val & CMD_DATA_MASK;
+	int mux = (data & MUX_ID_MASK) >> MUX_ID_SHIFT;
+	int sel = (data & MUX_SEL_MASK) >> MUX_SEL_SHIFT;
+
+	return clk_mux_set_parent(priv, mux, sel);
+}
+
+int clk_stm32_set_div(struct stm32_clk_priv *priv, uint32_t div_id, uint32_t value)
+{
+	const struct div_cfg *divider;
+	uintptr_t address;
+	uint64_t timeout;
+	uint32_t mask;
+
+	if (div_id >= priv->nb_div) {
+		panic();
+	}
+
+	divider = &priv->div[div_id];
+	address = priv->base + divider->offset;
+
+	mask = MASK_WIDTH_SHIFT(divider->width, divider->shift);
+	mmio_clrsetbits_32(address, mask, (value << divider->shift) & mask);
+
+	if (divider->bitrdy == DIV_NO_BIT_RDY) {
+		return 0;
+	}
+
+	timeout = timeout_init_us(CLKSRC_TIMEOUT);
+	mask = BIT(divider->bitrdy);
+
+	while ((mmio_read_32(address) & mask) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
 const char *stm32mp_osc_node_label[NB_OSC] = {
 	[_LSI] = "clk-lsi",
 	[_LSE] = "clk-lse",
@@ -206,23 +464,6 @@ enum stm32mp1_clkdiv_id {
 	CLKDIV_NB
 };
 
-enum stm32mp1_pllcfg {
-	PLLCFG_M,
-	PLLCFG_N,
-	PLLCFG_P,
-	PLLCFG_Q,
-	PLLCFG_R,
-	PLLCFG_O,
-	PLLCFG_NB
-};
-
-enum stm32mp1_pllcsg {
-	PLLCSG_MOD_PER,
-	PLLCSG_INC_STEP,
-	PLLCSG_SSCG_MODE,
-	PLLCSG_NB
-};
-
 enum stm32mp1_plltype {
 	PLL_800,
 	PLL_1600,
@@ -537,7 +778,18 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
 };
 
 /* Define characteristic of PLL according type */
-#define DIVN_MIN	24
+#define POST_DIVM_MIN	8000000U
+#define POST_DIVM_MAX	16000000U
+#define DIVM_MIN	0U
+#define DIVM_MAX	63U
+#define DIVN_MIN	24U
+#define DIVN_MAX	99U
+#define DIVP_MIN	0U
+#define DIVP_MAX	127U
+#define FRAC_MAX	8192U
+#define VCO_MIN		800000000U
+#define VCO_MAX		1600000000U
+
 static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
 	[PLL_800] = {
 		.refclk_min = 4,
@@ -1327,6 +1579,11 @@ static void stm32mp1_lse_enable(bool bypass, bool digbyp, uint32_t lsedrv)
 	uint32_t value;
 	uintptr_t rcc_base = stm32mp_rcc_base();
 
+	/* Do not reconfigure LSE if it is already ON */
+	if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_LSEON) == RCC_BDCR_LSEON) {
+		return;
+	}
+
 	if (digbyp) {
 		mmio_setbits_32(rcc_base + RCC_BDCR, RCC_BDCR_DIGBYP);
 	}
@@ -1360,7 +1617,7 @@ static void stm32mp1_lse_enable(bool bypass, bool digbyp, uint32_t lsedrv)
 static void stm32mp1_lse_wait(void)
 {
 	if (stm32mp1_osc_wait(true, RCC_BDCR, RCC_BDCR_LSERDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1369,7 +1626,7 @@ static void stm32mp1_lsi_set(bool enable)
 	stm32mp1_ls_osc_set(enable, RCC_RDLSICR, RCC_RDLSICR_LSION);
 
 	if (stm32mp1_osc_wait(enable, RCC_RDLSICR, RCC_RDLSICR_LSIRDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1387,7 +1644,7 @@ static void stm32mp1_hse_enable(bool bypass, bool digbyp, bool css)
 
 	stm32mp1_hs_ocs_set(true, RCC_OCENR_HSEON);
 	if (stm32mp1_osc_wait(true, RCC_OCRDYR, RCC_OCRDYR_HSERDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 
 	if (css) {
@@ -1406,7 +1663,7 @@ static void stm32mp1_csi_set(bool enable)
 {
 	stm32mp1_hs_ocs_set(enable, RCC_OCENR_CSION);
 	if (stm32mp1_osc_wait(enable, RCC_OCRDYR, RCC_OCRDYR_CSIRDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1414,7 +1671,7 @@ static void stm32mp1_hsi_set(bool enable)
 {
 	stm32mp1_hs_ocs_set(enable, RCC_OCENR_HSION);
 	if (stm32mp1_osc_wait(enable, RCC_OCRDYR, RCC_OCRDYR_HSIRDY) != 0) {
-		VERBOSE("%s: failed\n", __func__);
+		EARLY_ERROR("%s: failed\n", __func__);
 	}
 }
 
@@ -1454,7 +1711,7 @@ static int stm32mp1_hsidiv(unsigned long hsifreq)
 	}
 
 	if (hsidiv == 4U) {
-		ERROR("Invalid clk-hsi frequency\n");
+		EARLY_ERROR("Invalid clk-hsi frequency\n");
 		return -1;
 	}
 
@@ -1467,7 +1724,7 @@ static int stm32mp1_hsidiv(unsigned long hsifreq)
 
 static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id,
 				    unsigned int clksrc,
-				    uint32_t *pllcfg, int plloff)
+				    uint32_t *pllcfg, uint32_t fracv)
 {
 	const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
 	uintptr_t rcc_base = stm32mp_rcc_base();
@@ -1476,8 +1733,7 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id,
 	uintptr_t clksrc_address = rcc_base + (clksrc >> 4);
 	unsigned long refclk;
 	uint32_t ifrge = 0U;
-	uint32_t src, value, fracv = 0;
-	void *fdt;
+	uint32_t src, value;
 
 	/* Check PLL output */
 	if (mmio_read_32(pllxcr) != RCC_PLLNCR_PLLON) {
@@ -1516,10 +1772,6 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id,
 	}
 
 	/* Fractional configuration */
-	if (fdt_get_address(&fdt) == 1) {
-		fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0);
-	}
-
 	value = fracv << RCC_PLLNFRACR_FRACV_SHIFT;
 	value |= RCC_PLLNFRACR_FRACLE;
 	if (mmio_read_32(rcc_base + pll->pllxfracr) != value) {
@@ -1561,8 +1813,8 @@ static int stm32mp1_pll_output(enum stm32mp1_pll_id pll_id, uint32_t output)
 	/* Wait PLL lock */
 	while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) == 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("PLL%u start failed @ 0x%lx: 0x%x\n",
-			      pll_id, pllxcr, mmio_read_32(pllxcr));
+			EARLY_ERROR("PLL%u start failed @ 0x%lx: 0x%x\n",
+				    pll_id, pllxcr, mmio_read_32(pllxcr));
 			return -ETIMEDOUT;
 		}
 	}
@@ -1590,8 +1842,8 @@ static int stm32mp1_pll_stop(enum stm32mp1_pll_id pll_id)
 	/* Wait PLL stopped */
 	while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) != 0U) {
 		if (timeout_elapsed(timeout)) {
-			ERROR("PLL%u stop failed @ 0x%lx: 0x%x\n",
-			      pll_id, pllxcr, mmio_read_32(pllxcr));
+			EARLY_ERROR("PLL%u stop failed @ 0x%lx: 0x%x\n",
+				    pll_id, pllxcr, mmio_read_32(pllxcr));
 			return -ETIMEDOUT;
 		}
 	}
@@ -1683,190 +1935,270 @@ static void stm32mp1_pll_csg(enum stm32mp1_pll_id pll_id, uint32_t *csg)
 			RCC_PLLNCR_SSCG_CTRL);
 }
 
-static int stm32mp1_set_clksrc(unsigned int clksrc)
+static int clk_compute_pll1_settings(unsigned long input_freq,
+				     uint32_t freq_khz,
+				     uint32_t *pllcfg, uint32_t *fracv)
 {
-	uintptr_t clksrc_address = stm32mp_rcc_base() + (clksrc >> 4);
-	uint64_t timeout;
+	unsigned long long best_diff = ULLONG_MAX;
+	unsigned int divm;
 
-	mmio_clrsetbits_32(clksrc_address, RCC_SELR_SRC_MASK,
-			   clksrc & RCC_SELR_SRC_MASK);
+	/* Following parameters have always the same value */
+	pllcfg[PLLCFG_Q] = 0U;
+	pllcfg[PLLCFG_R] = 0U;
+	pllcfg[PLLCFG_O] = PQR(1, 0, 0);
 
-	timeout = timeout_init_us(CLKSRC_TIMEOUT);
-	while ((mmio_read_32(clksrc_address) & RCC_SELR_SRCRDY) == 0U) {
-		if (timeout_elapsed(timeout)) {
-			ERROR("CLKSRC %x start failed @ 0x%lx: 0x%x\n", clksrc,
-			      clksrc_address, mmio_read_32(clksrc_address));
-			return -ETIMEDOUT;
+	for (divm = (DIVM_MAX + 1U); divm != DIVM_MIN; divm--) {
+		unsigned long post_divm = input_freq / divm;
+		unsigned int divp;
+
+		if ((post_divm < POST_DIVM_MIN) || (post_divm > POST_DIVM_MAX)) {
+			continue;
 		}
-	}
 
-	return 0;
-}
+		for (divp = DIVP_MIN; divp <= DIVP_MAX; divp++) {
+			unsigned long long output_freq = freq_khz * 1000ULL;
+			unsigned long long freq;
+			unsigned long long divn;
+			unsigned long long frac;
+			unsigned int i;
 
-static int stm32mp1_set_clkdiv(unsigned int clkdiv, uintptr_t address)
-{
-	uint64_t timeout;
+			freq = output_freq * divm * (divp + 1U);
 
-	mmio_clrsetbits_32(address, RCC_DIVR_DIV_MASK,
-			   clkdiv & RCC_DIVR_DIV_MASK);
+			divn = (freq / input_freq) - 1U;
+			if ((divn < DIVN_MIN) || (divn > DIVN_MAX)) {
+				continue;
+			}
 
-	timeout = timeout_init_us(CLKDIV_TIMEOUT);
-	while ((mmio_read_32(address) & RCC_DIVR_DIVRDY) == 0U) {
-		if (timeout_elapsed(timeout)) {
-			ERROR("CLKDIV %x start failed @ 0x%lx: 0x%x\n",
-			      clkdiv, address, mmio_read_32(address));
-			return -ETIMEDOUT;
+			frac = ((freq * FRAC_MAX) / input_freq) - ((divn + 1U) * FRAC_MAX);
+
+			/* 2 loops to refine the fractional part */
+			for (i = 2U; i != 0U; i--) {
+				unsigned long long diff;
+				unsigned long long vco;
+
+				if (frac > FRAC_MAX) {
+					break;
+				}
+
+				vco = (post_divm * (divn + 1U)) + ((post_divm * frac) / FRAC_MAX);
+
+				if ((vco < (VCO_MIN / 2U)) || (vco > (VCO_MAX / 2U))) {
+					frac++;
+					continue;
+				}
+
+				freq = vco / (divp + 1U);
+				if (output_freq < freq) {
+					diff = freq - output_freq;
+				} else {
+					diff = output_freq - freq;
+				}
+
+				if (diff < best_diff)  {
+					pllcfg[PLLCFG_M] = divm - 1U;
+					pllcfg[PLLCFG_N] = (uint32_t)divn;
+					pllcfg[PLLCFG_P] = divp;
+					*fracv = (uint32_t)frac;
+
+					if (diff == 0U) {
+						return 0;
+					}
+
+					best_diff = diff;
+				}
+
+				frac++;
+			}
 		}
 	}
 
+	if (best_diff == ULLONG_MAX) {
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
-static void stm32mp1_mco_csg(uint32_t clksrc, uint32_t clkdiv)
+static int clk_get_pll1_settings(uint32_t clksrc, uint32_t freq_khz,
+				 uint32_t *pllcfg, uint32_t *fracv)
 {
-	uintptr_t clksrc_address = stm32mp_rcc_base() + (clksrc >> 4);
+	unsigned long input_freq = 0UL;
 
-	/*
-	 * Binding clksrc :
-	 *      bit15-4 offset
-	 *      bit3:   disable
-	 *      bit2-0: MCOSEL[2:0]
-	 */
-	if ((clksrc & 0x8U) != 0U) {
-		mmio_clrbits_32(clksrc_address, RCC_MCOCFG_MCOON);
-	} else {
-		mmio_clrsetbits_32(clksrc_address,
-				   RCC_MCOCFG_MCOSRC_MASK,
-				   clksrc & RCC_MCOCFG_MCOSRC_MASK);
-		mmio_clrsetbits_32(clksrc_address,
-				   RCC_MCOCFG_MCODIV_MASK,
-				   clkdiv << RCC_MCOCFG_MCODIV_SHIFT);
-		mmio_setbits_32(clksrc_address, RCC_MCOCFG_MCOON);
+	assert(pllcfg != NULL);
+	assert(fracv != NULL);
+
+	switch (clksrc) {
+	case CLK_PLL12_HSI:
+		input_freq = stm32mp_clk_get_rate(CK_HSI);
+		break;
+	case CLK_PLL12_HSE:
+		input_freq = stm32mp_clk_get_rate(CK_HSE);
+		break;
+	default:
+		break;
 	}
+
+	if (input_freq == 0UL) {
+		panic();
+	}
+
+	return clk_compute_pll1_settings(input_freq, freq_khz, pllcfg, fracv);
 }
 
-static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css)
+static int stm32_clk_dividers_configure(struct stm32_clk_priv *priv)
 {
-	uintptr_t address = stm32mp_rcc_base() + RCC_BDCR;
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	uint32_t i;
+
+	for (i = 0U; i < pdata->nclkdiv; i++) {
+		uint32_t div_id, div_n;
+		uint32_t val;
+		int ret;
 
-	if (((mmio_read_32(address) & RCC_BDCR_RTCCKEN) == 0U) ||
-	    (clksrc != (uint32_t)CLK_RTC_DISABLED)) {
-		mmio_clrsetbits_32(address,
-				   RCC_BDCR_RTCSRC_MASK,
-				   (clksrc & RCC_SELR_SRC_MASK) << RCC_BDCR_RTCSRC_SHIFT);
+		val = pdata->clkdiv[i] & CMD_DATA_MASK;
+		div_id = (val & DIV_ID_MASK) >> DIV_ID_SHIFT;
+		div_n = (val & DIV_DIVN_MASK) >> DIV_DIVN_SHIFT;
 
-		mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
+		ret = clk_stm32_set_div(priv, div_id, div_n);
+		if (ret != 0) {
+			return ret;
+		}
 	}
 
-	if (lse_css) {
-		mmio_setbits_32(address, RCC_BDCR_LSECSSON);
+	return 0;
+}
+
+static int stm32_clk_configure_clk(struct stm32_clk_priv *priv, uint32_t data)
+{
+	uint32_t sel = (data & CLK_SEL_MASK) >> CLK_SEL_SHIFT;
+	uint32_t enable = (data & CLK_ON_MASK) >> CLK_ON_SHIFT;
+	unsigned long binding_id = ((unsigned long)data & CLK_ID_MASK) >> CLK_ID_SHIFT;
+	struct stm32_clk_platdata *pdata = priv->pdata;
+
+	if (binding_id == RTC) {
+		uintptr_t address = stm32mp_rcc_base() + RCC_BDCR;
+
+		if (((mmio_read_32(address) & RCC_BDCR_RTCCKEN) == 0U) || (enable != 0U)) {
+			mmio_clrsetbits_32(address, RCC_BDCR_RTCSRC_MASK,
+					   (sel & RCC_SELR_SRC_MASK) << RCC_BDCR_RTCSRC_SHIFT);
+
+			mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
+			/* Configure LSE CSS */
+			if (pdata->lse_css) {
+				mmio_setbits_32(priv->base + RCC_BDCR, RCC_BDCR_LSECSSON);
+			}
+		}
 	}
+
+	return 0;
 }
 
-static void stm32mp1_pkcs_config(uint32_t pkcs)
+static int stm32_clk_configure_by_addr_val(struct stm32_clk_priv *priv,
+					   uint32_t data)
 {
-	uintptr_t address = stm32mp_rcc_base() + ((pkcs >> 4) & 0xFFFU);
-	uint32_t value = pkcs & 0xFU;
-	uint32_t mask = 0xFU;
+	uint32_t addr = data >> CLK_ADDR_SHIFT;
+	uint32_t val = data & CLK_ADDR_VAL_MASK;
 
-	if ((pkcs & BIT(31)) != 0U) {
-		mask <<= 4;
-		value <<= 4;
-	}
+	mmio_setbits_32(priv->base + addr, val);
 
-	mmio_clrsetbits_32(address, mask, value);
+	return 0;
 }
 
-static int clk_get_pll_settings_from_dt(int plloff, unsigned int *pllcfg,
-					uint32_t *fracv, uint32_t *csg,
-					bool *csg_set)
+static int stm32_clk_source_configure(struct stm32_clk_priv *priv)
 {
-	void *fdt;
-	int ret;
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	bool ckper_disabled = false;
+	uint32_t i;
+
+	for (i = 0U; i < pdata->nclksrc; i++) {
+		uint32_t val = pdata->clksrc[i];
+		uint32_t cmd, cmd_data;
+		int ret;
+
+		if (val & CMD_ADDR_BIT) {
+			ret = stm32_clk_configure_by_addr_val(priv, val & ~CMD_ADDR_BIT);
+			if (ret != 0) {
+				return ret;
+			}
 
-	if (fdt_get_address(&fdt) == 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
+			continue;
+		}
 
-	ret = fdt_read_uint32_array(fdt, plloff, "cfg", (uint32_t)PLLCFG_NB,
-				    pllcfg);
-	if (ret < 0) {
-		return -FDT_ERR_NOTFOUND;
+		if (val == (uint32_t)CLK_CKPER_DISABLED) {
+			ckper_disabled = true;
+			continue;
+		}
+
+		cmd = (val & CMD_MASK) >> CMD_SHIFT;
+		cmd_data = val & ~CMD_MASK;
+
+		switch (cmd) {
+		case CMD_MUX:
+			ret = stm32_clk_configure_mux(priv, cmd_data);
+			break;
+
+		case CMD_CLK:
+			ret = stm32_clk_configure_clk(priv, cmd_data);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+
+		if (ret != 0) {
+			return ret;
+		}
 	}
 
-	*fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0);
+	/*
+	 * CKPER is source for some peripheral clocks
+	 * (FMC-NAND / QPSI-NOR) and switching source is allowed
+	 * only if previous clock is still ON
+	 * => deactivate CKPER only after switching clock
+	 */
+	if (!ckper_disabled) {
+		return 0;
+	}
 
-	ret = fdt_read_uint32_array(fdt, plloff, "csg", (uint32_t)PLLCSG_NB,
-				    csg);
+	return stm32_clk_configure_mux(priv, CLK_CKPER_DISABLED);
+}
 
-	*csg_set = (ret == 0);
+static int stm32mp1_pll_configure_src(struct stm32_clk_priv *priv, int pll_idx)
+{
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_pll_dt_cfg *pll_conf = &pdata->pll[pll_idx];
 
-	if (ret == -FDT_ERR_NOTFOUND) {
-		ret = 0;
+	if (!pll_conf->status) {
+		return 0;
 	}
 
-	return ret;
+	return stm32_clk_configure_mux(priv, pll_conf->src);
 }
 
 int stm32mp1_clk_init(void)
 {
-	uintptr_t rcc_base = stm32mp_rcc_base();
-	uint32_t pllfracv[_PLL_NB];
-	uint32_t pllcsg[_PLL_NB][PLLCSG_NB];
-	unsigned int clksrc[CLKSRC_NB];
-	unsigned int clkdiv[CLKDIV_NB];
-	unsigned int pllcfg[_PLL_NB][PLLCFG_NB];
-	int plloff[_PLL_NB];
-	int ret, len;
+	struct stm32_clk_priv *priv = clk_stm32_get_priv();
+	struct stm32_clk_platdata *pdata = priv->pdata;
+	struct stm32_pll_dt_cfg *pll_conf = pdata->pll;
+	int ret;
 	enum stm32mp1_pll_id i;
-	bool pllcsg_set[_PLL_NB];
-	bool pllcfg_valid[_PLL_NB];
-	bool lse_css = false;
 	bool pll3_preserve = false;
 	bool pll4_preserve = false;
 	bool pll4_bootrom = false;
-	const fdt32_t *pkcs_cell;
-	void *fdt;
 	int stgen_p = stm32mp1_clk_get_parent(STGEN_K);
 	int usbphy_p = stm32mp1_clk_get_parent(USBPHY_K);
+	uint32_t usbreg_bootrom = 0U;
 
-	if (fdt_get_address(&fdt) == 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	ret = fdt_rcc_read_uint32_array("st,clksrc", (uint32_t)CLKSRC_NB,
-					clksrc);
-	if (ret < 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	ret = fdt_rcc_read_uint32_array("st,clkdiv", (uint32_t)CLKDIV_NB,
-					clkdiv);
-	if (ret < 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
-		char name[12];
-
-		snprintf(name, sizeof(name), "st,pll@%u", i);
-		plloff[i] = fdt_rcc_subnode_offset(name);
-
-		pllcfg_valid[i] = fdt_check_node(plloff[i]);
-		if (!pllcfg_valid[i]) {
-			continue;
-		}
-
-		ret = clk_get_pll_settings_from_dt(plloff[i], pllcfg[i],
-						   &pllfracv[i], pllcsg[i],
-						   &pllcsg_set[i]);
+	if (!pll_conf[_PLL1].status) {
+		ret = clk_get_pll1_settings(pll_conf[_PLL2].src, PLL1_NOMINAL_FREQ_IN_KHZ,
+					    pll_conf[_PLL1].cfg, &pll_conf[_PLL1].frac);
 		if (ret != 0) {
 			return ret;
 		}
-	}
 
-	stm32mp1_mco_csg(clksrc[CLKSRC_MCO1], clkdiv[CLKDIV_MCO1]);
-	stm32mp1_mco_csg(clksrc[CLKSRC_MCO2], clkdiv[CLKDIV_MCO2]);
+		pll_conf[_PLL1].status = true;
+		pll_conf[_PLL1].src = pll_conf[_PLL2].src;
+	}
 
 	/*
 	 * Switch ON oscillator found in device-tree.
@@ -1882,7 +2214,7 @@ int stm32mp1_clk_init(void)
 
 		bypass = fdt_clk_read_bool(name, "st,bypass");
 		digbyp = fdt_clk_read_bool(name, "st,digbypass");
-		lse_css = fdt_clk_read_bool(name, "st,css");
+		pdata->lse_css = fdt_clk_read_bool(name, "st,css");
 		lsedrv = fdt_clk_read_uint32_default(name, "st,drive",
 						     LSEDRV_MEDIUM_HIGH);
 		stm32mp1_lse_enable(bypass, digbyp, lsedrv);
@@ -1903,36 +2235,28 @@ int stm32mp1_clk_init(void)
 	stm32mp1_csi_set(true);
 
 	/* Come back to HSI */
-	ret = stm32mp1_set_clksrc(CLK_MPU_HSI);
+	ret = stm32_clk_configure_mux(priv, CLK_MPU_HSI);
 	if (ret != 0) {
 		return ret;
 	}
-	ret = stm32mp1_set_clksrc(CLK_AXI_HSI);
+	ret = stm32_clk_configure_mux(priv, CLK_AXI_HSI);
 	if (ret != 0) {
 		return ret;
 	}
-	ret = stm32mp1_set_clksrc(CLK_MCU_HSI);
+	ret = stm32_clk_configure_mux(priv, CLK_MCU_HSI);
 	if (ret != 0) {
 		return ret;
 	}
-
-	if ((mmio_read_32(rcc_base + RCC_MP_RSTSCLRR) &
+	if ((mmio_read_32(priv->base + RCC_MP_RSTSCLRR) &
 	     RCC_MP_RSTSCLRR_MPUP0RSTF) != 0) {
-		if (pllcfg_valid[_PLL3]) {
-			pll3_preserve =
-				stm32mp1_check_pll_conf(_PLL3,
-							clksrc[CLKSRC_PLL3],
-							pllcfg[_PLL3],
-							plloff[_PLL3]);
-		}
-
-		if (pllcfg_valid[_PLL4]) {
-			pll4_preserve =
-				stm32mp1_check_pll_conf(_PLL4,
-							clksrc[CLKSRC_PLL4],
-							pllcfg[_PLL4],
-							plloff[_PLL4]);
-		}
+		pll3_preserve = stm32mp1_check_pll_conf(_PLL3,
+							pll_conf[_PLL3].src,
+							pll_conf[_PLL3].cfg,
+							pll_conf[_PLL3].frac);
+		pll4_preserve = stm32mp1_check_pll_conf(_PLL4,
+							pll_conf[_PLL4].src,
+							pll_conf[_PLL4].cfg,
+							pll_conf[_PLL4].frac);
 	}
 	/* Don't initialize PLL4, when used by BOOTROM */
 	if ((stm32mp_get_boot_itf_selected() ==
@@ -1964,58 +2288,27 @@ int stm32mp1_clk_init(void)
 		stm32mp_stgen_config(stm32mp_clk_get_rate(STGEN_K));
 	}
 
-	/* Select DIV */
-	/* No ready bit when MPUSRC != CLK_MPU_PLL1P_DIV, MPUDIV is disabled */
-	mmio_write_32(rcc_base + RCC_MPCKDIVR,
-		      clkdiv[CLKDIV_MPU] & RCC_DIVR_DIV_MASK);
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_AXI], rcc_base + RCC_AXIDIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB4], rcc_base + RCC_APB4DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB5], rcc_base + RCC_APB5DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_MCU], rcc_base + RCC_MCUDIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB1], rcc_base + RCC_APB1DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB2], rcc_base + RCC_APB2DIVR);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB3], rcc_base + RCC_APB3DIVR);
+	/* Configure dividers */
+	ret = stm32_clk_dividers_configure(priv);
 	if (ret != 0) {
 		return ret;
 	}
 
-	/* No ready bit for RTC */
-	mmio_write_32(rcc_base + RCC_RTCDIVR,
-		      clkdiv[CLKDIV_RTC] & RCC_DIVR_DIV_MASK);
-
 	/* Configure PLLs source */
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_PLL12]);
+	ret = stm32mp1_pll_configure_src(priv, _PLL1);
 	if (ret != 0) {
 		return ret;
 	}
 
 	if (!pll3_preserve) {
-		ret = stm32mp1_set_clksrc(clksrc[CLKSRC_PLL3]);
+		ret = stm32mp1_pll_configure_src(priv, _PLL3);
 		if (ret != 0) {
 			return ret;
 		}
 	}
 
 	if (!pll4_preserve) {
-		ret = stm32mp1_set_clksrc(clksrc[CLKSRC_PLL4]);
+		ret = stm32mp1_pll_configure_src(priv, _PLL4);
 		if (ret != 0) {
 			return ret;
 		}
@@ -2028,34 +2321,34 @@ int stm32mp1_clk_init(void)
 			continue;
 		}
 
-		if (!pllcfg_valid[i]) {
+		if (!pll_conf[i].status) {
 			continue;
 		}
 
 		if ((i == _PLL4) && pll4_bootrom) {
 			/* Set output divider if not done by the Bootrom */
-			stm32mp1_pll_config_output(i, pllcfg[i]);
+			stm32mp1_pll_config_output(i, pll_conf[i].cfg);
 			continue;
 		}
 
-		ret = stm32mp1_pll_config(i, pllcfg[i], pllfracv[i]);
+		ret = stm32mp1_pll_config(i, pll_conf[i].cfg, pll_conf[i].frac);
 		if (ret != 0) {
 			return ret;
 		}
 
-		if (pllcsg_set[i]) {
-			stm32mp1_pll_csg(i, pllcsg[i]);
+		if (pll_conf[i].csg_enabled) {
+			stm32mp1_pll_csg(i, pll_conf[i].csg);
 		}
 
 		stm32mp1_pll_start(i);
 	}
 	/* Wait and start PLLs output when ready */
 	for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
-		if (!pllcfg_valid[i]) {
+		if (!pll_conf[i].status) {
 			continue;
 		}
 
-		ret = stm32mp1_pll_output(i, pllcfg[i][PLLCFG_O]);
+		ret = stm32mp1_pll_output(i, pll_conf[i].cfg[PLLCFG_O]);
 		if (ret != 0) {
 			return ret;
 		}
@@ -2065,69 +2358,32 @@ int stm32mp1_clk_init(void)
 		stm32mp1_lse_wait();
 	}
 
-	/* Configure with expected clock source */
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_MPU]);
-	if (ret != 0) {
-		return ret;
+	if (pll4_bootrom) {
+		usbreg_bootrom = mmio_read_32(priv->base + RCC_USBCKSELR);
 	}
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_AXI]);
-	if (ret != 0) {
-		return ret;
-	}
-	ret = stm32mp1_set_clksrc(clksrc[CLKSRC_MCU]);
+
+	/* Configure with expected clock source */
+	ret = stm32_clk_source_configure(priv);
 	if (ret != 0) {
-		return ret;
+		panic();
 	}
-	stm32mp1_set_rtcsrc(clksrc[CLKSRC_RTC], lse_css);
-
-	/* Configure PKCK */
-	pkcs_cell = fdt_rcc_read_prop("st,pkcs", &len);
-	if (pkcs_cell != NULL) {
-		bool ckper_disabled = false;
-		uint32_t j;
-		uint32_t usbreg_bootrom = 0U;
-
-		if (pll4_bootrom) {
-			usbreg_bootrom = mmio_read_32(rcc_base + RCC_USBCKSELR);
-		}
-
-		for (j = 0; j < ((uint32_t)len / sizeof(uint32_t)); j++) {
-			uint32_t pkcs = fdt32_to_cpu(pkcs_cell[j]);
 
-			if (pkcs == (uint32_t)CLK_CKPER_DISABLED) {
-				ckper_disabled = true;
-				continue;
-			}
-			stm32mp1_pkcs_config(pkcs);
-		}
+	if (pll4_bootrom) {
+		uint32_t usbreg_value, usbreg_mask;
+		const struct stm32mp1_clk_sel *sel;
 
-		/*
-		 * CKPER is source for some peripheral clocks
-		 * (FMC-NAND / QPSI-NOR) and switching source is allowed
-		 * only if previous clock is still ON
-		 * => deactivated CKPER only after switching clock
-		 */
-		if (ckper_disabled) {
-			stm32mp1_pkcs_config(CLK_CKPER_DISABLED);
-		}
+		sel = clk_sel_ref(_USBPHY_SEL);
+		usbreg_mask = (uint32_t)sel->msk << sel->src;
+		sel = clk_sel_ref(_USBO_SEL);
+		usbreg_mask |= (uint32_t)sel->msk << sel->src;
 
-		if (pll4_bootrom) {
-			uint32_t usbreg_value, usbreg_mask;
-			const struct stm32mp1_clk_sel *sel;
-
-			sel = clk_sel_ref(_USBPHY_SEL);
-			usbreg_mask = (uint32_t)sel->msk << sel->src;
-			sel = clk_sel_ref(_USBO_SEL);
-			usbreg_mask |= (uint32_t)sel->msk << sel->src;
-
-			usbreg_value = mmio_read_32(rcc_base + RCC_USBCKSELR) &
-				       usbreg_mask;
-			usbreg_bootrom &= usbreg_mask;
-			if (usbreg_bootrom != usbreg_value) {
-				VERBOSE("forbidden new USB clk path\n");
-				VERBOSE("vs bootrom on USB boot\n");
-				return -FDT_ERR_BADVALUE;
-			}
+		usbreg_value = mmio_read_32(priv->base + RCC_USBCKSELR) &
+			       usbreg_mask;
+		usbreg_bootrom &= usbreg_mask;
+		if (usbreg_bootrom != usbreg_value) {
+			EARLY_ERROR("forbidden new USB clk path\n");
+			EARLY_ERROR("vs bootrom on USB boot\n");
+			return -FDT_ERR_BADVALUE;
 		}
 	}
 
@@ -2139,7 +2395,7 @@ int stm32mp1_clk_init(void)
 	stm32mp_stgen_config(stm32mp_clk_get_rate(STGEN_K));
 
 	/* Software Self-Refresh mode (SSR) during DDR initilialization */
-	mmio_clrsetbits_32(rcc_base + RCC_DDRITFCR,
+	mmio_clrsetbits_32(priv->base + RCC_DDRITFCR,
 			   RCC_DDRITFCR_DDRCKMOD_MASK,
 			   RCC_DDRITFCR_DDRCKMOD_SSR <<
 			   RCC_DDRITFCR_DDRCKMOD_SHIFT);
@@ -2326,6 +2582,17 @@ void stm32mp1_register_clock_parents_secure(unsigned long clock_id)
 }
 #endif /* STM32MP_SHARED_RESOURCES */
 
+void stm32mp1_clk_mcuss_protect(bool enable)
+{
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	if (enable) {
+		mmio_setbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT);
+	} else {
+		mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT);
+	}
+}
+
 static void sync_earlyboot_clocks_state(void)
 {
 	unsigned int idx;
@@ -2355,8 +2622,199 @@ static const struct clk_ops stm32mp_clk_ops = {
 	.get_parent	= stm32mp1_clk_get_parent,
 };
 
+struct stm32_pll_dt_cfg mp15_pll[_PLL_NB];
+uint32_t mp15_clksrc[MUX_NB];
+uint32_t mp15_clkdiv[DIV_NB];
+
+struct stm32_clk_platdata stm32mp15_clock_pdata = {
+	.pll		= mp15_pll,
+	.npll		= _PLL_NB,
+	.clksrc		= mp15_clksrc,
+	.nclksrc	= MUX_NB,
+	.clkdiv		= mp15_clkdiv,
+	.nclkdiv	= DIV_NB,
+};
+
+static struct stm32_clk_priv stm32mp15_clock_data = {
+	.base		= RCC_BASE,
+	.parents	= parent_mp15,
+	.nb_parents	= ARRAY_SIZE(parent_mp15),
+	.div		= dividers_mp15,
+	.nb_div		= ARRAY_SIZE(dividers_mp15),
+	.pdata		= &stm32mp15_clock_pdata,
+};
+
+static int stm32_clk_parse_fdt_by_name(void *fdt, int node, const char *name,
+				       uint32_t *tab, uint32_t *nb)
+{
+	const fdt32_t *cell;
+	int len = 0;
+	uint32_t i;
+
+	cell = fdt_getprop(fdt, node, name, &len);
+	if (cell == NULL) {
+		*nb = 0U;
+		return 0;
+	}
+
+	for (i = 0U; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+		tab[i] = fdt32_to_cpu(cell[i]);
+	}
+
+	*nb = (uint32_t)len / sizeof(uint32_t);
+
+	return 0;
+}
+
+#define RCC_PLL_NAME_SIZE 12
+
+static int clk_stm32_load_vco_config(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	int err;
+
+	err = fdt_read_uint32_array(fdt, subnode, "divmn", (int)PLL_DIV_MN_NB, &pll->cfg[PLLCFG_M]);
+	if (err != 0) {
+		return err;
+	}
+
+	err = fdt_read_uint32_array(fdt, subnode, "csg", (int)PLLCSG_NB, pll->csg);
+	if (err == 0) {
+		pll->csg_enabled = true;
+	} else if (err == -FDT_ERR_NOTFOUND) {
+		pll->csg_enabled = false;
+	} else {
+		return err;
+	}
+
+	pll->status = true;
+
+	pll->frac = fdt_read_uint32_default(fdt, subnode, "frac", 0);
+
+	pll->src = fdt_read_uint32_default(fdt, subnode, "src", UINT32_MAX);
+
+	return 0;
+}
+
+static int clk_stm32_load_output_config(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	int err;
+
+	err = fdt_read_uint32_array(fdt, subnode, "st,pll_div_pqr", (int)PLL_DIV_PQR_NB,
+				    &pll->cfg[PLLCFG_P]);
+	if (err != 0) {
+		return err;
+	}
+
+	pll->cfg[PLLCFG_O] = PQR(1, 1, 1);
+
+	return 0;
+}
+
+static int clk_stm32_parse_pll_fdt(void *fdt, int subnode, struct stm32_pll_dt_cfg *pll)
+{
+	const fdt32_t *cuint;
+	int subnode_pll;
+	int subnode_vco;
+	int err;
+
+	cuint = fdt_getprop(fdt, subnode, "st,pll", NULL);
+	if (cuint == NULL) {
+		/* Case of no pll is defined */
+		return 0;
+	}
+
+	subnode_pll = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+	if (subnode_pll < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	cuint = fdt_getprop(fdt, subnode_pll, "st,pll_vco", NULL);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	subnode_vco = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+	if (subnode_vco < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	err = clk_stm32_load_vco_config(fdt, subnode_vco, pll);
+	if (err != 0) {
+		return err;
+	}
+
+	err = clk_stm32_load_output_config(fdt, subnode_pll, pll);
+	if (err != 0) {
+		return err;
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt_all_pll(void *fdt, int node, struct stm32_clk_platdata *pdata)
+{
+	size_t i = 0U;
+
+	for (i = _PLL1; i < pdata->npll; i++) {
+		struct stm32_pll_dt_cfg *pll = pdata->pll + i;
+		char name[RCC_PLL_NAME_SIZE];
+		int subnode;
+		int err;
+
+		snprintf(name, sizeof(name), "st,pll@%u", i);
+
+		subnode = fdt_subnode_offset(fdt, node, name);
+		if (!fdt_check_node(subnode)) {
+			continue;
+		}
+
+		err = clk_stm32_parse_pll_fdt(fdt, subnode, pll);
+		if (err != 0) {
+			panic();
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_clk_parse_fdt(struct stm32_clk_platdata *pdata)
+{
+	void *fdt = NULL;
+	int node;
+	uint32_t err;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	if (node < 0) {
+		panic();
+	}
+
+	err = stm32_clk_parse_fdt_all_pll(fdt, node, pdata);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clkdiv", pdata->clkdiv, &pdata->nclkdiv);
+	if (err != 0) {
+		return err;
+	}
+
+	err = stm32_clk_parse_fdt_by_name(fdt, node, "st,clksrc", pdata->clksrc, &pdata->nclksrc);
+	if (err != 0) {
+		return err;
+	}
+
+	return 0;
+}
+
 int stm32mp1_clk_probe(void)
 {
+	uintptr_t base = RCC_BASE;
+	int ret;
+
 #if defined(IMAGE_BL32)
 	if (!fdt_get_rcc_secure_state()) {
 		mmio_write_32(stm32mp_rcc_base() + RCC_TZCR, 0U);
@@ -2365,6 +2823,16 @@ int stm32mp1_clk_probe(void)
 
 	stm32mp1_osc_init();
 
+	ret = stm32_clk_parse_fdt(&stm32mp15_clock_pdata);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = clk_stm32_init(&stm32mp15_clock_data, base);
+	if (ret != 0) {
+		return ret;
+	}
+
 	sync_earlyboot_clocks_state();
 
 	clk_register(&stm32mp_clk_ops);
diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c
index 379547fd..69922fd2 100644
--- a/drivers/st/clk/stm32mp_clkfunc.c
+++ b/drivers/st/clk/stm32mp_clkfunc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -334,6 +334,19 @@ static void stgen_set_counter(unsigned long long counter)
 #endif
 }
 
+/*******************************************************************************
+ * This function returns the STGEN counter value.
+ ******************************************************************************/
+static unsigned long long stm32mp_stgen_get_counter(void)
+{
+#ifdef __aarch64__
+	return mmio_read_64(STGEN_BASE + CNTCV_OFF);
+#else
+	return (((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) |
+		mmio_read_32(STGEN_BASE + CNTCVL_OFF));
+#endif
+}
+
 /*******************************************************************************
  * This function configures and restores the STGEN counter depending on the
  * connected clock.
@@ -350,9 +363,11 @@ void stm32mp_stgen_config(unsigned long rate)
 	}
 
 	mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
-	counter = stm32mp_stgen_get_counter() * rate / cntfid0;
 
-	stgen_set_counter(counter);
+	if (cntfid0 != 0U) {
+		counter = stm32mp_stgen_get_counter() * rate / cntfid0;
+		stgen_set_counter(counter);
+	}
 	mmio_write_32(STGEN_BASE + CNTFID_OFF, rate);
 	mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
 
@@ -363,32 +378,13 @@ void stm32mp_stgen_config(unsigned long rate)
 }
 
 /*******************************************************************************
- * This function returns the STGEN counter value.
+ * This function restores CPU generic timer rate from the STGEN clock rate.
  ******************************************************************************/
-unsigned long long stm32mp_stgen_get_counter(void)
+void stm32mp_stgen_restore_rate(void)
 {
-#ifdef __aarch64__
-	return mmio_read_64(STGEN_BASE + CNTCV_OFF);
-#else
-	return (((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) |
-		mmio_read_32(STGEN_BASE + CNTCVL_OFF));
-#endif
-}
+	unsigned long rate;
 
-/*******************************************************************************
- * This function restores the STGEN counter value.
- * It takes a first input value as a counter backup value to be restored and a
- * offset in ms to be added.
- ******************************************************************************/
-void stm32mp_stgen_restore_counter(unsigned long long value,
-				   unsigned long long offset_in_ms)
-{
-	unsigned long long cnt;
+	rate = mmio_read_32(STGEN_BASE + CNTFID_OFF);
 
-	cnt = value + ((offset_in_ms *
-			mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U);
-
-	mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
-	stgen_set_counter(cnt);
-	mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
+	write_cntfrq_el0((u_register_t)rate);
 }
diff --git a/drivers/st/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c
index e92f9800..bd493245 100644
--- a/drivers/st/crypto/stm32_hash.c
+++ b/drivers/st/crypto/stm32_hash.c
@@ -10,6 +10,7 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <common/sha_common_macros.h>
 #include <drivers/clk.h>
 #include <drivers/delay_timer.h>
 #include <drivers/st/stm32_hash.h>
@@ -62,15 +63,6 @@
 #define HASH_STR_NBLW_MASK		GENMASK(4, 0)
 #define HASH_STR_DCAL			BIT(8)
 
-#define MD5_DIGEST_SIZE			16U
-#define SHA1_DIGEST_SIZE		20U
-#define SHA224_DIGEST_SIZE		28U
-#define SHA256_DIGEST_SIZE		32U
-#define SHA384_DIGEST_SIZE		48U
-#define SHA512_224_DIGEST_SIZE		28U
-#define SHA512_256_DIGEST_SIZE		32U
-#define SHA512_DIGEST_SIZE		64U
-
 #define RESET_TIMEOUT_US_1MS		1000U
 #define HASH_TIMEOUT_US			10000U
 
diff --git a/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr3.h b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr3.h
new file mode 100644
index 00000000..936b73c0
--- /dev/null
+++ b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr3.h
@@ -0,0 +1,935 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MNPMUSRAMMSGBLOCK_DDR3_H
+#define MNPMUSRAMMSGBLOCK_DDR3_H
+
+/*
+ * DDR3U_1D training firmware message block structure
+ *
+ * Please refer to the Training Firmware App Note for futher information about
+ * the usage for Message Block.
+ */
+struct pmu_smb_ddr_1d {
+	uint8_t reserved00;		/*
+					 * Byte offset 0x00, CSR Addr 0x54000, Direction=In
+					 * reserved00[0:4] RFU, must be zero
+					 *
+					 * reserved00[5] = Train vrefDAC0 During Read Deskew
+					 *   0x1 = Read Deskew will begin by enabling and roughly
+					 *   training the phy's per-lane reference voltages.
+					 *   Training the vrefDACs CSRs will increase the maximum 1D
+					 *   training time by around half a millisecond, but will
+					 *   improve 1D training accuracy on systems with
+					 *   significant voltage-offsets between lane read eyes.
+					 *   0x0 = Read Deskew will assume the messageblock's
+					 *   phyVref setting will work for all lanes.
+					 *
+					 * reserved00[6] = Enable High Effort WrDQ1D
+					 *   0x1 = WrDQ1D will conditionally retry training at
+					 *   several extra RxClkDly Timings. This will increase the
+					 *   maximum 1D training time by up to 4 extra iterations of
+					 *   WrDQ1D. This is only required in systems that suffer
+					 *   from very large, asymmetric eye-collapse when receiving
+					 *   PRBS patterns.
+					 *   0x0 = WrDQ1D assume rxClkDly values found by SI
+					 *   Friendly RdDqs1D will work for receiving PRBS patterns
+					 *
+					 * reserved00[7] = Optimize for the special hard macros in
+					 * TSMC28.
+					 *   0x1 = set if the phy being trained was manufactured in
+					 *   any TSMC28 process node.
+					 *   0x0 = otherwise, when not training a TSMC28 phy, leave
+					 *   this field as 0.
+					 */
+	uint8_t msgmisc;		/*
+					 * Byte offset 0x01, CSR Addr 0x54000, Direction=In
+					 * Contains various global options for training.
+					 *
+					 * Bit fields:
+					 *
+					 * msgmisc[0] = MTESTEnable
+					 *   0x1 = Pulse primary digital test output bump at the end
+					 *   of each major training stage. This enables observation
+					 *   of training stage completion by observing the digital
+					 *   test output.
+					 *   0x0 = Do not pulse primary digital test output bump
+					 *
+					 * msgmisc[1] = SimulationOnlyReset
+					 *   0x1 = Verilog only simulation option to shorten
+					 *   duration of DRAM reset pulse length to 1ns.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use reset pulse length specified by JEDEC
+					 *   standard.
+					 *
+					 * msgmisc[2] = SimulationOnlyTraining
+					 *   0x1 = Verilog only simulation option to shorten the
+					 *   duration of the training steps by performing fewer
+					 *   iterations.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use standard training duration.
+					 *
+					 * msgmisc[3] = RFU, must be zero
+					 *
+					 * msgmisc[4] = Suppress streaming messages, including
+					 * assertions, regardless of hdtctrl setting.
+					 * Stage Completion messages, as well as training completion
+					 * and error messages are still sent depending on hdtctrl
+					 * setting.
+					 *
+					 * msgmisc[5] = PerByteMaxRdLat
+					 *   0x1 = Each DBYTE will return dfi_rddata_valid at the
+					 *   lowest possible latency. This may result in unaligned
+					 *   data between bytes to be returned to the DFI.
+					 *   0x0 = Every DBYTE will return dfi_rddata_valid
+					 *   simultaneously. This will ensure that data bytes will
+					 *   return aligned accesses to the DFI.
+					 *
+					 * msgmisc[6] = PartialRank (DDR3 UDIMM and DDR4 UDIMM only,
+					 * otherwise RFU, must be zero)
+					 *   0x1 = Support rank populated with a subset of byte, but
+					 *   where even-odd pair of rank support all the byte
+					 *   0x0 = All rank populated with all the byte (tyical
+					 *   configuration)
+					 *
+					 * msgmisc[7] RFU, must be zero
+					 *
+					 * Notes:
+					 *
+					 * - SimulationOnlyReset and SimulationOnlyTraining can be
+					 *   used to speed up simulation run times, and must never
+					 *   be used in real silicon. Some VIPs may have checks on
+					 *   DRAM reset parameters that may need to be disabled when
+					 *   using SimulationOnlyReset.
+					 */
+	uint16_t pmurevision;		/*
+					 * Byte offset 0x02, CSR Addr 0x54001, Direction=Out
+					 * PMU firmware revision ID
+					 * After training is run, this address will contain the
+					 * revision ID of the firmware.
+					 * Please reference this revision ID when filing support
+					 * cases.
+					 */
+	uint8_t pstate;			/*
+					 * Byte offset 0x04, CSR Addr 0x54002, Direction=In
+					 * Must be set to the target pstate to be trained
+					 *   0x0 = pstate 0
+					 *   0x1 = pstate 1
+					 *   0x2 = pstate 2
+					 *   0x3 = pstate 3
+					 *   All other encodings are reserved
+					 */
+	uint8_t pllbypassen;		/*
+					 * Byte offset 0x05, CSR Addr 0x54002, Direction=In
+					 * Set according to whether target pstate uses PHY PLL
+					 * bypass
+					 *   0x0 = PHY PLL is enabled for target pstate
+					 *   0x1 = PHY PLL is bypassed for target pstate
+					 */
+	uint16_t dramfreq;		/*
+					 * Byte offset 0x06, CSR Addr 0x54003, Direction=In
+					 * DDR data rate for the target pstate in units of MT/s.
+					 * For example enter 0x0640 for DDR1600.
+					 */
+	uint8_t dfifreqratio;		/*
+					 * Byte offset 0x08, CSR Addr 0x54004, Direction=In
+					 * Frequency ratio betwen DfiCtlClk and SDRAM memclk.
+					 *   0x1 = 1:1
+					 *   0x2 = 1:2
+					 *   0x4 = 1:4
+					 */
+	uint8_t bpznresval;		/*
+					 * Byte offset 0x09, CSR Addr 0x54004, Direction=In
+					 * Overwrite the value of precision resistor connected to
+					 * Phy BP_ZN
+					 *   0x00 = Do not program. Use current CSR value.
+					 *   0xf0 = 240 Ohm
+					 *   0x78 = 120 Ohm
+					 *   0x28 = 40 Ohm
+					 *   All other values are reserved.
+					 * It is recommended to set this to 0x00.
+					 */
+	uint8_t phyodtimpedance;	/*
+					 * Byte offset 0x0a, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the termination impedance in ohms
+					 * used by PHY during reads.
+					 *
+					 *   0x0 = Firmware skips programming (must be manually
+					 *   programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal termination impedance values.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must determine the correct value
+					 * through SI simulation or other methods.
+					 */
+	uint8_t phydrvimpedance;	/*
+					 * Byte offset 0x0b, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the driver impedance in ohms used
+					 * by PHY during writes for all DBYTE drivers
+					 * (DQ/DM/DBI/DQS).
+					 *
+					 *   0x0 = Firmware skips programming (must be manually
+					 *   programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal R_on driver impedance values.
+					 *
+					 * For digital simulation, any value can be used that is not
+					 * Hi-Z. For silicon, the users must determine the correct
+					 * value through SI simulation or other methods.
+					 */
+	uint8_t phyvref;		/*
+					 * Byte offset 0x0c, CSR Addr 0x54006, Direction=In
+					 * Must be programmed with the Vref level to be used by the
+					 * PHY during reads
+					 *
+					 * The units of this field are a percentage of VDDQ
+					 * according to the following equation:
+					 *
+					 * Receiver Vref = VDDQ*phyvref[6:0]/128
+					 *
+					 * For example to set Vref at 0.75*VDDQ, set this field to
+					 * 0x60.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must calculate the analytical Vref by
+					 * using the impedances, terminations, and series resistance
+					 * present in the system.
+					 */
+	uint8_t dramtype;		/*
+					 * Byte offset 0x0d, CSR Addr 0x54006, Direction=In
+					 * Module Type:
+					 *   0x01 = DDR3 unbuffered
+					 *   0x02 = Reserved
+					 *   0x03 = Reserved
+					 *   0x04 = Reserved
+					 *   0x05 = Reserved
+					 */
+	uint8_t disableddbyte;		/*
+					 * Byte offset 0x0e, CSR Addr 0x54007, Direction=In
+					 * Bitmap to indicate which Dbyte are not connected (for
+					 * DByte 0 to 7):
+					 * Set disableddbyte[i] to 1 only to specify that DByte is
+					 * not need to be trained (DByte 8 can be disabled via
+					 * enableddqs setting)
+					 */
+	uint8_t enableddqs;		/*
+					 * Byte offset 0x0f, CSR Addr 0x54007, Direction=In
+					 * Total number of DQ bits enabled in PHY
+					 */
+	uint8_t cspresent;		/*
+					 * Byte offset 0x10, CSR Addr 0x54008, Direction=In
+					 * Indicates presence of DRAM at each chip select for PHY.
+					 * Each bit corresponds to a logical CS.
+					 *
+					 * If the bit is set to 1, the CS is connected to DRAM.
+					 * If the bit is set to 0, the CS is not connected to DRAM.
+					 *
+					 * cspresent[0] = CS0 is populated with DRAM
+					 * cspresent[1] = CS1 is populated with DRAM
+					 * cspresent[2] = CS2 is populated with DRAM
+					 * cspresent[3] = CS3 is populated with DRAM
+					 * cspresent[7:4] = Reserved (must be programmed to 0)
+					 */
+	uint8_t cspresentd0;		/*
+					 * Byte offset 0x11, CSR Addr 0x54008, Direction=In
+					 * The CS signals from field cspresent that are routed to
+					 * DIMM connector 0
+					 */
+	uint8_t cspresentd1;		/*
+					 * Byte offset 0x12, CSR Addr 0x54009, Direction=In
+					 * The CS signals from field cspresent that are routed to
+					 * DIMM connector 1
+					 */
+	uint8_t addrmirror;		/*
+					 * Byte offset 0x13, CSR Addr 0x54009, Direction=In
+					 * Corresponds to CS[3:0]
+					 *   1 = Address Mirror.
+					 *   0 = No Address Mirror.
+					 */
+	uint8_t cstestfail;		/*
+					 * Byte offset 0x14, CSR Addr 0x5400a, Direction=Out
+					 * This field will be set if training fails on any rank.
+					 *   0x0 = No failures
+					 *   non-zero = one or more ranks failed training
+					 */
+	uint8_t phycfg;			/*
+					 * Byte offset 0x15, CSR Addr 0x5400a, Direction=In
+					 * Additional mode bits.
+					 *
+					 * Bit fields:
+					 * [0] SlowAccessMode:
+					 *   1 = 2T Address Timing.
+					 *   0 = 1T Address Timing.
+					 * [7-1] RFU, must be zero
+					 *
+					 * WARNING: In case of DDR4 Geardown Mode (mr3[A3] == 1),
+					 * phycfg[0] must be 0.
+					 */
+	uint16_t sequencectrl;		/*
+					 * Byte offset 0x16, CSR Addr 0x5400b, Direction=In
+					 * Controls the training steps to be run. Each bit
+					 * corresponds to a training step.
+					 *
+					 * If the bit is set to 1, the training step will run.
+					 * If the bit is set to 0, the training step will be
+					 * skipped.
+					 *
+					 * Training step to bit mapping:
+					 * sequencectrl[0] = Run DevInit - Device/phy
+					 *		     initialization. Should always be set.
+					 * sequencectrl[1] = Run WrLvl - Write leveling
+					 * sequencectrl[2] = Run RxEn - Read gate training
+					 * sequencectrl[3] = Run RdDQS1D - 1d read dqs training
+					 * sequencectrl[4] = Run WrDQ1D - 1d write dq training
+					 * sequencectrl[5] = RFU, must be zero
+					 * sequencectrl[6] = RFU, must be zero
+					 * sequencectrl[7] = RFU, must be zero
+					 * sequencectrl[8] = Run RdDeskew - Per lane read dq deskew
+					 *		     training
+					 * sequencectrl[9] = Run MxRdLat - Max read latency training
+					 * sequencectrl[10] = RFU, must be zero
+					 * sequencectrl[11] = RFU, must be zero
+					 * sequencectrl[12] = RFU, must be zero
+					 * sequencectrl[13] = RFU, must be zero
+					 * sequencectrl[15-14] = RFU, must be zero
+					 */
+	uint8_t hdtctrl;		/*
+					 * Byte offset 0x18, CSR Addr 0x5400c, Direction=In
+					 * To control the total number of debug messages, a
+					 * verbosity subfield (hdtctrl, Hardware Debug Trace
+					 * Control) exists in the message block. Every message has a
+					 * verbosity level associated with it, and as the hdtctrl
+					 * value is increased, less important s messages stop being
+					 * sent through the mailboxes. The meanings of several major
+					 * hdtctrl thresholds are explained below:
+					 *
+					 *   0x04 = Maximal debug messages (e.g., Eye contours)
+					 *   0x05 = Detailed debug messages (e.g. Eye delays)
+					 *   0x0A = Coarse debug messages (e.g. rank information)
+					 *   0xC8 = Stage completion
+					 *   0xC9 = Assertion messages
+					 *   0xFF = Firmware completion messages only
+					 */
+	uint8_t reserved19;		/* Byte offset 0x19, CSR Addr 0x5400c, Direction=N/A */
+	uint8_t reserved1a;		/* Byte offset 0x1a, CSR Addr 0x5400d, Direction=N/A */
+	uint8_t share2dvrefresult;	/*
+					 * Byte offset 0x1b, CSR Addr 0x5400d, Direction=In
+					 * Bitmap that designates the phy's vref source for every
+					 * pstate
+					 * If share2dvrefresult[x] = 0, then after 2D training,
+					 * pstate x will continue using the phyVref provided in
+					 * pstate x's 1D messageblock.
+					 * If share2dvrefresult[x] = 1, then after 2D training,
+					 * pstate x will use the per-lane VrefDAC0/1 CSRs trained by
+					 * 2d training.
+					 */
+	uint8_t reserved1c;		/* Byte offset 0x1c, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1d;		/* Byte offset 0x1d, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1e;		/*
+					 * Byte offset 0x1e, CSR Addr 0x5400f, Direction=In
+					 * Input for constraining the range of vref(DQ) values
+					 * training will collect data for, usually reducing training
+					 * time. However, too large of a voltage range may cause
+					 * longer 2D training times while too small of a voltage
+					 * range may truncate passing regions. When in doubt, leave
+					 * this field set to 0.
+					 * Used by 2D training in: Rd2D, Wr2D
+					 *
+					 * reserved1E[0-3]: Rd2D Voltage Range
+					 *   0 = Training will search all phy vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from phyVref
+					 *   2 = limit to +/-4 %VDDQ from phyVref
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from phyVref
+					 *
+					 * reserved1E[4-7]: Wr2D Voltage Range
+					 *   0 = Training will search all dram vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from mr6
+					 *   2 = limit to +/-4 %VDDQ from mr6
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from mr6
+					 */
+	uint8_t reserved1f;		/*
+					 * Byte offset 0x1f, CSR Addr 0x5400f, Direction=In
+					 * Extended training option:
+					 *
+					 * reserved1F[1:0]: Configured RxClkDly offset try during
+					 * WrDq1D high-effort (i.e., when reserved00[6] is set)
+					 *   0: -8, +8, -16, +16
+					 *   1: -4, +4, -8, +8, -12, +12, -16, +16
+					 *   2: -2, +2, -4, +4, -6, +6, -8, +8
+					 *   3: -2, +2, -4, +4, -6, +6, -8, +8, -10, +10, -12, +12,
+					 *      -14, +14, -16, +16
+					 *
+					 * reserved1F[2]: When set, execute again WrDq1D after
+					 * RdDqs1D PRBS
+					 *
+					 * reserved1F[3]: When set redo RdDeskew with PRBS after
+					 * (first) WrDqs1D
+					 *
+					 * reserved1F[7:4]: This field is reserved and must be
+					 * programmed to 0x00.
+					 */
+	uint8_t reserved20;		/*
+					 * Byte offset 0x20, CSR Addr 0x54010, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for Reserved:
+					 * Reserved MREP assume raising edge is found when
+					 * reserved20[3:0]+3 consecutive 1 are received during MREP
+					 * fine delay swept; reserved20[6:0] thus permits to
+					 * increase tolerance for noisy system. And if reserved20[7]
+					 * is set, MREP training is failing if no raising edge is
+					 * found (otherwise the raising edge is assume close to
+					 * delay 0).
+					 */
+	uint8_t reserved21;		/*
+					 * Byte offset 0x21, CSR Addr 0x54010, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for Reserved:
+					 * Reserved DWL assume raising edge is found when
+					 * reserved21[3:0]+3 consecutive 1 are received during DWL
+					 * fine delay swept; reserved21[6:0] thus permits to
+					 * increase tolerance for noisy system. And if reserved21[7]
+					 * is set, DWL training is failing if no raising edge is
+					 * found (otherwise the raising edge is assume close to
+					 * delay 0).
+					 */
+	uint16_t phyconfigoverride;	/*
+					 * Byte offset 0x22, CSR Addr 0x54011, Direction=In
+					 * Override PhyConfig csr.
+					 *   0x0: Use hardware csr value for PhyConfing
+					 *   (recommended)
+					 *   Other values: Use value for PhyConfig instead of
+					 *   Hardware value.
+					 */
+	uint8_t dfimrlmargin;		/*
+					 * Byte offset 0x24, CSR Addr 0x54012, Direction=In
+					 * Margin added to smallest passing trained DFI Max Read
+					 * Latency value, in units of DFI clocks. Recommended to be
+					 * >= 1.
+					 */
+	int8_t cdd_rr_3_2;		/*
+					 * Byte offset 0x25, CSR Addr 0x54012, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 2.
+					 */
+	int8_t cdd_rr_3_1;		/*
+					 * Byte offset 0x26, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 1.
+					 */
+	int8_t cdd_rr_3_0;		/*
+					 * Byte offset 0x27, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 0.
+					 */
+	int8_t cdd_rr_2_3;		/*
+					 * Byte offset 0x28, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 3.
+					 */
+	int8_t cdd_rr_2_1;		/*
+					 * Byte offset 0x29, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 1.
+					 */
+	int8_t cdd_rr_2_0;		/*
+					 * Byte offset 0x2a, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 0.
+					 */
+	int8_t cdd_rr_1_3;		/*
+					 * Byte offset 0x2b, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 3.
+					 */
+	int8_t cdd_rr_1_2;		/*
+					 * Byte offset 0x2c, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 2.
+					 */
+	int8_t cdd_rr_1_0;		/*
+					 * Byte offset 0x2d, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 0.
+					 */
+	int8_t cdd_rr_0_3;		/*
+					 * Byte offset 0x2e, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 3.
+					 */
+	int8_t cdd_rr_0_2;		/*
+					 * Byte offset 0x2f, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 2.
+					 */
+	int8_t cdd_rr_0_1;		/*
+					 * Byte offset 0x30, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 1.
+					 */
+	int8_t cdd_ww_3_2;		/*
+					 * Byte offset 0x31, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_3_1;		/*
+					 * Byte offset 0x32, CSR Addr 0x54019, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 1.
+					 */
+	int8_t cdd_ww_3_0;		/*
+					 * Byte offset 0x33, CSR Addr 0x54019, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_2_3;		/*
+					 * Byte offset 0x34, CSR Addr 0x5401a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_2_1;		/*
+					 * Byte offset 0x35, CSR Addr 0x5401a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 1.
+					 */
+	int8_t cdd_ww_2_0;		/*
+					 * Byte offset 0x36, CSR Addr 0x5401b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_1_3;		/*
+					 * Byte offset 0x37, CSR Addr 0x5401b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_1_2;		/*
+					 * Byte offset 0x38, CSR Addr 0x5401c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_1_0;		/*
+					 * Byte offset 0x39, CSR Addr 0x5401c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_0_3;		/*
+					 * Byte offset 0x3a, CSR Addr 0x5401d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_0_2;		/*
+					 * Byte offset 0x3b, CSR Addr 0x5401d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_0_1;		/*
+					 * Byte offset 0x3c, CSR Addr 0x5401e, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 1.
+					 */
+	int8_t cdd_rw_3_3;		/*
+					 * Byte offset 0x3d, CSR Addr 0x5401e, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_3_2;		/*
+					 * Byte offset 0x3e, CSR Addr 0x5401f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_3_1;		/*
+					 * Byte offset 0x3f, CSR Addr 0x5401f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_3_0;		/*
+					 * Byte offset 0x40, CSR Addr 0x54020, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_2_3;		/*
+					 * Byte offset 0x41, CSR Addr 0x54020, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_2_2;		/*
+					 * Byte offset 0x42, CSR Addr 0x54021, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_2_1;		/*
+					 * Byte offset 0x43, CSR Addr 0x54021, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_2_0;		/*
+					 * Byte offset 0x44, CSR Addr 0x54022, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_1_3;		/*
+					 * Byte offset 0x45, CSR Addr 0x54022, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_1_2;		/*
+					 * Byte offset 0x46, CSR Addr 0x54023, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_1_1;		/*
+					 * Byte offset 0x47, CSR Addr 0x54023, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_1_0;		/*
+					 * Byte offset 0x48, CSR Addr 0x54024, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_0_3;		/*
+					 * Byte offset 0x49, CSR Addr 0x54024, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_0_2;		/*
+					 * Byte offset 0x4a, CSR Addr 0x54025, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_0_1;		/*
+					 * Byte offset 0x4b, CSR Addr 0x54025, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_0_0;		/*
+					 * Byte offset 0x4c, CSR Addr 0x54026, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_3_3;		/*
+					 * Byte offset 0x4d, CSR Addr 0x54026, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_3_2;		/*
+					 * Byte offset 0x4e, CSR Addr 0x54027, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_3_1;		/*
+					 * Byte offset 0x4f, CSR Addr 0x54027, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_3_0;		/*
+					 * Byte offset 0x50, CSR Addr 0x54028, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_2_3;		/*
+					 * Byte offset 0x51, CSR Addr 0x54028, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_2_2;		/*
+					 * Byte offset 0x52, CSR Addr 0x54029, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_2_1;		/*
+					 * Byte offset 0x53, CSR Addr 0x54029, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_2_0;		/*
+					 * Byte offset 0x54, CSR Addr 0x5402a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_1_3;		/*
+					 * Byte offset 0x55, CSR Addr 0x5402a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_1_2;		/*
+					 * Byte offset 0x56, CSR Addr 0x5402b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_1_1;		/*
+					 * Byte offset 0x57, CSR Addr 0x5402b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_1_0;		/*
+					 * Byte offset 0x58, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_0_3;		/*
+					 * Byte offset 0x59, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_0_2;		/*
+					 * Byte offset 0x5a, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_0_1;		/*
+					 * Byte offset 0x5b, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_0_0;		/*
+					 * Byte offset 0x5c, CSR Addr 0x5402e, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 0.
+					 */
+	uint8_t reserved5d;		/*
+					 * Byte offset 0x5d, CSR Addr 0x5402e, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for DDR4:
+					 * By default, if this parameter is 0, the offset applied at
+					 * the end of DDR4 RxEn training resulting in the trained
+					 * RxEnDly is 3/8 of the RX preamble width; if reserved5D is
+					 * non zero, this offset is used instead (in fine step).
+					 */
+	uint16_t mr0;			/*
+					 * Byte offset 0x5e, CSR Addr 0x5402f, Direction=In
+					 * Value of DDR mode register mr0 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr1;			/*
+					 * Byte offset 0x60, CSR Addr 0x54030, Direction=In
+					 * Value of DDR mode register mr1 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr2;			/*
+					 * Byte offset 0x62, CSR Addr 0x54031, Direction=In
+					 * Value of DDR mode register mr2 for all ranks for current
+					 * pstate.
+					 */
+	uint8_t reserved64;		/*
+					 * Byte offset 0x64, CSR Addr 0x54032, Direction=In
+					 * Reserved64[0] = protect memory reset
+					 *   0x0 = dfi_reset_n cannot control CP_MEMRESET_L to
+					 *	   devices after training. (Default value)
+					 *   0x1 = dfi_reset_n can control CP_MEMRESET_L to
+					 *	   devices after training.
+					 *
+					 * Reserved64[7:1] RFU, must be zero
+					 */
+	uint8_t reserved65;		/*
+					 * Byte offset 0x65, CSR Addr 0x54032, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved66;		/*
+					 * Byte offset 0x66, CSR Addr 0x54033, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved67;		/*
+					 * Byte offset 0x67, CSR Addr 0x54033, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved68;		/*
+					 * Byte offset 0x68, CSR Addr 0x54034, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved69;		/*
+					 * Byte offset 0x69, CSR Addr 0x54034, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6a;		/*
+					 * Byte offset 0x6a, CSR Addr 0x54035, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6b;		/*
+					 * Byte offset 0x6b, CSR Addr 0x54035, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6c;		/*
+					 * Byte offset 0x6c, CSR Addr 0x54036, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6d;		/*
+					 * Byte offset 0x6d, CSR Addr 0x54036, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6e;		/*
+					 * Byte offset 0x6e, CSR Addr 0x54037, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved6f;		/*
+					 * Byte offset 0x6f, CSR Addr 0x54037, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved70;		/*
+					 * Byte offset 0x70, CSR Addr 0x54038, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved71;		/*
+					 * Byte offset 0x71, CSR Addr 0x54038, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved72;		/*
+					 * Byte offset 0x72, CSR Addr 0x54039, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved73;		/*
+					 * Byte offset 0x73, CSR Addr 0x54039, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t acsmodtctrl0;		/*
+					 * Byte offset 0x74, CSR Addr 0x5403a, Direction=In
+					 * Odt pattern for accesses targeting rank 0. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl1;		/*
+					 * Byte offset 0x75, CSR Addr 0x5403a, Direction=In
+					 * Odt pattern for accesses targeting rank 1. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl2;		/*
+					 * Byte offset 0x76, CSR Addr 0x5403b, Direction=In
+					 * Odt pattern for accesses targeting rank 2. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl3;		/*
+					 * Byte offset 0x77, CSR Addr 0x5403b, Direction=In
+					 * Odt pattern for accesses targeting rank 3. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl4;		/*
+					 * Byte offset 0x78, CSR Addr 0x5403c, Direction=In
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t acsmodtctrl5;		/*
+					 * Byte offset 0x79, CSR Addr 0x5403c, Direction=In
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t acsmodtctrl6;		/*
+					 * Byte offset 0x7a, CSR Addr 0x5403d, Direction=In
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t acsmodtctrl7;		/*
+					 * Byte offset 0x7b, CSR Addr 0x5403d, Direction=In
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved7c;		/*
+					 * Byte offset 0x7c, CSR Addr 0x5403e, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved7d;		/*
+					 * Byte offset 0x7d, CSR Addr 0x5403e, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved7e;		/*
+					 * Byte offset 0x7e, CSR Addr 0x5403f, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved7f;		/*
+					 * Byte offset 0x7f, CSR Addr 0x5403f, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved80;		/*
+					 * Byte offset 0x80, CSR Addr 0x54040, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved81;		/*
+					 * Byte offset 0x81, CSR Addr 0x54040, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved82;		/*
+					 * Byte offset 0x82, CSR Addr 0x54041, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved83;		/*
+					 * Byte offset 0x83, CSR Addr 0x54041, Direction=N/A
+					 * This field is reserved and must be programmed to 0x00.
+					 */
+	uint8_t reserved84;		/* Byte offset 0x84, CSR Addr 0x54042, Direction=N/A */
+	uint8_t reserved85;		/* Byte offset 0x85, CSR Addr 0x54042, Direction=N/A */
+	uint8_t reserved86;		/* Byte offset 0x86, CSR Addr 0x54043, Direction=N/A */
+	uint8_t reserved87;		/* Byte offset 0x87, CSR Addr 0x54043, Direction=N/A */
+	uint8_t reserved88;		/* Byte offset 0x88, CSR Addr 0x54044, Direction=N/A */
+	uint8_t reserved89;		/* Byte offset 0x89, CSR Addr 0x54044, Direction=N/A */
+	uint8_t reserved8a;		/* Byte offset 0x8a, CSR Addr 0x54045, Direction=N/A */
+	uint8_t reserved8b;		/* Byte offset 0x8b, CSR Addr 0x54045, Direction=N/A */
+	uint8_t reserved8c;		/* Byte offset 0x8c, CSR Addr 0x54046, Direction=N/A */
+	uint8_t reserved8d;		/* Byte offset 0x8d, CSR Addr 0x54046, Direction=N/A */
+	uint8_t reserved8e;		/* Byte offset 0x8e, CSR Addr 0x54047, Direction=N/A */
+	uint8_t reserved8f;		/* Byte offset 0x8f, CSR Addr 0x54047, Direction=N/A */
+	uint8_t reserved90;		/* Byte offset 0x90, CSR Addr 0x54048, Direction=N/A */
+	uint8_t reserved91;		/* Byte offset 0x91, CSR Addr 0x54048, Direction=N/A */
+	uint8_t reserved92;		/* Byte offset 0x92, CSR Addr 0x54049, Direction=N/A */
+	uint8_t reserved93;		/* Byte offset 0x93, CSR Addr 0x54049, Direction=N/A */
+	uint8_t reserved94;		/* Byte offset 0x94, CSR Addr 0x5404a, Direction=N/A */
+	uint8_t reserved95;		/* Byte offset 0x95, CSR Addr 0x5404a, Direction=N/A */
+	uint8_t reserved96;		/* Byte offset 0x96, CSR Addr 0x5404b, Direction=N/A */
+	uint8_t reserved97;		/* Byte offset 0x97, CSR Addr 0x5404b, Direction=N/A */
+	uint8_t reserved98;		/* Byte offset 0x98, CSR Addr 0x5404c, Direction=N/A */
+	uint8_t reserved99;		/* Byte offset 0x99, CSR Addr 0x5404c, Direction=N/A */
+	uint8_t reserved9a;		/* Byte offset 0x9a, CSR Addr 0x5404d, Direction=N/A */
+	uint8_t reserved9b;		/* Byte offset 0x9b, CSR Addr 0x5404d, Direction=N/A */
+	uint8_t reserved9c;		/* Byte offset 0x9c, CSR Addr 0x5404e, Direction=N/A */
+	uint8_t reserved9d;		/* Byte offset 0x9d, CSR Addr 0x5404e, Direction=N/A */
+	uint8_t reserved9e;		/* Byte offset 0x9e, CSR Addr 0x5404f, Direction=N/A */
+	uint8_t reserved9f;		/* Byte offset 0x9f, CSR Addr 0x5404f, Direction=N/A */
+	uint8_t reserveda0;		/* Byte offset 0xa0, CSR Addr 0x54050, Direction=N/A */
+	uint8_t reserveda1;		/* Byte offset 0xa1, CSR Addr 0x54050, Direction=N/A */
+	uint8_t reserveda2;		/* Byte offset 0xa2, CSR Addr 0x54051, Direction=N/A */
+	uint8_t reserveda3;		/* Byte offset 0xa3, CSR Addr 0x54051, Direction=N/A */
+} __packed __aligned(2);
+
+#endif /* MNPMUSRAMMSGBLOCK_DDR3_H */
diff --git a/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr4.h b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr4.h
new file mode 100644
index 00000000..384650e4
--- /dev/null
+++ b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_ddr4.h
@@ -0,0 +1,2203 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MNPMUSRAMMSGBLOCK_DDR4_H
+#define MNPMUSRAMMSGBLOCK_DDR4_H
+
+/* DDR4U_1D training firmware message block structure
+ *
+ * Please refer to the Training Firmware App Note for futher information about
+ * the usage for Message Block.
+ */
+struct pmu_smb_ddr_1d {
+	uint8_t reserved00;		/*
+					 * Byte offset 0x00, CSR Addr 0x54000, Direction=In
+					 * reserved00[0:4] RFU, must be zero
+					 *
+					 * reserved00[5] = Train vrefDAC0 During Read Deskew
+					 *   0x1 = Read Deskew will begin by enabling and roughly
+					 *   training the phy's per-lane reference voltages.
+					 *   Training the vrefDACs CSRs will increase the maximum 1D
+					 *   training time by around half a millisecond, but will
+					 *   improve 1D training accuracy on systems with
+					 *   significant voltage-offsets between lane read eyes.
+					 *   0x0 = Read Deskew will assume the messageblock's
+					 *   phyVref setting will work for all lanes.
+					 *
+					 * reserved00[6] = Enable High Effort WrDQ1D
+					 *   0x1 = WrDQ1D will conditionally retry training at
+					 *   several extra RxClkDly Timings. This will increase the
+					 *   maximum 1D training time by up to 4 extra iterations of
+					 *   WrDQ1D. This is only required in systems that suffer
+					 *   from very large, asymmetric eye-collapse when receiving
+					 *   PRBS patterns.
+					 *   0x0 = WrDQ1D assume rxClkDly values found by SI
+					 *   Friendly RdDqs1D will work for receiving PRBS patterns
+					 *
+					 * reserved00[7] = Optimize for the special hard macros in
+					 * TSMC28.
+					 *   0x1 = set if the phy being trained was manufactured in
+					 *   any TSMC28 process node.
+					 *   0x0 = otherwise, when not training a TSMC28 phy, leave
+					 *   this field as 0.
+					 */
+	uint8_t msgmisc;		/*
+					 * Byte offset 0x01, CSR Addr 0x54000, Direction=In
+					 * Contains various global options for training.
+					 *
+					 * Bit fields:
+					 *
+					 * msgmisc[0] = MTESTEnable
+					 *   0x1 = Pulse primary digital test output bump at the end
+					 *   of each major training stage. This enables observation
+					 *   of training stage completion by observing the digital
+					 *   test output.
+					 *   0x0 = Do not pulse primary digital test output bump
+					 *
+					 * msgmisc[1] = SimulationOnlyReset
+					 *   0x1 = Verilog only simulation option to shorten
+					 *   duration of DRAM reset pulse length to 1ns.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use reset pulse length specified by JEDEC
+					 *   standard.
+					 *
+					 * msgmisc[2] = SimulationOnlyTraining
+					 *   0x1 = Verilog only simulation option to shorten the
+					 *   duration of the training steps by performing fewer
+					 *   iterations.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use standard training duration.
+					 *
+					 * msgmisc[3] = RFU, must be zero
+					 *   0x1 = Program user characterized Vref DQ values per
+					 *   DDR4 DRAM device. The message block vrefdqr*nib* fields
+					 *   must be populated with the desired per device Vref DQs
+					 *   when using this option. Note: this option is not
+					 *   applicable in 2D training because these values are
+					 *   explicitly trained in 2D.
+					 *   0x0 = Program Vref DQ for all DDR4 devices with the
+					 *   single value provided in mr6 message block field
+					 *
+					 * msgmisc[4] = Suppress streaming messages, including
+					 * assertions, regardless of hdtctrl setting.
+					 * Stage Completion messages, as well as training completion
+					 * and error messages are still sent depending on hdtctrl
+					 * setting.
+					 *
+					 * msgmisc[5] = PerByteMaxRdLat
+					 *   0x1 = Each DBYTE will return dfi_rddata_valid at the
+					 *   lowest possible latency. This may result in unaligned
+					 *   data between bytes to be returned to the DFI.
+					 *   0x0 = Every DBYTE will return dfi_rddata_valid
+					 *   simultaneously. This will ensure that data bytes will
+					 *   return aligned accesses to the DFI.
+					 *
+					 * msgmisc[6] = PartialRank (DDR3 UDIMM and DDR4 UDIMM only,
+					 * otherwise RFU, must be zero)
+					 *   0x1 = Support rank populated with a subset of byte, but
+					 *   where even-odd pair of rank support all the byte
+					 *   0x0 = All rank populated with all the byte (tyical
+					 *   configuration)
+					 *
+					 * msgmisc[7] RFU, must be zero
+					 *
+					 * Notes:
+					 *
+					 * - SimulationOnlyReset and SimulationOnlyTraining can be
+					 *   used to speed up simulation run times, and must never
+					 *   be used in real silicon. Some VIPs may have checks on
+					 *   DRAM reset parameters that may need to be disabled when
+					 *   using SimulationOnlyReset.
+					 */
+	uint16_t pmurevision;		/*
+					 * Byte offset 0x02, CSR Addr 0x54001, Direction=Out
+					 * PMU firmware revision ID
+					 * After training is run, this address will contain the
+					 * revision ID of the firmware.
+					 * Please reference this revision ID when filing support
+					 * cases.
+					 */
+	uint8_t pstate;			/*
+					 * Byte offset 0x04, CSR Addr 0x54002, Direction=In
+					 * Must be set to the target pstate to be trained
+					 *   0x0 = pstate 0
+					 *   0x1 = pstate 1
+					 *   0x2 = pstate 2
+					 *   0x3 = pstate 3
+					 *   All other encodings are reserved
+					 */
+	uint8_t pllbypassen;		/*
+					 * Byte offset 0x05, CSR Addr 0x54002, Direction=In
+					 * Set according to whether target pstate uses PHY PLL
+					 * bypass
+					 *   0x0 = PHY PLL is enabled for target pstate
+					 *   0x1 = PHY PLL is bypassed for target pstate
+					 */
+	uint16_t dramfreq;		/*
+					 * Byte offset 0x06, CSR Addr 0x54003, Direction=In
+					 * DDR data rate for the target pstate in units of MT/s.
+					 * For example enter 0x0640 for DDR1600.
+					 */
+	uint8_t dfifreqratio;		/*
+					 * Byte offset 0x08, CSR Addr 0x54004, Direction=In
+					 * Frequency ratio betwen DfiCtlClk and SDRAM memclk.
+					 *   0x1 = 1:1
+					 *   0x2 = 1:2
+					 *   0x4 = 1:4
+					 */
+	uint8_t bpznresval;		/*
+					 * Byte offset 0x09, CSR Addr 0x54004, Direction=In
+					 * Overwrite the value of precision resistor connected to
+					 * Phy BP_ZN
+					 *   0x00 = Do not program. Use current CSR value.
+					 *   0xf0 = 240 Ohm
+					 *   0x78 = 120 Ohm
+					 *   0x28 = 40 Ohm
+					 *   All other values are reserved.
+					 * It is recommended to set this to 0x00.
+					 */
+	uint8_t phyodtimpedance;	/*
+					 * Byte offset 0x0a, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the termination impedance in ohms
+					 * used by PHY during reads.
+					 *
+					 * 0x0 = Firmware skips programming (must be manually
+					 * programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal termination impedance values.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must determine the correct value
+					 * through SI simulation or other methods.
+					 */
+	uint8_t phydrvimpedance;	/*
+					 * Byte offset 0x0b, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the driver impedance in ohms used
+					 * by PHY during writes for all DBYTE drivers
+					 * (DQ/DM/DBI/DQS).
+					 *
+					 *   0x0 = Firmware skips programming (must be manually
+					 *   programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal R_on driver impedance values.
+					 *
+					 * For digital simulation, any value can be used that is not
+					 * Hi-Z. For silicon, the users must determine the correct
+					 * value through SI simulation or other methods.
+					 */
+	uint8_t phyvref;		/*
+					 * Byte offset 0x0c, CSR Addr 0x54006, Direction=In
+					 * Must be programmed with the Vref level to be used by the
+					 * PHY during reads
+					 *
+					 * The units of this field are a percentage of VDDQ
+					 * according to the following equation:
+					 *
+					 * Receiver Vref = VDDQ*phyvref[6:0]/128
+					 *
+					 * For example to set Vref at 0.75*VDDQ, set this field to
+					 * 0x60.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must calculate the analytical Vref by
+					 * using the impedances, terminations, and series resistance
+					 * present in the system.
+					 */
+	uint8_t dramtype;		/*
+					 * Byte offset 0x0d, CSR Addr 0x54006, Direction=In
+					 * Module Type:
+					 *   0x01 = Reserved
+					 *   0x02 = DDR4 unbuffered
+					 *   0x03 = Reserved
+					 *   0x04 = Reserved
+					 *   0x05 = Reserved
+					 */
+	uint8_t disableddbyte;		/*
+					 * Byte offset 0x0e, CSR Addr 0x54007, Direction=In
+					 * Bitmap to indicate which Dbyte are not connected (for
+					 * DByte 0 to 7):
+					 * Set disableddbyte[i] to 1 only to specify that DByte is
+					 * not need to be trained (DByte 8 can be disabled via
+					 * enableddqs setting)
+					 */
+	uint8_t enableddqs;		/*
+					 * Byte offset 0x0f, CSR Addr 0x54007, Direction=In
+					 * Total number of DQ bits enabled in PHY
+					 */
+	uint8_t cspresent;		/*
+					 * Byte offset 0x10, CSR Addr 0x54008, Direction=In
+					 * Indicates presence of DRAM at each chip select for PHY.
+					 * Each bit corresponds to a logical CS.
+					 *
+					 * If the bit is set to 1, the CS is connected to DRAM.
+					 * If the bit is set to 0, the CS is not connected to DRAM.
+					 *
+					 * cspresent[0] = CS0 is populated with DRAM
+					 * cspresent[1] = CS1 is populated with DRAM
+					 * cspresent[2] = CS2 is populated with DRAM
+					 * cspresent[3] = CS3 is populated with DRAM
+					 * cspresent[7:4] = Reserved (must be programmed to 0)
+					 */
+	uint8_t cspresentd0;		/*
+					 * Byte offset 0x11, CSR Addr 0x54008, Direction=In
+					 * The CS signals from field cspresent that are routed to
+					 * DIMM connector 0
+					 */
+	uint8_t cspresentd1;		/*
+					 * Byte offset 0x12, CSR Addr 0x54009, Direction=In
+					 * The CS signals from field cspresent that are routed to
+					 * DIMM connector 1
+					 */
+	uint8_t addrmirror;		/*
+					 * Byte offset 0x13, CSR Addr 0x54009, Direction=In
+					 * Corresponds to CS[3:0]
+					 *   1 = Address Mirror.
+					 *   0 = No Address Mirror.
+					 */
+	uint8_t cstestfail;		/*
+					 * Byte offset 0x14, CSR Addr 0x5400a, Direction=Out
+					 * This field will be set if training fails on any rank.
+					 *   0x0 = No failures
+					 *   non-zero = one or more ranks failed training
+					 */
+	uint8_t phycfg;			/*
+					 * Byte offset 0x15, CSR Addr 0x5400a, Direction=In
+					 * Additional mode bits.
+					 *
+					 * Bit fields:
+					 * [0] SlowAccessMode:
+					 *   1 = 2T Address Timing.
+					 *   0 = 1T Address Timing.
+					 * [7-1] RFU, must be zero
+					 *
+					 * WARNING: In case of DDR4 Geardown Mode (mr3[A3] == 1),
+					 * phycfg[0] must be 0.
+					 */
+	uint16_t sequencectrl;		/*
+					 * Byte offset 0x16, CSR Addr 0x5400b, Direction=In
+					 * Controls the training steps to be run. Each bit
+					 * corresponds to a training step.
+					 *
+					 * If the bit is set to 1, the training step will run.
+					 * If the bit is set to 0, the training step will be
+					 * skipped.
+					 *
+					 * Training step to bit mapping:
+					 * sequencectrl[0] = Run DevInit - Device/phy
+					 *		     initialization. Should always be set.
+					 * sequencectrl[1] = Run WrLvl - Write leveling
+					 * sequencectrl[2] = Run RxEn - Read gate training
+					 * sequencectrl[3] = Run RdDQS1D - 1d read dqs training
+					 * sequencectrl[4] = Run WrDQ1D - 1d write dq training
+					 * sequencectrl[5] = RFU, must be zero
+					 * sequencectrl[6] = RFU, must be zero
+					 * sequencectrl[7] = RFU, must be zero
+					 * sequencectrl[8] = Run RdDeskew - Per lane read dq deskew
+					 *		     training
+					 * sequencectrl[9] = Run MxRdLat - Max read latency training
+					 * sequencectrl[10] = Run Reserved
+					 * sequencectrl[11] = Run Reserved
+					 * sequencectrl[12] = Run Reserved
+					 * sequencectrl[13] = Run Reserved
+					 * sequencectrl[15-14] = RFU, must be zero
+					 */
+	uint8_t hdtctrl;		/*
+					 * Byte offset 0x18, CSR Addr 0x5400c, Direction=In
+					 * To control the total number of debug messages, a
+					 * verbosity subfield (hdtctrl, Hardware Debug Trace
+					 * Control) exists in the message block. Every message has a
+					 * verbosity level associated with it, and as the hdtctrl
+					 * value is increased, less important s messages stop being
+					 * sent through the mailboxes. The meanings of several major
+					 * hdtctrl thresholds are explained below:
+					 *
+					 *   0x04 = Maximal debug messages (e.g., Eye contours)
+					 *   0x05 = Detailed debug messages (e.g. Eye delays)
+					 *   0x0A = Coarse debug messages (e.g. rank information)
+					 *   0xC8 = Stage completion
+					 *   0xC9 = Assertion messages
+					 *   0xFF = Firmware completion messages only
+					 */
+	uint8_t reserved19;		/* Byte offset 0x19, CSR Addr 0x5400c, Direction=N/A */
+	uint8_t reserved1a;		/* Byte offset 0x1a, CSR Addr 0x5400d, Direction=N/A */
+	uint8_t share2dvrefresult;	/*
+					 * Byte offset 0x1b, CSR Addr 0x5400d, Direction=In
+					 * Bitmap that designates the phy's vref source for every
+					 * pstate
+					 * If share2dvrefresult[x] = 0, then after 2D training,
+					 * pstate x will continue using the phyVref provided in
+					 * pstate x's 1D messageblock.
+					 * If share2dvrefresult[x] = 1, then after 2D training,
+					 * pstate x will use the per-lane VrefDAC0/1 CSRs trained by
+					 * 2d training.
+					 */
+	uint8_t reserved1c;		/* Byte offset 0x1c, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1d;		/* Byte offset 0x1d, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1e;		/*
+					 * Byte offset 0x1e, CSR Addr 0x5400f, Direction=In
+					 * Input for constraining the range of vref(DQ) values
+					 * training will collect data for, usually reducing training
+					 * time. However, too large of a voltage range may cause
+					 * longer 2D training times while too small of a voltage
+					 * range may truncate passing regions. When in doubt, leave
+					 * this field set to 0.
+					 * Used by 2D training in: Rd2D, Wr2D
+					 *
+					 * reserved1E[0-3]: Rd2D Voltage Range
+					 *   0 = Training will search all phy vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from phyVref
+					 *   2 = limit to +/-4 %VDDQ from phyVref
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from phyVref
+					 *
+					 * reserved1E[4-7]: Wr2D Voltage Range
+					 *   0 = Training will search all dram vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from mr6
+					 *   2 = limit to +/-4 %VDDQ from mr6
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from mr6
+					 */
+	uint8_t reserved1f;		/*
+					 * Byte offset 0x1f, CSR Addr 0x5400f, Direction=In
+					 * Extended training option:
+					 *
+					 * reserved1F[1:0]: Configured RxClkDly offset try during
+					 * WrDq1D high-effort (i.e., when reserved00[6] is set)
+					 *   0: -8, +8, -16, +16
+					 *   1: -4, +4, -8, +8, -12, +12, -16, +16
+					 *   2: -2, +2, -4, +4, -6, +6, -8, +8
+					 *   3: -2, +2, -4, +4, -6, +6, -8, +8, -10, +10, -12, +12,
+					 *      -14, +14, -16, +16
+					 *
+					 * reserved1F[2]: When set, execute again WrDq1D after
+					 * RdDqs1D PRBS
+					 * reserved1F[3]: When set redo RdDeskew with PRBS after
+					 * (first) WrDqs1D
+					 * reserved1F[7:4]: This field is reserved and must be
+					 * programmed to 0x00.
+					 */
+	uint8_t reserved20;		/*
+					 * Byte offset 0x20, CSR Addr 0x54010, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for Reserved:
+					 * Reserved MREP assume raising edge is found when
+					 * reserved20[3:0]+3 consecutive 1 are received during MREP
+					 * fine delay swept; reserved20[6:0] thus permits to
+					 * increase tolerance for noisy system. And if reserved20[7]
+					 * is set, MREP training is failing if no raising edge is
+					 * found (otherwise the raising edge is assume close to
+					 * delay 0).
+					 */
+	uint8_t reserved21;		/*
+					 * Byte offset 0x21, CSR Addr 0x54010, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for Reserved:
+					 * Reserved DWL assume raising edge is found when
+					 * reserved21[3:0]+3 consecutive 1 are received during DWL
+					 * fine delay swept; reserved21[6:0] thus permits to
+					 * increase tolerance for noisy system. And if reserved21[7]
+					 * is set, DWL training is failing if no raising edge is
+					 * found (otherwise the raising edge is assume close to
+					 * delay 0).
+					 */
+	uint16_t phyconfigoverride;	/*
+					 * Byte offset 0x22, CSR Addr 0x54011, Direction=In
+					 * Override PhyConfig csr.
+					 *   0x0: Use hardware csr value for PhyConfing
+					 *   (recommended)
+					 *   Other values: Use value for PhyConfig instead of
+					 *   Hardware value.
+					 */
+	uint8_t dfimrlmargin;		/*
+					 * Byte offset 0x24, CSR Addr 0x54012, Direction=In
+					 * Margin added to smallest passing trained DFI Max Read
+					 * Latency value, in units of DFI clocks. Recommended to be
+					 * >= 1.
+					 */
+	int8_t cdd_rr_3_2;		/*
+					 * Byte offset 0x25, CSR Addr 0x54012, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 2.
+					 */
+	int8_t cdd_rr_3_1;		/*
+					 * Byte offset 0x26, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 1.
+					 */
+	int8_t cdd_rr_3_0;		/*
+					 * Byte offset 0x27, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 3 to cs 0.
+					 */
+	int8_t cdd_rr_2_3;		/*
+					 * Byte offset 0x28, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 3.
+					 */
+	int8_t cdd_rr_2_1;		/*
+					 * Byte offset 0x29, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 1.
+					 */
+	int8_t cdd_rr_2_0;		/*
+					 * Byte offset 0x2a, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 2 to cs 0.
+					 */
+	int8_t cdd_rr_1_3;		/*
+					 * Byte offset 0x2b, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 3.
+					 */
+	int8_t cdd_rr_1_2;		/*
+					 * Byte offset 0x2c, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 2.
+					 */
+	int8_t cdd_rr_1_0;		/*
+					 * Byte offset 0x2d, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 0.
+					 */
+	int8_t cdd_rr_0_3;		/*
+					 * Byte offset 0x2e, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 3.
+					 */
+	int8_t cdd_rr_0_2;		/*
+					 * Byte offset 0x2f, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 2.
+					 */
+	int8_t cdd_rr_0_1;		/*
+					 * Byte offset 0x30, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 1.
+					 */
+	int8_t cdd_ww_3_2;		/*
+					 * Byte offset 0x31, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_3_1;		/*
+					 * Byte offset 0x32, CSR Addr 0x54019, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 1.
+					 */
+	int8_t cdd_ww_3_0;		/*
+					 * Byte offset 0x33, CSR Addr 0x54019, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 3 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_2_3;		/*
+					 * Byte offset 0x34, CSR Addr 0x5401a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_2_1;		/*
+					 * Byte offset 0x35, CSR Addr 0x5401a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 1.
+					 */
+	int8_t cdd_ww_2_0;		/*
+					 * Byte offset 0x36, CSR Addr 0x5401b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 2 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_1_3;		/*
+					 * Byte offset 0x37, CSR Addr 0x5401b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_1_2;		/*
+					 * Byte offset 0x38, CSR Addr 0x5401c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_1_0;		/*
+					 * Byte offset 0x39, CSR Addr 0x5401c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 0.
+					 */
+	int8_t cdd_ww_0_3;		/*
+					 * Byte offset 0x3a, CSR Addr 0x5401d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 3.
+					 */
+	int8_t cdd_ww_0_2;		/*
+					 * Byte offset 0x3b, CSR Addr 0x5401d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 2.
+					 */
+	int8_t cdd_ww_0_1;		/*
+					 * Byte offset 0x3c, CSR Addr 0x5401e, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 1.
+					 */
+	int8_t cdd_rw_3_3;		/*
+					 * Byte offset 0x3d, CSR Addr 0x5401e, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_3_2;		/*
+					 * Byte offset 0x3e, CSR Addr 0x5401f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_3_1;		/*
+					 * Byte offset 0x3f, CSR Addr 0x5401f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_3_0;		/*
+					 * Byte offset 0x40, CSR Addr 0x54020, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 3 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_2_3;		/*
+					 * Byte offset 0x41, CSR Addr 0x54020, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_2_2;		/*
+					 * Byte offset 0x42, CSR Addr 0x54021, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_2_1;		/*
+					 * Byte offset 0x43, CSR Addr 0x54021, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_2_0;		/*
+					 * Byte offset 0x44, CSR Addr 0x54022, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 2 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_1_3;		/*
+					 * Byte offset 0x45, CSR Addr 0x54022, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_1_2;		/*
+					 * Byte offset 0x46, CSR Addr 0x54023, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_1_1;		/*
+					 * Byte offset 0x47, CSR Addr 0x54023, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_1_0;		/*
+					 * Byte offset 0x48, CSR Addr 0x54024, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to
+					 * cs 0.
+					 */
+	int8_t cdd_rw_0_3;		/*
+					 * Byte offset 0x49, CSR Addr 0x54024, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 3.
+					 */
+	int8_t cdd_rw_0_2;		/*
+					 * Byte offset 0x4a, CSR Addr 0x54025, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 2.
+					 */
+	int8_t cdd_rw_0_1;		/*
+					 * Byte offset 0x4b, CSR Addr 0x54025, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 1.
+					 */
+	int8_t cdd_rw_0_0;		/*
+					 * Byte offset 0x4c, CSR Addr 0x54026, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_3_3;		/*
+					 * Byte offset 0x4d, CSR Addr 0x54026, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_3_2;		/*
+					 * Byte offset 0x4e, CSR Addr 0x54027, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_3_1;		/*
+					 * Byte offset 0x4f, CSR Addr 0x54027, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_3_0;		/*
+					 * Byte offset 0x50, CSR Addr 0x54028, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 3 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_2_3;		/*
+					 * Byte offset 0x51, CSR Addr 0x54028, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_2_2;		/*
+					 * Byte offset 0x52, CSR Addr 0x54029, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_2_1;		/*
+					 * Byte offset 0x53, CSR Addr 0x54029, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_2_0;		/*
+					 * Byte offset 0x54, CSR Addr 0x5402a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 2 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_1_3;		/*
+					 * Byte offset 0x55, CSR Addr 0x5402a, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_1_2;		/*
+					 * Byte offset 0x56, CSR Addr 0x5402b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_1_1;		/*
+					 * Byte offset 0x57, CSR Addr 0x5402b, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_1_0;		/*
+					 * Byte offset 0x58, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to
+					 * cs 0.
+					 */
+	int8_t cdd_wr_0_3;		/*
+					 * Byte offset 0x59, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 3.
+					 */
+	int8_t cdd_wr_0_2;		/*
+					 * Byte offset 0x5a, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 2.
+					 */
+	int8_t cdd_wr_0_1;		/*
+					 * Byte offset 0x5b, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 1.
+					 */
+	int8_t cdd_wr_0_0;		/*
+					 * Byte offset 0x5c, CSR Addr 0x5402e, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to
+					 * cs 0.
+					 */
+	uint8_t reserved5d;		/*
+					 * Byte offset 0x5d, CSR Addr 0x5402e, Direction=In
+					 * This field is reserved and must be programmed to 0x00,
+					 * excepted for DDR4:
+					 * By default, if this parameter is 0, the offset applied at
+					 * the end of DDR4 RxEn training resulting in the trained
+					 * RxEnDly is 3/8 of the RX preamble width; if reserved5D is
+					 * non zero, this offset is used instead (in fine step).
+					 */
+	uint16_t mr0;			/*
+					 * Byte offset 0x5e, CSR Addr 0x5402f, Direction=In
+					 * Value of DDR mode register mr0 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr1;			/*
+					 * Byte offset 0x60, CSR Addr 0x54030, Direction=In
+					 * Value of DDR mode register mr1 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr2;			/*
+					 * Byte offset 0x62, CSR Addr 0x54031, Direction=In
+					 * Value of DDR mode register mr2 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr3;			/*
+					 * Byte offset 0x64, CSR Addr 0x54032, Direction=In
+					 * Value of DDR mode register mr3 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr4;			/*
+					 * Byte offset 0x66, CSR Addr 0x54033, Direction=In
+					 * Value of DDR mode register mr4 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr5;			/*
+					 * Byte offset 0x68, CSR Addr 0x54034, Direction=In
+					 * Value of DDR mode register mr5 for all ranks for current
+					 * pstate.
+					 */
+	uint16_t mr6;			/*
+					 * Byte offset 0x6a, CSR Addr 0x54035, Direction=In
+					 * Value of DDR mode register mr6 for all ranks for current
+					 * pstate. Note: The initial VrefDq value and range must be
+					 * set in A6:A0.
+					 */
+	uint8_t x16present;		/*
+					 * Byte offset 0x6c, CSR Addr 0x54036, Direction=In
+					 * X16 device map. Corresponds to CS[3:0].
+					 * x16present[0] = CS0 is populated with X16 devices
+					 * x16present[1] = CS1 is populated with X16 devices
+					 * x16present[2] = CS2 is populated with X16 devices
+					 * x16present[3] = CS3 is populated with X16 devices
+					 * x16present[7:4] = Reserved (must be programmed to 0)
+					 *
+					 * Ranks may not contain mixed device types.
+					 */
+	uint8_t cssetupgddec;		/*
+					 * Byte offset 0x6d, CSR Addr 0x54036, Direction=In
+					 * controls timing of chip select signals when DDR4
+					 * gear-down mode is active
+					 *   0 - Leave delay of chip select timing group signal
+					 *   the same both before and after gear-down sync occurs
+					 *   1 - Add 1UI of delay to chip select timing group
+					 *   signals when geardown-mode is active. This allows CS
+					 *   signals to have equal setup and hold time in gear-down
+					 *   mode
+					 */
+	uint16_t rtt_nom_wr_park0;	/*
+					 * Byte offset 0x6e, CSR Addr 0x54037, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 0
+					 * DRAM:
+					 * rtt_nom_wr_park0[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park0[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 0
+					 * rtt_nom_wr_park0[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 0
+					 * rtt_nom_wr_park0[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 0
+					 */
+	uint16_t rtt_nom_wr_park1;	/*
+					 * Byte offset 0x70, CSR Addr 0x54038, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 1
+					 * DRAM:
+					 * rtt_nom_wr_park1[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park1[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 1
+					 * rtt_nom_wr_park1[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 1
+					 * rtt_nom_wr_park1[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 1
+					 */
+	uint16_t rtt_nom_wr_park2;	/*
+					 * Byte offset 0x72, CSR Addr 0x54039, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 2
+					 * DRAM:
+					 * rtt_nom_wr_park2[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park2[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 2
+					 * rtt_nom_wr_park2[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 2
+					 * rtt_nom_wr_park2[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 2
+					 */
+	uint16_t rtt_nom_wr_park3;	/*
+					 * Byte offset 0x74, CSR Addr 0x5403a, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 3
+					 * DRAM:
+					 * rtt_nom_wr_park3[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park3[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 3
+					 * rtt_nom_wr_park3[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 3
+					 * rtt_nom_wr_park3[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 3
+					 */
+	uint16_t rtt_nom_wr_park4;	/*
+					 * Byte offset 0x76, CSR Addr 0x5403b, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 4
+					 * DRAM:
+					 * rtt_nom_wr_park4[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park4[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 4
+					 * rtt_nom_wr_park4[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 4
+					 * rtt_nom_wr_park4[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 4
+					 */
+	uint16_t rtt_nom_wr_park5;	/*
+					 * Byte offset 0x78, CSR Addr 0x5403c, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 5
+					 * DRAM:
+					 * rtt_nom_wr_park5[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park5[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 5
+					 * rtt_nom_wr_park5[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 5
+					 * rtt_nom_wr_park5[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 5
+					 */
+	uint16_t rtt_nom_wr_park6;	/*
+					 * Byte offset 0x7a, CSR Addr 0x5403d, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 6
+					 * DRAM:
+					 * rtt_nom_wr_park6[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park6[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 6
+					 * rtt_nom_wr_park6[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 6
+					 * rtt_nom_wr_park6[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 6
+					 */
+	uint16_t rtt_nom_wr_park7;	/*
+					 * Byte offset 0x7c, CSR Addr 0x5403e, Direction=In
+					 * Optional RTT_NOM, RTT_WR and RTT_PARK values for rank 7
+					 * DRAM:
+					 * rtt_nom_wr_park7[0] = 1: Option is enable (otherwise,
+					 * remaining bit fields are don't care)
+					 * rtt_nom_wr_park7[5:3]: Optional RTT_NOM value to be used
+					 * in mr1[10:8] for rank 7
+					 * rtt_nom_wr_park7[11:9]: Optional RTT_WR value to be used
+					 * in mr2[11:9] for rank 7
+					 * rtt_nom_wr_park7[8:6]: Optional RTT_PARK value to be used
+					 * in mr5[8:6] for rank 7
+					 */
+	uint8_t acsmodtctrl0;		/*
+					 * Byte offset 0x7e, CSR Addr 0x5403f, Direction=In
+					 * Odt pattern for accesses targeting rank 0. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl1;		/*
+					 * Byte offset 0x7f, CSR Addr 0x5403f, Direction=In
+					 * Odt pattern for accesses targeting rank 1. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl2;		/*
+					 * Byte offset 0x80, CSR Addr 0x54040, Direction=In
+					 * Odt pattern for accesses targeting rank 2. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl3;		/*
+					 * Byte offset 0x81, CSR Addr 0x54040, Direction=In
+					 * Odt pattern for accesses targeting rank 3. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl4;		/*
+					 * Byte offset 0x82, CSR Addr 0x54041, Direction=In
+					 * Odt pattern for accesses targeting rank 4. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl5;		/*
+					 * Byte offset 0x83, CSR Addr 0x54041, Direction=In
+					 * Odt pattern for accesses targeting rank 5. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl6;		/*
+					 * Byte offset 0x84, CSR Addr 0x54042, Direction=In
+					 * Odt pattern for accesses targeting rank 6. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t acsmodtctrl7;		/*
+					 * Byte offset 0x85, CSR Addr 0x54042, Direction=In
+					 * Odt pattern for accesses targeting rank 7. [3:0] is used
+					 * for write ODT [7:4] is used for read ODT
+					 */
+	uint8_t vrefdqr0nib0;		/*
+					 * Byte offset 0x86, CSR Addr 0x54043, Direction=InOut
+					 * VrefDq for rank 0 nibble 0. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib1;		/*
+					 * Byte offset 0x87, CSR Addr 0x54043, Direction=InOut
+					 * VrefDq for rank 0 nibble 1. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib0 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib2;		/*
+					 * Byte offset 0x88, CSR Addr 0x54044, Direction=InOut
+					 * VrefDq for rank 0 nibble 2. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib0 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib3;		/*
+					 * Byte offset 0x89, CSR Addr 0x54044, Direction=InOut
+					 * VrefDq for rank 0 nibble 3. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib0 for x16 devices, or
+					 * vrefdqr0nib2 for x8 devices.
+					 */
+	uint8_t vrefdqr0nib4;		/*
+					 * Byte offset 0x8a, CSR Addr 0x54045, Direction=InOut
+					 * VrefDq for rank 0 nibble 4. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib5;		/*
+					 * Byte offset 0x8b, CSR Addr 0x54045, Direction=InOut
+					 * VrefDq for rank 0 nibble 5. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib4 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib6;		/*
+					 * Byte offset 0x8c, CSR Addr 0x54046, Direction=InOut
+					 * VrefDq for rank 0 nibble 6. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib4 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib7;		/*
+					 * Byte offset 0x8d, CSR Addr 0x54046, Direction=InOut
+					 * VrefDq for rank 0 nibble 7. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib4 for x16 devices,
+					 * or vrefdqr0nib6 for x8 devices.
+					 */
+	uint8_t vrefdqr0nib8;		/*
+					 * Byte offset 0x8e, CSR Addr 0x54047, Direction=InOut
+					 * VrefDq for rank 0 nibble 8. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib9;		/*
+					 * Byte offset 0x8f, CSR Addr 0x54047, Direction=InOut
+					 * VrefDq for rank 0 nibble 9. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib8 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib10;		/*
+					 * Byte offset 0x90, CSR Addr 0x54048, Direction=InOut
+					 * VrefDq for rank 0 nibble 10. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib8 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib11;		/*
+					 * Byte offset 0x91, CSR Addr 0x54048, Direction=InOut
+					 * VrefDq for rank 0 nibble 11. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib8 for x16 devices,
+					 * or vrefdqr0nib10 for x8 devices.
+					 */
+	uint8_t vrefdqr0nib12;		/*
+					 * Byte offset 0x92, CSR Addr 0x54049, Direction=InOut
+					 * VrefDq for rank 0 nibble 12. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib13;		/*
+					 * Byte offset 0x93, CSR Addr 0x54049, Direction=InOut
+					 * VrefDq for rank 0 nibble 13. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib12 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib14;		/*
+					 * Byte offset 0x94, CSR Addr 0x5404a, Direction=InOut
+					 * VrefDq for rank 0 nibble 14. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib12 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib15;		/*
+					 * Byte offset 0x95, CSR Addr 0x5404a, Direction=InOut
+					 * VrefDq for rank 0 nibble 15. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib12 for x16 devices,
+					 * or vrefdqr0nib14 for x8 devices.
+					 */
+	uint8_t vrefdqr0nib16;		/*
+					 * Byte offset 0x96, CSR Addr 0x5404b, Direction=InOut
+					 * VrefDq for rank 0 nibble 16. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr0nib17;		/*
+					 * Byte offset 0x97, CSR Addr 0x5404b, Direction=InOut
+					 * VrefDq for rank 0 nibble 17. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib16 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr0nib18;		/*
+					 * Byte offset 0x98, CSR Addr 0x5404c, Direction=InOut
+					 * VrefDq for rank 0 nibble 18. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib16 for x16 devices.
+					 */
+	uint8_t vrefdqr0nib19;		/*
+					 * Byte offset 0x99, CSR Addr 0x5404c, Direction=InOut
+					 * VrefDq for rank 0 nibble 19. Specifies mr6[6:0].
+					 * Identical to vrefdqr0nib16 for x16 devices,
+					 * or vrefdqr0nib18 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib0;		/*
+					 * Byte offset 0x9a, CSR Addr 0x5404d, Direction=InOut
+					 * VrefDq for rank 1 nibble 0. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib1;		/*
+					 * Byte offset 0x9b, CSR Addr 0x5404d, Direction=InOut
+					 * VrefDq for rank 1 nibble 1. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib0 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib2;		/*
+					 * Byte offset 0x9c, CSR Addr 0x5404e, Direction=InOut
+					 * VrefDq for rank 1 nibble 2. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib0 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib3;		/*
+					 * Byte offset 0x9d, CSR Addr 0x5404e, Direction=InOut
+					 * VrefDq for rank 1 nibble 3. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib0 for x16 devices,
+					 * or vrefdqr1nib2 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib4;		/*
+					 * Byte offset 0x9e, CSR Addr 0x5404f, Direction=InOut
+					 * VrefDq for rank 1 nibble 4. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib5;		/*
+					 * Byte offset 0x9f, CSR Addr 0x5404f, Direction=InOut
+					 * VrefDq for rank 1 nibble 5. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib4 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib6;		/*
+					 * Byte offset 0xa0, CSR Addr 0x54050, Direction=InOut
+					 * VrefDq for rank 1 nibble 6. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib4 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib7;		/*
+					 * Byte offset 0xa1, CSR Addr 0x54050, Direction=InOut
+					 * VrefDq for rank 1 nibble 7. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib4 for x16 devices,
+					 * or vrefdqr1nib6 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib8;		/*
+					 * Byte offset 0xa2, CSR Addr 0x54051, Direction=InOut
+					 * VrefDq for rank 1 nibble 8. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib9;		/*
+					 * Byte offset 0xa3, CSR Addr 0x54051, Direction=InOut
+					 * VrefDq for rank 1 nibble 9. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib8 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib10;		/*
+					 * Byte offset 0xa4, CSR Addr 0x54052, Direction=InOut
+					 * VrefDq for rank 1 nibble 10. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib8 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib11;		/*
+					 * Byte offset 0xa5, CSR Addr 0x54052, Direction=InOut
+					 * VrefDq for rank 1 nibble 11. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib8 for x16 devices,
+					 * or vrefdqr1nib10 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib12;		/*
+					 * Byte offset 0xa6, CSR Addr 0x54053, Direction=InOut
+					 * VrefDq for rank 1 nibble 12. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib13;		/*
+					 * Byte offset 0xa7, CSR Addr 0x54053, Direction=InOut
+					 * VrefDq for rank 1 nibble 13. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib12 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib14;		/*
+					 * Byte offset 0xa8, CSR Addr 0x54054, Direction=InOut
+					 * VrefDq for rank 1 nibble 14. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib12 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib15;		/*
+					 * Byte offset 0xa9, CSR Addr 0x54054, Direction=InOut
+					 * VrefDq for rank 1 nibble 15. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib12 for x16 devices,
+					 * or vrefdqr1nib14 for x8 devices.
+					 */
+	uint8_t vrefdqr1nib16;		/*
+					 * Byte offset 0xaa, CSR Addr 0x54055, Direction=InOut
+					 * VrefDq for rank 1 nibble 16. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr1nib17;		/*
+					 * Byte offset 0xab, CSR Addr 0x54055, Direction=InOut
+					 * VrefDq for rank 1 nibble 17. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib16 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr1nib18;		/*
+					 * Byte offset 0xac, CSR Addr 0x54056, Direction=InOut
+					 * VrefDq for rank 1 nibble 18. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib16 for x16 devices.
+					 */
+	uint8_t vrefdqr1nib19;		/*
+					 * Byte offset 0xad, CSR Addr 0x54056, Direction=InOut
+					 * VrefDq for rank 1 nibble 19. Specifies mr6[6:0].
+					 * Identical to vrefdqr1nib16 for x16 devices,
+					 * or vrefdqr1nib18 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib0;		/*
+					 * Byte offset 0xae, CSR Addr 0x54057, Direction=InOut
+					 * VrefDq for rank 2 nibble 0. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib1;		/*
+					 * Byte offset 0xaf, CSR Addr 0x54057, Direction=InOut
+					 * VrefDq for rank 2 nibble 1. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib0 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib2;		/*
+					 * Byte offset 0xb0, CSR Addr 0x54058, Direction=InOut
+					 * VrefDq for rank 2 nibble 2. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib0 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib3;		/*
+					 * Byte offset 0xb1, CSR Addr 0x54058, Direction=InOut
+					 * VrefDq for rank 2 nibble 3. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib0 for x16 devices,
+					 * or vrefdqr2nib2 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib4;		/*
+					 * Byte offset 0xb2, CSR Addr 0x54059, Direction=InOut
+					 * VrefDq for rank 2 nibble 4. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib5;		/*
+					 * Byte offset 0xb3, CSR Addr 0x54059, Direction=InOut
+					 * VrefDq for rank 2 nibble 5. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib4 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib6;		/*
+					 * Byte offset 0xb4, CSR Addr 0x5405a, Direction=InOut
+					 * VrefDq for rank 2 nibble 6. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib4 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib7;		/*
+					 * Byte offset 0xb5, CSR Addr 0x5405a, Direction=InOut
+					 * VrefDq for rank 2 nibble 7. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib4 for x16 devices,
+					 * or vrefdqr2nib6 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib8;		/*
+					 * Byte offset 0xb6, CSR Addr 0x5405b, Direction=InOut
+					 * VrefDq for rank 2 nibble 8. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib9;		/*
+					 * Byte offset 0xb7, CSR Addr 0x5405b, Direction=InOut
+					 * VrefDq for rank 2 nibble 9. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib8 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib10;		/*
+					 * Byte offset 0xb8, CSR Addr 0x5405c, Direction=InOut
+					 * VrefDq for rank 2 nibble 10. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib8 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib11;		/*
+					 * Byte offset 0xb9, CSR Addr 0x5405c, Direction=InOut
+					 * VrefDq for rank 2 nibble 11. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib8 for x16 devices,
+					 * or vrefdqr2nib10 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib12;		/*
+					 * Byte offset 0xba, CSR Addr 0x5405d, Direction=InOut
+					 * VrefDq for rank 2 nibble 12. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib13;		/*
+					 * Byte offset 0xbb, CSR Addr 0x5405d, Direction=InOut
+					 * VrefDq for rank 2 nibble 13. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib12 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib14;		/*
+					 * Byte offset 0xbc, CSR Addr 0x5405e, Direction=InOut
+					 * VrefDq for rank 2 nibble 14. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib12 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib15;		/*
+					 * Byte offset 0xbd, CSR Addr 0x5405e, Direction=InOut
+					 * VrefDq for rank 2 nibble 15. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib12 for x16 devices,
+					 * or vrefdqr2nib14 for x8 devices.
+					 */
+	uint8_t vrefdqr2nib16;		/*
+					 * Byte offset 0xbe, CSR Addr 0x5405f, Direction=InOut
+					 * VrefDq for rank 2 nibble 16. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr2nib17;		/*
+					 * Byte offset 0xbf, CSR Addr 0x5405f, Direction=InOut
+					 * VrefDq for rank 2 nibble 17. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib16 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr2nib18;		/*
+					 * Byte offset 0xc0, CSR Addr 0x54060, Direction=InOut
+					 * VrefDq for rank 2 nibble 18. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib16 for x16 devices.
+					 */
+	uint8_t vrefdqr2nib19;		/*
+					 * Byte offset 0xc1, CSR Addr 0x54060, Direction=InOut
+					 * VrefDq for rank 2 nibble 19. Specifies mr6[6:0].
+					 * Identical to vrefdqr2nib16 for x16 devices,
+					 * or vrefdqr2nib18 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib0;		/*
+					 * Byte offset 0xc2, CSR Addr 0x54061, Direction=InOut
+					 * VrefDq for rank 3 nibble 0. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib1;		/*
+					 * Byte offset 0xc3, CSR Addr 0x54061, Direction=InOut
+					 * VrefDq for rank 3 nibble 1. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib0 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib2;		/*
+					 * Byte offset 0xc4, CSR Addr 0x54062, Direction=InOut
+					 * VrefDq for rank 3 nibble 2. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib0 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib3;		/*
+					 * Byte offset 0xc5, CSR Addr 0x54062, Direction=InOut
+					 * VrefDq for rank 3 nibble 3. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib0 for x16 devices,
+					 * or vrefdqr3nib2 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib4;		/*
+					 * Byte offset 0xc6, CSR Addr 0x54063, Direction=InOut
+					 * VrefDq for rank 3 nibble 4. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib5;		/*
+					 * Byte offset 0xc7, CSR Addr 0x54063, Direction=InOut
+					 * VrefDq for rank 3 nibble 5. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib4 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib6;		/*
+					 * Byte offset 0xc8, CSR Addr 0x54064, Direction=InOut
+					 * VrefDq for rank 3 nibble 6. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib4 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib7;		/*
+					 * Byte offset 0xc9, CSR Addr 0x54064, Direction=InOut
+					 * VrefDq for rank 3 nibble 7. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib4 for x16 devices,
+					 * or vrefdqr3nib6 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib8;		/*
+					 * Byte offset 0xca, CSR Addr 0x54065, Direction=InOut
+					 * VrefDq for rank 3 nibble 8. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib9;		/*
+					 * Byte offset 0xcb, CSR Addr 0x54065, Direction=InOut
+					 * VrefDq for rank 3 nibble 9. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib8 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib10;		/*
+					 * Byte offset 0xcc, CSR Addr 0x54066, Direction=InOut
+					 * VrefDq for rank 3 nibble 10. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib8 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib11;		/*
+					 * Byte offset 0xcd, CSR Addr 0x54066, Direction=InOut
+					 * VrefDq for rank 3 nibble 11. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib8 for x16 devices,
+					 * or vrefdqr3nib10 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib12;		/*
+					 * Byte offset 0xce, CSR Addr 0x54067, Direction=InOut
+					 * VrefDq for rank 3 nibble 12. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib13;		/*
+					 * Byte offset 0xcf, CSR Addr 0x54067, Direction=InOut
+					 * VrefDq for rank 3 nibble 13. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib12 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib14;		/*
+					 * Byte offset 0xd0, CSR Addr 0x54068, Direction=InOut
+					 * VrefDq for rank 3 nibble 14. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib12 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib15;		/*
+					 * Byte offset 0xd1, CSR Addr 0x54068, Direction=InOut
+					 * VrefDq for rank 3 nibble 15. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib12 for x16 devices,
+					 * or vrefdqr3nib14 for x8 devices.
+					 */
+	uint8_t vrefdqr3nib16;		/*
+					 * Byte offset 0xd2, CSR Addr 0x54069, Direction=InOut
+					 * VrefDq for rank 3 nibble 16. Specifies mr6[6:0]
+					 */
+	uint8_t vrefdqr3nib17;		/*
+					 * Byte offset 0xd3, CSR Addr 0x54069, Direction=InOut
+					 * VrefDq for rank 3 nibble 17. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib16 for x8 or x16 devices.
+					 */
+	uint8_t vrefdqr3nib18;		/*
+					 * Byte offset 0xd4, CSR Addr 0x5406a, Direction=InOut
+					 * VrefDq for rank 3 nibble 18. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib16 for x16 devices.
+					 */
+	uint8_t vrefdqr3nib19;		/*
+					 * Byte offset 0xd5, CSR Addr 0x5406a, Direction=InOut
+					 * VrefDq for rank 3 nibble 19. Specifies mr6[6:0].
+					 * Identical to vrefdqr3nib16 for x16 devices,
+					 * or vrefdqr3nib18 for x8 devices.
+					 */
+	uint8_t reservedd6;		/* Byte offset 0xd6, CSR Addr 0x5406b, Direction=N/A */
+	uint8_t reservedd7;		/* Byte offset 0xd7, CSR Addr 0x5406b, Direction=N/A */
+	uint8_t reservedd8;		/* Byte offset 0xd8, CSR Addr 0x5406c, Direction=N/A */
+	uint8_t reservedd9;		/* Byte offset 0xd9, CSR Addr 0x5406c, Direction=N/A */
+	uint8_t reservedda;		/* Byte offset 0xda, CSR Addr 0x5406d, Direction=N/A */
+	uint8_t reserveddb;		/* Byte offset 0xdb, CSR Addr 0x5406d, Direction=N/A */
+	uint8_t reserveddc;		/* Byte offset 0xdc, CSR Addr 0x5406e, Direction=N/A */
+	uint8_t reserveddd;		/* Byte offset 0xdd, CSR Addr 0x5406e, Direction=N/A */
+	uint8_t reservedde;		/* Byte offset 0xde, CSR Addr 0x5406f, Direction=N/A */
+	uint8_t reserveddf;		/* Byte offset 0xdf, CSR Addr 0x5406f, Direction=N/A */
+	uint8_t reservede0;		/* Byte offset 0xe0, CSR Addr 0x54070, Direction=N/A */
+	uint8_t reservede1;		/* Byte offset 0xe1, CSR Addr 0x54070, Direction=N/A */
+	uint8_t reservede2;		/* Byte offset 0xe2, CSR Addr 0x54071, Direction=N/A */
+	uint8_t reservede3;		/* Byte offset 0xe3, CSR Addr 0x54071, Direction=N/A */
+	uint8_t reservede4;		/* Byte offset 0xe4, CSR Addr 0x54072, Direction=N/A */
+	uint8_t reservede5;		/* Byte offset 0xe5, CSR Addr 0x54072, Direction=N/A */
+	uint8_t reservede6;		/* Byte offset 0xe6, CSR Addr 0x54073, Direction=N/A */
+	uint8_t reservede7;		/* Byte offset 0xe7, CSR Addr 0x54073, Direction=N/A */
+	uint8_t reservede8;		/* Byte offset 0xe8, CSR Addr 0x54074, Direction=N/A */
+	uint8_t reservede9;		/* Byte offset 0xe9, CSR Addr 0x54074, Direction=N/A */
+	uint8_t reservedea;		/* Byte offset 0xea, CSR Addr 0x54075, Direction=N/A */
+	uint8_t reservedeb;		/* Byte offset 0xeb, CSR Addr 0x54075, Direction=N/A */
+	uint8_t reservedec;		/* Byte offset 0xec, CSR Addr 0x54076, Direction=N/A */
+	uint8_t reserveded;		/* Byte offset 0xed, CSR Addr 0x54076, Direction=N/A */
+	uint8_t reservedee;		/* Byte offset 0xee, CSR Addr 0x54077, Direction=N/A */
+	uint8_t reservedef;		/* Byte offset 0xef, CSR Addr 0x54077, Direction=N/A */
+	uint8_t reservedf0;		/* Byte offset 0xf0, CSR Addr 0x54078, Direction=N/A */
+	uint8_t reservedf1;		/* Byte offset 0xf1, CSR Addr 0x54078, Direction=N/A */
+	uint8_t reservedf2;		/* Byte offset 0xf2, CSR Addr 0x54079, Direction=N/A */
+	uint8_t reservedf3;		/* Byte offset 0xf3, CSR Addr 0x54079, Direction=N/A */
+	uint8_t reservedf4;		/* Byte offset 0xf4, CSR Addr 0x5407a, Direction=N/A */
+	uint8_t reservedf5;		/* Byte offset 0xf5, CSR Addr 0x5407a, Direction=N/A */
+	uint8_t reservedf6;		/* Byte offset 0xf6, CSR Addr 0x5407b, Direction=N/A */
+	uint8_t reservedf7;		/* Byte offset 0xf7, CSR Addr 0x5407b, Direction=N/A */
+	uint8_t reservedf8;		/* Byte offset 0xf8, CSR Addr 0x5407c, Direction=N/A */
+	uint8_t reservedf9;		/* Byte offset 0xf9, CSR Addr 0x5407c, Direction=N/A */
+	uint8_t reservedfa;		/* Byte offset 0xfa, CSR Addr 0x5407d, Direction=N/A */
+	uint8_t reservedfb;		/* Byte offset 0xfb, CSR Addr 0x5407d, Direction=N/A */
+	uint8_t reservedfc;		/* Byte offset 0xfc, CSR Addr 0x5407e, Direction=N/A */
+	uint8_t reservedfd;		/* Byte offset 0xfd, CSR Addr 0x5407e, Direction=N/A */
+	uint8_t reservedfe;		/* Byte offset 0xfe, CSR Addr 0x5407f, Direction=N/A */
+	uint8_t reservedff;		/* Byte offset 0xff, CSR Addr 0x5407f, Direction=N/A */
+	uint8_t reserved100;		/* Byte offset 0x100, CSR Addr 0x54080, Direction=N/A */
+	uint8_t reserved101;		/* Byte offset 0x101, CSR Addr 0x54080, Direction=N/A */
+	uint8_t reserved102;		/* Byte offset 0x102, CSR Addr 0x54081, Direction=N/A */
+	uint8_t reserved103;		/* Byte offset 0x103, CSR Addr 0x54081, Direction=N/A */
+	uint8_t reserved104;		/* Byte offset 0x104, CSR Addr 0x54082, Direction=N/A */
+	uint8_t reserved105;		/* Byte offset 0x105, CSR Addr 0x54082, Direction=N/A */
+	uint8_t reserved106;		/* Byte offset 0x106, CSR Addr 0x54083, Direction=N/A */
+	uint8_t reserved107;		/* Byte offset 0x107, CSR Addr 0x54083, Direction=N/A */
+	uint8_t reserved108;		/* Byte offset 0x108, CSR Addr 0x54084, Direction=N/A */
+	uint8_t reserved109;		/* Byte offset 0x109, CSR Addr 0x54084, Direction=N/A */
+	uint8_t reserved10a;		/* Byte offset 0x10a, CSR Addr 0x54085, Direction=N/A */
+	uint8_t reserved10b;		/* Byte offset 0x10b, CSR Addr 0x54085, Direction=N/A */
+	uint8_t reserved10c;		/* Byte offset 0x10c, CSR Addr 0x54086, Direction=N/A */
+	uint8_t reserved10d;		/* Byte offset 0x10d, CSR Addr 0x54086, Direction=N/A */
+	uint8_t reserved10e;		/* Byte offset 0x10e, CSR Addr 0x54087, Direction=N/A */
+	uint8_t reserved10f;		/* Byte offset 0x10f, CSR Addr 0x54087, Direction=N/A */
+	uint8_t reserved110;		/* Byte offset 0x110, CSR Addr 0x54088, Direction=N/A */
+	uint8_t reserved111;		/* Byte offset 0x111, CSR Addr 0x54088, Direction=N/A */
+	uint8_t reserved112;		/* Byte offset 0x112, CSR Addr 0x54089, Direction=N/A */
+	uint8_t reserved113;		/* Byte offset 0x113, CSR Addr 0x54089, Direction=N/A */
+	uint8_t reserved114;		/* Byte offset 0x114, CSR Addr 0x5408a, Direction=N/A */
+	uint8_t reserved115;		/* Byte offset 0x115, CSR Addr 0x5408a, Direction=N/A */
+	uint8_t reserved116;		/* Byte offset 0x116, CSR Addr 0x5408b, Direction=N/A */
+	uint8_t reserved117;		/* Byte offset 0x117, CSR Addr 0x5408b, Direction=N/A */
+	uint8_t reserved118;		/* Byte offset 0x118, CSR Addr 0x5408c, Direction=N/A */
+	uint8_t reserved119;		/* Byte offset 0x119, CSR Addr 0x5408c, Direction=N/A */
+	uint8_t reserved11a;		/* Byte offset 0x11a, CSR Addr 0x5408d, Direction=N/A */
+	uint8_t reserved11b;		/* Byte offset 0x11b, CSR Addr 0x5408d, Direction=N/A */
+	uint8_t reserved11c;		/* Byte offset 0x11c, CSR Addr 0x5408e, Direction=N/A */
+	uint8_t reserved11d;		/* Byte offset 0x11d, CSR Addr 0x5408e, Direction=N/A */
+	uint8_t reserved11e;		/* Byte offset 0x11e, CSR Addr 0x5408f, Direction=N/A */
+	uint8_t reserved11f;		/* Byte offset 0x11f, CSR Addr 0x5408f, Direction=N/A */
+	uint8_t reserved120;		/* Byte offset 0x120, CSR Addr 0x54090, Direction=N/A */
+	uint8_t reserved121;		/* Byte offset 0x121, CSR Addr 0x54090, Direction=N/A */
+	uint8_t reserved122;		/* Byte offset 0x122, CSR Addr 0x54091, Direction=N/A */
+	uint8_t reserved123;		/* Byte offset 0x123, CSR Addr 0x54091, Direction=N/A */
+	uint8_t reserved124;		/* Byte offset 0x124, CSR Addr 0x54092, Direction=N/A */
+	uint8_t reserved125;		/* Byte offset 0x125, CSR Addr 0x54092, Direction=N/A */
+	uint8_t reserved126;		/* Byte offset 0x126, CSR Addr 0x54093, Direction=N/A */
+	uint8_t reserved127;		/* Byte offset 0x127, CSR Addr 0x54093, Direction=N/A */
+	uint8_t reserved128;		/* Byte offset 0x128, CSR Addr 0x54094, Direction=N/A */
+	uint8_t reserved129;		/* Byte offset 0x129, CSR Addr 0x54094, Direction=N/A */
+	uint8_t reserved12a;		/* Byte offset 0x12a, CSR Addr 0x54095, Direction=N/A */
+	uint8_t reserved12b;		/* Byte offset 0x12b, CSR Addr 0x54095, Direction=N/A */
+	uint8_t reserved12c;		/* Byte offset 0x12c, CSR Addr 0x54096, Direction=N/A */
+	uint8_t reserved12d;		/* Byte offset 0x12d, CSR Addr 0x54096, Direction=N/A */
+	uint8_t reserved12e;		/* Byte offset 0x12e, CSR Addr 0x54097, Direction=N/A */
+	uint8_t reserved12f;		/* Byte offset 0x12f, CSR Addr 0x54097, Direction=N/A */
+	uint8_t reserved130;		/* Byte offset 0x130, CSR Addr 0x54098, Direction=N/A */
+	uint8_t reserved131;		/* Byte offset 0x131, CSR Addr 0x54098, Direction=N/A */
+	uint8_t reserved132;		/* Byte offset 0x132, CSR Addr 0x54099, Direction=N/A */
+	uint8_t reserved133;		/* Byte offset 0x133, CSR Addr 0x54099, Direction=N/A */
+	uint8_t reserved134;		/* Byte offset 0x134, CSR Addr 0x5409a, Direction=N/A */
+	uint8_t reserved135;		/* Byte offset 0x135, CSR Addr 0x5409a, Direction=N/A */
+	uint8_t reserved136;		/* Byte offset 0x136, CSR Addr 0x5409b, Direction=N/A */
+	uint8_t reserved137;		/* Byte offset 0x137, CSR Addr 0x5409b, Direction=N/A */
+	uint8_t reserved138;		/* Byte offset 0x138, CSR Addr 0x5409c, Direction=N/A */
+	uint8_t reserved139;		/* Byte offset 0x139, CSR Addr 0x5409c, Direction=N/A */
+	uint8_t reserved13a;		/* Byte offset 0x13a, CSR Addr 0x5409d, Direction=N/A */
+	uint8_t reserved13b;		/* Byte offset 0x13b, CSR Addr 0x5409d, Direction=N/A */
+	uint8_t reserved13c;		/* Byte offset 0x13c, CSR Addr 0x5409e, Direction=N/A */
+	uint8_t reserved13d;		/* Byte offset 0x13d, CSR Addr 0x5409e, Direction=N/A */
+	uint8_t reserved13e;		/* Byte offset 0x13e, CSR Addr 0x5409f, Direction=N/A */
+	uint8_t reserved13f;		/* Byte offset 0x13f, CSR Addr 0x5409f, Direction=N/A */
+	uint8_t reserved140;		/* Byte offset 0x140, CSR Addr 0x540a0, Direction=N/A */
+	uint8_t reserved141;		/* Byte offset 0x141, CSR Addr 0x540a0, Direction=N/A */
+	uint8_t reserved142;		/* Byte offset 0x142, CSR Addr 0x540a1, Direction=N/A */
+	uint8_t reserved143;		/* Byte offset 0x143, CSR Addr 0x540a1, Direction=N/A */
+	uint8_t reserved144;		/* Byte offset 0x144, CSR Addr 0x540a2, Direction=N/A */
+	uint8_t reserved145;		/* Byte offset 0x145, CSR Addr 0x540a2, Direction=N/A */
+	uint8_t reserved146;		/* Byte offset 0x146, CSR Addr 0x540a3, Direction=N/A */
+	uint8_t reserved147;		/* Byte offset 0x147, CSR Addr 0x540a3, Direction=N/A */
+	uint8_t reserved148;		/* Byte offset 0x148, CSR Addr 0x540a4, Direction=N/A */
+	uint8_t reserved149;		/* Byte offset 0x149, CSR Addr 0x540a4, Direction=N/A */
+	uint8_t reserved14a;		/* Byte offset 0x14a, CSR Addr 0x540a5, Direction=N/A */
+	uint8_t reserved14b;		/* Byte offset 0x14b, CSR Addr 0x540a5, Direction=N/A */
+	uint8_t reserved14c;		/* Byte offset 0x14c, CSR Addr 0x540a6, Direction=N/A */
+	uint8_t reserved14d;		/* Byte offset 0x14d, CSR Addr 0x540a6, Direction=N/A */
+	uint8_t reserved14e;		/* Byte offset 0x14e, CSR Addr 0x540a7, Direction=N/A */
+	uint8_t reserved14f;		/* Byte offset 0x14f, CSR Addr 0x540a7, Direction=N/A */
+	uint8_t reserved150;		/* Byte offset 0x150, CSR Addr 0x540a8, Direction=N/A */
+	uint8_t reserved151;		/* Byte offset 0x151, CSR Addr 0x540a8, Direction=N/A */
+	uint8_t reserved152;		/* Byte offset 0x152, CSR Addr 0x540a9, Direction=N/A */
+	uint8_t reserved153;		/* Byte offset 0x153, CSR Addr 0x540a9, Direction=N/A */
+	uint8_t reserved154;		/* Byte offset 0x154, CSR Addr 0x540aa, Direction=N/A */
+	uint8_t reserved155;		/* Byte offset 0x155, CSR Addr 0x540aa, Direction=N/A */
+	uint8_t reserved156;		/* Byte offset 0x156, CSR Addr 0x540ab, Direction=N/A */
+	uint8_t reserved157;		/* Byte offset 0x157, CSR Addr 0x540ab, Direction=N/A */
+	uint8_t reserved158;		/* Byte offset 0x158, CSR Addr 0x540ac, Direction=N/A */
+	uint8_t reserved159;		/* Byte offset 0x159, CSR Addr 0x540ac, Direction=N/A */
+	uint8_t reserved15a;		/* Byte offset 0x15a, CSR Addr 0x540ad, Direction=N/A */
+	uint8_t reserved15b;		/* Byte offset 0x15b, CSR Addr 0x540ad, Direction=N/A */
+	uint8_t reserved15c;		/* Byte offset 0x15c, CSR Addr 0x540ae, Direction=N/A */
+	uint8_t reserved15d;		/* Byte offset 0x15d, CSR Addr 0x540ae, Direction=N/A */
+	uint8_t reserved15e;		/* Byte offset 0x15e, CSR Addr 0x540af, Direction=N/A */
+	uint8_t reserved15f;		/* Byte offset 0x15f, CSR Addr 0x540af, Direction=N/A */
+	uint8_t reserved160;		/* Byte offset 0x160, CSR Addr 0x540b0, Direction=N/A */
+	uint8_t reserved161;		/* Byte offset 0x161, CSR Addr 0x540b0, Direction=N/A */
+	uint8_t reserved162;		/* Byte offset 0x162, CSR Addr 0x540b1, Direction=N/A */
+	uint8_t reserved163;		/* Byte offset 0x163, CSR Addr 0x540b1, Direction=N/A */
+	uint8_t reserved164;		/* Byte offset 0x164, CSR Addr 0x540b2, Direction=N/A */
+	uint8_t reserved165;		/* Byte offset 0x165, CSR Addr 0x540b2, Direction=N/A */
+	uint8_t reserved166;		/* Byte offset 0x166, CSR Addr 0x540b3, Direction=N/A */
+	uint8_t reserved167;		/* Byte offset 0x167, CSR Addr 0x540b3, Direction=N/A */
+	uint8_t reserved168;		/* Byte offset 0x168, CSR Addr 0x540b4, Direction=N/A */
+	uint8_t reserved169;		/* Byte offset 0x169, CSR Addr 0x540b4, Direction=N/A */
+	uint8_t reserved16a;		/* Byte offset 0x16a, CSR Addr 0x540b5, Direction=N/A */
+	uint8_t reserved16b;		/* Byte offset 0x16b, CSR Addr 0x540b5, Direction=N/A */
+	uint8_t reserved16c;		/* Byte offset 0x16c, CSR Addr 0x540b6, Direction=N/A */
+	uint8_t reserved16d;		/* Byte offset 0x16d, CSR Addr 0x540b6, Direction=N/A */
+	uint8_t reserved16e;		/* Byte offset 0x16e, CSR Addr 0x540b7, Direction=N/A */
+	uint8_t reserved16f;		/* Byte offset 0x16f, CSR Addr 0x540b7, Direction=N/A */
+	uint8_t reserved170;		/* Byte offset 0x170, CSR Addr 0x540b8, Direction=N/A */
+	uint8_t reserved171;		/* Byte offset 0x171, CSR Addr 0x540b8, Direction=N/A */
+	uint8_t reserved172;		/* Byte offset 0x172, CSR Addr 0x540b9, Direction=N/A */
+	uint8_t reserved173;		/* Byte offset 0x173, CSR Addr 0x540b9, Direction=N/A */
+	uint8_t reserved174;		/* Byte offset 0x174, CSR Addr 0x540ba, Direction=N/A */
+	uint8_t reserved175;		/* Byte offset 0x175, CSR Addr 0x540ba, Direction=N/A */
+	uint8_t reserved176;		/* Byte offset 0x176, CSR Addr 0x540bb, Direction=N/A */
+	uint8_t reserved177;		/* Byte offset 0x177, CSR Addr 0x540bb, Direction=N/A */
+	uint8_t reserved178;		/* Byte offset 0x178, CSR Addr 0x540bc, Direction=N/A */
+	uint8_t reserved179;		/* Byte offset 0x179, CSR Addr 0x540bc, Direction=N/A */
+	uint8_t reserved17a;		/* Byte offset 0x17a, CSR Addr 0x540bd, Direction=N/A */
+	uint8_t reserved17b;		/* Byte offset 0x17b, CSR Addr 0x540bd, Direction=N/A */
+	uint8_t reserved17c;		/* Byte offset 0x17c, CSR Addr 0x540be, Direction=N/A */
+	uint8_t reserved17d;		/* Byte offset 0x17d, CSR Addr 0x540be, Direction=N/A */
+	uint8_t reserved17e;		/* Byte offset 0x17e, CSR Addr 0x540bf, Direction=N/A */
+	uint8_t reserved17f;		/* Byte offset 0x17f, CSR Addr 0x540bf, Direction=N/A */
+	uint8_t reserved180;		/* Byte offset 0x180, CSR Addr 0x540c0, Direction=N/A */
+	uint8_t reserved181;		/* Byte offset 0x181, CSR Addr 0x540c0, Direction=N/A */
+	uint8_t reserved182;		/* Byte offset 0x182, CSR Addr 0x540c1, Direction=N/A */
+	uint8_t reserved183;		/* Byte offset 0x183, CSR Addr 0x540c1, Direction=N/A */
+	uint8_t reserved184;		/* Byte offset 0x184, CSR Addr 0x540c2, Direction=N/A */
+	uint8_t reserved185;		/* Byte offset 0x185, CSR Addr 0x540c2, Direction=N/A */
+	uint8_t reserved186;		/* Byte offset 0x186, CSR Addr 0x540c3, Direction=N/A */
+	uint8_t reserved187;		/* Byte offset 0x187, CSR Addr 0x540c3, Direction=N/A */
+	uint8_t reserved188;		/* Byte offset 0x188, CSR Addr 0x540c4, Direction=N/A */
+	uint8_t reserved189;		/* Byte offset 0x189, CSR Addr 0x540c4, Direction=N/A */
+	uint8_t reserved18a;		/* Byte offset 0x18a, CSR Addr 0x540c5, Direction=N/A */
+	uint8_t reserved18b;		/* Byte offset 0x18b, CSR Addr 0x540c5, Direction=N/A */
+	uint8_t reserved18c;		/* Byte offset 0x18c, CSR Addr 0x540c6, Direction=N/A */
+	uint8_t reserved18d;		/* Byte offset 0x18d, CSR Addr 0x540c6, Direction=N/A */
+	uint8_t reserved18e;		/* Byte offset 0x18e, CSR Addr 0x540c7, Direction=N/A */
+	uint8_t reserved18f;		/* Byte offset 0x18f, CSR Addr 0x540c7, Direction=N/A */
+	uint8_t reserved190;		/* Byte offset 0x190, CSR Addr 0x540c8, Direction=N/A */
+	uint8_t reserved191;		/* Byte offset 0x191, CSR Addr 0x540c8, Direction=N/A */
+	uint8_t reserved192;		/* Byte offset 0x192, CSR Addr 0x540c9, Direction=N/A */
+	uint8_t reserved193;		/* Byte offset 0x193, CSR Addr 0x540c9, Direction=N/A */
+	uint8_t reserved194;		/* Byte offset 0x194, CSR Addr 0x540ca, Direction=N/A */
+	uint8_t reserved195;		/* Byte offset 0x195, CSR Addr 0x540ca, Direction=N/A */
+	uint8_t reserved196;		/* Byte offset 0x196, CSR Addr 0x540cb, Direction=N/A */
+	uint8_t reserved197;		/* Byte offset 0x197, CSR Addr 0x540cb, Direction=N/A */
+	uint8_t reserved198;		/* Byte offset 0x198, CSR Addr 0x540cc, Direction=N/A */
+	uint8_t reserved199;		/* Byte offset 0x199, CSR Addr 0x540cc, Direction=N/A */
+	uint8_t reserved19a;		/* Byte offset 0x19a, CSR Addr 0x540cd, Direction=N/A */
+	uint8_t reserved19b;		/* Byte offset 0x19b, CSR Addr 0x540cd, Direction=N/A */
+	uint8_t reserved19c;		/* Byte offset 0x19c, CSR Addr 0x540ce, Direction=N/A */
+	uint8_t reserved19d;		/* Byte offset 0x19d, CSR Addr 0x540ce, Direction=N/A */
+	uint8_t reserved19e;		/* Byte offset 0x19e, CSR Addr 0x540cf, Direction=N/A */
+	uint8_t reserved19f;		/* Byte offset 0x19f, CSR Addr 0x540cf, Direction=N/A */
+	uint8_t reserved1a0;		/* Byte offset 0x1a0, CSR Addr 0x540d0, Direction=N/A */
+	uint8_t reserved1a1;		/* Byte offset 0x1a1, CSR Addr 0x540d0, Direction=N/A */
+	uint8_t reserved1a2;		/* Byte offset 0x1a2, CSR Addr 0x540d1, Direction=N/A */
+	uint8_t reserved1a3;		/* Byte offset 0x1a3, CSR Addr 0x540d1, Direction=N/A */
+	uint8_t reserved1a4;		/* Byte offset 0x1a4, CSR Addr 0x540d2, Direction=N/A */
+	uint8_t reserved1a5;		/* Byte offset 0x1a5, CSR Addr 0x540d2, Direction=N/A */
+	uint8_t reserved1a6;		/* Byte offset 0x1a6, CSR Addr 0x540d3, Direction=N/A */
+	uint8_t reserved1a7;		/* Byte offset 0x1a7, CSR Addr 0x540d3, Direction=N/A */
+	uint8_t reserved1a8;		/* Byte offset 0x1a8, CSR Addr 0x540d4, Direction=N/A */
+	uint8_t reserved1a9;		/* Byte offset 0x1a9, CSR Addr 0x540d4, Direction=N/A */
+	uint8_t reserved1aa;		/* Byte offset 0x1aa, CSR Addr 0x540d5, Direction=N/A */
+	uint8_t reserved1ab;		/* Byte offset 0x1ab, CSR Addr 0x540d5, Direction=N/A */
+	uint8_t reserved1ac;		/* Byte offset 0x1ac, CSR Addr 0x540d6, Direction=N/A */
+	uint8_t reserved1ad;		/* Byte offset 0x1ad, CSR Addr 0x540d6, Direction=N/A */
+	uint8_t reserved1ae;		/* Byte offset 0x1ae, CSR Addr 0x540d7, Direction=N/A */
+	uint8_t reserved1af;		/* Byte offset 0x1af, CSR Addr 0x540d7, Direction=N/A */
+	uint8_t reserved1b0;		/* Byte offset 0x1b0, CSR Addr 0x540d8, Direction=N/A */
+	uint8_t reserved1b1;		/* Byte offset 0x1b1, CSR Addr 0x540d8, Direction=N/A */
+	uint8_t reserved1b2;		/* Byte offset 0x1b2, CSR Addr 0x540d9, Direction=N/A */
+	uint8_t reserved1b3;		/* Byte offset 0x1b3, CSR Addr 0x540d9, Direction=N/A */
+	uint8_t reserved1b4;		/* Byte offset 0x1b4, CSR Addr 0x540da, Direction=N/A */
+	uint8_t reserved1b5;		/* Byte offset 0x1b5, CSR Addr 0x540da, Direction=N/A */
+	uint8_t reserved1b6;		/* Byte offset 0x1b6, CSR Addr 0x540db, Direction=N/A */
+	uint8_t reserved1b7;		/* Byte offset 0x1b7, CSR Addr 0x540db, Direction=N/A */
+	uint8_t reserved1b8;		/* Byte offset 0x1b8, CSR Addr 0x540dc, Direction=N/A */
+	uint8_t reserved1b9;		/* Byte offset 0x1b9, CSR Addr 0x540dc, Direction=N/A */
+	uint8_t reserved1ba;		/* Byte offset 0x1ba, CSR Addr 0x540dd, Direction=N/A */
+	uint8_t reserved1bb;		/* Byte offset 0x1bb, CSR Addr 0x540dd, Direction=N/A */
+	uint8_t reserved1bc;		/* Byte offset 0x1bc, CSR Addr 0x540de, Direction=N/A */
+	uint8_t reserved1bd;		/* Byte offset 0x1bd, CSR Addr 0x540de, Direction=N/A */
+	uint8_t reserved1be;		/* Byte offset 0x1be, CSR Addr 0x540df, Direction=N/A */
+	uint8_t reserved1bf;		/* Byte offset 0x1bf, CSR Addr 0x540df, Direction=N/A */
+	uint8_t reserved1c0;		/* Byte offset 0x1c0, CSR Addr 0x540e0, Direction=N/A */
+	uint8_t reserved1c1;		/* Byte offset 0x1c1, CSR Addr 0x540e0, Direction=N/A */
+	uint8_t reserved1c2;		/* Byte offset 0x1c2, CSR Addr 0x540e1, Direction=N/A */
+	uint8_t reserved1c3;		/* Byte offset 0x1c3, CSR Addr 0x540e1, Direction=N/A */
+	uint8_t reserved1c4;		/* Byte offset 0x1c4, CSR Addr 0x540e2, Direction=N/A */
+	uint8_t reserved1c5;		/* Byte offset 0x1c5, CSR Addr 0x540e2, Direction=N/A */
+	uint8_t reserved1c6;		/* Byte offset 0x1c6, CSR Addr 0x540e3, Direction=N/A */
+	uint8_t reserved1c7;		/* Byte offset 0x1c7, CSR Addr 0x540e3, Direction=N/A */
+	uint8_t reserved1c8;		/* Byte offset 0x1c8, CSR Addr 0x540e4, Direction=N/A */
+	uint8_t reserved1c9;		/* Byte offset 0x1c9, CSR Addr 0x540e4, Direction=N/A */
+	uint8_t reserved1ca;		/* Byte offset 0x1ca, CSR Addr 0x540e5, Direction=N/A */
+	uint8_t reserved1cb;		/* Byte offset 0x1cb, CSR Addr 0x540e5, Direction=N/A */
+	uint8_t reserved1cc;		/* Byte offset 0x1cc, CSR Addr 0x540e6, Direction=N/A */
+	uint8_t reserved1cd;		/* Byte offset 0x1cd, CSR Addr 0x540e6, Direction=N/A */
+	uint8_t reserved1ce;		/* Byte offset 0x1ce, CSR Addr 0x540e7, Direction=N/A */
+	uint8_t reserved1cf;		/* Byte offset 0x1cf, CSR Addr 0x540e7, Direction=N/A */
+	uint8_t reserved1d0;		/* Byte offset 0x1d0, CSR Addr 0x540e8, Direction=N/A */
+	uint8_t reserved1d1;		/* Byte offset 0x1d1, CSR Addr 0x540e8, Direction=N/A */
+	uint8_t reserved1d2;		/* Byte offset 0x1d2, CSR Addr 0x540e9, Direction=N/A */
+	uint8_t reserved1d3;		/* Byte offset 0x1d3, CSR Addr 0x540e9, Direction=N/A */
+	uint8_t reserved1d4;		/* Byte offset 0x1d4, CSR Addr 0x540ea, Direction=N/A */
+	uint8_t reserved1d5;		/* Byte offset 0x1d5, CSR Addr 0x540ea, Direction=N/A */
+	uint8_t reserved1d6;		/* Byte offset 0x1d6, CSR Addr 0x540eb, Direction=N/A */
+	uint8_t reserved1d7;		/* Byte offset 0x1d7, CSR Addr 0x540eb, Direction=N/A */
+	uint8_t reserved1d8;		/* Byte offset 0x1d8, CSR Addr 0x540ec, Direction=N/A */
+	uint8_t reserved1d9;		/* Byte offset 0x1d9, CSR Addr 0x540ec, Direction=N/A */
+	uint8_t reserved1da;		/* Byte offset 0x1da, CSR Addr 0x540ed, Direction=N/A */
+	uint8_t reserved1db;		/* Byte offset 0x1db, CSR Addr 0x540ed, Direction=N/A */
+	uint8_t reserved1dc;		/* Byte offset 0x1dc, CSR Addr 0x540ee, Direction=N/A */
+	uint8_t reserved1dd;		/* Byte offset 0x1dd, CSR Addr 0x540ee, Direction=N/A */
+	uint8_t reserved1de;		/* Byte offset 0x1de, CSR Addr 0x540ef, Direction=N/A */
+	uint8_t reserved1df;		/* Byte offset 0x1df, CSR Addr 0x540ef, Direction=N/A */
+	uint8_t reserved1e0;		/* Byte offset 0x1e0, CSR Addr 0x540f0, Direction=N/A */
+	uint8_t reserved1e1;		/* Byte offset 0x1e1, CSR Addr 0x540f0, Direction=N/A */
+	uint8_t reserved1e2;		/* Byte offset 0x1e2, CSR Addr 0x540f1, Direction=N/A */
+	uint8_t reserved1e3;		/* Byte offset 0x1e3, CSR Addr 0x540f1, Direction=N/A */
+	uint8_t reserved1e4;		/* Byte offset 0x1e4, CSR Addr 0x540f2, Direction=N/A */
+	uint8_t reserved1e5;		/* Byte offset 0x1e5, CSR Addr 0x540f2, Direction=N/A */
+	uint8_t reserved1e6;		/* Byte offset 0x1e6, CSR Addr 0x540f3, Direction=N/A */
+	uint8_t reserved1e7;		/* Byte offset 0x1e7, CSR Addr 0x540f3, Direction=N/A */
+	uint8_t reserved1e8;		/* Byte offset 0x1e8, CSR Addr 0x540f4, Direction=N/A */
+	uint8_t reserved1e9;		/* Byte offset 0x1e9, CSR Addr 0x540f4, Direction=N/A */
+	uint8_t reserved1ea;		/* Byte offset 0x1ea, CSR Addr 0x540f5, Direction=N/A */
+	uint8_t reserved1eb;		/* Byte offset 0x1eb, CSR Addr 0x540f5, Direction=N/A */
+	uint8_t reserved1ec;		/* Byte offset 0x1ec, CSR Addr 0x540f6, Direction=N/A */
+	uint8_t reserved1ed;		/* Byte offset 0x1ed, CSR Addr 0x540f6, Direction=N/A */
+	uint8_t reserved1ee;		/* Byte offset 0x1ee, CSR Addr 0x540f7, Direction=N/A */
+	uint8_t reserved1ef;		/* Byte offset 0x1ef, CSR Addr 0x540f7, Direction=N/A */
+	uint8_t reserved1f0;		/* Byte offset 0x1f0, CSR Addr 0x540f8, Direction=N/A */
+	uint8_t reserved1f1;		/* Byte offset 0x1f1, CSR Addr 0x540f8, Direction=N/A */
+	uint8_t reserved1f2;		/* Byte offset 0x1f2, CSR Addr 0x540f9, Direction=N/A */
+	uint8_t reserved1f3;		/* Byte offset 0x1f3, CSR Addr 0x540f9, Direction=N/A */
+	uint8_t reserved1f4;		/* Byte offset 0x1f4, CSR Addr 0x540fa, Direction=N/A */
+	uint8_t reserved1f5;		/* Byte offset 0x1f5, CSR Addr 0x540fa, Direction=N/A */
+	uint8_t reserved1f6;		/* Byte offset 0x1f6, CSR Addr 0x540fb, Direction=N/A */
+	uint8_t reserved1f7;		/* Byte offset 0x1f7, CSR Addr 0x540fb, Direction=N/A */
+	uint8_t reserved1f8;		/* Byte offset 0x1f8, CSR Addr 0x540fc, Direction=N/A */
+	uint8_t reserved1f9;		/* Byte offset 0x1f9, CSR Addr 0x540fc, Direction=N/A */
+	uint8_t reserved1fa;		/* Byte offset 0x1fa, CSR Addr 0x540fd, Direction=N/A */
+	uint8_t reserved1fb;		/* Byte offset 0x1fb, CSR Addr 0x540fd, Direction=N/A */
+	uint8_t reserved1fc;		/* Byte offset 0x1fc, CSR Addr 0x540fe, Direction=N/A */
+	uint8_t reserved1fd;		/* Byte offset 0x1fd, CSR Addr 0x540fe, Direction=N/A */
+	uint8_t reserved1fe;		/* Byte offset 0x1fe, CSR Addr 0x540ff, Direction=N/A */
+	uint8_t reserved1ff;		/* Byte offset 0x1ff, CSR Addr 0x540ff, Direction=N/A */
+	uint8_t reserved200;		/* Byte offset 0x200, CSR Addr 0x54100, Direction=N/A */
+	uint8_t reserved201;		/* Byte offset 0x201, CSR Addr 0x54100, Direction=N/A */
+	uint8_t reserved202;		/* Byte offset 0x202, CSR Addr 0x54101, Direction=N/A */
+	uint8_t reserved203;		/* Byte offset 0x203, CSR Addr 0x54101, Direction=N/A */
+	uint8_t reserved204;		/* Byte offset 0x204, CSR Addr 0x54102, Direction=N/A */
+	uint8_t reserved205;		/* Byte offset 0x205, CSR Addr 0x54102, Direction=N/A */
+	uint8_t reserved206;		/* Byte offset 0x206, CSR Addr 0x54103, Direction=N/A */
+	uint8_t reserved207;		/* Byte offset 0x207, CSR Addr 0x54103, Direction=N/A */
+	uint8_t reserved208;		/* Byte offset 0x208, CSR Addr 0x54104, Direction=N/A */
+	uint8_t reserved209;		/* Byte offset 0x209, CSR Addr 0x54104, Direction=N/A */
+	uint8_t reserved20a;		/* Byte offset 0x20a, CSR Addr 0x54105, Direction=N/A */
+	uint8_t reserved20b;		/* Byte offset 0x20b, CSR Addr 0x54105, Direction=N/A */
+	uint8_t reserved20c;		/* Byte offset 0x20c, CSR Addr 0x54106, Direction=N/A */
+	uint8_t reserved20d;		/* Byte offset 0x20d, CSR Addr 0x54106, Direction=N/A */
+	uint8_t reserved20e;		/* Byte offset 0x20e, CSR Addr 0x54107, Direction=N/A */
+	uint8_t reserved20f;		/* Byte offset 0x20f, CSR Addr 0x54107, Direction=N/A */
+	uint8_t reserved210;		/* Byte offset 0x210, CSR Addr 0x54108, Direction=N/A */
+	uint8_t reserved211;		/* Byte offset 0x211, CSR Addr 0x54108, Direction=N/A */
+	uint8_t reserved212;		/* Byte offset 0x212, CSR Addr 0x54109, Direction=N/A */
+	uint8_t reserved213;		/* Byte offset 0x213, CSR Addr 0x54109, Direction=N/A */
+	uint8_t reserved214;		/* Byte offset 0x214, CSR Addr 0x5410a, Direction=N/A */
+	uint8_t reserved215;		/* Byte offset 0x215, CSR Addr 0x5410a, Direction=N/A */
+	uint8_t reserved216;		/* Byte offset 0x216, CSR Addr 0x5410b, Direction=N/A */
+	uint8_t reserved217;		/* Byte offset 0x217, CSR Addr 0x5410b, Direction=N/A */
+	uint8_t reserved218;		/* Byte offset 0x218, CSR Addr 0x5410c, Direction=N/A */
+	uint8_t reserved219;		/* Byte offset 0x219, CSR Addr 0x5410c, Direction=N/A */
+	uint8_t reserved21a;		/* Byte offset 0x21a, CSR Addr 0x5410d, Direction=N/A */
+	uint8_t reserved21b;		/* Byte offset 0x21b, CSR Addr 0x5410d, Direction=N/A */
+	uint8_t reserved21c;		/* Byte offset 0x21c, CSR Addr 0x5410e, Direction=N/A */
+	uint8_t reserved21d;		/* Byte offset 0x21d, CSR Addr 0x5410e, Direction=N/A */
+	uint8_t reserved21e;		/* Byte offset 0x21e, CSR Addr 0x5410f, Direction=N/A */
+	uint8_t reserved21f;		/* Byte offset 0x21f, CSR Addr 0x5410f, Direction=N/A */
+	uint8_t reserved220;		/* Byte offset 0x220, CSR Addr 0x54110, Direction=N/A */
+	uint8_t reserved221;		/* Byte offset 0x221, CSR Addr 0x54110, Direction=N/A */
+	uint8_t reserved222;		/* Byte offset 0x222, CSR Addr 0x54111, Direction=N/A */
+	uint8_t reserved223;		/* Byte offset 0x223, CSR Addr 0x54111, Direction=N/A */
+	uint8_t reserved224;		/* Byte offset 0x224, CSR Addr 0x54112, Direction=N/A */
+	uint8_t reserved225;		/* Byte offset 0x225, CSR Addr 0x54112, Direction=N/A */
+	uint8_t reserved226;		/* Byte offset 0x226, CSR Addr 0x54113, Direction=N/A */
+	uint8_t reserved227;		/* Byte offset 0x227, CSR Addr 0x54113, Direction=N/A */
+	uint8_t reserved228;		/* Byte offset 0x228, CSR Addr 0x54114, Direction=N/A */
+	uint8_t reserved229;		/* Byte offset 0x229, CSR Addr 0x54114, Direction=N/A */
+	uint8_t reserved22a;		/* Byte offset 0x22a, CSR Addr 0x54115, Direction=N/A */
+	uint8_t reserved22b;		/* Byte offset 0x22b, CSR Addr 0x54115, Direction=N/A */
+	uint8_t reserved22c;		/* Byte offset 0x22c, CSR Addr 0x54116, Direction=N/A */
+	uint8_t reserved22d;		/* Byte offset 0x22d, CSR Addr 0x54116, Direction=N/A */
+	uint8_t reserved22e;		/* Byte offset 0x22e, CSR Addr 0x54117, Direction=N/A */
+	uint8_t reserved22f;		/* Byte offset 0x22f, CSR Addr 0x54117, Direction=N/A */
+	uint8_t reserved230;		/* Byte offset 0x230, CSR Addr 0x54118, Direction=N/A */
+	uint8_t reserved231;		/* Byte offset 0x231, CSR Addr 0x54118, Direction=N/A */
+	uint8_t reserved232;		/* Byte offset 0x232, CSR Addr 0x54119, Direction=N/A */
+	uint8_t reserved233;		/* Byte offset 0x233, CSR Addr 0x54119, Direction=N/A */
+	uint8_t reserved234;		/* Byte offset 0x234, CSR Addr 0x5411a, Direction=N/A */
+	uint8_t reserved235;		/* Byte offset 0x235, CSR Addr 0x5411a, Direction=N/A */
+	uint8_t reserved236;		/* Byte offset 0x236, CSR Addr 0x5411b, Direction=N/A */
+	uint8_t reserved237;		/* Byte offset 0x237, CSR Addr 0x5411b, Direction=N/A */
+	uint8_t reserved238;		/* Byte offset 0x238, CSR Addr 0x5411c, Direction=N/A */
+	uint8_t reserved239;		/* Byte offset 0x239, CSR Addr 0x5411c, Direction=N/A */
+	uint8_t reserved23a;		/* Byte offset 0x23a, CSR Addr 0x5411d, Direction=N/A */
+	uint8_t reserved23b;		/* Byte offset 0x23b, CSR Addr 0x5411d, Direction=N/A */
+	uint8_t reserved23c;		/* Byte offset 0x23c, CSR Addr 0x5411e, Direction=N/A */
+	uint8_t reserved23d;		/* Byte offset 0x23d, CSR Addr 0x5411e, Direction=N/A */
+	uint8_t reserved23e;		/* Byte offset 0x23e, CSR Addr 0x5411f, Direction=N/A */
+	uint8_t reserved23f;		/* Byte offset 0x23f, CSR Addr 0x5411f, Direction=N/A */
+	uint8_t reserved240;		/* Byte offset 0x240, CSR Addr 0x54120, Direction=N/A */
+	uint8_t reserved241;		/* Byte offset 0x241, CSR Addr 0x54120, Direction=N/A */
+	uint8_t reserved242;		/* Byte offset 0x242, CSR Addr 0x54121, Direction=N/A */
+	uint8_t reserved243;		/* Byte offset 0x243, CSR Addr 0x54121, Direction=N/A */
+	uint8_t reserved244;		/* Byte offset 0x244, CSR Addr 0x54122, Direction=N/A */
+	uint8_t reserved245;		/* Byte offset 0x245, CSR Addr 0x54122, Direction=N/A */
+	uint8_t reserved246;		/* Byte offset 0x246, CSR Addr 0x54123, Direction=N/A */
+	uint8_t reserved247;		/* Byte offset 0x247, CSR Addr 0x54123, Direction=N/A */
+	uint8_t reserved248;		/* Byte offset 0x248, CSR Addr 0x54124, Direction=N/A */
+	uint8_t reserved249;		/* Byte offset 0x249, CSR Addr 0x54124, Direction=N/A */
+	uint8_t reserved24a;		/* Byte offset 0x24a, CSR Addr 0x54125, Direction=N/A */
+	uint8_t reserved24b;		/* Byte offset 0x24b, CSR Addr 0x54125, Direction=N/A */
+	uint8_t reserved24c;		/* Byte offset 0x24c, CSR Addr 0x54126, Direction=N/A */
+	uint8_t reserved24d;		/* Byte offset 0x24d, CSR Addr 0x54126, Direction=N/A */
+	uint8_t reserved24e;		/* Byte offset 0x24e, CSR Addr 0x54127, Direction=N/A */
+	uint8_t reserved24f;		/* Byte offset 0x24f, CSR Addr 0x54127, Direction=N/A */
+	uint8_t reserved250;		/* Byte offset 0x250, CSR Addr 0x54128, Direction=N/A */
+	uint8_t reserved251;		/* Byte offset 0x251, CSR Addr 0x54128, Direction=N/A */
+	uint8_t reserved252;		/* Byte offset 0x252, CSR Addr 0x54129, Direction=N/A */
+	uint8_t reserved253;		/* Byte offset 0x253, CSR Addr 0x54129, Direction=N/A */
+	uint8_t reserved254;		/* Byte offset 0x254, CSR Addr 0x5412a, Direction=N/A */
+	uint8_t reserved255;		/* Byte offset 0x255, CSR Addr 0x5412a, Direction=N/A */
+	uint8_t reserved256;		/* Byte offset 0x256, CSR Addr 0x5412b, Direction=N/A */
+	uint8_t reserved257;		/* Byte offset 0x257, CSR Addr 0x5412b, Direction=N/A */
+	uint8_t reserved258;		/* Byte offset 0x258, CSR Addr 0x5412c, Direction=N/A */
+	uint8_t reserved259;		/* Byte offset 0x259, CSR Addr 0x5412c, Direction=N/A */
+	uint8_t reserved25a;		/* Byte offset 0x25a, CSR Addr 0x5412d, Direction=N/A */
+	uint8_t reserved25b;		/* Byte offset 0x25b, CSR Addr 0x5412d, Direction=N/A */
+	uint8_t reserved25c;		/* Byte offset 0x25c, CSR Addr 0x5412e, Direction=N/A */
+	uint8_t reserved25d;		/* Byte offset 0x25d, CSR Addr 0x5412e, Direction=N/A */
+	uint8_t reserved25e;		/* Byte offset 0x25e, CSR Addr 0x5412f, Direction=N/A */
+	uint8_t reserved25f;		/* Byte offset 0x25f, CSR Addr 0x5412f, Direction=N/A */
+	uint8_t reserved260;		/* Byte offset 0x260, CSR Addr 0x54130, Direction=N/A */
+	uint8_t reserved261;		/* Byte offset 0x261, CSR Addr 0x54130, Direction=N/A */
+	uint8_t reserved262;		/* Byte offset 0x262, CSR Addr 0x54131, Direction=N/A */
+	uint8_t reserved263;		/* Byte offset 0x263, CSR Addr 0x54131, Direction=N/A */
+	uint8_t reserved264;		/* Byte offset 0x264, CSR Addr 0x54132, Direction=N/A */
+	uint8_t reserved265;		/* Byte offset 0x265, CSR Addr 0x54132, Direction=N/A */
+	uint8_t reserved266;		/* Byte offset 0x266, CSR Addr 0x54133, Direction=N/A */
+	uint8_t reserved267;		/* Byte offset 0x267, CSR Addr 0x54133, Direction=N/A */
+	uint8_t reserved268;		/* Byte offset 0x268, CSR Addr 0x54134, Direction=N/A */
+	uint8_t reserved269;		/* Byte offset 0x269, CSR Addr 0x54134, Direction=N/A */
+	uint8_t reserved26a;		/* Byte offset 0x26a, CSR Addr 0x54135, Direction=N/A */
+	uint8_t reserved26b;		/* Byte offset 0x26b, CSR Addr 0x54135, Direction=N/A */
+	uint8_t reserved26c;		/* Byte offset 0x26c, CSR Addr 0x54136, Direction=N/A */
+	uint8_t reserved26d;		/* Byte offset 0x26d, CSR Addr 0x54136, Direction=N/A */
+	uint8_t reserved26e;		/* Byte offset 0x26e, CSR Addr 0x54137, Direction=N/A */
+	uint8_t reserved26f;		/* Byte offset 0x26f, CSR Addr 0x54137, Direction=N/A */
+	uint8_t reserved270;		/* Byte offset 0x270, CSR Addr 0x54138, Direction=N/A */
+	uint8_t reserved271;		/* Byte offset 0x271, CSR Addr 0x54138, Direction=N/A */
+	uint8_t reserved272;		/* Byte offset 0x272, CSR Addr 0x54139, Direction=N/A */
+	uint8_t reserved273;		/* Byte offset 0x273, CSR Addr 0x54139, Direction=N/A */
+	uint8_t reserved274;		/* Byte offset 0x274, CSR Addr 0x5413a, Direction=N/A */
+	uint8_t reserved275;		/* Byte offset 0x275, CSR Addr 0x5413a, Direction=N/A */
+	uint8_t reserved276;		/* Byte offset 0x276, CSR Addr 0x5413b, Direction=N/A */
+	uint8_t reserved277;		/* Byte offset 0x277, CSR Addr 0x5413b, Direction=N/A */
+	uint8_t reserved278;		/* Byte offset 0x278, CSR Addr 0x5413c, Direction=N/A */
+	uint8_t reserved279;		/* Byte offset 0x279, CSR Addr 0x5413c, Direction=N/A */
+	uint8_t reserved27a;		/* Byte offset 0x27a, CSR Addr 0x5413d, Direction=N/A */
+	uint8_t reserved27b;		/* Byte offset 0x27b, CSR Addr 0x5413d, Direction=N/A */
+	uint8_t reserved27c;		/* Byte offset 0x27c, CSR Addr 0x5413e, Direction=N/A */
+	uint8_t reserved27d;		/* Byte offset 0x27d, CSR Addr 0x5413e, Direction=N/A */
+	uint8_t reserved27e;		/* Byte offset 0x27e, CSR Addr 0x5413f, Direction=N/A */
+	uint8_t reserved27f;		/* Byte offset 0x27f, CSR Addr 0x5413f, Direction=N/A */
+	uint8_t reserved280;		/* Byte offset 0x280, CSR Addr 0x54140, Direction=N/A */
+	uint8_t reserved281;		/* Byte offset 0x281, CSR Addr 0x54140, Direction=N/A */
+	uint8_t reserved282;		/* Byte offset 0x282, CSR Addr 0x54141, Direction=N/A */
+	uint8_t reserved283;		/* Byte offset 0x283, CSR Addr 0x54141, Direction=N/A */
+	uint8_t reserved284;		/* Byte offset 0x284, CSR Addr 0x54142, Direction=N/A */
+	uint8_t reserved285;		/* Byte offset 0x285, CSR Addr 0x54142, Direction=N/A */
+	uint8_t reserved286;		/* Byte offset 0x286, CSR Addr 0x54143, Direction=N/A */
+	uint8_t reserved287;		/* Byte offset 0x287, CSR Addr 0x54143, Direction=N/A */
+	uint8_t reserved288;		/* Byte offset 0x288, CSR Addr 0x54144, Direction=N/A */
+	uint8_t reserved289;		/* Byte offset 0x289, CSR Addr 0x54144, Direction=N/A */
+	uint8_t reserved28a;		/* Byte offset 0x28a, CSR Addr 0x54145, Direction=N/A */
+	uint8_t reserved28b;		/* Byte offset 0x28b, CSR Addr 0x54145, Direction=N/A */
+	uint8_t reserved28c;		/* Byte offset 0x28c, CSR Addr 0x54146, Direction=N/A */
+	uint8_t reserved28d;		/* Byte offset 0x28d, CSR Addr 0x54146, Direction=N/A */
+	uint8_t reserved28e;		/* Byte offset 0x28e, CSR Addr 0x54147, Direction=N/A */
+	uint8_t reserved28f;		/* Byte offset 0x28f, CSR Addr 0x54147, Direction=N/A */
+	uint8_t reserved290;		/* Byte offset 0x290, CSR Addr 0x54148, Direction=N/A */
+	uint8_t reserved291;		/* Byte offset 0x291, CSR Addr 0x54148, Direction=N/A */
+	uint8_t reserved292;		/* Byte offset 0x292, CSR Addr 0x54149, Direction=N/A */
+	uint8_t reserved293;		/* Byte offset 0x293, CSR Addr 0x54149, Direction=N/A */
+	uint8_t reserved294;		/* Byte offset 0x294, CSR Addr 0x5414a, Direction=N/A */
+	uint8_t reserved295;		/* Byte offset 0x295, CSR Addr 0x5414a, Direction=N/A */
+	uint8_t reserved296;		/* Byte offset 0x296, CSR Addr 0x5414b, Direction=N/A */
+	uint8_t reserved297;		/* Byte offset 0x297, CSR Addr 0x5414b, Direction=N/A */
+	uint8_t reserved298;		/* Byte offset 0x298, CSR Addr 0x5414c, Direction=N/A */
+	uint8_t reserved299;		/* Byte offset 0x299, CSR Addr 0x5414c, Direction=N/A */
+	uint8_t reserved29a;		/* Byte offset 0x29a, CSR Addr 0x5414d, Direction=N/A */
+	uint8_t reserved29b;		/* Byte offset 0x29b, CSR Addr 0x5414d, Direction=N/A */
+	uint8_t reserved29c;		/* Byte offset 0x29c, CSR Addr 0x5414e, Direction=N/A */
+	uint8_t reserved29d;		/* Byte offset 0x29d, CSR Addr 0x5414e, Direction=N/A */
+	uint8_t reserved29e;		/* Byte offset 0x29e, CSR Addr 0x5414f, Direction=N/A */
+	uint8_t reserved29f;		/* Byte offset 0x29f, CSR Addr 0x5414f, Direction=N/A */
+	uint8_t reserved2a0;		/* Byte offset 0x2a0, CSR Addr 0x54150, Direction=N/A */
+	uint8_t reserved2a1;		/* Byte offset 0x2a1, CSR Addr 0x54150, Direction=N/A */
+	uint8_t reserved2a2;		/* Byte offset 0x2a2, CSR Addr 0x54151, Direction=N/A */
+	uint8_t reserved2a3;		/* Byte offset 0x2a3, CSR Addr 0x54151, Direction=N/A */
+	uint8_t reserved2a4;		/* Byte offset 0x2a4, CSR Addr 0x54152, Direction=N/A */
+	uint8_t reserved2a5;		/* Byte offset 0x2a5, CSR Addr 0x54152, Direction=N/A */
+	uint8_t reserved2a6;		/* Byte offset 0x2a6, CSR Addr 0x54153, Direction=N/A */
+	uint8_t reserved2a7;		/* Byte offset 0x2a7, CSR Addr 0x54153, Direction=N/A */
+	uint8_t reserved2a8;		/* Byte offset 0x2a8, CSR Addr 0x54154, Direction=N/A */
+	uint8_t reserved2a9;		/* Byte offset 0x2a9, CSR Addr 0x54154, Direction=N/A */
+	uint8_t reserved2aa;		/* Byte offset 0x2aa, CSR Addr 0x54155, Direction=N/A */
+	uint8_t reserved2ab;		/* Byte offset 0x2ab, CSR Addr 0x54155, Direction=N/A */
+	uint8_t reserved2ac;		/* Byte offset 0x2ac, CSR Addr 0x54156, Direction=N/A */
+	uint8_t reserved2ad;		/* Byte offset 0x2ad, CSR Addr 0x54156, Direction=N/A */
+	uint8_t reserved2ae;		/* Byte offset 0x2ae, CSR Addr 0x54157, Direction=N/A */
+	uint8_t reserved2af;		/* Byte offset 0x2af, CSR Addr 0x54157, Direction=N/A */
+	uint8_t reserved2b0;		/* Byte offset 0x2b0, CSR Addr 0x54158, Direction=N/A */
+	uint8_t reserved2b1;		/* Byte offset 0x2b1, CSR Addr 0x54158, Direction=N/A */
+	uint8_t reserved2b2;		/* Byte offset 0x2b2, CSR Addr 0x54159, Direction=N/A */
+	uint8_t reserved2b3;		/* Byte offset 0x2b3, CSR Addr 0x54159, Direction=N/A */
+	uint8_t reserved2b4;		/* Byte offset 0x2b4, CSR Addr 0x5415a, Direction=N/A */
+	uint8_t reserved2b5;		/* Byte offset 0x2b5, CSR Addr 0x5415a, Direction=N/A */
+	uint8_t reserved2b6;		/* Byte offset 0x2b6, CSR Addr 0x5415b, Direction=N/A */
+	uint8_t reserved2b7;		/* Byte offset 0x2b7, CSR Addr 0x5415b, Direction=N/A */
+	uint8_t reserved2b8;		/* Byte offset 0x2b8, CSR Addr 0x5415c, Direction=N/A */
+	uint8_t reserved2b9;		/* Byte offset 0x2b9, CSR Addr 0x5415c, Direction=N/A */
+	uint8_t reserved2ba;		/* Byte offset 0x2ba, CSR Addr 0x5415d, Direction=N/A */
+	uint8_t reserved2bb;		/* Byte offset 0x2bb, CSR Addr 0x5415d, Direction=N/A */
+	uint8_t reserved2bc;		/* Byte offset 0x2bc, CSR Addr 0x5415e, Direction=N/A */
+	uint8_t reserved2bd;		/* Byte offset 0x2bd, CSR Addr 0x5415e, Direction=N/A */
+	uint8_t reserved2be;		/* Byte offset 0x2be, CSR Addr 0x5415f, Direction=N/A */
+	uint8_t reserved2bf;		/* Byte offset 0x2bf, CSR Addr 0x5415f, Direction=N/A */
+	uint8_t reserved2c0;		/* Byte offset 0x2c0, CSR Addr 0x54160, Direction=N/A */
+	uint8_t reserved2c1;		/* Byte offset 0x2c1, CSR Addr 0x54160, Direction=N/A */
+	uint8_t reserved2c2;		/* Byte offset 0x2c2, CSR Addr 0x54161, Direction=N/A */
+	uint8_t reserved2c3;		/* Byte offset 0x2c3, CSR Addr 0x54161, Direction=N/A */
+	uint8_t reserved2c4;		/* Byte offset 0x2c4, CSR Addr 0x54162, Direction=N/A */
+	uint8_t reserved2c5;		/* Byte offset 0x2c5, CSR Addr 0x54162, Direction=N/A */
+	uint8_t reserved2c6;		/* Byte offset 0x2c6, CSR Addr 0x54163, Direction=N/A */
+	uint8_t reserved2c7;		/* Byte offset 0x2c7, CSR Addr 0x54163, Direction=N/A */
+	uint8_t reserved2c8;		/* Byte offset 0x2c8, CSR Addr 0x54164, Direction=N/A */
+	uint8_t reserved2c9;		/* Byte offset 0x2c9, CSR Addr 0x54164, Direction=N/A */
+	uint8_t reserved2ca;		/* Byte offset 0x2ca, CSR Addr 0x54165, Direction=N/A */
+	uint8_t reserved2cb;		/* Byte offset 0x2cb, CSR Addr 0x54165, Direction=N/A */
+	uint8_t reserved2cc;		/* Byte offset 0x2cc, CSR Addr 0x54166, Direction=N/A */
+	uint8_t reserved2cd;		/* Byte offset 0x2cd, CSR Addr 0x54166, Direction=N/A */
+	uint8_t reserved2ce;		/* Byte offset 0x2ce, CSR Addr 0x54167, Direction=N/A */
+	uint8_t reserved2cf;		/* Byte offset 0x2cf, CSR Addr 0x54167, Direction=N/A */
+	uint8_t reserved2d0;		/* Byte offset 0x2d0, CSR Addr 0x54168, Direction=N/A */
+	uint8_t reserved2d1;		/* Byte offset 0x2d1, CSR Addr 0x54168, Direction=N/A */
+	uint8_t reserved2d2;		/* Byte offset 0x2d2, CSR Addr 0x54169, Direction=N/A */
+	uint8_t reserved2d3;		/* Byte offset 0x2d3, CSR Addr 0x54169, Direction=N/A */
+	uint8_t reserved2d4;		/* Byte offset 0x2d4, CSR Addr 0x5416a, Direction=N/A */
+	uint8_t reserved2d5;		/* Byte offset 0x2d5, CSR Addr 0x5416a, Direction=N/A */
+	uint8_t reserved2d6;		/* Byte offset 0x2d6, CSR Addr 0x5416b, Direction=N/A */
+	uint8_t reserved2d7;		/* Byte offset 0x2d7, CSR Addr 0x5416b, Direction=N/A */
+	uint8_t reserved2d8;		/* Byte offset 0x2d8, CSR Addr 0x5416c, Direction=N/A */
+	uint8_t reserved2d9;		/* Byte offset 0x2d9, CSR Addr 0x5416c, Direction=N/A */
+	uint8_t reserved2da;		/* Byte offset 0x2da, CSR Addr 0x5416d, Direction=N/A */
+	uint8_t reserved2db;		/* Byte offset 0x2db, CSR Addr 0x5416d, Direction=N/A */
+	uint8_t reserved2dc;		/* Byte offset 0x2dc, CSR Addr 0x5416e, Direction=N/A */
+	uint8_t reserved2dd;		/* Byte offset 0x2dd, CSR Addr 0x5416e, Direction=N/A */
+	uint8_t reserved2de;		/* Byte offset 0x2de, CSR Addr 0x5416f, Direction=N/A */
+	uint8_t reserved2df;		/* Byte offset 0x2df, CSR Addr 0x5416f, Direction=N/A */
+	uint8_t reserved2e0;		/* Byte offset 0x2e0, CSR Addr 0x54170, Direction=N/A */
+	uint8_t reserved2e1;		/* Byte offset 0x2e1, CSR Addr 0x54170, Direction=N/A */
+	uint8_t reserved2e2;		/* Byte offset 0x2e2, CSR Addr 0x54171, Direction=N/A */
+	uint8_t reserved2e3;		/* Byte offset 0x2e3, CSR Addr 0x54171, Direction=N/A */
+	uint8_t reserved2e4;		/* Byte offset 0x2e4, CSR Addr 0x54172, Direction=N/A */
+	uint8_t reserved2e5;		/* Byte offset 0x2e5, CSR Addr 0x54172, Direction=N/A */
+	uint8_t reserved2e6;		/* Byte offset 0x2e6, CSR Addr 0x54173, Direction=N/A */
+	uint8_t reserved2e7;		/* Byte offset 0x2e7, CSR Addr 0x54173, Direction=N/A */
+	uint8_t reserved2e8;		/* Byte offset 0x2e8, CSR Addr 0x54174, Direction=N/A */
+	uint8_t reserved2e9;		/* Byte offset 0x2e9, CSR Addr 0x54174, Direction=N/A */
+	uint8_t reserved2ea;		/* Byte offset 0x2ea, CSR Addr 0x54175, Direction=N/A */
+	uint8_t reserved2eb;		/* Byte offset 0x2eb, CSR Addr 0x54175, Direction=N/A */
+	uint8_t reserved2ec;		/* Byte offset 0x2ec, CSR Addr 0x54176, Direction=N/A */
+	uint8_t reserved2ed;		/* Byte offset 0x2ed, CSR Addr 0x54176, Direction=N/A */
+	uint8_t reserved2ee;		/* Byte offset 0x2ee, CSR Addr 0x54177, Direction=N/A */
+	uint8_t reserved2ef;		/* Byte offset 0x2ef, CSR Addr 0x54177, Direction=N/A */
+	uint8_t reserved2f0;		/* Byte offset 0x2f0, CSR Addr 0x54178, Direction=N/A */
+	uint8_t reserved2f1;		/* Byte offset 0x2f1, CSR Addr 0x54178, Direction=N/A */
+	uint8_t reserved2f2;		/* Byte offset 0x2f2, CSR Addr 0x54179, Direction=N/A */
+	uint8_t reserved2f3;		/* Byte offset 0x2f3, CSR Addr 0x54179, Direction=N/A */
+	uint8_t reserved2f4;		/* Byte offset 0x2f4, CSR Addr 0x5417a, Direction=N/A */
+	uint8_t reserved2f5;		/* Byte offset 0x2f5, CSR Addr 0x5417a, Direction=N/A */
+	uint8_t reserved2f6;		/* Byte offset 0x2f6, CSR Addr 0x5417b, Direction=N/A */
+	uint8_t reserved2f7;		/* Byte offset 0x2f7, CSR Addr 0x5417b, Direction=N/A */
+	uint8_t reserved2f8;		/* Byte offset 0x2f8, CSR Addr 0x5417c, Direction=N/A */
+	uint8_t reserved2f9;		/* Byte offset 0x2f9, CSR Addr 0x5417c, Direction=N/A */
+	uint8_t reserved2fa;		/* Byte offset 0x2fa, CSR Addr 0x5417d, Direction=N/A */
+	uint8_t reserved2fb;		/* Byte offset 0x2fb, CSR Addr 0x5417d, Direction=N/A */
+	uint8_t reserved2fc;		/* Byte offset 0x2fc, CSR Addr 0x5417e, Direction=N/A */
+	uint8_t reserved2fd;		/* Byte offset 0x2fd, CSR Addr 0x5417e, Direction=N/A */
+	uint8_t reserved2fe;		/* Byte offset 0x2fe, CSR Addr 0x5417f, Direction=N/A */
+	uint8_t reserved2ff;		/* Byte offset 0x2ff, CSR Addr 0x5417f, Direction=N/A */
+	uint8_t reserved300;		/* Byte offset 0x300, CSR Addr 0x54180, Direction=N/A */
+	uint8_t reserved301;		/* Byte offset 0x301, CSR Addr 0x54180, Direction=N/A */
+	uint8_t reserved302;		/* Byte offset 0x302, CSR Addr 0x54181, Direction=N/A */
+	uint8_t reserved303;		/* Byte offset 0x303, CSR Addr 0x54181, Direction=N/A */
+	uint8_t reserved304;		/* Byte offset 0x304, CSR Addr 0x54182, Direction=N/A */
+	uint8_t reserved305;		/* Byte offset 0x305, CSR Addr 0x54182, Direction=N/A */
+	uint8_t reserved306;		/* Byte offset 0x306, CSR Addr 0x54183, Direction=N/A */
+	uint8_t reserved307;		/* Byte offset 0x307, CSR Addr 0x54183, Direction=N/A */
+	uint8_t reserved308;		/* Byte offset 0x308, CSR Addr 0x54184, Direction=N/A */
+	uint8_t reserved309;		/* Byte offset 0x309, CSR Addr 0x54184, Direction=N/A */
+	uint8_t reserved30a;		/* Byte offset 0x30a, CSR Addr 0x54185, Direction=N/A */
+	uint8_t reserved30b;		/* Byte offset 0x30b, CSR Addr 0x54185, Direction=N/A */
+	uint8_t reserved30c;		/* Byte offset 0x30c, CSR Addr 0x54186, Direction=N/A */
+	uint8_t reserved30d;		/* Byte offset 0x30d, CSR Addr 0x54186, Direction=N/A */
+	uint8_t reserved30e;		/* Byte offset 0x30e, CSR Addr 0x54187, Direction=N/A */
+	uint8_t reserved30f;		/* Byte offset 0x30f, CSR Addr 0x54187, Direction=N/A */
+	uint8_t reserved310;		/* Byte offset 0x310, CSR Addr 0x54188, Direction=N/A */
+	uint8_t reserved311;		/* Byte offset 0x311, CSR Addr 0x54188, Direction=N/A */
+	uint8_t reserved312;		/* Byte offset 0x312, CSR Addr 0x54189, Direction=N/A */
+	uint8_t reserved313;		/* Byte offset 0x313, CSR Addr 0x54189, Direction=N/A */
+	uint8_t reserved314;		/* Byte offset 0x314, CSR Addr 0x5418a, Direction=N/A */
+	uint8_t reserved315;		/* Byte offset 0x315, CSR Addr 0x5418a, Direction=N/A */
+	uint8_t reserved316;		/* Byte offset 0x316, CSR Addr 0x5418b, Direction=N/A */
+	uint8_t reserved317;		/* Byte offset 0x317, CSR Addr 0x5418b, Direction=N/A */
+	uint8_t reserved318;		/* Byte offset 0x318, CSR Addr 0x5418c, Direction=N/A */
+	uint8_t reserved319;		/* Byte offset 0x319, CSR Addr 0x5418c, Direction=N/A */
+	uint8_t reserved31a;		/* Byte offset 0x31a, CSR Addr 0x5418d, Direction=N/A */
+	uint8_t reserved31b;		/* Byte offset 0x31b, CSR Addr 0x5418d, Direction=N/A */
+	uint8_t reserved31c;		/* Byte offset 0x31c, CSR Addr 0x5418e, Direction=N/A */
+	uint8_t reserved31d;		/* Byte offset 0x31d, CSR Addr 0x5418e, Direction=N/A */
+	uint8_t reserved31e;		/* Byte offset 0x31e, CSR Addr 0x5418f, Direction=N/A */
+	uint8_t reserved31f;		/* Byte offset 0x31f, CSR Addr 0x5418f, Direction=N/A */
+	uint8_t reserved320;		/* Byte offset 0x320, CSR Addr 0x54190, Direction=N/A */
+	uint8_t reserved321;		/* Byte offset 0x321, CSR Addr 0x54190, Direction=N/A */
+	uint8_t reserved322;		/* Byte offset 0x322, CSR Addr 0x54191, Direction=N/A */
+	uint8_t reserved323;		/* Byte offset 0x323, CSR Addr 0x54191, Direction=N/A */
+	uint8_t reserved324;		/* Byte offset 0x324, CSR Addr 0x54192, Direction=N/A */
+	uint8_t reserved325;		/* Byte offset 0x325, CSR Addr 0x54192, Direction=N/A */
+	uint8_t reserved326;		/* Byte offset 0x326, CSR Addr 0x54193, Direction=N/A */
+	uint8_t reserved327;		/* Byte offset 0x327, CSR Addr 0x54193, Direction=N/A */
+	uint8_t reserved328;		/* Byte offset 0x328, CSR Addr 0x54194, Direction=N/A */
+	uint8_t reserved329;		/* Byte offset 0x329, CSR Addr 0x54194, Direction=N/A */
+	uint8_t reserved32a;		/* Byte offset 0x32a, CSR Addr 0x54195, Direction=N/A */
+	uint8_t reserved32b;		/* Byte offset 0x32b, CSR Addr 0x54195, Direction=N/A */
+	uint8_t reserved32c;		/* Byte offset 0x32c, CSR Addr 0x54196, Direction=N/A */
+	uint8_t reserved32d;		/* Byte offset 0x32d, CSR Addr 0x54196, Direction=N/A */
+	uint8_t reserved32e;		/* Byte offset 0x32e, CSR Addr 0x54197, Direction=N/A */
+	uint8_t reserved32f;		/* Byte offset 0x32f, CSR Addr 0x54197, Direction=N/A */
+	uint8_t reserved330;		/* Byte offset 0x330, CSR Addr 0x54198, Direction=N/A */
+	uint8_t reserved331;		/* Byte offset 0x331, CSR Addr 0x54198, Direction=N/A */
+	uint8_t reserved332;		/* Byte offset 0x332, CSR Addr 0x54199, Direction=N/A */
+	uint8_t reserved333;		/* Byte offset 0x333, CSR Addr 0x54199, Direction=N/A */
+	uint8_t reserved334;		/* Byte offset 0x334, CSR Addr 0x5419a, Direction=N/A */
+	uint8_t reserved335;		/* Byte offset 0x335, CSR Addr 0x5419a, Direction=N/A */
+	uint8_t reserved336;		/* Byte offset 0x336, CSR Addr 0x5419b, Direction=N/A */
+	uint8_t reserved337;		/* Byte offset 0x337, CSR Addr 0x5419b, Direction=N/A */
+	uint8_t reserved338;		/* Byte offset 0x338, CSR Addr 0x5419c, Direction=N/A */
+	uint8_t reserved339;		/* Byte offset 0x339, CSR Addr 0x5419c, Direction=N/A */
+	uint8_t reserved33a;		/* Byte offset 0x33a, CSR Addr 0x5419d, Direction=N/A */
+	uint8_t reserved33b;		/* Byte offset 0x33b, CSR Addr 0x5419d, Direction=N/A */
+	uint8_t reserved33c;		/* Byte offset 0x33c, CSR Addr 0x5419e, Direction=N/A */
+	uint8_t reserved33d;		/* Byte offset 0x33d, CSR Addr 0x5419e, Direction=N/A */
+	uint8_t reserved33e;		/* Byte offset 0x33e, CSR Addr 0x5419f, Direction=N/A */
+	uint8_t reserved33f;		/* Byte offset 0x33f, CSR Addr 0x5419f, Direction=N/A */
+	uint8_t reserved340;		/* Byte offset 0x340, CSR Addr 0x541a0, Direction=N/A */
+	uint8_t reserved341;		/* Byte offset 0x341, CSR Addr 0x541a0, Direction=N/A */
+	uint8_t reserved342;		/* Byte offset 0x342, CSR Addr 0x541a1, Direction=N/A */
+	uint8_t reserved343;		/* Byte offset 0x343, CSR Addr 0x541a1, Direction=N/A */
+	uint8_t reserved344;		/* Byte offset 0x344, CSR Addr 0x541a2, Direction=N/A */
+	uint8_t reserved345;		/* Byte offset 0x345, CSR Addr 0x541a2, Direction=N/A */
+	uint8_t reserved346;		/* Byte offset 0x346, CSR Addr 0x541a3, Direction=N/A */
+	uint8_t reserved347;		/* Byte offset 0x347, CSR Addr 0x541a3, Direction=N/A */
+	uint8_t reserved348;		/* Byte offset 0x348, CSR Addr 0x541a4, Direction=N/A */
+	uint8_t reserved349;		/* Byte offset 0x349, CSR Addr 0x541a4, Direction=N/A */
+	uint8_t reserved34a;		/* Byte offset 0x34a, CSR Addr 0x541a5, Direction=N/A */
+	uint8_t reserved34b;		/* Byte offset 0x34b, CSR Addr 0x541a5, Direction=N/A */
+	uint8_t reserved34c;		/* Byte offset 0x34c, CSR Addr 0x541a6, Direction=N/A */
+	uint8_t reserved34d;		/* Byte offset 0x34d, CSR Addr 0x541a6, Direction=N/A */
+	uint8_t reserved34e;		/* Byte offset 0x34e, CSR Addr 0x541a7, Direction=N/A */
+	uint8_t reserved34f;		/* Byte offset 0x34f, CSR Addr 0x541a7, Direction=N/A */
+	uint8_t reserved350;		/* Byte offset 0x350, CSR Addr 0x541a8, Direction=N/A */
+	uint8_t reserved351;		/* Byte offset 0x351, CSR Addr 0x541a8, Direction=N/A */
+	uint8_t reserved352;		/* Byte offset 0x352, CSR Addr 0x541a9, Direction=N/A */
+	uint8_t reserved353;		/* Byte offset 0x353, CSR Addr 0x541a9, Direction=N/A */
+	uint8_t reserved354;		/* Byte offset 0x354, CSR Addr 0x541aa, Direction=N/A */
+	uint8_t reserved355;		/* Byte offset 0x355, CSR Addr 0x541aa, Direction=N/A */
+	uint8_t reserved356;		/* Byte offset 0x356, CSR Addr 0x541ab, Direction=N/A */
+	uint8_t reserved357;		/* Byte offset 0x357, CSR Addr 0x541ab, Direction=N/A */
+	uint8_t reserved358;		/* Byte offset 0x358, CSR Addr 0x541ac, Direction=N/A */
+	uint8_t reserved359;		/* Byte offset 0x359, CSR Addr 0x541ac, Direction=N/A */
+	uint8_t reserved35a;		/* Byte offset 0x35a, CSR Addr 0x541ad, Direction=N/A */
+	uint8_t reserved35b;		/* Byte offset 0x35b, CSR Addr 0x541ad, Direction=N/A */
+	uint8_t reserved35c;		/* Byte offset 0x35c, CSR Addr 0x541ae, Direction=N/A */
+	uint8_t reserved35d;		/* Byte offset 0x35d, CSR Addr 0x541ae, Direction=N/A */
+	uint8_t reserved35e;		/* Byte offset 0x35e, CSR Addr 0x541af, Direction=N/A */
+	uint8_t reserved35f;		/* Byte offset 0x35f, CSR Addr 0x541af, Direction=N/A */
+	uint8_t reserved360;		/* Byte offset 0x360, CSR Addr 0x541b0, Direction=N/A */
+	uint8_t reserved361;		/* Byte offset 0x361, CSR Addr 0x541b0, Direction=N/A */
+	uint8_t reserved362;		/* Byte offset 0x362, CSR Addr 0x541b1, Direction=N/A */
+	uint8_t reserved363;		/* Byte offset 0x363, CSR Addr 0x541b1, Direction=N/A */
+	uint8_t reserved364;		/* Byte offset 0x364, CSR Addr 0x541b2, Direction=N/A */
+	uint8_t reserved365;		/* Byte offset 0x365, CSR Addr 0x541b2, Direction=N/A */
+	uint8_t reserved366;		/* Byte offset 0x366, CSR Addr 0x541b3, Direction=N/A */
+	uint8_t reserved367;		/* Byte offset 0x367, CSR Addr 0x541b3, Direction=N/A */
+	uint8_t reserved368;		/* Byte offset 0x368, CSR Addr 0x541b4, Direction=N/A */
+	uint8_t reserved369;		/* Byte offset 0x369, CSR Addr 0x541b4, Direction=N/A */
+	uint8_t reserved36a;		/* Byte offset 0x36a, CSR Addr 0x541b5, Direction=N/A */
+	uint8_t reserved36b;		/* Byte offset 0x36b, CSR Addr 0x541b5, Direction=N/A */
+	uint8_t reserved36c;		/* Byte offset 0x36c, CSR Addr 0x541b6, Direction=N/A */
+	uint8_t reserved36d;		/* Byte offset 0x36d, CSR Addr 0x541b6, Direction=N/A */
+	uint8_t reserved36e;		/* Byte offset 0x36e, CSR Addr 0x541b7, Direction=N/A */
+	uint8_t reserved36f;		/* Byte offset 0x36f, CSR Addr 0x541b7, Direction=N/A */
+	uint8_t reserved370;		/* Byte offset 0x370, CSR Addr 0x541b8, Direction=N/A */
+	uint8_t reserved371;		/* Byte offset 0x371, CSR Addr 0x541b8, Direction=N/A */
+	uint8_t reserved372;		/* Byte offset 0x372, CSR Addr 0x541b9, Direction=N/A */
+	uint8_t reserved373;		/* Byte offset 0x373, CSR Addr 0x541b9, Direction=N/A */
+	uint8_t reserved374;		/* Byte offset 0x374, CSR Addr 0x541ba, Direction=N/A */
+	uint8_t reserved375;		/* Byte offset 0x375, CSR Addr 0x541ba, Direction=N/A */
+	uint8_t reserved376;		/* Byte offset 0x376, CSR Addr 0x541bb, Direction=N/A */
+	uint8_t reserved377;		/* Byte offset 0x377, CSR Addr 0x541bb, Direction=N/A */
+	uint8_t reserved378;		/* Byte offset 0x378, CSR Addr 0x541bc, Direction=N/A */
+	uint8_t reserved379;		/* Byte offset 0x379, CSR Addr 0x541bc, Direction=N/A */
+	uint8_t reserved37a;		/* Byte offset 0x37a, CSR Addr 0x541bd, Direction=N/A */
+	uint8_t reserved37b;		/* Byte offset 0x37b, CSR Addr 0x541bd, Direction=N/A */
+	uint8_t reserved37c;		/* Byte offset 0x37c, CSR Addr 0x541be, Direction=N/A */
+	uint8_t reserved37d;		/* Byte offset 0x37d, CSR Addr 0x541be, Direction=N/A */
+	uint8_t reserved37e;		/* Byte offset 0x37e, CSR Addr 0x541bf, Direction=N/A */
+	uint8_t reserved37f;		/* Byte offset 0x37f, CSR Addr 0x541bf, Direction=N/A */
+	uint8_t reserved380;		/* Byte offset 0x380, CSR Addr 0x541c0, Direction=N/A */
+	uint8_t reserved381;		/* Byte offset 0x381, CSR Addr 0x541c0, Direction=N/A */
+	uint8_t reserved382;		/* Byte offset 0x382, CSR Addr 0x541c1, Direction=N/A */
+	uint8_t reserved383;		/* Byte offset 0x383, CSR Addr 0x541c1, Direction=N/A */
+	uint8_t reserved384;		/* Byte offset 0x384, CSR Addr 0x541c2, Direction=N/A */
+	uint8_t reserved385;		/* Byte offset 0x385, CSR Addr 0x541c2, Direction=N/A */
+	uint8_t reserved386;		/* Byte offset 0x386, CSR Addr 0x541c3, Direction=N/A */
+	uint8_t reserved387;		/* Byte offset 0x387, CSR Addr 0x541c3, Direction=N/A */
+	uint8_t reserved388;		/* Byte offset 0x388, CSR Addr 0x541c4, Direction=N/A */
+	uint8_t reserved389;		/* Byte offset 0x389, CSR Addr 0x541c4, Direction=N/A */
+	uint8_t reserved38a;		/* Byte offset 0x38a, CSR Addr 0x541c5, Direction=N/A */
+	uint8_t reserved38b;		/* Byte offset 0x38b, CSR Addr 0x541c5, Direction=N/A */
+	uint8_t reserved38c;		/* Byte offset 0x38c, CSR Addr 0x541c6, Direction=N/A */
+	uint8_t reserved38d;		/* Byte offset 0x38d, CSR Addr 0x541c6, Direction=N/A */
+	uint8_t reserved38e;		/* Byte offset 0x38e, CSR Addr 0x541c7, Direction=N/A */
+	uint8_t reserved38f;		/* Byte offset 0x38f, CSR Addr 0x541c7, Direction=N/A */
+	uint8_t reserved390;		/* Byte offset 0x390, CSR Addr 0x541c8, Direction=N/A */
+	uint8_t reserved391;		/* Byte offset 0x391, CSR Addr 0x541c8, Direction=N/A */
+	uint8_t reserved392;		/* Byte offset 0x392, CSR Addr 0x541c9, Direction=N/A */
+	uint8_t reserved393;		/* Byte offset 0x393, CSR Addr 0x541c9, Direction=N/A */
+	uint8_t reserved394;		/* Byte offset 0x394, CSR Addr 0x541ca, Direction=N/A */
+	uint8_t reserved395;		/* Byte offset 0x395, CSR Addr 0x541ca, Direction=N/A */
+	uint8_t reserved396;		/* Byte offset 0x396, CSR Addr 0x541cb, Direction=N/A */
+	uint8_t reserved397;		/* Byte offset 0x397, CSR Addr 0x541cb, Direction=N/A */
+	uint8_t reserved398;		/* Byte offset 0x398, CSR Addr 0x541cc, Direction=N/A */
+	uint8_t reserved399;		/* Byte offset 0x399, CSR Addr 0x541cc, Direction=N/A */
+	uint8_t reserved39a;		/* Byte offset 0x39a, CSR Addr 0x541cd, Direction=N/A */
+	uint8_t reserved39b;		/* Byte offset 0x39b, CSR Addr 0x541cd, Direction=N/A */
+	uint8_t reserved39c;		/* Byte offset 0x39c, CSR Addr 0x541ce, Direction=N/A */
+	uint8_t reserved39d;		/* Byte offset 0x39d, CSR Addr 0x541ce, Direction=N/A */
+	uint8_t reserved39e;		/* Byte offset 0x39e, CSR Addr 0x541cf, Direction=N/A */
+	uint8_t reserved39f;		/* Byte offset 0x39f, CSR Addr 0x541cf, Direction=N/A */
+	uint8_t reserved3a0;		/* Byte offset 0x3a0, CSR Addr 0x541d0, Direction=N/A */
+	uint8_t reserved3a1;		/* Byte offset 0x3a1, CSR Addr 0x541d0, Direction=N/A */
+	uint8_t reserved3a2;		/* Byte offset 0x3a2, CSR Addr 0x541d1, Direction=N/A */
+	uint8_t reserved3a3;		/* Byte offset 0x3a3, CSR Addr 0x541d1, Direction=N/A */
+	uint8_t reserved3a4;		/* Byte offset 0x3a4, CSR Addr 0x541d2, Direction=N/A */
+	uint8_t reserved3a5;		/* Byte offset 0x3a5, CSR Addr 0x541d2, Direction=N/A */
+	uint8_t reserved3a6;		/* Byte offset 0x3a6, CSR Addr 0x541d3, Direction=N/A */
+	uint8_t reserved3a7;		/* Byte offset 0x3a7, CSR Addr 0x541d3, Direction=N/A */
+	uint8_t reserved3a8;		/* Byte offset 0x3a8, CSR Addr 0x541d4, Direction=N/A */
+	uint8_t reserved3a9;		/* Byte offset 0x3a9, CSR Addr 0x541d4, Direction=N/A */
+	uint8_t reserved3aa;		/* Byte offset 0x3aa, CSR Addr 0x541d5, Direction=N/A */
+	uint8_t reserved3ab;		/* Byte offset 0x3ab, CSR Addr 0x541d5, Direction=N/A */
+	uint8_t reserved3ac;		/* Byte offset 0x3ac, CSR Addr 0x541d6, Direction=N/A */
+	uint8_t reserved3ad;		/* Byte offset 0x3ad, CSR Addr 0x541d6, Direction=N/A */
+	uint8_t reserved3ae;		/* Byte offset 0x3ae, CSR Addr 0x541d7, Direction=N/A */
+	uint8_t reserved3af;		/* Byte offset 0x3af, CSR Addr 0x541d7, Direction=N/A */
+	uint8_t reserved3b0;		/* Byte offset 0x3b0, CSR Addr 0x541d8, Direction=N/A */
+	uint8_t reserved3b1;		/* Byte offset 0x3b1, CSR Addr 0x541d8, Direction=N/A */
+	uint8_t reserved3b2;		/* Byte offset 0x3b2, CSR Addr 0x541d9, Direction=N/A */
+	uint8_t reserved3b3;		/* Byte offset 0x3b3, CSR Addr 0x541d9, Direction=N/A */
+	uint8_t reserved3b4;		/* Byte offset 0x3b4, CSR Addr 0x541da, Direction=N/A */
+	uint8_t reserved3b5;		/* Byte offset 0x3b5, CSR Addr 0x541da, Direction=N/A */
+	uint8_t reserved3b6;		/* Byte offset 0x3b6, CSR Addr 0x541db, Direction=N/A */
+	uint8_t reserved3b7;		/* Byte offset 0x3b7, CSR Addr 0x541db, Direction=N/A */
+	uint8_t reserved3b8;		/* Byte offset 0x3b8, CSR Addr 0x541dc, Direction=N/A */
+	uint8_t reserved3b9;		/* Byte offset 0x3b9, CSR Addr 0x541dc, Direction=N/A */
+	uint8_t reserved3ba;		/* Byte offset 0x3ba, CSR Addr 0x541dd, Direction=N/A */
+	uint8_t reserved3bb;		/* Byte offset 0x3bb, CSR Addr 0x541dd, Direction=N/A */
+	uint8_t reserved3bc;		/* Byte offset 0x3bc, CSR Addr 0x541de, Direction=N/A */
+	uint8_t reserved3bd;		/* Byte offset 0x3bd, CSR Addr 0x541de, Direction=N/A */
+	uint8_t reserved3be;		/* Byte offset 0x3be, CSR Addr 0x541df, Direction=N/A */
+	uint8_t reserved3bf;		/* Byte offset 0x3bf, CSR Addr 0x541df, Direction=N/A */
+	uint8_t reserved3c0;		/* Byte offset 0x3c0, CSR Addr 0x541e0, Direction=N/A */
+	uint8_t reserved3c1;		/* Byte offset 0x3c1, CSR Addr 0x541e0, Direction=N/A */
+	uint8_t reserved3c2;		/* Byte offset 0x3c2, CSR Addr 0x541e1, Direction=N/A */
+	uint8_t reserved3c3;		/* Byte offset 0x3c3, CSR Addr 0x541e1, Direction=N/A */
+	uint8_t reserved3c4;		/* Byte offset 0x3c4, CSR Addr 0x541e2, Direction=N/A */
+	uint8_t reserved3c5;		/* Byte offset 0x3c5, CSR Addr 0x541e2, Direction=N/A */
+	uint8_t reserved3c6;		/* Byte offset 0x3c6, CSR Addr 0x541e3, Direction=N/A */
+	uint8_t reserved3c7;		/* Byte offset 0x3c7, CSR Addr 0x541e3, Direction=N/A */
+	uint8_t reserved3c8;		/* Byte offset 0x3c8, CSR Addr 0x541e4, Direction=N/A */
+	uint8_t reserved3c9;		/* Byte offset 0x3c9, CSR Addr 0x541e4, Direction=N/A */
+	uint8_t reserved3ca;		/* Byte offset 0x3ca, CSR Addr 0x541e5, Direction=N/A */
+	uint8_t reserved3cb;		/* Byte offset 0x3cb, CSR Addr 0x541e5, Direction=N/A */
+	uint8_t reserved3cc;		/* Byte offset 0x3cc, CSR Addr 0x541e6, Direction=N/A */
+	uint8_t reserved3cd;		/* Byte offset 0x3cd, CSR Addr 0x541e6, Direction=N/A */
+	uint8_t reserved3ce;		/* Byte offset 0x3ce, CSR Addr 0x541e7, Direction=N/A */
+	uint8_t reserved3cf;		/* Byte offset 0x3cf, CSR Addr 0x541e7, Direction=N/A */
+	uint8_t reserved3d0;		/* Byte offset 0x3d0, CSR Addr 0x541e8, Direction=N/A */
+	uint8_t reserved3d1;		/* Byte offset 0x3d1, CSR Addr 0x541e8, Direction=N/A */
+	uint8_t reserved3d2;		/* Byte offset 0x3d2, CSR Addr 0x541e9, Direction=N/A */
+	uint8_t reserved3d3;		/* Byte offset 0x3d3, CSR Addr 0x541e9, Direction=N/A */
+	uint8_t reserved3d4;		/* Byte offset 0x3d4, CSR Addr 0x541ea, Direction=N/A */
+	uint8_t reserved3d5;		/* Byte offset 0x3d5, CSR Addr 0x541ea, Direction=N/A */
+	uint8_t reserved3d6;		/* Byte offset 0x3d6, CSR Addr 0x541eb, Direction=N/A */
+	uint8_t reserved3d7;		/* Byte offset 0x3d7, CSR Addr 0x541eb, Direction=N/A */
+	uint8_t reserved3d8;		/* Byte offset 0x3d8, CSR Addr 0x541ec, Direction=N/A */
+	uint8_t reserved3d9;		/* Byte offset 0x3d9, CSR Addr 0x541ec, Direction=N/A */
+	uint8_t reserved3da;		/* Byte offset 0x3da, CSR Addr 0x541ed, Direction=N/A */
+	uint8_t reserved3db;		/* Byte offset 0x3db, CSR Addr 0x541ed, Direction=N/A */
+	uint8_t reserved3dc;		/* Byte offset 0x3dc, CSR Addr 0x541ee, Direction=N/A */
+	uint8_t reserved3dd;		/* Byte offset 0x3dd, CSR Addr 0x541ee, Direction=N/A */
+	uint8_t reserved3de;		/* Byte offset 0x3de, CSR Addr 0x541ef, Direction=N/A */
+	uint8_t reserved3df;		/* Byte offset 0x3df, CSR Addr 0x541ef, Direction=N/A */
+	uint8_t reserved3e0;		/* Byte offset 0x3e0, CSR Addr 0x541f0, Direction=N/A */
+	uint8_t reserved3e1;		/* Byte offset 0x3e1, CSR Addr 0x541f0, Direction=N/A */
+	uint8_t reserved3e2;		/* Byte offset 0x3e2, CSR Addr 0x541f1, Direction=N/A */
+	uint8_t reserved3e3;		/* Byte offset 0x3e3, CSR Addr 0x541f1, Direction=N/A */
+	uint8_t reserved3e4;		/* Byte offset 0x3e4, CSR Addr 0x541f2, Direction=N/A */
+	uint8_t reserved3e5;		/* Byte offset 0x3e5, CSR Addr 0x541f2, Direction=N/A */
+	uint8_t reserved3e6;		/* Byte offset 0x3e6, CSR Addr 0x541f3, Direction=N/A */
+	uint8_t reserved3e7;		/* Byte offset 0x3e7, CSR Addr 0x541f3, Direction=N/A */
+	uint8_t reserved3e8;		/* Byte offset 0x3e8, CSR Addr 0x541f4, Direction=N/A */
+	uint8_t reserved3e9;		/* Byte offset 0x3e9, CSR Addr 0x541f4, Direction=N/A */
+	uint8_t reserved3ea;		/* Byte offset 0x3ea, CSR Addr 0x541f5, Direction=N/A */
+	uint8_t reserved3eb;		/* Byte offset 0x3eb, CSR Addr 0x541f5, Direction=N/A */
+	uint8_t reserved3ec;		/* Byte offset 0x3ec, CSR Addr 0x541f6, Direction=N/A */
+	uint8_t reserved3ed;		/* Byte offset 0x3ed, CSR Addr 0x541f6, Direction=N/A */
+	uint8_t reserved3ee;		/* Byte offset 0x3ee, CSR Addr 0x541f7, Direction=N/A */
+	uint8_t reserved3ef;		/* Byte offset 0x3ef, CSR Addr 0x541f7, Direction=N/A */
+	uint8_t reserved3f0;		/* Byte offset 0x3f0, CSR Addr 0x541f8, Direction=N/A */
+	uint8_t reserved3f1;		/* Byte offset 0x3f1, CSR Addr 0x541f8, Direction=N/A */
+	uint8_t reserved3f2;		/* Byte offset 0x3f2, CSR Addr 0x541f9, Direction=N/A */
+	uint8_t reserved3f3;		/* Byte offset 0x3f3, CSR Addr 0x541f9, Direction=N/A */
+	uint8_t reserved3f4;		/* Byte offset 0x3f4, CSR Addr 0x541fa, Direction=N/A */
+	uint8_t reserved3f5;		/* Byte offset 0x3f5, CSR Addr 0x541fa, Direction=N/A */
+	uint16_t alt_cas_l;		/*
+					 * Byte offset 0x3f6, CSR Addr 0x541fb, Direction=in
+					 * This field must be populated if RdDBI is enabled
+					 * (applicable when mr5[A12] == 1).
+					 * RdDBI is dynamically disabled in certain training steps,
+					 * and so the [RdDBI disabled] CAS Latency must be provided
+					 * in this field.
+					 * The required encoding is as follows:
+					 * alt_cas_l[0] == 0: use value in mr0
+					 * alt_cas_l[0] == 1: use value in alt_cas_l, i.e.,
+					 *   mr0{A[12],A[6],A[5],A[4],A[2]} = alt_cas_l[12,6,5,4,2]
+					 * Other bits are ignored
+					 */
+	uint8_t alt_wcas_l;		/*
+					 * Byte offset 0x3f8, CSR Addr 0x541fc, Direction=In
+					 * This field must be populated if 2tCK write preambles are
+					 * enabled (applicable when mr4[A12] == 1).
+					 * 2tCK write prambles are dynamically disabled in certain
+					 * training steps, and so the [1tCK write preamble] WCAS
+					 * Latency must be provided in this field.
+					 * The required encoding is as follows:
+					 * alt_wcas_l[0] == 0: use value in mr2
+					 * alt_wcas_l[0] == 1: use value in alt_wcas_l, i.e.,
+					 *   mr2{A[5],A[4],A[3]} = alt_wcas_l[5,4,3]
+					 * Other bits are ignored
+					 */
+	uint8_t d4misc;			/*
+					 * Byte offset 0x3f9, CSR Addr 0x541fc, Direction=In
+					 * Contains various options for training DDR4 Devices.
+					 *
+					 * Bit fields:
+					 *
+					 * d4misc[7:5,2,1] RFU, must be zero
+					 *
+					 * d4misc[0] = protect memory reset
+					 *   0x1 = dfi_reset_n cannot control BP_MEMRESERT_L to
+					 *         devices after training.
+					 *   0x0 = dfi_resert_n can control BP_MEMRESERT_L to
+					 *         devices after training
+					 *
+					 * d4misc[3]: reserved
+					 *
+					 * d4misc[4]: DRAM reset mode
+					 *   0x1 = Do not reset DRAM during devinit
+					 *   0x0 = Reset DRAM during devinit
+					 */
+} __packed __aligned(2);
+
+#endif /* MNPMUSRAMMSGBLOCK_DDR4_H */
diff --git a/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_lpddr4.h b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_lpddr4.h
new file mode 100644
index 00000000..fb1cd58b
--- /dev/null
+++ b/drivers/st/ddr/phy/firmware/include/mnpmusrammsgblock_lpddr4.h
@@ -0,0 +1,925 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MNPMUSRAMMSGBLOCK_LPDDR4_H
+#define MNPMUSRAMMSGBLOCK_LPDDR4_H
+
+/* LPDDR4_1D training firmware message block structure
+ *
+ * Please refer to the Training Firmware App Note for futher information about
+ * the usage for Message Block.
+ */
+struct pmu_smb_ddr_1d {
+	uint8_t reserved00;		/*
+					 * Byte offset 0x00, CSR Addr 0x54000, Direction=In
+					 * reserved00[0:4] RFU, must be zero
+					 *
+					 * reserved00[5] = Quick Rd2D during 1D Training
+					 *   0x1 = Read Deskew will begin by enabling and quickly
+					 *   training the phy's per-lane reference voltages.
+					 *   Training the vrefDACs CSRs will increase the maximum 1D
+					 *   training time by around half a millisecond, but will
+					 *   improve 1D training accuracy on systems with
+					 *   significant voltage-offsets between lane read eyes.
+					 *   0x0 = Read Deskew will assume the messageblock's
+					 *   phyVref setting is optimal for all lanes.
+					 *
+					 * reserved00[6] = Enable High Effort WrDQ1D
+					 *   0x1 = WrDQ1D will conditionally retry training at
+					 *   several extra RxClkDly Timings. This will increase the
+					 *   maximum 1D training time by up to 4 extra iterations of
+					 *   WrDQ1D. This is only required in systems that suffer
+					 *   from very large, asymmetric eye-collapse when receiving
+					 *   PRBS patterns.
+					 *   0x0 = WrDQ1D assume rxClkDly values found by SI
+					 *   Friendly RdDqs1D will work for receiving PRBS patterns
+					 *
+					 * reserved00[7] = Optimize for the special hard macros in
+					 * TSMC28.
+					 *   0x1 = set if the phy being trained was manufactured in
+					 *   any TSMC28 process node.
+					 *   0x0 = otherwise, when not training a TSMC28 phy, leave
+					 *   this field as 0.
+					 */
+	uint8_t msgmisc;		/*
+					 * Byte offset 0x01, CSR Addr 0x54000, Direction=In
+					 * Contains various global options for training.
+					 *
+					 * Bit fields:
+					 *
+					 * msgmisc[0] MTESTEnable
+					 *   0x1 = Pulse primary digital test output bump at the end
+					 *   of each major training stage. This enables observation
+					 *   of training stage completion by observing the digital
+					 *   test output.
+					 *   0x0 = Do not pulse primary digital test output bump
+					 *
+					 * msgmisc[1] SimulationOnlyReset
+					 *   0x1 = Verilog only simulation option to shorten
+					 *   duration of DRAM reset pulse length to 1ns.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use reset pulse length specified by JEDEC
+					 *   standard.
+					 *
+					 * msgmisc[2] SimulationOnlyTraining
+					 *   0x1 = Verilog only simulation option to shorten the
+					 *   duration of the training steps by performing fewer
+					 *   iterations.
+					 *   Must never be set to 1 in silicon.
+					 *   0x0 = Use standard training duration.
+					 *
+					 * msgmisc[3] Disable Boot Clock
+					 *   0x1 = Disable boot frequency clock when initializing
+					 *   DRAM. (not recommended)
+					 *   0x0 = Use Boot Frequency Clock
+					 *
+					 * msgmisc[4] Suppress streaming messages, including
+					 * assertions, regardless of hdtctrl setting.
+					 * Stage Completion messages, as well as training completion
+					 * and error messages are still sent depending on hdtctrl
+					 * setting.
+					 *
+					 * msgmisc[5] PerByteMaxRdLat
+					 *   0x1 = Each DBYTE will return dfi_rddata_valid at the
+					 *   lowest possible latency. This may result in unaligned
+					 *   data between bytes to be returned to the DFI.
+					 *   0x0 = Every DBYTE will return dfi_rddata_valid
+					 *   simultaneously. This will ensure that data bytes will
+					 *   return aligned accesses to the DFI.
+					 *
+					 * msgmisc[7-6] RFU, must be zero
+					 *
+					 * Notes:
+					 *
+					 * - SimulationOnlyReset and SimulationOnlyTraining can be
+					 *   used to speed up simulation run times, and must never
+					 *   be used in real silicon. Some VIPs may have checks on
+					 *   DRAM reset parameters that may need to be disabled when
+					 *   using SimulationOnlyReset.
+					 */
+	uint16_t pmurevision;		/*
+					 * Byte offset 0x02, CSR Addr 0x54001, Direction=Out
+					 * PMU firmware revision ID
+					 * After training is run, this address will contain the
+					 * revision ID of the firmware
+					 */
+	uint8_t pstate;			/*
+					 * Byte offset 0x04, CSR Addr 0x54002, Direction=In
+					 * Must be set to the target pstate to be trained
+					 *   0x0 = pstate 0
+					 *   0x1 = pstate 1
+					 *   0x2 = pstate 2
+					 *   0x3 = pstate 3
+					 *   All other encodings are reserved
+					 */
+	uint8_t pllbypassen;		/*
+					 * Byte offset 0x05, CSR Addr 0x54002, Direction=In
+					 * Set according to whether target pstate uses PHY PLL
+					 * bypass
+					 *   0x0 = PHY PLL is enabled for target pstate
+					 *   0x1 = PHY PLL is bypassed for target pstate
+					 */
+	uint16_t dramfreq;		/*
+					 * Byte offset 0x06, CSR Addr 0x54003, Direction=In
+					 * DDR data rate for the target pstate in units of MT/s.
+					 * For example enter 0x0640 for DDR1600.
+					 */
+	uint8_t dfifreqratio;		/*
+					 * Byte offset 0x08, CSR Addr 0x54004, Direction=In
+					 * Frequency ratio betwen DfiCtlClk and SDRAM memclk.
+					 *   0x1 = 1:1
+					 *   0x2 = 1:2
+					 *   0x4 = 1:4
+					 */
+	uint8_t bpznresval;		/*
+					 * Byte offset 0x09, CSR Addr 0x54004, Direction=In
+					 * Overwrite the value of precision resistor connected to
+					 * Phy BP_ZN
+					 *   0x00 = Do not program. Use current CSR value.
+					 *   0xf0 = 240 Ohm
+					 *   0x78 = 120 Ohm
+					 *   0x28 = 40 Ohm
+					 *   All other values are reserved.
+					 * It is recommended to set this to 0x00.
+					 */
+	uint8_t phyodtimpedance;	/*
+					 * Byte offset 0x0a, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the termination impedance in ohms
+					 * used by PHY during reads.
+					 *
+					 * 0x0 = Firmware skips programming (must be manually
+					 * programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal termination impedance values.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must determine the correct value
+					 * through SI simulation or other methods.
+					 */
+	uint8_t phydrvimpedance;	/*
+					 * Byte offset 0x0b, CSR Addr 0x54005, Direction=In
+					 * Must be programmed to the driver impedance in ohms used
+					 * by PHY during writes for all DBYTE drivers
+					 * (DQ/DM/DBI/DQS).
+					 *
+					 *   0x0 = Firmware skips programming (must be manually
+					 *   programmed by user prior to training start)
+					 *
+					 * See PHY databook for legal R_on driver impedance values.
+					 *
+					 * For digital simulation, any value can be used that is not
+					 * Hi-Z. For silicon, the users must determine the correct
+					 * value through SI simulation or other methods.
+					 */
+	uint8_t phyvref;		/*
+					 * Byte offset 0x0c, CSR Addr 0x54006, Direction=In
+					 * Must be programmed with the Vref level to be used by the
+					 * PHY during reads
+					 *
+					 * The units of this field are a percentage of VDDQ
+					 * according to the following equation:
+					 *
+					 * Receiver Vref = VDDQ*phyvref[6:0]/128
+					 *
+					 * For example to set Vref at 0.25*VDDQ, set this field to
+					 * 0x20.
+					 *
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must calculate the analytical Vref by
+					 * using the impedances, terminations, and series resistance
+					 * present in the system.
+					 */
+	uint8_t lp4misc;		/*
+					 * Byte offset 0x0d, CSR Addr 0x54006, Direction=In
+					 * Lp4 specific options for training.
+					 *
+					 * Bit fields:
+					 *
+					 * lp4misc[0] Enable dfi_reset_n
+					 *
+					 *   0x0 = (Recommended) PHY internal registers control
+					 *   memreset during training, and also after training.
+					 *   dfi_reset_n cannot control the PHY BP_MEMRESET_L pin.
+					 *
+					 *   0x1 = Enables dfi_reset_n to control memreset after
+					 *   training. PHY Internal registers control memreset
+					 *   during training only. To ensure that no glitches occur
+					 *   on BP_MEMRESET at the end of training, The MC must
+					 *   drive dfi_reset_n=1'b1 _prior to starting training_
+					 *
+					 * lp4misc[7-1] RFU, must be zero
+					 */
+	uint8_t reserved0e;		/*
+					 * Byte offset 0x0e, CSR Addr 0x54007, Direction=In
+					 * Bit Field for enabling optional 2D training features
+					 * that impact both Rx2D and Tx2D.
+					 *
+					 * reserved0E[0:3]: bitTimeControl
+					 * input for the amount of data bits 2D writes/reads per DQ
+					 * before deciding if any specific voltage and delay setting
+					 * passes or fails. Every time this input increases by 1,
+					 * the number of 2D data comparisons is doubled. The 2D run
+					 * time will increase proportionally to the number of bit
+					 * times requested per point.
+					 *   0 = 288 bits per point (legacy behavior)
+					 *   1 = 576 bits per point
+					 *   2 = 1.125 kilobits per point
+					 *     . . .
+					 *   15 = 9 megabits per point
+					 *
+					 * reserved0E[4]: Exhaustive2D
+					 *   0 = 2D optimization assumes the optimal trained point
+					 *   is near the 1D trained point (legacy behavior)
+					 *   1 = 2D optimization searches the entire passing region
+					 *   at the cost of run time. Recommended for optimal
+					 *   results any time the optimal trained point is expected
+					 *   to be near the edges of the eyes instead of near the 1D
+					 *   trained point.
+					 *
+					 * reserved0E[5]: Detect Vref Eye Truncation, ignored if
+					 * eyeWeight2DControl == 0.
+					 *   0 = 2D optimizes for the passing region it can measure.
+					 *   1 = For every eye, 2D checks If the legal voltage range
+					 *   truncated the eye. If the true voltage margin cannot be
+					 *   measured, 2D will optimize heavily for delay margin
+					 *   instead of using incomplete voltage margin data. Eyes
+					 *   that are not truncated will still be optimized using
+					 *   user programmed weights.
+					 *
+					 * reserved0E[6]: eyeWeight2DControl
+					 *   0 = Use 8 bit weights for Delay_Weight2D and
+					 *   Voltage_Weight2D and disable TrunkV behavior.
+					 *   1 = Use 4 bit weights for Delay_weight2D and
+					 *   Voltage_Weight2D and enable TrunkV behavior.
+					 *
+					 * reserved0E[7]: RFU, must be 0
+					 */
+	uint8_t cstestfail;		/*
+					 * Byte offset 0x0f, CSR Addr 0x54007, Direction=Out
+					 * This field will be set if training fails on any rank.
+					 *   0x0 = No failures
+					 *   non-zero = one or more ranks failed training
+					 */
+	uint16_t sequencectrl;		/*
+					 * Byte offset 0x10, CSR Addr 0x54008, Direction=In
+					 * Controls the training steps to be run. Each bit
+					 * corresponds to a training step.
+					 *
+					 * If the bit is set to 1, the training step will run.
+					 * If the bit is set to 0, the training step will be
+					 * skipped.
+					 *
+					 * Training step to bit mapping:
+					 * sequencectrl[0] = Run DevInit - Device/phy
+					 *                   initialization. Should always be set.
+					 * sequencectrl[1] = Run WrLvl - Write leveling
+					 * sequencectrl[2] = Run RxEn - Read gate training
+					 * sequencectrl[3] = Run RdDQS1D - 1d read dqs training
+					 * sequencectrl[4] = Run WrDQ1D - 1d write dq training
+					 * sequencectrl[5] = RFU, must be zero
+					 * sequencectrl[6] = RFU, must be zero
+					 * sequencectrl[7] = RFU, must be zero
+					 * sequencectrl[8] = Run RdDeskew - Per lane read dq deskew
+					 *                   training
+					 * sequencectrl[9] = Run MxRdLat - Max read latency training
+					 * sequencectrl[11-10] = RFU, must be zero
+					 * sequencectrl[12] = Run LPCA - CA Training
+					 * sequencectrl[15-13] = RFU, must be zero
+					 */
+	uint8_t hdtctrl;		/*
+					 * Byte offset 0x12, CSR Addr 0x54009, Direction=In
+					 * To control the total number of debug messages, a
+					 * verbosity subfield (hdtctrl, Hardware Debug Trace
+					 * Control) exists in the message block. Every message has a
+					 * verbosity level associated with it, and as the hdtctrl
+					 * value is increased, less important s messages stop being
+					 * sent through the mailboxes. The meanings of several major
+					 * hdtctrl thresholds are explained below:
+					 *
+					 *   0x04 = Maximal debug messages (e.g., Eye contours)
+					 *   0x05 = Detailed debug messages (e.g. Eye delays)
+					 *   0x0A = Coarse debug messages (e.g. rank information)
+					 *   0xC8 = Stage completion
+					 *   0xC9 = Assertion messages
+					 *   0xFF = Firmware completion messages only
+					 */
+	uint8_t reserved13;		/*
+					 * Byte offset 0x13, CSR Addr 0x54009, Direction=In
+					 *
+					 *   0 = Default operation, unchanged.
+					 *   Others = RD DQ calibration Training steps are completed
+					 *   with user specified pattern.
+					 */
+	uint8_t reserved14;		/*
+					 * Byte offset 0x14, CSR Addr 0x5400a, Direction=In
+					 * Configure rd2D search iteration from a starting seed
+					 * point:
+					 *
+					 * reserved14[5:0]: If reserved14[6] is 0, Number of search
+					 * iterations (if 0, then default is 20); otherwise if this
+					 * value non zero, this value is used as a delta to filter
+					 * out points during the averaging: when averaging over a
+					 * dimension (delay or voltage), the points having a margin
+					 * smaller than the max of the eye in this dimension by at
+					 * least this delta value are filtered out.
+					 *
+					 * reserved14[6]: If set, instead of search, extract center
+					 * using an averaging function over the eye surface area,
+					 * where some points can be filtered out using
+					 * reserved14[5:0]
+					 *
+					 * reserved14[7]: if set, start search with large step size,
+					 * decreasing at each 4 iterations, down to 1 (do not care
+					 * if reserved14[6] is set)
+					 */
+	uint8_t reserved15;		/*
+					 * Byte offset 0x15, CSR Addr 0x5400a, Direction=In
+					 * Configure wr2D search iteration from a starting seed
+					 * point:
+					 *
+					 * reserved15[5:0]: If reserved15[6] is 0, Number of search
+					 * iterations (if 0, then default is 20); otherwise if this
+					 * value non zero, this value is used as a delta to filter
+					 * out points during the averaging: when averaging over a
+					 * dimension (delay or voltage), the points having a margin
+					 * smaller than the max of the eye in this dimension by at
+					 * least this delta value are filtered out.
+					 *
+					 * reserved15[6]: If set, instead of search, extract center
+					 * using an averaging function over the eye surface area,
+					 * where some points can be filtered out using
+					 * reserved15[5:0]
+					 *
+					 * reserved15[7]: if set, start search with large step size,
+					 * decreasing at each 4 iterations, down to 1 (do not care
+					 * if reserved15[6] is set)
+					 */
+	uint8_t dfimrlmargin;		/*
+					 * Byte offset 0x16, CSR Addr 0x5400b, Direction=In
+					 * Margin added to smallest passing trained DFI Max Read
+					 * Latency value, in units of DFI clocks. Recommended to be
+					 * >= 1.
+					 *
+					 * This margin must include the maximum positive drift
+					 * expected in tDQSCK over the target temperature and
+					 * voltage range of the users system.
+					 */
+	uint8_t reserved17;		/*
+					 * Byte offset 0x17, CSR Addr 0x5400b, Direction=In
+					 * Configure DB from which extra info is dump during 2D
+					 * training when maximal debug is set:
+					 *
+					 * reserved17[3:0]: first DB
+					 *
+					 * reserved17[7:4]: number of DB, including first DB (if 0,
+					 * no extra debug per DB is dump)
+					 */
+	uint8_t usebroadcastmr;		/*
+					 * Byte offset 0x18, CSR Addr 0x5400c, Direction=In
+					 * Training firmware can optionally set per rank mode
+					 * register values for DRAM partial array self-refresh
+					 * features if desired.
+					 *
+					 *   0x0 = Use mr<1:4, 11:14, 16:17, 22, 24>_a0 for rank 0
+					 *	   channel A
+					 *	   Use mr<1:4, 11:14, 16:17, 22, 24>_b0 for rank 0
+					 *	   channel B
+					 *	   Use mr<1:4, 11:14, 16:17, 22, 24>_a1 for rank 1
+					 *	   channel A
+					 *	   Use mr<1:4, 11:14, 16:17, 22, 24>_b1 for rank 1
+					 *	   channel B
+					 *
+					 *   0x1 = Use mr<1:4, 11:14, 16:17, 22, 24>_a0 setting for
+					 *	   all channels/ranks
+					 *
+					 * It is recommended in most LPDDR4 system configurations
+					 * to set this to 1.
+					 * It is recommended in LPDDR4x system configurations to
+					 * set this to 0.
+					 */
+	uint8_t lp4quickboot;		/*
+					 * Byte offset 0x19, CSR Addr 0x5400c, Direction=In
+					 * Enable Quickboot. It must be set to 0x0 since Quickboot
+					 * is only supported in dedicated Quickboot firmware.
+					 */
+	uint8_t reserved1a;		/*
+					 * Byte offset 0x1a, CSR Addr 0x5400d, Direction=In
+					 * Input for constraining the range of vref(DQ) values
+					 * training will collect data for, usually reducing training
+					 * time. However, too large of a voltage range may cause
+					 * longer 2D training times while too small of a voltage
+					 * range may truncate passing regions. When in doubt, leave
+					 * this field set to 0.
+					 * Used by 2D stages: Rd2D, Wr2D
+					 *
+					 * reserved1A[0-3]: Rd2D Voltage Range
+					 *   0 = Training will search all phy vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from phyVref
+					 *   2 = limit to +/-4 %VDDQ from phyVref
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from phyVref
+					 *
+					 * reserved1A[4-7]: Wr2D Voltage Range
+					 *   0 = Training will search all dram vref(DQ) settings
+					 *   1 = limit to +/-2 %VDDQ from mr14
+					 *   2 = limit to +/-4 %VDDQ from mr14
+					 *     . . .
+					 *   15 = limit to +/-30% VDDQ from mr14
+					 */
+	uint8_t catrainopt;		/*
+					 * Byte offset 0x1b, CSR Addr 0x5400d, Direction=In
+					 * CA training option bit field
+					 * [0] CA VREF Training
+					 *   1 = Enable CA VREF Training
+					 *   0 = Disable CA VREF Training
+					 *  WARNING: catrainopt[0] must be set to the same value in
+					 *  1D and 2D training.
+					 *
+					 * [1] Train terminated Rank only
+					 *   1 = Only train terminated rank in CA training
+					 *   0 = Train all ranks in CA training
+					 *
+					 * [2-7] RFU must be zero
+					 */
+	uint8_t x8mode;			/*
+					 * Byte offset 0x1c, CSR Addr 0x5400e, Direction=In
+					 * X8 mode configuration:
+					 *   0x0 = x16 configuration for all devices
+					 *   0xF = x8 configuration for all devices
+					 * All other values are RFU
+					 */
+	uint8_t reserved1d;		/* Byte offset 0x1d, CSR Addr 0x5400e, Direction=N/A */
+	uint8_t reserved1e;		/* Byte offset 0x1e, CSR Addr 0x5400f, Direction=N/A */
+	uint8_t share2dvrefresult;	/*
+					 * Byte offset 0x1f, CSR Addr 0x5400f, Direction=In
+					 * Bitmap that designates the phy's vref source for every
+					 * pstate
+					 * If share2dvrefresult[x] = 0, then after 2D training,
+					 * pstate x will continue using the phyVref provided in
+					 * pstate x's 1D messageblock.
+					 * If share2dvrefresult[x] = 1, then after 2D training,
+					 * pstate x will use the per-lane VrefDAC0/1 CSRs trained by
+					 * 2d training.
+					 */
+	uint8_t reserved20;		/* Byte offset 0x20, CSR Addr 0x54010, Direction=N/A */
+	uint8_t reserved21;		/* Byte offset 0x21, CSR Addr 0x54010, Direction=N/A */
+	uint16_t phyconfigoverride;	/*
+					 * Byte offset 0x22, CSR Addr 0x54011, Direction=In
+					 * Override PhyConfig csr.
+					 *   0x0: Use hardware csr value for PhyConfing
+					 *   (recommended)
+					 *   Other values: Use value for PhyConfig instead of
+					 *   Hardware value.
+					 *
+					 */
+	uint8_t enableddqscha;		/*
+					 * Byte offset 0x24, CSR Addr 0x54012, Direction=In
+					 * Total number of DQ bits enabled in PHY Channel A
+					 */
+	uint8_t cspresentcha;		/*
+					 * Byte offset 0x25, CSR Addr 0x54012, Direction=In
+					 * Indicates presence of DRAM at each chip select for PHY
+					 * channel A.
+					 *   0x1 = CS0 is populated with DRAM
+					 *   0x3 = CS0 and CS1 are populated with DRAM
+					 *
+					 * All other encodings are illegal
+					 */
+	int8_t cdd_cha_rr_1_0;		/*
+					 * Byte offset 0x26, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rr_0_1;		/*
+					 * Byte offset 0x27, CSR Addr 0x54013, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rw_1_1;		/*
+					 * Byte offset 0x28, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rw_1_0;		/*
+					 * Byte offset 0x29, CSR Addr 0x54014, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rw_0_1;		/*
+					 * Byte offset 0x2a, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_rw_0_0;		/*
+					 * Byte offset 0x2b, CSR Addr 0x54015, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs0 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_wr_1_1;		/*
+					 * Byte offset 0x2c, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_wr_1_0;		/*
+					 * Byte offset 0x2d, CSR Addr 0x54016, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_wr_0_1;		/*
+					 * Byte offset 0x2e, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to cs 1
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_wr_0_0;		/*
+					 * Byte offset 0x2f, CSR Addr 0x54017, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to cs 0
+					 * on Channel A.
+					 */
+	int8_t cdd_cha_ww_1_0;		/*
+					 * Byte offset 0x30, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 0 on Channel A.
+					 */
+	int8_t cdd_cha_ww_0_1;		/*
+					 * Byte offset 0x31, CSR Addr 0x54018, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 1 on Channel A.
+					 */
+	uint8_t mr1_a0;			/*
+					 * Byte offset 0x32, CSR Addr 0x54019, Direction=In
+					 * Value to be programmed in DRAM Mode Register 1
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr2_a0;			/*
+					 * Byte offset 0x33, CSR Addr 0x54019, Direction=In
+					 * Value to be programmed in DRAM Mode Register 2
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr3_a0;			/*
+					 * Byte offset 0x34, CSR Addr 0x5401a, Direction=In
+					 * Value to be programmed in DRAM Mode Register 3
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr4_a0;			/*
+					 * Byte offset 0x35, CSR Addr 0x5401a, Direction=In
+					 * Value to be programmed in DRAM Mode Register 4
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr11_a0;		/*
+					 * Byte offset 0x36, CSR Addr 0x5401b, Direction=In
+					 * Value to be programmed in DRAM Mode Register 11
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr12_a0;		/*
+					 * Byte offset 0x37, CSR Addr 0x5401b, Direction=In
+					 * Value to be programmed in DRAM Mode Register 12
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr13_a0;		/*
+					 * Byte offset 0x38, CSR Addr 0x5401c, Direction=In
+					 * Value to be programmed in DRAM Mode Register 13
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr14_a0;		/*
+					 * Byte offset 0x39, CSR Addr 0x5401c, Direction=In
+					 * Value to be programmed in DRAM Mode Register 14
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr16_a0;		/*
+					 * Byte offset 0x3a, CSR Addr 0x5401d, Direction=In
+					 * Value to be programmed in DRAM Mode Register 16
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr17_a0;		/*
+					 * Byte offset 0x3b, CSR Addr 0x5401d, Direction=In
+					 * Value to be programmed in DRAM Mode Register 17
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr22_a0;		/*
+					 * Byte offset 0x3c, CSR Addr 0x5401e, Direction=In
+					 * Value to be programmed in DRAM Mode Register 22
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr24_a0;		/*
+					 * Byte offset 0x3d, CSR Addr 0x5401e, Direction=In
+					 * Value to be programmed in DRAM Mode Register 24
+					 * {Channel A, Rank 0}
+					 */
+	uint8_t mr1_a1;			/*
+					 * Byte offset 0x3e, CSR Addr 0x5401f, Direction=In
+					 * Value to be programmed in DRAM Mode Register 1
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr2_a1;			/*
+					 * Byte offset 0x3f, CSR Addr 0x5401f, Direction=In
+					 * Value to be programmed in DRAM Mode Register 2
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr3_a1;			/*
+					 * Byte offset 0x40, CSR Addr 0x54020, Direction=In
+					 * Value to be programmed in DRAM Mode Register 3
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr4_a1;			/*
+					 * Byte offset 0x41, CSR Addr 0x54020, Direction=In
+					 * Value to be programmed in DRAM Mode Register 4
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr11_a1;		/*
+					 * Byte offset 0x42, CSR Addr 0x54021, Direction=In
+					 * Value to be programmed in DRAM Mode Register 11
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr12_a1;		/*
+					 * Byte offset 0x43, CSR Addr 0x54021, Direction=In
+					 * Value to be programmed in DRAM Mode Register 12
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr13_a1;		/*
+					 * Byte offset 0x44, CSR Addr 0x54022, Direction=In
+					 * Value to be programmed in DRAM Mode Register 13
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr14_a1;		/*
+					 * Byte offset 0x45, CSR Addr 0x54022, Direction=In
+					 * Value to be programmed in DRAM Mode Register 14
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr16_a1;		/*
+					 * Byte offset 0x46, CSR Addr 0x54023, Direction=In
+					 * Value to be programmed in DRAM Mode Register 16
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr17_a1;		/*
+					 * Byte offset 0x47, CSR Addr 0x54023, Direction=In
+					 * Value to be programmed in DRAM Mode Register 17
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr22_a1;		/*
+					 * Byte offset 0x48, CSR Addr 0x54024, Direction=In
+					 * Value to be programmed in DRAM Mode Register 22
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t mr24_a1;		/*
+					 * Byte offset 0x49, CSR Addr 0x54024, Direction=In
+					 * Value to be programmed in DRAM Mode Register 24
+					 * {Channel A, Rank 1}
+					 */
+	uint8_t caterminatingrankcha;	/* Byte offset 0x4a, CSR Addr 0x54025, Direction=In
+					 * Terminating Rank for CA bus on Channel A
+					 *   0x0 = Rank 0 is terminating rank
+					 *   0x1 = Rank 1 is terminating rank
+					 */
+	uint8_t reserved4b;		/* Byte offset 0x4b, CSR Addr 0x54025, Direction=N/A */
+	uint8_t reserved4c;		/* Byte offset 0x4c, CSR Addr 0x54026, Direction=N/A */
+	uint8_t reserved4d;		/* Byte offset 0x4d, CSR Addr 0x54026, Direction=N/A */
+	uint8_t reserved4e;		/* Byte offset 0x4e, CSR Addr 0x54027, Direction=N/A */
+	uint8_t reserved4f;		/* Byte offset 0x4f, CSR Addr 0x54027, Direction=N/A */
+	uint8_t reserved50;		/* Byte offset 0x50, CSR Addr 0x54028, Direction=N/A */
+	uint8_t reserved51;		/* Byte offset 0x51, CSR Addr 0x54028, Direction=N/A */
+	uint8_t reserved52;		/* Byte offset 0x52, CSR Addr 0x54029, Direction=N/A */
+	uint8_t reserved53;		/* Byte offset 0x53, CSR Addr 0x54029, Direction=N/A */
+	uint8_t reserved54;		/* Byte offset 0x54, CSR Addr 0x5402a, Direction=N/A */
+	uint8_t reserved55;		/* Byte offset 0x55, CSR Addr 0x5402a, Direction=N/A */
+	uint8_t reserved56;		/* Byte offset 0x56, CSR Addr 0x5402b, Direction=N/A */
+	uint8_t enableddqschb;		/*
+					 * Byte offset 0x57, CSR Addr 0x5402b, Direction=In
+					 * Total number of DQ bits enabled in PHY Channel B
+					 */
+	uint8_t cspresentchb;		/*
+					 * Byte offset 0x58, CSR Addr 0x5402c, Direction=In
+					 * Indicates presence of DRAM at each chip select for PHY
+					 * channel B.
+					 *   0x0 = No chip selects are populated with DRAM
+					 *   0x1 = CS0 is populated with DRAM
+					 *   0x3 = CS0 and CS1 are populated with DRAM
+					 *
+					 * All other encodings are illegal
+					 */
+	int8_t cdd_chb_rr_1_0;		/*
+					 * Byte offset 0x59, CSR Addr 0x5402c, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 1 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rr_0_1;		/*
+					 * Byte offset 0x5a, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Read to read critical delay difference from cs 0 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rw_1_1;		/*
+					 * Byte offset 0x5b, CSR Addr 0x5402d, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rw_1_0;		/*
+					 * Byte offset 0x5c, CSR Addr 0x5402e, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 1 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rw_0_1;		/*
+					 * Byte offset 0x5d, CSR Addr 0x5402e, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs 0 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_rw_0_0;		/*
+					 * Byte offset 0x5e, CSR Addr 0x5402f, Direction=Out
+					 * This is a signed integer value.
+					 * Read to write critical delay difference from cs01 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_wr_1_1;		/*
+					 * Byte offset 0x5f, CSR Addr 0x5402f, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_wr_1_0;		/*
+					 * Byte offset 0x60, CSR Addr 0x54030, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 1 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_wr_0_1;		/*
+					 * Byte offset 0x61, CSR Addr 0x54030, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to cs 1
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_wr_0_0;		/*
+					 * Byte offset 0x62, CSR Addr 0x54031, Direction=Out
+					 * This is a signed integer value.
+					 * Write to read critical delay difference from cs 0 to cs 0
+					 * on Channel B.
+					 */
+	int8_t cdd_chb_ww_1_0;		/*
+					 * Byte offset 0x63, CSR Addr 0x54031, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 1 to cs
+					 * 0 on Channel B.
+					 */
+	int8_t cdd_chb_ww_0_1;		/*
+					 * Byte offset 0x64, CSR Addr 0x54032, Direction=Out
+					 * This is a signed integer value.
+					 * Write to write critical delay difference from cs 0 to cs
+					 * 1 on Channel B.
+					 */
+	uint8_t mr1_b0;			/*
+					 * Byte offset 0x65, CSR Addr 0x54032, Direction=In
+					 * Value to be programmed in DRAM Mode Register 1
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr2_b0;			/*
+					 * Byte offset 0x66, CSR Addr 0x54033, Direction=In
+					 * Value to be programmed in DRAM Mode Register 2
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr3_b0;			/*
+					 * Byte offset 0x67, CSR Addr 0x54033, Direction=In
+					 * Value to be programmed in DRAM Mode Register 3
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr4_b0;			/*
+					 * Byte offset 0x68, CSR Addr 0x54034, Direction=In
+					 * Value to be programmed in DRAM Mode Register 4
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr11_b0;		/*
+					 * Byte offset 0x69, CSR Addr 0x54034, Direction=In
+					 * Value to be programmed in DRAM Mode Register 11
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr12_b0;		/*
+					 * Byte offset 0x6a, CSR Addr 0x54035, Direction=In
+					 * Value to be programmed in DRAM Mode Register 12
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr13_b0;		/*
+					 * Byte offset 0x6b, CSR Addr 0x54035, Direction=In
+					 * Value to be programmed in DRAM Mode Register 13
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr14_b0;		/*
+					 * Byte offset 0x6c, CSR Addr 0x54036, Direction=In
+					 * Value to be programmed in DRAM Mode Register 14
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr16_b0;		/*
+					 * Byte offset 0x6d, CSR Addr 0x54036, Direction=In
+					 * Value to be programmed in DRAM Mode Register 16
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr17_b0;		/*
+					 * Byte offset 0x6e, CSR Addr 0x54037, Direction=In
+					 * Value to be programmed in DRAM Mode Register 17
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr22_b0;		/*
+					 * Byte offset 0x6f, CSR Addr 0x54037, Direction=In
+					 * Value to be programmed in DRAM Mode Register 22
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr24_b0;		/*
+					 * Byte offset 0x70, CSR Addr 0x54038, Direction=In
+					 * Value to be programmed in DRAM Mode Register 24
+					 * {Channel B, Rank 0}
+					 */
+	uint8_t mr1_b1;			/*
+					 * Byte offset 0x71, CSR Addr 0x54038, Direction=In
+					 * Value to be programmed in DRAM Mode Register 1
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr2_b1;			/*
+					 * Byte offset 0x72, CSR Addr 0x54039, Direction=In
+					 * Value to be programmed in DRAM Mode Register 2
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr3_b1;			/*
+					 * Byte offset 0x73, CSR Addr 0x54039, Direction=In
+					 * Value to be programmed in DRAM Mode Register 3
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr4_b1;			/*
+					 * Byte offset 0x74, CSR Addr 0x5403a, Direction=In
+					 * Value to be programmed in DRAM Mode Register 4
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr11_b1;		/*
+					 * Byte offset 0x75, CSR Addr 0x5403a, Direction=In
+					 * Value to be programmed in DRAM Mode Register 11
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr12_b1;		/*
+					 * Byte offset 0x76, CSR Addr 0x5403b, Direction=In
+					 * Value to be programmed in DRAM Mode Register 12
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr13_b1;		/*
+					 * Byte offset 0x77, CSR Addr 0x5403b, Direction=In
+					 * Value to be programmed in DRAM Mode Register 13
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr14_b1;		/*
+					 * Byte offset 0x78, CSR Addr 0x5403c, Direction=In
+					 * Value to be programmed in DRAM Mode Register 14
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr16_b1;		/*
+					 * Byte offset 0x79, CSR Addr 0x5403c, Direction=In
+					 * Value to be programmed in DRAM Mode Register 16
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr17_b1;		/*
+					 * Byte offset 0x7a, CSR Addr 0x5403d, Direction=In
+					 * Value to be programmed in DRAM Mode Register 17
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr22_b1;		/*
+					 * Byte offset 0x7b, CSR Addr 0x5403d, Direction=In
+					 * Value to be programmed in DRAM Mode Register 22
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t mr24_b1;		/*
+					 * Byte offset 0x7c, CSR Addr 0x5403e, Direction=In
+					 * Value to be programmed in DRAM Mode Register 24
+					 * {Channel B, Rank 1}
+					 */
+	uint8_t caterminatingrankchb;	/* Byte offset 0x7d, CSR Addr 0x5403e, Direction=In
+					 * Terminating Rank for CA bus on Channel B
+					 *   0x0 = Rank 0 is terminating rank
+					 *   0x1 = Rank 1 is terminating rank
+					 */
+	uint8_t reserved7e;		/* Byte offset 0x7e, CSR Addr 0x5403f, Direction=N/A */
+	uint8_t reserved7f;		/* Byte offset 0x7f, CSR Addr 0x5403f, Direction=N/A */
+	uint8_t reserved80;		/* Byte offset 0x80, CSR Addr 0x54040, Direction=N/A */
+	uint8_t reserved81;		/* Byte offset 0x81, CSR Addr 0x54040, Direction=N/A */
+	uint8_t reserved82;		/* Byte offset 0x82, CSR Addr 0x54041, Direction=N/A */
+	uint8_t reserved83;		/* Byte offset 0x83, CSR Addr 0x54041, Direction=N/A */
+	uint8_t reserved84;		/* Byte offset 0x84, CSR Addr 0x54042, Direction=N/A */
+	uint8_t reserved85;		/* Byte offset 0x85, CSR Addr 0x54042, Direction=N/A */
+	uint8_t reserved86;		/* Byte offset 0x86, CSR Addr 0x54043, Direction=N/A */
+	uint8_t reserved87;		/* Byte offset 0x87, CSR Addr 0x54043, Direction=N/A */
+	uint8_t reserved88;		/* Byte offset 0x88, CSR Addr 0x54044, Direction=N/A */
+	uint8_t reserved89;		/* Byte offset 0x89, CSR Addr 0x54044, Direction=N/A */
+} __packed __aligned(2);
+
+#endif /* MNPMUSRAMMSGBLOCK_LPDDR4_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_csr_all_cdefines.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_csr_all_cdefines.h
new file mode 100644
index 00000000..99a8c4cc
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_csr_all_cdefines.h
@@ -0,0 +1,6944 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_PHYINIT_CSR_ALL_DEFINES_H
+#define DDRPHY_PHYINIT_CSR_ALL_DEFINES_H
+
+/* ANIBx register offsets */
+#define CSR_MTESTMUXSEL_ADDR				0x1AU
+#define CSR_AFORCEDRVCONT_ADDR				0x27U
+#define CSR_AFORCETRICONT_ADDR				0x28U
+#define CSR_ATXIMPEDANCE_ADDR				0x43U
+#define CSR_ATESTPRBSERR_ADDR				0x53U
+#define CSR_ATXSLEWRATE_ADDR				0x55U
+#define CSR_ATESTPRBSERRCNT_ADDR			0x56U
+#define CSR_ATXDLY_ADDR					0x80U
+
+/* DBYTEx register offsets */
+#define CSR_DBYTEMISCMODE_ADDR				0x0U
+#define CSR_TSMBYTE0_ADDR				0x1U
+#define CSR_TRAININGPARAM_ADDR				0x2U
+#define CSR_USEDQSENREPLICA_ADDR			0x3U
+#define CSR_RXTRAINPATTERNENABLE_ADDR			0x10U
+#define CSR_TSMBYTE1_ADDR				0x11U
+#define CSR_TSMBYTE2_ADDR				0x12U
+#define CSR_TSMBYTE3_ADDR				0x13U
+#define CSR_TSMBYTE4_ADDR				0x14U
+#define CSR_TESTMODECONFIG_ADDR				0x17U
+#define CSR_TSMBYTE5_ADDR				0x18U
+/* MTESTMUXSEL already defined in ANIBx section */
+#define CSR_DTSMTRAINMODECTRL_ADDR			0x1FU
+#define CSR_DFIMRL_ADDR					0x20U
+#define CSR_ASYNCDBYTEMODE_ADDR				0x24U
+#define CSR_ASYNCDBYTETXEN_ADDR				0x26U
+#define CSR_ASYNCDBYTETXDATA_ADDR			0x28U
+#define CSR_ASYNCDBYTERXDATA_ADDR			0x2AU
+#define CSR_VREFDAC1_ADDR				0x30U
+#define CSR_TRAININGCNTR_ADDR				0x32U
+#define CSR_VREFDAC0_ADDR				0x40U
+#define CSR_TXIMPEDANCECTRL0_ADDR			0x41U
+#define CSR_DQDQSRCVCNTRL_ADDR				0x43U
+#define CSR_TXEQUALIZATIONMODE_ADDR			0x48U
+#define CSR_TXIMPEDANCECTRL1_ADDR			0x49U
+#define CSR_DQDQSRCVCNTRL1_ADDR				0x4AU
+#define CSR_TXIMPEDANCECTRL2_ADDR			0x4BU
+#define CSR_DQDQSRCVCNTRL2_ADDR				0x4CU
+#define CSR_TXODTDRVSTREN_ADDR				0x4DU
+#define CSR_RXFIFOCHECKSTATUS_ADDR			0x56U
+#define CSR_RXFIFOCHECKERRVALUES_ADDR			0x57U
+#define CSR_RXFIFOINFO_ADDR				0x58U
+#define CSR_RXFIFOVISIBILITY_ADDR			0x59U
+#define CSR_RXFIFOCONTENTSDQ3210_ADDR			0x5AU
+#define CSR_RXFIFOCONTENTSDQ7654_ADDR			0x5BU
+#define CSR_RXFIFOCONTENTSDBI_ADDR			0x5CU
+#define CSR_TXSLEWRATE_ADDR				0x5FU
+#define CSR_TRAININGINCDECDTSMEN_ADDR			0x62U
+#define CSR_RXPBDLYTG0_ADDR				0x68U
+#define CSR_RXPBDLYTG1_ADDR				0x69U
+#define CSR_RXPBDLYTG2_ADDR				0x6AU
+#define CSR_RXPBDLYTG3_ADDR				0x6BU
+#define CSR_RXENDLYTG0_ADDR				0x80U
+#define CSR_RXENDLYTG1_ADDR				0x81U
+#define CSR_RXENDLYTG2_ADDR				0x82U
+#define CSR_RXENDLYTG3_ADDR				0x83U
+#define CSR_RXCLKDLYTG0_ADDR				0x8CU
+#define CSR_RXCLKDLYTG1_ADDR				0x8DU
+#define CSR_RXCLKDLYTG2_ADDR				0x8EU
+#define CSR_RXCLKDLYTG3_ADDR				0x8FU
+#define CSR_RXCLKCDLYTG0_ADDR				0x90U
+#define CSR_RXCLKCDLYTG1_ADDR				0x91U
+#define CSR_RXCLKCDLYTG2_ADDR				0x92U
+#define CSR_RXCLKCDLYTG3_ADDR				0x93U
+#define CSR_DQ0LNSEL_ADDR				0xA0U
+#define CSR_DQ1LNSEL_ADDR				0xA1U
+#define CSR_DQ2LNSEL_ADDR				0xA2U
+#define CSR_DQ3LNSEL_ADDR				0xA3U
+#define CSR_DQ4LNSEL_ADDR				0xA4U
+#define CSR_DQ5LNSEL_ADDR				0xA5U
+#define CSR_DQ6LNSEL_ADDR				0xA6U
+#define CSR_DQ7LNSEL_ADDR				0xA7U
+#define CSR_PPTCTLSTATIC_ADDR				0xAAU
+#define CSR_PPTCTLDYN_ADDR				0xABU
+#define CSR_PPTINFO_ADDR				0xACU
+#define CSR_PPTRXENEVNT_ADDR				0xADU
+#define CSR_PPTDQSCNTINVTRNTG0_ADDR			0xAEU
+#define CSR_PPTDQSCNTINVTRNTG1_ADDR			0xAFU
+#define CSR_DTSMBLANKINGCTRL_ADDR			0xB1U
+#define CSR_TSM0_ADDR					0xB2U
+#define CSR_TSM1_ADDR					0xB3U
+#define CSR_TSM2_ADDR					0xB4U
+#define CSR_TSM3_ADDR					0xB5U
+#define CSR_TXCHKDATASELECTS_ADDR			0xB6U
+#define CSR_DTSMUPTHLDXINGIND_ADDR			0xB7U
+#define CSR_DTSMLOTHLDXINGIND_ADDR			0xB8U
+#define CSR_DBYTEALLDTSMCTRL0_ADDR			0xB9U
+#define CSR_DBYTEALLDTSMCTRL1_ADDR			0xBAU
+#define CSR_DBYTEALLDTSMCTRL2_ADDR			0xBBU
+#define CSR_TXDQDLYTG0_ADDR				0xC0U
+#define CSR_TXDQDLYTG1_ADDR				0xC1U
+#define CSR_TXDQDLYTG2_ADDR				0xC2U
+#define CSR_TXDQDLYTG3_ADDR				0xC3U
+#define CSR_TXDQSDLYTG0_ADDR				0xD0U
+#define CSR_TXDQSDLYTG1_ADDR				0xD1U
+#define CSR_TXDQSDLYTG2_ADDR				0xD2U
+#define CSR_TXDQSDLYTG3_ADDR				0xD3U
+#define CSR_DXLCDLSTATUS_ADDR				0xE4U
+
+/* MASTER0 register offsets */
+#define CSR_RXFIFOINIT_ADDR				0x0U
+#define CSR_FORCECLKDISABLE_ADDR			0x1U
+#define CSR_CLOCKINGCTRL_ADDR				0x2U
+#define CSR_FORCEINTERNALUPDATE_ADDR			0x3U
+#define CSR_PHYCONFIG_ADDR				0x4U
+#define CSR_PGCR_ADDR					0x5U
+#define CSR_TESTBUMPCNTRL1_ADDR				0x7U
+#define CSR_CALUCLKINFO_ADDR				0x8U
+#define CSR_TESTBUMPCNTRL_ADDR				0xAU
+#define CSR_SEQ0BDLY0_ADDR				0xBU
+#define CSR_SEQ0BDLY1_ADDR				0xCU
+#define CSR_SEQ0BDLY2_ADDR				0xDU
+#define CSR_SEQ0BDLY3_ADDR				0xEU
+#define CSR_PHYALERTSTATUS_ADDR				0xFU
+#define CSR_PPTTRAINSETUP_ADDR				0x10U
+#define CSR_PPTTRAINSETUP2_ADDR				0x11U
+#define CSR_ATESTMODE_ADDR				0x12U
+#define CSR_TXCALBINP_ADDR				0x14U
+#define CSR_TXCALBINN_ADDR				0x15U
+#define CSR_TXCALPOVR_ADDR				0x16U
+#define CSR_TXCALNOVR_ADDR				0x17U
+#define CSR_DFIMODE_ADDR				0x18U
+#define CSR_TRISTATEMODECA_ADDR				0x19U
+/* MTESTMUXSEL already defined in ANIBx section */
+#define CSR_MTESTPGMINFO_ADDR				0x1BU
+#define CSR_DYNPWRDNUP_ADDR				0x1CU
+#define CSR_PMIENABLE_ADDR				0x1DU
+#define CSR_PHYTID_ADDR					0x1EU
+#define CSR_HWTMRL_ADDR					0x20U
+#define CSR_DFIPHYUPD_ADDR				0x21U
+#define CSR_PDAMRSWRITEMODE_ADDR			0x22U
+#define CSR_DFIGEARDOWNCTL_ADDR				0x23U
+#define CSR_DQSPREAMBLECONTROL_ADDR			0x24U
+#define CSR_MASTERX4CONFIG_ADDR				0x25U
+#define CSR_WRLEVBITS_ADDR				0x26U
+#define CSR_ENABLECSMULTICAST_ADDR			0x27U
+#define CSR_HWTLPCSMULTICAST_ADDR			0x28U
+#define CSR_ACX4ANIBDIS_ADDR				0x2CU
+#define CSR_DMIPINPRESENT_ADDR				0x2DU
+#define CSR_ARDPTRINITVAL_ADDR				0x2EU
+#define CSR_DB0LCDLCALPHDETOUT_ADDR			0x30U
+#define CSR_DB1LCDLCALPHDETOUT_ADDR			0x31U
+#define CSR_DB2LCDLCALPHDETOUT_ADDR			0x32U
+#define CSR_DB3LCDLCALPHDETOUT_ADDR			0x33U
+#define CSR_DB4LCDLCALPHDETOUT_ADDR			0x34U
+#define CSR_DB5LCDLCALPHDETOUT_ADDR			0x35U
+#define CSR_DB6LCDLCALPHDETOUT_ADDR			0x36U
+#define CSR_DB7LCDLCALPHDETOUT_ADDR			0x37U
+#define CSR_DB8LCDLCALPHDETOUT_ADDR			0x38U
+#define CSR_DB9LCDLCALPHDETOUT_ADDR			0x39U
+#define CSR_DBYTEDLLMODECNTRL_ADDR			0x3AU
+#define CSR_DBYTERXENTRAIN_ADDR				0x3BU
+#define CSR_ANLCDLCALPHDETOUT_ADDR			0x3FU
+#define CSR_CALOFFSETS_ADDR				0x45U
+#define CSR_SARINITVALS_ADDR				0x47U
+#define CSR_CALPEXTOVR_ADDR				0x49U
+#define CSR_CALCMPR5OVR_ADDR				0x4AU
+#define CSR_CALNINTOVR_ADDR				0x4BU
+#define CSR_CALDRVSTR0_ADDR				0x50U
+#define CSR_PROCODTCTL_ADDR				0x55U
+#define CSR_PROCODTTIMECTL_ADDR				0x56U
+#define CSR_MEMALERTCONTROL_ADDR			0x5BU
+#define CSR_MEMALERTCONTROL2_ADDR			0x5CU
+#define CSR_MEMRESETL_ADDR				0x60U
+#define CSR_PUBMODE_ADDR				0x6EU
+#define CSR_MISCPHYSTATUS_ADDR				0x6FU
+#define CSR_CORELOOPBACKSEL_ADDR			0x70U
+#define CSR_DLLTRAINPARAM_ADDR				0x71U
+#define CSR_HWTLPCSENA_ADDR				0x72U
+#define CSR_HWTLPCSENB_ADDR				0x73U
+#define CSR_HWTLPCSENBYPASS_ADDR			0x74U
+#define CSR_DFICAMODE_ADDR				0x75U
+#define CSR_HWTCACTL_ADDR				0x76U
+#define CSR_HWTCAMODE_ADDR				0x77U
+#define CSR_DLLCONTROL_ADDR				0x78U
+#define CSR_PULSEDLLUPDATEPHASE_ADDR			0x79U
+#define CSR_HWTCONTROLOVR0_ADDR				0x7AU
+#define CSR_HWTCONTROLOVR1_ADDR				0x7BU
+#define CSR_DLLGAINCTL_ADDR				0x7CU
+#define CSR_DLLLOCKPARAM_ADDR				0x7DU
+#define CSR_HWTCONTROLVAL0_ADDR				0x7EU
+#define CSR_HWTCONTROLVAL1_ADDR				0x7FU
+#define CSR_ACSMGLBLSTART_ADDR				0x81U
+#define CSR_ACSMGLBLSGLSTPCTRL_ADDR			0x82U
+#define CSR_LCDLCALPHASE_ADDR				0x84U
+#define CSR_LCDLCALCTRL_ADDR				0x85U
+#define CSR_CALRATE_ADDR				0x88U
+#define CSR_CALZAP_ADDR					0x89U
+#define CSR_PSTATE_ADDR					0x8BU
+#define CSR_CALPREDRIVEROVERRIDE_ADDR			0x8CU
+#define CSR_PLLOUTGATECONTROL_ADDR			0x8DU
+#define CSR_UCMEMRESETCONTROL_ADDR			0x8FU
+#define CSR_PORCONTROL_ADDR				0x90U
+#define CSR_CALBUSY_ADDR				0x97U
+#define CSR_CALMISC2_ADDR				0x98U
+#define CSR_CALMISC_ADDR				0x9AU
+#define CSR_CALVREFS_ADDR				0x9BU
+#define CSR_CALCMPR5_ADDR				0x9CU
+#define CSR_CALNINT_ADDR				0x9DU
+#define CSR_CALPEXT_ADDR				0x9EU
+#define CSR_CALCMPINVERT_ADDR				0xA8U
+#define CSR_CALCMPANACNTRL_ADDR				0xAEU
+#define CSR_DFIRDDATACSDESTMAP_ADDR			0xB0U
+#define CSR_VREFINGLOBAL_ADDR				0xB2U
+#define CSR_DFIWRDATACSDESTMAP_ADDR			0xB4U
+#define CSR_MASUPDGOODCTR_ADDR				0xB5U
+#define CSR_PHYUPD0GOODCTR_ADDR				0xB6U
+#define CSR_PHYUPD1GOODCTR_ADDR				0xB7U
+#define CSR_CTLUPD0GOODCTR_ADDR				0xB8U
+#define CSR_CTLUPD1GOODCTR_ADDR				0xB9U
+#define CSR_MASUPDFAILCTR_ADDR				0xBAU
+#define CSR_PHYUPD0FAILCTR_ADDR				0xBBU
+#define CSR_PHYUPD1FAILCTR_ADDR				0xBCU
+#define CSR_PHYPERFCTRENABLE_ADDR			0xBDU
+#define CSR_DFIWRRDDATACSCONFIG_ADDR			0xBEU
+#define CSR_PLLPWRDN_ADDR				0xC3U
+#define CSR_PLLRESET_ADDR				0xC4U
+#define CSR_PLLCTRL2_ADDR				0xC5U
+#define CSR_PLLCTRL0_ADDR				0xC6U
+#define CSR_PLLCTRL1_ADDR				0xC7U
+#define CSR_PLLTST_ADDR					0xC8U
+#define CSR_PLLLOCKSTATUS_ADDR				0xC9U
+#define CSR_PLLTESTMODE_ADDR				0xCAU
+#define CSR_PLLCTRL3_ADDR				0xCBU
+#define CSR_PLLCTRL4_ADDR				0xCCU
+#define CSR_PLLENDOFCAL_ADDR				0xCDU
+#define CSR_PLLSTANDBYEFF_ADDR				0xCEU
+#define CSR_PLLDACVALOUT_ADDR				0xCFU
+#define CSR_DLYTESTSEQ_ADDR				0xD0U
+#define CSR_DLYTESTRINGSELDB_ADDR			0xD1U
+#define CSR_DLYTESTRINGSELAC_ADDR			0xD2U
+#define CSR_DLYTESTCNTDFICLKIV_ADDR			0xD3U
+#define CSR_DLYTESTCNTDFICLK_ADDR			0xD4U
+#define CSR_DLYTESTCNTRINGOSCDB0_ADDR			0xD5U
+#define CSR_DLYTESTCNTRINGOSCDB1_ADDR			0xD6U
+#define CSR_DLYTESTCNTRINGOSCDB2_ADDR			0xD7U
+#define CSR_DLYTESTCNTRINGOSCDB3_ADDR			0xD8U
+#define CSR_DLYTESTCNTRINGOSCDB4_ADDR			0xD9U
+#define CSR_DLYTESTCNTRINGOSCDB5_ADDR			0xDAU
+#define CSR_DLYTESTCNTRINGOSCDB6_ADDR			0xDBU
+#define CSR_DLYTESTCNTRINGOSCDB7_ADDR			0xDCU
+#define CSR_DLYTESTCNTRINGOSCDB8_ADDR			0xDDU
+#define CSR_DLYTESTCNTRINGOSCDB9_ADDR			0xDEU
+#define CSR_DLYTESTCNTRINGOSCAC_ADDR			0xDFU
+#define CSR_MSTLCDLDBGCNTL_ADDR				0xE0U
+#define CSR_MSTLCDL0DBGRES_ADDR				0xE1U
+#define CSR_MSTLCDL1DBGRES_ADDR				0xE2U
+#define CSR_LCDLDBGCNTL_ADDR				0xE3U
+#define CSR_ACLCDLSTATUS_ADDR				0xE4U
+#define CSR_CUSTPHYREV_ADDR				0xEDU
+#define CSR_PHYREV_ADDR					0xEEU
+#define CSR_LP3EXITSEQ0BSTARTVECTOR_ADDR		0xEFU
+#define CSR_DFIFREQXLAT0_ADDR				0xF0U
+#define CSR_DFIFREQXLAT1_ADDR				0xF1U
+#define CSR_DFIFREQXLAT2_ADDR				0xF2U
+#define CSR_DFIFREQXLAT3_ADDR				0xF3U
+#define CSR_DFIFREQXLAT4_ADDR				0xF4U
+#define CSR_DFIFREQXLAT5_ADDR				0xF5U
+#define CSR_DFIFREQXLAT6_ADDR				0xF6U
+#define CSR_DFIFREQXLAT7_ADDR				0xF7U
+#define CSR_TXRDPTRINIT_ADDR				0xF8U
+#define CSR_DFIINITCOMPLETE_ADDR			0xF9U
+#define CSR_DFIFREQRATIO_ADDR				0xFAU
+#define CSR_RXFIFOCHECKS_ADDR				0xFBU
+#define CSR_MTESTDTOCTRL_ADDR				0xFFU
+#define CSR_MAPCAA0TODFI_ADDR				0x100U
+#define CSR_MAPCAA1TODFI_ADDR				0x101U
+#define CSR_MAPCAA2TODFI_ADDR				0x102U
+#define CSR_MAPCAA3TODFI_ADDR				0x103U
+#define CSR_MAPCAA4TODFI_ADDR				0x104U
+#define CSR_MAPCAA5TODFI_ADDR				0x105U
+#define CSR_MAPCAA6TODFI_ADDR				0x106U
+#define CSR_MAPCAA7TODFI_ADDR				0x107U
+#define CSR_MAPCAA8TODFI_ADDR				0x108U
+#define CSR_MAPCAA9TODFI_ADDR				0x109U
+#define CSR_MAPCAB0TODFI_ADDR				0x110U
+#define CSR_MAPCAB1TODFI_ADDR				0x111U
+#define CSR_MAPCAB2TODFI_ADDR				0x112U
+#define CSR_MAPCAB3TODFI_ADDR				0x113U
+#define CSR_MAPCAB4TODFI_ADDR				0x114U
+#define CSR_MAPCAB5TODFI_ADDR				0x115U
+#define CSR_MAPCAB6TODFI_ADDR				0x116U
+#define CSR_MAPCAB7TODFI_ADDR				0x117U
+#define CSR_MAPCAB8TODFI_ADDR				0x118U
+#define CSR_MAPCAB9TODFI_ADDR				0x119U
+#define CSR_PHYINTERRUPTENABLE_ADDR			0x11BU
+#define CSR_PHYINTERRUPTFWCONTROL_ADDR			0x11CU
+#define CSR_PHYINTERRUPTMASK_ADDR			0x11DU
+#define CSR_PHYINTERRUPTCLEAR_ADDR			0x11EU
+#define CSR_PHYINTERRUPTSTATUS_ADDR			0x11FU
+#define CSR_HWTSWIZZLEHWTADDRESS0_ADDR			0x120U
+#define CSR_HWTSWIZZLEHWTADDRESS1_ADDR			0x121U
+#define CSR_HWTSWIZZLEHWTADDRESS2_ADDR			0x122U
+#define CSR_HWTSWIZZLEHWTADDRESS3_ADDR			0x123U
+#define CSR_HWTSWIZZLEHWTADDRESS4_ADDR			0x124U
+#define CSR_HWTSWIZZLEHWTADDRESS5_ADDR			0x125U
+#define CSR_HWTSWIZZLEHWTADDRESS6_ADDR			0x126U
+#define CSR_HWTSWIZZLEHWTADDRESS7_ADDR			0x127U
+#define CSR_HWTSWIZZLEHWTADDRESS8_ADDR			0x128U
+#define CSR_HWTSWIZZLEHWTADDRESS9_ADDR			0x129U
+#define CSR_HWTSWIZZLEHWTADDRESS10_ADDR			0x12AU
+#define CSR_HWTSWIZZLEHWTADDRESS11_ADDR			0x12BU
+#define CSR_HWTSWIZZLEHWTADDRESS12_ADDR			0x12CU
+#define CSR_HWTSWIZZLEHWTADDRESS13_ADDR			0x12DU
+#define CSR_HWTSWIZZLEHWTADDRESS14_ADDR			0x12EU
+#define CSR_HWTSWIZZLEHWTADDRESS15_ADDR			0x12FU
+#define CSR_HWTSWIZZLEHWTADDRESS17_ADDR			0x130U
+#define CSR_HWTSWIZZLEHWTACTN_ADDR			0x131U
+#define CSR_HWTSWIZZLEHWTBANK0_ADDR			0x132U
+#define CSR_HWTSWIZZLEHWTBANK1_ADDR			0x133U
+#define CSR_HWTSWIZZLEHWTBANK2_ADDR			0x134U
+#define CSR_HWTSWIZZLEHWTBG0_ADDR			0x135U
+#define CSR_HWTSWIZZLEHWTBG1_ADDR			0x136U
+#define CSR_HWTSWIZZLEHWTCASN_ADDR			0x137U
+#define CSR_HWTSWIZZLEHWTRASN_ADDR			0x138U
+#define CSR_HWTSWIZZLEHWTWEN_ADDR			0x139U
+#define CSR_HWTSWIZZLEHWTPARITYIN_ADDR			0x13AU
+#define CSR_DFIHANDSHAKEDELAYS0_ADDR			0x13CU
+#define CSR_DFIHANDSHAKEDELAYS1_ADDR			0x13DU
+#define CSR_REMOTEIMPCAL_ADDR				0x13EU
+#define CSR_ACLOOPBACKCTL_ADDR				0x13FU
+
+/* ACSM0 register offsets */
+#define CSR_ACSMSEQ0X0_ADDR				0x0U
+#define CSR_ACSMSEQ0X1_ADDR				0x1U
+#define CSR_ACSMSEQ0X2_ADDR				0x2U
+#define CSR_ACSMSEQ0X3_ADDR				0x3U
+#define CSR_ACSMSEQ0X4_ADDR				0x4U
+#define CSR_ACSMSEQ0X5_ADDR				0x5U
+#define CSR_ACSMSEQ0X6_ADDR				0x6U
+#define CSR_ACSMSEQ0X7_ADDR				0x7U
+#define CSR_ACSMSEQ0X8_ADDR				0x8U
+#define CSR_ACSMSEQ0X9_ADDR				0x9U
+#define CSR_ACSMSEQ0X10_ADDR				0xAU
+#define CSR_ACSMSEQ0X11_ADDR				0xBU
+#define CSR_ACSMSEQ0X12_ADDR				0xCU
+#define CSR_ACSMSEQ0X13_ADDR				0xDU
+#define CSR_ACSMSEQ0X14_ADDR				0xEU
+#define CSR_ACSMSEQ0X15_ADDR				0xFU
+#define CSR_ACSMSEQ0X16_ADDR				0x10U
+#define CSR_ACSMSEQ0X17_ADDR				0x11U
+#define CSR_ACSMSEQ0X18_ADDR				0x12U
+#define CSR_ACSMSEQ0X19_ADDR				0x13U
+#define CSR_ACSMSEQ0X20_ADDR				0x14U
+#define CSR_ACSMSEQ0X21_ADDR				0x15U
+#define CSR_ACSMSEQ0X22_ADDR				0x16U
+#define CSR_ACSMSEQ0X23_ADDR				0x17U
+#define CSR_ACSMSEQ0X24_ADDR				0x18U
+#define CSR_ACSMSEQ0X25_ADDR				0x19U
+#define CSR_ACSMSEQ0X26_ADDR				0x1AU
+#define CSR_ACSMSEQ0X27_ADDR				0x1BU
+#define CSR_ACSMSEQ0X28_ADDR				0x1CU
+#define CSR_ACSMSEQ0X29_ADDR				0x1DU
+#define CSR_ACSMSEQ0X30_ADDR				0x1EU
+#define CSR_ACSMSEQ0X31_ADDR				0x1FU
+#define CSR_ACSMSEQ1X0_ADDR				0x20U
+#define CSR_ACSMSEQ1X1_ADDR				0x21U
+#define CSR_ACSMSEQ1X2_ADDR				0x22U
+#define CSR_ACSMSEQ1X3_ADDR				0x23U
+#define CSR_ACSMSEQ1X4_ADDR				0x24U
+#define CSR_ACSMSEQ1X5_ADDR				0x25U
+#define CSR_ACSMSEQ1X6_ADDR				0x26U
+#define CSR_ACSMSEQ1X7_ADDR				0x27U
+#define CSR_ACSMSEQ1X8_ADDR				0x28U
+#define CSR_ACSMSEQ1X9_ADDR				0x29U
+#define CSR_ACSMSEQ1X10_ADDR				0x2AU
+#define CSR_ACSMSEQ1X11_ADDR				0x2BU
+#define CSR_ACSMSEQ1X12_ADDR				0x2CU
+#define CSR_ACSMSEQ1X13_ADDR				0x2DU
+#define CSR_ACSMSEQ1X14_ADDR				0x2EU
+#define CSR_ACSMSEQ1X15_ADDR				0x2FU
+#define CSR_ACSMSEQ1X16_ADDR				0x30U
+#define CSR_ACSMSEQ1X17_ADDR				0x31U
+#define CSR_ACSMSEQ1X18_ADDR				0x32U
+#define CSR_ACSMSEQ1X19_ADDR				0x33U
+#define CSR_ACSMSEQ1X20_ADDR				0x34U
+#define CSR_ACSMSEQ1X21_ADDR				0x35U
+#define CSR_ACSMSEQ1X22_ADDR				0x36U
+#define CSR_ACSMSEQ1X23_ADDR				0x37U
+#define CSR_ACSMSEQ1X24_ADDR				0x38U
+#define CSR_ACSMSEQ1X25_ADDR				0x39U
+#define CSR_ACSMSEQ1X26_ADDR				0x3AU
+#define CSR_ACSMSEQ1X27_ADDR				0x3BU
+#define CSR_ACSMSEQ1X28_ADDR				0x3CU
+#define CSR_ACSMSEQ1X29_ADDR				0x3DU
+#define CSR_ACSMSEQ1X30_ADDR				0x3EU
+#define CSR_ACSMSEQ1X31_ADDR				0x3FU
+#define CSR_ACSMSEQ2X0_ADDR				0x40U
+#define CSR_ACSMSEQ2X1_ADDR				0x41U
+#define CSR_ACSMSEQ2X2_ADDR				0x42U
+#define CSR_ACSMSEQ2X3_ADDR				0x43U
+#define CSR_ACSMSEQ2X4_ADDR				0x44U
+#define CSR_ACSMSEQ2X5_ADDR				0x45U
+#define CSR_ACSMSEQ2X6_ADDR				0x46U
+#define CSR_ACSMSEQ2X7_ADDR				0x47U
+#define CSR_ACSMSEQ2X8_ADDR				0x48U
+#define CSR_ACSMSEQ2X9_ADDR				0x49U
+#define CSR_ACSMSEQ2X10_ADDR				0x4AU
+#define CSR_ACSMSEQ2X11_ADDR				0x4BU
+#define CSR_ACSMSEQ2X12_ADDR				0x4CU
+#define CSR_ACSMSEQ2X13_ADDR				0x4DU
+#define CSR_ACSMSEQ2X14_ADDR				0x4EU
+#define CSR_ACSMSEQ2X15_ADDR				0x4FU
+#define CSR_ACSMSEQ2X16_ADDR				0x50U
+#define CSR_ACSMSEQ2X17_ADDR				0x51U
+#define CSR_ACSMSEQ2X18_ADDR				0x52U
+#define CSR_ACSMSEQ2X19_ADDR				0x53U
+#define CSR_ACSMSEQ2X20_ADDR				0x54U
+#define CSR_ACSMSEQ2X21_ADDR				0x55U
+#define CSR_ACSMSEQ2X22_ADDR				0x56U
+#define CSR_ACSMSEQ2X23_ADDR				0x57U
+#define CSR_ACSMSEQ2X24_ADDR				0x58U
+#define CSR_ACSMSEQ2X25_ADDR				0x59U
+#define CSR_ACSMSEQ2X26_ADDR				0x5AU
+#define CSR_ACSMSEQ2X27_ADDR				0x5BU
+#define CSR_ACSMSEQ2X28_ADDR				0x5CU
+#define CSR_ACSMSEQ2X29_ADDR				0x5DU
+#define CSR_ACSMSEQ2X30_ADDR				0x5EU
+#define CSR_ACSMSEQ2X31_ADDR				0x5FU
+#define CSR_ACSMSEQ3X0_ADDR				0x60U
+#define CSR_ACSMSEQ3X1_ADDR				0x61U
+#define CSR_ACSMSEQ3X2_ADDR				0x62U
+#define CSR_ACSMSEQ3X3_ADDR				0x63U
+#define CSR_ACSMSEQ3X4_ADDR				0x64U
+#define CSR_ACSMSEQ3X5_ADDR				0x65U
+#define CSR_ACSMSEQ3X6_ADDR				0x66U
+#define CSR_ACSMSEQ3X7_ADDR				0x67U
+#define CSR_ACSMSEQ3X8_ADDR				0x68U
+#define CSR_ACSMSEQ3X9_ADDR				0x69U
+#define CSR_ACSMSEQ3X10_ADDR				0x6AU
+#define CSR_ACSMSEQ3X11_ADDR				0x6BU
+#define CSR_ACSMSEQ3X12_ADDR				0x6CU
+#define CSR_ACSMSEQ3X13_ADDR				0x6DU
+#define CSR_ACSMSEQ3X14_ADDR				0x6EU
+#define CSR_ACSMSEQ3X15_ADDR				0x6FU
+#define CSR_ACSMSEQ3X16_ADDR				0x70U
+#define CSR_ACSMSEQ3X17_ADDR				0x71U
+#define CSR_ACSMSEQ3X18_ADDR				0x72U
+#define CSR_ACSMSEQ3X19_ADDR				0x73U
+#define CSR_ACSMSEQ3X20_ADDR				0x74U
+#define CSR_ACSMSEQ3X21_ADDR				0x75U
+#define CSR_ACSMSEQ3X22_ADDR				0x76U
+#define CSR_ACSMSEQ3X23_ADDR				0x77U
+#define CSR_ACSMSEQ3X24_ADDR				0x78U
+#define CSR_ACSMSEQ3X25_ADDR				0x79U
+#define CSR_ACSMSEQ3X26_ADDR				0x7AU
+#define CSR_ACSMSEQ3X27_ADDR				0x7BU
+#define CSR_ACSMSEQ3X28_ADDR				0x7CU
+#define CSR_ACSMSEQ3X29_ADDR				0x7DU
+#define CSR_ACSMSEQ3X30_ADDR				0x7EU
+#define CSR_ACSMSEQ3X31_ADDR				0x7FU
+#define CSR_ACSMPLAYBACK0X0_ADDR			0x80U
+#define CSR_ACSMPLAYBACK1X0_ADDR			0x81U
+#define CSR_ACSMPLAYBACK0X1_ADDR			0x82U
+#define CSR_ACSMPLAYBACK1X1_ADDR			0x83U
+#define CSR_ACSMPLAYBACK0X2_ADDR			0x84U
+#define CSR_ACSMPLAYBACK1X2_ADDR			0x85U
+#define CSR_ACSMPLAYBACK0X3_ADDR			0x86U
+#define CSR_ACSMPLAYBACK1X3_ADDR			0x87U
+#define CSR_ACSMPLAYBACK0X4_ADDR			0x88U
+#define CSR_ACSMPLAYBACK1X4_ADDR			0x89U
+#define CSR_ACSMPLAYBACK0X5_ADDR			0x8AU
+#define CSR_ACSMPLAYBACK1X5_ADDR			0x8BU
+#define CSR_ACSMPLAYBACK0X6_ADDR			0x8CU
+#define CSR_ACSMPLAYBACK1X6_ADDR			0x8DU
+#define CSR_ACSMPLAYBACK0X7_ADDR			0x8EU
+#define CSR_ACSMPLAYBACK1X7_ADDR			0x8FU
+#define CSR_ACSMPSTATEOVREN_ADDR			0x90U
+#define CSR_ACSMPSTATEOVRVAL_ADDR			0x91U
+#define CSR_ACSMCTRL23_ADDR				0xC0U
+#define CSR_ACSMCKEVAL_ADDR				0xC2U
+#define CSR_LOWSPEEDCLOCKDIVIDER_ADDR			0xC8U
+#define CSR_ACSMCSMAPCTRL0_ADDR				0xD0U
+#define CSR_ACSMCSMAPCTRL1_ADDR				0xD1U
+#define CSR_ACSMCSMAPCTRL2_ADDR				0xD2U
+#define CSR_ACSMCSMAPCTRL3_ADDR				0xD3U
+#define CSR_ACSMCSMAPCTRL4_ADDR				0xD4U
+#define CSR_ACSMCSMAPCTRL5_ADDR				0xD5U
+#define CSR_ACSMCSMAPCTRL6_ADDR				0xD6U
+#define CSR_ACSMCSMAPCTRL7_ADDR				0xD7U
+#define CSR_ACSMCSMAPCTRL8_ADDR				0xD8U
+#define CSR_ACSMCSMAPCTRL9_ADDR				0xD9U
+#define CSR_ACSMCSMAPCTRL10_ADDR			0xDAU
+#define CSR_ACSMCSMAPCTRL11_ADDR			0xDBU
+#define CSR_ACSMCSMAPCTRL12_ADDR			0xDCU
+#define CSR_ACSMCSMAPCTRL13_ADDR			0xDDU
+#define CSR_ACSMCSMAPCTRL14_ADDR			0xDEU
+#define CSR_ACSMCSMAPCTRL15_ADDR			0xDFU
+#define CSR_ACSMODTCTRL0_ADDR				0xE0U
+#define CSR_ACSMODTCTRL1_ADDR				0xE1U
+#define CSR_ACSMODTCTRL2_ADDR				0xE2U
+#define CSR_ACSMODTCTRL3_ADDR				0xE3U
+#define CSR_ACSMODTCTRL4_ADDR				0xE4U
+#define CSR_ACSMODTCTRL5_ADDR				0xE5U
+#define CSR_ACSMODTCTRL6_ADDR				0xE6U
+#define CSR_ACSMODTCTRL7_ADDR				0xE7U
+#define CSR_ACSMODTCTRL8_ADDR				0xE8U
+#define CSR_ACSMCTRL16_ADDR				0xE9U
+#define CSR_LOWSPEEDCLOCKSTOPVAL_ADDR			0xEAU
+#define CSR_ACSMCTRL18_ADDR				0xEBU
+#define CSR_ACSMCTRL19_ADDR				0xECU
+#define CSR_ACSMCTRL20_ADDR				0xEDU
+#define CSR_ACSMCTRL21_ADDR				0xEEU
+#define CSR_ACSMCTRL22_ADDR				0xEFU
+#define CSR_ACSMCTRL0_ADDR				0xF0U
+#define CSR_ACSMCTRL1_ADDR				0xF1U
+#define CSR_ACSMCTRL2_ADDR				0xF2U
+#define CSR_ACSMCTRL3_ADDR				0xF3U
+#define CSR_ACSMCTRL4_ADDR				0xF4U
+#define CSR_ACSMCTRL5_ADDR				0xF5U
+#define CSR_ACSMCTRL6_ADDR				0xF6U
+#define CSR_ACSMCTRL7_ADDR				0xF7U
+#define CSR_ACSMCTRL8_ADDR				0xF8U
+#define CSR_ACSMCTRL9_ADDR				0xF9U
+#define CSR_ACSMCTRL10_ADDR				0xFAU
+#define CSR_ACSMCTRL11_ADDR				0xFBU
+#define CSR_ACSMCTRL12_ADDR				0xFCU
+#define CSR_ACSMCTRL13_ADDR				0xFDU
+#define CSR_ACSMCTRL14_ADDR				0xFEU
+#define CSR_ACSMCTRL15_ADDR				0xFFU
+
+/* PPGC0 register offsets */
+#define CSR_PPGCCTRL1_ADDR				0x11U
+#define CSR_PPGCLANE2CRCINMAP0_ADDR			0x15U
+#define CSR_PPGCLANE2CRCINMAP1_ADDR			0x16U
+#define CSR_PRBSTAPDLY0_ADDR				0x24U
+#define CSR_PRBSTAPDLY1_ADDR				0x25U
+#define CSR_PRBSTAPDLY2_ADDR				0x26U
+#define CSR_PRBSTAPDLY3_ADDR				0x27U
+#define CSR_GENPRBSBYTE0_ADDR				0x30U
+#define CSR_GENPRBSBYTE1_ADDR				0x31U
+#define CSR_GENPRBSBYTE2_ADDR				0x32U
+#define CSR_GENPRBSBYTE3_ADDR				0x33U
+#define CSR_GENPRBSBYTE4_ADDR				0x34U
+#define CSR_GENPRBSBYTE5_ADDR				0x35U
+#define CSR_GENPRBSBYTE6_ADDR				0x36U
+#define CSR_GENPRBSBYTE7_ADDR				0x37U
+#define CSR_GENPRBSBYTE8_ADDR				0x38U
+#define CSR_GENPRBSBYTE9_ADDR				0x39U
+#define CSR_GENPRBSBYTE10_ADDR				0x3AU
+#define CSR_GENPRBSBYTE11_ADDR				0x3BU
+#define CSR_GENPRBSBYTE12_ADDR				0x3CU
+#define CSR_GENPRBSBYTE13_ADDR				0x3DU
+#define CSR_GENPRBSBYTE14_ADDR				0x3EU
+#define CSR_GENPRBSBYTE15_ADDR				0x3FU
+#define CSR_PRBSGENCTL_ADDR				0x60U
+#define CSR_PRBSGENSTATELO_ADDR				0x61U
+#define CSR_PRBSGENSTATEHI_ADDR				0x62U
+#define CSR_PRBSCHKSTATELO_ADDR				0x63U
+#define CSR_PRBSCHKSTATEHI_ADDR				0x64U
+#define CSR_PRBSGENCTL1_ADDR				0x65U
+#define CSR_PRBSGENCTL2_ADDR				0x66U
+
+/* INITENG0 register offsets */
+#define CSR_PRESEQUENCEREG0B0S0_ADDR			0x0U
+#define CSR_PRESEQUENCEREG0B0S1_ADDR			0x1U
+#define CSR_PRESEQUENCEREG0B0S2_ADDR			0x2U
+#define CSR_PRESEQUENCEREG0B1S0_ADDR			0x3U
+#define CSR_PRESEQUENCEREG0B1S1_ADDR			0x4U
+#define CSR_PRESEQUENCEREG0B1S2_ADDR			0x5U
+#define CSR_POSTSEQUENCEREG0B0S0_ADDR			0x6U
+#define CSR_POSTSEQUENCEREG0B0S1_ADDR			0x7U
+#define CSR_POSTSEQUENCEREG0B0S2_ADDR			0x8U
+#define CSR_POSTSEQUENCEREG0B1S0_ADDR			0x9U
+#define CSR_POSTSEQUENCEREG0B1S1_ADDR			0xAU
+#define CSR_POSTSEQUENCEREG0B1S2_ADDR			0xBU
+#define CSR_SEQ0BDISABLEFLAG0_ADDR			0xCU
+#define CSR_SEQ0BDISABLEFLAG1_ADDR			0xDU
+#define CSR_SEQ0BDISABLEFLAG2_ADDR			0xEU
+#define CSR_SEQ0BDISABLEFLAG3_ADDR			0xFU
+#define CSR_SEQ0BDISABLEFLAG4_ADDR			0x10U
+#define CSR_SEQ0BDISABLEFLAG5_ADDR			0x11U
+#define CSR_SEQ0BDISABLEFLAG6_ADDR			0x12U
+#define CSR_SEQ0BDISABLEFLAG7_ADDR			0x13U
+#define CSR_STARTVECTOR0B0_ADDR				0x17U
+#define CSR_STARTVECTOR0B1_ADDR				0x18U
+#define CSR_STARTVECTOR0B2_ADDR				0x19U
+#define CSR_STARTVECTOR0B3_ADDR				0x1AU
+#define CSR_STARTVECTOR0B4_ADDR				0x1BU
+#define CSR_STARTVECTOR0B5_ADDR				0x1CU
+#define CSR_STARTVECTOR0B6_ADDR				0x1DU
+#define CSR_STARTVECTOR0B7_ADDR				0x1EU
+#define CSR_STARTVECTOR0B8_ADDR				0x1FU
+#define CSR_STARTVECTOR0B9_ADDR				0x20U
+#define CSR_STARTVECTOR0B10_ADDR			0x21U
+#define CSR_STARTVECTOR0B11_ADDR			0x22U
+#define CSR_STARTVECTOR0B12_ADDR			0x23U
+#define CSR_STARTVECTOR0B13_ADDR			0x24U
+#define CSR_STARTVECTOR0B14_ADDR			0x25U
+#define CSR_STARTVECTOR0B15_ADDR			0x26U
+#define CSR_SEQ0BWAITCONDSEL_ADDR			0x27U
+#define CSR_PHYINLP3_ADDR				0x28U
+#define CSR_SEQUENCEREG0B0S0_ADDR			0x29U
+#define CSR_SEQUENCEREG0B0S1_ADDR			0x2AU
+#define CSR_SEQUENCEREG0B0S2_ADDR			0x2BU
+#define CSR_SEQUENCEREG0B1S0_ADDR			0x2CU
+#define CSR_SEQUENCEREG0B1S1_ADDR			0x2DU
+#define CSR_SEQUENCEREG0B1S2_ADDR			0x2EU
+#define CSR_SEQUENCEREG0B2S0_ADDR			0x2FU
+#define CSR_SEQUENCEREG0B2S1_ADDR			0x30U
+#define CSR_SEQUENCEREG0B2S2_ADDR			0x31U
+#define CSR_SEQUENCEREG0B3S0_ADDR			0x32U
+#define CSR_SEQUENCEREG0B3S1_ADDR			0x33U
+#define CSR_SEQUENCEREG0B3S2_ADDR			0x34U
+#define CSR_SEQUENCEREG0B4S0_ADDR			0x35U
+#define CSR_SEQUENCEREG0B4S1_ADDR			0x36U
+#define CSR_SEQUENCEREG0B4S2_ADDR			0x37U
+#define CSR_SEQUENCEREG0B5S0_ADDR			0x38U
+#define CSR_SEQUENCEREG0B5S1_ADDR			0x39U
+#define CSR_SEQUENCEREG0B5S2_ADDR			0x3AU
+#define CSR_SEQUENCEREG0B6S0_ADDR			0x3BU
+#define CSR_SEQUENCEREG0B6S1_ADDR			0x3CU
+#define CSR_SEQUENCEREG0B6S2_ADDR			0x3DU
+#define CSR_SEQUENCEREG0B7S0_ADDR			0x3EU
+#define CSR_SEQUENCEREG0B7S1_ADDR			0x3FU
+#define CSR_SEQUENCEREG0B7S2_ADDR			0x40U
+#define CSR_SEQUENCEREG0B8S0_ADDR			0x41U
+#define CSR_SEQUENCEREG0B8S1_ADDR			0x42U
+#define CSR_SEQUENCEREG0B8S2_ADDR			0x43U
+#define CSR_SEQUENCEREG0B9S0_ADDR			0x44U
+#define CSR_SEQUENCEREG0B9S1_ADDR			0x45U
+#define CSR_SEQUENCEREG0B9S2_ADDR			0x46U
+#define CSR_SEQUENCEREG0B10S0_ADDR			0x47U
+#define CSR_SEQUENCEREG0B10S1_ADDR			0x48U
+#define CSR_SEQUENCEREG0B10S2_ADDR			0x49U
+#define CSR_SEQUENCEREG0B11S0_ADDR			0x4AU
+#define CSR_SEQUENCEREG0B11S1_ADDR			0x4BU
+#define CSR_SEQUENCEREG0B11S2_ADDR			0x4CU
+#define CSR_SEQUENCEREG0B12S0_ADDR			0x4DU
+#define CSR_SEQUENCEREG0B12S1_ADDR			0x4EU
+#define CSR_SEQUENCEREG0B12S2_ADDR			0x4FU
+#define CSR_SEQUENCEREG0B13S0_ADDR			0x50U
+#define CSR_SEQUENCEREG0B13S1_ADDR			0x51U
+#define CSR_SEQUENCEREG0B13S2_ADDR			0x52U
+#define CSR_SEQUENCEREG0B14S0_ADDR			0x53U
+#define CSR_SEQUENCEREG0B14S1_ADDR			0x54U
+#define CSR_SEQUENCEREG0B14S2_ADDR			0x55U
+#define CSR_SEQUENCEREG0B15S0_ADDR			0x56U
+#define CSR_SEQUENCEREG0B15S1_ADDR			0x57U
+#define CSR_SEQUENCEREG0B15S2_ADDR			0x58U
+#define CSR_SEQUENCEREG0B16S0_ADDR			0x59U
+#define CSR_SEQUENCEREG0B16S1_ADDR			0x5AU
+#define CSR_SEQUENCEREG0B16S2_ADDR			0x5BU
+#define CSR_SEQUENCEREG0B17S0_ADDR			0x5CU
+#define CSR_SEQUENCEREG0B17S1_ADDR			0x5DU
+#define CSR_SEQUENCEREG0B17S2_ADDR			0x5EU
+#define CSR_SEQUENCEREG0B18S0_ADDR			0x5FU
+#define CSR_SEQUENCEREG0B18S1_ADDR			0x60U
+#define CSR_SEQUENCEREG0B18S2_ADDR			0x61U
+#define CSR_SEQUENCEREG0B19S0_ADDR			0x62U
+#define CSR_SEQUENCEREG0B19S1_ADDR			0x63U
+#define CSR_SEQUENCEREG0B19S2_ADDR			0x64U
+#define CSR_SEQUENCEREG0B20S0_ADDR			0x65U
+#define CSR_SEQUENCEREG0B20S1_ADDR			0x66U
+#define CSR_SEQUENCEREG0B20S2_ADDR			0x67U
+#define CSR_SEQUENCEREG0B21S0_ADDR			0x68U
+#define CSR_SEQUENCEREG0B21S1_ADDR			0x69U
+#define CSR_SEQUENCEREG0B21S2_ADDR			0x6AU
+#define CSR_SEQUENCEREG0B22S0_ADDR			0x6BU
+#define CSR_SEQUENCEREG0B22S1_ADDR			0x6CU
+#define CSR_SEQUENCEREG0B22S2_ADDR			0x6DU
+#define CSR_SEQUENCEREG0B23S0_ADDR			0x6EU
+#define CSR_SEQUENCEREG0B23S1_ADDR			0x6FU
+#define CSR_SEQUENCEREG0B23S2_ADDR			0x70U
+#define CSR_SEQUENCEREG0B24S0_ADDR			0x71U
+#define CSR_SEQUENCEREG0B24S1_ADDR			0x72U
+#define CSR_SEQUENCEREG0B24S2_ADDR			0x73U
+#define CSR_SEQUENCEREG0B25S0_ADDR			0x74U
+#define CSR_SEQUENCEREG0B25S1_ADDR			0x75U
+#define CSR_SEQUENCEREG0B25S2_ADDR			0x76U
+#define CSR_SEQUENCEREG0B26S0_ADDR			0x77U
+#define CSR_SEQUENCEREG0B26S1_ADDR			0x78U
+#define CSR_SEQUENCEREG0B26S2_ADDR			0x79U
+#define CSR_SEQUENCEREG0B27S0_ADDR			0x7AU
+#define CSR_SEQUENCEREG0B27S1_ADDR			0x7BU
+#define CSR_SEQUENCEREG0B27S2_ADDR			0x7CU
+#define CSR_SEQUENCEREG0B28S0_ADDR			0x7DU
+#define CSR_SEQUENCEREG0B28S1_ADDR			0x7EU
+#define CSR_SEQUENCEREG0B28S2_ADDR			0x7FU
+#define CSR_SEQUENCEREG0B29S0_ADDR			0x80U
+#define CSR_SEQUENCEREG0B29S1_ADDR			0x81U
+#define CSR_SEQUENCEREG0B29S2_ADDR			0x82U
+#define CSR_SEQUENCEREG0B30S0_ADDR			0x83U
+#define CSR_SEQUENCEREG0B30S1_ADDR			0x84U
+#define CSR_SEQUENCEREG0B30S2_ADDR			0x85U
+#define CSR_SEQUENCEREG0B31S0_ADDR			0x86U
+#define CSR_SEQUENCEREG0B31S1_ADDR			0x87U
+#define CSR_SEQUENCEREG0B31S2_ADDR			0x88U
+#define CSR_SEQUENCEREG0B32S0_ADDR			0x89U
+#define CSR_SEQUENCEREG0B32S1_ADDR			0x8AU
+#define CSR_SEQUENCEREG0B32S2_ADDR			0x8BU
+#define CSR_SEQUENCEREG0B33S0_ADDR			0x8CU
+#define CSR_SEQUENCEREG0B33S1_ADDR			0x8DU
+#define CSR_SEQUENCEREG0B33S2_ADDR			0x8EU
+#define CSR_SEQUENCEREG0B34S0_ADDR			0x8FU
+#define CSR_SEQUENCEREG0B34S1_ADDR			0x90U
+#define CSR_SEQUENCEREG0B34S2_ADDR			0x91U
+#define CSR_SEQUENCEREG0B35S0_ADDR			0x92U
+#define CSR_SEQUENCEREG0B35S1_ADDR			0x93U
+#define CSR_SEQUENCEREG0B35S2_ADDR			0x94U
+#define CSR_SEQUENCEREG0B36S0_ADDR			0x95U
+#define CSR_SEQUENCEREG0B36S1_ADDR			0x96U
+#define CSR_SEQUENCEREG0B36S2_ADDR			0x97U
+#define CSR_SEQUENCEREG0B37S0_ADDR			0x98U
+#define CSR_SEQUENCEREG0B37S1_ADDR			0x99U
+#define CSR_SEQUENCEREG0B37S2_ADDR			0x9AU
+#define CSR_SEQUENCEREG0B38S0_ADDR			0x9BU
+#define CSR_SEQUENCEREG0B38S1_ADDR			0x9CU
+#define CSR_SEQUENCEREG0B38S2_ADDR			0x9DU
+#define CSR_SEQUENCEREG0B39S0_ADDR			0x9EU
+#define CSR_SEQUENCEREG0B39S1_ADDR			0x9FU
+#define CSR_SEQUENCEREG0B39S2_ADDR			0xA0U
+#define CSR_SEQUENCEREG0B40S0_ADDR			0xA1U
+#define CSR_SEQUENCEREG0B40S1_ADDR			0xA2U
+#define CSR_SEQUENCEREG0B40S2_ADDR			0xA3U
+#define CSR_SEQUENCEREG0B41S0_ADDR			0xA4U
+#define CSR_SEQUENCEREG0B41S1_ADDR			0xA5U
+#define CSR_SEQUENCEREG0B41S2_ADDR			0xA6U
+#define CSR_SEQUENCEREG0B42S0_ADDR			0xA7U
+#define CSR_SEQUENCEREG0B42S1_ADDR			0xA8U
+#define CSR_SEQUENCEREG0B42S2_ADDR			0xA9U
+#define CSR_SEQUENCEREG0B43S0_ADDR			0xAAU
+#define CSR_SEQUENCEREG0B43S1_ADDR			0xABU
+#define CSR_SEQUENCEREG0B43S2_ADDR			0xACU
+#define CSR_SEQUENCEREG0B44S0_ADDR			0xADU
+#define CSR_SEQUENCEREG0B44S1_ADDR			0xAEU
+#define CSR_SEQUENCEREG0B44S2_ADDR			0xAFU
+#define CSR_SEQUENCEREG0B45S0_ADDR			0xB0U
+#define CSR_SEQUENCEREG0B45S1_ADDR			0xB1U
+#define CSR_SEQUENCEREG0B45S2_ADDR			0xB2U
+#define CSR_SEQUENCEREG0B46S0_ADDR			0xB3U
+#define CSR_SEQUENCEREG0B46S1_ADDR			0xB4U
+#define CSR_SEQUENCEREG0B46S2_ADDR			0xB5U
+#define CSR_SEQUENCEREG0B47S0_ADDR			0xB6U
+#define CSR_SEQUENCEREG0B47S1_ADDR			0xB7U
+#define CSR_SEQUENCEREG0B47S2_ADDR			0xB8U
+#define CSR_SEQUENCEREG0B48S0_ADDR			0xB9U
+#define CSR_SEQUENCEREG0B48S1_ADDR			0xBAU
+#define CSR_SEQUENCEREG0B48S2_ADDR			0xBBU
+#define CSR_SEQUENCEREG0B49S0_ADDR			0xBCU
+#define CSR_SEQUENCEREG0B49S1_ADDR			0xBDU
+#define CSR_SEQUENCEREG0B49S2_ADDR			0xBEU
+#define CSR_SEQUENCEREG0B50S0_ADDR			0xBFU
+#define CSR_SEQUENCEREG0B50S1_ADDR			0xC0U
+#define CSR_SEQUENCEREG0B50S2_ADDR			0xC1U
+#define CSR_SEQUENCEREG0B51S0_ADDR			0xC2U
+#define CSR_SEQUENCEREG0B51S1_ADDR			0xC3U
+#define CSR_SEQUENCEREG0B51S2_ADDR			0xC4U
+#define CSR_SEQUENCEREG0B52S0_ADDR			0xC5U
+#define CSR_SEQUENCEREG0B52S1_ADDR			0xC6U
+#define CSR_SEQUENCEREG0B52S2_ADDR			0xC7U
+#define CSR_SEQUENCEREG0B53S0_ADDR			0xC8U
+#define CSR_SEQUENCEREG0B53S1_ADDR			0xC9U
+#define CSR_SEQUENCEREG0B53S2_ADDR			0xCAU
+#define CSR_SEQUENCEREG0B54S0_ADDR			0xCBU
+#define CSR_SEQUENCEREG0B54S1_ADDR			0xCCU
+#define CSR_SEQUENCEREG0B54S2_ADDR			0xCDU
+#define CSR_SEQUENCEREG0B55S0_ADDR			0xCEU
+#define CSR_SEQUENCEREG0B55S1_ADDR			0xCFU
+#define CSR_SEQUENCEREG0B55S2_ADDR			0xD0U
+#define CSR_SEQUENCEREG0B56S0_ADDR			0xD1U
+#define CSR_SEQUENCEREG0B56S1_ADDR			0xD2U
+#define CSR_SEQUENCEREG0B56S2_ADDR			0xD3U
+#define CSR_SEQUENCEREG0B57S0_ADDR			0xD4U
+#define CSR_SEQUENCEREG0B57S1_ADDR			0xD5U
+#define CSR_SEQUENCEREG0B57S2_ADDR			0xD6U
+#define CSR_SEQUENCEREG0B58S0_ADDR			0xD7U
+#define CSR_SEQUENCEREG0B58S1_ADDR			0xD8U
+#define CSR_SEQUENCEREG0B58S2_ADDR			0xD9U
+#define CSR_SEQUENCEREG0B59S0_ADDR			0xDAU
+#define CSR_SEQUENCEREG0B59S1_ADDR			0xDBU
+#define CSR_SEQUENCEREG0B59S2_ADDR			0xDCU
+#define CSR_SEQUENCEREG0B60S0_ADDR			0xDDU
+#define CSR_SEQUENCEREG0B60S1_ADDR			0xDEU
+#define CSR_SEQUENCEREG0B60S2_ADDR			0xDFU
+#define CSR_SEQUENCEREG0B61S0_ADDR			0xE0U
+#define CSR_SEQUENCEREG0B61S1_ADDR			0xE1U
+#define CSR_SEQUENCEREG0B61S2_ADDR			0xE2U
+#define CSR_SEQUENCEREG0B62S0_ADDR			0xE3U
+#define CSR_SEQUENCEREG0B62S1_ADDR			0xE4U
+#define CSR_SEQUENCEREG0B62S2_ADDR			0xE5U
+#define CSR_SEQUENCEREG0B63S0_ADDR			0xE6U
+#define CSR_SEQUENCEREG0B63S1_ADDR			0xE7U
+#define CSR_SEQUENCEREG0B63S2_ADDR			0xE8U
+#define CSR_SEQUENCEREG0B64S0_ADDR			0xE9U
+#define CSR_SEQUENCEREG0B64S1_ADDR			0xEAU
+#define CSR_SEQUENCEREG0B64S2_ADDR			0xEBU
+#define CSR_SEQUENCEREG0B65S0_ADDR			0xECU
+#define CSR_SEQUENCEREG0B65S1_ADDR			0xEDU
+#define CSR_SEQUENCEREG0B65S2_ADDR			0xEEU
+#define CSR_SEQUENCEREG0B66S0_ADDR			0xEFU
+#define CSR_SEQUENCEREG0B66S1_ADDR			0xF0U
+#define CSR_SEQUENCEREG0B66S2_ADDR			0xF1U
+#define CSR_SEQUENCEREG0B67S0_ADDR			0xF2U
+#define CSR_SEQUENCEREG0B67S1_ADDR			0xF3U
+#define CSR_SEQUENCEREG0B67S2_ADDR			0xF4U
+#define CSR_SEQUENCEREG0B68S0_ADDR			0xF5U
+#define CSR_SEQUENCEREG0B68S1_ADDR			0xF6U
+#define CSR_SEQUENCEREG0B68S2_ADDR			0xF7U
+#define CSR_SEQUENCEREG0B69S0_ADDR			0xF8U
+#define CSR_SEQUENCEREG0B69S1_ADDR			0xF9U
+#define CSR_SEQUENCEREG0B69S2_ADDR			0xFAU
+#define CSR_SEQUENCEREG0B70S0_ADDR			0xFBU
+#define CSR_SEQUENCEREG0B70S1_ADDR			0xFCU
+#define CSR_SEQUENCEREG0B70S2_ADDR			0xFDU
+#define CSR_SEQUENCEREG0B71S0_ADDR			0xFEU
+#define CSR_SEQUENCEREG0B71S1_ADDR			0xFFU
+#define CSR_SEQUENCEREG0B71S2_ADDR			0x100U
+#define CSR_SEQUENCEREG0B72S0_ADDR			0x101U
+#define CSR_SEQUENCEREG0B72S1_ADDR			0x102U
+#define CSR_SEQUENCEREG0B72S2_ADDR			0x103U
+#define CSR_SEQUENCEREG0B73S0_ADDR			0x104U
+#define CSR_SEQUENCEREG0B73S1_ADDR			0x105U
+#define CSR_SEQUENCEREG0B73S2_ADDR			0x106U
+#define CSR_SEQUENCEREG0B74S0_ADDR			0x107U
+#define CSR_SEQUENCEREG0B74S1_ADDR			0x108U
+#define CSR_SEQUENCEREG0B74S2_ADDR			0x109U
+#define CSR_SEQUENCEREG0B75S0_ADDR			0x10AU
+#define CSR_SEQUENCEREG0B75S1_ADDR			0x10BU
+#define CSR_SEQUENCEREG0B75S2_ADDR			0x10CU
+#define CSR_SEQUENCEREG0B76S0_ADDR			0x10DU
+#define CSR_SEQUENCEREG0B76S1_ADDR			0x10EU
+#define CSR_SEQUENCEREG0B76S2_ADDR			0x10FU
+#define CSR_SEQUENCEREG0B77S0_ADDR			0x110U
+#define CSR_SEQUENCEREG0B77S1_ADDR			0x111U
+#define CSR_SEQUENCEREG0B77S2_ADDR			0x112U
+#define CSR_SEQUENCEREG0B78S0_ADDR			0x113U
+#define CSR_SEQUENCEREG0B78S1_ADDR			0x114U
+#define CSR_SEQUENCEREG0B78S2_ADDR			0x115U
+#define CSR_SEQUENCEREG0B79S0_ADDR			0x116U
+#define CSR_SEQUENCEREG0B79S1_ADDR			0x117U
+#define CSR_SEQUENCEREG0B79S2_ADDR			0x118U
+#define CSR_SEQUENCEREG0B80S0_ADDR			0x119U
+#define CSR_SEQUENCEREG0B80S1_ADDR			0x11AU
+#define CSR_SEQUENCEREG0B80S2_ADDR			0x11BU
+#define CSR_SEQUENCEREG0B81S0_ADDR			0x11CU
+#define CSR_SEQUENCEREG0B81S1_ADDR			0x11DU
+#define CSR_SEQUENCEREG0B81S2_ADDR			0x11EU
+#define CSR_SEQUENCEREG0B82S0_ADDR			0x11FU
+#define CSR_SEQUENCEREG0B82S1_ADDR			0x120U
+#define CSR_SEQUENCEREG0B82S2_ADDR			0x121U
+#define CSR_SEQUENCEREG0B83S0_ADDR			0x122U
+#define CSR_SEQUENCEREG0B83S1_ADDR			0x123U
+#define CSR_SEQUENCEREG0B83S2_ADDR			0x124U
+#define CSR_SEQUENCEREG0B84S0_ADDR			0x125U
+#define CSR_SEQUENCEREG0B84S1_ADDR			0x126U
+#define CSR_SEQUENCEREG0B84S2_ADDR			0x127U
+#define CSR_SEQUENCEREG0B85S0_ADDR			0x128U
+#define CSR_SEQUENCEREG0B85S1_ADDR			0x129U
+#define CSR_SEQUENCEREG0B85S2_ADDR			0x12AU
+#define CSR_SEQUENCEREG0B86S0_ADDR			0x12BU
+#define CSR_SEQUENCEREG0B86S1_ADDR			0x12CU
+#define CSR_SEQUENCEREG0B86S2_ADDR			0x12DU
+#define CSR_SEQUENCEREG0B87S0_ADDR			0x12EU
+#define CSR_SEQUENCEREG0B87S1_ADDR			0x12FU
+#define CSR_SEQUENCEREG0B87S2_ADDR			0x130U
+#define CSR_SEQUENCEREG0B88S0_ADDR			0x131U
+#define CSR_SEQUENCEREG0B88S1_ADDR			0x132U
+#define CSR_SEQUENCEREG0B88S2_ADDR			0x133U
+#define CSR_SEQUENCEREG0B89S0_ADDR			0x134U
+#define CSR_SEQUENCEREG0B89S1_ADDR			0x135U
+#define CSR_SEQUENCEREG0B89S2_ADDR			0x136U
+#define CSR_SEQUENCEREG0B90S0_ADDR			0x137U
+#define CSR_SEQUENCEREG0B90S1_ADDR			0x138U
+#define CSR_SEQUENCEREG0B90S2_ADDR			0x139U
+#define CSR_SEQUENCEREG0B91S0_ADDR			0x13AU
+#define CSR_SEQUENCEREG0B91S1_ADDR			0x13BU
+#define CSR_SEQUENCEREG0B91S2_ADDR			0x13CU
+#define CSR_SEQUENCEREG0B92S0_ADDR			0x13DU
+#define CSR_SEQUENCEREG0B92S1_ADDR			0x13EU
+#define CSR_SEQUENCEREG0B92S2_ADDR			0x13FU
+#define CSR_SEQUENCEREG0B93S0_ADDR			0x140U
+#define CSR_SEQUENCEREG0B93S1_ADDR			0x141U
+#define CSR_SEQUENCEREG0B93S2_ADDR			0x142U
+#define CSR_SEQUENCEREG0B94S0_ADDR			0x143U
+#define CSR_SEQUENCEREG0B94S1_ADDR			0x144U
+#define CSR_SEQUENCEREG0B94S2_ADDR			0x145U
+#define CSR_SEQUENCEREG0B95S0_ADDR			0x146U
+#define CSR_SEQUENCEREG0B95S1_ADDR			0x147U
+#define CSR_SEQUENCEREG0B95S2_ADDR			0x148U
+#define CSR_SEQUENCEREG0B96S0_ADDR			0x149U
+#define CSR_SEQUENCEREG0B96S1_ADDR			0x14AU
+#define CSR_SEQUENCEREG0B96S2_ADDR			0x14BU
+#define CSR_SEQUENCEREG0B97S0_ADDR			0x14CU
+#define CSR_SEQUENCEREG0B97S1_ADDR			0x14DU
+#define CSR_SEQUENCEREG0B97S2_ADDR			0x14EU
+#define CSR_SEQUENCEREG0B98S0_ADDR			0x14FU
+#define CSR_SEQUENCEREG0B98S1_ADDR			0x150U
+#define CSR_SEQUENCEREG0B98S2_ADDR			0x151U
+#define CSR_SEQUENCEREG0B99S0_ADDR			0x152U
+#define CSR_SEQUENCEREG0B99S1_ADDR			0x153U
+#define CSR_SEQUENCEREG0B99S2_ADDR			0x154U
+#define CSR_SEQUENCEREG0B100S0_ADDR			0x155U
+#define CSR_SEQUENCEREG0B100S1_ADDR			0x156U
+#define CSR_SEQUENCEREG0B100S2_ADDR			0x157U
+#define CSR_SEQUENCEREG0B101S0_ADDR			0x158U
+#define CSR_SEQUENCEREG0B101S1_ADDR			0x159U
+#define CSR_SEQUENCEREG0B101S2_ADDR			0x15AU
+#define CSR_SEQUENCEREG0B102S0_ADDR			0x15BU
+#define CSR_SEQUENCEREG0B102S1_ADDR			0x15CU
+#define CSR_SEQUENCEREG0B102S2_ADDR			0x15DU
+#define CSR_SEQUENCEREG0B103S0_ADDR			0x15EU
+#define CSR_SEQUENCEREG0B103S1_ADDR			0x15FU
+#define CSR_SEQUENCEREG0B103S2_ADDR			0x160U
+#define CSR_SEQUENCEREG0B104S0_ADDR			0x161U
+#define CSR_SEQUENCEREG0B104S1_ADDR			0x162U
+#define CSR_SEQUENCEREG0B104S2_ADDR			0x163U
+#define CSR_SEQUENCEREG0B105S0_ADDR			0x164U
+#define CSR_SEQUENCEREG0B105S1_ADDR			0x165U
+#define CSR_SEQUENCEREG0B105S2_ADDR			0x166U
+#define CSR_SEQUENCEREG0B106S0_ADDR			0x167U
+#define CSR_SEQUENCEREG0B106S1_ADDR			0x168U
+#define CSR_SEQUENCEREG0B106S2_ADDR			0x169U
+#define CSR_SEQUENCEREG0B107S0_ADDR			0x16AU
+#define CSR_SEQUENCEREG0B107S1_ADDR			0x16BU
+#define CSR_SEQUENCEREG0B107S2_ADDR			0x16CU
+#define CSR_SEQUENCEREG0B108S0_ADDR			0x16DU
+#define CSR_SEQUENCEREG0B108S1_ADDR			0x16EU
+#define CSR_SEQUENCEREG0B108S2_ADDR			0x16FU
+#define CSR_SEQUENCEREG0B109S0_ADDR			0x170U
+#define CSR_SEQUENCEREG0B109S1_ADDR			0x171U
+#define CSR_SEQUENCEREG0B109S2_ADDR			0x172U
+#define CSR_SEQUENCEREG0B110S0_ADDR			0x173U
+#define CSR_SEQUENCEREG0B110S1_ADDR			0x174U
+#define CSR_SEQUENCEREG0B110S2_ADDR			0x175U
+#define CSR_SEQUENCEREG0B111S0_ADDR			0x176U
+#define CSR_SEQUENCEREG0B111S1_ADDR			0x177U
+#define CSR_SEQUENCEREG0B111S2_ADDR			0x178U
+#define CSR_SEQUENCEREG0B112S0_ADDR			0x179U
+#define CSR_SEQUENCEREG0B112S1_ADDR			0x17AU
+#define CSR_SEQUENCEREG0B112S2_ADDR			0x17BU
+#define CSR_SEQUENCEREG0B113S0_ADDR			0x17CU
+#define CSR_SEQUENCEREG0B113S1_ADDR			0x17DU
+#define CSR_SEQUENCEREG0B113S2_ADDR			0x17EU
+#define CSR_SEQUENCEREG0B114S0_ADDR			0x17FU
+#define CSR_SEQUENCEREG0B114S1_ADDR			0x180U
+#define CSR_SEQUENCEREG0B114S2_ADDR			0x181U
+#define CSR_SEQUENCEREG0B115S0_ADDR			0x182U
+#define CSR_SEQUENCEREG0B115S1_ADDR			0x183U
+#define CSR_SEQUENCEREG0B115S2_ADDR			0x184U
+#define CSR_SEQUENCEREG0B116S0_ADDR			0x185U
+#define CSR_SEQUENCEREG0B116S1_ADDR			0x186U
+#define CSR_SEQUENCEREG0B116S2_ADDR			0x187U
+#define CSR_SEQUENCEREG0B117S0_ADDR			0x188U
+#define CSR_SEQUENCEREG0B117S1_ADDR			0x189U
+#define CSR_SEQUENCEREG0B117S2_ADDR			0x18AU
+#define CSR_SEQUENCEREG0B118S0_ADDR			0x18BU
+#define CSR_SEQUENCEREG0B118S1_ADDR			0x18CU
+#define CSR_SEQUENCEREG0B118S2_ADDR			0x18DU
+#define CSR_SEQUENCEREG0B119S0_ADDR			0x18EU
+#define CSR_SEQUENCEREG0B119S1_ADDR			0x18FU
+#define CSR_SEQUENCEREG0B119S2_ADDR			0x190U
+#define CSR_SEQUENCEREG0B120S0_ADDR			0x191U
+#define CSR_SEQUENCEREG0B120S1_ADDR			0x192U
+#define CSR_SEQUENCEREG0B120S2_ADDR			0x193U
+#define CSR_SEQUENCEREG0B121S0_ADDR			0x194U
+#define CSR_SEQUENCEREG0B121S1_ADDR			0x195U
+#define CSR_SEQUENCEREG0B121S2_ADDR			0x196U
+#define CSR_SEQ0BGPR1_ADDR				0x201U
+#define CSR_SEQ0BGPR2_ADDR				0x202U
+#define CSR_SEQ0BGPR3_ADDR				0x203U
+#define CSR_SEQ0BGPR4_ADDR				0x204U
+#define CSR_SEQ0BGPR5_ADDR				0x205U
+#define CSR_SEQ0BGPR6_ADDR				0x206U
+#define CSR_SEQ0BGPR7_ADDR				0x207U
+#define CSR_SEQ0BGPR8_ADDR				0x208U
+#define CSR_SEQ0BFIXEDADDRBITS_ADDR			0x2FFU
+
+/* DRTUB0 register offsets */
+#define CSR_DCTSHADOWREGS_ADDR				0x4U
+#define CSR_DCTWRITEONLYSHADOW_ADDR			0x30U
+#define CSR_UCTWRITEONLY_ADDR				0x32U
+#define CSR_UCTWRITEPROT_ADDR				0x33U
+#define CSR_UCTDATWRITEONLY_ADDR			0x34U
+#define CSR_UCTDATWRITEPROT_ADDR			0x35U
+#define CSR_UCTLERR_ADDR				0x36U
+#define CSR_UCCLKHCLKENABLES_ADDR			0x80U
+#define CSR_CURPSTATE0B_ADDR				0x81U
+#define CSR_CLRWAKEUPSTICKY_ADDR			0x95U
+#define CSR_WAKEUPMASK_ADDR				0x96U
+#define CSR_CUSTPUBREV_ADDR				0xEDU
+#define CSR_PUBREV_ADDR					0xEEU
+
+/* APBONLY0 register offsets */
+#define CSR_MICROCONTMUXSEL_ADDR			0x0U
+#define CSR_UCTSHADOWREGS_ADDR				0x4U
+#define CSR_DCTWRITEONLY_ADDR				0x30U
+#define CSR_DCTWRITEPROT_ADDR				0x31U
+#define CSR_UCTWRITEONLYSHADOW_ADDR			0x32U
+#define CSR_UCTDATWRITEONLYSHADOW_ADDR			0x34U
+#define CSR_NEVERGATECSRCLOCK_ADDR			0x35U
+#define CSR_DFICFGRDDATAVALIDTICKS_ADDR			0x37U
+#define CSR_MICRORESET_ADDR				0x99U
+#define CSR_SEQUENCEROVERRIDE_ADDR			0xE7U
+#define CSR_DFIINITCOMPLETESHADOW_ADDR			0xFAU
+
+/* ANIBx register bit fields */
+/* CSR_MTESTMUXSEL */
+#define CSR_MTESTMUXSEL_LSB				0
+#define CSR_MTESTMUXSEL_MASK				GENMASK_32(5, 0)
+/* CSR_AFORCEDRVCONT */
+#define CSR_AFORCEDRVCONT_LSB				0
+#define CSR_AFORCEDRVCONT_MASK				GENMASK_32(3, 0)
+/* CSR_AFORCETRICONT */
+#define CSR_AFORCETRICONT_LSB				0
+#define CSR_AFORCETRICONT_MASK				GENMASK_32(3, 0)
+/* CSR_ATXIMPEDANCE */
+#define CSR_ATXIMPEDANCE_LSB				0
+#define CSR_ATXIMPEDANCE_MASK				GENMASK_32(9, 0)
+#define CSR_ADRVSTRENP_LSB				0
+#define CSR_ADRVSTRENP_MASK				GENMASK_32(4, 0)
+#define CSR_ADRVSTRENN_LSB				5
+#define CSR_ADRVSTRENN_MASK				GENMASK_32(9, 5)
+/* CSR_ATESTPRBSERR */
+#define CSR_ATESTPRBSERR_LSB				0
+#define CSR_ATESTPRBSERR_MASK				GENMASK_32(3, 0)
+/* CSR_ATXSLEWRATE */
+#define CSR_ATXSLEWRATE_LSB				0
+#define CSR_ATXSLEWRATE_MASK				GENMASK_32(10, 0)
+#define CSR_ATXPREP_LSB					0
+#define CSR_ATXPREP_MASK				GENMASK_32(3, 0)
+#define CSR_ATXPREN_LSB					4
+#define CSR_ATXPREN_MASK				GENMASK_32(7, 4)
+#define CSR_ATXPREDRVMODE_LSB				8
+#define CSR_ATXPREDRVMODE_MASK				GENMASK_32(10, 8)
+/* CSR_ATESTPRBSERRCNT */
+#define CSR_ATESTPRBSERRCNT_LSB				0
+#define CSR_ATESTPRBSERRCNT_MASK			GENMASK_32(15, 0)
+/* CSR_ATXDLY */
+#define CSR_ATXDLY_LSB					0
+#define CSR_ATXDLY_MASK					GENMASK_32(6, 0)
+
+/* DBYTEx register bit fields */
+/* CSR_DBYTEMISCMODE */
+#define CSR_DBYTEMISCMODE_LSB				2
+#define CSR_DBYTEMISCMODE_MASK				BIT(2)
+#define CSR_DBYTEDISABLE_LSB				2
+#define CSR_DBYTEDISABLE_MASK				BIT(2)
+/* CSR_TSMBYTE0 */
+#define CSR_TSMBYTE0_LSB				0
+#define CSR_TSMBYTE0_MASK				GENMASK_32(15, 0)
+#define CSR_PERPHTRAINEN_LSB				0
+#define CSR_PERPHTRAINEN_MASK				BIT(0)
+#define CSR_EYEINC_LSB					1
+#define CSR_EYEINC_MASK					BIT(1)
+#define CSR_EDGEINC_LSB					2
+#define CSR_EDGEINC_MASK				BIT(2)
+#define CSR_EDGEEYEMXSEL_LSB				3
+#define CSR_EDGEEYEMXSEL_MASK				BIT(3)
+#define CSR_TSMBYTE0RSVD_LSB				4
+#define CSR_TSMBYTE0RSVD_MASK				GENMASK_32(5, 4)
+#define CSR_DIMMBROADINC_LSB				6
+#define CSR_DIMMBROADINC_MASK				BIT(6)
+#define CSR_DIMMINC_LSB					7
+#define CSR_DIMMINC_MASK				GENMASK_32(8, 7)
+#define CSR_COARSEINC_LSB				9
+#define CSR_COARSEINC_MASK				BIT(9)
+#define CSR_DELAYINC_LSB				10
+#define CSR_DELAYINC_MASK				BIT(10)
+#define CSR_RXINC_LSB					11
+#define CSR_RXINC_MASK					BIT(11)
+#define CSR_RXPERTRAIN_LSB				12
+#define CSR_RXPERTRAIN_MASK				BIT(12)
+#define CSR_TXPERTRAIN_LSB				13
+#define CSR_TXPERTRAIN_MASK				BIT(13)
+#define CSR_DMTRAIN_LSB					14
+#define CSR_DMTRAIN_MASK				BIT(14)
+#define CSR_WRLEVTRAIN_LSB				15
+#define CSR_WRLEVTRAIN_MASK				BIT(15)
+/* CSR_TRAININGPARAM */
+#define CSR_TRAININGPARAM_LSB				0
+#define CSR_TRAININGPARAM_MASK				GENMASK_32(15, 0)
+#define CSR_ENDYNRATEREDUCTION_LSB			0
+#define CSR_ENDYNRATEREDUCTION_MASK			BIT(0)
+#define CSR_TRAININGPARAM01RSVD_LSB			1
+#define CSR_TRAININGPARAM01RSVD_MASK			BIT(1)
+#define CSR_TRAINENRXCLK_LSB				2
+#define CSR_TRAINENRXCLK_MASK				BIT(2)
+#define CSR_TRAINENRXEN_LSB				3
+#define CSR_TRAINENRXEN_MASK				BIT(3)
+#define CSR_TRAINENTXDQS_LSB				4
+#define CSR_TRAINENTXDQS_MASK				BIT(4)
+#define CSR_TRAINENTXDQ_LSB				5
+#define CSR_TRAINENTXDQ_MASK				BIT(5)
+#define CSR_TRAINENVREFDAC1_LSB				6
+#define CSR_TRAINENVREFDAC1_MASK			BIT(6)
+#define CSR_TRAINENVREFDAC0_LSB				7
+#define CSR_TRAINENVREFDAC0_MASK			BIT(7)
+#define CSR_TRAINENRXPBD_LSB				8
+#define CSR_TRAINENRXPBD_MASK				BIT(8)
+#define CSR_ROLLINTOCOARSE_LSB				9
+#define CSR_ROLLINTOCOARSE_MASK				BIT(9)
+#define CSR_TRAINUSINGNATIVEDDLCNTL_LSB			10
+#define CSR_TRAINUSINGNATIVEDDLCNTL_MASK		BIT(10)
+#define CSR_TRAININGPARAM11RSVD_LSB			11
+#define CSR_TRAININGPARAM11RSVD_MASK			BIT(11)
+#define CSR_TRAININGPARAM12RSVD_LSB			12
+#define CSR_TRAININGPARAM12RSVD_MASK			BIT(12)
+#define CSR_INCDECRATE_LSB				13
+#define CSR_INCDECRATE_MASK				GENMASK_32(15, 13)
+/* CSR_USEDQSENREPLICA */
+#define CSR_USEDQSENREPLICA_LSB				0
+#define CSR_USEDQSENREPLICA_MASK			BIT(0)
+/* CSR_RXTRAINPATTERNENABLE */
+#define CSR_RXTRAINPATTERNENABLE_LSB			0
+#define CSR_RXTRAINPATTERNENABLE_MASK			BIT(0)
+/* CSR_TSMBYTE1 */
+#define CSR_TSMBYTE1_LSB				0
+#define CSR_TSMBYTE1_MASK				GENMASK_32(15, 0)
+#define CSR_DTSMBDSTP_LSB				0
+#define CSR_DTSMBDSTP_MASK				GENMASK_32(7, 0)
+#define CSR_DTSMGDSTP_LSB				8
+#define CSR_DTSMGDSTP_MASK				GENMASK_32(15, 8)
+/* CSR_TSMBYTE2 */
+#define CSR_TSMBYTE2_LSB				0
+#define CSR_TSMBYTE2_MASK				GENMASK_32(15, 0)
+#define CSR_DTSMGDBAR_LSB				0
+#define CSR_DTSMGDBAR_MASK				GENMASK_32(15, 0)
+/* CSR_TSMBYTE3 */
+#define CSR_TSMBYTE3_LSB				0
+#define CSR_TSMBYTE3_MASK				GENMASK_32(8, 0)
+#define CSR_DTSMINCDECMODE_LSB				0
+#define CSR_DTSMINCDECMODE_MASK				BIT(0)
+#define CSR_DTSMINCDECCTRL_LSB				1
+#define CSR_DTSMINCDECCTRL_MASK				BIT(1)
+#define CSR_ENBLRXSAMPFLOPS_LSB				2
+#define CSR_ENBLRXSAMPFLOPS_MASK			BIT(2)
+#define CSR_SELRXSAMPFLOPS_LSB				3
+#define CSR_SELRXSAMPFLOPS_MASK				BIT(3)
+#define CSR_SELRXBYBASS_LSB				4
+#define CSR_SELRXBYBASS_MASK				BIT(4)
+#define CSR_DTSMIGNUPDATEACK_LSB			5
+#define CSR_DTSMIGNUPDATEACK_MASK			BIT(5)
+#define CSR_ENABLERXDQASYNC_LSB				6
+#define CSR_ENABLERXDQASYNC_MASK			BIT(6)
+#define CSR_DTSMSTATICCMPR_LSB				7
+#define CSR_DTSMSTATICCMPR_MASK				BIT(7)
+#define CSR_DTSMSTATICCMPRVAL_LSB			8
+#define CSR_DTSMSTATICCMPRVAL_MASK			BIT(8)
+/* CSR_TSMBYTE4 */
+#define CSR_TSMBYTE4_LSB				0
+#define CSR_TSMBYTE4_MASK				GENMASK_32(3, 0)
+#define CSR_DTSMINCDECPW_LSB				0
+#define CSR_DTSMINCDECPW_MASK				GENMASK_32(3, 0)
+/* CSR_TESTMODECONFIG */
+#define CSR_TESTMODECONFIG_LSB				0
+#define CSR_TESTMODECONFIG_MASK				GENMASK_32(9, 0)
+#define CSR_LOOPBACKEN_LSB				0
+#define CSR_LOOPBACKEN_MASK				BIT(0)
+#define CSR_RSVDTESTDLLEN_LSB				1
+#define CSR_RSVDTESTDLLEN_MASK				BIT(1)
+#define CSR_RSVDTWOTCKTXDQSPRE_LSB			2
+#define CSR_RSVDTWOTCKTXDQSPRE_MASK			BIT(2)
+#define CSR_TESTMODERSVD_LSB				3
+#define CSR_TESTMODERSVD_MASK				GENMASK_32(7, 3)
+#define CSR_LOOPBACKDISDQSTRI_LSB			8
+#define CSR_LOOPBACKDISDQSTRI_MASK			BIT(8)
+#define CSR_RSVDDISTXDQEQPREAMBLE_LSB			9
+#define CSR_RSVDDISTXDQEQPREAMBLE_MASK			BIT(9)
+/* CSR_TSMBYTE5 */
+#define CSR_TSMBYTE5_LSB				0
+#define CSR_TSMBYTE5_MASK				GENMASK_32(15, 0)
+#define CSR_DTSMBDBAR_LSB				0
+#define CSR_DTSMBDBAR_MASK				GENMASK_32(15, 0)
+/* MTESTMUXSEL already defined in ANIBx section */
+/* CSR_DTSMTRAINMODECTRL */
+#define CSR_DTSMTRAINMODECTRL_LSB			0
+#define CSR_DTSMTRAINMODECTRL_MASK			GENMASK_32(3, 0)
+#define CSR_DTSMSOELANEMODE_LSB				0
+#define CSR_DTSMSOELANEMODE_MASK			GENMASK_32(1, 0)
+#define CSR_DTSMBYTEERRANDMODE_LSB			2
+#define CSR_DTSMBYTEERRANDMODE_MASK			BIT(2)
+#define CSR_DTSMNIBERRMODE_LSB				3
+#define CSR_DTSMNIBERRMODE_MASK				BIT(3)
+/* CSR_DFIMRL */
+#define CSR_DFIMRL_LSB					0
+#define CSR_DFIMRL_MASK					GENMASK_32(4, 0)
+/* CSR_ASYNCDBYTEMODE */
+#define CSR_ASYNCDBYTEMODE_LSB				0
+#define CSR_ASYNCDBYTEMODE_MASK				GENMASK_32(8, 0)
+/* CSR_ASYNCDBYTETXEN */
+#define CSR_ASYNCDBYTETXEN_LSB				0
+#define CSR_ASYNCDBYTETXEN_MASK				GENMASK_32(11, 0)
+/* CSR_ASYNCDBYTETXDATA */
+#define CSR_ASYNCDBYTETXDATA_LSB			0
+#define CSR_ASYNCDBYTETXDATA_MASK			GENMASK_32(11, 0)
+/* CSR_ASYNCDBYTERXDATA */
+#define CSR_ASYNCDBYTERXDATA_LSB			0
+#define CSR_ASYNCDBYTERXDATA_MASK			GENMASK_32(11, 0)
+/* CSR_VREFDAC1 */
+#define CSR_VREFDAC1_LSB				0
+#define CSR_VREFDAC1_MASK				GENMASK_32(6, 0)
+/* CSR_TRAININGCNTR */
+#define CSR_TRAININGCNTR_LSB				0
+#define CSR_TRAININGCNTR_MASK				GENMASK_32(15, 0)
+#define CSR_TRAININGCNTRFINE_LSB			0
+#define CSR_TRAININGCNTRFINE_MASK			GENMASK_32(9, 0)
+#define CSR_TRAININGCNTRCOARSE_LSB			10
+#define CSR_TRAININGCNTRCOARSE_MASK			GENMASK_32(15, 10)
+/* CSR_VREFDAC0 */
+#define CSR_VREFDAC0_LSB				0
+#define CSR_VREFDAC0_MASK				GENMASK_32(6, 0)
+/* CSR_TXIMPEDANCECTRL0 */
+#define CSR_TXIMPEDANCECTRL0_LSB			0
+#define CSR_TXIMPEDANCECTRL0_MASK			GENMASK_32(11, 0)
+#define CSR_DRVSTRENDQP_LSB				0
+#define CSR_DRVSTRENDQP_MASK				GENMASK_32(5, 0)
+#define CSR_DRVSTRENDQN_LSB				6
+#define CSR_DRVSTRENDQN_MASK				GENMASK_32(11, 6)
+/* CSR_DQDQSRCVCNTRL */
+#define CSR_DQDQSRCVCNTRL_LSB				0
+#define CSR_DQDQSRCVCNTRL_MASK				GENMASK_32(15, 0)
+#define CSR_SELANALOGVREF_LSB				0
+#define CSR_SELANALOGVREF_MASK				BIT(0)
+#define CSR_EXTVREFRANGE_LSB				1
+#define CSR_EXTVREFRANGE_MASK				BIT(1)
+#define CSR_DFECTRL_LSB					2
+#define CSR_DFECTRL_MASK				GENMASK_32(3, 2)
+#define CSR_MAJORMODEDBYTE_LSB				4
+#define CSR_MAJORMODEDBYTE_MASK				GENMASK_32(6, 4)
+#define CSR_GAINCURRADJ_LSB				7
+#define CSR_GAINCURRADJ_MASK				GENMASK_32(11, 7)
+#define CSR_RESERVED_LSB				12
+#define CSR_RESERVED_MASK				GENMASK_32(15, 12)
+/* CSR_TXEQUALIZATIONMODE */
+#define CSR_TXEQUALIZATIONMODE_LSB			0
+#define CSR_TXEQUALIZATIONMODE_MASK			GENMASK_32(1, 0)
+#define CSR_TXEQMODE_LSB				0
+#define CSR_TXEQMODE_MASK				GENMASK_32(1, 0)
+/* CSR_TXIMPEDANCECTRL1 */
+#define CSR_TXIMPEDANCECTRL1_LSB			0
+#define CSR_TXIMPEDANCECTRL1_MASK			GENMASK_32(11, 0)
+#define CSR_DRVSTRENFSDQP_LSB				0
+#define CSR_DRVSTRENFSDQP_MASK				GENMASK_32(5, 0)
+#define CSR_DRVSTRENFSDQN_LSB				6
+#define CSR_DRVSTRENFSDQN_MASK				GENMASK_32(11, 6)
+/* CSR_DQDQSRCVCNTRL1 */
+#define CSR_DQDQSRCVCNTRL1_LSB				0
+#define CSR_DQDQSRCVCNTRL1_MASK				GENMASK_32(11, 0)
+#define CSR_POWERDOWNRCVR_LSB				0
+#define CSR_POWERDOWNRCVR_MASK				GENMASK_32(8, 0)
+#define CSR_POWERDOWNRCVRDQS_LSB			9
+#define CSR_POWERDOWNRCVRDQS_MASK			BIT(9)
+#define CSR_RXPADSTANDBYEN_LSB				10
+#define CSR_RXPADSTANDBYEN_MASK				BIT(10)
+#define CSR_ENLPREQPDR_LSB				11
+#define CSR_ENLPREQPDR_MASK				BIT(11)
+/* CSR_TXIMPEDANCECTRL2 */
+#define CSR_TXIMPEDANCECTRL2_LSB			0
+#define CSR_TXIMPEDANCECTRL2_MASK			GENMASK_32(11, 0)
+#define CSR_DRVSTRENEQHIDQP_LSB				0
+#define CSR_DRVSTRENEQHIDQP_MASK			GENMASK_32(5, 0)
+#define CSR_DRVSTRENEQLODQN_LSB				6
+#define CSR_DRVSTRENEQLODQN_MASK			GENMASK_32(11, 6)
+/* CSR_DQDQSRCVCNTRL2 */
+#define CSR_DQDQSRCVCNTRL2_LSB				0
+#define CSR_DQDQSRCVCNTRL2_MASK				BIT(0)
+#define CSR_ENRXAGRESSIVEPDR_LSB			0
+#define CSR_ENRXAGRESSIVEPDR_MASK			BIT(0)
+/* CSR_TXODTDRVSTREN */
+#define CSR_TXODTDRVSTREN_LSB				0
+#define CSR_TXODTDRVSTREN_MASK				GENMASK_32(11, 0)
+#define CSR_ODTSTRENP_LSB				0
+#define CSR_ODTSTRENP_MASK				GENMASK_32(5, 0)
+#define CSR_ODTSTRENN_LSB				6
+#define CSR_ODTSTRENN_MASK				GENMASK_32(11, 6)
+/* CSR_RXFIFOCHECKSTATUS */
+#define CSR_RXFIFOCHECKSTATUS_LSB			0
+#define CSR_RXFIFOCHECKSTATUS_MASK			GENMASK_32(1, 0)
+#define CSR_RXFIFOLOCERR_LSB				0
+#define CSR_RXFIFOLOCERR_MASK				BIT(0)
+#define CSR_RXFIFOLOCUERR_LSB				1
+#define CSR_RXFIFOLOCUERR_MASK				BIT(1)
+/* CSR_RXFIFOCHECKERRVALUES */
+#define CSR_RXFIFOCHECKERRVALUES_LSB			0
+#define CSR_RXFIFOCHECKERRVALUES_MASK			GENMASK_32(15, 0)
+#define CSR_RXFIFORDLOCERRVALUE_LSB			0
+#define CSR_RXFIFORDLOCERRVALUE_MASK			GENMASK_32(3, 0)
+#define CSR_RXFIFOWRLOCERRVALUE_LSB			4
+#define CSR_RXFIFOWRLOCERRVALUE_MASK			GENMASK_32(7, 4)
+#define CSR_RXFIFORDLOCUERRVALUE_LSB			8
+#define CSR_RXFIFORDLOCUERRVALUE_MASK			GENMASK_32(11, 8)
+#define CSR_RXFIFOWRLOCUERRVALUE_LSB			12
+#define CSR_RXFIFOWRLOCUERRVALUE_MASK			GENMASK_32(15, 12)
+/* CSR_RXFIFOINFO */
+#define CSR_RXFIFOINFO_LSB				0
+#define CSR_RXFIFOINFO_MASK				GENMASK_32(15, 0)
+#define CSR_RXFIFORDLOC_LSB				0
+#define CSR_RXFIFORDLOC_MASK				GENMASK_32(3, 0)
+#define CSR_RXFIFOWRLOC_LSB				4
+#define CSR_RXFIFOWRLOC_MASK				GENMASK_32(7, 4)
+#define CSR_RXFIFORDLOCU_LSB				8
+#define CSR_RXFIFORDLOCU_MASK				GENMASK_32(11, 8)
+#define CSR_RXFIFOWRLOCU_LSB				12
+#define CSR_RXFIFOWRLOCU_MASK				GENMASK_32(15, 12)
+/* CSR_RXFIFOVISIBILITY */
+#define CSR_RXFIFOVISIBILITY_LSB			0
+#define CSR_RXFIFOVISIBILITY_MASK			GENMASK_32(4, 0)
+#define CSR_RXFIFORDPTR_LSB				0
+#define CSR_RXFIFORDPTR_MASK				GENMASK_32(2, 0)
+#define CSR_RXFIFORDPTROVR_LSB				3
+#define CSR_RXFIFORDPTROVR_MASK				BIT(3)
+#define CSR_RXFIFORDEN_LSB				4
+#define CSR_RXFIFORDEN_MASK				BIT(4)
+/* CSR_RXFIFOCONTENTSDQ3210 */
+#define CSR_RXFIFOCONTENTSDQ3210_LSB			0
+#define CSR_RXFIFOCONTENTSDQ3210_MASK			GENMASK_32(15, 0)
+/* CSR_RXFIFOCONTENTSDQ7654 */
+#define CSR_RXFIFOCONTENTSDQ7654_LSB			0
+#define CSR_RXFIFOCONTENTSDQ7654_MASK			GENMASK_32(15, 0)
+/* CSR_RXFIFOCONTENTSDBI */
+#define CSR_RXFIFOCONTENTSDBI_LSB			0
+#define CSR_RXFIFOCONTENTSDBI_MASK			GENMASK_32(3, 0)
+/* CSR_TXSLEWRATE */
+#define CSR_TXSLEWRATE_LSB				0
+#define CSR_TXSLEWRATE_MASK				GENMASK_32(10, 0)
+#define CSR_TXPREP_LSB					0
+#define CSR_TXPREP_MASK					GENMASK_32(3, 0)
+#define CSR_TXPREN_LSB					4
+#define CSR_TXPREN_MASK					GENMASK_32(7, 4)
+#define CSR_TXPREDRVMODE_LSB				8
+#define CSR_TXPREDRVMODE_MASK				GENMASK_32(10, 8)
+/* CSR_TRAININGINCDECDTSMEN */
+#define CSR_TRAININGINCDECDTSMEN_LSB			0
+#define CSR_TRAININGINCDECDTSMEN_MASK			GENMASK_32(8, 0)
+/* CSR_RXPBDLYTG0 */
+#define CSR_RXPBDLYTG0_LSB				0
+#define CSR_RXPBDLYTG0_MASK				GENMASK_32(6, 0)
+/* CSR_RXPBDLYTG1 */
+#define CSR_RXPBDLYTG1_LSB				0
+#define CSR_RXPBDLYTG1_MASK				GENMASK_32(6, 0)
+/* CSR_RXPBDLYTG2 */
+#define CSR_RXPBDLYTG2_LSB				0
+#define CSR_RXPBDLYTG2_MASK				GENMASK_32(6, 0)
+/* CSR_RXPBDLYTG3 */
+#define CSR_RXPBDLYTG3_LSB				0
+#define CSR_RXPBDLYTG3_MASK				GENMASK_32(6, 0)
+/* CSR_RXENDLYTG0 */
+#define CSR_RXENDLYTG0_LSB				0
+#define CSR_RXENDLYTG0_MASK				GENMASK_32(10, 0)
+/* CSR_RXENDLYTG1 */
+#define CSR_RXENDLYTG1_LSB				0
+#define CSR_RXENDLYTG1_MASK				GENMASK_32(10, 0)
+/* CSR_RXENDLYTG2 */
+#define CSR_RXENDLYTG2_LSB				0
+#define CSR_RXENDLYTG2_MASK				GENMASK_32(10, 0)
+/* CSR_RXENDLYTG3 */
+#define CSR_RXENDLYTG3_LSB				0
+#define CSR_RXENDLYTG3_MASK				GENMASK_32(10, 0)
+/* CSR_RXCLKDLYTG0 */
+#define CSR_RXCLKDLYTG0_LSB				0
+#define CSR_RXCLKDLYTG0_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKDLYTG1 */
+#define CSR_RXCLKDLYTG1_LSB				0
+#define CSR_RXCLKDLYTG1_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKDLYTG2 */
+#define CSR_RXCLKDLYTG2_LSB				0
+#define CSR_RXCLKDLYTG2_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKDLYTG3 */
+#define CSR_RXCLKDLYTG3_LSB				0
+#define CSR_RXCLKDLYTG3_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKCDLYTG0 */
+#define CSR_RXCLKCDLYTG0_LSB				0
+#define CSR_RXCLKCDLYTG0_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKCDLYTG1 */
+#define CSR_RXCLKCDLYTG1_LSB				0
+#define CSR_RXCLKCDLYTG1_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKCDLYTG2 */
+#define CSR_RXCLKCDLYTG2_LSB				0
+#define CSR_RXCLKCDLYTG2_MASK				GENMASK_32(5, 0)
+/* CSR_RXCLKCDLYTG3 */
+#define CSR_RXCLKCDLYTG3_LSB				0
+#define CSR_RXCLKCDLYTG3_MASK				GENMASK_32(5, 0)
+/* CSR_DQ0LNSEL */
+#define CSR_DQ0LNSEL_LSB				0
+#define CSR_DQ0LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ1LNSEL */
+#define CSR_DQ1LNSEL_LSB				0
+#define CSR_DQ1LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ2LNSEL */
+#define CSR_DQ2LNSEL_LSB				0
+#define CSR_DQ2LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ3LNSEL */
+#define CSR_DQ3LNSEL_LSB				0
+#define CSR_DQ3LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ4LNSEL */
+#define CSR_DQ4LNSEL_LSB				0
+#define CSR_DQ4LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ5LNSEL */
+#define CSR_DQ5LNSEL_LSB				0
+#define CSR_DQ5LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ6LNSEL */
+#define CSR_DQ6LNSEL_LSB				0
+#define CSR_DQ6LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_DQ7LNSEL */
+#define CSR_DQ7LNSEL_LSB				0
+#define CSR_DQ7LNSEL_MASK				GENMASK_32(2, 0)
+/* CSR_PPTCTLSTATIC */
+#define CSR_PPTCTLSTATIC_LSB				0
+#define CSR_PPTCTLSTATIC_MASK				GENMASK_32(11, 0)
+#define CSR_PPTENDQS2DQTG0_LSB				0
+#define CSR_PPTENDQS2DQTG0_MASK				BIT(0)
+#define CSR_PPTENDQS2DQTG1_LSB				1
+#define CSR_PPTENDQS2DQTG1_MASK				BIT(1)
+#define CSR_DOCBYTESELTG0_LSB				2
+#define CSR_DOCBYTESELTG0_MASK				BIT(2)
+#define CSR_DOCBYTESELTG1_LSB				3
+#define CSR_DOCBYTESELTG1_MASK				BIT(3)
+#define CSR_PPTINFOSEL_LSB				4
+#define CSR_PPTINFOSEL_MASK				GENMASK_32(7, 4)
+#define CSR_PPTENRXENDLYTG0_LSB				8
+#define CSR_PPTENRXENDLYTG0_MASK			BIT(8)
+#define CSR_PPTENRXENDLYTG1_LSB				9
+#define CSR_PPTENRXENDLYTG1_MASK			BIT(9)
+#define CSR_PPTENRXENBACKOFF_LSB			10
+#define CSR_PPTENRXENBACKOFF_MASK			GENMASK_32(11, 10)
+/* CSR_PPTCTLDYN */
+#define CSR_PPTCTLDYN_LSB				0
+#define CSR_PPTCTLDYN_MASK				GENMASK_32(1, 0)
+#define CSR_PPTDQS2DQACTIVE_LSB				0
+#define CSR_PPTDQS2DQACTIVE_MASK			BIT(0)
+#define CSR_PPTENRXENUSEDQSSAMPVAL_LSB			1
+#define CSR_PPTENRXENUSEDQSSAMPVAL_MASK			BIT(1)
+/* CSR_PPTINFO */
+#define CSR_PPTINFO_LSB					0
+#define CSR_PPTINFO_MASK				GENMASK_32(15, 0)
+/* CSR_PPTRXENEVNT */
+#define CSR_PPTRXENEVNT_LSB				0
+#define CSR_PPTRXENEVNT_MASK				GENMASK_32(1, 0)
+#define CSR_PPTRXENINIT_LSB				0
+#define CSR_PPTRXENINIT_MASK				BIT(0)
+#define CSR_PPTRXENMHUI_LSB				1
+#define CSR_PPTRXENMHUI_MASK				BIT(1)
+/* CSR_PPTDQSCNTINVTRNTG0 */
+#define CSR_PPTDQSCNTINVTRNTG0_LSB			0
+#define CSR_PPTDQSCNTINVTRNTG0_MASK			GENMASK_32(15, 0)
+/* CSR_PPTDQSCNTINVTRNTG1 */
+#define CSR_PPTDQSCNTINVTRNTG1_LSB			0
+#define CSR_PPTDQSCNTINVTRNTG1_MASK			GENMASK_32(15, 0)
+/* CSR_DTSMBLANKINGCTRL */
+#define CSR_DTSMBLANKINGCTRL_LSB			0
+#define CSR_DTSMBLANKINGCTRL_MASK			GENMASK_32(9, 0)
+#define CSR_DTSMBLANK_LSB				0
+#define CSR_DTSMBLANK_MASK				GENMASK_32(9, 0)
+/* CSR_TSM0 */
+#define CSR_TSM0_LSB					0
+#define CSR_TSM0_MASK					GENMASK_32(13, 0)
+#define CSR_DTSMENB_LSB					0
+#define CSR_DTSMENB_MASK				BIT(0)
+#define CSR_DTSMDIR_LSB					1
+#define CSR_DTSMDIR_MASK				BIT(1)
+#define CSR_DTSMIGNFRST_LSB				2
+#define CSR_DTSMIGNFRST_MASK				BIT(2)
+#define CSR_DTSMODDPHASE_LSB				3
+#define CSR_DTSMODDPHASE_MASK				BIT(3)
+#define CSR_DTSMFLTPRE_LSB				4
+#define CSR_DTSMFLTPRE_MASK				BIT(4)
+#define CSR_DTSMFLTCUR_LSB				5
+#define CSR_DTSMFLTCUR_MASK				BIT(5)
+#define CSR_DTSMFLTNXT_LSB				6
+#define CSR_DTSMFLTNXT_MASK				BIT(6)
+#define CSR_DTSMFLTVAL_LSB				7
+#define CSR_DTSMFLTVAL_MASK				GENMASK_32(9, 7)
+#define CSR_DTSMMSKBIT_LSB				10
+#define CSR_DTSMMSKBIT_MASK				GENMASK_32(13, 10)
+/* CSR_TSM1 */
+#define CSR_TSM1_LSB					0
+#define CSR_TSM1_MASK					GENMASK_32(15, 0)
+#define CSR_DTSMERRCNT_LSB				0
+#define CSR_DTSMERRCNT_MASK				GENMASK_32(15, 0)
+/* CSR_TSM2 */
+#define CSR_TSM2_LSB					0
+#define CSR_TSM2_MASK					BIT(0)
+#define CSR_DTSMDISERRCHK_LSB				0
+#define CSR_DTSMDISERRCHK_MASK				BIT(0)
+/* CSR_TSM3 */
+#define CSR_TSM3_LSB					0
+#define CSR_TSM3_MASK					GENMASK_32(9, 0)
+#define CSR_DTSMCLRERRCNTMSK_LSB			0
+#define CSR_DTSMCLRERRCNTMSK_MASK			GENMASK_32(8, 0)
+#define CSR_DTSMCLRERRCNT_LSB				9
+#define CSR_DTSMCLRERRCNT_MASK				BIT(9)
+/* CSR_TXCHKDATASELECTS */
+#define CSR_TXCHKDATASELECTS_LSB			0
+#define CSR_TXCHKDATASELECTS_MASK			GENMASK_32(1, 0)
+#define CSR_SELCHKTOTX_LSB				0
+#define CSR_SELCHKTOTX_MASK				BIT(0)
+#define CSR_SELTXTOCHK_LSB				1
+#define CSR_SELTXTOCHK_MASK				BIT(1)
+/* CSR_DTSMUPTHLDXINGIND */
+#define CSR_DTSMUPTHLDXINGIND_LSB			0
+#define CSR_DTSMUPTHLDXINGIND_MASK			GENMASK_32(8, 0)
+/* CSR_DTSMLOTHLDXINGIND */
+#define CSR_DTSMLOTHLDXINGIND_LSB			0
+#define CSR_DTSMLOTHLDXINGIND_MASK			GENMASK_32(8, 0)
+/* CSR_DBYTEALLDTSMCTRL0 */
+#define CSR_DBYTEALLDTSMCTRL0_LSB			0
+#define CSR_DBYTEALLDTSMCTRL0_MASK			GENMASK_32(8, 0)
+#define CSR_DTSMINHIBDTSM_LSB				0
+#define CSR_DTSMINHIBDTSM_MASK				GENMASK_32(8, 0)
+/* CSR_DBYTEALLDTSMCTRL1 */
+#define CSR_DBYTEALLDTSMCTRL1_LSB			0
+#define CSR_DBYTEALLDTSMCTRL1_MASK			GENMASK_32(8, 0)
+#define CSR_DTSMGATEINC_LSB				0
+#define CSR_DTSMGATEINC_MASK				GENMASK_32(8, 0)
+/* CSR_DBYTEALLDTSMCTRL2 */
+#define CSR_DBYTEALLDTSMCTRL2_LSB			0
+#define CSR_DBYTEALLDTSMCTRL2_MASK			GENMASK_32(8, 0)
+#define CSR_DTSMGATEDEC_LSB				0
+#define CSR_DTSMGATEDEC_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQDLYTG0 */
+#define CSR_TXDQDLYTG0_LSB				0
+#define CSR_TXDQDLYTG0_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQDLYTG1 */
+#define CSR_TXDQDLYTG1_LSB				0
+#define CSR_TXDQDLYTG1_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQDLYTG2 */
+#define CSR_TXDQDLYTG2_LSB				0
+#define CSR_TXDQDLYTG2_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQDLYTG3 */
+#define CSR_TXDQDLYTG3_LSB				0
+#define CSR_TXDQDLYTG3_MASK				GENMASK_32(8, 0)
+/* CSR_TXDQSDLYTG0 */
+#define CSR_TXDQSDLYTG0_LSB				0
+#define CSR_TXDQSDLYTG0_MASK				GENMASK_32(9, 0)
+/* CSR_TXDQSDLYTG1 */
+#define CSR_TXDQSDLYTG1_LSB				0
+#define CSR_TXDQSDLYTG1_MASK				GENMASK_32(9, 0)
+/* CSR_TXDQSDLYTG2 */
+#define CSR_TXDQSDLYTG2_LSB				0
+#define CSR_TXDQSDLYTG2_MASK				GENMASK_32(9, 0)
+/* CSR_TXDQSDLYTG3 */
+#define CSR_TXDQSDLYTG3_LSB				0
+#define CSR_TXDQSDLYTG3_MASK				GENMASK_32(9, 0)
+/* CSR_DXLCDLSTATUS_ADDR */
+#define CSR_DXLCDLSTATUS_LSB				0
+#define CSR_DXLCDLSTATUS_MASK				GENMASK_32(13, 0)
+#define CSR_DXLCDLFINESNAPVAL_LSB			0
+#define CSR_DXLCDLFINESNAPVAL_MASK			GENMASK_32(9, 0)
+#define CSR_DXLCDLPHDSNAPVAL_LSB			10
+#define CSR_DXLCDLPHDSNAPVAL_MASK			BIT(10)
+#define CSR_DXLCDLSTICKYLOCK_LSB			11
+#define CSR_DXLCDLSTICKYLOCK_MASK			BIT(11)
+#define CSR_DXLCDLSTICKYUNLOCK_LSB			12
+#define CSR_DXLCDLSTICKYUNLOCK_MASK			BIT(12)
+#define CSR_DXLCDLLIVELOCK_LSB				13
+#define CSR_DXLCDLLIVELOCK_MASK				BIT(13)
+
+/* MASTER0 register offsets */
+/* CSR_RXFIFOINIT */
+#define CSR_RXFIFOINIT_LSB				0
+#define CSR_RXFIFOINIT_MASK				GENMASK_32(1, 0)
+#define CSR_RXFIFOINITPTR_LSB				0
+#define CSR_RXFIFOINITPTR_MASK				BIT(0)
+#define CSR_INHIBITRXFIFORD_LSB				1
+#define CSR_INHIBITRXFIFORD_MASK			BIT(1)
+/* CSR_FORCECLKDISABLE */
+#define CSR_FORCECLKDISABLE_LSB				0
+#define CSR_FORCECLKDISABLE_MASK			GENMASK_32(3, 0)
+/* CSR_CLOCKINGCTRL */
+#define CSR_CLOCKINGCTRL_LSB				0
+#define CSR_CLOCKINGCTRL_MASK				GENMASK_32(1, 0)
+#define CSR_PCLKENASYNCCTRL_LSB				0
+#define CSR_PCLKENASYNCCTRL_MASK			BIT(0)
+#define CSR_DLLTRACKENCTRL_LSB				1
+#define CSR_DLLTRACKENCTRL_MASK				BIT(1)
+/* CSR_FORCEINTERNALUPDATE */
+#define CSR_FORCEINTERNALUPDATE_LSB			0
+#define CSR_FORCEINTERNALUPDATE_MASK			BIT(0)
+/* CSR_PHYCONFIG */
+#define CSR_PHYCONFIG_LSB				0
+#define CSR_PHYCONFIG_MASK				GENMASK_32(9, 0)
+#define CSR_PHYCONFIGANIBS_LSB				0
+#define CSR_PHYCONFIGANIBS_MASK				GENMASK_32(3, 0)
+#define CSR_PHYCONFIGDBYTES_LSB				4
+#define CSR_PHYCONFIGDBYTES_MASK			GENMASK_32(7, 4)
+#define CSR_PHYCONFIGDFI_LSB				8
+#define CSR_PHYCONFIGDFI_MASK				GENMASK_32(9, 8)
+/* CSR_PGCR */
+#define CSR_PGCR_LSB					0
+#define CSR_PGCR_MASK					BIT(0)
+#define CSR_RXCLKRISEFALLMODE_LSB			0
+#define CSR_RXCLKRISEFALLMODE_MASK			BIT(0)
+/* CSR_TESTBUMPCNTRL1 */
+#define CSR_TESTBUMPCNTRL1_LSB				0
+#define CSR_TESTBUMPCNTRL1_MASK				GENMASK_32(15, 0)
+#define CSR_TESTMAJORMODE_LSB				0
+#define CSR_TESTMAJORMODE_MASK				GENMASK_32(2, 0)
+#define CSR_TESTBIASBYPASSEN_LSB			3
+#define CSR_TESTBIASBYPASSEN_MASK			BIT(3)
+#define CSR_TESTANALOGOUTCTRL_LSB			4
+#define CSR_TESTANALOGOUTCTRL_MASK			GENMASK_32(7, 4)
+#define CSR_TESTGAINCURRADJ_LSB				8
+#define CSR_TESTGAINCURRADJ_MASK			GENMASK_32(12, 8)
+#define CSR_TESTSELEXTERNALVREF_LSB			13
+#define CSR_TESTSELEXTERNALVREF_MASK			BIT(13)
+#define CSR_TESTEXTVREFRANGE_LSB			14
+#define CSR_TESTEXTVREFRANGE_MASK			BIT(14)
+#define CSR_TESTPOWERGATEEN_LSB				15
+#define CSR_TESTPOWERGATEEN_MASK			BIT(15)
+/* CSR_CALUCLKINFO */
+#define CSR_CALUCLKINFO_LSB				0
+#define CSR_CALUCLKINFO_MASK				GENMASK_32(10, 0)
+#define CSR_CALUCLKTICKSPER1US_LSB			0
+#define CSR_CALUCLKTICKSPER1US_MASK			GENMASK_32(10, 0)
+/* CSR_TESTBUMPCNTRL */
+#define CSR_TESTBUMPCNTRL_LSB				0
+#define CSR_TESTBUMPCNTRL_MASK				GENMASK_32(9, 0)
+#define CSR_TESTBUMPEN_LSB				0
+#define CSR_TESTBUMPEN_MASK				GENMASK_32(1, 0)
+#define CSR_TESTBUMPTOGGLE_LSB				2
+#define CSR_TESTBUMPTOGGLE_MASK				BIT(2)
+#define CSR_TESTBUMPDATASEL_LSB				3
+#define CSR_TESTBUMPDATASEL_MASK			GENMASK_32(8, 3)
+#define CSR_FORCEMTESTONALERT_LSB			9
+#define CSR_FORCEMTESTONALERT_MASK			BIT(9)
+/* CSR_SEQ0BDLY0 */
+#define CSR_SEQ0BDLY0_LSB				0
+#define CSR_SEQ0BDLY0_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BDLY1 */
+#define CSR_SEQ0BDLY1_LSB				0
+#define CSR_SEQ0BDLY1_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BDLY2 */
+#define CSR_SEQ0BDLY2_LSB				0
+#define CSR_SEQ0BDLY2_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BDLY3 */
+#define CSR_SEQ0BDLY3_LSB				0
+#define CSR_SEQ0BDLY3_MASK				GENMASK_32(15, 0)
+/* CSR_PHYALERTSTATUS */
+#define CSR_PHYALERTSTATUS_LSB				0
+#define CSR_PHYALERTSTATUS_MASK				BIT(0)
+#define CSR_PHYALERT_LSB				0
+#define CSR_PHYALERT_MASK				BIT(0)
+/* CSR_PPTTRAINSETUP */
+#define CSR_PPTTRAINSETUP_LSB				0
+#define CSR_PPTTRAINSETUP_MASK				GENMASK_32(6, 0)
+#define CSR_PHYMSTRTRAININTERVAL_LSB			0
+#define CSR_PHYMSTRTRAININTERVAL_MASK			GENMASK_32(3, 0)
+#define CSR_PHYMSTRMAXREQTOACK_LSB			4
+#define CSR_PHYMSTRMAXREQTOACK_MASK			GENMASK_32(6, 4)
+/* CSR_PPTTRAINSETUP2 */
+#define CSR_PPTTRAINSETUP2_LSB				0
+#define CSR_PPTTRAINSETUP2_MASK				GENMASK_32(2, 0)
+#define CSR_PHYMSTRFREQOVERRIDE_LSB			0
+#define CSR_PHYMSTRFREQOVERRIDE_MASK			GENMASK_32(2, 0)
+/* CSR_ATESTMODE */
+#define CSR_ATESTMODE_LSB				0
+#define CSR_ATESTMODE_MASK				GENMASK_32(4, 0)
+#define CSR_ATESTPRBSEN_LSB				0
+#define CSR_ATESTPRBSEN_MASK				BIT(0)
+#define CSR_ATESTCLKEN_LSB				1
+#define CSR_ATESTCLKEN_MASK				BIT(1)
+#define CSR_ATESTMODESEL_LSB				2
+#define CSR_ATESTMODESEL_MASK				GENMASK_32(4, 2)
+/* CSR_TXCALBINP */
+#define CSR_TXCALBINP_LSB				0
+#define CSR_TXCALBINP_MASK				GENMASK_32(4, 0)
+/* CSR_TXCALBINN */
+#define CSR_TXCALBINN_LSB				0
+#define CSR_TXCALBINN_MASK				GENMASK_32(4, 0)
+/* CSR_TXCALPOVR */
+#define CSR_TXCALPOVR_LSB				0
+#define CSR_TXCALPOVR_MASK				GENMASK_32(5, 0)
+#define CSR_TXCALBINPOVRVAL_LSB				0
+#define CSR_TXCALBINPOVRVAL_MASK			GENMASK_32(4, 0)
+#define CSR_TXCALBINPOVREN_LSB				5
+#define CSR_TXCALBINPOVREN_MASK				BIT(5)
+/* CSR_TXCALNOVR */
+#define CSR_TXCALNOVR_LSB				0
+#define CSR_TXCALNOVR_MASK				GENMASK_32(5, 0)
+#define CSR_TXCALBINNOVRVAL_LSB				0
+#define CSR_TXCALBINNOVRVAL_MASK			GENMASK_32(4, 0)
+#define CSR_TXCALBINNOVREN_LSB				5
+#define CSR_TXCALBINNOVREN_MASK				BIT(5)
+/* CSR_DFIMODE */
+#define CSR_DFIMODE_LSB					0
+#define CSR_DFIMODE_MASK				GENMASK_32(2, 0)
+#define CSR_DFI0ENABLE_LSB				0
+#define CSR_DFI0ENABLE_MASK				BIT(0)
+#define CSR_DFI1ENABLE_LSB				1
+#define CSR_DFI1ENABLE_MASK				BIT(1)
+#define CSR_DFI1OVERRIDE_LSB				2
+#define CSR_DFI1OVERRIDE_MASK				BIT(2)
+/* CSR_TRISTATEMODECA */
+#define CSR_TRISTATEMODECA_LSB				0
+#define CSR_TRISTATEMODECA_MASK				GENMASK_32(3, 0)
+#define CSR_DISDYNADRTRI_LSB				0
+#define CSR_DISDYNADRTRI_MASK				BIT(0)
+#define CSR_DDR2TMODE_LSB				1
+#define CSR_DDR2TMODE_MASK				BIT(1)
+#define CSR_CKDISVAL_LSB				2
+#define CSR_CKDISVAL_MASK				GENMASK_32(3, 2)
+/* MTESTMUXSEL already defined in ANIBx section */
+/* CSR_MTESTPGMINFO */
+#define CSR_MTESTPGMINFO_LSB				0
+#define CSR_MTESTPGMINFO_MASK				BIT(0)
+/* CSR_DYNPWRDNUP */
+#define CSR_DYNPWRDNUP_LSB				0
+#define CSR_DYNPWRDNUP_MASK				BIT(0)
+#define CSR_DYNPOWERDOWN_LSB				0
+#define CSR_DYNPOWERDOWN_MASK				BIT(0)
+/* CSR_PMIENABLE */
+#define CSR_PMIENABLE_LSB				0
+#define CSR_PMIENABLE_MASK				BIT(0)
+/* CSR_PHYTID */
+#define CSR_PHYTID_LSB					0
+#define CSR_PHYTID_MASK					GENMASK_32(15, 0)
+/* CSR_HWTMRL */
+#define CSR_HWTMRL_LSB					0
+#define CSR_HWTMRL_MASK					GENMASK_32(4, 0)
+/* CSR_DFIPHYUPD */
+#define CSR_DFIPHYUPD_LSB				0
+#define CSR_DFIPHYUPD_MASK				GENMASK_32(15, 0)
+#define CSR_DFIPHYUPDCNT_LSB				0
+#define CSR_DFIPHYUPDCNT_MASK				GENMASK_32(3, 0)
+#define CSR_DFIPHYUPDRESP_LSB				4
+#define CSR_DFIPHYUPDRESP_MASK				GENMASK_32(6, 4)
+#define CSR_DFIPHYUPDMODE_LSB				7
+#define CSR_DFIPHYUPDMODE_MASK				BIT(7)
+#define CSR_DFIPHYUPDTHRESHOLD_LSB			8
+#define CSR_DFIPHYUPDTHRESHOLD_MASK			GENMASK_32(11, 8)
+#define CSR_DFIPHYUPDINTTHRESHOLD_LSB			12
+#define CSR_DFIPHYUPDINTTHRESHOLD_MASK			GENMASK_32(15, 12)
+/* CSR_PDAMRSWRITEMODE */
+#define CSR_PDAMRSWRITEMODE_LSB				0
+#define CSR_PDAMRSWRITEMODE_MASK			BIT(0)
+/* CSR_DFIGEARDOWNCTL */
+#define CSR_DFIGEARDOWNCTL_LSB				0
+#define CSR_DFIGEARDOWNCTL_MASK				GENMASK_32(1, 0)
+/* CSR_DQSPREAMBLECONTROL */
+#define CSR_DQSPREAMBLECONTROL_LSB			0
+#define CSR_DQSPREAMBLECONTROL_MASK			GENMASK_32(8, 0)
+#define CSR_TWOTCKRXDQSPRE_LSB				0
+#define CSR_TWOTCKRXDQSPRE_MASK				BIT(0)
+#define CSR_TWOTCKTXDQSPRE_LSB				1
+#define CSR_TWOTCKTXDQSPRE_MASK				BIT(1)
+#define CSR_POSITIONDFEINIT_LSB				2
+#define CSR_POSITIONDFEINIT_MASK			GENMASK_32(4, 2)
+#define CSR_LP4TGLTWOTCKTXDQSPRE_LSB			5
+#define CSR_LP4TGLTWOTCKTXDQSPRE_MASK			BIT(5)
+#define CSR_LP4POSTAMBLEEXT_LSB				6
+#define CSR_LP4POSTAMBLEEXT_MASK			BIT(6)
+#define CSR_LP4STTCPREBRIDGERXEN_LSB			7
+#define CSR_LP4STTCPREBRIDGERXEN_MASK			BIT(7)
+#define CSR_WDQSEXTENSION_LSB				8
+#define CSR_WDQSEXTENSION_MASK				BIT(8)
+/* CSR_MASTERX4CONFIG */
+#define CSR_MASTERX4CONFIG_LSB				0
+#define CSR_MASTERX4CONFIG_MASK				GENMASK_32(3, 0)
+#define CSR_X4TG_LSB					0
+#define CSR_X4TG_MASK					GENMASK_32(3, 0)
+/* CSR_WRLEVBITS */
+#define CSR_WRLEVBITS_LSB				0
+#define CSR_WRLEVBITS_MASK				GENMASK_32(7, 0)
+#define CSR_WRLEVFORDQSL_LSB				0
+#define CSR_WRLEVFORDQSL_MASK				GENMASK_32(3, 0)
+#define CSR_WRLEVFORDQSU_LSB				4
+#define CSR_WRLEVFORDQSU_MASK				GENMASK_32(7, 4)
+/* CSR_ENABLECSMULTICAST */
+#define CSR_ENABLECSMULTICAST_LSB			0
+#define CSR_ENABLECSMULTICAST_MASK			BIT(0)
+/* CSR_HWTLPCSMULTICAST */
+#define CSR_HWTLPCSMULTICAST_LSB			0
+#define CSR_HWTLPCSMULTICAST_MASK			BIT(0)
+/* CSR_ACX4ANIBDIS */
+#define CSR_ACX4ANIBDIS_LSB				0
+#define CSR_ACX4ANIBDIS_MASK				GENMASK_32(11, 0)
+/* CSR_DMIPINPRESENT */
+#define CSR_DMIPINPRESENT_LSB				0
+#define CSR_DMIPINPRESENT_MASK				BIT(0)
+#define CSR_RDDBIENABLED_LSB				0
+#define CSR_RDDBIENABLED_MASK				BIT(0)
+/* CSR_ARDPTRINITVAL */
+#define CSR_ARDPTRINITVAL_LSB				0
+#define CSR_ARDPTRINITVAL_MASK				GENMASK_32(3, 0)
+/* CSR_DB0LCDLCALPHDETOUT */
+#define CSR_DB0LCDLCALPHDETOUT_LSB			0
+#define CSR_DB0LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB1LCDLCALPHDETOUT */
+#define CSR_DB1LCDLCALPHDETOUT_LSB			0
+#define CSR_DB1LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB2LCDLCALPHDETOUT */
+#define CSR_DB2LCDLCALPHDETOUT_LSB			0
+#define CSR_DB2LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB3LCDLCALPHDETOUT */
+#define CSR_DB3LCDLCALPHDETOUT_LSB			0
+#define CSR_DB3LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB4LCDLCALPHDETOUT */
+#define CSR_DB4LCDLCALPHDETOUT_LSB			0
+#define CSR_DB4LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB5LCDLCALPHDETOUT */
+#define CSR_DB5LCDLCALPHDETOUT_LSB			0
+#define CSR_DB5LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB6LCDLCALPHDETOUT */
+#define CSR_DB6LCDLCALPHDETOUT_LSB			0
+#define CSR_DB6LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB7LCDLCALPHDETOUT */
+#define CSR_DB7LCDLCALPHDETOUT_LSB			0
+#define CSR_DB7LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB8LCDLCALPHDETOUT */
+#define CSR_DB8LCDLCALPHDETOUT_LSB			0
+#define CSR_DB8LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DB9LCDLCALPHDETOUT */
+#define CSR_DB9LCDLCALPHDETOUT_LSB			0
+#define CSR_DB9LCDLCALPHDETOUT_MASK			GENMASK_32(15, 0)
+/* CSR_DBYTEDLLMODECNTRL */
+#define CSR_DBYTEDLLMODECNTRL_LSB			1
+#define CSR_DBYTEDLLMODECNTRL_MASK			BIT(1)
+#define CSR_DLLRXPREAMBLEMODE_LSB			1
+#define CSR_DLLRXPREAMBLEMODE_MASK			BIT(1)
+/* CSR_DBYTERXENTRAIN */
+#define CSR_DBYTERXENTRAIN_LSB				0
+#define CSR_DBYTERXENTRAIN_MASK				BIT(0)
+#define CSR_RXENTRAIN_LSB				0
+#define CSR_RXENTRAIN_MASK				BIT(0)
+/* CSR_ANLCDLCALPHDETOUT */
+#define CSR_ANLCDLCALPHDETOUT_LSB			0
+#define CSR_ANLCDLCALPHDETOUT_MASK			GENMASK_32(11, 0)
+/* CSR_CALOFFSETS */
+#define CSR_CALOFFSETS_LSB				0
+#define CSR_CALOFFSETS_MASK				GENMASK_32(13, 0)
+#define CSR_CALCMPR5OFFSET_LSB				0
+#define CSR_CALCMPR5OFFSET_MASK				GENMASK_32(5, 0)
+#define CSR_CALDRVPDTHOFFSET_LSB			6
+#define CSR_CALDRVPDTHOFFSET_MASK			GENMASK_32(9, 6)
+#define CSR_CALDRVPUTHOFFSET_LSB			10
+#define CSR_CALDRVPUTHOFFSET_MASK			GENMASK_32(13, 10)
+/* CSR_SARINITVALS */
+#define CSR_SARINITVALS_LSB				0
+#define CSR_SARINITVALS_MASK				GENMASK_32(8, 0)
+#define CSR_SARINITOFFSET05_LSB				0
+#define CSR_SARINITOFFSET05_MASK			GENMASK_32(2, 0)
+#define CSR_SARINITNINT_LSB				3
+#define CSR_SARINITNINT_MASK				GENMASK_32(5, 3)
+#define CSR_SARINITPEXT_LSB				6
+#define CSR_SARINITPEXT_MASK				GENMASK_32(8, 6)
+/* CSR_CALPEXTOVR */
+#define CSR_CALPEXTOVR_LSB				0
+#define CSR_CALPEXTOVR_MASK				GENMASK_32(4, 0)
+/* CSR_CALCMPR5OVR */
+#define CSR_CALCMPR5OVR_LSB				0
+#define CSR_CALCMPR5OVR_MASK				GENMASK_32(7, 0)
+/* CSR_CALNINTOVR */
+#define CSR_CALNINTOVR_LSB				0
+#define CSR_CALNINTOVR_MASK				GENMASK_32(4, 0)
+/* CSR_CALDRVSTR0 */
+#define CSR_CALDRVSTR0_LSB				0
+#define CSR_CALDRVSTR0_MASK				GENMASK_32(7, 0)
+#define CSR_CALDRVSTRPD50_LSB				0
+#define CSR_CALDRVSTRPD50_MASK				GENMASK_32(3, 0)
+#define CSR_CALDRVSTRPU50_LSB				4
+#define CSR_CALDRVSTRPU50_MASK				GENMASK_32(7, 4)
+/* CSR_PROCODTCTL */
+#define CSR_PROCODTCTL_LSB				0
+#define CSR_PROCODTCTL_MASK				GENMASK_32(1, 0)
+#define CSR_PROCODTALWAYSOFF_LSB			0
+#define CSR_PROCODTALWAYSOFF_MASK			BIT(0)
+#define CSR_PROCODTALWAYSON_LSB				1
+#define CSR_PROCODTALWAYSON_MASK			BIT(1)
+/* CSR_PROCODTTIMECTL */
+#define CSR_PROCODTTIMECTL_LSB				0
+#define CSR_PROCODTTIMECTL_MASK				GENMASK_32(5, 0)
+#define CSR_PODTTAILWIDTH_LSB				0
+#define CSR_PODTTAILWIDTH_MASK				GENMASK_32(1, 0)
+#define CSR_PODTSTARTDELAY_LSB				2
+#define CSR_PODTSTARTDELAY_MASK				GENMASK_32(3, 2)
+#define CSR_PODTTAILWIDTHEXT_LSB			4
+#define CSR_PODTTAILWIDTHEXT_MASK			GENMASK_32(5, 4)
+/* CSR_MEMALERTCONTROL */
+#define CSR_MEMALERTCONTROL_LSB				0
+#define CSR_MEMALERTCONTROL_MASK			GENMASK_32(15, 0)
+#define CSR_MALERTVREFLEVEL_LSB				0
+#define CSR_MALERTVREFLEVEL_MASK			GENMASK_32(6, 0)
+#define CSR_MALERTVREFEXTEN_LSB				7
+#define CSR_MALERTVREFEXTEN_MASK			BIT(7)
+#define CSR_MALERTPUSTREN_LSB				8
+#define CSR_MALERTPUSTREN_MASK				GENMASK_32(11, 8)
+#define CSR_MALERTPUEN_LSB				12
+#define CSR_MALERTPUEN_MASK				BIT(12)
+#define CSR_MALERTRXEN_LSB				13
+#define CSR_MALERTRXEN_MASK				BIT(13)
+#define CSR_MALERTDISABLEVAL_LSB			14
+#define CSR_MALERTDISABLEVAL_MASK			BIT(14)
+#define CSR_MALERTFORCEERROR_LSB			15
+#define CSR_MALERTFORCEERROR_MASK			BIT(15)
+/* CSR_MEMALERTCONTROL2 */
+#define CSR_MEMALERTCONTROL2_LSB			0
+#define CSR_MEMALERTCONTROL2_MASK			BIT(0)
+#define CSR_MALERTSYNCBYPASS_LSB			0
+#define CSR_MALERTSYNCBYPASS_MASK			BIT(0)
+/* CSR_MEMRESETL */
+#define CSR_MEMRESETL_LSB				0
+#define CSR_MEMRESETL_MASK				GENMASK_32(1, 0)
+#define CSR_MEMRESETLVALUE_LSB				0
+#define CSR_MEMRESETLVALUE_MASK				BIT(0)
+#define CSR_PROTECTMEMRESET_LSB				1
+#define CSR_PROTECTMEMRESET_MASK			BIT(1)
+/* CSR_PUBMODE */
+#define CSR_PUBMODE_LSB					0
+#define CSR_PUBMODE_MASK				BIT(0)
+#define CSR_HWTMEMSRC_LSB				0
+#define CSR_HWTMEMSRC_MASK				BIT(0)
+/* CSR_MISCPHYSTATUS */
+#define CSR_MISCPHYSTATUS_LSB				0
+#define CSR_MISCPHYSTATUS_MASK				GENMASK_32(1, 0)
+#define CSR_DCTSANE_LSB					0
+#define CSR_DCTSANE_MASK				BIT(0)
+#define CSR_PORMEMRESET_LSB				1
+#define CSR_PORMEMRESET_MASK				BIT(1)
+/* CSR_CORELOOPBACKSEL */
+#define CSR_CORELOOPBACKSEL_LSB				0
+#define CSR_CORELOOPBACKSEL_MASK			BIT(0)
+/* CSR_DLLTRAINPARAM */
+#define CSR_DLLTRAINPARAM_LSB				0
+#define CSR_DLLTRAINPARAM_MASK				GENMASK_32(1, 0)
+#define CSR_EXTENDPHDTIME_LSB				0
+#define CSR_EXTENDPHDTIME_MASK				GENMASK_32(1, 0)
+/* CSR_HWTLPCSENA */
+#define CSR_HWTLPCSENA_LSB				0
+#define CSR_HWTLPCSENA_MASK				GENMASK_32(1, 0)
+/* CSR_HWTLPCSENB */
+#define CSR_HWTLPCSENB_LSB				0
+#define CSR_HWTLPCSENB_MASK				GENMASK_32(1, 0)
+/* CSR_HWTLPCSENBYPASS */
+#define CSR_HWTLPCSENBYPASS_LSB				0
+#define CSR_HWTLPCSENBYPASS_MASK			BIT(0)
+/* CSR_DFICAMODE */
+#define CSR_DFICAMODE_LSB				0
+#define CSR_DFICAMODE_MASK				GENMASK_32(3, 0)
+#define CSR_DFILP3CAMODE_LSB				0
+#define CSR_DFILP3CAMODE_MASK				BIT(0)
+#define CSR_DFID4CAMODE_LSB				1
+#define CSR_DFID4CAMODE_MASK				BIT(1)
+#define CSR_DFILP4CAMODE_LSB				2
+#define CSR_DFILP4CAMODE_MASK				BIT(2)
+#define CSR_DFID4ALTCAMODE_LSB				3
+#define CSR_DFID4ALTCAMODE_MASK				BIT(3)
+/* CSR_HWTCACTL */
+#define CSR_HWTCACTL_LSB				0
+#define CSR_HWTCACTL_MASK				BIT(0)
+#define CSR_HWTDISDYNADRTRI_LSB				0
+#define CSR_HWTDISDYNADRTRI_MASK			BIT(0)
+/* CSR_HWTCAMODE */
+#define CSR_HWTCAMODE_LSB				0
+#define CSR_HWTCAMODE_MASK				GENMASK_32(5, 0)
+#define CSR_HWTLP3CAMODE_LSB				0
+#define CSR_HWTLP3CAMODE_MASK				BIT(0)
+#define CSR_HWTD4CAMODE_LSB				1
+#define CSR_HWTD4CAMODE_MASK				BIT(1)
+#define CSR_HWTLP4CAMODE_LSB				2
+#define CSR_HWTLP4CAMODE_MASK				BIT(2)
+#define CSR_HWTD4ALTCAMODE_LSB				3
+#define CSR_HWTD4ALTCAMODE_MASK				BIT(3)
+#define CSR_HWTCSINVERT_LSB				4
+#define CSR_HWTCSINVERT_MASK				BIT(4)
+#define CSR_HWTDBIINVERT_LSB				5
+#define CSR_HWTDBIINVERT_MASK				BIT(5)
+/* CSR_DLLCONTROL */
+#define CSR_DLLCONTROL_LSB				0
+#define CSR_DLLCONTROL_MASK				GENMASK_32(2, 0)
+#define CSR_DLLRESETRELOCK_LSB				0
+#define CSR_DLLRESETRELOCK_MASK				BIT(0)
+#define CSR_DLLRESETSLAVE_LSB				1
+#define CSR_DLLRESETSLAVE_MASK				BIT(1)
+#define CSR_DLLRESETRSVD_LSB				2
+#define CSR_DLLRESETRSVD_MASK				BIT(2)
+/* CSR_PULSEDLLUPDATEPHASE */
+#define CSR_PULSEDLLUPDATEPHASE_LSB			0
+#define CSR_PULSEDLLUPDATEPHASE_MASK			GENMASK_32(7, 0)
+#define CSR_PULSEDBYTEDLLUPDATEPHASE_LSB		0
+#define CSR_PULSEDBYTEDLLUPDATEPHASE_MASK		BIT(0)
+#define CSR_PULSEACKDLLUPDATEPHASE_LSB			1
+#define CSR_PULSEACKDLLUPDATEPHASE_MASK			BIT(1)
+#define CSR_PULSEACADLLUPDATEPHASE_LSB			2
+#define CSR_PULSEACADLLUPDATEPHASE_MASK			BIT(2)
+#define CSR_UPDATEPHASEDESTRESERVED_LSB			3
+#define CSR_UPDATEPHASEDESTRESERVED_MASK		GENMASK_32(5, 3)
+#define CSR_TRAINUPDATEPHASEONLONGBUBBLE_LSB		6
+#define CSR_TRAINUPDATEPHASEONLONGBUBBLE_MASK		BIT(6)
+#define CSR_ALWAYSUPDATELCDLPHASE_LSB			7
+#define CSR_ALWAYSUPDATELCDLPHASE_MASK			BIT(7)
+/* CSR_HWTCONTROLOVR0 */
+#define CSR_HWTCONTROLOVR0_LSB				0
+#define CSR_HWTCONTROLOVR0_MASK				GENMASK_32(12, 0)
+#define CSR_HWTCS0OVR0_LSB				0
+#define CSR_HWTCS0OVR0_MASK				BIT(0)
+#define CSR_HWTCS1OVR0_LSB				1
+#define CSR_HWTCS1OVR0_MASK				BIT(1)
+#define CSR_HWTCS2OVR0_LSB				2
+#define CSR_HWTCS2OVR0_MASK				BIT(2)
+#define CSR_HWTCS3OVR0_LSB				3
+#define CSR_HWTCS3OVR0_MASK				BIT(3)
+#define CSR_HWTCKE0OVR0_LSB				4
+#define CSR_HWTCKE0OVR0_MASK				BIT(4)
+#define CSR_HWTCKE1OVR0_LSB				5
+#define CSR_HWTCKE1OVR0_MASK				BIT(5)
+#define CSR_HWTCKE2OVR0_LSB				6
+#define CSR_HWTCKE2OVR0_MASK				BIT(6)
+#define CSR_HWTCKE3OVR0_LSB				7
+#define CSR_HWTCKE3OVR0_MASK				BIT(7)
+#define CSR_HWTODT0OVR0_LSB				8
+#define CSR_HWTODT0OVR0_MASK				BIT(8)
+#define CSR_HWTODT1OVR0_LSB				9
+#define CSR_HWTODT1OVR0_MASK				BIT(9)
+#define CSR_HWTODT2OVR0_LSB				10
+#define CSR_HWTODT2OVR0_MASK				BIT(10)
+#define CSR_HWTODT3OVR0_LSB				11
+#define CSR_HWTODT3OVR0_MASK				BIT(11)
+#define CSR_HWTPARITYOVR0_LSB				12
+#define CSR_HWTPARITYOVR0_MASK				BIT(12)
+/* CSR_HWTCONTROLOVR1 */
+#define CSR_HWTCONTROLOVR1_LSB				0
+#define CSR_HWTCONTROLOVR1_MASK				GENMASK_32(12, 0)
+#define CSR_HWTCS0OVR1_LSB				0
+#define CSR_HWTCS0OVR1_MASK				BIT(0)
+#define CSR_HWTCS1OVR1_LSB				1
+#define CSR_HWTCS1OVR1_MASK				BIT(1)
+#define CSR_HWTCS2OVR1_LSB				2
+#define CSR_HWTCS2OVR1_MASK				BIT(2)
+#define CSR_HWTCS3OVR1_LSB				3
+#define CSR_HWTCS3OVR1_MASK				BIT(3)
+#define CSR_HWTCKE0OVR1_LSB				4
+#define CSR_HWTCKE0OVR1_MASK				BIT(4)
+#define CSR_HWTCKE1OVR1_LSB				5
+#define CSR_HWTCKE1OVR1_MASK				BIT(5)
+#define CSR_HWTCKE2OVR1_LSB				6
+#define CSR_HWTCKE2OVR1_MASK				BIT(6)
+#define CSR_HWTCKE3OVR1_LSB				7
+#define CSR_HWTCKE3OVR1_MASK				BIT(7)
+#define CSR_HWTODT0OVR1_LSB				8
+#define CSR_HWTODT0OVR1_MASK				BIT(8)
+#define CSR_HWTODT1OVR1_LSB				9
+#define CSR_HWTODT1OVR1_MASK				BIT(9)
+#define CSR_HWTODT2OVR1_LSB				10
+#define CSR_HWTODT2OVR1_MASK				BIT(10)
+#define CSR_HWTODT3OVR1_LSB				11
+#define CSR_HWTODT3OVR1_MASK				BIT(11)
+#define CSR_HWTPARITYOVR1_LSB				12
+#define CSR_HWTPARITYOVR1_MASK				BIT(12)
+/* CSR_DLLGAINCTL */
+#define CSR_DLLGAINCTL_LSB				0
+#define CSR_DLLGAINCTL_MASK				GENMASK_32(11, 0)
+#define CSR_DLLGAINIV_LSB				0
+#define CSR_DLLGAINIV_MASK				GENMASK_32(3, 0)
+#define CSR_DLLGAINTV_LSB				4
+#define CSR_DLLGAINTV_MASK				GENMASK_32(7, 4)
+#define CSR_DLLSEEDSEL_LSB				8
+#define CSR_DLLSEEDSEL_MASK				GENMASK_32(11, 8)
+/* CSR_DLLLOCKPARAM */
+#define CSR_DLLLOCKPARAM_LSB				0
+#define CSR_DLLLOCKPARAM_MASK				GENMASK_32(12, 0)
+#define CSR_DISDLLSEEDSEL_LSB				0
+#define CSR_DISDLLSEEDSEL_MASK				BIT(0)
+#define CSR_DISDLLGAINIVSEED_LSB			1
+#define CSR_DISDLLGAINIVSEED_MASK			BIT(1)
+#define CSR_DLLLOCKPARAMSPARE_LSB			2
+#define CSR_DLLLOCKPARAMSPARE_MASK			GENMASK_32(3, 2)
+#define CSR_LCDLSEED0_LSB				4
+#define CSR_LCDLSEED0_MASK				GENMASK_32(12, 4)
+/* CSR_HWTCONTROLVAL0 */
+#define CSR_HWTCONTROLVAL0_LSB				0
+#define CSR_HWTCONTROLVAL0_MASK				GENMASK_32(12, 0)
+#define CSR_HWTCS0VAL0_LSB				0
+#define CSR_HWTCS0VAL0_MASK				BIT(0)
+#define CSR_HWTCS1VAL0_LSB				1
+#define CSR_HWTCS1VAL0_MASK				BIT(1)
+#define CSR_HWTCS2VAL0_LSB				2
+#define CSR_HWTCS2VAL0_MASK				BIT(2)
+#define CSR_HWTCS3VAL0_LSB				3
+#define CSR_HWTCS3VAL0_MASK				BIT(3)
+#define CSR_HWTCKE0VAL0_LSB				4
+#define CSR_HWTCKE0VAL0_MASK				BIT(4)
+#define CSR_HWTCKE1VAL0_LSB				5
+#define CSR_HWTCKE1VAL0_MASK				BIT(5)
+#define CSR_HWTCKE2VAL0_LSB				6
+#define CSR_HWTCKE2VAL0_MASK				BIT(6)
+#define CSR_HWTCKE3VAL0_LSB				7
+#define CSR_HWTCKE3VAL0_MASK				BIT(7)
+#define CSR_HWTODT0VAL0_LSB				8
+#define CSR_HWTODT0VAL0_MASK				BIT(8)
+#define CSR_HWTODT1VAL0_LSB				9
+#define CSR_HWTODT1VAL0_MASK				BIT(9)
+#define CSR_HWTODT2VAL0_LSB				10
+#define CSR_HWTODT2VAL0_MASK				BIT(10)
+#define CSR_HWTODT3VAL0_LSB				11
+#define CSR_HWTODT3VAL0_MASK				BIT(11)
+#define CSR_HWTPARITYVAL0_LSB				12
+#define CSR_HWTPARITYVAL0_MASK				BIT(12)
+/* CSR_HWTCONTROLVAL1 */
+#define CSR_HWTCONTROLVAL1_LSB				0
+#define CSR_HWTCONTROLVAL1_MASK				GENMASK_32(12, 0)
+#define CSR_HWTCS0VAL1_LSB				0
+#define CSR_HWTCS0VAL1_MASK				BIT(0)
+#define CSR_HWTCS1VAL1_LSB				1
+#define CSR_HWTCS1VAL1_MASK				BIT(1)
+#define CSR_HWTCS2VAL1_LSB				2
+#define CSR_HWTCS2VAL1_MASK				BIT(2)
+#define CSR_HWTCS3VAL1_LSB				3
+#define CSR_HWTCS3VAL1_MASK				BIT(3)
+#define CSR_HWTCKE0VAL1_LSB				4
+#define CSR_HWTCKE0VAL1_MASK				BIT(4)
+#define CSR_HWTCKE1VAL1_LSB				5
+#define CSR_HWTCKE1VAL1_MASK				BIT(5)
+#define CSR_HWTCKE2VAL1_LSB				6
+#define CSR_HWTCKE2VAL1_MASK				BIT(6)
+#define CSR_HWTCKE3VAL1_LSB				7
+#define CSR_HWTCKE3VAL1_MASK				BIT(7)
+#define CSR_HWTODT0VAL1_LSB				8
+#define CSR_HWTODT0VAL1_MASK				BIT(8)
+#define CSR_HWTODT1VAL1_LSB				9
+#define CSR_HWTODT1VAL1_MASK				BIT(9)
+#define CSR_HWTODT2VAL1_LSB				10
+#define CSR_HWTODT2VAL1_MASK				BIT(10)
+#define CSR_HWTODT3VAL1_LSB				11
+#define CSR_HWTODT3VAL1_MASK				BIT(11)
+#define CSR_HWTPARITYVAL1_LSB				12
+#define CSR_HWTPARITYVAL1_MASK				BIT(12)
+/* CSR_ACSMGLBLSTART */
+#define CSR_ACSMGLBLSTART_LSB				0
+#define CSR_ACSMGLBLSTART_MASK				BIT(0)
+/* CSR_ACSMGLBLSGLSTPCTRL */
+#define CSR_ACSMGLBLSGLSTPCTRL_LSB			0
+#define CSR_ACSMGLBLSGLSTPCTRL_MASK			GENMASK_32(1, 0)
+#define CSR_ACSMSGLSTPMODE_LSB				0
+#define CSR_ACSMSGLSTPMODE_MASK				BIT(0)
+#define CSR_ACSMSGLSTP_LSB				1
+#define CSR_ACSMSGLSTP_MASK				BIT(1)
+/* CSR_LCDLCALPHASE */
+#define CSR_LCDLCALPHASE_LSB				0
+#define CSR_LCDLCALPHASE_MASK				GENMASK_32(8, 0)
+/* CSR_LCDLCALCTRL */
+#define CSR_LCDLCALCTRL_LSB				0
+#define CSR_LCDLCALCTRL_MASK				GENMASK_32(6, 0)
+#define CSR_LCDLCALMODE_LSB				0
+#define CSR_LCDLCALMODE_MASK				BIT(0)
+#define CSR_LCDLCALSLOWCLKSEL_LSB			1
+#define CSR_LCDLCALSLOWCLKSEL_MASK			BIT(1)
+#define CSR_LCDLCALEN_LSB				2
+#define CSR_LCDLCALEN_MASK				BIT(2)
+#define CSR_LCDLCALPHASEUPDATE_LSB			3
+#define CSR_LCDLCALPHASEUPDATE_MASK			BIT(3)
+#define CSR_LCDLCALCLKEN_LSB				4
+#define CSR_LCDLCALCLKEN_MASK				BIT(4)
+#define CSR_LCDLCALSAMPEN_LSB				5
+#define CSR_LCDLCALSAMPEN_MASK				BIT(5)
+#define CSR_LCDLCALSLOWCLKEN_LSB			6
+#define CSR_LCDLCALSLOWCLKEN_MASK			BIT(6)
+/* CSR_CALRATE */
+#define CSR_CALRATE_LSB					0
+#define CSR_CALRATE_MASK				GENMASK_32(6, 0)
+#define CSR_CALINTERVAL_LSB				0
+#define CSR_CALINTERVAL_MASK				GENMASK_32(3, 0)
+#define CSR_CALRUN_LSB					4
+#define CSR_CALRUN_MASK					BIT(4)
+#define CSR_CALONCE_LSB					5
+#define CSR_CALONCE_MASK				BIT(5)
+#define CSR_DISABLEBACKGROUNDZQUPDATES_LSB		6
+#define CSR_DISABLEBACKGROUNDZQUPDATES_MASK		BIT(6)
+/* CSR_CALZAP */
+#define CSR_CALZAP_LSB					0
+#define CSR_CALZAP_MASK					BIT(0)
+/* CSR_PSTATE */
+#define CSR_PSTATE_LSB					0
+#define CSR_PSTATE_MASK					GENMASK_32(3, 0)
+/* CSR_CALPREDRIVEROVERRIDE */
+#define CSR_CALPREDRIVEROVERRIDE_LSB			0
+#define CSR_CALPREDRIVEROVERRIDE_MASK			GENMASK_32(7, 0)
+#define CSR_TXPREOVN_LSB				0
+#define CSR_TXPREOVN_MASK				GENMASK_32(3, 0)
+#define CSR_TXPREOVP_LSB				4
+#define CSR_TXPREOVP_MASK				GENMASK_32(7, 4)
+/* CSR_PLLOUTGATECONTROL */
+#define CSR_PLLOUTGATECONTROL_LSB			0
+#define CSR_PLLOUTGATECONTROL_MASK			GENMASK_32(1, 0)
+#define CSR_PCLKGATEEN_LSB				0
+#define CSR_PCLKGATEEN_MASK				BIT(0)
+#define CSR_RESERVED2X1_LSB				1
+#define CSR_RESERVED2X1_MASK				BIT(1)
+/* CSR_UCMEMRESETCONTROL */
+#define CSR_UCMEMRESETCONTROL_LSB			0
+#define CSR_UCMEMRESETCONTROL_MASK			BIT(0)
+#define CSR_UCDCTSANE_LSB				0
+#define CSR_UCDCTSANE_MASK				BIT(0)
+/* CSR_PORCONTROL */
+#define CSR_PORCONTROL_LSB				0
+#define CSR_PORCONTROL_MASK				BIT(0)
+#define CSR_PLLDLLLOCKDONE_LSB				0
+#define CSR_PLLDLLLOCKDONE_MASK				BIT(0)
+/* CSR_CALBUSY */
+#define CSR_CALBUSY_LSB					0
+#define CSR_CALBUSY_MASK				BIT(0)
+/* CSR_CALMISC2 */
+#define CSR_CALMISC2_LSB				0
+#define CSR_CALMISC2_MASK				GENMASK_32(15, 0)
+#define CSR_CALNUMVOTES_LSB				0
+#define CSR_CALNUMVOTES_MASK				GENMASK_32(2, 0)
+#define CSR_RESERVED10X3_LSB				3
+#define CSR_RESERVED10X3_MASK				GENMASK_32(10, 3)
+#define CSR_RESERVED11_LSB				11
+#define CSR_RESERVED11_MASK				BIT(11)
+#define CSR_CALCMPTRRESTRIM_LSB				12
+#define CSR_CALCMPTRRESTRIM_MASK			BIT(12)
+#define CSR_CALCANCELROUNDERRDIS_LSB			13
+#define CSR_CALCANCELROUNDERRDIS_MASK			BIT(13)
+#define CSR_CALSLOWCMPANA_LSB				14
+#define CSR_CALSLOWCMPANA_MASK				BIT(14)
+#define CSR_RESERVED15_LSB				15
+#define CSR_RESERVED15_MASK				BIT(15)
+/* CSR_CALMISC */
+#define CSR_CALMISC_LSB					0
+#define CSR_CALMISC_MASK				GENMASK_32(2, 0)
+#define CSR_CALCMPR5DIS_LSB				0
+#define CSR_CALCMPR5DIS_MASK				BIT(0)
+#define CSR_CALNINTDIS_LSB				1
+#define CSR_CALNINTDIS_MASK				BIT(1)
+#define CSR_CALPEXTDIS_LSB				2
+#define CSR_CALPEXTDIS_MASK				BIT(2)
+/* CSR_CALVREFS */
+#define CSR_CALVREFS_LSB				0
+#define CSR_CALVREFS_MASK				GENMASK_32(1, 0)
+/* CSR_CALCMPR5 */
+#define CSR_CALCMPR5_LSB				0
+#define CSR_CALCMPR5_MASK				GENMASK_32(7, 0)
+/* CSR_CALNINT */
+#define CSR_CALNINT_LSB					0
+#define CSR_CALNINT_MASK				GENMASK_32(4, 0)
+#define CSR_CALNINTTHB_LSB				0
+#define CSR_CALNINTTHB_MASK				GENMASK_32(4, 0)
+/* CSR_CALPEXT */
+#define CSR_CALPEXT_LSB					0
+#define CSR_CALPEXT_MASK				GENMASK_32(4, 0)
+#define CSR_CALPEXTTHB_LSB				0
+#define CSR_CALPEXTTHB_MASK				GENMASK_32(4, 0)
+/* CSR_CALCMPINVERT */
+#define CSR_CALCMPINVERT_LSB				0
+#define CSR_CALCMPINVERT_MASK				GENMASK_32(4, 0)
+#define CSR_CMPINVERTCALDAC50_LSB			0
+#define CSR_CMPINVERTCALDAC50_MASK			BIT(0)
+#define CSR_CMPINVERTCALDRVPD50_LSB			1
+#define CSR_CMPINVERTCALDRVPD50_MASK			BIT(1)
+#define CSR_CMPINVERTCALDRVPU50_LSB			2
+#define CSR_CMPINVERTCALDRVPU50_MASK			BIT(2)
+#define CSR_CMPINVERTCALODTPD_LSB			3
+#define CSR_CMPINVERTCALODTPD_MASK			BIT(3)
+#define CSR_CMPINVERTCALODTPU_LSB			4
+#define CSR_CMPINVERTCALODTPU_MASK			BIT(4)
+/* CSR_CALCMPANACNTRL */
+#define CSR_CALCMPANACNTRL_LSB				0
+#define CSR_CALCMPANACNTRL_MASK				GENMASK_32(9, 0)
+#define CSR_CMPRGAINCURRADJ_LSB				0
+#define CSR_CMPRGAINCURRADJ_MASK			GENMASK_32(7, 0)
+#define CSR_CMPRGAINRESADJ_LSB				8
+#define CSR_CMPRGAINRESADJ_MASK				BIT(8)
+#define CSR_CMPRBIASBYPASSEN_LSB			9
+#define CSR_CMPRBIASBYPASSEN_MASK			BIT(9)
+/* CSR_DFIRDDATACSDESTMAP */
+#define CSR_DFIRDDATACSDESTMAP_LSB			0
+#define CSR_DFIRDDATACSDESTMAP_MASK			GENMASK_32(7, 0)
+#define CSR_DFIRDDESTM0_LSB				0
+#define CSR_DFIRDDESTM0_MASK				GENMASK_32(1, 0)
+#define CSR_DFIRDDESTM1_LSB				2
+#define CSR_DFIRDDESTM1_MASK				GENMASK_32(3, 2)
+#define CSR_DFIRDDESTM2_LSB				4
+#define CSR_DFIRDDESTM2_MASK				GENMASK_32(5, 4)
+#define CSR_DFIRDDESTM3_LSB				6
+#define CSR_DFIRDDESTM3_MASK				GENMASK_32(7, 6)
+/* CSR_VREFINGLOBAL */
+#define CSR_VREFINGLOBAL_LSB				0
+#define CSR_VREFINGLOBAL_MASK				GENMASK_32(14, 0)
+#define CSR_GLOBALVREFINSEL_LSB				0
+#define CSR_GLOBALVREFINSEL_MASK			GENMASK_32(2, 0)
+#define CSR_GLOBALVREFINDAC_LSB				3
+#define CSR_GLOBALVREFINDAC_MASK			GENMASK_32(9, 3)
+#define CSR_GLOBALVREFINTRIM_LSB			10
+#define CSR_GLOBALVREFINTRIM_MASK			GENMASK_32(13, 10)
+#define CSR_GLOBALVREFINMODE_LSB			14
+#define CSR_GLOBALVREFINMODE_MASK			BIT(14)
+/* CSR_DFIWRDATACSDESTMAP */
+#define CSR_DFIWRDATACSDESTMAP_LSB			0
+#define CSR_DFIWRDATACSDESTMAP_MASK			GENMASK_32(7, 0)
+#define CSR_DFIWRDESTM0_LSB				0
+#define CSR_DFIWRDESTM0_MASK				GENMASK_32(1, 0)
+#define CSR_DFIWRDESTM1_LSB				2
+#define CSR_DFIWRDESTM1_MASK				GENMASK_32(3, 2)
+#define CSR_DFIWRDESTM2_LSB				4
+#define CSR_DFIWRDESTM2_MASK				GENMASK_32(5, 4)
+#define CSR_DFIWRDESTM3_LSB				6
+#define CSR_DFIWRDESTM3_MASK				GENMASK_32(7, 6)
+/* CSR_MASUPDGOODCTR */
+#define CSR_MASUPDGOODCTR_LSB				0
+#define CSR_MASUPDGOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYUPD0GOODCTR */
+#define CSR_PHYUPD0GOODCTR_LSB				0
+#define CSR_PHYUPD0GOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYUPD1GOODCTR */
+#define CSR_PHYUPD1GOODCTR_LSB				0
+#define CSR_PHYUPD1GOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_CTLUPD0GOODCTR */
+#define CSR_CTLUPD0GOODCTR_LSB				0
+#define CSR_CTLUPD0GOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_CTLUPD1GOODCTR */
+#define CSR_CTLUPD1GOODCTR_LSB				0
+#define CSR_CTLUPD1GOODCTR_MASK				GENMASK_32(15, 0)
+/* CSR_MASUPDFAILCTR */
+#define CSR_MASUPDFAILCTR_LSB				0
+#define CSR_MASUPDFAILCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYUPD0FAILCTR */
+#define CSR_PHYUPD0FAILCTR_LSB				0
+#define CSR_PHYUPD0FAILCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYUPD1FAILCTR */
+#define CSR_PHYUPD1FAILCTR_LSB				0
+#define CSR_PHYUPD1FAILCTR_MASK				GENMASK_32(15, 0)
+/* CSR_PHYPERFCTRENABLE */
+#define CSR_PHYPERFCTRENABLE_LSB			0
+#define CSR_PHYPERFCTRENABLE_MASK			GENMASK_32(7, 0)
+#define CSR_MASUPDGOODCTL_LSB				0
+#define CSR_MASUPDGOODCTL_MASK				BIT(0)
+#define CSR_PHYUPD0GOODCTL_LSB				1
+#define CSR_PHYUPD0GOODCTL_MASK				BIT(1)
+#define CSR_PHYUPD1GOODCTL_LSB				2
+#define CSR_PHYUPD1GOODCTL_MASK				BIT(2)
+#define CSR_CTLUPD0GOODCTL_LSB				3
+#define CSR_CTLUPD0GOODCTL_MASK				BIT(3)
+#define CSR_CTLUPD1GOODCTL_LSB				4
+#define CSR_CTLUPD1GOODCTL_MASK				BIT(4)
+#define CSR_MASUPDFAILCTL_LSB				5
+#define CSR_MASUPDFAILCTL_MASK				BIT(5)
+#define CSR_PHYUPD0FAILCTL_LSB				6
+#define CSR_PHYUPD0FAILCTL_MASK				BIT(6)
+#define CSR_PHYUPD1FAILCTL_LSB				7
+#define CSR_PHYUPD1FAILCTL_MASK				BIT(7)
+/* CSR_DFIWRRDDATACSCONFIG */
+#define CSR_DFIWRRDDATACSCONFIG_LSB			0
+#define CSR_DFIWRRDDATACSCONFIG_MASK			GENMASK_32(1, 0)
+#define CSR_DFIWRDATACSPOLARITY_LSB			0
+#define CSR_DFIWRDATACSPOLARITY_MASK			BIT(0)
+#define CSR_DFIRDDATACSPOLARITY_LSB			1
+#define CSR_DFIRDDATACSPOLARITY_MASK			BIT(1)
+/* CSR_PLLPWRDN */
+#define CSR_PLLPWRDN_LSB				0
+#define CSR_PLLPWRDN_MASK				BIT(0)
+/* CSR_PLLRESET */
+#define CSR_PLLRESET_LSB				0
+#define CSR_PLLRESET_MASK				BIT(0)
+/* CSR_PLLCTRL2 */
+#define CSR_PLLCTRL2_LSB				0
+#define CSR_PLLCTRL2_MASK				GENMASK_32(4, 0)
+#define CSR_PLLFREQSEL_LSB				0
+#define CSR_PLLFREQSEL_MASK				GENMASK_32(4, 0)
+/* CSR_PLLCTRL0 */
+#define CSR_PLLCTRL0_LSB				0
+#define CSR_PLLCTRL0_MASK				GENMASK_32(15, 0)
+#define CSR_PLLSTANDBY_LSB				0
+#define CSR_PLLSTANDBY_MASK				BIT(0)
+#define CSR_PLLBYPSEL_LSB				1
+#define CSR_PLLBYPSEL_MASK				BIT(1)
+#define CSR_PLLX2MODE_LSB				2
+#define CSR_PLLX2MODE_MASK				BIT(2)
+#define CSR_PLLOUTBYPEN_LSB				3
+#define CSR_PLLOUTBYPEN_MASK				BIT(3)
+#define CSR_PLLPRESET_LSB				4
+#define CSR_PLLPRESET_MASK				BIT(4)
+#define CSR_PLLBYPASSMODE_LSB				5
+#define CSR_PLLBYPASSMODE_MASK				BIT(5)
+#define CSR_PLLSELDFIFREQRATIO_LSB			6
+#define CSR_PLLSELDFIFREQRATIO_MASK			BIT(6)
+#define CSR_PLLSYNCBUSFLUSH_LSB				7
+#define CSR_PLLSYNCBUSFLUSH_MASK			BIT(7)
+#define CSR_PLLSYNCBUSBYP_LSB				8
+#define CSR_PLLSYNCBUSBYP_MASK				BIT(8)
+#define CSR_PLLRESERVED10X9_LSB				9
+#define CSR_PLLRESERVED10X9_MASK			GENMASK_32(10, 9)
+#define CSR_PLLGEARSHIFT_LSB				11
+#define CSR_PLLGEARSHIFT_MASK				BIT(11)
+#define CSR_PLLLOCKCNTSEL_LSB				12
+#define CSR_PLLLOCKCNTSEL_MASK				BIT(12)
+#define CSR_PLLLOCKPHSEL_LSB				13
+#define CSR_PLLLOCKPHSEL_MASK				GENMASK_32(14, 13)
+#define CSR_PLLSPARECTRL0_LSB				15
+#define CSR_PLLSPARECTRL0_MASK				BIT(15)
+/* CSR_PLLCTRL1 */
+#define CSR_PLLCTRL1_LSB				0
+#define CSR_PLLCTRL1_MASK				GENMASK_32(8, 0)
+#define CSR_PLLCPINTCTRL_LSB				0
+#define CSR_PLLCPINTCTRL_MASK				GENMASK_32(4, 0)
+#define CSR_PLLCPPROPCTRL_LSB				5
+#define CSR_PLLCPPROPCTRL_MASK				GENMASK_32(8, 5)
+/* CSR_PLLTST */
+#define CSR_PLLTST_LSB					0
+#define CSR_PLLTST_MASK					GENMASK_32(8, 0)
+#define CSR_PLLANATSTEN_LSB				0
+#define CSR_PLLANATSTEN_MASK				BIT(0)
+#define CSR_PLLANATSTSEL_LSB				1
+#define CSR_PLLANATSTSEL_MASK				GENMASK_32(4, 1)
+#define CSR_PLLDIGTSTSEL_LSB				5
+#define CSR_PLLDIGTSTSEL_MASK				GENMASK_32(8, 5)
+/* CSR_PLLLOCKSTATUS */
+#define CSR_PLLLOCKSTATUS_LSB				0
+#define CSR_PLLLOCKSTATUS_MASK				BIT(0)
+/* CSR_PLLTESTMODE */
+#define CSR_PLLTESTMODE_LSB				0
+#define CSR_PLLTESTMODE_MASK				GENMASK_32(15, 0)
+/* CSR_PLLCTRL3 */
+#define CSR_PLLCTRL3_LSB				0
+#define CSR_PLLCTRL3_MASK				GENMASK_32(15, 0)
+#define CSR_PLLSPARE_LSB				0
+#define CSR_PLLSPARE_MASK				GENMASK_32(3, 0)
+#define CSR_PLLMAXRANGE_LSB				4
+#define CSR_PLLMAXRANGE_MASK				GENMASK_32(8, 4)
+#define CSR_PLLDACVALIN_LSB				9
+#define CSR_PLLDACVALIN_MASK				GENMASK_32(13, 9)
+#define CSR_PLLFORCECAL_LSB				14
+#define CSR_PLLFORCECAL_MASK				BIT(14)
+#define CSR_PLLENCAL_LSB				15
+#define CSR_PLLENCAL_MASK				BIT(15)
+/* CSR_PLLCTRL4 */
+#define CSR_PLLCTRL4_LSB				0
+#define CSR_PLLCTRL4_MASK				GENMASK_32(8, 0)
+#define CSR_PLLCPINTGSCTRL_LSB				0
+#define CSR_PLLCPINTGSCTRL_MASK				GENMASK_32(4, 0)
+#define CSR_PLLCPPROPGSCTRL_LSB				5
+#define CSR_PLLCPPROPGSCTRL_MASK			GENMASK_32(8, 5)
+/* CSR_PLLENDOFCAL */
+#define CSR_PLLENDOFCAL_LSB				0
+#define CSR_PLLENDOFCAL_MASK				BIT(0)
+/* CSR_PLLSTANDBYEFF */
+#define CSR_PLLSTANDBYEFF_LSB				0
+#define CSR_PLLSTANDBYEFF_MASK				BIT(0)
+/* CSR_PLLDACVALOUT */
+#define CSR_PLLDACVALOUT_LSB				0
+#define CSR_PLLDACVALOUT_MASK				GENMASK_32(4, 0)
+/* CSR_DLYTESTSEQ */
+#define CSR_DLYTESTSEQ_LSB				0
+#define CSR_DLYTESTSEQ_MASK				GENMASK_32(5, 0)
+#define CSR_DLYTESTEN_LSB				0
+#define CSR_DLYTESTEN_MASK				BIT(0)
+#define CSR_DLYTESTCNTINIT_LSB				1
+#define CSR_DLYTESTCNTINIT_MASK				BIT(1)
+#define CSR_DLYTESTENOVERRIDE1_LSB			2
+#define CSR_DLYTESTENOVERRIDE1_MASK			BIT(2)
+#define CSR_DLYTESTENOVERRIDE2_LSB			3
+#define CSR_DLYTESTENOVERRIDE2_MASK			BIT(3)
+#define CSR_SYNCDLYMULTIPLIER_LSB			4
+#define CSR_SYNCDLYMULTIPLIER_MASK			GENMASK_32(5, 4)
+/* CSR_DLYTESTRINGSELDB */
+#define CSR_DLYTESTRINGSELDB_LSB			0
+#define CSR_DLYTESTRINGSELDB_MASK			GENMASK_32(4, 0)
+#define CSR_DLYTESTCUTDB_LSB				0
+#define CSR_DLYTESTCUTDB_MASK				GENMASK_32(4, 0)
+/* CSR_DLYTESTRINGSELAC */
+#define CSR_DLYTESTRINGSELAC_LSB			0
+#define CSR_DLYTESTRINGSELAC_MASK			GENMASK_32(4, 0)
+#define CSR_DLYTESTCUTAC_LSB				0
+#define CSR_DLYTESTCUTAC_MASK				GENMASK_32(4, 0)
+/* CSR_DLYTESTCNTDFICLKIV */
+#define CSR_DLYTESTCNTDFICLKIV_LSB			0
+#define CSR_DLYTESTCNTDFICLKIV_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTDFICLK */
+#define CSR_DLYTESTCNTDFICLK_LSB			0
+#define CSR_DLYTESTCNTDFICLK_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB0 */
+#define CSR_DLYTESTCNTRINGOSCDB0_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB0_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB1 */
+#define CSR_DLYTESTCNTRINGOSCDB1_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB1_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB2 */
+#define CSR_DLYTESTCNTRINGOSCDB2_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB2_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB3 */
+#define CSR_DLYTESTCNTRINGOSCDB3_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB3_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB4 */
+#define CSR_DLYTESTCNTRINGOSCDB4_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB4_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB5 */
+#define CSR_DLYTESTCNTRINGOSCDB5_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB5_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB6 */
+#define CSR_DLYTESTCNTRINGOSCDB6_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB6_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB7 */
+#define CSR_DLYTESTCNTRINGOSCDB7_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB7_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB8 */
+#define CSR_DLYTESTCNTRINGOSCDB8_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB8_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCDB9 */
+#define CSR_DLYTESTCNTRINGOSCDB9_LSB			0
+#define CSR_DLYTESTCNTRINGOSCDB9_MASK			GENMASK_32(15, 0)
+/* CSR_DLYTESTCNTRINGOSCAC */
+#define CSR_DLYTESTCNTRINGOSCAC_LSB			0
+#define CSR_DLYTESTCNTRINGOSCAC_MASK			GENMASK_32(15, 0)
+/* CSR_MSTLCDLDBGCNTL */
+#define CSR_MSTLCDLDBGCNTL_LSB				0
+#define CSR_MSTLCDLDBGCNTL_MASK				GENMASK_32(11, 0)
+#define CSR_MSTLCDLFINEOVRVAL_LSB			0
+#define CSR_MSTLCDLFINEOVRVAL_MASK			GENMASK_32(8, 0)
+#define CSR_MSTLCDLFINEOVR_LSB				9
+#define CSR_MSTLCDLFINEOVR_MASK				BIT(9)
+#define CSR_MSTLCDLFINESNAP_LSB				10
+#define CSR_MSTLCDLFINESNAP_MASK			BIT(10)
+#define CSR_MSTLCDLTSTENABLE_LSB			11
+#define CSR_MSTLCDLTSTENABLE_MASK			BIT(11)
+/* CSR_MSTLCDL0DBGRES */
+#define CSR_MSTLCDL0DBGRES_LSB				0
+#define CSR_MSTLCDL0DBGRES_MASK				GENMASK_32(12, 0)
+#define CSR_MSTLCDL0FINESNAPVAL_LSB			0
+#define CSR_MSTLCDL0FINESNAPVAL_MASK			GENMASK_32(8, 0)
+#define CSR_MSTLCDL0PHDSNAPVAL_LSB			9
+#define CSR_MSTLCDL0PHDSNAPVAL_MASK			BIT(9)
+#define CSR_MSTLCDL0STICKYLOCK_LSB			10
+#define CSR_MSTLCDL0STICKYLOCK_MASK			BIT(10)
+#define CSR_MSTLCDL0STICKYUNLOCK_LSB			11
+#define CSR_MSTLCDL0STICKYUNLOCK_MASK			BIT(11)
+#define CSR_MSTLCDL0LIVELOCK_LSB			12
+#define CSR_MSTLCDL0LIVELOCK_MASK			BIT(12)
+/* CSR_MSTLCDL1DBGRES */
+#define CSR_MSTLCDL1DBGRES_LSB				0
+#define CSR_MSTLCDL1DBGRES_MASK				GENMASK_32(12, 0)
+#define CSR_MSTLCDL1FINESNAPVAL_LSB			0
+#define CSR_MSTLCDL1FINESNAPVAL_MASK			GENMASK_32(8, 0)
+#define CSR_MSTLCDL1PHDSNAPVAL_LSB			9
+#define CSR_MSTLCDL1PHDSNAPVAL_MASK			BIT(9)
+#define CSR_MSTLCDL1STICKYLOCK_LSB			10
+#define CSR_MSTLCDL1STICKYLOCK_MASK			BIT(10)
+#define CSR_MSTLCDL1STICKYUNLOCK_LSB			11
+#define CSR_MSTLCDL1STICKYUNLOCK_MASK			BIT(11)
+#define CSR_MSTLCDL1LIVELOCK_LSB			12
+#define CSR_MSTLCDL1LIVELOCK_MASK			BIT(12)
+/* CSR_LCDLDBGCNTL */
+#define CSR_LCDLDBGCNTL_LSB				0
+#define CSR_LCDLDBGCNTL_MASK				GENMASK_32(15, 0)
+#define CSR_LCDLFINEOVRVAL_LSB				0
+#define CSR_LCDLFINEOVRVAL_MASK				GENMASK_32(8, 0)
+#define CSR_LCDLFINEOVR_LSB				9
+#define CSR_LCDLFINEOVR_MASK				BIT(9)
+#define CSR_LCDLFINESNAP_LSB				10
+#define CSR_LCDLFINESNAP_MASK				BIT(10)
+#define CSR_LCDLTSTENABLE_LSB				11
+#define CSR_LCDLTSTENABLE_MASK				BIT(11)
+#define CSR_LCDLSTATUSSEL_LSB				12
+#define CSR_LCDLSTATUSSEL_MASK				GENMASK_32(15, 12)
+/* CSR_ACLCDLSTATUS */
+#define CSR_ACLCDLSTATUS_LSB				0
+#define CSR_ACLCDLSTATUS_MASK				GENMASK_32(13, 0)
+#define CSR_ACLCDLFINESNAPVAL_LSB			0
+#define CSR_ACLCDLFINESNAPVAL_MASK			GENMASK_32(9, 0)
+#define CSR_ACLCDLPHDSNAPVAL_LSB			10
+#define CSR_ACLCDLPHDSNAPVAL_MASK			BIT(10)
+#define CSR_ACLCDLSTICKYLOCK_LSB			11
+#define CSR_ACLCDLSTICKYLOCK_MASK			BIT(11)
+#define CSR_ACLCDLSTICKYUNLOCK_LSB			12
+#define CSR_ACLCDLSTICKYUNLOCK_MASK			BIT(12)
+#define CSR_ACLCDLLIVELOCK_LSB				13
+#define CSR_ACLCDLLIVELOCK_MASK				BIT(13)
+/* CSR_CUSTPHYREV */
+#define CSR_CUSTPHYREV_LSB				0
+#define CSR_CUSTPHYREV_MASK				GENMASK_32(5, 0)
+/* CSR_PHYREV */
+#define CSR_PHYREV_LSB					0
+#define CSR_PHYREV_MASK					GENMASK_32(15, 0)
+#define CSR_PHYMNR_LSB					0
+#define CSR_PHYMNR_MASK					GENMASK_32(3, 0)
+#define CSR_PHYMDR_LSB					4
+#define CSR_PHYMDR_MASK					GENMASK_32(7, 4)
+#define CSR_PHYMJR_LSB					8
+#define CSR_PHYMJR_MASK					GENMASK_32(15, 8)
+/* CSR_LP3EXITSEQ0BSTARTVECTOR */
+#define CSR_LP3EXITSEQ0BSTARTVECTOR_LSB			0
+#define CSR_LP3EXITSEQ0BSTARTVECTOR_MASK		GENMASK_32(7, 0)
+#define CSR_LP3EXITSEQ0BSTARTVECPLLENABLED_LSB		0
+#define CSR_LP3EXITSEQ0BSTARTVECPLLENABLED_MASK		GENMASK_32(3, 0)
+#define CSR_LP3EXITSEQ0BSTARTVECPLLBYPASSED_LSB		4
+#define CSR_LP3EXITSEQ0BSTARTVECPLLBYPASSED_MASK	GENMASK_32(7, 4)
+/* CSR_DFIFREQXLAT0 */
+#define CSR_DFIFREQXLAT0_LSB				0
+#define CSR_DFIFREQXLAT0_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL0_LSB				0
+#define CSR_DFIFREQXLATVAL0_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL1_LSB				4
+#define CSR_DFIFREQXLATVAL1_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL2_LSB				8
+#define CSR_DFIFREQXLATVAL2_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL3_LSB				12
+#define CSR_DFIFREQXLATVAL3_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT1 */
+#define CSR_DFIFREQXLAT1_LSB				0
+#define CSR_DFIFREQXLAT1_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL4_LSB				0
+#define CSR_DFIFREQXLATVAL4_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL5_LSB				4
+#define CSR_DFIFREQXLATVAL5_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL6_LSB				8
+#define CSR_DFIFREQXLATVAL6_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL7_LSB				12
+#define CSR_DFIFREQXLATVAL7_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT2 */
+#define CSR_DFIFREQXLAT2_LSB				0
+#define CSR_DFIFREQXLAT2_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL8_LSB				0
+#define CSR_DFIFREQXLATVAL8_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL9_LSB				4
+#define CSR_DFIFREQXLATVAL9_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL10_LSB			8
+#define CSR_DFIFREQXLATVAL10_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL11_LSB			12
+#define CSR_DFIFREQXLATVAL11_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT3 */
+#define CSR_DFIFREQXLAT3_LSB				0
+#define CSR_DFIFREQXLAT3_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL12_LSB			0
+#define CSR_DFIFREQXLATVAL12_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL13_LSB			4
+#define CSR_DFIFREQXLATVAL13_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL14_LSB			8
+#define CSR_DFIFREQXLATVAL14_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL15_LSB			12
+#define CSR_DFIFREQXLATVAL15_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT4 */
+#define CSR_DFIFREQXLAT4_LSB				0
+#define CSR_DFIFREQXLAT4_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL16_LSB			0
+#define CSR_DFIFREQXLATVAL16_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL17_LSB			4
+#define CSR_DFIFREQXLATVAL17_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL18_LSB			8
+#define CSR_DFIFREQXLATVAL18_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL19_LSB			12
+#define CSR_DFIFREQXLATVAL19_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT5 */
+#define CSR_DFIFREQXLAT5_LSB				0
+#define CSR_DFIFREQXLAT5_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL20_LSB			0
+#define CSR_DFIFREQXLATVAL20_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL21_LSB			4
+#define CSR_DFIFREQXLATVAL21_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL22_LSB			8
+#define CSR_DFIFREQXLATVAL22_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL23_LSB			12
+#define CSR_DFIFREQXLATVAL23_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT6 */
+#define CSR_DFIFREQXLAT6_LSB				0
+#define CSR_DFIFREQXLAT6_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL24_LSB			0
+#define CSR_DFIFREQXLATVAL24_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL25_LSB			4
+#define CSR_DFIFREQXLATVAL25_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL26_LSB			8
+#define CSR_DFIFREQXLATVAL26_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL27_LSB			12
+#define CSR_DFIFREQXLATVAL27_MASK			GENMASK_32(15, 12)
+/* CSR_DFIFREQXLAT7 */
+#define CSR_DFIFREQXLAT7_LSB				0
+#define CSR_DFIFREQXLAT7_MASK				GENMASK_32(15, 0)
+#define CSR_DFIFREQXLATVAL28_LSB			0
+#define CSR_DFIFREQXLATVAL28_MASK			GENMASK_32(3, 0)
+#define CSR_DFIFREQXLATVAL29_LSB			4
+#define CSR_DFIFREQXLATVAL29_MASK			GENMASK_32(7, 4)
+#define CSR_DFIFREQXLATVAL30_LSB			8
+#define CSR_DFIFREQXLATVAL30_MASK			GENMASK_32(11, 8)
+#define CSR_DFIFREQXLATVAL31_LSB			12
+#define CSR_DFIFREQXLATVAL31_MASK			GENMASK_32(15, 12)
+/* CSR_TXRDPTRINIT */
+#define CSR_TXRDPTRINIT_LSB				0
+#define CSR_TXRDPTRINIT_MASK				BIT(0)
+/* CSR_DFIINITCOMPLETE */
+#define CSR_DFIINITCOMPLETE_LSB				0
+#define CSR_DFIINITCOMPLETE_MASK			BIT(0)
+/* CSR_DFIFREQRATIO */
+#define CSR_DFIFREQRATIO_LSB				0
+#define CSR_DFIFREQRATIO_MASK				GENMASK_32(1, 0)
+/* CSR_RXFIFOCHECKS */
+#define CSR_RXFIFOCHECKS_LSB				0
+#define CSR_RXFIFOCHECKS_MASK				BIT(0)
+#define CSR_DOFREQUENTRXFIFOCHECKS_LSB			0
+#define CSR_DOFREQUENTRXFIFOCHECKS_MASK			BIT(0)
+/* CSR_MTESTDTOCTRL */
+#define CSR_MTESTDTOCTRL_LSB				0
+#define CSR_MTESTDTOCTRL_MASK				BIT(0)
+#define CSR_MTESTDTOEN_LSB				0
+#define CSR_MTESTDTOEN_MASK				BIT(0)
+/* CSR_MAPCAA0TODFI */
+#define CSR_MAPCAA0TODFI_LSB				0
+#define CSR_MAPCAA0TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA1TODFI */
+#define CSR_MAPCAA1TODFI_LSB				0
+#define CSR_MAPCAA1TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA2TODFI */
+#define CSR_MAPCAA2TODFI_LSB				0
+#define CSR_MAPCAA2TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA3TODFI */
+#define CSR_MAPCAA3TODFI_LSB				0
+#define CSR_MAPCAA3TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA4TODFI */
+#define CSR_MAPCAA4TODFI_LSB				0
+#define CSR_MAPCAA4TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA5TODFI */
+#define CSR_MAPCAA5TODFI_LSB				0
+#define CSR_MAPCAA5TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA6TODFI */
+#define CSR_MAPCAA6TODFI_LSB				0
+#define CSR_MAPCAA6TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA7TODFI */
+#define CSR_MAPCAA7TODFI_LSB				0
+#define CSR_MAPCAA7TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA8TODFI */
+#define CSR_MAPCAA8TODFI_LSB				0
+#define CSR_MAPCAA8TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAA9TODFI */
+#define CSR_MAPCAA9TODFI_LSB				0
+#define CSR_MAPCAA9TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB0TODFI */
+#define CSR_MAPCAB0TODFI_LSB				0
+#define CSR_MAPCAB0TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB1TODFI */
+#define CSR_MAPCAB1TODFI_LSB				0
+#define CSR_MAPCAB1TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB2TODFI */
+#define CSR_MAPCAB2TODFI_LSB				0
+#define CSR_MAPCAB2TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB3TODFI */
+#define CSR_MAPCAB3TODFI_LSB				0
+#define CSR_MAPCAB3TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB4TODFI */
+#define CSR_MAPCAB4TODFI_LSB				0
+#define CSR_MAPCAB4TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB5TODFI */
+#define CSR_MAPCAB5TODFI_LSB				0
+#define CSR_MAPCAB5TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB6TODFI */
+#define CSR_MAPCAB6TODFI_LSB				0
+#define CSR_MAPCAB6TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB7TODFI */
+#define CSR_MAPCAB7TODFI_LSB				0
+#define CSR_MAPCAB7TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB8TODFI */
+#define CSR_MAPCAB8TODFI_LSB				0
+#define CSR_MAPCAB8TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_MAPCAB9TODFI */
+#define CSR_MAPCAB9TODFI_LSB				0
+#define CSR_MAPCAB9TODFI_MASK				GENMASK_32(3, 0)
+/* CSR_PHYINTERRUPTENABLE */
+#define CSR_PHYINTERRUPTENABLE_LSB			0
+#define CSR_PHYINTERRUPTENABLE_MASK			GENMASK_32(15, 0)
+#define CSR_PHYTRNGCMPLTEN_LSB				0
+#define CSR_PHYTRNGCMPLTEN_MASK				BIT(0)
+#define CSR_PHYINITCMPLTEN_LSB				1
+#define CSR_PHYINITCMPLTEN_MASK				BIT(1)
+#define CSR_PHYTRNGFAILEN_LSB				2
+#define CSR_PHYTRNGFAILEN_MASK				BIT(2)
+#define CSR_PHYFWRESERVEDEN_LSB				3
+#define CSR_PHYFWRESERVEDEN_MASK			GENMASK_32(7, 3)
+#define CSR_PHYVTDRIFTALARMEN_LSB			8
+#define CSR_PHYVTDRIFTALARMEN_MASK			GENMASK_32(9, 8)
+#define CSR_PHYRXFIFOCHECKEN_LSB			10
+#define CSR_PHYRXFIFOCHECKEN_MASK			BIT(10)
+#define CSR_PHYHWRESERVEDEN_LSB				11
+#define CSR_PHYHWRESERVEDEN_MASK			GENMASK_32(15, 11)
+/* CSR_PHYINTERRUPTFWCONTROL */
+#define CSR_PHYINTERRUPTFWCONTROL_LSB			0
+#define CSR_PHYINTERRUPTFWCONTROL_MASK			GENMASK_32(7, 0)
+#define CSR_PHYTRNGCMPLTFW_LSB				0
+#define CSR_PHYTRNGCMPLTFW_MASK				BIT(0)
+#define CSR_PHYINITCMPLTFW_LSB				1
+#define CSR_PHYINITCMPLTFW_MASK				BIT(1)
+#define CSR_PHYTRNGFAILFW_LSB				2
+#define CSR_PHYTRNGFAILFW_MASK				BIT(2)
+#define CSR_PHYFWRESERVEDFW_LSB				3
+#define CSR_PHYFWRESERVEDFW_MASK			GENMASK_32(7, 3)
+/* CSR_PHYINTERRUPTMASK */
+#define CSR_PHYINTERRUPTMASK_LSB			0
+#define CSR_PHYINTERRUPTMASK_MASK			GENMASK_32(15, 0)
+#define CSR_PHYTRNGCMPLTMSK_LSB				0
+#define CSR_PHYTRNGCMPLTMSK_MASK			BIT(0)
+#define CSR_PHYINITCMPLTMSK_LSB				1
+#define CSR_PHYINITCMPLTMSK_MASK			BIT(1)
+#define CSR_PHYTRNGFAILMSK_LSB				2
+#define CSR_PHYTRNGFAILMSK_MASK				BIT(2)
+#define CSR_PHYFWRESERVEDMSK_LSB			3
+#define CSR_PHYFWRESERVEDMSK_MASK			GENMASK_32(7, 3)
+#define CSR_PHYVTDRIFTALARMMSK_LSB			8
+#define CSR_PHYVTDRIFTALARMMSK_MASK			GENMASK_32(9, 8)
+#define CSR_PHYRXFIFOCHECKMSK_LSB			10
+#define CSR_PHYRXFIFOCHECKMSK_MASK			BIT(10)
+#define CSR_PHYHWRESERVEDMSK_LSB			11
+#define CSR_PHYHWRESERVEDMSK_MASK			GENMASK_32(15, 11)
+/* CSR_PHYINTERRUPTCLEAR */
+#define CSR_PHYINTERRUPTCLEAR_LSB			0
+#define CSR_PHYINTERRUPTCLEAR_MASK			GENMASK_32(15, 0)
+#define CSR_PHYTRNGCMPLTCLR_LSB				0
+#define CSR_PHYTRNGCMPLTCLR_MASK			BIT(0)
+#define CSR_PHYINITCMPLTCLR_LSB				1
+#define CSR_PHYINITCMPLTCLR_MASK			BIT(1)
+#define CSR_PHYTRNGFAILCLR_LSB				2
+#define CSR_PHYTRNGFAILCLR_MASK				BIT(2)
+#define CSR_PHYFWRESERVEDCLR_LSB			3
+#define CSR_PHYFWRESERVEDCLR_MASK			GENMASK_32(7, 3)
+#define CSR_PHYVTDRIFTALARMCLR_LSB			8
+#define CSR_PHYVTDRIFTALARMCLR_MASK			GENMASK_32(9, 8)
+#define CSR_PHYRXFIFOCHECKCLR_LSB			10
+#define CSR_PHYRXFIFOCHECKCLR_MASK			BIT(10)
+#define CSR_PHYHWRESERVEDCLR_LSB			11
+#define CSR_PHYHWRESERVEDCLR_MASK			GENMASK_32(15, 11)
+/* CSR_PHYINTERRUPTSTATUS */
+#define CSR_PHYINTERRUPTSTATUS_LSB			0
+#define CSR_PHYINTERRUPTSTATUS_MASK			GENMASK_32(15, 0)
+#define CSR_PHYTRNGCMPLT_LSB				0
+#define CSR_PHYTRNGCMPLT_MASK				BIT(0)
+#define CSR_PHYINITCMPLT_LSB				1
+#define CSR_PHYINITCMPLT_MASK				BIT(1)
+#define CSR_PHYTRNGFAIL_LSB				2
+#define CSR_PHYTRNGFAIL_MASK				BIT(2)
+#define CSR_PHYFWRESERVED_LSB				3
+#define CSR_PHYFWRESERVED_MASK				GENMASK_32(7, 3)
+#define CSR_VTDRIFTALARM_LSB				8
+#define CSR_VTDRIFTALARM_MASK				GENMASK_32(9, 8)
+#define CSR_PHYRXFIFOCHECK_LSB				10
+#define CSR_PHYRXFIFOCHECK_MASK				BIT(10)
+#define CSR_PHYHWRESERVED_LSB				11
+#define CSR_PHYHWRESERVED_MASK				GENMASK_32(15, 11)
+/* CSR_HWTSWIZZLEHWTADDRESS0 */
+#define CSR_HWTSWIZZLEHWTADDRESS0_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS0_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS1 */
+#define CSR_HWTSWIZZLEHWTADDRESS1_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS1_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS2 */
+#define CSR_HWTSWIZZLEHWTADDRESS2_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS2_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS3 */
+#define CSR_HWTSWIZZLEHWTADDRESS3_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS3_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS4 */
+#define CSR_HWTSWIZZLEHWTADDRESS4_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS4_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS5 */
+#define CSR_HWTSWIZZLEHWTADDRESS5_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS5_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS6 */
+#define CSR_HWTSWIZZLEHWTADDRESS6_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS6_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS7 */
+#define CSR_HWTSWIZZLEHWTADDRESS7_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS7_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS8 */
+#define CSR_HWTSWIZZLEHWTADDRESS8_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS8_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS9 */
+#define CSR_HWTSWIZZLEHWTADDRESS9_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS9_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS10 */
+#define CSR_HWTSWIZZLEHWTADDRESS10_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS10_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS11 */
+#define CSR_HWTSWIZZLEHWTADDRESS11_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS11_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS12 */
+#define CSR_HWTSWIZZLEHWTADDRESS12_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS12_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS13 */
+#define CSR_HWTSWIZZLEHWTADDRESS13_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS13_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS14 */
+#define CSR_HWTSWIZZLEHWTADDRESS14_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS14_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS15 */
+#define CSR_HWTSWIZZLEHWTADDRESS15_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS15_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTADDRESS17 */
+#define CSR_HWTSWIZZLEHWTADDRESS17_LSB			0
+#define CSR_HWTSWIZZLEHWTADDRESS17_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTACTN */
+#define CSR_HWTSWIZZLEHWTACTN_LSB			0
+#define CSR_HWTSWIZZLEHWTACTN_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBANK0 */
+#define CSR_HWTSWIZZLEHWTBANK0_LSB			0
+#define CSR_HWTSWIZZLEHWTBANK0_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBANK1 */
+#define CSR_HWTSWIZZLEHWTBANK1_LSB			0
+#define CSR_HWTSWIZZLEHWTBANK1_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBANK2 */
+#define CSR_HWTSWIZZLEHWTBANK2_LSB			0
+#define CSR_HWTSWIZZLEHWTBANK2_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBG0 */
+#define CSR_HWTSWIZZLEHWTBG0_LSB			0
+#define CSR_HWTSWIZZLEHWTBG0_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTBG1 */
+#define CSR_HWTSWIZZLEHWTBG1_LSB			0
+#define CSR_HWTSWIZZLEHWTBG1_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTCASN */
+#define CSR_HWTSWIZZLEHWTCASN_LSB			0
+#define CSR_HWTSWIZZLEHWTCASN_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTRASN */
+#define CSR_HWTSWIZZLEHWTRASN_LSB			0
+#define CSR_HWTSWIZZLEHWTRASN_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTWEN */
+#define CSR_HWTSWIZZLEHWTWEN_LSB			0
+#define CSR_HWTSWIZZLEHWTWEN_MASK			GENMASK_32(4, 0)
+/* CSR_HWTSWIZZLEHWTPARITYIN */
+#define CSR_HWTSWIZZLEHWTPARITYIN_LSB			0
+#define CSR_HWTSWIZZLEHWTPARITYIN_MASK			GENMASK_32(4, 0)
+/* CSR_DFIHANDSHAKEDELAYS0 */
+#define CSR_DFIHANDSHAKEDELAYS0_LSB			0
+#define CSR_DFIHANDSHAKEDELAYS0_MASK			GENMASK_32(15, 0)
+#define CSR_PHYUPDACKDELAY0_LSB				0
+#define CSR_PHYUPDACKDELAY0_MASK			GENMASK_32(3, 0)
+#define CSR_PHYUPDREQDELAY0_LSB				4
+#define CSR_PHYUPDREQDELAY0_MASK			GENMASK_32(7, 4)
+#define CSR_CTRLUPDACKDELAY0_LSB			8
+#define CSR_CTRLUPDACKDELAY0_MASK			GENMASK_32(11, 8)
+#define CSR_CTRLUPDREQDELAY0_LSB			12
+#define CSR_CTRLUPDREQDELAY0_MASK			GENMASK_32(15, 12)
+/* CSR_DFIHANDSHAKEDELAYS1 */
+#define CSR_DFIHANDSHAKEDELAYS1_LSB			0
+#define CSR_DFIHANDSHAKEDELAYS1_MASK			GENMASK_32(15, 0)
+#define CSR_PHYUPDACKDELAY1_LSB				0
+#define CSR_PHYUPDACKDELAY1_MASK			GENMASK_32(3, 0)
+#define CSR_PHYUPDREQDELAY1_LSB				4
+#define CSR_PHYUPDREQDELAY1_MASK			GENMASK_32(7, 4)
+#define CSR_CTRLUPDACKDELAY1_LSB			8
+#define CSR_CTRLUPDACKDELAY1_MASK			GENMASK_32(11, 8)
+#define CSR_CTRLUPDREQDELAY1_LSB			12
+#define CSR_CTRLUPDREQDELAY1_MASK			GENMASK_32(15, 12)
+/* CSR_REMOTEIMPCAL */
+#define CSR_REMOTEIMPCAL_LSB				0
+#define CSR_REMOTEIMPCAL_MASK				GENMASK_32(1, 0)
+#define CSR_CALIBSLAVE_LSB				0
+#define CSR_CALIBSLAVE_MASK				BIT(0)
+#define CSR_SLAVECODEUPDATED_LSB			1
+#define CSR_SLAVECODEUPDATED_MASK			BIT(1)
+/* CSR_ACLOOPBACKCTL */
+#define CSR_ACLOOPBACKCTL_LSB				0
+#define CSR_ACLOOPBACKCTL_MASK				GENMASK_32(1, 0)
+#define CSR_TERMINATION_LSB				0
+#define CSR_TERMINATION_MASK				BIT(0)
+#define CSR_NOISECANCEL_LSB				1
+#define CSR_NOISECANCEL_MASK				BIT(1)
+
+/* ACSM0 register offsets */
+/* CSR_ACSMSEQ0X0 */
+#define CSR_ACSMSEQ0X0_LSB				0
+#define CSR_ACSMSEQ0X0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY0_LSB				0
+#define CSR_ACSMMCLKDLY0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE0_LSB				8
+#define CSR_ACSMDDRWE0_MASK				BIT(8)
+#define CSR_ACSMDDRCAS0_LSB				9
+#define CSR_ACSMDDRCAS0_MASK				BIT(9)
+#define CSR_ACSMDDRRAS0_LSB				10
+#define CSR_ACSMDDRRAS0_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET0_LSB				11
+#define CSR_ACSMDDRCKESET0_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR0_LSB				12
+#define CSR_ACSMDDRCKECLR0_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD0_LSB				13
+#define CSR_ACSMSEQGATECMD0_MASK			BIT(13)
+#define CSR_ACSMSEQTERM0_LSB				14
+#define CSR_ACSMSEQTERM0_MASK				BIT(14)
+#define CSR_ACSMLP3CA30_LSB				15
+#define CSR_ACSMLP3CA30_MASK				BIT(15)
+/* CSR_ACSMSEQ0X1 */
+#define CSR_ACSMSEQ0X1_LSB				0
+#define CSR_ACSMSEQ0X1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY1_LSB				0
+#define CSR_ACSMMCLKDLY1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE1_LSB				8
+#define CSR_ACSMDDRWE1_MASK				BIT(8)
+#define CSR_ACSMDDRCAS1_LSB				9
+#define CSR_ACSMDDRCAS1_MASK				BIT(9)
+#define CSR_ACSMDDRRAS1_LSB				10
+#define CSR_ACSMDDRRAS1_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET1_LSB				11
+#define CSR_ACSMDDRCKESET1_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR1_LSB				12
+#define CSR_ACSMDDRCKECLR1_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD1_LSB				13
+#define CSR_ACSMSEQGATECMD1_MASK			BIT(13)
+#define CSR_ACSMSEQTERM1_LSB				14
+#define CSR_ACSMSEQTERM1_MASK				BIT(14)
+#define CSR_ACSMLP3CA31_LSB				15
+#define CSR_ACSMLP3CA31_MASK				BIT(15)
+/* CSR_ACSMSEQ0X2 */
+#define CSR_ACSMSEQ0X2_LSB				0
+#define CSR_ACSMSEQ0X2_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY2_LSB				0
+#define CSR_ACSMMCLKDLY2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE2_LSB				8
+#define CSR_ACSMDDRWE2_MASK				BIT(8)
+#define CSR_ACSMDDRCAS2_LSB				9
+#define CSR_ACSMDDRCAS2_MASK				BIT(9)
+#define CSR_ACSMDDRRAS2_LSB				10
+#define CSR_ACSMDDRRAS2_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET2_LSB				11
+#define CSR_ACSMDDRCKESET2_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR2_LSB				12
+#define CSR_ACSMDDRCKECLR2_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD2_LSB				13
+#define CSR_ACSMSEQGATECMD2_MASK			BIT(13)
+#define CSR_ACSMSEQTERM2_LSB				14
+#define CSR_ACSMSEQTERM2_MASK				BIT(14)
+#define CSR_ACSMLP3CA32_LSB				15
+#define CSR_ACSMLP3CA32_MASK				BIT(15)
+/* CSR_ACSMSEQ0X3 */
+#define CSR_ACSMSEQ0X3_LSB				0
+#define CSR_ACSMSEQ0X3_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY3_LSB				0
+#define CSR_ACSMMCLKDLY3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE3_LSB				8
+#define CSR_ACSMDDRWE3_MASK				BIT(8)
+#define CSR_ACSMDDRCAS3_LSB				9
+#define CSR_ACSMDDRCAS3_MASK				BIT(9)
+#define CSR_ACSMDDRRAS3_LSB				10
+#define CSR_ACSMDDRRAS3_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET3_LSB				11
+#define CSR_ACSMDDRCKESET3_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR3_LSB				12
+#define CSR_ACSMDDRCKECLR3_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD3_LSB				13
+#define CSR_ACSMSEQGATECMD3_MASK			BIT(13)
+#define CSR_ACSMSEQTERM3_LSB				14
+#define CSR_ACSMSEQTERM3_MASK				BIT(14)
+#define CSR_ACSMLP3CA33_LSB				15
+#define CSR_ACSMLP3CA33_MASK				BIT(15)
+/* CSR_ACSMSEQ0X4 */
+#define CSR_ACSMSEQ0X4_LSB				0
+#define CSR_ACSMSEQ0X4_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY4_LSB				0
+#define CSR_ACSMMCLKDLY4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE4_LSB				8
+#define CSR_ACSMDDRWE4_MASK				BIT(8)
+#define CSR_ACSMDDRCAS4_LSB				9
+#define CSR_ACSMDDRCAS4_MASK				BIT(9)
+#define CSR_ACSMDDRRAS4_LSB				10
+#define CSR_ACSMDDRRAS4_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET4_LSB				11
+#define CSR_ACSMDDRCKESET4_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR4_LSB				12
+#define CSR_ACSMDDRCKECLR4_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD4_LSB				13
+#define CSR_ACSMSEQGATECMD4_MASK			BIT(13)
+#define CSR_ACSMSEQTERM4_LSB				14
+#define CSR_ACSMSEQTERM4_MASK				BIT(14)
+#define CSR_ACSMLP3CA34_LSB				15
+#define CSR_ACSMLP3CA34_MASK				BIT(15)
+/* CSR_ACSMSEQ0X5 */
+#define CSR_ACSMSEQ0X5_LSB				0
+#define CSR_ACSMSEQ0X5_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY5_LSB				0
+#define CSR_ACSMMCLKDLY5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE5_LSB				8
+#define CSR_ACSMDDRWE5_MASK				BIT(8)
+#define CSR_ACSMDDRCAS5_LSB				9
+#define CSR_ACSMDDRCAS5_MASK				BIT(9)
+#define CSR_ACSMDDRRAS5_LSB				10
+#define CSR_ACSMDDRRAS5_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET5_LSB				11
+#define CSR_ACSMDDRCKESET5_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR5_LSB				12
+#define CSR_ACSMDDRCKECLR5_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD5_LSB				13
+#define CSR_ACSMSEQGATECMD5_MASK			BIT(13)
+#define CSR_ACSMSEQTERM5_LSB				14
+#define CSR_ACSMSEQTERM5_MASK				BIT(14)
+#define CSR_ACSMLP3CA35_LSB				15
+#define CSR_ACSMLP3CA35_MASK				BIT(15)
+/* CSR_ACSMSEQ0X6 */
+#define CSR_ACSMSEQ0X6_LSB				0
+#define CSR_ACSMSEQ0X6_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY6_LSB				0
+#define CSR_ACSMMCLKDLY6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE6_LSB				8
+#define CSR_ACSMDDRWE6_MASK				BIT(8)
+#define CSR_ACSMDDRCAS6_LSB				9
+#define CSR_ACSMDDRCAS6_MASK				BIT(9)
+#define CSR_ACSMDDRRAS6_LSB				10
+#define CSR_ACSMDDRRAS6_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET6_LSB				11
+#define CSR_ACSMDDRCKESET6_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR6_LSB				12
+#define CSR_ACSMDDRCKECLR6_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD6_LSB				13
+#define CSR_ACSMSEQGATECMD6_MASK			BIT(13)
+#define CSR_ACSMSEQTERM6_LSB				14
+#define CSR_ACSMSEQTERM6_MASK				BIT(14)
+#define CSR_ACSMLP3CA36_LSB				15
+#define CSR_ACSMLP3CA36_MASK				BIT(15)
+/* CSR_ACSMSEQ0X7 */
+#define CSR_ACSMSEQ0X7_LSB				0
+#define CSR_ACSMSEQ0X7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY7_LSB				0
+#define CSR_ACSMMCLKDLY7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE7_LSB				8
+#define CSR_ACSMDDRWE7_MASK				BIT(8)
+#define CSR_ACSMDDRCAS7_LSB				9
+#define CSR_ACSMDDRCAS7_MASK				BIT(9)
+#define CSR_ACSMDDRRAS7_LSB				10
+#define CSR_ACSMDDRRAS7_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET7_LSB				11
+#define CSR_ACSMDDRCKESET7_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR7_LSB				12
+#define CSR_ACSMDDRCKECLR7_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD7_LSB				13
+#define CSR_ACSMSEQGATECMD7_MASK			BIT(13)
+#define CSR_ACSMSEQTERM7_LSB				14
+#define CSR_ACSMSEQTERM7_MASK				BIT(14)
+#define CSR_ACSMLP3CA37_LSB				15
+#define CSR_ACSMLP3CA37_MASK				BIT(15)
+/* CSR_ACSMSEQ0X8 */
+#define CSR_ACSMSEQ0X8_LSB				0
+#define CSR_ACSMSEQ0X8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY8_LSB				0
+#define CSR_ACSMMCLKDLY8_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE8_LSB				8
+#define CSR_ACSMDDRWE8_MASK				BIT(8)
+#define CSR_ACSMDDRCAS8_LSB				9
+#define CSR_ACSMDDRCAS8_MASK				BIT(9)
+#define CSR_ACSMDDRRAS8_LSB				10
+#define CSR_ACSMDDRRAS8_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET8_LSB				11
+#define CSR_ACSMDDRCKESET8_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR8_LSB				12
+#define CSR_ACSMDDRCKECLR8_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD8_LSB				13
+#define CSR_ACSMSEQGATECMD8_MASK			BIT(13)
+#define CSR_ACSMSEQTERM8_LSB				14
+#define CSR_ACSMSEQTERM8_MASK				BIT(14)
+#define CSR_ACSMLP3CA38_LSB				15
+#define CSR_ACSMLP3CA38_MASK				BIT(15)
+/* CSR_ACSMSEQ0X9 */
+#define CSR_ACSMSEQ0X9_LSB				0
+#define CSR_ACSMSEQ0X9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY9_LSB				0
+#define CSR_ACSMMCLKDLY9_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE9_LSB				8
+#define CSR_ACSMDDRWE9_MASK				BIT(8)
+#define CSR_ACSMDDRCAS9_LSB				9
+#define CSR_ACSMDDRCAS9_MASK				BIT(9)
+#define CSR_ACSMDDRRAS9_LSB				10
+#define CSR_ACSMDDRRAS9_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET9_LSB				11
+#define CSR_ACSMDDRCKESET9_MASK				BIT(11)
+#define CSR_ACSMDDRCKECLR9_LSB				12
+#define CSR_ACSMDDRCKECLR9_MASK				BIT(12)
+#define CSR_ACSMSEQGATECMD9_LSB				13
+#define CSR_ACSMSEQGATECMD9_MASK			BIT(13)
+#define CSR_ACSMSEQTERM9_LSB				14
+#define CSR_ACSMSEQTERM9_MASK				BIT(14)
+#define CSR_ACSMLP3CA39_LSB				15
+#define CSR_ACSMLP3CA39_MASK				BIT(15)
+/* CSR_ACSMSEQ0X10 */
+#define CSR_ACSMSEQ0X10_LSB				0
+#define CSR_ACSMSEQ0X10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY10_LSB				0
+#define CSR_ACSMMCLKDLY10_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE10_LSB				8
+#define CSR_ACSMDDRWE10_MASK				BIT(8)
+#define CSR_ACSMDDRCAS10_LSB				9
+#define CSR_ACSMDDRCAS10_MASK				BIT(9)
+#define CSR_ACSMDDRRAS10_LSB				10
+#define CSR_ACSMDDRRAS10_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET10_LSB				11
+#define CSR_ACSMDDRCKESET10_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR10_LSB				12
+#define CSR_ACSMDDRCKECLR10_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD10_LSB			13
+#define CSR_ACSMSEQGATECMD10_MASK			BIT(13)
+#define CSR_ACSMSEQTERM10_LSB				14
+#define CSR_ACSMSEQTERM10_MASK				BIT(14)
+#define CSR_ACSMLP3CA310_LSB				15
+#define CSR_ACSMLP3CA310_MASK				BIT(15)
+/* CSR_ACSMSEQ0X11 */
+#define CSR_ACSMSEQ0X11_LSB				0
+#define CSR_ACSMSEQ0X11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY11_LSB				0
+#define CSR_ACSMMCLKDLY11_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE11_LSB				8
+#define CSR_ACSMDDRWE11_MASK				BIT(8)
+#define CSR_ACSMDDRCAS11_LSB				9
+#define CSR_ACSMDDRCAS11_MASK				BIT(9)
+#define CSR_ACSMDDRRAS11_LSB				10
+#define CSR_ACSMDDRRAS11_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET11_LSB				11
+#define CSR_ACSMDDRCKESET11_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR11_LSB				12
+#define CSR_ACSMDDRCKECLR11_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD11_LSB			13
+#define CSR_ACSMSEQGATECMD11_MASK			BIT(13)
+#define CSR_ACSMSEQTERM11_LSB				14
+#define CSR_ACSMSEQTERM11_MASK				BIT(14)
+#define CSR_ACSMLP3CA311_LSB				15
+#define CSR_ACSMLP3CA311_MASK				BIT(15)
+/* CSR_ACSMSEQ0X12 */
+#define CSR_ACSMSEQ0X12_LSB				0
+#define CSR_ACSMSEQ0X12_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY12_LSB				0
+#define CSR_ACSMMCLKDLY12_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE12_LSB				8
+#define CSR_ACSMDDRWE12_MASK				BIT(8)
+#define CSR_ACSMDDRCAS12_LSB				9
+#define CSR_ACSMDDRCAS12_MASK				BIT(9)
+#define CSR_ACSMDDRRAS12_LSB				10
+#define CSR_ACSMDDRRAS12_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET12_LSB				11
+#define CSR_ACSMDDRCKESET12_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR12_LSB				12
+#define CSR_ACSMDDRCKECLR12_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD12_LSB			13
+#define CSR_ACSMSEQGATECMD12_MASK			BIT(13)
+#define CSR_ACSMSEQTERM12_LSB				14
+#define CSR_ACSMSEQTERM12_MASK				BIT(14)
+#define CSR_ACSMLP3CA312_LSB				15
+#define CSR_ACSMLP3CA312_MASK				BIT(15)
+/* CSR_ACSMSEQ0X13 */
+#define CSR_ACSMSEQ0X13_LSB				0
+#define CSR_ACSMSEQ0X13_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY13_LSB				0
+#define CSR_ACSMMCLKDLY13_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE13_LSB				8
+#define CSR_ACSMDDRWE13_MASK				BIT(8)
+#define CSR_ACSMDDRCAS13_LSB				9
+#define CSR_ACSMDDRCAS13_MASK				BIT(9)
+#define CSR_ACSMDDRRAS13_LSB				10
+#define CSR_ACSMDDRRAS13_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET13_LSB				11
+#define CSR_ACSMDDRCKESET13_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR13_LSB				12
+#define CSR_ACSMDDRCKECLR13_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD13_LSB			13
+#define CSR_ACSMSEQGATECMD13_MASK			BIT(13)
+#define CSR_ACSMSEQTERM13_LSB				14
+#define CSR_ACSMSEQTERM13_MASK				BIT(14)
+#define CSR_ACSMLP3CA313_LSB				15
+#define CSR_ACSMLP3CA313_MASK				BIT(15)
+/* CSR_ACSMSEQ0X14 */
+#define CSR_ACSMSEQ0X14_LSB				0
+#define CSR_ACSMSEQ0X14_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY14_LSB				0
+#define CSR_ACSMMCLKDLY14_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE14_LSB				8
+#define CSR_ACSMDDRWE14_MASK				BIT(8)
+#define CSR_ACSMDDRCAS14_LSB				9
+#define CSR_ACSMDDRCAS14_MASK				BIT(9)
+#define CSR_ACSMDDRRAS14_LSB				10
+#define CSR_ACSMDDRRAS14_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET14_LSB				11
+#define CSR_ACSMDDRCKESET14_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR14_LSB				12
+#define CSR_ACSMDDRCKECLR14_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD14_LSB			13
+#define CSR_ACSMSEQGATECMD14_MASK			BIT(13)
+#define CSR_ACSMSEQTERM14_LSB				14
+#define CSR_ACSMSEQTERM14_MASK				BIT(14)
+#define CSR_ACSMLP3CA314_LSB				15
+#define CSR_ACSMLP3CA314_MASK				BIT(15)
+/* CSR_ACSMSEQ0X15 */
+#define CSR_ACSMSEQ0X15_LSB				0
+#define CSR_ACSMSEQ0X15_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY15_LSB				0
+#define CSR_ACSMMCLKDLY15_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE15_LSB				8
+#define CSR_ACSMDDRWE15_MASK				BIT(8)
+#define CSR_ACSMDDRCAS15_LSB				9
+#define CSR_ACSMDDRCAS15_MASK				BIT(9)
+#define CSR_ACSMDDRRAS15_LSB				10
+#define CSR_ACSMDDRRAS15_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET15_LSB				11
+#define CSR_ACSMDDRCKESET15_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR15_LSB				12
+#define CSR_ACSMDDRCKECLR15_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD15_LSB			13
+#define CSR_ACSMSEQGATECMD15_MASK			BIT(13)
+#define CSR_ACSMSEQTERM15_LSB				14
+#define CSR_ACSMSEQTERM15_MASK				BIT(14)
+#define CSR_ACSMLP3CA315_LSB				15
+#define CSR_ACSMLP3CA315_MASK				BIT(15)
+/* CSR_ACSMSEQ0X16 */
+#define CSR_ACSMSEQ0X16_LSB				0
+#define CSR_ACSMSEQ0X16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY16_LSB				0
+#define CSR_ACSMMCLKDLY16_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE16_LSB				8
+#define CSR_ACSMDDRWE16_MASK				BIT(8)
+#define CSR_ACSMDDRCAS16_LSB				9
+#define CSR_ACSMDDRCAS16_MASK				BIT(9)
+#define CSR_ACSMDDRRAS16_LSB				10
+#define CSR_ACSMDDRRAS16_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET16_LSB				11
+#define CSR_ACSMDDRCKESET16_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR16_LSB				12
+#define CSR_ACSMDDRCKECLR16_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD16_LSB			13
+#define CSR_ACSMSEQGATECMD16_MASK			BIT(13)
+#define CSR_ACSMSEQTERM16_LSB				14
+#define CSR_ACSMSEQTERM16_MASK				BIT(14)
+#define CSR_ACSMLP3CA316_LSB				15
+#define CSR_ACSMLP3CA316_MASK				BIT(15)
+/* CSR_ACSMSEQ0X17 */
+#define CSR_ACSMSEQ0X17_LSB				0
+#define CSR_ACSMSEQ0X17_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY17_LSB				0
+#define CSR_ACSMMCLKDLY17_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE17_LSB				8
+#define CSR_ACSMDDRWE17_MASK				BIT(8)
+#define CSR_ACSMDDRCAS17_LSB				9
+#define CSR_ACSMDDRCAS17_MASK				BIT(9)
+#define CSR_ACSMDDRRAS17_LSB				10
+#define CSR_ACSMDDRRAS17_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET17_LSB				11
+#define CSR_ACSMDDRCKESET17_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR17_LSB				12
+#define CSR_ACSMDDRCKECLR17_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD17_LSB			13
+#define CSR_ACSMSEQGATECMD17_MASK			BIT(13)
+#define CSR_ACSMSEQTERM17_LSB				14
+#define CSR_ACSMSEQTERM17_MASK				BIT(14)
+#define CSR_ACSMLP3CA317_LSB				15
+#define CSR_ACSMLP3CA317_MASK				BIT(15)
+/* CSR_ACSMSEQ0X18 */
+#define CSR_ACSMSEQ0X18_LSB				0
+#define CSR_ACSMSEQ0X18_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY18_LSB				0
+#define CSR_ACSMMCLKDLY18_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE18_LSB				8
+#define CSR_ACSMDDRWE18_MASK				BIT(8)
+#define CSR_ACSMDDRCAS18_LSB				9
+#define CSR_ACSMDDRCAS18_MASK				BIT(9)
+#define CSR_ACSMDDRRAS18_LSB				10
+#define CSR_ACSMDDRRAS18_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET18_LSB				11
+#define CSR_ACSMDDRCKESET18_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR18_LSB				12
+#define CSR_ACSMDDRCKECLR18_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD18_LSB			13
+#define CSR_ACSMSEQGATECMD18_MASK			BIT(13)
+#define CSR_ACSMSEQTERM18_LSB				14
+#define CSR_ACSMSEQTERM18_MASK				BIT(14)
+#define CSR_ACSMLP3CA318_LSB				15
+#define CSR_ACSMLP3CA318_MASK				BIT(15)
+/* CSR_ACSMSEQ0X19 */
+#define CSR_ACSMSEQ0X19_LSB				0
+#define CSR_ACSMSEQ0X19_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY19_LSB				0
+#define CSR_ACSMMCLKDLY19_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE19_LSB				8
+#define CSR_ACSMDDRWE19_MASK				BIT(8)
+#define CSR_ACSMDDRCAS19_LSB				9
+#define CSR_ACSMDDRCAS19_MASK				BIT(9)
+#define CSR_ACSMDDRRAS19_LSB				10
+#define CSR_ACSMDDRRAS19_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET19_LSB				11
+#define CSR_ACSMDDRCKESET19_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR19_LSB				12
+#define CSR_ACSMDDRCKECLR19_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD19_LSB			13
+#define CSR_ACSMSEQGATECMD19_MASK			BIT(13)
+#define CSR_ACSMSEQTERM19_LSB				14
+#define CSR_ACSMSEQTERM19_MASK				BIT(14)
+#define CSR_ACSMLP3CA319_LSB				15
+#define CSR_ACSMLP3CA319_MASK				BIT(15)
+/* CSR_ACSMSEQ0X20 */
+#define CSR_ACSMSEQ0X20_LSB				0
+#define CSR_ACSMSEQ0X20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY20_LSB				0
+#define CSR_ACSMMCLKDLY20_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE20_LSB				8
+#define CSR_ACSMDDRWE20_MASK				BIT(8)
+#define CSR_ACSMDDRCAS20_LSB				9
+#define CSR_ACSMDDRCAS20_MASK				BIT(9)
+#define CSR_ACSMDDRRAS20_LSB				10
+#define CSR_ACSMDDRRAS20_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET20_LSB				11
+#define CSR_ACSMDDRCKESET20_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR20_LSB				12
+#define CSR_ACSMDDRCKECLR20_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD20_LSB			13
+#define CSR_ACSMSEQGATECMD20_MASK			BIT(13)
+#define CSR_ACSMSEQTERM20_LSB				14
+#define CSR_ACSMSEQTERM20_MASK				BIT(14)
+#define CSR_ACSMLP3CA320_LSB				15
+#define CSR_ACSMLP3CA320_MASK				BIT(15)
+/* CSR_ACSMSEQ0X21 */
+#define CSR_ACSMSEQ0X21_LSB				0
+#define CSR_ACSMSEQ0X21_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY21_LSB				0
+#define CSR_ACSMMCLKDLY21_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE21_LSB				8
+#define CSR_ACSMDDRWE21_MASK				BIT(8)
+#define CSR_ACSMDDRCAS21_LSB				9
+#define CSR_ACSMDDRCAS21_MASK				BIT(9)
+#define CSR_ACSMDDRRAS21_LSB				10
+#define CSR_ACSMDDRRAS21_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET21_LSB				11
+#define CSR_ACSMDDRCKESET21_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR21_LSB				12
+#define CSR_ACSMDDRCKECLR21_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD21_LSB			13
+#define CSR_ACSMSEQGATECMD21_MASK			BIT(13)
+#define CSR_ACSMSEQTERM21_LSB				14
+#define CSR_ACSMSEQTERM21_MASK				BIT(14)
+#define CSR_ACSMLP3CA321_LSB				15
+#define CSR_ACSMLP3CA321_MASK				BIT(15)
+/* CSR_ACSMSEQ0X22 */
+#define CSR_ACSMSEQ0X22_LSB				0
+#define CSR_ACSMSEQ0X22_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY22_LSB				0
+#define CSR_ACSMMCLKDLY22_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE22_LSB				8
+#define CSR_ACSMDDRWE22_MASK				BIT(8)
+#define CSR_ACSMDDRCAS22_LSB				9
+#define CSR_ACSMDDRCAS22_MASK				BIT(9)
+#define CSR_ACSMDDRRAS22_LSB				10
+#define CSR_ACSMDDRRAS22_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET22_LSB				11
+#define CSR_ACSMDDRCKESET22_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR22_LSB				12
+#define CSR_ACSMDDRCKECLR22_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD22_LSB			13
+#define CSR_ACSMSEQGATECMD22_MASK			BIT(13)
+#define CSR_ACSMSEQTERM22_LSB				14
+#define CSR_ACSMSEQTERM22_MASK				BIT(14)
+#define CSR_ACSMLP3CA322_LSB				15
+#define CSR_ACSMLP3CA322_MASK				BIT(15)
+/* CSR_ACSMSEQ0X23 */
+#define CSR_ACSMSEQ0X23_LSB				0
+#define CSR_ACSMSEQ0X23_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY23_LSB				0
+#define CSR_ACSMMCLKDLY23_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE23_LSB				8
+#define CSR_ACSMDDRWE23_MASK				BIT(8)
+#define CSR_ACSMDDRCAS23_LSB				9
+#define CSR_ACSMDDRCAS23_MASK				BIT(9)
+#define CSR_ACSMDDRRAS23_LSB				10
+#define CSR_ACSMDDRRAS23_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET23_LSB				11
+#define CSR_ACSMDDRCKESET23_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR23_LSB				12
+#define CSR_ACSMDDRCKECLR23_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD23_LSB			13
+#define CSR_ACSMSEQGATECMD23_MASK			BIT(13)
+#define CSR_ACSMSEQTERM23_LSB				14
+#define CSR_ACSMSEQTERM23_MASK				BIT(14)
+#define CSR_ACSMLP3CA323_LSB				15
+#define CSR_ACSMLP3CA323_MASK				BIT(15)
+/* CSR_ACSMSEQ0X24 */
+#define CSR_ACSMSEQ0X24_LSB				0
+#define CSR_ACSMSEQ0X24_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY24_LSB				0
+#define CSR_ACSMMCLKDLY24_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE24_LSB				8
+#define CSR_ACSMDDRWE24_MASK				BIT(8)
+#define CSR_ACSMDDRCAS24_LSB				9
+#define CSR_ACSMDDRCAS24_MASK				BIT(9)
+#define CSR_ACSMDDRRAS24_LSB				10
+#define CSR_ACSMDDRRAS24_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET24_LSB				11
+#define CSR_ACSMDDRCKESET24_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR24_LSB				12
+#define CSR_ACSMDDRCKECLR24_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD24_LSB			13
+#define CSR_ACSMSEQGATECMD24_MASK			BIT(13)
+#define CSR_ACSMSEQTERM24_LSB				14
+#define CSR_ACSMSEQTERM24_MASK				BIT(14)
+#define CSR_ACSMLP3CA324_LSB				15
+#define CSR_ACSMLP3CA324_MASK				BIT(15)
+/* CSR_ACSMSEQ0X25 */
+#define CSR_ACSMSEQ0X25_LSB				0
+#define CSR_ACSMSEQ0X25_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY25_LSB				0
+#define CSR_ACSMMCLKDLY25_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE25_LSB				8
+#define CSR_ACSMDDRWE25_MASK				BIT(8)
+#define CSR_ACSMDDRCAS25_LSB				9
+#define CSR_ACSMDDRCAS25_MASK				BIT(9)
+#define CSR_ACSMDDRRAS25_LSB				10
+#define CSR_ACSMDDRRAS25_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET25_LSB				11
+#define CSR_ACSMDDRCKESET25_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR25_LSB				12
+#define CSR_ACSMDDRCKECLR25_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD25_LSB			13
+#define CSR_ACSMSEQGATECMD25_MASK			BIT(13)
+#define CSR_ACSMSEQTERM25_LSB				14
+#define CSR_ACSMSEQTERM25_MASK				BIT(14)
+#define CSR_ACSMLP3CA325_LSB				15
+#define CSR_ACSMLP3CA325_MASK				BIT(15)
+/* CSR_ACSMSEQ0X26 */
+#define CSR_ACSMSEQ0X26_LSB				0
+#define CSR_ACSMSEQ0X26_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY26_LSB				0
+#define CSR_ACSMMCLKDLY26_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE26_LSB				8
+#define CSR_ACSMDDRWE26_MASK				BIT(8)
+#define CSR_ACSMDDRCAS26_LSB				9
+#define CSR_ACSMDDRCAS26_MASK				BIT(9)
+#define CSR_ACSMDDRRAS26_LSB				10
+#define CSR_ACSMDDRRAS26_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET26_LSB				11
+#define CSR_ACSMDDRCKESET26_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR26_LSB				12
+#define CSR_ACSMDDRCKECLR26_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD26_LSB			13
+#define CSR_ACSMSEQGATECMD26_MASK			BIT(13)
+#define CSR_ACSMSEQTERM26_LSB				14
+#define CSR_ACSMSEQTERM26_MASK				BIT(14)
+#define CSR_ACSMLP3CA326_LSB				15
+#define CSR_ACSMLP3CA326_MASK				BIT(15)
+/* CSR_ACSMSEQ0X27 */
+#define CSR_ACSMSEQ0X27_LSB				0
+#define CSR_ACSMSEQ0X27_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY27_LSB				0
+#define CSR_ACSMMCLKDLY27_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE27_LSB				8
+#define CSR_ACSMDDRWE27_MASK				BIT(8)
+#define CSR_ACSMDDRCAS27_LSB				9
+#define CSR_ACSMDDRCAS27_MASK				BIT(9)
+#define CSR_ACSMDDRRAS27_LSB				10
+#define CSR_ACSMDDRRAS27_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET27_LSB				11
+#define CSR_ACSMDDRCKESET27_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR27_LSB				12
+#define CSR_ACSMDDRCKECLR27_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD27_LSB			13
+#define CSR_ACSMSEQGATECMD27_MASK			BIT(13)
+#define CSR_ACSMSEQTERM27_LSB				14
+#define CSR_ACSMSEQTERM27_MASK				BIT(14)
+#define CSR_ACSMLP3CA327_LSB				15
+#define CSR_ACSMLP3CA327_MASK				BIT(15)
+/* CSR_ACSMSEQ0X28 */
+#define CSR_ACSMSEQ0X28_LSB				0
+#define CSR_ACSMSEQ0X28_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY28_LSB				0
+#define CSR_ACSMMCLKDLY28_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE28_LSB				8
+#define CSR_ACSMDDRWE28_MASK				BIT(8)
+#define CSR_ACSMDDRCAS28_LSB				9
+#define CSR_ACSMDDRCAS28_MASK				BIT(9)
+#define CSR_ACSMDDRRAS28_LSB				10
+#define CSR_ACSMDDRRAS28_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET28_LSB				11
+#define CSR_ACSMDDRCKESET28_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR28_LSB				12
+#define CSR_ACSMDDRCKECLR28_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD28_LSB			13
+#define CSR_ACSMSEQGATECMD28_MASK			BIT(13)
+#define CSR_ACSMSEQTERM28_LSB				14
+#define CSR_ACSMSEQTERM28_MASK				BIT(14)
+#define CSR_ACSMLP3CA328_LSB				15
+#define CSR_ACSMLP3CA328_MASK				BIT(15)
+/* CSR_ACSMSEQ0X29 */
+#define CSR_ACSMSEQ0X29_LSB				0
+#define CSR_ACSMSEQ0X29_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY29_LSB				0
+#define CSR_ACSMMCLKDLY29_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE29_LSB				8
+#define CSR_ACSMDDRWE29_MASK				BIT(8)
+#define CSR_ACSMDDRCAS29_LSB				9
+#define CSR_ACSMDDRCAS29_MASK				BIT(9)
+#define CSR_ACSMDDRRAS29_LSB				10
+#define CSR_ACSMDDRRAS29_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET29_LSB				11
+#define CSR_ACSMDDRCKESET29_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR29_LSB				12
+#define CSR_ACSMDDRCKECLR29_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD29_LSB			13
+#define CSR_ACSMSEQGATECMD29_MASK			BIT(13)
+#define CSR_ACSMSEQTERM29_LSB				14
+#define CSR_ACSMSEQTERM29_MASK				BIT(14)
+#define CSR_ACSMLP3CA329_LSB				15
+#define CSR_ACSMLP3CA329_MASK				BIT(15)
+/* CSR_ACSMSEQ0X30 */
+#define CSR_ACSMSEQ0X30_LSB				0
+#define CSR_ACSMSEQ0X30_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY30_LSB				0
+#define CSR_ACSMMCLKDLY30_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE30_LSB				8
+#define CSR_ACSMDDRWE30_MASK				BIT(8)
+#define CSR_ACSMDDRCAS30_LSB				9
+#define CSR_ACSMDDRCAS30_MASK				BIT(9)
+#define CSR_ACSMDDRRAS30_LSB				10
+#define CSR_ACSMDDRRAS30_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET30_LSB				11
+#define CSR_ACSMDDRCKESET30_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR30_LSB				12
+#define CSR_ACSMDDRCKECLR30_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD30_LSB			13
+#define CSR_ACSMSEQGATECMD30_MASK			BIT(13)
+#define CSR_ACSMSEQTERM30_LSB				14
+#define CSR_ACSMSEQTERM30_MASK				BIT(14)
+#define CSR_ACSMLP3CA330_LSB				15
+#define CSR_ACSMLP3CA330_MASK				BIT(15)
+/* CSR_ACSMSEQ0X31 */
+#define CSR_ACSMSEQ0X31_LSB				0
+#define CSR_ACSMSEQ0X31_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMMCLKDLY31_LSB				0
+#define CSR_ACSMMCLKDLY31_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDDRWE31_LSB				8
+#define CSR_ACSMDDRWE31_MASK				BIT(8)
+#define CSR_ACSMDDRCAS31_LSB				9
+#define CSR_ACSMDDRCAS31_MASK				BIT(9)
+#define CSR_ACSMDDRRAS31_LSB				10
+#define CSR_ACSMDDRRAS31_MASK				BIT(10)
+#define CSR_ACSMDDRCKESET31_LSB				11
+#define CSR_ACSMDDRCKESET31_MASK			BIT(11)
+#define CSR_ACSMDDRCKECLR31_LSB				12
+#define CSR_ACSMDDRCKECLR31_MASK			BIT(12)
+#define CSR_ACSMSEQGATECMD31_LSB			13
+#define CSR_ACSMSEQGATECMD31_MASK			BIT(13)
+#define CSR_ACSMSEQTERM31_LSB				14
+#define CSR_ACSMSEQTERM31_MASK				BIT(14)
+#define CSR_ACSMLP3CA331_LSB				15
+#define CSR_ACSMLP3CA331_MASK				BIT(15)
+/* CSR_ACSMSEQ1X0 */
+#define CSR_ACSMSEQ1X0_LSB				0
+#define CSR_ACSMSEQ1X0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS0_LSB				0
+#define CSR_ACSMDDRCS0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN0_LSB				8
+#define CSR_ACSMSAVEGEN0_MASK				BIT(8)
+#define CSR_ACSMLOADCHK0_LSB				9
+#define CSR_ACSMLOADCHK0_MASK				BIT(9)
+#define CSR_ACSMNORXENB0_LSB				10
+#define CSR_ACSMNORXENB0_MASK				BIT(10)
+#define CSR_ACSMNORXVAL0_LSB				11
+#define CSR_ACSMNORXVAL0_MASK				BIT(11)
+#define CSR_ACSMDDRBNK0_LSB				12
+#define CSR_ACSMDDRBNK0_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X1 */
+#define CSR_ACSMSEQ1X1_LSB				0
+#define CSR_ACSMSEQ1X1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS1_LSB				0
+#define CSR_ACSMDDRCS1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN1_LSB				8
+#define CSR_ACSMSAVEGEN1_MASK				BIT(8)
+#define CSR_ACSMLOADCHK1_LSB				9
+#define CSR_ACSMLOADCHK1_MASK				BIT(9)
+#define CSR_ACSMNORXENB1_LSB				10
+#define CSR_ACSMNORXENB1_MASK				BIT(10)
+#define CSR_ACSMNORXVAL1_LSB				11
+#define CSR_ACSMNORXVAL1_MASK				BIT(11)
+#define CSR_ACSMDDRBNK1_LSB				12
+#define CSR_ACSMDDRBNK1_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X2 */
+#define CSR_ACSMSEQ1X2_LSB				0
+#define CSR_ACSMSEQ1X2_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS2_LSB				0
+#define CSR_ACSMDDRCS2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN2_LSB				8
+#define CSR_ACSMSAVEGEN2_MASK				BIT(8)
+#define CSR_ACSMLOADCHK2_LSB				9
+#define CSR_ACSMLOADCHK2_MASK				BIT(9)
+#define CSR_ACSMNORXENB2_LSB				10
+#define CSR_ACSMNORXENB2_MASK				BIT(10)
+#define CSR_ACSMNORXVAL2_LSB				11
+#define CSR_ACSMNORXVAL2_MASK				BIT(11)
+#define CSR_ACSMDDRBNK2_LSB				12
+#define CSR_ACSMDDRBNK2_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X3 */
+#define CSR_ACSMSEQ1X3_LSB				0
+#define CSR_ACSMSEQ1X3_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS3_LSB				0
+#define CSR_ACSMDDRCS3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN3_LSB				8
+#define CSR_ACSMSAVEGEN3_MASK				BIT(8)
+#define CSR_ACSMLOADCHK3_LSB				9
+#define CSR_ACSMLOADCHK3_MASK				BIT(9)
+#define CSR_ACSMNORXENB3_LSB				10
+#define CSR_ACSMNORXENB3_MASK				BIT(10)
+#define CSR_ACSMNORXVAL3_LSB				11
+#define CSR_ACSMNORXVAL3_MASK				BIT(11)
+#define CSR_ACSMDDRBNK3_LSB				12
+#define CSR_ACSMDDRBNK3_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X4 */
+#define CSR_ACSMSEQ1X4_LSB				0
+#define CSR_ACSMSEQ1X4_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS4_LSB				0
+#define CSR_ACSMDDRCS4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN4_LSB				8
+#define CSR_ACSMSAVEGEN4_MASK				BIT(8)
+#define CSR_ACSMLOADCHK4_LSB				9
+#define CSR_ACSMLOADCHK4_MASK				BIT(9)
+#define CSR_ACSMNORXENB4_LSB				10
+#define CSR_ACSMNORXENB4_MASK				BIT(10)
+#define CSR_ACSMNORXVAL4_LSB				11
+#define CSR_ACSMNORXVAL4_MASK				BIT(11)
+#define CSR_ACSMDDRBNK4_LSB				12
+#define CSR_ACSMDDRBNK4_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X5 */
+#define CSR_ACSMSEQ1X5_LSB				0
+#define CSR_ACSMSEQ1X5_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS5_LSB				0
+#define CSR_ACSMDDRCS5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN5_LSB				8
+#define CSR_ACSMSAVEGEN5_MASK				BIT(8)
+#define CSR_ACSMLOADCHK5_LSB				9
+#define CSR_ACSMLOADCHK5_MASK				BIT(9)
+#define CSR_ACSMNORXENB5_LSB				10
+#define CSR_ACSMNORXENB5_MASK				BIT(10)
+#define CSR_ACSMNORXVAL5_LSB				11
+#define CSR_ACSMNORXVAL5_MASK				BIT(11)
+#define CSR_ACSMDDRBNK5_LSB				12
+#define CSR_ACSMDDRBNK5_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X6 */
+#define CSR_ACSMSEQ1X6_LSB				0
+#define CSR_ACSMSEQ1X6_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS6_LSB				0
+#define CSR_ACSMDDRCS6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN6_LSB				8
+#define CSR_ACSMSAVEGEN6_MASK				BIT(8)
+#define CSR_ACSMLOADCHK6_LSB				9
+#define CSR_ACSMLOADCHK6_MASK				BIT(9)
+#define CSR_ACSMNORXENB6_LSB				10
+#define CSR_ACSMNORXENB6_MASK				BIT(10)
+#define CSR_ACSMNORXVAL6_LSB				11
+#define CSR_ACSMNORXVAL6_MASK				BIT(11)
+#define CSR_ACSMDDRBNK6_LSB				12
+#define CSR_ACSMDDRBNK6_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X7 */
+#define CSR_ACSMSEQ1X7_LSB				0
+#define CSR_ACSMSEQ1X7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS7_LSB				0
+#define CSR_ACSMDDRCS7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN7_LSB				8
+#define CSR_ACSMSAVEGEN7_MASK				BIT(8)
+#define CSR_ACSMLOADCHK7_LSB				9
+#define CSR_ACSMLOADCHK7_MASK				BIT(9)
+#define CSR_ACSMNORXENB7_LSB				10
+#define CSR_ACSMNORXENB7_MASK				BIT(10)
+#define CSR_ACSMNORXVAL7_LSB				11
+#define CSR_ACSMNORXVAL7_MASK				BIT(11)
+#define CSR_ACSMDDRBNK7_LSB				12
+#define CSR_ACSMDDRBNK7_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X8 */
+#define CSR_ACSMSEQ1X8_LSB				0
+#define CSR_ACSMSEQ1X8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS8_LSB				0
+#define CSR_ACSMDDRCS8_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN8_LSB				8
+#define CSR_ACSMSAVEGEN8_MASK				BIT(8)
+#define CSR_ACSMLOADCHK8_LSB				9
+#define CSR_ACSMLOADCHK8_MASK				BIT(9)
+#define CSR_ACSMNORXENB8_LSB				10
+#define CSR_ACSMNORXENB8_MASK				BIT(10)
+#define CSR_ACSMNORXVAL8_LSB				11
+#define CSR_ACSMNORXVAL8_MASK				BIT(11)
+#define CSR_ACSMDDRBNK8_LSB				12
+#define CSR_ACSMDDRBNK8_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X9 */
+#define CSR_ACSMSEQ1X9_LSB				0
+#define CSR_ACSMSEQ1X9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS9_LSB				0
+#define CSR_ACSMDDRCS9_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN9_LSB				8
+#define CSR_ACSMSAVEGEN9_MASK				BIT(8)
+#define CSR_ACSMLOADCHK9_LSB				9
+#define CSR_ACSMLOADCHK9_MASK				BIT(9)
+#define CSR_ACSMNORXENB9_LSB				10
+#define CSR_ACSMNORXENB9_MASK				BIT(10)
+#define CSR_ACSMNORXVAL9_LSB				11
+#define CSR_ACSMNORXVAL9_MASK				BIT(11)
+#define CSR_ACSMDDRBNK9_LSB				12
+#define CSR_ACSMDDRBNK9_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X10 */
+#define CSR_ACSMSEQ1X10_LSB				0
+#define CSR_ACSMSEQ1X10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS10_LSB				0
+#define CSR_ACSMDDRCS10_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN10_LSB				8
+#define CSR_ACSMSAVEGEN10_MASK				BIT(8)
+#define CSR_ACSMLOADCHK10_LSB				9
+#define CSR_ACSMLOADCHK10_MASK				BIT(9)
+#define CSR_ACSMNORXENB10_LSB				10
+#define CSR_ACSMNORXENB10_MASK				BIT(10)
+#define CSR_ACSMNORXVAL10_LSB				11
+#define CSR_ACSMNORXVAL10_MASK				BIT(11)
+#define CSR_ACSMDDRBNK10_LSB				12
+#define CSR_ACSMDDRBNK10_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X11 */
+#define CSR_ACSMSEQ1X11_LSB				0
+#define CSR_ACSMSEQ1X11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS11_LSB				0
+#define CSR_ACSMDDRCS11_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN11_LSB				8
+#define CSR_ACSMSAVEGEN11_MASK				BIT(8)
+#define CSR_ACSMLOADCHK11_LSB				9
+#define CSR_ACSMLOADCHK11_MASK				BIT(9)
+#define CSR_ACSMNORXENB11_LSB				10
+#define CSR_ACSMNORXENB11_MASK				BIT(10)
+#define CSR_ACSMNORXVAL11_LSB				11
+#define CSR_ACSMNORXVAL11_MASK				BIT(11)
+#define CSR_ACSMDDRBNK11_LSB				12
+#define CSR_ACSMDDRBNK11_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X12 */
+#define CSR_ACSMSEQ1X12_LSB				0
+#define CSR_ACSMSEQ1X12_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS12_LSB				0
+#define CSR_ACSMDDRCS12_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN12_LSB				8
+#define CSR_ACSMSAVEGEN12_MASK				BIT(8)
+#define CSR_ACSMLOADCHK12_LSB				9
+#define CSR_ACSMLOADCHK12_MASK				BIT(9)
+#define CSR_ACSMNORXENB12_LSB				10
+#define CSR_ACSMNORXENB12_MASK				BIT(10)
+#define CSR_ACSMNORXVAL12_LSB				11
+#define CSR_ACSMNORXVAL12_MASK				BIT(11)
+#define CSR_ACSMDDRBNK12_LSB				12
+#define CSR_ACSMDDRBNK12_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X13 */
+#define CSR_ACSMSEQ1X13_LSB				0
+#define CSR_ACSMSEQ1X13_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS13_LSB				0
+#define CSR_ACSMDDRCS13_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN13_LSB				8
+#define CSR_ACSMSAVEGEN13_MASK				BIT(8)
+#define CSR_ACSMLOADCHK13_LSB				9
+#define CSR_ACSMLOADCHK13_MASK				BIT(9)
+#define CSR_ACSMNORXENB13_LSB				10
+#define CSR_ACSMNORXENB13_MASK				BIT(10)
+#define CSR_ACSMNORXVAL13_LSB				11
+#define CSR_ACSMNORXVAL13_MASK				BIT(11)
+#define CSR_ACSMDDRBNK13_LSB				12
+#define CSR_ACSMDDRBNK13_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X14 */
+#define CSR_ACSMSEQ1X14_LSB				0
+#define CSR_ACSMSEQ1X14_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS14_LSB				0
+#define CSR_ACSMDDRCS14_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN14_LSB				8
+#define CSR_ACSMSAVEGEN14_MASK				BIT(8)
+#define CSR_ACSMLOADCHK14_LSB				9
+#define CSR_ACSMLOADCHK14_MASK				BIT(9)
+#define CSR_ACSMNORXENB14_LSB				10
+#define CSR_ACSMNORXENB14_MASK				BIT(10)
+#define CSR_ACSMNORXVAL14_LSB				11
+#define CSR_ACSMNORXVAL14_MASK				BIT(11)
+#define CSR_ACSMDDRBNK14_LSB				12
+#define CSR_ACSMDDRBNK14_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X15 */
+#define CSR_ACSMSEQ1X15_LSB				0
+#define CSR_ACSMSEQ1X15_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS15_LSB				0
+#define CSR_ACSMDDRCS15_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN15_LSB				8
+#define CSR_ACSMSAVEGEN15_MASK				BIT(8)
+#define CSR_ACSMLOADCHK15_LSB				9
+#define CSR_ACSMLOADCHK15_MASK				BIT(9)
+#define CSR_ACSMNORXENB15_LSB				10
+#define CSR_ACSMNORXENB15_MASK				BIT(10)
+#define CSR_ACSMNORXVAL15_LSB				11
+#define CSR_ACSMNORXVAL15_MASK				BIT(11)
+#define CSR_ACSMDDRBNK15_LSB				12
+#define CSR_ACSMDDRBNK15_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X16 */
+#define CSR_ACSMSEQ1X16_LSB				0
+#define CSR_ACSMSEQ1X16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS16_LSB				0
+#define CSR_ACSMDDRCS16_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN16_LSB				8
+#define CSR_ACSMSAVEGEN16_MASK				BIT(8)
+#define CSR_ACSMLOADCHK16_LSB				9
+#define CSR_ACSMLOADCHK16_MASK				BIT(9)
+#define CSR_ACSMNORXENB16_LSB				10
+#define CSR_ACSMNORXENB16_MASK				BIT(10)
+#define CSR_ACSMNORXVAL16_LSB				11
+#define CSR_ACSMNORXVAL16_MASK				BIT(11)
+#define CSR_ACSMDDRBNK16_LSB				12
+#define CSR_ACSMDDRBNK16_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X17 */
+#define CSR_ACSMSEQ1X17_LSB				0
+#define CSR_ACSMSEQ1X17_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS17_LSB				0
+#define CSR_ACSMDDRCS17_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN17_LSB				8
+#define CSR_ACSMSAVEGEN17_MASK				BIT(8)
+#define CSR_ACSMLOADCHK17_LSB				9
+#define CSR_ACSMLOADCHK17_MASK				BIT(9)
+#define CSR_ACSMNORXENB17_LSB				10
+#define CSR_ACSMNORXENB17_MASK				BIT(10)
+#define CSR_ACSMNORXVAL17_LSB				11
+#define CSR_ACSMNORXVAL17_MASK				BIT(11)
+#define CSR_ACSMDDRBNK17_LSB				12
+#define CSR_ACSMDDRBNK17_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X18 */
+#define CSR_ACSMSEQ1X18_LSB				0
+#define CSR_ACSMSEQ1X18_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS18_LSB				0
+#define CSR_ACSMDDRCS18_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN18_LSB				8
+#define CSR_ACSMSAVEGEN18_MASK				BIT(8)
+#define CSR_ACSMLOADCHK18_LSB				9
+#define CSR_ACSMLOADCHK18_MASK				BIT(9)
+#define CSR_ACSMNORXENB18_LSB				10
+#define CSR_ACSMNORXENB18_MASK				BIT(10)
+#define CSR_ACSMNORXVAL18_LSB				11
+#define CSR_ACSMNORXVAL18_MASK				BIT(11)
+#define CSR_ACSMDDRBNK18_LSB				12
+#define CSR_ACSMDDRBNK18_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X19 */
+#define CSR_ACSMSEQ1X19_LSB				0
+#define CSR_ACSMSEQ1X19_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS19_LSB				0
+#define CSR_ACSMDDRCS19_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN19_LSB				8
+#define CSR_ACSMSAVEGEN19_MASK				BIT(8)
+#define CSR_ACSMLOADCHK19_LSB				9
+#define CSR_ACSMLOADCHK19_MASK				BIT(9)
+#define CSR_ACSMNORXENB19_LSB				10
+#define CSR_ACSMNORXENB19_MASK				BIT(10)
+#define CSR_ACSMNORXVAL19_LSB				11
+#define CSR_ACSMNORXVAL19_MASK				BIT(11)
+#define CSR_ACSMDDRBNK19_LSB				12
+#define CSR_ACSMDDRBNK19_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X20 */
+#define CSR_ACSMSEQ1X20_LSB				0
+#define CSR_ACSMSEQ1X20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS20_LSB				0
+#define CSR_ACSMDDRCS20_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN20_LSB				8
+#define CSR_ACSMSAVEGEN20_MASK				BIT(8)
+#define CSR_ACSMLOADCHK20_LSB				9
+#define CSR_ACSMLOADCHK20_MASK				BIT(9)
+#define CSR_ACSMNORXENB20_LSB				10
+#define CSR_ACSMNORXENB20_MASK				BIT(10)
+#define CSR_ACSMNORXVAL20_LSB				11
+#define CSR_ACSMNORXVAL20_MASK				BIT(11)
+#define CSR_ACSMDDRBNK20_LSB				12
+#define CSR_ACSMDDRBNK20_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X21 */
+#define CSR_ACSMSEQ1X21_LSB				0
+#define CSR_ACSMSEQ1X21_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS21_LSB				0
+#define CSR_ACSMDDRCS21_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN21_LSB				8
+#define CSR_ACSMSAVEGEN21_MASK				BIT(8)
+#define CSR_ACSMLOADCHK21_LSB				9
+#define CSR_ACSMLOADCHK21_MASK				BIT(9)
+#define CSR_ACSMNORXENB21_LSB				10
+#define CSR_ACSMNORXENB21_MASK				BIT(10)
+#define CSR_ACSMNORXVAL21_LSB				11
+#define CSR_ACSMNORXVAL21_MASK				BIT(11)
+#define CSR_ACSMDDRBNK21_LSB				12
+#define CSR_ACSMDDRBNK21_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X22 */
+#define CSR_ACSMSEQ1X22_LSB				0
+#define CSR_ACSMSEQ1X22_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS22_LSB				0
+#define CSR_ACSMDDRCS22_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN22_LSB				8
+#define CSR_ACSMSAVEGEN22_MASK				BIT(8)
+#define CSR_ACSMLOADCHK22_LSB				9
+#define CSR_ACSMLOADCHK22_MASK				BIT(9)
+#define CSR_ACSMNORXENB22_LSB				10
+#define CSR_ACSMNORXENB22_MASK				BIT(10)
+#define CSR_ACSMNORXVAL22_LSB				11
+#define CSR_ACSMNORXVAL22_MASK				BIT(11)
+#define CSR_ACSMDDRBNK22_LSB				12
+#define CSR_ACSMDDRBNK22_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X23 */
+#define CSR_ACSMSEQ1X23_LSB				0
+#define CSR_ACSMSEQ1X23_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS23_LSB				0
+#define CSR_ACSMDDRCS23_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN23_LSB				8
+#define CSR_ACSMSAVEGEN23_MASK				BIT(8)
+#define CSR_ACSMLOADCHK23_LSB				9
+#define CSR_ACSMLOADCHK23_MASK				BIT(9)
+#define CSR_ACSMNORXENB23_LSB				10
+#define CSR_ACSMNORXENB23_MASK				BIT(10)
+#define CSR_ACSMNORXVAL23_LSB				11
+#define CSR_ACSMNORXVAL23_MASK				BIT(11)
+#define CSR_ACSMDDRBNK23_LSB				12
+#define CSR_ACSMDDRBNK23_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X24 */
+#define CSR_ACSMSEQ1X24_LSB				0
+#define CSR_ACSMSEQ1X24_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS24_LSB				0
+#define CSR_ACSMDDRCS24_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN24_LSB				8
+#define CSR_ACSMSAVEGEN24_MASK				BIT(8)
+#define CSR_ACSMLOADCHK24_LSB				9
+#define CSR_ACSMLOADCHK24_MASK				BIT(9)
+#define CSR_ACSMNORXENB24_LSB				10
+#define CSR_ACSMNORXENB24_MASK				BIT(10)
+#define CSR_ACSMNORXVAL24_LSB				11
+#define CSR_ACSMNORXVAL24_MASK				BIT(11)
+#define CSR_ACSMDDRBNK24_LSB				12
+#define CSR_ACSMDDRBNK24_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X25 */
+#define CSR_ACSMSEQ1X25_LSB				0
+#define CSR_ACSMSEQ1X25_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS25_LSB				0
+#define CSR_ACSMDDRCS25_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN25_LSB				8
+#define CSR_ACSMSAVEGEN25_MASK				BIT(8)
+#define CSR_ACSMLOADCHK25_LSB				9
+#define CSR_ACSMLOADCHK25_MASK				BIT(9)
+#define CSR_ACSMNORXENB25_LSB				10
+#define CSR_ACSMNORXENB25_MASK				BIT(10)
+#define CSR_ACSMNORXVAL25_LSB				11
+#define CSR_ACSMNORXVAL25_MASK				BIT(11)
+#define CSR_ACSMDDRBNK25_LSB				12
+#define CSR_ACSMDDRBNK25_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X26 */
+#define CSR_ACSMSEQ1X26_LSB				0
+#define CSR_ACSMSEQ1X26_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS26_LSB				0
+#define CSR_ACSMDDRCS26_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN26_LSB				8
+#define CSR_ACSMSAVEGEN26_MASK				BIT(8)
+#define CSR_ACSMLOADCHK26_LSB				9
+#define CSR_ACSMLOADCHK26_MASK				BIT(9)
+#define CSR_ACSMNORXENB26_LSB				10
+#define CSR_ACSMNORXENB26_MASK				BIT(10)
+#define CSR_ACSMNORXVAL26_LSB				11
+#define CSR_ACSMNORXVAL26_MASK				BIT(11)
+#define CSR_ACSMDDRBNK26_LSB				12
+#define CSR_ACSMDDRBNK26_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X27 */
+#define CSR_ACSMSEQ1X27_LSB				0
+#define CSR_ACSMSEQ1X27_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS27_LSB				0
+#define CSR_ACSMDDRCS27_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN27_LSB				8
+#define CSR_ACSMSAVEGEN27_MASK				BIT(8)
+#define CSR_ACSMLOADCHK27_LSB				9
+#define CSR_ACSMLOADCHK27_MASK				BIT(9)
+#define CSR_ACSMNORXENB27_LSB				10
+#define CSR_ACSMNORXENB27_MASK				BIT(10)
+#define CSR_ACSMNORXVAL27_LSB				11
+#define CSR_ACSMNORXVAL27_MASK				BIT(11)
+#define CSR_ACSMDDRBNK27_LSB				12
+#define CSR_ACSMDDRBNK27_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X28 */
+#define CSR_ACSMSEQ1X28_LSB				0
+#define CSR_ACSMSEQ1X28_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS28_LSB				0
+#define CSR_ACSMDDRCS28_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN28_LSB				8
+#define CSR_ACSMSAVEGEN28_MASK				BIT(8)
+#define CSR_ACSMLOADCHK28_LSB				9
+#define CSR_ACSMLOADCHK28_MASK				BIT(9)
+#define CSR_ACSMNORXENB28_LSB				10
+#define CSR_ACSMNORXENB28_MASK				BIT(10)
+#define CSR_ACSMNORXVAL28_LSB				11
+#define CSR_ACSMNORXVAL28_MASK				BIT(11)
+#define CSR_ACSMDDRBNK28_LSB				12
+#define CSR_ACSMDDRBNK28_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X29 */
+#define CSR_ACSMSEQ1X29_LSB				0
+#define CSR_ACSMSEQ1X29_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS29_LSB				0
+#define CSR_ACSMDDRCS29_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN29_LSB				8
+#define CSR_ACSMSAVEGEN29_MASK				BIT(8)
+#define CSR_ACSMLOADCHK29_LSB				9
+#define CSR_ACSMLOADCHK29_MASK				BIT(9)
+#define CSR_ACSMNORXENB29_LSB				10
+#define CSR_ACSMNORXENB29_MASK				BIT(10)
+#define CSR_ACSMNORXVAL29_LSB				11
+#define CSR_ACSMNORXVAL29_MASK				BIT(11)
+#define CSR_ACSMDDRBNK29_LSB				12
+#define CSR_ACSMDDRBNK29_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X30 */
+#define CSR_ACSMSEQ1X30_LSB				0
+#define CSR_ACSMSEQ1X30_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS30_LSB				0
+#define CSR_ACSMDDRCS30_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN30_LSB				8
+#define CSR_ACSMSAVEGEN30_MASK				BIT(8)
+#define CSR_ACSMLOADCHK30_LSB				9
+#define CSR_ACSMLOADCHK30_MASK				BIT(9)
+#define CSR_ACSMNORXENB30_LSB				10
+#define CSR_ACSMNORXENB30_MASK				BIT(10)
+#define CSR_ACSMNORXVAL30_LSB				11
+#define CSR_ACSMNORXVAL30_MASK				BIT(11)
+#define CSR_ACSMDDRBNK30_LSB				12
+#define CSR_ACSMDDRBNK30_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ1X31 */
+#define CSR_ACSMSEQ1X31_LSB				0
+#define CSR_ACSMSEQ1X31_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRCS31_LSB				0
+#define CSR_ACSMDDRCS31_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMSAVEGEN31_LSB				8
+#define CSR_ACSMSAVEGEN31_MASK				BIT(8)
+#define CSR_ACSMLOADCHK31_LSB				9
+#define CSR_ACSMLOADCHK31_MASK				BIT(9)
+#define CSR_ACSMNORXENB31_LSB				10
+#define CSR_ACSMNORXENB31_MASK				BIT(10)
+#define CSR_ACSMNORXVAL31_LSB				11
+#define CSR_ACSMNORXVAL31_MASK				BIT(11)
+#define CSR_ACSMDDRBNK31_LSB				12
+#define CSR_ACSMDDRBNK31_MASK				GENMASK_32(15, 12)
+/* CSR_ACSMSEQ2X0 */
+#define CSR_ACSMSEQ2X0_LSB				0
+#define CSR_ACSMSEQ2X0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X0_LSB			0
+#define CSR_ACSMDDRADRX15X0X0_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X1 */
+#define CSR_ACSMSEQ2X1_LSB				0
+#define CSR_ACSMSEQ2X1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X1_LSB			0
+#define CSR_ACSMDDRADRX15X0X1_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X2 */
+#define CSR_ACSMSEQ2X2_LSB				0
+#define CSR_ACSMSEQ2X2_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X2_LSB			0
+#define CSR_ACSMDDRADRX15X0X2_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X3 */
+#define CSR_ACSMSEQ2X3_LSB				0
+#define CSR_ACSMSEQ2X3_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X3_LSB			0
+#define CSR_ACSMDDRADRX15X0X3_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X4 */
+#define CSR_ACSMSEQ2X4_LSB				0
+#define CSR_ACSMSEQ2X4_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X4_LSB			0
+#define CSR_ACSMDDRADRX15X0X4_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X5 */
+#define CSR_ACSMSEQ2X5_LSB				0
+#define CSR_ACSMSEQ2X5_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X5_LSB			0
+#define CSR_ACSMDDRADRX15X0X5_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X6 */
+#define CSR_ACSMSEQ2X6_LSB				0
+#define CSR_ACSMSEQ2X6_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X6_LSB			0
+#define CSR_ACSMDDRADRX15X0X6_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X7 */
+#define CSR_ACSMSEQ2X7_LSB				0
+#define CSR_ACSMSEQ2X7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X7_LSB			0
+#define CSR_ACSMDDRADRX15X0X7_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X8 */
+#define CSR_ACSMSEQ2X8_LSB				0
+#define CSR_ACSMSEQ2X8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X8_LSB			0
+#define CSR_ACSMDDRADRX15X0X8_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X9 */
+#define CSR_ACSMSEQ2X9_LSB				0
+#define CSR_ACSMSEQ2X9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X9_LSB			0
+#define CSR_ACSMDDRADRX15X0X9_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X10 */
+#define CSR_ACSMSEQ2X10_LSB				0
+#define CSR_ACSMSEQ2X10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X10_LSB			0
+#define CSR_ACSMDDRADRX15X0X10_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X11 */
+#define CSR_ACSMSEQ2X11_LSB				0
+#define CSR_ACSMSEQ2X11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X11_LSB			0
+#define CSR_ACSMDDRADRX15X0X11_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X12 */
+#define CSR_ACSMSEQ2X12_LSB				0
+#define CSR_ACSMSEQ2X12_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X12_LSB			0
+#define CSR_ACSMDDRADRX15X0X12_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X13 */
+#define CSR_ACSMSEQ2X13_LSB				0
+#define CSR_ACSMSEQ2X13_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X13_LSB			0
+#define CSR_ACSMDDRADRX15X0X13_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X14 */
+#define CSR_ACSMSEQ2X14_LSB				0
+#define CSR_ACSMSEQ2X14_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X14_LSB			0
+#define CSR_ACSMDDRADRX15X0X14_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X15 */
+#define CSR_ACSMSEQ2X15_LSB				0
+#define CSR_ACSMSEQ2X15_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X15_LSB			0
+#define CSR_ACSMDDRADRX15X0X15_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X16 */
+#define CSR_ACSMSEQ2X16_LSB				0
+#define CSR_ACSMSEQ2X16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X16_LSB			0
+#define CSR_ACSMDDRADRX15X0X16_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X17 */
+#define CSR_ACSMSEQ2X17_LSB				0
+#define CSR_ACSMSEQ2X17_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X17_LSB			0
+#define CSR_ACSMDDRADRX15X0X17_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X18 */
+#define CSR_ACSMSEQ2X18_LSB				0
+#define CSR_ACSMSEQ2X18_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X18_LSB			0
+#define CSR_ACSMDDRADRX15X0X18_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X19 */
+#define CSR_ACSMSEQ2X19_LSB				0
+#define CSR_ACSMSEQ2X19_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X19_LSB			0
+#define CSR_ACSMDDRADRX15X0X19_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X20 */
+#define CSR_ACSMSEQ2X20_LSB				0
+#define CSR_ACSMSEQ2X20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X20_LSB			0
+#define CSR_ACSMDDRADRX15X0X20_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X21 */
+#define CSR_ACSMSEQ2X21_LSB				0
+#define CSR_ACSMSEQ2X21_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X21_LSB			0
+#define CSR_ACSMDDRADRX15X0X21_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X22 */
+#define CSR_ACSMSEQ2X22_LSB				0
+#define CSR_ACSMSEQ2X22_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X22_LSB			0
+#define CSR_ACSMDDRADRX15X0X22_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X23 */
+#define CSR_ACSMSEQ2X23_LSB				0
+#define CSR_ACSMSEQ2X23_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X23_LSB			0
+#define CSR_ACSMDDRADRX15X0X23_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X24 */
+#define CSR_ACSMSEQ2X24_LSB				0
+#define CSR_ACSMSEQ2X24_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X24_LSB			0
+#define CSR_ACSMDDRADRX15X0X24_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X25 */
+#define CSR_ACSMSEQ2X25_LSB				0
+#define CSR_ACSMSEQ2X25_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X25_LSB			0
+#define CSR_ACSMDDRADRX15X0X25_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X26 */
+#define CSR_ACSMSEQ2X26_LSB				0
+#define CSR_ACSMSEQ2X26_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X26_LSB			0
+#define CSR_ACSMDDRADRX15X0X26_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X27 */
+#define CSR_ACSMSEQ2X27_LSB				0
+#define CSR_ACSMSEQ2X27_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X27_LSB			0
+#define CSR_ACSMDDRADRX15X0X27_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X28 */
+#define CSR_ACSMSEQ2X28_LSB				0
+#define CSR_ACSMSEQ2X28_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X28_LSB			0
+#define CSR_ACSMDDRADRX15X0X28_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X29 */
+#define CSR_ACSMSEQ2X29_LSB				0
+#define CSR_ACSMSEQ2X29_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X29_LSB			0
+#define CSR_ACSMDDRADRX15X0X29_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X30 */
+#define CSR_ACSMSEQ2X30_LSB				0
+#define CSR_ACSMSEQ2X30_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X30_LSB			0
+#define CSR_ACSMDDRADRX15X0X30_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ2X31 */
+#define CSR_ACSMSEQ2X31_LSB				0
+#define CSR_ACSMSEQ2X31_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRX15X0X31_LSB			0
+#define CSR_ACSMDDRADRX15X0X31_MASK			GENMASK_32(15, 0)
+/* CSR_ACSMSEQ3X0 */
+#define CSR_ACSMSEQ3X0_LSB				0
+#define CSR_ACSMSEQ3X0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT0_LSB				0
+#define CSR_ACSMCMDREPCNT0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV0_LSB				8
+#define CSR_ACSMADRADV0_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV0_LSB				10
+#define CSR_ACSMBNKADV0_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD0_LSB				12
+#define CSR_ACSMADRSELLOAD0_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD0_LSB				14
+#define CSR_ACSMBNKSELLOAD0_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE0_LSB				15
+#define CSR_ACSMLONGBUBBLE0_MASK			BIT(15)
+/* CSR_ACSMSEQ3X1 */
+#define CSR_ACSMSEQ3X1_LSB				0
+#define CSR_ACSMSEQ3X1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT1_LSB				0
+#define CSR_ACSMCMDREPCNT1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV1_LSB				8
+#define CSR_ACSMADRADV1_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV1_LSB				10
+#define CSR_ACSMBNKADV1_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD1_LSB				12
+#define CSR_ACSMADRSELLOAD1_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD1_LSB				14
+#define CSR_ACSMBNKSELLOAD1_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE1_LSB				15
+#define CSR_ACSMLONGBUBBLE1_MASK			BIT(15)
+/* CSR_ACSMSEQ3X2 */
+#define CSR_ACSMSEQ3X2_LSB				0
+#define CSR_ACSMSEQ3X2_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT2_LSB				0
+#define CSR_ACSMCMDREPCNT2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV2_LSB				8
+#define CSR_ACSMADRADV2_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV2_LSB				10
+#define CSR_ACSMBNKADV2_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD2_LSB				12
+#define CSR_ACSMADRSELLOAD2_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD2_LSB				14
+#define CSR_ACSMBNKSELLOAD2_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE2_LSB				15
+#define CSR_ACSMLONGBUBBLE2_MASK			BIT(15)
+/* CSR_ACSMSEQ3X3 */
+#define CSR_ACSMSEQ3X3_LSB				0
+#define CSR_ACSMSEQ3X3_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT3_LSB				0
+#define CSR_ACSMCMDREPCNT3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV3_LSB				8
+#define CSR_ACSMADRADV3_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV3_LSB				10
+#define CSR_ACSMBNKADV3_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD3_LSB				12
+#define CSR_ACSMADRSELLOAD3_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD3_LSB				14
+#define CSR_ACSMBNKSELLOAD3_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE3_LSB				15
+#define CSR_ACSMLONGBUBBLE3_MASK			BIT(15)
+/* CSR_ACSMSEQ3X4 */
+#define CSR_ACSMSEQ3X4_LSB				0
+#define CSR_ACSMSEQ3X4_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT4_LSB				0
+#define CSR_ACSMCMDREPCNT4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV4_LSB				8
+#define CSR_ACSMADRADV4_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV4_LSB				10
+#define CSR_ACSMBNKADV4_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD4_LSB				12
+#define CSR_ACSMADRSELLOAD4_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD4_LSB				14
+#define CSR_ACSMBNKSELLOAD4_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE4_LSB				15
+#define CSR_ACSMLONGBUBBLE4_MASK			BIT(15)
+/* CSR_ACSMSEQ3X5 */
+#define CSR_ACSMSEQ3X5_LSB				0
+#define CSR_ACSMSEQ3X5_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT5_LSB				0
+#define CSR_ACSMCMDREPCNT5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV5_LSB				8
+#define CSR_ACSMADRADV5_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV5_LSB				10
+#define CSR_ACSMBNKADV5_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD5_LSB				12
+#define CSR_ACSMADRSELLOAD5_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD5_LSB				14
+#define CSR_ACSMBNKSELLOAD5_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE5_LSB				15
+#define CSR_ACSMLONGBUBBLE5_MASK			BIT(15)
+/* CSR_ACSMSEQ3X6 */
+#define CSR_ACSMSEQ3X6_LSB				0
+#define CSR_ACSMSEQ3X6_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT6_LSB				0
+#define CSR_ACSMCMDREPCNT6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV6_LSB				8
+#define CSR_ACSMADRADV6_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV6_LSB				10
+#define CSR_ACSMBNKADV6_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD6_LSB				12
+#define CSR_ACSMADRSELLOAD6_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD6_LSB				14
+#define CSR_ACSMBNKSELLOAD6_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE6_LSB				15
+#define CSR_ACSMLONGBUBBLE6_MASK			BIT(15)
+/* CSR_ACSMSEQ3X7 */
+#define CSR_ACSMSEQ3X7_LSB				0
+#define CSR_ACSMSEQ3X7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT7_LSB				0
+#define CSR_ACSMCMDREPCNT7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV7_LSB				8
+#define CSR_ACSMADRADV7_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV7_LSB				10
+#define CSR_ACSMBNKADV7_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD7_LSB				12
+#define CSR_ACSMADRSELLOAD7_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD7_LSB				14
+#define CSR_ACSMBNKSELLOAD7_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE7_LSB				15
+#define CSR_ACSMLONGBUBBLE7_MASK			BIT(15)
+/* CSR_ACSMSEQ3X8 */
+#define CSR_ACSMSEQ3X8_LSB				0
+#define CSR_ACSMSEQ3X8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT8_LSB				0
+#define CSR_ACSMCMDREPCNT8_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV8_LSB				8
+#define CSR_ACSMADRADV8_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV8_LSB				10
+#define CSR_ACSMBNKADV8_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD8_LSB				12
+#define CSR_ACSMADRSELLOAD8_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD8_LSB				14
+#define CSR_ACSMBNKSELLOAD8_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE8_LSB				15
+#define CSR_ACSMLONGBUBBLE8_MASK			BIT(15)
+/* CSR_ACSMSEQ3X9 */
+#define CSR_ACSMSEQ3X9_LSB				0
+#define CSR_ACSMSEQ3X9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT9_LSB				0
+#define CSR_ACSMCMDREPCNT9_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMADRADV9_LSB				8
+#define CSR_ACSMADRADV9_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV9_LSB				10
+#define CSR_ACSMBNKADV9_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD9_LSB				12
+#define CSR_ACSMADRSELLOAD9_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD9_LSB				14
+#define CSR_ACSMBNKSELLOAD9_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE9_LSB				15
+#define CSR_ACSMLONGBUBBLE9_MASK			BIT(15)
+/* CSR_ACSMSEQ3X10 */
+#define CSR_ACSMSEQ3X10_LSB				0
+#define CSR_ACSMSEQ3X10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT10_LSB				0
+#define CSR_ACSMCMDREPCNT10_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV10_LSB				8
+#define CSR_ACSMADRADV10_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV10_LSB				10
+#define CSR_ACSMBNKADV10_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD10_LSB			12
+#define CSR_ACSMADRSELLOAD10_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD10_LSB			14
+#define CSR_ACSMBNKSELLOAD10_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE10_LSB			15
+#define CSR_ACSMLONGBUBBLE10_MASK			BIT(15)
+/* CSR_ACSMSEQ3X11 */
+#define CSR_ACSMSEQ3X11_LSB				0
+#define CSR_ACSMSEQ3X11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT11_LSB				0
+#define CSR_ACSMCMDREPCNT11_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV11_LSB				8
+#define CSR_ACSMADRADV11_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV11_LSB				10
+#define CSR_ACSMBNKADV11_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD11_LSB			12
+#define CSR_ACSMADRSELLOAD11_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD11_LSB			14
+#define CSR_ACSMBNKSELLOAD11_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE11_LSB			15
+#define CSR_ACSMLONGBUBBLE11_MASK			BIT(15)
+/* CSR_ACSMSEQ3X12 */
+#define CSR_ACSMSEQ3X12_LSB				0
+#define CSR_ACSMSEQ3X12_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT12_LSB				0
+#define CSR_ACSMCMDREPCNT12_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV12_LSB				8
+#define CSR_ACSMADRADV12_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV12_LSB				10
+#define CSR_ACSMBNKADV12_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD12_LSB			12
+#define CSR_ACSMADRSELLOAD12_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD12_LSB			14
+#define CSR_ACSMBNKSELLOAD12_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE12_LSB			15
+#define CSR_ACSMLONGBUBBLE12_MASK			BIT(15)
+/* CSR_ACSMSEQ3X13 */
+#define CSR_ACSMSEQ3X13_LSB				0
+#define CSR_ACSMSEQ3X13_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT13_LSB				0
+#define CSR_ACSMCMDREPCNT13_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV13_LSB				8
+#define CSR_ACSMADRADV13_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV13_LSB				10
+#define CSR_ACSMBNKADV13_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD13_LSB			12
+#define CSR_ACSMADRSELLOAD13_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD13_LSB			14
+#define CSR_ACSMBNKSELLOAD13_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE13_LSB			15
+#define CSR_ACSMLONGBUBBLE13_MASK			BIT(15)
+/* CSR_ACSMSEQ3X14 */
+#define CSR_ACSMSEQ3X14_LSB				0
+#define CSR_ACSMSEQ3X14_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT14_LSB				0
+#define CSR_ACSMCMDREPCNT14_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV14_LSB				8
+#define CSR_ACSMADRADV14_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV14_LSB				10
+#define CSR_ACSMBNKADV14_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD14_LSB			12
+#define CSR_ACSMADRSELLOAD14_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD14_LSB			14
+#define CSR_ACSMBNKSELLOAD14_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE14_LSB			15
+#define CSR_ACSMLONGBUBBLE14_MASK			BIT(15)
+/* CSR_ACSMSEQ3X15 */
+#define CSR_ACSMSEQ3X15_LSB				0
+#define CSR_ACSMSEQ3X15_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT15_LSB				0
+#define CSR_ACSMCMDREPCNT15_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV15_LSB				8
+#define CSR_ACSMADRADV15_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV15_LSB				10
+#define CSR_ACSMBNKADV15_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD15_LSB			12
+#define CSR_ACSMADRSELLOAD15_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD15_LSB			14
+#define CSR_ACSMBNKSELLOAD15_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE15_LSB			15
+#define CSR_ACSMLONGBUBBLE15_MASK			BIT(15)
+/* CSR_ACSMSEQ3X16 */
+#define CSR_ACSMSEQ3X16_LSB				0
+#define CSR_ACSMSEQ3X16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT16_LSB				0
+#define CSR_ACSMCMDREPCNT16_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV16_LSB				8
+#define CSR_ACSMADRADV16_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV16_LSB				10
+#define CSR_ACSMBNKADV16_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD16_LSB			12
+#define CSR_ACSMADRSELLOAD16_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD16_LSB			14
+#define CSR_ACSMBNKSELLOAD16_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE16_LSB			15
+#define CSR_ACSMLONGBUBBLE16_MASK			BIT(15)
+/* CSR_ACSMSEQ3X17 */
+#define CSR_ACSMSEQ3X17_LSB				0
+#define CSR_ACSMSEQ3X17_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT17_LSB				0
+#define CSR_ACSMCMDREPCNT17_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV17_LSB				8
+#define CSR_ACSMADRADV17_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV17_LSB				10
+#define CSR_ACSMBNKADV17_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD17_LSB			12
+#define CSR_ACSMADRSELLOAD17_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD17_LSB			14
+#define CSR_ACSMBNKSELLOAD17_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE17_LSB			15
+#define CSR_ACSMLONGBUBBLE17_MASK			BIT(15)
+/* CSR_ACSMSEQ3X18 */
+#define CSR_ACSMSEQ3X18_LSB				0
+#define CSR_ACSMSEQ3X18_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT18_LSB				0
+#define CSR_ACSMCMDREPCNT18_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV18_LSB				8
+#define CSR_ACSMADRADV18_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV18_LSB				10
+#define CSR_ACSMBNKADV18_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD18_LSB			12
+#define CSR_ACSMADRSELLOAD18_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD18_LSB			14
+#define CSR_ACSMBNKSELLOAD18_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE18_LSB			15
+#define CSR_ACSMLONGBUBBLE18_MASK			BIT(15)
+/* CSR_ACSMSEQ3X19 */
+#define CSR_ACSMSEQ3X19_LSB				0
+#define CSR_ACSMSEQ3X19_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT19_LSB				0
+#define CSR_ACSMCMDREPCNT19_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV19_LSB				8
+#define CSR_ACSMADRADV19_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV19_LSB				10
+#define CSR_ACSMBNKADV19_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD19_LSB			12
+#define CSR_ACSMADRSELLOAD19_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD19_LSB			14
+#define CSR_ACSMBNKSELLOAD19_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE19_LSB			15
+#define CSR_ACSMLONGBUBBLE19_MASK			BIT(15)
+/* CSR_ACSMSEQ3X20 */
+#define CSR_ACSMSEQ3X20_LSB				0
+#define CSR_ACSMSEQ3X20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT20_LSB				0
+#define CSR_ACSMCMDREPCNT20_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV20_LSB				8
+#define CSR_ACSMADRADV20_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV20_LSB				10
+#define CSR_ACSMBNKADV20_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD20_LSB			12
+#define CSR_ACSMADRSELLOAD20_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD20_LSB			14
+#define CSR_ACSMBNKSELLOAD20_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE20_LSB			15
+#define CSR_ACSMLONGBUBBLE20_MASK			BIT(15)
+/* CSR_ACSMSEQ3X21 */
+#define CSR_ACSMSEQ3X21_LSB				0
+#define CSR_ACSMSEQ3X21_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT21_LSB				0
+#define CSR_ACSMCMDREPCNT21_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV21_LSB				8
+#define CSR_ACSMADRADV21_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV21_LSB				10
+#define CSR_ACSMBNKADV21_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD21_LSB			12
+#define CSR_ACSMADRSELLOAD21_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD21_LSB			14
+#define CSR_ACSMBNKSELLOAD21_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE21_LSB			15
+#define CSR_ACSMLONGBUBBLE21_MASK			BIT(15)
+/* CSR_ACSMSEQ3X22 */
+#define CSR_ACSMSEQ3X22_LSB				0
+#define CSR_ACSMSEQ3X22_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT22_LSB				0
+#define CSR_ACSMCMDREPCNT22_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV22_LSB				8
+#define CSR_ACSMADRADV22_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV22_LSB				10
+#define CSR_ACSMBNKADV22_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD22_LSB			12
+#define CSR_ACSMADRSELLOAD22_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD22_LSB			14
+#define CSR_ACSMBNKSELLOAD22_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE22_LSB			15
+#define CSR_ACSMLONGBUBBLE22_MASK			BIT(15)
+/* CSR_ACSMSEQ3X23 */
+#define CSR_ACSMSEQ3X23_LSB				0
+#define CSR_ACSMSEQ3X23_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT23_LSB				0
+#define CSR_ACSMCMDREPCNT23_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV23_LSB				8
+#define CSR_ACSMADRADV23_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV23_LSB				10
+#define CSR_ACSMBNKADV23_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD23_LSB			12
+#define CSR_ACSMADRSELLOAD23_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD23_LSB			14
+#define CSR_ACSMBNKSELLOAD23_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE23_LSB			15
+#define CSR_ACSMLONGBUBBLE23_MASK			BIT(15)
+/* CSR_ACSMSEQ3X24 */
+#define CSR_ACSMSEQ3X24_LSB				0
+#define CSR_ACSMSEQ3X24_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT24_LSB				0
+#define CSR_ACSMCMDREPCNT24_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV24_LSB				8
+#define CSR_ACSMADRADV24_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV24_LSB				10
+#define CSR_ACSMBNKADV24_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD24_LSB			12
+#define CSR_ACSMADRSELLOAD24_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD24_LSB			14
+#define CSR_ACSMBNKSELLOAD24_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE24_LSB			15
+#define CSR_ACSMLONGBUBBLE24_MASK			BIT(15)
+/* CSR_ACSMSEQ3X25 */
+#define CSR_ACSMSEQ3X25_LSB				0
+#define CSR_ACSMSEQ3X25_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT25_LSB				0
+#define CSR_ACSMCMDREPCNT25_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV25_LSB				8
+#define CSR_ACSMADRADV25_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV25_LSB				10
+#define CSR_ACSMBNKADV25_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD25_LSB			12
+#define CSR_ACSMADRSELLOAD25_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD25_LSB			14
+#define CSR_ACSMBNKSELLOAD25_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE25_LSB			15
+#define CSR_ACSMLONGBUBBLE25_MASK			BIT(15)
+/* CSR_ACSMSEQ3X26 */
+#define CSR_ACSMSEQ3X26_LSB				0
+#define CSR_ACSMSEQ3X26_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT26_LSB				0
+#define CSR_ACSMCMDREPCNT26_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV26_LSB				8
+#define CSR_ACSMADRADV26_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV26_LSB				10
+#define CSR_ACSMBNKADV26_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD26_LSB			12
+#define CSR_ACSMADRSELLOAD26_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD26_LSB			14
+#define CSR_ACSMBNKSELLOAD26_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE26_LSB			15
+#define CSR_ACSMLONGBUBBLE26_MASK			BIT(15)
+/* CSR_ACSMSEQ3X27 */
+#define CSR_ACSMSEQ3X27_LSB				0
+#define CSR_ACSMSEQ3X27_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT27_LSB				0
+#define CSR_ACSMCMDREPCNT27_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV27_LSB				8
+#define CSR_ACSMADRADV27_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV27_LSB				10
+#define CSR_ACSMBNKADV27_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD27_LSB			12
+#define CSR_ACSMADRSELLOAD27_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD27_LSB			14
+#define CSR_ACSMBNKSELLOAD27_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE27_LSB			15
+#define CSR_ACSMLONGBUBBLE27_MASK			BIT(15)
+/* CSR_ACSMSEQ3X28 */
+#define CSR_ACSMSEQ3X28_LSB				0
+#define CSR_ACSMSEQ3X28_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT28_LSB				0
+#define CSR_ACSMCMDREPCNT28_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV28_LSB				8
+#define CSR_ACSMADRADV28_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV28_LSB				10
+#define CSR_ACSMBNKADV28_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD28_LSB			12
+#define CSR_ACSMADRSELLOAD28_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD28_LSB			14
+#define CSR_ACSMBNKSELLOAD28_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE28_LSB			15
+#define CSR_ACSMLONGBUBBLE28_MASK			BIT(15)
+/* CSR_ACSMSEQ3X29 */
+#define CSR_ACSMSEQ3X29_LSB				0
+#define CSR_ACSMSEQ3X29_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT29_LSB				0
+#define CSR_ACSMCMDREPCNT29_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV29_LSB				8
+#define CSR_ACSMADRADV29_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV29_LSB				10
+#define CSR_ACSMBNKADV29_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD29_LSB			12
+#define CSR_ACSMADRSELLOAD29_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD29_LSB			14
+#define CSR_ACSMBNKSELLOAD29_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE29_LSB			15
+#define CSR_ACSMLONGBUBBLE29_MASK			BIT(15)
+/* CSR_ACSMSEQ3X30 */
+#define CSR_ACSMSEQ3X30_LSB				0
+#define CSR_ACSMSEQ3X30_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT30_LSB				0
+#define CSR_ACSMCMDREPCNT30_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV30_LSB				8
+#define CSR_ACSMADRADV30_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV30_LSB				10
+#define CSR_ACSMBNKADV30_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD30_LSB			12
+#define CSR_ACSMADRSELLOAD30_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD30_LSB			14
+#define CSR_ACSMBNKSELLOAD30_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE30_LSB			15
+#define CSR_ACSMLONGBUBBLE30_MASK			BIT(15)
+/* CSR_ACSMSEQ3X31 */
+#define CSR_ACSMSEQ3X31_LSB				0
+#define CSR_ACSMSEQ3X31_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCMDREPCNT31_LSB				0
+#define CSR_ACSMCMDREPCNT31_MASK			GENMASK_32(7, 0)
+#define CSR_ACSMADRADV31_LSB				8
+#define CSR_ACSMADRADV31_MASK				GENMASK_32(9, 8)
+#define CSR_ACSMBNKADV31_LSB				10
+#define CSR_ACSMBNKADV31_MASK				GENMASK_32(11, 10)
+#define CSR_ACSMADRSELLOAD31_LSB			12
+#define CSR_ACSMADRSELLOAD31_MASK			GENMASK_32(13, 12)
+#define CSR_ACSMBNKSELLOAD31_LSB			14
+#define CSR_ACSMBNKSELLOAD31_MASK			BIT(14)
+#define CSR_ACSMLONGBUBBLE31_LSB			15
+#define CSR_ACSMLONGBUBBLE31_MASK			BIT(15)
+/* CSR_ACSMPLAYBACK0X0 */
+#define CSR_ACSMPLAYBACK0X0_LSB				0
+#define CSR_ACSMPLAYBACK0X0_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X0 */
+#define CSR_ACSMPLAYBACK1X0_LSB				0
+#define CSR_ACSMPLAYBACK1X0_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X1 */
+#define CSR_ACSMPLAYBACK0X1_LSB				0
+#define CSR_ACSMPLAYBACK0X1_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X1 */
+#define CSR_ACSMPLAYBACK1X1_LSB				0
+#define CSR_ACSMPLAYBACK1X1_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X2 */
+#define CSR_ACSMPLAYBACK0X2_LSB				0
+#define CSR_ACSMPLAYBACK0X2_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X2 */
+#define CSR_ACSMPLAYBACK1X2_LSB				0
+#define CSR_ACSMPLAYBACK1X2_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X3 */
+#define CSR_ACSMPLAYBACK0X3_LSB				0
+#define CSR_ACSMPLAYBACK0X3_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X3 */
+#define CSR_ACSMPLAYBACK1X3_LSB				0
+#define CSR_ACSMPLAYBACK1X3_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X4 */
+#define CSR_ACSMPLAYBACK0X4_LSB				0
+#define CSR_ACSMPLAYBACK0X4_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X4 */
+#define CSR_ACSMPLAYBACK1X4_LSB				0
+#define CSR_ACSMPLAYBACK1X4_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X5 */
+#define CSR_ACSMPLAYBACK0X5_LSB				0
+#define CSR_ACSMPLAYBACK0X5_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X5 */
+#define CSR_ACSMPLAYBACK1X5_LSB				0
+#define CSR_ACSMPLAYBACK1X5_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X6 */
+#define CSR_ACSMPLAYBACK0X6_LSB				0
+#define CSR_ACSMPLAYBACK0X6_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X6 */
+#define CSR_ACSMPLAYBACK1X6_LSB				0
+#define CSR_ACSMPLAYBACK1X6_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK0X7 */
+#define CSR_ACSMPLAYBACK0X7_LSB				0
+#define CSR_ACSMPLAYBACK0X7_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPLAYBACK1X7 */
+#define CSR_ACSMPLAYBACK1X7_LSB				0
+#define CSR_ACSMPLAYBACK1X7_MASK			GENMASK_32(11, 0)
+/* CSR_ACSMPSTATEOVREN */
+#define CSR_ACSMPSTATEOVREN_LSB				0
+#define CSR_ACSMPSTATEOVREN_MASK			BIT(0)
+/* CSR_ACSMPSTATEOVRVAL */
+#define CSR_ACSMPSTATEOVRVAL_LSB			0
+#define CSR_ACSMPSTATEOVRVAL_MASK			GENMASK_32(3, 0)
+/* CSR_ACSMCTRL23 */
+#define CSR_ACSMCTRL23_LSB				0
+#define CSR_ACSMCTRL23_MASK				GENMASK_32(12, 0)
+#define CSR_ACSMCSMASK_LSB				0
+#define CSR_ACSMCSMASK_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMCSMODE_LSB				8
+#define CSR_ACSMCSMODE_MASK				BIT(8)
+#define CSR_ACSMPARMASK_LSB				9
+#define CSR_ACSMPARMASK_MASK				GENMASK_32(12, 9)
+/* CSR_ACSMCKEVAL */
+#define CSR_ACSMCKEVAL_LSB				0
+#define CSR_ACSMCKEVAL_MASK				GENMASK_32(3, 0)
+/* CSR_LOWSPEEDCLOCKDIVIDER */
+#define CSR_LOWSPEEDCLOCKDIVIDER_LSB			0
+#define CSR_LOWSPEEDCLOCKDIVIDER_MASK			GENMASK_32(5, 0)
+/* CSR_ACSMCSMAPCTRL0 */
+#define CSR_ACSMCSMAPCTRL0_LSB				0
+#define CSR_ACSMCSMAPCTRL0_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP0_LSB				0
+#define CSR_ACSMCSMAP0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP0_LSB				8
+#define CSR_ACSMDESTMAP0_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP0_LSB				12
+#define CSR_ACSMODTMAP0_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL1 */
+#define CSR_ACSMCSMAPCTRL1_LSB				0
+#define CSR_ACSMCSMAPCTRL1_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP1_LSB				0
+#define CSR_ACSMCSMAP1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP1_LSB				8
+#define CSR_ACSMDESTMAP1_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP1_LSB				12
+#define CSR_ACSMODTMAP1_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL2 */
+#define CSR_ACSMCSMAPCTRL2_LSB				0
+#define CSR_ACSMCSMAPCTRL2_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP2_LSB				0
+#define CSR_ACSMCSMAP2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP2_LSB				8
+#define CSR_ACSMDESTMAP2_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP2_LSB				12
+#define CSR_ACSMODTMAP2_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL3 */
+#define CSR_ACSMCSMAPCTRL3_LSB				0
+#define CSR_ACSMCSMAPCTRL3_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP3_LSB				0
+#define CSR_ACSMCSMAP3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP3_LSB				8
+#define CSR_ACSMDESTMAP3_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP3_LSB				12
+#define CSR_ACSMODTMAP3_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL4 */
+#define CSR_ACSMCSMAPCTRL4_LSB				0
+#define CSR_ACSMCSMAPCTRL4_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP4_LSB				0
+#define CSR_ACSMCSMAP4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP4_LSB				8
+#define CSR_ACSMDESTMAP4_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP4_LSB				12
+#define CSR_ACSMODTMAP4_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL5 */
+#define CSR_ACSMCSMAPCTRL5_LSB				0
+#define CSR_ACSMCSMAPCTRL5_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP5_LSB				0
+#define CSR_ACSMCSMAP5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP5_LSB				8
+#define CSR_ACSMDESTMAP5_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP5_LSB				12
+#define CSR_ACSMODTMAP5_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL6 */
+#define CSR_ACSMCSMAPCTRL6_LSB				0
+#define CSR_ACSMCSMAPCTRL6_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP6_LSB				0
+#define CSR_ACSMCSMAP6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP6_LSB				8
+#define CSR_ACSMDESTMAP6_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP6_LSB				12
+#define CSR_ACSMODTMAP6_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL7 */
+#define CSR_ACSMCSMAPCTRL7_LSB				0
+#define CSR_ACSMCSMAPCTRL7_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP7_LSB				0
+#define CSR_ACSMCSMAP7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP7_LSB				8
+#define CSR_ACSMDESTMAP7_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP7_LSB				12
+#define CSR_ACSMODTMAP7_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL8 */
+#define CSR_ACSMCSMAPCTRL8_LSB				0
+#define CSR_ACSMCSMAPCTRL8_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP8_LSB				0
+#define CSR_ACSMCSMAP8_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP8_LSB				8
+#define CSR_ACSMDESTMAP8_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP8_LSB				12
+#define CSR_ACSMODTMAP8_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL9 */
+#define CSR_ACSMCSMAPCTRL9_LSB				0
+#define CSR_ACSMCSMAPCTRL9_MASK				GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP9_LSB				0
+#define CSR_ACSMCSMAP9_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP9_LSB				8
+#define CSR_ACSMDESTMAP9_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP9_LSB				12
+#define CSR_ACSMODTMAP9_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL10 */
+#define CSR_ACSMCSMAPCTRL10_LSB				0
+#define CSR_ACSMCSMAPCTRL10_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP10_LSB				0
+#define CSR_ACSMCSMAP10_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP10_LSB				8
+#define CSR_ACSMDESTMAP10_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP10_LSB				12
+#define CSR_ACSMODTMAP10_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL11 */
+#define CSR_ACSMCSMAPCTRL11_LSB				0
+#define CSR_ACSMCSMAPCTRL11_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP11_LSB				0
+#define CSR_ACSMCSMAP11_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP11_LSB				8
+#define CSR_ACSMDESTMAP11_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP11_LSB				12
+#define CSR_ACSMODTMAP11_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL12 */
+#define CSR_ACSMCSMAPCTRL12_LSB				0
+#define CSR_ACSMCSMAPCTRL12_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP12_LSB				0
+#define CSR_ACSMCSMAP12_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP12_LSB				8
+#define CSR_ACSMDESTMAP12_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP12_LSB				12
+#define CSR_ACSMODTMAP12_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL13 */
+#define CSR_ACSMCSMAPCTRL13_LSB				0
+#define CSR_ACSMCSMAPCTRL13_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP13_LSB				0
+#define CSR_ACSMCSMAP13_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP13_LSB				8
+#define CSR_ACSMDESTMAP13_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP13_LSB				12
+#define CSR_ACSMODTMAP13_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL14 */
+#define CSR_ACSMCSMAPCTRL14_LSB				0
+#define CSR_ACSMCSMAPCTRL14_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP14_LSB				0
+#define CSR_ACSMCSMAP14_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP14_LSB				8
+#define CSR_ACSMDESTMAP14_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP14_LSB				12
+#define CSR_ACSMODTMAP14_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMCSMAPCTRL15 */
+#define CSR_ACSMCSMAPCTRL15_LSB				0
+#define CSR_ACSMCSMAPCTRL15_MASK			GENMASK_32(14, 0)
+#define CSR_ACSMCSMAP15_LSB				0
+#define CSR_ACSMCSMAP15_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMDESTMAP15_LSB				8
+#define CSR_ACSMDESTMAP15_MASK				GENMASK_32(11, 8)
+#define CSR_ACSMODTMAP15_LSB				12
+#define CSR_ACSMODTMAP15_MASK				GENMASK_32(14, 12)
+/* CSR_ACSMODTCTRL0 */
+#define CSR_ACSMODTCTRL0_LSB				0
+#define CSR_ACSMODTCTRL0_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS0_LSB				0
+#define CSR_ACSMODTWRPATCS0_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS0_LSB				4
+#define CSR_ACSMODTRDPATCS0_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL1 */
+#define CSR_ACSMODTCTRL1_LSB				0
+#define CSR_ACSMODTCTRL1_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS1_LSB				0
+#define CSR_ACSMODTWRPATCS1_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS1_LSB				4
+#define CSR_ACSMODTRDPATCS1_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL2 */
+#define CSR_ACSMODTCTRL2_LSB				0
+#define CSR_ACSMODTCTRL2_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS2_LSB				0
+#define CSR_ACSMODTWRPATCS2_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS2_LSB				4
+#define CSR_ACSMODTRDPATCS2_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL3 */
+#define CSR_ACSMODTCTRL3_LSB				0
+#define CSR_ACSMODTCTRL3_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS3_LSB				0
+#define CSR_ACSMODTWRPATCS3_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS3_LSB				4
+#define CSR_ACSMODTRDPATCS3_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL4 */
+#define CSR_ACSMODTCTRL4_LSB				0
+#define CSR_ACSMODTCTRL4_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS4_LSB				0
+#define CSR_ACSMODTWRPATCS4_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS4_LSB				4
+#define CSR_ACSMODTRDPATCS4_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL5 */
+#define CSR_ACSMODTCTRL5_LSB				0
+#define CSR_ACSMODTCTRL5_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS5_LSB				0
+#define CSR_ACSMODTWRPATCS5_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS5_LSB				4
+#define CSR_ACSMODTRDPATCS5_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL6 */
+#define CSR_ACSMODTCTRL6_LSB				0
+#define CSR_ACSMODTCTRL6_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS6_LSB				0
+#define CSR_ACSMODTWRPATCS6_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS6_LSB				4
+#define CSR_ACSMODTRDPATCS6_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL7 */
+#define CSR_ACSMODTCTRL7_LSB				0
+#define CSR_ACSMODTCTRL7_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMODTWRPATCS7_LSB				0
+#define CSR_ACSMODTWRPATCS7_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDPATCS7_LSB				4
+#define CSR_ACSMODTRDPATCS7_MASK			GENMASK_32(7, 4)
+/* CSR_ACSMODTCTRL8 */
+#define CSR_ACSMODTCTRL8_LSB				0
+#define CSR_ACSMODTCTRL8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMODTWRDURCTRL_LSB			0
+#define CSR_ACSMODTWRDURCTRL_MASK			GENMASK_32(3, 0)
+#define CSR_ACSMODTRDDURCTRL_LSB			4
+#define CSR_ACSMODTRDDURCTRL_MASK			GENMASK_32(7, 4)
+#define CSR_ACSMODTWRSTRTCTRL_LSB			8
+#define CSR_ACSMODTWRSTRTCTRL_MASK			GENMASK_32(11, 8)
+#define CSR_ACSMODTRDSTRTCTRL_LSB			12
+#define CSR_ACSMODTRDSTRTCTRL_MASK			GENMASK_32(15, 12)
+/* CSR_ACSMCTRL16 */
+#define CSR_ACSMCTRL16_LSB				0
+#define CSR_ACSMCTRL16_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMDDRADRUP_LSB				0
+#define CSR_ACSMDDRADRUP_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMHIGHADDR_LSB				4
+#define CSR_ACSMHIGHADDR_MASK				BIT(4)
+#define CSR_ACSMADR13PLUGHOLE_LSB			5
+#define CSR_ACSMADR13PLUGHOLE_MASK			BIT(5)
+#define CSR_ACSMCTRL16RSVD_LSB				6
+#define CSR_ACSMCTRL16RSVD_MASK				BIT(6)
+#define CSR_ACSMWRTLVLODTCTRL_LSB			7
+#define CSR_ACSMWRTLVLODTCTRL_MASK			BIT(7)
+#define CSR_ACSMWRTLVLODT_LSB				8
+#define CSR_ACSMWRTLVLODT_MASK				GENMASK_32(11, 8)
+#define CSR_ACSM2TGRPINHIBIT_LSB			12
+#define CSR_ACSM2TGRPINHIBIT_MASK			GENMASK_32(15, 12)
+/* CSR_LOWSPEEDCLOCKSTOPVAL */
+#define CSR_LOWSPEEDCLOCKSTOPVAL_LSB			0
+#define CSR_LOWSPEEDCLOCKSTOPVAL_MASK			BIT(0)
+/* CSR_ACSMCTRL18 */
+#define CSR_ACSMCTRL18_LSB				0
+#define CSR_ACSMCTRL18_MASK				GENMASK_32(1, 0)
+#define CSR_ACSMLOCALDONE_LSB				0
+#define CSR_ACSMLOCALDONE_MASK				BIT(0)
+#define CSR_ACSMSTOPONERRASRTD_LSB			1
+#define CSR_ACSMSTOPONERRASRTD_MASK			BIT(1)
+/* CSR_ACSMCTRL19 */
+#define CSR_ACSMCTRL19_LSB				0
+#define CSR_ACSMCTRL19_MASK				GENMASK_32(2, 0)
+#define CSR_ACSMVISSEL_LSB				0
+#define CSR_ACSMVISSEL_MASK				GENMASK_32(2, 0)
+/* CSR_ACSMCTRL20 */
+#define CSR_ACSMCTRL20_LSB				0
+#define CSR_ACSMCTRL20_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMVISVAL_LSB				0
+#define CSR_ACSMVISVAL_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL21 */
+#define CSR_ACSMCTRL21_LSB				0
+#define CSR_ACSMCTRL21_MASK				GENMASK_32(11, 0)
+#define CSR_ACSMMAPDIMMCS0_LSB				0
+#define CSR_ACSMMAPDIMMCS0_MASK				GENMASK_32(2, 0)
+#define CSR_ACSMMAPDIMMCS1_LSB				3
+#define CSR_ACSMMAPDIMMCS1_MASK				GENMASK_32(5, 3)
+#define CSR_ACSMMAPDIMMCS2_LSB				6
+#define CSR_ACSMMAPDIMMCS2_MASK				GENMASK_32(8, 6)
+#define CSR_ACSMMAPDIMMCS3_LSB				9
+#define CSR_ACSMMAPDIMMCS3_MASK				GENMASK_32(11, 9)
+/* CSR_ACSMCTRL22 */
+#define CSR_ACSMCTRL22_LSB				0
+#define CSR_ACSMCTRL22_MASK				GENMASK_32(11, 0)
+#define CSR_ACSMMAPDIMMCS4_LSB				0
+#define CSR_ACSMMAPDIMMCS4_MASK				GENMASK_32(2, 0)
+#define CSR_ACSMMAPDIMMCS5_LSB				3
+#define CSR_ACSMMAPDIMMCS5_MASK				GENMASK_32(5, 3)
+#define CSR_ACSMMAPDIMMCS6_LSB				6
+#define CSR_ACSMMAPDIMMCS6_MASK				GENMASK_32(8, 6)
+#define CSR_ACSMMAPDIMMCS7_LSB				9
+#define CSR_ACSMMAPDIMMCS7_MASK				GENMASK_32(11, 9)
+/* CSR_ACSMCTRL0 */
+#define CSR_ACSMCTRL0_LSB				0
+#define CSR_ACSMCTRL0_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMRSVDCTRL00_LSB				0
+#define CSR_ACSMRSVDCTRL00_MASK				BIT(0)
+#define CSR_ACSMDYNBLMODE_LSB				1
+#define CSR_ACSMDYNBLMODE_MASK				BIT(1)
+#define CSR_ACSMBURSTLEN_LSB				2
+#define CSR_ACSMBURSTLEN_MASK				BIT(2)
+#define CSR_ACSMINFLOOP_LSB				3
+#define CSR_ACSMINFLOOP_MASK				BIT(3)
+#define CSR_ACSMRXVALMODE_LSB				4
+#define CSR_ACSMRXVALMODE_MASK				BIT(4)
+#define CSR_ACSMSTPONERRMODE_LSB			5
+#define CSR_ACSMSTPONERRMODE_MASK			BIT(5)
+#define CSR_ACSM2TMODE_LSB				6
+#define CSR_ACSM2TMODE_MASK				BIT(6)
+#define CSR_ACSMTRAINSOEMODE_LSB			7
+#define CSR_ACSMTRAINSOEMODE_MASK			BIT(7)
+#define CSR_ACSMGATEDDRCMD_LSB				8
+#define CSR_ACSMGATEDDRCMD_MASK				BIT(8)
+#define CSR_ACSMGEARDOWNMODE_LSB			9
+#define CSR_ACSMGEARDOWNMODE_MASK			BIT(9)
+#define CSR_ACSMGEARDOWNPHASE_LSB			10
+#define CSR_ACSMGEARDOWNPHASE_MASK			BIT(10)
+#define CSR_ACSMGEARDOWNSYNC_LSB			11
+#define CSR_ACSMGEARDOWNSYNC_MASK			BIT(11)
+#define CSR_ACSMCAPRBSMODE_LSB				12
+#define CSR_ACSMCAPRBSMODE_MASK				BIT(12)
+#define CSR_ACSMGATERXFIFOWRITE_LSB			13
+#define CSR_ACSMGATERXFIFOWRITE_MASK			BIT(13)
+#define CSR_ACSMPARMODE_LSB				14
+#define CSR_ACSMPARMODE_MASK				BIT(14)
+#define CSR_ACSMTDSMODE_LSB				15
+#define CSR_ACSMTDSMODE_MASK				BIT(15)
+/* CSR_ACSMCTRL1 */
+#define CSR_ACSMCTRL1_LSB				0
+#define CSR_ACSMCTRL1_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMREPCNT_LSB				0
+#define CSR_ACSMREPCNT_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL2 */
+#define CSR_ACSMCTRL2_LSB				0
+#define CSR_ACSMCTRL2_MASK				GENMASK_32(4, 0)
+#define CSR_ACSMSTARTPTR_LSB				0
+#define CSR_ACSMSTARTPTR_MASK				GENMASK_32(4, 0)
+/* CSR_ACSMCTRL3 */
+#define CSR_ACSMCTRL3_LSB				0
+#define CSR_ACSMCTRL3_MASK				GENMASK_32(4, 0)
+#define CSR_ACSMLOOPPTR_LSB				0
+#define CSR_ACSMLOOPPTR_MASK				GENMASK_32(4, 0)
+/* CSR_ACSMCTRL4 */
+#define CSR_ACSMCTRL4_LSB				0
+#define CSR_ACSMCTRL4_MASK				GENMASK_32(4, 0)
+#define CSR_ACSMENDPTR_LSB				0
+#define CSR_ACSMENDPTR_MASK				GENMASK_32(4, 0)
+/* CSR_ACSMCTRL5 */
+#define CSR_ACSMCTRL5_LSB				0
+#define CSR_ACSMCTRL5_MASK				GENMASK_32(13, 0)
+#define CSR_ACSMMXRDLAT_LSB				0
+#define CSR_ACSMMXRDLAT_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMRCASLAT_LSB				8
+#define CSR_ACSMRCASLAT_MASK				GENMASK_32(13, 8)
+/* CSR_ACSMCTRL6 */
+#define CSR_ACSMCTRL6_LSB				0
+#define CSR_ACSMCTRL6_MASK				GENMASK_32(10, 0)
+#define CSR_ACSMWCASLAT_LSB				0
+#define CSR_ACSMWCASLAT_MASK				GENMASK_32(5, 0)
+#define CSR_ACSMWRRSVD_LSB				6
+#define CSR_ACSMWRRSVD_MASK				GENMASK_32(7, 6)
+#define CSR_ACSMWRDATLAT_LSB				8
+#define CSR_ACSMWRDATLAT_MASK				GENMASK_32(10, 8)
+/* CSR_ACSMCTRL7 */
+#define CSR_ACSMCTRL7_LSB				0
+#define CSR_ACSMCTRL7_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMRASPCFG_LSB				0
+#define CSR_ACSMRASPCFG_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL8 */
+#define CSR_ACSMCTRL8_LSB				0
+#define CSR_ACSMCTRL8_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMRASPSEED_LSB				0
+#define CSR_ACSMRASPSEED_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL9 */
+#define CSR_ACSMCTRL9_LSB				0
+#define CSR_ACSMCTRL9_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCASPCFG_LSB				0
+#define CSR_ACSMCASPCFG_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL10 */
+#define CSR_ACSMCTRL10_LSB				0
+#define CSR_ACSMCTRL10_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMCASPSEED_LSB				0
+#define CSR_ACSMCASPSEED_MASK				GENMASK_32(15, 0)
+/* CSR_ACSMCTRL11 */
+#define CSR_ACSMCTRL11_LSB				0
+#define CSR_ACSMCTRL11_MASK				GENMASK_32(15, 0)
+#define CSR_ACSMRASADRINC_LSB				0
+#define CSR_ACSMRASADRINC_MASK				GENMASK_32(7, 0)
+#define CSR_ACSMCASADRINC_LSB				8
+#define CSR_ACSMCASADRINC_MASK				GENMASK_32(15, 8)
+/* CSR_ACSMCTRL12 */
+#define CSR_ACSMCTRL12_LSB				0
+#define CSR_ACSMCTRL12_MASK				GENMASK_32(11, 0)
+#define CSR_ACSMBNKPCFG_LSB				0
+#define CSR_ACSMBNKPCFG_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMBNKPSEED_LSB				4
+#define CSR_ACSMBNKPSEED_MASK				GENMASK_32(7, 4)
+#define CSR_ACSMBNKADRINC_LSB				8
+#define CSR_ACSMBNKADRINC_MASK				GENMASK_32(11, 8)
+/* CSR_ACSMCTRL13 */
+#define CSR_ACSMCTRL13_LSB				0
+#define CSR_ACSMCTRL13_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMCKEENB_LSB				0
+#define CSR_ACSMCKEENB_MASK				GENMASK_32(3, 0)
+/* CSR_ACSMCTRL14 */
+#define CSR_ACSMCTRL14_LSB				0
+#define CSR_ACSMCTRL14_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMRASPCFGUP_LSB				0
+#define CSR_ACSMRASPCFGUP_MASK				GENMASK_32(3, 0)
+/* CSR_ACSMCTRL15 */
+#define CSR_ACSMCTRL15_LSB				0
+#define CSR_ACSMCTRL15_MASK				GENMASK_32(3, 0)
+#define CSR_ACSMRASPSEEDUP_LSB				0
+#define CSR_ACSMRASPSEEDUP_MASK				GENMASK_32(3, 0)
+
+/* PPGC0 register offsets */
+/* CSR_PPGCCTRL1 */
+#define CSR_PPGCCTRL1_LSB				1
+#define CSR_PPGCCTRL1_MASK				GENMASK_32(4, 1)
+#define CSR_HWTTXDBIEN_LSB				1
+#define CSR_HWTTXDBIEN_MASK				BIT(1)
+#define CSR_HWTRXDBIEN_LSB				2
+#define CSR_HWTRXDBIEN_MASK				BIT(2)
+#define CSR_HWTTXDMDBIVAL_LSB				3
+#define CSR_HWTTXDMDBIVAL_MASK				BIT(3)
+#define CSR_HWTTXDMDBISEL_LSB				4
+#define CSR_HWTTXDMDBISEL_MASK				BIT(4)
+/* CSR_PPGCLANE2CRCINMAP0 */
+#define CSR_PPGCLANE2CRCINMAP0_LSB			0
+#define CSR_PPGCLANE2CRCINMAP0_MASK			GENMASK_32(11, 0)
+#define CSR_PPGCCRCLANEMAP0_LSB				0
+#define CSR_PPGCCRCLANEMAP0_MASK			GENMASK_32(2, 0)
+#define CSR_PPGCCRCLANEMAP1_LSB				3
+#define CSR_PPGCCRCLANEMAP1_MASK			GENMASK_32(5, 3)
+#define CSR_PPGCCRCLANEMAP2_LSB				6
+#define CSR_PPGCCRCLANEMAP2_MASK			GENMASK_32(8, 6)
+#define CSR_PPGCCRCLANEMAP3_LSB				9
+#define CSR_PPGCCRCLANEMAP3_MASK			GENMASK_32(11, 9)
+/* CSR_PPGCLANE2CRCINMAP1 */
+#define CSR_PPGCLANE2CRCINMAP1_LSB			0
+#define CSR_PPGCLANE2CRCINMAP1_MASK			GENMASK_32(11, 0)
+#define CSR_PPGCCRCLANEMAP4_LSB				0
+#define CSR_PPGCCRCLANEMAP4_MASK			GENMASK_32(2, 0)
+#define CSR_PPGCCRCLANEMAP5_LSB				3
+#define CSR_PPGCCRCLANEMAP5_MASK			GENMASK_32(5, 3)
+#define CSR_PPGCCRCLANEMAP6_LSB				6
+#define CSR_PPGCCRCLANEMAP6_MASK			GENMASK_32(8, 6)
+#define CSR_PPGCCRCLANEMAP7_LSB				9
+#define CSR_PPGCCRCLANEMAP7_MASK			GENMASK_32(11, 9)
+/* CSR_PRBSTAPDLY0 */
+#define CSR_PRBSTAPDLY0_LSB				0
+#define CSR_PRBSTAPDLY0_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSTAPDLY1 */
+#define CSR_PRBSTAPDLY1_LSB				0
+#define CSR_PRBSTAPDLY1_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSTAPDLY2 */
+#define CSR_PRBSTAPDLY2_LSB				0
+#define CSR_PRBSTAPDLY2_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSTAPDLY3 */
+#define CSR_PRBSTAPDLY3_LSB				0
+#define CSR_PRBSTAPDLY3_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE0 */
+#define CSR_GENPRBSBYTE0_LSB				0
+#define CSR_GENPRBSBYTE0_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE1² */
+#define CSR_GENPRBSBYTE1_LSB				0
+#define CSR_GENPRBSBYTE1_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE2 */
+#define CSR_GENPRBSBYTE2_LSB				0
+#define CSR_GENPRBSBYTE2_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE3 */
+#define CSR_GENPRBSBYTE3_LSB				0
+#define CSR_GENPRBSBYTE3_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE4 */
+#define CSR_GENPRBSBYTE4_LSB				0
+#define CSR_GENPRBSBYTE4_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE5 */
+#define CSR_GENPRBSBYTE5_LSB				0
+#define CSR_GENPRBSBYTE5_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE6 */
+#define CSR_GENPRBSBYTE6_LSB				0
+#define CSR_GENPRBSBYTE6_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE7 */
+#define CSR_GENPRBSBYTE7_LSB				0
+#define CSR_GENPRBSBYTE7_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE8 */
+#define CSR_GENPRBSBYTE8_LSB				0
+#define CSR_GENPRBSBYTE8_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE9 */
+#define CSR_GENPRBSBYTE9_LSB				0
+#define CSR_GENPRBSBYTE9_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE10 */
+#define CSR_GENPRBSBYTE10_LSB				0
+#define CSR_GENPRBSBYTE10_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE11 */
+#define CSR_GENPRBSBYTE11_LSB				0
+#define CSR_GENPRBSBYTE11_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE12 */
+#define CSR_GENPRBSBYTE12_LSB				0
+#define CSR_GENPRBSBYTE12_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE13 */
+#define CSR_GENPRBSBYTE13_LSB				0
+#define CSR_GENPRBSBYTE13_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE14 */
+#define CSR_GENPRBSBYTE14_LSB				0
+#define CSR_GENPRBSBYTE14_MASK				GENMASK_32(15, 0)
+/* CSR_GENPRBSBYTE15 */
+#define CSR_GENPRBSBYTE15_LSB				0
+#define CSR_GENPRBSBYTE15_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSGENCTL */
+#define CSR_PRBSGENCTL_LSB				0
+#define CSR_PRBSGENCTL_MASK				GENMASK_32(6, 0)
+#define CSR_PPGCMODE_LSB				0
+#define CSR_PPGCMODE_MASK				BIT(0)
+#define CSR_PPGCDMMODE_LSB				1
+#define CSR_PPGCDMMODE_MASK				BIT(1)
+#define CSR_PPGCLDFFMODE_LSB				2
+#define CSR_PPGCLDFFMODE_MASK				BIT(2)
+#define CSR_PPGCSEL23BPRBS_LSB				3
+#define CSR_PPGCSEL23BPRBS_MASK				BIT(3)
+#define CSR_PPGCPATADV_LSB				4
+#define CSR_PPGCPATADV_MASK				GENMASK_32(5, 4)
+#define CSR_PPGCENBPATSTRESSMODE_LSB			6
+#define CSR_PPGCENBPATSTRESSMODE_MASK			BIT(6)
+/* CSR_PRBSGENSTATELO */
+#define CSR_PRBSGENSTATELO_LSB				0
+#define CSR_PRBSGENSTATELO_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSGENSTATEHI */
+#define CSR_PRBSGENSTATEHI_LSB				0
+#define CSR_PRBSGENSTATEHI_MASK				GENMASK_32(6, 0)
+/* CSR_PRBSCHKSTATELO */
+#define CSR_PRBSCHKSTATELO_LSB				0
+#define CSR_PRBSCHKSTATELO_MASK				GENMASK_32(15, 0)
+/* CSR_PRBSCHKSTATEHI */
+#define CSR_PRBSCHKSTATEHI_LSB				0
+#define CSR_PRBSCHKSTATEHI_MASK				GENMASK_32(6, 0)
+/* CSR_PRBSGENCTL1 */
+#define CSR_PRBSGENCTL1_LSB				0
+#define CSR_PRBSGENCTL1_MASK				GENMASK_32(8, 0)
+#define CSR_PPGCMODELANE_LSB				0
+#define CSR_PPGCMODELANE_MASK				GENMASK_32(8, 0)
+/* CSR_PRBSGENCTL2 */
+#define CSR_PRBSGENCTL2_LSB				0
+#define CSR_PRBSGENCTL2_MASK				GENMASK_32(15, 0)
+#define CSR_PPGCMSKPERIODLIM_LSB			0
+#define CSR_PPGCMSKPERIODLIM_MASK			GENMASK_32(15, 0)
+
+/* INITENG0 register offsets */
+/* CSR_PRESEQUENCEREG0B0S0 */
+#define CSR_PRESEQUENCEREG0B0S0_LSB			0
+#define CSR_PRESEQUENCEREG0B0S0_MASK			GENMASK_32(15, 0)
+/* CSR_PRESEQUENCEREG0B0S1 */
+#define CSR_PRESEQUENCEREG0B0S1_LSB			0
+#define CSR_PRESEQUENCEREG0B0S1_MASK			GENMASK_32(15, 0)
+/* CSR_PRESEQUENCEREG0B0S2 */
+#define CSR_PRESEQUENCEREG0B0S2_LSB			0
+#define CSR_PRESEQUENCEREG0B0S2_MASK			GENMASK_32(8, 0)
+/* CSR_PRESEQUENCEREG0B1S0 */
+#define CSR_PRESEQUENCEREG0B1S0_LSB			0
+#define CSR_PRESEQUENCEREG0B1S0_MASK			GENMASK_32(15, 0)
+/* CSR_PRESEQUENCEREG0B1S1 */
+#define CSR_PRESEQUENCEREG0B1S1_LSB			0
+#define CSR_PRESEQUENCEREG0B1S1_MASK			GENMASK_32(15, 0)
+/* CSR_PRESEQUENCEREG0B1S2 */
+#define CSR_PRESEQUENCEREG0B1S2_LSB			0
+#define CSR_PRESEQUENCEREG0B1S2_MASK			GENMASK_32(8, 0)
+/* CSR_POSTSEQUENCEREG0B0S0 */
+#define CSR_POSTSEQUENCEREG0B0S0_LSB			0
+#define CSR_POSTSEQUENCEREG0B0S0_MASK			GENMASK_32(15, 0)
+/* CSR_POSTSEQUENCEREG0B0S1 */
+#define CSR_POSTSEQUENCEREG0B0S1_LSB			0
+#define CSR_POSTSEQUENCEREG0B0S1_MASK			GENMASK_32(15, 0)
+/* CSR_POSTSEQUENCEREG0B0S2 */
+#define CSR_POSTSEQUENCEREG0B0S2_LSB			0
+#define CSR_POSTSEQUENCEREG0B0S2_MASK			GENMASK_32(8, 0)
+/* CSR_POSTSEQUENCEREG0B1S0 */
+#define CSR_POSTSEQUENCEREG0B1S0_LSB			0
+#define CSR_POSTSEQUENCEREG0B1S0_MASK			GENMASK_32(15, 0)
+/* CSR_POSTSEQUENCEREG0B1S1 */
+#define CSR_POSTSEQUENCEREG0B1S1_LSB			0
+#define CSR_POSTSEQUENCEREG0B1S1_MASK			GENMASK_32(15, 0)
+/* CSR_POSTSEQUENCEREG0B1S2 */
+#define CSR_POSTSEQUENCEREG0B1S2_LSB			0
+#define CSR_POSTSEQUENCEREG0B1S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQ0BDISABLEFLAG0 */
+#define CSR_SEQ0BDISABLEFLAG0_LSB			0
+#define CSR_SEQ0BDISABLEFLAG0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG1 */
+#define CSR_SEQ0BDISABLEFLAG1_LSB			0
+#define CSR_SEQ0BDISABLEFLAG1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG2 */
+#define CSR_SEQ0BDISABLEFLAG2_LSB			0
+#define CSR_SEQ0BDISABLEFLAG2_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG3 */
+#define CSR_SEQ0BDISABLEFLAG3_LSB			0
+#define CSR_SEQ0BDISABLEFLAG3_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG4 */
+#define CSR_SEQ0BDISABLEFLAG4_LSB			0
+#define CSR_SEQ0BDISABLEFLAG4_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG5 */
+#define CSR_SEQ0BDISABLEFLAG5_LSB			0
+#define CSR_SEQ0BDISABLEFLAG5_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG6 */
+#define CSR_SEQ0BDISABLEFLAG6_LSB			0
+#define CSR_SEQ0BDISABLEFLAG6_MASK			GENMASK_32(15, 0)
+/* CSR_SEQ0BDISABLEFLAG7 */
+#define CSR_SEQ0BDISABLEFLAG7_LSB			0
+#define CSR_SEQ0BDISABLEFLAG7_MASK			GENMASK_32(15, 0)
+/* CSR_STARTVECTOR0B0 */
+#define CSR_STARTVECTOR0B0_LSB				0
+#define CSR_STARTVECTOR0B0_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC0_LSB				0
+#define CSR_SEQ0BSTARTVEC0_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B1 */
+#define CSR_STARTVECTOR0B1_LSB				0
+#define CSR_STARTVECTOR0B1_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC1_LSB				0
+#define CSR_SEQ0BSTARTVEC1_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B2 */
+#define CSR_STARTVECTOR0B2_LSB				0
+#define CSR_STARTVECTOR0B2_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC2_LSB				0
+#define CSR_SEQ0BSTARTVEC2_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B3 */
+#define CSR_STARTVECTOR0B3_LSB				0
+#define CSR_STARTVECTOR0B3_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC3_LSB				0
+#define CSR_SEQ0BSTARTVEC3_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B4 */
+#define CSR_STARTVECTOR0B4_LSB				0
+#define CSR_STARTVECTOR0B4_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC4_LSB				0
+#define CSR_SEQ0BSTARTVEC4_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B5 */
+#define CSR_STARTVECTOR0B5_LSB				0
+#define CSR_STARTVECTOR0B5_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC5_LSB				0
+#define CSR_SEQ0BSTARTVEC5_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B6 */
+#define CSR_STARTVECTOR0B6_LSB				0
+#define CSR_STARTVECTOR0B6_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC6_LSB				0
+#define CSR_SEQ0BSTARTVEC6_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B7 */
+#define CSR_STARTVECTOR0B7_LSB				0
+#define CSR_STARTVECTOR0B7_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC7_LSB				0
+#define CSR_SEQ0BSTARTVEC7_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B8 */
+#define CSR_STARTVECTOR0B8_LSB				0
+#define CSR_STARTVECTOR0B8_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC8_LSB				0
+#define CSR_SEQ0BSTARTVEC8_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B9 */
+#define CSR_STARTVECTOR0B9_LSB				0
+#define CSR_STARTVECTOR0B9_MASK				GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC9_LSB				0
+#define CSR_SEQ0BSTARTVEC9_MASK				GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B10 */
+#define CSR_STARTVECTOR0B10_LSB				0
+#define CSR_STARTVECTOR0B10_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC10_LSB				0
+#define CSR_SEQ0BSTARTVEC10_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B11 */
+#define CSR_STARTVECTOR0B11_LSB				0
+#define CSR_STARTVECTOR0B11_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC11_LSB				0
+#define CSR_SEQ0BSTARTVEC11_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B12 */
+#define CSR_STARTVECTOR0B12_LSB				0
+#define CSR_STARTVECTOR0B12_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC12_LSB				0
+#define CSR_SEQ0BSTARTVEC12_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B13 */
+#define CSR_STARTVECTOR0B13_LSB				0
+#define CSR_STARTVECTOR0B13_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC13_LSB				0
+#define CSR_SEQ0BSTARTVEC13_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B14 */
+#define CSR_STARTVECTOR0B14_LSB				0
+#define CSR_STARTVECTOR0B14_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC14_LSB				0
+#define CSR_SEQ0BSTARTVEC14_MASK			GENMASK_32(6, 0)
+/* CSR_STARTVECTOR0B15 */
+#define CSR_STARTVECTOR0B15_LSB				0
+#define CSR_STARTVECTOR0B15_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BSTARTVEC15_LSB				0
+#define CSR_SEQ0BSTARTVEC15_MASK			GENMASK_32(6, 0)
+/* CSR_SEQ0BWAITCONDSEL */
+#define CSR_SEQ0BWAITCONDSEL_LSB			0
+#define CSR_SEQ0BWAITCONDSEL_MASK			GENMASK_32(2, 0)
+/* CSR_PHYINLP3 */
+#define CSR_PHYINLP3_LSB				0
+#define CSR_PHYINLP3_MASK				BIT(0)
+/* CSR_SEQUENCEREG0B0S0 */
+#define CSR_SEQUENCEREG0B0S0_LSB			0
+#define CSR_SEQUENCEREG0B0S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B0S1 */
+#define CSR_SEQUENCEREG0B0S1_LSB			0
+#define CSR_SEQUENCEREG0B0S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B0S2 */
+#define CSR_SEQUENCEREG0B0S2_LSB			0
+#define CSR_SEQUENCEREG0B0S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B1S0 */
+#define CSR_SEQUENCEREG0B1S0_LSB			0
+#define CSR_SEQUENCEREG0B1S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B1S1 */
+#define CSR_SEQUENCEREG0B1S1_LSB			0
+#define CSR_SEQUENCEREG0B1S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B1S2 */
+#define CSR_SEQUENCEREG0B1S2_LSB			0
+#define CSR_SEQUENCEREG0B1S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B2S0 */
+#define CSR_SEQUENCEREG0B2S0_LSB			0
+#define CSR_SEQUENCEREG0B2S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B2S1 */
+#define CSR_SEQUENCEREG0B2S1_LSB			0
+#define CSR_SEQUENCEREG0B2S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B2S2 */
+#define CSR_SEQUENCEREG0B2S2_LSB			0
+#define CSR_SEQUENCEREG0B2S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B3S0 */
+#define CSR_SEQUENCEREG0B3S0_LSB			0
+#define CSR_SEQUENCEREG0B3S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B3S1 */
+#define CSR_SEQUENCEREG0B3S1_LSB			0
+#define CSR_SEQUENCEREG0B3S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B3S2 */
+#define CSR_SEQUENCEREG0B3S2_LSB			0
+#define CSR_SEQUENCEREG0B3S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B4S0 */
+#define CSR_SEQUENCEREG0B4S0_LSB			0
+#define CSR_SEQUENCEREG0B4S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B4S1 */
+#define CSR_SEQUENCEREG0B4S1_LSB			0
+#define CSR_SEQUENCEREG0B4S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B4S2 */
+#define CSR_SEQUENCEREG0B4S2_LSB			0
+#define CSR_SEQUENCEREG0B4S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B5S0 */
+#define CSR_SEQUENCEREG0B5S0_LSB			0
+#define CSR_SEQUENCEREG0B5S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B5S1 */
+#define CSR_SEQUENCEREG0B5S1_LSB			0
+#define CSR_SEQUENCEREG0B5S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B5S2 */
+#define CSR_SEQUENCEREG0B5S2_LSB			0
+#define CSR_SEQUENCEREG0B5S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B6S0 */
+#define CSR_SEQUENCEREG0B6S0_LSB			0
+#define CSR_SEQUENCEREG0B6S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B6S1 */
+#define CSR_SEQUENCEREG0B6S1_LSB			0
+#define CSR_SEQUENCEREG0B6S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B6S2 */
+#define CSR_SEQUENCEREG0B6S2_LSB			0
+#define CSR_SEQUENCEREG0B6S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B7S0 */
+#define CSR_SEQUENCEREG0B7S0_LSB			0
+#define CSR_SEQUENCEREG0B7S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B7S1 */
+#define CSR_SEQUENCEREG0B7S1_LSB			0
+#define CSR_SEQUENCEREG0B7S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B7S2 */
+#define CSR_SEQUENCEREG0B7S2_LSB			0
+#define CSR_SEQUENCEREG0B7S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B8S0 */
+#define CSR_SEQUENCEREG0B8S0_LSB			0
+#define CSR_SEQUENCEREG0B8S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B8S1 */
+#define CSR_SEQUENCEREG0B8S1_LSB			0
+#define CSR_SEQUENCEREG0B8S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B8S2 */
+#define CSR_SEQUENCEREG0B8S2_LSB			0
+#define CSR_SEQUENCEREG0B8S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B9S0 */
+#define CSR_SEQUENCEREG0B9S0_LSB			0
+#define CSR_SEQUENCEREG0B9S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B9S1 */
+#define CSR_SEQUENCEREG0B9S1_LSB			0
+#define CSR_SEQUENCEREG0B9S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B9S2 */
+#define CSR_SEQUENCEREG0B9S2_LSB			0
+#define CSR_SEQUENCEREG0B9S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B10S0 */
+#define CSR_SEQUENCEREG0B10S0_LSB			0
+#define CSR_SEQUENCEREG0B10S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B10S1 */
+#define CSR_SEQUENCEREG0B10S1_LSB			0
+#define CSR_SEQUENCEREG0B10S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B10S2 */
+#define CSR_SEQUENCEREG0B10S2_LSB			0
+#define CSR_SEQUENCEREG0B10S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B11S0 */
+#define CSR_SEQUENCEREG0B11S0_LSB			0
+#define CSR_SEQUENCEREG0B11S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B11S1 */
+#define CSR_SEQUENCEREG0B11S1_LSB			0
+#define CSR_SEQUENCEREG0B11S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B11S2 */
+#define CSR_SEQUENCEREG0B11S2_LSB			0
+#define CSR_SEQUENCEREG0B11S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B12S0 */
+#define CSR_SEQUENCEREG0B12S0_LSB			0
+#define CSR_SEQUENCEREG0B12S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B12S1 */
+#define CSR_SEQUENCEREG0B12S1_LSB			0
+#define CSR_SEQUENCEREG0B12S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B12S2 */
+#define CSR_SEQUENCEREG0B12S2_LSB			0
+#define CSR_SEQUENCEREG0B12S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B13S0 */
+#define CSR_SEQUENCEREG0B13S0_LSB			0
+#define CSR_SEQUENCEREG0B13S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B13S1 */
+#define CSR_SEQUENCEREG0B13S1_LSB			0
+#define CSR_SEQUENCEREG0B13S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B13S2 */
+#define CSR_SEQUENCEREG0B13S2_LSB			0
+#define CSR_SEQUENCEREG0B13S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B14S0 */
+#define CSR_SEQUENCEREG0B14S0_LSB			0
+#define CSR_SEQUENCEREG0B14S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B14S1 */
+#define CSR_SEQUENCEREG0B14S1_LSB			0
+#define CSR_SEQUENCEREG0B14S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B14S2 */
+#define CSR_SEQUENCEREG0B14S2_LSB			0
+#define CSR_SEQUENCEREG0B14S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B15S0 */
+#define CSR_SEQUENCEREG0B15S0_LSB			0
+#define CSR_SEQUENCEREG0B15S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B15S1 */
+#define CSR_SEQUENCEREG0B15S1_LSB			0
+#define CSR_SEQUENCEREG0B15S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B15S2 */
+#define CSR_SEQUENCEREG0B15S2_LSB			0
+#define CSR_SEQUENCEREG0B15S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B16S0 */
+#define CSR_SEQUENCEREG0B16S0_LSB			0
+#define CSR_SEQUENCEREG0B16S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B16S1 */
+#define CSR_SEQUENCEREG0B16S1_LSB			0
+#define CSR_SEQUENCEREG0B16S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B16S2 */
+#define CSR_SEQUENCEREG0B16S2_LSB			0
+#define CSR_SEQUENCEREG0B16S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B17S0 */
+#define CSR_SEQUENCEREG0B17S0_LSB			0
+#define CSR_SEQUENCEREG0B17S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B17S1 */
+#define CSR_SEQUENCEREG0B17S1_LSB			0
+#define CSR_SEQUENCEREG0B17S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B17S2 */
+#define CSR_SEQUENCEREG0B17S2_LSB			0
+#define CSR_SEQUENCEREG0B17S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B18S0 */
+#define CSR_SEQUENCEREG0B18S0_LSB			0
+#define CSR_SEQUENCEREG0B18S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B18S1 */
+#define CSR_SEQUENCEREG0B18S1_LSB			0
+#define CSR_SEQUENCEREG0B18S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B18S2 */
+#define CSR_SEQUENCEREG0B18S2_LSB			0
+#define CSR_SEQUENCEREG0B18S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B19S0 */
+#define CSR_SEQUENCEREG0B19S0_LSB			0
+#define CSR_SEQUENCEREG0B19S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B19S1 */
+#define CSR_SEQUENCEREG0B19S1_LSB			0
+#define CSR_SEQUENCEREG0B19S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B19S2 */
+#define CSR_SEQUENCEREG0B19S2_LSB			0
+#define CSR_SEQUENCEREG0B19S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B20S0 */
+#define CSR_SEQUENCEREG0B20S0_LSB			0
+#define CSR_SEQUENCEREG0B20S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B20S1 */
+#define CSR_SEQUENCEREG0B20S1_LSB			0
+#define CSR_SEQUENCEREG0B20S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B20S2 */
+#define CSR_SEQUENCEREG0B20S2_LSB			0
+#define CSR_SEQUENCEREG0B20S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B21S0 */
+#define CSR_SEQUENCEREG0B21S0_LSB			0
+#define CSR_SEQUENCEREG0B21S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B21S1 */
+#define CSR_SEQUENCEREG0B21S1_LSB			0
+#define CSR_SEQUENCEREG0B21S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B21S2 */
+#define CSR_SEQUENCEREG0B21S2_LSB			0
+#define CSR_SEQUENCEREG0B21S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B22S0 */
+#define CSR_SEQUENCEREG0B22S0_LSB			0
+#define CSR_SEQUENCEREG0B22S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B22S1 */
+#define CSR_SEQUENCEREG0B22S1_LSB			0
+#define CSR_SEQUENCEREG0B22S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B22S2 */
+#define CSR_SEQUENCEREG0B22S2_LSB			0
+#define CSR_SEQUENCEREG0B22S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B23S0 */
+#define CSR_SEQUENCEREG0B23S0_LSB			0
+#define CSR_SEQUENCEREG0B23S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B23S1 */
+#define CSR_SEQUENCEREG0B23S1_LSB			0
+#define CSR_SEQUENCEREG0B23S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B23S2 */
+#define CSR_SEQUENCEREG0B23S2_LSB			0
+#define CSR_SEQUENCEREG0B23S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B24S0 */
+#define CSR_SEQUENCEREG0B24S0_LSB			0
+#define CSR_SEQUENCEREG0B24S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B24S1 */
+#define CSR_SEQUENCEREG0B24S1_LSB			0
+#define CSR_SEQUENCEREG0B24S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B24S2 */
+#define CSR_SEQUENCEREG0B24S2_LSB			0
+#define CSR_SEQUENCEREG0B24S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B25S0 */
+#define CSR_SEQUENCEREG0B25S0_LSB			0
+#define CSR_SEQUENCEREG0B25S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B25S1 */
+#define CSR_SEQUENCEREG0B25S1_LSB			0
+#define CSR_SEQUENCEREG0B25S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B25S2 */
+#define CSR_SEQUENCEREG0B25S2_LSB			0
+#define CSR_SEQUENCEREG0B25S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B26S0 */
+#define CSR_SEQUENCEREG0B26S0_LSB			0
+#define CSR_SEQUENCEREG0B26S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B26S1 */
+#define CSR_SEQUENCEREG0B26S1_LSB			0
+#define CSR_SEQUENCEREG0B26S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B26S2 */
+#define CSR_SEQUENCEREG0B26S2_LSB			0
+#define CSR_SEQUENCEREG0B26S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B27S0 */
+#define CSR_SEQUENCEREG0B27S0_LSB			0
+#define CSR_SEQUENCEREG0B27S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B27S1 */
+#define CSR_SEQUENCEREG0B27S1_LSB			0
+#define CSR_SEQUENCEREG0B27S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B27S2 */
+#define CSR_SEQUENCEREG0B27S2_LSB			0
+#define CSR_SEQUENCEREG0B27S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B28S0 */
+#define CSR_SEQUENCEREG0B28S0_LSB			0
+#define CSR_SEQUENCEREG0B28S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B28S1 */
+#define CSR_SEQUENCEREG0B28S1_LSB			0
+#define CSR_SEQUENCEREG0B28S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B28S2 */
+#define CSR_SEQUENCEREG0B28S2_LSB			0
+#define CSR_SEQUENCEREG0B28S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B29S0 */
+#define CSR_SEQUENCEREG0B29S0_LSB			0
+#define CSR_SEQUENCEREG0B29S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B29S1 */
+#define CSR_SEQUENCEREG0B29S1_LSB			0
+#define CSR_SEQUENCEREG0B29S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B29S2 */
+#define CSR_SEQUENCEREG0B29S2_LSB			0
+#define CSR_SEQUENCEREG0B29S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B30S0 */
+#define CSR_SEQUENCEREG0B30S0_LSB			0
+#define CSR_SEQUENCEREG0B30S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B30S1 */
+#define CSR_SEQUENCEREG0B30S1_LSB			0
+#define CSR_SEQUENCEREG0B30S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B30S2 */
+#define CSR_SEQUENCEREG0B30S2_LSB			0
+#define CSR_SEQUENCEREG0B30S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B31S0 */
+#define CSR_SEQUENCEREG0B31S0_LSB			0
+#define CSR_SEQUENCEREG0B31S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B31S1 */
+#define CSR_SEQUENCEREG0B31S1_LSB			0
+#define CSR_SEQUENCEREG0B31S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B31S2 */
+#define CSR_SEQUENCEREG0B31S2_LSB			0
+#define CSR_SEQUENCEREG0B31S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B32S0 */
+#define CSR_SEQUENCEREG0B32S0_LSB			0
+#define CSR_SEQUENCEREG0B32S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B32S1 */
+#define CSR_SEQUENCEREG0B32S1_LSB			0
+#define CSR_SEQUENCEREG0B32S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B32S2 */
+#define CSR_SEQUENCEREG0B32S2_LSB			0
+#define CSR_SEQUENCEREG0B32S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B33S0 */
+#define CSR_SEQUENCEREG0B33S0_LSB			0
+#define CSR_SEQUENCEREG0B33S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B33S1 */
+#define CSR_SEQUENCEREG0B33S1_LSB			0
+#define CSR_SEQUENCEREG0B33S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B33S2 */
+#define CSR_SEQUENCEREG0B33S2_LSB			0
+#define CSR_SEQUENCEREG0B33S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B34S0 */
+#define CSR_SEQUENCEREG0B34S0_LSB			0
+#define CSR_SEQUENCEREG0B34S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B34S1 */
+#define CSR_SEQUENCEREG0B34S1_LSB			0
+#define CSR_SEQUENCEREG0B34S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B34S2 */
+#define CSR_SEQUENCEREG0B34S2_LSB			0
+#define CSR_SEQUENCEREG0B34S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B35S0 */
+#define CSR_SEQUENCEREG0B35S0_LSB			0
+#define CSR_SEQUENCEREG0B35S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B35S1 */
+#define CSR_SEQUENCEREG0B35S1_LSB			0
+#define CSR_SEQUENCEREG0B35S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B35S2 */
+#define CSR_SEQUENCEREG0B35S2_LSB			0
+#define CSR_SEQUENCEREG0B35S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B36S0 */
+#define CSR_SEQUENCEREG0B36S0_LSB			0
+#define CSR_SEQUENCEREG0B36S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B36S1 */
+#define CSR_SEQUENCEREG0B36S1_LSB			0
+#define CSR_SEQUENCEREG0B36S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B36S2 */
+#define CSR_SEQUENCEREG0B36S2_LSB			0
+#define CSR_SEQUENCEREG0B36S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B37S0 */
+#define CSR_SEQUENCEREG0B37S0_LSB			0
+#define CSR_SEQUENCEREG0B37S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B37S1 */
+#define CSR_SEQUENCEREG0B37S1_LSB			0
+#define CSR_SEQUENCEREG0B37S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B37S2 */
+#define CSR_SEQUENCEREG0B37S2_LSB			0
+#define CSR_SEQUENCEREG0B37S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B38S0 */
+#define CSR_SEQUENCEREG0B38S0_LSB			0
+#define CSR_SEQUENCEREG0B38S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B38S1 */
+#define CSR_SEQUENCEREG0B38S1_LSB			0
+#define CSR_SEQUENCEREG0B38S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B38S2 */
+#define CSR_SEQUENCEREG0B38S2_LSB			0
+#define CSR_SEQUENCEREG0B38S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B39S0 */
+#define CSR_SEQUENCEREG0B39S0_LSB			0
+#define CSR_SEQUENCEREG0B39S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B39S1 */
+#define CSR_SEQUENCEREG0B39S1_LSB			0
+#define CSR_SEQUENCEREG0B39S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B39S2 */
+#define CSR_SEQUENCEREG0B39S2_LSB			0
+#define CSR_SEQUENCEREG0B39S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B40S0 */
+#define CSR_SEQUENCEREG0B40S0_LSB			0
+#define CSR_SEQUENCEREG0B40S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B40S1 */
+#define CSR_SEQUENCEREG0B40S1_LSB			0
+#define CSR_SEQUENCEREG0B40S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B40S2 */
+#define CSR_SEQUENCEREG0B40S2_LSB			0
+#define CSR_SEQUENCEREG0B40S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B41S0 */
+#define CSR_SEQUENCEREG0B41S0_LSB			0
+#define CSR_SEQUENCEREG0B41S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B41S1 */
+#define CSR_SEQUENCEREG0B41S1_LSB			0
+#define CSR_SEQUENCEREG0B41S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B41S2 */
+#define CSR_SEQUENCEREG0B41S2_LSB			0
+#define CSR_SEQUENCEREG0B41S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B42S0 */
+#define CSR_SEQUENCEREG0B42S0_LSB			0
+#define CSR_SEQUENCEREG0B42S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B42S1 */
+#define CSR_SEQUENCEREG0B42S1_LSB			0
+#define CSR_SEQUENCEREG0B42S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B42S2 */
+#define CSR_SEQUENCEREG0B42S2_LSB			0
+#define CSR_SEQUENCEREG0B42S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B43S0 */
+#define CSR_SEQUENCEREG0B43S0_LSB			0
+#define CSR_SEQUENCEREG0B43S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B43S1 */
+#define CSR_SEQUENCEREG0B43S1_LSB			0
+#define CSR_SEQUENCEREG0B43S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B43S2 */
+#define CSR_SEQUENCEREG0B43S2_LSB			0
+#define CSR_SEQUENCEREG0B43S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B44S0 */
+#define CSR_SEQUENCEREG0B44S0_LSB			0
+#define CSR_SEQUENCEREG0B44S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B44S1 */
+#define CSR_SEQUENCEREG0B44S1_LSB			0
+#define CSR_SEQUENCEREG0B44S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B44S2 */
+#define CSR_SEQUENCEREG0B44S2_LSB			0
+#define CSR_SEQUENCEREG0B44S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B45S0 */
+#define CSR_SEQUENCEREG0B45S0_LSB			0
+#define CSR_SEQUENCEREG0B45S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B45S1 */
+#define CSR_SEQUENCEREG0B45S1_LSB			0
+#define CSR_SEQUENCEREG0B45S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B45S2 */
+#define CSR_SEQUENCEREG0B45S2_LSB			0
+#define CSR_SEQUENCEREG0B45S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B46S0 */
+#define CSR_SEQUENCEREG0B46S0_LSB			0
+#define CSR_SEQUENCEREG0B46S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B46S1 */
+#define CSR_SEQUENCEREG0B46S1_LSB			0
+#define CSR_SEQUENCEREG0B46S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B46S2 */
+#define CSR_SEQUENCEREG0B46S2_LSB			0
+#define CSR_SEQUENCEREG0B46S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B47S0 */
+#define CSR_SEQUENCEREG0B47S0_LSB			0
+#define CSR_SEQUENCEREG0B47S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B47S1 */
+#define CSR_SEQUENCEREG0B47S1_LSB			0
+#define CSR_SEQUENCEREG0B47S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B47S2 */
+#define CSR_SEQUENCEREG0B47S2_LSB			0
+#define CSR_SEQUENCEREG0B47S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B48S0 */
+#define CSR_SEQUENCEREG0B48S0_LSB			0
+#define CSR_SEQUENCEREG0B48S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B48S1 */
+#define CSR_SEQUENCEREG0B48S1_LSB			0
+#define CSR_SEQUENCEREG0B48S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B48S2 */
+#define CSR_SEQUENCEREG0B48S2_LSB			0
+#define CSR_SEQUENCEREG0B48S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B49S0 */
+#define CSR_SEQUENCEREG0B49S0_LSB			0
+#define CSR_SEQUENCEREG0B49S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B49S1 */
+#define CSR_SEQUENCEREG0B49S1_LSB			0
+#define CSR_SEQUENCEREG0B49S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B49S2 */
+#define CSR_SEQUENCEREG0B49S2_LSB			0
+#define CSR_SEQUENCEREG0B49S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B50S0 */
+#define CSR_SEQUENCEREG0B50S0_LSB			0
+#define CSR_SEQUENCEREG0B50S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B50S1 */
+#define CSR_SEQUENCEREG0B50S1_LSB			0
+#define CSR_SEQUENCEREG0B50S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B50S2 */
+#define CSR_SEQUENCEREG0B50S2_LSB			0
+#define CSR_SEQUENCEREG0B50S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B51S0 */
+#define CSR_SEQUENCEREG0B51S0_LSB			0
+#define CSR_SEQUENCEREG0B51S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B51S1 */
+#define CSR_SEQUENCEREG0B51S1_LSB			0
+#define CSR_SEQUENCEREG0B51S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B51S2 */
+#define CSR_SEQUENCEREG0B51S2_LSB			0
+#define CSR_SEQUENCEREG0B51S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B52S0 */
+#define CSR_SEQUENCEREG0B52S0_LSB			0
+#define CSR_SEQUENCEREG0B52S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B52S1 */
+#define CSR_SEQUENCEREG0B52S1_LSB			0
+#define CSR_SEQUENCEREG0B52S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B52S2 */
+#define CSR_SEQUENCEREG0B52S2_LSB			0
+#define CSR_SEQUENCEREG0B52S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B53S0 */
+#define CSR_SEQUENCEREG0B53S0_LSB			0
+#define CSR_SEQUENCEREG0B53S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B53S1 */
+#define CSR_SEQUENCEREG0B53S1_LSB			0
+#define CSR_SEQUENCEREG0B53S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B53S2 */
+#define CSR_SEQUENCEREG0B53S2_LSB			0
+#define CSR_SEQUENCEREG0B53S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B54S0 */
+#define CSR_SEQUENCEREG0B54S0_LSB			0
+#define CSR_SEQUENCEREG0B54S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B54S1 */
+#define CSR_SEQUENCEREG0B54S1_LSB			0
+#define CSR_SEQUENCEREG0B54S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B54S2 */
+#define CSR_SEQUENCEREG0B54S2_LSB			0
+#define CSR_SEQUENCEREG0B54S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B55S0 */
+#define CSR_SEQUENCEREG0B55S0_LSB			0
+#define CSR_SEQUENCEREG0B55S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B55S1 */
+#define CSR_SEQUENCEREG0B55S1_LSB			0
+#define CSR_SEQUENCEREG0B55S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B55S2 */
+#define CSR_SEQUENCEREG0B55S2_LSB			0
+#define CSR_SEQUENCEREG0B55S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B56S0 */
+#define CSR_SEQUENCEREG0B56S0_LSB			0
+#define CSR_SEQUENCEREG0B56S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B56S1 */
+#define CSR_SEQUENCEREG0B56S1_LSB			0
+#define CSR_SEQUENCEREG0B56S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B56S2 */
+#define CSR_SEQUENCEREG0B56S2_LSB			0
+#define CSR_SEQUENCEREG0B56S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B57S0 */
+#define CSR_SEQUENCEREG0B57S0_LSB			0
+#define CSR_SEQUENCEREG0B57S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B57S1 */
+#define CSR_SEQUENCEREG0B57S1_LSB			0
+#define CSR_SEQUENCEREG0B57S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B57S2 */
+#define CSR_SEQUENCEREG0B57S2_LSB			0
+#define CSR_SEQUENCEREG0B57S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B58S0 */
+#define CSR_SEQUENCEREG0B58S0_LSB			0
+#define CSR_SEQUENCEREG0B58S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B58S1 */
+#define CSR_SEQUENCEREG0B58S1_LSB			0
+#define CSR_SEQUENCEREG0B58S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B58S2 */
+#define CSR_SEQUENCEREG0B58S2_LSB			0
+#define CSR_SEQUENCEREG0B58S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B59S0 */
+#define CSR_SEQUENCEREG0B59S0_LSB			0
+#define CSR_SEQUENCEREG0B59S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B59S1 */
+#define CSR_SEQUENCEREG0B59S1_LSB			0
+#define CSR_SEQUENCEREG0B59S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B59S2 */
+#define CSR_SEQUENCEREG0B59S2_LSB			0
+#define CSR_SEQUENCEREG0B59S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B60S0 */
+#define CSR_SEQUENCEREG0B60S0_LSB			0
+#define CSR_SEQUENCEREG0B60S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B60S1 */
+#define CSR_SEQUENCEREG0B60S1_LSB			0
+#define CSR_SEQUENCEREG0B60S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B60S2 */
+#define CSR_SEQUENCEREG0B60S2_LSB			0
+#define CSR_SEQUENCEREG0B60S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B61S0 */
+#define CSR_SEQUENCEREG0B61S0_LSB			0
+#define CSR_SEQUENCEREG0B61S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B61S1 */
+#define CSR_SEQUENCEREG0B61S1_LSB			0
+#define CSR_SEQUENCEREG0B61S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B61S2 */
+#define CSR_SEQUENCEREG0B61S2_LSB			0
+#define CSR_SEQUENCEREG0B61S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B62S0 */
+#define CSR_SEQUENCEREG0B62S0_LSB			0
+#define CSR_SEQUENCEREG0B62S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B62S1 */
+#define CSR_SEQUENCEREG0B62S1_LSB			0
+#define CSR_SEQUENCEREG0B62S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B62S2 */
+#define CSR_SEQUENCEREG0B62S2_LSB			0
+#define CSR_SEQUENCEREG0B62S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B63S0 */
+#define CSR_SEQUENCEREG0B63S0_LSB			0
+#define CSR_SEQUENCEREG0B63S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B63S1 */
+#define CSR_SEQUENCEREG0B63S1_LSB			0
+#define CSR_SEQUENCEREG0B63S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B63S2 */
+#define CSR_SEQUENCEREG0B63S2_LSB			0
+#define CSR_SEQUENCEREG0B63S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B64S0 */
+#define CSR_SEQUENCEREG0B64S0_LSB			0
+#define CSR_SEQUENCEREG0B64S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B64S1 */
+#define CSR_SEQUENCEREG0B64S1_LSB			0
+#define CSR_SEQUENCEREG0B64S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B64S2 */
+#define CSR_SEQUENCEREG0B64S2_LSB			0
+#define CSR_SEQUENCEREG0B64S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B65S0 */
+#define CSR_SEQUENCEREG0B65S0_LSB			0
+#define CSR_SEQUENCEREG0B65S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B65S1 */
+#define CSR_SEQUENCEREG0B65S1_LSB			0
+#define CSR_SEQUENCEREG0B65S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B65S2 */
+#define CSR_SEQUENCEREG0B65S2_LSB			0
+#define CSR_SEQUENCEREG0B65S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B66S0 */
+#define CSR_SEQUENCEREG0B66S0_LSB			0
+#define CSR_SEQUENCEREG0B66S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B66S1 */
+#define CSR_SEQUENCEREG0B66S1_LSB			0
+#define CSR_SEQUENCEREG0B66S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B66S2 */
+#define CSR_SEQUENCEREG0B66S2_LSB			0
+#define CSR_SEQUENCEREG0B66S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B67S0 */
+#define CSR_SEQUENCEREG0B67S0_LSB			0
+#define CSR_SEQUENCEREG0B67S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B67S1 */
+#define CSR_SEQUENCEREG0B67S1_LSB			0
+#define CSR_SEQUENCEREG0B67S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B67S2 */
+#define CSR_SEQUENCEREG0B67S2_LSB			0
+#define CSR_SEQUENCEREG0B67S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B68S0 */
+#define CSR_SEQUENCEREG0B68S0_LSB			0
+#define CSR_SEQUENCEREG0B68S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B68S1 */
+#define CSR_SEQUENCEREG0B68S1_LSB			0
+#define CSR_SEQUENCEREG0B68S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B68S2 */
+#define CSR_SEQUENCEREG0B68S2_LSB			0
+#define CSR_SEQUENCEREG0B68S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B69S0 */
+#define CSR_SEQUENCEREG0B69S0_LSB			0
+#define CSR_SEQUENCEREG0B69S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B69S1 */
+#define CSR_SEQUENCEREG0B69S1_LSB			0
+#define CSR_SEQUENCEREG0B69S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B69S2 */
+#define CSR_SEQUENCEREG0B69S2_LSB			0
+#define CSR_SEQUENCEREG0B69S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B70S0 */
+#define CSR_SEQUENCEREG0B70S0_LSB			0
+#define CSR_SEQUENCEREG0B70S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B70S1 */
+#define CSR_SEQUENCEREG0B70S1_LSB			0
+#define CSR_SEQUENCEREG0B70S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B70S2 */
+#define CSR_SEQUENCEREG0B70S2_LSB			0
+#define CSR_SEQUENCEREG0B70S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B71S0 */
+#define CSR_SEQUENCEREG0B71S0_LSB			0
+#define CSR_SEQUENCEREG0B71S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B71S1 */
+#define CSR_SEQUENCEREG0B71S1_LSB			0
+#define CSR_SEQUENCEREG0B71S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B71S2 */
+#define CSR_SEQUENCEREG0B71S2_LSB			0
+#define CSR_SEQUENCEREG0B71S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B72S0 */
+#define CSR_SEQUENCEREG0B72S0_LSB			0
+#define CSR_SEQUENCEREG0B72S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B72S1 */
+#define CSR_SEQUENCEREG0B72S1_LSB			0
+#define CSR_SEQUENCEREG0B72S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B72S2 */
+#define CSR_SEQUENCEREG0B72S2_LSB			0
+#define CSR_SEQUENCEREG0B72S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B73S0 */
+#define CSR_SEQUENCEREG0B73S0_LSB			0
+#define CSR_SEQUENCEREG0B73S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B73S1 */
+#define CSR_SEQUENCEREG0B73S1_LSB			0
+#define CSR_SEQUENCEREG0B73S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B73S2 */
+#define CSR_SEQUENCEREG0B73S2_LSB			0
+#define CSR_SEQUENCEREG0B73S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B74S0 */
+#define CSR_SEQUENCEREG0B74S0_LSB			0
+#define CSR_SEQUENCEREG0B74S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B74S1 */
+#define CSR_SEQUENCEREG0B74S1_LSB			0
+#define CSR_SEQUENCEREG0B74S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B74S2 */
+#define CSR_SEQUENCEREG0B74S2_LSB			0
+#define CSR_SEQUENCEREG0B74S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B75S0 */
+#define CSR_SEQUENCEREG0B75S0_LSB			0
+#define CSR_SEQUENCEREG0B75S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B75S1 */
+#define CSR_SEQUENCEREG0B75S1_LSB			0
+#define CSR_SEQUENCEREG0B75S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B75S2 */
+#define CSR_SEQUENCEREG0B75S2_LSB			0
+#define CSR_SEQUENCEREG0B75S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B76S0 */
+#define CSR_SEQUENCEREG0B76S0_LSB			0
+#define CSR_SEQUENCEREG0B76S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B76S1 */
+#define CSR_SEQUENCEREG0B76S1_LSB			0
+#define CSR_SEQUENCEREG0B76S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B76S2 */
+#define CSR_SEQUENCEREG0B76S2_LSB			0
+#define CSR_SEQUENCEREG0B76S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B77S0 */
+#define CSR_SEQUENCEREG0B77S0_LSB			0
+#define CSR_SEQUENCEREG0B77S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B77S1 */
+#define CSR_SEQUENCEREG0B77S1_LSB			0
+#define CSR_SEQUENCEREG0B77S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B77S2 */
+#define CSR_SEQUENCEREG0B77S2_LSB			0
+#define CSR_SEQUENCEREG0B77S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B78S0 */
+#define CSR_SEQUENCEREG0B78S0_LSB			0
+#define CSR_SEQUENCEREG0B78S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B78S1 */
+#define CSR_SEQUENCEREG0B78S1_LSB			0
+#define CSR_SEQUENCEREG0B78S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B78S2 */
+#define CSR_SEQUENCEREG0B78S2_LSB			0
+#define CSR_SEQUENCEREG0B78S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B79S0 */
+#define CSR_SEQUENCEREG0B79S0_LSB			0
+#define CSR_SEQUENCEREG0B79S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B79S1 */
+#define CSR_SEQUENCEREG0B79S1_LSB			0
+#define CSR_SEQUENCEREG0B79S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B79S2 */
+#define CSR_SEQUENCEREG0B79S2_LSB			0
+#define CSR_SEQUENCEREG0B79S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B80S0 */
+#define CSR_SEQUENCEREG0B80S0_LSB			0
+#define CSR_SEQUENCEREG0B80S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B80S1 */
+#define CSR_SEQUENCEREG0B80S1_LSB			0
+#define CSR_SEQUENCEREG0B80S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B80S2 */
+#define CSR_SEQUENCEREG0B80S2_LSB			0
+#define CSR_SEQUENCEREG0B80S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B81S0 */
+#define CSR_SEQUENCEREG0B81S0_LSB			0
+#define CSR_SEQUENCEREG0B81S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B81S1 */
+#define CSR_SEQUENCEREG0B81S1_LSB			0
+#define CSR_SEQUENCEREG0B81S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B81S2 */
+#define CSR_SEQUENCEREG0B81S2_LSB			0
+#define CSR_SEQUENCEREG0B81S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B82S0 */
+#define CSR_SEQUENCEREG0B82S0_LSB			0
+#define CSR_SEQUENCEREG0B82S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B82S1 */
+#define CSR_SEQUENCEREG0B82S1_LSB			0
+#define CSR_SEQUENCEREG0B82S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B82S2 */
+#define CSR_SEQUENCEREG0B82S2_LSB			0
+#define CSR_SEQUENCEREG0B82S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B83S0 */
+#define CSR_SEQUENCEREG0B83S0_LSB			0
+#define CSR_SEQUENCEREG0B83S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B83S1 */
+#define CSR_SEQUENCEREG0B83S1_LSB			0
+#define CSR_SEQUENCEREG0B83S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B83S2 */
+#define CSR_SEQUENCEREG0B83S2_LSB			0
+#define CSR_SEQUENCEREG0B83S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B84S0 */
+#define CSR_SEQUENCEREG0B84S0_LSB			0
+#define CSR_SEQUENCEREG0B84S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B84S1 */
+#define CSR_SEQUENCEREG0B84S1_LSB			0
+#define CSR_SEQUENCEREG0B84S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B84S2 */
+#define CSR_SEQUENCEREG0B84S2_LSB			0
+#define CSR_SEQUENCEREG0B84S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B85S0 */
+#define CSR_SEQUENCEREG0B85S0_LSB			0
+#define CSR_SEQUENCEREG0B85S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B85S1 */
+#define CSR_SEQUENCEREG0B85S1_LSB			0
+#define CSR_SEQUENCEREG0B85S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B85S2 */
+#define CSR_SEQUENCEREG0B85S2_LSB			0
+#define CSR_SEQUENCEREG0B85S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B86S0 */
+#define CSR_SEQUENCEREG0B86S0_LSB			0
+#define CSR_SEQUENCEREG0B86S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B86S1 */
+#define CSR_SEQUENCEREG0B86S1_LSB			0
+#define CSR_SEQUENCEREG0B86S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B86S2 */
+#define CSR_SEQUENCEREG0B86S2_LSB			0
+#define CSR_SEQUENCEREG0B86S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B87S0 */
+#define CSR_SEQUENCEREG0B87S0_LSB			0
+#define CSR_SEQUENCEREG0B87S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B87S1 */
+#define CSR_SEQUENCEREG0B87S1_LSB			0
+#define CSR_SEQUENCEREG0B87S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B87S2 */
+#define CSR_SEQUENCEREG0B87S2_LSB			0
+#define CSR_SEQUENCEREG0B87S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B88S0 */
+#define CSR_SEQUENCEREG0B88S0_LSB			0
+#define CSR_SEQUENCEREG0B88S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B88S1 */
+#define CSR_SEQUENCEREG0B88S1_LSB			0
+#define CSR_SEQUENCEREG0B88S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B88S2 */
+#define CSR_SEQUENCEREG0B88S2_LSB			0
+#define CSR_SEQUENCEREG0B88S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B89S0 */
+#define CSR_SEQUENCEREG0B89S0_LSB			0
+#define CSR_SEQUENCEREG0B89S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B89S1 */
+#define CSR_SEQUENCEREG0B89S1_LSB			0
+#define CSR_SEQUENCEREG0B89S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B89S2 */
+#define CSR_SEQUENCEREG0B89S2_LSB			0
+#define CSR_SEQUENCEREG0B89S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B90S0 */
+#define CSR_SEQUENCEREG0B90S0_LSB			0
+#define CSR_SEQUENCEREG0B90S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B90S1 */
+#define CSR_SEQUENCEREG0B90S1_LSB			0
+#define CSR_SEQUENCEREG0B90S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B90S2 */
+#define CSR_SEQUENCEREG0B90S2_LSB			0
+#define CSR_SEQUENCEREG0B90S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B91S0 */
+#define CSR_SEQUENCEREG0B91S0_LSB			0
+#define CSR_SEQUENCEREG0B91S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B91S1 */
+#define CSR_SEQUENCEREG0B91S1_LSB			0
+#define CSR_SEQUENCEREG0B91S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B91S2 */
+#define CSR_SEQUENCEREG0B91S2_LSB			0
+#define CSR_SEQUENCEREG0B91S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B92S0 */
+#define CSR_SEQUENCEREG0B92S0_LSB			0
+#define CSR_SEQUENCEREG0B92S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B92S1 */
+#define CSR_SEQUENCEREG0B92S1_LSB			0
+#define CSR_SEQUENCEREG0B92S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B92S2 */
+#define CSR_SEQUENCEREG0B92S2_LSB			0
+#define CSR_SEQUENCEREG0B92S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B93S0 */
+#define CSR_SEQUENCEREG0B93S0_LSB			0
+#define CSR_SEQUENCEREG0B93S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B93S1 */
+#define CSR_SEQUENCEREG0B93S1_LSB			0
+#define CSR_SEQUENCEREG0B93S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B93S2 */
+#define CSR_SEQUENCEREG0B93S2_LSB			0
+#define CSR_SEQUENCEREG0B93S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B94S0 */
+#define CSR_SEQUENCEREG0B94S0_LSB			0
+#define CSR_SEQUENCEREG0B94S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B94S1 */
+#define CSR_SEQUENCEREG0B94S1_LSB			0
+#define CSR_SEQUENCEREG0B94S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B94S2 */
+#define CSR_SEQUENCEREG0B94S2_LSB			0
+#define CSR_SEQUENCEREG0B94S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B95S0 */
+#define CSR_SEQUENCEREG0B95S0_LSB			0
+#define CSR_SEQUENCEREG0B95S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B95S1 */
+#define CSR_SEQUENCEREG0B95S1_LSB			0
+#define CSR_SEQUENCEREG0B95S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B95S2 */
+#define CSR_SEQUENCEREG0B95S2_LSB			0
+#define CSR_SEQUENCEREG0B95S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B96S0 */
+#define CSR_SEQUENCEREG0B96S0_LSB			0
+#define CSR_SEQUENCEREG0B96S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B96S1 */
+#define CSR_SEQUENCEREG0B96S1_LSB			0
+#define CSR_SEQUENCEREG0B96S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B96S2 */
+#define CSR_SEQUENCEREG0B96S2_LSB			0
+#define CSR_SEQUENCEREG0B96S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B97S0 */
+#define CSR_SEQUENCEREG0B97S0_LSB			0
+#define CSR_SEQUENCEREG0B97S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B97S1 */
+#define CSR_SEQUENCEREG0B97S1_LSB			0
+#define CSR_SEQUENCEREG0B97S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B97S2 */
+#define CSR_SEQUENCEREG0B97S2_LSB			0
+#define CSR_SEQUENCEREG0B97S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B98S0 */
+#define CSR_SEQUENCEREG0B98S0_LSB			0
+#define CSR_SEQUENCEREG0B98S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B98S1 */
+#define CSR_SEQUENCEREG0B98S1_LSB			0
+#define CSR_SEQUENCEREG0B98S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B98S2 */
+#define CSR_SEQUENCEREG0B98S2_LSB			0
+#define CSR_SEQUENCEREG0B98S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B99S0 */
+#define CSR_SEQUENCEREG0B99S0_LSB			0
+#define CSR_SEQUENCEREG0B99S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B99S1 */
+#define CSR_SEQUENCEREG0B99S1_LSB			0
+#define CSR_SEQUENCEREG0B99S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B99S2 */
+#define CSR_SEQUENCEREG0B99S2_LSB			0
+#define CSR_SEQUENCEREG0B99S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B100S0 */
+#define CSR_SEQUENCEREG0B100S0_LSB			0
+#define CSR_SEQUENCEREG0B100S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B100S1 */
+#define CSR_SEQUENCEREG0B100S1_LSB			0
+#define CSR_SEQUENCEREG0B100S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B100S2 */
+#define CSR_SEQUENCEREG0B100S2_LSB			0
+#define CSR_SEQUENCEREG0B100S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B101S0 */
+#define CSR_SEQUENCEREG0B101S0_LSB			0
+#define CSR_SEQUENCEREG0B101S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B101S1 */
+#define CSR_SEQUENCEREG0B101S1_LSB			0
+#define CSR_SEQUENCEREG0B101S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B101S2 */
+#define CSR_SEQUENCEREG0B101S2_LSB			0
+#define CSR_SEQUENCEREG0B101S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B102S0 */
+#define CSR_SEQUENCEREG0B102S0_LSB			0
+#define CSR_SEQUENCEREG0B102S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B102S1 */
+#define CSR_SEQUENCEREG0B102S1_LSB			0
+#define CSR_SEQUENCEREG0B102S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B102S2 */
+#define CSR_SEQUENCEREG0B102S2_LSB			0
+#define CSR_SEQUENCEREG0B102S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B103S0 */
+#define CSR_SEQUENCEREG0B103S0_LSB			0
+#define CSR_SEQUENCEREG0B103S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B103S1 */
+#define CSR_SEQUENCEREG0B103S1_LSB			0
+#define CSR_SEQUENCEREG0B103S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B103S2 */
+#define CSR_SEQUENCEREG0B103S2_LSB			0
+#define CSR_SEQUENCEREG0B103S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B104S0 */
+#define CSR_SEQUENCEREG0B104S0_LSB			0
+#define CSR_SEQUENCEREG0B104S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B104S1 */
+#define CSR_SEQUENCEREG0B104S1_LSB			0
+#define CSR_SEQUENCEREG0B104S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B104S2 */
+#define CSR_SEQUENCEREG0B104S2_LSB			0
+#define CSR_SEQUENCEREG0B104S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B105S0 */
+#define CSR_SEQUENCEREG0B105S0_LSB			0
+#define CSR_SEQUENCEREG0B105S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B105S1 */
+#define CSR_SEQUENCEREG0B105S1_LSB			0
+#define CSR_SEQUENCEREG0B105S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B105S2 */
+#define CSR_SEQUENCEREG0B105S2_LSB			0
+#define CSR_SEQUENCEREG0B105S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B106S0 */
+#define CSR_SEQUENCEREG0B106S0_LSB			0
+#define CSR_SEQUENCEREG0B106S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B106S1 */
+#define CSR_SEQUENCEREG0B106S1_LSB			0
+#define CSR_SEQUENCEREG0B106S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B106S2 */
+#define CSR_SEQUENCEREG0B106S2_LSB			0
+#define CSR_SEQUENCEREG0B106S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B107S0 */
+#define CSR_SEQUENCEREG0B107S0_LSB			0
+#define CSR_SEQUENCEREG0B107S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B107S1 */
+#define CSR_SEQUENCEREG0B107S1_LSB			0
+#define CSR_SEQUENCEREG0B107S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B107S2 */
+#define CSR_SEQUENCEREG0B107S2_LSB			0
+#define CSR_SEQUENCEREG0B107S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B108S0 */
+#define CSR_SEQUENCEREG0B108S0_LSB			0
+#define CSR_SEQUENCEREG0B108S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B108S1 */
+#define CSR_SEQUENCEREG0B108S1_LSB			0
+#define CSR_SEQUENCEREG0B108S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B108S2 */
+#define CSR_SEQUENCEREG0B108S2_LSB			0
+#define CSR_SEQUENCEREG0B108S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B109S0 */
+#define CSR_SEQUENCEREG0B109S0_LSB			0
+#define CSR_SEQUENCEREG0B109S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B109S1 */
+#define CSR_SEQUENCEREG0B109S1_LSB			0
+#define CSR_SEQUENCEREG0B109S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B109S2 */
+#define CSR_SEQUENCEREG0B109S2_LSB			0
+#define CSR_SEQUENCEREG0B109S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B110S0 */
+#define CSR_SEQUENCEREG0B110S0_LSB			0
+#define CSR_SEQUENCEREG0B110S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B110S1 */
+#define CSR_SEQUENCEREG0B110S1_LSB			0
+#define CSR_SEQUENCEREG0B110S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B110S2 */
+#define CSR_SEQUENCEREG0B110S2_LSB			0
+#define CSR_SEQUENCEREG0B110S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B111S0 */
+#define CSR_SEQUENCEREG0B111S0_LSB			0
+#define CSR_SEQUENCEREG0B111S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B111S1 */
+#define CSR_SEQUENCEREG0B111S1_LSB			0
+#define CSR_SEQUENCEREG0B111S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B111S2 */
+#define CSR_SEQUENCEREG0B111S2_LSB			0
+#define CSR_SEQUENCEREG0B111S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B112S0 */
+#define CSR_SEQUENCEREG0B112S0_LSB			0
+#define CSR_SEQUENCEREG0B112S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B112S1 */
+#define CSR_SEQUENCEREG0B112S1_LSB			0
+#define CSR_SEQUENCEREG0B112S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B112S2 */
+#define CSR_SEQUENCEREG0B112S2_LSB			0
+#define CSR_SEQUENCEREG0B112S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B113S0 */
+#define CSR_SEQUENCEREG0B113S0_LSB			0
+#define CSR_SEQUENCEREG0B113S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B113S1 */
+#define CSR_SEQUENCEREG0B113S1_LSB			0
+#define CSR_SEQUENCEREG0B113S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B113S2 */
+#define CSR_SEQUENCEREG0B113S2_LSB			0
+#define CSR_SEQUENCEREG0B113S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B114S0 */
+#define CSR_SEQUENCEREG0B114S0_LSB			0
+#define CSR_SEQUENCEREG0B114S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B114S1 */
+#define CSR_SEQUENCEREG0B114S1_LSB			0
+#define CSR_SEQUENCEREG0B114S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B114S2 */
+#define CSR_SEQUENCEREG0B114S2_LSB			0
+#define CSR_SEQUENCEREG0B114S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B115S0 */
+#define CSR_SEQUENCEREG0B115S0_LSB			0
+#define CSR_SEQUENCEREG0B115S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B115S1 */
+#define CSR_SEQUENCEREG0B115S1_LSB			0
+#define CSR_SEQUENCEREG0B115S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B115S2 */
+#define CSR_SEQUENCEREG0B115S2_LSB			0
+#define CSR_SEQUENCEREG0B115S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B116S0 */
+#define CSR_SEQUENCEREG0B116S0_LSB			0
+#define CSR_SEQUENCEREG0B116S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B116S1 */
+#define CSR_SEQUENCEREG0B116S1_LSB			0
+#define CSR_SEQUENCEREG0B116S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B116S2 */
+#define CSR_SEQUENCEREG0B116S2_LSB			0
+#define CSR_SEQUENCEREG0B116S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B117S0 */
+#define CSR_SEQUENCEREG0B117S0_LSB			0
+#define CSR_SEQUENCEREG0B117S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B117S1 */
+#define CSR_SEQUENCEREG0B117S1_LSB			0
+#define CSR_SEQUENCEREG0B117S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B117S2 */
+#define CSR_SEQUENCEREG0B117S2_LSB			0
+#define CSR_SEQUENCEREG0B117S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B118S0 */
+#define CSR_SEQUENCEREG0B118S0_LSB			0
+#define CSR_SEQUENCEREG0B118S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B118S1 */
+#define CSR_SEQUENCEREG0B118S1_LSB			0
+#define CSR_SEQUENCEREG0B118S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B118S2 */
+#define CSR_SEQUENCEREG0B118S2_LSB			0
+#define CSR_SEQUENCEREG0B118S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B119S0 */
+#define CSR_SEQUENCEREG0B119S0_LSB			0
+#define CSR_SEQUENCEREG0B119S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B119S1 */
+#define CSR_SEQUENCEREG0B119S1_LSB			0
+#define CSR_SEQUENCEREG0B119S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B119S2 */
+#define CSR_SEQUENCEREG0B119S2_LSB			0
+#define CSR_SEQUENCEREG0B119S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B120S0 */
+#define CSR_SEQUENCEREG0B120S0_LSB			0
+#define CSR_SEQUENCEREG0B120S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B120S1 */
+#define CSR_SEQUENCEREG0B120S1_LSB			0
+#define CSR_SEQUENCEREG0B120S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B120S2 */
+#define CSR_SEQUENCEREG0B120S2_LSB			0
+#define CSR_SEQUENCEREG0B120S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQUENCEREG0B121S0 */
+#define CSR_SEQUENCEREG0B121S0_LSB			0
+#define CSR_SEQUENCEREG0B121S0_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B121S1 */
+#define CSR_SEQUENCEREG0B121S1_LSB			0
+#define CSR_SEQUENCEREG0B121S1_MASK			GENMASK_32(15, 0)
+/* CSR_SEQUENCEREG0B121S2 */
+#define CSR_SEQUENCEREG0B121S2_LSB			0
+#define CSR_SEQUENCEREG0B121S2_MASK			GENMASK_32(8, 0)
+/* CSR_SEQ0BGPR1 */
+#define CSR_SEQ0BGPR1_LSB				0
+#define CSR_SEQ0BGPR1_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR2 */
+#define CSR_SEQ0BGPR2_LSB				0
+#define CSR_SEQ0BGPR2_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR3 */
+#define CSR_SEQ0BGPR3_LSB				0
+#define CSR_SEQ0BGPR3_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR4 */
+#define CSR_SEQ0BGPR4_LSB				0
+#define CSR_SEQ0BGPR4_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR5 */
+#define CSR_SEQ0BGPR5_LSB				0
+#define CSR_SEQ0BGPR5_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR6 */
+#define CSR_SEQ0BGPR6_LSB				0
+#define CSR_SEQ0BGPR6_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR7 */
+#define CSR_SEQ0BGPR7_LSB				0
+#define CSR_SEQ0BGPR7_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BGPR8 */
+#define CSR_SEQ0BGPR8_LSB				0
+#define CSR_SEQ0BGPR8_MASK				GENMASK_32(15, 0)
+/* CSR_SEQ0BFIXEDADDRBITS */
+#define CSR_SEQ0BFIXEDADDRBITS_LSB			0
+#define CSR_SEQ0BFIXEDADDRBITS_MASK			GENMASK_32(6, 0)
+#define CSR_SEQ0BCHIPLETBITS_LSB			0
+#define CSR_SEQ0BCHIPLETBITS_MASK			GENMASK_32(3, 0)
+#define CSR_SEQ0BPSTATEBITS_LSB				4
+#define CSR_SEQ0BPSTATEBITS_MASK			GENMASK_32(6, 4)
+
+/* DRTUB0 register offsets */
+/* CSR_DCTSHADOWREGS */
+#define CSR_DCTSHADOWREGS_LSB				0
+#define CSR_DCTSHADOWREGS_MASK				BIT(0)
+#define CSR_DCTWRITEPROTSHADOW_LSB			0
+#define CSR_DCTWRITEPROTSHADOW_MASK			BIT(0)
+/* CSR_DCTWRITEONLYSHADOW */
+#define CSR_DCTWRITEONLYSHADOW_LSB			0
+#define CSR_DCTWRITEONLYSHADOW_MASK			GENMASK_32(15, 0)
+/* CSR_UCTWRITEONLY */
+#define CSR_UCTWRITEONLY_LSB				0
+#define CSR_UCTWRITEONLY_MASK				GENMASK_32(15, 0)
+/* CSR_UCTWRITEPROT */
+#define CSR_UCTWRITEPROT_LSB				0
+#define CSR_UCTWRITEPROT_MASK				BIT(0)
+/* CSR_UCTDATWRITEONLY */
+#define CSR_UCTDATWRITEONLY_LSB				0
+#define CSR_UCTDATWRITEONLY_MASK			GENMASK_32(15, 0)
+/* CSR_UCTDATWRITEPROT */
+#define CSR_UCTDATWRITEPROT_LSB				0
+#define CSR_UCTDATWRITEPROT_MASK			BIT(0)
+/* CSR_UCTLERR */
+#define CSR_UCTLERR_LSB					0
+#define CSR_UCTLERR_MASK				BIT(0)
+/* CSR_UCCLKHCLKENABLES */
+#define CSR_UCCLKHCLKENABLES_LSB			0
+#define CSR_UCCLKHCLKENABLES_MASK			GENMASK_32(1, 0)
+#define CSR_UCCLKEN_LSB					0
+#define CSR_UCCLKEN_MASK				BIT(0)
+#define CSR_HCLKEN_LSB					1
+#define CSR_HCLKEN_MASK					BIT(1)
+/* CSR_CURPSTATE0B */
+#define CSR_CURPSTATE0B_LSB				0
+#define CSR_CURPSTATE0B_MASK				GENMASK_32(3, 0)
+/* CSR_CLRWAKEUPSTICKY */
+#define CSR_CLRWAKEUPSTICKY_LSB				0
+#define CSR_CLRWAKEUPSTICKY_MASK			GENMASK_32(3, 0)
+/* CSR_WAKEUPMASK */
+#define CSR_WAKEUPMASK_LSB				0
+#define CSR_WAKEUPMASK_MASK				GENMASK_32(3, 0)
+/* CSR_CUSTPUBREV */
+#define CSR_CUSTPUBREV_LSB				0
+#define CSR_CUSTPUBREV_MASK				GENMASK_32(5, 0)
+/* CSR_PUBREV */
+#define CSR_PUBREV_LSB					0
+#define CSR_PUBREV_MASK					GENMASK_32(15, 0)
+#define CSR_RESERVEDPUBREV_LSB				0
+#define CSR_RESERVEDPUBREV_MASK				GENMASK_32(3, 0)
+#define CSR_PUBMNR_LSB					4
+#define CSR_PUBMNR_MASK					GENMASK_32(7, 4)
+#define CSR_PUBMDR_LSB					8
+#define CSR_PUBMDR_MASK					GENMASK_32(11, 8)
+#define CSR_PUBMJR_LSB					12
+#define CSR_PUBMJR_MASK					GENMASK_32(15, 12)
+
+/* APBONLY0 register offsets */
+/* CSR_MICROCONTMUXSEL */
+#define CSR_MICROCONTMUXSEL_LSB				0
+#define CSR_MICROCONTMUXSEL_MASK			BIT(0)
+/* CSR_UCTSHADOWREGS */
+#define CSR_UCTSHADOWREGS_LSB				0
+#define CSR_UCTSHADOWREGS_MASK				GENMASK_32(1, 0)
+#define CSR_UCTWRITEPROTSHADOW_LSB			0
+#define CSR_UCTWRITEPROTSHADOW_MASK			BIT(0)
+#define CSR_UCTDATWRITEPROTSHADOW_LSB			1
+#define CSR_UCTDATWRITEPROTSHADOW_MASK			BIT(1)
+/* CSR_DCTWRITEONLY */
+#define CSR_DCTWRITEONLY_LSB				0
+#define CSR_DCTWRITEONLY_MASK				GENMASK_32(15, 0)
+/* CSR_DCTWRITEPROT */
+#define CSR_DCTWRITEPROT_LSB				0
+#define CSR_DCTWRITEPROT_MASK				BIT(0)
+/* CSR_UCTWRITEONLYSHADOW */
+#define CSR_UCTWRITEONLYSHADOW_LSB			0
+#define CSR_UCTWRITEONLYSHADOW_MASK			GENMASK_32(15, 0)
+/* CSR_UCTDATWRITEONLYSHADOW */
+#define CSR_UCTDATWRITEONLYSHADOW_LSB			0
+#define CSR_UCTDATWRITEONLYSHADOW_MASK			GENMASK_32(15, 0)
+/* CSR_NEVERGATECSRCLOCK */
+#define CSR_NEVERGATECSRCLOCK_LSB			0
+#define CSR_NEVERGATECSRCLOCK_MASK			BIT(0)
+/* CSR_DFICFGRDDATAVALIDTICKS */
+#define CSR_DFICFGRDDATAVALIDTICKS_LSB			0
+#define CSR_DFICFGRDDATAVALIDTICKS_MASK			GENMASK_32(5, 0)
+/* CSR_MICRORESET */
+#define CSR_MICRORESET_LSB				0
+#define CSR_MICRORESET_MASK				GENMASK_32(3, 0)
+#define CSR_STALLTOMICRO_LSB				0
+#define CSR_STALLTOMICRO_MASK				BIT(0)
+#define CSR_TESTWAKEUP_LSB				1
+#define CSR_TESTWAKEUP_MASK				BIT(1)
+#define CSR_RSVDMICRO_LSB				2
+#define CSR_RSVDMICRO_MASK				BIT(2)
+#define CSR_RESETTOMICRO_LSB				3
+#define CSR_RESETTOMICRO_MASK				BIT(3)
+/* CSR_SEQUENCEROVERRIDE */
+#define CSR_SEQUENCEROVERRIDE_LSB			0
+#define CSR_SEQUENCEROVERRIDE_MASK			GENMASK_32(10, 0)
+#define CSR_FORCESEQ0BDFIFREQ_LSB			0
+#define CSR_FORCESEQ0BDFIFREQ_MASK			GENMASK_32(4, 0)
+#define CSR_FORCESEQ0BSTART_LSB				5
+#define CSR_FORCESEQ0BSTART_MASK			BIT(5)
+#define CSR_FORCESEQ0BSTOP_LSB				6
+#define CSR_FORCESEQ0BSTOP_MASK				BIT(6)
+#define CSR_BLOCKSEQ0BREQUESTS_LSB			7
+#define CSR_BLOCKSEQ0BREQUESTS_MASK			BIT(7)
+#define CSR_BLOCKSEQ0BACK_LSB				8
+#define CSR_BLOCKSEQ0BACK_MASK				BIT(8)
+#define CSR_DISABLETERMINATEFLAG_LSB			9
+#define CSR_DISABLETERMINATEFLAG_MASK			BIT(9)
+#define CSR_SELECTDFIFREQTOGPRMUX_LSB			10
+#define CSR_SELECTDFIFREQTOGPRMUX_MASK			BIT(10)
+/* CSR_DFIINITCOMPLETESHADOW */
+#define CSR_DFIINITCOMPLETESHADOW_LSB			0
+#define CSR_DFIINITCOMPLETESHADOW_MASK			BIT(0)
+
+/* Fields brought to you by the letter B */
+#define B_MIN						0U
+#define B_MAX						1U
+#define B0						0x0U
+#define B1						0x100U
+#define BBRD						0xF00U
+#define BB_MIN						0U
+#define BB_MAX						15U
+#define BB0						0x0U
+#define BB1						0x1000U
+#define BB2						0x2000U
+#define BB3						0x3000U
+#define BB4						0x4000U
+#define BB5						0x5000U
+#define BB6						0x6000U
+#define BB7						0x7000U
+#define BB8						0x8000U
+#define BB9						0x9000U
+#define BB10						0xA000U
+#define BB11						0xB000U
+#define BB12						0xC000U
+#define BB13						0xD000U
+#define BB14						0xE000U
+#define BB15						0xF000U
+#define BBBRD						0xF000U
+/* Fields brought to you by the letter C */
+#define C_MIN						0U
+#define C_MAX						15U
+#define C0						0x0U
+#define C1						0x1000U
+#define C2						0x2000U
+#define C3						0x3000U
+#define C4						0x4000U
+#define C5						0x5000U
+#define C6						0x6000U
+#define C7						0x7000U
+#define C8						0x8000U
+#define C9						0x9000U
+#define C10						0xA000U
+#define C11						0xB000U
+#define C12						0xC000U
+#define C13						0xD000U
+#define C14						0xE000U
+#define C15						0xF000U
+#define CBRD						0xF000U
+/* Fields brought to you by the letter D */
+#define D_MIN						0U
+#define D_MAX						3U
+#define D0						0x0U
+#define D1						0x100U
+#define D2						0x200U
+#define D3						0x300U
+#define DBRD						0xF00U
+/* Fields brought to you by the letter I */
+#define I_MIN						0U
+#define I_MAX						8U
+#define I0						0x0U
+#define I1						0x100U
+#define I2						0x200U
+#define I3						0x300U
+#define I4						0x400U
+#define I5						0x500U
+#define I6						0x600U
+#define I7						0x700U
+#define I8						0x800U
+#define IBRD						0xF00U
+/* Fields brought to you by the letter J */
+#define J_MIN						0U
+#define J_MAX						0U
+#define J0						0x0U
+#define JBRD						0xF00U
+/* Fields brought to you by the letter L */
+#define L_MIN						0U
+#define L_MAX						13U
+#define L0						0x0U
+#define L1						0x100U
+#define L2						0x200U
+#define L3						0x300U
+#define L4						0x400U
+#define L5						0x500U
+#define L6						0x600U
+#define L7						0x700U
+#define L8						0x800U
+#define L9						0x900U
+#define L10						0xA00U
+#define L11						0xB00U
+#define L12						0xC00U
+#define L13						0xD00U
+#define LBRD						0xF00U
+/* Fields brought to you by the letter M */
+#define M_MIN						0U
+#define M_MAX						8U
+#define M0						0x0U
+#define M1						0x100U
+#define M2						0x200U
+#define M3						0x300U
+#define M4						0x400U
+#define M5						0x500U
+#define M6						0x600U
+#define M7						0x700U
+#define M8						0x800U
+#define MBRD						0xF00U
+/* Fields brought to you by the letter N */
+#define N_MIN						0U
+#define N_MAX						15U
+#define N0						0x0U
+#define N1						0x100U
+#define N2						0x200U
+#define N3						0x300U
+#define N4						0x400U
+#define N5						0x500U
+#define N6						0x600U
+#define N7						0x700U
+#define N8						0x800U
+#define N9						0x900U
+#define N10						0xA00U
+#define N11						0xB00U
+#define N12						0xC00U
+#define N13						0xD00U
+#define N14						0xE00U
+#define N15						0xF00U
+#define NBRD						0xF00U
+/* Fields brought to you by the letter P */
+#define P_MIN						0U
+#define P_MAX						3U
+#define P0						0x0U
+#define P1						0x100000U
+#define P2						0x200000U
+#define P3						0x300000U
+#define PBRD						0x700000U
+#define PP_MIN						0U
+#define PP_MAX						3U
+#define PP0						0x0U
+#define PP1						0x100000U
+#define PP2						0x200000U
+#define PP3						0x300000U
+#define PPBRD						0x700000U
+/* Fields brought to you by the letter Q */
+#define Q_MIN						0U
+#define Q_MAX						3U
+#define Q0						0x0U
+#define Q1						0x100000U
+#define Q2						0x200000U
+#define Q3						0x300000U
+#define QBRD						0x700000U
+/* Fields brought to you by the letter R */
+#define R_MIN						0U
+#define R_MAX						8U
+#define R0						0x0U
+#define R1						0x100U
+#define R2						0x200U
+#define R3						0x300U
+#define R4						0x400U
+#define R5						0x500U
+#define R6						0x600U
+#define R7						0x700U
+#define R8						0x800U
+#define RBRD						0xF00U
+/* Fields brought to you by the letter T */
+#define T_MIN						0U
+#define T_MAX						15U
+#define T0						0x0U
+#define T1						0x10000U
+#define T2						0x20000U
+#define T3						0x30000U
+#define T4						0x40000U
+#define T5						0x50000U
+#define T6						0x60000U
+#define T7						0x70000U
+#define T8						0x80000U
+#define T9						0x90000U
+#define T10						0xA0000U
+#define T11						0xB0000U
+#define T12						0xC0000U
+#define T13						0xD0000U
+#define T14						0xE0000U
+#define T15						0xF0000U
+#define TBRD						0xF0000U
+/* Fields brought to you by the letter U */
+#define U_MIN						0U
+#define U_MAX						1U
+#define U0						0x0U
+#define U1						0x100U
+#define UBRD						0xF00U
+/* Fields brought to you by the letter Y */
+#define Y_MIN						0U
+#define Y_MAX						0U
+#define Y0						0x0U
+#define YBRD						0xF000000U
+
+#define TACSM						0x40000U
+#define TACSMBRD					0x4F000U
+#define TALL						0xF0000U
+#define TALLBRD						0xFF000U
+#define TANIB						0x0U
+#define TANIBBRD					0xF000U
+#define TAPBONLY					0xD0000U
+#define TAPBONLYBRD					0xDF000U
+#define TDBYTE						0x10000U
+#define TDBYTEBRD					0x1F000U
+#define TDRTUB						0xC0000U
+#define TDRTUBBRD					0xCF000U
+#define TINITENG					0x90000U
+#define TINITENGBRD					0x9F000U
+#define TMASTER						0x20000U
+#define TMASTERBRD					0x2F000U
+#define TPPGC						0x70000U
+#define TPPGCBRD					0x7F000U
+#define TUCTL_MEM					0x50000U
+#define TUCTL_MEMBRD					0x5F000U
+
+#define DBYTE_NUM					9U
+#define ANIB_NUM					12U
+
+#endif /* DDRPHY_PHYINIT_CSR_ALL_DEFINES_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit.h
new file mode 100644
index 00000000..acd7072a
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_PHYINIT_H
+#define DDRPHY_PHYINIT_H
+
+#include <stdbool.h>
+
+#include <ddrphy_phyinit_usercustom.h>
+
+enum message_block_field {
+	MB_FIELD_PSTATE,
+	MB_FIELD_PLLBYPASSEN,
+	MB_FIELD_DRAMFREQ,
+	MB_FIELD_DFIFREQRATIO,
+	MB_FIELD_BPZNRESVAL,
+	MB_FIELD_PHYODTIMPEDANCE,
+	MB_FIELD_PHYDRVIMPEDANCE,
+	MB_FIELD_DRAMTYPE,
+	MB_FIELD_DISABLEDDBYTE,
+	MB_FIELD_ENABLEDDQS,
+	MB_FIELD_PHYCFG,
+	MB_FIELD_X16PRESENT,
+	MB_FIELD_ENABLEDDQSCHA,
+	MB_FIELD_CSPRESENTCHA,
+	MB_FIELD_ENABLEDDQSCHB,
+	MB_FIELD_CSPRESENTCHB,
+};
+
+/* Function definitions */
+int ddrphy_phyinit_softsetmb(struct pmu_smb_ddr_1d *mb_ddr_1d, enum message_block_field field,
+			     uint32_t value);
+void ddrphy_phyinit_initstruct(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d);
+#endif /* DDRPHY_PHYINIT_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_struct.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_struct.h
new file mode 100644
index 00000000..ae34c0c8
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_struct.h
@@ -0,0 +1,786 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_PHYINIT_STRUCT_H
+#define DDRPHY_PHYINIT_STRUCT_H
+
+/* This file defines the internal data structures used in PhyInit to store user configuration */
+
+/* DIMM Type definitions */
+#define DDR_DIMMTYPE_NODIMM 4U /* No DIMM (Soldered-on) */
+
+/*
+ * Structure for basic user inputs
+ *
+ * The following basic data structure must be set and completed correctly so
+ * that the PhyInit software package can accurate program PHY registers.
+ */
+struct user_input_basic {
+	uint32_t dramtype;		/*
+					 * DRAM module type.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | DDR4
+					 *   0x1 | DDR3
+					 *   0x2 | LPDDR4
+					 */
+
+	uint32_t dimmtype;		/*
+					 * DIMM type.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x4 | No DIMM (Soldered-on) (DDR_DIMMTYPE_NODIMM)
+					 */
+
+	uint32_t lp4xmode;		/*
+					 * LPDDR4X mode support.
+					 * Only used for LPDDR4, but not valid here.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | LPDDR4 mode, when dramtype is LPDDR4
+					 */
+
+	uint32_t numdbyte;		/* Number of dbytes physically instantiated */
+
+	uint32_t numactivedbytedfi0;	/* Number of active dbytes to be controlled by dfi0 */
+
+	uint32_t numactivedbytedfi1;	/*
+					 * Number of active dbytes to be controlled by dfi1.
+					 * Only used for LPDDR4.
+					 */
+
+	uint32_t numanib;		/* Number of ANIBs physically instantiated */
+
+	uint32_t numrank_dfi0;		/* Number of ranks in DFI0 channel */
+
+	uint32_t numrank_dfi1;		/* Number of ranks in DFI1 channel (if DFI1 exists) */
+
+	uint32_t dramdatawidth;		/*
+					 * Width of the DRAM device.
+					 *
+					 * Enter 4,8,16 or 32 depending on protocol and dram type
+					 * according below table.
+					 *
+					 * Protocol | Valid Options | Default
+					 * -------- | ------------- | ---
+					 * DDR3     | 4,8,16        | 8
+					 * DDR4     | 4,8,16        | 8
+					 * LPDDR4   | 8,16          | 16
+					 *
+					 * For mixed x8 and x16 width devices, set variable to x8.
+					 */
+
+	uint32_t numpstates;		/* Number of p-states used. Must be set to 1 */
+
+	uint32_t frequency;		/*
+					 * Memclk frequency for each PState.
+					 * Memclk frequency in MHz round up to next highest integer.
+					 * Enter 334 for 333.333, etc.
+					 */
+
+	uint32_t pllbypass;		/*
+					 * Indicates if PLL should be in Bypass mode.
+					 * If DDR datarate < 333, PLL must be in Bypass Mode.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x1 | Enabled
+					 *   0x0 | Disabled
+					 */
+
+	uint32_t dfifreqratio;		/*
+					 * Selected Dfi Frequency ratio.
+					 * Used to program the dfifreqratio register. This register
+					 * controls how dfi_freq_ratio input pin should be driven
+					 * inaccordance with DFI Spec.
+					 *
+					 * Binary Value | Description
+					 *        ----- | ------
+					 *        2'b01 | 1:2 DFI Frequency Ratio (default)
+					 */
+
+	uint32_t dfi1exists;		/* Indicates if the PHY configuration has Dfi1 channel */
+
+	uint32_t train2d;		/* Obsolete. Not used. */
+
+	uint32_t hardmacrover;		/*
+					 * Hard Macro Family version in use.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   3   | hardmacro family D
+					 */
+
+	uint32_t readdbienable;		/* Obsolete. Not Used. */
+
+	uint32_t dfimode;		/* Obsolete. Not Used. */
+};
+
+/*
+ * Structure for advanced user inputs
+ */
+struct user_input_advanced {
+	uint32_t lp4rxpreamblemode;	/*
+					 * Selects between DRAM read static vs toggle preamble.
+					 * Determine desired DRAM Read Preamble Mode based on SI
+					 * Analysis and DRAM Part in use.
+					 * The PHY training firmware will program DRAM mr1-OP[3]
+					 * after training based on setting.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x1 | toggling preamble
+					 *   0x0 | static preamble
+					 */
+
+	uint32_t lp4postambleext;	/*
+					 * Extend write postamble in LPDDR4.
+					 * Only used for LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr3-OP[1] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Set value according to your SI analysis and DRAM
+					 * requirement.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | half Memclk postamble
+					 *   0x1 | 1.5 Memclk postabmle (default)
+					 */
+
+	uint32_t d4rxpreamblelength;	/*
+					 * Length of read preamble in DDR4 mode.
+					 * Only used for DDR4.
+					 * This variable is used to calculate DDR4 mr4-OP[11] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Set value according to your SI analysis and DRAM
+					 * requirement.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 |  1 Tck
+					 *   0x1 |  2 Tck (default)
+					 */
+
+	uint32_t d4txpreamblelength;	/*
+					 * Length of write preamble in DDR4 mode.
+					 * Only used for DDR4.
+					 * This variable is used to calculate DDR4 mr4-OP[12] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Set value according to your SI analysis and DRAM
+					 * requirement.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | 1 Tck (default)
+					 *   0x1 | 2 Tck
+					 */
+
+	uint32_t extcalresval;		/*
+					 * External Impedance calibration pull-down resistor value
+					 * select.
+					 * Indicates value of impedance calibration pull-down
+					 * resistor connected to BP_ZN pin of the PHY.
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | 240 ohm (default)
+					 */
+
+	uint32_t is2ttiming;		/*
+					 * Set to 1 to use 2T timing for address/command, otherwise
+					 * 1T timing will be used.
+					 * Determine 1T or 2T Timing operation mode based on SI
+					 * Analysis and DRAM Timing.
+					 *   - In 1T mode, CK, CS, CA all have the same nominal
+					 *     timing, ie. ATxDly[6:0] will have same value for all
+					 *     ANIBs.
+					 *   - In 2T mode, CK, CS,have the same nominal timing
+					 *     (e.g. AtxDly[6:0]=0x00), while CA is delayed by 1UI
+					 *     (e.g. ATxDly[6:0]=0x40)
+					 * Used to program phycfg setting in messageBlock.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | 1T Timing (default)
+					 *   0x1 | 2T Timing
+					 */
+
+	uint32_t odtimpedance;		/*
+					 * ODT impedance in ohm.
+					 * Used for programming TxOdtDrvStren registers.
+					 * Enter 0 for open/high-impedance.
+					 * Default value: 60
+					 */
+
+	uint32_t tximpedance;		/*
+					 * Tx Drive Impedance for DQ/DQS in ohm.
+					 * Used for programming TxImpedanceCtrl1 registers.
+					 * Enter 0 for open/high-impedance.
+					 * Default value: 60
+					 */
+
+	uint32_t atximpedance;		/*
+					 * Tx Drive Impedance for AC in ohm.
+					 * Used for programming ATxImpedance register.
+					 * Enter 0 for open/high-impedance
+					 * Default value: 20 (HMA,HMB,HMC,HMD), 40 (HME)
+					 */
+
+	uint32_t memalerten;		/*
+					 * Enables BP_ALERT programming of PHY registers.
+					 * Only used for DDR3 and DDR4.
+					 * Used for programming MemAlertControl and MemAlertControl2
+					 * registers.
+					 * Program if you require using BP_ALERT pin (to receive or
+					 * terminate signal) of the PHY otherwise leave at default
+					 * value to save power.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 * 0x0 | Disable BP_ALERT (default)
+					 */
+
+	uint32_t memalertpuimp;		/*
+					 * Specify MemAlert Pull-up Termination Impedance.
+					 * Programs the pull-up termination on BP_ALERT.
+					 * Not valid here (fixed 0 value).
+					 */
+
+	uint32_t memalertvreflevel;	/*
+					 * Specify the Vref level for BP_ALERT(MemAlert) Receiver.
+					 * Not valid here (fixed 0 value).
+					 */
+
+	uint32_t memalertsyncbypass;	/*
+					 * When set, this bit bypasses the DfiClk synchronizer on
+					 * dfi_alert_n.
+					 * Not valid here (fixed 0 value).
+					 */
+
+	uint32_t disdynadrtri;		/*
+					 * Disable Dynamic Per-MEMCLK Address Tristate feature.
+					 * Program this variable if you require to disable this
+					 * feature.
+					 *   - In DDR3/2T and DDR4/2T/2N modes, the dynamic tristate
+					 *     feature should be disabled if the controller cannot
+					 *     follow the 2T PHY tristate protocol.
+					 *   - In LPDDR4 mode, the dynamic tristate feature should
+					 *     be disabled.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *  0x1  | Disable Dynamic Tristate
+					 */
+
+	uint32_t phymstrtraininterval;	/*
+					 * Specifies the how frequent dfi_phymstr_req is issued by
+					 * PHY.
+					 * Only required in LPDDR4.
+					 * Based on SI analysis determine how frequent DRAM drift
+					 * compensation and re-training is required.
+					 * Determine if Memory controller supports DFI PHY Master
+					 * Interface.
+					 * Program based on desired setting for
+					 * PPTTrainSetup.PhyMstrTrainInterval register.
+					 * Default value: 0xa
+					 *
+					 * Example:
+					 * Value | Description
+					 * ----- | ------
+					 *   0xa | PPT Train Interval = 268435456 MEMCLKs (default)
+					 */
+
+	uint32_t phymstrmaxreqtoack;	/*
+					 * Max time from dfi_phymstr_req asserted to dfi_phymstr_ack
+					 * asserted.
+					 * Only required in LPDDR4.
+					 * Based on your Memory controller's(MC) specification
+					 * determine how long the PHY should wait for the assertion
+					 * of dfi_phymstr_ack once dfi_phymstr_req has been issued
+					 * by the PHY. If the MC does not ack the PHY's request, PHY
+					 * may issue dfi_error.
+					 * This value will be used to program
+					 * PPTTrainSetup.PhyMstrMaxReqToAck register.
+					 * Default value: 0x5
+					 *
+					 * Example:
+					 * Value | Description
+					 * ----- | ------
+					 *   0x5 | PPT Max. Req to Ack. = 8192 MEMCLKs (default)
+					 */
+
+	uint32_t wdqsext;		/*
+					 * Enable Write DQS Extension feature of PHY.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 *   0x0 | Disable Write DQS Extension feature. (default)
+					 *   0x1 | Enable Write DQS Extension feature.
+					 */
+
+	uint32_t calinterval;		/*
+					 * Specifies the interval between successive calibrations,
+					 * in mS.
+					 * Program variable based on desired setting for
+					 * CalRate.CalInterval register.
+					 * - Fixed 0x9 value (20mS interval)
+					 */
+
+	uint32_t calonce;		/*
+					 * This setting changes the behaviour of CalRun register.
+					 * If you desire to manually trigger impedance calibration
+					 * in mission mode set this variable to 1, and toggle CalRun
+					 * in mission mode.
+					 *
+					 * Value | Description
+					 * ----- | ------
+					 * 0x0   | Calibration will proceed at the rate determined
+					 *       | by CalInterval. This field should only be changed
+					 *       | while the calibrator is idle. ie before csr
+					 *       | CalRun is set.
+					 */
+
+	uint32_t lp4rl;			/*
+					 * LPDDR4 Dram Read Latency.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr2-OP[2:0]
+					 * set in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 * Determine values based on your DRAM part's supported
+					 * speed and latency bin.
+					 * Default: calculated based on user_input_basic.frequency
+					 * and "JEDEC JESD209-4A (LPDDR4)" Table 28 "Read and Write
+					 * Latencies".
+					 * Lowest latency selected when more than one latency can be
+					 * used. For example given configuration for LPDDR4, x16,
+					 * NoDbi and DDR533, RL=10 is selected rather than 14.
+					 */
+
+	uint32_t lp4wl;			/*
+					 * LPDDR4 Dram Write Latency.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr2-OP[5:3]
+					 * set in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 * Determine values based on your DRAM part's supported
+					 * speed and latency bin.
+					 * Default: calculated based on user_input_basic.frequency
+					 * and "JEDEC JESD209-4A (LPDDR4)" Table 28 "Read and Write
+					 * Latencies".
+					 * Lowest latency selected when more than one latency can be
+					 * used.
+					 */
+
+	uint32_t lp4wls;		/*
+					 * LPDDR4 Dram WL Set.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr2-OP[6] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 * Determine value based on Memory controllers requirement
+					 * of DRAM State after PHY training.
+					 *
+					 * Value | Description
+					 *   --- | ---
+					 *   0x0 | WL Set "A" (default)
+					 */
+
+	uint32_t lp4dbird;		/*
+					 * LPDDR4 Dram DBI-Read Enable.
+					 * Applicable only if dramtype == LPDDR4.
+					 * Determine if you require to using DBI for the given
+					 * PState.
+					 * If Read DBI is not used PHY receivers are turned off to
+					 * save power.
+					 * This variable is used to calculate LPDDR4 mr3-OP[6] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * PHY register DMIPinPresent is programmed based on this
+					 * parameter.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 *
+					 * Value | Description
+					 *   --- | ---
+					 *   0x0 | Disabled (default)
+					 *   0x1 | Enabled
+					 */
+
+	uint32_t lp4dbiwr;		/*
+					 * LPDDR4 Dram DBI-Write Enable.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr3-OP[7] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 *
+					 * Value | Description
+					 *   --- | ---
+					 *   0x0 | Disabled (default)
+					 *   0x1 | Enabled
+					 */
+
+	uint32_t lp4nwr;		/*
+					 * LPDDR4 Write-Recovery for Auto- Pre-charge commands.
+					 * Applicable only if dramtype == LPDDR4.
+					 * This variable is used to calculate LPDDR4 mr1-OP[6:4] set
+					 * in the messageBlock.
+					 * The training firmware will set DRAM MR according to MR
+					 * value in the messageBlock at the end of training.
+					 * Please refer to JEDEC JESD209-4A (LPDDR4) Spec for
+					 * definition of MR.
+					 * Determine values based on your DRAM part's supported
+					 * speed and latency bin.
+					 * Default: calculated based on user_input_basic.frequency
+					 * and "JEDEC JESD209-4A (LPDDR4)" Table 28 "Read and Write
+					 * Latencies".
+					 * Lowest latency selected when more than one latency can be
+					 * used.
+					 *
+					 * Binary Value | Description
+					 * --- | ---
+					 * 000 | nWR = 6 (default)
+					 * 001 | nWR = 10
+					 * 010 | nWR = 16
+					 * 011 | nWR = 20
+					 * 100 | nWR = 24
+					 * 101 | nWR = 30
+					 * 110 | nWR = 34
+					 * 111 | nWR = 40
+					 */
+
+	uint32_t lp4lowpowerdrv;	/*
+					 * Configure output Driver in Low power mode.
+					 * Feature only supported for Hard Macro Family E (HME).
+					 * Use NMOS Pull-up for Low-Power IO.
+					 * Not valid here
+					 */
+
+	uint32_t drambyteswap;		/*
+					 * DRAM Oscillator count source mapping for skip_training.
+					 * The PHY supports swapping of DRAM oscillator count values
+					 * between paired DBytes for the purpose of tDQSDQ DRAM
+					 * Drift Compensation(DDC).
+					 * Each DByte has a register bit to control the source of
+					 * the oscillator count value used to perform tDQSDQ Drift
+					 * compensation.
+					 * On silicon the training firmware will determine the DByte
+					 * swap and program PptCtlStatic register to select
+					 * oscillator count source. When skip_train is used,
+					 * training firmware is skipped thus manual programming may
+					 * be required depending on configuration.
+					 * The default hardware configuration is for odd Dbyte
+					 * instance n to use oscillator count values from its paired
+					 * Dbyte instance n-1. So Dbyte1 will use the oscillator
+					 * count values from Dbyte0, Dbyte3 will use Dbyte2 and so
+					 * on. This is required for DRAM Data width =16.
+					 * Each bit of this field corresponds to a DBYTE:
+					 *   - bit-0 = setting for DBYTE0
+					 *   - bit-1 = setting for DBYTE1
+					 *   - bit-2 = setting for DBYTE2
+					 *   - . . .
+					 *   - bit-n = setting for DBYTEn
+					 * By setting the associated bit for each DByte to 1, PHY
+					 * will use non-default source for count value.
+					 *   - for even Dbytes, non-default source is to use the odd
+					 *     pair count value.
+					 *   - for odd Dbytes, no-default source to use data
+					 *     received directly from the DRAM.
+					 * Byte swapping must be the same across different ranks.
+					 * Default value: 0x0
+					 * If Byte mode devices are indicated via the x8mode
+					 * messageBlock parameter, this variable is ignored as PHY
+					 * only supports a limited configuration set based on Byte
+					 * mode configuration.
+					 *
+					 * Example:
+					 * DramByteSwap = 0x03 - Dbyte0: use count values from
+					 * Dbyte1, Dbyte1 uses count values received directly
+					 * received from DRAM.
+					 * Rest of Dbytes have default source for DRAM oscilator
+					 * count.
+					 */
+
+	uint32_t rxenbackoff;		/*
+					 * Determines the Placement of PHY Read Gate signal.
+					 * Only used in LPDDR4 when lp4rxpreamblemode==0 (static
+					 * preamble) for skip_train==true.
+					 * For other dramtypes or LPDDR4-toggling-preamble no
+					 * options are available and PhyInit will set position as
+					 * required. See source code in
+					 * ddrphy_phyinit_c_initphyconfig() to see how the
+					 * RxEnBackOff register is set.
+					 * For skip_train==false, FW will set the position based on
+					 * Preamble.
+					 * We recommend keeping this setting at default value.
+					 * SI analysis is required to determine if default value
+					 * needs to be changed.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x1 | Position read gate 1UI from the first valid edge
+					 *       | of DQS_t (LPDDR4 Static preamble only) (default)
+					 */
+
+	uint32_t trainsequencectrl;	/*
+					 * Firmware Training Sequence Control.
+					 * This input is used to program sequencectrl in
+					 * messageBlock.
+					 * It controls the training stages executed by firmware.
+					 * For production silicon we recommend to use default value
+					 * programmed by PhyInit.
+					 */
+
+	uint32_t snpsumctlopt;		/*
+					 * Enable Fast Frequency Change (FFC) Optimizations
+					 * specific to UMCTL2 (DDRCTRL).
+					 * Not valid for dimmtype=NODIMM.
+					 * Consult DDRCTRL documentation in Reference Manual to
+					 * ensure when optimizations can be enabled.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 * 0 | Disable FFC MRW optimization (default)
+					 */
+
+	uint32_t snpsumctlf0rc5x;	/*
+					 * F0RX5x RCD Control Word when using Fast Frequency
+					 * Change(FFC) optimizations specific to UMCTL2
+					 * Not valid for dimmtype=NODIMM.
+					 * Only valid for when SnpsUmctlOpt=1.
+					 * When UMCTL2 optimizations are enabled PHY will perform
+					 * RCD MRW during fast frequency change request.
+					 * The correct RCD control word value for each PState must
+					 * be programmed in this field.
+					 * Consult the RCD spec and UMCTL documentation to
+					 * determine the correct value based on DRAM configuration
+					 * and operating speed.
+					 */
+
+	uint32_t txslewrisedq;		/*
+					 * Pull-up slew rate control for DBYTE Tx.
+					 * Value specified here will be written to register
+					 * TxSlewRate.TxPreP by PhyInit.
+					 * See register description for more information.
+					 */
+
+	uint32_t txslewfalldq;		/*
+					 * Pull-down slew rate control for DBYTE Tx.
+					 * Value specified here will be written to
+					 * TxSlewRate.TxPreN by PhyInit.
+					 * See register description for more information.
+					 */
+
+	uint32_t txslewriseac;		/*
+					 * Pull-up slew rate control for ANIB Tx.
+					 * Value specified here will be written to
+					 * ATxSlewRate.ATxPreP.
+					 * See register description for more information.
+					 */
+
+	uint32_t txslewfallac;		/*
+					 * Pull-down slew rate control for ANIB Tx.
+					 * Value specified here will be written to
+					 * ATxSlewRate.ATxPreN.
+					 * See register description for more information.
+					 */
+
+	uint32_t disableretraining;	/*
+					 * Disable PHY DRAM Drift compensation re-training.
+					 * Only applied to LPDDR4. No retraining is required in
+					 * DDR4/3.
+					 * Disable PHY re-training during DFI frequency change
+					 * requests in LPDDR4.
+					 * The purpose of retraining is to compensate for drift in
+					 * the DRAM.
+					 * Determine based on SI analysis and DRAM datasheet if
+					 * retraining can be disabled.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x1 | Disable retraining
+					 *   0x0 | Enable retraining
+					 */
+
+	uint32_t disablephyupdate;	/*
+					 * Disable DFI PHY Update feature.
+					 * Only effects LPDDR4.
+					 * Disable DFI PHY Update feature. When set PHY will not
+					 * assert dfi0/1_phyupd_req.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x1 | Disable DFI PHY Update
+					 *   0x0 | Enable DFI PHY Update
+					 */
+
+	uint32_t enablehighclkskewfix;	/*
+					 * Enable alternative PIE program.
+					 * If enabled the PIE reinitializes the FIFO pointers a
+					 * second time due for designs with large skew between
+					 * chiplet DfiClk branches. If enabled PIE latencies in all
+					 * protocols are increased by 60 DfiClks.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x0 | Disable (default)
+					 */
+
+	uint32_t disableunusedaddrlns;  /*
+					 * Turn off or tristate Address Lanes when possible.
+					 *
+					 * When enabled, PHY will tristate unused address lanes to
+					 * save power when possible by using Acx4AnibDis and
+					 * AForceTriCont registers.
+					 * This feature is only implemented for the default PHY
+					 * Address bump mapping and Ranks must be populated in
+					 * order. ie Rank1 cannot be used if Rank0 is unpopulated.
+					 * For alternative bump mapping follow the following
+					 * guideline to achieve maximum power savings:
+					 *   - For each unused BP_A bump program AForceTriCont[4:0]
+					 *     bits based on register description.
+					 *   - if all lanes of an Anib are unused _AND_ ANIB is not
+					 *     the first or last instance set bit associated with
+					 *     the instance in Acs4AnibDis registers. see register
+					 *     description for details.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x1 | Enable
+					 */
+
+	uint32_t phyinitsequencenum;	/*
+					 * Switches between supported phyinit training sequences.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x0 | Minimizes number of Imem/Dmem loads (default)
+					 */
+
+	uint32_t enabledficspolarityfix;/*
+					 * Enable alternative PIE program.
+					 * Set to 1 if PUB_VERSION <2.43a, otherwise set to 0. If
+					 * enabled the PIE programs Dfi{Rd,Wr}DataCsDestMap CSR's
+					 * to default values 0x00E4 before running PPT.
+					 * Before exiting PPT, PIE will restore
+					 * Dfi{Rd,Wr}DataCsDestMap CSR's to 0x00E1.
+					 *
+					 * Value | Description
+					 * ----- | ---
+					 *   0x0 | Disable (default)
+					 */
+
+	uint32_t phyvref;		/*
+					 * Must be programmed with the Vref level to be used by the
+					 * PHY during reads.
+					 * The units of this field are a percentage of VDDQ
+					 * according to the following equation:
+					 * Receiver Vref = VDDQ*phyvref[6:0]/128
+					 * For example to set Vref at 0.75*VDDQ, set this field to
+					 * 0x60.
+					 * For digital simulation, any legal value can be used. For
+					 * silicon, the users must calculate the analytical Vref by
+					 * using the impedances, terminations, and series resistance
+					 * present in the system.
+					 */
+
+	uint32_t sequencectrl;		/*
+					 * Controls the training steps to be run. Each bit
+					 * corresponds to a training step.
+					 * If the bit is set to 1, the training step will run.
+					 * If the bit is set to 0, the training step will be
+					 * skipped.
+					 * Training step to bit mapping:
+					 * sequencectrl[0] = Run DevInit - Device/phy
+					 *		     initialization. Should always be set.
+					 * sequencectrl[1] = Run WrLvl - Write leveling
+					 * sequencectrl[2] = Run RxEn - Read gate training
+					 * sequencectrl[3] = Run RdDQS1D - 1d read dqs training
+					 * sequencectrl[4] = Run WrDQ1D - 1d write dq training
+					 * sequencectrl[5] = RFU, must be zero
+					 * sequencectrl[6] = RFU, must be zero
+					 * sequencectrl[7] = RFU, must be zero
+					 * sequencectrl[8] = Run RdDeskew - Per lane read dq deskew
+					 *		     training
+					 * sequencectrl[9] = Run MxRdLat - Max read latency training
+					 * sequencectrl[10] = RFU, must be zero
+					 * sequencectrl[11] = RFU, must be zero
+					 * sequencectrl[12] = RFU, must be zero
+					 * sequencectrl[13] = RFU, must be zero
+					 * sequencectrl[15-14] = RFU, must be zero
+					 */
+};
+
+/*
+ * Structure for mode register user inputs
+ *
+ * The following data structure must be set and completed correctly so that the PhyInit software
+ * package can accurate fill message block structure.
+ * Only some mrx are used per DDR type, on related width:
+ * - DDR3: mr0..2 are used (16-bits values)
+ * - DDR4: mr0..6 are used (16-bits values)
+ * - LPDDR4: mr1..4 and mr11..22 are used (8-bits values)
+ */
+struct user_input_mode_register {
+	uint32_t mr0;
+	uint32_t mr1;
+	uint32_t mr2;
+	uint32_t mr3;
+	uint32_t mr4;
+	uint32_t mr5;
+	uint32_t mr6;
+	uint32_t mr11;
+	uint32_t mr12;
+	uint32_t mr13;
+	uint32_t mr14;
+	uint32_t mr22;
+};
+
+/*
+ * Structure for swizzle user inputs
+ *
+ * The following data structure must be set and completed correctly sothat the PhyInit software
+ * package can accurate set swizzle (IO muxing) config.
+ * Only some swizzles are used per DDR type:
+ * - DDR3/DDR4: swizzle 0..32 are used
+ *   - 26 for hwtswizzle
+ *   - 7 for acswizzle
+ * - LPDDR4:  swizzle 0..43 are used
+ *   - 8 per byte for dqlnsel (total 32)
+ *   - 6 for mapcaatodfi
+ *   - 6 for mapcabtodfi
+ */
+#define NB_HWT_SWIZZLE			26U
+#define NB_AC_SWIZZLE			7U
+#define NB_DQLNSEL_SWIZZLE_PER_BYTE	8U
+#define NB_MAPCAATODFI_SWIZZLE		6U
+#define NB_MAPCABTODFI_SWIZZLE		6U
+#define NB_SWIZZLE	44
+struct user_input_swizzle {
+	uint32_t swizzle[NB_SWIZZLE];
+};
+
+#endif /* DDRPHY_PHYINIT_STRUCT_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_usercustom.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_usercustom.h
new file mode 100644
index 00000000..b248f592
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_phyinit_usercustom.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_PHYINIT_USERCUSTOM_H
+#define DDRPHY_PHYINIT_USERCUSTOM_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <ddrphy_csr_all_cdefines.h>
+
+#include <drivers/st/stm32mp2_ddr.h>
+
+/* Message Block Structure Definitions */
+#if STM32MP_DDR3_TYPE
+#include <mnpmusrammsgblock_ddr3.h>
+#elif STM32MP_DDR4_TYPE
+#include <mnpmusrammsgblock_ddr4.h>
+#else /* STM32MP_LPDDR4_TYPE */
+#include <mnpmusrammsgblock_lpddr4.h>
+#endif /* STM32MP_DDR3_TYPE */
+
+/*
+ * -------------------------------------------------------------
+ * Defines for Firmware Images
+ * - indicate IMEM/DMEM address, size (bytes) and offsets.
+ * -------------------------------------------------------------
+ *
+ * IMEM_SIZE max size of instruction memory.
+ * DMEM_SIZE max size of data memory.
+ *
+ * IMEM_ST_ADDR start of IMEM address in memory.
+ * DMEM_ST_ADDR start of DMEM address in memory.
+ * DMEM_BIN_OFFSET start offset in DMEM memory (message block).
+ */
+#if STM32MP_DDR3_TYPE
+#define IMEM_SIZE			0x4C28U
+#define DMEM_SIZE			0x6C8U
+#elif STM32MP_DDR4_TYPE
+#define IMEM_SIZE			0x6D24U
+#define DMEM_SIZE			0x6CCU
+#else /* STM32MP_LPDDR4_TYPE */
+#define IMEM_SIZE			0x7E50U
+#define DMEM_SIZE			0x67CU
+#endif /* STM32MP_DDR3_TYPE */
+#define IMEM_ST_ADDR			0x50000U
+#define DMEM_ST_ADDR			0x54000U
+#define DMEM_BIN_OFFSET			0x200U
+
+/*
+ * ------------------
+ * Type definitions
+ * ------------------
+ */
+
+/* A structure used to SRAM memory address space */
+enum return_offset_lastaddr {
+	RETURN_OFFSET,
+	RETURN_LASTADDR
+};
+
+/* Enumeration of instructions for PhyInit Register Interface */
+enum reginstr {
+	STARTTRACK,	/* Start register tracking */
+	STOPTRACK,	/* Stop register tracking */
+	SAVEREGS,	/* Save(read) tracked register values */
+	RESTOREREGS,	/* Restore (write) saved register values */
+};
+
+/* Data structure to store register address/value pairs */
+struct reg_addr_val {
+	uint32_t	address;	/* Register address */
+	uint16_t	value;		/* Register value */
+};
+
+/* Target CSR for the impedance value for ddrphy_phyinit_mapdrvstren() */
+enum drvtype {
+	DRVSTRENFSDQP,
+	DRVSTRENFSDQN,
+	ODTSTRENP,
+	ODTSTRENN,
+	ADRVSTRENP,
+	ADRVSTRENN
+};
+
+/*
+ * -------------------------------------------------------------
+ * Fixed Function prototypes
+ * -------------------------------------------------------------
+ */
+int ddrphy_phyinit_sequence(struct stm32mp_ddr_config *config, bool skip_training, bool reten);
+int ddrphy_phyinit_restore_sequence(void);
+int ddrphy_phyinit_c_initphyconfig(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t *ardptrinitval);
+void ddrphy_phyinit_d_loadimem(void);
+void ddrphy_phyinit_progcsrskiptrain(struct stm32mp_ddr_config *config,
+				     struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t ardptrinitval);
+int ddrphy_phyinit_f_loaddmem(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d);
+int ddrphy_phyinit_g_execfw(void);
+void ddrphy_phyinit_i_loadpieimage(struct stm32mp_ddr_config *config, bool skip_training);
+void ddrphy_phyinit_loadpieprodcode(void);
+int ddrphy_phyinit_mapdrvstren(uint32_t drvstren_ohm, enum drvtype targetcsr);
+int ddrphy_phyinit_calcmb(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d);
+void ddrphy_phyinit_writeoutmem(uint32_t *mem, uint32_t mem_offset, uint32_t mem_size);
+void ddrphy_phyinit_writeoutmsgblk(uint16_t *mem, uint32_t mem_offset, uint32_t mem_size);
+int ddrphy_phyinit_isdbytedisabled(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t dbytenumber);
+int ddrphy_phyinit_trackreg(uint32_t adr);
+int ddrphy_phyinit_reginterface(enum reginstr myreginstr, uint32_t adr, uint16_t dat);
+
+void ddrphy_phyinit_usercustom_custompretrain(struct stm32mp_ddr_config *config);
+int ddrphy_phyinit_usercustom_g_waitfwdone(void);
+int ddrphy_phyinit_usercustom_saveretregs(struct stm32mp_ddr_config *config);
+
+#endif /* DDRPHY_PHYINIT_USERCUSTOM_H */
diff --git a/drivers/st/ddr/phy/phyinit/include/ddrphy_wrapper.h b/drivers/st/ddr/phy/phyinit/include/ddrphy_wrapper.h
new file mode 100644
index 00000000..ed4be1c0
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/include/ddrphy_wrapper.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DDRPHY_WRAPPER_H
+#define DDRPHY_WRAPPER_H
+
+static inline long long fmodll(long long x, long long y)
+{
+	return x - ((x / y) * y);
+}
+
+static inline int fmodi(int x, int y)
+{
+	return (int)fmodll((long long)x, (long long)y);
+}
+
+#endif /* DDRPHY_WRAPPER_H */
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
new file mode 100644
index 00000000..e5c82580
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c
@@ -0,0 +1,1141 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+#include <ddrphy_wrapper.h>
+
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+
+/*
+ * Program txslewrate:
+ * - txslewrate::txpredrvmode is dependent on dramtype.
+ * - txslewrate::txprep and txslewrate::txpren are technology-specific.
+ */
+static void txslewrate_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t txpredrvmode;
+	uint32_t byte;
+	uint32_t txpren; /* Default to 0xf (max). Optimal setting is technology specific */
+	uint32_t txprep; /* Default to 0xf (max). Optimal setting is technology specific */
+	uint16_t txslewrate;
+
+#if STM32MP_DDR3_TYPE
+	txpredrvmode = 0x3U;
+#elif STM32MP_DDR4_TYPE
+	txpredrvmode = 0x2U;
+#else /* STM32MP_LPDDR4_TYPE */
+	txpredrvmode = 0x1U;
+#endif /* STM32MP_DDR3_TYPE */
+
+	txprep = config->uia.txslewrisedq;
+	txpren = config->uia.txslewfalldq;
+
+	txslewrate = (uint16_t)((txpredrvmode << CSR_TXPREDRVMODE_LSB) |
+				(txpren << CSR_TXPREN_LSB) |
+				(txprep << CSR_TXPREP_LSB));
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane <= B_MAX; lane++) {
+			uint32_t b_addr;
+
+			b_addr = lane << 8;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | c_addr | b_addr |
+									CSR_TXSLEWRATE_ADDR))),
+				      txslewrate);
+		}
+	}
+}
+
+/*
+ * Program atxslewrate:
+ * - atxslewrate::atxpredrvmode is dependent on dramtype and whether
+ *   the ACX4 instance is used for AC or CK.
+ * - atxslewrate::atxprep and atxslewrate::atxpren are technology-specific.
+ */
+static void atxslewrate_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t anib;
+	uint32_t atxpren; /* Default to 0xf (max). Optimal setting is technology specific */
+	uint32_t atxprep; /* Default to 0xf (max). Optimal setting is technology specific */
+	uint32_t ck_anib_inst[2] = {0};
+
+	atxprep = config->uia.txslewriseac;
+	atxpren = config->uia.txslewfallac;
+
+	/*
+	 * # of ANIBs      CK ANIB Instance
+	 * ACX8            ANIB 1
+	 */
+	if (config->uib.numanib == 8U) {
+		ck_anib_inst[0] = 1U;
+		ck_anib_inst[1] = 1U;
+	}
+
+	for (anib = 0U; anib < config->uib.numanib; anib++) {
+		uint32_t atxpredrvmode;
+		uint32_t c_addr;
+		uint16_t atxslewrate;
+
+		c_addr = anib << 12;
+
+		if ((anib == ck_anib_inst[0]) || (anib == ck_anib_inst[1])) {
+			/* CK ANIB instance */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			atxpredrvmode = 0x0U;
+#else /* STM32MP_LPDDR4_TYPE */
+			atxpredrvmode = 0x1U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+		} else {
+			/* non-CK ANIB instance */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			atxpredrvmode = 0x3U;
+#else /* STM32MP_LPDDR4_TYPE */
+			atxpredrvmode = 0x1U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+		}
+
+		atxslewrate = (uint16_t)((atxpredrvmode << CSR_ATXPREDRVMODE_LSB) |
+					 (atxpren << CSR_ATXPREN_LSB) |
+					 (atxprep << CSR_ATXPREP_LSB));
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TANIB | c_addr |
+								CSR_ATXSLEWRATE_ADDR))),
+			      atxslewrate);
+	}
+}
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+/*
+ * Program dfirddatacsdestmap and dfiwrdatacsdestmap:
+ * - Dependencies: mb_ddr_1d->msgmisc[6] Determine Partial Rank Support.
+ */
+static void dfidatacsdestmap_program(struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	if ((mb_ddr_1d->msgmisc & 0x40U) != 0U) {
+		uint16_t dfirddatacsdestmap = 0xA0U;
+		uint16_t dfiwrdatacsdestmap = 0xA0U;
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER |
+								CSR_DFIRDDATACSDESTMAP_ADDR))),
+			      dfirddatacsdestmap);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER |
+								CSR_DFIWRDATACSDESTMAP_ADDR))),
+			      dfiwrdatacsdestmap);
+	}
+}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+/*
+ * Program pllctrl2:
+ * - Calculate PLL controls from frequency.
+ */
+static void pllctrl2_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t pllctrl2;
+	uint32_t halffreq = config->uib.frequency / 2U;
+
+	if (halffreq < 235U) {
+		pllctrl2 = 0x7U;
+	} else if (halffreq < 313U) {
+		pllctrl2 = 0x6U;
+	} else if (halffreq < 469U) {
+		pllctrl2 = 0xBU;
+	} else if (halffreq < 625U) {
+		pllctrl2 = 0xAU;
+	} else if (halffreq < 938U) {
+		pllctrl2 = 0x19U;
+	} else if (halffreq < 1067U) {
+		pllctrl2 = 0x18U;
+	} else {
+		pllctrl2 = 0x19U;
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_PLLCTRL2_ADDR))), pllctrl2);
+}
+
+/*
+ * Program ardptrinitval:
+ * - The values programmed here assume ideal properties of DfiClk and Pclk including:
+ *   - DfiClk skew
+ *   - DfiClk jitter
+ *   - DfiClk PVT variations
+ *   - Pclk skew
+ *   - Pclk jitter
+ *
+ * ardptrinitval Programmed differently based on PLL Bypass mode and frequency:
+ * - PLL Bypassed mode:
+ *   - For MemClk frequency > 933MHz, the valid range of ardptrinitval[3:0] is: 2-5
+ *   - For MemClk frequency < 933MHz, the valid range of ardptrinitval[3:0] is: 1-5
+ * - PLL Enabled mode:
+ *   - For MemClk frequency > 933MHz, the valid range of ardptrinitval[3:0] is: 1-5
+ *   - For MemClk frequency < 933MHz, the valid range of ardptrinitval[3:0] is: 0-5
+ */
+static void ardptrinitval_program(struct stm32mp_ddr_config *config, uint32_t *ardptrinitval)
+{
+	uint16_t regdata;
+
+	if (config->uib.frequency >= 933U) {
+		regdata = 0x2U;
+	} else {
+		regdata = 0x1U;
+	}
+
+	/* Add one UI for synchronizer on SyncBus when PLL is bypassed */
+	if (config->uib.pllbypass == 1U) {
+		regdata++;
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_ARDPTRINITVAL_ADDR))),
+		      regdata);
+
+	*ardptrinitval = (uint32_t)regdata;
+}
+
+#if STM32MP_LPDDR4_TYPE
+/*
+ * Program ProcOdtCtl:
+ * - Sets procodtalwayson/procodtalwaysoff for LPDDR4 using the PIE register seq0bgpr4.
+ */
+static void procodtctl_program(void)
+{
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | C0 | CSR_SEQ0BGPR4_ADDR))), 0U);
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+/*
+ * Program dbytedllmodecntrl:
+ * - dllrxpreamblemode
+ * Program dqspreamblecontrol:
+ * - Fields:
+ *   - twotckrxdqspre
+ *   - twotcktxdqspre
+ *   - positiondfeinit
+ *   - lp4tgltwotcktxdqspre
+ *   - lp4postambleext
+ *   - lp4sttcprebridgerxen
+ * - Dependencies:
+ *   - user_input_advanced.lp4rxpreamblemode (LPDDR4)
+ *   - user_input_advanced.lp4postambleext (LPDDR4)
+ *   - user_input_advanced.wdqsext (LPDDR4)
+ *   - user_input_advanced.d4rxpreamblelength (DDR4)
+ *   - user_input_advanced.d4txpreamblelength (DDR4)
+ */
+static void dbytedllmodecntrl_program(struct stm32mp_ddr_config *config, uint32_t *twotckrxdqspre)
+{
+	uint32_t disdllgainivseed = 1U;
+	uint32_t disdllseedsel = 0U;
+	uint32_t dllgainiv = 0x1U;
+	uint32_t dllgaintv = 0x6U;
+	uint32_t dllrxpreamblemode = 0U;
+	uint32_t lcdlseed0 = 0x21U;
+	uint32_t lp4postambleext = 0U;
+	uint32_t lp4sttcprebridgerxen = 0U;
+	uint32_t lp4tgltwotcktxdqspre = 0U;
+	uint32_t positiondfeinit;
+	uint32_t twotcktxdqspre = 0U;
+	uint32_t wdqsextension = 0U;
+	uint16_t dbytedllmodecntrl;
+	uint16_t dllgainctl;
+	uint16_t dlllockparam;
+	uint16_t dqspreamblecontrol;
+
+#if STM32MP_DDR3_TYPE
+	/* Same as default */
+	*twotckrxdqspre		= 0x0U;
+	lp4sttcprebridgerxen	= 0x0U;
+	dllrxpreamblemode	= 0x0U;
+	twotcktxdqspre		= 0x0U;
+	lp4tgltwotcktxdqspre	= 0x0U;
+	positiondfeinit		= 0x0U;
+	lp4postambleext		= 0x0U;
+#elif STM32MP_DDR4_TYPE
+	*twotckrxdqspre		= config->uia.d4rxpreamblelength;
+	lp4sttcprebridgerxen	= 0x0U;
+	dllrxpreamblemode	= 0x1U;
+	twotcktxdqspre		= config->uia.d4txpreamblelength;
+	lp4tgltwotcktxdqspre	= 0x0U;
+	positiondfeinit		= 0x2U;
+	lp4postambleext		= 0x0U;
+#else /* STM32MP_LPDDR4_TYPE */
+	/* Set to 1 if static Rx preamble */
+	*twotckrxdqspre		= (config->uia.lp4rxpreamblemode == 0U) ? 1U : 0U;
+	/* Set to 1 if static Rx preamble */
+	lp4sttcprebridgerxen	= (config->uia.lp4rxpreamblemode == 0U) ? 1U : 0U;
+	dllrxpreamblemode	= 0x1U;
+	/* Must be 2*Tck Tx preamble according to JEDEC (mr1.OP[2] = 1) */
+	twotcktxdqspre		= 0x1U;
+	/* Must be toggling Tx preamble */
+	lp4tgltwotcktxdqspre	= 0x1U;
+	positiondfeinit		= 0x0U;
+	lp4postambleext		= config->uia.lp4postambleext;
+	wdqsextension		= config->uia.wdqsext;
+#endif /* STM32MP_DDR3_TYPE */
+
+	dqspreamblecontrol = (uint16_t)((wdqsextension << CSR_WDQSEXTENSION_LSB) |
+					(lp4sttcprebridgerxen << CSR_LP4STTCPREBRIDGERXEN_LSB) |
+					(lp4postambleext << CSR_LP4POSTAMBLEEXT_LSB) |
+					(lp4tgltwotcktxdqspre << CSR_LP4TGLTWOTCKTXDQSPRE_LSB) |
+					(positiondfeinit << CSR_POSITIONDFEINIT_LSB) |
+					(twotcktxdqspre << CSR_TWOTCKTXDQSPRE_LSB) |
+					(*twotckrxdqspre << CSR_TWOTCKRXDQSPRE_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DQSPREAMBLECONTROL_ADDR))),
+		      dqspreamblecontrol);
+
+	dbytedllmodecntrl = (uint16_t)(dllrxpreamblemode << CSR_DLLRXPREAMBLEMODE_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DBYTEDLLMODECNTRL_ADDR))),
+		      dbytedllmodecntrl);
+
+	dllgainctl = (uint16_t)(dllgainiv | (dllgaintv << CSR_DLLGAINTV_LSB));
+	dlllockparam = (uint16_t)(disdllseedsel | (disdllgainivseed << CSR_DISDLLGAINIVSEED_LSB) |
+				  (lcdlseed0 << CSR_LCDLSEED0_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DLLLOCKPARAM_ADDR))),
+		      dlllockparam);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DLLGAINCTL_ADDR))),
+		      dllgainctl);
+}
+
+/*
+ * Program procodttimectl:
+ * - Fields:
+ *   - POdtStartDelay[3:2]
+ *   - POdtTailWidth[1:0]
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ *   - user_input_advanced.wdqsext
+ */
+static void procodttimectl_program(struct stm32mp_ddr_config *config, uint32_t twotckrxdqspre)
+{
+	uint16_t procodttimectl;
+
+	if (config->uia.wdqsext != 0U) {
+		/* POdtStartDelay = 0x0 and  POdtTailWidth  = 0x3 */
+		procodttimectl = 0x3U;
+	} else if (config->uib.frequency <= 933U) {
+		/* Memclk Freq <= 933MHz: POdtStartDelay = 0x2 and POdtTailWidth  = 0x2 */
+		procodttimectl = 0xAU;
+	} else if (config->uib.frequency <= 1200U) {
+		/* 933MHz < Memclk Freq <= 1200MHz */
+		if (twotckrxdqspre == 1U) {
+			/* POdtStartDelay = 0x0 and  POdtTailWidth  = 0x2 */
+			procodttimectl = 0x2U;
+		} else {
+			/* POdtStartDelay = 0x1 and POdtTailWidth  = 0x2 */
+			procodttimectl = 0x6U;
+		}
+	} else {
+		/* Memclk Freq > 1200MHz */
+		if (twotckrxdqspre == 1U) {
+			/* POdtStartDelay = 0x0 and POdtTailWidth  = 0x3 */
+			procodttimectl = 0x3U;
+		} else {
+			/* POdtStartDelay = 0x1 and POdtTailWidth  = 0x3 */
+			procodttimectl = 0x7U;
+		}
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_PROCODTTIMECTL_ADDR))),
+		      procodttimectl);
+}
+
+/*
+ * Program txodtdrvstren:
+ * - Fields:
+ *   - ODTStrenP_px[5:0]
+ *   - ODTStrenN_px[11:6]
+ * - Dependencies:
+ *   - user_input_basic.numdbyte
+ *   - user_input_advanced.odtimpedance
+ * \return 0 on success.
+ */
+static int txodtdrvstren_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte;
+	int odtstrenn_state;
+	int odtstrenp_state;
+	uint16_t txodtdrvstren;
+
+	odtstrenp_state = ddrphy_phyinit_mapdrvstren(config->uia.odtimpedance, ODTSTRENP);
+	if (odtstrenp_state < 0) {
+		return odtstrenp_state;
+	}
+
+	odtstrenn_state = ddrphy_phyinit_mapdrvstren(config->uia.odtimpedance, ODTSTRENN);
+	if (odtstrenn_state < 0) {
+		return odtstrenn_state;
+	}
+
+	txodtdrvstren = (uint16_t)((odtstrenn_state << CSR_ODTSTRENN_LSB) | odtstrenp_state);
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane <= B_MAX; lane++) {
+			uint32_t b_addr;
+
+			b_addr = lane << 8;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | c_addr | b_addr |
+									CSR_TXODTDRVSTREN_ADDR))),
+				      txodtdrvstren);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Program tximpedancectrl1:
+ * - Fields:
+ *   - DrvStrenFSDqP[5:0]
+ *   - DrvStrenFSDqN[11:6]
+ * - Dependencies:
+ *   - user_input_basic.numdbyte
+ *   - user_input_advanced.tximpedance
+ * \return 0 on success.
+ */
+static int tximpedancectrl1_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte;
+	int drvstrenfsdqn_state;
+	int drvstrenfsdqp_state;
+	uint16_t tximpedancectrl1;
+
+	drvstrenfsdqp_state = ddrphy_phyinit_mapdrvstren(config->uia.tximpedance,
+							 DRVSTRENFSDQP);
+	if (drvstrenfsdqp_state < 0) {
+		return drvstrenfsdqp_state;
+	}
+
+	drvstrenfsdqn_state = ddrphy_phyinit_mapdrvstren(config->uia.tximpedance,
+							 DRVSTRENFSDQN);
+	if (drvstrenfsdqn_state < 0) {
+		return drvstrenfsdqn_state;
+	}
+
+	tximpedancectrl1 = (uint16_t)((drvstrenfsdqn_state << CSR_DRVSTRENFSDQN_LSB) |
+				      (drvstrenfsdqp_state << CSR_DRVSTRENFSDQP_LSB));
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane <= B_MAX; lane++) {
+			uint32_t b_addr;
+
+			b_addr = lane << 8;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U *
+								  (TDBYTE | c_addr | b_addr |
+								   CSR_TXIMPEDANCECTRL1_ADDR))),
+				      tximpedancectrl1);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Program atximpedance:
+ * - Fields:
+ *   - ADrvStrenP[4:0]
+ *   - ADrvStrenN[9:5]
+ * - Dependencies:
+ *   - user_input_basic.numanib
+ *   - user_input_advanced.atximpedance
+ * \return 0 on success.
+ */
+static int atximpedance_program(struct stm32mp_ddr_config *config)
+{
+	int adrvstrenn_state;
+	int adrvstrenp_state;
+	uint32_t anib;
+	uint16_t atximpedance;
+
+	adrvstrenp_state = ddrphy_phyinit_mapdrvstren(config->uia.atximpedance,
+						      ADRVSTRENP);
+	if (adrvstrenp_state < 0) {
+		return adrvstrenp_state;
+	}
+
+	adrvstrenn_state = ddrphy_phyinit_mapdrvstren(config->uia.atximpedance,
+						      ADRVSTRENN);
+	if (adrvstrenn_state < 0) {
+		return adrvstrenn_state;
+	}
+
+	atximpedance = (uint16_t)((adrvstrenn_state << CSR_ADRVSTRENN_LSB) |
+				  (adrvstrenp_state << CSR_ADRVSTRENP_LSB));
+
+	for (anib = 0U; anib < config->uib.numanib; anib++) {
+		uint32_t c_addr;
+
+		c_addr = anib << 12;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TANIB | c_addr |
+								CSR_ATXIMPEDANCE_ADDR))),
+			      atximpedance);
+	}
+
+	return 0;
+}
+
+/*
+ * Program dfimode:
+ * - Dependencies:
+ *   - user_input_basic.dfi1exists
+ */
+static void dfimode_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t dfimode = 0x5U;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	if (config->uib.dfi1exists == 0U) {
+		dfimode = 0x1U; /* DFI1 does not physically exists */
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DFIMODE_ADDR))), dfimode);
+}
+
+/*
+ * Program dficamode:
+ * - Fields:
+ *   - DfiLp3CAMode
+ *   - DfiD4CAMode
+ *   - DfiLp4CAMode
+ *   - DfiD4AltCAMode
+ */
+static void dficamode_program(void)
+{
+	uint16_t dficamode;
+
+#if STM32MP_DDR3_TYPE
+	dficamode = 0U;
+#elif STM32MP_DDR4_TYPE
+	dficamode = 2U;
+#else /* STM32MP_LPDDR4_TYPE */
+	dficamode = 4U;
+#endif /* STM32MP_DDR3_TYPE */
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DFICAMODE_ADDR))), dficamode);
+}
+
+/*
+ * Program caldrvstr0:
+ * - Fields:
+ *   - caldrvstrpd50[3:0]
+ *   - caldrvstrpu50[7:4]
+ * - Dependencies:
+ *   - user_input_advanced.extcalresval
+ */
+static void caldrvstr0_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t caldrvstr0;
+	uint16_t caldrvstrp50 = (uint16_t)config->uia.extcalresval;
+
+	caldrvstr0 = (caldrvstrp50 << CSR_CALDRVSTRPU50_LSB) | caldrvstrp50;
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALDRVSTR0_ADDR))),
+		      caldrvstr0);
+}
+
+/*
+ * Program CalUclkInfo:
+ * - Impedance calibration CLK Counter.
+ * - Fields:
+ *   - caluclkticksper1us
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ */
+static void caluclkinfo_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t caluclkticksper1us_x10;
+	uint16_t caluclkticksper1us;
+
+	/* Number of DfiClk cycles per 1us */
+	caluclkticksper1us_x10 = (10U * config->uib.frequency) / 2U;
+	caluclkticksper1us = (uint16_t)(caluclkticksper1us_x10 / 10U);
+
+	if ((config->uib.frequency % 2U) != 0U) {
+		caluclkticksper1us++;
+	}
+
+	if (caluclkticksper1us < 24U) {
+		/* Minimum value of caluclkticksper1us = 24 */
+		caluclkticksper1us = 24U;
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALUCLKINFO_ADDR))),
+		      caluclkticksper1us);
+}
+
+/*
+ * Program Calibration CSRs based on user input
+ * - Fields:
+ *   - calinterval
+ *   - calonce
+ * - Dependencies:
+ *   - user_input_advanced.calinterval
+ *   - user_input_advanced.calonce
+ */
+static void calibration_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t calinterval;
+	uint32_t calonce;
+	uint16_t calrate;
+
+	calinterval = config->uia.calinterval;
+	calonce = config->uia.calonce;
+
+	calrate = (uint16_t)((calonce << CSR_CALONCE_LSB) | (calinterval << CSR_CALINTERVAL_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALRATE_ADDR))), calrate);
+}
+
+/*
+ * Program vrefinglobal:
+ * - dqdqsrcvcntrl and csrvrefinglobal to select Global VREF
+ *   from Master to be used in each DQ.
+ * - Fields:
+ *   - globalvrefinsel: Select Range of GlobalVref DAC. Default: set to 1.
+ *   - globalvrefindac: Vref level is set based on mb_ddr_1d->phyvref value.
+ *     The following formula is used to convert the phyvref into the register setting.
+ *       \f{eqnarray*}{
+ *           PhyVrefPrcnt &=& \frac{mb_ddr_1d->phyvref}{128} \\
+ *        if globalvrefinsel = 1 :
+ *           globalvrefindac &=& 1+\frac{PhyVrefPrcnt}{0.005} \\
+ *        if globalvrefinsel = 0 :
+ *           globalvrefindac &=& \frac{(PhyVrefPrcnt-0.345)}{0.005} \\
+ *           RxVref &=& (globalvrefindac == 0) ? Hi-Z : (PhyVrefPrcnt \times VDDQ)
+ *        \f}
+ *
+ * Program dqdqsrcvcntrl:
+ * - dqdqsrcvcntrl and csrvrefinglobal to select Global VREF
+ *   from Master to be used in each DQ
+ * - Fields:
+ *  - selanalogvref
+ *  - majormodedbyte
+ *  - ExtVrefRange
+ *  - DfeCtrl
+ *  - GainCurrAdj
+ * - Dependencies:
+ *   - user_input_basic.numdbyte
+ */
+static void vrefinglobal_program(struct stm32mp_ddr_config *config,
+				 struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint32_t majormodedbyte;
+	int32_t vref_percentvddq = (int32_t)mb_ddr_1d->phyvref * 1000 * 100 / 128;
+	uint8_t globalvrefindac = 0x0U;
+	uint8_t globalvrefinsel = 0x4U;
+	uint32_t byte;
+	uint32_t dfectrl_defval = 0U;
+	uint32_t extvrefrange_defval = 0U;
+	uint32_t gaincurradj_defval = 0xBU;
+	uint32_t selanalogvref = 1U; /* Use Global VREF from Master */
+	uint16_t dqdqsrcvcntrl;
+	uint16_t vrefinglobal;
+
+#if STM32MP_DDR3_TYPE
+	majormodedbyte = 0U;
+#elif STM32MP_DDR4_TYPE
+	majormodedbyte = 3U;
+#else /* STM32MP_LPDDR4_TYPE */
+	majormodedbyte = 2U;
+#endif /* STM32MP_DDR3_TYPE */
+
+	/* Check range1 first. Only use range0 if customer input maxes out range1. */
+	globalvrefindac = (uint8_t)((vref_percentvddq / 500) + 1);
+	if (globalvrefindac > 127U) {
+		/* Min value is 1 */
+		globalvrefindac = (uint8_t)(MAX((vref_percentvddq - 34500), 500) / 500);
+		globalvrefinsel = 0x0U;
+	}
+	globalvrefindac = MIN(globalvrefindac, (uint8_t)127);
+
+	vrefinglobal = (uint16_t)((globalvrefindac << CSR_GLOBALVREFINDAC_LSB) | globalvrefinsel);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_VREFINGLOBAL_ADDR))),
+		      vrefinglobal);
+
+	dqdqsrcvcntrl = (uint16_t)((gaincurradj_defval << CSR_GAINCURRADJ_LSB) |
+				   (majormodedbyte << CSR_MAJORMODEDBYTE_LSB) |
+				   (dfectrl_defval << CSR_DFECTRL_LSB) |
+				   (extvrefrange_defval << CSR_EXTVREFRANGE_LSB) |
+				   (selanalogvref << CSR_SELANALOGVREF_LSB));
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane <= B_MAX; lane++) {
+			uint32_t b_addr;
+
+			b_addr = lane << 8;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | c_addr | b_addr |
+									CSR_DQDQSRCVCNTRL_ADDR))),
+				      dqdqsrcvcntrl);
+		}
+	}
+}
+
+/*
+ * Program dfifreqratio :
+ * - Dependencies:
+ *   - user_input_basic.dfifreqratio
+ */
+static void dfifreqratio_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t dfifreqratio;
+
+	dfifreqratio = (uint16_t)config->uib.dfifreqratio;
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DFIFREQRATIO_ADDR))),
+		      dfifreqratio);
+}
+
+/*
+ * Program tristatemodeca based on dramtype and 2T Timing
+ * - Fields:
+ *   - CkDisVal
+ *   - disdynadrtri
+ *   - ddr2tmode
+ * - Dependencies:
+ *   - user_input_advanced.is2ttiming
+ *   - user_input_advanced.disdynadrtri
+ */
+static void tristatemodeca_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t ckdisval_def;
+	uint32_t ddr2tmode;
+	uint32_t disdynadrtri;
+	uint16_t tristatemodeca;
+
+	/* CkDisVal depends on dramtype */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	ckdisval_def = 1U; /* {CLK_t,CLK_c} = 2'b00; */
+#else /* STM32MP_LPDDR4_TYPE */
+	ckdisval_def = 0U; /* {CLK_t,CLK_c} = 2'b01; */
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	disdynadrtri = config->uia.disdynadrtri;
+#else /* STM32MP_LPDDR4_TYPE */
+	disdynadrtri = 1U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	ddr2tmode = config->uia.is2ttiming;
+
+	tristatemodeca = (uint16_t)((ckdisval_def << CSR_CKDISVAL_LSB) |
+				    (ddr2tmode << CSR_DDR2TMODE_LSB) |
+				    (disdynadrtri << CSR_DISDYNADRTRI_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_TRISTATEMODECA_ADDR))),
+		      tristatemodeca);
+}
+
+/*
+ * Program DfiXlat based on Pll Bypass Input
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ *   - user_input_basic.pllbypass
+ */
+static void dfixlat_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t loopvector;
+	uint16_t pllbypass_dat = 0U;
+
+	pllbypass_dat |= (uint16_t)config->uib.pllbypass;
+
+	for (loopvector = 0U; loopvector < 8U; loopvector++) {
+		uint16_t dfifreqxlat_dat;
+		uintptr_t reg = (uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER |
+								  (CSR_DFIFREQXLAT0_ADDR +
+								   loopvector))));
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+		if (loopvector == 0U) {
+			/*
+			 * Relock DfiFreq = 00,01,02,03)  Use StartVec 5 (pll_enabled) or
+			 * StartVec 6 (pll_bypassed).
+			 */
+			dfifreqxlat_dat = pllbypass_dat + 0x5555U;
+
+			mmio_write_16(reg, dfifreqxlat_dat);
+		} else if (loopvector == 7U) {
+			/* LP3-entry DfiFreq = 1F */
+			mmio_write_16(reg, 0xF000U);
+		} else {
+			/*
+			 * Everything else = skip retrain  (could also map to 0000 since retrain
+			 * code is excluded, but this is cleaner).
+			 */
+			mmio_write_16(reg, 0x5555U);
+		}
+#else /* STM32MP_LPDDR4_TYPE */
+		if (loopvector == 0U) {
+			uint16_t skipddc_dat = 0U;	/*
+							 * Set to vector offset based on frequency
+							 * to disable dram drift compensation.
+							 */
+
+			if (config->uib.frequency < 333U) {
+				skipddc_dat |= 0x5U;
+			}
+
+			/*
+			 * Retrain & Relock DfiFreq = 00,01,02,03)  Use StartVec 0 (pll_enabled) or
+			 * StartVec 1 (pll_bypassed).
+			 */
+			dfifreqxlat_dat = pllbypass_dat + skipddc_dat;
+			mmio_write_16(reg, dfifreqxlat_dat);
+		} else if (loopvector == 2U) {
+			/*
+			 * Retrain only DfiFreq = 08,09,0A,0B)  Use StartVec 4 (1, and maybe 2,3,
+			 * used by verif).
+			 */
+			mmio_write_16(reg, 0x4444U);
+		} else if (loopvector == 3U) {
+			/* Phymstr type state change, StartVec 8 */
+			mmio_write_16(reg, 0x8888U);
+		} else if (loopvector == 4U) {
+			/*
+			 * Relock only DfiFreq = 10,11,12,13   Use StartVec 5 (pll_enabled) or
+			 * StartVec 6 (pll_bypassed).
+			 */
+			dfifreqxlat_dat = pllbypass_dat + 0x5555U;
+			mmio_write_16(reg, dfifreqxlat_dat);
+		} else if (loopvector == 7U) {
+			/* LP3-entry DfiFreq = 1F */
+			mmio_write_16(reg, 0xF000U);
+		} else {
+			/* Everything else */
+			mmio_write_16(reg, 0x0000U);
+		}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+	}
+}
+
+/*
+ * Program dqdqsrcvcntrl1 (Receiver Powerdown) and DbyteMiscMode
+ * - see function ddrphy_phyinit_isdbytedisabled() to determine
+ *   which DBytes are turned off completely based on PHY configuration.
+ * - Fields:
+ *   - DByteDisable
+ *   - PowerDownRcvr
+ *   - PowerDownRcvrDqs
+ *   - RxPadStandbyEn
+ * - Dependencies:
+ *   - user_input_basic.numdbyte
+ *   - user_input_basic.dramdatawidth (DDR3/DDR4)
+ *   - mb_ddr_1d->mr5 (DDR4)
+ *   - user_input_advanced.lp4dbird (LPDDR4)
+ */
+static void dqdqsrcvcntrl1_program(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint32_t d;
+	uint16_t mr5 __maybe_unused;
+	uint16_t regdata;
+	uint16_t regdata1;
+	uint16_t regdata2; /* Turn off Rx of DBI lane */
+
+	regdata = 0x1U << CSR_DBYTEDISABLE_LSB;
+
+	regdata1 = (0x1FFU << CSR_POWERDOWNRCVR_LSB) |
+		   (0x1U << CSR_POWERDOWNRCVRDQS_LSB) |
+		   (0x1U << CSR_RXPADSTANDBYEN_LSB);
+
+	regdata2 = (0x100U << CSR_POWERDOWNRCVR_LSB) | CSR_RXPADSTANDBYEN_MASK;
+
+#if STM32MP_DDR4_TYPE
+	/* OR all mr4 masked values, to help check in next loop */
+	mr5 = (mb_ddr_1d->mr5 >> 12) & 0x1U;
+#endif /* STM32MP_DDR4_TYPE */
+
+	for (d = 0U; d < config->uib.numdbyte; d++) {
+		uint32_t c_addr;
+
+		c_addr = d * C1;
+		if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, d) != 0) {
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+									CSR_DBYTEMISCMODE_ADDR))),
+				      regdata);
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+									CSR_DQDQSRCVCNTRL1_ADDR))),
+				      regdata1);
+		} else {
+			/* Disable RDBI lane if not used. */
+#if STM32MP_DDR3_TYPE
+			if (config->uib.dramdatawidth != 4U) {
+#elif STM32MP_DDR4_TYPE
+			if ((config->uib.dramdatawidth != 4U) && (mr5 == 0U)) {
+#else /* STM32MP_LPDDR4_TYPE */
+			if (config->uia.lp4dbird == 0U) {
+#endif /* STM32MP_DDR3_TYPE */
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								     CSR_DQDQSRCVCNTRL1_ADDR))),
+					      regdata2);
+			}
+		}
+	}
+}
+
+/*
+ * Program masterx4config
+ * - Fields:
+ *   - x4tg
+ *   - masterx4config
+ * - Dependencies:
+ *   - user_input_basic.dramdatawidth
+ *
+ * \note PHY does not support mixed dram device data width
+ */
+static void masterx4config_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t x4tg = 0U;
+	uint16_t masterx4config;
+
+	if (config->uib.dramdatawidth == 4U) {
+		x4tg = 0xFU;
+	}
+
+	masterx4config = (uint16_t)(x4tg << CSR_X4TG_LSB);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MASTERX4CONFIG_ADDR))),
+		      masterx4config);
+}
+
+#if !STM32MP_DDR3_TYPE
+/*
+ * Program dmipinpresent based on dramtype and Read-DBI enable
+ * - Fields:
+ *   - RdDbiEnabled
+ * - Dependencies:
+ *   - mb_ddr_1d->mr5 (DDR4)
+ *   - user_input_advanced.lp4dbird (LPDDR4)
+ */
+static void dmipinpresent_program(struct stm32mp_ddr_config *config,
+				  struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint16_t dmipinpresent;
+
+#if STM32MP_DDR4_TYPE
+	/* For DDR4, Read DBI is enabled in mr5-A12 */
+	dmipinpresent = (mb_ddr_1d->mr5 >> 12) & 0x1U;
+#else /* STM32MP_LPDDR4_TYPE */
+	dmipinpresent = (uint16_t)config->uia.lp4dbird;
+#endif /* STM32MP_DDR4_TYPE */
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DMIPINPRESENT_ADDR))),
+		      dmipinpresent);
+}
+#endif /* !STM32MP_DDR3_TYPE */
+
+/*
+ * Program aforcetricont and acx4anibdis
+ * - Fields:
+ *   - aforcetricont
+ *   - acx4anibdis
+ * - Dependencies:
+ *   - user_input_basic.numrank_dfi0
+ *   - user_input_basic.numrank_dfi1
+ *   - user_input_basic.numanib
+ *   - user_input_advanced.disableunusedaddrlns
+ */
+static void aforcetricont_acx4anibdis_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t anib;
+	uint16_t acx4anibdis = 0x0U;
+
+	for (anib = 0U; (anib < config->uib.numanib) && (config->uia.disableunusedaddrlns != 0U);
+	     anib++) {
+		uint32_t c_addr;
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+		uint32_t numrank = config->uib.numrank_dfi0 + config->uib.numrank_dfi1;
+#else /* STM32MP_LPDDR4_TYPE */
+		uint32_t numrank0 = config->uib.numrank_dfi0;
+		uint32_t numrank1 = config->uib.numrank_dfi1;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+		uint16_t aforcetricont = 0x0U;
+
+		c_addr = anib << 12;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+		if ((anib == 0U) && (numrank == 1U)) {
+			aforcetricont = 0x2U;
+		} else if ((anib == 1U) && (numrank == 1U)) {
+			aforcetricont = 0xCU;
+		} else if (anib == 6U) {
+			aforcetricont = 0x1U;
+		}
+#else /* STM32MP_LPDDR4_TYPE */
+		if ((anib == 0U) && (numrank0 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 0U) && (numrank0 == 1U)) {
+			aforcetricont = 0x2U;
+		} else if ((anib == 1U) && (numrank0 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 1U) && (numrank0 == 1U)) {
+			aforcetricont = 0x8U;
+		} else if ((anib == 2U) && (numrank0 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 3U) && (numrank1 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 3U) && (numrank1 == 1U)) {
+			aforcetricont = 0x2U;
+		} else if ((anib == 4U) && (numrank1 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if ((anib == 4U) && (numrank1 == 1U)) {
+			aforcetricont = 0x8U;
+		} else if ((anib == 5U) && (numrank1 == 0U)) {
+			aforcetricont = 0xFU;
+		} else if (anib == 6U) {
+			aforcetricont = 0xFU;
+		} else if (anib == 7U) {
+			aforcetricont = 0xFU;
+		}
+
+		/*
+		 * If all the lanes can be disabled, and Anib is not the first or last disable
+		 * entire chiplet
+		 */
+		if ((aforcetricont == 0xFU) && (anib != 0U) &&
+		    (anib != (config->uib.numanib - 1U))) {
+			acx4anibdis = acx4anibdis | (0x1U << anib);
+		}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TANIB | c_addr |
+								CSR_AFORCETRICONT_ADDR))),
+			      aforcetricont);
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_ACX4ANIBDIS_ADDR))),
+		      acx4anibdis);
+}
+
+/*
+ * Implements Step C of initialization sequence
+ *
+ * This function programs majority of PHY configuration registers based
+ * on data input into PhyInit data structures.
+ *
+ * This function programs PHY configuration registers based on information
+ * provided in the PhyInit data structures (config->uib, config->uia).
+ * The user can overwrite the programming of this function by modifying
+ * ddrphy_phyinit_usercustom_custompretrain().  Please see
+ * ddrphy_phyinit_struct.h for PhyInit data structure definition.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_c_initphyconfig(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t *ardptrinitval)
+{
+	uint32_t twotckrxdqspre;
+	int ret;
+
+	/*
+	 * Step (C) Initialize PHY Configuration
+	 * Load the required PHY configuration registers for the appropriate mode and memory
+	 * configuration.
+	 */
+
+	txslewrate_program(config);
+
+	atxslewrate_program(config);
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	dfidatacsdestmap_program(mb_ddr_1d);
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	pllctrl2_program(config);
+
+	ardptrinitval_program(config, ardptrinitval);
+
+#if STM32MP_LPDDR4_TYPE
+	procodtctl_program();
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	dbytedllmodecntrl_program(config, &twotckrxdqspre);
+
+	procodttimectl_program(config, twotckrxdqspre);
+
+	ret = txodtdrvstren_program(config);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = tximpedancectrl1_program(config);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = atximpedance_program(config);
+	if (ret != 0) {
+		return ret;
+	}
+
+	dfimode_program(config);
+
+	dficamode_program();
+
+	caldrvstr0_program(config);
+
+	caluclkinfo_program(config);
+
+	calibration_program(config);
+
+	vrefinglobal_program(config, mb_ddr_1d);
+
+	dfifreqratio_program(config);
+
+	tristatemodeca_program(config);
+
+	dfixlat_program(config);
+
+	dqdqsrcvcntrl1_program(config, mb_ddr_1d);
+
+	masterx4config_program(config);
+
+#if !STM32MP_DDR3_TYPE
+	dmipinpresent_program(config, mb_ddr_1d);
+
+#if STM32MP_LPDDR4_TYPE
+	/*
+	 * Program DFIPHYUPD
+	 * - Fields:
+	 *   - DFIPHYUPDMODE
+	 *   - DFIPHYUPDCNT
+	 * - Dependencies:
+	 *   - user_input_advanced.disablephyupdate
+	 */
+	if (config->uia.disablephyupdate != 0U) {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DFIPHYUPD_ADDR))),
+			      0x0U);
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+#endif /* !STM32MP_DDR3_TYPE */
+
+	aforcetricont_acx4anibdis_program(config);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_calcmb.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_calcmb.c
new file mode 100644
index 00000000..c5fa5f1b
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_calcmb.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * Reads PhyInit inputs structures and sets relevant message block
+ * parameters.
+ *
+ * This function sets Message Block parameters based on user_input_basic and
+ * user_input_advanced. user changes in these files takes precedence
+ * over this function call.
+ *
+ * MessageBlock fields set :
+ *  - dramtype
+ *  - pstate
+ *  - dramfreq
+ *  - pllbypassen
+ *  - dfifreqratio
+ *  - phyodtimpedance
+ *  - phydrvimpedance
+ *  - bpznresval
+ *  - enableddqscha (LPDDR4)
+ *  - cspresentcha (LPDDR4)
+ *  - enableddqsChb (LPDDR4)
+ *  - cspresentchb (LPDDR4)
+ *  - enableddqs (DDR3/DDR4)
+ *  - phycfg (DDR3/DDR4)
+ *  - x16present (DDR4)
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_calcmb(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint32_t nad0 = config->uib.numactivedbytedfi0;
+	uint32_t nad1 = 0;
+	uint16_t mr4 __maybe_unused;
+	uint16_t disableddbyte __maybe_unused;
+	uint32_t dbyte __maybe_unused;
+	int ret;
+
+#if STM32MP_LPDDR4_TYPE
+	nad1 = config->uib.numactivedbytedfi1;
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	/* A few checks to make sure valid programming */
+	if ((nad0 == 0U) || (config->uib.numdbyte == 0U)) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s numactivedbytedfi0, numactivedbytedfi0, NumByte out of range.\n",
+			__func__);
+		return -1;
+	}
+
+	if ((nad0 + nad1) > config->uib.numdbyte) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s numactivedbytedfi0+numactivedbytedfi1 is larger than numdbyteDfi0\n",
+			__func__);
+		return -1;
+	}
+
+	if ((config->uib.dfi1exists == 0U) && (nad1 != 0U)) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s dfi1exists==0 but numdbyteDfi0 != 0\n", __func__);
+		return -1;
+	}
+
+#if STM32MP_DDR4_TYPE
+	/* OR all mr4 masked values, to help check in next loop */
+	mr4 = mb_ddr_1d->mr4 & 0x1C0U;
+
+	/* 1D message block defaults */
+	if (mr4 != 0x0U) {
+		ERROR("mr4 != 0x0\n");
+		VERBOSE("%s Setting DRAM CAL mode is not supported by the PHY.\n", __func__);
+		VERBOSE("Memory controller may set CAL mode after PHY has entered mission\n");
+		VERBOSE("mode. Please check value programmed in mb_ddr_1d[*].mr4\n");
+		VERBOSE("and unset A8:6\n");
+		return -1;
+	}
+#endif /* STM32MP_DDR4_TYPE */
+
+#if STM32MP_DDR3_TYPE
+	if (config->uib.dimmtype == DDR_DIMMTYPE_NODIMM) {
+		ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DRAMTYPE, 0x1U);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+#elif STM32MP_DDR4_TYPE
+	if (config->uib.dimmtype == DDR_DIMMTYPE_NODIMM) {
+		ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DRAMTYPE, 0x2U);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+#else /* STM32MP_LPDDR4_TYPE */
+	/* Nothing to do */
+#endif /* STM32MP_DDR3_TYPE */
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PSTATE, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DRAMFREQ, config->uib.frequency * 2U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PLLBYPASSEN, config->uib.pllbypass);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (config->uib.dfifreqratio == 1U) {
+		ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DFIFREQRATIO, 0x2U);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PHYODTIMPEDANCE, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PHYDRVIMPEDANCE, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_BPZNRESVAL, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_ENABLEDDQS, nad0 * 8U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	disableddbyte = 0x0U;
+
+	for (dbyte = 0U; (dbyte < config->uib.numdbyte) && (dbyte < 8U); dbyte++) {
+		if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, dbyte) != 0) {
+			disableddbyte |= 0x1U << dbyte;
+		}
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_DISABLEDDBYTE, disableddbyte);
+	if (ret != 0) {
+		return ret;
+	}
+
+#if STM32MP_DDR3_TYPE
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PHYCFG, config->uia.is2ttiming);
+	if (ret != 0) {
+		return ret;
+	}
+#else /* STM32MP_DDR4_TYPE */
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_PHYCFG,
+				       ((mb_ddr_1d->mr3 & 0x8U) != 0U) ?
+				       0U : config->uia.is2ttiming);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_X16PRESENT,
+				       (config->uib.dramdatawidth == 0x10U) ?
+				       mb_ddr_1d->cspresent : 0x0U);
+	if (ret != 0) {
+		return ret;
+	}
+#endif /* STM32MP_DDR3_TYPE */
+#else /* STM32MP_LPDDR4_TYPE */
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_ENABLEDDQSCHA, nad0 * 8U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_CSPRESENTCHA,
+				       (config->uib.numrank_dfi0 == 2U) ?
+				       0x3U : config->uib.numrank_dfi0);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_ENABLEDDQSCHB, nad1 * 8U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_softsetmb(mb_ddr_1d, MB_FIELD_CSPRESENTCHB,
+				       (config->uib.numrank_dfi1 == 2U) ?
+				       0x3U : config->uib.numrank_dfi1);
+	if (ret != 0) {
+		return ret;
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_d_loadimem.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_d_loadimem.c
new file mode 100644
index 00000000..8bec30ba
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_d_loadimem.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * This function loads the training firmware IMEM image into the PHY.
+ *
+ * This function reads the DDR firmware source memory area to generate a
+ * set of apb writes to load IMEM image into the PHY. The exact steps in this
+ * function are as follows:
+ *
+ * -# Ensure DRAM is in reset.
+ * -# Load the microcontroller memory with the provided training firmware
+ * -# Initialize the firmware mailbox structures to be able to communicate with
+ * the firmware.
+ *
+ * \return void
+ */
+void ddrphy_phyinit_d_loadimem(void)
+{
+	uint16_t memresetl;
+	uint32_t *ptr32;
+
+	/* Set memresetl to avoid glitch on BP_MemReset_L during training */
+	memresetl = CSR_PROTECTMEMRESET_MASK;
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MEMRESETL_ADDR))), memresetl);
+
+	ptr32 = (uint32_t *)(STM32MP_DDR_FW_BASE + STM32MP_DDR_FW_IMEM_OFFSET);
+	ddrphy_phyinit_writeoutmem(ptr32, IMEM_ST_ADDR, IMEM_SIZE);
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_f_loaddmem.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_f_loaddmem.c
new file mode 100644
index 00000000..3c6c87f4
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_f_loaddmem.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <platform_def.h>
+
+/*
+ * This function loads the training firmware DMEM image and write the
+ * Message Block parameters for the training firmware into the PHY.
+ *
+ * This function performs the following tasks:
+ *
+ * -# Load the firmware DMEM segment to initialize the data structures from the
+ * DDR firmware source memory area.
+ * -# Write the Firmware Message Block with the required contents detailing the training parameters.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_f_loaddmem(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	uint32_t sizeofmsgblk;
+	uint16_t *ptr16;
+	uint32_t *ptr32;
+
+	/* Some basic checks on MessageBlock */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	if ((mb_ddr_1d->enableddqs > (8U * (uint8_t)config->uib.numactivedbytedfi0)) ||
+	    (mb_ddr_1d->enableddqs <= 0U)) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s enableddqs is Zero or greater than NumActiveDbytes for Dfi0\n",
+			__func__);
+		return -1;
+	}
+#else /* STM32MP_LPDDR4_TYPE */
+	if (((mb_ddr_1d->enableddqscha % 16U) != 0U) || ((mb_ddr_1d->enableddqschb % 16U) != 0U)) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s Lp3/Lp4 - Number of Dq's Enabled per Channel much be multipe of 16\n",
+			__func__);
+		return -1;
+	}
+
+	if ((mb_ddr_1d->enableddqscha > (uint8_t)(8U * config->uib.numactivedbytedfi0)) ||
+	    (mb_ddr_1d->enableddqschb > (uint8_t)(8U * config->uib.numactivedbytedfi1)) ||
+	    ((mb_ddr_1d->enableddqscha == 0U) && (mb_ddr_1d->enableddqschb == 0U))) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s EnabledDqsChA/B are not set correctly./1\n", __func__);
+		return -1;
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	sizeofmsgblk = sizeof(struct pmu_smb_ddr_1d);
+
+	ptr16 = (uint16_t *)mb_ddr_1d;
+	ddrphy_phyinit_writeoutmsgblk(ptr16, DMEM_ST_ADDR, sizeofmsgblk);
+
+	ptr32 = (uint32_t *)(STM32MP_DDR_FW_BASE + STM32MP_DDR_FW_DMEM_OFFSET);
+	ddrphy_phyinit_writeoutmem(ptr32, DMEM_ST_ADDR + DMEM_BIN_OFFSET,
+				   DMEM_SIZE - STM32MP_DDR_FW_DMEM_OFFSET);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_g_execfw.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_g_execfw.c
new file mode 100644
index 00000000..0c11594b
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_g_execfw.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * Execute the Training Firmware
+ *
+ * The training firmware is executed with the procedure:
+ *
+ * -# Reset the firmware microcontroller by writing the MicroReset register to
+ * set the StallToMicro and ResetToMicro fields to 1 (all other fields should be
+ * zero). Then rewrite the registers so that only the StallToMicro remains set
+ * (all other fields should be zero).
+ * -# Begin execution of the training firmware by setting the MicroReset
+ * register to 0.
+ * -# Wait for the training firmware to complete by following the procedure implemented in
+ * ddrphy_phyinit_usercustom_g_waitfwdone() function.
+ * -# Halt the microcontroller.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_g_execfw(void)
+{
+	int ret;
+
+	/*
+	 * 1. Reset the firmware microcontroller by writing the MicroReset CSR to set the
+	 * StallToMicro and ResetToMicro fields to 1 (all other fields should be zero).
+	 * Then rewrite the CSR so that only the StallToMicro remains set (all other fields should
+	 * be zero).
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      CSR_STALLTOMICRO_MASK);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICRORESET_ADDR))),
+		      CSR_RESETTOMICRO_MASK | CSR_STALLTOMICRO_MASK);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICRORESET_ADDR))),
+		      CSR_STALLTOMICRO_MASK);
+
+	/* 2. Begin execution of the training firmware by setting the MicroReset CSR to 0 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICRORESET_ADDR))), 0x0U);
+
+	/*
+	 * 3. Wait for the training firmware to complete by following the procedure
+	 * implemented in ddrphy_phyinit_usercustom_g_waitfwdone() function.
+	 */
+	ret = ddrphy_phyinit_usercustom_g_waitfwdone();
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* 4. Halt the microcontroller */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICRORESET_ADDR))),
+		      CSR_STALLTOMICRO_MASK);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_i_loadpieimage.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_i_loadpieimage.c
new file mode 100644
index 00000000..6ca0ddcd
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_i_loadpieimage.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#if STM32MP_LPDDR4_TYPE
+/*
+ * Program DfiWrRdDataCsConfig
+ * - Fields:
+ *   - dfiwrdatacspolarity
+ *   - dfirddatacspolarity
+ */
+static void dfiwrrddatacsconfig_program(void)
+{
+	uint16_t dfiwrdatacspolarity;
+	uint16_t dfirddatacspolarity;
+
+	/*
+	 * DfiWrRdDataCsConfig : dfiwrdatacspolarity=0x1 and dfirddatacspolarity=0x1.
+	 * Set DataCsPolarity bits to enable active high
+	 */
+	dfiwrdatacspolarity = 0x1U;
+	dfirddatacspolarity = 0x1U;
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | C0 |
+							CSR_DFIWRRDDATACSCONFIG_ADDR))),
+		      (dfiwrdatacspolarity << CSR_DFIWRDATACSPOLARITY_LSB) |
+		      (dfirddatacspolarity << CSR_DFIRDDATACSPOLARITY_LSB));
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+/*
+ * Registers: Seq0BDLY0, Seq0BDLY1, Seq0BDLY2, Seq0BDLY3
+ * - Program PIE instruction delays
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ */
+static void seq0bdly_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t lowfreqopt __unused;
+	uint16_t dfifrq_x10;
+	uint16_t pscount_ref;
+	uint16_t pscount[4]; /* Need delays for 0.5us, 1us, 10us, and 25us */
+
+	/*
+	 * Calculate the counts to obtain the correct delay for each frequency
+	 * Need to divide by 4 since the delay value are specified in units of
+	 * 4 clocks.
+	 */
+	dfifrq_x10 = (10U * (uint16_t)config->uib.frequency) / 2U;
+	pscount_ref = dfifrq_x10 / 4U;
+	pscount[0] = pscount_ref / (2U * 10U);
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	if (config->uib.frequency < 400U) {
+		lowfreqopt = 3U;
+	} else if (config->uib.frequency < 533U) {
+		lowfreqopt = 11U;
+	} else {
+		lowfreqopt = 0U;
+	}
+
+	pscount[1] = (pscount_ref / 10U) - lowfreqopt;
+#else /* STM32MP_LPDDR4_TYPE */
+	pscount[1] = pscount_ref / 10U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+	pscount[2] = pscount_ref;
+
+	if (dfifrq_x10 > 2665U) {
+		pscount[3] = 44U;
+	} else if ((dfifrq_x10 <= 2665U) && (dfifrq_x10 > 2000U)) {
+		pscount[3] = 33U;
+	} else {
+		pscount[3] = 16U;
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER | CSR_SEQ0BDLY0_ADDR))),
+		      pscount[0]);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER | CSR_SEQ0BDLY1_ADDR))),
+		      pscount[1]);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER | CSR_SEQ0BDLY2_ADDR))),
+		      pscount[2]);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TMASTER | CSR_SEQ0BDLY3_ADDR))),
+		      pscount[3]);
+}
+
+/*
+ * Registers: Seq0BDisableFlag0..7
+ * - Program PIE Instruction Disable Flags
+ * - Dependencies:
+ *   - user_input_advanced.DisableRetraining (LPDDR4)
+ *   - skip_training (LPDDR4)
+ *   - user_input_basic.frequency (LPDDR4)
+ */
+static void seq0bdisableflag_program(struct stm32mp_ddr_config *config, bool skip_training)
+{
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG0_ADDR))),
+		      0x0000U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG1_ADDR))),
+		      0x0173U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG2_ADDR))),
+		      0x0060U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG3_ADDR))),
+		      0x6110U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG4_ADDR))),
+		      0x2152U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG5_ADDR))),
+		      0xDFBDU);
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG6_ADDR))),
+		      0xFFFFU);
+#else /* STM32MP_LPDDR4_TYPE */
+	if (skip_training || (config->uia.disableretraining != 0U) ||
+	    (config->uib.frequency < 333U)) {
+		/* Disabling DRAM drift compensation */
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG |
+								CSR_SEQ0BDISABLEFLAG6_ADDR))),
+			      0xFFFFU);
+	} else {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG |
+								CSR_SEQ0BDISABLEFLAG6_ADDR))),
+			      0x2060U);
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	/*
+	 * - Register: Seq0BGPR7
+	 *   - Program active CSx for MRS7 during D4 RDIMM frequency change
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BDISABLEFLAG7_ADDR))),
+		      0x6152U);
+}
+
+#if STM32MP_LPDDR4_TYPE
+/*
+ * Registers: ppttrainsetup and ppttrainsetup2
+ * - Related to DFI PHY Master Interface (PMI).
+ * - Enable DFI PMI if training firmware was run
+ * - Fields:
+ *   - PhyMstrTrainInterval
+ *   - PhyMstrMaxReqToAck
+ *   - PhyMstrFreqOverride
+ * - Dependencies:
+ *   - user_input_basic.frequency
+ *   - user_input_advanced.PhyMstrTrainInterval
+ *   - user_input_advanced.PhyMstrMaxReqToAck
+ */
+static void ppttrainsetup_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t ppttrainsetup;
+
+	/* Enabling Phy Master Interface for DRAM drift compensation */
+	if (config->uib.frequency >= 333U) {
+		ppttrainsetup =	(uint16_t)((config->uia.phymstrtraininterval <<
+					    CSR_PHYMSTRTRAININTERVAL_LSB) |
+					   (config->uia.phymstrmaxreqtoack <<
+					    CSR_PHYMSTRMAXREQTOACK_LSB));
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_PPTTRAINSETUP_ADDR))),
+			      ppttrainsetup);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER |
+								CSR_PPTTRAINSETUP2_ADDR))),
+			      0x0003U);
+	}
+}
+
+/*
+ * Registers AcsmPlayback*x*
+ * - Program Address/Command Sequence Engine (ACSM) registers with
+ *   required instructions for retraining algorithm.
+ */
+static void acsmplayback_program(void)
+{
+	uint32_t vec;
+
+	for (vec = 0U; vec < 3U; vec++) {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TACSM | (CSR_ACSMPLAYBACK0X0_ADDR +
+									 (vec * 2U))))),
+			      0xE0U);
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TACSM | (CSR_ACSMPLAYBACK1X0_ADDR +
+									 (vec * 2U))))),
+			      0x12U);
+	}
+}
+
+/*
+ * Program Training Hardware Registers for mission mode retraining
+ * and DRAM drift compensation algorithm.
+ */
+static void traininghwreg_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte;
+
+	/* Programing Training Hardware Registers for mission mode retraining */
+
+	/*
+	 * - Register: AcsmCtrl13
+	 *   - Fields: AcsmCkeEnb
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TACSM | CSR_ACSMCTRL13_ADDR))),
+		      0xFU << CSR_ACSMCKEENB_LSB);
+
+	/*
+	 * - Register: AcsmCtrl1
+	 *   - Fields: AcsmRepCnt
+	 *             Need 19 iterations @ 0.25ui increments to cover 4.5UI
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TACSM | CSR_ACSMCTRL1_ADDR))),
+		      0xEU << CSR_ACSMREPCNT_LSB);
+
+	/*
+	 * - Register: TsmByte1, TsmByte2
+	 *   - Dependencies: config->uib.numdbyte
+	 */
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t i_addr;
+		uint16_t regdata;
+		uint32_t vec;
+
+		c_addr = byte * C1;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TSMBYTE1_ADDR))),
+			      0x1U);   /* [15:8] gstep; [7:0]bstep; */
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TSMBYTE2_ADDR))),
+			      0x1U);   /* [15:0] good_bar; */
+
+		regdata = (CSR_DTSMSTATICCMPR_MASK | CSR_DTSMSTATICCMPRVAL_MASK);
+
+		/*
+		 * - Register: TsmByte3, TsmByte5
+		 *   - Fields:
+		 *     - DtsmStaticCmpr
+		 *     - DtsmStaticCmprVal
+		 */
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TSMBYTE3_ADDR))),
+			      regdata);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TSMBYTE5_ADDR))),
+			      0x1U); /* [15:0] bad_bar; */
+
+		/*
+		 * - Register: TrainingParam
+		 *   - Fields:
+		 *     - EnDynRateReduction
+		 *     - RollIntoCoarse
+		 *     - IncDecRate
+		 *     - TrainEnRxEn
+		 *   - Dependencies:
+		 *     - user_input_advanced.DisableRetraining
+		 */
+		regdata = (CSR_ENDYNRATEREDUCTION_MASK | CSR_ROLLINTOCOARSE_MASK |
+			   (0x3U << CSR_INCDECRATE_LSB));
+		regdata = config->uia.disableretraining ?
+			  regdata : (regdata | CSR_TRAINENRXEN_MASK);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_TRAININGPARAM_ADDR))),
+			      regdata);
+
+		/*
+		 * - Register: Tsm0
+		 *   - Fields:
+		 *     - DtsmEnb
+		 */
+		regdata = (0x1U << CSR_DTSMENB_LSB);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | I0 | TDBYTE |
+								CSR_TSM0_ADDR))),
+			      regdata);
+
+		/*
+		 * - Register: Tsm2
+		 *   - Fields:
+		 *     - DtsmDisErrChk
+		 */
+		regdata = (0x1U << CSR_DTSMDISERRCHK_LSB);
+		for (vec = 1U; vec <= I_MAX; vec++) {
+			i_addr = vec * I1;
+			mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | i_addr | TDBYTE |
+									CSR_TSM2_ADDR))),
+				      regdata);
+		}
+	}
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+/*
+ * - Register: calrate
+ *   - Fields:
+ *     - calOnce
+ *     - calinterval
+ *   - Dependencies
+ *     - user_input_advanced.calinterval
+ *     - user_input_advanced.calonce
+ */
+static void calrate_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t calinterval;
+	uint32_t calonce;
+	uint16_t calrate;
+
+	calinterval = config->uia.calinterval;
+	calonce = config->uia.calonce;
+
+	calrate = (uint16_t)((0x1U << CSR_CALRUN_LSB) | (calonce << CSR_CALONCE_LSB) |
+			     (calinterval << CSR_CALINTERVAL_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALRATE_ADDR))), calrate);
+}
+
+/*
+ * Loads registers after training
+ *
+ * This function programs the PHY Initialization Engine (PIE) instructions and
+ * the associated registers.
+ * Training hardware registers are also programmed to for mission mode
+ * retraining. (LPDDR4)
+ *
+ * \return void
+ */
+void ddrphy_phyinit_i_loadpieimage(struct stm32mp_ddr_config *config, bool skip_training)
+{
+	/*
+	 * Enable access to the internal CSRs by setting the MicroContMuxSel CSR to 0.
+	 * This allows the memory controller unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+
+	ddrphy_phyinit_loadpieprodcode();
+
+#if STM32MP_LPDDR4_TYPE
+	/*
+	 * No user specified EnableDfiCsPolarityFix, running with new PUB with DFI CS polarity fix
+	 * so program the data polarity CSR.
+	 */
+	dfiwrrddatacsconfig_program();
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	seq0bdly_program(config);
+
+	seq0bdisableflag_program(config, skip_training);
+
+#if STM32MP_LPDDR4_TYPE
+	if (!skip_training) {
+		ppttrainsetup_program(config);
+	}
+
+	acsmplayback_program();
+
+	traininghwreg_program(config);
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	/*
+	 * - Register: CalZap
+	 *   - Prepare the calibration controller for mission mode.
+	 *     Turn on calibration and hold idle until dfi_init_start is asserted sequence is
+	 *     triggered.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALZAP_ADDR))), 0x1U);
+
+	calrate_program(config);
+
+	/*
+	 * At the end of this function, PHY Clk gating register UcclkHclkEnables is
+	 * set for mission mode.  Additionally APB access is Isolated by setting
+	 * MicroContMuxSel.
+	 */
+	/* Disabling Ucclk (PMU) and Hclk (training hardware) */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x0U);
+
+	/* Isolate the APB access from the internal CSRs by setting the MicroContMuxSel CSR to 1 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_initstruct.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_initstruct.c
new file mode 100644
index 00000000..50a88be4
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_initstruct.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * This is used to initialize the PhyInit structures before user defaults and overrides are applied.
+ *
+ * @return Void
+ */
+void ddrphy_phyinit_initstruct(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	/*
+	 * ##############################################################
+	 * Basic Message Block Variables
+	 * ##############################################################
+	 */
+
+	uint8_t msgmisc = 0x00U;	/* For fast simulation */
+	uint8_t reserved00 = 0x0U;	/*
+					 * Set reserved00[7] = 1 (If using T28 attenuated receivers)
+					 * Set reserved00[6:0] = 0 (Reserved; must be set to 0)
+					 */
+
+	uint8_t hdtctrl = 0xFFU;
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	uint8_t cspresent = 0x01U;	/*
+					 * Indicates presence of DRAM at each chip select for PHY.
+					 *
+					 * If the bit is set to 1, the CS is connected to DRAM.
+					 * If the bit is set to 0, the CS is not connected to DRAM.
+					 *
+					 * Set cspresent[0]   = 1 (if CS0 is populated with DRAM)
+					 * Set cspresent[1]   = 1 (if CS1 is populated with DRAM)
+					 * Set cspresent[2]   = 1 (if CS2 is populated with DRAM)
+					 * Set cspresent[3]   = 1 (if CS3 is populated with DRAM)
+					 * Set cspresent[7:4] = 0 (Reserved; must be set to 0)
+					 */
+	uint8_t dfimrlmargin = 0x01U;	/* 1 is typically good in DDR3 */
+#if STM32MP_DDR3_TYPE
+	uint8_t addrmirror = 0x00U;	/*
+					 * Set addrmirror if CS is mirrored.
+					 * (typically odd CS are mirroed in DIMMs)
+					 */
+#else /* STM32MP_DDR4_TYPE */
+	uint8_t addrmirror = 0xAAU;
+#endif /* STM32MP_DDR3_TYPE */
+	uint8_t wrodtpat_rank0 = 0x01U;	/*
+					 * When Writing Rank0 : Bits[3:0] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+	uint8_t wrodtpat_rank1 = 0x02U;	/*
+					 * When Writing Rank1 : Bits[3:0] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+#if STM32MP_DDR3_TYPE
+	uint8_t wrodtpat_rank2 = 0x04U;	/*
+					 * When Writing Rank2 : Bits[3:0] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+	uint8_t wrodtpat_rank3 = 0x08U;	/*
+					 * When Writing Rank3 : Bits[3:0] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+#else /* STM32MP_DDR4_TYPE */
+	uint8_t wrodtpat_rank2 = 0x00U;
+	uint8_t wrodtpat_rank3 = 0x00U;
+#endif /* STM32MP_DDR3_TYPE */
+	uint8_t rdodtpat_rank0 = 0x20U;	/*
+					 * When Reading Rank0 : Bits[7:4] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+	uint8_t rdodtpat_rank1 = 0x10U;	/*
+					 * When Reading Rank1 : Bits[7:4] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+#if STM32MP_DDR3_TYPE
+	uint8_t rdodtpat_rank2 = 0x80U;	/*
+					 * When Reading Rank2 : Bits[7:4] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+	uint8_t rdodtpat_rank3 = 0x40U;	/*
+					 * When Reading Rank3 : Bits[7:4] should be set to the
+					 * desired setting of ODT[3:0] to the DRAM
+					 */
+#else /* STM32MP_DDR4_TYPE */
+	uint8_t rdodtpat_rank2 = 0x00U;
+	uint8_t rdodtpat_rank3 = 0x00U;
+
+	uint8_t d4misc = 0x1U;		/*
+					 * Protect memory reset:
+					 * 0x1 = dfi_reset_n cannot control BP_MEMRESERT_L to
+					 *       devices after training.
+					 * 0x0 = dfi_resert_n can control BP_MEMRESERT_L to
+					 *       devices after training.
+					 */
+#endif /* STM32MP_DDR3_TYPE */
+#else /* STM32MP_LPDDR4_TYPE */
+	uint8_t caterminatingrankcha = 0x00U; /* Usually Rank0 is terminating rank */
+	uint8_t caterminatingrankchb = 0x00U; /* Usually Rank0 is terminating rank */
+	uint8_t dfimrlmargin = 0x02U; /* This needs to be large enough for max tDQSCK variation */
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+#if STM32MP_DDR3_TYPE
+	uint8_t share2dvrefresult = 0x0U;	/*
+						 * Bitmap that controls which vref generator the
+						 * phy will use per pstate
+						 *     If share2dvrefresult[x] = 1, pstate x will
+						 *     use the per-lane VrefDAC0/1 CSRs which can be
+						 *     trained by 2d training. If 2D has not run
+						 *     yet, VrefDAC0/1 will default to pstate 0's
+						 *     1D phyVref messageBlock setting.
+						 *     If share2dvrefresult[x] = 0, pstate x will
+						 *     use the per-phy VrefInGlobal CSR, which are
+						 *     set to pstate x's 1D phyVref messageBlock
+						 *     setting.
+						 */
+#elif STM32MP_DDR4_TYPE
+	uint8_t share2dvrefresult = 0x1U;
+#else /* STM32MP_LPDDR4_TYPE */
+	uint8_t share2dvrefresult = 0x1U;
+	uint8_t usebroadcastmr = 0x00U;
+#endif /* STM32MP_DDR3_TYPE */
+
+	/* 1D message block defaults */
+	memset((void *)mb_ddr_1d, 0, sizeof(struct pmu_smb_ddr_1d));
+
+	mb_ddr_1d->pstate = 0U;
+	mb_ddr_1d->sequencectrl = (uint16_t)config->uia.sequencectrl;
+	mb_ddr_1d->phyconfigoverride = 0x0U;
+	mb_ddr_1d->hdtctrl = hdtctrl;
+	mb_ddr_1d->msgmisc = msgmisc;
+	mb_ddr_1d->reserved00 = reserved00;
+	mb_ddr_1d->dfimrlmargin = dfimrlmargin;
+	mb_ddr_1d->phyvref = (uint8_t)config->uia.phyvref;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	mb_ddr_1d->cspresent = cspresent;
+	mb_ddr_1d->cspresentd0 = cspresent;
+	/* mb_ddr_1d->cspresentd1 = 0x0U; Unused */
+	mb_ddr_1d->addrmirror = addrmirror;
+
+	mb_ddr_1d->acsmodtctrl0 = wrodtpat_rank0 | rdodtpat_rank0;
+	mb_ddr_1d->acsmodtctrl1 = wrodtpat_rank1 | rdodtpat_rank1;
+	mb_ddr_1d->acsmodtctrl2 = wrodtpat_rank2 | rdodtpat_rank2;
+	mb_ddr_1d->acsmodtctrl3 = wrodtpat_rank3 | rdodtpat_rank3;
+
+	/* mb_ddr_1d->acsmodtctrl4 = 0x0U; Unused */
+	/* mb_ddr_1d->acsmodtctrl5 = 0x0U; Unused */
+	/* mb_ddr_1d->acsmodtctrl6 = 0x0U; Unused */
+	/* mb_ddr_1d->acsmodtctrl7 = 0x0U; Unused */
+	mb_ddr_1d->enableddqs = (uint8_t)((config->uib.numactivedbytedfi0 +
+					   config->uib.numactivedbytedfi1) * 8U);
+#if STM32MP_DDR3_TYPE
+	mb_ddr_1d->phycfg = (uint8_t)config->uia.is2ttiming;
+#else /* STM32MP_DDR4_TYPE */
+	mb_ddr_1d->phycfg = ((config->uim.mr3 & 0x8U) == 0x8U) ?
+			      0U : (uint8_t)config->uia.is2ttiming;
+	mb_ddr_1d->x16present = (config->uib.dramdatawidth == 0x10) ?
+				mb_ddr_1d->cspresent : 0x0U;
+	mb_ddr_1d->d4misc = d4misc;
+	mb_ddr_1d->cssetupgddec = 0x1U;	/* If Geardown is chosen, dynamically modify CS timing */
+
+	/*
+	 * Outputs - just initialize these to zero
+	 * mb_ddr_1d->rtt_nom_wr_park<0..7>
+	 */
+#endif /* STM32MP_DDR3_TYPE */
+
+	mb_ddr_1d->mr0 = (uint16_t)config->uim.mr0;
+	mb_ddr_1d->mr1 = (uint16_t)config->uim.mr1;
+	mb_ddr_1d->mr2 = (uint16_t)config->uim.mr2;
+#if STM32MP_DDR4_TYPE
+	mb_ddr_1d->mr3 = (uint16_t)config->uim.mr3;
+	mb_ddr_1d->mr4 = (uint16_t)config->uim.mr4;
+	mb_ddr_1d->mr5 = (uint16_t)config->uim.mr5;
+	mb_ddr_1d->mr6 = (uint16_t)config->uim.mr6;
+
+	mb_ddr_1d->alt_cas_l = 0x0U;
+	mb_ddr_1d->alt_wcas_l = 0x0U;
+
+	/*
+	 * Outputs - just initialize these to zero
+	 * mb_ddr_1d->vrefdqr<0..3>nib<0..19>
+	 */
+#endif /* STM32MP_DDR4_TYPE */
+#else /* STM32MP_LPDDR4_TYPE */
+	mb_ddr_1d->enableddqscha = (uint8_t)(config->uib.numactivedbytedfi0 * 8U);
+	mb_ddr_1d->cspresentcha = (config->uib.numrank_dfi0 == 2U) ?
+				  0x3U : (uint8_t)config->uib.numrank_dfi0;
+	mb_ddr_1d->enableddqschb = (uint8_t)(config->uib.numactivedbytedfi1 * 8U);
+	mb_ddr_1d->cspresentchb = (config->uib.numrank_dfi1 == 2U) ?
+				  0x3U : (uint8_t)config->uib.numrank_dfi1;
+	mb_ddr_1d->usebroadcastmr = usebroadcastmr;
+
+	mb_ddr_1d->lp4misc = 0x00U;
+	mb_ddr_1d->caterminatingrankcha = caterminatingrankcha;
+	mb_ddr_1d->caterminatingrankchb = caterminatingrankchb;
+	mb_ddr_1d->lp4quickboot = 0x00U;
+	mb_ddr_1d->catrainopt = 0x00U;
+	mb_ddr_1d->x8mode = 0x00U;
+
+	mb_ddr_1d->mr1_a0 = (uint8_t)config->uim.mr1;
+	mb_ddr_1d->mr2_a0 = (uint8_t)config->uim.mr2;
+	mb_ddr_1d->mr3_a0 = (uint8_t)config->uim.mr3;
+	mb_ddr_1d->mr4_a0 = (uint8_t)config->uim.mr4;
+	mb_ddr_1d->mr11_a0 = (uint8_t)config->uim.mr11;
+	mb_ddr_1d->mr12_a0 = (uint8_t)config->uim.mr12;
+	mb_ddr_1d->mr13_a0 = (uint8_t)config->uim.mr13;
+	mb_ddr_1d->mr14_a0 = (uint8_t)config->uim.mr14;
+	mb_ddr_1d->mr16_a0 = 0x00U;
+	mb_ddr_1d->mr17_a0 = 0x00U;
+	mb_ddr_1d->mr22_a0 = (uint8_t)config->uim.mr22;
+	mb_ddr_1d->mr24_a0 = 0x00U;
+	mb_ddr_1d->mr1_a1 = (uint8_t)config->uim.mr1;
+	mb_ddr_1d->mr2_a1 = (uint8_t)config->uim.mr2;
+	mb_ddr_1d->mr3_a1 = (uint8_t)config->uim.mr3;
+	mb_ddr_1d->mr4_a1 = (uint8_t)config->uim.mr4;
+	mb_ddr_1d->mr11_a1 = (uint8_t)config->uim.mr11;
+	mb_ddr_1d->mr12_a1 = (uint8_t)config->uim.mr12;
+	mb_ddr_1d->mr13_a1 = (uint8_t)config->uim.mr13;
+	mb_ddr_1d->mr14_a1 = (uint8_t)config->uim.mr14;
+	mb_ddr_1d->mr16_a1 = 0x00U;
+	mb_ddr_1d->mr17_a1 = 0x00U;
+	mb_ddr_1d->mr22_a1 = (uint8_t)config->uim.mr22;
+	mb_ddr_1d->mr24_a1 = 0x00U;
+
+	mb_ddr_1d->mr1_b0 = (uint8_t)config->uim.mr1;
+	mb_ddr_1d->mr2_b0 = (uint8_t)config->uim.mr2;
+	mb_ddr_1d->mr3_b0 = (uint8_t)config->uim.mr3;
+	mb_ddr_1d->mr4_b0 = (uint8_t)config->uim.mr4;
+	mb_ddr_1d->mr11_b0 = (uint8_t)config->uim.mr11;
+	mb_ddr_1d->mr12_b0 = (uint8_t)config->uim.mr12;
+	mb_ddr_1d->mr13_b0 = (uint8_t)config->uim.mr13;
+	mb_ddr_1d->mr14_b0 = (uint8_t)config->uim.mr14;
+	mb_ddr_1d->mr16_b0 = 0x00U;
+	mb_ddr_1d->mr17_b0 = 0x00U;
+	mb_ddr_1d->mr22_b0 = (uint8_t)config->uim.mr22;
+	mb_ddr_1d->mr24_b0 = 0x00U;
+	mb_ddr_1d->mr1_b1 = (uint8_t)config->uim.mr1;
+	mb_ddr_1d->mr2_b1 = (uint8_t)config->uim.mr2;
+	mb_ddr_1d->mr3_b1 = (uint8_t)config->uim.mr3;
+	mb_ddr_1d->mr4_b1 = (uint8_t)config->uim.mr4;
+	mb_ddr_1d->mr11_b1 = (uint8_t)config->uim.mr11;
+	mb_ddr_1d->mr12_b1 = (uint8_t)config->uim.mr12;
+	mb_ddr_1d->mr13_b1 = (uint8_t)config->uim.mr13;
+	mb_ddr_1d->mr14_b1 = (uint8_t)config->uim.mr14;
+	mb_ddr_1d->mr16_b1 = 0x00U;
+	mb_ddr_1d->mr17_b1 = 0x00U;
+	mb_ddr_1d->mr22_b1 = (uint8_t)config->uim.mr22;
+	mb_ddr_1d->mr24_b1 = 0x00U;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	mb_ddr_1d->share2dvrefresult = share2dvrefresult;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_isdbytedisabled.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_isdbytedisabled.c
new file mode 100644
index 00000000..4daf2bb0
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_isdbytedisabled.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+#include <ddrphy_wrapper.h>
+
+/*
+ * Helper function to determine if a given DByte is Disabled given PhyInit inputs.
+ * @return 1 if disabled, 0 if enabled.
+ */
+int ddrphy_phyinit_isdbytedisabled(struct stm32mp_ddr_config *config,
+				   struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t dbytenumber)
+{
+	int disabledbyte;
+	uint32_t nad0 __maybe_unused;
+	uint32_t nad1 __maybe_unused;
+
+	disabledbyte = 0; /* Default assume Dbyte is Enabled */
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	disabledbyte = (dbytenumber > (config->uib.numactivedbytedfi0 - 1U)) ? 1 : 0;
+#else /* STM32MP_LPDDR4_TYPE */
+	nad0 = config->uib.numactivedbytedfi0;
+	nad1 = config->uib.numactivedbytedfi1;
+
+	if ((nad0 + nad1) > config->uib.numdbyte) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s invalid PHY configuration:\n", __func__);
+		VERBOSE("numactivedbytedfi0(%u)+numactivedbytedfi1(%u)>numdbytes(%u).\n",
+			nad0, nad1, config->uib.numdbyte);
+	}
+
+	if (config->uib.dfi1exists != 0U) {
+		if (config->uib.numactivedbytedfi1 == 0U) {
+			/* Only dfi0 (ChA) is enabled, dfi1 (ChB) disabled */
+			disabledbyte = (dbytenumber > (config->uib.numactivedbytedfi0 - 1U)) ?
+				       1 : 0;
+		} else {
+			/* DFI1 enabled */
+			disabledbyte = (((config->uib.numactivedbytedfi0 - 1U) < dbytenumber) &&
+					(dbytenumber < (config->uib.numdbyte / 2U))) ?
+				       1 : (dbytenumber >
+					    ((config->uib.numdbyte / 2U) +
+					     config->uib.numactivedbytedfi1 - 1U)) ? 1 : 0;
+		}
+	} else {
+		disabledbyte = (dbytenumber > (config->uib.numactivedbytedfi0 - 1U)) ? 1 : 0;
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	/* Qualify results against MessageBlock */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	if ((mb_ddr_1d->enableddqs < 1U) ||
+	    (mb_ddr_1d->enableddqs > (uint8_t)(8U * config->uib.numactivedbytedfi0))) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s enableddqs(%u)\n", __func__, mb_ddr_1d->enableddqs);
+		VERBOSE("Value must be 0 < enableddqs < config->uib.numactivedbytedfi0 * 8.\n");
+	}
+
+	if (dbytenumber < 8) {
+		disabledbyte |= (int)mb_ddr_1d->disableddbyte & (0x1 << dbytenumber);
+	}
+#else /* STM32MP_LPDDR4_TYPE */
+	if ((mb_ddr_1d->enableddqscha < 1U) ||
+	    (mb_ddr_1d->enableddqscha > (uint8_t)(8U * config->uib.numactivedbytedfi0))) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s enableddqscha(%u)\n", __func__, mb_ddr_1d->enableddqscha);
+		VERBOSE("Value must be 0 < enableddqscha < config->uib.numactivedbytedfi0*8\n");
+	}
+
+	if ((config->uib.dfi1exists != 0U) && (config->uib.numactivedbytedfi1 > 0U) &&
+	    ((mb_ddr_1d->enableddqschb < 1U) ||
+	     (mb_ddr_1d->enableddqschb > (uint8_t)(8U * config->uib.numactivedbytedfi1)))) {
+		ERROR("%s %d\n", __func__, __LINE__);
+		VERBOSE("%s enableddqschb(%u)\n", __func__, mb_ddr_1d->enableddqschb);
+		VERBOSE("Value must be 0 < enableddqschb < config->uib.numactivedbytedfi1*8\n");
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+	return disabledbyte;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_loadpieprodcode.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_loadpieprodcode.c
new file mode 100644
index 00000000..2843b10e
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_loadpieprodcode.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+#define PRODCODE_SIZE	177
+
+static const uint32_t prodcode_addr[PRODCODE_SIZE] = {
+	0x90000U, 0x90001U, 0x90002U, 0x90003U, 0x90004U, 0x90005U, 0x90029U, 0x9002AU, 0x9002BU,
+	0x9002CU, 0x9002DU, 0x9002EU, 0x9002FU, 0x90030U, 0x90031U, 0x90032U, 0x90033U, 0x90034U,
+	0x90035U, 0x90036U, 0x90037U, 0x90038U, 0x90039U, 0x9003AU, 0x9003BU, 0x9003CU, 0x9003DU,
+	0x9003EU, 0x9003FU, 0x90040U, 0x90041U, 0x90042U, 0x90043U, 0x90044U, 0x90045U, 0x90046U,
+	0x90047U, 0x90048U, 0x90049U, 0x9004AU, 0x9004BU, 0x9004CU, 0x9004DU, 0x9004EU, 0x9004FU,
+	0x90050U, 0x90051U, 0x90052U, 0x90053U, 0x90054U, 0x90055U, 0x90056U, 0x90057U, 0x90058U,
+	0x90059U, 0x9005AU, 0x9005BU, 0x9005CU, 0x9005DU, 0x9005EU, 0x9005FU, 0x90060U, 0x90061U,
+	0x90062U, 0x90063U, 0x90064U, 0x90065U, 0x90066U, 0x90067U, 0x90068U, 0x90069U, 0x9006AU,
+	0x9006BU, 0x9006CU, 0x9006DU, 0x9006EU, 0x9006FU, 0x90070U, 0x90071U, 0x90072U, 0x90073U,
+	0x90074U, 0x90075U, 0x90076U, 0x90077U, 0x90078U, 0x90079U, 0x9007AU, 0x9007BU, 0x9007CU,
+	0x9007DU, 0x9007EU, 0x9007FU, 0x90080U, 0x90081U, 0x90082U, 0x90083U, 0x90084U, 0x90085U,
+	0x90086U, 0x90087U, 0x90088U, 0x90089U, 0x9008AU, 0x9008BU, 0x9008CU, 0x9008DU, 0x9008EU,
+	0x9008FU, 0x90090U, 0x90091U, 0x90092U, 0x90093U, 0x90094U, 0x90095U, 0x90096U, 0x90097U,
+	0x90098U, 0x90099U, 0x9009AU, 0x9009BU, 0x9009CU, 0x9009DU, 0x9009EU, 0x9009FU, 0x900A0U,
+	0x900A1U, 0x900A2U, 0x900A3U, 0x900A4U, 0x900A5U, 0x900A6U, 0x900A7U, 0x900A8U, 0x900A9U,
+	0x900AAU, 0x900ABU, 0x900ACU, 0x900ADU, 0x900AEU, 0x900AFU, 0x900B0U, 0x900B1U, 0x900B2U,
+	0x900B3U, 0x900B4U, 0x900B5U, 0x900B6U, 0x900B7U, 0x900B8U, 0x900B9U, 0x900BAU, 0x900BBU,
+	0x900BCU, 0x900BDU, 0x900BEU, 0x900BFU, 0x900C0U, 0x900C1U, 0x900C2U, 0x900C3U, 0x900C4U,
+	0x900C5U, 0x900C6U, 0x900C7U, 0x900C8U, 0x900C9U, 0x900CAU, 0x90006U, 0x90007U, 0x90008U,
+	0x90009U, 0x9000AU, 0x9000BU, 0xD00E7U, 0x90017U, 0x90026U,
+};
+
+static const uint16_t prodcode_data[PRODCODE_SIZE] = {
+	0x0010U, 0x0400U, 0x010EU, 0x0000U, 0x0000U, 0x0008U, 0x000BU, 0x0480U, 0x0109U, 0x0008U,
+	0x0448U, 0x0139U, 0x0008U, 0x0478U, 0x0109U, 0x0002U, 0x0010U, 0x0139U, 0x000BU, 0x07C0U,
+	0x0139U, 0x0044U, 0x0633U, 0x0159U, 0x014FU, 0x0630U, 0x0159U, 0x0047U, 0x0633U, 0x0149U,
+	0x004FU, 0x0633U, 0x0179U, 0x0008U, 0x00E0U, 0x0109U, 0x0000U, 0x07C8U, 0x0109U, 0x0000U,
+	0x0001U, 0x0008U, 0x0030U, 0x065AU, 0x0009U, 0x0000U, 0x045AU, 0x0009U, 0x0000U, 0x0448U,
+	0x0109U, 0x0040U, 0x0633U, 0x0179U, 0x0001U, 0x0618U, 0x0109U, 0x40C0U, 0x0633U, 0x0149U,
+	0x0008U, 0x0004U, 0x0048U, 0x4040U, 0x0633U, 0x0149U, 0x0000U, 0x0004U, 0x0048U, 0x0040U,
+	0x0633U, 0x0149U, 0x0000U, 0x0658U, 0x0109U, 0x0010U, 0x0004U, 0x0018U, 0x0000U, 0x0004U,
+	0x0078U, 0x0549U, 0x0633U, 0x0159U, 0x0D49U, 0x0633U, 0x0159U, 0x094AU, 0x0633U, 0x0159U,
+	0x0441U, 0x0633U, 0x0149U, 0x0042U, 0x0633U, 0x0149U, 0x0001U, 0x0633U, 0x0149U, 0x0000U,
+	0x00E0U, 0x0109U, 0x000AU, 0x0010U, 0x0109U, 0x0009U, 0x03C0U, 0x0149U, 0x0009U, 0x03C0U,
+	0x0159U, 0x0018U, 0x0010U, 0x0109U, 0x0000U, 0x03C0U, 0x0109U, 0x0018U, 0x0004U, 0x0048U,
+	0x0018U, 0x0004U, 0x0058U, 0x000BU, 0x0010U, 0x0109U, 0x0001U, 0x0010U, 0x0109U, 0x0005U,
+	0x07C0U, 0x0109U, 0x0000U, 0x8140U, 0x010CU, 0x0010U, 0x8138U, 0x0104U, 0x0008U, 0x0448U,
+	0x0109U, 0x000FU, 0x07C0U, 0x0109U, 0x0047U, 0x0630U, 0x0109U, 0x0008U, 0x0618U, 0x0109U,
+	0x0008U, 0x00E0U, 0x0109U, 0x0000U, 0x07C8U, 0x0109U, 0x0008U, 0x8140U, 0x010CU, 0x0000U,
+	0x0478U, 0x0109U, 0x0000U, 0x0001U, 0x0008U, 0x0008U, 0x0004U, 0x0000U, 0x0008U, 0x07C8U,
+	0x0109U, 0x0000U, 0x0400U, 0x0106U, 0x0400U, 0x0000U, 0x002CU,
+	};
+
+#else /* STM32MP_LPDDR4_TYPE */
+#define PRODCODE_SIZE		481
+
+static const uint32_t prodcode_addr[PRODCODE_SIZE] = {
+	0x90000U, 0x90001U, 0x90002U, 0x90003U, 0x90004U, 0x90005U, 0x90029U, 0x9002AU, 0x9002BU,
+	0x9002CU, 0x9002DU, 0x9002EU, 0x9002FU, 0x90030U, 0x90031U, 0x90032U, 0x90033U, 0x90034U,
+	0x90035U, 0x90036U, 0x90037U, 0x90038U, 0x90039U, 0x9003AU, 0x9003BU, 0x9003CU, 0x9003DU,
+	0x9003EU, 0x9003FU, 0x90040U, 0x90041U, 0x90042U, 0x90043U, 0x90044U, 0x90045U, 0x90046U,
+	0x90047U, 0x90048U, 0x90049U, 0x9004AU, 0x9004BU, 0x9004CU, 0x9004DU, 0x9004EU, 0x9004FU,
+	0x90050U, 0x90051U, 0x90052U, 0x90053U, 0x90054U, 0x90055U, 0x90056U, 0x90057U, 0x90058U,
+	0x90059U, 0x9005AU, 0x9005BU, 0x9005CU, 0x9005DU, 0x9005EU, 0x9005FU, 0x90060U, 0x90061U,
+	0x90062U, 0x90063U, 0x90064U, 0x90065U, 0x90066U, 0x90067U, 0x90068U, 0x90069U, 0x9006AU,
+	0x9006BU, 0x9006CU, 0x9006DU, 0x9006EU, 0x9006FU, 0x90070U, 0x90071U, 0x90072U, 0x90073U,
+	0x90074U, 0x90075U, 0x90076U, 0x90077U, 0x90078U, 0x90079U, 0x9007AU, 0x9007BU, 0x9007CU,
+	0x9007DU, 0x9007EU, 0x9007FU, 0x90080U, 0x90081U, 0x90082U, 0x90083U, 0x90084U, 0x90085U,
+	0x90086U, 0x90087U, 0x90088U, 0x90089U, 0x9008AU, 0x9008BU, 0x9008CU, 0x9008DU, 0x9008EU,
+	0x9008FU, 0x90090U, 0x90091U, 0x90092U, 0x90093U, 0x90094U, 0x90095U, 0x90096U, 0x90097U,
+	0x90098U, 0x90099U, 0x9009AU, 0x9009BU, 0x9009CU, 0x9009DU, 0x9009EU, 0x9009FU, 0x900A0U,
+	0x900A1U, 0x900A2U, 0x900A3U, 0x900A4U, 0x900A5U, 0x900A6U, 0x900A7U, 0x900A8U, 0x900A9U,
+	0x40000U, 0x40020U, 0x40040U, 0x40060U, 0x40001U, 0x40021U, 0x40041U, 0x40061U, 0x40002U,
+	0x40022U, 0x40042U, 0x40062U, 0x40003U, 0x40023U, 0x40043U, 0x40063U, 0x40004U, 0x40024U,
+	0x40044U, 0x40064U, 0x40005U, 0x40025U, 0x40045U, 0x40065U, 0x40006U, 0x40026U, 0x40046U,
+	0x40066U, 0x40007U, 0x40027U, 0x40047U, 0x40067U, 0x40008U, 0x40028U, 0x40048U, 0x40068U,
+	0x40009U, 0x40029U, 0x40049U, 0x40069U, 0x4000AU, 0x4002AU, 0x4004AU, 0x4006AU, 0x4000BU,
+	0x4002BU, 0x4004BU, 0x4006BU, 0x4000CU, 0x4002CU, 0x4004CU, 0x4006CU, 0x4000DU, 0x4002DU,
+	0x4004DU, 0x4006DU, 0x4000EU, 0x4002EU, 0x4004EU, 0x4006EU, 0x4000FU, 0x4002FU, 0x4004FU,
+	0x4006FU, 0x40010U, 0x40030U, 0x40050U, 0x40070U, 0x40011U, 0x40031U, 0x40051U, 0x40071U,
+	0x40012U, 0x40032U, 0x40052U, 0x40072U, 0x40013U, 0x40033U, 0x40053U, 0x40073U, 0x40014U,
+	0x40034U, 0x40054U, 0x40074U, 0x40015U, 0x40035U, 0x40055U, 0x40075U, 0x40016U, 0x40036U,
+	0x40056U, 0x40076U, 0x40017U, 0x40037U, 0x40057U, 0x40077U, 0x40018U, 0x40038U, 0x40058U,
+	0x40078U, 0x40019U, 0x40039U, 0x40059U, 0x40079U, 0x4001AU, 0x4003AU, 0x4005AU, 0x4007AU,
+	0x900AAU, 0x900ABU, 0x900ACU, 0x900ADU, 0x900AEU, 0x900AFU, 0x900B0U, 0x900B1U, 0x900B2U,
+	0x900B3U, 0x900B4U, 0x900B5U, 0x900B6U, 0x900B7U, 0x900B8U, 0x900B9U, 0x900BAU, 0x900BBU,
+	0x900BCU, 0x900BDU, 0x900BEU, 0x900BFU, 0x900C0U, 0x900C1U, 0x900C2U, 0x900C3U, 0x900C4U,
+	0x900C5U, 0x900C6U, 0x900C7U, 0x900C8U, 0x900C9U, 0x900CAU, 0x900CBU, 0x900CCU, 0x900CDU,
+	0x900CEU, 0x900CFU, 0x900D0U, 0x900D1U, 0x900D2U, 0x900D3U, 0x900D4U, 0x900D5U, 0x900D6U,
+	0x900D7U, 0x900D8U, 0x900D9U, 0x900DAU, 0x900DBU, 0x900DCU, 0x900DDU, 0x900DEU, 0x900DFU,
+	0x900E0U, 0x900E1U, 0x900E2U, 0x900E3U, 0x900E4U, 0x900E5U, 0x900E6U, 0x900E7U, 0x900E8U,
+	0x900E9U, 0x900EAU, 0x900EBU, 0x900ECU, 0x900EDU, 0x900EEU, 0x900EFU, 0x900F0U, 0x900F1U,
+	0x900F2U, 0x900F3U, 0x900F4U, 0x900F5U, 0x900F6U, 0x900F7U, 0x900F8U, 0x900F9U, 0x900FAU,
+	0x900FBU, 0x900FCU, 0x900FDU, 0x900FEU, 0x900FFU, 0x90100U, 0x90101U, 0x90102U, 0x90103U,
+	0x90104U, 0x90105U, 0x90106U, 0x90107U, 0x90108U, 0x90109U, 0x9010AU, 0x9010BU, 0x9010CU,
+	0x9010DU, 0x9010EU, 0x9010FU, 0x90110U, 0x90111U, 0x90112U, 0x90113U, 0x90114U, 0x90115U,
+	0x90116U, 0x90117U, 0x90118U, 0x90119U, 0x9011AU, 0x9011BU, 0x9011CU, 0x9011DU, 0x9011EU,
+	0x9011FU, 0x90120U, 0x90121U, 0x90122U, 0x90123U, 0x90124U, 0x90125U, 0x90126U, 0x90127U,
+	0x90128U, 0x90129U, 0x9012AU, 0x9012BU, 0x9012CU, 0x9012DU, 0x9012EU, 0x9012FU, 0x90130U,
+	0x90131U, 0x90132U, 0x90133U, 0x90134U, 0x90135U, 0x90136U, 0x90137U, 0x90138U, 0x90139U,
+	0x9013AU, 0x9013BU, 0x9013CU, 0x9013DU, 0x9013EU, 0x9013FU, 0x90140U, 0x90141U, 0x90142U,
+	0x90143U, 0x90144U, 0x90145U, 0x90146U, 0x90147U, 0x90148U, 0x90149U, 0x9014AU, 0x9014BU,
+	0x9014CU, 0x9014DU, 0x9014EU, 0x9014FU, 0x90150U, 0x90151U, 0x90152U, 0x90153U, 0x90154U,
+	0x90155U, 0x90156U, 0x90157U, 0x90158U, 0x90159U, 0x9015AU, 0x9015BU, 0x9015CU, 0x9015DU,
+	0x9015EU, 0x9015FU, 0x90160U, 0x90161U, 0x90162U, 0x90163U, 0x90164U, 0x90165U, 0x90166U,
+	0x90167U, 0x90168U, 0x90169U, 0x9016AU, 0x9016BU, 0x9016CU, 0x9016DU, 0x9016EU, 0x9016FU,
+	0x90170U, 0x90171U, 0x90172U, 0x90173U, 0x90174U, 0x90175U, 0x90176U, 0x90177U, 0x90178U,
+	0x90179U, 0x9017AU, 0x9017BU, 0x9017CU, 0x9017DU, 0x9017EU, 0x9017FU, 0x90180U, 0x90181U,
+	0x90182U, 0x90183U, 0x90184U, 0x90006U, 0x90007U, 0x90008U, 0x90009U, 0x9000AU, 0x9000BU,
+	0xD00E7U, 0x90017U, 0x9001FU, 0x90026U, 0x400D0U, 0x400D1U, 0x400D2U, 0x400D3U, 0x400D4U,
+	0x400D5U, 0x400D6U, 0x400D7U, 0x2003AU,
+	};
+
+static const uint16_t prodcode_data[PRODCODE_SIZE] = {
+	0x0010U, 0x0400U, 0x010EU, 0x0000U, 0x0000U, 0x0008U, 0x000BU, 0x0480U, 0x0109U, 0x0008U,
+	0x0448U, 0x0139U, 0x0008U, 0x0478U, 0x0109U, 0x0000U, 0x00E8U, 0x0109U, 0x0002U, 0x0010U,
+	0x0139U, 0x000BU, 0x07C0U, 0x0139U, 0x0044U, 0x0633U, 0x0159U, 0x014FU, 0x0630U, 0x0159U,
+	0x0047U, 0x0633U, 0x0149U, 0x004FU, 0x0633U, 0x0179U, 0x0008U, 0x00E0U, 0x0109U, 0x0000U,
+	0x07C8U, 0x0109U, 0x0000U, 0x0001U, 0x0008U, 0x0030U, 0x065AU, 0x0009U, 0x0000U, 0x045AU,
+	0x0009U, 0x0000U, 0x0448U, 0x0109U, 0x0040U, 0x0633U, 0x0179U, 0x0001U, 0x0618U, 0x0109U,
+	0x40C0U, 0x0633U, 0x0149U, 0x0008U, 0x0004U, 0x0048U, 0x4040U, 0x0633U, 0x0149U, 0x0000U,
+	0x0004U, 0x0048U, 0x0040U, 0x0633U, 0x0149U, 0x0000U, 0x0658U, 0x0109U, 0x0010U, 0x0004U,
+	0x0018U, 0x0000U, 0x0004U, 0x0078U, 0x0549U, 0x0633U, 0x0159U, 0x0D49U, 0x0633U, 0x0159U,
+	0x094AU, 0x0633U, 0x0159U, 0x0441U, 0x0633U, 0x0149U, 0x0042U, 0x0633U, 0x0149U, 0x0001U,
+	0x0633U, 0x0149U, 0x0000U, 0x00E0U, 0x0109U, 0x000AU, 0x0010U, 0x0109U, 0x0009U, 0x03C0U,
+	0x0149U, 0x0009U, 0x03C0U, 0x0159U, 0x0018U, 0x0010U, 0x0109U, 0x0000U, 0x03C0U, 0x0109U,
+	0x0018U, 0x0004U, 0x0048U, 0x0018U, 0x0004U, 0x0058U, 0x000BU, 0x0010U, 0x0109U, 0x0001U,
+	0x0010U, 0x0109U, 0x0005U, 0x07C0U, 0x0109U, 0x0811U, 0x0880U, 0x0000U, 0x0000U, 0x4008U,
+	0x0083U, 0x004FU, 0x0000U, 0x4040U, 0x0083U, 0x0051U, 0x0000U, 0x0811U, 0x0880U, 0x0000U,
+	0x0000U, 0x0720U, 0x000FU, 0x1740U, 0x0000U, 0x0016U, 0x0083U, 0x004BU, 0x0000U, 0x0716U,
+	0x000FU, 0x2001U, 0x0000U, 0x0716U, 0x000FU, 0x2800U, 0x0000U, 0x0716U, 0x000FU, 0x0F00U,
+	0x0000U, 0x0720U, 0x000FU, 0x1400U, 0x0000U, 0x0E08U, 0x0C15U, 0x0000U, 0x0000U, 0x0625U,
+	0x0015U, 0x0000U, 0x0000U, 0x4028U, 0x0080U, 0x0000U, 0x0000U, 0x0E08U, 0x0C1AU, 0x0000U,
+	0x0000U, 0x0625U, 0x001AU, 0x0000U, 0x0000U, 0x4040U, 0x0080U, 0x0000U, 0x0000U, 0x2604U,
+	0x0015U, 0x0000U, 0x0000U, 0x0708U, 0x0005U, 0x0000U, 0x2002U, 0x0008U, 0x0080U, 0x0000U,
+	0x0000U, 0x2604U, 0x001AU, 0x0000U, 0x0000U, 0x0708U, 0x000AU, 0x0000U, 0x2002U, 0x4040U,
+	0x0080U, 0x0000U, 0x0000U, 0x060AU, 0x0015U, 0x1200U, 0x0000U, 0x061AU, 0x0015U, 0x1300U,
+	0x0000U, 0x060AU, 0x001AU, 0x1200U, 0x0000U, 0x0642U, 0x001AU, 0x1300U, 0x0000U, 0x4808U,
+	0x0880U, 0x0000U, 0x0000U, 0x0000U, 0x0790U, 0x011AU, 0x0008U, 0x07AAU, 0x002AU, 0x0010U,
+	0x07B2U, 0x002AU, 0x0000U, 0x07C8U, 0x0109U, 0x0010U, 0x0010U, 0x0109U, 0x0010U, 0x02A8U,
+	0x0129U, 0x0008U, 0x0370U, 0x0129U, 0x000AU, 0x03C8U, 0x01A9U, 0x000CU, 0x0408U, 0x0199U,
+	0x0014U, 0x0790U, 0x011AU, 0x0008U, 0x0004U, 0x0018U, 0x000EU, 0x0408U, 0x0199U, 0x0008U,
+	0x8568U, 0x0108U, 0x0018U, 0x0790U, 0x016AU, 0x0008U, 0x01D8U, 0x0169U, 0x0010U, 0x8558U,
+	0x0168U, 0x1FF8U, 0x85A8U, 0x01E8U, 0x0050U, 0x0798U, 0x016AU, 0x0060U, 0x07A0U, 0x016AU,
+	0x0008U, 0x8310U, 0x0168U, 0x0008U, 0xA310U, 0x0168U, 0x000AU, 0x0408U, 0x0169U, 0x006EU,
+	0x0000U, 0x0068U, 0x0000U, 0x0408U, 0x0169U, 0x0000U, 0x8310U, 0x0168U, 0x0000U, 0xA310U,
+	0x0168U, 0x1FF8U, 0x85A8U, 0x01E8U, 0x0068U, 0x0798U, 0x016AU, 0x0078U, 0x07A0U, 0x016AU,
+	0x0068U, 0x0790U, 0x016AU, 0x0008U, 0x8B10U, 0x0168U, 0x0008U, 0xAB10U, 0x0168U, 0x000AU,
+	0x0408U, 0x0169U, 0x0058U, 0x0000U, 0x0068U, 0x0000U, 0x0408U, 0x0169U, 0x0000U, 0x8B10U,
+	0x0168U, 0x0001U, 0xAB10U, 0x0168U, 0x0000U, 0x01D8U, 0x0169U, 0x0080U, 0x0790U, 0x016AU,
+	0x0018U, 0x07AAU, 0x006AU, 0x000AU, 0x0000U, 0x01E9U, 0x0008U, 0x8080U, 0x0108U, 0x000FU,
+	0x0408U, 0x0169U, 0x000CU, 0x0000U, 0x0068U, 0x0009U, 0x0000U, 0x01A9U, 0x0000U, 0x0408U,
+	0x0169U, 0x0000U, 0x8080U, 0x0108U, 0x0008U, 0x07AAU, 0x006AU, 0x0000U, 0x8568U, 0x0108U,
+	0x00B7U, 0x0790U, 0x016AU, 0x001FU, 0x0000U, 0x0068U, 0x0008U, 0x8558U, 0x0168U, 0x000FU,
+	0x0408U, 0x0169U, 0x000DU, 0x0000U, 0x0068U, 0x0000U, 0x0408U, 0x0169U, 0x0000U, 0x8558U,
+	0x0168U, 0x0008U, 0x03C8U, 0x01A9U, 0x0003U, 0x0370U, 0x0129U, 0x0020U, 0x02AAU, 0x0009U,
+	0x0008U, 0x00E8U, 0x0109U, 0x0000U, 0x8140U, 0x010CU, 0x0010U, 0x8138U, 0x0104U, 0x0008U,
+	0x0448U, 0x0109U, 0x000FU, 0x07C0U, 0x0109U, 0x0000U, 0x00E8U, 0x0109U, 0x0047U, 0x0630U,
+	0x0109U, 0x0008U, 0x0618U, 0x0109U, 0x0008U, 0x00E0U, 0x0109U, 0x0000U, 0x07C8U, 0x0109U,
+	0x0008U, 0x8140U, 0x010CU, 0x0000U, 0x0478U, 0x0109U, 0x0000U, 0x0001U, 0x0008U, 0x0008U,
+	0x0004U, 0x0000U, 0x0008U, 0x07C8U, 0x0109U, 0x0000U, 0x0400U, 0x0106U, 0x0400U, 0x0000U,
+	0x002BU, 0x0069U, 0x0000U, 0x0101U, 0x0105U, 0x0107U, 0x010FU, 0x0202U, 0x020AU, 0x020BU,
+	0x0002U,
+	};
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+/*
+ * Loads PIE instruction sequence PHY registers
+ * @returns void
+ */
+void ddrphy_phyinit_loadpieprodcode(void)
+{
+	int i;
+
+	for (i = 0; i < PRODCODE_SIZE; i++) {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * prodcode_addr[i])),
+			      prodcode_data[i]);
+	}
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c
new file mode 100644
index 00000000..f1eeb820
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * Maps impedance values to register settings
+ *
+ * Reads the pull-up/pull-down driver impedance from drvstren_ohm input
+ * and encodes that value for the CSR field specified in targetcsr input,
+ * based on DDR protocol.
+ *
+ * @param[in] drvstren_ohm drive strenght / ODT impedance in Ohms
+ *
+ * @param[in] targetcsr Target CSR for the impedance value. on of following
+ * enum drvtype:
+ *   - DRVSTRENFSDQP
+ *   - DRVSTRENFSDQN
+ *   - ODTSTRENP
+ *   - ODTSTRENN
+ *   - ADRVSTRENP
+ *   - ADRVSTRENN
+ *
+ * \return >=0 value on success, else negative.
+ */
+int ddrphy_phyinit_mapdrvstren(uint32_t drvstren_ohm, enum drvtype targetcsr)
+{
+	int stren_setting = -1;
+
+	if ((targetcsr == DRVSTRENFSDQP) || (targetcsr == DRVSTRENFSDQN)) {
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 31U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 35U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 41U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 50U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 56U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 64U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 74U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 88U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 108U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 140U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 200U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 360U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 481U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+	} else if (targetcsr == ODTSTRENP) {
+#if STM32MP_DDR3_TYPE
+		/*
+		 * DDR3 - P and N has the same impedance and non-zero.
+		 * user input is half the individual pull-up and pull-down impedances values
+		 * because of parallel between them.
+		 */
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 15U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 16U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 17U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 18U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 20U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 21U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 23U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 26U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 55U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 71U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 101U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 181U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 241U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+#elif STM32MP_DDR4_TYPE
+		/* DDR4 - P is non-zero */
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 31U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 35U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 41U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 50U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 56U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 64U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 74U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 88U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 108U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 140U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 200U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 360U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 481U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+#else /* STM32MP_LPDDR4_TYPE */
+		/* LPDDR4 - P is high-Z */
+		stren_setting = 0x00; /* High-impedance */
+#endif /* STM32MP_DDR3_TYPE */
+	} else if (targetcsr == ODTSTRENN) {
+#if STM32MP_DDR3_TYPE
+		/*
+		 * DDR3 - P and N has the same impedance and non-zero.
+		 * Times 2 of user input because of parallel pull-up and pull-down termination.
+		 */
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 15U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 16U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 17U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 18U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 20U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 21U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 23U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 26U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 55U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 71U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 101U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 181U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 241U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+#elif STM32MP_DDR4_TYPE
+		/* DDR4 - N is high-Z */
+		stren_setting = 0x00; /* High-impedance */
+#else /* STM32MP_LPDDR4_TYPE */
+		/* LPDDR4 - N is non-zero */
+		if (drvstren_ohm == 0U) {
+			stren_setting = 0x00; /* High-impedance */
+		} else if (drvstren_ohm < 29U) {
+			stren_setting = 0x3f;
+		} else if (drvstren_ohm < 31U) {
+			stren_setting = 0x3e;
+		} else if (drvstren_ohm < 33U) {
+			stren_setting = 0x3b;
+		} else if (drvstren_ohm < 35U) {
+			stren_setting = 0x3a;
+		} else if (drvstren_ohm < 38U) {
+			stren_setting = 0x39;
+		} else if (drvstren_ohm < 41U) {
+			stren_setting = 0x38;
+		} else if (drvstren_ohm < 45U) {
+			stren_setting = 0x1b;
+		} else if (drvstren_ohm < 50U) {
+			stren_setting = 0x1a;
+		} else if (drvstren_ohm < 56U) {
+			stren_setting = 0x19;
+		} else if (drvstren_ohm < 64U) {
+			stren_setting = 0x18;
+		} else if (drvstren_ohm < 74U) {
+			stren_setting = 0x0b;
+		} else if (drvstren_ohm < 88U) {
+			stren_setting = 0x0a;
+		} else if (drvstren_ohm < 108U) {
+			stren_setting = 0x09;
+		} else if (drvstren_ohm < 140U) {
+			stren_setting = 0x08;
+		} else if (drvstren_ohm < 200U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm < 360U) {
+			stren_setting = 0x02;
+		} else if (drvstren_ohm < 481U) {
+			stren_setting = 0x01;
+		} else {
+			stren_setting = 0x00; /* High-impedance */
+		}
+#endif /* STM32MP_DDR3_TYPE */
+	} else {
+		/* if ((targetcsr == ADRVSTRENP) || (targetcsr == ADRVSTRENN)) */
+		if (drvstren_ohm == 120U) {
+			stren_setting = 0x00;
+		} else if (drvstren_ohm == 60U) {
+			stren_setting = 0x01;
+		} else if (drvstren_ohm == 40U) {
+			stren_setting = 0x03;
+		} else if (drvstren_ohm == 30U) {
+			stren_setting = 0x07;
+		} else if (drvstren_ohm == 24U) {
+			stren_setting = 0x0F;
+		} else if (drvstren_ohm == 20U) {
+			stren_setting = 0x1F;
+		} else {
+			ERROR("%s %d\n", __func__, __LINE__);
+			VERBOSE("%s userinputadvanced.atximpedance %u Ohms value is not valid.\n",
+				__func__, drvstren_ohm);
+			VERBOSE("Valid values are: 20, 24, 30, 40, 60 and 120 Ohms.\n");
+		}
+	}
+
+	return stren_setting;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_progcsrskiptrain.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_progcsrskiptrain.c
new file mode 100644
index 00000000..c9a71f4d
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_progcsrskiptrain.c
@@ -0,0 +1,893 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+#include <ddrphy_wrapper.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+struct phyinit_timings {
+	int tstaoff;
+	int tpdm;
+	int tcasl_add;
+};
+
+static struct phyinit_timings timings;
+
+/*
+ * Program dfimrl according to this formula:
+ *
+ *         dfimrl = ceiling( (ARdPtrinitval*UI + phy_tx_insertion_dly +
+ *                            phy_rx_insertion_dly + PHY_Rx_Fifo_dly + tDQSCK + tstaoff) /
+ *                           dficlk_period)
+ *
+ * All terms in above equation specified in ps
+ * tDQSCK - determine from memory model
+ * tstaoff - determine from memory model
+ * phy_tx_insertion_dly = 200ps
+ * phy_rx_insertion_dly = 200ps
+ * phy_rx_fifo_dly      = 200ps + 4UI
+ */
+static void dfimrl_program(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d,
+			   int ardptrinitval)
+{
+	uint32_t byte;
+	int dfimrl_in_dficlk;
+	int phy_rx_fifo_dly;
+	int phy_rx_insertion_dly = 200;
+	int phy_tx_insertion_dly = 200;
+	long long dficlk_period_x1000;
+	long long dfimrl_in_fs;
+	long long uifs;
+	uint16_t dfimrl;
+
+	uifs = (1000 * 1000000) / ((int)config->uib.frequency * 2);
+	dficlk_period_x1000 = 4 * uifs;
+
+	phy_rx_fifo_dly = (int)(((200 * 1000) + (4 * uifs)) / 1000);
+
+	dfimrl_in_fs = (ardptrinitval * uifs) +
+		       ((phy_tx_insertion_dly + phy_rx_insertion_dly + phy_rx_fifo_dly +
+			 timings.tstaoff + timings.tcasl_add + timings.tpdm) * 1000);
+
+	dfimrl_in_dficlk = (int)(dfimrl_in_fs / dficlk_period_x1000);
+	if ((dfimrl_in_fs % dficlk_period_x1000) != 0) {
+		dfimrl_in_dficlk++;
+	}
+	dfimrl = (uint16_t)(dfimrl_in_dficlk + mb_ddr_1d->dfimrlmargin);
+
+	/*
+	 * mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | CBRD | CSR_DFIMRL_ADDR))),
+	 *               dfimrl);
+	 */
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+
+		c_addr = byte << 12;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDBYTE | c_addr |
+								CSR_DFIMRL_ADDR))),
+			      dfimrl);
+	}
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTMRL_ADDR))), dfimrl);
+}
+
+/*
+ * Program txdqsdlytg0/1[9:0]:
+ *
+ *         txdqsdlytg*[9:6] = floor( (4*UI + tstaoff) / UI)
+ *         txdqsdlytg*[5:0] = ceiling( (tstaoff%UI / UI) * 32)
+ *
+ * tstaoff and UI expressed in ps
+ *
+ * For HMD and LPDDR4X and MEMCLK <= 533 mhz:
+ *    txdqsdlytg*[9:6] = 0x5
+ *
+ * For other dimm types, leave TDqsDlyTg*[9:0] at default 0x100
+ *
+ * ppp_0001_cccc_uuuu_1101_0000
+ *
+ * if DDR3 or DDR4
+ *      num_timingroup = numrank_dfi0;
+ * else
+ *      num_timingroup = numrank_dfi0 + numrank_dfi1 * dfi1exists;
+ */
+static void txdqsdlytg_program(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d,
+			       uint16_t *txdqsdly)
+{
+	uint32_t byte;
+	int txdqsdlytg_5to0; /* Fine delay - 1/32UI per increment */
+	int txdqsdlytg_9to6; /* Coarse delay - 1UI per increment */
+	int txdqsdlytg_fine_default = 0;
+	int txdqsdlytg_coarse_default = 4;
+	long long tmp_value;
+	long long uifs;
+
+	uifs = (1000 * 1000000) / ((int)config->uib.frequency * 2);
+
+	txdqsdlytg_9to6 = (int)(((int)((txdqsdlytg_coarse_default * uifs) / 1000) +
+				 timings.tstaoff + timings.tcasl_add
+				 - timings.tpdm) / (int)(uifs / 1000));
+
+	tmp_value = fmodll(((txdqsdlytg_fine_default * uifs / 32) +
+			    ((timings.tstaoff + timings.tcasl_add) * 1000) -
+			    (timings.tpdm * 1000)),
+			   uifs);
+	txdqsdlytg_5to0 = (int)(tmp_value / uifs * 32);
+	if ((tmp_value % uifs) != 0) {
+		txdqsdlytg_5to0++;
+	}
+
+	/* Bit-5 of LCDL is no longer used, so bumping bit-5 of fine_dly up to coarse_dly */
+	if (txdqsdlytg_5to0 >= 32) {
+		txdqsdlytg_9to6 = txdqsdlytg_9to6 + 1;
+		txdqsdlytg_5to0 = txdqsdlytg_5to0 - 32;
+	}
+
+	*txdqsdly = (uint16_t)((txdqsdlytg_9to6 << 6) | txdqsdlytg_5to0);
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t nibble;
+
+		c_addr = byte << 12;
+		for (nibble = 0U; nibble < 2U; nibble++) {
+			uint32_t u_addr;
+
+			if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, byte) != 0) {
+				continue;
+			}
+
+			u_addr = nibble << 8;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			if ((mb_ddr_1d->cspresent & 0x1U) != 0U) {
+#else /* STM32MP_LPDDR4_TYPE */
+			if (((mb_ddr_1d->cspresentcha & 0x1U) |
+			     (mb_ddr_1d->cspresentchb & 0x1U)) != 0U) {
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | u_addr |
+								     CSR_TXDQSDLYTG0_ADDR))),
+					      *txdqsdly);
+			}
+
+#if STM32MP_LPDDR4_TYPE
+			if ((((mb_ddr_1d->cspresentcha & 0x2U) >> 1) |
+			     ((mb_ddr_1d->cspresentchb & 0x2U) >> 1)) != 0U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | u_addr |
+								     CSR_TXDQSDLYTG1_ADDR))),
+					      *txdqsdly);
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+	}
+}
+
+/*
+ * ##############################################################
+ *
+ * Program txdqdlyTg0/1[8:0]:
+ *
+ *     txdqdlyTg*[8:6] = floor( (txdqsdlytg*[5:0]*UI/32 + tDQS2DQ + 0.5UI) / UI)
+ *     txdqdlyTg*[5:0] = ceil( ((txdqsdlytg*[5:0]*UI/32 + tDQS2DQ + 0.5UI)%UI / UI) * 32)
+ *
+ * ##############################################################
+ */
+static void txdqdlytg_program(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d,
+			      uint16_t txdqsdly)
+{
+	uint32_t byte;
+	int txdqdly_5to0; /* Fine delay - 1/32UI per increment */
+	int txdqdly_8to6; /* Coarse delay - 1UI per increment */
+	int txdqsdlytg_5to0; /* Fine delay - 1/32UI per increment */
+	long long tmp_value;
+	long long uifs;
+	uint16_t txdqdly;
+
+	uifs = (1000 * 1000000) / ((int)config->uib.frequency * 2);
+
+	txdqsdlytg_5to0 = (int)txdqsdly & 0x3F;
+
+	txdqdly_8to6 = (int)(((txdqsdlytg_5to0 * uifs / 32) + (uifs / 2)) / uifs);
+	tmp_value = fmodll(((txdqsdlytg_5to0 * uifs / 32) + (uifs / 2)), uifs);
+	txdqdly_5to0 = (int)(((tmp_value * 32) / uifs));
+	if ((tmp_value % uifs) != 0) {
+		txdqdly_5to0++;
+	}
+
+	/* Bit-5 of LCDL is no longer used, so bumping bit-5 of fine_dly up to coarse_dly */
+	if (txdqdly_5to0 >= 32) {
+		txdqdly_8to6 = txdqdly_8to6 + 1;
+		txdqdly_5to0 = txdqdly_5to0 - 32;
+	}
+
+	txdqdly = (uint16_t)((txdqdly_8to6 << 6) | txdqdly_5to0);
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t lane;
+
+		c_addr = byte << 12;
+		for (lane = 0U; lane < 9U; lane++) {
+			uint32_t r_addr;
+
+			if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, byte) != 0) {
+				continue;
+			}
+
+			r_addr = lane << 8;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			if ((mb_ddr_1d->cspresent & 0x1U) != 0U) {
+#else /* STM32MP_LPDDR4_TYPE */
+			if (((mb_ddr_1d->cspresentcha & 0x1U) |
+			     (mb_ddr_1d->cspresentchb & 0x1U)) != 0U) {
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | r_addr |
+								     CSR_TXDQDLYTG0_ADDR))),
+					      txdqdly);
+			}
+
+#if STM32MP_LPDDR4_TYPE
+			if ((((mb_ddr_1d->cspresentcha & 0x2U) >> 1) |
+			     ((mb_ddr_1d->cspresentchb & 0x2U) >> 1)) != 0U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | r_addr |
+								     CSR_TXDQDLYTG1_ADDR))),
+					      txdqdly);
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+	}
+}
+
+/*
+ * Program rxendly0/1[10:0]:
+ *
+ *         rxendly[10:6] = floor( (4*UI + tDQSCK + tstaoff) / UI)
+ *         rxendly[5:0]  = ceil( ((tDQSCK + tstaoff) % UI) * 32)
+ *
+ * tDQSCK, tstaoff and UI expressed in ps
+ */
+static void rxendly_program(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
+{
+	int rxendly_coarse_default = 4;
+	int rxendly_fine_default = 0;
+
+	int backoff_x1000 __maybe_unused;
+	int zerobackoff_x1000 __maybe_unused;
+	uint32_t byte;
+	int rxendly_10to6; /* Coarse delay - 1UI per increment */
+	int rxendly_5to0; /* Fine delay - 1/32UI per increment */
+	int totfinestep;
+	long long finestepfs; /* Fine steps in fs */
+	long long rxendly_offset_x1000000 = 0; /* 0 Offset is 1UI before the first DQS. */
+	long long totfs;
+	long long uifs;
+	uint16_t rxendly;
+
+	uifs = (1000 * 1000000) / ((int)config->uib.frequency * 2);
+
+#if STM32MP_LPDDR4_TYPE
+	/* Compensate for pptenrxenbackoff */
+	zerobackoff_x1000 = (1000 * 24) / 32;
+	if (config->uia.lp4rxpreamblemode == 1U) {
+		backoff_x1000 = 1000 - ((1000 * 2) / 32);
+	} else {
+		backoff_x1000 = (1000 * (int)config->uia.rxenbackoff) - ((1000 * 2) / 32);
+	}
+
+	if (config->uia.disableretraining == 0U) {
+		rxendly_offset_x1000000 = config->uib.frequency < 333U ?
+					  backoff_x1000 * uifs : zerobackoff_x1000 * uifs;
+	} else {
+		rxendly_offset_x1000000 = zerobackoff_x1000 * uifs;
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	finestepfs = uifs / 32;
+	totfs = ((32 * rxendly_coarse_default * finestepfs) +
+		 (rxendly_fine_default * finestepfs) +
+		 ((timings.tstaoff + timings.tcasl_add +
+		   timings.tpdm) * 1000) + (rxendly_offset_x1000000 / 1000));
+	totfinestep = totfs / finestepfs;
+
+	rxendly_10to6 = totfinestep / 32;
+	rxendly_5to0  = fmodi(totfinestep, 32);
+
+	/* Bit-5 of LCDL is no longer used, so bumping bit-5 of fine_dly up to coarse_dly */
+	if (rxendly_5to0 >= 32) {
+		rxendly_10to6 = rxendly_10to6 + 1;
+		rxendly_5to0 = rxendly_5to0 - 32;
+	}
+
+	rxendly = (uint16_t)((rxendly_10to6 << 6) | rxendly_5to0);
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint32_t nibble;
+
+		c_addr = byte << 12;
+		for (nibble = 0U; nibble < 2U; nibble++) {
+			uint32_t u_addr;
+
+			if (ddrphy_phyinit_isdbytedisabled(config, mb_ddr_1d, byte) != 0) {
+				continue;
+			}
+
+			u_addr = nibble << 8;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+			if ((mb_ddr_1d->cspresent & 0x1U) != 0) {
+#else /* STM32MP_LPDDR4_TYPE */
+			if (((mb_ddr_1d->cspresentcha & 0x1U) |
+			     (mb_ddr_1d->cspresentchb & 0x1U)) != 0U) {
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | u_addr |
+								     CSR_RXENDLYTG0_ADDR))),
+					      rxendly);
+			}
+
+#if STM32MP_LPDDR4_TYPE
+			if ((((mb_ddr_1d->cspresentcha & 0x2U) >> 1) |
+			     ((mb_ddr_1d->cspresentchb & 0x2U) >> 1)) != 0U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr | u_addr |
+								     CSR_RXENDLYTG1_ADDR))),
+					      rxendly);
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+	}
+}
+
+#if STM32MP_LPDDR4_TYPE
+/*
+ * Programming Seq0BGPR1/2/3 for LPDDR4
+ */
+static void seq0bgpr_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t extradly = 3U;
+	uint32_t rl = 0U; /* Computed read latency */
+	uint32_t wl = 0U; /* Computed write latency */
+	uint16_t mr_dbi_rd; /* Extracted field from MR */
+	uint16_t mr_rl;
+	uint16_t mr_wl;
+	uint16_t mr_wls;
+	uint16_t regdata;
+
+	mr_rl = (uint16_t)config->uia.lp4rl;	/* RL[2:0] */
+	mr_wl = (uint16_t)config->uia.lp4wl;	/* WL[5:3] */
+	mr_wls = (uint16_t)config->uia.lp4wls;	/* WLS */
+	mr_dbi_rd = (uint16_t)config->uia.lp4dbird; /* DBI-RD */
+
+	switch ((mr_dbi_rd << 3) | mr_rl) {
+		/* DBI-RD Disabled */
+	case  0U:
+		rl = 6U;
+		break;
+	case  1U:
+		rl = 10U;
+		break;
+	case  2U:
+		rl = 14U;
+		break;
+	case  3U:
+		rl = 20U;
+		break;
+	case  4U:
+		rl = 24U;
+		break;
+	case  5U:
+		rl = 28U;
+		break;
+	case  6U:
+		rl = 32U;
+		break;
+	case  7U:
+		rl = 36U;
+		break;
+		/* DBI-RD Enabled */
+	case  8U:
+		rl = 6U;
+		break;
+	case  9U:
+		rl = 12U;
+		break;
+	case 10U:
+		rl = 16U;
+		break;
+	case 11U:
+		rl = 22U;
+		break;
+	case 12U:
+		rl = 28U;
+		break;
+	case 13U:
+		rl = 32U;
+		break;
+	case 14U:
+		rl = 36U;
+		break;
+	case 15U:
+		rl = 40U;
+		break;
+	default:
+		rl = 6U;
+		break;
+	}
+
+	switch ((mr_wls << 3) | mr_wl) {
+		/* DBI-RD Disabled */
+	case  0U:
+		wl = 4U;
+		break;
+	case  1U:
+		wl = 6U;
+		break;
+	case  2U:
+		wl = 8U;
+		break;
+	case  3U:
+		wl = 10U;
+		break;
+	case  4U:
+		wl = 12U;
+		break;
+	case  5U:
+		wl = 14U;
+		break;
+	case  6U:
+		wl = 16U;
+		break;
+	case  7U:
+		wl = 18U;
+		break;
+		/* DBI-RD Enabled */
+	case  8U:
+		wl = 4U;
+		break;
+	case  9U:
+		wl = 8U;
+		break;
+	case 10U:
+		wl = 12U;
+		break;
+	case 11U:
+		wl = 18U;
+		break;
+	case 12U:
+		wl = 22U;
+		break;
+	case 13U:
+		wl = 26U;
+		break;
+	case 14U:
+		wl = 30U;
+		break;
+	case 15U:
+		wl = 34U;
+		break;
+	default:
+		wl = 4U;
+		break;
+	}
+
+	/* Program Seq0b_GPRx */
+	regdata = (uint16_t)((rl - 5U + extradly) << CSR_ACSMRCASLAT_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (P0 | C0 | TINITENG | R2 |
+							CSR_SEQ0BGPR1_ADDR))),
+		      regdata);
+
+	regdata = (uint16_t)((wl - 5U + extradly) << CSR_ACSMWCASLAT_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (P0 | C0 | TINITENG | R2 |
+							CSR_SEQ0BGPR2_ADDR))),
+		      regdata);
+
+	regdata = (uint16_t)((rl - 5U + extradly + 4U + 8U) << CSR_ACSMRCASLAT_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (P0 | C0 | TINITENG | R2 |
+							CSR_SEQ0BGPR3_ADDR))),
+		      regdata);
+}
+
+/*
+ * Program hwtlpcsena and hwtlpcsenb based on number of ranks per channel
+ * Applicable only for LPDDR4.  These CSRs have no effect for DDR3/4.
+ *
+ * CSRs to program:
+ *      hwtlpcsena
+ *      hwtlpcsenb
+ *
+ * User input dependencies:
+ *      config->uib.numrank_dfi0
+ *      config->uib.numrank_dfi1
+ *      config->uib.dfi1exists
+ *      config->uib.numactivedbytedfi1
+ */
+static void hwtlpcsen_program(struct stm32mp_ddr_config *config)
+{
+	uint16_t hwtlpcsena;
+	uint16_t hwtlpcsenb;
+
+	/* Channel A - 1'b01 if signal-rank, 2'b11 if dual-rank */
+	hwtlpcsena = (uint16_t)config->uib.numrank_dfi0 | 0x1U;
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTLPCSENA_ADDR))),
+		      hwtlpcsena);
+
+	/*
+	 * Channel B - 1'b01 if signal-rank, 2'b11 if dual-rank
+	 * If DFI1 exists but disabled, numrank_dfi0 is used to program CsEnB
+	 */
+	if ((config->uib.dfi1exists != 0U) && (config->uib.numactivedbytedfi1 == 0U)) {
+		hwtlpcsenb = (uint16_t)config->uib.numrank_dfi0 | 0x1U;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTLPCSENB_ADDR))),
+			      hwtlpcsenb);
+	} else if ((config->uib.dfi1exists != 0U) && (config->uib.numactivedbytedfi1 > 0U)) {
+		hwtlpcsenb = (uint16_t)config->uib.numrank_dfi1 | 0x1U;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTLPCSENB_ADDR))),
+			      hwtlpcsenb);
+	} else {
+		/* Disable Channel B */
+		hwtlpcsenb = 0x0U;
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTLPCSENB_ADDR))),
+			      hwtlpcsenb);
+	}
+}
+
+/*
+ * Program pptdqscntinvtrntg0 and pptdqscntinvtrntg1
+ * Calculated based on tDQS2DQ and Frequencey
+ * Applicable to LPDDR4 only
+ *
+ * 65536*(tdqs2dq_value_rank<rank>_chan<chan>*2)/(2*2048*UI(ps)_int)
+ *
+ * CSRs to program:
+ *      pptdqscntinvtrntg0
+ *      pptdqscntinvtrntg1
+ *
+ * User input dependencies:
+ *      config->uib.numrank_dfi0
+ *      config->uib.numrank_dfi1
+ *      config->uib.dfi1exists
+ *      config->uib.numdbyte
+ */
+static void pptdqscntinvtrntg_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t numrank_total = config->uib.numrank_dfi0;
+	uint32_t rank;
+
+	/* Calculate total number of timing groups (ranks) */
+	if (config->uib.dfi1exists != 0U) {
+		numrank_total += config->uib.numrank_dfi1;
+	}
+
+	/* Set per timing group */
+	for (rank = 0U; rank < numrank_total; rank++) {
+		uint32_t byte;
+
+		for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+			uint32_t c_addr;
+
+			c_addr = byte << 12;
+			if (rank == 0U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr |
+							       CSR_PPTDQSCNTINVTRNTG0_ADDR))),
+					      0U);
+			} else if (rank == 1U) {
+				mmio_write_16((uintptr_t)
+					      (DDRPHYC_BASE + (4U * (TDBYTE | c_addr |
+							       CSR_PPTDQSCNTINVTRNTG1_ADDR))),
+					      0U);
+			}
+		}
+	}
+}
+
+/*
+ * CSRs to program:
+ *      PptCtlStatic:: DOCByteSelTg0/1
+ *                   :: pptenrxenbackoff
+ *
+ * User input dependencies::
+ *      config->uib.numdbyte
+ *      config->uib.numrank_dfi0
+ *      config->uib.numrank_dfi1
+ *      config->uia.lp4rxpreamblemode
+ *      config->uia.rxenbackoff
+ *      config->uia.drambyteswap
+ */
+static void pptctlstatic_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte;
+	uint32_t pptenrxenbackoff;
+
+	/*
+	 * The customer will setup some fields in this csr so the fw needs to do a
+	 * read-modify-write here.
+	 */
+
+	if (config->uia.lp4rxpreamblemode == 1U) {
+		/* Rx-preamble mode for PS0 */
+		/* Programming PptCtlStatic detected toggling preamble */
+		pptenrxenbackoff = 0x1U; /* Toggling RD_PRE */
+	} else {
+		pptenrxenbackoff = config->uia.rxenbackoff; /* Static RD_PRE */
+	}
+
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		uint32_t c_addr;
+		uint16_t regdata;
+		uint8_t pptentg1;
+		uint32_t docbytetg0;
+		uint32_t docbytetg1;
+
+		/* Each Dbyte could have a different configuration */
+		c_addr = byte * C1;
+		if ((byte % 2) == 0) {
+			docbytetg0 = 0x1U & (config->uia.drambyteswap >> byte);
+			docbytetg1 = 0x1U & (config->uia.drambyteswap >> byte);
+		} else {
+			docbytetg0 = 0x1U & (~(config->uia.drambyteswap >> byte));
+			docbytetg1 = 0x1U & (~(config->uia.drambyteswap >> byte));
+		}
+
+		pptentg1 = ((config->uib.numrank_dfi0 == 2U) || (config->uib.numrank_dfi1 == 2U)) ?
+			   0x1U : 0x0U;
+		regdata = (uint16_t)((0x1U << CSR_PPTENDQS2DQTG0_LSB) |
+				     (pptentg1 << CSR_PPTENDQS2DQTG1_LSB) |
+				     (0x1U << CSR_PPTENRXENDLYTG0_LSB) |
+				     (pptentg1 << CSR_PPTENRXENDLYTG1_LSB) |
+				     (pptenrxenbackoff << CSR_PPTENRXENBACKOFF_LSB) |
+				     (docbytetg0 << CSR_DOCBYTESELTG0_LSB) |
+				     (docbytetg1 << CSR_DOCBYTESELTG1_LSB));
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (c_addr | TDBYTE |
+								CSR_PPTCTLSTATIC_ADDR))),
+			      regdata);
+	}
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+/*
+ * Program hwtcamode based on dram type
+ *
+ * CSRs to program:
+ *      hwtcamode::hwtlp3camode
+ *               ::hwtd4camode
+ *               ::hwtlp4camode
+ *               ::hwtd4altcamode
+ *               ::hwtcsinvert
+ *               ::hwtdbiinvert
+ */
+static void hwtcamode_program(void)
+{
+	uint32_t hwtlp3camode = 0U;
+	uint32_t hwtd4camode = 0U;
+	uint32_t hwtlp4camode = 0U;
+	uint32_t hwtd4altcamode = 0U;
+	uint32_t hwtcsinvert = 0U;
+	uint32_t hwtdbiinvert = 0U;
+	uint16_t hwtcamode;
+
+#if STM32MP_DDR4_TYPE
+	hwtd4camode = 1U;
+#elif STM32MP_LPDDR4_TYPE
+	hwtlp4camode = 1U;
+	hwtcsinvert = 1U;
+	hwtdbiinvert = 1U;
+#else /* STM32MP_DDR3_TYPE */
+	/* Nothing to declare */
+#endif /* STM32MP_DDR4_TYPE */
+
+	hwtcamode = (uint16_t)((hwtdbiinvert << CSR_HWTDBIINVERT_LSB) |
+			       (hwtcsinvert << CSR_HWTCSINVERT_LSB) |
+			       (hwtd4altcamode << CSR_HWTD4ALTCAMODE_LSB) |
+			       (hwtlp4camode << CSR_HWTLP4CAMODE_LSB) |
+			       (hwtd4camode << CSR_HWTD4CAMODE_LSB) |
+			       (hwtlp3camode << CSR_HWTLP3CAMODE_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTCAMODE_ADDR))), hwtcamode);
+}
+
+/*
+ * Program DllGainCtl and DllLockParam based on frequency
+ */
+static void dllgainctl_dlllockparam_program(struct stm32mp_ddr_config *config)
+{
+	uint32_t dllgainiv;
+	uint32_t dllgaintv;
+	uint32_t lcdlseed;
+	uint32_t memck_freq;
+	uint32_t stepsize_x10 = 47U;	/*
+					 * Nominal stepsize, in units of tenths of a ps,
+					 * if nominal=4.7ps use 47
+					 */
+	uint16_t wddllgainctl;
+	uint16_t wddlllockparam;
+
+	memck_freq = config->uib.frequency;
+
+	/*
+	 * lcdlseed = ((1000000/memck_freq)/2)/lcdl_stepsize  ...
+	 * where default lcdl_stepsize=4.7 in simulation.
+	 */
+	if (memck_freq >= 1200U) {
+		dllgainiv = 0x04U;
+		dllgaintv = 0x05U;
+	} else if (memck_freq >= 800U) {
+		dllgainiv = 0x03U;
+		dllgaintv = 0x05U;
+	} else if (memck_freq >= 532U) {
+		dllgainiv = 0x02U;
+		dllgaintv = 0x04U;
+	} else if (memck_freq >= 332U) {
+		dllgainiv = 0x01U;
+		dllgaintv = 0x03U;
+	} else {
+		dllgainiv = 0x00U;
+		dllgaintv = 0x02U;
+	}
+
+	/*
+	 * lcdlseed= (1000000/(2*memck_freq)) * (100/(120*(stepsize_nominal)));
+	 * *100/105 is to bias the seed low.
+	 */
+	lcdlseed = (1000000U * 10U * 100U) / (2U * memck_freq * stepsize_x10 * 105U);
+
+	if (lcdlseed > (511U - 32U)) {
+		lcdlseed = 511U - 32U;
+	}
+
+	if (lcdlseed < 32U) {
+		lcdlseed = 32U;
+	}
+
+	wddllgainctl = (uint16_t)((CSR_DLLGAINTV_MASK & (dllgaintv << CSR_DLLGAINTV_LSB)) |
+				  (CSR_DLLGAINIV_MASK & (dllgainiv << CSR_DLLGAINIV_LSB)));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DLLGAINCTL_ADDR))),
+		      wddllgainctl);
+
+	wddlllockparam = (uint16_t)((CSR_LCDLSEED0_MASK & (lcdlseed << CSR_LCDLSEED0_LSB)) |
+				    (CSR_DISDLLGAINIVSEED_MASK & 0xFFFFU));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_DLLLOCKPARAM_ADDR))),
+		      wddlllockparam);
+}
+
+/*
+ * Program AcsmCtrl23 for Fw and Ppt.
+ *
+ * CSRs to program:
+ *   AcsmCtrl23::AcsmCsMask
+ *               AcsmCsMode
+ */
+static void acsmctrl23_program(void)
+{
+	uint16_t regdata;
+
+	regdata = (0x0FU << CSR_ACSMCSMASK_LSB) | (0x1U << CSR_ACSMCSMODE_LSB);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (C0 | TACSM | CSR_ACSMCTRL23_ADDR))),
+		      regdata);
+}
+
+/*
+ * Set PllForceCal to 1 and PllDacValIn to some arbitrary value
+ */
+static void pllforcecal_plldacvalin_program(void)
+{
+	uint32_t dacval_in = 0x10U;
+	uint32_t force_cal = 0x1U;
+	uint32_t pllencal = 0x1U;
+	uint32_t maxrange = 0x1FU;
+	uint16_t pllctrl3_gpr;
+	uint16_t pllctrl3_startup;
+
+	pllctrl3_startup = (uint16_t)((dacval_in << CSR_PLLDACVALIN_LSB) |
+				      (maxrange << CSR_PLLMAXRANGE_LSB));
+	pllctrl3_gpr = pllctrl3_startup | (uint16_t)((force_cal << CSR_PLLFORCECAL_LSB) |
+						     (pllencal << CSR_PLLENCAL_LSB));
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_PLLCTRL3_ADDR))),
+		      pllctrl3_startup);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_SEQ0BGPR6_ADDR))),
+		      pllctrl3_gpr);
+}
+
+/*
+ * This function programs registers that are normally set by training
+ * firmware.
+ *
+ * This function is used in place of running 1D or 1D training steps. PhyInit
+ * calls this function when skip_train = true. In that case, PhyInit does not
+ * execute training firmware and this function is called instead to program
+ * PHY registers according to DRAM timing parameters specified in userInput
+ * data structure. See documentation of ddrphy_phyinit_struct.h file
+ * details of timing parameters available in skip training.
+ *
+ * \warning ddrphy_phyinit_progcsrskiptrain() only supports zero board
+ * delay model. If system board delays are set or randomized, full 1D or 1D
+ * initialization flow must be executed.
+ *
+ * This function replaces these steps in the PHY Initialization sequence:
+ *  - (E) Set the PHY input clocks to the desired frequency
+ *  - (F) Write the Message Block parameters for the training firmware
+ *  - (G) Execute the Training Firmware
+ *  - (H) Read the Message Block results
+ *
+ * \returns \c void
+ */
+void ddrphy_phyinit_progcsrskiptrain(struct stm32mp_ddr_config *config,
+				     struct pmu_smb_ddr_1d *mb_ddr_1d, uint32_t ardptrinitval)
+{
+	uint16_t txdqsdly;
+
+	/*
+	 * Program ATxDlY
+	 * For DDR4, DDR3 and LPDDR4, leave AtxDly[6:0] at default (0x0)
+	 */
+
+	dfimrl_program(config, mb_ddr_1d, ardptrinitval);
+
+	txdqsdlytg_program(config, mb_ddr_1d, &txdqsdly);
+
+	txdqdlytg_program(config, mb_ddr_1d, txdqsdly);
+
+	rxendly_program(config, mb_ddr_1d);
+
+#if STM32MP_LPDDR4_TYPE
+	seq0bgpr_program(config);
+
+	hwtlpcsen_program(config);
+
+	pptdqscntinvtrntg_program(config);
+
+	pptctlstatic_program(config);
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	hwtcamode_program();
+
+	dllgainctl_dlllockparam_program(config);
+
+	acsmctrl23_program();
+
+	pllforcecal_plldacvalin_program();
+
+	/*
+	 * ##############################################################
+	 *
+	 * Setting PhyInLP3 to 0 to cause PIE to execute LP2 sequence instead of INIT on first
+	 * dfi_init_start.
+	 * This prevents any DRAM commands before DRAM is initialized, which is the case for
+	 * skip_train.
+	 *
+	 * Moved to here from dddrphy_phyinit_I_loadPIEImage()
+	 * These should not be needed on S3-exit
+	 *
+	 * Note this executes for SkipTrain only, *not* DevInit+SkipTrain
+	 * DevInit+SkipTrain already initializes DRAM and thus don't need to avoid DRAM commands
+	 *
+	 * ##############################################################
+	 */
+
+	/*
+	 * Special skipTraining configuration to Prevent DRAM Commands on the first dfi
+	 * status interface handshake. In order to see this behavior, the first dfi_freq
+	 * should be in the range of 0x0f < dfi_freq_sel[4:0] < 0x14.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TINITENG | CSR_PHYINLP3_ADDR))), 0x0U);
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_reginterface.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_reginterface.c
new file mode 100644
index 00000000..21400f72
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_reginterface.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * This file provides a group of functions that are used to track PHY register
+ * writes by intercepting io_write16 function calls.  Once the registers are
+ * tracked, their value can be saved at a given time spot, and restored later
+ * as required. This implementation is useful to capture any PHY register
+ * programing in any function during PHY initialization.
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * MAX_NUM_RET_REGS default Max number of retention registers.
+ *
+ * This define is only used by the PhyInit Register interface to define the max
+ * amount of registered that can be saved. The user may increase this variable
+ * as desired if a larger number of registers need to be restored.
+ */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+#define MAX_NUM_RET_REGS	129
+#else /* STM32MP_LPDDR4_TYPE */
+#define MAX_NUM_RET_REGS	283
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+
+/*
+ * Array of Address/value pairs used to store register values for the purpose
+ * of retention restore.
+ */
+#define RETREG_AREA	(MAX_NUM_RET_REGS + 1) * sizeof(struct reg_addr_val)
+#define RETREG_BASE	RETRAM_BASE + RETRAM_SIZE - RETREG_AREA
+
+static int *retregsize = (int *)(RETREG_BASE);
+static struct reg_addr_val *retreglist = (struct reg_addr_val *)(RETREG_BASE + sizeof(int));
+
+static int numregsaved; /* Current Number of registers saved. */
+static int tracken = 1; /* Enabled tracking of registers */
+
+/*
+ * Tags a register if tracking is enabled in the register
+ * interface.
+ *
+ * During PhyInit registers writes, keeps track of address
+ * for the purpose of restoring the PHY register state during PHY
+ * retention exit process. Tracking can be turned on/off via the
+ * ddrphy_phyinit_reginterface STARTTRACK, STOPTRACK instructions. By
+ * default tracking is always turned on.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_trackreg(uint32_t adr)
+{
+	int regindx = 0;
+
+	/* Return if tracking is disabled */
+	if (tracken == 0) {
+		return 0;
+	}
+
+	/* Search register address within the array */
+	for (regindx = 0; regindx < numregsaved; regindx++) {
+		if (retreglist[regindx].address == adr) {
+			/* Register found */
+			return 0;
+		}
+	}
+
+	/* Register not found, so add it */
+	if (numregsaved > MAX_NUM_RET_REGS) {
+		ERROR("numregsaved > MAX_NUM_RET_REGS\n");
+		VERBOSE("[ddrphy_phyinit_reginterface:%s]\n", __func__);
+		VERBOSE("Max Number of Restore Registers reached: %d.\n", numregsaved);
+		VERBOSE("Please recompile PhyInit with larger MAX_NUM_RET_REG value.\n");
+		return -1;
+	}
+
+	retreglist[regindx].address = adr;
+	numregsaved++;
+
+	return 0;
+}
+
+/*
+ * Register interface function used to track, save and restore retention registers.
+ *
+ * ### Usage
+ * Register tracking is enabled by calling:
+ *
+ *  \code
+ *  ddrphy_phyinit_reginterface(STARTTRACK,0,0);
+ *  \endcode
+ *
+ * from this point on any call to mmio_write_16() in
+ * return will be capture by the register interface via a call to
+ * ddrphy_phyinit_trackreg(). Tracking is disabled by calling:
+ *
+ *  \code
+ *  ddrphy_phyinit_reginterface(STOPTRACK,0,0);
+ *  \endcode
+ *
+ * On calling this function, register write via mmio_write_16 are no longer tracked until a
+ * STARTTRACK call is made. Once all the register write are complete, SAVEREGS
+ * command can be issue to save register values into the internal data array of
+ * the register interface. Upon retention exit RESTOREREGS are command can be
+ * used to issue register write commands to the PHY based on values stored in
+ * the array.
+ *  \code
+ *   ddrphy_phyinit_reginterface(SAVEREGS,0,0);
+ *   ddrphy_phyinit_reginterface(RESTOREREGS,0,0);
+ *  \endcode
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_reginterface(enum reginstr myreginstr, uint32_t adr, uint16_t dat)
+{
+	if (myreginstr == SAVEREGS) {
+		int regindx;
+
+		/*
+		 * Go through all the tracked registers, issue a register read and place
+		 * the result in the data structure for future recovery.
+		 */
+		for (regindx = 0; regindx < numregsaved; regindx++) {
+			uint16_t data;
+
+			data = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+							(4U * retreglist[regindx].address)));
+			retreglist[regindx].value = data;
+		}
+
+		*retregsize = numregsaved;
+
+		return 0;
+	} else if (myreginstr == RESTOREREGS) {
+		int regindx;
+
+		/*
+		 * Write PHY registers based on Address, Data value pairs stores in
+		 * retreglist.
+		 */
+		for (regindx = 0; regindx < *retregsize; regindx++) {
+			mmio_write_16((uintptr_t)
+				      (DDRPHYC_BASE + (4U * retreglist[regindx].address)),
+				      retreglist[regindx].value);
+		}
+
+		return 0;
+	} else if (myreginstr == STARTTRACK) {
+		/* Enable tracking */
+		tracken = 1;
+		return 0;
+	} else if (myreginstr == STOPTRACK) {
+		/* Disable tracking */
+		tracken = 0;
+		return 0;
+	} else {
+		return -1;
+	}
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_restore_sequence.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_restore_sequence.c
new file mode 100644
index 00000000..cddb9552
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_restore_sequence.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * This function implements the register restore portion of S3/IO
+ * retention sequence.
+ *
+ * \note This function requiers the runtime_config.reten=1 to enable PhyInit exit retention feature.
+ * This variable can be set as in
+ * \return 0 on completion of the sequence, EXIT_FAILURE on error.
+ */
+int ddrphy_phyinit_restore_sequence(void)
+{
+	int ret;
+
+	/*
+	 * Before you call this functions perform the following:
+	 * --------------------------------------------------------------------------
+	 * -# Bring up VDD, VDDQ should already be up
+	 * -# Since the CKE* and MEMRESET pin state must be protected, special care
+	 *    must be taken to ensure that the following signals
+	 *    - atpg_mode = 1'b0
+	 *    - PwrOkIn = 1'b0
+	 *
+	 * -# The {BypassModeEn*, WRSTN} signals may be defined at VDD power-on, but
+	 *    must be driven to ZERO at least 10ns prior to the asserting edge of PwrOkIn.
+	 *
+	 * -# Start Clocks and Reset the PHY
+	 *    This step is identical to ddrphy_phyinit_usercustom_b_startclockresetphy()
+	 */
+
+	/* Write the MicroContMuxSel CSR to 0x0 to allow access to the internal CSRs */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+
+	/*
+	 * Write the UcclkHclkEnables CSR to 0x3 to enable all the clocks so the reads can
+	 * complete.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x3U);
+
+	/*
+	 * Assert CalZap to force impedance calibration FSM to idle.
+	 * De-asserted as part of dfi_init_start/complete handshake by the PIE when DfiClk is valid.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_CALZAP_ADDR))), 0x1U);
+
+	/* Issue register writes to restore registers values */
+	ret = ddrphy_phyinit_reginterface(RESTOREREGS, 0U, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/*
+	 * Write the UcclkHclkEnables CSR to disable the appropriate clocks after all reads done.
+	 * Disabling Ucclk (PMU) and Hclk (training hardware).
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x0U);
+
+	/* Write the MicroContMuxSel CSR to 0x1 to isolate the internal CSRs during mission mode */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_sequence.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_sequence.c
new file mode 100644
index 00000000..adc43773
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_sequence.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * This function implements the flow of PhyInit software to initialize the PHY.
+ *
+ * The execution sequence follows the overview figure provided in the Reference Manual.
+ *
+ * \returns 0 on completion of the sequence, EXIT_FAILURE on error.
+ */
+int ddrphy_phyinit_sequence(struct stm32mp_ddr_config *config, bool skip_training, bool reten)
+{
+	int ret;
+	uint32_t ardptrinitval;	/*
+				 * Represents the value stored in Step C into the register with the
+				 * same name. Defined as a global variable so that implementation
+				 * of ddrphy_phyinit_progcsrskiptrain() function does not require
+				 * a PHY read register implementation.
+				 */
+	struct pmu_smb_ddr_1d mb_ddr_1d; /* Firmware 1D Message Block structure */
+
+	/* Check user input pstate number consistency vs. SW capabilities */
+	if (config->uib.numpstates > 1U) {
+		return -1;
+	}
+
+	/* Initialize structures */
+	ddrphy_phyinit_initstruct(config, &mb_ddr_1d);
+
+	/* Re-calculate Firmware Message Block input based on final user input */
+	ret = ddrphy_phyinit_calcmb(config, &mb_ddr_1d);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* (A) Bring up VDD, VDDQ, and VAA */
+	/* ddrphy_phyinit_usercustom_a_bringuppower(); */
+
+	/* (B) Start Clocks and Reset the PHY */
+	/* ddrphy_phyinit_usercustom_b_startclockresetphy(); */
+
+	/* (C) Initialize PHY Configuration */
+	ret = ddrphy_phyinit_c_initphyconfig(config, &mb_ddr_1d, &ardptrinitval);
+	if (ret != 0) {
+		return ret;
+	}
+	/*
+	 * Customize any register write desired; This can include any CSR not covered by PhyInit
+	 * or user wish to override values calculated in step_C.
+	 */
+	ddrphy_phyinit_usercustom_custompretrain(config);
+
+	/* Stop retention register tracking for training firmware related registers */
+	ret = ddrphy_phyinit_reginterface(STOPTRACK, 0U, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (skip_training) {
+		/* Skip running training firmware entirely */
+		ddrphy_phyinit_progcsrskiptrain(config, &mb_ddr_1d, ardptrinitval);
+	} else {
+		/* (D) Load the IMEM Memory for 1D training */
+		ddrphy_phyinit_d_loadimem();
+
+		/* (E) Set the PHY input clocks to the desired frequency */
+		/* ddrphy_phyinit_usercustom_e_setdficlk(pstate); */
+
+		/* (F) Write the Message Block parameters for the training firmware */
+		ret = ddrphy_phyinit_f_loaddmem(config, &mb_ddr_1d);
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* (G) Execute the Training Firmware */
+		ret = ddrphy_phyinit_g_execfw();
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* (H) Read the Message Block results */
+		/* ddrphy_phyinit_h_readmsgblock(); */
+	}
+
+	/* Start retention register tracking for training firmware related registers */
+	ret = ddrphy_phyinit_reginterface(STARTTRACK, 0U, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* (I) Load PHY Init Engine Image */
+	ddrphy_phyinit_i_loadpieimage(config, skip_training);
+
+	/*
+	 * Customize any CSR write desired to override values programmed by firmware or
+	 * ddrphy_phyinit_i_loadpieimage()
+	 */
+	/* ddrphy_phyinit_usercustom_customposttrain(); */
+
+	if (reten) {
+		/* Save value of tracked registers for retention restore sequence. */
+		ret = ddrphy_phyinit_usercustom_saveretregs(config);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	/* (J) Initialize the PHY to Mission Mode through DFI Initialization */
+	/* ddrphy_phyinit_usercustom_j_entermissionmode(); */
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_softsetmb.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_softsetmb.c
new file mode 100644
index 00000000..86b084d6
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_softsetmb.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+/*
+ * Set messageBlock variable only if not set by user
+ *
+ * This function is used by ddrphy_phyinit_calcmb() to set calculated
+ * messageBlock variables only when the user has not directly programmed them.
+ *
+ * @param[in]   field   A string representing the messageBlock field to be programed.
+ * @param[in]   value   filed value
+ *
+ * @return 0 on success.
+ * On error  returns the following values based on error:
+ * - -1 : message block field specified by the input \c field string is not
+ * found in the message block data structure.
+ */
+int ddrphy_phyinit_softsetmb(struct pmu_smb_ddr_1d *mb_ddr_1d, enum message_block_field field,
+			     uint32_t value)
+{
+	int ret = 0;
+
+	if (field == MB_FIELD_DRAMFREQ) {
+		assert(value <= UINT16_MAX);
+	} else {
+		assert(value <= UINT8_MAX);
+	}
+
+	switch (field) {
+	case MB_FIELD_PSTATE:
+		mb_ddr_1d->pstate = (uint8_t)value;
+		break;
+	case MB_FIELD_PLLBYPASSEN:
+		mb_ddr_1d->pllbypassen = (uint8_t)value;
+		break;
+	case MB_FIELD_DRAMFREQ:
+		mb_ddr_1d->dramfreq = (uint16_t)value;
+		break;
+	case MB_FIELD_DFIFREQRATIO:
+		mb_ddr_1d->dfifreqratio = (uint8_t)value;
+		break;
+	case MB_FIELD_BPZNRESVAL:
+		mb_ddr_1d->bpznresval = (uint8_t)value;
+		break;
+	case MB_FIELD_PHYODTIMPEDANCE:
+		mb_ddr_1d->phyodtimpedance = (uint8_t)value;
+		break;
+	case MB_FIELD_PHYDRVIMPEDANCE:
+		mb_ddr_1d->phydrvimpedance = (uint8_t)value;
+		break;
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	case MB_FIELD_DRAMTYPE:
+		mb_ddr_1d->dramtype = (uint8_t)value;
+		break;
+	case MB_FIELD_DISABLEDDBYTE:
+		mb_ddr_1d->disableddbyte = (uint8_t)value;
+		break;
+	case MB_FIELD_ENABLEDDQS:
+		mb_ddr_1d->enableddqs = (uint8_t)value;
+		break;
+	case MB_FIELD_PHYCFG:
+		mb_ddr_1d->phycfg = (uint8_t)value;
+		break;
+#if STM32MP_DDR4_TYPE
+	case MB_FIELD_X16PRESENT:
+		mb_ddr_1d->x16present = (uint8_t)value;
+		break;
+#endif /* STM32MP_DDR4_TYPE */
+#else /* STM32MP_LPDDR4_TYPE */
+	case MB_FIELD_ENABLEDDQSCHA:
+		mb_ddr_1d->enableddqscha = (uint8_t)value;
+		break;
+	case MB_FIELD_CSPRESENTCHA:
+		mb_ddr_1d->cspresentcha = (uint8_t)value;
+		break;
+	case MB_FIELD_ENABLEDDQSCHB:
+		mb_ddr_1d->enableddqschb = (uint8_t)value;
+		break;
+	case MB_FIELD_CSPRESENTCHB:
+		mb_ddr_1d->cspresentchb = (uint8_t)value;
+		break;
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+	default:
+		ERROR("unknown message block field %u\n", field);
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
diff --git a/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_writeoutmem.c b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_writeoutmem.c
new file mode 100644
index 00000000..868800e2
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_writeoutmem.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * Writes local memory content into the SRAM via APB interface.
+ *
+ * This function issued APB writes commands to SRAM address based on values
+ * stored in a local PhyInit array that contains consolidated IMEM and DMEM
+ * data.
+ * @param[in] mem[] Local memory array.
+ * @param[in] mem_offset offset index. if provided, skips to the offset index
+ * from the local array and issues APB commands from mem_offset to mem_size.
+ * @param[in] mem_size size of the memroy (in mem array index)
+ * @returns void
+ */
+void ddrphy_phyinit_writeoutmem(uint32_t *mem, uint32_t mem_offset, uint32_t mem_size)
+{
+	uint32_t index;
+
+	/*
+	 * 1. Enable access to the internal CSRs by setting the MicroContMuxSel CSR to 0.
+	 *    This allows the memory controller unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+
+	for (index = 0U; index < mem_size / sizeof(uint32_t); index++) {
+		uint32_t data = mem[index];
+
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * ((index * 2) + mem_offset))),
+			      data & 0xFFFFU);
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * ((index * 2) + 1 + mem_offset))),
+			      (data >> 16) & 0xFFFFU);
+	}
+
+	/*
+	 * 2. Isolate the APB access from the internal CSRs by setting the MicroContMuxSel CSR to 1.
+	 *    This allows the firmware unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+}
+
+/* Similar function for message block */
+void ddrphy_phyinit_writeoutmsgblk(uint16_t *mem, uint32_t mem_offset, uint32_t mem_size)
+{
+	uint32_t index;
+
+	/*
+	 * 1. Enable access to the internal CSRs by setting the MicroContMuxSel CSR to 0.
+	 *    This allows the memory controller unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+
+	for (index = 0U; index < mem_size / sizeof(uint16_t); index++) {
+		mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (index + mem_offset))), mem[index]);
+	}
+
+	/*
+	 * 2. Isolate the APB access from the internal CSRs by setting the MicroContMuxSel CSR to 1.
+	 *    This allows the firmware unrestricted access to the configuration CSRs.
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+}
diff --git a/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_custompretrain.c b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_custompretrain.c
new file mode 100644
index 00000000..6a200131
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_custompretrain.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/* DDRDBG registers */
+#define DDRDBG_DDR34_AC_SWIZZLE_ADD3_0		U(0x100)
+
+/*
+ * This function is called before training firmware is executed. Any
+ * register override in this function might affect the firmware training
+ * results.
+ *
+ * This function is executed before firmware execution loop. Thus this function
+ * should be used only for the following:
+ *
+ *  - Override PHY register values written by
+ *  ddrphy_phyinit_c_initphyconfig. An example use case is when this
+ *  function does not perform the exact programing desired by the user.
+ *  - Write custom PHY registers that need to take effect before training
+ *  firmware execution.
+ *
+ * User shall use mmio_write_16 to write PHY registers in order for the register
+ * to be tracked by PhyInit for retention restore.
+ *
+ * To override settings in the message block, users can assign values to the
+ * fields in the message block data structure directly.
+ *
+ * \ref examples/simple/ddrphy_phyinit_usercustom_custompretrain.c example of this function.
+ *
+ * @return Void
+ */
+void ddrphy_phyinit_usercustom_custompretrain(struct stm32mp_ddr_config *config)
+{
+	uint32_t byte __unused;
+	uint32_t i = 0U;
+	uint32_t j;
+	uintptr_t base;
+
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	base = (uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTSWIZZLEHWTADDRESS0_ADDR)));
+
+	for (i = 0U; i < NB_HWT_SWIZZLE; i++) {
+		mmio_write_16(base + (i * sizeof(uint32_t)),
+			      (uint16_t)config->uis.swizzle[i]);
+	}
+
+	base = (uintptr_t)(stm32_ddrdbg_get_base() + DDRDBG_DDR34_AC_SWIZZLE_ADD3_0);
+
+	for (j = 0U; j < NB_AC_SWIZZLE; j++, i++) {
+		mmio_write_32(base + (j * sizeof(uint32_t)), config->uis.swizzle[i]);
+	}
+#else /* STM32MP_LPDDR4_TYPE */
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		base = (uintptr_t)(DDRPHYC_BASE + (4U *
+						   ((byte << 12) | TDBYTE | CSR_DQ0LNSEL_ADDR)));
+
+		for (j = 0U; j < NB_DQLNSEL_SWIZZLE_PER_BYTE; j++, i++) {
+			mmio_write_16(base + (j * sizeof(uint32_t)),
+				      (uint16_t)config->uis.swizzle[i]);
+		}
+	}
+
+	base = (uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MAPCAA0TODFI_ADDR)));
+
+	for (j = 0U; j < NB_MAPCAATODFI_SWIZZLE; j++, i++) {
+		mmio_write_16(base + (j * sizeof(uint32_t)),
+			      (uint16_t)config->uis.swizzle[i]);
+	}
+
+	base = (uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MAPCAB0TODFI_ADDR)));
+
+	for (j = 0U; j < NB_MAPCABTODFI_SWIZZLE; j++, i++) {
+		mmio_write_16(base + (j * sizeof(uint32_t)),
+			      (uint16_t)config->uis.swizzle[i]);
+	}
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+}
diff --git a/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_g_waitfwdone.c b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_g_waitfwdone.c
new file mode 100644
index 00000000..3d00d3d4
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_g_waitfwdone.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <drivers/delay_timer.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/* Firmware major messages */
+#define FW_MAJ_MSG_TRAINING_SUCCESS	0x0000007U
+#define FW_MAJ_MSG_START_STREAMING	0x0000008U
+#define FW_MAJ_MSG_TRAINING_FAILED	0x00000FFU
+
+#define PHYINIT_DELAY_1US		1U
+#define PHYINIT_DELAY_10US		10U
+#define PHYINIT_TIMEOUT_US_1S		1000000U
+
+static int wait_uctwriteprotshadow(bool state)
+{
+	uint64_t timeout;
+	uint16_t read_data;
+	uint16_t value = state ? BIT(0) : 0U;
+
+	timeout = timeout_init_us(PHYINIT_TIMEOUT_US_1S);
+
+	do {
+		read_data = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+						     (4U * (TAPBONLY | CSR_UCTSHADOWREGS_ADDR))));
+		udelay(PHYINIT_DELAY_1US);
+		if (timeout_elapsed(timeout)) {
+			return -1;
+		}
+	} while ((read_data & BIT(0)) != value);
+
+	return 0;
+}
+
+static int ack_message_receipt(void)
+{
+	int ret;
+
+	/* Acknowledge the receipt of the message */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_DCTWRITEPROT_ADDR))), 0U);
+
+	udelay(PHYINIT_DELAY_1US);
+
+	ret = wait_uctwriteprotshadow(true);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Complete the 4-phase protocol */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_DCTWRITEPROT_ADDR))), 1U);
+
+	udelay(PHYINIT_DELAY_1US);
+
+	return 0;
+}
+
+static int get_major_message(uint32_t *msg)
+{
+	uint16_t message_number;
+	int ret;
+
+	ret = wait_uctwriteprotshadow(false);
+	if (ret != 0) {
+		return ret;
+	}
+
+	message_number = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+							    (4U * (TAPBONLY |
+								   CSR_UCTWRITEONLYSHADOW_ADDR))));
+
+	ret = ack_message_receipt();
+	if (ret != 0) {
+		return ret;
+	}
+
+	*msg = (uint32_t)message_number;
+
+	return 0;
+}
+
+static int get_streaming_message(uint32_t *msg)
+{
+	uint16_t stream_word_lower_part;
+	uint16_t stream_word_upper_part;
+	int ret;
+
+	ret = wait_uctwriteprotshadow(false);
+	if (ret != 0) {
+		return ret;
+	}
+
+	stream_word_lower_part = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+							  (4U * (TAPBONLY |
+								 CSR_UCTWRITEONLYSHADOW_ADDR))));
+
+	stream_word_upper_part = mmio_read_16((uintptr_t)(DDRPHYC_BASE +
+							  (4U * (TAPBONLY |
+								 CSR_UCTDATWRITEONLYSHADOW_ADDR))));
+
+	ret = ack_message_receipt();
+	if (ret != 0) {
+		return ret;
+	}
+
+	*msg = (uint32_t)stream_word_lower_part | ((uint32_t)stream_word_upper_part << 16);
+
+	return 0;
+}
+
+/*
+ * Implements the mechanism to wait for completion of training firmware execution.
+ *
+ * The purpose of user this function is to wait for firmware to finish training.
+ * The user can either implement a counter to wait or implement the polling
+ * mechanism (our choice here). The wait time is highly dependent on the training features
+ * enabled via sequencectrl input to the message block.
+ *
+ * The default behavior of this function is to print comments relating to this
+ * process. A function call of the same name will be printed in the output text
+ * file.
+ *
+ * The user can choose to leave this function as is, or implement mechanism to
+ * trigger mailbox poling event in simulation.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_usercustom_g_waitfwdone(void)
+{
+	uint32_t fw_major_message;
+	int ret;
+
+	do {
+		ret = get_major_message(&fw_major_message);
+		if (ret != 0) {
+			return ret;
+		}
+
+		VERBOSE("fw_major_message = %x\n", (unsigned int)fw_major_message);
+
+		if (fw_major_message == FW_MAJ_MSG_START_STREAMING) {
+			uint32_t i;
+			uint32_t read_data;
+			uint32_t stream_len;
+
+			ret = get_streaming_message(&read_data);
+			if (ret != 0) {
+				return ret;
+			}
+
+			stream_len = read_data & 0xFFFFU;
+
+			for (i = 0U; i < stream_len; i++) {
+				ret = get_streaming_message(&read_data);
+				if (ret != 0) {
+					return ret;
+				}
+
+				VERBOSE("streaming message = %x\n", (unsigned int)read_data);
+			}
+		}
+	} while ((fw_major_message != FW_MAJ_MSG_TRAINING_SUCCESS) &&
+		 (fw_major_message != FW_MAJ_MSG_TRAINING_FAILED));
+
+	udelay(PHYINIT_DELAY_10US);
+
+	if (fw_major_message == FW_MAJ_MSG_TRAINING_FAILED) {
+		ERROR("%s Training has failed.\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_saveretregs.c b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_saveretregs.c
new file mode 100644
index 00000000..b573de32
--- /dev/null
+++ b/drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_saveretregs.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/*
+ * This function can be used to implement saving of PHY registers to be
+ * restored on retention exit.
+ *
+ * The requirement of this function is to issue register reads and store the
+ * value to be recovered on retention exit. The following is an example
+ * implementation and the user may implement alternate methods that suit their
+ * specific SoC system needs.
+ *
+ * In this implementation PhyInit saves register values in an internal C array.
+ * During retention exit it restores register values from the array. The exact
+ * list of registers to save and later restore can be seen in the output txt
+ * file with an associated calls to mmio_read_16().
+ *
+ * PhyInit provides a register interface and a tracking mechanism to minimize
+ * the number registers needing restore. Refer to source code for
+ * ddrphy_phyinit_reginterface() for detailed implementation of tracking
+ * mechanism. Tracking is disabled from step D to Step H as these involve
+ * loading, executing and checking the state of training firmware execution
+ * which are not required to implement the retention exit sequence. The registers
+ * specified representing training results are also saved in addition to registers
+ * written by PhyInit during PHY initialization.
+ *
+ * \return 0 on success.
+ */
+int ddrphy_phyinit_usercustom_saveretregs(struct stm32mp_ddr_config *config)
+{
+	uint32_t anib;
+	uint32_t byte;
+	uint32_t nibble;
+	uint32_t lane;
+	uint32_t c_addr;
+	uint32_t u_addr;
+	uint32_t b_addr;
+	uint32_t r_addr;
+	int ret;
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * 1. Enable tracking of training firmware result registers
+	 *
+	 *    \note  The tagged registers in this step are in
+	 *    addition to what is automatically tagged during Steps C to I.
+	 *
+	 * --------------------------------------------------------------------------
+	 */
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_PLLCTRL3_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Non-PState Dbyte Registers */
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		c_addr = byte << 12;
+
+		for (lane = 0U; lane <= R_MAX; lane++) {
+			r_addr = lane << 8;
+
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | r_addr |
+						      CSR_RXPBDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | r_addr |
+						      CSR_RXPBDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+
+#if STM32MP_LPDDR4_TYPE
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_PPTCTLSTATIC_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_TRAININGINCDECDTSMEN_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_TSMBYTE0_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ0LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ1LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ2LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ3LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ4LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ5LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ6LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DQ7LNSEL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+#endif /* STM32MP_LPDDR4_TYPE */
+	}
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_VREFINGLOBAL_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Anib Registers */
+	for (anib = 0U; anib < config->uib.numanib; anib++) {
+		c_addr = anib << 12;
+
+		ret = ddrphy_phyinit_trackreg(TANIB | c_addr | CSR_ATXDLY_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	/* Dbyte Registers */
+	for (byte = 0U; byte < config->uib.numdbyte; byte++) {
+		c_addr = byte << 12;
+
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_DFIMRL_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+
+		for (nibble = 0U; nibble <= B_MAX; nibble++) {
+			b_addr = nibble << 8;
+
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | b_addr |
+						      CSR_DQDQSRCVCNTRL_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+		}
+
+		for (nibble = 0U; nibble < 2U; nibble++) {
+			u_addr = nibble << 8;
+
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_RXENDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_RXENDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_TXDQSDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_TXDQSDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_RXCLKDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | u_addr |
+						      CSR_RXCLKDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+
+		for (lane = R_MIN; lane <= R_MAX; lane++) {
+			r_addr = lane << 8;
+
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | r_addr |
+						      CSR_TXDQDLYTG0_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#if STM32MP_LPDDR4_TYPE
+			ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | r_addr |
+						      CSR_TXDQDLYTG1_ADDR);
+			if (ret != 0) {
+				return ret;
+			}
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+
+#if STM32MP_LPDDR4_TYPE
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_PPTDQSCNTINVTRNTG0_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+		ret = ddrphy_phyinit_trackreg(TDBYTE | c_addr | CSR_PPTDQSCNTINVTRNTG1_ADDR);
+		if (ret != 0) {
+			return ret;
+		}
+#endif /* STM32MP_LPDDR4_TYPE */
+	}
+
+	/* PIE Registers */
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR1_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR2_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR3_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR4_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR5_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR6_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR7_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BGPR8_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Master Registers */
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_DLLGAINCTL_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_DLLLOCKPARAM_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+#if STM32MP_LPDDR4_TYPE
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_HWTMRL_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* INITENG Registers */
+	ret = ddrphy_phyinit_trackreg(TINITENG | CSR_SEQ0BDISABLEFLAG6_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_HWTCAMODE_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+#if STM32MP_LPDDR4_TYPE
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_HWTLPCSENA_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TMASTER | CSR_HWTLPCSENB_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* ACSM registers */
+	ret = ddrphy_phyinit_trackreg(TACSM | CSR_ACSMCTRL13_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = ddrphy_phyinit_trackreg(TACSM | CSR_ACSMCTRL23_ADDR);
+	if (ret != 0) {
+		return ret;
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * 2. Track any additional registers
+	 *    Register writes made using the any of the PhyInit functions are
+	 *    automatically tracked using the call to ddrphy_phyinit_trackreg() in
+	 *    mmio_write_16(). Use this section to track additional registers.
+	 * --------------------------------------------------------------------------
+	 */
+
+	/*
+	 * Example:
+	 * ddrphy_phyinit_trackreg(<addr>);
+	 */
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * 3. Prepare for register reads
+	 *    - Write the MicroContMuxSel CSR to 0x0 to allow access to the internal CSRs
+	 *    - Write the UcclkHclkEnables CSR to 0x3 to enable all the clocks so the reads
+	 *      can complete.
+	 * --------------------------------------------------------------------------
+	 */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x0U);
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x3U);
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * / 4. Read and save all the registers
+	 * /    - The list of registers differ depending on protocol and 1D training.
+	 * --------------------------------------------------------------------------
+	 */
+
+	ret = ddrphy_phyinit_reginterface(SAVEREGS, 0U, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/*
+	 * --------------------------------------------------------------------------
+	 * 5. Prepare for mission mode
+	 *  - Write the UcclkHclkEnables CSR to disable the appropriate clocks after all reads done.
+	 *  - Write the MicroContMuxSel CSR to 0x1 to isolate the internal CSRs during mission mode.
+	 * --------------------------------------------------------------------------
+	 */
+
+	/* Disabling Ucclk (PMU) and Hclk (training hardware) */
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TDRTUB | CSR_UCCLKHCLKENABLES_ADDR))),
+		      0x0U);
+
+	mmio_write_16((uintptr_t)(DDRPHYC_BASE + (4U * (TAPBONLY | CSR_MICROCONTMUXSEL_ADDR))),
+		      0x1U);
+
+	return 0;
+}
diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c
index 27d8b2c0..415d9e40 100644
--- a/drivers/st/ddr/stm32mp1_ddr.c
+++ b/drivers/st/ddr/stm32mp1_ddr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -24,14 +24,12 @@
 
 #define DDRCTL_REG(x, y)					\
 	{							\
-		.name = #x,					\
 		.offset = offsetof(struct stm32mp_ddrctl, x),	\
 		.par_offset = offsetof(struct y, x)		\
 	}
 
 #define DDRPHY_REG(x, y)					\
 	{							\
-		.name = #x,					\
 		.offset = offsetof(struct stm32mp_ddrphy, x),	\
 		.par_offset = offsetof(struct y, x)		\
 	}
@@ -215,7 +213,7 @@ static void stm32mp1_ddrphy_idone_wait(struct stm32mp_ddrphy *phy)
 {
 	uint32_t pgsr;
 	int error = 0;
-	uint64_t timeout = timeout_init_us(TIMEOUT_US_1S);
+	uint64_t timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
 
 	do {
 		pgsr = mmio_read_32((uintptr_t)&phy->pgsr);
@@ -266,7 +264,7 @@ static void stm32mp1_ddrphy_init(struct stm32mp_ddrphy *phy, uint32_t pir)
 		mmio_read_32((uintptr_t)&phy->pir));
 
 	/* Need to wait 10 configuration clock before start polling */
-	udelay(10);
+	udelay(DDR_DELAY_10US);
 
 	/* Wait DRAM initialization and Gate Training Evaluation complete */
 	stm32mp1_ddrphy_idone_wait(phy);
@@ -279,7 +277,7 @@ static void stm32mp1_wait_operating_mode(struct stm32mp_ddr_priv *priv, uint32_t
 	uint32_t stat;
 	int break_loop = 0;
 
-	timeout = timeout_init_us(TIMEOUT_US_1S);
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
 	for ( ; ; ) {
 		uint32_t operating_mode;
 		uint32_t selref_type;
@@ -508,8 +506,7 @@ static void stm32mp1_ddr3_dll_off(struct stm32mp_ddr_priv *priv)
 #endif
 
 	/* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
-	mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl,
-			DDRCTRL_PWRCTL_SELFREF_SW);
+	stm32mp_ddr_sw_selfref_exit(priv->ctl);
 	stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
 
 	/*
@@ -524,10 +521,7 @@ static void stm32mp1_ddr3_dll_off(struct stm32mp_ddr_priv *priv)
 	 */
 
 	/* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */
-	mmio_clrbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
-	VERBOSE("[0x%lx] dbg1 = 0x%x\n",
-		(uintptr_t)&priv->ctl->dbg1,
-		mmio_read_32((uintptr_t)&priv->ctl->dbg1));
+	stm32mp_ddr_enable_host_interface(priv->ctl);
 }
 
 static void stm32mp1_refresh_disable(struct stm32mp_ddrctl *ctl)
@@ -614,7 +608,7 @@ void stm32mp1_ddr_init(struct stm32mp_ddr_priv *priv,
 	mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
 
 	/* 1.4. wait 128 cycles to permit initialization of end logic */
-	udelay(2);
+	udelay(DDR_DELAY_2US);
 	/* For PCLK = 133MHz => 1 us is enough, 2 to allow lower frequency */
 
 	/* 1.5. initialize registers ddr_umctl2 */
diff --git a/drivers/st/ddr/stm32mp2_ddr.c b/drivers/st/ddr/stm32mp2_ddr.c
new file mode 100644
index 00000000..5193d118
--- /dev/null
+++ b/drivers/st/ddr/stm32mp2_ddr.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+
+#include <ddrphy_phyinit.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp2_ddr_regs.h>
+#include <drivers/st/stm32mp_ddr.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#define DDRDBG_FRAC_PLL_LOCK	U(0x10)
+
+#define DDRCTL_REG(x, y, z)					\
+	{							\
+		.offset = offsetof(struct stm32mp_ddrctl, x),	\
+		.par_offset = offsetof(struct y, x),		\
+		.qd = z						\
+	}
+
+/*
+ * PARAMETERS: value get from device tree :
+ *             size / order need to be aligned with binding
+ *             modification NOT ALLOWED !!!
+ */
+#define DDRCTL_REG_REG_SIZE	48	/* st,ctl-reg */
+#define DDRCTL_REG_TIMING_SIZE	20	/* st,ctl-timing */
+#define DDRCTL_REG_MAP_SIZE	12	/* st,ctl-map */
+#if STM32MP_DDR_DUAL_AXI_PORT
+#define DDRCTL_REG_PERF_SIZE	21	/* st,ctl-perf */
+#else /* !STM32MP_DDR_DUAL_AXI_PORT */
+#define DDRCTL_REG_PERF_SIZE	14	/* st,ctl-perf */
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
+
+#define DDRPHY_REG_REG_SIZE	0	/* st,phy-reg */
+#define	DDRPHY_REG_TIMING_SIZE	0	/* st,phy-timing */
+
+#define DDRCTL_REG_REG(x, z)	DDRCTL_REG(x, stm32mp2_ddrctrl_reg, z)
+static const struct stm32mp_ddr_reg_desc ddr_reg[DDRCTL_REG_REG_SIZE] = {
+	DDRCTL_REG_REG(mstr, true),
+	DDRCTL_REG_REG(mrctrl0, false),
+	DDRCTL_REG_REG(mrctrl1, false),
+	DDRCTL_REG_REG(mrctrl2, false),
+	DDRCTL_REG_REG(derateen, true),
+	DDRCTL_REG_REG(derateint, false),
+	DDRCTL_REG_REG(deratectl, false),
+	DDRCTL_REG_REG(pwrctl, false),
+	DDRCTL_REG_REG(pwrtmg, true),
+	DDRCTL_REG_REG(hwlpctl, true),
+	DDRCTL_REG_REG(rfshctl0, false),
+	DDRCTL_REG_REG(rfshctl1, false),
+	DDRCTL_REG_REG(rfshctl3, true),
+	DDRCTL_REG_REG(crcparctl0, false),
+	DDRCTL_REG_REG(crcparctl1, false),
+	DDRCTL_REG_REG(init0, true),
+	DDRCTL_REG_REG(init1, false),
+	DDRCTL_REG_REG(init2, false),
+	DDRCTL_REG_REG(init3, true),
+	DDRCTL_REG_REG(init4, true),
+	DDRCTL_REG_REG(init5, false),
+	DDRCTL_REG_REG(init6, true),
+	DDRCTL_REG_REG(init7, true),
+	DDRCTL_REG_REG(dimmctl, false),
+	DDRCTL_REG_REG(rankctl, true),
+	DDRCTL_REG_REG(rankctl1, true),
+	DDRCTL_REG_REG(zqctl0, true),
+	DDRCTL_REG_REG(zqctl1, false),
+	DDRCTL_REG_REG(zqctl2, false),
+	DDRCTL_REG_REG(dfitmg0, true),
+	DDRCTL_REG_REG(dfitmg1, true),
+	DDRCTL_REG_REG(dfilpcfg0, false),
+	DDRCTL_REG_REG(dfilpcfg1, false),
+	DDRCTL_REG_REG(dfiupd0, true),
+	DDRCTL_REG_REG(dfiupd1, false),
+	DDRCTL_REG_REG(dfiupd2, false),
+	DDRCTL_REG_REG(dfimisc, true),
+	DDRCTL_REG_REG(dfitmg2, true),
+	DDRCTL_REG_REG(dfitmg3, false),
+	DDRCTL_REG_REG(dbictl, true),
+	DDRCTL_REG_REG(dfiphymstr, false),
+	DDRCTL_REG_REG(dbg0, false),
+	DDRCTL_REG_REG(dbg1, false),
+	DDRCTL_REG_REG(dbgcmd, false),
+	DDRCTL_REG_REG(swctl, false), /* forced qd value */
+	DDRCTL_REG_REG(swctlstatic, false),
+	DDRCTL_REG_REG(poisoncfg, false),
+	DDRCTL_REG_REG(pccfg, false),
+};
+
+#define DDRCTL_REG_TIMING(x, z)	DDRCTL_REG(x, stm32mp2_ddrctrl_timing, z)
+static const struct stm32mp_ddr_reg_desc ddr_timing[DDRCTL_REG_TIMING_SIZE] = {
+	DDRCTL_REG_TIMING(rfshtmg, false),
+	DDRCTL_REG_TIMING(rfshtmg1, false),
+	DDRCTL_REG_TIMING(dramtmg0, true),
+	DDRCTL_REG_TIMING(dramtmg1, true),
+	DDRCTL_REG_TIMING(dramtmg2, true),
+	DDRCTL_REG_TIMING(dramtmg3, true),
+	DDRCTL_REG_TIMING(dramtmg4, true),
+	DDRCTL_REG_TIMING(dramtmg5, true),
+	DDRCTL_REG_TIMING(dramtmg6, true),
+	DDRCTL_REG_TIMING(dramtmg7, true),
+	DDRCTL_REG_TIMING(dramtmg8, true),
+	DDRCTL_REG_TIMING(dramtmg9, true),
+	DDRCTL_REG_TIMING(dramtmg10, true),
+	DDRCTL_REG_TIMING(dramtmg11, true),
+	DDRCTL_REG_TIMING(dramtmg12, true),
+	DDRCTL_REG_TIMING(dramtmg13, true),
+	DDRCTL_REG_TIMING(dramtmg14, true),
+	DDRCTL_REG_TIMING(dramtmg15, true),
+	DDRCTL_REG_TIMING(odtcfg, true),
+	DDRCTL_REG_TIMING(odtmap, false),
+};
+
+#define DDRCTL_REG_MAP(x)	DDRCTL_REG(x, stm32mp2_ddrctrl_map, false)
+static const struct stm32mp_ddr_reg_desc ddr_map[DDRCTL_REG_MAP_SIZE] = {
+	DDRCTL_REG_MAP(addrmap0),
+	DDRCTL_REG_MAP(addrmap1),
+	DDRCTL_REG_MAP(addrmap2),
+	DDRCTL_REG_MAP(addrmap3),
+	DDRCTL_REG_MAP(addrmap4),
+	DDRCTL_REG_MAP(addrmap5),
+	DDRCTL_REG_MAP(addrmap6),
+	DDRCTL_REG_MAP(addrmap7),
+	DDRCTL_REG_MAP(addrmap8),
+	DDRCTL_REG_MAP(addrmap9),
+	DDRCTL_REG_MAP(addrmap10),
+	DDRCTL_REG_MAP(addrmap11),
+};
+
+#define DDRCTL_REG_PERF(x, z)	DDRCTL_REG(x, stm32mp2_ddrctrl_perf, z)
+static const struct stm32mp_ddr_reg_desc ddr_perf[DDRCTL_REG_PERF_SIZE] = {
+	DDRCTL_REG_PERF(sched, true),
+	DDRCTL_REG_PERF(sched1, false),
+	DDRCTL_REG_PERF(perfhpr1, true),
+	DDRCTL_REG_PERF(perflpr1, true),
+	DDRCTL_REG_PERF(perfwr1, true),
+	DDRCTL_REG_PERF(sched3, false),
+	DDRCTL_REG_PERF(sched4, false),
+	DDRCTL_REG_PERF(pcfgr_0, false),
+	DDRCTL_REG_PERF(pcfgw_0, false),
+	DDRCTL_REG_PERF(pctrl_0, false),
+	DDRCTL_REG_PERF(pcfgqos0_0, true),
+	DDRCTL_REG_PERF(pcfgqos1_0, true),
+	DDRCTL_REG_PERF(pcfgwqos0_0, true),
+	DDRCTL_REG_PERF(pcfgwqos1_0, true),
+#if STM32MP_DDR_DUAL_AXI_PORT
+	DDRCTL_REG_PERF(pcfgr_1, false),
+	DDRCTL_REG_PERF(pcfgw_1, false),
+	DDRCTL_REG_PERF(pctrl_1, false),
+	DDRCTL_REG_PERF(pcfgqos0_1, true),
+	DDRCTL_REG_PERF(pcfgqos1_1, true),
+	DDRCTL_REG_PERF(pcfgwqos0_1, true),
+	DDRCTL_REG_PERF(pcfgwqos1_1, true),
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
+};
+
+static const struct stm32mp_ddr_reg_desc ddrphy_reg[DDRPHY_REG_REG_SIZE] = {};
+
+static const struct stm32mp_ddr_reg_desc ddrphy_timing[DDRPHY_REG_TIMING_SIZE] = {};
+
+/*
+ * REGISTERS ARRAY: used to parse device tree and interactive mode
+ */
+static const struct stm32mp_ddr_reg_info ddr_registers[REG_TYPE_NB] __unused = {
+	[REG_REG] = {
+		.name = "static",
+		.desc = ddr_reg,
+		.size = DDRCTL_REG_REG_SIZE,
+		.base = DDR_BASE
+	},
+	[REG_TIMING] = {
+		.name = "timing",
+		.desc = ddr_timing,
+		.size = DDRCTL_REG_TIMING_SIZE,
+		.base = DDR_BASE
+	},
+	[REG_PERF] = {
+		.name = "perf",
+		.desc = ddr_perf,
+		.size = DDRCTL_REG_PERF_SIZE,
+		.base = DDR_BASE
+	},
+	[REG_MAP] = {
+		.name = "map",
+		.desc = ddr_map,
+		.size = DDRCTL_REG_MAP_SIZE,
+		.base = DDR_BASE
+	},
+	[REGPHY_REG] = {
+		.name = "static",
+		.desc = ddrphy_reg,
+		.size = DDRPHY_REG_REG_SIZE,
+		.base = DDRPHY_BASE
+	},
+	[REGPHY_TIMING] = {
+		.name = "timing",
+		.desc = ddrphy_timing,
+		.size = DDRPHY_REG_TIMING_SIZE,
+		.base = DDRPHY_BASE
+	},
+};
+
+static void ddr_reset(struct stm32mp_ddr_priv *priv)
+{
+	udelay(DDR_DELAY_1US);
+
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_write_32(priv->rcc + RCC_DDRPHYCAPBCFGR,
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBEN | RCC_DDRPHYCAPBCFGR_DDRPHYCAPBLPEN |
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBRST);
+	mmio_write_32(priv->rcc + RCC_DDRCAPBCFGR,
+		      RCC_DDRCAPBCFGR_DDRCAPBEN | RCC_DDRCAPBCFGR_DDRCAPBLPEN |
+		      RCC_DDRCAPBCFGR_DDRCAPBRST);
+	mmio_write_32(priv->rcc + RCC_DDRCFGR,
+		      RCC_DDRCFGR_DDRCFGEN | RCC_DDRCFGR_DDRCFGLPEN | RCC_DDRCFGR_DDRCFGRST);
+
+	udelay(DDR_DELAY_1US);
+
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_write_32(priv->rcc + RCC_DDRPHYCAPBCFGR,
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBEN | RCC_DDRPHYCAPBCFGR_DDRPHYCAPBLPEN);
+	mmio_write_32(priv->rcc + RCC_DDRCAPBCFGR,
+		      RCC_DDRCAPBCFGR_DDRCAPBEN | RCC_DDRCAPBCFGR_DDRCAPBLPEN);
+	mmio_write_32(priv->rcc + RCC_DDRCFGR, RCC_DDRCFGR_DDRCFGEN | RCC_DDRCFGR_DDRCFGLPEN);
+
+	udelay(DDR_DELAY_1US);
+}
+
+static void ddr_standby_reset(struct stm32mp_ddr_priv *priv)
+{
+	udelay(DDR_DELAY_1US);
+
+	mmio_write_32(priv->rcc + RCC_DDRCPCFGR,
+		      RCC_DDRCPCFGR_DDRCPEN | RCC_DDRCPCFGR_DDRCPLPEN | RCC_DDRCPCFGR_DDRCPRST);
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_write_32(priv->rcc + RCC_DDRPHYCAPBCFGR,
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBEN | RCC_DDRPHYCAPBCFGR_DDRPHYCAPBLPEN |
+		      RCC_DDRPHYCAPBCFGR_DDRPHYCAPBRST);
+	mmio_write_32(priv->rcc + RCC_DDRCAPBCFGR,
+		      RCC_DDRCAPBCFGR_DDRCAPBEN | RCC_DDRCAPBCFGR_DDRCAPBLPEN |
+		      RCC_DDRCAPBCFGR_DDRCAPBRST);
+
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRPHYDLP);
+	mmio_setbits_32(priv->rcc + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+
+	udelay(DDR_DELAY_1US);
+}
+
+static void ddr_standby_reset_release(struct stm32mp_ddr_priv *priv)
+{
+	udelay(DDR_DELAY_1US);
+
+	mmio_write_32(priv->rcc + RCC_DDRCPCFGR, RCC_DDRCPCFGR_DDRCPEN | RCC_DDRCPCFGR_DDRCPLPEN);
+	mmio_clrbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_clrbits_32(priv->rcc + RCC_DDRPHYCAPBCFGR, RCC_DDRPHYCAPBCFGR_DDRPHYCAPBRST);
+	mmio_write_32(priv->rcc + RCC_DDRCFGR, RCC_DDRCFGR_DDRCFGEN | RCC_DDRCFGR_DDRCFGLPEN);
+
+	udelay(DDR_DELAY_1US);
+}
+
+static void ddr_sysconf_configuration(struct stm32mp_ddr_priv *priv,
+				      struct stm32mp_ddr_config *config)
+{
+	mmio_write_32(stm32_ddrdbg_get_base() + DDRDBG_LP_DISABLE,
+		      DDRDBG_LP_DISABLE_LPI_XPI_DISABLE | DDRDBG_LP_DISABLE_LPI_DDRC_DISABLE);
+
+	mmio_write_32(stm32_ddrdbg_get_base() + DDRDBG_BYPASS_PCLKEN,
+		      (uint32_t)config->uib.pllbypass);
+
+	mmio_write_32(priv->rcc + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+	mmio_setbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+
+	udelay(DDR_DELAY_1US);
+}
+
+static void set_dfi_init_complete_en(struct stm32mp_ddrctl *ctl, bool phy_init_done)
+{
+	/*
+	 * Manage quasi-dynamic registers modification
+	 * dfimisc.dfi_init_complete_en : Group 3
+	 */
+	stm32mp_ddr_set_qd3_update_conditions(ctl);
+
+	udelay(DDR_DELAY_1US);
+
+	if (phy_init_done) {
+		/* Indicates to controller that PHY has completed initialization */
+		mmio_setbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	} else {
+		/* PHY not initialized yet, wait for completion */
+		mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	}
+
+	udelay(DDR_DELAY_1US);
+
+	stm32mp_ddr_unset_qd3_update_conditions(ctl);
+
+}
+
+static void disable_refresh(struct stm32mp_ddrctl *ctl)
+{
+	mmio_setbits_32((uintptr_t)&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
+
+	stm32mp_ddr_wait_refresh_update_done_ack(ctl);
+
+	udelay(DDR_DELAY_1US);
+
+	mmio_clrbits_32((uintptr_t)&ctl->pwrctl,
+			DDRCTRL_PWRCTL_POWERDOWN_EN | DDRCTRL_PWRCTL_SELFREF_EN);
+
+	udelay(DDR_DELAY_1US);
+
+	set_dfi_init_complete_en(ctl, false);
+}
+
+static void restore_refresh(struct stm32mp_ddrctl *ctl, uint32_t rfshctl3, uint32_t pwrctl)
+{
+	if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) {
+		mmio_clrbits_32((uintptr_t)&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
+
+		stm32mp_ddr_wait_refresh_update_done_ack(ctl);
+
+		udelay(DDR_DELAY_1US);
+	}
+
+	if ((pwrctl & DDRCTRL_PWRCTL_SELFREF_SW) != 0U) {
+		mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_SW);
+
+		udelay(DDR_DELAY_1US);
+	}
+
+	if ((pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) != 0U) {
+		mmio_setbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+
+		udelay(DDR_DELAY_1US);
+	}
+
+	if ((pwrctl & DDRCTRL_PWRCTL_SELFREF_EN) != 0U) {
+		mmio_setbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_EN);
+
+		udelay(DDR_DELAY_1US);
+	}
+
+	set_dfi_init_complete_en(ctl, true);
+}
+
+void stm32mp2_ddr_init(struct stm32mp_ddr_priv *priv,
+		       struct stm32mp_ddr_config *config)
+{
+	int ret = -EINVAL;
+	uint32_t ddr_retdis;
+	enum ddr_type ddr_type;
+
+	if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
+		ddr_type = STM32MP_DDR3;
+	} else if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR4) != 0U) {
+		ddr_type = STM32MP_DDR4;
+	} else if ((config->c_reg.mstr & DDRCTRL_MSTR_LPDDR4) != 0U) {
+		ddr_type = STM32MP_LPDDR4;
+	} else {
+		ERROR("DDR type not supported\n");
+		panic();
+	}
+
+	VERBOSE("name = %s\n", config->info.name);
+	VERBOSE("speed = %u kHz\n", config->info.speed);
+	VERBOSE("size  = 0x%zx\n", config->info.size);
+	if (config->self_refresh) {
+		VERBOSE("sel-refresh exit (zdata = 0x%x)\n", config->zdata);
+	}
+
+	/* Check DDR PHY pads retention */
+	ddr_retdis = mmio_read_32(priv->pwr + PWR_CR11) & PWR_CR11_DDRRETDIS;
+	if (config->self_refresh) {
+		if (ddr_retdis == PWR_CR11_DDRRETDIS) {
+			VERBOSE("self-refresh aborted: no retention\n");
+			config->self_refresh = false;
+		}
+	}
+
+	if (config->self_refresh) {
+		ddr_standby_reset(priv);
+
+		VERBOSE("disable DDR PHY retention\n");
+		mmio_setbits_32(priv->pwr + PWR_CR11, PWR_CR11_DDRRETDIS);
+
+		udelay(DDR_DELAY_1US);
+
+		mmio_clrbits_32(priv->rcc + RCC_DDRCAPBCFGR, RCC_DDRCAPBCFGR_DDRCAPBRST);
+
+		udelay(DDR_DELAY_1US);
+
+	} else {
+		if (stm32mp_board_ddr_power_init(ddr_type) != 0) {
+			ERROR("DDR power init failed\n");
+			panic();
+		}
+
+		VERBOSE("disable DDR PHY retention\n");
+		mmio_setbits_32(priv->pwr + PWR_CR11, PWR_CR11_DDRRETDIS);
+
+		ddr_reset(priv);
+
+		ddr_sysconf_configuration(priv, config);
+	}
+
+#if STM32MP_LPDDR4_TYPE
+	/*
+	 * Enable PWRCTL.SELFREF_SW to ensure correct setting of PWRCTL.LPDDR4_SR_ALLOWED.
+	 * Later disabled in restore_refresh().
+	 */
+	config->c_reg.pwrctl |= DDRCTRL_PWRCTL_SELFREF_SW;
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	stm32mp_ddr_set_reg(priv, REG_REG, &config->c_reg, ddr_registers);
+	stm32mp_ddr_set_reg(priv, REG_TIMING, &config->c_timing, ddr_registers);
+	stm32mp_ddr_set_reg(priv, REG_MAP, &config->c_map, ddr_registers);
+	stm32mp_ddr_set_reg(priv, REG_PERF, &config->c_perf, ddr_registers);
+
+	if (!config->self_refresh) {
+		/*  DDR core and PHY reset de-assert */
+		mmio_clrbits_32(priv->rcc + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+
+		disable_refresh(priv->ctl);
+	}
+
+	if (config->self_refresh) {
+		ddr_standby_reset_release(priv);
+
+		/* Initialize DDR by skipping training and disabling result saving */
+		ret = ddrphy_phyinit_sequence(config, true, false);
+
+		if (ret == 0) {
+			ret = ddrphy_phyinit_restore_sequence();
+		}
+
+		/* Poll on ddrphy_initeng0_phyinlpx.phyinlp3 = 0 */
+		ddr_wait_lp3_mode(false);
+	} else {
+		/* Initialize DDR including training and result saving */
+		ret = ddrphy_phyinit_sequence(config, false, true);
+	}
+
+	if (ret != 0) {
+		ERROR("DDR PHY init: Error %d\n", ret);
+		panic();
+	}
+
+	ddr_activate_controller(priv->ctl, false);
+
+	if (config->self_refresh) {
+		struct stm32mp_ddrctl *ctl = priv->ctl;
+
+		/* SW self refresh exit prequested */
+		mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_SW);
+
+		if (ddr_sr_exit_loop() != 0) {
+			ERROR("DDR Standby exit error\n");
+			panic();
+		}
+
+		/* Re-enable DFI low-power interface */
+		mmio_clrbits_32((uintptr_t)&ctl->dfilpcfg0, DDRCTRL_DFILPCFG0_DFI_LP_EN_SR);
+	} else {
+		restore_refresh(priv->ctl, config->c_reg.rfshctl3, config->c_reg.pwrctl);
+	}
+
+	stm32mp_ddr_enable_axi_port(priv->ctl);
+}
diff --git a/drivers/st/ddr/stm32mp2_ddr_helpers.c b/drivers/st/ddr/stm32mp2_ddr_helpers.c
new file mode 100644
index 00000000..a2a40822
--- /dev/null
+++ b/drivers/st/ddr/stm32mp2_ddr_helpers.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp2_ddr.h>
+#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp2_ddr_regs.h>
+#include <drivers/st/stm32mp_ddr.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+/* HW idle period (unit: Multiples of 32 DFI clock cycles) */
+#define HW_IDLE_PERIOD			0x3U
+
+static enum stm32mp2_ddr_sr_mode saved_ddr_sr_mode;
+
+#pragma weak stm32_ddrdbg_get_base
+uintptr_t stm32_ddrdbg_get_base(void)
+{
+	return 0U;
+}
+
+static void set_qd1_qd3_update_conditions(struct stm32mp_ddrctl *ctl)
+{
+	mmio_setbits_32((uintptr_t)&ctl->dbg1, DDRCTRL_DBG1_DIS_DQ);
+
+	stm32mp_ddr_set_qd3_update_conditions(ctl);
+}
+
+static void unset_qd1_qd3_update_conditions(struct stm32mp_ddrctl *ctl)
+{
+	stm32mp_ddr_unset_qd3_update_conditions(ctl);
+
+	mmio_clrbits_32((uintptr_t)&ctl->dbg1, DDRCTRL_DBG1_DIS_DQ);
+}
+
+static void wait_dfi_init_complete(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t dfistat;
+
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		dfistat = mmio_read_32((uintptr_t)&ctl->dfistat);
+		VERBOSE("[0x%lx] dfistat = 0x%x ", (uintptr_t)&ctl->dfistat, dfistat);
+
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+	} while ((dfistat & DDRCTRL_DFISTAT_DFI_INIT_COMPLETE) == 0U);
+
+	VERBOSE("[0x%lx] dfistat = 0x%x\n", (uintptr_t)&ctl->dfistat, dfistat);
+}
+
+static void disable_dfi_low_power_interface(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t dfistat;
+	uint32_t stat;
+
+	mmio_clrbits_32((uintptr_t)&ctl->dfilpcfg0, DDRCTRL_DFILPCFG0_DFI_LP_EN_SR);
+
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		dfistat = mmio_read_32((uintptr_t)&ctl->dfistat);
+		stat = mmio_read_32((uintptr_t)&ctl->stat);
+		VERBOSE("[0x%lx] dfistat = 0x%x ", (uintptr_t)&ctl->dfistat, dfistat);
+		VERBOSE("[0x%lx] stat = 0x%x ", (uintptr_t)&ctl->stat, stat);
+
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+	} while (((dfistat & DDRCTRL_DFISTAT_DFI_LP_ACK) != 0U) ||
+		 ((stat & DDRCTRL_STAT_OPERATING_MODE_MASK) == DDRCTRL_STAT_OPERATING_MODE_SR));
+
+	VERBOSE("[0x%lx] dfistat = 0x%x\n", (uintptr_t)&ctl->dfistat, dfistat);
+	VERBOSE("[0x%lx] stat = 0x%x\n", (uintptr_t)&ctl->stat, stat);
+}
+
+void ddr_activate_controller(struct stm32mp_ddrctl *ctl, bool sr_entry)
+{
+	/*
+	 * Manage quasi-dynamic registers modification
+	 * dfimisc.dfi_frequency : Group 1
+	 * dfimisc.dfi_init_complete_en and dfimisc.dfi_init_start : Group 3
+	 */
+	set_qd1_qd3_update_conditions(ctl);
+
+	if (sr_entry) {
+		mmio_setbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_FREQUENCY);
+	} else {
+		mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_FREQUENCY);
+	}
+
+	mmio_setbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_START);
+	mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_START);
+
+	wait_dfi_init_complete(ctl);
+
+	udelay(DDR_DELAY_1US);
+
+	if (sr_entry) {
+		mmio_clrbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	} else {
+		mmio_setbits_32((uintptr_t)&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+	}
+
+	udelay(DDR_DELAY_1US);
+
+	unset_qd1_qd3_update_conditions(ctl);
+}
+
+#if STM32MP_LPDDR4_TYPE
+static void disable_phy_ddc(void)
+{
+	/* Enable APB access to internal CSR registers */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_APBONLY0_MICROCONTMUXSEL, 0U);
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES,
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_UCCLKEN |
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN);
+
+	/* Disable DRAM drift compensation */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_INITENG0_P0_SEQ0BDISABLEFLAG6, 0xFFFFU);
+
+	/* Disable APB access to internal CSR registers */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES,
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN);
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_APBONLY0_MICROCONTMUXSEL,
+		      DDRPHY_APBONLY0_MICROCONTMUXSEL_MICROCONTMUXSEL);
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+void ddr_wait_lp3_mode(bool sr_entry)
+{
+	uint64_t timeout;
+	bool repeat_loop = false;
+
+	/* Enable APB access to internal CSR registers */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_APBONLY0_MICROCONTMUXSEL, 0U);
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES,
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_UCCLKEN |
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN);
+
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		uint16_t phyinlpx = mmio_read_32(stm32mp_ddrphyc_base() +
+						 DDRPHY_INITENG0_P0_PHYINLPX);
+
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+
+		if (sr_entry) {
+			repeat_loop = (phyinlpx & DDRPHY_INITENG0_P0_PHYINLPX_PHYINLP3) == 0U;
+		} else {
+			repeat_loop = (phyinlpx & DDRPHY_INITENG0_P0_PHYINLPX_PHYINLP3) != 0U;
+		}
+	} while (repeat_loop);
+
+	/* Disable APB access to internal CSR registers */
+#if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES, 0U);
+#else /* STM32MP_LPDDR4_TYPE */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_DRTUB0_UCCLKHCLKENABLES,
+		      DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN);
+#endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
+	mmio_write_32(stm32mp_ddrphyc_base() + DDRPHY_APBONLY0_MICROCONTMUXSEL,
+		      DDRPHY_APBONLY0_MICROCONTMUXSEL_MICROCONTMUXSEL);
+}
+
+static int sr_loop(bool is_entry)
+{
+	uint32_t type;
+	uint32_t state __maybe_unused;
+	uint64_t timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	bool repeat_loop = false;
+
+	/*
+	 * Wait for DDRCTRL to be out of or back to "normal/mission mode".
+	 * Consider also SRPD mode for LPDDR4 only.
+	 */
+	do {
+		type = mmio_read_32(stm32mp_ddrctrl_base() + DDRCTRL_STAT) &
+		       DDRCTRL_STAT_SELFREF_TYPE_MASK;
+#if STM32MP_LPDDR4_TYPE
+		state = mmio_read_32(stm32mp_ddrctrl_base() + DDRCTRL_STAT) &
+		       DDRCTRL_STAT_SELFREF_STATE_MASK;
+#endif /* STM32MP_LPDDR4_TYPE */
+
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+
+		if (is_entry) {
+#if STM32MP_LPDDR4_TYPE
+			repeat_loop = (type == 0x0U) || (state != DDRCTRL_STAT_SELFREF_STATE_SRPD);
+#else /* !STM32MP_LPDDR4_TYPE */
+			repeat_loop = (type == 0x0U);
+#endif /* STM32MP_LPDDR4_TYPE */
+		} else {
+#if STM32MP_LPDDR4_TYPE
+			repeat_loop = (type != 0x0U) || (state != 0x0U);
+#else /* !STM32MP_LPDDR4_TYPE */
+			repeat_loop = (type != 0x0U);
+#endif /* STM32MP_LPDDR4_TYPE */
+		}
+	} while (repeat_loop);
+
+	return 0;
+}
+
+static int sr_entry_loop(void)
+{
+	return sr_loop(true);
+}
+
+int ddr_sr_exit_loop(void)
+{
+	return sr_loop(false);
+}
+
+static int sr_ssr_set(void)
+{
+	uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
+
+	/*
+	 * Disable Clock disable with LP modes
+	 * (used in RUN mode for LPDDR2 with specific timing).
+	 */
+	mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE);
+
+	/* Disable automatic Self-Refresh mode */
+	mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_EN);
+
+	mmio_write_32(stm32_ddrdbg_get_base() + DDRDBG_LP_DISABLE,
+		      DDRDBG_LP_DISABLE_LPI_XPI_DISABLE | DDRDBG_LP_DISABLE_LPI_DDRC_DISABLE);
+
+	return 0;
+}
+
+static int sr_ssr_entry(bool standby)
+{
+	uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	if (stm32mp_ddr_disable_axi_port((struct stm32mp_ddrctl *)ddrctrl_base) != 0) {
+		panic();
+	}
+
+#if STM32MP_LPDDR4_TYPE
+	if (standby) {
+		/* Disable DRAM drift compensation */
+		disable_phy_ddc();
+	}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	disable_dfi_low_power_interface((struct stm32mp_ddrctl *)ddrctrl_base);
+
+	/* SW self refresh entry prequested */
+	mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_SW);
+#if STM32MP_LPDDR4_TYPE
+	mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_STAY_IN_SELFREF);
+#endif /* STM32MP_LPDDR4_TYPE */
+
+	if (sr_entry_loop() != 0) {
+		return -1;
+	}
+
+	ddr_activate_controller((struct stm32mp_ddrctl *)ddrctrl_base, true);
+
+	/* Poll on ddrphy_initeng0_phyinlpx.phyinlp3 = 1 */
+	ddr_wait_lp3_mode(true);
+
+	if (standby) {
+		mmio_clrbits_32(stm32mp_pwr_base() + PWR_CR11, PWR_CR11_DDRRETDIS);
+	}
+
+	mmio_clrsetbits_32(rcc_base + RCC_DDRCPCFGR, RCC_DDRCPCFGR_DDRCPLPEN,
+			   RCC_DDRCPCFGR_DDRCPEN);
+	mmio_setbits_32(rcc_base + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+	mmio_setbits_32(rcc_base + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRPHYDLP);
+
+	return 0;
+}
+
+static int sr_ssr_exit(void)
+{
+	uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	mmio_setbits_32(rcc_base + RCC_DDRCPCFGR,
+			RCC_DDRCPCFGR_DDRCPLPEN | RCC_DDRCPCFGR_DDRCPEN);
+	mmio_clrbits_32(rcc_base + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRPHYDLP);
+	mmio_setbits_32(rcc_base + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+
+	udelay(DDR_DELAY_1US);
+
+	ddr_activate_controller((struct stm32mp_ddrctl *)ddrctrl_base, false);
+
+	/* Poll on ddrphy_initeng0_phyinlpx.phyinlp3 = 0 */
+	ddr_wait_lp3_mode(false);
+
+	/* SW self refresh exit prequested */
+	mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_SW);
+
+	if (ddr_sr_exit_loop() != 0) {
+		return -1;
+	}
+
+	/* Re-enable DFI low-power interface */
+	mmio_setbits_32(ddrctrl_base + DDRCTRL_DFILPCFG0, DDRCTRL_DFILPCFG0_DFI_LP_EN_SR);
+
+	stm32mp_ddr_enable_axi_port((struct stm32mp_ddrctl *)ddrctrl_base);
+
+	return 0;
+}
+
+static int sr_hsr_set(void)
+{
+	uintptr_t ddrctrl_base = stm32mp_ddrctrl_base();
+
+	mmio_clrsetbits_32(stm32mp_rcc_base() + RCC_DDRITFCFGR,
+			   RCC_DDRITFCFGR_DDRCKMOD_MASK, RCC_DDRITFCFGR_DDRCKMOD_HSR);
+
+	/*
+	 * manage quasi-dynamic registers modification
+	 * hwlpctl.hw_lp_en : Group 2
+	 */
+	if (stm32mp_ddr_sw_selfref_entry((struct stm32mp_ddrctl *)ddrctrl_base) != 0) {
+		panic();
+	}
+	stm32mp_ddr_start_sw_done((struct stm32mp_ddrctl *)ddrctrl_base);
+
+	mmio_write_32(ddrctrl_base + DDRCTRL_HWLPCTL,
+		      DDRCTRL_HWLPCTL_HW_LP_EN | DDRCTRL_HWLPCTL_HW_LP_EXIT_IDLE_EN |
+		      (HW_IDLE_PERIOD << DDRCTRL_HWLPCTL_HW_LP_IDLE_X32_SHIFT));
+
+	stm32mp_ddr_wait_sw_done_ack((struct stm32mp_ddrctl *)ddrctrl_base);
+	stm32mp_ddr_sw_selfref_exit((struct stm32mp_ddrctl *)ddrctrl_base);
+
+	return 0;
+}
+
+static int sr_hsr_entry(void)
+{
+	mmio_write_32(stm32mp_rcc_base() + RCC_DDRCPCFGR, RCC_DDRCPCFGR_DDRCPLPEN);
+
+	return sr_entry_loop(); /* read_data should be equal to 0x223 */
+}
+
+static int sr_hsr_exit(void)
+{
+	mmio_write_32(stm32mp_rcc_base() + RCC_DDRCPCFGR,
+		      RCC_DDRCPCFGR_DDRCPLPEN | RCC_DDRCPCFGR_DDRCPEN);
+
+	/* TODO: check if ddr_sr_exit_loop() is needed here */
+
+	return 0;
+}
+
+static int sr_asr_set(void)
+{
+	mmio_write_32(stm32_ddrdbg_get_base() + DDRDBG_LP_DISABLE, 0U);
+
+	return 0;
+}
+
+static int sr_asr_entry(void)
+{
+	/*
+	 * Automatically enter into self refresh when there is no ddr traffic
+	 * for the delay programmed into SYSCONF_DDRC_AUTO_SR_DELAY register.
+	 * Default value is 0x20 (unit: Multiples of 32 DFI clock cycles).
+	 */
+	return sr_entry_loop();
+}
+
+static int sr_asr_exit(void)
+{
+	return ddr_sr_exit_loop();
+}
+
+uint32_t ddr_get_io_calibration_val(void)
+{
+	/* TODO create related service */
+
+	return 0U;
+}
+
+int ddr_sr_entry(bool standby)
+{
+	int ret = -EINVAL;
+
+	switch (saved_ddr_sr_mode) {
+	case DDR_SSR_MODE:
+		ret = sr_ssr_entry(standby);
+		break;
+	case DDR_HSR_MODE:
+		ret = sr_hsr_entry();
+		break;
+	case DDR_ASR_MODE:
+		ret = sr_asr_entry();
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+int ddr_sr_exit(void)
+{
+	int ret = -EINVAL;
+
+	switch (saved_ddr_sr_mode) {
+	case DDR_SSR_MODE:
+		ret = sr_ssr_exit();
+		break;
+	case DDR_HSR_MODE:
+		ret = sr_hsr_exit();
+		break;
+	case DDR_ASR_MODE:
+		ret = sr_asr_exit();
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+enum stm32mp2_ddr_sr_mode ddr_read_sr_mode(void)
+{
+	uint32_t pwrctl = mmio_read_32(stm32mp_ddrctrl_base() + DDRCTRL_PWRCTL);
+	enum stm32mp2_ddr_sr_mode mode = DDR_SR_MODE_INVALID;
+
+	switch (pwrctl & (DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE |
+			  DDRCTRL_PWRCTL_SELFREF_EN)) {
+	case 0U:
+		mode = DDR_SSR_MODE;
+		break;
+	case DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE:
+		mode = DDR_HSR_MODE;
+		break;
+	case DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE | DDRCTRL_PWRCTL_SELFREF_EN:
+		mode = DDR_ASR_MODE;
+		break;
+	default:
+		break;
+	}
+
+	return mode;
+}
+
+void ddr_set_sr_mode(enum stm32mp2_ddr_sr_mode mode)
+{
+	int ret = -EINVAL;
+
+	if (mode == saved_ddr_sr_mode) {
+		return;
+	}
+
+	switch (mode) {
+	case DDR_SSR_MODE:
+		ret = sr_ssr_set();
+		break;
+	case DDR_HSR_MODE:
+		ret = sr_hsr_set();
+		break;
+	case DDR_ASR_MODE:
+		ret = sr_asr_set();
+		break;
+	default:
+		break;
+	}
+
+	if (ret != 0) {
+		ERROR("Unknown Self Refresh mode\n");
+		panic();
+	}
+
+	saved_ddr_sr_mode = mode;
+}
+
+void ddr_save_sr_mode(void)
+{
+	saved_ddr_sr_mode = ddr_read_sr_mode();
+}
+
+void ddr_restore_sr_mode(void)
+{
+	ddr_set_sr_mode(saved_ddr_sr_mode);
+}
+
+void ddr_sub_system_clk_init(void)
+{
+	mmio_write_32(stm32mp_rcc_base() + RCC_DDRCPCFGR,
+		      RCC_DDRCPCFGR_DDRCPEN | RCC_DDRCPCFGR_DDRCPLPEN);
+}
+
+void ddr_sub_system_clk_off(void)
+{
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	/* Clear DDR IO retention */
+	mmio_clrbits_32(stm32mp_pwr_base() + PWR_CR11, PWR_CR11_DDRRETDIS);
+
+	/* Reset DDR sub system */
+	mmio_write_32(rcc_base + RCC_DDRCPCFGR, RCC_DDRCPCFGR_DDRCPRST);
+	mmio_write_32(rcc_base + RCC_DDRITFCFGR, RCC_DDRITFCFGR_DDRRST);
+	mmio_write_32(rcc_base + RCC_DDRPHYCAPBCFGR, RCC_DDRPHYCAPBCFGR_DDRPHYCAPBRST);
+	mmio_write_32(rcc_base + RCC_DDRCAPBCFGR, RCC_DDRCAPBCFGR_DDRCAPBRST);
+
+	/* Deactivate clocks and PLL2 */
+	mmio_clrbits_32(rcc_base + RCC_DDRPHYCCFGR, RCC_DDRPHYCCFGR_DDRPHYCEN);
+	mmio_clrbits_32(rcc_base + RCC_PLL2CFGR1, RCC_PLL2CFGR1_PLLEN);
+}
diff --git a/drivers/st/ddr/stm32mp2_ram.c b/drivers/st/ddr/stm32mp2_ram.c
new file mode 100644
index 00000000..95f05e7b
--- /dev/null
+++ b/drivers/st/ddr/stm32mp2_ram.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <drivers/clk.h>
+#include <drivers/st/stm32mp2_ddr.h>
+#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp2_ram.h>
+#include <drivers/st/stm32mp_ddr.h>
+#include <drivers/st/stm32mp_ddr_test.h>
+#include <drivers/st/stm32mp_ram.h>
+
+#include <lib/mmio.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+static struct stm32mp_ddr_priv ddr_priv_data;
+static bool ddr_self_refresh;
+
+static int ddr_dt_get_ui_param(void *fdt, int node, struct stm32mp_ddr_config *config)
+{
+	int ret;
+	uint32_t size;
+
+	size = sizeof(struct user_input_basic) / sizeof(int);
+	ret = fdt_read_uint32_array(fdt, node, "st,phy-basic", size, (uint32_t *)&config->uib);
+
+	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-basic", size, ret);
+	if (ret != 0) {
+		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-basic", ret);
+		return -EINVAL;
+	}
+
+	size = sizeof(struct user_input_advanced) / sizeof(int);
+	ret = fdt_read_uint32_array(fdt, node, "st,phy-advanced", size, (uint32_t *)&config->uia);
+
+	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-advanced", size, ret);
+	if (ret != 0) {
+		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-advanced", ret);
+		return -EINVAL;
+	}
+
+	size = sizeof(struct user_input_mode_register) / sizeof(int);
+	ret = fdt_read_uint32_array(fdt, node, "st,phy-mr", size, (uint32_t *)&config->uim);
+
+	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-mr", size, ret);
+	if (ret != 0) {
+		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-mr", ret);
+		return -EINVAL;
+	}
+
+	size = sizeof(struct user_input_swizzle) / sizeof(int);
+	ret = fdt_read_uint32_array(fdt, node, "st,phy-swizzle", size, (uint32_t *)&config->uis);
+
+	VERBOSE("%s: %s[0x%x] = %d\n", __func__, "st,phy-swizzle", size, ret);
+	if (ret != 0) {
+		ERROR("%s: can't read %s, error=%d\n", __func__, "st,phy-swizzle", ret);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int stm32mp2_ddr_setup(void)
+{
+	struct stm32mp_ddr_priv *priv = &ddr_priv_data;
+	int ret;
+	struct stm32mp_ddr_config config;
+	int node;
+	uintptr_t uret;
+	void *fdt;
+
+	const struct stm32mp_ddr_param param[] = {
+		CTL_PARAM(reg),
+		CTL_PARAM(timing),
+		CTL_PARAM(map),
+		CTL_PARAM(perf)
+	};
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
+	if (node < 0) {
+		ERROR("%s: can't read DDR node in DT\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = stm32mp_ddr_dt_get_info(fdt, node, &config.info);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = stm32mp_ddr_dt_get_param(fdt, node, param, ARRAY_SIZE(param), (uintptr_t)&config);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = ddr_dt_get_ui_param(fdt, node, &config);
+	if (ret < 0) {
+		return ret;
+	}
+
+	config.self_refresh = false;
+
+	if (stm32mp_is_wakeup_from_standby()) {
+		config.self_refresh = true;
+	}
+
+	/*  Map dynamically RETRAM area to save or restore PHY retention registers */
+	if (stm32mp_map_retram() != 0) {
+		panic();
+	}
+
+	stm32mp2_ddr_init(priv, &config);
+
+	/*  Unmap RETRAM, no more used until next DDR initialization call */
+	if (stm32mp_unmap_retram() != 0) {
+		panic();
+	}
+
+	priv->info.size = config.info.size;
+
+	VERBOSE("%s : ram size(%lx, %lx)\n", __func__, priv->info.base, priv->info.size);
+
+	if (stm32mp_map_ddr_non_cacheable() != 0) {
+		panic();
+	}
+
+	if (config.self_refresh) {
+		uret = stm32mp_ddr_test_rw_access();
+		if (uret != 0UL) {
+			ERROR("DDR rw test: can't access memory @ 0x%lx\n", uret);
+			panic();
+		}
+
+		/* TODO Restore area overwritten by training */
+		//stm32_restore_ddr_training_area();
+	} else {
+		size_t retsize;
+
+		uret = stm32mp_ddr_test_data_bus();
+		if (uret != 0UL) {
+			ERROR("DDR data bus test: can't access memory @ 0x%lx\n", uret);
+			panic();
+		}
+
+		uret = stm32mp_ddr_test_addr_bus(config.info.size);
+		if (uret != 0UL) {
+			ERROR("DDR addr bus test: can't access memory @ 0x%lx\n", uret);
+			panic();
+		}
+
+		retsize = stm32mp_ddr_check_size();
+		if (retsize < config.info.size) {
+			ERROR("DDR size: 0x%zx does not match DT config: 0x%zx\n",
+			      retsize, config.info.size);
+			panic();
+		}
+
+		INFO("Memory size = 0x%zx (%zu MB)\n", retsize, retsize / (1024U * 1024U));
+	}
+
+	/*
+	 * Initialization sequence has configured DDR registers with settings.
+	 * The Self Refresh (SR) mode corresponding to these settings has now
+	 * to be set.
+	 */
+	ddr_set_sr_mode(ddr_read_sr_mode());
+
+	if (stm32mp_unmap_ddr() != 0) {
+		panic();
+	}
+
+	/* Save DDR self_refresh state */
+	ddr_self_refresh = config.self_refresh;
+
+	return 0;
+}
+
+bool stm32mp2_ddr_is_restored(void)
+{
+	return ddr_self_refresh;
+}
+
+int stm32mp2_ddr_probe(void)
+{
+	struct stm32mp_ddr_priv *priv = &ddr_priv_data;
+
+	VERBOSE("STM32MP DDR probe\n");
+
+	priv->ctl = (struct stm32mp_ddrctl *)stm32mp_ddrctrl_base();
+	priv->phy = (struct stm32mp_ddrphy *)stm32mp_ddrphyc_base();
+	priv->pwr = stm32mp_pwr_base();
+	priv->rcc = stm32mp_rcc_base();
+
+	priv->info.base = STM32MP_DDR_BASE;
+	priv->info.size = 0;
+
+	return stm32mp2_ddr_setup();
+}
diff --git a/drivers/st/ddr/stm32mp_ddr.c b/drivers/st/ddr/stm32mp_ddr.c
index 6776e3ba..98968d57 100644
--- a/drivers/st/ddr/stm32mp_ddr.c
+++ b/drivers/st/ddr/stm32mp_ddr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,13 +8,15 @@
 #include <drivers/delay_timer.h>
 #include <drivers/st/stm32mp_ddr.h>
 #include <drivers/st/stm32mp_ddrctrl_regs.h>
-#include <drivers/st/stm32mp_pmic.h>
 #include <lib/mmio.h>
 
 #include <platform_def.h>
 
 #define INVALID_OFFSET	0xFFU
 
+static bool axi_port_reenable_request;
+static bool host_interface_reenable_request;
+
 static uintptr_t get_base_addr(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_base_type base)
 {
 	if (base == DDRPHY_BASE) {
@@ -38,12 +40,23 @@ void stm32mp_ddr_set_reg(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_r
 		uintptr_t ptr = base_addr + desc[i].offset;
 
 		if (desc[i].par_offset == INVALID_OFFSET) {
-			ERROR("invalid parameter offset for %s", desc[i].name);
+			ERROR("invalid parameter offset for %s - index %u",
+			      ddr_registers[type].name, i);
 			panic();
 		} else {
+#if !STM32MP13 && !STM32MP15
+			if (desc[i].qd) {
+				stm32mp_ddr_start_sw_done(priv->ctl);
+			}
+#endif
 			value = *((uint32_t *)((uintptr_t)param +
 					       desc[i].par_offset));
 			mmio_write_32(ptr, value);
+#if !STM32MP13 && !STM32MP15
+			if (desc[i].qd) {
+				stm32mp_ddr_wait_sw_done_ack(priv->ctl);
+			}
+#endif
 		}
 	}
 }
@@ -66,7 +79,7 @@ void stm32mp_ddr_wait_sw_done_ack(struct stm32mp_ddrctl *ctl)
 	VERBOSE("[0x%lx] swctl = 0x%x\n",
 		(uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl));
 
-	timeout = timeout_init_us(TIMEOUT_US_1S);
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
 	do {
 		swstat = mmio_read_32((uintptr_t)&ctl->swstat);
 		VERBOSE("[0x%lx] swstat = 0x%x ",
@@ -93,14 +106,194 @@ void stm32mp_ddr_enable_axi_port(struct stm32mp_ddrctl *ctl)
 	VERBOSE("[0x%lx] pctrl_1 = 0x%x\n", (uintptr_t)&ctl->pctrl_1,
 		mmio_read_32((uintptr_t)&ctl->pctrl_1));
 #endif
+}
+
+int stm32mp_ddr_disable_axi_port(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t pstat;
+
+	/* Disable uMCTL2 AXI port 0 */
+	mmio_clrbits_32((uintptr_t)&ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
+	VERBOSE("[0x%lx] pctrl_0 = 0x%x\n", (uintptr_t)&ctl->pctrl_0,
+		mmio_read_32((uintptr_t)&ctl->pctrl_0));
+
+#if STM32MP_DDR_DUAL_AXI_PORT
+	/* Disable uMCTL2 AXI port 1 */
+	mmio_clrbits_32((uintptr_t)&ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
+	VERBOSE("[0x%lx] pctrl_1 = 0x%x\n", (uintptr_t)&ctl->pctrl_1,
+		mmio_read_32((uintptr_t)&ctl->pctrl_1));
+#endif
+
+	/*
+	 * Waits until all AXI ports are idle
+	 * Poll PSTAT.rd_port_busy_n = 0
+	 * Poll PSTAT.wr_port_busy_n = 0
+	 */
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		pstat = mmio_read_32((uintptr_t)&ctl->pstat);
+		VERBOSE("[0x%lx] pstat = 0x%x ",
+			(uintptr_t)&ctl->pstat, pstat);
+		if (timeout_elapsed(timeout)) {
+			return -1;
+		}
+	} while (pstat != 0U);
+
+	return 0;
+}
+
+static bool ddr_is_axi_port_enabled(struct stm32mp_ddrctl *ctl)
+{
+	return (mmio_read_32((uintptr_t)&ctl->pctrl_0) & DDRCTRL_PCTRL_N_PORT_EN) != 0U;
+}
+
+void stm32mp_ddr_enable_host_interface(struct stm32mp_ddrctl *ctl)
+{
+	mmio_clrbits_32((uintptr_t)&ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+	VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+		(uintptr_t)&ctl->dbg1,
+		mmio_read_32((uintptr_t)&ctl->dbg1));
+}
+
+void stm32mp_ddr_disable_host_interface(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t dbgcam;
+	int count = 0;
+
+	mmio_setbits_32((uintptr_t)&ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+	VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+		(uintptr_t)&ctl->dbg1,
+		mmio_read_32((uintptr_t)&ctl->dbg1));
+
+	/*
+	 * Waits until all queues and pipelines are empty
+	 * Poll DBGCAM.dbg_wr_q_empty = 1
+	 * Poll DBGCAM.dbg_rd_q_empty = 1
+	 * Poll DBGCAM.dbg_wr_data_pipeline_empty = 1
+	 * Poll DBGCAM.dbg_rd_data_pipeline_empty = 1
+	 *
+	 * data_pipeline fields must be polled twice to ensure
+	 * value propoagation, so count is added to loop condition.
+	 */
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		dbgcam = mmio_read_32((uintptr_t)&ctl->dbgcam);
+		VERBOSE("[0x%lx] dbgcam = 0x%x ",
+			(uintptr_t)&ctl->dbgcam, dbgcam);
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+		count++;
+	} while (((dbgcam & DDRCTRL_DBG_Q_AND_DATA_PIPELINE_EMPTY) !=
+		  DDRCTRL_DBG_Q_AND_DATA_PIPELINE_EMPTY) || (count < 2));
+}
+
+static bool ddr_is_host_interface_enabled(struct stm32mp_ddrctl *ctl)
+{
+	return (mmio_read_32((uintptr_t)&ctl->dbg1) & DDRCTRL_DBG1_DIS_HIF) == 0U;
+}
+
+int stm32mp_ddr_sw_selfref_entry(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t stat;
+	uint32_t operating_mode;
+	uint32_t selref_type;
+
+	mmio_setbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_SW);
+	VERBOSE("[0x%lx] pwrctl = 0x%x\n",
+		(uintptr_t)&ctl->pwrctl,
+		mmio_read_32((uintptr_t)&ctl->pwrctl));
+
+	/*
+	 * Wait operating mode change in self-refresh mode
+	 * with STAT.operating_mode[1:0]==11.
+	 * Ensure transition to self-refresh was due to software
+	 * by checking also that STAT.selfref_type[1:0]=2.
+	 */
+	timeout = timeout_init_us(DDR_TIMEOUT_500US);
+	while (!timeout_elapsed(timeout)) {
+		stat = mmio_read_32((uintptr_t)&ctl->stat);
+		operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK;
+		selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK;
+
+		if ((operating_mode == DDRCTRL_STAT_OPERATING_MODE_SR) &&
+		    (selref_type == DDRCTRL_STAT_SELFREF_TYPE_SR)) {
+			return 0;
+		}
+	}
 
+	return -1;
 }
 
-int stm32mp_board_ddr_power_init(enum ddr_type ddr_type)
+void stm32mp_ddr_sw_selfref_exit(struct stm32mp_ddrctl *ctl)
 {
-	if (dt_pmic_status() > 0) {
-		return pmic_ddr_power_init(ddr_type);
+	mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_SW);
+	VERBOSE("[0x%lx] pwrctl = 0x%x\n",
+		(uintptr_t)&ctl->pwrctl,
+		mmio_read_32((uintptr_t)&ctl->pwrctl));
+}
+
+void stm32mp_ddr_set_qd3_update_conditions(struct stm32mp_ddrctl *ctl)
+{
+	if (ddr_is_axi_port_enabled(ctl)) {
+		if (stm32mp_ddr_disable_axi_port(ctl) != 0) {
+			panic();
+		}
+		axi_port_reenable_request = true;
 	}
 
-	return 0;
+	if (ddr_is_host_interface_enabled(ctl)) {
+		stm32mp_ddr_disable_host_interface(ctl);
+		host_interface_reenable_request = true;
+	}
+
+	stm32mp_ddr_start_sw_done(ctl);
+}
+
+void stm32mp_ddr_unset_qd3_update_conditions(struct stm32mp_ddrctl *ctl)
+{
+	stm32mp_ddr_wait_sw_done_ack(ctl);
+
+	if (host_interface_reenable_request) {
+		stm32mp_ddr_enable_host_interface(ctl);
+		host_interface_reenable_request = false;
+	}
+
+	if (axi_port_reenable_request) {
+		stm32mp_ddr_enable_axi_port(ctl);
+		axi_port_reenable_request = false;
+	}
+}
+
+void stm32mp_ddr_wait_refresh_update_done_ack(struct stm32mp_ddrctl *ctl)
+{
+	uint64_t timeout;
+	uint32_t rfshctl3;
+	uint32_t refresh_update_level = DDRCTRL_RFSHCTL3_REFRESH_UPDATE_LEVEL;
+
+	/* Toggle rfshctl3.refresh_update_level */
+	rfshctl3 = mmio_read_32((uintptr_t)&ctl->rfshctl3);
+	if ((rfshctl3 & refresh_update_level) == refresh_update_level) {
+		mmio_setbits_32((uintptr_t)&ctl->rfshctl3, refresh_update_level);
+	} else {
+		mmio_clrbits_32((uintptr_t)&ctl->rfshctl3, refresh_update_level);
+		refresh_update_level = 0U;
+	}
+
+	VERBOSE("[0x%lx] rfshctl3 = 0x%x\n",
+		(uintptr_t)&ctl->rfshctl3, mmio_read_32((uintptr_t)&ctl->rfshctl3));
+
+	timeout = timeout_init_us(DDR_TIMEOUT_US_1S);
+	do {
+		rfshctl3 = mmio_read_32((uintptr_t)&ctl->rfshctl3);
+		VERBOSE("[0x%lx] rfshctl3 = 0x%x ", (uintptr_t)&ctl->rfshctl3, rfshctl3);
+		if (timeout_elapsed(timeout)) {
+			panic();
+		}
+	} while ((rfshctl3 & DDRCTRL_RFSHCTL3_REFRESH_UPDATE_LEVEL) != refresh_update_level);
+
+	VERBOSE("[0x%lx] rfshctl3 = 0x%x\n", (uintptr_t)&ctl->rfshctl3, rfshctl3);
 }
diff --git a/drivers/st/ddr/stm32mp_ddr_test.c b/drivers/st/ddr/stm32mp_ddr_test.c
index 0f6aff1d..707a6ff0 100644
--- a/drivers/st/ddr/stm32mp_ddr_test.c
+++ b/drivers/st/ddr/stm32mp_ddr_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,8 +10,31 @@
 
 #include <platform_def.h>
 
+#ifdef __aarch64__
+#define DDR_PATTERN	0xAAAAAAAAAAAAAAAAUL
+#define DDR_ANTIPATTERN	0x5555555555555555UL
+#else /* !__aarch64__ */
 #define DDR_PATTERN	0xAAAAAAAAU
 #define DDR_ANTIPATTERN	0x55555555U
+#endif /* __aarch64__ */
+
+static void mmio_write_pattern(uintptr_t addr, u_register_t value)
+{
+#ifdef __aarch64__
+	mmio_write_64(addr, (uint64_t)value);
+#else /* !__aarch64__ */
+	mmio_write_32(addr, (uint32_t)value);
+#endif /* __aarch64__ */
+}
+
+static u_register_t mmio_read_pattern(uintptr_t addr)
+{
+#ifdef __aarch64__
+	return (u_register_t)mmio_read_64(addr);
+#else /* !__aarch64__ */
+	return (u_register_t)mmio_read_32(addr);
+#endif /* __aarch64__ */
+}
 
 /*******************************************************************************
  * This function tests a simple read/write access to the DDR.
@@ -20,15 +43,15 @@
  ******************************************************************************/
 uintptr_t stm32mp_ddr_test_rw_access(void)
 {
-	uint32_t saved_value = mmio_read_32(STM32MP_DDR_BASE);
+	u_register_t saved_value = mmio_read_pattern(STM32MP_DDR_BASE);
 
-	mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN);
+	mmio_write_pattern(STM32MP_DDR_BASE, DDR_PATTERN);
 
-	if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) {
+	if (mmio_read_pattern(STM32MP_DDR_BASE) != DDR_PATTERN) {
 		return STM32MP_DDR_BASE;
 	}
 
-	mmio_write_32(STM32MP_DDR_BASE, saved_value);
+	mmio_write_pattern(STM32MP_DDR_BASE, saved_value);
 
 	return 0UL;
 }
@@ -43,12 +66,12 @@ uintptr_t stm32mp_ddr_test_rw_access(void)
  ******************************************************************************/
 uintptr_t stm32mp_ddr_test_data_bus(void)
 {
-	uint32_t pattern;
+	u_register_t pattern;
 
 	for (pattern = 1U; pattern != 0U; pattern <<= 1U) {
-		mmio_write_32(STM32MP_DDR_BASE, pattern);
+		mmio_write_pattern(STM32MP_DDR_BASE, pattern);
 
-		if (mmio_read_32(STM32MP_DDR_BASE) != pattern) {
+		if (mmio_read_pattern(STM32MP_DDR_BASE) != pattern) {
 			return STM32MP_DDR_BASE;
 		}
 	}
@@ -72,41 +95,41 @@ uintptr_t stm32mp_ddr_test_addr_bus(size_t size)
 	size_t testoffset = 0U;
 
 	/* Write the default pattern at each of the power-of-two offsets. */
-	for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+	for (offset = sizeof(u_register_t); (offset & addressmask) != 0U;
 	     offset <<= 1U) {
-		mmio_write_32(STM32MP_DDR_BASE + offset, DDR_PATTERN);
+		mmio_write_pattern(STM32MP_DDR_BASE + offset, DDR_PATTERN);
 	}
 
 	/* Check for address bits stuck high. */
-	mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
+	mmio_write_pattern(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
 
-	for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+	for (offset = sizeof(u_register_t); (offset & addressmask) != 0U;
 	     offset <<= 1U) {
-		if (mmio_read_32(STM32MP_DDR_BASE + offset) != DDR_PATTERN) {
+		if (mmio_read_pattern(STM32MP_DDR_BASE + offset) != DDR_PATTERN) {
 			return STM32MP_DDR_BASE + offset;
 		}
 	}
 
-	mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
+	mmio_write_pattern(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
 
 	/* Check for address bits stuck low or shorted. */
-	for (testoffset = sizeof(uint32_t); (testoffset & addressmask) != 0U;
+	for (testoffset = sizeof(u_register_t); (testoffset & addressmask) != 0U;
 	     testoffset <<= 1U) {
-		mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
+		mmio_write_pattern(STM32MP_DDR_BASE + testoffset, DDR_ANTIPATTERN);
 
-		if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) {
+		if (mmio_read_pattern(STM32MP_DDR_BASE) != DDR_PATTERN) {
 			return STM32MP_DDR_BASE;
 		}
 
-		for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
-		     offset <<= 1) {
-			if ((mmio_read_32(STM32MP_DDR_BASE + offset) != DDR_PATTERN) &&
+		for (offset = sizeof(u_register_t); (offset & addressmask) != 0U;
+		     offset <<= 1U) {
+			if ((mmio_read_pattern(STM32MP_DDR_BASE + offset) != DDR_PATTERN) &&
 			    (offset != testoffset)) {
 				return STM32MP_DDR_BASE + offset;
 			}
 		}
 
-		mmio_write_32(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
+		mmio_write_pattern(STM32MP_DDR_BASE + testoffset, DDR_PATTERN);
 	}
 
 	return 0UL;
@@ -121,15 +144,15 @@ uintptr_t stm32mp_ddr_test_addr_bus(size_t size)
  ******************************************************************************/
 size_t stm32mp_ddr_check_size(void)
 {
-	size_t offset = sizeof(uint32_t);
+	size_t offset = sizeof(u_register_t);
 
-	mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN);
+	mmio_write_pattern(STM32MP_DDR_BASE, DDR_PATTERN);
 
 	while (offset < STM32MP_DDR_MAX_SIZE) {
-		mmio_write_32(STM32MP_DDR_BASE + offset, DDR_ANTIPATTERN);
+		mmio_write_pattern(STM32MP_DDR_BASE + offset, DDR_ANTIPATTERN);
 		dsb();
 
-		if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) {
+		if (mmio_read_pattern(STM32MP_DDR_BASE) != DDR_PATTERN) {
 			break;
 		}
 
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
index a4a64ca7..44d7c095 100644
--- a/drivers/st/gpio/stm32_gpio.c
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -282,6 +282,7 @@ static void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t type,
 
 	clk_disable(clock);
 
+#if STM32MP13 || STM32MP15
 	if (status == DT_SECURE) {
 		stm32mp_register_secure_gpio(bank, pin);
 #if !IMAGE_BL2
@@ -294,6 +295,9 @@ static void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t type,
 		set_gpio_secure_cfg(bank, pin, false);
 #endif
 	}
+#else /* !STM32MP13 && !STM32MP15 */
+	set_gpio_secure_cfg(bank, pin, true);
+#endif /* STM32MP13 || STM32MP15 */
 }
 
 void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
@@ -321,3 +325,74 @@ void set_gpio_reset_cfg(uint32_t bank, uint32_t pin)
 		 GPIO_ALTERNATE_(0), DT_DISABLED);
 	set_gpio_secure_cfg(bank, pin, stm32_gpio_is_secure_at_reset(bank));
 }
+
+void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level)
+{
+	uintptr_t base = stm32_get_gpio_bank_base(bank);
+	unsigned long clock = stm32_get_gpio_bank_clock(bank);
+
+	assert(pin <= GPIO_PIN_MAX);
+
+	clk_enable(clock);
+
+	if (level == GPIO_LEVEL_HIGH) {
+		mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin));
+	} else {
+		mmio_write_32(base + GPIO_BSRR_OFFSET, BIT(pin + 16U));
+	}
+
+	VERBOSE("GPIO %u level set to 0x%x\n", bank,
+		mmio_read_32(base + GPIO_IDR_OFFSET));
+
+	clk_disable(clock);
+}
+
+enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin)
+{
+	uintptr_t base = stm32_get_gpio_bank_base(bank);
+	unsigned long clock = stm32_get_gpio_bank_clock(bank);
+	enum gpio_level level = GPIO_LEVEL_LOW;
+
+	assert(pin <= GPIO_PIN_MAX);
+
+	clk_enable(clock);
+
+	if (mmio_read_32(base + GPIO_IDR_OFFSET) & BIT(pin)) {
+		level = GPIO_LEVEL_HIGH;
+	}
+
+	VERBOSE("GPIO %u get level 0x%x\n", bank,
+		mmio_read_32(base + GPIO_IDR_OFFSET));
+
+	clk_disable(clock);
+
+	return level;
+}
+
+void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status)
+{
+	uint32_t mode = GPIO_MODE_OUTPUT;
+	uint32_t od = 0U;
+	uint32_t pull = GPIO_NO_PULL;
+
+	VERBOSE("GPIO %u:%u set config to 0x%x\n", bank, pin, config);
+
+	if (config & GPIOF_DIR_IN) {
+		mode = GPIO_MODE_INPUT;
+	}
+
+	if (config & GPIOF_OUT_INIT_HIGH) {
+		od = 1U;
+	}
+
+	if (config & GPIOF_PULL_UP) {
+		pull |= GPIO_PULL_UP;
+	}
+
+	if (config & GPIOF_PULL_DOWN) {
+		pull |= GPIO_PULL_DOWN;
+	}
+
+	set_gpio(bank, pin, mode, GPIO_TYPE_PUSH_PULL, GPIO_SPEED_LOW,
+		 pull, od, GPIO_ALTERNATE_(0), status);
+}
diff --git a/drivers/st/i2c/stm32_i2c.c b/drivers/st/i2c/stm32_i2c.c
index bf6c3eee..32cecff6 100644
--- a/drivers/st/i2c/stm32_i2c.c
+++ b/drivers/st/i2c/stm32_i2c.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,17 +8,17 @@
 #include <stdbool.h>
 #include <stdlib.h>
 
-#include <libfdt.h>
-
-#include <platform_def.h>
-
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/clk.h>
 #include <drivers/delay_timer.h>
 #include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32_i2c.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
 
 /* STM32 I2C registers offsets */
 #define I2C_CR1			0x00U
@@ -97,40 +97,29 @@ static int i2c_config_analog_filter(struct i2c_handle_s *hi2c,
 int stm32_i2c_get_setup_from_fdt(void *fdt, int node,
 				 struct stm32_i2c_init_s *init)
 {
-	const fdt32_t *cuint;
-
-	cuint = fdt_getprop(fdt, node, "i2c-scl-rising-time-ns", NULL);
-	if (cuint == NULL) {
-		init->rise_time = STM32_I2C_RISE_TIME_DEFAULT;
-	} else {
-		init->rise_time = fdt32_to_cpu(*cuint);
-	}
-
-	cuint = fdt_getprop(fdt, node, "i2c-scl-falling-time-ns", NULL);
-	if (cuint == NULL) {
-		init->fall_time = STM32_I2C_FALL_TIME_DEFAULT;
-	} else {
-		init->fall_time = fdt32_to_cpu(*cuint);
-	}
-
-	cuint = fdt_getprop(fdt, node, "clock-frequency", NULL);
-	if (cuint == NULL) {
-		init->speed_mode = STM32_I2C_SPEED_DEFAULT;
-	} else {
-		switch (fdt32_to_cpu(*cuint)) {
-		case STANDARD_RATE:
-			init->speed_mode = I2C_SPEED_STANDARD;
-			break;
-		case FAST_RATE:
-			init->speed_mode = I2C_SPEED_FAST;
-			break;
-		case FAST_PLUS_RATE:
-			init->speed_mode = I2C_SPEED_FAST_PLUS;
-			break;
-		default:
-			init->speed_mode = STM32_I2C_SPEED_DEFAULT;
-			break;
-		}
+	uint32_t read_val;
+
+	init->rise_time = fdt_read_uint32_default(fdt, node,
+						  "i2c-scl-rising-time-ns",
+						  STM32_I2C_RISE_TIME_DEFAULT);
+
+	init->fall_time = fdt_read_uint32_default(fdt, node,
+						  "i2c-scl-falling-time-ns",
+						  STM32_I2C_FALL_TIME_DEFAULT);
+
+	read_val = fdt_read_uint32_default(fdt, node, "clock-frequency",
+					   STANDARD_RATE);
+	switch (read_val) {
+	case FAST_PLUS_RATE:
+		init->speed_mode = I2C_SPEED_FAST_PLUS;
+		break;
+	case FAST_RATE:
+		init->speed_mode = I2C_SPEED_FAST;
+		break;
+	case STANDARD_RATE:
+	default:
+		init->speed_mode = I2C_SPEED_STANDARD;
+		break;
 	}
 
 	return dt_set_pinctrl_config(node);
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index be722f32..66988d71 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -129,7 +129,11 @@
 #define DT_SDMMC2_COMPAT		"st,stm32-sdmmc2"
 #endif
 
+#if STM32MP13 || STM32MP15
 #define SDMMC_FIFO_SIZE			64U
+#else
+#define SDMMC_FIFO_SIZE			1024U
+#endif
 
 #define STM32MP_MMC_INIT_FREQ			U(400000)	/*400 KHz*/
 #define STM32MP_SD_NORMAL_SPEED_MAX_FREQ	U(25000000)	/*25 MHz*/
diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
index 1e162877..58f97b3e 100644
--- a/drivers/st/pmic/stm32mp_pmic.c
+++ b/drivers/st/pmic/stm32mp_pmic.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -216,120 +216,6 @@ void print_pmic_info_and_debug(void)
 }
 #endif
 
-int pmic_ddr_power_init(enum ddr_type ddr_type)
-{
-	int status;
-	uint16_t buck3_min_mv;
-	struct rdev *buck2, *buck3, *vref;
-	struct rdev *ldo3 __unused;
-
-	buck2 = regulator_get_by_name("buck2");
-	if (buck2 == NULL) {
-		return -ENOENT;
-	}
-
-#if STM32MP15
-	ldo3 = regulator_get_by_name("ldo3");
-	if (ldo3 == NULL) {
-		return -ENOENT;
-	}
-#endif
-
-	vref = regulator_get_by_name("vref_ddr");
-	if (vref == NULL) {
-		return -ENOENT;
-	}
-
-	switch (ddr_type) {
-	case STM32MP_DDR3:
-#if STM32MP15
-		status = regulator_set_flag(ldo3, REGUL_SINK_SOURCE);
-		if (status != 0) {
-			return status;
-		}
-#endif
-
-		status = regulator_set_min_voltage(buck2);
-		if (status != 0) {
-			return status;
-		}
-
-		status = regulator_enable(buck2);
-		if (status != 0) {
-			return status;
-		}
-
-		status = regulator_enable(vref);
-		if (status != 0) {
-			return status;
-		}
-
-#if STM32MP15
-		status = regulator_enable(ldo3);
-		if (status != 0) {
-			return status;
-		}
-#endif
-		break;
-
-	case STM32MP_LPDDR2:
-	case STM32MP_LPDDR3:
-		/*
-		 * Set LDO3 to 1.8V
-		 * Set LDO3 to bypass mode if BUCK3 = 1.8V
-		 * Set LDO3 to normal mode if BUCK3 != 1.8V
-		 */
-		buck3 = regulator_get_by_name("buck3");
-		if (buck3 == NULL) {
-			return -ENOENT;
-		}
-
-		regulator_get_range(buck3, &buck3_min_mv, NULL);
-
-#if STM32MP15
-		if (buck3_min_mv != 1800) {
-			status = regulator_set_min_voltage(ldo3);
-			if (status != 0) {
-				return status;
-			}
-		} else {
-			status = regulator_set_flag(ldo3, REGUL_ENABLE_BYPASS);
-			if (status != 0) {
-				return status;
-			}
-		}
-#endif
-
-		status = regulator_set_min_voltage(buck2);
-		if (status != 0) {
-			return status;
-		}
-
-#if STM32MP15
-		status = regulator_enable(ldo3);
-		if (status != 0) {
-			return status;
-		}
-#endif
-
-		status = regulator_enable(buck2);
-		if (status != 0) {
-			return status;
-		}
-
-		status = regulator_enable(vref);
-		if (status != 0) {
-			return status;
-		}
-		break;
-
-	default:
-		break;
-	};
-
-	return 0;
-}
-
 int pmic_voltages_init(void)
 {
 #if STM32MP13
diff --git a/drivers/st/pmic/stm32mp_pmic2.c b/drivers/st/pmic/stm32mp_pmic2.c
new file mode 100644
index 00000000..c19d36a4
--- /dev/null
+++ b/drivers/st/pmic/stm32mp_pmic2.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/regulator.h>
+#include <drivers/st/stm32_i2c.h>
+#include <drivers/st/stm32mp_pmic2.h>
+#include <drivers/st/stpmic2.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#define PMIC_NODE_NOT_FOUND	1
+
+struct regul_handle_s {
+	const uint32_t id;
+	uint16_t bypass_mv;
+};
+
+static struct pmic_handle_s pmic2_handle;
+static struct i2c_handle_s i2c_handle;
+
+/* This driver is monoinstance */
+static struct pmic_handle_s *pmic2;
+
+static int dt_get_pmic_node(void *fdt)
+{
+	static int node = -FDT_ERR_BADOFFSET;
+
+	if (node == -FDT_ERR_BADOFFSET) {
+		node = fdt_node_offset_by_compatible(fdt, -1, "st,stpmic2");
+	}
+
+	return node;
+}
+
+int dt_pmic_status(void)
+{
+	static int status = -FDT_ERR_BADVALUE;
+	int node;
+	void *fdt;
+
+	if (status != -FDT_ERR_BADVALUE) {
+		return status;
+	}
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	node = dt_get_pmic_node(fdt);
+	if (node <= 0) {
+		status = -FDT_ERR_NOTFOUND;
+
+		return status;
+	}
+
+	status = DT_SECURE;
+
+	return status;
+}
+
+/*
+ * Get PMIC and its I2C bus configuration from the device tree.
+ * Return 0 on success, negative on error, 1 if no PMIC node is defined.
+ */
+static int dt_pmic2_i2c_config(struct dt_node_info *i2c_info,
+			       struct stm32_i2c_init_s *init,
+			       uint32_t *i2c_addr)
+{
+	static int i2c_node = -FDT_ERR_NOTFOUND;
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if (i2c_node == -FDT_ERR_NOTFOUND) {
+		int pmic_node;
+		const fdt32_t *cuint;
+
+		pmic_node = dt_get_pmic_node(fdt);
+		if (pmic_node < 0) {
+			return PMIC_NODE_NOT_FOUND;
+		}
+
+		cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
+		if (cuint == NULL) {
+			return -FDT_ERR_NOTFOUND;
+		}
+
+		*i2c_addr = fdt32_to_cpu(*cuint) << 1;
+		if (*i2c_addr > UINT16_MAX) {
+			return -FDT_ERR_BADVALUE;
+		}
+
+		i2c_node = fdt_parent_offset(fdt, pmic_node);
+		if (i2c_node < 0) {
+			return -FDT_ERR_NOTFOUND;
+		}
+	}
+
+	dt_fill_device_info(i2c_info, i2c_node);
+	if (i2c_info->base == 0U) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	i2c_info->status = DT_SECURE;
+
+	return stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init);
+}
+
+bool initialize_pmic_i2c(void)
+{
+	int ret;
+	struct dt_node_info i2c_info;
+	struct i2c_handle_s *i2c = &i2c_handle;
+	uint32_t i2c_addr = 0U;
+	struct stm32_i2c_init_s i2c_init;
+
+	ret = dt_pmic2_i2c_config(&i2c_info, &i2c_init, &i2c_addr);
+	if (ret < 0) {
+		ERROR("I2C configuration failed %d\n", ret);
+		panic();
+	}
+
+	if (ret != 0) {
+		return false;
+	}
+
+	/* Initialize PMIC I2C */
+	i2c->i2c_base_addr		= i2c_info.base;
+	i2c->dt_status			= i2c_info.status;
+	i2c->clock			= i2c_info.clock;
+	i2c->i2c_state			= I2C_STATE_RESET;
+	i2c_init.own_address1		= i2c_addr;
+	i2c_init.addressing_mode	= I2C_ADDRESSINGMODE_7BIT;
+	i2c_init.dual_address_mode	= I2C_DUALADDRESS_DISABLE;
+	i2c_init.own_address2		= 0;
+	i2c_init.own_address2_masks	= I2C_OAR2_OA2NOMASK;
+	i2c_init.general_call_mode	= I2C_GENERALCALL_DISABLE;
+	i2c_init.no_stretch_mode	= I2C_NOSTRETCH_DISABLE;
+	i2c_init.analog_filter		= 1;
+	i2c_init.digital_filter_coef	= 0;
+
+	ret = stm32_i2c_init(i2c, &i2c_init);
+	if (ret != 0) {
+		ERROR("Cannot initialize I2C %x (%d)\n",
+		      i2c->i2c_base_addr, ret);
+		panic();
+	}
+
+	if (!stm32_i2c_is_device_ready(i2c, i2c_addr, 1,
+				       I2C_TIMEOUT_BUSY_MS)) {
+		ERROR("I2C device not ready\n");
+		panic();
+	}
+
+	pmic2 = &pmic2_handle;
+	pmic2->i2c_handle = &i2c_handle;
+	pmic2->i2c_addr = i2c_addr;
+
+	return true;
+}
+
+static int pmic2_set_state(const struct regul_description *desc, bool enable)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+
+	VERBOSE("%s: set state to %d\n", desc->node_name, enable);
+
+	return stpmic2_regulator_set_state(pmic2, regul->id, enable);
+}
+
+static int pmic2_get_state(const struct regul_description *desc)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+	bool enabled;
+
+	VERBOSE("%s: get state\n", desc->node_name);
+
+	if (stpmic2_regulator_get_state(pmic2, regul->id, &enabled) < 0) {
+		panic();
+	}
+
+	return enabled;
+}
+
+static int pmic2_get_voltage(const struct regul_description *desc)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+	uint16_t mv;
+
+	VERBOSE("%s: get volt\n", desc->node_name);
+
+	if (regul->bypass_mv != 0U) {
+		int ret;
+
+		/* If the regul is in bypass mode, return bypass value */
+		ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS);
+		if (ret < 0) {
+			return ret;
+		}
+
+		if (ret == 1) {
+			return regul->bypass_mv;
+		}
+	};
+
+	if (stpmic2_regulator_get_voltage(pmic2, regul->id, &mv) < 0) {
+		panic();
+	}
+
+	return mv;
+}
+
+static int pmic2_set_voltage(const struct regul_description *desc, uint16_t mv)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+
+	VERBOSE("%s: set volt\n", desc->node_name);
+
+	if (regul->bypass_mv != 0U) {
+		int ret;
+
+		/* If the regul is in bypass mode, authorize bypass mV */
+		ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS);
+		if (ret < 0) {
+			return ret;
+		}
+
+		if ((ret == 1) && (mv != regul->bypass_mv)) {
+			return -EPERM;
+		}
+	};
+
+	return stpmic2_regulator_set_voltage(pmic2, regul->id, mv);
+}
+
+static int pmic2_list_voltages(const struct regul_description *desc,
+			       const uint16_t **levels, size_t *count)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+
+	VERBOSE("%s: list volt\n", desc->node_name);
+
+	if (regul->bypass_mv != 0U) {
+		int ret;
+
+		ret = stpmic2_regulator_get_prop(pmic2, regul->id, STPMIC2_BYPASS);
+		if (ret < 0) {
+			return ret;
+		}
+
+		/* bypass is enabled, return a list with only bypass mV */
+		if (ret == 1) {
+			if (count != NULL) {
+				*count = 1U;
+			}
+			if (levels != NULL) {
+				*levels = &regul->bypass_mv;
+			}
+			return 0;
+		}
+	};
+
+	return stpmic2_regulator_levels_mv(pmic2, regul->id, levels, count);
+}
+
+static int pmic2_set_flag(const struct regul_description *desc, uint16_t flag)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+	uint32_t id = regul->id;
+	int ret = -EPERM;
+
+	VERBOSE("%s: set_flag 0x%x\n", desc->node_name, flag);
+
+	switch (flag) {
+	case REGUL_PULL_DOWN:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_PULL_DOWN, 1U);
+		break;
+	case REGUL_OCP:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_OCP, 1U);
+		break;
+	case REGUL_SINK_SOURCE:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_SINK_SOURCE, 1U);
+		break;
+	case REGUL_ENABLE_BYPASS:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_BYPASS, 1U);
+		break;
+	case REGUL_MASK_RESET:
+		ret = stpmic2_regulator_set_prop(pmic2, id, STPMIC2_MASK_RESET, 1U);
+		break;
+	default:
+		ERROR("Invalid flag %u", flag);
+		panic();
+	}
+
+	if (ret != 0) {
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+int stpmic2_set_prop(const struct regul_description *desc, uint16_t prop, uint32_t value)
+{
+	struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+	int ret;
+
+	VERBOSE("%s: set_prop 0x%x val=%u\n", desc->node_name, prop, value);
+
+	ret = stpmic2_regulator_set_prop(pmic2, regul->id, prop, value);
+	if (ret != 0)
+		return -EPERM;
+
+	return 0;
+}
+
+static struct regul_ops pmic2_ops = {
+	.set_state = pmic2_set_state,
+	.get_state = pmic2_get_state,
+	.set_voltage = pmic2_set_voltage,
+	.get_voltage = pmic2_get_voltage,
+	.list_voltages = pmic2_list_voltages,
+	.set_flag = pmic2_set_flag,
+};
+
+#define DEFINE_PMIC_REGUL_HANDLE(rid) \
+[(rid)] = { \
+	.id = (rid), \
+}
+
+static struct regul_handle_s pmic2_regul_handles[STPMIC2_NB_REG] = {
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK1),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK2),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK3),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK4),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK5),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK6),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_BUCK7),
+
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO1),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO2),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO3),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO4),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO5),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO6),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO7),
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_LDO8),
+
+	DEFINE_PMIC_REGUL_HANDLE(STPMIC2_REFDDR),
+};
+
+#define DEFINE_REGUL(rid, name) \
+[rid] = { \
+	.node_name = name, \
+	.ops = &pmic2_ops, \
+	.driver_data = &pmic2_regul_handles[rid], \
+}
+
+static const struct regul_description pmic2_descs[STPMIC2_NB_REG] = {
+	DEFINE_REGUL(STPMIC2_BUCK1, "buck1"),
+	DEFINE_REGUL(STPMIC2_BUCK2, "buck2"),
+	DEFINE_REGUL(STPMIC2_BUCK3, "buck3"),
+	DEFINE_REGUL(STPMIC2_BUCK4, "buck4"),
+	DEFINE_REGUL(STPMIC2_BUCK5, "buck5"),
+	DEFINE_REGUL(STPMIC2_BUCK6, "buck6"),
+	DEFINE_REGUL(STPMIC2_BUCK7, "buck7"),
+
+	DEFINE_REGUL(STPMIC2_LDO1, "ldo1"),
+	DEFINE_REGUL(STPMIC2_LDO2, "ldo2"),
+	DEFINE_REGUL(STPMIC2_LDO3, "ldo3"),
+	DEFINE_REGUL(STPMIC2_LDO4, "ldo4"),
+	DEFINE_REGUL(STPMIC2_LDO5, "ldo5"),
+	DEFINE_REGUL(STPMIC2_LDO6, "ldo6"),
+	DEFINE_REGUL(STPMIC2_LDO7, "ldo7"),
+	DEFINE_REGUL(STPMIC2_LDO8, "ldo8"),
+
+	DEFINE_REGUL(STPMIC2_REFDDR, "refddr"),
+};
+
+static int register_pmic2(void)
+{
+	void *fdt;
+	int pmic_node, regulators_node, subnode;
+
+	VERBOSE("Register pmic2\n");
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	pmic_node = dt_get_pmic_node(fdt);
+	if (pmic_node < 0) {
+		return pmic_node;
+	}
+
+	regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
+	if (regulators_node < 0) {
+		return -ENOENT;
+	}
+
+	fdt_for_each_subnode(subnode, fdt, regulators_node) {
+		const char *reg_name = fdt_get_name(fdt, subnode, NULL);
+		const struct regul_description *desc;
+		unsigned int i;
+		int ret;
+		const fdt32_t *cuint;
+
+		for (i = 0; i < STPMIC2_NB_REG; i++) {
+			desc = &pmic2_descs[i];
+			if (strcmp(desc->node_name, reg_name) == 0) {
+				break;
+			}
+		}
+		assert(i < STPMIC2_NB_REG);
+
+		ret = regulator_register(desc, subnode);
+		if (ret != 0) {
+			WARN("%s:%d failed to register %s\n", __func__,
+			     __LINE__, reg_name);
+			return ret;
+		}
+
+		cuint = fdt_getprop(fdt, subnode, "st,regulator-bypass-microvolt", NULL);
+		if (cuint != NULL) {
+			struct regul_handle_s *regul = (struct regul_handle_s *)desc->driver_data;
+
+			regul->bypass_mv = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
+			VERBOSE("%s: bypass voltage=%umV\n", desc->node_name,
+				regul->bypass_mv);
+		}
+
+		if (fdt_getprop(fdt, subnode, "st,mask-reset", NULL)  != NULL) {
+			VERBOSE("%s: set mask-reset\n", desc->node_name);
+			ret = pmic2_set_flag(desc, REGUL_MASK_RESET);
+			if (ret != 0) {
+				ERROR("set mask-reset failed\n");
+				return ret;
+			}
+		}
+
+		if (fdt_getprop(fdt, subnode, "st,regulator-sink-source", NULL) != NULL) {
+			VERBOSE("%s: set regulator-sink-source\n", desc->node_name);
+			ret = pmic2_set_flag(desc, REGUL_SINK_SOURCE);
+			if (ret != 0) {
+				ERROR("set regulator-sink-source failed\n");
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+void initialize_pmic(void)
+{
+	int ret;
+	uint8_t val;
+
+	ret = initialize_pmic_i2c();
+	if (!ret) {
+		VERBOSE("No PMIC2\n");
+		return;
+	}
+
+	if (stpmic2_get_version(pmic2, &val) != 0) {
+		ERROR("Failed to access PMIC\n");
+		panic();
+	}
+	INFO("PMIC2 version = 0x%02x\n", val);
+
+	if (stpmic2_get_product_id(pmic2, &val) != 0) {
+		ERROR("Failed to access PMIC\n");
+		panic();
+	}
+	INFO("PMIC2 product ID = 0x%02x\n", val);
+
+	ret = register_pmic2();
+	if (ret < 0) {
+		ERROR("Register pmic2 failed\n");
+		panic();
+	}
+
+#if EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE
+	stpmic2_dump_regulators(pmic2);
+#endif
+}
diff --git a/drivers/st/pmic/stpmic2.c b/drivers/st/pmic/stpmic2.c
new file mode 100644
index 00000000..05a80ecf
--- /dev/null
+++ b/drivers/st/pmic/stpmic2.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/st/stpmic2.h>
+
+#define RET_SUCCESS			0
+#define RET_ERROR_NOT_SUPPORTED		-1
+#define RET_ERROR_GENERIC		-2
+#define RET_ERROR_BAD_PARAMETERS	-3
+
+#define I2C_TIMEOUT_MS			25
+
+#define VOLTAGE_INDEX_INVALID		((size_t)~0U)
+
+struct regul_struct {
+	const char *name;
+	const uint16_t *volt_table;
+	uint8_t volt_table_size;
+	uint8_t volt_cr;
+	uint8_t volt_shift;
+	uint8_t en_cr;
+	uint8_t alt_en_cr;
+	uint8_t msrt_reg;
+	uint8_t msrt_mask;
+	uint8_t pd_reg;
+	uint8_t pd_val;
+	uint8_t ocp_reg;
+	uint8_t ocp_mask;
+};
+
+/* Voltage tables in mV */
+static const uint16_t buck1236_volt_table[] = {
+	500U, 510U, 520U, 530U, 540U, 550U, 560U, 570U, 580U, 590U,
+	600U, 610U, 620U, 630U, 640U, 650U, 660U, 670U, 680U, 690U,
+	700U, 710U, 720U, 730U, 740U, 750U, 760U, 770U, 780U, 790U,
+	800U, 810U, 820U, 830U, 840U, 850U, 860U, 870U, 880U, 890U,
+	900U, 910U, 920U, 930U, 940U, 950U, 960U, 970U, 980U, 990U,
+	1000U, 1010U, 1020U, 1030U, 1040U, 1050U, 1060U, 1070U, 1080U, 1090U,
+	1100U, 1110U, 1120U, 1130U, 1140U, 1150U, 1160U, 1170U, 1180U, 1190U,
+	1200U, 1210U, 1220U, 1230U, 1240U, 1250U, 1260U, 1270U, 1280U, 1290U,
+	1300U, 1310U, 1320U, 1330U, 1340U, 1350U, 1360U, 1370U, 1380U, 1390U,
+	1400U, 1410U, 1420U, 1430U, 1440U, 1450U, 1460U, 1470U, 1480U, 1490U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U
+};
+
+static const uint16_t buck457_volt_table[] = {
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U, 1500U,
+	1500U, 1600U, 1700U, 1800U, 1900U, 2000U, 2100U, 2200U, 2300U, 2400U,
+	2500U, 2600U, 2700U, 2800U, 2900U, 3000U, 3100U, 3200U, 3300U, 3400U,
+	3500U, 3600U, 3700U, 3800U, 3900U, 4000U, 4100U, 4200U
+};
+
+static const uint16_t ldo235678_volt_table[] = {
+	900U, 1000U, 1100U, 1200U, 1300U, 1400U, 1500U, 1600U, 1700U, 1800U,
+	1900U, 2000U, 2100U, 2200U, 2300U, 2400U, 2500U, 2600U, 2700U, 2800U,
+	2900U, 3000U, 3100U, 3200U, 3300U, 3400U, 3500U, 3600U, 3700U, 3800U,
+	3900U, 4000U
+};
+
+static const uint16_t ldo1_volt_table[] = {
+	1800U,
+};
+
+static const uint16_t ldo4_volt_table[] = {
+	3300U,
+};
+
+static const uint16_t refddr_volt_table[] = {
+	0,
+};
+
+#define DEFINE_BUCK(regu_name, ID, pd, table) { \
+	.name			= regu_name, \
+	.volt_table		= table, \
+	.volt_table_size	= ARRAY_SIZE(table), \
+	.en_cr			= ID ## _MAIN_CR2, \
+	.volt_cr		= ID ## _MAIN_CR1, \
+	.alt_en_cr		= ID ## _ALT_CR2, \
+	.msrt_reg		= BUCKS_MRST_CR, \
+	.msrt_mask		= ID ## _MRST, \
+	.pd_reg			= pd, \
+	.pd_val			= ID ## _PD_FAST, \
+	.ocp_reg		= FS_OCP_CR1, \
+	.ocp_mask		= FS_OCP_ ## ID, \
+}
+
+#define DEFINE_LDOx(regu_name, ID, table) { \
+	.name			= regu_name, \
+	.volt_table		= table, \
+	.volt_table_size	= ARRAY_SIZE(table), \
+	.volt_shift		= LDO_VOLT_SHIFT, \
+	.en_cr			= ID ## _MAIN_CR, \
+	.volt_cr		= ID ## _MAIN_CR, \
+	.alt_en_cr		= ID ## _ALT_CR, \
+	.msrt_reg		= LDOS_MRST_CR, \
+	.msrt_mask		= ID ## _MRST, \
+	.pd_reg			= LDOS_PD_CR1, \
+	.pd_val			= ID ## _PD, \
+	.ocp_reg		= FS_OCP_CR2, \
+	.ocp_mask		= FS_OCP_ ## ID, \
+}
+
+#define DEFINE_REFDDR(regu_name, ID, table) { \
+	.name			= regu_name, \
+	.volt_table		= table, \
+	.volt_table_size	= ARRAY_SIZE(table), \
+	.en_cr			= ID ## _MAIN_CR, \
+	.volt_cr		= ID ## _MAIN_CR, \
+	.alt_en_cr		= ID ## _ALT_CR, \
+	.msrt_reg		= BUCKS_MRST_CR, \
+	.msrt_mask		= ID ## _MRST, \
+	.pd_reg			= LDOS_PD_CR2, \
+	.pd_val			= ID ## _PD, \
+	.ocp_reg		= FS_OCP_CR1, \
+	.ocp_mask		= FS_OCP_ ## ID, \
+}
+
+/* Table of Regulators in PMIC SoC */
+static const struct regul_struct regul_table[STPMIC2_NB_REG] = {
+	[STPMIC2_BUCK1] = DEFINE_BUCK("buck1", BUCK1, BUCKS_PD_CR1,
+				      buck1236_volt_table),
+	[STPMIC2_BUCK2] = DEFINE_BUCK("buck2", BUCK2, BUCKS_PD_CR1,
+				      buck1236_volt_table),
+	[STPMIC2_BUCK3] = DEFINE_BUCK("buck3", BUCK3, BUCKS_PD_CR1,
+				      buck1236_volt_table),
+	[STPMIC2_BUCK4] = DEFINE_BUCK("buck4", BUCK4, BUCKS_PD_CR1,
+				      buck457_volt_table),
+	[STPMIC2_BUCK5] = DEFINE_BUCK("buck5", BUCK5, BUCKS_PD_CR2,
+				      buck457_volt_table),
+	[STPMIC2_BUCK6] = DEFINE_BUCK("buck6", BUCK6, BUCKS_PD_CR2,
+				      buck1236_volt_table),
+	[STPMIC2_BUCK7] = DEFINE_BUCK("buck7", BUCK7, BUCKS_PD_CR2,
+				      buck457_volt_table),
+
+	[STPMIC2_REFDDR] = DEFINE_REFDDR("refddr", REFDDR, refddr_volt_table),
+
+	[STPMIC2_LDO1] = DEFINE_LDOx("ldo1", LDO1, ldo1_volt_table),
+	[STPMIC2_LDO2] = DEFINE_LDOx("ldo2", LDO2, ldo235678_volt_table),
+	[STPMIC2_LDO3] = DEFINE_LDOx("ldo3", LDO3, ldo235678_volt_table),
+	[STPMIC2_LDO4] = DEFINE_LDOx("ldo4", LDO4, ldo4_volt_table),
+	[STPMIC2_LDO5] = DEFINE_LDOx("ldo5", LDO5, ldo235678_volt_table),
+	[STPMIC2_LDO6] = DEFINE_LDOx("ldo6", LDO6, ldo235678_volt_table),
+	[STPMIC2_LDO7] = DEFINE_LDOx("ldo7", LDO7, ldo235678_volt_table),
+	[STPMIC2_LDO8] = DEFINE_LDOx("ldo8", LDO8, ldo235678_volt_table),
+
+};
+
+int stpmic2_register_read(struct pmic_handle_s *pmic,
+			  uint8_t register_id, uint8_t *value)
+{
+	int ret = stm32_i2c_mem_read(pmic->i2c_handle,
+				     pmic->i2c_addr,
+				     (uint16_t)register_id,
+				     I2C_MEMADD_SIZE_8BIT, value,
+				     1, I2C_TIMEOUT_MS);
+	if (ret != 0) {
+		ERROR("Failed to read reg:0x%x\n", register_id);
+	}
+
+	return ret;
+}
+
+int stpmic2_register_write(struct pmic_handle_s *pmic,
+			   uint8_t register_id, uint8_t value)
+{
+	uint8_t val = value;
+	int ret = stm32_i2c_mem_write(pmic->i2c_handle,
+				      pmic->i2c_addr,
+				      (uint16_t)register_id,
+				      I2C_MEMADD_SIZE_8BIT, &val,
+				      1, I2C_TIMEOUT_MS);
+	if (ret != 0) {
+		ERROR("Failed to write reg:0x%x\n", register_id);
+	}
+
+	return ret;
+}
+
+int stpmic2_register_update(struct pmic_handle_s *pmic,
+			    uint8_t register_id, uint8_t value, uint8_t mask)
+{
+	int status;
+	uint8_t val = 0U;
+
+	status = stpmic2_register_read(pmic, register_id, &val);
+	if (status != 0) {
+		return status;
+	}
+
+	val = (val & ((uint8_t)~mask)) | (value & mask);
+
+	VERBOSE("REG:0x%x v=0x%x mask=0x%x -> 0x%x\n",
+		register_id, value, mask, val);
+
+	return stpmic2_register_write(pmic, register_id, val);
+}
+
+int stpmic2_regulator_set_state(struct pmic_handle_s *pmic,
+				uint8_t id, bool enable)
+{
+	const struct regul_struct *regul = &regul_table[id];
+
+	if (enable) {
+		return stpmic2_register_update(pmic, regul->en_cr, 1U, 1U);
+	} else {
+		return stpmic2_register_update(pmic, regul->en_cr, 0, 1U);
+	}
+}
+
+int stpmic2_regulator_get_state(struct pmic_handle_s *pmic,
+				uint8_t id, bool *enabled)
+{
+	const struct regul_struct *regul = &regul_table[id];
+	uint8_t val;
+
+	if (stpmic2_register_read(pmic, regul->en_cr, &val) != 0) {
+		return RET_ERROR_GENERIC;
+	}
+
+	*enabled = (val & 1U) == 1U;
+
+	return RET_SUCCESS;
+}
+
+int stpmic2_regulator_levels_mv(struct pmic_handle_s *pmic,
+				uint8_t id, const uint16_t **levels,
+				size_t *levels_count)
+{
+	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;
+	}
+	if (levels != NULL) {
+		*levels = regul->volt_table;
+	}
+
+	return RET_SUCCESS;
+}
+
+int stpmic2_regulator_get_voltage(struct pmic_handle_s *pmic,
+				  uint8_t id, uint16_t *val)
+{
+	const struct regul_struct *regul = &regul_table[id];
+	uint8_t value = 0U;
+	uint8_t mask;
+
+	if (regul->volt_table_size == 0U) {
+		return RET_ERROR_GENERIC;
+	}
+
+	mask = regul->volt_table_size - 1U;
+	if (mask != 0U) {
+		if (stpmic2_register_read(pmic, regul->volt_cr, &value) != 0) {
+			return RET_ERROR_GENERIC;
+		}
+
+		value = (value >> regul->volt_shift) & mask;
+	}
+
+	if (value > regul->volt_table_size) {
+		return RET_ERROR_GENERIC;
+	}
+
+	*val = regul->volt_table[value];
+
+	return RET_SUCCESS;
+}
+
+static size_t voltage_to_index(const struct regul_struct *regul,
+			       uint16_t millivolts)
+{
+	unsigned int i;
+
+	assert(regul->volt_table);
+	for (i = 0U; i < regul->volt_table_size; i++) {
+		if (regul->volt_table[i] == millivolts) {
+			return i;
+		}
+	}
+
+	return VOLTAGE_INDEX_INVALID;
+}
+
+int stpmic2_regulator_set_voltage(struct pmic_handle_s *pmic,
+				  uint8_t id, uint16_t millivolts)
+{
+	const struct regul_struct *regul = &regul_table[id];
+	size_t index;
+	uint8_t mask;
+
+	if (!regul->volt_table_size) {
+		return RET_SUCCESS;
+	}
+
+	mask = regul->volt_table_size - 1U;
+
+	index = voltage_to_index(regul, millivolts);
+	if (index == VOLTAGE_INDEX_INVALID) {
+		return RET_ERROR_GENERIC;
+	}
+
+	return stpmic2_register_update(pmic, regul->volt_cr,
+				       index << regul->volt_shift,
+				       mask << regul->volt_shift);
+}
+
+/* update both normal and alternate register */
+static int stpmic2_update_en_crs(struct pmic_handle_s *pmic, uint8_t id,
+				 uint8_t value, uint8_t mask)
+{
+	const struct regul_struct *regul = &regul_table[id];
+
+	if (stpmic2_register_update(pmic, regul->en_cr, value, mask) != 0) {
+		return RET_ERROR_GENERIC;
+	}
+
+	if (stpmic2_register_update(pmic, regul->alt_en_cr, value, mask) != 0) {
+		return RET_ERROR_GENERIC;
+	}
+
+	return RET_SUCCESS;
+}
+
+int stpmic2_regulator_get_prop(struct pmic_handle_s *pmic, uint8_t id,
+			       enum stpmic2_prop_id prop)
+{
+	const struct regul_struct *regul = &regul_table[id];
+	uint8_t val;
+
+	VERBOSE("%s: get prop 0x%x\n", regul->name, prop);
+
+	switch (prop) {
+	case STPMIC2_BYPASS:
+		if ((id <= STPMIC2_BUCK7) || (id == STPMIC2_LDO1) ||
+		    (id == STPMIC2_LDO4) || (id == STPMIC2_REFDDR)) {
+			return 0;
+		}
+
+		if (stpmic2_register_read(pmic, regul->en_cr, &val) != 0) {
+			return -EIO;
+		}
+
+		if ((val & LDO_BYPASS) != 0) {
+			return 1;
+		}
+
+		break;
+	default:
+		ERROR("Invalid prop %u\n", prop);
+		panic();
+	}
+
+	return 0;
+}
+
+int stpmic2_regulator_set_prop(struct pmic_handle_s *pmic, uint8_t id,
+			       enum stpmic2_prop_id prop, uint32_t arg)
+{
+	const struct regul_struct *regul = &regul_table[id];
+
+	VERBOSE("%s: set prop 0x%x arg=%u\n", regul->name, prop, arg);
+
+	switch (prop) {
+	case STPMIC2_PULL_DOWN:
+		return stpmic2_register_update(pmic, regul->pd_reg,
+					       regul->pd_val,
+					       regul->pd_val);
+	case STPMIC2_MASK_RESET:
+		if (!regul->msrt_mask) {
+			return RET_ERROR_NOT_SUPPORTED;
+		}
+		/* enable mask reset */
+		return stpmic2_register_update(pmic, regul->msrt_reg,
+					       regul->msrt_mask,
+					       regul->msrt_mask);
+	case STPMIC2_BYPASS:
+		if ((id <= STPMIC2_BUCK7) || (id == STPMIC2_LDO1) ||
+		    (id == STPMIC2_LDO4) || (id == STPMIC2_REFDDR)) {
+			return RET_ERROR_NOT_SUPPORTED;
+		}
+
+		/* clear sink source mode */
+		if ((id == STPMIC2_LDO3) && (arg != 0U)) {
+			if (stpmic2_update_en_crs(pmic, id, 0, LDO3_SNK_SRC) != 0) {
+				return RET_ERROR_GENERIC;
+			}
+		}
+
+		/* enable bypass mode */
+		return stpmic2_update_en_crs(pmic, id,
+					     (arg != 0U) ? LDO_BYPASS : 0,
+					     LDO_BYPASS);
+	case STPMIC2_SINK_SOURCE:
+		if (id != STPMIC2_LDO3) {
+			return RET_ERROR_NOT_SUPPORTED;
+		}
+
+		/* clear bypass mode */
+		if (stpmic2_update_en_crs(pmic, id, 0, LDO_BYPASS) != 0) {
+			return RET_ERROR_GENERIC;
+		}
+
+		return stpmic2_update_en_crs(pmic, id, LDO3_SNK_SRC,
+					     LDO3_SNK_SRC);
+	case STPMIC2_OCP:
+		return stpmic2_register_update(pmic, regul->ocp_reg,
+					       regul->ocp_mask,
+					       regul->ocp_mask);
+	default:
+		ERROR("Invalid prop %u\n", prop);
+		panic();
+	}
+
+	return -EPERM;
+}
+
+#if EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE
+void stpmic2_dump_regulators(struct pmic_handle_s *pmic)
+{
+	size_t i;
+	char const *name;
+
+	for (i = 0U; i < ARRAY_SIZE(regul_table); i++) {
+		uint16_t val;
+		bool state;
+
+		if (!regul_table[i].volt_cr) {
+			continue;
+		}
+
+		stpmic2_regulator_get_voltage(pmic, i, &val);
+		stpmic2_regulator_get_state(pmic, i, &state);
+
+		name = regul_table[i].name;
+
+		VERBOSE("PMIC regul %s: %s, %dmV\n",
+			name, state ? "EN" : "DIS", val);
+	}
+}
+#endif
+
+int stpmic2_get_version(struct pmic_handle_s *pmic, uint8_t *val)
+{
+	return stpmic2_register_read(pmic, VERSION_SR, val);
+}
+
+int stpmic2_get_product_id(struct pmic_handle_s *pmic, uint8_t *val)
+{
+	return stpmic2_register_read(pmic, PRODUCT_ID, val);
+}
diff --git a/drivers/st/regulator/regulator_core.c b/drivers/st/regulator/regulator_core.c
index 2a5d0f7a..b369acdb 100644
--- a/drivers/st/regulator/regulator_core.c
+++ b/drivers/st/regulator/regulator_core.c
@@ -215,14 +215,18 @@ int regulator_set_voltage(struct rdev *rdev, uint16_t mvolt)
 
 	VERBOSE("%s: set mvolt\n", rdev->desc->node_name);
 
-	if (rdev->desc->ops->set_voltage == NULL) {
-		return -ENODEV;
-	}
-
 	if ((mvolt < rdev->min_mv) || (mvolt > rdev->max_mv)) {
 		return -EPERM;
 	}
 
+	if (regulator_get_voltage(rdev) == mvolt) {
+		return 0U;
+	}
+
+	if (rdev->desc->ops->set_voltage == NULL) {
+		return -ENODEV;
+	}
+
 	lock_driver(rdev);
 
 	ret = rdev->desc->ops->set_voltage(rdev->desc, mvolt);
@@ -420,6 +424,7 @@ int regulator_set_flag(struct rdev *rdev, uint16_t flag)
 
 static int parse_properties(const void *fdt, struct rdev *rdev, int node)
 {
+	const fdt32_t *cuint;
 	int ret;
 
 	if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL) {
@@ -430,6 +435,13 @@ static int parse_properties(const void *fdt, struct rdev *rdev, int node)
 		}
 	}
 
+	cuint = fdt_getprop(fdt, node, "regulator-enable-ramp-delay", NULL);
+	if (cuint != NULL) {
+		rdev->enable_ramp_delay = fdt32_to_cpu(*cuint);
+		VERBOSE("%s: enable_ramp_delay=%u\n", rdev->desc->node_name,
+			rdev->enable_ramp_delay);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c
index 98c8dcf7..8b828a15 100644
--- a/drivers/st/reset/stm32mp1_reset.c
+++ b/drivers/st/reset/stm32mp1_reset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,6 @@
 #include <errno.h>
 #include <limits.h>
 
-#include <platform_def.h>
-
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
@@ -16,6 +14,8 @@
 #include <lib/mmio.h>
 #include <lib/utils_def.h>
 
+#include <platform_def.h>
+
 static uint32_t id2reg_offset(unsigned int reset_id)
 {
 	return ((reset_id & GENMASK(31, 5)) >> 5) * sizeof(uint32_t);
@@ -67,3 +67,16 @@ int stm32mp_reset_deassert(uint32_t id, unsigned int to_us)
 
 	return 0;
 }
+
+void __dead2 stm32mp_system_reset(void)
+{
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	mmio_setbits_32(rcc_base + RCC_MP_GRSTCSETR,
+			RCC_MP_GRSTCSETR_MPSYSRST);
+
+	/* Loop in case system reset is not immediately caught */
+	while (true) {
+		wfi();
+	}
+}
diff --git a/drivers/st/reset/stm32mp2_reset.c b/drivers/st/reset/stm32mp2_reset.c
new file mode 100644
index 00000000..0918df59
--- /dev/null
+++ b/drivers/st/reset/stm32mp2_reset.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+
+static uint32_t id2reg_offset(unsigned int reset_id)
+{
+	return ((reset_id & GENMASK(31, 5)) >> 5) * sizeof(uint32_t);
+}
+
+static uint8_t id2reg_bit_pos(unsigned int reset_id)
+{
+	return (uint8_t)(reset_id & GENMASK(4, 0));
+}
+
+static int reset_toggle(uint32_t id, unsigned int to_us, bool reset_status)
+{
+	uint32_t offset = id2reg_offset(id);
+	uint32_t bitmsk = BIT(id2reg_bit_pos(id));
+	uint32_t bit_check;
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	if (reset_status) {
+		mmio_setbits_32(rcc_base + offset, bitmsk);
+		bit_check = bitmsk;
+	} else {
+		mmio_clrbits_32(rcc_base + offset, bitmsk);
+		bit_check = 0U;
+	}
+
+	if (to_us != 0U) {
+		uint64_t timeout_ref = timeout_init_us(to_us);
+
+		while ((mmio_read_32(rcc_base + offset) & bitmsk) != bit_check) {
+			if (timeout_elapsed(timeout_ref)) {
+				return -ETIMEDOUT;
+			}
+		}
+	}
+
+	return 0;
+}
+
+int stm32mp_reset_assert(uint32_t id, unsigned int to_us)
+{
+	return reset_toggle(id, to_us, true);
+}
+
+int stm32mp_reset_deassert(uint32_t id, unsigned int to_us)
+{
+	return reset_toggle(id, to_us, false);
+}
+
+void __dead2 stm32mp_system_reset(void)
+{
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	mmio_setbits_32(rcc_base + RCC_GRSTCSETR, RCC_GRSTCSETR_SYSRST);
+
+	/* Loop in case system reset is not immediately caught */
+	while (true) {
+		wfi();
+	}
+}
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 19f894ff..33ceb263 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -966,8 +966,7 @@ static void ufs_get_device_info(struct ufs_dev_desc *card_data)
 {
 	uint8_t desc_buf[DESC_DEVICE_MAX_SIZE];
 
-	ufs_query(QUERY_READ_DESC, DESC_TYPE_DEVICE, 0, 0,
-				(uintptr_t)desc_buf, DESC_DEVICE_MAX_SIZE);
+	ufs_read_desc(DESC_TYPE_DEVICE, 0, (uintptr_t)desc_buf, DESC_DEVICE_MAX_SIZE);
 
 	/*
 	 * getting vendor (manufacturerID) and Bank Index in big endian
diff --git a/fdts/cca_cot_descriptors.dtsi b/fdts/cca_cot_descriptors.dtsi
new file mode 100644
index 00000000..93d60ea3
--- /dev/null
+++ b/fdts/cca_cot_descriptors.dtsi
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <tools_share/cca_oid.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <common/nv_cntr_ids.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		cca_content_cert: cca_content_cert {
+			root-certificate;
+			image-id =<CCA_CONTENT_CERT_ID>;
+			antirollback-counter = <&cca_nv_ctr>;
+
+			tb_fw_hash: tb_fw_hash {
+				oid = TRUSTED_BOOT_FW_HASH_OID;
+			};
+			tb_fw_config_hash: tb_fw_config_hash {
+				oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID;
+			};
+			hw_config_hash: hw_config_hash {
+				oid = HW_CONFIG_HASH_OID;
+			};
+			fw_config_hash: fw_config_hash {
+				oid = FW_CONFIG_HASH_OID;
+			};
+			soc_fw_hash: soc_fw_hash {
+				oid = SOC_AP_FW_HASH_OID;
+			};
+			soc_fw_config_hash: soc_fw_config_hash {
+				oid = SOC_FW_CONFIG_HASH_OID;
+			};
+			rmm_hash: rmm_hash {
+				oid = RMM_HASH_OID;
+			};
+		};
+
+		core_swd_key_cert: core_swd_key_cert {
+			root-certificate;
+			image-id = <CORE_SWD_KEY_CERT_ID>;
+			signing-key = <&swd_rot_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			core_swd_pk: core_swd_pk {
+				oid = CORE_SWD_PK_OID;
+			};
+		};
+
+		trusted_os_fw_content_cert: trusted_os_fw_content_cert {
+			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
+			parent = <&core_swd_key_cert>;
+			signing-key = <&core_swd_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			tos_fw_hash: tos_fw_hash {
+				oid = TRUSTED_OS_FW_HASH_OID;
+			};
+			tos_fw_config_hash: tos_fw_config_hash {
+				oid = TRUSTED_OS_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		plat_key_cert: plat_key_cert {
+			root-certificate;
+			image-id = <PLAT_KEY_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			plat_pk: plat_pk {
+				oid = PLAT_PK_OID;
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			parent = <&plat_key_cert>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid = NON_TRUSTED_FW_CONFIG_HASH_OID;
+			};
+		};
+
+#if defined(SPD_spmd)
+		sip_sp_content_cert: sip_sp_content_cert {
+			image-id = <SIP_SP_CONTENT_CERT_ID>;
+			parent = <&core_swd_key_cert>;
+			signing-key = <&core_swd_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			sp_pkg1_hash: sp_pkg1_hash {
+				oid = SP_PKG1_HASH_OID;
+			};
+			sp_pkg2_hash: sp_pkg2_hash {
+				oid = SP_PKG2_HASH_OID;
+			};
+			sp_pkg3_hash: sp_pkg3_hash {
+				oid = SP_PKG3_HASH_OID;
+			};
+			sp_pkg4_hash: sp_pkg4_hash {
+				oid = SP_PKG4_HASH_OID;
+			};
+		};
+
+		plat_sp_content_cert: plat_sp_content_cert {
+			image-id = <PLAT_SP_CONTENT_CERT_ID>;
+			parent = <&plat_key_cert>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			sp_pkg5_hash: sp_pkg5_hash {
+				oid = SP_PKG5_HASH_OID;
+			};
+			sp_pkg6_hash: sp_pkg6_hash {
+				oid = SP_PKG6_HASH_OID;
+			};
+			sp_pkg7_hash: sp_pkg7_hash {
+				oid = SP_PKG7_HASH_OID;
+			};
+			sp_pkg8_hash: sp_pkg8_hash {
+				oid = SP_PKG8_HASH_OID;
+			};
+		};
+#endif
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <HW_CONFIG_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		bl31_image {
+			image-id = <BL31_IMAGE_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <SOC_FW_CONFIG_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		rmm_image {
+			image-id = <RMM_IMAGE_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&rmm_hash>;
+		};
+
+		bl32_image {
+			image-id = <BL32_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_hash>;
+		};
+
+		tos_fw_config {
+			image-id = <TOS_FW_CONFIG_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <BL33_IMAGE_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <NT_FW_CONFIG_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_fw_config_hash>;
+		};
+
+#if defined(SPD_spmd)
+		sp_pkg1 {
+			image-id = <SP_PKG1_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg1_hash>;
+		};
+
+		sp_pkg2 {
+			image-id = <SP_PKG2_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg2_hash>;
+		};
+
+		sp_pkg3 {
+			image-id = <SP_PKG3_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg3_hash>;
+		};
+
+		sp_pkg4 {
+			image-id = <SP_PKG4_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg4_hash>;
+		};
+
+		sp_pkg5 {
+			image-id = <SP_PKG5_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg5_hash>;
+		};
+
+		sp_pkg6 {
+			image-id = <SP_PKG6_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg6_hash>;
+		};
+
+		sp_pkg7 {
+			image-id = <SP_PKG7_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg7_hash>;
+		};
+
+		sp_pkg8 {
+			image-id = <SP_PKG8_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg8_hash>;
+		};
+#endif
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	cca_nv_ctr: cca_nv_ctr {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = CCA_FW_NVCOUNTER_OID;
+	};
+
+	trusted_nv_ctr: trusted_nv_ctr {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = TRUSTED_FW_NVCOUNTER_OID;
+	};
+
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
+		id  = <NON_TRUSTED_NV_CTR_ID>;
+		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys {
+	swd_rot_pk: swd_rot_pk {
+		oid = SWD_ROT_PK_OID;
+	};
+
+	prot_pk: prot_pk {
+		oid = PROT_PK_OID;
+	};
+};
diff --git a/fdts/dualroot_cot_descriptors.dtsi b/fdts/dualroot_cot_descriptors.dtsi
new file mode 100644
index 00000000..bea7af5b
--- /dev/null
+++ b/fdts/dualroot_cot_descriptors.dtsi
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <tools_share/dualroot_oid.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <common/nv_cntr_ids.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		trusted_boot_fw_cert: trusted_boot_fw_cert {
+			root-certificate;
+			image-id =<TRUSTED_BOOT_FW_CERT_ID>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			tb_fw_hash: tb_fw_hash {
+				oid = TRUSTED_BOOT_FW_HASH_OID;
+			};
+			tb_fw_config_hash: tb_fw_config_hash {
+				oid = TRUSTED_BOOT_FW_CONFIG_HASH_OID;
+			};
+			hw_config_hash: hw_config_hash {
+				oid = HW_CONFIG_HASH_OID;
+			};
+			fw_config_hash: fw_config_hash {
+				oid = FW_CONFIG_HASH_OID;
+			};
+		};
+
+		trusted_key_cert: trusted_key_cert {
+			root-certificate;
+			image-id = <TRUSTED_KEY_CERT_ID>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			trusted_world_pk: trusted_world_pk {
+				oid = TRUSTED_WORLD_PK_OID;
+			};
+		};
+
+		scp_fw_key_cert: scp_fw_key_cert {
+			image-id = <SCP_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			scp_fw_content_pk: scp_fw_content_pk {
+				oid = SCP_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		scp_fw_content_cert: scp_fw_content_cert {
+			image-id = <SCP_FW_CONTENT_CERT_ID>;
+			parent = <&scp_fw_key_cert>;
+			signing-key = <&scp_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			scp_fw_hash: scp_fw_hash {
+				oid = SCP_FW_HASH_OID;
+			};
+		};
+
+		soc_fw_key_cert: soc_fw_key_cert {
+			image-id = <SOC_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+			soc_fw_content_pk: soc_fw_content_pk {
+				oid = SOC_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		soc_fw_content_cert: soc_fw_content_cert {
+			image-id = <SOC_FW_CONTENT_CERT_ID>;
+			parent = <&soc_fw_key_cert>;
+			signing-key = <&soc_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			soc_fw_hash: soc_fw_hash {
+				oid = SOC_AP_FW_HASH_OID;
+			};
+			soc_fw_config_hash: soc_fw_config_hash {
+				oid = SOC_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		trusted_os_fw_key_cert: trusted_os_fw_key_cert {
+			image-id = <TRUSTED_OS_FW_KEY_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			tos_fw_content_pk: tos_fw_content_pk {
+				oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID;
+			};
+		};
+
+		trusted_os_fw_content_cert: trusted_os_fw_content_cert {
+			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
+			parent = <&trusted_os_fw_key_cert>;
+			signing-key = <&tos_fw_content_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			tos_fw_hash: tos_fw_hash {
+				oid = TRUSTED_OS_FW_HASH_OID;
+			};
+			tos_fw_extra1_hash: tos_fw_extra1_hash {
+				oid = TRUSTED_OS_FW_EXTRA1_HASH_OID;
+			};
+			tos_fw_extra2_hash: tos_fw_extra2_hash {
+				oid = TRUSTED_OS_FW_EXTRA2_HASH_OID;
+			};
+			tos_fw_config_hash: tos_fw_config_hash {
+				oid = TRUSTED_OS_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			root-certificate;
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid = NON_TRUSTED_FW_CONFIG_HASH_OID;
+			};
+		};
+
+#if defined(SPD_spmd)
+		sip_sp_content_cert: sip_sp_content_cert {
+			image-id = <SIP_SP_CONTENT_CERT_ID>;
+			parent = <&trusted_key_cert>;
+			signing-key = <&trusted_world_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			sp_pkg1_hash: sp_pkg1_hash {
+				oid = SP_PKG1_HASH_OID;
+			};
+			sp_pkg2_hash: sp_pkg2_hash {
+				oid = SP_PKG2_HASH_OID;
+			};
+			sp_pkg3_hash: sp_pkg3_hash {
+				oid = SP_PKG3_HASH_OID;
+			};
+			sp_pkg4_hash: sp_pkg4_hash {
+				oid = SP_PKG4_HASH_OID;
+			};
+		};
+
+		plat_sp_content_cert: plat_sp_content_cert {
+			root-certificate;
+			image-id = <PLAT_SP_CONTENT_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			sp_pkg5_hash: sp_pkg5_hash {
+				oid = SP_PKG5_HASH_OID;
+			};
+			sp_pkg6_hash: sp_pkg6_hash {
+				oid = SP_PKG6_HASH_OID;
+			};
+			sp_pkg7_hash: sp_pkg7_hash {
+				oid = SP_PKG7_HASH_OID;
+			};
+			sp_pkg8_hash: sp_pkg8_hash {
+				oid = SP_PKG8_HASH_OID;
+			};
+		};
+#endif
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <HW_CONFIG_ID>;
+			parent = <&trusted_boot_fw_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		scp_bl2_image {
+			image-id = <SCP_BL2_IMAGE_ID>;
+			parent = <&scp_fw_content_cert>;
+			hash = <&scp_fw_hash>;
+		};
+
+		bl31_image {
+			image-id = <BL31_IMAGE_ID>;
+			parent = <&soc_fw_content_cert>;
+			hash = <&soc_fw_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <SOC_FW_CONFIG_ID>;
+			parent = <&soc_fw_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		bl32_image {
+			image-id = <BL32_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_hash>;
+		};
+
+		bl32_extra1_image {
+			image-id = <BL32_EXTRA1_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_extra1_hash>;
+		};
+
+		bl32_extra2_image {
+			image-id = <BL32_EXTRA2_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_extra2_hash>;
+		};
+
+		tos_fw_config {
+			image-id = <TOS_FW_CONFIG_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <BL33_IMAGE_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <NT_FW_CONFIG_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_fw_config_hash>;
+		};
+
+#if defined(SPD_spmd)
+		sp_pkg1 {
+			image-id = <SP_PKG1_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg1_hash>;
+		};
+
+		sp_pkg2 {
+			image-id = <SP_PKG2_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg2_hash>;
+		};
+
+		sp_pkg3 {
+			image-id = <SP_PKG3_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg3_hash>;
+		};
+
+		sp_pkg4 {
+			image-id = <SP_PKG4_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg4_hash>;
+		};
+
+		sp_pkg5 {
+			image-id = <SP_PKG5_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg5_hash>;
+		};
+
+		sp_pkg6 {
+			image-id = <SP_PKG6_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg6_hash>;
+		};
+
+		sp_pkg7 {
+			image-id = <SP_PKG7_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg7_hash>;
+		};
+
+		sp_pkg8 {
+			image-id = <SP_PKG8_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg8_hash>;
+		};
+#endif
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	trusted_nv_ctr: trusted_nv_ctr {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = TRUSTED_FW_NVCOUNTER_OID;
+	};
+
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
+		id  = <NON_TRUSTED_NV_CTR_ID>;
+		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys {
+	prot_pk: prot_pk {
+		oid = PROT_PK_OID;
+	};
+};
diff --git a/fdts/fvp-base-psci-common.dtsi b/fdts/fvp-base-psci-common.dtsi
index 79cf37d3..583bba70 100644
--- a/fdts/fvp-base-psci-common.dtsi
+++ b/fdts/fvp-base-psci-common.dtsi
@@ -27,11 +27,12 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	chosen {
+		stdout-path = "serial0:115200n8";
 #if (ENABLE_RME == 1)
-	chosen { bootargs = "console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda ip=on";};
-#else
-	chosen {};
+		bootargs = "console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda ip=on";
 #endif
+	};
 
 	aliases {
 		serial0 = &v2m_serial0;
@@ -243,6 +244,9 @@
 				<0 0 39 &gic 0 GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
 				<0 0 40 &gic 0 GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 				<0 0 41 &gic 0 GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
-				<0 0 42 &gic 0 GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+				<0 0 42 &gic 0 GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 43 &gic 0 GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 44 &gic 0 GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				<0 0 46 &gic 0 GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts
index 5a82c460..653c75fb 100644
--- a/fdts/fvp-foundation-gicv2-psci.dts
+++ b/fdts/fvp-foundation-gicv2-psci.dts
@@ -26,7 +26,9 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	chosen { };
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
 
 	aliases {
 		serial0 = &v2m_serial0;
diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts
index e1249d45..28272970 100644
--- a/fdts/fvp-foundation-gicv3-psci.dts
+++ b/fdts/fvp-foundation-gicv3-psci.dts
@@ -26,7 +26,9 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	chosen { };
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
 
 	aliases {
 		serial0 = &v2m_serial0;
diff --git a/fdts/rd1ae.dts b/fdts/rd1ae.dts
new file mode 100644
index 00000000..3060b5a7
--- /dev/null
+++ b/fdts/rd1ae.dts
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	model = "RD-1 AE";
+	compatible = "arm,rd1ae", "arm,neoverse";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen {
+		stdout-path = &soc_serial0;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu1: cpu@10000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu2: cpu@20000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x20000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu3: cpu@30000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x30000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu4: cpu@40000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x40000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu5: cpu@50000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x50000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu6: cpu@60000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x60000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu7: cpu@70000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x70000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu8: cpu@80000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x80000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu9: cpu@90000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0x90000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu10: cpu@a0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xa0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu11: cpu@b0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xb0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu12: cpu@c0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xc0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu13: cpu@d0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xd0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu14: cpu@e0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xe0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+		cpu15: cpu@f0000 {
+			device_type = "cpu";
+			compatible = "arm,neoverse-v3";
+			reg = <0x0 0xf0000>;
+			enable-method = "psci";
+			i-cache-size = <0x10000>;
+			i-cache-line-size = <0x40>;
+			i-cache-sets = <0x100>;
+			d-cache-size = <0x10000>;
+			d-cache-line-size = <0x40>;
+			d-cache-sets = <0x100>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		/*
+		 * 0x7fc0 0000 - 0x7fff ffff : BL32
+		 * 0x7fbf 0000 - 0x7fbf ffff : FFA_SHARED_MM_BUF
+		 */
+		reg = <0x00000000 0x80000000 0 0x7fbf0000>,
+			  <0x00000080 0x80000000 0 0x80000000>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	soc_clk24mhz: clk24mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "refclk24mhz";
+	};
+
+	soc_refclk1mhz: refclk1mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000>;
+		clock-output-names = "refclk1mhz";
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller@30000000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x30000000 0 0x10000>,	// GICD
+				  <0x0 0x301c0000 0 0x8000000>;	// GICR
+			#interrupt-cells = <3>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+			its1: msi-controller@30040000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30040000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its2: msi-controller@30080000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30080000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its3: msi-controller@300c0000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x300c0000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its4: msi-controller@30100000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30100000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its5: msi-controller@30140000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30140000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+			its6: msi-controller@30180000 {
+				compatible = "arm,gic-v3-its";
+				reg = <0x0 0x30180000 0x0 0x40000>;
+				msi-controller;
+				#msi-cells = <1>;
+			};
+		};
+
+		soc_serial0: serial@2a400000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x0 0x2a400000 0x0 0x10000>;
+			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&soc_clk24mhz>, <&soc_clk24mhz>;
+			clock-names = "uartclk", "apb_pclk";
+		};
+
+		watchdog@2a440000 {
+			compatible = "arm,sbsa-gwdt";
+			reg = <0x0 0x2a440000 0 0x1000>,
+				  <0x0 0x2a450000 0 0x1000>;
+			interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		rtc@c170000 {
+			compatible = "arm,pl031", "arm,primecell";
+			reg = <0x0 0x0c170000 0x0 0x10000>;
+			interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&soc_clk24mhz>;
+			clock-names = "apb_pclk";
+		};
+
+		virtio-net@c150000 {
+			compatible = "virtio,mmio";
+			reg = <0x0 0xc150000 0x0 0x200>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		virtio-block@c130000 {
+			compatible = "virtio,mmio";
+			reg = <0x0 0xc130000 0x0 0x200>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		virtio-rng@c140000 {
+			compatible = "virtio,mmio";
+			reg = <0x0 0xc140000 0x0 0x200>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pci@4000000000 {
+			#address-cells = <0x03>;
+			#size-cells = <0x02>;
+			compatible = "pci-host-ecam-generic";
+			device_type = "pci";
+			bus-range = <0x00 0x11>;
+			reg = <0x40 0x00 0x00 0x04000000>;
+			ranges = <0x43000000 0x40 0x40000000 0x40 0x40000000 0x10 0x00000000
+				  0x02000000 0x00 0x60000000 0x00 0x60000000 0x00 0x08000000
+				  0x01000000 0x00 0x00 0x00 0x77800000 0x00 0x800000>;
+			msi-map = <0x00 &its1 0x40000 0x10000>;
+			iommu-map = <0x00 &smmu 0x40000 0x10000>;
+			dma-coherent;
+		};
+
+		smmu: iommu@280000000 {
+			compatible = "arm,smmu-v3";
+			reg = <0x2 0x80000000 0x0 0x100000>;
+			dma-coherent;
+			#iommu-cells = <1>;
+			interrupts = <1 210 1>,
+				     <1 211 1>,
+				     <1 212 1>,
+				     <1 213 1>;
+			interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
+			msi-parent = <&its1 0x10000>;
+		};
+
+		sysreg: sysreg@c010000 {
+			compatible = "arm,vexpress-sysreg";
+			reg = <0x0 0xc010000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		fixed_3v3: v2m-3v3@c011000 {
+			compatible = "regulator-fixed";
+			reg = <0x0 0xc011000 0x0 0x1000>;
+			regulator-name = "3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		mmci@c050000 {
+			compatible = "arm,pl180", "arm,primecell";
+			reg = <0x0 0xc050000 0x0 0x1000>;
+			interrupts = <0 0x8B 0x4>,
+				     <0 0x8C 0x4>;
+			cd-gpios = <&sysreg 0 0>;
+			wp-gpios = <&sysreg 1 0>;
+			bus-width = <8>;
+			max-frequency = <12000000>;
+			vmmc-supply = <&fixed_3v3>;
+			clocks = <&soc_clk24mhz>, <&soc_clk24mhz>;
+			clock-names = "mclk", "apb_pclk";
+		};
+
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+		cpu_suspend = <0xc4000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0x84000003>;
+	};
+
+};
diff --git a/fdts/rtsm_ve-motherboard.dtsi b/fdts/rtsm_ve-motherboard.dtsi
index 0a824b34..5a34aae4 100644
--- a/fdts/rtsm_ve-motherboard.dtsi
+++ b/fdts/rtsm_ve-motherboard.dtsi
@@ -230,6 +230,25 @@
 					interrupts = <42>;
 				};
 
+				virtio@140000 {
+					compatible = "virtio,mmio";
+					reg = <0x140000 0x200>;
+					interrupts = <43>;
+				};
+
+				virtio@150000 {
+					compatible = "virtio,mmio";
+					reg = <0x150000 0x200>;
+					interrupts = <44>;
+				};
+
+				virtio@200000 {
+					compatible = "virtio,mmio";
+					reg = <0x200000 0x200>;
+					interrupts = <46>;
+					status = "disabled";
+				};
+
 				rtc@170000 {
 					compatible = "arm,pl031", "arm,primecell";
 					reg = <0x170000 0x1000>;
diff --git a/fdts/stm32mp1-cot-descriptors.dtsi b/fdts/stm32mp1-cot-descriptors.dtsi
index eb632ffa..05326be7 100644
--- a/fdts/stm32mp1-cot-descriptors.dtsi
+++ b/fdts/stm32mp1-cot-descriptors.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2024, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,7 +15,7 @@ cot {
 		stm32mp_cfg_cert: stm32mp_cfg_cert {
 			root-certificate;
 			image-id = <STM32MP_CONFIG_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			hw_config_hash: hw_config_hash {
 				oid = HW_CONFIG_HASH_OID;
@@ -29,7 +29,7 @@ cot {
 		trusted_key_cert: trusted_key_cert {
 			root-certificate;
 			image-id = <TRUSTED_KEY_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			trusted_world_pk: trusted_world_pk {
 				oid = TRUSTED_WORLD_PK_OID;
@@ -43,7 +43,7 @@ cot {
 			image-id = <TRUSTED_OS_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_content_pk: tos_fw_content_pk {
 				oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID;
@@ -54,7 +54,7 @@ cot {
 			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
 			parent = <&trusted_os_fw_key_cert>;
 			signing-key = <&tos_fw_content_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_hash: tos_fw_hash {
 				oid = TRUSTED_OS_FW_HASH_OID;
@@ -74,7 +74,7 @@ cot {
 			image-id = <NON_TRUSTED_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&non_trusted_world_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_fw_content_pk: nt_fw_content_pk {
 				oid = NON_TRUSTED_FW_CONTENT_CERT_PK_OID;
@@ -85,7 +85,7 @@ cot {
 			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
 			parent = <&non_trusted_fw_key_cert>;
 			signing-key = <&nt_fw_content_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_world_bl_hash: nt_world_bl_hash {
 				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
@@ -144,12 +144,12 @@ non_volatile_counters: non_volatile_counters {
 	#address-cells = <1>;
 	#size-cells = <0>;
 
-	trusted_nv_counter: trusted_nv_counter {
+	trusted_nv_ctr: trusted_nv_ctr {
 		id  = <TRUSTED_NV_CTR_ID>;
 		oid = TRUSTED_FW_NVCOUNTER_OID;
 	};
 
-	non_trusted_nv_counter: non_trusted_nv_counter {
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
 		id  = <NON_TRUSTED_NV_CTR_ID>;
 		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
 	};
diff --git a/fdts/stm32mp131.dtsi b/fdts/stm32mp131.dtsi
index 8bcf363b..520d90be 100644
--- a/fdts/stm32mp131.dtsi
+++ b/fdts/stm32mp131.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 #include <dt-bindings/clock/stm32mp13-clks.h>
@@ -420,25 +420,25 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 
-			cfg0_otp: cfg0_otp@0 {
+			cfg0_otp: cfg0-otp@0 {
 				reg = <0x0 0x2>;
 			};
 			part_number_otp: part-number-otp@4 {
 				reg = <0x4 0x2>;
 			};
-			monotonic_otp: monotonic_otp@10 {
+			monotonic_otp: monotonic-otp@10 {
 				reg = <0x10 0x4>;
 			};
-			nand_otp: cfg9_otp@24 {
+			nand_otp: cfg9-otp@24 {
 				reg = <0x24 0x4>;
 			};
-			nand2_otp: cfg10_otp@28 {
+			nand2_otp: cfg10-otp@28 {
 				reg = <0x28 0x4>;
 			};
-			uid_otp: uid_otp@34 {
+			uid_otp: uid-otp@34 {
 				reg = <0x34 0xc>;
 			};
-			hw2_otp: hw2_otp@48 {
+			hw2_otp: hw2-otp@48 {
 				reg = <0x48 0x4>;
 			};
 			ts_cal1: calib@5c {
@@ -447,14 +447,14 @@
 			ts_cal2: calib@5e {
 				reg = <0x5e 0x2>;
 			};
-			pkh_otp: pkh_otp@60 {
+			pkh_otp: pkh-otp@60 {
 				reg = <0x60 0x20>;
 			};
-			mac_addr: mac_addr@e4 {
+			mac_addr: mac@e4 {
 				reg = <0xe4 0xc>;
 				st,non-secure-otp;
 			};
-			enckey_otp: enckey_otp@170 {
+			oem_enc_key: oem-enc-key@170 {
 				reg = <0x170 0x10>;
 			};
 		};
diff --git a/fdts/stm32mp135f-dk.dts b/fdts/stm32mp135f-dk.dts
index 12046920..08fbbb9a 100644
--- a/fdts/stm32mp135f-dk.dts
+++ b/fdts/stm32mp135f-dk.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 
@@ -50,7 +50,7 @@
 };
 
 &bsec {
-	board_id: board_id@f0 {
+	board_id: board-id@f0 {
 		reg = <0xf0 0x4>;
 		st,non-secure-otp;
 	};
@@ -190,7 +190,6 @@
 		CLK_AXI_PLL2P
 		CLK_MLAHBS_PLL3
 		CLK_CKPER_HSE
-		CLK_RTC_LSE
 		CLK_SDMMC1_PLL4P
 		CLK_SDMMC2_PLL4P
 		CLK_STGEN_HSE
@@ -212,16 +211,9 @@
 		DIV(DIV_APB4, 1)
 		DIV(DIV_APB5, 2)
 		DIV(DIV_APB6, 1)
-		DIV(DIV_RTC, 0)
 	>;
 
 	st,pll_vco {
-		pll1_vco_1300Mhz: pll1-vco-1300Mhz {
-			src = < CLK_PLL12_HSE >;
-			divmn = < 2 80 >;
-			frac = < 0x800 >;
-		};
-
 		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
 			src = <CLK_PLL12_HSE>;
 			divmn = <2 65>;
@@ -240,19 +232,6 @@
 		};
 	};
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1:st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-
-		st,pll = < &pll1_cfg1 >;
-
-		pll1_cfg1: pll1_cfg1 {
-			st,pll_vco = < &pll1_vco_1300Mhz >;
-			st,pll_div_pqr = < 0 1 1 >;
-		};
-	};
-
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 266, R = 533 (DDR) */
 	pll2:st,pll@1 {
 		compatible = "st,stm32mp1-pll";
diff --git a/fdts/stm32mp15-fw-config.dtsi b/fdts/stm32mp15-fw-config.dtsi
index d5836729..6f478d49 100644
--- a/fdts/stm32mp15-fw-config.dtsi
+++ b/fdts/stm32mp15-fw-config.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
  */
 
 #include <common/tbbr/tbbr_img_def.h>
@@ -14,12 +14,9 @@
 
 #define DDR_NS_BASE	STM32MP_DDR_BASE
 #ifdef AARCH32_SP_OPTEE
-/* OP-TEE reserved shared memory: located at DDR top or null size */
-#define DDR_SHARE_SIZE	STM32MP_DDR_SHMEM_SIZE
-#define DDR_SHARE_BASE	(STM32MP_DDR_BASE + (DDR_SIZE - DDR_SHARE_SIZE))
-/* OP-TEE secure memory: located right below OP-TEE reserved shared memory */
+/* OP-TEE secure memory: located at DDR top */
 #define DDR_SEC_SIZE	STM32MP_DDR_S_SIZE
-#define DDR_SEC_BASE	(DDR_SHARE_BASE - DDR_SEC_SIZE)
+#define DDR_SEC_BASE	(STM32MP_DDR_BASE + (DDR_SIZE - DDR_SEC_SIZE))
 #define DDR_NS_SIZE	(DDR_SEC_BASE - DDR_NS_BASE)
 #else /* !AARCH32_SP_OPTEE */
 #define DDR_NS_SIZE	DDR_SIZE
@@ -70,10 +67,6 @@
 		memory-ranges = <
 			DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR
 			DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0
-#if STM32MP15_OPTEE_RSV_SHM
-			DDR_SHARE_BASE DDR_SHARE_SIZE TZC_REGION_S_NONE
-			TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)
-#endif
 			>;
 #else
 		memory-ranges = <
diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi
index 7a22a1c7..449ddbbf 100644
--- a/fdts/stm32mp151.dtsi
+++ b/fdts/stm32mp151.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (c) 2017-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -458,25 +458,25 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 
-			cfg0_otp: cfg0_otp@0 {
+			cfg0_otp: cfg0-otp@0 {
 				reg = <0x0 0x1>;
 			};
 			part_number_otp: part-number-otp@4 {
 				reg = <0x4 0x1>;
 			};
-			monotonic_otp: monotonic_otp@10 {
+			monotonic_otp: monotonic-otp@10 {
 				reg = <0x10 0x4>;
 			};
-			nand_otp: nand_otp@24 {
+			nand_otp: nand-otp@24 {
 				reg = <0x24 0x4>;
 			};
-			uid_otp: uid_otp@34 {
+			uid_otp: uid-otp@34 {
 				reg = <0x34 0xc>;
 			};
-			package_otp: package_otp@40 {
+			package_otp: package-otp@40 {
 				reg = <0x40 0x4>;
 			};
-			hw2_otp: hw2_otp@48 {
+			hw2_otp: hw2-otp@48 {
 				reg = <0x48 0x4>;
 			};
 			ts_cal1: calib@5c {
@@ -485,10 +485,10 @@
 			ts_cal2: calib@5e {
 				reg = <0x5e 0x2>;
 			};
-			pkh_otp: pkh_otp@60 {
+			pkh_otp: pkh-otp@60 {
 				reg = <0x60 0x20>;
 			};
-			mac_addr: mac_addr@e4 {
+			ethernet_mac_address: mac@e4 {
 				reg = <0xe4 0x8>;
 				st,non-secure-otp;
 			};
diff --git a/fdts/stm32mp151a-prtt1a.dts b/fdts/stm32mp151a-prtt1a.dts
index 36346208..9742dcb6 100644
--- a/fdts/stm32mp151a-prtt1a.dts
+++ b/fdts/stm32mp151a-prtt1a.dts
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * Copyright (C) 2023, Protonic Holland - All Rights Reserved
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
  * Author: David Jander <david@protonic.nl>
  */
 /dts-v1/;
@@ -123,7 +124,7 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
diff --git a/fdts/stm32mp157a-avenger96.dts b/fdts/stm32mp157a-avenger96.dts
index f0da350b..7135970c 100644
--- a/fdts/stm32mp157a-avenger96.dts
+++ b/fdts/stm32mp157a-avenger96.dts
@@ -175,29 +175,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -228,42 +208,83 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	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_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_480Mhz: pll4-vco-480Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <1 39>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 480.0 MHz => P = 120, Q = 40, R = 96 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <1 39 3 11 4 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_480Mhz>;
+			st,pll_div_pqr = <3 11 4>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index 949c929a..d85221b0 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-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
 /dts-v1/;
@@ -31,7 +31,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
@@ -194,29 +194,8 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
-		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -247,42 +226,82 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	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)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp157c-odyssey-som.dtsi b/fdts/stm32mp157c-odyssey-som.dtsi
index 091e327c..e5d41fc7 100644
--- a/fdts/stm32mp157c-odyssey-som.dtsi
+++ b/fdts/stm32mp157c-odyssey-som.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019, STMicroelectronics. All Rights Reserved.
+ * Copyright (C) 2019-2024, STMicroelectronics. All Rights Reserved.
  * Copyright (C) 2021, Grzegorz Szymaszek.
  *
  * SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
@@ -28,7 +28,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
@@ -207,29 +207,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -260,42 +240,83 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	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_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-dhcom-som.dtsi b/fdts/stm32mp15xx-dhcom-som.dtsi
index 7737a447..46ef0f05 100644
--- a/fdts/stm32mp15xx-dhcom-som.dtsi
+++ b/fdts/stm32mp15xx-dhcom-som.dtsi
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2019-2020 Marek Vasut <marex@denx.de>
  * Copyright (C) 2022 DH electronics GmbH
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  */
 
 #include "stm32mp15-pinctrl.dtsi"
@@ -18,7 +18,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
@@ -193,29 +193,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
-		CLK_MCO2_PLL4P
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		1 /*MCO2*/
-	>;
-
-	st,pkcs = <
+		CLK_MCO2_PLL4
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -246,42 +226,83 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	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_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 1)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_600Mhz: pll4-vco-600hz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <1 49>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 600.0 MHz => P = 50, Q = 50, R = 50 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <1 49 5 11 11 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_600Mhz>;
+			st,pll_div_pqr = <5 11 11>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-dhcor-som.dtsi b/fdts/stm32mp15xx-dhcor-som.dtsi
index 8d829a41..2ebfb2de 100644
--- a/fdts/stm32mp15xx-dhcor-som.dtsi
+++ b/fdts/stm32mp15xx-dhcor-som.dtsi
@@ -4,7 +4,7 @@
  * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
  * Copyright (C) 2020 Marek Vasut <marex@denx.de>
  * Copyright (C) 2022 DH electronics GmbH
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  */
 
 #include "stm32mp15-pinctrl.dtsi"
@@ -188,29 +188,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -241,42 +221,84 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = <2 80 0 0 0 PQR(1,0,0)>;
-		frac = <0x800>;
+	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_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
-	/* VCO = 600.0 MHz => P = 99, Q = 74, R = 99 */
+	/* VCO = 600.0 MHz => P = 99, Q = 74, R = 99 */ /* @TOCHECK */
+	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 5 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi
index f8baa9d4..bac9e053 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-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
  */
 
@@ -29,7 +29,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
@@ -198,29 +198,8 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
-		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -251,42 +230,82 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
+	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)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
 
diff --git a/fdts/stm32mp15xx-osd32.dtsi b/fdts/stm32mp15xx-osd32.dtsi
index 52a5d380..6e27b413 100644
--- a/fdts/stm32mp15xx-osd32.dtsi
+++ b/fdts/stm32mp15xx-osd32.dtsi
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) */
 /*
- * Copyright (C) 2020 STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2020-2024 STMicroelectronics - All Rights Reserved
  * Copyright (C) 2020 Ahmad Fatoum, Pengutronix
  */
 
@@ -157,7 +157,7 @@
 };
 
 &bsec {
-	board_id: board_id@ec {
+	board_id: board-id@ec {
 		reg = <0xec 0x4>;
 		st,non-secure-otp;
 	};
@@ -185,29 +185,9 @@
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
 		CLK_MCU_PLL3P
-		CLK_PLL12_HSE
-		CLK_PLL3_HSE
-		CLK_PLL4_HSE
 		CLK_RTC_LSE
 		CLK_MCO1_DISABLED
 		CLK_MCO2_DISABLED
-	>;
-
-	st,clkdiv = <
-		1 /*MPU*/
-		0 /*AXI*/
-		0 /*MCU*/
-		1 /*APB1*/
-		1 /*APB2*/
-		1 /*APB3*/
-		1 /*APB4*/
-		2 /*APB5*/
-		23 /*RTC*/
-		0 /*MCO1*/
-		0 /*MCO2*/
-	>;
-
-	st,pkcs = <
 		CLK_CKPER_HSE
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
@@ -238,41 +218,82 @@
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_LSI
+		CLK_RNG1_CSI
 		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
 		CLK_LPTIM45_LSE
 	>;
 
-	/* VCO = 1300.0 MHz => P = 650 (CPU) */
-	pll1: st,pll@0 {
-		compatible = "st,stm32mp1-pll";
-		reg = <0>;
-		cfg = < 2 80 0 0 0 PQR(1,0,0) >;
-		frac = < 0x800 >;
+	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_RTC, 23)
+		DIV(DIV_MCO1, 0)
+		DIV(DIV_MCO2, 0)
+	>;
+
+	st,pll_vco {
+		pll2_vco_1066Mhz: pll2-vco-1066Mhz {
+			src = <CLK_PLL12_HSE>;
+			divmn = <2 65>;
+			frac = <0x1400>;
+		};
+
+		pll3_vco_417Mhz: pll3-vco-417Mhz {
+			src = <CLK_PLL3_HSE>;
+			divmn = <1 33>;
+			frac = <0x1a04>;
+		};
+
+		pll4_vco_594Mhz: pll4-vco-594Mhz {
+			src = <CLK_PLL4_HSE>;
+			divmn = <3 98>;
+		};
 	};
 
 	/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
 	pll2: st,pll@1 {
 		compatible = "st,stm32mp1-pll";
 		reg = <1>;
-		cfg = <2 65 1 0 0 PQR(1,1,1)>;
-		frac = <0x1400>;
+
+		st,pll = <&pll2_cfg1>;
+
+		pll2_cfg1: pll2_cfg1 {
+			st,pll_vco = <&pll2_vco_1066Mhz>;
+			st,pll_div_pqr = <1 0 0>;
+		};
 	};
 
 	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
 		compatible = "st,stm32mp1-pll";
 		reg = <2>;
-		cfg = <1 33 1 16 36 PQR(1,1,1)>;
-		frac = <0x1a04>;
+
+		st,pll = <&pll3_cfg1>;
+
+		pll3_cfg1: pll3_cfg1 {
+			st,pll_vco = <&pll3_vco_417Mhz>;
+			st,pll_div_pqr = <1 16 36>;
+		};
 	};
 
 	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
 		compatible = "st,stm32mp1-pll";
 		reg = <3>;
-		cfg = <3 98 5 7 7 PQR(1,1,1)>;
+
+		st,pll = <&pll4_cfg1>;
+
+		pll4_cfg1: pll4_cfg1 {
+			st,pll_vco = <&pll4_vco_594Mhz>;
+			st,pll_div_pqr = <5 7 7>;
+		};
 	};
 };
diff --git a/fdts/stm32mp25-bl2.dtsi b/fdts/stm32mp25-bl2.dtsi
index 438a58ca..e6662d07 100644
--- a/fdts/stm32mp25-bl2.dtsi
+++ b/fdts/stm32mp25-bl2.dtsi
@@ -1,4 +1,39 @@
 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  */
+
+/ {
+	soc@0 {
+#if !STM32MP_EMMC && !STM32MP_SDMMC
+		rifsc@42080000 {
+			/delete-node/ mmc@48220000;
+			/delete-node/ mmc@48230000;
+		};
+#endif
+	};
+
+	/*
+	 * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in
+	 * network order (big endian)
+	 */
+
+	st-io_policies {
+		fip-handles {
+			compatible = "st,io-fip-handle";
+#if STM32MP_DDR_FIP_IO_STORAGE
+			ddr_fw_uuid = "b11249be-92dd-4b10-867c-2c6a4b47a7fb";
+#endif
+			fw_cfg_uuid = "5807e16a-8459-47be-8ed5-648e8dddab0e";
+			bl31_uuid = "47d4086d-4cfe-9846-9b95-2950cbbd5a00";
+			bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38";
+			bl32_extra1_uuid = "0b70c29b-2a5a-7840-9f65-0a5682738288";
+			bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
+			bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
+			hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
+			soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
+			tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
+			nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
+		};
+	};
+};
diff --git a/fdts/stm32mp25-bl31.dtsi b/fdts/stm32mp25-bl31.dtsi
new file mode 100644
index 00000000..fa63f639
--- /dev/null
+++ b/fdts/stm32mp25-bl31.dtsi
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+/ {
+	soc@0 {
+		rifsc@42080000 {
+			/delete-node/ mmc@48220000;
+			/delete-node/ mmc@48230000;
+		};
+	};
+};
diff --git a/fdts/stm32mp25-ddr.dtsi b/fdts/stm32mp25-ddr.dtsi
new file mode 100644
index 00000000..1fcd13dd
--- /dev/null
+++ b/fdts/stm32mp25-ddr.dtsi
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+&ddr{
+	st,mem-name = DDR_MEM_NAME;
+	st,mem-speed = <DDR_MEM_SPEED>;
+	st,mem-size = <(DDR_MEM_SIZE >> 32) (DDR_MEM_SIZE & 0xFFFFFFFF)>;
+
+	st,ctl-reg = <
+		DDR_MSTR
+		DDR_MRCTRL0
+		DDR_MRCTRL1
+		DDR_MRCTRL2
+		DDR_DERATEEN
+		DDR_DERATEINT
+		DDR_DERATECTL
+		DDR_PWRCTL
+		DDR_PWRTMG
+		DDR_HWLPCTL
+		DDR_RFSHCTL0
+		DDR_RFSHCTL1
+		DDR_RFSHCTL3
+		DDR_CRCPARCTL0
+		DDR_CRCPARCTL1
+		DDR_INIT0
+		DDR_INIT1
+		DDR_INIT2
+		DDR_INIT3
+		DDR_INIT4
+		DDR_INIT5
+		DDR_INIT6
+		DDR_INIT7
+		DDR_DIMMCTL
+		DDR_RANKCTL
+		DDR_RANKCTL1
+		DDR_ZQCTL0
+		DDR_ZQCTL1
+		DDR_ZQCTL2
+		DDR_DFITMG0
+		DDR_DFITMG1
+		DDR_DFILPCFG0
+		DDR_DFILPCFG1
+		DDR_DFIUPD0
+		DDR_DFIUPD1
+		DDR_DFIUPD2
+		DDR_DFIMISC
+		DDR_DFITMG2
+		DDR_DFITMG3
+		DDR_DBICTL
+		DDR_DFIPHYMSTR
+		DDR_DBG0
+		DDR_DBG1
+		DDR_DBGCMD
+		DDR_SWCTL
+		DDR_SWCTLSTATIC
+		DDR_POISONCFG
+		DDR_PCCFG
+	>;
+
+	st,ctl-timing = <
+		DDR_RFSHTMG
+		DDR_RFSHTMG1
+		DDR_DRAMTMG0
+		DDR_DRAMTMG1
+		DDR_DRAMTMG2
+		DDR_DRAMTMG3
+		DDR_DRAMTMG4
+		DDR_DRAMTMG5
+		DDR_DRAMTMG6
+		DDR_DRAMTMG7
+		DDR_DRAMTMG8
+		DDR_DRAMTMG9
+		DDR_DRAMTMG10
+		DDR_DRAMTMG11
+		DDR_DRAMTMG12
+		DDR_DRAMTMG13
+		DDR_DRAMTMG14
+		DDR_DRAMTMG15
+		DDR_ODTCFG
+		DDR_ODTMAP
+	>;
+
+	st,ctl-map = <
+		DDR_ADDRMAP0
+		DDR_ADDRMAP1
+		DDR_ADDRMAP2
+		DDR_ADDRMAP3
+		DDR_ADDRMAP4
+		DDR_ADDRMAP5
+		DDR_ADDRMAP6
+		DDR_ADDRMAP7
+		DDR_ADDRMAP8
+		DDR_ADDRMAP9
+		DDR_ADDRMAP10
+		DDR_ADDRMAP11
+	>;
+
+	st,ctl-perf = <
+		DDR_SCHED
+		DDR_SCHED1
+		DDR_PERFHPR1
+		DDR_PERFLPR1
+		DDR_PERFWR1
+		DDR_SCHED3
+		DDR_SCHED4
+		DDR_PCFGR_0
+		DDR_PCFGW_0
+		DDR_PCTRL_0
+		DDR_PCFGQOS0_0
+		DDR_PCFGQOS1_0
+		DDR_PCFGWQOS0_0
+		DDR_PCFGWQOS1_0
+		DDR_PCFGR_1
+		DDR_PCFGW_1
+		DDR_PCTRL_1
+		DDR_PCFGQOS0_1
+		DDR_PCFGQOS1_1
+		DDR_PCFGWQOS0_1
+		DDR_PCFGWQOS1_1
+	>;
+
+	st,phy-basic = <
+		DDR_UIB_DRAMTYPE
+		DDR_UIB_DIMMTYPE
+		DDR_UIB_LP4XMODE
+		DDR_UIB_NUMDBYTE
+		DDR_UIB_NUMACTIVEDBYTEDFI0
+		DDR_UIB_NUMACTIVEDBYTEDFI1
+		DDR_UIB_NUMANIB
+		DDR_UIB_NUMRANK_DFI0
+		DDR_UIB_NUMRANK_DFI1
+		DDR_UIB_DRAMDATAWIDTH
+		DDR_UIB_NUMPSTATES
+		DDR_UIB_FREQUENCY_0
+		DDR_UIB_PLLBYPASS_0
+		DDR_UIB_DFIFREQRATIO_0
+		DDR_UIB_DFI1EXISTS
+		DDR_UIB_TRAIN2D
+		DDR_UIB_HARDMACROVER
+		DDR_UIB_READDBIENABLE_0
+		DDR_UIB_DFIMODE
+	>;
+
+	st,phy-advanced = <
+		DDR_UIA_LP4RXPREAMBLEMODE_0
+		DDR_UIA_LP4POSTAMBLEEXT_0
+		DDR_UIA_D4RXPREAMBLELENGTH_0
+		DDR_UIA_D4TXPREAMBLELENGTH_0
+		DDR_UIA_EXTCALRESVAL
+		DDR_UIA_IS2TTIMING_0
+		DDR_UIA_ODTIMPEDANCE_0
+		DDR_UIA_TXIMPEDANCE_0
+		DDR_UIA_ATXIMPEDANCE
+		DDR_UIA_MEMALERTEN
+		DDR_UIA_MEMALERTPUIMP
+		DDR_UIA_MEMALERTVREFLEVEL
+		DDR_UIA_MEMALERTSYNCBYPASS
+		DDR_UIA_DISDYNADRTRI_0
+		DDR_UIA_PHYMSTRTRAININTERVAL_0
+		DDR_UIA_PHYMSTRMAXREQTOACK_0
+		DDR_UIA_WDQSEXT
+		DDR_UIA_CALINTERVAL
+		DDR_UIA_CALONCE
+		DDR_UIA_LP4RL_0
+		DDR_UIA_LP4WL_0
+		DDR_UIA_LP4WLS_0
+		DDR_UIA_LP4DBIRD_0
+		DDR_UIA_LP4DBIWR_0
+		DDR_UIA_LP4NWR_0
+		DDR_UIA_LP4LOWPOWERDRV
+		DDR_UIA_DRAMBYTESWAP
+		DDR_UIA_RXENBACKOFF
+		DDR_UIA_TRAINSEQUENCECTRL
+		DDR_UIA_SNPSUMCTLOPT
+		DDR_UIA_SNPSUMCTLF0RC5X_0
+		DDR_UIA_TXSLEWRISEDQ_0
+		DDR_UIA_TXSLEWFALLDQ_0
+		DDR_UIA_TXSLEWRISEAC
+		DDR_UIA_TXSLEWFALLAC
+		DDR_UIA_DISABLERETRAINING
+		DDR_UIA_DISABLEPHYUPDATE
+		DDR_UIA_ENABLEHIGHCLKSKEWFIX
+		DDR_UIA_DISABLEUNUSEDADDRLNS
+		DDR_UIA_PHYINITSEQUENCENUM
+		DDR_UIA_ENABLEDFICSPOLARITYFIX
+		DDR_UIA_PHYVREF
+		DDR_UIA_SEQUENCECTRL_0
+	>;
+
+	st,phy-mr = <
+		DDR_UIM_MR0_0
+		DDR_UIM_MR1_0
+		DDR_UIM_MR2_0
+		DDR_UIM_MR3_0
+		DDR_UIM_MR4_0
+		DDR_UIM_MR5_0
+		DDR_UIM_MR6_0
+		DDR_UIM_MR11_0
+		DDR_UIM_MR12_0
+		DDR_UIM_MR13_0
+		DDR_UIM_MR14_0
+		DDR_UIM_MR22_0
+	>;
+
+	st,phy-swizzle = <
+		DDR_UIS_SWIZZLE_0
+		DDR_UIS_SWIZZLE_1
+		DDR_UIS_SWIZZLE_2
+		DDR_UIS_SWIZZLE_3
+		DDR_UIS_SWIZZLE_4
+		DDR_UIS_SWIZZLE_5
+		DDR_UIS_SWIZZLE_6
+		DDR_UIS_SWIZZLE_7
+		DDR_UIS_SWIZZLE_8
+		DDR_UIS_SWIZZLE_9
+		DDR_UIS_SWIZZLE_10
+		DDR_UIS_SWIZZLE_11
+		DDR_UIS_SWIZZLE_12
+		DDR_UIS_SWIZZLE_13
+		DDR_UIS_SWIZZLE_14
+		DDR_UIS_SWIZZLE_15
+		DDR_UIS_SWIZZLE_16
+		DDR_UIS_SWIZZLE_17
+		DDR_UIS_SWIZZLE_18
+		DDR_UIS_SWIZZLE_19
+		DDR_UIS_SWIZZLE_20
+		DDR_UIS_SWIZZLE_21
+		DDR_UIS_SWIZZLE_22
+		DDR_UIS_SWIZZLE_23
+		DDR_UIS_SWIZZLE_24
+		DDR_UIS_SWIZZLE_25
+		DDR_UIS_SWIZZLE_26
+		DDR_UIS_SWIZZLE_27
+		DDR_UIS_SWIZZLE_28
+		DDR_UIS_SWIZZLE_29
+		DDR_UIS_SWIZZLE_30
+		DDR_UIS_SWIZZLE_31
+		DDR_UIS_SWIZZLE_32
+		DDR_UIS_SWIZZLE_33
+		DDR_UIS_SWIZZLE_34
+		DDR_UIS_SWIZZLE_35
+		DDR_UIS_SWIZZLE_36
+		DDR_UIS_SWIZZLE_37
+		DDR_UIS_SWIZZLE_38
+		DDR_UIS_SWIZZLE_39
+		DDR_UIS_SWIZZLE_40
+		DDR_UIS_SWIZZLE_41
+		DDR_UIS_SWIZZLE_42
+		DDR_UIS_SWIZZLE_43
+	>;
+};
diff --git a/fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi b/fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi
new file mode 100644
index 00000000..3d69448a
--- /dev/null
+++ b/fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 DDR4 board configuration
+ * DDR4 2x16Gbits 2x16bits 1200MHz
+ *
+ * version      2
+ * package      1        Package selection (14x14 and 18x18)
+ * memclk       1200MHz  (2x DFI clock) + range check
+ * Speed_Bin    Worse    from JEDEC
+ * device_width 16       x16 by default
+ * width        32       32: full width / 16: half width
+ * density      16Gbits  (per 16bit device)
+ * Addressing   RBC      row/bank interleaving
+ * RDBI         No       Read DBI
+ */
+
+#define DDR_MEM_NAME	"DDR4 2x16Gbits 2x16bits 1200MHz"
+#define DDR_MEM_SPEED	1200000
+#define DDR_MEM_SIZE	0x100000000
+
+#define DDR_MSTR 0x01040010
+#define DDR_MRCTRL0 0x00000030
+#define DDR_MRCTRL1 0x00000000
+#define DDR_MRCTRL2 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00000000
+#define DDR_DERATECTL 0x00000000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00130001
+#define DDR_HWLPCTL 0x00000002
+#define DDR_RFSHCTL0 0x00210010
+#define DDR_RFSHCTL1 0x00000000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0092014A
+#define DDR_RFSHTMG1 0x008C0000
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_CRCPARCTL1 0x00001000
+#define DDR_INIT0 0xC0020002
+#define DDR_INIT1 0x00010002
+#define DDR_INIT2 0x00000D00
+#define DDR_INIT3 0x09400103
+#define DDR_INIT4 0x00180000
+#define DDR_INIT5 0x00100004
+#define DDR_INIT6 0x00080460
+#define DDR_INIT7 0x00000C16
+#define DDR_DIMMCTL 0x00000000
+#define DDR_RANKCTL 0x0000066F
+#define DDR_RANKCTL1 0x0000000D
+#define DDR_DRAMTMG0 0x11152815
+#define DDR_DRAMTMG1 0x0004051E
+#define DDR_DRAMTMG2 0x0609060D
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x0904050A
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020005
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x0606100B
+#define DDR_DRAMTMG9 0x0002040A
+#define DDR_DRAMTMG10 0x001C180A
+#define DDR_DRAMTMG11 0x4408021C
+#define DDR_DRAMTMG12 0x0C020010
+#define DDR_DRAMTMG13 0x1C200004
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_DRAMTMG15 0x00000000
+#define DDR_ZQCTL0 0x01000040
+#define DDR_ZQCTL1 0x2000493E
+#define DDR_ZQCTL2 0x00000000
+#define DDR_DFITMG0 0x038F8209
+#define DDR_DFITMG1 0x00080303
+#define DDR_DFILPCFG0 0x07004111
+#define DDR_DFILPCFG1 0x00000000
+#define DDR_DFIUPD0 0xC0300018
+#define DDR_DFIUPD1 0x005700B4
+#define DDR_DFIUPD2 0x80000000
+#define DDR_DFIMISC 0x00000041
+#define DDR_DFITMG2 0x00000F09
+#define DDR_DFITMG3 0x00000000
+#define DDR_DBICTL 0x00000001
+#define DDR_DFIPHYMSTR 0x80000000
+#define DDR_ADDRMAP0 0x0000001F
+#define DDR_ADDRMAP1 0x003F0909
+#define DDR_ADDRMAP2 0x00000700
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x070F0707
+#define DDR_ADDRMAP6 0x07070707
+#define DDR_ADDRMAP7 0x00000F07
+#define DDR_ADDRMAP8 0x00003F01
+#define DDR_ADDRMAP9 0x07070707
+#define DDR_ADDRMAP10 0x07070707
+#define DDR_ADDRMAP11 0x00000007
+#define DDR_ODTCFG 0x06000618
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x80001B00
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x04000200
+#define DDR_PERFLPR1 0x08000080
+#define DDR_PERFWR1 0x08000400
+#define DDR_SCHED3 0x04040208
+#define DDR_SCHED4 0x08400810
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_SWCTL 0x00000000
+#define DDR_SWCTLSTATIC 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000000
+#define DDR_PCFGR_0 0x00704100
+#define DDR_PCFGW_0 0x00004100
+#define DDR_PCTRL_0 0x00000000
+#define DDR_PCFGQOS0_0 0x0021000C
+#define DDR_PCFGQOS1_0 0x01000080
+#define DDR_PCFGWQOS0_0 0x01100C07
+#define DDR_PCFGWQOS1_0 0x04000200
+#define DDR_PCFGR_1 0x00704100
+#define DDR_PCFGW_1 0x00004100
+#define DDR_PCTRL_1 0x00000000
+#define DDR_PCFGQOS0_1 0x00100007
+#define DDR_PCFGQOS1_1 0x01000080
+#define DDR_PCFGWQOS0_1 0x01100C07
+#define DDR_PCFGWQOS1_1 0x04000200
+
+#define DDR_UIB_DRAMTYPE 0x00000000
+#define DDR_UIB_DIMMTYPE 0x00000004
+#define DDR_UIB_LP4XMODE 0x00000000
+#define DDR_UIB_NUMDBYTE 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI0 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI1 0x00000000
+#define DDR_UIB_NUMANIB 0x00000008
+#define DDR_UIB_NUMRANK_DFI0 0x00000001
+#define DDR_UIB_NUMRANK_DFI1 0x00000001
+#define DDR_UIB_DRAMDATAWIDTH 0x00000010
+#define DDR_UIB_NUMPSTATES 0x00000001
+#define DDR_UIB_FREQUENCY_0 0x000004B0
+#define DDR_UIB_PLLBYPASS_0 0x00000000
+#define DDR_UIB_DFIFREQRATIO_0 0x00000001
+#define DDR_UIB_DFI1EXISTS 0x00000001
+#define DDR_UIB_TRAIN2D 0x00000000
+#define DDR_UIB_HARDMACROVER 0x00000003
+#define DDR_UIB_READDBIENABLE_0 0x00000000
+#define DDR_UIB_DFIMODE 0x00000000
+
+#define DDR_UIA_LP4RXPREAMBLEMODE_0 0x00000000
+#define DDR_UIA_LP4POSTAMBLEEXT_0 0x00000000
+#define DDR_UIA_D4RXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_D4TXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_EXTCALRESVAL 0x00000000
+#define DDR_UIA_IS2TTIMING_0 0x00000000
+#define DDR_UIA_ODTIMPEDANCE_0 0x00000035
+#define DDR_UIA_TXIMPEDANCE_0 0x00000028
+#define DDR_UIA_ATXIMPEDANCE 0x00000028
+#define DDR_UIA_MEMALERTEN 0x00000000
+#define DDR_UIA_MEMALERTPUIMP 0x00000000
+#define DDR_UIA_MEMALERTVREFLEVEL 0x00000000
+#define DDR_UIA_MEMALERTSYNCBYPASS 0x00000000
+#define DDR_UIA_DISDYNADRTRI_0 0x00000001
+#define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x00000000
+#define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000000
+#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_CALINTERVAL 0x00000009
+#define DDR_UIA_CALONCE 0x00000000
+#define DDR_UIA_LP4RL_0 0x00000000
+#define DDR_UIA_LP4WL_0 0x00000000
+#define DDR_UIA_LP4WLS_0 0x00000000
+#define DDR_UIA_LP4DBIRD_0 0x00000000
+#define DDR_UIA_LP4DBIWR_0 0x00000000
+#define DDR_UIA_LP4NWR_0 0x00000000
+#define DDR_UIA_LP4LOWPOWERDRV 0x00000000
+#define DDR_UIA_DRAMBYTESWAP 0x00000000
+#define DDR_UIA_RXENBACKOFF 0x00000000
+#define DDR_UIA_TRAINSEQUENCECTRL 0x00000000
+#define DDR_UIA_SNPSUMCTLOPT 0x00000000
+#define DDR_UIA_SNPSUMCTLF0RC5X_0 0x00000000
+#define DDR_UIA_TXSLEWRISEDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWFALLDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWRISEAC 0x0000000F
+#define DDR_UIA_TXSLEWFALLAC 0x0000000F
+#define DDR_UIA_DISABLERETRAINING 0x00000001
+#define DDR_UIA_DISABLEPHYUPDATE 0x00000000
+#define DDR_UIA_ENABLEHIGHCLKSKEWFIX 0x00000000
+#define DDR_UIA_DISABLEUNUSEDADDRLNS 0x00000001
+#define DDR_UIA_PHYINITSEQUENCENUM 0x00000000
+#define DDR_UIA_ENABLEDFICSPOLARITYFIX 0x00000000
+#define DDR_UIA_PHYVREF 0x0000005E
+#define DDR_UIA_SEQUENCECTRL_0 0x0000031F
+
+#define DDR_UIM_MR0_0 0x00000940
+#define DDR_UIM_MR1_0 0x00000103
+#define DDR_UIM_MR2_0 0x00000018
+#define DDR_UIM_MR3_0 0x00000000
+#define DDR_UIM_MR4_0 0x00000008
+#define DDR_UIM_MR5_0 0x00000460
+#define DDR_UIM_MR6_0 0x00000C16
+#define DDR_UIM_MR11_0 0x00000000
+#define DDR_UIM_MR12_0 0x00000000
+#define DDR_UIM_MR13_0 0x00000000
+#define DDR_UIM_MR14_0 0x00000000
+#define DDR_UIM_MR22_0 0x00000000
+
+#define DDR_UIS_SWIZZLE_0 0x0000000C
+#define DDR_UIS_SWIZZLE_1 0x00000005
+#define DDR_UIS_SWIZZLE_2 0x00000013
+#define DDR_UIS_SWIZZLE_3 0x0000001A
+#define DDR_UIS_SWIZZLE_4 0x00000009
+#define DDR_UIS_SWIZZLE_5 0x00000003
+#define DDR_UIS_SWIZZLE_6 0x00000001
+#define DDR_UIS_SWIZZLE_7 0x00000019
+#define DDR_UIS_SWIZZLE_8 0x00000007
+#define DDR_UIS_SWIZZLE_9 0x00000004
+#define DDR_UIS_SWIZZLE_10 0x0000000A
+#define DDR_UIS_SWIZZLE_11 0x0000000D
+#define DDR_UIS_SWIZZLE_12 0x00000014
+#define DDR_UIS_SWIZZLE_13 0x00000000
+#define DDR_UIS_SWIZZLE_14 0x00000000
+#define DDR_UIS_SWIZZLE_15 0x00000000
+#define DDR_UIS_SWIZZLE_16 0x00000000
+#define DDR_UIS_SWIZZLE_17 0x00000000
+#define DDR_UIS_SWIZZLE_18 0x00000006
+#define DDR_UIS_SWIZZLE_19 0x0000000B
+#define DDR_UIS_SWIZZLE_20 0x00000000
+#define DDR_UIS_SWIZZLE_21 0x00000000
+#define DDR_UIS_SWIZZLE_22 0x00000000
+#define DDR_UIS_SWIZZLE_23 0x00000008
+#define DDR_UIS_SWIZZLE_24 0x00000002
+#define DDR_UIS_SWIZZLE_25 0x00000018
+#define DDR_UIS_SWIZZLE_26 0x1A13050C
+#define DDR_UIS_SWIZZLE_27 0x19010309
+#define DDR_UIS_SWIZZLE_28 0x0D0A0407
+#define DDR_UIS_SWIZZLE_29 0x00000014
+#define DDR_UIS_SWIZZLE_30 0x000B0600
+#define DDR_UIS_SWIZZLE_31 0x02080000
+#define DDR_UIS_SWIZZLE_32 0x00000018
+#define DDR_UIS_SWIZZLE_33 0x00000000
+#define DDR_UIS_SWIZZLE_34 0x00000000
+#define DDR_UIS_SWIZZLE_35 0x00000000
+#define DDR_UIS_SWIZZLE_36 0x00000000
+#define DDR_UIS_SWIZZLE_37 0x00000000
+#define DDR_UIS_SWIZZLE_38 0x00000000
+#define DDR_UIS_SWIZZLE_39 0x00000000
+#define DDR_UIS_SWIZZLE_40 0x00000000
+#define DDR_UIS_SWIZZLE_41 0x00000000
+#define DDR_UIS_SWIZZLE_42 0x00000000
+#define DDR_UIS_SWIZZLE_43 0x00000000
+
+#include "stm32mp25-ddr.dtsi"
diff --git a/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi b/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
new file mode 100644
index 00000000..674cb3da
--- /dev/null
+++ b/fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 DDR4 board configuration
+ * DDR4 2x8Gbits 2x16bits 1200MHz
+ *
+ * version     1
+ * package     1        Package selection (14x14 and 18x18)
+ * memclk      1200MHz  (2x DFI clock) + range check
+ * Speed_Bin   Worse    from JEDEC
+ * width       32       32: full width / 16: half width
+ * ranks       1        Single or Dual rank
+ * density     8Gbits   (per 16bit device)
+ * Addressing  RBC      row/bank interleaving
+ * RDBI        No       Read DBI
+ */
+
+#define DDR_MEM_NAME	"DDR4 2x8Gbits 2x16bits 1200MHz"
+#define DDR_MEM_SPEED	1200000
+#define DDR_MEM_SIZE	0x80000000
+
+#define DDR_MSTR 0x01040010
+#define DDR_MRCTRL0 0x00000030
+#define DDR_MRCTRL1 0x00000000
+#define DDR_MRCTRL2 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00000000
+#define DDR_DERATECTL 0x00000000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00130001
+#define DDR_HWLPCTL 0x00000002
+#define DDR_RFSHCTL0 0x00210010
+#define DDR_RFSHCTL1 0x00000000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x009200D2
+#define DDR_RFSHTMG1 0x008C0000
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_CRCPARCTL1 0x00001000
+#define DDR_INIT0 0xC0020002
+#define DDR_INIT1 0x00010002
+#define DDR_INIT2 0x00000D00
+#define DDR_INIT3 0x09400103
+#define DDR_INIT4 0x00180000
+#define DDR_INIT5 0x00100004
+#define DDR_INIT6 0x00080460
+#define DDR_INIT7 0x00000C16
+#define DDR_DIMMCTL 0x00000000
+#define DDR_RANKCTL 0x0000066F
+#define DDR_DRAMTMG0 0x11152815
+#define DDR_DRAMTMG1 0x0004051E
+#define DDR_DRAMTMG2 0x0609060D
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x0904050A
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020005
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x04041007
+#define DDR_DRAMTMG9 0x0002040A
+#define DDR_DRAMTMG10 0x001C180A
+#define DDR_DRAMTMG11 0x4408021C
+#define DDR_DRAMTMG12 0x0C020010
+#define DDR_DRAMTMG13 0x1C200004
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_DRAMTMG15 0x00000000
+#define DDR_ZQCTL0 0x01000040
+#define DDR_ZQCTL1 0x2000493E
+#define DDR_ZQCTL2 0x00000000
+#define DDR_DFITMG0 0x038F8209
+#define DDR_DFITMG1 0x00080303
+#define DDR_DFILPCFG0 0x07004111
+#define DDR_DFILPCFG1 0x00000000
+#define DDR_DFIUPD0 0xC0300018
+#define DDR_DFIUPD1 0x005700B4
+#define DDR_DFIUPD2 0x80000000
+#define DDR_DFIMISC 0x00000041
+#define DDR_DFITMG2 0x00000F09
+#define DDR_DFITMG3 0x00000000
+#define DDR_DBICTL 0x00000001
+#define DDR_DFIPHYMSTR 0x80000000
+#define DDR_ADDRMAP0 0x0000001F
+#define DDR_ADDRMAP1 0x003F0909
+#define DDR_ADDRMAP2 0x00000700
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x070F0707
+#define DDR_ADDRMAP6 0x07070707
+#define DDR_ADDRMAP7 0x00000F0F
+#define DDR_ADDRMAP8 0x00003F01
+#define DDR_ADDRMAP9 0x07070707
+#define DDR_ADDRMAP10 0x07070707
+#define DDR_ADDRMAP11 0x00000007
+#define DDR_ODTCFG 0x06000618
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00000F00
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x0F000001
+#define DDR_PERFLPR1 0x0F000080
+#define DDR_PERFWR1 0x01000200
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_SWCTL 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000000
+#define DDR_PCFGR_0 0x00004100
+#define DDR_PCFGW_0 0x00004100
+#define DDR_PCTRL_0 0x00000000
+#define DDR_PCFGQOS0_0 0x00200007
+#define DDR_PCFGQOS1_0 0x01000100
+#define DDR_PCFGWQOS0_0 0x00000C07
+#define DDR_PCFGWQOS1_0 0x02000200
+#define DDR_PCFGR_1 0x00004100
+#define DDR_PCFGW_1 0x00004100
+#define DDR_PCTRL_1 0x00000000
+#define DDR_PCFGQOS0_1 0x00200007
+#define DDR_PCFGQOS1_1 0x01000180
+#define DDR_PCFGWQOS0_1 0x00000C07
+#define DDR_PCFGWQOS1_1 0x04000400
+
+#define DDR_UIB_DRAMTYPE 0x00000000
+#define DDR_UIB_DIMMTYPE 0x00000004
+#define DDR_UIB_LP4XMODE 0x00000000
+#define DDR_UIB_NUMDBYTE 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI0 0x00000004
+#define DDR_UIB_NUMACTIVEDBYTEDFI1 0x00000000
+#define DDR_UIB_NUMANIB 0x00000008
+#define DDR_UIB_NUMRANK_DFI0 0x00000001
+#define DDR_UIB_NUMRANK_DFI1 0x00000001
+#define DDR_UIB_DRAMDATAWIDTH 0x00000010
+#define DDR_UIB_NUMPSTATES 0x00000001
+#define DDR_UIB_FREQUENCY_0 0x000004B0
+#define DDR_UIB_PLLBYPASS_0 0x00000000
+#define DDR_UIB_DFIFREQRATIO_0 0x00000001
+#define DDR_UIB_DFI1EXISTS 0x00000001
+#define DDR_UIB_TRAIN2D 0x00000000
+#define DDR_UIB_HARDMACROVER 0x00000003
+#define DDR_UIB_READDBIENABLE_0 0x00000000
+#define DDR_UIB_DFIMODE 0x00000000
+
+#define DDR_UIA_LP4RXPREAMBLEMODE_0 0x00000000
+#define DDR_UIA_LP4POSTAMBLEEXT_0 0x00000000
+#define DDR_UIA_D4RXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_D4TXPREAMBLELENGTH_0 0x00000000
+#define DDR_UIA_EXTCALRESVAL 0x00000000
+#define DDR_UIA_IS2TTIMING_0 0x00000000
+#define DDR_UIA_ODTIMPEDANCE_0 0x00000035
+#define DDR_UIA_TXIMPEDANCE_0 0x00000028
+#define DDR_UIA_ATXIMPEDANCE 0x00000028
+#define DDR_UIA_MEMALERTEN 0x00000000
+#define DDR_UIA_MEMALERTPUIMP 0x00000000
+#define DDR_UIA_MEMALERTVREFLEVEL 0x00000000
+#define DDR_UIA_MEMALERTSYNCBYPASS 0x00000000
+#define DDR_UIA_DISDYNADRTRI_0 0x00000001
+#define DDR_UIA_PHYMSTRTRAININTERVAL_0 0x00000000
+#define DDR_UIA_PHYMSTRMAXREQTOACK_0 0x00000000
+#define DDR_UIA_WDQSEXT 0x00000000
+#define DDR_UIA_CALINTERVAL 0x00000009
+#define DDR_UIA_CALONCE 0x00000000
+#define DDR_UIA_LP4RL_0 0x00000000
+#define DDR_UIA_LP4WL_0 0x00000000
+#define DDR_UIA_LP4WLS_0 0x00000000
+#define DDR_UIA_LP4DBIRD_0 0x00000000
+#define DDR_UIA_LP4DBIWR_0 0x00000000
+#define DDR_UIA_LP4NWR_0 0x00000000
+#define DDR_UIA_LP4LOWPOWERDRV 0x00000000
+#define DDR_UIA_DRAMBYTESWAP 0x00000000
+#define DDR_UIA_RXENBACKOFF 0x00000000
+#define DDR_UIA_TRAINSEQUENCECTRL 0x00000000
+#define DDR_UIA_SNPSUMCTLOPT 0x00000000
+#define DDR_UIA_SNPSUMCTLF0RC5X_0 0x00000000
+#define DDR_UIA_TXSLEWRISEDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWFALLDQ_0 0x0000000F
+#define DDR_UIA_TXSLEWRISEAC 0x0000000F
+#define DDR_UIA_TXSLEWFALLAC 0x0000000F
+#define DDR_UIA_DISABLERETRAINING 0x00000001
+#define DDR_UIA_DISABLEPHYUPDATE 0x00000000
+#define DDR_UIA_ENABLEHIGHCLKSKEWFIX 0x00000000
+#define DDR_UIA_DISABLEUNUSEDADDRLNS 0x00000001
+#define DDR_UIA_PHYINITSEQUENCENUM 0x00000000
+#define DDR_UIA_ENABLEDFICSPOLARITYFIX 0x00000000
+#define DDR_UIA_PHYVREF 0x0000005E
+#define DDR_UIA_SEQUENCECTRL_0 0x0000031F
+
+#define DDR_UIM_MR0_0 0x00000940
+#define DDR_UIM_MR1_0 0x00000103
+#define DDR_UIM_MR2_0 0x00000018
+#define DDR_UIM_MR3_0 0x00000000
+#define DDR_UIM_MR4_0 0x00000008
+#define DDR_UIM_MR5_0 0x00000460
+#define DDR_UIM_MR6_0 0x00000C16
+#define DDR_UIM_MR11_0 0x00000000
+#define DDR_UIM_MR12_0 0x00000000
+#define DDR_UIM_MR13_0 0x00000000
+#define DDR_UIM_MR14_0 0x00000000
+#define DDR_UIM_MR22_0 0x00000000
+
+#define DDR_UIS_SWIZZLE_0 0x0000000C
+#define DDR_UIS_SWIZZLE_1 0x00000005
+#define DDR_UIS_SWIZZLE_2 0x00000013
+#define DDR_UIS_SWIZZLE_3 0x0000001A
+#define DDR_UIS_SWIZZLE_4 0x00000009
+#define DDR_UIS_SWIZZLE_5 0x00000003
+#define DDR_UIS_SWIZZLE_6 0x00000001
+#define DDR_UIS_SWIZZLE_7 0x00000019
+#define DDR_UIS_SWIZZLE_8 0x00000007
+#define DDR_UIS_SWIZZLE_9 0x00000004
+#define DDR_UIS_SWIZZLE_10 0x0000000A
+#define DDR_UIS_SWIZZLE_11 0x0000000D
+#define DDR_UIS_SWIZZLE_12 0x00000014
+#define DDR_UIS_SWIZZLE_13 0x00000000
+#define DDR_UIS_SWIZZLE_14 0x00000000
+#define DDR_UIS_SWIZZLE_15 0x00000000
+#define DDR_UIS_SWIZZLE_16 0x00000000
+#define DDR_UIS_SWIZZLE_17 0x00000000
+#define DDR_UIS_SWIZZLE_18 0x00000006
+#define DDR_UIS_SWIZZLE_19 0x0000000B
+#define DDR_UIS_SWIZZLE_20 0x00000000
+#define DDR_UIS_SWIZZLE_21 0x00000000
+#define DDR_UIS_SWIZZLE_22 0x00000000
+#define DDR_UIS_SWIZZLE_23 0x00000008
+#define DDR_UIS_SWIZZLE_24 0x00000002
+#define DDR_UIS_SWIZZLE_25 0x00000018
+#define DDR_UIS_SWIZZLE_26 0x1A13050C
+#define DDR_UIS_SWIZZLE_27 0x19010309
+#define DDR_UIS_SWIZZLE_28 0x0D0A0407
+#define DDR_UIS_SWIZZLE_29 0x00000014
+#define DDR_UIS_SWIZZLE_30 0x000B0600
+#define DDR_UIS_SWIZZLE_31 0x02080000
+#define DDR_UIS_SWIZZLE_32 0x00000018
+#define DDR_UIS_SWIZZLE_33 0x00000000
+#define DDR_UIS_SWIZZLE_34 0x00000000
+#define DDR_UIS_SWIZZLE_35 0x00000000
+#define DDR_UIS_SWIZZLE_36 0x00000000
+#define DDR_UIS_SWIZZLE_37 0x00000000
+#define DDR_UIS_SWIZZLE_38 0x00000000
+#define DDR_UIS_SWIZZLE_39 0x00000000
+#define DDR_UIS_SWIZZLE_40 0x00000000
+#define DDR_UIS_SWIZZLE_41 0x00000000
+#define DDR_UIS_SWIZZLE_42 0x00000000
+#define DDR_UIS_SWIZZLE_43 0x00000000
+
+#include "stm32mp25-ddr.dtsi"
diff --git a/fdts/stm32mp25-fw-config.dtsi b/fdts/stm32mp25-fw-config.dtsi
new file mode 100644
index 00000000..2f83f24e
--- /dev/null
+++ b/fdts/stm32mp25-fw-config.dtsi
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+#include <platform_def.h>
+
+/dts-v1/;
+
+/ {
+	dtb-registry {
+		compatible = "fconf,dyn_cfg-dtb_registry";
+
+		hw-config {
+			load-address = <0x0 STM32MP_HW_CONFIG_BASE>;
+			max-size = <STM32MP_HW_CONFIG_MAX_SIZE>;
+			id = <HW_CONFIG_ID>;
+		};
+
+		nt_fw {
+			load-address = <0x0 STM32MP_BL33_BASE>;
+			max-size = <STM32MP_BL33_MAX_SIZE>;
+			id = <BL33_IMAGE_ID>;
+		};
+
+		soc_fw {
+			load-address = <0x0 STM32MP_SYSRAM_BASE>;
+			max-size = <STM32MP_BL31_SIZE>;
+			id = <BL31_IMAGE_ID>;
+		};
+
+		soc_fw-config {
+			id = <SOC_FW_CONFIG_ID>;
+		};
+
+		tos_fw {
+			id = <BL32_IMAGE_ID>;
+		};
+	};
+};
diff --git a/fdts/stm32mp25-pinctrl.dtsi b/fdts/stm32mp25-pinctrl.dtsi
index 05876a39..a22c8239 100644
--- a/fdts/stm32mp25-pinctrl.dtsi
+++ b/fdts/stm32mp25-pinctrl.dtsi
@@ -1,11 +1,75 @@
 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
 
 &pinctrl {
+	/omit-if-no-ref/
+	i2c7_pins_a: i2c7-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('D', 15, AF10)>, /* I2C7_SCL */
+				 <STM32_PINMUX('D', 14, AF10)>; /* I2C7_SDA */
+			bias-disable;
+			drive-open-drain;
+			slew-rate = <0>;
+		};
+	};
+
+	/omit-if-no-ref/
+	sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
+				 <STM32_PINMUX('E', 5, AF10)>, /* SDMMC1_D1 */
+				 <STM32_PINMUX('E', 0, AF10)>, /* SDMMC1_D2 */
+				 <STM32_PINMUX('E', 1, AF10)>, /* SDMMC1_D3 */
+				 <STM32_PINMUX('E', 2, AF10)>; /* SDMMC1_CMD */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-disable;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC1_CK */
+			slew-rate = <3>;
+			drive-push-pull;
+			bias-disable;
+		};
+	};
+
+	/omit-if-no-ref/
+	sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('E', 13, AF12)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('E', 11, AF12)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('E', 8, AF12)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('E', 12, AF12)>, /* SDMMC2_D3 */
+				 <STM32_PINMUX('E', 15, AF12)>; /* SDMMC2_CMD */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('E', 14, AF12)>; /* SDMMC2_CK */
+			slew-rate = <3>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+	};
+
+	/omit-if-no-ref/
+	sdmmc2_d47_pins_a: sdmmc2-d47-0 {
+		pins {
+			pinmux = <STM32_PINMUX('E', 10, AF12)>, /* SDMMC2_D4 */
+				 <STM32_PINMUX('E', 9, AF12)>, /* SDMMC2_D5 */
+				 <STM32_PINMUX('E', 6, AF12)>, /* SDMMC2_D6 */
+				 <STM32_PINMUX('E', 7, AF12)>; /* SDMMC2_D7 */
+			slew-rate = <2>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+	};
+
 	/omit-if-no-ref/
 	usart2_pins_a: usart2-0 {
 		pins1 {
diff --git a/fdts/stm32mp251.dtsi b/fdts/stm32mp251.dtsi
index f55a3b97..c2c27644 100644
--- a/fdts/stm32mp251.dtsi
+++ b/fdts/stm32mp251.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 
@@ -97,6 +97,198 @@
 				resets = <&rcc USART2_R>;
 				status = "disabled";
 			};
+
+			usart3: serial@400f0000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x400f0000 0x400>;
+				clocks = <&rcc CK_KER_USART3>;
+				resets = <&rcc USART3_R>;
+				status = "disabled";
+			};
+
+			uart4: serial@40100000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40100000 0x400>;
+				clocks = <&rcc CK_KER_UART4>;
+				resets = <&rcc UART4_R>;
+				status = "disabled";
+			};
+
+			uart5: serial@40110000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40110000 0x400>;
+				clocks = <&rcc CK_KER_UART5>;
+				resets = <&rcc UART5_R>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@40120000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40120000 0x400>;
+				clocks = <&rcc CK_KER_I2C1>;
+				resets = <&rcc I2C1_R>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@40130000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40130000 0x400>;
+				clocks = <&rcc CK_KER_I2C2>;
+				resets = <&rcc I2C2_R>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@40140000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40140000 0x400>;
+				clocks = <&rcc CK_KER_I2C3>;
+				resets = <&rcc I2C3_R>;
+				status = "disabled";
+			};
+
+			i2c4: i2c@40150000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40150000 0x400>;
+				clocks = <&rcc CK_KER_I2C4>;
+				resets = <&rcc I2C4_R>;
+				status = "disabled";
+			};
+
+			i2c5: i2c@40160000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40160000 0x400>;
+				clocks = <&rcc CK_KER_I2C5>;
+				resets = <&rcc I2C5_R>;
+				status = "disabled";
+			};
+
+			i2c6: i2c@40170000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40170000 0x400>;
+				clocks = <&rcc CK_KER_I2C6>;
+				resets = <&rcc I2C6_R>;
+				status = "disabled";
+			};
+
+			i2c7: i2c@40180000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x40180000 0x400>;
+				clocks = <&rcc CK_KER_I2C7>;
+				resets = <&rcc I2C7_R>;
+				status = "disabled";
+			};
+
+			usart6: serial@40220000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40220000 0x400>;
+				clocks = <&rcc CK_KER_USART6>;
+				resets = <&rcc USART6_R>;
+				status = "disabled";
+			};
+
+			uart9: serial@402c0000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x402c0000 0x400>;
+				clocks = <&rcc CK_KER_UART9>;
+				resets = <&rcc UART9_R>;
+				status = "disabled";
+			};
+
+			usart1: serial@40330000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40330000 0x400>;
+				clocks = <&rcc CK_KER_USART1>;
+				resets = <&rcc USART1_R>;
+				status = "disabled";
+			};
+
+			uart7: serial@40370000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40370000 0x400>;
+				clocks = <&rcc CK_KER_UART7>;
+				resets = <&rcc UART7_R>;
+				status = "disabled";
+			};
+
+			uart8: serial@40380000 {
+				compatible = "st,stm32h7-uart";
+				reg = <0x40380000 0x400>;
+				clocks = <&rcc CK_KER_UART8>;
+				resets = <&rcc UART8_R>;
+				status = "disabled";
+			};
+
+			i2c8: i2c@46040000 {
+				compatible = "st,stm32mp25-i2c";
+				reg = <0x46040000 0x400>;
+				clocks = <&rcc CK_KER_I2C8>;
+				resets = <&rcc I2C8_R>;
+				status = "disabled";
+			};
+
+			sdmmc1: mmc@48220000 {
+				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
+				arm,primecell-periphid = <0x00353180>;
+				reg = <0x48220000 0x400>, <0x44230400 0x8>;
+				clocks = <&rcc CK_KER_SDMMC1>;
+				clock-names = "apb_pclk";
+				resets = <&rcc SDMMC1_R>;
+				cap-sd-highspeed;
+				cap-mmc-highspeed;
+				max-frequency = <120000000>;
+				status = "disabled";
+			};
+
+			sdmmc2: mmc@48230000 {
+				compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell";
+				arm,primecell-periphid = <0x00353180>;
+				reg = <0x48230000 0x400>, <0x44230800 0x8>;
+				clocks = <&rcc CK_KER_SDMMC2>;
+				clock-names = "apb_pclk";
+				resets = <&rcc SDMMC2_R>;
+				cap-sd-highspeed;
+				cap-mmc-highspeed;
+				max-frequency = <120000000>;
+				status = "disabled";
+			};
+		};
+
+		bsec: efuse@44000000 {
+			compatible = "st,stm32mp25-bsec";
+			reg = <0x44000000 0x400>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			uid_otp: uid-otp@14 {
+				reg = <0x14 0xc>;
+			};
+			part_number_otp: part-number-otp@24 {
+				reg = <0x24 0x4>;
+			};
+			nand_otp: otp16@40 {
+				reg = <0x40 0x4>;
+			};
+			lifecycle2_otp: otp18@48 {
+				reg = <0x48 0x4>;
+			};
+			nand2_otp: otp20@50 {
+				reg = <0x50 0x4>;
+			};
+			rev_otp@198 {
+				reg = <0x198 0x4>;
+			};
+			package_otp: package-otp@1e8 {
+				reg = <0x1e8 0x1>;
+			};
+			hconf1_otp: otp124@1f0 {
+				reg = <0x1f0 0x4>;
+			};
+			pkh_otp: otp144@240 {
+				reg = <0x240 0x20>;
+			};
+			oem_fip_enc_key: otp260@410 {
+				reg = <0x410 0x20>;
+			};
 		};
 
 		rcc: rcc@44200000 {
@@ -136,12 +328,18 @@
 			reg = <0x44230000 0x10000>;
 		};
 
+		ddr: ddr@48040000 {
+			compatible = "st,stm32mp2-ddr";
+			reg = <0x48040000 0x10000>,
+			      <0x48c00000 0x400000>;
+			status = "okay";
+		};
+
 		pinctrl: pinctrl@44240000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "st,stm32mp257-pinctrl";
 			ranges = <0 0x44240000 0xa0400>;
-			pins-are-numbered;
 
 			gpioa: gpio@44240000 {
 				gpio-controller;
@@ -270,7 +468,6 @@
 			#size-cells = <1>;
 			compatible = "st,stm32mp257-z-pinctrl";
 			ranges = <0 0x46200000 0x400>;
-			pins-are-numbered;
 
 			gpioz: gpio@46200000 {
 				gpio-controller;
diff --git a/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
new file mode 100644
index 00000000..5bfcf8dd
--- /dev/null
+++ b/fdts/stm32mp257f-ev1-ca35tdcid-fw-config.dtsi
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2024 - All Rights Reserved
+ */
+
+/*
+ * STM32MP25 tf-a firmware config
+ * Project : open
+ * Generated by XLmx tool version 2.2 - 2/27/2024 11:46:17 AM
+ */
+
+/ {
+	dtb-registry {
+		soc_fw-config {
+			load-address = <0x0 0x81ff0000>;
+			max-size = <0x10000>;
+		};
+		tos_fw {
+			load-address = <0x0 0x82000000>;
+			max-size = <0x2000000>;
+		};
+	};
+};
diff --git a/fdts/stm32mp257f-ev1-ca35tdcid-rcc.dtsi b/fdts/stm32mp257f-ev1-ca35tdcid-rcc.dtsi
new file mode 100644
index 00000000..3e84df5e
--- /dev/null
+++ b/fdts/stm32mp257f-ev1-ca35tdcid-rcc.dtsi
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2024 - All Rights Reserved
+ * Author: Loic Pallardy loic.pallardy@foss.st.com for STMicroelectronics.
+ */
+
+/*
+ * STM32MP25 Clock tree device tree configuration
+ * Project : open
+ * Generated by XLmx tool version 2.2 - 2/27/2024 11:46:16 AM
+ */
+
+&clk_hse {
+	clock-frequency = <40000000>;
+};
+
+&clk_hsi {
+	clock-frequency = <64000000>;
+};
+
+&clk_lse {
+	clock-frequency = <32768>;
+};
+
+&clk_lsi {
+	clock-frequency = <32000>;
+};
+
+&clk_msi {
+	clock-frequency = <16000000>;
+};
+
+&rcc {
+	st,busclk = <
+		DIV_CFG(DIV_LSMCU, 1)
+		DIV_CFG(DIV_APB1, 0)
+		DIV_CFG(DIV_APB2, 0)
+		DIV_CFG(DIV_APB3, 0)
+		DIV_CFG(DIV_APB4, 0)
+		DIV_CFG(DIV_APBDBG, 0)
+	>;
+
+	st,flexgen = <
+		FLEXGEN_CFG(0, XBAR_SRC_PLL4, 0, 2)
+		FLEXGEN_CFG(1, XBAR_SRC_PLL4, 0, 5)
+		FLEXGEN_CFG(2, XBAR_SRC_PLL4, 0, 1)
+		FLEXGEN_CFG(4, XBAR_SRC_PLL4, 0, 3)
+		FLEXGEN_CFG(5, XBAR_SRC_PLL4, 0, 2)
+		FLEXGEN_CFG(8, XBAR_SRC_HSI_KER, 0, 0)
+		FLEXGEN_CFG(48, XBAR_SRC_PLL5, 0, 3)
+		FLEXGEN_CFG(51, XBAR_SRC_PLL4, 0, 5)
+		FLEXGEN_CFG(52, XBAR_SRC_PLL4, 0, 5)
+		FLEXGEN_CFG(58, XBAR_SRC_HSE, 0, 1)
+		FLEXGEN_CFG(63, XBAR_SRC_PLL4, 0, 2)
+	>;
+
+	st,kerclk = <
+		MUX_CFG(MUX_USB2PHY1, MUX_USB2PHY1_FLEX57)
+		MUX_CFG(MUX_USB2PHY2, MUX_USB2PHY2_FLEX58)
+	>;
+
+	pll1: st,pll-1 {
+		st,pll = <&pll1_cfg_1200Mhz>;
+
+		pll1_cfg_1200Mhz: pll1-cfg-1200Mhz {
+			cfg = <30 1 1 1>;
+			src = <MUX_CFG(MUX_MUXSEL5, MUXSEL_HSE)>;
+		};
+	};
+
+	pll2: st,pll-2 {
+		st,pll = <&pll2_cfg_600Mhz>;
+
+		pll2_cfg_600Mhz: pll2-cfg-600Mhz {
+			cfg = <30 1 1 2>;
+			src = <MUX_CFG(MUX_MUXSEL6, MUXSEL_HSE)>;
+		};
+	};
+
+	pll4: st,pll-4 {
+		st,pll = <&pll4_cfg_1200Mhz>;
+
+		pll4_cfg_1200Mhz: pll4-cfg-1200Mhz {
+			cfg = <30 1 1 1>;
+			src = <MUX_CFG(MUX_MUXSEL0, MUXSEL_HSE)>;
+		};
+	};
+
+	pll5: st,pll-5 {
+		st,pll = <&pll5_cfg_532Mhz>;
+
+		pll5_cfg_532Mhz: pll5-cfg-532Mhz {
+			cfg = <133 5 1 2>;
+			src = <MUX_CFG(MUX_MUXSEL1, MUXSEL_HSE)>;
+		};
+	};
+};
diff --git a/fdts/stm32mp257f-ev1-fw-config.dts b/fdts/stm32mp257f-ev1-fw-config.dts
new file mode 100644
index 00000000..9424f493
--- /dev/null
+++ b/fdts/stm32mp257f-ev1-fw-config.dts
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ */
+
+#include "stm32mp25-fw-config.dtsi"
+#include "stm32mp257f-ev1-ca35tdcid-fw-config.dtsi"
diff --git a/fdts/stm32mp257f-ev1.dts b/fdts/stm32mp257f-ev1.dts
index b7e92e47..5d5e35de 100644
--- a/fdts/stm32mp257f-ev1.dts
+++ b/fdts/stm32mp257f-ev1.dts
@@ -1,13 +1,16 @@
 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 
 /dts-v1/;
 
+#include <dt-bindings/clock/stm32mp25-clksrc.h>
 #include "stm32mp257.dtsi"
 #include "stm32mp25xf.dtsi"
+#include "stm32mp257f-ev1-ca35tdcid-rcc.dtsi"
+#include "stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi"
 #include "stm32mp25-pinctrl.dtsi"
 #include "stm32mp25xxai-pinctrl.dtsi"
 
@@ -29,6 +32,163 @@
 	};
 };
 
+&bsec {
+	board_id: board-id@3d8 {
+		reg = <0x3d8 0x4>;
+	};
+};
+
+&ddr {
+	vdd-supply = <&vdd_ddr>;
+	vtt-supply = <&vtt_ddr>;
+	vpp-supply = <&vpp_ddr>;
+	vref-supply = <&vref_ddr>;
+};
+
+&i2c7 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c7_pins_a>;
+	i2c-scl-rising-time-ns = <185>;
+	i2c-scl-falling-time-ns = <20>;
+	clock-frequency = <400000>;
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	pmic2: stpmic@33 {
+		compatible = "st,stpmic2";
+		reg = <0x33>;
+		status = "okay";
+
+		regulators {
+			compatible = "st,stpmic2-regulators";
+
+			vddcpu: buck1 {
+				regulator-name = "vddcpu";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <910000>;
+				regulator-always-on;
+			};
+			vddcore: buck2 {
+				regulator-name = "vddcore";
+				regulator-min-microvolt = <820000>;
+				regulator-max-microvolt = <820000>;
+				regulator-always-on;
+			};
+			vddgpu: buck3 {
+				regulator-name = "vddgpu";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <900000>;
+				regulator-always-on;
+			};
+			vddio_pmic: buck4 {
+				regulator-name = "vddio_pmic";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			v1v8: buck5 {
+				regulator-name = "v1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+			vdd_ddr: buck6 {
+				regulator-name = "vdd_ddr";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+			};
+			v3v3: buck7 {
+				regulator-name = "v3v3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vdda1v8_aon: ldo1 {
+				regulator-name = "vdda1v8_aon";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+			};
+			vdd_emmc: ldo2 {
+				regulator-name = "vdd_emmc";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vtt_ddr: ldo3 {
+				regulator-name = "vtt_ddr";
+				st,regulator-sink-source;
+			};
+			vdd3v3_usb: ldo4 {
+				regulator-name = "vdd3v3_usb";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vpp_ddr: ldo5 {
+				regulator-name = "vpp_ddr";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-enable-ramp-delay = <1000>;
+			};
+			vdd_sdcard: ldo7 {
+				regulator-name = "vdd_sdcard";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vddio_sdcard: ldo8 {
+				regulator-name = "vddio_sdcard";
+				st,regulator-bypass-microvolt = <3300000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+			vref_ddr: refddr {
+				regulator-name = "vref_ddr";
+			};
+		};
+	};
+};
+
+&pwr {
+	vddio1: vddio1 {
+		vddio1-supply = <&vddio_sdcard>;
+	};
+	vddio2: vddio2 {
+		vddio2-supply = <&v1v8>;
+	};
+	vddio3: vddio3 {
+		vddio3-supply = <&vddio_pmic>;
+	};
+	vddio4: vddio4 {
+		vddio4-supply = <&vddio_pmic>;
+	};
+	vddio: vddio {
+		vdd-supply = <&vddio_pmic>;
+	};
+};
+
+&sdmmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc1_b4_pins_a>;
+	st,neg-edge;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&sdmmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
+	non-removable;
+	no-sd;
+	no-sdio;
+	st,neg-edge;
+	bus-width = <8>;
+	status = "okay";
+};
+
 &usart2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usart2_pins_a>;
diff --git a/fdts/cot_descriptors.dtsi b/fdts/tbbr_cot_descriptors.dtsi
similarity index 89%
rename from fdts/cot_descriptors.dtsi
rename to fdts/tbbr_cot_descriptors.dtsi
index 411bae6c..253297f3 100644
--- a/fdts/cot_descriptors.dtsi
+++ b/fdts/tbbr_cot_descriptors.dtsi
@@ -1,10 +1,15 @@
 /*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#if USE_TBBR_DEFS
 #include <tools_share/tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+
 #include <common/tbbr/tbbr_img_def.h>
 #include <common/nv_cntr_ids.h>
 
@@ -15,7 +20,7 @@ cot {
 		trusted_boot_fw_cert: trusted_boot_fw_cert {
 			root-certificate;
 			image-id =<TRUSTED_BOOT_FW_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tb_fw_hash: tb_fw_hash {
 				oid = TRUSTED_BOOT_FW_HASH_OID;
@@ -34,7 +39,7 @@ cot {
 		trusted_key_cert: trusted_key_cert {
 			root-certificate;
 			image-id = <TRUSTED_KEY_CERT_ID>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			trusted_world_pk: trusted_world_pk {
 				oid = TRUSTED_WORLD_PK_OID;
@@ -48,7 +53,7 @@ cot {
 			image-id = <SCP_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			scp_fw_content_pk: scp_fw_content_pk {
 				oid = SCP_FW_CONTENT_CERT_PK_OID;
@@ -59,7 +64,7 @@ cot {
 			image-id = <SCP_FW_CONTENT_CERT_ID>;
 			parent = <&scp_fw_key_cert>;
 			signing-key = <&scp_fw_content_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			scp_fw_hash: scp_fw_hash {
 				oid = SCP_FW_HASH_OID;
@@ -70,7 +75,7 @@ cot {
 			image-id = <SOC_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 			soc_fw_content_pk: soc_fw_content_pk {
 				oid = SOC_FW_CONTENT_CERT_PK_OID;
 			};
@@ -80,7 +85,7 @@ cot {
 			image-id = <SOC_FW_CONTENT_CERT_ID>;
 			parent = <&soc_fw_key_cert>;
 			signing-key = <&soc_fw_content_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			soc_fw_hash: soc_fw_hash {
 				oid = SOC_AP_FW_HASH_OID;
@@ -94,7 +99,7 @@ cot {
 			image-id = <TRUSTED_OS_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_content_pk: tos_fw_content_pk {
 				oid = TRUSTED_OS_FW_CONTENT_CERT_PK_OID;
@@ -105,7 +110,7 @@ cot {
 			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
 			parent = <&trusted_os_fw_key_cert>;
 			signing-key = <&tos_fw_content_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			tos_fw_hash: tos_fw_hash {
 				oid = TRUSTED_OS_FW_HASH_OID;
@@ -125,7 +130,7 @@ cot {
 			image-id = <NON_TRUSTED_FW_KEY_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&non_trusted_world_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_fw_content_pk: nt_fw_content_pk {
 				oid = NON_TRUSTED_FW_CONTENT_CERT_PK_OID;
@@ -136,7 +141,7 @@ cot {
 			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
 			parent = <&non_trusted_fw_key_cert>;
 			signing-key = <&nt_fw_content_pk>;
-			antirollback-counter = <&non_trusted_nv_counter>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
 
 			nt_world_bl_hash: nt_world_bl_hash {
 				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
@@ -151,7 +156,7 @@ cot {
 			image-id = <SIP_SP_CONTENT_CERT_ID>;
 			parent = <&trusted_key_cert>;
 			signing-key = <&trusted_world_pk>;
-			antirollback-counter = <&trusted_nv_counter>;
+			antirollback-counter = <&trusted_nv_ctr>;
 
 			sp_pkg1_hash: sp_pkg1_hash {
 				oid = SP_PKG1_HASH_OID;
@@ -190,10 +195,10 @@ cot {
 			hash = <&hw_config_hash>;
 		};
 
-		tb_fw_config {
-			image-id = <TB_FW_CONFIG_ID>;
+		fw_config {
+			image-id = <FW_CONFIG_ID>;
 			parent = <&trusted_boot_fw_cert>;
-			hash = <&tb_fw_config_hash>;
+			hash = <&fw_config_hash>;
 		};
 
 		scp_bl2_image {
@@ -308,12 +313,12 @@ non_volatile_counters: non_volatile_counters {
 	#address-cells = <1>;
 	#size-cells = <0>;
 
-	trusted_nv_counter: trusted_nv_counter {
+	trusted_nv_ctr: trusted_nv_ctr {
 		id  = <TRUSTED_NV_CTR_ID>;
 		oid = TRUSTED_FW_NVCOUNTER_OID;
 	};
 
-	non_trusted_nv_counter: non_trusted_nv_counter {
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
 		id  = <NON_TRUSTED_NV_CTR_ID>;
 		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
 	};
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
new file mode 100644
index 00000000..735d429a
--- /dev/null
+++ b/fdts/tc-base.dtsi
@@ -0,0 +1,683 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* If SCMI power domain control is enabled */
+#if TC_SCMI_PD_CTRL_EN
+#define GPU_SCMI_PD_IDX		(PLAT_MAX_CPUS_PER_CLUSTER + 1)
+#define DPU_SCMI_PD_IDX		(PLAT_MAX_CPUS_PER_CLUSTER + 2)
+#endif /* TC_SCMI_PD_CTRL_EN */
+
+/* Use SCMI controlled clocks */
+#if TC_DPU_USE_SCMI_CLK
+#define DPU_CLK_ATTR1								\
+	clocks = <&scmi_clk 0>;							\
+	clock-names = "aclk"
+
+#define DPU_CLK_ATTR2								\
+	clocks = <&scmi_clk 1>;							\
+	clock-names = "pxclk"
+
+#define DPU_CLK_ATTR3								\
+	clocks = <&scmi_clk 2>;							\
+	clock-names = "pxclk"							\
+/* Use fixed clocks */
+#else /* !TC_DPU_USE_SCMI_CLK */
+#define DPU_CLK_ATTR1								\
+	clocks = <&dpu_aclk>;							\
+	clock-names = "aclk"
+
+#define DPU_CLK_ATTR2								\
+	clocks = <&dpu_pixel_clk>, <&dpu_aclk>;					\
+	clock-names = "pxclk", "aclk"
+
+#define DPU_CLK_ATTR3 DPU_CLK_ATTR2
+#endif /* !TC_DPU_USE_SCMI_CLK */
+
+/ {
+	compatible = "arm,tc";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &os_uart;
+	};
+
+	chosen {
+		/*
+		 * Add some dummy entropy for Linux so it
+		 * doesn't delay the boot waiting for it.
+		 */
+		rng-seed = <0x01 0x02 0x04 0x05 0x06 0x07 0x08 \
+			    0x01 0x02 0x04 0x05 0x06 0x07 0x08 \
+			    0x01 0x02 0x04 0x05 0x06 0x07 0x08 \
+			    0x01 0x02 0x04 0x05 0x06 0x07 0x08 \
+			    0x01 0x02 0x04 0x05 0x06 0x07 0x08 \
+			    0x01 0x02 0x04 0x05 0x06 0x07 0x08 \
+			    0x01 0x02 0x04 0x05 0x06 0x07 0x08 \
+			    0x01 0x02 0x04 0x05 0x06 0x07 0x08 >;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+				core4 {
+					cpu = <&CPU4>;
+				};
+				core5 {
+					cpu = <&CPU5>;
+				};
+				core6 {
+					cpu = <&CPU6>;
+				};
+				core7 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+
+		/*
+		 * The timings below are just to demonstrate working cpuidle.
+		 * These values may be inaccurate.
+		 */
+		idle-states {
+			entry-method = "psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x0010000>;
+				local-timer-stop;
+				entry-latency-us = <300>;
+				exit-latency-us = <1200>;
+				min-residency-us = <2000>;
+			};
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x1010000>;
+				local-timer-stop;
+				entry-latency-us = <400>;
+				exit-latency-us = <1200>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		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";
+			reg = <0x0>;
+			enable-method = "psci";
+			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 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x100>;
+			enable-method = "psci";
+			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 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x200>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU3:cpu@300 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x300>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU4:cpu@400 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x400>;
+			enable-method = "psci";
+			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 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x500>;
+			enable-method = "psci";
+			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 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x600>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU7:cpu@700 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x700>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		linux,cma {
+			compatible = "shared-dma-pool";
+			reusable;
+			size = <0x0 0x8000000>;
+			linux,cma-default;
+		};
+
+		optee {
+			compatible = "restricted-dma-pool";
+			reg = <0x0 TC_NS_OPTEE_BASE 0x0 TC_NS_OPTEE_SIZE>;
+		};
+
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 TC_NS_DRAM1_BASE 0x0 TC_NS_DRAM1_SIZE>,
+		      <HI(PLAT_ARM_DRAM2_BASE) LO(PLAT_ARM_DRAM2_BASE)
+		       HI(TC_NS_DRAM2_SIZE) LO(TC_NS_DRAM2_SIZE)>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpu-pmu-little {
+		compatible = LIT_CPU_PMU_COMPATIBLE;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_little>;
+		status = "okay";
+	};
+
+	cpu-pmu-mid {
+		compatible = MID_CPU_PMU_COMPATIBLE;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_mid>;
+		status = "okay";
+	};
+
+	cpu-pmu-big {
+		compatible = BIG_CPU_PMU_COMPATIBLE;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_big>;
+		status = "okay";
+	};
+
+	sram: sram@6000000 {
+		compatible = "mmio-sram";
+		reg = <0x0 PLAT_ARM_NSRAM_BASE 0x0 PLAT_ARM_NSRAM_SIZE>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x0 PLAT_ARM_NSRAM_BASE PLAT_ARM_NSRAM_SIZE>;
+
+		cpu_scp_scmi_a2p: scp-shmem@0 {
+			compatible = "arm,scmi-shmem";
+			reg = <0x0 0x80>;
+		};
+	};
+
+	mbox_db_rx: mhu@MHU_RX_ADDR {
+		compatible = MHU_RX_COMPAT;
+		reg = <0x0 ADDRESSIFY(MHU_RX_ADDR) 0x0 MHU_OFFSET>;
+		clocks = <&soc_refclk>;
+		clock-names = "apb_pclk";
+		#mbox-cells = <MHU_MBOX_CELLS>;
+		interrupts = <GIC_SPI MHU_RX_INT_NUM IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = MHU_RX_INT_NAME;
+	};
+
+	mbox_db_tx: mhu@MHU_TX_ADDR {
+		compatible = MHU_TX_COMPAT;
+		reg = <0x0 ADDRESSIFY(MHU_TX_ADDR) 0x0 MHU_OFFSET>;
+		clocks = <&soc_refclk>;
+		clock-names = "apb_pclk";
+		#mbox-cells = <MHU_MBOX_CELLS>;
+		interrupt-names = MHU_TX_INT_NAME;
+	};
+
+	firmware {
+		scmi {
+			compatible = "arm,scmi";
+			mbox-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+#if TC_SCMI_PD_CTRL_EN
+			scmi_devpd: protocol@11 {
+				reg = <0x11>;
+				#power-domain-cells = <1>;
+			};
+#endif /* TC_SCMI_PD_CTRL_EN */
+
+			scmi_dvfs: protocol@13 {
+				reg = <0x13>;
+				#clock-cells = <1>;
+			};
+
+			scmi_clk: protocol@14 {
+				reg = <0x14>;
+				#clock-cells = <1>;
+			};
+		};
+	};
+
+	gic: interrupt-controller@GIC_CTRL_ADDR {
+		compatible = "arm,gic-v3";
+		#address-cells = <2>;
+		#interrupt-cells = <4>;
+		#size-cells = <2>;
+		ranges;
+		interrupt-controller;
+		reg = <0x0 0x30000000 0 0x10000>, /* GICD */
+		      <0x0 0x30080000 0 GIC_GICR_OFFSET>; /* GICR */
+		interrupts = <GIC_PPI 0x9 IRQ_TYPE_LEVEL_LOW 0>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW 0>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW 0>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW 0>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>;
+	};
+
+	spe-pmu-mid {
+		compatible = "arm,statistical-profiling-extension-v1";
+		interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_HIGH &ppi_partition_mid>;
+		status = "disabled";
+	};
+
+	spe-pmu-big {
+		compatible = "arm,statistical-profiling-extension-v1";
+		interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_HIGH &ppi_partition_big>;
+		status = "disabled";
+	};
+
+	soc_refclk: refclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000000>;
+		clock-output-names = "apb_pclk";
+	};
+
+	soc_refclk60mhz: refclk60mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <60000000>;
+		clock-output-names = "iofpga_clk";
+	};
+
+	soc_uartclk: uartclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <UARTCLK_FREQ>;
+		clock-output-names = "uartclk";
+	};
+
+	/* soc_uart0 on FPGA, ap_ns_uart on FVP */
+	os_uart: serial@2a400000 {
+		compatible = "arm,pl011", "arm,primecell";
+		reg = <0x0 0x2A400000 0x0 UART_OFFSET>;
+		interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&soc_uartclk>, <&soc_refclk>;
+		clock-names = "uartclk", "apb_pclk";
+		status = "okay";
+	};
+
+#if !TC_DPU_USE_SCMI_CLK
+	dpu_aclk: dpu_aclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <VENCODER_TIMING_CLK>;
+		clock-output-names = "fpga:dpu_aclk";
+	};
+
+	dpu_pixel_clk: dpu-pixel-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <VENCODER_TIMING_CLK>;
+		clock-output-names = "pxclk";
+	};
+#endif /* !TC_DPU_USE_SCMI_CLK */
+
+	vencoder {
+		compatible = "drm,virtual-encoder";
+		port {
+			vencoder_in: endpoint {
+				remote-endpoint = <&dp_pl0_out0>;
+			};
+		};
+
+		display-timings {
+			timing-panel {
+				VENCODER_TIMING;
+			};
+		};
+
+	};
+
+	ethernet: ethernet@ETHERNET_ADDR {
+		reg = <0x0 ADDRESSIFY(ETHERNET_ADDR) 0x0 0x10000>;
+		interrupts = <GIC_SPI ETHERNET_INT IRQ_TYPE_LEVEL_HIGH 0>;
+
+		reg-io-width = <2>;
+		smsc,irq-push-pull;
+	};
+
+	bp_clock24mhz: clock24mhz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "bp:clock24mhz";
+	};
+
+	sysreg: sysreg@SYS_REGS_ADDR {
+		compatible = "arm,vexpress-sysreg";
+		reg = <0x0 ADDRESSIFY(SYS_REGS_ADDR) 0x0 0x1000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	fixed_3v3: v2m-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	mmci: mmci@MMC_ADDR {
+		compatible = "arm,pl180", "arm,primecell";
+		reg = <0x0 ADDRESSIFY(MMC_ADDR) 0x0 0x1000>;
+		interrupts = <GIC_SPI MMC_INT_0 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI MMC_INT_1 IRQ_TYPE_LEVEL_HIGH 0>;
+		wp-gpios = <&sysreg 1 0>;
+		bus-width = <4>;
+		max-frequency = <25000000>;
+		vmmc-supply = <&fixed_3v3>;
+		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+		clock-names = "mclk", "apb_pclk";
+	};
+
+	gpu_clk: gpu_clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000000>;
+	};
+
+	gpu_core_clk: gpu_core_clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1000000000>;
+	};
+
+	gpu: gpu@2d000000 {
+		compatible = "arm,mali-midgard";
+		reg = <0x0 0x2d000000 0x0 0x200000>;
+		clocks = <&gpu_core_clk>;
+		clock-names = "shadercores";
+#if TC_SCMI_PD_CTRL_EN
+		power-domains = <&scmi_devpd GPU_SCMI_PD_IDX>;
+		scmi-perf-domain = <3>;
+#endif /* TC_SCMI_PD_CTRL_EN */
+
+		pbha {
+			int-id-override = <0 0x22>, <2 0x23>, <4 0x23>, <7 0x22>,
+					  <8 0x22>, <9 0x22>, <10 0x22>, <11 0x22>,
+					  <12 0x22>, <13 0x22>, <16 0x22>, <17 0x32>,
+					  <18 0x32>, <19 0x22>, <20 0x22>, <21 0x32>,
+					  <22 0x32>, <24 0x22>, <28 0x32>;
+			propagate-bits = <0x0f>;
+		};
+	};
+
+	power_model_simple {
+		/*
+		 * Numbers used are irrelevant to Titan,
+		 * it helps suppressing the kernel warnings.
+		 */
+		compatible = "arm,mali-simple-power-model";
+		static-coefficient = <2427750>;
+		dynamic-coefficient = <4687>;
+		ts = <20000 2000 (-20) 2>;
+		thermal-zone = "";
+	};
+
+	smmu_600: smmu@2ce00000 {
+		compatible = "arm,smmu-v3";
+		reg = <0 0x2ce00000 0 0x20000>;
+		interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 74 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 76 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 77 IRQ_TYPE_EDGE_RISING 0>;
+		interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
+		#iommu-cells = <1>;
+		status = "disabled";
+	};
+
+	smmu_700: iommu@3f000000 {
+		#iommu-cells = <1>;
+		compatible = "arm,smmu-v3";
+		reg = <0x0 0x3f000000 0x0 0x5000000>;
+		interrupts = <GIC_SPI 228 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 229 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 230 IRQ_TYPE_EDGE_RISING 0>;
+		interrupt-names = "eventq", "cmdq-sync", "gerror";
+		dma-coherent;
+		status = "disabled";
+	};
+
+	smmu_700_dpu: iommu@4002a00000 {
+		#iommu-cells = <1>;
+		compatible = "arm,smmu-v3";
+		reg = <HI(0x4002a00000) LO(0x4002a00000) 0x0 0x5000000>;
+		interrupts = <GIC_SPI 481 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 482 IRQ_TYPE_EDGE_RISING 0>,
+			     <GIC_SPI 483 IRQ_TYPE_EDGE_RISING 0>;
+		interrupt-names = "eventq", "cmdq-sync", "gerror";
+		dma-coherent;
+		status = "disabled";
+	};
+
+	dp0: display@DPU_ADDR {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "arm,mali-d71";
+		reg = <HI(ADDRESSIFY(DPU_ADDR)) LO(ADDRESSIFY(DPU_ADDR)) 0 0x20000>;
+		interrupts = <GIC_SPI DPU_IRQ IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "DPU";
+		DPU_CLK_ATTR1;
+
+		pl0: pipeline@0 {
+			reg = <0>;
+			DPU_CLK_ATTR2;
+			pl_id = <0>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					dp_pl0_out0: endpoint {
+						remote-endpoint = <&vencoder_in>;
+					};
+				};
+			};
+		};
+
+		pl1: pipeline@1 {
+			reg = <1>;
+			DPU_CLK_ATTR3;
+			pl_id = <1>;
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+				};
+			};
+		};
+	};
+
+	/*
+	 * L3 cache in the DSU is the Memory System Component (MSC)
+	 * The MPAM registers are accessed through utility bus in the DSU
+	 */
+	msc0 {
+		compatible = "arm,mpam-msc";
+		reg = <MPAM_ADDR 0x0 0x2000>;
+	};
+
+	ete0 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU0>;
+	};
+
+	ete1 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU1>;
+	};
+
+	ete2 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU2>;
+	};
+
+	ete3 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU3>;
+	};
+
+	ete4 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU4>;
+	};
+
+	ete5 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU5>;
+	};
+
+	ete6 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU6>;
+	};
+
+	ete7 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU7>;
+	};
+
+	trbe {
+		compatible = "arm,trace-buffer-extension";
+		interrupts = <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW 0>;
+	};
+
+	trusty {
+		#size-cells = <0x02>;
+		#address-cells = <0x02>;
+		ranges = <0x00>;
+		compatible = "android,trusty-v1";
+
+		virtio {
+			compatible = "android,trusty-virtio-v1";
+		};
+
+		test {
+			compatible = "android,trusty-test-v1";
+		};
+
+		log {
+			compatible = "android,trusty-log-v1";
+		};
+
+		irq {
+			ipi-range = <0x08 0x0f 0x08>;
+			interrupt-ranges = <0x00 0x0f 0x00 0x10 0x1f 0x01 0x20 0x3f 0x02>;
+			interrupt-templates = <0x01 0x00 0x8001 0x01 0x01 0x04 0x8001 0x01 0x00 0x04>;
+			compatible = "android,trusty-irq-v1";
+		};
+	};
+
+	/* used in U-boot, Linux doesn't care */
+	arm_ffa {
+		compatible = "arm,ffa";
+		method = "smc";
+	};
+};
diff --git a/fdts/tc-common.dtsi b/fdts/tc-common.dtsi
new file mode 100644
index 00000000..c3311930
--- /dev/null
+++ b/fdts/tc-common.dtsi
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define PASTER(x, y)		x ## y
+#define EVALUATOR(x, y)		PASTER(x, y)
+#define ADDRESSIFY(addr)	EVALUATOR(0x, addr)
diff --git a/fdts/tc-fpga.dtsi b/fdts/tc-fpga.dtsi
new file mode 100644
index 00000000..08b9ae56
--- /dev/null
+++ b/fdts/tc-fpga.dtsi
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define GIC_CTRL_ADDR		30000000
+#define GIC_GICR_OFFSET		0x1000000
+#define UART_OFFSET		0x10000
+/* 1440x3200@120 framebuffer */
+#define VENCODER_TIMING_CLK 836000000
+#define VENCODER_TIMING								\
+	clock-frequency = <VENCODER_TIMING_CLK>;				\
+	hactive = <1440>;							\
+	vactive = <3200>;							\
+	hfront-porch = <136>;							\
+	hback-porch = <296>;							\
+	hsync-len = <160>;							\
+	vfront-porch = <3>;							\
+	vback-porch = <217>;							\
+	vsync-len = <10>
+
+/ {
+	chosen {
+		stdout-path = "serial0:38400n8";
+	};
+
+	ethernet: ethernet@ETHERNET_ADDR {
+		compatible = "smsc,lan9115";
+		phy-mode = "mii";
+	};
+
+	mmci: mmci@MMC_ADDR {
+		non-removable;
+	};
+};
diff --git a/fdts/tc-fvp.dtsi b/fdts/tc-fvp.dtsi
new file mode 100644
index 00000000..f57e21da
--- /dev/null
+++ b/fdts/tc-fvp.dtsi
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define GIC_CTRL_ADDR		2c010000
+#define GIC_GICR_OFFSET		0x200000
+#define UART_OFFSET		0x1000
+
+#ifdef TC_RESOLUTION_1920X1080P60
+
+#define VENCODER_TIMING_CLK 148500000
+#define VENCODER_TIMING								\
+	clock-frequency = <VENCODER_TIMING_CLK>;				\
+	hactive = <1920>;							\
+	vactive = <1080>;							\
+	hfront-porch = <88>;							\
+	hback-porch = <148>;							\
+	hsync-len = <44>;							\
+	vfront-porch = <4>;							\
+	vback-porch = <36>;							\
+	vsync-len = <5>
+
+#else /* TC_RESOLUTION_640X480P60 */
+
+#define VENCODER_TIMING_CLK 25175000
+#define VENCODER_TIMING								\
+	clock-frequency = <VENCODER_TIMING_CLK>;				\
+	hactive = <640>;							\
+	vactive = <480>;							\
+	hfront-porch = <16>;							\
+	hback-porch = <48>;							\
+	hsync-len = <96>;							\
+	vfront-porch = <10>;							\
+	vback-porch = <33>;							\
+	vsync-len = <2>
+
+#endif
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	ethernet: ethernet@ETHERNET_ADDR {
+		compatible = "smsc,lan91c111";
+	};
+
+	mmci: mmci@MMC_ADDR {
+		cd-gpios = <&sysreg 0 0>;
+	};
+
+	rtc@RTC_ADDR {
+		compatible = "arm,pl031", "arm,primecell";
+		reg = <0x0 ADDRESSIFY(RTC_ADDR) 0x0 0x1000>;
+		interrupts = <GIC_SPI RTC_INT IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&soc_refclk>;
+		clock-names = "apb_pclk";
+	};
+
+	kmi@KMI_0_ADDR {
+		compatible = "arm,pl050", "arm,primecell";
+		reg = <0x0 ADDRESSIFY(KMI_0_ADDR) 0x0 0x1000>;
+		interrupts = <GIC_SPI KMI_0_INT IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+		clock-names = "KMIREFCLK", "apb_pclk";
+	};
+
+	kmi@1c070000 {
+		compatible = "arm,pl050", "arm,primecell";
+		reg = <0x0 0x001c070000 0x0 0x1000>;
+		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+		clock-names = "KMIREFCLK", "apb_pclk";
+	};
+
+	virtio_block@VIRTIO_BLOCK_ADDR {
+		compatible = "virtio,mmio";
+		reg = <0x0 ADDRESSIFY(VIRTIO_BLOCK_ADDR) 0x0 0x200>;
+		/* spec lists this wrong */
+		interrupts = <GIC_SPI VIRTIO_BLOCK_INT IRQ_TYPE_LEVEL_HIGH 0>;
+	};
+};
diff --git a/fdts/tc.dts b/fdts/tc.dts
deleted file mode 100644
index 4f275895..00000000
--- a/fdts/tc.dts
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/dts-v1/;
-
-/ {
-	compatible = "arm,tc";
-	interrupt-parent = <&gic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	aliases {
-		serial0 = &soc_uart0;
-	};
-
-	chosen {
-		stdout-path = "serial0:115200n8";
-	};
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		cpu-map {
-			cluster0 {
-				core0 {
-					cpu = <&CPU0>;
-				};
-				core1 {
-					cpu = <&CPU1>;
-				};
-				core2 {
-					cpu = <&CPU2>;
-				};
-				core3 {
-					cpu = <&CPU3>;
-				};
-				core4 {
-					cpu = <&CPU4>;
-				};
-				core5 {
-					cpu = <&CPU5>;
-				};
-				core6 {
-					cpu = <&CPU6>;
-				};
-				core7 {
-					cpu = <&CPU7>;
-				};
-			};
-		};
-
-		/*
-		 * The timings below are just to demonstrate working cpuidle.
-		 * These values may be inaccurate.
-		 */
-		idle-states {
-			entry-method = "arm,psci";
-
-			CPU_SLEEP_0: cpu-sleep-0 {
-				compatible = "arm,idle-state";
-				arm,psci-suspend-param = <0x0010000>;
-				local-timer-stop;
-				entry-latency-us = <300>;
-				exit-latency-us = <1200>;
-				min-residency-us = <2000>;
-			};
-			CLUSTER_SLEEP_0: cluster-sleep-0 {
-				compatible = "arm,idle-state";
-				arm,psci-suspend-param = <0x1010000>;
-				local-timer-stop;
-				entry-latency-us = <400>;
-				exit-latency-us = <1200>;
-				min-residency-us = <2500>;
-			};
-		};
-
-		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";
-			reg = <0x0>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 0>;
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <406>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU1:cpu@100 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x100>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 0>;
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <406>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU2:cpu@200 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x200>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 0>;
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <406>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU3:cpu@300 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x300>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 0>;
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <406>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU4:cpu@400 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x400>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 1>;
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <912>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU5:cpu@500 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x500>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 1>;
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <912>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU6:cpu@600 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x600>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 1>;
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <912>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-		CPU7:cpu@700 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x700>;
-			enable-method = "psci";
-			clocks = <&scmi_dvfs 2>;
-			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
-			capacity-dmips-mhz = <1024>;
-			amu = <&amu>;
-			supports-mpmm;
-		};
-
-	};
-
-	reserved-memory {
-		#address-cells = <2>;
-		#size-cells = <2>;
-		ranges;
-
-		linux,cma {
-			compatible = "shared-dma-pool";
-			reusable;
-			size = <0x0 0x8000000>;
-			linux,cma-default;
-		};
-
-		optee@0xf8e00000 {
-			compatible = "restricted-dma-pool";
-			reg = <0x00000000 0xf8e00000 0 0x00200000>;
-		};
-	};
-
-	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2";
-		method = "smc";
-	};
-
-	sram: sram@6000000 {
-		compatible = "mmio-sram";
-		reg = <0x0 0x06000000 0x0 0x8000>;
-
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0x0 0x06000000 0x8000>;
-
-		cpu_scp_scmi_mem: scp-shmem@0 {
-			compatible = "arm,scmi-shmem";
-			reg = <0x0 0x80>;
-		};
-	};
-
-	mbox_db_rx: mhu@45010000 {
-		compatible = "arm,mhuv2-rx","arm,primecell";
-		reg = <0x0 0x45010000 0x0 0x1000>;
-		clocks = <&soc_refclk100mhz>;
-		clock-names = "apb_pclk";
-		#mbox-cells = <2>;
-		interrupts = <0 317 4>;
-		interrupt-names = "mhu_rx";
-		mhu-protocol = "doorbell";
-		arm,mhuv2-protocols = <0 1>;
-	};
-
-	mbox_db_tx: mhu@45000000 {
-		compatible = "arm,mhuv2-tx","arm,primecell";
-		reg = <0x0 0x45000000 0x0 0x1000>;
-		clocks = <&soc_refclk100mhz>;
-		clock-names = "apb_pclk";
-		#mbox-cells = <2>;
-		interrupt-names = "mhu_tx";
-		mhu-protocol = "doorbell";
-		arm,mhuv2-protocols = <0 1>;
-	};
-
-	cmn-pmu {
-		compatible = "arm,ci-700";
-		reg = <0x0 0x50000000 0x0 0x10000000>;
-		interrupts = <0x0 460 0x4>;
-	};
-
-	scmi {
-		compatible = "arm,scmi";
-		mbox-names = "tx", "rx";
-		mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0 >;
-		shmem = <&cpu_scp_scmi_mem &cpu_scp_scmi_mem>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		scmi_dvfs: protocol@13 {
-			reg = <0x13>;
-			#clock-cells = <1>;
-		};
-
-		scmi_clk: protocol@14 {
-			reg = <0x14>;
-			#clock-cells = <1>;
-		};
-	};
-
-	gic: interrupt-controller@2c010000 {
-		compatible = "arm,gic-600", "arm,gic-v3";
-		#address-cells = <2>;
-		#interrupt-cells = <3>;
-		#size-cells = <2>;
-		ranges;
-		interrupt-controller;
-		reg = <0x0 0x30000000 0 0x10000>, /* GICD */
-		      <0x0 0x30080000 0 0x200000>; /* GICR */
-		interrupts = <0x1 0x9 0x4>;
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts = <0x1 13 0x8>,
-			     <0x1 14 0x8>,
-			     <0x1 11 0x8>,
-			     <0x1 10 0x8>;
-	};
-
-	soc_refclk100mhz: refclk100mhz {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <100000000>;
-		clock-output-names = "apb_pclk";
-	};
-
-	soc_refclk60mhz: refclk60mhz {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <60000000>;
-		clock-output-names = "iofpga_clk";
-	};
-
-	soc_uartclk:  uartclk {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <50000000>;
-		clock-output-names = "uartclk";
-	};
-
-	soc_uart0: uart@7ff80000 {
-		compatible = "arm,pl011", "arm,primecell";
-		reg = <0x0 0x7ff80000 0x0 0x1000>;
-		interrupts = <0x0 116 0x4>;
-		clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
-		clock-names = "uartclk", "apb_pclk";
-		status = "okay";
-	};
-
-	rtc0: rtc@1C170000 {
-		compatible = "arm,pl031", "arm,primecell";
-		reg = <0x0 0x1C170000 0x0 0x1000>;
-		interrupts = <0x0 100 0x4>;
-		clocks = <&soc_refclk100mhz>;
-		clock-names = "apb_pclk";
-		wakeup-source;
-	};
-
-	vencoder {
-		compatible = "drm,virtual-encoder";
-
-		port {
-			vencoder_in: endpoint {
-				remote-endpoint = <&dp_pl0_out0>;
-			};
-		};
-
-		display-timings {
-			panel-timing {
-				clock-frequency = <25175000>;
-				hactive = <640>;
-				vactive = <480>;
-				hfront-porch = <16>;
-				hback-porch = <48>;
-				hsync-len = <96>;
-				vfront-porch = <10>;
-				vback-porch = <33>;
-				vsync-len = <2>;
-			};
-		};
-
-	};
-
-	hdlcd: hdlcd@7ff60000 {
-		compatible = "arm,hdlcd";
-		reg = <0x0 0x7ff60000 0x0 0x1000>;
-		interrupts = <0x0 117 0x4>;
-		clocks = <&fake_hdlcd_clk>;
-		clock-names = "pxlclk";
-		status = "disabled";
-
-		port {
-			hdlcd_out: endpoint {
-				remote-endpoint = <&vencoder_in>;
-			};
-		};
-	};
-
-	fake_hdlcd_clk: fake-hdlcd-clk {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <25175000>;
-		clock-output-names = "pxlclk";
-	};
-
-	ethernet@18000000 {
-		compatible = "smsc,lan91c111";
-		reg = <0x0 0x18000000 0x0 0x10000>;
-		interrupts = <0 109 4>;
-	};
-
-	kmi@1c060000 {
-		compatible = "arm,pl050", "arm,primecell";
-		reg = <0x0 0x001c060000 0x0 0x1000>;
-		interrupts = <0 197 4>;
-		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
-		clock-names = "KMIREFCLK", "apb_pclk";
-	};
-
-	kmi@1c070000 {
-		compatible = "arm,pl050", "arm,primecell";
-		reg = <0x0 0x001c070000 0x0 0x1000>;
-		interrupts = <0 103 4>;
-		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
-		clock-names = "KMIREFCLK", "apb_pclk";
-	};
-
-	bp_clock24mhz: clock24mhz {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <24000000>;
-		clock-output-names = "bp:clock24mhz";
-	};
-
-	virtio_block@1c130000 {
-		compatible = "virtio,mmio";
-		reg = <0x0 0x1c130000 0x0 0x200>;
-		interrupts = <0 204 4>;
-	};
-
-	sysreg: sysreg@1c010000 {
-		compatible = "arm,vexpress-sysreg";
-		reg = <0x0 0x001c010000 0x0 0x1000>;
-		gpio-controller;
-		#gpio-cells = <2>;
-	};
-
-	fixed_3v3: v2m-3v3 {
-		compatible = "regulator-fixed";
-		regulator-name = "3V3";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-always-on;
-	};
-
-	mmci@1c050000 {
-		compatible = "arm,pl180", "arm,primecell";
-		reg = <0x0 0x001c050000 0x0 0x1000>;
-		interrupts = <0 107 0x4>,
-			     <0 108 0x4>;
-		cd-gpios = <&sysreg 0 0>;
-		wp-gpios = <&sysreg 1 0>;
-		bus-width = <8>;
-		max-frequency = <12000000>;
-		vmmc-supply = <&fixed_3v3>;
-		clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
-		clock-names = "mclk", "apb_pclk";
-	};
-
-	gpu_clk: gpu_clk {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <1000000000>;
-	};
-
-	gpu_core_clk: gpu_core_clk {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <1000000000>;
-	};
-
-	gpu: gpu@2d000000 {
-		compatible = "arm,mali-midgard";
-		reg = <0x0 0x2d000000 0x0 0x200000>;
-		interrupts = <0 66 4>, <0 67 4>, <0 65 4>;
-		interrupt-names = "JOB", "MMU", "GPU";
-		clocks = <&gpu_clk>, <&gpu_core_clk>;
-		clock-names = "clk_mali", "shadercores";
-		iommus = <&smmu_700 0x200>;
-		operating-points = <
-			/* KHz uV */
-			50000 820000
-		>;
-	};
-
-	power_model@simple {
-		/*
-		 * Numbers used are irrelevant to Titan,
-		 * it helps suppressing the kernel warnings.
-		 */
-		compatible = "arm,mali-simple-power-model";
-		static-coefficient = <2427750>;
-		dynamic-coefficient = <4687>;
-		ts = <20000 2000 (-20) 2>;
-		thermal-zone = "";
-	};
-
-	smmu_700: smmu_700@3f000000 {
-		#iommu-cells = <1>;
-		compatible = "arm,smmu-v3";
-		reg = <0x0 0x3f000000 0x0 0x5000000>;
-		dma-coherent;
-	};
-
-	dp0: display@2cc00000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "arm,mali-d71";
-		reg = <0 0x2cc00000 0 0x20000>;
-		interrupts = <0 69 4>;
-		interrupt-names = "DPU";
-		clocks = <&scmi_clk 0>;
-		clock-names = "aclk";
-		iommus = <&smmu_700 0x100>;
-		pl0: pipeline@0 {
-			reg = <0>;
-			clocks = <&scmi_clk 1>;
-			clock-names = "pxclk";
-			pl_id = <0>;
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				port@0 {
-					reg = <0>;
-					dp_pl0_out0: endpoint {
-						remote-endpoint = <&vencoder_in>;
-					};
-				};
-			};
-		};
-
-		pl1: pipeline@1 {
-			reg = <1>;
-			clocks = <&scmi_clk 2>;
-			clock-names = "pxclk";
-			pl_id = <1>;
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				port@0 {
-					reg = <0>;
-				};
-			};
-		};
-	};
-
-	/*
-	 * L3 cache in the DSU is the Memory System Component (MSC)
-	 * The MPAM registers are accessed through utility bus in the DSU
-	 */
-	msc0 {
-		compatible = "arm,mpam-msc";
-		reg = <0x1 0x00010000 0x0 0x2000>;
-	};
-
-	ete0 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU0>;
-	};
-
-	ete1 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU1>;
-	};
-
-	ete2 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU2>;
-	};
-
-	ete3 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU3>;
-	};
-
-	ete4 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU4>;
-	};
-
-	ete5 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU5>;
-	};
-
-	ete6 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU6>;
-	};
-
-	ete7 {
-		compatible = "arm,embedded-trace-extension";
-		cpu = <&CPU7>;
-	};
-
-	trbe0 {
-		compatible = "arm,trace-buffer-extension";
-		interrupts = <1 2 4>;
-	};
-};
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
new file mode 100644
index 00000000..c4922749
--- /dev/null
+++ b/fdts/tc2.dts
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <platform_def.h>
+
+#if TARGET_FLAVOUR_FVP
+#define LIT_CAPACITY			406
+#define MID_CAPACITY			912
+#else /* TARGET_FLAVOUR_FPGA */
+#define LIT_CAPACITY			280
+#define MID_CAPACITY			775
+/* this is an area optimized configuration of the big core */
+#define BIG2_CAPACITY			930
+#endif /* TARGET_FLAVOUR_FPGA */
+#define BIG_CAPACITY			1024
+
+#define MHU_TX_ADDR			45000000 /* hex */
+#define MHU_TX_COMPAT			"arm,mhuv2-tx","arm,primecell"
+#define MHU_TX_INT_NAME			"mhu_tx"
+
+#define MHU_RX_ADDR			45010000 /* hex */
+#define MHU_RX_COMPAT			"arm,mhuv2-rx","arm,primecell"
+#define MHU_OFFSET			0x1000
+#define MHU_MBOX_CELLS			2
+#define MHU_RX_INT_NUM			317
+#define MHU_RX_INT_NAME			"mhu_rx"
+
+#define LIT_CPU_PMU_COMPATIBLE		"arm,cortex-a520-pmu"
+#define MID_CPU_PMU_COMPATIBLE		"arm,cortex-a720-pmu"
+#define BIG_CPU_PMU_COMPATIBLE		"arm,cortex-x4-pmu"
+
+#define MPAM_ADDR			0x1 0x00010000 /* 0x1_0001_0000 */
+#define UARTCLK_FREQ			5000000
+
+#define DPU_ADDR			2cc00000
+#define DPU_IRQ				69
+
+#define ETHERNET_ADDR			18000000
+#define ETHERNET_INT			109
+
+#define SYS_REGS_ADDR			1c010000
+
+#define MMC_ADDR			1c050000
+#define MMC_INT_0			107
+#define MMC_INT_1			108
+
+#define RTC_ADDR			1c170000
+#define RTC_INT				100
+
+#define KMI_0_ADDR			1c060000
+#define KMI_0_INT			197
+#define KMI_1_ADDR			1c070000
+#define KMI_1_INT			103
+
+#define VIRTIO_BLOCK_ADDR		1c130000
+#define VIRTIO_BLOCK_INT		204
+
+#include "tc-common.dtsi"
+#if TARGET_FLAVOUR_FVP
+#include "tc-fvp.dtsi"
+#else
+#include "tc-fpga.dtsi"
+#endif /* TARGET_FLAVOUR_FVP */
+#include "tc-base.dtsi"
+
+/ {
+	cpus {
+#if TARGET_FLAVOUR_FPGA
+		cpu-map {
+			cluster0 {
+				core8 {
+					cpu = <&CPU8>;
+				};
+				core9 {
+					cpu = <&CPU9>;
+				};
+				core10 {
+					cpu = <&CPU10>;
+				};
+				core11 {
+					cpu = <&CPU11>;
+				};
+				core12 {
+					cpu = <&CPU12>;
+				};
+				core13 {
+					cpu = <&CPU13>;
+				};
+			};
+		};
+#endif
+
+		CPU2:cpu@200 {
+			clocks = <&scmi_dvfs 0>;
+			capacity-dmips-mhz = <LIT_CAPACITY>;
+		};
+
+		CPU3:cpu@300 {
+			clocks = <&scmi_dvfs 0>;
+			capacity-dmips-mhz = <LIT_CAPACITY>;
+		};
+
+		CPU6:cpu@600 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+		CPU7:cpu@700 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+#if TARGET_FLAVOUR_FPGA
+		CPU8:cpu@800 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x800>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU9:cpu@900 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x900>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG2_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU10:cpu@A00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xA00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG2_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU11:cpu@B00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xB00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG2_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU12:cpu@C00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xC00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 3>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+
+		CPU13:cpu@D00 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0xD00>;
+			enable-method = "psci";
+			clocks = <&scmi_dvfs 3>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+			amu = <&amu>;
+			supports-mpmm;
+		};
+#endif
+	};
+
+#if TARGET_FLAVOUR_FPGA
+	ete8 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU8>;
+	};
+
+	ete9 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU9>;
+	};
+
+	ete10 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU10>;
+	};
+
+	ete11 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU11>;
+	};
+
+	ete12 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU12>;
+	};
+
+	ete13 {
+		compatible = "arm,embedded-trace-extension";
+		cpu = <&CPU13>;
+	};
+#endif /* TARGET_FLAVOUR_FPGA */
+
+	cmn-pmu {
+		compatible = "arm,ci-700";
+		reg = <0x0 0x50000000 0x0 0x10000000>;
+		interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH 0>;
+	};
+
+	mbox_db_rx: mhu@MHU_RX_ADDR {
+		arm,mhuv2-protocols = <0 1>;
+	};
+
+	mbox_db_tx: mhu@MHU_TX_ADDR {
+		arm,mhuv2-protocols = <0 1>;
+	};
+
+	firmware {
+		/*
+		 * TC2 does not have a P2A channel, but wiring one was needed to make Linux work
+		 * (by chance). At the time the SCMI driver did not support bidirectional
+		 * mailboxes so as a workaround, the A2P channel was wired for TX communication
+		 * and the synchronous replies would be read asyncrhonously as if coming from
+		 * the P2A channel, while being the actual A2P channel.
+		 *
+		 * This will not work with kernels > 5.15, but keep it around to keep TC2
+		 * working with its target kernel. Newer kernels will still work, but SCMI
+		 * won't as they check that the two regions are distinct.
+		 */
+		scmi {
+			mboxes = <&mbox_db_tx 0 0 &mbox_db_rx 0 0>;
+			shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_a2p>;
+		};
+	};
+
+	gic: interrupt-controller@GIC_CTRL_ADDR {
+		ppi-partitions {
+			ppi_partition_little: interrupt-partition-0 {
+				affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>;
+			};
+
+#if TARGET_FLAVOUR_FVP
+			ppi_partition_mid: interrupt-partition-1 {
+				affinity = <&CPU4>, <&CPU5>, <&CPU6>;
+			};
+
+			ppi_partition_big: interrupt-partition-2 {
+				affinity = <&CPU7>;
+			};
+#elif TARGET_FLAVOUR_FPGA
+			ppi_partition_mid: interrupt-partition-1 {
+				affinity = <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>, <&CPU8>;
+			};
+
+			ppi_partition_big: interrupt-partition-2 {
+				affinity = <&CPU9>, <&CPU10>, <&CPU11>, <&CPU12>, <&CPU13>;
+			};
+#endif
+		};
+	};
+
+	spe-pmu-big {
+		status = "okay";
+	};
+
+	smmu_700: iommu@3f000000 {
+		status = "okay";
+	};
+
+	dp0: display@DPU_ADDR {
+#if TC_SCMI_PD_CTRL_EN
+		power-domains = <&scmi_devpd (PLAT_MAX_CPUS_PER_CLUSTER + 2)>;
+#endif
+		iommus = <&smmu_700 0x100>;
+	};
+
+	gpu: gpu@2d000000 {
+		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "JOB", "MMU", "GPU";
+		iommus = <&smmu_700 0x200>;
+	};
+};
diff --git a/fdts/tc3-4-base.dtsi b/fdts/tc3-4-base.dtsi
new file mode 100644
index 00000000..2de5fd3a
--- /dev/null
+++ b/fdts/tc3-4-base.dtsi
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define LIT_CAPACITY			239
+#define MID_CAPACITY			686
+#define BIG_CAPACITY			1024
+
+#define MHU_TX_COMPAT			"arm,mhuv3"
+#define MHU_TX_INT_NAME			""
+
+#define MHU_RX_COMPAT			"arm,mhuv3"
+#define MHU_OFFSET			0x10000
+#define MHU_MBOX_CELLS			3
+#define MHU_RX_INT_NUM			300
+#define MHU_RX_INT_NAME			"combined"
+
+#define MPAM_ADDR			0x0 0x5f010000 /* 0x5f01_0000 */
+#define UARTCLK_FREQ			3750000
+
+#if TARGET_FLAVOUR_FVP
+#define DPU_ADDR			4000000000
+#define DPU_IRQ				579
+#elif TARGET_FLAVOUR_FPGA
+#define DPU_ADDR			2cc00000
+#define DPU_IRQ				69
+#endif
+#include "tc-base.dtsi"
+
+/ {
+	cpus {
+		CPU2:cpu@200 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+		CPU3:cpu@300 {
+			clocks = <&scmi_dvfs 1>;
+			capacity-dmips-mhz = <MID_CAPACITY>;
+		};
+
+		CPU6:cpu@600 {
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+		};
+
+		CPU7:cpu@700 {
+			clocks = <&scmi_dvfs 2>;
+			capacity-dmips-mhz = <BIG_CAPACITY>;
+		};
+	};
+
+	gic: interrupt-controller@GIC_CTRL_ADDR {
+		ppi-partitions {
+			ppi_partition_little: interrupt-partition-0 {
+				affinity = <&CPU0>, <&CPU1>;
+			};
+
+			ppi_partition_mid: interrupt-partition-1 {
+				affinity = <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>;
+			};
+
+			ppi_partition_big: interrupt-partition-2 {
+				affinity = <&CPU6>, <&CPU7>;
+			};
+		};
+	};
+
+	sram: sram@6000000 {
+		cpu_scp_scmi_p2a: scp-shmem@80 {
+			compatible = "arm,scmi-shmem";
+			reg = <0x80 0x80>;
+		};
+	};
+
+	firmware {
+		scmi {
+			mboxes = <&mbox_db_tx 0 0 0 &mbox_db_rx 0 0 0 &mbox_db_rx 0 0 1>;
+			shmem = <&cpu_scp_scmi_a2p &cpu_scp_scmi_p2a>;
+		};
+	};
+};
diff --git a/fdts/tc3.dts b/fdts/tc3.dts
new file mode 100644
index 00000000..ffe3b6d9
--- /dev/null
+++ b/fdts/tc3.dts
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <platform_def.h>
+
+#define MHU_TX_ADDR			46040000 /* hex */
+#define MHU_RX_ADDR			46140000 /* hex */
+
+#define LIT_CPU_PMU_COMPATIBLE		"arm,cortex-a520-pmu"
+#define MID_CPU_PMU_COMPATIBLE		"arm,cortex-a725-pmu"
+#define BIG_CPU_PMU_COMPATIBLE		"arm,cortex-x925-pmu"
+
+#define ETHERNET_ADDR			18000000
+#define ETHERNET_INT			109
+
+#define SYS_REGS_ADDR			1c010000
+
+#define MMC_ADDR			1c050000
+#define MMC_INT_0			107
+#define MMC_INT_1			108
+
+#define RTC_ADDR			1c170000
+#define RTC_INT				100
+
+#define KMI_0_ADDR			1c060000
+#define KMI_0_INT			197
+#define KMI_1_ADDR			1c070000
+#define KMI_1_INT			103
+
+#define VIRTIO_BLOCK_ADDR		1c130000
+#define VIRTIO_BLOCK_INT		204
+
+#include "tc-common.dtsi"
+#if TARGET_FLAVOUR_FVP
+#include "tc-fvp.dtsi"
+#else
+#include "tc-fpga.dtsi"
+#endif /* TARGET_FLAVOUR_FVP */
+#include "tc3-4-base.dtsi"
+
+/ {
+	cs-pmu@0 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(0) 0x0 0xffc>;
+	};
+
+	cs-pmu@1 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(1) 0x0 0xffc>;
+	};
+
+	cs-pmu@2 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(2) 0x0 0xffc>;
+	};
+
+	cs-pmu@3 {
+		compatible = "arm,coresight-pmu";
+		reg = <0x0 MCN_PMU_ADDR(3) 0x0 0xffc>;
+	};
+
+	spe-pmu-mid {
+		status = "okay";
+	};
+
+	spe-pmu-big {
+		status = "okay";
+	};
+
+	dsu-pmu {
+		compatible = "arm,dsu-pmu";
+		cpus = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
+	};
+
+	ni-pmu {
+		compatible = "arm,ni-tower";
+		reg = <0x0 0x4f000000 0x0 0x4000000>;
+	};
+
+#if TARGET_FLAVOUR_FVP
+	smmu_700: iommu@3f000000 {
+		status = "okay";
+	};
+
+	smmu_700_dpu: iommu@4002a00000 {
+		status = "okay";
+	};
+#else
+	smmu_600: smmu@2ce00000 {
+		status = "okay";
+	};
+#endif
+
+	dp0: display@DPU_ADDR {
+#if TARGET_FLAVOUR_FVP
+		iommus = <&smmu_700_dpu 0x000>, <&smmu_700_dpu 0x100>,
+			 <&smmu_700_dpu 0x200>, <&smmu_700_dpu 0x600>;
+#else /* TARGET_FLAVOUR_FPGA */
+		iommus = <&smmu_600 0>, <&smmu_600 1>, <&smmu_600 2>, <&smmu_600 3>,
+			 <&smmu_600 4>, <&smmu_600 5>, <&smmu_600 6>, <&smmu_600 7>,
+			 <&smmu_600 8>, <&smmu_600 9>;
+#endif
+	};
+
+	gpu: gpu@2d000000 {
+		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "JOB", "MMU", "GPU";
+#if TARGET_FLAVOUR_FVP
+		iommus = <&smmu_700 0x200>;
+#endif
+	};
+};
diff --git a/fdts/tc4.dts b/fdts/tc4.dts
new file mode 100644
index 00000000..135d30a2
--- /dev/null
+++ b/fdts/tc4.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <platform_def.h>
+
+#define MHU_TX_ADDR			46240000 /* hex */
+#define MHU_RX_ADDR			46250000 /* hex */
+
+#define LIT_CPU_PMU_COMPATIBLE		"arm,armv8-pmuv3"
+#define MID_CPU_PMU_COMPATIBLE		"arm,armv8-pmuv3"
+#define BIG_CPU_PMU_COMPATIBLE		"arm,armv8-pmuv3"
+
+#define ETHERNET_ADDR			64000000
+#define ETHERNET_INT			799
+
+#define SYS_REGS_ADDR			60080000
+
+#define MMC_ADDR			600b0000
+#define MMC_INT_0			778
+#define MMC_INT_1			779
+
+#define RTC_ADDR			600a0000
+#define RTC_INT				777
+
+#define KMI_0_ADDR			60100000
+#define KMI_0_INT			784
+#define KMI_1_ADDR			60110000
+#define KMI_1_INT			785
+
+#define VIRTIO_BLOCK_ADDR		60020000
+#define VIRTIO_BLOCK_INT		769
+
+#include "tc-common.dtsi"
+#if TARGET_FLAVOUR_FVP
+#include "tc-fvp.dtsi"
+#else
+#include "tc-fpga.dtsi"
+#endif /* TARGET_FLAVOUR_FVP */
+#include "tc3-4-base.dtsi"
+
+/ {
+	smmu_700: iommu@3f000000 {
+		status = "okay";
+	};
+
+	smmu_700_dpu: iommu@4002a00000 {
+		status = "okay";
+	};
+
+	dp0: display@DPU_ADDR {
+		iommus = <&smmu_700_dpu 0x000>, <&smmu_700_dpu 0x100>,
+			 <&smmu_700_dpu 0x200>, <&smmu_700_dpu 0x600>;
+	};
+
+	gpu: gpu@2d000000 {
+		interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "IRQAW";
+		iommus = <&smmu_700 0x200>;
+	};
+};
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index a7117532..d2591ddb 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -111,18 +111,18 @@
 #define ID_DFR0_PERFMON_PMUV3P5		U(6)
 #define ID_DFR0_COPTRC_SHIFT		U(12)
 #define ID_DFR0_COPTRC_MASK		U(0xf)
-#define ID_DFR0_COPTRC_SUPPORTED	U(1)
+#define COPTRC_IMPLEMENTED		U(1)
 #define ID_DFR0_COPTRC_LENGTH		U(4)
 #define ID_DFR0_TRACEFILT_SHIFT		U(28)
 #define ID_DFR0_TRACEFILT_MASK		U(0xf)
-#define ID_DFR0_TRACEFILT_SUPPORTED	U(1)
+#define TRACEFILT_IMPLEMENTED		U(1)
 #define ID_DFR0_TRACEFILT_LENGTH	U(4)
 
 /* ID_DFR1_EL1 definitions */
 #define ID_DFR1_MTPMU_SHIFT	U(0)
 #define ID_DFR1_MTPMU_MASK	U(0xf)
-#define ID_DFR1_MTPMU_SUPPORTED	U(1)
-#define ID_DFR1_MTPMU_DISABLED	U(15)
+#define MTPMU_IMPLEMENTED	U(1)
+#define MTPMU_NOT_IMPLEMENTED	U(15)
 
 /* ID_MMFR3 definitions */
 #define ID_MMFR3_PAN_SHIFT	U(16)
@@ -141,14 +141,13 @@
 #define ID_PFR0_AMU_SHIFT	U(20)
 #define ID_PFR0_AMU_LENGTH	U(4)
 #define ID_PFR0_AMU_MASK	U(0xf)
-#define ID_PFR0_AMU_NOT_SUPPORTED	U(0x0)
 #define ID_PFR0_AMU_V1		U(0x1)
 #define ID_PFR0_AMU_V1P1	U(0x2)
 
 #define ID_PFR0_DIT_SHIFT	U(24)
 #define ID_PFR0_DIT_LENGTH	U(4)
 #define ID_PFR0_DIT_MASK	U(0xf)
-#define ID_PFR0_DIT_SUPPORTED	(U(1) << ID_PFR0_DIT_SHIFT)
+#define DIT_IMPLEMENTED		(U(1) << ID_PFR0_DIT_SHIFT)
 
 /* ID_PFR1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
@@ -163,6 +162,11 @@
 #define ID_PFR1_SEC_MASK	U(0xf)
 #define ID_PFR1_ELx_ENABLED	U(1)
 
+/* ID_PFR2 definitions */
+#define ID_PFR2_SSBS_SHIFT	U(4)
+#define ID_PFR2_SSBS_MASK	U(0xf)
+#define SSBS_NOT_IMPLEMENTED	U(0)
+
 /* SCTLR definitions */
 #define SCTLR_RES1_DEF		((U(1) << 23) | (U(1) << 22) | (U(1) << 4) | \
 				 (U(1) << 3))
@@ -552,6 +556,7 @@
 #define ID_DFR1		p15, 0, c0, c3, 5
 #define ID_PFR0		p15, 0, c0, c1, 0
 #define ID_PFR1		p15, 0, c0, c1, 1
+#define ID_PFR2		p15, 0, c0, c3, 4
 #define MAIR0		p15, 0, c10, c2, 0
 #define MAIR1		p15, 0, c10, c2, 1
 #define TTBCR		p15, 0, c2, c0, 2
@@ -692,8 +697,7 @@
 /* PAR fields */
 #define PAR_F_SHIFT	U(0)
 #define PAR_F_MASK	ULL(0x1)
-#define PAR_ADDR_SHIFT	U(12)
-#define PAR_ADDR_MASK	(BIT_64(40) - ULL(1)) /* 40-bits-wide page address */
+#define PAR_ADDR_MASK	GENMASK_64(39, 12) /* 28-bits-wide page address */
 
 /*******************************************************************************
  * Definitions for system register interface to AMU for FEAT_AMUv1
@@ -790,7 +794,21 @@
 /*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
  ******************************************************************************/
-#define CLUSTERPWRDN	p15, 0, c15, c3, 6
+#define CLUSTERPWRDN		p15, 0, c15, c3, 6
+#define CLUSTERPMCR		p15, 0, c15, c5, 0
+#define CLUSTERPMCNTENSET	p15, 0, c15, c5, 1
+#define CLUSTERPMCCNTR		p15, 0, c15, c6, 0
+#define CLUSTERPMOVSSET		p15, 0, c15, c5, 3
+#define CLUSTERPMOVSCLR		p15, 0, c15, c5, 4
+#define CLUSTERPMSELR		p15, 0, c15, c5, 5
+#define CLUSTERPMXEVTYPER	p15, 0,	c15, c6, 1
+#define CLUSTERPMXEVCNTR	p15, 0, c15, c6, 2
+
+/* CLUSTERPMCR register definitions */
+#define CLUSTERPMCR_E_BIT	BIT(0)
+#define CLUSTERPMCR_N_SHIFT	U(11)
+#define CLUSTERPMCR_N_MASK	U(0x1f)
+
 
 /* CLUSTERPWRDN register definitions */
 #define DSU_CLUSTER_PWR_OFF	0
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index f19c4c2f..e3472401 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,179 +12,191 @@
 #include <arch_helpers.h>
 #include <common/feat_detect.h>
 
-#define ISOLATE_FIELD(reg, feat)					\
-	((unsigned int)(((reg) >> (feat ## _SHIFT)) & (feat ## _MASK)))
+#define ISOLATE_FIELD(reg, feat, mask)						\
+	((unsigned int)(((reg) >> (feat)) & mask))
 
-static inline bool is_armv7_gentimer_present(void)
-{
-	return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER) != 0U;
-}
-
-static inline bool is_armv8_2_ttcnp_present(void)
-{
-	return ISOLATE_FIELD(read_id_mmfr4(), ID_MMFR4_CNP) != 0U;
+#define CREATE_FEATURE_SUPPORTED(name, read_func, guard)			\
+__attribute__((always_inline))							\
+static inline bool is_ ## name ## _supported(void)				\
+{										\
+	if ((guard) == FEAT_STATE_DISABLED) {					\
+		return false;							\
+	}									\
+	if ((guard) == FEAT_STATE_ALWAYS) {					\
+		return true;							\
+	}									\
+	return read_func();							\
 }
 
-static unsigned int read_feat_amu_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_AMU);
+#define CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)		\
+__attribute__((always_inline))							\
+static inline bool is_ ## name ## _present(void)				\
+{										\
+	return (ISOLATE_FIELD(read_ ## idreg(), idfield, mask) >= idval) 	\
+		? true : false;							\
 }
 
-static inline bool is_feat_amu_supported(void)
-{
-	if (ENABLE_FEAT_AMU == FEAT_STATE_DISABLED) {
-		return false;
-	}
+#define CREATE_FEATURE_FUNCS(name, idreg, idfield, mask, idval, guard)		\
+CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)			\
+CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard)
 
-	if (ENABLE_FEAT_AMU == FEAT_STATE_ALWAYS) {
-		return true;
-	}
 
-	return read_feat_amu_id_field() >= ID_PFR0_AMU_V1;
-}
+/*
+ * +----------------------------+
+ * |	Features supported	|
+ * +----------------------------+
+ * |	GENTIMER		|
+ * +----------------------------+
+ * |	FEAT_TTCNP		|
+ * +----------------------------+
+ * |	FEAT_AMU		|
+ * +----------------------------+
+ * |	FEAT_AMUV1P1		|
+ * +----------------------------+
+ * |	FEAT_TRF		|
+ * +----------------------------+
+ * |	FEAT_SYS_REG_TRACE 	|
+ * +----------------------------+
+ * |	FEAT_DIT		|
+ * +----------------------------+
+ * |	FEAT_PAN		|
+ * +----------------------------+
+ * |	FEAT_SSBS		|
+ * +----------------------------+
+ * |	FEAT_PMUV3		|
+ * +----------------------------+
+ * |	FEAT_MTPMU		|
+ * +----------------------------+
+ */
 
-static inline bool is_feat_amuv1p1_supported(void)
+/* GENTIMER */
+__attribute__((always_inline))
+static inline bool is_armv7_gentimer_present(void)
 {
-	if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_amu_id_field() >= ID_PFR0_AMU_V1P1;
+	return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER_SHIFT,
+			    ID_PFR1_GENTIMER_MASK) != 0U;
 }
 
-static inline unsigned int read_feat_trf_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_TRACEFILT);
-}
+/* FEAT_TTCNP: Translation table common not private */
+CREATE_FEATURE_PRESENT(feat_ttcnp, id_mmfr4, ID_MMFR4_CNP_SHIFT,
+		      ID_MMFR4_CNP_MASK, 1U)
 
-static inline bool is_feat_trf_supported(void)
-{
-	if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
+/* FEAT_AMU: Activity Monitors Extension */
+CREATE_FEATURE_FUNCS(feat_amu, id_pfr0, ID_PFR0_AMU_SHIFT,
+		    ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1, ENABLE_FEAT_AMU)
 
-	if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
+/* 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)
 
-	return read_feat_trf_id_field() != 0U;
-}
+/* FEAT_TRF: Tracefilter */
+CREATE_FEATURE_FUNCS(feat_trf, id_dfr0, ID_DFR0_TRACEFILT_SHIFT,
+		    ID_DFR0_TRACEFILT_MASK, 1U, ENABLE_TRF_FOR_NS)
 
-static inline unsigned int read_feat_coptrc_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_COPTRC);
-}
+/* FEAT_SYS_REG_TRACE */
+CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_dfr0, ID_DFR0_COPTRC_SHIFT,
+		    ID_DFR0_COPTRC_MASK, 1U, ENABLE_SYS_REG_TRACE_FOR_NS)
 
-static inline bool is_feat_sys_reg_trace_supported(void)
-{
-	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
-		return false;
-	}
+/* FEAT_DIT: Data independent timing */
+CREATE_FEATURE_FUNCS(feat_dit, id_pfr0, ID_PFR0_DIT_SHIFT,
+		    ID_PFR0_DIT_MASK, 1U, ENABLE_FEAT_DIT)
 
-	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
-		return true;
-	}
+/* FEAT_PAN: Privileged access never */
+CREATE_FEATURE_FUNCS(feat_pan, id_mmfr3, ID_MMFR3_PAN_SHIFT,
+		    ID_MMFR3_PAN_MASK, 1U, ENABLE_FEAT_PAN)
 
-	return read_feat_coptrc_id_field() != 0U;
-}
+/* FEAT_SSBS: Speculative store bypass safe */
+CREATE_FEATURE_PRESENT(feat_ssbs, id_pfr2, ID_PFR2_SSBS_SHIFT,
+		      ID_PFR2_SSBS_MASK, 1U)
 
-static inline unsigned int read_feat_dit_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_DIT);
-}
+/* FEAT_PMUV3 */
+CREATE_FEATURE_PRESENT(feat_pmuv3, id_dfr0, ID_DFR0_PERFMON_SHIFT,
+		      ID_DFR0_PERFMON_MASK, 3U)
 
-static inline bool is_feat_dit_supported(void)
+/* FEAT_MTPMU */
+__attribute__((always_inline))
+static inline bool is_feat_mtpmu_present(void)
 {
-	if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_dit_id_field() != 0U;
-}
-
-static inline unsigned int read_feat_pan_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_mmfr3(), ID_MMFR3_PAN);
-}
-
-static inline bool is_feat_pan_supported(void)
-{
-	if (ENABLE_FEAT_PAN == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	return read_feat_pan_id_field() != 0U;
+	unsigned int mtpmu = ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU_SHIFT,
+			    ID_DFR1_MTPMU_MASK);
+	return (mtpmu != 0U) && (mtpmu != MTPMU_NOT_IMPLEMENTED);
 }
+CREATE_FEATURE_SUPPORTED(feat_mtpmu, is_feat_mtpmu_present, DISABLE_MTPMU)
 
 /*
  * TWED, ECV, CSV2, RAS are only used by the AArch64 EL2 context switch
  * code. In fact, EL2 context switching is only needed for AArch64 (since
  * there is no secure AArch32 EL2), so just disable these features here.
  */
+__attribute__((always_inline))
 static inline bool is_feat_twed_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_ecv_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_ecv_v2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_csv2_2_supported(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_csv2_3_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_ras_supported(void) { return false; }
 
 /* The following features are supported in AArch64 only. */
+__attribute__((always_inline))
 static inline bool is_feat_vhe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sel2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_fgt_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_tcr2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_spe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_rng_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_gcs_supported(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_mte2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_mpam_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_hcx_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sve_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_brbe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_trbe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_nv2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sme_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sme2_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_s2poe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_s1poe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sxpoe_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_s2pie_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_s1pie_supported(void) { return false; }
+__attribute__((always_inline))
 static inline bool is_feat_sxpie_supported(void) { return false; }
-
-static inline unsigned int read_feat_pmuv3_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_PERFMON);
-}
-
-static inline unsigned int read_feat_mtpmu_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU);
-}
-
-static inline bool is_feat_mtpmu_supported(void)
-{
-	if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	unsigned int mtpmu = read_feat_mtpmu_id_field();
-
-	return mtpmu != 0U && mtpmu != ID_DFR1_MTPMU_DISABLED;
-}
+__attribute__((always_inline))
+static inline bool is_feat_uao_present(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_nmi_present(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_ebep_present(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_sebep_present(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_d128_present(void) { return false; }
+__attribute__((always_inline))
+static inline bool is_feat_ls64_accdata_present(void) { return false; }
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index 3a7c7680..adc96ae0 100644
--- a/include/arch/aarch32/arch_helpers.h
+++ b/include/arch/aarch32/arch_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -224,6 +224,7 @@ DEFINE_COPROCR_READ_FUNC(id_dfr0, ID_DFR0)
 DEFINE_COPROCR_READ_FUNC(id_dfr1, ID_DFR1)
 DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0)
 DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
+DEFINE_COPROCR_READ_FUNC(id_pfr2, ID_PFR2)
 DEFINE_COPROCR_READ_FUNC(isr, ISR)
 DEFINE_COPROCR_READ_FUNC(clidr, CLIDR)
 DEFINE_COPROCR_READ_FUNC_64(cntpct, CNTPCT_64)
@@ -353,6 +354,14 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC)
  * DynamIQ Shared Unit power management
  */
 DEFINE_COPROCR_RW_FUNCS(clusterpwrdn, CLUSTERPWRDN)
+DEFINE_COPROCR_RW_FUNCS(clusterpmcr, CLUSTERPMCR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmcntenset, CLUSTERPMCNTENSET)
+DEFINE_COPROCR_RW_FUNCS(clusterpmccntr, CLUSTERPMCCNTR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmovsset, CLUSTERPMOVSSET)
+DEFINE_COPROCR_RW_FUNCS(clusterpmovsclr, CLUSTERPMOVSCLR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmselr, CLUSTERPMSELR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmxevcntr, CLUSTERPMXEVCNTR)
+DEFINE_COPROCR_RW_FUNCS(clusterpmxevtyper, CLUSTERPMXEVTYPER)
 
 /*
  * RNDR is AArch64 only, so just provide a placeholder here to make the
diff --git a/include/arch/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S
index 3ba86e95..bccd2a7d 100644
--- a/include/arch/aarch32/asm_macros.S
+++ b/include/arch/aarch32/asm_macros.S
@@ -241,4 +241,13 @@ div2:
 	cmp     \temp, \bot
 	bhs     div2
 	.endm
+
+	/*
+	 * Helper macro to instruction adr <reg>, <symbol> where <symbol> is
+	 * within the range +/- 4 GB.
+	 */
+	.macro adr_l, dst, sym
+	adrp	\dst, \sym
+	add	\dst, \dst, :lo12:\sym
+	.endm
 #endif /* ASM_MACROS_S */
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index 697eb82c..41eeabb5 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -76,7 +76,7 @@
 	orr	r0, r0, #(NSACR_RESET_VAL | NSACR_ENABLE_FP_ACCESS)
 	ldcopr	r1, ID_DFR0
 	ubfx	r1, r1, #ID_DFR0_COPTRC_SHIFT, #ID_DFR0_COPTRC_LENGTH
-	cmp	r1, #ID_DFR0_COPTRC_SUPPORTED
+	cmp	r1, #COPTRC_IMPLEMENTED
 	bne	1f
 	orr	r0, r0, #NSTRCDIS_BIT
 1:
@@ -143,7 +143,7 @@
 		      SDCR_SCCD_BIT) & ~SDCR_TTRF_BIT)
 	ldcopr	r1, ID_DFR0
 	ubfx	r1, r1, #ID_DFR0_TRACEFILT_SHIFT, #ID_DFR0_TRACEFILT_LENGTH
-	cmp	r1, #ID_DFR0_TRACEFILT_SUPPORTED
+	cmp	r1, #TRACEFILT_IMPLEMENTED
 	bne	1f
 	orr	r0, r0, #SDCR_TTRF_BIT
 1:
@@ -182,7 +182,7 @@
 	 */
 	ldcopr	r0, ID_PFR0
 	and	r0, r0, #(ID_PFR0_DIT_MASK << ID_PFR0_DIT_SHIFT)
-	cmp	r0, #ID_PFR0_DIT_SUPPORTED
+	cmp	r0, #DIT_IMPLEMENTED
 	bne	1f
 	mrs	r0, cpsr
 	orr	r0, r0, #CPSR_DIT_BIT
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index e9d22b61..737d07ad 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -24,6 +24,9 @@
 #define MIDR_PN_MASK		U(0xfff)
 #define MIDR_PN_SHIFT		U(0x4)
 
+/* Extracts the CPU part number from MIDR for checking CPU match */
+#define EXTRACT_PARTNUM(x)     ((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+
 /*******************************************************************************
  * MPIDR macros
  ******************************************************************************/
@@ -74,6 +77,19 @@
  */
 #define INVALID_MPID		U(0xFFFFFFFF)
 
+/*******************************************************************************
+ * Definitions for Exception vector offsets
+ ******************************************************************************/
+#define CURRENT_EL_SP0		0x0
+#define CURRENT_EL_SPX		0x200
+#define LOWER_EL_AARCH64	0x400
+#define LOWER_EL_AARCH32	0x600
+
+#define SYNC_EXCEPTION		0x0
+#define IRQ_EXCEPTION		0x80
+#define FIQ_EXCEPTION		0x100
+#define SERROR_EXCEPTION	0x180
+
 /*******************************************************************************
  * Definitions for CPU system register interface to GICv3
  ******************************************************************************/
@@ -101,9 +117,14 @@
  * Definitions for EL2 system registers for save/restore routine
  ******************************************************************************/
 #define CNTPOFF_EL2		S3_4_C14_C0_6
-#define HAFGRTR_EL2		S3_4_C3_C1_6
+#define HDFGRTR2_EL2		S3_4_C3_C1_0
+#define HDFGWTR2_EL2		S3_4_C3_C1_1
+#define HFGRTR2_EL2		S3_4_C3_C1_2
+#define HFGWTR2_EL2		S3_4_C3_C1_3
 #define HDFGRTR_EL2		S3_4_C3_C1_4
 #define HDFGWTR_EL2		S3_4_C3_C1_5
+#define HAFGRTR_EL2		S3_4_C3_C1_6
+#define HFGITR2_EL2		S3_4_C3_C1_7
 #define HFGITR_EL2		S3_4_C1_C1_6
 #define HFGRTR_EL2		S3_4_C1_C1_4
 #define HFGWTR_EL2		S3_4_C1_C1_5
@@ -118,7 +139,6 @@
 #define MPAMVPM6_EL2		S3_4_C10_C6_6
 #define MPAMVPM7_EL2		S3_4_C10_C6_7
 #define MPAMVPMV_EL2		S3_4_C10_C4_1
-#define TRFCR_EL2		S3_4_C1_C2_1
 #define VNCR_EL2		S3_4_C2_C2_0
 #define PMSCR_EL2		S3_4_C9_C9_0
 #define TFSR_EL2		S3_4_C5_C6_0
@@ -167,7 +187,6 @@
 
 #define ID_AA64PFR0_AMU_SHIFT			U(44)
 #define ID_AA64PFR0_AMU_MASK			ULL(0xf)
-#define ID_AA64PFR0_AMU_NOT_SUPPORTED		U(0x0)
 #define ID_AA64PFR0_AMU_V1			ULL(0x1)
 #define ID_AA64PFR0_AMU_V1P1			U(0x2)
 
@@ -179,8 +198,8 @@
 
 #define ID_AA64PFR0_SVE_SHIFT			U(32)
 #define ID_AA64PFR0_SVE_MASK			ULL(0xf)
-#define ID_AA64PFR0_SVE_SUPPORTED		ULL(0x1)
 #define ID_AA64PFR0_SVE_LENGTH			U(4)
+#define SVE_IMPLEMENTED				ULL(0x1)
 
 #define ID_AA64PFR0_SEL2_SHIFT			U(36)
 #define ID_AA64PFR0_SEL2_MASK			ULL(0xf)
@@ -191,22 +210,21 @@
 #define ID_AA64PFR0_DIT_SHIFT			U(48)
 #define ID_AA64PFR0_DIT_MASK			ULL(0xf)
 #define ID_AA64PFR0_DIT_LENGTH			U(4)
-#define ID_AA64PFR0_DIT_SUPPORTED		U(1)
+#define DIT_IMPLEMENTED				ULL(1)
 
 #define ID_AA64PFR0_CSV2_SHIFT			U(56)
 #define ID_AA64PFR0_CSV2_MASK			ULL(0xf)
 #define ID_AA64PFR0_CSV2_LENGTH			U(4)
-#define ID_AA64PFR0_CSV2_2_SUPPORTED		ULL(0x2)
+#define CSV2_2_IMPLEMENTED			ULL(0x2)
+#define CSV2_3_IMPLEMENTED			ULL(0x3)
 
 #define ID_AA64PFR0_FEAT_RME_SHIFT		U(52)
 #define ID_AA64PFR0_FEAT_RME_MASK		ULL(0xf)
 #define ID_AA64PFR0_FEAT_RME_LENGTH		U(4)
-#define ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED	U(0)
-#define ID_AA64PFR0_FEAT_RME_V1			U(1)
+#define RME_NOT_IMPLEMENTED			ULL(0)
 
 #define ID_AA64PFR0_RAS_SHIFT			U(28)
 #define ID_AA64PFR0_RAS_MASK			ULL(0xf)
-#define ID_AA64PFR0_RAS_NOT_SUPPORTED		ULL(0x0)
 #define ID_AA64PFR0_RAS_LENGTH			U(4)
 
 /* Exception level handling */
@@ -214,43 +232,59 @@
 #define EL_IMPL_A64ONLY		ULL(1)
 #define EL_IMPL_A64_A32		ULL(2)
 
+/* ID_AA64DFR0_EL1.DebugVer definitions */
+#define ID_AA64DFR0_DEBUGVER_SHIFT		U(0)
+#define ID_AA64DFR0_DEBUGVER_MASK		ULL(0xf)
+#define DEBUGVER_V8P9_IMPLEMENTED		ULL(0xb)
+
 /* ID_AA64DFR0_EL1.TraceVer definitions */
 #define ID_AA64DFR0_TRACEVER_SHIFT	U(4)
 #define ID_AA64DFR0_TRACEVER_MASK	ULL(0xf)
-#define ID_AA64DFR0_TRACEVER_SUPPORTED	ULL(1)
 #define ID_AA64DFR0_TRACEVER_LENGTH	U(4)
+
 #define ID_AA64DFR0_TRACEFILT_SHIFT	U(40)
 #define ID_AA64DFR0_TRACEFILT_MASK	U(0xf)
-#define ID_AA64DFR0_TRACEFILT_SUPPORTED	U(1)
 #define ID_AA64DFR0_TRACEFILT_LENGTH	U(4)
+#define TRACEFILT_IMPLEMENTED		ULL(1)
+
 #define ID_AA64DFR0_PMUVER_LENGTH	U(4)
 #define ID_AA64DFR0_PMUVER_SHIFT	U(8)
 #define ID_AA64DFR0_PMUVER_MASK		U(0xf)
 #define ID_AA64DFR0_PMUVER_PMUV3	U(1)
-#define ID_AA64DFR0_PMUVER_PMUV3P7	U(7)
+#define ID_AA64DFR0_PMUVER_PMUV3P8	U(8)
 #define ID_AA64DFR0_PMUVER_IMP_DEF	U(0xf)
 
+/* ID_AA64DFR0_EL1.SEBEP definitions */
+#define ID_AA64DFR0_SEBEP_SHIFT		U(24)
+#define ID_AA64DFR0_SEBEP_MASK		ULL(0xf)
+#define SEBEP_IMPLEMENTED		ULL(1)
+
 /* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
 #define ID_AA64DFR0_PMS_SHIFT		U(32)
 #define ID_AA64DFR0_PMS_MASK		ULL(0xf)
-#define ID_AA64DFR0_SPE_SUPPORTED	ULL(0x1)
-#define ID_AA64DFR0_SPE_NOT_SUPPORTED   ULL(0x0)
+#define SPE_IMPLEMENTED			ULL(0x1)
+#define SPE_NOT_IMPLEMENTED		ULL(0x0)
 
 /* ID_AA64DFR0_EL1.TraceBuffer definitions */
 #define ID_AA64DFR0_TRACEBUFFER_SHIFT		U(44)
 #define ID_AA64DFR0_TRACEBUFFER_MASK		ULL(0xf)
-#define ID_AA64DFR0_TRACEBUFFER_SUPPORTED	ULL(1)
+#define TRACEBUFFER_IMPLEMENTED			ULL(1)
 
 /* ID_AA64DFR0_EL1.MTPMU definitions (for ARMv8.6+) */
 #define ID_AA64DFR0_MTPMU_SHIFT		U(48)
 #define ID_AA64DFR0_MTPMU_MASK		ULL(0xf)
-#define ID_AA64DFR0_MTPMU_SUPPORTED	ULL(1)
-#define ID_AA64DFR0_MTPMU_DISABLED	ULL(15)
+#define MTPMU_IMPLEMENTED		ULL(1)
+#define MTPMU_NOT_IMPLEMENTED		ULL(15)
 
 /* ID_AA64DFR0_EL1.BRBE definitions */
 #define ID_AA64DFR0_BRBE_SHIFT		U(52)
 #define ID_AA64DFR0_BRBE_MASK		ULL(0xf)
-#define ID_AA64DFR0_BRBE_SUPPORTED	ULL(1)
+#define BRBE_IMPLEMENTED		ULL(1)
+
+/* ID_AA64DFR1_EL1 definitions */
+#define ID_AA64DFR1_EBEP_SHIFT		U(48)
+#define ID_AA64DFR1_EBEP_MASK		ULL(0xf)
+#define EBEP_IMPLEMENTED		ULL(1)
 
 /* ID_AA64ISAR0_EL1 definitions */
 #define ID_AA64ISAR0_RNDR_SHIFT	U(60)
@@ -259,6 +293,18 @@
 /* ID_AA64ISAR1_EL1 definitions */
 #define ID_AA64ISAR1_EL1		S3_0_C0_C6_1
 
+#define ID_AA64ISAR1_LS64_SHIFT		U(60)
+#define ID_AA64ISAR1_LS64_MASK		ULL(0xf)
+#define LS64_ACCDATA_IMPLEMENTED	ULL(0x3)
+#define LS64_V_IMPLEMENTED		ULL(0x2)
+#define LS64_IMPLEMENTED		ULL(0x1)
+#define LS64_NOT_IMPLEMENTED		ULL(0x0)
+
+#define ID_AA64ISAR1_SB_SHIFT		U(36)
+#define ID_AA64ISAR1_SB_MASK		ULL(0xf)
+#define SB_IMPLEMENTED			ULL(0x1)
+#define SB_NOT_IMPLEMENTED		ULL(0x0)
+
 #define ID_AA64ISAR1_GPI_SHIFT		U(28)
 #define ID_AA64ISAR1_GPI_MASK		ULL(0xf)
 #define ID_AA64ISAR1_GPA_SHIFT		U(24)
@@ -269,11 +315,6 @@
 #define ID_AA64ISAR1_APA_SHIFT		U(4)
 #define ID_AA64ISAR1_APA_MASK		ULL(0xf)
 
-#define ID_AA64ISAR1_SB_SHIFT		U(36)
-#define ID_AA64ISAR1_SB_MASK		ULL(0xf)
-#define ID_AA64ISAR1_SB_SUPPORTED	ULL(0x1)
-#define ID_AA64ISAR1_SB_NOT_SUPPORTED	ULL(0x0)
-
 /* ID_AA64ISAR2_EL1 definitions */
 #define ID_AA64ISAR2_EL1		S3_0_C0_C6_2
 
@@ -297,55 +338,46 @@
 #define PARANGE_0100	U(44)
 #define PARANGE_0101	U(48)
 #define PARANGE_0110	U(52)
+#define PARANGE_0111	U(56)
 
 #define ID_AA64MMFR0_EL1_ECV_SHIFT		U(60)
 #define ID_AA64MMFR0_EL1_ECV_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_ECV_NOT_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR0_EL1_ECV_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR0_EL1_ECV_SELF_SYNCH	ULL(0x2)
+#define ID_AA64MMFR0_EL1_ECV_SELF_SYNCH		ULL(0x2)
+#define ECV_IMPLEMENTED				ULL(0x1)
 
 #define ID_AA64MMFR0_EL1_FGT_SHIFT		U(56)
 #define ID_AA64MMFR0_EL1_FGT_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_FGT_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR0_EL1_FGT_NOT_SUPPORTED	ULL(0x0)
+#define FGT2_IMPLEMENTED			ULL(0x2)
+#define FGT_IMPLEMENTED				ULL(0x1)
+#define FGT_NOT_IMPLEMENTED			ULL(0x0)
 
 #define ID_AA64MMFR0_EL1_TGRAN4_SHIFT		U(28)
 #define ID_AA64MMFR0_EL1_TGRAN4_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN4_52B_SUPPORTED	ULL(0x1)
-#define ID_AA64MMFR0_EL1_TGRAN4_NOT_SUPPORTED	ULL(0xf)
 
 #define ID_AA64MMFR0_EL1_TGRAN64_SHIFT		U(24)
 #define ID_AA64MMFR0_EL1_TGRAN64_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN64_NOT_SUPPORTED	ULL(0xf)
 
 #define ID_AA64MMFR0_EL1_TGRAN16_SHIFT		U(20)
 #define ID_AA64MMFR0_EL1_TGRAN16_MASK		ULL(0xf)
-#define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED	ULL(0x1)
-#define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN16_52B_SUPPORTED	ULL(0x2)
+#define TGRAN16_IMPLEMENTED			ULL(0x1)
 
 /* ID_AA64MMFR1_EL1 definitions */
 #define ID_AA64MMFR1_EL1_TWED_SHIFT		U(32)
 #define ID_AA64MMFR1_EL1_TWED_MASK		ULL(0xf)
-#define ID_AA64MMFR1_EL1_TWED_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR1_EL1_TWED_NOT_SUPPORTED	ULL(0x0)
+#define TWED_IMPLEMENTED			ULL(0x1)
 
 #define ID_AA64MMFR1_EL1_PAN_SHIFT		U(20)
 #define ID_AA64MMFR1_EL1_PAN_MASK		ULL(0xf)
-#define ID_AA64MMFR1_EL1_PAN_NOT_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR1_EL1_PAN_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR1_EL1_PAN2_SUPPORTED		ULL(0x2)
-#define ID_AA64MMFR1_EL1_PAN3_SUPPORTED		ULL(0x3)
+#define PAN_IMPLEMENTED				ULL(0x1)
+#define PAN2_IMPLEMENTED			ULL(0x2)
+#define PAN3_IMPLEMENTED			ULL(0x3)
 
 #define ID_AA64MMFR1_EL1_VHE_SHIFT		U(8)
 #define ID_AA64MMFR1_EL1_VHE_MASK		ULL(0xf)
 
 #define ID_AA64MMFR1_EL1_HCX_SHIFT		U(40)
 #define ID_AA64MMFR1_EL1_HCX_MASK		ULL(0xf)
-#define ID_AA64MMFR1_EL1_HCX_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED	ULL(0x0)
+#define HCX_IMPLEMENTED				ULL(0x1)
 
 /* ID_AA64MMFR2_EL1 definitions */
 #define ID_AA64MMFR2_EL1			S3_0_C0_C7_2
@@ -357,18 +389,23 @@
 #define ID_AA64MMFR2_EL1_CCIDX_MASK		ULL(0xf)
 #define ID_AA64MMFR2_EL1_CCIDX_LENGTH		U(4)
 
+#define ID_AA64MMFR2_EL1_UAO_SHIFT		U(4)
+#define ID_AA64MMFR2_EL1_UAO_MASK		ULL(0xf)
+
 #define ID_AA64MMFR2_EL1_CNP_SHIFT		U(0)
 #define ID_AA64MMFR2_EL1_CNP_MASK		ULL(0xf)
 
 #define ID_AA64MMFR2_EL1_NV_SHIFT		U(24)
 #define ID_AA64MMFR2_EL1_NV_MASK		ULL(0xf)
-#define ID_AA64MMFR2_EL1_NV_NOT_SUPPORTED	ULL(0x0)
-#define ID_AA64MMFR2_EL1_NV_SUPPORTED		ULL(0x1)
-#define ID_AA64MMFR2_EL1_NV2_SUPPORTED		ULL(0x2)
+#define NV2_IMPLEMENTED				ULL(0x2)
 
 /* ID_AA64MMFR3_EL1 definitions */
 #define ID_AA64MMFR3_EL1			S3_0_C0_C7_3
 
+#define ID_AA64MMFR3_EL1_D128_SHIFT		U(32)
+#define ID_AA64MMFR3_EL1_D128_MASK		ULL(0xf)
+#define D128_IMPLEMENTED			ULL(0x1)
+
 #define ID_AA64MMFR3_EL1_S2POE_SHIFT		U(20)
 #define ID_AA64MMFR3_EL1_S2POE_MASK		ULL(0xf)
 
@@ -381,22 +418,22 @@
 #define ID_AA64MMFR3_EL1_S1PIE_SHIFT		U(8)
 #define ID_AA64MMFR3_EL1_S1PIE_MASK		ULL(0xf)
 
+#define ID_AA64MMFR3_EL1_SCTLR2_SHIFT		U(4)
+#define ID_AA64MMFR3_EL1_SCTLR2_MASK		ULL(0xf)
+#define SCTLR2_IMPLEMENTED			ULL(1)
+
 #define ID_AA64MMFR3_EL1_TCRX_SHIFT		U(0)
 #define ID_AA64MMFR3_EL1_TCRX_MASK		ULL(0xf)
 
 /* ID_AA64PFR1_EL1 definitions */
-#define ID_AA64PFR1_EL1_GCS_SHIFT	U(44)
-#define ID_AA64PFR1_EL1_GCS_MASK	ULL(0xf)
-
-#define ID_AA64PFR1_EL1_SSBS_SHIFT	U(4)
-#define ID_AA64PFR1_EL1_SSBS_MASK	ULL(0xf)
-
-#define SSBS_UNAVAILABLE	ULL(0)	/* No architectural SSBS support */
 
 #define ID_AA64PFR1_EL1_BT_SHIFT	U(0)
 #define ID_AA64PFR1_EL1_BT_MASK		ULL(0xf)
+#define BTI_IMPLEMENTED			ULL(1)	/* The BTI mechanism is implemented */
 
-#define BTI_IMPLEMENTED		ULL(1)	/* The BTI mechanism is implemented */
+#define ID_AA64PFR1_EL1_SSBS_SHIFT	U(4)
+#define ID_AA64PFR1_EL1_SSBS_MASK	ULL(0xf)
+#define SSBS_NOT_IMPLEMENTED		ULL(0)	/* No architectural SSBS support */
 
 #define ID_AA64PFR1_EL1_MTE_SHIFT	U(8)
 #define ID_AA64PFR1_EL1_MTE_MASK	ULL(0xf)
@@ -404,8 +441,19 @@
 #define ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT	U(28)
 #define ID_AA64PFR1_EL1_RNDR_TRAP_MASK	U(0xf)
 
-#define ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED	ULL(0x1)
-#define ID_AA64PFR1_EL1_RNG_TRAP_NOT_SUPPORTED	ULL(0x0)
+#define ID_AA64PFR1_EL1_NMI_SHIFT	U(36)
+#define ID_AA64PFR1_EL1_NMI_MASK	ULL(0xf)
+#define NMI_IMPLEMENTED			ULL(1)
+
+#define ID_AA64PFR1_EL1_GCS_SHIFT	U(44)
+#define ID_AA64PFR1_EL1_GCS_MASK	ULL(0xf)
+#define GCS_IMPLEMENTED			ULL(1)
+
+#define ID_AA64PFR1_EL1_THE_SHIFT	U(48)
+#define ID_AA64PFR1_EL1_THE_MASK	ULL(0xf)
+#define THE_IMPLEMENTED			ULL(1)
+
+#define RNG_TRAP_IMPLEMENTED		ULL(0x1)
 
 /* ID_AA64PFR2_EL1 definitions */
 #define ID_AA64PFR2_EL1_MTEPERM_SHIFT		U(0)
@@ -438,9 +486,9 @@
 #define ID_AA64PFR1_EL1_SME_SHIFT		U(24)
 #define ID_AA64PFR1_EL1_SME_MASK		ULL(0xf)
 #define ID_AA64PFR1_EL1_SME_WIDTH		U(4)
-#define ID_AA64PFR1_EL1_SME_NOT_SUPPORTED	ULL(0x0)
-#define ID_AA64PFR1_EL1_SME_SUPPORTED		ULL(0x1)
-#define ID_AA64PFR1_EL1_SME2_SUPPORTED		ULL(0x2)
+#define SME_IMPLEMENTED				ULL(0x1)
+#define SME2_IMPLEMENTED			ULL(0x2)
+#define SME_NOT_IMPLEMENTED			ULL(0x0)
 
 /* ID_PFR1_EL1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
@@ -502,6 +550,7 @@
 #define SCTLR_TCF0_SHIFT	U(38)
 #define SCTLR_TCF0_MASK		ULL(3)
 #define SCTLR_ENTP2_BIT		(ULL(1) << 60)
+#define SCTLR_SPINTMASK_BIT	(ULL(1) << 62)
 
 /* Tag Check Faults in EL0 have no effect on the PE */
 #define	SCTLR_TCF0_NO_EFFECT	U(0)
@@ -554,17 +603,23 @@
 /* SCR definitions */
 #define SCR_RES1_BITS		((U(1) << 4) | (U(1) << 5))
 #define SCR_NSE_SHIFT		U(62)
+#define SCR_FGTEN2_BIT		(UL(1) << 59)
 #define SCR_NSE_BIT		(ULL(1) << SCR_NSE_SHIFT)
 #define SCR_GPF_BIT		(UL(1) << 48)
+#define SCR_D128En_BIT		(UL(1) << 47)
 #define SCR_TWEDEL_SHIFT	U(30)
 #define SCR_TWEDEL_MASK		ULL(0xf)
 #define SCR_PIEN_BIT		(UL(1) << 45)
+#define SCR_SCTLR2En_BIT	(UL(1) << 44)
 #define SCR_TCR2EN_BIT		(UL(1) << 43)
+#define SCR_RCWMASKEn_BIT	(UL(1) << 42)
+#define SCR_ENTP2_SHIFT		U(41)
+#define SCR_ENTP2_BIT		(UL(1) << SCR_ENTP2_SHIFT)
 #define SCR_TRNDR_BIT		(UL(1) << 40)
 #define SCR_GCSEn_BIT		(UL(1) << 39)
 #define SCR_HXEn_BIT		(UL(1) << 38)
-#define SCR_ENTP2_SHIFT		U(41)
-#define SCR_ENTP2_BIT		(UL(1) << SCR_ENTP2_SHIFT)
+#define SCR_ADEn_BIT		(UL(1) << 37)
+#define SCR_EnAS0_BIT		(UL(1) << 36)
 #define SCR_AMVOFFEN_SHIFT	U(35)
 #define SCR_AMVOFFEN_BIT	(UL(1) << SCR_AMVOFFEN_SHIFT)
 #define SCR_TWEDEn_BIT		(UL(1) << 29)
@@ -592,6 +647,9 @@
 #define SCR_RESET_VAL		SCR_RES1_BITS
 
 /* MDCR_EL3 definitions */
+#define MDCR_EBWE_BIT		(ULL(1) << 43)
+#define MDCR_E3BREC		(ULL(1) << 38)
+#define MDCR_E3BREW		(ULL(1) << 37)
 #define MDCR_EnPMSN_BIT		(ULL(1) << 36)
 #define MDCR_MPMX_BIT		(ULL(1) << 35)
 #define MDCR_MCCD_BIT		(ULL(1) << 34)
@@ -729,6 +787,10 @@
 #define DAIF_IRQ_BIT		(U(1) << 1)
 #define DAIF_ABT_BIT		(U(1) << 2)
 #define DAIF_DBG_BIT		(U(1) << 3)
+#define SPSR_V_BIT		(U(1) << 28)
+#define SPSR_C_BIT		(U(1) << 29)
+#define SPSR_Z_BIT		(U(1) << 30)
+#define SPSR_N_BIT		(U(1) << 31)
 #define SPSR_DAIF_SHIFT		U(6)
 #define SPSR_DAIF_MASK		U(0xf)
 
@@ -749,25 +811,32 @@
 #define SPSR_M_MASK		U(0x1)
 #define SPSR_M_AARCH64		U(0x0)
 #define SPSR_M_AARCH32		U(0x1)
+#define SPSR_M_EL1H		U(0x5)
 #define SPSR_M_EL2H		U(0x9)
 
 #define SPSR_EL_SHIFT		U(2)
 #define SPSR_EL_WIDTH		U(2)
 
-#define SPSR_SSBS_SHIFT_AARCH64 U(12)
+#define SPSR_BTYPE_SHIFT_AARCH64	U(10)
+#define SPSR_BTYPE_MASK_AARCH64	U(0x3)
+#define SPSR_SSBS_SHIFT_AARCH64	U(12)
 #define SPSR_SSBS_BIT_AARCH64	(ULL(1) << SPSR_SSBS_SHIFT_AARCH64)
 #define SPSR_SSBS_SHIFT_AARCH32 U(23)
 #define SPSR_SSBS_BIT_AARCH32	(ULL(1) << SPSR_SSBS_SHIFT_AARCH32)
-
+#define SPSR_ALLINT_BIT_AARCH64	BIT_64(13)
+#define SPSR_IL_BIT		BIT_64(20)
+#define SPSR_SS_BIT		BIT_64(21)
 #define SPSR_PAN_BIT		BIT_64(22)
-
+#define SPSR_UAO_BIT_AARCH64	BIT_64(23)
 #define SPSR_DIT_BIT		BIT(24)
-
 #define SPSR_TCO_BIT_AARCH64	BIT_64(25)
+#define SPSR_PM_BIT_AARCH64	BIT_64(32)
+#define SPSR_PPEND_BIT		BIT(33)
+#define SPSR_EXLOCK_BIT_AARCH64	BIT_64(34)
+#define SPSR_NZCV		(SPSR_V_BIT | SPSR_C_BIT | SPSR_Z_BIT | SPSR_N_BIT)
 
 #define DISABLE_ALL_EXCEPTIONS \
 		(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
-
 #define DISABLE_INTERRUPTS	(DAIF_FIQ_BIT | DAIF_IRQ_BIT)
 
 /*
@@ -945,6 +1014,7 @@
 #define ESR_EC_LENGTH			U(6)
 #define ESR_ISS_SHIFT			U(0)
 #define ESR_ISS_LENGTH			U(25)
+#define ESR_IL_BIT			(U(1) << 25)
 #define EC_UNKNOWN			U(0x0)
 #define EC_WFE_WFI			U(0x1)
 #define EC_AARCH32_CP15_MRC_MCR		U(0x3)
@@ -1059,11 +1129,11 @@
 /* ID_AA64SMFR0_EL1 definitions */
 #define ID_AA64SMFR0_EL1_SME_FA64_SHIFT		U(63)
 #define ID_AA64SMFR0_EL1_SME_FA64_MASK		U(0x1)
-#define ID_AA64SMFR0_EL1_SME_FA64_SUPPORTED	U(0x1)
+#define SME_FA64_IMPLEMENTED			U(0x1)
 #define ID_AA64SMFR0_EL1_SME_VER_SHIFT		U(55)
 #define ID_AA64SMFR0_EL1_SME_VER_MASK		ULL(0xf)
-#define ID_AA64SMFR0_EL1_SME_INST_SUPPORTED	ULL(0x0)
-#define ID_AA64SMFR0_EL1_SME2_INST_SUPPORTED	ULL(0x1)
+#define SME_INST_IMPLEMENTED			ULL(0x0)
+#define SME2_INST_IMPLEMENTED			ULL(0x1)
 
 /* SMCR_ELx definitions */
 #define SMCR_ELX_LEN_SHIFT		U(0)
@@ -1124,8 +1194,9 @@
 /* PAR_EL1 fields */
 #define PAR_F_SHIFT	U(0)
 #define PAR_F_MASK	ULL(0x1)
-#define PAR_ADDR_SHIFT	U(12)
-#define PAR_ADDR_MASK	(BIT(40) - ULL(1)) /* 40-bits-wide page address */
+
+#define PAR_D128_ADDR_MASK	GENMASK(55, 12) /* 44-bits-wide page address */
+#define PAR_ADDR_MASK		GENMASK(51, 12) /* 40-bits-wide page address */
 
 /*******************************************************************************
  * Definitions for system register interface to SPE
@@ -1293,6 +1364,8 @@
 #define GPTBR_EL3			S3_6_C2_C1_4
 
 #define SCXTNUM_EL2			S3_4_C13_C0_7
+#define SCXTNUM_EL1			S3_0_C13_C0_7
+#define SCXTNUM_EL0			S3_3_C13_C0_7
 
 /*******************************************************************************
  * RAS system registers
@@ -1357,6 +1430,8 @@
 #define RGSR_EL1		S3_0_C1_C0_5
 #define GCR_EL1			S3_0_C1_C0_6
 
+#define GCR_EL1_RRND_BIT	(UL(1) << 16)
+
 /*******************************************************************************
  * Armv8.5 - Random Number Generator Registers
  ******************************************************************************/
@@ -1389,24 +1464,58 @@
 #define HFGWTR_EL2_INIT_VAL	ULL(0xC4000000000000)
 
 /*******************************************************************************
- * FEAT_TCR2 - Extended Translation Control Register
+ * FEAT_TCR2 - Extended Translation Control Registers
  ******************************************************************************/
+#define TCR2_EL1		S3_0_C2_C0_3
 #define TCR2_EL2		S3_4_C2_C0_3
 
 /*******************************************************************************
- * Permission indirection and overlay
+ * Permission indirection and overlay Registers
  ******************************************************************************/
 
+#define PIRE0_EL1		S3_0_C10_C2_2
 #define PIRE0_EL2		S3_4_C10_C2_2
+#define PIR_EL1			S3_0_C10_C2_3
 #define PIR_EL2			S3_4_C10_C2_3
+#define POR_EL1			S3_0_C10_C2_4
 #define POR_EL2			S3_4_C10_C2_4
 #define S2PIR_EL2		S3_4_C10_C2_5
+#define S2POR_EL1		S3_0_C10_C2_5
 
 /*******************************************************************************
  * FEAT_GCS - Guarded Control Stack Registers
  ******************************************************************************/
 #define GCSCR_EL2		S3_4_C2_C5_0
 #define GCSPR_EL2		S3_4_C2_C5_1
+#define GCSCR_EL1		S3_0_C2_C5_0
+#define GCSCRE0_EL1		S3_0_C2_C5_2
+#define GCSPR_EL1		S3_0_C2_C5_1
+#define GCSPR_EL0		S3_3_C2_C5_1
+
+#define GCSCR_EXLOCK_EN_BIT	(UL(1) << 6)
+
+/*******************************************************************************
+ * FEAT_TRF - Trace Filter Control Registers
+ ******************************************************************************/
+#define TRFCR_EL2		S3_4_C1_C2_1
+#define TRFCR_EL1		S3_0_C1_C2_1
+
+/*******************************************************************************
+ * FEAT_THE - Translation Hardening Extension Registers
+ ******************************************************************************/
+#define RCWMASK_EL1		S3_0_C13_C0_6
+#define RCWSMASK_EL1		S3_0_C13_C0_3
+
+/*******************************************************************************
+ * FEAT_SCTLR2 - Extension to SCTLR_ELx Registers
+ ******************************************************************************/
+#define SCTLR2_EL2		S3_4_C1_C0_3
+#define SCTLR2_EL1		S3_0_C1_C0_3
+
+/*******************************************************************************
+ * FEAT_LS64_ACCDATA - LoadStore64B with status data
+ ******************************************************************************/
+#define ACCDATA_EL1		S3_0_C13_C0_5
 
 /*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
@@ -1434,4 +1543,17 @@
 /* alternative system register encoding for the "sb" speculation barrier */
 #define SYSREG_SB			S0_3_C3_C0_7
 
+#define CLUSTERPMCR_EL1			S3_0_C15_C5_0
+#define CLUSTERPMCNTENSET_EL1		S3_0_C15_C5_1
+#define CLUSTERPMCCNTR_EL1		S3_0_C15_C6_0
+#define CLUSTERPMOVSSET_EL1		S3_0_C15_C5_3
+#define CLUSTERPMOVSCLR_EL1		S3_0_C15_C5_4
+#define CLUSTERPMSELR_EL1		S3_0_C15_C5_5
+#define CLUSTERPMXEVTYPER_EL1		S3_0_C15_C6_1
+#define CLUSTERPMXEVCNTR_EL1		S3_0_C15_C6_2
+
+#define CLUSTERPMCR_E_BIT		BIT(0)
+#define CLUSTERPMCR_N_SHIFT		U(11)
+#define CLUSTERPMCR_N_MASK		U(0x1f)
+
 #endif /* ARCH_H */
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index cf8da5e8..59188da3 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,55 +12,168 @@
 #include <arch_helpers.h>
 #include <common/feat_detect.h>
 
-#define ISOLATE_FIELD(reg, feat)					\
-	((unsigned int)(((reg) >> (feat)) & ID_REG_FIELD_MASK))
-
-#define CREATE_FEATURE_FUNCS_VER(name, read_func, idvalue, guard)	\
-static inline bool is_ ## name ## _supported(void)			\
-{									\
-	if ((guard) == FEAT_STATE_DISABLED) {				\
-		return false;						\
-	}								\
-	if ((guard) == FEAT_STATE_ALWAYS) {				\
-		return true;						\
-	}								\
-	return read_func() >= (idvalue);				\
+#define ISOLATE_FIELD(reg, feat, mask)						\
+	((unsigned int)(((reg) >> (feat)) & mask))
+
+#define CREATE_FEATURE_SUPPORTED(name, read_func, guard)			\
+__attribute__((always_inline))							\
+static inline bool is_ ## name ## _supported(void)				\
+{										\
+	if ((guard) == FEAT_STATE_DISABLED) {					\
+		return false;							\
+	}									\
+	if ((guard) == FEAT_STATE_ALWAYS) {					\
+		return true;							\
+	}									\
+	return read_func();							\
 }
 
-#define CREATE_FEATURE_FUNCS(name, idreg, idfield, guard)		\
-static unsigned int read_ ## name ## _id_field(void)			\
-{									\
-	return ISOLATE_FIELD(read_ ## idreg(), idfield);		\
-}									\
-CREATE_FEATURE_FUNCS_VER(name, read_ ## name ## _id_field, 1U, guard)
+#define CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)		\
+__attribute__((always_inline))							\
+static inline bool is_ ## name ## _present(void)				\
+{										\
+	return (ISOLATE_FIELD(read_ ## idreg(), idfield, mask) >= idval) 	\
+		? true : false; 						\
+}
+
+#define CREATE_FEATURE_FUNCS(name, idreg, idfield, mask, idval, guard)		\
+CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)			\
+CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard)
+
+
+/* +----------------------------+
+ * |	Features supported	|
+ * +----------------------------+
+ * |	GENTIMER		|
+ * +----------------------------+
+ * |	FEAT_PAN		|
+ * +----------------------------+
+ * |	FEAT_VHE		|
+ * +----------------------------+
+ * |	FEAT_TTCNP		|
+ * +----------------------------+
+ * |	FEAT_UAO		|
+ * +----------------------------+
+ * |	FEAT_PACQARMA3		|
+ * +----------------------------+
+ * |	FEAT_PAUTH		|
+ * +----------------------------+
+ * |	FEAT_TTST		|
+ * +----------------------------+
+ * |	FEAT_BTI		|
+ * +----------------------------+
+ * |	FEAT_MTE2		|
+ * +----------------------------+
+ * |	FEAT_SSBS		|
+ * +----------------------------+
+ * |	FEAT_NMI		|
+ * +----------------------------+
+ * |	FEAT_GCS		|
+ * +----------------------------+
+ * |	FEAT_EBEP		|
+ * +----------------------------+
+ * |	FEAT_SEBEP		|
+ * +----------------------------+
+ * |	FEAT_SEL2		|
+ * +----------------------------+
+ * |	FEAT_TWED		|
+ * +----------------------------+
+ * |	FEAT_FGT		|
+ * +----------------------------+
+ * |	FEAT_EC/ECV2		|
+ * +----------------------------+
+ * |	FEAT_RNG		|
+ * +----------------------------+
+ * |	FEAT_TCR2		|
+ * +----------------------------+
+ * |	FEAT_S2POE		|
+ * +----------------------------+
+ * |	FEAT_S1POE		|
+ * +----------------------------+
+ * |	FEAT_S2PIE		|
+ * +----------------------------+
+ * |	FEAT_S1PIE		|
+ * +----------------------------+
+ * |	FEAT_AMU/AMUV1P1	|
+ * +----------------------------+
+ * |	FEAT_MPAM		|
+ * +----------------------------+
+ * |	FEAT_HCX		|
+ * +----------------------------+
+ * |	FEAT_RNG_TRAP		|
+ * +----------------------------+
+ * |	FEAT_RME		|
+ * +----------------------------+
+ * |	FEAT_SB			|
+ * +----------------------------+
+ * |	FEAT_CSV2/CSV3		|
+ * +----------------------------+
+ * |	FEAT_SPE		|
+ * +----------------------------+
+ * |	FEAT_SVE		|
+ * +----------------------------+
+ * |	FEAT_RAS		|
+ * +----------------------------+
+ * |	FEAT_DIT		|
+ * +----------------------------+
+ * |	FEAT_SYS_REG_TRACE	|
+ * +----------------------------+
+ * |	FEAT_TRF		|
+ * +----------------------------+
+ * |	FEAT_NV/NV2		|
+ * +----------------------------+
+ * |	FEAT_BRBE		|
+ * +----------------------------+
+ * |	FEAT_TRBE		|
+ * +----------------------------+
+ * |	FEAT_SME/SME2		|
+ * +----------------------------+
+ * |	FEAT_PMUV3		|
+ * +----------------------------+
+ * |	FEAT_MTPMU		|
+ * +----------------------------+
+ * |	FEAT_FGT2		|
+ * +----------------------------+
+ * |	FEAT_THE		|
+ * +----------------------------+
+ * |	FEAT_SCTLR2		|
+ * +----------------------------+
+ * |	FEAT_D128		|
+ * +----------------------------+
+ * |	FEAT_LS64_ACCDATA	|
+ * +----------------------------+
+ */
 
+__attribute__((always_inline))
 static inline bool is_armv7_gentimer_present(void)
 {
 	/* The Generic Timer is always present in an ARMv8-A implementation */
 	return true;
 }
 
+/* FEAT_PAN: Privileged access never */
 CREATE_FEATURE_FUNCS(feat_pan, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_PAN_SHIFT,
-		     ENABLE_FEAT_PAN)
+		     ID_AA64MMFR1_EL1_PAN_MASK, 1U, ENABLE_FEAT_PAN)
+
+/* FEAT_VHE: Virtualization Host Extensions */
 CREATE_FEATURE_FUNCS(feat_vhe, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_VHE_SHIFT,
-		     ENABLE_FEAT_VHE)
+		     ID_AA64MMFR1_EL1_VHE_MASK, 1U, ENABLE_FEAT_VHE)
 
-static inline bool is_armv8_2_ttcnp_present(void)
-{
-	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
-		ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
-}
+/* FEAT_TTCNP: Translation table common not private */
+CREATE_FEATURE_PRESENT(feat_ttcnp, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_CNP_SHIFT,
+			ID_AA64MMFR2_EL1_CNP_MASK, 1U)
 
-static inline bool is_feat_pacqarma3_present(void)
-{
-	uint64_t mask_id_aa64isar2 =
-			(ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
-			(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
+/* FEAT_UAO: User access override */
+CREATE_FEATURE_PRESENT(feat_uao, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_UAO_SHIFT,
+			ID_AA64MMFR2_EL1_UAO_MASK, 1U)
 
-	/* If any of the fields is not zero, QARMA3 algorithm is present */
-	return (read_id_aa64isar2_el1() & mask_id_aa64isar2) != 0U;
-}
+/* If any of the fields is not zero, QARMA3 algorithm is present */
+CREATE_FEATURE_PRESENT(feat_pacqarma3, id_aa64isar2_el1, 0,
+			((ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
+			(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT)), 1U)
 
+/* PAUTH */
+__attribute__((always_inline))
 static inline bool is_armv8_3_pauth_present(void)
 {
 	uint64_t mask_id_aa64isar1 =
@@ -77,55 +190,101 @@ static inline bool is_armv8_3_pauth_present(void)
 		is_feat_pacqarma3_present());
 }
 
-static inline bool is_armv8_4_ttst_present(void)
-{
-	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
-		ID_AA64MMFR2_EL1_ST_MASK) == 1U;
-}
+/* FEAT_TTST: Small translation tables */
+CREATE_FEATURE_PRESENT(feat_ttst, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_ST_SHIFT,
+			ID_AA64MMFR2_EL1_ST_MASK, 1U)
 
-static inline bool is_armv8_5_bti_present(void)
-{
-	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_BT_SHIFT) &
-		ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
-}
+/* FEAT_BTI: Branch target identification */
+CREATE_FEATURE_PRESENT(feat_bti, id_aa64pfr1_el1, ID_AA64PFR1_EL1_BT_SHIFT,
+			ID_AA64PFR1_EL1_BT_MASK, BTI_IMPLEMENTED)
 
-static inline unsigned int get_armv8_5_mte_support(void)
-{
-	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
-		ID_AA64PFR1_EL1_MTE_MASK);
-}
+/* FEAT_MTE2: Memory tagging extension */
+CREATE_FEATURE_FUNCS(feat_mte2, id_aa64pfr1_el1, ID_AA64PFR1_EL1_MTE_SHIFT,
+		     ID_AA64PFR1_EL1_MTE_MASK, MTE_IMPLEMENTED_ELX, ENABLE_FEAT_MTE2)
+
+/* FEAT_SSBS: Speculative store bypass safe */
+CREATE_FEATURE_PRESENT(feat_ssbs, id_aa64pfr1_el1, ID_AA64PFR1_EL1_SSBS_SHIFT,
+			ID_AA64PFR1_EL1_SSBS_MASK, 1U)
+
+/* FEAT_NMI: Non-maskable interrupts */
+CREATE_FEATURE_PRESENT(feat_nmi, id_aa64pfr1_el1, ID_AA64PFR1_EL1_NMI_SHIFT,
+			ID_AA64PFR1_EL1_NMI_MASK, NMI_IMPLEMENTED)
 
+/* FEAT_EBEP */
+CREATE_FEATURE_PRESENT(feat_ebep, id_aa64dfr1_el1, ID_AA64DFR1_EBEP_SHIFT,
+			ID_AA64DFR1_EBEP_MASK, EBEP_IMPLEMENTED)
+
+/* FEAT_SEBEP */
+CREATE_FEATURE_PRESENT(feat_sebep, id_aa64dfr0_el1, ID_AA64DFR0_SEBEP_SHIFT,
+			ID_AA64DFR0_SEBEP_MASK, SEBEP_IMPLEMENTED)
+
+/* FEAT_SEL2: Secure EL2 */
 CREATE_FEATURE_FUNCS(feat_sel2, id_aa64pfr0_el1, ID_AA64PFR0_SEL2_SHIFT,
-		     ENABLE_FEAT_SEL2)
+		     ID_AA64PFR0_SEL2_MASK, 1U, ENABLE_FEAT_SEL2)
+
+/* FEAT_TWED: Delayed trapping of WFE */
 CREATE_FEATURE_FUNCS(feat_twed, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_TWED_SHIFT,
-		     ENABLE_FEAT_TWED)
+		     ID_AA64MMFR1_EL1_TWED_MASK, 1U, ENABLE_FEAT_TWED)
+
+/* FEAT_FGT: Fine-grained traps */
 CREATE_FEATURE_FUNCS(feat_fgt, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_FGT_SHIFT,
-		     ENABLE_FEAT_FGT)
-CREATE_FEATURE_FUNCS(feat_mte_perm, id_aa64pfr2_el1,
-		     ID_AA64PFR2_EL1_MTEPERM_SHIFT, ENABLE_FEAT_MTE_PERM)
+		     ID_AA64MMFR0_EL1_FGT_MASK, 1U, ENABLE_FEAT_FGT)
+
+/* FEAT_FGT2: Fine-grained traps extended */
+CREATE_FEATURE_FUNCS(feat_fgt2, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_FGT_SHIFT,
+		     ID_AA64MMFR0_EL1_FGT_MASK, FGT2_IMPLEMENTED, ENABLE_FEAT_FGT2)
+
+/* FEAT_ECV: Enhanced Counter Virtualization */
 CREATE_FEATURE_FUNCS(feat_ecv, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_ECV_SHIFT,
-		     ENABLE_FEAT_ECV)
-CREATE_FEATURE_FUNCS_VER(feat_ecv_v2, read_feat_ecv_id_field,
-			 ID_AA64MMFR0_EL1_ECV_SELF_SYNCH, ENABLE_FEAT_ECV)
+		     ID_AA64MMFR0_EL1_ECV_MASK, 1U, ENABLE_FEAT_ECV)
+CREATE_FEATURE_FUNCS(feat_ecv_v2, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_ECV_SHIFT,
+		     ID_AA64MMFR0_EL1_ECV_MASK, ID_AA64MMFR0_EL1_ECV_SELF_SYNCH, ENABLE_FEAT_ECV)
 
+/* FEAT_RNG: Random number generator */
 CREATE_FEATURE_FUNCS(feat_rng, id_aa64isar0_el1, ID_AA64ISAR0_RNDR_SHIFT,
-		     ENABLE_FEAT_RNG)
+		     ID_AA64ISAR0_RNDR_MASK, 1U, ENABLE_FEAT_RNG)
+
+/* FEAT_TCR2: Support TCR2_ELx regs */
 CREATE_FEATURE_FUNCS(feat_tcr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_TCRX_SHIFT,
-		     ENABLE_FEAT_TCR2)
+		     ID_AA64MMFR3_EL1_TCRX_MASK, 1U, ENABLE_FEAT_TCR2)
 
+/* FEAT_S2POE */
 CREATE_FEATURE_FUNCS(feat_s2poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2POE_SHIFT,
-		     ENABLE_FEAT_S2POE)
+		     ID_AA64MMFR3_EL1_S2POE_MASK, 1U, ENABLE_FEAT_S2POE)
+
+/* FEAT_S1POE */
 CREATE_FEATURE_FUNCS(feat_s1poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1POE_SHIFT,
-		     ENABLE_FEAT_S1POE)
+		     ID_AA64MMFR3_EL1_S1POE_MASK, 1U, ENABLE_FEAT_S1POE)
+
+__attribute__((always_inline))
 static inline bool is_feat_sxpoe_supported(void)
 {
 	return is_feat_s1poe_supported() || is_feat_s2poe_supported();
 }
 
+/* FEAT_S2PIE */
 CREATE_FEATURE_FUNCS(feat_s2pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2PIE_SHIFT,
-		     ENABLE_FEAT_S2PIE)
+		     ID_AA64MMFR3_EL1_S2PIE_MASK, 1U, ENABLE_FEAT_S2PIE)
+
+/* FEAT_S1PIE */
 CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
-		     ENABLE_FEAT_S1PIE)
+		     ID_AA64MMFR3_EL1_S1PIE_MASK, 1U, ENABLE_FEAT_S1PIE)
+
+/* FEAT_THE: Translation Hardening Extension */
+CREATE_FEATURE_FUNCS(feat_the, id_aa64pfr1_el1, ID_AA64PFR1_EL1_THE_SHIFT,
+		     ID_AA64PFR1_EL1_THE_MASK, THE_IMPLEMENTED, ENABLE_FEAT_THE)
+
+/* FEAT_SCTLR2 */
+CREATE_FEATURE_FUNCS(feat_sctlr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_SCTLR2_SHIFT,
+		     ID_AA64MMFR3_EL1_SCTLR2_MASK, SCTLR2_IMPLEMENTED,
+		     ENABLE_FEAT_SCTLR2)
+
+/* FEAT_D128 */
+CREATE_FEATURE_FUNCS(feat_d128, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_D128_SHIFT,
+		     ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED,
+		     ENABLE_FEAT_D128)
+
+__attribute__((always_inline))
 static inline bool is_feat_sxpie_supported(void)
 {
 	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
@@ -133,13 +292,15 @@ static inline bool is_feat_sxpie_supported(void)
 
 /* FEAT_GCS: Guarded Control Stack */
 CREATE_FEATURE_FUNCS(feat_gcs, id_aa64pfr1_el1, ID_AA64PFR1_EL1_GCS_SHIFT,
-		     ENABLE_FEAT_GCS)
+		     ID_AA64PFR1_EL1_GCS_MASK, 1U, ENABLE_FEAT_GCS)
 
 /* FEAT_AMU: Activity Monitors Extension */
 CREATE_FEATURE_FUNCS(feat_amu, id_aa64pfr0_el1, ID_AA64PFR0_AMU_SHIFT,
-		     ENABLE_FEAT_AMU)
-CREATE_FEATURE_FUNCS_VER(feat_amuv1p1, read_feat_amu_id_field,
-			 ID_AA64PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1)
+		     ID_AA64PFR0_AMU_MASK, 1U, ENABLE_FEAT_AMU)
+
+/* 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)
 
 /*
  * Return MPAM version:
@@ -150,144 +311,159 @@ CREATE_FEATURE_FUNCS_VER(feat_amuv1p1, read_feat_amu_id_field,
  * 0x11: v1.1 Armv8.4 or later
  *
  */
-static inline unsigned int read_feat_mpam_version(void)
+__attribute__((always_inline))
+static inline bool is_feat_mpam_present(void)
 {
-	return (unsigned int)((((read_id_aa64pfr0_el1() >>
+	unsigned int ret = (unsigned int)((((read_id_aa64pfr0_el1() >>
 		ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
-				((read_id_aa64pfr1_el1() >>
-		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
+		((read_id_aa64pfr1_el1() >> ID_AA64PFR1_MPAM_FRAC_SHIFT)
+			& ID_AA64PFR1_MPAM_FRAC_MASK));
+	return ret;
 }
 
-CREATE_FEATURE_FUNCS_VER(feat_mpam, read_feat_mpam_version, 1U,
-			 ENABLE_FEAT_MPAM)
+CREATE_FEATURE_SUPPORTED(feat_mpam, is_feat_mpam_present, ENABLE_FEAT_MPAM)
+
+/*
+ * FEAT_DebugV8P9: Debug extension. This function checks the field 3:0 of
+ * ID_AA64DFR0 Aarch64 Debug Feature Register 0 for the version of
+ * Feat_Debug supported. The value of the field determines feature presence
+ *
+ * 0b0110 - Arm v8.0 debug
+ * 0b0111 - Arm v8.0 debug architecture with Virtualization host extensions
+ * 0x1000 - FEAT_Debugv8p2 is supported
+ * 0x1001 - FEAT_Debugv8p4 is supported
+ * 0x1010 - FEAT_Debugv8p8 is supported
+ * 0x1011 - FEAT_Debugv8p9 is supported
+ *
+ */
+CREATE_FEATURE_FUNCS(feat_debugv8p9, id_aa64dfr0_el1, ID_AA64DFR0_DEBUGVER_SHIFT,
+		ID_AA64DFR0_DEBUGVER_MASK, DEBUGVER_V8P9_IMPLEMENTED,
+		ENABLE_FEAT_DEBUGV8P9)
 
 /* FEAT_HCX: Extended Hypervisor Configuration Register */
 CREATE_FEATURE_FUNCS(feat_hcx, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_HCX_SHIFT,
-		     ENABLE_FEAT_HCX)
+		     ID_AA64MMFR1_EL1_HCX_MASK, 1U, ENABLE_FEAT_HCX)
 
-static inline bool is_feat_rng_trap_present(void)
-{
-	return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
-			ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
-			== ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
-}
+/* FEAT_RNG_TRAP: Trapping support */
+CREATE_FEATURE_PRESENT(feat_rng_trap, id_aa64pfr1_el1, ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT,
+		      ID_AA64PFR1_EL1_RNDR_TRAP_MASK, RNG_TRAP_IMPLEMENTED)
 
-static inline unsigned int get_armv9_2_feat_rme_support(void)
-{
-	/*
-	 * Return the RME version, zero if not supported.  This function can be
-	 * used as both an integer value for the RME version or compared to zero
-	 * to detect RME presence.
-	 */
-	return (unsigned int)(read_id_aa64pfr0_el1() >>
-		ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
-}
+/* Return the RME version, zero if not supported. */
+CREATE_FEATURE_FUNCS(feat_rme, id_aa64pfr0_el1, ID_AA64PFR0_FEAT_RME_SHIFT,
+		    ID_AA64PFR0_FEAT_RME_MASK, 1U, ENABLE_RME)
 
-/*********************************************************************************
- * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
- ********************************************************************************/
-static inline unsigned int read_feat_sb_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT);
-}
+/* FEAT_SB: Speculation barrier instruction */
+CREATE_FEATURE_PRESENT(feat_sb, id_aa64isar1_el1, ID_AA64ISAR1_SB_SHIFT,
+		       ID_AA64ISAR1_SB_MASK, 1U)
+
+/*
+ * FEAT_CSV2: Cache Speculation Variant 2. This checks bit fields[56-59]
+ * of id_aa64pfr0_el1 register and can be used to check for below features:
+ * FEAT_CSV2_2: Cache Speculation Variant CSV2_2.
+ * FEAT_CSV2_3: Cache Speculation Variant CSV2_3.
+ * 0b0000 - Feature FEAT_CSV2 is not implemented.
+ * 0b0001 - Feature FEAT_CSV2 is implemented, but FEAT_CSV2_2 and FEAT_CSV2_3
+ *          are not implemented.
+ * 0b0010 - Feature FEAT_CSV2_2 is implemented but FEAT_CSV2_3 is not
+ *          implemented.
+ * 0b0011 - Feature FEAT_CSV2_3 is implemented.
+ */
 
-/* FEAT_CSV2_2: Cache Speculation Variant 2 */
-CREATE_FEATURE_FUNCS(feat_csv2, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT, 0)
-CREATE_FEATURE_FUNCS_VER(feat_csv2_2, read_feat_csv2_id_field,
-			 ID_AA64PFR0_CSV2_2_SUPPORTED, ENABLE_FEAT_CSV2_2)
+CREATE_FEATURE_FUNCS(feat_csv2_2, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT,
+		     ID_AA64PFR0_CSV2_MASK, CSV2_2_IMPLEMENTED, ENABLE_FEAT_CSV2_2)
+CREATE_FEATURE_FUNCS(feat_csv2_3, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT,
+		     ID_AA64PFR0_CSV2_MASK, CSV2_3_IMPLEMENTED, ENABLE_FEAT_CSV2_3)
 
 /* FEAT_SPE: Statistical Profiling Extension */
 CREATE_FEATURE_FUNCS(feat_spe, id_aa64dfr0_el1, ID_AA64DFR0_PMS_SHIFT,
-		     ENABLE_SPE_FOR_NS)
+		     ID_AA64DFR0_PMS_MASK, 1U, ENABLE_SPE_FOR_NS)
 
 /* FEAT_SVE: Scalable Vector Extension */
 CREATE_FEATURE_FUNCS(feat_sve, id_aa64pfr0_el1, ID_AA64PFR0_SVE_SHIFT,
-		     ENABLE_SVE_FOR_NS)
+		     ID_AA64PFR0_SVE_MASK, 1U, ENABLE_SVE_FOR_NS)
 
 /* FEAT_RAS: Reliability, Accessibility, Serviceability */
-CREATE_FEATURE_FUNCS(feat_ras, id_aa64pfr0_el1,
-		     ID_AA64PFR0_RAS_SHIFT, ENABLE_FEAT_RAS)
+CREATE_FEATURE_FUNCS(feat_ras, id_aa64pfr0_el1, ID_AA64PFR0_RAS_SHIFT,
+		     ID_AA64PFR0_RAS_MASK, 1U, ENABLE_FEAT_RAS)
 
 /* FEAT_DIT: Data Independent Timing instructions */
-CREATE_FEATURE_FUNCS(feat_dit, id_aa64pfr0_el1,
-		     ID_AA64PFR0_DIT_SHIFT, ENABLE_FEAT_DIT)
+CREATE_FEATURE_FUNCS(feat_dit, id_aa64pfr0_el1, ID_AA64PFR0_DIT_SHIFT,
+		     ID_AA64PFR0_DIT_MASK, 1U, ENABLE_FEAT_DIT)
 
-CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_aa64dfr0_el1,
-		     ID_AA64DFR0_TRACEVER_SHIFT, ENABLE_SYS_REG_TRACE_FOR_NS)
+/* FEAT_SYS_REG_TRACE */
+CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_aa64dfr0_el1, ID_AA64DFR0_TRACEVER_SHIFT,
+		    ID_AA64DFR0_TRACEVER_MASK, 1U, ENABLE_SYS_REG_TRACE_FOR_NS)
 
 /* FEAT_TRF: TraceFilter */
 CREATE_FEATURE_FUNCS(feat_trf, id_aa64dfr0_el1, ID_AA64DFR0_TRACEFILT_SHIFT,
-		     ENABLE_TRF_FOR_NS)
+		     ID_AA64DFR0_TRACEFILT_MASK, 1U, ENABLE_TRF_FOR_NS)
 
 /* FEAT_NV2: Enhanced Nested Virtualization */
-CREATE_FEATURE_FUNCS(feat_nv, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_NV_SHIFT, 0)
-CREATE_FEATURE_FUNCS_VER(feat_nv2, read_feat_nv_id_field,
-			 ID_AA64MMFR2_EL1_NV2_SUPPORTED, CTX_INCLUDE_NEVE_REGS)
+CREATE_FEATURE_FUNCS(feat_nv, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_NV_SHIFT,
+		     ID_AA64MMFR2_EL1_NV_MASK, 1U, 0U)
+CREATE_FEATURE_FUNCS(feat_nv2, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_NV_SHIFT,
+		     ID_AA64MMFR2_EL1_NV_MASK, NV2_IMPLEMENTED, CTX_INCLUDE_NEVE_REGS)
 
 /* FEAT_BRBE: Branch Record Buffer Extension */
 CREATE_FEATURE_FUNCS(feat_brbe, id_aa64dfr0_el1, ID_AA64DFR0_BRBE_SHIFT,
-		     ENABLE_BRBE_FOR_NS)
+		     ID_AA64DFR0_BRBE_MASK, 1U, ENABLE_BRBE_FOR_NS)
 
 /* FEAT_TRBE: Trace Buffer Extension */
 CREATE_FEATURE_FUNCS(feat_trbe, id_aa64dfr0_el1, ID_AA64DFR0_TRACEBUFFER_SHIFT,
-		     ENABLE_TRBE_FOR_NS)
+		     ID_AA64DFR0_TRACEBUFFER_MASK, 1U, ENABLE_TRBE_FOR_NS)
+
+/* FEAT_SME_FA64: Full A64 Instruction support in streaming SVE mode */
+CREATE_FEATURE_PRESENT(feat_sme_fa64, id_aa64smfr0_el1, ID_AA64SMFR0_EL1_SME_FA64_SHIFT,
+		    ID_AA64SMFR0_EL1_SME_FA64_MASK, 1U)
 
-static inline unsigned int read_feat_sme_fa64_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64smfr0_el1(),
-			     ID_AA64SMFR0_EL1_SME_FA64_SHIFT);
-}
 /* FEAT_SMEx: Scalar Matrix Extension */
 CREATE_FEATURE_FUNCS(feat_sme, id_aa64pfr1_el1, ID_AA64PFR1_EL1_SME_SHIFT,
-		     ENABLE_SME_FOR_NS)
-CREATE_FEATURE_FUNCS_VER(feat_sme2, read_feat_sme_id_field,
-			 ID_AA64PFR1_EL1_SME2_SUPPORTED, ENABLE_SME2_FOR_NS)
+		     ID_AA64PFR1_EL1_SME_MASK, 1U, ENABLE_SME_FOR_NS)
+
+CREATE_FEATURE_FUNCS(feat_sme2, id_aa64pfr1_el1, ID_AA64PFR1_EL1_SME_SHIFT,
+		     ID_AA64PFR1_EL1_SME_MASK, SME2_IMPLEMENTED, ENABLE_SME2_FOR_NS)
+
+/* FEAT_LS64_ACCDATA: */
+CREATE_FEATURE_FUNCS(feat_ls64_accdata, id_aa64isar1_el1, ID_AA64ISAR1_LS64_SHIFT,
+		     ID_AA64ISAR1_LS64_MASK, LS64_ACCDATA_IMPLEMENTED,
+		     ENABLE_FEAT_LS64_ACCDATA)
 
 /*******************************************************************************
  * Function to get hardware granularity support
  ******************************************************************************/
 
-static inline unsigned int read_id_aa64mmfr0_el0_tgran4_field(void)
+__attribute__((always_inline))
+static inline bool is_feat_tgran4K_present(void)
 {
-	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
-			     ID_AA64MMFR0_EL1_TGRAN4_SHIFT);
+	unsigned int tgranx = ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
+			     ID_AA64MMFR0_EL1_TGRAN4_SHIFT, ID_REG_FIELD_MASK);
+	return (tgranx < 8U);
 }
 
-static inline unsigned int read_id_aa64mmfr0_el0_tgran16_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
-			     ID_AA64MMFR0_EL1_TGRAN16_SHIFT);
-}
+CREATE_FEATURE_PRESENT(feat_tgran16K, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_TGRAN16_SHIFT,
+		       ID_AA64MMFR0_EL1_TGRAN16_MASK, TGRAN16_IMPLEMENTED)
 
-static inline unsigned int read_id_aa64mmfr0_el0_tgran64_field(void)
+__attribute__((always_inline))
+static inline bool is_feat_tgran64K_present(void)
 {
-	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
-			     ID_AA64MMFR0_EL1_TGRAN64_SHIFT);
+	unsigned int tgranx = ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
+			     ID_AA64MMFR0_EL1_TGRAN64_SHIFT, ID_REG_FIELD_MASK);
+	return (tgranx < 8U);
 }
 
-static inline unsigned int read_feat_pmuv3_id_field(void)
-{
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER_SHIFT);
-}
+/* FEAT_PMUV3 */
+CREATE_FEATURE_PRESENT(feat_pmuv3, id_aa64dfr0_el1, ID_AA64DFR0_PMUVER_SHIFT,
+		      ID_AA64DFR0_PMUVER_MASK, 1U)
 
-static inline unsigned int read_feat_mtpmu_id_field(void)
+/* FEAT_MTPMU */
+__attribute__((always_inline))
+static inline bool is_feat_mtpmu_present(void)
 {
-	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT);
+	unsigned int mtpmu = ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT,
+					   ID_AA64DFR0_MTPMU_MASK);
+	return (mtpmu != 0U) && (mtpmu != MTPMU_NOT_IMPLEMENTED);
 }
 
-static inline bool is_feat_mtpmu_supported(void)
-{
-	if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
-		return false;
-	}
-
-	if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
-		return true;
-	}
-
-	unsigned int mtpmu = read_feat_mtpmu_id_field();
-
-	return (mtpmu != 0U) && (mtpmu != ID_AA64DFR0_MTPMU_DISABLED);
-}
+CREATE_FEATURE_SUPPORTED(feat_mtpmu, is_feat_mtpmu_present, DISABLE_MTPMU)
 
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 6fdc7e8a..119c4289 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <string.h>
 
 #include <arch.h>
+#include <lib/extensions/sysreg128.h>
 
 /**********************************************************************
  * Macros which create inline functions to read or write CPU system
@@ -241,6 +242,7 @@ DEFINE_SYSOP_PARAM_FUNC(xpaci)
 
 void flush_dcache_range(uintptr_t addr, size_t size);
 void flush_dcache_to_popa_range(uintptr_t addr, size_t size);
+void flush_dcache_to_popa_range_mte2(uintptr_t addr, size_t size);
 void clean_dcache_range(uintptr_t addr, size_t size);
 void inv_dcache_range(uintptr_t addr, size_t size);
 bool is_dcache_enabled(void);
@@ -262,7 +264,12 @@ void disable_mpu_icache_el2(void);
 #define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)
 #define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
 
+#if ENABLE_FEAT_D128
+DECLARE_SYSREG128_RW_FUNCS(par_el1)
+#else
 DEFINE_SYSREG_RW_FUNCS(par_el1)
+#endif
+
 DEFINE_IDREG_READ_FUNC(id_pfr1_el1)
 DEFINE_IDREG_READ_FUNC(id_aa64isar0_el1)
 DEFINE_IDREG_READ_FUNC(id_aa64isar1_el1)
@@ -271,6 +278,7 @@ DEFINE_IDREG_READ_FUNC(id_aa64pfr0_el1)
 DEFINE_IDREG_READ_FUNC(id_aa64pfr1_el1)
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64pfr2_el1, ID_AA64PFR2_EL1)
 DEFINE_IDREG_READ_FUNC(id_aa64dfr0_el1)
+DEFINE_IDREG_READ_FUNC(id_aa64dfr1_el1)
 DEFINE_IDREG_READ_FUNC(id_afr0_el1)
 DEFINE_SYSREG_READ_FUNC(CurrentEl)
 DEFINE_SYSREG_READ_FUNC(ctr_el0)
@@ -282,6 +290,7 @@ DEFINE_SYSREG_RW_FUNCS(elr_el1)
 DEFINE_SYSREG_RW_FUNCS(elr_el2)
 DEFINE_SYSREG_RW_FUNCS(elr_el3)
 DEFINE_SYSREG_RW_FUNCS(mdccsr_el0)
+DEFINE_SYSREG_RW_FUNCS(mdccint_el1)
 DEFINE_SYSREG_RW_FUNCS(dbgdtrrx_el0)
 DEFINE_SYSREG_RW_FUNCS(dbgdtrtx_el0)
 DEFINE_SYSREG_RW_FUNCS(sp_el1)
@@ -440,13 +449,21 @@ DEFINE_SYSREG_RW_FUNCS(tcr_el1)
 DEFINE_SYSREG_RW_FUNCS(tcr_el2)
 DEFINE_SYSREG_RW_FUNCS(tcr_el3)
 
+#if ENABLE_FEAT_D128
+DECLARE_SYSREG128_RW_FUNCS(ttbr0_el1)
+DECLARE_SYSREG128_RW_FUNCS(ttbr1_el1)
+DECLARE_SYSREG128_RW_FUNCS(ttbr0_el2)
+DECLARE_SYSREG128_RW_FUNCS(ttbr1_el2)
+DECLARE_SYSREG128_RW_FUNCS(vttbr_el2)
+#else
 DEFINE_SYSREG_RW_FUNCS(ttbr0_el1)
-DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
-DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
-
 DEFINE_SYSREG_RW_FUNCS(ttbr1_el1)
-
+DEFINE_SYSREG_RW_FUNCS(ttbr0_el2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
 DEFINE_SYSREG_RW_FUNCS(vttbr_el2)
+#endif
+
+DEFINE_SYSREG_RW_FUNCS(ttbr0_el3)
 
 DEFINE_SYSREG_RW_FUNCS(cptr_el2)
 DEFINE_SYSREG_RW_FUNCS(cptr_el3)
@@ -464,6 +481,9 @@ DEFINE_SYSREG_RW_FUNCS(cntp_tval_el0)
 DEFINE_SYSREG_RW_FUNCS(cntp_cval_el0)
 DEFINE_SYSREG_READ_FUNC(cntpct_el0)
 DEFINE_SYSREG_RW_FUNCS(cnthctl_el2)
+DEFINE_SYSREG_RW_FUNCS(cntv_ctl_el0)
+DEFINE_SYSREG_RW_FUNCS(cntv_cval_el0)
+DEFINE_SYSREG_RW_FUNCS(cntkctl_el1)
 
 DEFINE_SYSREG_RW_FUNCS(vtcr_el2)
 
@@ -480,6 +500,9 @@ DEFINE_SYSREG_RW_FUNCS(vtcr_el2)
 #define clr_cntp_ctl_enable(x)  ((x) &= ~(U(1) << CNTP_CTL_ENABLE_SHIFT))
 #define clr_cntp_ctl_imask(x)   ((x) &= ~(U(1) << CNTP_CTL_IMASK_SHIFT))
 
+DEFINE_SYSREG_RW_FUNCS(tpidr_el0)
+DEFINE_SYSREG_RW_FUNCS(tpidr_el1)
+DEFINE_SYSREG_RW_FUNCS(tpidr_el2)
 DEFINE_SYSREG_RW_FUNCS(tpidr_el3)
 
 DEFINE_SYSREG_RW_FUNCS(cntvoff_el2)
@@ -489,18 +512,29 @@ DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)
 
 DEFINE_SYSREG_RW_FUNCS(hacr_el2)
 DEFINE_SYSREG_RW_FUNCS(hpfar_el2)
-DEFINE_SYSREG_RW_FUNCS(tpidr_el2)
+
 DEFINE_SYSREG_RW_FUNCS(dbgvcr32_el2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(ich_hcr_el2, ICH_HCR_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(ich_vmcr_el2, ICH_VMCR_EL2)
 
 DEFINE_SYSREG_READ_FUNC(isr_el1)
 
+DEFINE_SYSREG_RW_FUNCS(mdscr_el1)
 DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
 DEFINE_SYSREG_RW_FUNCS(mdcr_el3)
 DEFINE_SYSREG_RW_FUNCS(hstr_el2)
 DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
 
+DEFINE_SYSREG_RW_FUNCS(csselr_el1)
+DEFINE_SYSREG_RW_FUNCS(tpidrro_el0)
+DEFINE_SYSREG_RW_FUNCS(contextidr_el1)
+DEFINE_SYSREG_RW_FUNCS(spsr_abt)
+DEFINE_SYSREG_RW_FUNCS(spsr_und)
+DEFINE_SYSREG_RW_FUNCS(spsr_irq)
+DEFINE_SYSREG_RW_FUNCS(spsr_fiq)
+DEFINE_SYSREG_RW_FUNCS(dacr32_el2)
+DEFINE_SYSREG_RW_FUNCS(ifsr32_el2)
+
 /* GICv3 System Registers */
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
@@ -549,15 +583,17 @@ DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el2, SCXTNUM_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el1, SCXTNUM_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el0, SCXTNUM_EL0)
 
 /* Armv8.1 VHE Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(contextidr_el2, CONTEXTIDR_EL2)
-DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
 
 /* Armv8.2 ID Registers */
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
 
 /* Armv8.2 RAS Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(disr_el1, DISR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(vdisr_el2, VDISR_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(vsesr_el2, VSESR_EL2)
 
@@ -585,6 +621,7 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(dit, DIT)
 
 /* Armv8.4 FEAT_TRF Register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(trfcr_el2, TRFCR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(trfcr_el1, TRFCR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(vncr_el2, VNCR_EL2)
 
 /* Armv8.5 MTE Registers */
@@ -615,23 +652,63 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)
 /* Armv8.9 system registers */
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr3_el1, ID_AA64MMFR3_EL1)
 
+/* Armv8.9 FEAT_FGT2 Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgrtr2_el2, HDFGRTR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgwtr2_el2, HDFGWTR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgitr2_el2, HFGITR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgrtr2_el2, HFGRTR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(hfgwtr2_el2, HFGWTR2_EL2)
+
 /* FEAT_TCR2 Register */
+DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el1, TCR2_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2)
 
 /* FEAT_SxPIE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(pire0_el1, PIRE0_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(pire0_el2, PIRE0_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(pir_el1, PIR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(pir_el2, PIR_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(s2pir_el2, S2PIR_EL2)
 
 /* FEAT_SxPOE Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(por_el1, POR_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(por_el2, POR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(s2por_el1, S2POR_EL1)
 
 /* FEAT_GCS Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcscr_el2, GCSCR_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el2, GCSPR_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcscr_el1, GCSCR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcscre0_el1, GCSCRE0_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
+
+/* FEAT_THE Registers */
+#if ENABLE_FEAT_D128
+DECLARE_SYSREG128_RW_FUNCS(rcwmask_el1)
+DECLARE_SYSREG128_RW_FUNCS(rcwsmask_el1)
+#else
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwmask_el1, RCWMASK_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(rcwsmask_el1, RCWSMASK_EL1)
+#endif
+
+/* FEAT_SCTLR2 Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el2, SCTLR2_EL2)
 
-/* DynamIQ Shared Unit power management */
+/* FEAT_LS64_ACCDATA Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(accdata_el1, ACCDATA_EL1)
+
+/* DynamIQ Control registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcr_el1, CLUSTERPMCR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcntenset_el1, CLUSTERPMCNTENSET_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmccntr_el1, CLUSTERPMCCNTR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmovsset_el1, CLUSTERPMOVSSET_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmovsclr_el1, CLUSTERPMOVSCLR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmselr_el1, CLUSTERPMSELR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmxevcntr_el1, CLUSTERPMXEVCNTR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmxevtyper_el1, CLUSTERPMXEVTYPER_EL1)
 
 /* CPU Power/Performance Management registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(cpuppmcr_el3, CPUPPMCR_EL3)
@@ -685,24 +762,86 @@ static inline uint64_t el_implemented(unsigned int el)
 }
 
 /*
- * TLBIPAALLOS instruction
- * (TLB Inivalidate GPT Information by PA,
- * All Entries, Outer Shareable)
+ * TLBI PAALLOS instruction
+ * (TLB Invalidate GPT Information by PA, All Entries, Outer Shareable)
  */
 static inline void tlbipaallos(void)
 {
-	__asm__("SYS #6,c8,c1,#4");
+	__asm__("sys #6, c8, c1, #4");
 }
 
 /*
- * Invalidate TLBs of GPT entries by Physical address, last level.
+ * TLBI RPALOS instructions
+ * (TLB Range Invalidate GPT Information by PA, Last level, Outer Shareable)
  *
- * @pa: the starting address for the range
- *      of invalidation
- * @size: size of the range of invalidation
+ * command SIZE, bits [47:44] field:
+ * 0b0000	4KB
+ * 0b0001	16KB
+ * 0b0010	64KB
+ * 0b0011	2MB
+ * 0b0100	32MB
+ * 0b0101	512MB
+ * 0b0110	1GB
+ * 0b0111	16GB
+ * 0b1000	64GB
+ * 0b1001	512GB
  */
-void gpt_tlbi_by_pa_ll(uint64_t pa, size_t size);
+#define TLBI_SZ_4K		0UL
+#define TLBI_SZ_16K		1UL
+#define TLBI_SZ_64K		2UL
+#define TLBI_SZ_2M		3UL
+#define TLBI_SZ_32M		4UL
+#define TLBI_SZ_512M		5UL
+#define TLBI_SZ_1G		6UL
+#define TLBI_SZ_16G		7UL
+#define TLBI_SZ_64G		8UL
+#define TLBI_SZ_512G		9UL
+
+#define	TLBI_ADDR_SHIFT		U(12)
+#define	TLBI_SIZE_SHIFT		U(44)
+
+#define TLBIRPALOS(_addr, _size)				\
+{								\
+	u_register_t arg = ((_addr) >> TLBI_ADDR_SHIFT) |	\
+			   ((_size) << TLBI_SIZE_SHIFT);	\
+	__asm__("sys #6, c8, c4, #7, %0" : : "r" (arg));	\
+}
 
+/* Note: addr must be aligned to 4KB */
+static inline void tlbirpalos_4k(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_4K);
+}
+
+/* Note: addr must be aligned to 16KB */
+static inline void tlbirpalos_16k(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_16K);
+}
+
+/* Note: addr must be aligned to 64KB */
+static inline void tlbirpalos_64k(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_64K);
+}
+
+/* Note: addr must be aligned to 2MB */
+static inline void tlbirpalos_2m(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_2M);
+}
+
+/* Note: addr must be aligned to 32MB */
+static inline void tlbirpalos_32m(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_32M);
+}
+
+/* Note: addr must be aligned to 512MB */
+static inline void tlbirpalos_512m(uintptr_t addr)
+{
+	TLBIRPALOS(addr, TLBI_SZ_512M);
+}
 
 /* Previously defined accessor functions with incomplete register names  */
 
@@ -723,8 +862,32 @@ void gpt_tlbi_by_pa_ll(uint64_t pa, size_t size);
 #define read_cpacr()		read_cpacr_el1()
 #define write_cpacr(_v)		write_cpacr_el1(_v)
 
-#define read_clusterpwrdn()	read_clusterpwrdn_el1()
-#define write_clusterpwrdn(_v)	write_clusterpwrdn_el1(_v)
+#define read_clusterpwrdn()		read_clusterpwrdn_el1()
+#define write_clusterpwrdn(_v)		write_clusterpwrdn_el1(_v)
+
+#define read_clusterpmcr()		read_clusterpmcr_el1()
+#define write_clusterpmcr(_v)		write_clusterpmcr_el1(_v)
+
+#define read_clusterpmcntenset()	read_clusterpmcntenset_el1()
+#define write_clusterpmcntenset(_v)	write_clusterpmcntenset_el1(_v)
+
+#define read_clusterpmccntr()		read_clusterpmccntr_el1()
+#define write_clusterpmccntr(_v)	write_clusterpmccntr_el1(_v)
+
+#define read_clusterpmovsset()		read_clusterpmovsset_el1()
+#define write_clusterpmovsset(_v)	write_clusterpmovsset_el1(_v)
+
+#define read_clusterpmovsclr()		read_clusterpmovsclr_el1()
+#define write_clusterpmovsclr(_v)	write_clusterpmovsclr_el1(_v)
+
+#define read_clusterpmselr()		read_clusterpmselr_el1()
+#define write_clusterpmselr(_v)		write_clusterpmselr_el1(_v)
+
+#define read_clusterpmxevcntr()		read_clusterpmxevcntr_el1()
+#define write_clusterpmxevcntr(_v)	write_clusterpmxevcntr_el1(_v)
+
+#define read_clusterpmxevtyper()	read_clusterpmxevtyper_el1()
+#define write_clusterpmxevtyper(_v)	write_clusterpmxevtyper_el1(_v)
 
 #if ERRATA_SPECULATIVE_AT
 /*
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index d09ad0f0..ec2acd56 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -317,4 +317,12 @@
 #endif
 	.endm
 
+	/*
+	 * Helper macro to instruction adr <reg>, <symbol> where <symbol> is
+	 * within the range +/- 4 GB.
+	 */
+	.macro adr_l, dst, sym
+	adrp	\dst, \sym
+	add	\dst, \dst, :lo12:\sym
+	.endm
 #endif /* ASM_MACROS_S */
diff --git a/include/arch/aarch64/el2_common_macros.S b/include/arch/aarch64/el2_common_macros.S
index 9609c0d8..b9b0e3db 100644
--- a/include/arch/aarch64/el2_common_macros.S
+++ b/include/arch/aarch64/el2_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -157,7 +157,7 @@
 	 */
 	mrs	x0, id_aa64pfr0_el1
 	ubfx	x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
-	cmp	x0, #ID_AA64PFR0_DIT_SUPPORTED
+	cmp	x0, #DIT_IMPLEMENTED
 	bne	1f
 	mov	x0, #DIT_BIT
 	msr	DIT, x0
@@ -408,7 +408,7 @@
 	 * -----------------------------------------------------------
 	 */
 	isb
-	ldp	x28, x29, [sp, #CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1]
+	ldp	x28, x29, [sp, #CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_SCTLR_EL1]
 	msr	sctlr_el1, x28
 	isb
 	msr	tcr_el1, x29
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index a78837f2..204625ce 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -59,47 +59,29 @@
 	 * zero here but are updated ahead of transitioning to a lower EL in the
 	 * function cm_init_context_common().
 	 *
-	 * SCR_EL3.SIF: Set to one to disable instruction fetches from
-	 *  Non-secure memory.
+	 * SCR_EL3.EEL2: Set to one if S-EL2 is present and enabled.
 	 *
-	 * SCR_EL3.EA: Set to one to route External Aborts and SError Interrupts
-	 *  to EL3 when executing at any EL.
+	 * NOTE: Modifying EEL2 bit along with EA bit ensures that we mitigate
+	 * against ERRATA_V2_3099206.
 	 * ---------------------------------------------------------------------
 	 */
-	mov_imm	x0, (SCR_RESET_VAL | SCR_EA_BIT | SCR_SIF_BIT)
+	mov_imm	x0, SCR_RESET_VAL
+#if IMAGE_BL31 && defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+	mrs	x1, id_aa64pfr0_el1
+	and	x1, x1, #(ID_AA64PFR0_SEL2_MASK << ID_AA64PFR0_SEL2_SHIFT)
+	cbz	x1, 1f
+	orr	x0, x0, #SCR_EEL2_BIT
+#endif
+1:
 	msr	scr_el3, x0
 
 	/* ---------------------------------------------------------------------
 	 * Initialise MDCR_EL3, setting all fields rather than relying on hw.
 	 * Some fields are architecturally UNKNOWN on reset.
-	 *
-	 * MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
-	 *  Debug exceptions, other than Breakpoint Instruction exceptions, are
-	 *  disabled from all ELs in Secure state.
-	 *
-	 * MDCR_EL3.SPD32: Set to 0b10 to disable AArch32 Secure self-hosted
-	 *  privileged debug from S-EL1.
-	 *
-	 * MDCR_EL3.TDOSA: Set to zero so that EL2 and EL2 System register
-	 *  access to the powerdown debug registers do not trap to EL3.
-	 *
-	 * MDCR_EL3.TDA: Set to zero to allow EL0, EL1 and EL2 access to the
-	 *  debug registers, other than those registers that are controlled by
-	 *  MDCR_EL3.TDOSA.
 	 */
-	mov_imm	x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \
-		      MDCR_SPD32(MDCR_SPD32_DISABLE)) & \
-		    ~(MDCR_TDOSA_BIT | MDCR_TDA_BIT))
-
+	mov_imm	x0, MDCR_EL3_RESET_VAL
 	msr	mdcr_el3, x0
 
-	/* ---------------------------------------------------------------------
-	 * Enable External Aborts and SError Interrupts now that the exception
-	 * vectors have been setup.
-	 * ---------------------------------------------------------------------
-	 */
-	msr	daifclr, #DAIF_ABT_BIT
-
 	/* ---------------------------------------------------------------------
 	 * Initialise CPTR_EL3, setting all fields rather than relying on hw.
 	 * All fields are architecturally UNKNOWN on reset.
@@ -108,28 +90,6 @@
 	mov_imm x0, CPTR_EL3_RESET_VAL
 	msr	cptr_el3, x0
 
-	/*
-	 * If Data Independent Timing (DIT) functionality is implemented,
-	 * always enable DIT in EL3.
-	 * First assert that the FEAT_DIT build flag matches the feature id
-	 * register value for DIT.
-	 */
-#if ENABLE_FEAT_DIT
-#if ENABLE_ASSERTIONS || ENABLE_FEAT_DIT > 1
-	mrs	x0, id_aa64pfr0_el1
-	ubfx	x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
-#if ENABLE_FEAT_DIT > 1
-	cbz	x0, 1f
-#else
-	cmp	x0, #ID_AA64PFR0_DIT_SUPPORTED
-	ASM_ASSERT(eq)
-#endif
-
-#endif /* ENABLE_ASSERTIONS */
-	mov	x0, #DIT_BIT
-	msr	DIT, x0
-1:
-#endif
 	.endm
 
 /* -----------------------------------------------------------------------------
@@ -271,6 +231,12 @@
 
 	el3_arch_init_common
 
+	/* ---------------------------------------------------------------------
+	 * Set the el3 execution context(i.e. root_context).
+	 * ---------------------------------------------------------------------
+	 */
+	setup_el3_execution_context
+
 	.if \_secondary_cold_boot
 		/* -------------------------------------------------------------
 		 * Check if this is a primary or secondary CPU cold boot.
@@ -374,7 +340,9 @@
 #endif
 
 #if defined(IMAGE_BL1) ||	\
-	(defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM)
+	(defined(IMAGE_BL2) && RESET_TO_BL2 && BL2_IN_XIP_MEM) || \
+	(defined(IMAGE_BL31) && SEPARATE_RWDATA_REGION)
+
 		adrp	x0, __DATA_RAM_START__
 		add	x0, x0, :lo12:__DATA_RAM_START__
 		adrp	x1, __DATA_ROM_START__
@@ -438,7 +406,7 @@
 	 * -----------------------------------------------------------
 	 */
 	isb
-	ldp	x28, x29, [sp, #CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1]
+	ldp	x28, x29, [sp, #CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_SCTLR_EL1]
 	msr	sctlr_el1, x28
 	isb
 	msr	tcr_el1, x29
@@ -461,4 +429,68 @@
 	end:
 	.endm
 
+/*-----------------------------------------------------------------------------
+ * Helper macro to configure EL3 registers we care about, while executing
+ * at EL3/Root world. Root world has its own execution environment and
+ * needs to have its settings configured to be independent of other worlds.
+ * -----------------------------------------------------------------------------
+ */
+	.macro setup_el3_execution_context
+
+	/* ---------------------------------------------------------------------
+	 * The following registers need to be part of separate root context
+	 * as their values are of importance during EL3 execution.
+	 * Hence these registers are overwritten to their intital values,
+	 * irrespective of whichever world they return from to ensure EL3 has a
+	 * consistent execution context throughout the lifetime of TF-A.
+	 *
+	 * DAIF.A: Enable External Aborts and SError Interrupts at EL3.
+	 *
+	 * MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
+	 *  Debug exceptions, other than Breakpoint Instruction exceptions, are
+	 *  disabled from all ELs in Secure state.
+	 *
+	 * SCR_EL3.EA: Set to one to enable SError interrupts at EL3.
+	 *
+	 * SCR_EL3.SIF: Set to one to disable instruction fetches from
+	 *  Non-secure memory.
+	 *
+	 * PMCR_EL0.DP: Set to one so that the cycle counter,
+	 *  PMCCNTR_EL0 does not count when event counting is prohibited.
+	 *  Necessary on PMUv3 <= p7 where MDCR_EL3.{SCCD,MCCD} are not
+	 *  available.
+	 *
+	 * PSTATE.DIT: Set to one to enable the Data Independent Timing (DIT)
+	 *  functionality, if implemented in EL3.
+	 * ---------------------------------------------------------------------
+	 */
+		msr	daifclr, #DAIF_ABT_BIT
+
+		mrs 	x15, mdcr_el3
+		orr	x15, x15, #MDCR_SDD_BIT
+		msr	mdcr_el3, x15
+
+		mrs	x15, scr_el3
+		orr	x15, x15, #SCR_EA_BIT
+		orr	x15, x15, #SCR_SIF_BIT
+		msr	scr_el3, x15
+
+		mrs 	x15, pmcr_el0
+		orr	x15, x15, #PMCR_EL0_DP_BIT
+		msr	pmcr_el0, x15
+
+#if ENABLE_FEAT_DIT
+#if ENABLE_FEAT_DIT > 1
+		mrs	x15, id_aa64pfr0_el1
+		ubfx	x15, x15, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
+		cbz	x15, 1f
+#endif
+		mov	x15, #DIT_BIT
+		msr	DIT, x15
+	1:
+#endif
+
+		isb
+	.endm
+
 #endif /* EL3_COMMON_MACROS_S */
diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h
index 7cd7e727..3ab88de9 100644
--- a/include/bl1/bl1.h
+++ b/include/bl1/bl1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -94,9 +94,5 @@ CASSERT(FWU_NUM_SMC_CALLS ==
 		(FWU_SMC_FID_END - FWU_SMC_FID_START + 1),
 		assert_FWU_NUM_SMC_CALLS_mismatch);
 
-/* Utility functions */
-void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
-			meminfo_t *bl2_mem_layout);
-
 #endif /* __ASSEMBLER__ */
 #endif /* BL1_H */
diff --git a/include/bl31/bl31.h b/include/bl31/bl31.h
index 1d58ef96..ed5374e0 100644
--- a/include/bl31/bl31.h
+++ b/include/bl31/bl31.h
@@ -22,6 +22,5 @@ void bl31_register_bl32_init(int32_t (*func)(void));
 void bl31_register_rmm_init(int32_t (*func)(void));
 void bl31_warm_entrypoint(void);
 void bl31_main(void);
-void bl31_lib_init(void);
 
 #endif /* BL31_H */
diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h
index 21af112a..8b9dfb64 100644
--- a/include/bl31/interrupt_mgmt.h
+++ b/include/bl31/interrupt_mgmt.h
@@ -107,10 +107,10 @@ static inline int32_t validate_ns_interrupt_rm(uint32_t x)
 
 static inline int32_t validate_el3_interrupt_rm(uint32_t x)
 {
-#if EL3_EXCEPTION_HANDLING && !(defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1))
+#if EL3_EXCEPTION_HANDLING && SPM_MM
 	/*
 	 * With EL3 exception handling, EL3 interrupts are always routed to EL3
-	 * from both Secure and Non-secure, when the SPMC does not live in S-EL2.
+	 * from Non-secure and from secure only if SPM_MM is present.
 	 * Therefore INTR_EL3_VALID_RM1 is the only valid routing model.
 	 */
 	if (x == INTR_EL3_VALID_RM1)
diff --git a/include/bl31/sync_handle.h b/include/bl31/sync_handle.h
index 1ac4f98c..394252b7 100644
--- a/include/bl31/sync_handle.h
+++ b/include/bl31/sync_handle.h
@@ -55,6 +55,11 @@ static inline bool is_sysreg_iss_write(uint64_t esr)
  */
 int handle_sysreg_trap(uint64_t esr_el3, cpu_context_t *ctx);
 
+/* Handler for injecting UNDEF exception to lower EL */
+void inject_undef64(cpu_context_t *ctx);
+
+u_register_t create_spsr(u_register_t old_spsr, unsigned int target_el);
+
 /* Prototypes for system register emulation handlers provided by platforms. */
 int plat_handle_impdef_trap(uint64_t esr_el3, cpu_context_t *ctx);
 int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx);
diff --git a/include/bl32/tsp/tsp.h b/include/bl32/tsp/tsp.h
index 285bfbe2..a63abf12 100644
--- a/include/bl32/tsp/tsp.h
+++ b/include/bl32/tsp/tsp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,12 +36,13 @@
  * Identifiers for various TSP services. Corresponding function IDs (whether
  * fast or yielding) are generated by macros defined below
  */
-#define TSP_ADD		0x2000
-#define TSP_SUB		0x2001
-#define TSP_MUL		0x2002
-#define TSP_DIV		0x2003
+#define TSP_ADD				0x2000
+#define TSP_SUB				0x2001
+#define TSP_MUL				0x2002
+#define TSP_DIV				0x2003
 #define TSP_HANDLE_SEL1_INTR_AND_RETURN	0x2004
-#define TSP_CHECK_DIT	0x2005
+#define TSP_CHECK_DIT			0x2005
+#define TSP_MODIFY_EL1_CTX		0x2006
 
 /*
  * Identify a TSP service from function ID filtering the last 16 bits from the
diff --git a/include/bl32/tsp/tsp_el1_context.h b/include/bl32/tsp/tsp_el1_context.h
new file mode 100644
index 00000000..64fde637
--- /dev/null
+++ b/include/bl32/tsp/tsp_el1_context.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TSP_EL1_CONTEXT_H
+#define TSP_EL1_CONTEXT_H
+
+#define TSP_CORRUPT_EL1_REGS        1
+#define TSP_RESTORE_EL1_REGS        0
+
+/* Public helper function to handle EL1 ctx registers at S-EL1(TSP) */
+void modify_el1_ctx_regs(const bool modify_option);
+
+#endif /* TSP_EL1_CONTEXT_H */
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 4c8a17c5..647ae853 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -180,8 +180,6 @@ int load_auth_image(unsigned int image_id, image_info_t *image_data);
 void dyn_disable_auth(void);
 #endif
 
-extern const char build_message[];
-extern const char version_string[];
 const char *get_version(void);
 
 void print_entry_point_info(const entry_point_info_t *ep_info);
diff --git a/include/common/build_message.h b/include/common/build_message.h
new file mode 100644
index 00000000..b7c2f724
--- /dev/null
+++ b/include/common/build_message.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BUILD_MESSAGE_H
+#define BUILD_MESSAGE_H
+
+static const char build_message[] = "Built : " BUILD_MESSAGE_TIMESTAMP;
+static const char build_version_string[] = BUILD_MESSAGE_VERSION_STRING;
+static const char build_version[] = BUILD_MESSAGE_VERSION;
+
+#endif /* BUILD_MESSAGE_H */
diff --git a/include/common/debug.h b/include/common/debug.h
index 5ea541da..0ddb4007 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -91,6 +91,12 @@
 # define VERBOSE(...)	no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
 #endif
 
+#if EARLY_CONSOLE
+#define EARLY_ERROR(...)	ERROR(__VA_ARGS__)
+#else /* !EARLY_CONSOLE */
+#define EARLY_ERROR(...)	no_tf_log(LOG_MARKER_ERROR __VA_ARGS__)
+#endif /* EARLY_CONSOLE */
+
 const char *get_el_str(unsigned int el);
 
 #if ENABLE_BACKTRACE
diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h
index abbf9764..de08f1db 100644
--- a/include/common/fdt_wrappers.h
+++ b/include/common/fdt_wrappers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,6 +21,8 @@ uint32_t fdt_read_uint32_default(const void *dtb, int node,
 				 const char *prop_name, uint32_t dflt_value);
 int fdt_read_uint64(const void *dtb, int node, const char *prop_name,
 		    uint64_t *value);
+uint64_t fdt_read_uint64_default(const void *dtb, int node,
+				 const char *prop_name, uint64_t dflt_value);
 int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name,
 			  unsigned int cells, uint32_t *value);
 int fdtw_read_string(const void *dtb, int node, const char *prop,
diff --git a/include/common/feat_detect.h b/include/common/feat_detect.h
index 788dfb31..b85e1ce9 100644
--- a/include/common/feat_detect.h
+++ b/include/common/feat_detect.h
@@ -11,8 +11,9 @@
 void detect_arch_features(void);
 
 /* Macro Definitions */
-#define FEAT_STATE_DISABLED	0
-#define FEAT_STATE_ALWAYS	1
-#define FEAT_STATE_CHECK	2
+#define FEAT_STATE_DISABLED		0
+#define FEAT_STATE_ALWAYS		1
+#define FEAT_STATE_CHECK		2
+#define FEAT_STATE_CHECK_ASYMMETRIC	3
 
 #endif /* FEAT_DETECT_H */
diff --git a/include/common/par.h b/include/common/par.h
new file mode 100644
index 00000000..c8d67a38
--- /dev/null
+++ b/include/common/par.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PAR_H
+#define PAR_H
+
+#include<arch_features.h>
+#include<lib/extensions/sysreg128.h>
+
+static inline uint64_t get_par_el1_pa(sysreg_t par)
+{
+	uint64_t pa = par & UINT64_MAX;
+	/* PA, bits [51:12] is Output address */
+	uint64_t mask = PAR_ADDR_MASK;
+
+#if ENABLE_FEAT_D128
+	/* If D128 is in use, the PA is in the upper 64-bit word of PAR_EL1 */
+	if (is_feat_d128_supported() && (par & PAR_EL1_D128)) {
+		pa = (par >> 64) & UINT64_MAX;
+		/* PA, bits [55:12] is Output address */
+		mask = PAR_D128_ADDR_MASK;
+	}
+#endif
+	return pa & mask;
+}
+
+#endif /* PAR_H */
diff --git a/include/common/sha_common_macros.h b/include/common/sha_common_macros.h
new file mode 100644
index 00000000..a419488f
--- /dev/null
+++ b/include/common/sha_common_macros.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SHA_COMMON_MACROS_H
+#define SHA_COMMON_MACROS_H
+
+#define MD5_DIGEST_SIZE                 16U
+#define SHA1_DIGEST_SIZE                20U
+#define SHA224_DIGEST_SIZE              28U
+#define SHA256_DIGEST_SIZE              32U
+#define SHA384_DIGEST_SIZE              48U
+#define SHA512_224_DIGEST_SIZE          28U
+#define SHA512_256_DIGEST_SIZE          32U
+#define SHA512_DIGEST_SIZE              64U
+
+#endif /* SHA_COMMON_MACROS_H */
diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h
index 88302fd7..d6c1a2a8 100644
--- a/include/drivers/arm/css/css_mhu_doorbell.h
+++ b/include/drivers/arm/css/css_mhu_doorbell.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,10 @@
 #define SENDER_REG_STAT(_channel)	(0x20 * (_channel))
 #define SENDER_REG_SET(_channel)	((0x20 * (_channel)) + 0xC)
 
+#define MHU_V3_PBX_PDBCW_PAGE_OFFSET		UL(0x1000)
+#define MHU_V3_SENDER_REG_SET(_channel)		(MHU_V3_PBX_PDBCW_PAGE_OFFSET + \
+						 SENDER_REG_SET(_channel))
+
 /* Helper macro to ring doorbell */
 #define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask)	do {	\
 		uint32_t db = mmio_read_32(addr) & (preserve_mask);	\
diff --git a/include/drivers/arm/css/dsu.h b/include/drivers/arm/css/dsu.h
new file mode 100644
index 00000000..4d7822b5
--- /dev/null
+++ b/include/drivers/arm/css/dsu.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DSU_H
+#define DSU_H
+
+#define PMCR_N_MAX			0x1f
+
+#define save_pmu_reg(state, reg) state->reg = read_##reg()
+
+#define restore_pmu_reg(context, reg) write_##reg(context->reg)
+
+typedef struct cluster_pmu_state{
+	uint64_t clusterpmcr;
+	uint64_t clusterpmcntenset;
+	uint64_t clusterpmccntr;
+	uint64_t clusterpmovsset;
+	uint64_t clusterpmselr;
+	uint64_t clusterpmsevtyper;
+	uint64_t counter_val[PMCR_N_MAX];
+	uint64_t counter_type[PMCR_N_MAX];
+} cluster_pmu_state_t;
+
+static inline unsigned int read_cluster_eventctr_num(void)
+{
+	return ((read_clusterpmcr() >> CLUSTERPMCR_N_SHIFT) &
+			CLUSTERPMCR_N_MASK);
+}
+
+
+void save_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_context);
+
+void restore_dsu_pmu_state(cluster_pmu_state_t *cluster_pmu_context);
+
+void cluster_on_dsu_pmu_context_restore(void);
+
+void cluster_off_dsu_pmu_context_save(void);
+
+#endif /* DSU_H */
diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h
index 356012bf..96e19246 100644
--- a/include/drivers/arm/css/scmi.h
+++ b/include/drivers/arm/css/scmi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -123,6 +123,8 @@ typedef struct scmi_channel_plat_info {
 	void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info);
 	/* cookie is unused now. But added for future enhancements. */
 	void *cookie;
+	/* Delay in micro-seconds while polling the channel status. */
+	uint32_t delay;
 } scmi_channel_plat_info_t;
 
 
diff --git a/include/drivers/arm/css/sds.h b/include/drivers/arm/css/sds.h
index db4cbaaf..ab957751 100644
--- a/include/drivers/arm/css/sds.h
+++ b/include/drivers/arm/css/sds.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -79,12 +79,33 @@ typedef enum {
 	SDS_ACCESS_MODE_CACHED,
 } sds_access_mode_t;
 
-int sds_init(void);
-int sds_struct_exists(unsigned int structure_id);
-int sds_struct_read(uint32_t structure_id, unsigned int fld_off, void *data,
-		size_t size, sds_access_mode_t mode);
-int sds_struct_write(uint32_t structure_id, unsigned int fld_off, void *data,
-		size_t size, sds_access_mode_t mode);
+/*
+ * The following structure describes a SDS memory region. Its items are used
+ * to track and maintain the state of the memory region reserved for usage
+ * by the SDS framework.
+ *
+ * The base address of the SDS memory region is platform specific. The
+ * SDS description structure must already contain the address when it is
+ * returned by the plat_sds_get_regions() platform API during SDS region
+ * initialization.
+ * The size of the SDS memory region is dynamically discovered during the
+ * initialization of the region and written into the 'size' item of the
+ * SDS description structure.
+ */
+typedef struct {
+	uintptr_t base;	/* Pointer to the base of the SDS memory region */
+	size_t size;	/* Size of the SDS memory region in bytes */
+} sds_region_desc_t;
+
+/* API to get the platform specific SDS region description(s) */
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count);
+
+int sds_init(unsigned int region_id);
+int sds_struct_exists(unsigned int region_id, unsigned int structure_id);
+int sds_struct_read(unsigned int region_id, uint32_t structure_id,
+	unsigned int fld_off, void *data, size_t size, sds_access_mode_t mode);
+int sds_struct_write(unsigned int region_id, uint32_t structure_id,
+	unsigned int fld_off, void *data, size_t size, sds_access_mode_t mode);
 #endif /*__ASSEMBLER__ */
 
 #endif /* SDS_H */
diff --git a/include/drivers/arm/dcc.h b/include/drivers/arm/dcc.h
index 072bed52..7f71932f 100644
--- a/include/drivers/arm/dcc.h
+++ b/include/drivers/arm/dcc.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2021,  Xilinx Inc.
+ * Copyright (c) 2021-2022, Xilinx Inc.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +15,7 @@
  * Initialize a new dcc console instance and register it with the console
  * framework.
  */
-int console_dcc_register(void);
-void console_dcc_unregister(void);
+int console_dcc_register(console_t *console);
+void console_dcc_unregister(console_t *console);
 
-#endif /* DCC */
+#endif /* DCC_H */
diff --git a/include/drivers/arm/fvp/fvp_cpu_pwr.h b/include/drivers/arm/fvp/fvp_cpu_pwr.h
new file mode 100644
index 00000000..488be18c
--- /dev/null
+++ b/include/drivers/arm/fvp/fvp_cpu_pwr.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FVP_CPU_PWR_H
+#define FVP_CPU_PWR_H
+
+#ifndef __ASSEMBLER__
+#include <stdbool.h>
+#include <stdint.h>
+
+#if __aarch64__
+bool check_cpupwrctrl_el1_is_available(void);
+#endif /* __aarch64__ */
+#endif /* __ASSEMBLER__ */
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define CPUPWRCTLR_EL1                  S3_0_C15_C2_7
+#define CPUPWRCTLR_EL1_CORE_PWRDN_BIT   U(1)
+
+#endif /* FVP_CPU_PWR_H */
diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h
index bebd9cef..c7c441d7 100644
--- a/include/drivers/arm/gicv2.h
+++ b/include/drivers/arm/gicv2.h
@@ -51,7 +51,7 @@
 #define SGIR_TGTLSTFLT_MASK	U(0x3)
 #define SGIR_TGTLST_SHIFT	16
 #define SGIR_TGTLST_MASK	U(0xff)
-#define SGIR_NSATT		(U(0x1) << 16)
+#define SGIR_NSATT		(U(0x1) << 15)
 #define SGIR_INTID_MASK		ULL(0xf)
 
 #define SGIR_TGT_SPECIFIC	U(0)
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index cf6a7465..0e6137d1 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -150,6 +150,7 @@
 /* GICD_TYPER shifts and masks */
 #define	TYPER_ESPI		U(1 << 8)
 #define	TYPER_DVIS		U(1 << 18)
+#define	TYPER_LPIS		U(1 << 17)
 #define	TYPER_ESPI_RANGE_MASK	U(0x1f)
 #define	TYPER_ESPI_RANGE_SHIFT	U(27)
 #define	TYPER_ESPI_RANGE	U(TYPER_ESPI_MASK << TYPER_ESPI_SHIFT)
@@ -340,7 +341,7 @@
 
 /* GITS_CTLR bit definitions */
 #define GITS_CTLR_ENABLED_BIT		BIT_32(0)
-#define GITS_CTLR_QUIESCENT_BIT		BIT_32(1)
+#define GITS_CTLR_QUIESCENT_BIT		BIT_32(31)
 
 #define GITS_TYPER_VSGI			BIT_64(39)
 
@@ -588,6 +589,7 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm,
 void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num);
 void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num);
 unsigned int gicv3_set_pmr(unsigned int mask);
+unsigned int gicv3_deactivate_priority(unsigned int mask);
 
 void gicv3_get_component_prodid_rev(const uintptr_t gicd_base,
 				    unsigned int *gic_prod_id,
diff --git a/include/drivers/arm/rss_comms.h b/include/drivers/arm/rse_comms.h
similarity index 53%
rename from include/drivers/arm/rss_comms.h
rename to include/drivers/arm/rse_comms.h
index b96c79f7..e4169a51 100644
--- a/include/drivers/arm/rss_comms.h
+++ b/include/drivers/arm/rse_comms.h
@@ -5,11 +5,11 @@
  *
  */
 
-#ifndef RSS_COMMS_H
-#define RSS_COMMS_H
+#ifndef RSE_COMMS_H
+#define RSE_COMMS_H
 
 #include <stdint.h>
 
-int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base);
+int rse_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base);
 
-#endif /* RSS_COMMS_H */
+#endif /* RSE_COMMS_H */
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-2.h b/include/drivers/auth/mbedtls/mbedtls_config-2.h
deleted file mode 100644
index 01e261a9..00000000
--- a/include/drivers/auth/mbedtls/mbedtls_config-2.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2015-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
-/*
- * Key algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_RSA			1
-#define TF_MBEDTLS_ECDSA		2
-#define TF_MBEDTLS_RSA_AND_ECDSA	3
-
-#define TF_MBEDTLS_USE_RSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA \
-		|| TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA)
-#define TF_MBEDTLS_USE_ECDSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA \
-		|| TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA)
-
-/*
- * Hash algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_SHA256		1
-#define TF_MBEDTLS_SHA384		2
-#define TF_MBEDTLS_SHA512		3
-
-/*
- * Configuration file to build mbed TLS with the required features for
- * Trusted Boot
- */
-
-#define MBEDTLS_PLATFORM_MEMORY
-#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
-/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
-#define MBEDTLS_PLATFORM_SNPRINTF_ALT
-
-#define MBEDTLS_PKCS1_V21
-
-#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
-#define MBEDTLS_X509_CHECK_KEY_USAGE
-#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
-
-#define MBEDTLS_ASN1_PARSE_C
-#define MBEDTLS_ASN1_WRITE_C
-
-#define MBEDTLS_BASE64_C
-#define MBEDTLS_BIGNUM_C
-
-#define MBEDTLS_ERROR_C
-#define MBEDTLS_MD_C
-
-#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
-#define MBEDTLS_OID_C
-
-#define MBEDTLS_PK_C
-#define MBEDTLS_PK_PARSE_C
-#define MBEDTLS_PK_WRITE_C
-
-#define MBEDTLS_PLATFORM_C
-
-#if TF_MBEDTLS_USE_ECDSA
-#define MBEDTLS_ECDSA_C
-#define MBEDTLS_ECP_C
-#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#define MBEDTLS_ECP_NO_INTERNAL_RNG
-#endif
-#if TF_MBEDTLS_USE_RSA
-#define MBEDTLS_RSA_C
-#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
-#endif
-
-#define MBEDTLS_SHA256_C
-
-/*
- * If either Trusted Boot or Measured Boot require a stronger algorithm than
- * SHA-256, pull in SHA-512 support.
- */
-#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256) /* TBB hash algo */
-#define	MBEDTLS_SHA512_C
-#else
-   /* TBB uses SHA-256, what about measured boot? */
-#if defined(TF_MBEDTLS_MBOOT_USE_SHA512)
-#define MBEDTLS_SHA512_C
-#endif
-#endif
-
-#define MBEDTLS_VERSION_C
-
-#define MBEDTLS_X509_USE_C
-#define MBEDTLS_X509_CRT_PARSE_C
-
-#if TF_MBEDTLS_USE_AES_GCM
-#define MBEDTLS_AES_C
-#define MBEDTLS_CIPHER_C
-#define MBEDTLS_GCM_C
-#endif
-
-/* MPI / BIGNUM options */
-#define MBEDTLS_MPI_WINDOW_SIZE			2
-
-#if TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define MBEDTLS_MPI_MAX_SIZE			256
-#else
-#define MBEDTLS_MPI_MAX_SIZE			512
-#endif
-#else
-#define MBEDTLS_MPI_MAX_SIZE			256
-#endif
-
-/* Memory buffer allocator options */
-#define MBEDTLS_MEMORY_ALIGN_MULTIPLE		8
-
-/*
- * Prevent the use of 128-bit division which
- * creates dependency on external libraries.
- */
-#define MBEDTLS_NO_UDBL_DIVISION
-
-#ifndef __ASSEMBLER__
-/* System headers required to build mbed TLS with the current configuration */
-#include <stdlib.h>
-#include <mbedtls/check_config.h>
-#endif
-
-/*
- * Determine Mbed TLS heap size
- * 13312 = 13*1024
- * 11264 = 11*1024
- * 7168  = 7*1024
- */
-#if TF_MBEDTLS_USE_ECDSA
-#define TF_MBEDTLS_HEAP_SIZE		U(13312)
-#elif TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define TF_MBEDTLS_HEAP_SIZE		U(7168)
-#else
-#define TF_MBEDTLS_HEAP_SIZE		U(11264)
-#endif
-#endif
-
-/*
- * Warn if errors from certain functions are ignored.
- *
- * The warnings are always enabled (where supported) for critical functions
- * where ignoring the return value is almost always a bug. This macro extends
- * the warnings to more functions.
- */
-#define MBEDTLS_CHECK_RETURN_WARNING
-
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/include/drivers/auth/mbedtls/mbedtls_config-3.h b/include/drivers/auth/mbedtls/mbedtls_config-3.h
index 923fc546..6ed93978 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config-3.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config-3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -73,23 +73,17 @@
 #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
 #endif
 
-/* The library does not currently support enabling SHA-256 without SHA-224. */
-#define MBEDTLS_SHA224_C
-#define MBEDTLS_SHA256_C
-/*
- * If either Trusted Boot or Measured Boot require a stronger algorithm than
- * SHA-256, pull in SHA-512 support. Library currently needs to have SHA_384
- * support when enabling SHA-512.
- */
-#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256) /* TBB hash algo */
-#define MBEDTLS_SHA384_C
-#define	MBEDTLS_SHA512_C
-#else
-   /* TBB uses SHA-256, what about measured boot? */
-#if defined(TF_MBEDTLS_MBOOT_USE_SHA512)
-#define MBEDTLS_SHA384_C
-#define MBEDTLS_SHA512_C
+/* Enable hash algorithms based on TBB or Measured Boot */
+#if (TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256) || defined(TF_MBEDTLS_MBOOT_USE_SHA256)
+    #define MBEDTLS_SHA256_C
 #endif
+
+#if (TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384) || defined(TF_MBEDTLS_MBOOT_USE_SHA384)
+    #define MBEDTLS_SHA384_C
+#endif
+
+#if (TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512) || defined(TF_MBEDTLS_MBOOT_USE_SHA512)
+    #define MBEDTLS_SHA512_C
 #endif
 
 #define MBEDTLS_VERSION_C
@@ -104,7 +98,9 @@
 #endif
 
 /* MPI / BIGNUM options */
-#define MBEDTLS_MPI_WINDOW_SIZE			2
+
+/* Note: Lower numbers trade longer execution time for less RAM allocation */
+#define MBEDTLS_MPI_WINDOW_SIZE			1
 
 #if TF_MBEDTLS_USE_RSA
 #if TF_MBEDTLS_KEY_SIZE <= 2048
@@ -128,7 +124,6 @@
 #ifndef __ASSEMBLER__
 /* System headers required to build mbed TLS with the current configuration */
 #include <stdlib.h>
-#include <mbedtls/check_config.h>
 #endif
 
 /*
diff --git a/include/drivers/auth/mbedtls/psa_mbedtls_config.h b/include/drivers/auth/mbedtls/psa_mbedtls_config.h
index ad825f0a..1001d895 100644
--- a/include/drivers/auth/mbedtls/psa_mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/psa_mbedtls_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Ltd. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Ltd. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,7 @@
 #include "mbedtls_config-3.h"
 
 #define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
 
 /*
  * Using PSA crypto API requires an RNG right now. If we don't define the macro
diff --git a/include/drivers/auth/tbbr_cot_common.h b/include/drivers/auth/tbbr_cot_common.h
index b4f2d220..019ae176 100644
--- a/include/drivers/auth/tbbr_cot_common.h
+++ b/include/drivers/auth/tbbr_cot_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020,2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,10 +21,10 @@ extern auth_param_type_desc_t sig_alg;
 extern auth_param_type_desc_t raw_data;
 
 extern auth_param_type_desc_t tb_fw_hash;
+extern auth_param_type_desc_t hw_config_hash;
 extern auth_param_type_desc_t tb_fw_config_hash;
 extern auth_param_type_desc_t fw_config_hash;
 
 extern const auth_img_desc_t trusted_boot_fw_cert;
-extern const auth_img_desc_t hw_config;
 
 #endif /* TBBR_COT_COMMON_H */
diff --git a/include/drivers/cadence/cdns_nand.h b/include/drivers/cadence/cdns_nand.h
index 64ba2676..f20627ba 100644
--- a/include/drivers/cadence/cdns_nand.h
+++ b/include/drivers/cadence/cdns_nand.h
@@ -198,6 +198,7 @@ typedef struct cnf_dev_info {
 #define CNF_OPR_WORK_MODE_RES				3
 
 /* Mini controller common settings register field offsets */
+#define CNF_CMN_SETTINGS_OPR_MASK			0x00000003
 #define CNF_CMN_SETTINGS_WR_WUP				20
 #define CNF_CMN_SETTINGS_RD_WUP				16
 #define CNF_CMN_SETTINGS_DEV16				8
diff --git a/include/drivers/cadence/cdns_sdmmc.h b/include/drivers/cadence/cdns_sdmmc.h
index 64527253..f8d616ff 100644
--- a/include/drivers/cadence/cdns_sdmmc.h
+++ b/include/drivers/cadence/cdns_sdmmc.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,23 +11,26 @@
 
 #include <drivers/cadence/cdns_combo_phy.h>
 #include <drivers/mmc.h>
-#include "socfpga_plat_def.h"
 
 #if MMC_DEVICE_TYPE == 0
-#define CONFIG_DMA_ADDR_T_64BIT		0
+#define CONFIG_DMA_ADDR_T_64BIT			0
 #endif
 
-#define MMC_REG_BASE			SOCFPGA_MMC_REG_BASE
-#define COMBO_PHY_REG		0x0
-#define SDHC_EXTENDED_WR_MODE_MASK	0xFFFFFFF7
-#define SDHC_DLL_RESET_MASK	0x00000001
+#define MMC_REG_BASE				SOCFPGA_MMC_REG_BASE
+#define COMBO_PHY_REG				0x0
+#define SDHC_EXTENDED_WR_MODE_MASK		0xFFFFFFF7
+#define SDHC_DLL_RESET_MASK			0x00000001
+#define MMC_MAX_BLOCK_LEN 512U
+
 /* HRS09 */
 #define SDHC_PHY_SW_RESET			BIT(0)
-#define SDHC_PHY_INIT_COMPLETE		BIT(1)
-#define SDHC_EXTENDED_RD_MODE(x)	((x) << 2)
+#define SDHC_PHY_INIT_COMPLETE			BIT(1)
+#define SDHC_EXTENDED_RD_MODE(x)		((x) << 2)
 #define EXTENDED_WR_MODE			3
-#define SDHC_EXTENDED_WR_MODE(x)	((x) << 3)
-#define RDCMD_EN					15
+#define SDHC_EXTENDED_WR_MODE(x)		((x) << 3)
+#define RDCMD_EN				(3 << 15)
+#define PHY_SW_RESET_EN				(1 << 0)
+#define PHY_INIT_COMPLETE_BIT			(1 << 1)
 #define SDHC_RDCMD_EN(x)			((x) << 15)
 #define SDHC_RDDATA_EN(x)			((x) << 16)
 
@@ -38,9 +42,9 @@
 /* • 1111b - Reserved */
 /* • 1110b - t_sdmclk*2(27+2) */
 /* • 1101b - t_sdmclk*2(26+2) */
-#define READ_CLK					0xa << 16
-#define WRITE_CLK					0xe << 16
-#define DTC_VAL						0xE
+#define READ_CLK				0xa << 16
+#define WRITE_CLK				0xe << 16
+#define DTC_VAL					0xE
 
 /* SRS00 */
 /* System Address / Argument 2 / 32-bit block count
@@ -49,18 +53,18 @@
  * • SDMA system memory address
  * • Auto CMD23 Argument
  */
-#define SAAR						(1)
+#define SAAR					(1)
 
 /* SRS01 */
 /* Transfer Block Size
  * This field defines block size for block data transfers
  */
-#define BLOCK_SIZE					0
+#define BLOCK_SIZE				0
 
 /* SDMA Buffer Boundary
  * System address boundary can be set for SDMA engine.
  */
-#define SDMA_BUF					7 << 12
+#define SDMA_BUF				7 << 12
 
 /* Block Count For Current Transfer
  * To set the number of data blocks can be defined for next transfer
@@ -68,93 +72,108 @@
 #define BLK_COUNT_CT				16
 
 /* SRS03 */
-#define CMD_START					(U(1) << 31)
+#define CMD_START				(U(1) << 31)
 #define CMD_USE_HOLD_REG			(1 << 29)
 #define CMD_UPDATE_CLK_ONLY			(1 << 21)
 #define CMD_SEND_INIT				(1 << 15)
 #define CMD_STOP_ABORT_CMD			(4 << 22)
 #define CMD_RESUME_CMD				(2 << 22)
 #define CMD_SUSPEND_CMD				(1 << 22)
-#define DATA_PRESENT				(1 << 21)
-#define CMD_IDX_CHK_ENABLE			(1 << 20)
-#define CMD_WRITE					(0 << 4)
-#define CMD_READ					(1 << 4)
+#define DATA_PRESENT				(0x20)
+#define CMD_IDX_CHK_ENABLE			(0x10)
+#define CMD_WRITE				(0 << 4)
+#define CMD_READ				(1 << 4)
 #define	MULTI_BLK_READ				(1 << 5)
-#define RESP_ERR					(1 << 7)
-#define CMD_CHECK_RESP_CRC			(1 << 19)
-#define RES_TYPE_SEL_48				(2 << 16)
-#define RES_TYPE_SEL_136			(1 << 16)
-#define RES_TYPE_SEL_48_B			(3 << 16)
-#define RES_TYPE_SEL_NO				(0 << 16)
-#define DMA_ENABLED					(1 << 0)
-#define BLK_CNT_EN					(1 << 1)
-#define AUTO_CMD_EN					(2 << 2)
-#define COM_IDX						24
-#define ERROR_INT					(1 << 15)
-#define INT_SBE						(1 << 13)
-#define INT_HLE						(1 << 12)
-#define INT_FRUN					(1 << 11)
-#define INT_DRT						(1 << 9)
-#define INT_RTO						(1 << 8)
-#define INT_DCRC					(1 << 7)
-#define INT_RCRC					(1 << 6)
-#define INT_RXDR					(1 << 5)
-#define INT_TXDR					(1 << 4)
-#define INT_DTO						(1 << 3)
+#define RESP_ERR				(1 << 7)
+#define CMD_CHECK_RESP_CRC			(0x08)
+#define RES_TYPE_SEL_48				(0x2)
+#define RES_TYPE_SEL_136			(0x1)
+#define RES_TYPE_SEL_48_B			(0x3)
+#define RES_TYPE_SEL_NO				(0x3)
+#define DMA_ENABLED				(1 << 0)
+#define BLK_CNT_EN				(1 << 1)
+#define AUTO_CMD_EN				(2 << 2)
+#define COM_IDX					24
+#define ERROR_INT				(1 << 15)
+#define INT_SBE					(1 << 13)
+#define INT_HLE					(1 << 12)
+#define INT_FRUN				(1 << 11)
+#define INT_DRT					(1 << 9)
+#define INT_RTO					(1 << 8)
+#define INT_DCRC				(1 << 7)
+#define INT_RCRC				(1 << 6)
+#define INT_RXDR				(1 << 5)
+#define INT_TXDR				(1 << 4)
+#define INT_DTO					(1 << 3)
 #define INT_CMD_DONE				(1 << 0)
-#define TRAN_COMP					(1 << 1)
+#define TRAN_COMP				(1 << 1)
 
 /* SRS09 */
 #define STATUS_DATA_BUSY			BIT(2)
+#define CI					16
+#define CHECK_CARD				BIT(CI)
 
 /* SRS10 */
+#define BIT1					(0 << 1)
+#define BIT4					(1 << 1)
+#define BIT8					(1 << 5)
+
 /* LED Control
  * State of this bit directly drives led port of the host
  * in order to control the external LED diode
  * Default value 0 << 1
  */
-#define LEDC						BIT(0)
-#define LEDC_OFF					0 << 1
+#define LEDC					BIT(0)
+#define LEDC_OFF				(0 << 1)
 
 /* Data Transfer Width
  * Bit used to configure DAT bus width to 1 or 4
  * Default value 1 << 1
  */
-#define DT_WIDTH					BIT(1)
-#define DTW_4BIT					1 << 1
+#define DT_WIDTH				BIT(1)
+#define DTW_4BIT				(1 << 1)
 
 /* Extended Data Transfer Width
  * This bit is to enable/disable 8-bit DAT bus width mode
  * Default value 1 << 5
  */
-#define EDTW_8BIT					1 << 5
+#define EDTW_8BIT				BIT(5)
 
 /* High Speed Enable
  * Selects operating mode to Default Speed (HSE=0) or High Speed (HSE=1)
  */
-#define HS_EN						BIT(2)
+#define HS_EN					BIT(2)
 
 /* here 0 defines the 64 Kb size */
 #define MAX_64KB_PAGE				0
-#define EMMC_DESC_SIZE		(1<<20)
-
+#define EMMC_DESC_SIZE				(1<<20)
+#define DTCV_OFFSET				(0x22E)
+#define DTCV_VAL				(0xE)
+#define CICE_OFFSET				(0x20E)
+#define SRS_12_CC_EN				(1 << 0)
 /* SRS11 */
 /* Software Reset For All
  * When set to 1, the entire slot is reset
  * After completing the reset operation, SRFA bit is automatically cleared
  */
-#define SRFA						BIT(24)
+#define SRFA					BIT(24)
 
 /* Software Reset For CMD Line
  * When set to 1, resets the logic related to the command generation and response checking
  */
-#define SRCMD						BIT(25)
+#define SRCMD					BIT(25)
 
 /* Software Reset For DAT Line
  * When set to 1, resets the logic related to the data path,
  * including data buffers and the DMA logic
  */
-#define SRDAT						BIT(26)
+#define SRDAT					BIT(26)
+
+
+/* SRS12 */
+/* Error mask */
+#define SRS12_ERR_MASK				0xFFFF8000U
+#define CDNS_CSD_BYTE_MASK			0x000000FFU
 
 /* SRS15 */
 /* UHS Mode Select
@@ -165,40 +184,43 @@
  * • 011b - SDR104
  * • 100b - DDR50
  */
-#define SDR12_MODE					0 << 16
-#define SDR25_MODE					1 << 16
-#define SDR50_MODE					2 << 16
-#define SDR104_MODE					3 << 16
-#define DDR50_MODE					4 << 16
+#define SDR12_MODE				0 << 16
+#define SDR25_MODE				1 << 16
+#define SDR50_MODE				2 << 16
+#define SDR104_MODE				3 << 16
+#define DDR50_MODE				4 << 16
 /* 1.8V Signaling Enable
  * • 0 - for Default Speed, High Speed mode
  * • 1 - for UHS-I mode
  */
-#define V18SE						BIT(19)
+#define V18SE					BIT(19)
 
 /* CMD23 Enable
  * In result of Card Identification process,
  * Host Driver set this bit to 1 if Card supports CMD23
  */
-#define CMD23_EN					BIT(27)
+#define CMD23_EN				BIT(27)
 
 /* Host Version 4.00 Enable
  * • 0 - Version 3.00
  * • 1 - Version 4.00
  */
-#define HV4E						BIT(28)
+#define HV4E					BIT(28)
 /* Conf depends on SRS15.HV4E */
-#define SDMA						0 << 3
-#define ADMA2_32					2 << 3
-#define ADMA2_64					3 << 3
+#define SDMA					0 << 3
+#define ADMA2_32				2 << 3
+#define ADMA2_64				3 << 3
+#define DMA_SEL_BIT				3 << 3
+#define DMA_SEL_BIT_2				2 << 3
+#define DMA_SEL_BIT_3				3 << 3
 
 /* Preset Value Enable
  * Setting this bit to 1 triggers an automatically update of SRS11
  */
-#define PVE							BIT(31)
+#define PVE					BIT(31)
 
-#define BIT_AD_32					0 << 29
-#define BIT_AD_64					1 << 29
+#define BIT_AD_32				0 << 29
+#define BIT_AD_64				1 << 29
 
 /* SW RESET REG*/
 #define SDHC_CDNS_HRS00				(0x00)
@@ -206,7 +228,7 @@
 
 /* PHY access port */
 #define SDHC_CDNS_HRS04				0x10
-#define SDHC_CDNS_HRS04_ADDR		GENMASK(5, 0)
+#define SDHC_CDNS_HRS04_ADDR			GENMASK(5, 0)
 
 /* PHY data access port */
 #define SDHC_CDNS_HRS05				0x14
@@ -233,14 +255,51 @@
 #define SDHC_CDNS_SRS13				0x234
 #define SDHC_CDNS_SRS14				0x238
 #define SDHC_CDNS_SRS15				0x23c
+#define SDHC_CDNS_SRS16				0x240
 #define SDHC_CDNS_SRS21				0x254
 #define SDHC_CDNS_SRS22				0x258
 #define SDHC_CDNS_SRS23				0x25c
+#define SDHC_CDNS_SRS24				0x260
+#define SDHC_CDNS_SRS25				0x264
+
+/* SRS00 */
+#define SAAR					(1)
+
+/* SRS03 */
+#define CMD_START				(U(1) << 31)
+#define CMD_USE_HOLD_REG			(1 << 29)
+#define CMD_UPDATE_CLK_ONLY			(1 << 21)
+#define CMD_SEND_INIT				(1 << 15)
+#define CMD_STOP_ABORT_CMD			(4 << 22)
+#define CMD_RESUME_CMD				(2 << 22)
+#define CMD_SUSPEND_CMD				(1 << 22)
+#define DMA_ENABLED				(1 << 0)
+#define BLK_CNT_EN				(1 << 1)
+#define AUTO_CMD_EN				(2 << 2)
+#define COM_IDX					24
+#define ERROR_INT				(1 << 15)
+#define INT_SBE					(1 << 13)
+#define INT_HLE					(1 << 12)
+#define INT_FRUN				(1 << 11)
+#define INT_DRT					(1 << 9)
+#define INT_RTO					(1 << 8)
+#define INT_DCRC				(1 << 7)
+#define INT_RCRC				(1 << 6)
+#define INT_RXDR				(1 << 5)
+#define INT_TXDR				(1 << 4)
+#define INT_DTO					(1 << 3)
+#define INT_CMD_DONE				(1 << 0)
+#define TRAN_COMP				(1 << 1)
+#define CDNS_HOST_CMD_INHIBIT			(BIT(0))
+#define CDNS_HOST_DATA_INHIBIT			(BIT(1))
+#define ACE_CMD_12				(BIT(2))
+
+#define PAGE_BUFFER_LEN				(64 * 1024)
 
 /* HRS07 */
 #define SDHC_CDNS_HRS07				0x1c
 #define SDHC_IDELAY_VAL(x)			((x) << 0)
-#define SDHC_RW_COMPENSATE(x)		((x) << 16)
+#define SDHC_RW_COMPENSATE(x)			((x) << 16)
 
 /* PHY reset port */
 #define SDHC_CDNS_HRS09				0x24
@@ -254,53 +313,49 @@
 
 /* Pinmux headers will reomove after ATF driver implementation */
 #define PINMUX_SDMMC_SEL			0x0
-#define PIN0SEL						0x00
-#define PIN1SEL						0x04
-#define PIN2SEL						0x08
-#define PIN3SEL						0x0C
-#define PIN4SEL						0x10
-#define PIN5SEL						0x14
-#define PIN6SEL						0x18
-#define PIN7SEL						0x1C
-#define PIN8SEL						0x20
-#define PIN9SEL						0x24
-#define PIN10SEL					0x28
+#define PIN0SEL					0x00
+#define PIN1SEL					0x04
+#define PIN2SEL					0x08
+#define PIN3SEL					0x0C
+#define PIN4SEL					0x10
+#define PIN5SEL					0x14
+#define PIN6SEL					0x18
+#define PIN7SEL					0x1C
+#define PIN8SEL					0x20
+#define PIN9SEL					0x24
+#define PIN10SEL				0x28
 
 /* HRS16 */
 #define SDHC_WRCMD0_DLY(x)			((x) << 0)
 #define SDHC_WRCMD1_DLY(x)			((x) << 4)
 #define SDHC_WRDATA0_DLY(x)			((x) << 8)
 #define SDHC_WRDATA1_DLY(x)			((x) << 12)
-#define SDHC_WRCMD0_SDCLK_DLY(x)	((x) << 16)
-#define SDHC_WRCMD1_SDCLK_DLY(x)	((x) << 20)
-#define SDHC_WRDATA0_SDCLK_DLY(x)	((x) << 24)
-#define SDHC_WRDATA1_SDCLK_DLY(x)	((x) << 28)
+#define SDHC_WRCMD0_SDCLK_DLY(x)		((x) << 16)
+#define SDHC_WRCMD1_SDCLK_DLY(x)		((x) << 20)
+#define SDHC_WRDATA0_SDCLK_DLY(x)		((x) << 24)
+#define SDHC_WRDATA1_SDCLK_DLY(x)		((x) << 28)
 
 /* Shared Macros */
 #define SDMMC_CDN(_reg)				(SDMMC_CDN_REG_BASE + \
 								(SDMMC_CDN_##_reg))
 
-/* Refer to atf/tools/cert_create/include/debug.h */
-#define BIT_32(nr)					(U(1) << (nr))
-
 /* MMC Peripheral Definition */
-#define SOCFPGA_MMC_BLOCK_SIZE		U(8192)
-#define SOCFPGA_MMC_BLOCK_MASK		(SOCFPGA_MMC_BLOCK_SIZE - U(1))
-#define SOCFPGA_MMC_BOOT_CLK_RATE	(400 * 1000)
+#define SOCFPGA_MMC_BLOCK_MASK			(SOCFPGA_MMC_BLOCK_SIZE - U(1))
+#define SOCFPGA_MMC_BOOT_CLK_RATE		(400 * 1000)
 #define MMC_RESPONSE_NONE			0
-#define SDHC_CDNS_SRS03_VALUE		0x01020013
+#define SDHC_CDNS_SRS03_VALUE			0x01020013
 
 /* Value randomly chosen for eMMC RCA, it should be > 1 */
-#define MMC_FIX_RCA					6
+#define MMC_FIX_RCA				6
 #define RCA_SHIFT_OFFSET			16
 
-#define CMD_EXTCSD_PARTITION_CONFIG	179
-#define CMD_EXTCSD_BUS_WIDTH		183
-#define CMD_EXTCSD_HS_TIMING		185
+#define CMD_EXTCSD_PARTITION_CONFIG		179
+#define CMD_EXTCSD_BUS_WIDTH			183
+#define CMD_EXTCSD_HS_TIMING			185
 #define CMD_EXTCSD_SEC_CNT			212
 
-#define PART_CFG_BOOT_PARTITION1_ENABLE	(U(1) << 3)
-#define PART_CFG_PARTITION1_ACCESS	(U(1) << 0)
+#define PART_CFG_BOOT_PARTITION1_ENABLE		(U(1) << 3)
+#define PART_CFG_PARTITION1_ACCESS		(U(1) << 0)
 
 /* Values in EXT CSD register */
 #define MMC_BUS_WIDTH_1				U(0)
@@ -308,8 +363,8 @@
 #define MMC_BUS_WIDTH_8				U(2)
 #define MMC_BUS_WIDTH_DDR_4			U(5)
 #define MMC_BUS_WIDTH_DDR_8			U(6)
-#define MMC_BOOT_MODE_BACKWARD		(U(0) << 3)
-#define MMC_BOOT_MODE_HS_TIMING		(U(1) << 3)
+#define MMC_BOOT_MODE_BACKWARD			(U(0) << 3)
+#define MMC_BOOT_MODE_HS_TIMING			(U(1) << 3)
 #define MMC_BOOT_MODE_DDR			(U(2) << 3)
 
 #define EXTCSD_SET_CMD				(U(0) << 24)
@@ -318,14 +373,14 @@
 #define EXTCSD_WRITE_BYTES			(U(3) << 24)
 #define EXTCSD_CMD(x)				(((x) & 0xff) << 16)
 #define EXTCSD_VALUE(x)				(((x) & 0xff) << 8)
-#define EXTCSD_CMD_SET_NORMAL		U(1)
+#define EXTCSD_CMD_SET_NORMAL			U(1)
 
-#define CSD_TRAN_SPEED_UNIT_MASK	GENMASK(2, 0)
-#define CSD_TRAN_SPEED_MULT_MASK	GENMASK(6, 3)
-#define CSD_TRAN_SPEED_MULT_SHIFT	3
+#define CSD_TRAN_SPEED_UNIT_MASK		GENMASK(2, 0)
+#define CSD_TRAN_SPEED_MULT_MASK		GENMASK(6, 3)
+#define CSD_TRAN_SPEED_MULT_SHIFT		3
 
-#define STATUS_CURRENT_STATE(x)		(((x) & 0xf) << 9)
-#define STATUS_READY_FOR_DATA		BIT(8)
+#define STATUS_CURRENT_STATE(x)			(((x) & 0xf) << 9)
+#define STATUS_READY_FOR_DATA			BIT(8)
 #define STATUS_SWITCH_ERROR			BIT(7)
 #define MMC_GET_STATE(x)			(((x) >> 9) & 0xf)
 #define MMC_STATE_IDLE				0
@@ -346,12 +401,51 @@
 #define VHS_2_7_3_6_V				BIT(8)
 
 /*ADMA table component*/
-#define ADMA_DESC_ATTR_VALID		BIT(0)
+#define ADMA_DESC_ATTR_VALID			BIT(0)
 #define ADMA_DESC_ATTR_END			BIT(1)
 #define ADMA_DESC_ATTR_INT			BIT(2)
 #define ADMA_DESC_ATTR_ACT1			BIT(4)
 #define ADMA_DESC_ATTR_ACT2			BIT(5)
-#define ADMA_DESC_TRANSFER_DATA		ADMA_DESC_ATTR_ACT2
+#define ADMA_DESC_TRANSFER_DATA			ADMA_DESC_ATTR_ACT2
+
+#define HRS_09_EXTENDED_RD_MODE			(1 << 2)
+#define HRS_09_EXTENDED_WR_MODE			(1 << 3)
+#define HRS_09_RDCMD_EN				(1 << 15)
+#define HRS_09_RDDATA_EN			(1 << 16)
+#define HRS_10_HCSDCLKADJ_VAL			(3)
+
+#define SRS11_SRFA				(1 << 24)
+#define SRS11_SRFA_CHK(x)			(x >> 24)
+#define CDNS_TIMEOUT				(5000)
+
+#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff))
+
+/* Card busy and present */
+#define CARD_BUSY				1
+#define CARD_NOT_BUSY				0
+
+/* 500 ms delay to read the RINST register */
+#define DELAY_MS_SRS_READ			500
+#define DELAY_RES				10
+
+/* Check DV dfi_init val=0 */
+#define IO_MASK_END_DATA			0x0
+
+/* Check DV dfi_init val=2; DDR Mode */
+#define IO_MASK_END_DATA_DDR			0x2
+#define IO_MASK_START_DATA			0x0
+#define DATA_SELECT_OE_END_DATA			0x1
+
+#define TIMEOUT					100000
+
+/* General define */
+#define SDHC_REG_MASK				UINT_MAX
+#define SD_HOST_BLOCK_SIZE			0x200
+#define DTCVVAL_DEFAULT_VAL			0xE
+#define CDMMC_DMA_MAX_BUFFER_SIZE		64*1024
+#define CDNSMMC_ADDRESS_MASK			U(0x0f)
+#define CONFIG_CDNS_DESC_COUNT			8
+#define SD_HOST_CLK				200000000
 
 enum sd_opcode {
 	SD_GO_IDLE_STATE = 0,
@@ -392,6 +486,16 @@ enum sd_app_cmd {
 	SD_APP_SEND_SCR = 51,
 };
 
+enum sd_opr_modes {
+	SD_HOST_OPR_MODE_HV4E_0_SDMA_32 = 0,
+	SD_HOST_OPR_MODE_HV4E_1_SDMA_32,
+	SD_HOST_OPR_MODE_HV4E_1_SDMA_64,
+	SD_HOST_OPR_MODE_HV4E_0_ADMA_32,
+	SD_HOST_OPR_MODE_HV4E_0_ADMA_64,
+	SD_HOST_OPR_MODE_HV4E_1_ADMA_32,
+	SD_HOST_OPR_MODE_HV4E_1_ADMA_64,
+};
+
 struct cdns_sdmmc_sdhc {
 	uint32_t	sdhc_extended_rd_mode;
 	uint32_t	sdhc_extended_wr_mode;
@@ -443,9 +547,6 @@ struct cdns_sdmmc_params {
 	uint32_t	combophy;
 };
 
-/* read and write API */
-size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size);
-size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size);
 
 struct cdns_idmac_desc {
 	/*8 bit attribute*/
@@ -471,4 +572,8 @@ int cdns_sd_host_init(struct cdns_sdmmc_combo_phy *mmc_combo_phy_reg,
 struct cdns_sdmmc_sdhc *mmc_sdhc_reg);
 void cdns_set_sdmmc_var(struct cdns_sdmmc_combo_phy *combo_phy_reg,
 struct cdns_sdmmc_sdhc *sdhc_reg);
+int cdns_mmc_init(struct cdns_sdmmc_params *params, struct mmc_device_info *info);
+int cdns_program_phy_reg(struct cdns_sdmmc_combo_phy *combo_phy_reg,
+				struct cdns_sdmmc_sdhc *sdhc_reg);
+void cdns_host_set_clk(uint32_t clk);
 #endif
diff --git a/include/drivers/clk.h b/include/drivers/clk.h
index a18f41ff..4db20f8e 100644
--- a/include/drivers/clk.h
+++ b/include/drivers/clk.h
@@ -13,15 +13,20 @@ struct clk_ops {
 	int (*enable)(unsigned long id);
 	void (*disable)(unsigned long id);
 	unsigned long (*get_rate)(unsigned long id);
+	int (*set_rate)(unsigned long id, unsigned long rate,
+			unsigned long *orate);
 	int (*get_parent)(unsigned long id);
+	int (*set_parent)(unsigned long id, unsigned long parent_id);
 	bool (*is_enabled)(unsigned long id);
 };
 
 int clk_enable(unsigned long id);
 void clk_disable(unsigned long id);
 unsigned long clk_get_rate(unsigned long id);
+int clk_set_rate(unsigned long id, unsigned long rate, unsigned long *orate);
 bool clk_is_enabled(unsigned long id);
 int clk_get_parent(unsigned long id);
+int clk_set_parent(unsigned long id, unsigned long parent_id);
 
 void clk_register(const struct clk_ops *ops);
 
diff --git a/include/drivers/delay_timer.h b/include/drivers/delay_timer.h
index 20a55435..e9fdfb78 100644
--- a/include/drivers/delay_timer.h
+++ b/include/drivers/delay_timer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019, Linaro Limited
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -25,27 +25,12 @@ typedef struct timer_ops {
 	uint32_t (*get_timer_value)(void);
 	uint32_t clk_mult;
 	uint32_t clk_div;
+	uint64_t (*timeout_init_us)(uint32_t usec);
+	bool (*timeout_elapsed)(uint64_t cnt);
 } timer_ops_t;
 
-static inline uint64_t timeout_cnt_us2cnt(uint32_t us)
-{
-	return ((uint64_t)us * (uint64_t)read_cntfrq_el0()) / 1000000ULL;
-}
-
-static inline uint64_t timeout_init_us(uint32_t us)
-{
-	uint64_t cnt = timeout_cnt_us2cnt(us);
-
-	cnt += read_cntpct_el0();
-
-	return cnt;
-}
-
-static inline bool timeout_elapsed(uint64_t expire_cnt)
-{
-	return read_cntpct_el0() > expire_cnt;
-}
-
+uint64_t timeout_init_us(uint32_t usec);
+bool timeout_elapsed(uint64_t cnt);
 void mdelay(uint32_t msec);
 void udelay(uint32_t usec);
 void timer_init(const timer_ops_t *ops_ptr);
diff --git a/include/drivers/fwu/fwu.h b/include/drivers/fwu/fwu.h
index 9f18e221..18e8a316 100644
--- a/include/drivers/fwu/fwu.h
+++ b/include/drivers/fwu/fwu.h
@@ -9,8 +9,15 @@
 
 #include <stdbool.h>
 
+#define FWU_BANK_STATE_ACCEPTED		0xFCU
+#define FWU_BANK_STATE_VALID		0xFEU
+#define FWU_BANK_STATE_INVALID		0xFFU
+
+#define INVALID_BOOT_IDX		0xFFFFFFFFU
+
 void fwu_init(void);
-bool fwu_is_trial_run_state(void);
+uint32_t fwu_get_active_bank_state(void);
+uint32_t fwu_get_alternate_boot_bank(void);
 const struct fwu_metadata *fwu_get_metadata(void);
 
 #endif /* FWU_H */
diff --git a/include/drivers/fwu/fwu_metadata.h b/include/drivers/fwu/fwu_metadata.h
index 2e88de5e..b441300e 100644
--- a/include/drivers/fwu/fwu_metadata.h
+++ b/include/drivers/fwu/fwu_metadata.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * FWU metadata information as per the specification section 4.1:
- * https://developer.arm.com/documentation/den0118/a/
+ * https://developer.arm.com/documentation/den0118/latest/
  *
  */
 
@@ -14,11 +14,13 @@
 #include <stdint.h>
 #include <tools_share/uuid.h>
 
+#define NR_OF_MAX_FW_BANKS	4
+
 /* Properties of image in a bank */
-struct fwu_image_properties {
+struct fwu_image_bank_info {
 
-	/* UUID of the image in this bank */
-	uuid_t img_uuid;
+	/* GUID of the image in this bank */
+	struct efi_guid img_guid;
 
 	/* [0]: bit describing the image acceptance status –
 	 *      1 means the image is accepted
@@ -34,14 +36,37 @@ struct fwu_image_properties {
 /* Image entry information */
 struct fwu_image_entry {
 
-	/* UUID identifying the image type */
-	uuid_t img_type_uuid;
+	/* GUID identifying the image type */
+	struct efi_guid img_type_guid;
 
-	/* UUID of the storage volume where the image is located */
-	uuid_t location_uuid;
+	/* GUID of the storage volume where the image is located */
+	struct efi_guid location_guid;
 
-	/* Properties of images with img_type_uuid in the different FW banks */
-	struct fwu_image_properties img_props[NR_OF_FW_BANKS];
+	/* Properties of images with img_type_guid in the different FW banks */
+	struct fwu_image_bank_info img_bank_info[NR_OF_FW_BANKS];
+
+} __packed;
+
+/* Firmware Image descriptor */
+struct fwu_fw_store_descriptor {
+
+	/* Number of Banks */
+	uint8_t num_banks;
+
+	/* Reserved */
+	uint8_t reserved;
+
+	/* Number of images per bank */
+	uint16_t num_images;
+
+	/* Size of image_entry(all banks) in bytes */
+	uint16_t img_entry_size;
+
+	/* Size of image bank info structure in bytes */
+	uint16_t bank_info_entry_size;
+
+	/* Array of fwu_image_entry structs */
+	struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK];
 
 } __packed;
 
@@ -66,8 +91,25 @@ struct fwu_metadata {
 	/* Previous bank index with which device booted successfully */
 	uint32_t previous_active_index;
 
+	/* Size of the entire metadata in bytes */
+	uint32_t metadata_size;
+
+	/* Offset of the image descriptor structure */
+	uint16_t desc_offset;
+
+	/* Reserved */
+	uint16_t reserved1;
+
+	/* Bank state */
+	uint8_t bank_state[NR_OF_MAX_FW_BANKS];
+
+	/* Reserved */
+	uint32_t reserved2;
+
+#if PSA_FWU_METADATA_FW_STORE_DESC
 	/* Image entry information */
-	struct fwu_image_entry img_entry[NR_OF_IMAGES_IN_FW_BANK];
+	struct fwu_fw_store_descriptor fw_desc;
+#endif
 
 } __packed;
 
diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h
index 794d6133..b44526aa 100644
--- a/include/drivers/measured_boot/event_log/event_log.h
+++ b/include/drivers/measured_boot/event_log/event_log.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,51 +43,6 @@
 
 #define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
 
-/*
- * Each event log entry has some metadata (i.e. a string) that identifies
- * what is measured.These macros define these strings.
- * Note that these strings follow the standardization recommendations
- * defined in the Arm Server Base Security Guide (a.k.a. SBSG, Arm DEN 0086),
- * where applicable. They should not be changed in the code.
- * Where the SBSG does not make recommendations, we are free to choose any
- * naming convention.
- * The key thing is to choose meaningful strings so that when the TPM event
- * log is used in attestation, the different components can be identified.
- */
-#define EVLOG_BL2_STRING		"BL_2"
-#define EVLOG_BL31_STRING		"SECURE_RT_EL3"
-#if defined(SPD_opteed)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_OPTEE"
-#elif defined(SPD_tspd)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_TSPD"
-#elif defined(SPD_tlkd)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_TLKD"
-#elif defined(SPD_trusty)
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_TRUSTY"
-#else
-#define EVLOG_BL32_STRING		"SECURE_RT_EL1_UNKNOWN"
-#endif
-#define	EVLOG_BL32_EXTRA1_STRING	"SECURE_RT_EL1_OPTEE_EXTRA1"
-#define	EVLOG_BL32_EXTRA2_STRING	"SECURE_RT_EL1_OPTEE_EXTRA2"
-#define EVLOG_BL33_STRING		"BL_33"
-#define EVLOG_FW_CONFIG_STRING		"FW_CONFIG"
-#define EVLOG_HW_CONFIG_STRING		"HW_CONFIG"
-#define EVLOG_NT_FW_CONFIG_STRING	"NT_FW_CONFIG"
-#define EVLOG_SCP_BL2_STRING		"SYS_CTRL_2"
-#define EVLOG_SOC_FW_CONFIG_STRING	"SOC_FW_CONFIG"
-#define EVLOG_STM32_STRING		"STM32"
-#define EVLOG_TB_FW_CONFIG_STRING	"TB_FW_CONFIG"
-#define	EVLOG_TOS_FW_CONFIG_STRING	"TOS_FW_CONFIG"
-#define EVLOG_RMM_STRING 		"RMM"
-#define EVLOG_SP1_STRING		"SP1"
-#define EVLOG_SP2_STRING		"SP2"
-#define EVLOG_SP3_STRING		"SP3"
-#define EVLOG_SP4_STRING		"SP4"
-#define EVLOG_SP5_STRING		"SP5"
-#define EVLOG_SP6_STRING		"SP6"
-#define EVLOG_SP7_STRING		"SP7"
-#define EVLOG_SP8_STRING		"SP8"
-
 typedef struct {
 	unsigned int id;
 	const char *name;
diff --git a/include/drivers/measured_boot/event_log/tcg.h b/include/drivers/measured_boot/event_log/tcg.h
index 4ac2c2ff..653f9c27 100644
--- a/include/drivers/measured_boot/event_log/tcg.h
+++ b/include/drivers/measured_boot/event_log/tcg.h
@@ -8,6 +8,7 @@
 #define TCG_H
 
 #include <stdint.h>
+#include <common/sha_common_macros.h>
 
 #define TCG_ID_EVENT_SIGNATURE_03	"Spec ID Event03"
 #define TCG_STARTUP_LOCALITY_SIGNATURE	"StartupLocality"
@@ -66,12 +67,6 @@
 #define PLATFORM_CLASS_CLIENT   0
 #define PLATFORM_CLASS_SERVER   1
 
-/* SHA digest sizes in bytes */
-#define SHA1_DIGEST_SIZE	20
-#define SHA256_DIGEST_SIZE	32
-#define SHA384_DIGEST_SIZE	48
-#define SHA512_DIGEST_SIZE	64
-
 enum {
 	/*
 	 * SRTM, BIOS, Host Platform Extensions, Embedded
diff --git a/include/drivers/measured_boot/metadata.h b/include/drivers/measured_boot/metadata.h
new file mode 100644
index 00000000..5e17a835
--- /dev/null
+++ b/include/drivers/measured_boot/metadata.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef METADATA_H
+#define METADATA_H
+
+/* Minimum measurement value size that can be requested to store */
+#define MEASUREMENT_VALUE_MIN_SIZE	32U
+/* Maximum measurement value size that can be requested to store */
+#define MEASUREMENT_VALUE_MAX_SIZE	64U
+/* Minimum signer id size that can be requested to store */
+#define SIGNER_ID_MIN_SIZE		MEASUREMENT_VALUE_MIN_SIZE
+/* Maximum signer id size that can be requested to store */
+#define SIGNER_ID_MAX_SIZE		MEASUREMENT_VALUE_MAX_SIZE
+/* The theoretical maximum image version is: "255.255.65535\0" */
+#define VERSION_MAX_SIZE		14U
+/* Example sw_type: "BL_2, BL_33, etc." */
+#define SW_TYPE_MAX_SIZE		32U
+
+/*
+ * Images, measured during the boot process, have some associated metadata.
+ * One of these types of metadata is the image identifier strings. These macros
+ * define these strings. They are used across the different measured boot
+ * backends.
+ * Note that these strings follow the standardization recommendations
+ * defined in the Arm Server Base Security Guide (a.k.a. SBSG, Arm DEN 0086),
+ * where applicable. They should not be changed in the code.
+ * Where the SBSG does not make recommendations, we are free to choose any
+ * naming convention.
+ * The key thing is to choose meaningful strings so that when the measured boot
+ * metadata is used in attestation, the different components can be identified.
+ */
+#define MBOOT_BL2_IMAGE_STRING		"BL_2"
+#define MBOOT_BL31_IMAGE_STRING		"SECURE_RT_EL3"
+#if defined(SPD_opteed)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_OPTEE"
+#elif defined(SPD_tspd)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_TSPD"
+#elif defined(SPD_tlkd)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_TLKD"
+#elif defined(SPD_trusty)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_TRUSTY"
+#elif defined(SPD_spmd)
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_SPMD"
+#else
+#define MBOOT_BL32_IMAGE_STRING		"SECURE_RT_EL1_UNKNOWN"
+#endif /* SPD_opteed */
+#define MBOOT_BL32_EXTRA1_IMAGE_STRING	"SECURE_RT_EL1_OPTEE_EXTRA1"
+#define MBOOT_BL32_EXTRA2_IMAGE_STRING	"SECURE_RT_EL1_OPTEE_EXTRA2"
+#define MBOOT_BL33_IMAGE_STRING		"BL_33"
+#define MBOOT_FW_CONFIG_STRING		"FW_CONFIG"
+#define MBOOT_HW_CONFIG_STRING		"HW_CONFIG"
+#define MBOOT_NT_FW_CONFIG_STRING	"NT_FW_CONFIG"
+#define MBOOT_SCP_BL2_IMAGE_STRING	"SYS_CTRL_2"
+#define MBOOT_SOC_FW_CONFIG_STRING	"SOC_FW_CONFIG"
+#define MBOOT_STM32_STRING		"STM32"
+#define MBOOT_TB_FW_CONFIG_STRING	"TB_FW_CONFIG"
+#define MBOOT_TOS_FW_CONFIG_STRING	"TOS_FW_CONFIG"
+#define MBOOT_RMM_IMAGE_STRING		"RMM"
+#define MBOOT_SP1_STRING		"SP1"
+#define MBOOT_SP2_STRING		"SP2"
+#define MBOOT_SP3_STRING		"SP3"
+#define MBOOT_SP4_STRING		"SP4"
+#define MBOOT_SP5_STRING		"SP5"
+#define MBOOT_SP6_STRING		"SP6"
+#define MBOOT_SP7_STRING		"SP7"
+#define MBOOT_SP8_STRING		"SP8"
+
+#endif /* METADATA_H */
diff --git a/include/drivers/measured_boot/rse/dice_prot_env.h b/include/drivers/measured_boot/rse/dice_prot_env.h
new file mode 100644
index 00000000..e5aef516
--- /dev/null
+++ b/include/drivers/measured_boot/rse/dice_prot_env.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DICE_PROT_ENV_H
+#define DICE_PROT_ENV_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <drivers/measured_boot/metadata.h>
+
+#define DPE_INVALID_ID	UINT32_MAX
+
+struct dpe_metadata {
+	unsigned int id;
+	uint32_t cert_id;
+	uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+	size_t  signer_id_size;
+	uint8_t version[VERSION_MAX_SIZE];
+	size_t  version_size;
+	uint8_t sw_type[SW_TYPE_MAX_SIZE];
+	size_t  sw_type_size;
+	bool allow_new_context_to_derive;
+	bool retain_parent_context;
+	bool create_certificate;
+	int target_locality;
+	void *pk_oid;
+};
+
+void dpe_init(struct dpe_metadata *metadata);
+
+/* Returns 0 in case of success otherwise -1. */
+int dpe_measure_and_record(struct dpe_metadata *metadata,
+			   uintptr_t data_base, uint32_t data_size,
+			   uint32_t data_id);
+
+int dpe_set_signer_id(struct dpe_metadata *metadata,
+		      const void *pk_oid, const void *pk_ptr, size_t pk_len);
+
+/* Child components inherit their first valid context handle from their parents.
+ * How to share context handle is platform specific.
+ */
+void plat_dpe_share_context_handle(int *ctx_handle, int *parent_ctx_handle);
+void plat_dpe_get_context_handle(int *ctx_handle);
+
+#endif /* DICE_PROT_ENV_H */
diff --git a/include/drivers/measured_boot/rse/rse_measured_boot.h b/include/drivers/measured_boot/rse/rse_measured_boot.h
new file mode 100644
index 00000000..2f605d71
--- /dev/null
+++ b/include/drivers/measured_boot/rse/rse_measured_boot.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RSE_MEASURED_BOOT_H
+#define RSE_MEASURED_BOOT_H
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/measured_boot/metadata.h>
+
+#define RSE_MBOOT_INVALID_ID	UINT32_MAX
+
+struct rse_mboot_metadata {
+	unsigned int id;
+	uint8_t slot;
+	uint8_t signer_id[SIGNER_ID_MAX_SIZE];
+	size_t  signer_id_size;
+	uint8_t version[VERSION_MAX_SIZE];
+	size_t  version_size;
+	uint8_t sw_type[SW_TYPE_MAX_SIZE];
+	size_t  sw_type_size;
+	void    *pk_oid;
+	bool    lock_measurement;
+};
+
+/* Functions' declarations */
+void rse_measured_boot_init(struct rse_mboot_metadata *metadata_ptr);
+int rse_mboot_measure_and_record(struct rse_mboot_metadata *metadata_ptr,
+				 uintptr_t data_base, uint32_t data_size,
+				 uint32_t data_id);
+
+int rse_mboot_set_signer_id(struct rse_mboot_metadata *metadata_ptr,
+			    const void *pk_oid, const void *pk_ptr,
+			    size_t pk_len);
+
+#endif /* RSE_MEASURED_BOOT_H */
diff --git a/include/drivers/measured_boot/rss/rss_measured_boot.h b/include/drivers/measured_boot/rss/rss_measured_boot.h
deleted file mode 100644
index 7ab517c1..00000000
--- a/include/drivers/measured_boot/rss/rss_measured_boot.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef RSS_MEASURED_BOOT_H
-#define RSS_MEASURED_BOOT_H
-
-#include <stdint.h>
-
-#include <common/debug.h>
-#include <measured_boot.h>
-
-#define RSS_MBOOT_INVALID_ID	UINT32_MAX
-
-/*
- * Each boot measurement has some metadata (i.e. a string) that identifies
- * what was measured and how. The sw_type field of the rss_mboot_metadata
- * structure represents the role of the software component that was measured.
- * The below macros define strings suitable for the sw_type.
- * The key thing is to choose meaningful strings so that when the attestation
- * token is verified, then the different components can be identified.
- */
-#define RSS_MBOOT_BL2_STRING		"BL_2"
-#define RSS_MBOOT_BL31_STRING		"SECURE_RT_EL3"
-#define RSS_MBOOT_HW_CONFIG_STRING	"HW_CONFIG"
-#define RSS_MBOOT_FW_CONFIG_STRING	"FW_CONFIG"
-#define RSS_MBOOT_TB_FW_CONFIG_STRING	"TB_FW_CONFIG"
-#define RSS_MBOOT_SOC_FW_CONFIG_STRING	"SOC_FW_CONFIG"
-#define RSS_MBOOT_RMM_STRING		"RMM"
-
-
-struct rss_mboot_metadata {
-	unsigned int id;
-	uint8_t slot;
-	uint8_t signer_id[SIGNER_ID_MAX_SIZE];
-	size_t  signer_id_size;
-	uint8_t version[VERSION_MAX_SIZE];
-	size_t  version_size;
-	uint8_t sw_type[SW_TYPE_MAX_SIZE];
-	size_t  sw_type_size;
-	void    *pk_oid;
-	bool    lock_measurement;
-};
-
-/* Functions' declarations */
-void rss_measured_boot_init(struct rss_mboot_metadata *metadata_ptr);
-int rss_mboot_measure_and_record(struct rss_mboot_metadata *metadata_ptr,
-				 uintptr_t data_base, uint32_t data_size,
-				 uint32_t data_id);
-
-int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
-			    const void *pk_oid, const void *pk_ptr,
-			    size_t pk_len);
-
-#endif /* RSS_MEASURED_BOOT_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
new file mode 100644
index 00000000..d879f5be
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef S32CC_CLK_DRV_H
+#define S32CC_CLK_DRV_H
+
+int s32cc_init_early_clks(void);
+
+#endif
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
new file mode 100644
index 00000000..d34dc22f
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-ids.h
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2024 NXP
+ */
+#ifndef S32CC_CLK_IDS_H
+#define S32CC_CLK_IDS_H
+
+#include <stdint.h>
+#include <lib/utils_def.h>
+
+/**
+ * Clock ID encoding:
+ *     31:30 bits = Type of the clock
+ *     29:0  bits = Clock ID within the clock category
+ */
+#define S32CC_CLK_ID_MASK	GENMASK_64(29U, 0U)
+#define S32CC_CLK_TYPE_MASK	GENMASK_64(31U, 30U)
+#define S32CC_CLK_ID(ID)	(((unsigned long)(ID)) & S32CC_CLK_ID_MASK)
+#define S32CC_CLK_TYPE(ID)	(((unsigned long)(ID)) & S32CC_CLK_TYPE_MASK)
+#define S32CC_CLK(TAG, ID)	(S32CC_CLK_ID(ID) | (S32CC_CLK_TYPE((TAG) << 30U)))
+#define S32CC_HW_CLK(ID)	S32CC_CLK(0UL, U(ID))
+#define S32CC_SW_CLK(SUB, ID)	S32CC_CLK(2UL | ((SUB) & 1UL), U(ID))
+
+/* SW clocks subcategories */
+#define S32CC_ARCH_CLK(ID)	S32CC_SW_CLK(0UL, ID)
+#define S32CC_PLAT_CLK(ID)	S32CC_SW_CLK(1UL, ID)
+
+/* IDs for clock selectors listed in S32CC Reference Manuals  */
+#define S32CC_CLK_FIRC				S32CC_HW_CLK(0)
+#define S32CC_CLK_SIRC				S32CC_HW_CLK(1)
+#define S32CC_CLK_FXOSC				S32CC_HW_CLK(2)
+#define S32CC_CLK_ARM_PLL_PHI0			S32CC_HW_CLK(4)
+#define S32CC_CLK_ARM_PLL_PHI1			S32CC_HW_CLK(5)
+#define S32CC_CLK_ARM_PLL_PHI2			S32CC_HW_CLK(6)
+#define S32CC_CLK_ARM_PLL_PHI3			S32CC_HW_CLK(7)
+#define S32CC_CLK_ARM_PLL_PHI4			S32CC_HW_CLK(8)
+#define S32CC_CLK_ARM_PLL_PHI5			S32CC_HW_CLK(9)
+#define S32CC_CLK_ARM_PLL_PHI6			S32CC_HW_CLK(10)
+#define S32CC_CLK_ARM_PLL_PHI7			S32CC_HW_CLK(11)
+#define S32CC_CLK_ARM_PLL_DFS1			S32CC_HW_CLK(12)
+#define S32CC_CLK_ARM_PLL_DFS2			S32CC_HW_CLK(13)
+#define S32CC_CLK_ARM_PLL_DFS3			S32CC_HW_CLK(14)
+#define S32CC_CLK_ARM_PLL_DFS4			S32CC_HW_CLK(15)
+#define S32CC_CLK_ARM_PLL_DFS5			S32CC_HW_CLK(16)
+#define S32CC_CLK_ARM_PLL_DFS6			S32CC_HW_CLK(17)
+#define S32CC_CLK_PERIPH_PLL_PHI0		S32CC_HW_CLK(18)
+#define S32CC_CLK_PERIPH_PLL_PHI1		S32CC_HW_CLK(19)
+#define S32CC_CLK_PERIPH_PLL_PHI2		S32CC_HW_CLK(20)
+#define S32CC_CLK_PERIPH_PLL_PHI3		S32CC_HW_CLK(21)
+#define S32CC_CLK_PERIPH_PLL_PHI4		S32CC_HW_CLK(22)
+#define S32CC_CLK_PERIPH_PLL_PHI5		S32CC_HW_CLK(23)
+#define S32CC_CLK_PERIPH_PLL_PHI6		S32CC_HW_CLK(24)
+#define S32CC_CLK_PERIPH_PLL_PHI7		S32CC_HW_CLK(25)
+#define S32CC_CLK_PERIPH_PLL_DFS1		S32CC_HW_CLK(26)
+#define S32CC_CLK_PERIPH_PLL_DFS2		S32CC_HW_CLK(27)
+#define S32CC_CLK_PERIPH_PLL_DFS3		S32CC_HW_CLK(28)
+#define S32CC_CLK_PERIPH_PLL_DFS4		S32CC_HW_CLK(29)
+#define S32CC_CLK_PERIPH_PLL_DFS5		S32CC_HW_CLK(30)
+#define S32CC_CLK_PERIPH_PLL_DFS6		S32CC_HW_CLK(31)
+#define S32CC_CLK_FTM0_EXT_REF			S32CC_HW_CLK(34)
+#define S32CC_CLK_FTM1_EXT_REF			S32CC_HW_CLK(35)
+#define S32CC_CLK_DDR_PLL_PHI0			S32CC_HW_CLK(36)
+#define S32CC_CLK_GMAC0_EXT_TX			S32CC_HW_CLK(37)
+#define S32CC_CLK_GMAC0_EXT_RX			S32CC_HW_CLK(38)
+#define S32CC_CLK_GMAC0_EXT_REF			S32CC_HW_CLK(39)
+#define S32CC_CLK_SERDES0_LANE0_TX		S32CC_HW_CLK(40)
+#define S32CC_CLK_SERDES0_LANE0_CDR		S32CC_HW_CLK(41)
+#define S32CC_CLK_GMAC0_EXT_TS			S32CC_HW_CLK(44)
+#define S32CC_CLK_GMAC0_REF_DIV			S32CC_HW_CLK(45)
+
+/* Software defined clock IDs */
+#define S32CC_CLK_ARM_PLL_MUX			S32CC_ARCH_CLK(0)
+#define S32CC_CLK_ARM_PLL_VCO			S32CC_ARCH_CLK(1)
+
+/* ARM CGM1 clocks */
+#define S32CC_CLK_MC_CGM1_MUX0			S32CC_ARCH_CLK(2)
+#define S32CC_CLK_A53_CORE			S32CC_ARCH_CLK(3)
+#define S32CC_CLK_A53_CORE_DIV2			S32CC_ARCH_CLK(4)
+#define S32CC_CLK_A53_CORE_DIV10		S32CC_ARCH_CLK(5)
+
+/* XBAR clock*/
+#define S32CC_CLK_MC_CGM0_MUX0			S32CC_ARCH_CLK(6)
+#define S32CC_CLK_XBAR_2X			S32CC_ARCH_CLK(7)
+#define S32CC_CLK_XBAR				S32CC_ARCH_CLK(8)
+#define S32CC_CLK_XBAR_DIV2			S32CC_ARCH_CLK(9)
+#define S32CC_CLK_XBAR_DIV3			S32CC_ARCH_CLK(10)
+#define S32CC_CLK_XBAR_DIV4			S32CC_ARCH_CLK(11)
+#define S32CC_CLK_XBAR_DIV6			S32CC_ARCH_CLK(12)
+
+/* Periph PLL */
+#define S32CC_CLK_PERIPH_PLL_MUX		S32CC_ARCH_CLK(13)
+#define S32CC_CLK_PERIPH_PLL_VCO		S32CC_ARCH_CLK(14)
+
+#define S32CC_CLK_MC_CGM0_MUX8			S32CC_ARCH_CLK(15)
+#define S32CC_CLK_LINFLEX_BAUD			S32CC_ARCH_CLK(16)
+#define S32CC_CLK_LINFLEX			S32CC_ARCH_CLK(17)
+
+/* DDR PLL */
+#define S32CC_CLK_DDR_PLL_MUX			S32CC_ARCH_CLK(18)
+#define S32CC_CLK_DDR_PLL_VCO			S32CC_ARCH_CLK(19)
+
+/* DDR clock */
+#define S32CC_CLK_MC_CGM5_MUX0			S32CC_ARCH_CLK(20)
+#define S32CC_CLK_DDR				S32CC_ARCH_CLK(21)
+
+#endif /* S32CC_CLK_IDS_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
new file mode 100644
index 00000000..4837f795
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h
@@ -0,0 +1,398 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2020-2024 NXP
+ */
+#ifndef S32CC_CLK_MODULES_H
+#define S32CC_CLK_MODULES_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#define MHZ	UL(1000000)
+#define GHZ	(UL(1000) * MHZ)
+
+enum s32cc_clkm_type {
+	s32cc_osc_t,
+	s32cc_clk_t,
+	s32cc_pll_t,
+	s32cc_pll_out_div_t,
+	s32cc_dfs_t,
+	s32cc_dfs_div_t,
+	s32cc_clkmux_t,
+	s32cc_shared_clkmux_t,
+	s32cc_fixed_div_t,
+	s32cc_part_t,
+	s32cc_part_block_t,
+	s32cc_part_block_link_t,
+};
+
+enum s32cc_clk_source {
+	S32CC_FIRC,
+	S32CC_FXOSC,
+	S32CC_SIRC,
+	S32CC_ARM_PLL,
+	S32CC_ARM_DFS,
+	S32CC_PERIPH_PLL,
+	S32CC_CGM0,
+	S32CC_CGM1,
+	S32CC_DDR_PLL,
+	S32CC_CGM5,
+};
+
+struct s32cc_clk_obj {
+	enum s32cc_clkm_type type;
+	uint32_t refcount;
+};
+
+struct s32cc_osc {
+	struct s32cc_clk_obj desc;
+	enum s32cc_clk_source source;
+	unsigned long freq;
+	void *base;
+};
+
+#define S32CC_OSC_INIT(SOURCE)       \
+{                                    \
+	.desc = {                    \
+		.type = s32cc_osc_t, \
+	},                           \
+	.source = (SOURCE),          \
+}
+
+struct s32cc_clkmux {
+	struct s32cc_clk_obj desc;
+	enum s32cc_clk_source module;
+	uint8_t index; /* Mux index in parent module */
+	unsigned long source_id; /* Selected source */
+	uint8_t nclks; /* Number of input clocks */
+	unsigned long clkids[5]; /* IDs of the input clocks */
+};
+
+#define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
+{                                                               \
+	.desc = {                                               \
+		.type = (TYPE),                                 \
+	},                                                      \
+	.module = (MODULE),                                     \
+	.index = (INDEX),                                       \
+	.nclks = (NCLKS),                                       \
+	.clkids = {__VA_ARGS__},                                \
+}
+
+#define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)     \
+	S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE,   \
+			       INDEX, NCLKS, __VA_ARGS__)
+
+#define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
+	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
+			       INDEX, NCLKS, __VA_ARGS__)
+
+struct s32cc_pll {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *source;
+	enum s32cc_clk_source instance;
+	unsigned long vco_freq;
+	uint32_t ndividers;
+	uintptr_t base;
+};
+
+#define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
+{                                                        \
+	.desc = {                                        \
+		.type = s32cc_pll_t,                     \
+	},                                               \
+	.source = &(PLL_MUX_CLK).desc,                   \
+	.instance = (INSTANCE),                          \
+	.ndividers = (NDIVIDERS),                        \
+}
+
+struct s32cc_pll_out_div {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	uint32_t index;
+	unsigned long freq;
+};
+
+#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
+{                                              \
+	.desc = {                              \
+		.type = s32cc_pll_out_div_t,   \
+	},                                     \
+	.parent = &(PARENT).desc,              \
+	.index = (INDEX),                      \
+}
+
+#define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
+{                                              \
+	.desc = {                              \
+		.type = s32cc_pll_out_div_t,   \
+	},                                     \
+	.parent = &(PARENT).desc,              \
+	.index = (INDEX),                      \
+}
+
+struct s32cc_dfs {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	enum s32cc_clk_source instance;
+	uintptr_t base;
+};
+
+#define S32CC_DFS_INIT(PARENT, INSTANCE) \
+{                                        \
+	.desc = {                        \
+		.type = s32cc_dfs_t,     \
+	},                               \
+	.parent = &(PARENT).desc,        \
+	.instance = (INSTANCE),          \
+}
+
+struct s32cc_dfs_div {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	uint32_t index;
+	unsigned long freq;
+};
+
+#define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
+{                                         \
+	.desc = {                         \
+		.type = s32cc_dfs_div_t,  \
+	},                                \
+	.parent = &(PARENT).desc,         \
+	.index = (INDEX),                 \
+}
+
+struct s32cc_fixed_div {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	uint32_t rate_div;
+};
+
+#define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
+{                                              \
+	.desc = {                              \
+		.type = s32cc_fixed_div_t,     \
+	},                                     \
+	.parent = &(PARENT).desc,              \
+	.rate_div = (RATE_DIV),                \
+}
+
+struct s32cc_clk {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *module;
+	struct s32cc_clk *pclock;
+	unsigned long min_freq;
+	unsigned long max_freq;
+};
+
+struct s32cc_clk_array {
+	unsigned long type_mask;
+	struct s32cc_clk **clks;
+	size_t n_clks;
+};
+
+#define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
+{                                                           \
+	.desc = {                                           \
+		.type = s32cc_clk_t,                        \
+	},                                                  \
+	.pclock = (PARENT),                                 \
+	.module = (PARENT_MODULE),                          \
+	.min_freq = (MIN_F),                                \
+	.max_freq = (MAX_F),                                \
+}
+
+#define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
+	S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
+
+#define S32CC_MODULE_CLK(PARENT_MODULE) \
+	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
+
+#define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
+	S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
+
+struct s32cc_part {
+	struct s32cc_clk_obj desc;
+	uint32_t partition_id;
+};
+
+#define S32CC_PART(PART_NUM)          \
+{                                     \
+	.desc = {                     \
+		.type = s32cc_part_t, \
+	},                            \
+	.partition_id = (PART_NUM),   \
+}
+
+enum s32cc_part_block_type {
+	s32cc_part_block0,
+	s32cc_part_block1,
+	s32cc_part_block2,
+	s32cc_part_block3,
+	s32cc_part_block4,
+	s32cc_part_block5,
+	s32cc_part_block6,
+	s32cc_part_block7,
+	s32cc_part_block8,
+	s32cc_part_block9,
+	s32cc_part_block10,
+	s32cc_part_block11,
+	s32cc_part_block12,
+	s32cc_part_block13,
+	s32cc_part_block14,
+	s32cc_part_block15,
+};
+
+struct s32cc_part_block {
+	struct s32cc_clk_obj desc;
+	struct s32cc_part *part;
+	enum s32cc_part_block_type block;
+	bool status;
+};
+
+#define S32CC_PART_BLOCK_STATUS(PART_META, BLOCK_TYPE, STATUS) \
+{                                                              \
+	.desc = {                                              \
+		.type = s32cc_part_block_t,                    \
+	},                                                     \
+	.part = (PART_META),                                   \
+	.block = (BLOCK_TYPE),                                 \
+	.status = (STATUS),                                    \
+}
+
+#define S32CC_PART_BLOCK(PARENT, BLOCK_TYPE) \
+	S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, true)
+
+#define S32CC_PART_BLOCK_NO_STATUS(PARENT, BLOCK_TYPE) \
+	S32CC_PART_BLOCK_STATUS(PARENT, BLOCK_TYPE, false)
+
+struct s32cc_part_block_link {
+	struct s32cc_clk_obj desc;
+	struct s32cc_clk_obj *parent;
+	struct s32cc_part_block *block;
+};
+
+#define S32CC_PART_BLOCK_LINK(PARENT, BLOCK)     \
+{                                                \
+	.desc = {                                \
+		.type = s32cc_part_block_link_t, \
+	},                                       \
+	.parent = &(PARENT).desc,                \
+	.block = (BLOCK),                        \
+}
+
+static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t osc_addr;
+
+	osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
+	return (struct s32cc_osc *)osc_addr;
+}
+
+static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t clk_addr;
+
+	clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
+	return (struct s32cc_clk *)clk_addr;
+}
+
+static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
+{
+	const struct s32cc_clk_obj *module;
+
+	module = clk->module;
+	if (module == NULL) {
+		return false;
+	}
+
+	return (module->type == s32cc_clkmux_t) ||
+	    (module->type == s32cc_shared_clkmux_t);
+}
+
+static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t cmux_addr;
+
+	cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
+	return (struct s32cc_clkmux *)cmux_addr;
+}
+
+static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
+{
+	if (!is_s32cc_clk_mux(clk)) {
+		return NULL;
+	}
+
+	return s32cc_obj2clkmux(clk->module);
+}
+
+static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t pll_addr;
+
+	pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
+	return (struct s32cc_pll *)pll_addr;
+}
+
+static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t plldiv_addr;
+
+	plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
+	return (struct s32cc_pll_out_div *)plldiv_addr;
+}
+
+static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t fdiv_addr;
+
+	fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
+	return (struct s32cc_fixed_div *)fdiv_addr;
+}
+
+static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t dfs_addr;
+
+	dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
+	return (struct s32cc_dfs *)dfs_addr;
+}
+
+static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t dfs_div_addr;
+
+	dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
+	return (struct s32cc_dfs_div *)dfs_div_addr;
+}
+
+static inline struct s32cc_part *s32cc_obj2part(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t part_addr;
+
+	part_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part, desc);
+	return (struct s32cc_part *)part_addr;
+}
+
+static inline struct s32cc_part_block *
+s32cc_obj2partblock(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t part_blk_addr;
+
+	part_blk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_part_block, desc);
+	return (struct s32cc_part_block *)part_blk_addr;
+}
+
+static inline struct s32cc_part_block_link *
+s32cc_obj2partblocklink(const struct s32cc_clk_obj *mod)
+{
+	uintptr_t blk_link;
+
+	blk_link = ((uintptr_t)mod) - offsetof(struct s32cc_part_block_link, desc);
+	return (struct s32cc_part_block_link *)blk_link;
+}
+
+#endif /* S32CC_CLK_MODULES_H */
diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
new file mode 100644
index 00000000..e6adeccd
--- /dev/null
+++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright 2024 NXP
+ */
+#ifndef S32CC_CLK_UTILS_H
+#define S32CC_CLK_UTILS_H
+
+#include <s32cc-clk-modules.h>
+
+struct s32cc_clk *s32cc_get_clk_from_table(const struct s32cc_clk_array *const *clk_arr,
+					   size_t size,
+					   unsigned long clk_id);
+
+int s32cc_get_id_from_table(const struct s32cc_clk_array *const *clk_arr,
+			    size_t size, const struct s32cc_clk *clk,
+			    unsigned long *clk_index);
+
+struct s32cc_clk *s32cc_get_arch_clk(unsigned long id);
+int s32cc_get_clk_id(const struct s32cc_clk *clk, unsigned long *id);
+
+void s32cc_clk_register_drv(void);
+
+#endif /* S32CC_CLK_UTILS_H */
diff --git a/include/drivers/nxp/console/linflex.h b/include/drivers/nxp/console/linflex.h
new file mode 100644
index 00000000..2b4e0d71
--- /dev/null
+++ b/include/drivers/nxp/console/linflex.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef LINFLEX_H
+#define LINFLEX_H
+
+#ifndef __ASSEMBLER__
+#include <drivers/console.h>
+
+int console_linflex_core_init(uintptr_t baseaddr, uint32_t clock,
+			      uint32_t baud);
+int console_linflex_register(uintptr_t baseaddr, uint32_t clock,
+			     uint32_t baud, console_t *console);
+#endif
+
+#endif /* LINFLEX_H */
diff --git a/include/drivers/nxp/crypto/caam/hash.h b/include/drivers/nxp/crypto/caam/hash.h
index 9136dca2..6201d232 100644
--- a/include/drivers/nxp/crypto/caam/hash.h
+++ b/include/drivers/nxp/crypto/caam/hash.h
@@ -9,6 +9,7 @@
 #define __HASH_H__
 
 #include <stdbool.h>
+#include <common/sha_common_macros.h>
 
 /* List of hash algorithms */
 enum hash_algo {
@@ -16,9 +17,6 @@ enum hash_algo {
 	SHA256
 };
 
-/* number of bytes in the SHA256-256 digest */
-#define SHA256_DIGEST_SIZE 32
-
 /*
  * number of words in the digest - Digest is kept internally
  * as 8 32-bit words
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
index d567d4cb..9e22d34c 100644
--- a/include/drivers/partition/partition.h
+++ b/include/drivers/partition/partition.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,13 +41,15 @@ typedef struct partition_entry {
 
 typedef struct partition_entry_list {
 	partition_entry_t	list[PLAT_PARTITION_MAX_ENTRIES];
-	int			entry_count;
+	unsigned int		entry_count;
 } partition_entry_list_t;
 
 int load_partition_table(unsigned int image_id);
 const partition_entry_t *get_partition_entry(const char *name);
-const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_guid);
-const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid);
+const partition_entry_t *get_partition_entry_by_type(
+	const struct efi_guid *type_guid);
+const partition_entry_t *get_partition_entry_by_guid(
+	const struct efi_guid *part_guid);
 const partition_entry_list_t *get_partition_entry_list(void);
 void partition_init(unsigned int image_id);
 int gpt_partition_init(void);
diff --git a/include/drivers/rpi3/mailbox/rpi3_mbox.h b/include/drivers/rpi3/mailbox/rpi3_mbox.h
index c1074402..33458e38 100644
--- a/include/drivers/rpi3/mailbox/rpi3_mbox.h
+++ b/include/drivers/rpi3/mailbox/rpi3_mbox.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,22 @@ typedef struct __packed __aligned(16) rpi3_mbox_request {
 	uint32_t	tags[0];
 } rpi3_mbox_request_t;
 
+/* VideoCore -> ARM */
+#define RPI3_MBOX0_READ_OFFSET		ULL(0x00000000)
+#define RPI3_MBOX0_PEEK_OFFSET		ULL(0x00000010)
+#define RPI3_MBOX0_SENDER_OFFSET	ULL(0x00000014)
+#define RPI3_MBOX0_STATUS_OFFSET	ULL(0x00000018)
+#define RPI3_MBOX0_CONFIG_OFFSET	ULL(0x0000001C)
+/* ARM -> VideoCore */
+#define RPI3_MBOX1_WRITE_OFFSET		ULL(0x00000020)
+#define RPI3_MBOX1_PEEK_OFFSET		ULL(0x00000030)
+#define RPI3_MBOX1_SENDER_OFFSET	ULL(0x00000034)
+#define RPI3_MBOX1_STATUS_OFFSET	ULL(0x00000038)
+#define RPI3_MBOX1_CONFIG_OFFSET	ULL(0x0000003C)
+/* Mailbox status constants */
+#define RPI3_MBOX_STATUS_FULL_MASK	U(0x80000000) /* Set if full */
+#define RPI3_MBOX_STATUS_EMPTY_MASK	U(0x40000000) /* Set if empty */
+
 #define RPI3_MBOX_BUFFER_SIZE		U(256)
 
 /* Constants to perform a request/check the status of a request. */
diff --git a/include/drivers/st/bsec.h b/include/drivers/st/bsec.h
index 60dcf3c1..4a1517af 100644
--- a/include/drivers/st/bsec.h
+++ b/include/drivers/st/bsec.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,13 +12,6 @@
 
 #include <lib/utils_def.h>
 
-/*
- * IP configuration
- */
-#define BSEC_OTP_MASK			GENMASK(4, 0)
-#define BSEC_OTP_BANK_SHIFT		5
-#define BSEC_TIMEOUT_VALUE		0xFFFF
-
 /*
  * Return status
  */
@@ -32,98 +25,49 @@
 #define BSEC_RETRY			0xFFFFFFF8U
 #define BSEC_NOT_SUPPORTED		0xFFFFFFF7U
 #define BSEC_WRITE_LOCKED		0xFFFFFFF6U
-#define BSEC_ERROR_INVALID_FVR		0xFFFFFFF5U
-
-/*
- * OTP MODE
- */
-#define BSEC_MODE_OPEN1			0x00U
-#define BSEC_MODE_SECURED		0x01U
-#define BSEC_MODE_OPEN2			0x02U
-#define BSEC_MODE_INVALID		0x04U
-
-/*
- * OTP Lock services definition.
- * Value must corresponding to the bit number in the register.
- * Special case: (bit number << 1) for BSEC3.
- */
-#define BSEC_LOCK_UPPER_OTP		0x00
-#define BSEC_LOCK_GWLOCK		0x01
-#define BSEC_LOCK_DEBUG			0x02
-#define BSEC_LOCK_PROGRAM		0x03
-#define BSEC_LOCK_KVLOCK		0x04
 
 /*
- * Values for struct bsec_config::freq
+ * get BSEC global state: result for bsec_get_secure_state()
+ * @state: global state
+ *           [1:0] BSEC state
+ *             00b: Sec Open
+ *             01b: Sec Closed
+ *             11b: Invalid
+ *           [8]: Hardware Key set = 1b
  */
-#define FREQ_10_20_MHZ			0x0
-#define FREQ_20_30_MHZ			0x1
-#define FREQ_30_45_MHZ			0x2
-#define FREQ_45_67_MHZ			0x3
-
-/*
- * Device info structure, providing device-specific functions and a means of
- * adding driver-specific state.
- */
-struct bsec_config {
-	uint8_t den_lock;	/*
-				 * Debug enable sticky lock
-				 * 1 debug enable is locked until next reset
-				 */
-
-	/*  BSEC2 only */
-	uint8_t tread;		/* SAFMEM Reading current level default 0 */
-	uint8_t pulse_width;	/* SAFMEM Programming pulse width default 1 */
-	uint8_t freq;		/*
-				 * SAFMEM CLOCK see freq value define
-				 * default FREQ_45_67_MHZ
-				 */
-	uint8_t power;		/* Power up SAFMEM. 1 power up, 0 power off */
-	uint8_t prog_lock;	/*
-				 * Programming Sticky lock
-				 * 1 programming is locked until next reset
-				 */
-	uint8_t upper_otp_lock;	/*
-				 * Shadowing of upper OTP sticky lock
-				 * 1 shadowing of upper OTP is locked
-				 * until next reset
-				 */
-};
+#define BSEC_STATE_SEC_OPEN		U(0x0)
+#define BSEC_STATE_SEC_CLOSED		U(0x1)
+#define BSEC_STATE_INVALID		U(0x3)
+#define BSEC_STATE_MASK			GENMASK_32(1, 0)
 
 uint32_t bsec_probe(void);
-uint32_t bsec_get_base(void);
-
-uint32_t bsec_set_config(struct bsec_config *cfg);
-uint32_t bsec_get_config(struct bsec_config *cfg);
 
-uint32_t bsec_shadow_register(uint32_t otp);
 uint32_t bsec_read_otp(uint32_t *val, uint32_t otp);
+uint32_t bsec_shadow_read_otp(uint32_t *val, uint32_t otp);
 uint32_t bsec_write_otp(uint32_t val, uint32_t otp);
 uint32_t bsec_program_otp(uint32_t val, uint32_t otp);
-uint32_t bsec_permanent_lock_otp(uint32_t otp);
 
-void bsec_write_debug_conf(uint32_t val);
 uint32_t bsec_read_debug_conf(void);
 
 void bsec_write_scratch(uint32_t val);
-uint32_t bsec_read_scratch(void);
-
-uint32_t bsec_get_status(void);
-uint32_t bsec_get_hw_conf(void);
-uint32_t bsec_get_version(void);
-uint32_t bsec_get_id(void);
-uint32_t bsec_get_magic_id(void);
 
+/* Sticky lock support */
 uint32_t bsec_set_sr_lock(uint32_t otp);
 uint32_t bsec_read_sr_lock(uint32_t otp, bool *value);
 uint32_t bsec_set_sw_lock(uint32_t otp);
 uint32_t bsec_read_sw_lock(uint32_t otp, bool *value);
 uint32_t bsec_set_sp_lock(uint32_t otp);
 uint32_t bsec_read_sp_lock(uint32_t otp, bool *value);
-uint32_t bsec_read_permanent_lock(uint32_t otp, bool *value);
-uint32_t bsec_otp_lock(uint32_t service);
 
-uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word);
+uint32_t bsec_get_secure_state(void);
+static inline bool bsec_mode_is_closed_device(void)
+{
+	return (bsec_get_secure_state() & BSEC_STATE_MASK) == BSEC_STATE_SEC_CLOSED;
+}
+
+#if defined(IMAGE_BL32)
+uint32_t bsec_permanent_lock_otp(uint32_t otp);
 uint32_t bsec_check_nsec_access_rights(uint32_t otp);
+#endif
 
 #endif /* BSEC_H */
diff --git a/include/drivers/st/bsec2_reg.h b/include/drivers/st/bsec2_reg.h
index f8950205..fa44cf15 100644
--- a/include/drivers/st/bsec2_reg.h
+++ b/include/drivers/st/bsec2_reg.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,22 +80,17 @@
 #define GPLOCK_LOCK_SHIFT		4
 
 /* BSEC_OTP_STATUS Register */
-#define BSEC_MODE_STATUS_MASK		GENMASK(2, 0)
-#define BSEC_MODE_SECURE_MASK		BIT(0)
-#define BSEC_MODE_FULLDBG_MASK		BIT(1)
-#define BSEC_MODE_INVALID_MASK		BIT(2)
-#define BSEC_MODE_BUSY_MASK		BIT(3)
-#define BSEC_MODE_PROGFAIL_MASK		BIT(4)
-#define BSEC_MODE_PWR_MASK		BIT(5)
-#define BSEC_MODE_BIST1_LOCK_MASK	BIT(6)
-#define BSEC_MODE_BIST2_LOCK_MASK	BIT(7)
+#define BSEC_OTP_STATUS_SECURE		BIT(0)
+#define BSEC_OTP_STATUS_INVALID		BIT(2)
+#define BSEC_OTP_STATUS_BUSY		BIT(3)
+#define BSEC_OTP_STATUS_PROGFAIL	BIT(4)
+#define BSEC_OTP_STATUS_PWRON		BIT(5)
 
 /* BSEC_DENABLE Register */
 #define BSEC_HDPEN			BIT(4)
 #define BSEC_SPIDEN			BIT(5)
 #define BSEC_SPINDEN			BIT(6)
 #define BSEC_DBGSWGEN			BIT(10)
-#define BSEC_DEN_ALL_MSK		GENMASK(10, 0)
 
 /* BSEC_FENABLE Register */
 #define BSEC_FEN_ALL_MSK		GENMASK(14, 0)
diff --git a/include/drivers/st/bsec3_reg.h b/include/drivers/st/bsec3_reg.h
new file mode 100644
index 00000000..177e30ba
--- /dev/null
+++ b/include/drivers/st/bsec3_reg.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BSEC3_REG_H
+#define BSEC3_REG_H
+
+#include <lib/utils_def.h>
+
+/* BSEC REGISTER OFFSET (base relative) */
+#define BSEC_FVR(x)			(U(0x000) + 4U * (x))
+#define BSEC_SPLOCK(x)			(U(0x800) + 4U * (x))
+#define BSEC_SWLOCK(x)			(U(0x840) + 4U * (x))
+#define BSEC_SRLOCK(x)			(U(0x880) + 4U * (x))
+#define BSEC_OTPVLDR(x)			(U(0x8C0) + 4U * (x))
+#define BSEC_SFSR(x)			(U(0x940) + 4U * (x))
+#define BSEC_OTPCR			U(0xC04)
+#define BSEC_WDR			U(0xC08)
+#define BSEC_SCRATCHR0			U(0xE00)
+#define BSEC_SCRATCHR1			U(0xE04)
+#define BSEC_SCRATCHR2			U(0xE08)
+#define BSEC_SCRATCHR3			U(0xE0C)
+#define BSEC_LOCKR			U(0xE10)
+#define BSEC_JTAGINR			U(0xE14)
+#define BSEC_JTAGOUTR			U(0xE18)
+#define BSEC_DENR			U(0xE20)
+#define BSEC_UNMAPR			U(0xE24)
+#define BSEC_SR				U(0xE40)
+#define BSEC_OTPSR			U(0xE44)
+#define BSEC_WRCR			U(0xF00)
+#define BSEC_HWCFGR			U(0xFF0)
+#define BSEC_VERR			U(0xFF4)
+#define BSEC_IPIDR			U(0xFF8)
+#define BSEC_SIDR			U(0xFFC)
+
+/* BSEC_OTPCR register fields */
+#define BSEC_OTPCR_ADDR_MASK		GENMASK_32(8, 0)
+#define BSEC_OTPCR_ADDR_SHIFT		U(0)
+#define BSEC_OTPCR_PROG			BIT_32(13)
+#define BSEC_OTPCR_PPLOCK		BIT_32(14)
+#define BSEC_OTPCR_LASTCID_MASK		GENMASK_32(21, 19)
+#define BSEC_OTPCR_LASTCID_SHIFT	U(19)
+
+/* BSEC_LOCKR register fields */
+#define BSEC_LOCKR_GWLOCK_MASK		BIT_32(0)
+#define BSEC_LOCKR_GWLOCK_SHIFT		U(0)
+#define BSEC_LOCKR_DENLOCK_MASK		BIT_32(1)
+#define BSEC_LOCKR_DENLOCK_SHIFT	U(1)
+#define BSEC_LOCKR_HKLOCK_MASK		BIT_32(2)
+#define BSEC_LOCKR_HKLOCK_SHIFT		U(2)
+
+/* BSEC_DENR register fields */
+#define BSEC_DENR_LPDBGEN		BIT_32(0)
+#define BSEC_DENR_DBGENA		BIT_32(1)
+#define BSEC_DENR_NIDENA		BIT_32(2)
+#define BSEC_DENR_DEVICEEN		BIT_32(3)
+#define BSEC_DENR_HDPEN			BIT_32(4)
+#define BSEC_DENR_SPIDENA		BIT_32(5)
+#define BSEC_DENR_SPNIDENA		BIT_32(6)
+#define BSEC_DENR_DBGSWEN		BIT_32(7)
+#define BSEC_DENR_DBGENM		BIT_32(8)
+#define BSEC_DENR_NIDENM		BIT_32(9)
+#define BSEC_DENR_SPIDENM		BIT_32(10)
+#define BSEC_DENR_SPNIDENM		BIT_32(11)
+#define BSEC_DENR_CFGSDIS		BIT_32(12)
+#define BSEC_DENR_CP15SDIS_MASK		GENMASK_32(14, 13)
+#define BSEC_DENR_CP15SDIS_SHIFT	U(13)
+#define BSEC_DENR_LPDBGDIS		BIT_32(15)
+#define BSEC_DENR_ALL_MSK		GENMASK_32(15, 0)
+
+/* BSEC_SR register fields */
+#define BSEC_SR_BUSY			BIT_32(0)
+#define BSEC_SR_HVALID			BIT_32(1)
+#define BSEC_SR_RNGERR			BIT_32(2)
+#define BSEC_SR_HKWW_MASK		GENMASK_32(15, 8)
+#define BSEC_SR_HKWW_SHIFT		U(8)
+#define BSEC_SR_NVSTATE_MASK		GENMASK_32(31, 26)
+#define BSEC_SR_NVSTATE_SHIFT		U(26)
+#define BSEC_SR_NVSTATE_OPEN		U(0x16)
+#define BSEC_SR_NVSTATE_CLOSED		U(0x0D)
+#define BSEC_SR_NVSTATE_OTP_LOCKED	U(0x23)
+
+/* BSEC_OTPSR register fields */
+#define BSEC_OTPSR_BUSY			BIT_32(0)
+#define BSEC_OTPSR_FUSEOK		BIT_32(1)
+#define BSEC_OTPSR_HIDEUP		BIT_32(2)
+#define BSEC_OTPSR_OTPNVIR		BIT_32(4)
+#define BSEC_OTPSR_OTPERR		BIT_32(5)
+#define BSEC_OTPSR_OTPSEC		BIT_32(6)
+#define BSEC_OTPSR_PROGFAIL		BIT_32(16)
+#define BSEC_OTPSR_DISTURBF		BIT_32(17)
+#define BSEC_OTPSR_DEDF			BIT_32(18)
+#define BSEC_OTPSR_SECF			BIT_32(19)
+#define BSEC_OTPSR_PPLF			BIT_32(20)
+#define BSEC_OTPSR_PPLMF		BIT_32(21)
+#define BSEC_OTPSR_AMEF			BIT_32(22)
+
+/* BSEC_VERR register fields */
+#define BSEC_VERR_MASK			GENMASK_32(7, 0)
+
+#endif /* BSEC3_REG_H */
diff --git a/include/drivers/st/stm32_gpio.h b/include/drivers/st/stm32_gpio.h
index eeef9da5..ef4eb04a 100644
--- a/include/drivers/st/stm32_gpio.h
+++ b/include/drivers/st/stm32_gpio.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #define GPIO_TYPE_OFFSET	U(0x04)
 #define GPIO_SPEED_OFFSET	U(0x08)
 #define GPIO_PUPD_OFFSET	U(0x0C)
+#define GPIO_IDR_OFFSET		U(0x10)
 #define GPIO_OD_OFFSET		U(0x14)
 #define GPIO_BSRR_OFFSET	U(0x18)
 #define GPIO_AFRL_OFFSET	U(0x20)
@@ -58,6 +59,16 @@
 int dt_set_pinctrl_config(int node);
 void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure);
 void set_gpio_reset_cfg(uint32_t bank, uint32_t pin);
+
+enum gpio_level {
+	GPIO_LEVEL_LOW,
+	GPIO_LEVEL_HIGH
+};
+
+void set_gpio_level(uint32_t bank, uint32_t pin, enum gpio_level level);
+enum gpio_level get_gpio_level(uint32_t bank, uint32_t pin);
+
+void set_gpio_config(uint32_t bank, uint32_t pin, uint32_t config, uint8_t status);
 #endif /*__ASSEMBLER__*/
 
 #endif /* STM32_GPIO_H */
diff --git a/include/drivers/st/stm32_i2c.h b/include/drivers/st/stm32_i2c.h
index 170d4cf8..ccb574b3 100644
--- a/include/drivers/st/stm32_i2c.h
+++ b/include/drivers/st/stm32_i2c.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -294,7 +294,6 @@ struct i2c_handle_s {
 /* STM32 specific defines */
 #define STM32_I2C_RISE_TIME_DEFAULT		25	/* ns */
 #define STM32_I2C_FALL_TIME_DEFAULT		10	/* ns */
-#define STM32_I2C_SPEED_DEFAULT			I2C_SPEED_STANDARD
 #define STM32_I2C_ANALOG_FILTER_DELAY_MIN	50	/* ns */
 #define STM32_I2C_ANALOG_FILTER_DELAY_MAX	260	/* ns */
 #define STM32_I2C_DIGITAL_FILTER_MAX		16
diff --git a/include/drivers/st/stm32mp1_clk.h b/include/drivers/st/stm32mp1_clk.h
index e2395bc5..93ec1c59 100644
--- a/include/drivers/st/stm32mp1_clk.h
+++ b/include/drivers/st/stm32mp1_clk.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,6 +32,8 @@ bool stm32mp1_rcc_is_mckprot(void);
 void stm32mp1_clk_rcc_regs_lock(void);
 void stm32mp1_clk_rcc_regs_unlock(void);
 
+void stm32mp1_clk_mcuss_protect(bool enable);
+
 #ifdef STM32MP_SHARED_RESOURCES
 void stm32mp1_register_clock_parents_secure(unsigned long id);
 #endif
diff --git a/include/drivers/st/stm32mp25_rcc.h b/include/drivers/st/stm32mp25_rcc.h
index 9dd25f3c..d5d228cb 100644
--- a/include/drivers/st/stm32mp25_rcc.h
+++ b/include/drivers/st/stm32mp25_rcc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -426,7 +426,7 @@
 #define RCC_USB2CFGR				U(0x7FC)
 #define RCC_USB2PHY1CFGR			U(0x800)
 #define RCC_USB2PHY2CFGR			U(0x804)
-#define RCC_USB3DRDCFGR				U(0x808)
+#define RCC_USB3DRCFGR				U(0x808)
 #define RCC_USB3PCIEPHYCFGR			U(0x80C)
 #define RCC_PCIECFGR				U(0x810)
 #define RCC_USBTCCFGR				U(0x814)
@@ -459,7 +459,6 @@
 #define RCC_IWDG5CFGR				U(0x898)
 #define RCC_WWDG1CFGR				U(0x89C)
 #define RCC_WWDG2CFGR				U(0x8A0)
-#define RCC_BUSPERFMCFGR			U(0x8A4)
 #define RCC_VREFCFGR				U(0x8A8)
 #define RCC_TMPSENSCFGR				U(0x8AC)
 #define RCC_CRCCFGR				U(0x8B4)
@@ -2352,11 +2351,13 @@
 /* RCC_C1SREQSETR register fields */
 #define RCC_C1SREQSETR_STPREQ_P0		BIT(0)
 #define RCC_C1SREQSETR_STPREQ_P1		BIT(1)
+#define RCC_C1SREQSETR_STPREQ_MASK		GENMASK_32(1, 0)
 #define RCC_C1SREQSETR_ESLPREQ			BIT(16)
 
 /* RCC_C1SREQCLRR register fields */
 #define RCC_C1SREQCLRR_STPREQ_P0		BIT(0)
 #define RCC_C1SREQCLRR_STPREQ_P1		BIT(1)
+#define RCC_C1SREQCLRR_STPREQ_MASK		GENMASK_32(1, 0)
 #define RCC_C1SREQCLRR_ESLPREQ			BIT(16)
 
 /* RCC_CPUBOOTCR register fields */
@@ -2401,12 +2402,12 @@
 #define RCC_BDCR_LSEDRV_WIDTH			2
 
 /* RCC_D3DCR register fields */
-#define RCC_D3DCR_CSION				BIT(0)
-#define RCC_D3DCR_CSIKERON			BIT(1)
-#define RCC_D3DCR_CSIRDY			BIT(2)
+#define RCC_D3DCR_MSION				BIT(0)
+#define RCC_D3DCR_MSIKERON			BIT(1)
+#define RCC_D3DCR_MSIRDY			BIT(2)
 #define RCC_D3DCR_D3PERCKSEL_MASK		GENMASK_32(17, 16)
 #define RCC_D3DCR_D3PERCKSEL_SHIFT		16
-#define RCC_D3DCR_CSIRDY_BIT			2
+#define RCC_D3DCR_MSIRDY_BIT			2
 
 /* RCC_D3DSR register fields */
 #define RCC_D3DSR_D3STATE_MASK			GENMASK_32(1, 0)
@@ -3458,11 +3459,11 @@
 #define RCC_USB2PHYxCFGR_USB2PHY1STPEN		BIT(4)
 #define RCC_USB2PHYxCFGR_USB2PHY1CKREFSEL	BIT(15)
 
-/* RCC_USB3DRDCFGR register fields */
-#define RCC_USB3DRDCFGR_USB3DRDRST		BIT(0)
-#define RCC_USB3DRDCFGR_USB3DRDEN		BIT(1)
-#define RCC_USB3DRDCFGR_USB3DRDLPEN		BIT(2)
-#define RCC_USB3DRDCFGR_USB3DRDSTPEN		BIT(4)
+/* RCC_USB3DRCFGR register fields */
+#define RCC_USB3DRCFGR_USB3DRRST		BIT(0)
+#define RCC_USB3DRCFGR_USB3DREN			BIT(1)
+#define RCC_USB3DRCFGR_USB3DRLPEN		BIT(2)
+#define RCC_USB3DRCFGR_USB3DRSTPEN		BIT(4)
 
 /* RCC_USB3PCIEPHYCFGR register fields */
 #define RCC_USB3PCIEPHYCFGR_USB3PCIEPHYRST	BIT(0)
@@ -3647,11 +3648,6 @@
 #define RCC_WWDG2CFGR_WWDG2LPEN			BIT(2)
 #define RCC_WWDG2CFGR_WWDG2AMEN			BIT(3)
 
-/* RCC_BUSPERFMCFGR register fields */
-#define RCC_BUSPERFMCFGR_BUSPERFMRST		BIT(0)
-#define RCC_BUSPERFMCFGR_BUSPERFMEN		BIT(1)
-#define RCC_BUSPERFMCFGR_BUSPERFMLPEN		BIT(2)
-
 /* RCC_VREFCFGR register fields */
 #define RCC_VREFCFGR_VREFRST			BIT(0)
 #define RCC_VREFCFGR_VREFEN			BIT(1)
diff --git a/include/drivers/st/stm32mp2_clk.h b/include/drivers/st/stm32mp2_clk.h
new file mode 100644
index 00000000..b9226cdc
--- /dev/null
+++ b/include/drivers/st/stm32mp2_clk.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_CLK_H
+#define STM32MP2_CLK_H
+
+#include <platform_def.h>
+
+enum stm32mp_osc_id {
+	_HSI,
+	_HSE,
+	_CSI,
+	_LSI,
+	_LSE,
+	_I2S_CKIN,
+	_SPDIF_SYMB,
+	NB_OSC,
+	_UNKNOWN_OSC_ID = 0xFF
+};
+
+extern const char *stm32mp_osc_node_label[NB_OSC];
+
+enum pll_cfg {
+	FBDIV,
+	REFDIV,
+	POSTDIV1,
+	POSTDIV2,
+	PLLCFG_NB
+};
+
+enum pll_csg {
+	DIVVAL,
+	SPREAD,
+	DOWNSPREAD,
+	PLLCSG_NB
+};
+
+int stm32mp2_clk_init(void);
+int stm32mp2_pll1_disable(void);
+
+#endif /* STM32MP2_CLK_H */
diff --git a/include/drivers/st/stm32mp2_ddr.h b/include/drivers/st/stm32mp2_ddr.h
new file mode 100644
index 00000000..6b0462c8
--- /dev/null
+++ b/include/drivers/st/stm32mp2_ddr.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef STM32MP2_DDR_H
+#define STM32MP2_DDR_H
+
+#include <stdbool.h>
+
+#include <ddrphy_phyinit_struct.h>
+
+#include <drivers/st/stm32mp_ddr.h>
+
+struct stm32mp2_ddrctrl_reg {
+	uint32_t mstr;
+	uint32_t mrctrl0;
+	uint32_t mrctrl1;
+	uint32_t mrctrl2;
+	uint32_t derateen;
+	uint32_t derateint;
+	uint32_t deratectl;
+	uint32_t pwrctl;
+	uint32_t pwrtmg;
+	uint32_t hwlpctl;
+	uint32_t rfshctl0;
+	uint32_t rfshctl1;
+	uint32_t rfshctl3;
+	uint32_t crcparctl0;
+	uint32_t crcparctl1;
+	uint32_t init0;
+	uint32_t init1;
+	uint32_t init2;
+	uint32_t init3;
+	uint32_t init4;
+	uint32_t init5;
+	uint32_t init6;
+	uint32_t init7;
+	uint32_t dimmctl;
+	uint32_t rankctl;
+	uint32_t rankctl1;
+	uint32_t zqctl0;
+	uint32_t zqctl1;
+	uint32_t zqctl2;
+	uint32_t dfitmg0;
+	uint32_t dfitmg1;
+	uint32_t dfilpcfg0;
+	uint32_t dfilpcfg1;
+	uint32_t dfiupd0;
+	uint32_t dfiupd1;
+	uint32_t dfiupd2;
+	uint32_t dfimisc;
+	uint32_t dfitmg2;
+	uint32_t dfitmg3;
+	uint32_t dbictl;
+	uint32_t dfiphymstr;
+	uint32_t dbg0;
+	uint32_t dbg1;
+	uint32_t dbgcmd;
+	uint32_t swctl;
+	uint32_t swctlstatic;
+	uint32_t poisoncfg;
+	uint32_t pccfg;
+};
+
+struct stm32mp2_ddrctrl_timing {
+	uint32_t rfshtmg;
+	uint32_t rfshtmg1;
+	uint32_t dramtmg0;
+	uint32_t dramtmg1;
+	uint32_t dramtmg2;
+	uint32_t dramtmg3;
+	uint32_t dramtmg4;
+	uint32_t dramtmg5;
+	uint32_t dramtmg6;
+	uint32_t dramtmg7;
+	uint32_t dramtmg8;
+	uint32_t dramtmg9;
+	uint32_t dramtmg10;
+	uint32_t dramtmg11;
+	uint32_t dramtmg12;
+	uint32_t dramtmg13;
+	uint32_t dramtmg14;
+	uint32_t dramtmg15;
+	uint32_t odtcfg;
+	uint32_t odtmap;
+};
+
+struct stm32mp2_ddrctrl_map {
+	uint32_t addrmap0;
+	uint32_t addrmap1;
+	uint32_t addrmap2;
+	uint32_t addrmap3;
+	uint32_t addrmap4;
+	uint32_t addrmap5;
+	uint32_t addrmap6;
+	uint32_t addrmap7;
+	uint32_t addrmap8;
+	uint32_t addrmap9;
+	uint32_t addrmap10;
+	uint32_t addrmap11;
+};
+
+struct stm32mp2_ddrctrl_perf {
+	uint32_t sched;
+	uint32_t sched1;
+	uint32_t perfhpr1;
+	uint32_t perflpr1;
+	uint32_t perfwr1;
+	uint32_t sched3;
+	uint32_t sched4;
+	uint32_t pcfgr_0;
+	uint32_t pcfgw_0;
+	uint32_t pctrl_0;
+	uint32_t pcfgqos0_0;
+	uint32_t pcfgqos1_0;
+	uint32_t pcfgwqos0_0;
+	uint32_t pcfgwqos1_0;
+#if STM32MP_DDR_DUAL_AXI_PORT
+	uint32_t pcfgr_1;
+	uint32_t pcfgw_1;
+	uint32_t pctrl_1;
+	uint32_t pcfgqos0_1;
+	uint32_t pcfgqos1_1;
+	uint32_t pcfgwqos0_1;
+	uint32_t pcfgwqos1_1;
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
+};
+
+struct stm32mp_ddr_config {
+	struct stm32mp_ddr_info info;
+	struct stm32mp2_ddrctrl_reg c_reg;
+	struct stm32mp2_ddrctrl_timing c_timing;
+	struct stm32mp2_ddrctrl_map c_map;
+	struct stm32mp2_ddrctrl_perf c_perf;
+	bool self_refresh;
+	uint32_t zdata;
+	struct user_input_basic uib;
+	struct user_input_advanced uia;
+	struct user_input_mode_register uim;
+	struct user_input_swizzle uis;
+};
+
+void stm32mp2_ddr_init(struct stm32mp_ddr_priv *priv, struct stm32mp_ddr_config *config);
+
+#endif /* STM32MP2_DDR_H */
diff --git a/include/drivers/st/stm32mp2_ddr_helpers.h b/include/drivers/st/stm32mp2_ddr_helpers.h
new file mode 100644
index 00000000..9329fff2
--- /dev/null
+++ b/include/drivers/st/stm32mp2_ddr_helpers.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_DDR_HELPERS_H
+#define STM32MP2_DDR_HELPERS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <drivers/st/stm32mp2_ddr_regs.h>
+
+enum stm32mp2_ddr_sr_mode {
+	DDR_SR_MODE_INVALID = 0,
+	DDR_SSR_MODE,
+	DDR_HSR_MODE,
+	DDR_ASR_MODE,
+};
+
+void ddr_activate_controller(struct stm32mp_ddrctl *ctl, bool sr_entry);
+void ddr_wait_lp3_mode(bool state);
+int ddr_sr_exit_loop(void);
+uint32_t ddr_get_io_calibration_val(void);
+int ddr_sr_entry(bool standby);
+int ddr_sr_exit(void);
+enum stm32mp2_ddr_sr_mode ddr_read_sr_mode(void);
+void ddr_set_sr_mode(enum stm32mp2_ddr_sr_mode mode);
+void ddr_save_sr_mode(void);
+void ddr_restore_sr_mode(void);
+void ddr_sub_system_clk_init(void);
+void ddr_sub_system_clk_off(void);
+
+#endif /* STM32MP2_DDR_HELPERS_H */
diff --git a/include/drivers/st/stm32mp2_ddr_regs.h b/include/drivers/st/stm32mp2_ddr_regs.h
new file mode 100644
index 00000000..9370f1ca
--- /dev/null
+++ b/include/drivers/st/stm32mp2_ddr_regs.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef STM32MP2_DDR_REGS_H
+#define STM32MP2_DDR_REGS_H
+
+#include <drivers/st/stm32mp_ddrctrl_regs.h>
+#include <lib/utils_def.h>
+
+/* DDR Physical Interface Control (DDRPHYC) registers*/
+struct stm32mp_ddrphy {
+	uint32_t dummy;
+} __packed;
+
+/* DDRPHY registers offsets */
+#define DDRPHY_INITENG0_P0_SEQ0BDISABLEFLAG6	U(0x240004)
+#define DDRPHY_INITENG0_P0_PHYINLPX		U(0x2400A0)
+#define DDRPHY_DRTUB0_UCCLKHCLKENABLES		U(0x300200)
+#define DDRPHY_APBONLY0_MICROCONTMUXSEL		U(0x340000)
+
+/* DDRPHY registers fields */
+#define DDRPHY_INITENG0_P0_PHYINLPX_PHYINLP3			BIT(0)
+#define DDRPHY_DRTUB0_UCCLKHCLKENABLES_UCCLKEN			BIT(0)
+#define DDRPHY_DRTUB0_UCCLKHCLKENABLES_HCLKEN			BIT(1)
+#define DDRPHY_APBONLY0_MICROCONTMUXSEL_MICROCONTMUXSEL		BIT(0)
+
+/* DDRDBG registers offsets */
+#define DDRDBG_LP_DISABLE			U(0x0)
+#define DDRDBG_BYPASS_PCLKEN			U(0x4)
+
+/* DDRDBG registers fields */
+#define DDRDBG_LP_DISABLE_LPI_XPI_DISABLE	BIT(0)
+#define DDRDBG_LP_DISABLE_LPI_DDRC_DISABLE	BIT(8)
+
+#endif /* STM32MP2_DDR_REGS_H */
diff --git a/include/drivers/st/stm32mp2_pwr.h b/include/drivers/st/stm32mp2_pwr.h
new file mode 100644
index 00000000..356399af
--- /dev/null
+++ b/include/drivers/st/stm32mp2_pwr.h
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_PWR_H
+#define STM32MP2_PWR_H
+
+#include <lib/utils_def.h>
+
+#define PWR_CR1					U(0x00)
+#define PWR_CR2					U(0x04)
+#define PWR_CR3					U(0x08)
+#define PWR_CR4					U(0x0C)
+#define PWR_CR5					U(0x10)
+#define PWR_CR6					U(0x14)
+#define PWR_CR7					U(0x18)
+#define PWR_CR8					U(0x1C)
+#define PWR_CR9					U(0x20)
+#define PWR_CR10				U(0x24)
+#define PWR_CR11				U(0x28)
+#define PWR_CR12				U(0x2C)
+#define PWR_UCPDR				U(0x30)
+#define PWR_BDCR1				U(0x38)
+#define PWR_BDCR2				U(0x3C)
+#define PWR_CPU1CR				U(0x40)
+#define PWR_CPU2CR				U(0x44)
+#define PWR_CPU3CR				U(0x48)
+#define PWR_D1CR				U(0x4C)
+#define PWR_D2CR				U(0x50)
+#define PWR_D3CR				U(0x54)
+#define PWR_WKUPCR1				U(0x60)
+#define PWR_WKUPCR2				U(0x64)
+#define PWR_WKUPCR3				U(0x68)
+#define PWR_WKUPCR4				U(0x6C)
+#define PWR_WKUPCR5				U(0x70)
+#define PWR_WKUPCR6				U(0x74)
+#define PWR_D3WKUPENR				U(0x98)
+#define PWR_RSECCFGR				U(0x100)
+#define PWR_RPRIVCFGR				U(0x104)
+#define PWR_R0CIDCFGR				U(0x108)
+#define PWR_R1CIDCFGR				U(0x10C)
+#define PWR_R2CIDCFGR				U(0x110)
+#define PWR_R3CIDCFGR				U(0x114)
+#define PWR_R4CIDCFGR				U(0x118)
+#define PWR_R5CIDCFGR				U(0x11C)
+#define PWR_R6CIDCFGR				U(0x120)
+#define PWR_WIOSECCFGR				U(0x180)
+#define PWR_WIOPRIVCFGR				U(0x184)
+#define PWR_WIO1CIDCFGR				U(0x188)
+#define PWR_WIO1SEMCR				U(0x18C)
+#define PWR_WIO2CIDCFGR				U(0x190)
+#define PWR_WIO2SEMCR				U(0x194)
+#define PWR_WIO3CIDCFGR				U(0x198)
+#define PWR_WIO3SEMCR				U(0x19C)
+#define PWR_WIO4CIDCFGR				U(0x1A0)
+#define PWR_WIO4SEMCR				U(0x1A4)
+#define PWR_WIO5CIDCFGR				U(0x1A8)
+#define PWR_WIO5SEMCR				U(0x1AC)
+#define PWR_WIO6CIDCFGR				U(0x1B0)
+#define PWR_WIO6SEMCR				U(0x1B4)
+#define PWR_CPU1D1SR				U(0x200)
+#define PWR_CPU2D2SR				U(0x204)
+#define PWR_CPU3D3SR				U(0x208)
+#define PWR_DBGR				U(0x308)
+#define PWR_VERR				U(0x3F4)
+#define PWR_IPIDR				U(0x3F8)
+#define PWR_SIDR				U(0x3FC)
+
+/* PWR_CR1 register fields */
+#define PWR_CR1_VDDIO3VMEN			BIT_32(0)
+#define PWR_CR1_VDDIO4VMEN			BIT_32(1)
+#define PWR_CR1_USB33VMEN			BIT_32(2)
+#define PWR_CR1_UCPDVMEN			BIT_32(3)
+#define PWR_CR1_AVMEN				BIT_32(4)
+#define PWR_CR1_VDDIO3SV			BIT_32(8)
+#define PWR_CR1_VDDIO4SV			BIT_32(9)
+#define PWR_CR1_USB33SV				BIT_32(10)
+#define PWR_CR1_UCPDSV				BIT_32(11)
+#define PWR_CR1_ASV				BIT_32(12)
+#define PWR_CR1_VDDIO3RDY			BIT_32(16)
+#define PWR_CR1_VDDIO4RDY			BIT_32(17)
+#define PWR_CR1_USB33RDY			BIT_32(18)
+#define PWR_CR1_UCPDRDY				BIT_32(19)
+#define PWR_CR1_ARDY				BIT_32(20)
+#define PWR_CR1_VDDIOVRSEL			BIT_32(24)
+#define PWR_CR1_VDDIO3VRSEL			BIT_32(25)
+#define PWR_CR1_VDDIO4VRSEL			BIT_32(26)
+#define PWR_CR1_GPVMO				BIT_32(31)
+
+/* PWR_CR2 register fields */
+#define PWR_CR2_MONEN				BIT_32(0)
+#define PWR_CR2_VBATL				BIT_32(8)
+#define PWR_CR2_VBATH				BIT_32(9)
+#define PWR_CR2_TEMPL				BIT_32(10)
+#define PWR_CR2_TEMPH				BIT_32(11)
+
+/* PWR_CR3 register fields */
+#define PWR_CR3_PVDEN				BIT_32(0)
+#define PWR_CR3_PVDO				BIT_32(8)
+
+/* PWR_CR5 register fields */
+#define PWR_CR5_VCOREMONEN			BIT_32(0)
+#define PWR_CR5_VCOREL				BIT_32(8)
+#define PWR_CR5_VCOREH				BIT_32(9)
+
+/* PWR_CR6 register fields */
+#define PWR_CR6_VCPUMONEN			BIT_32(0)
+#define PWR_CR6_VCPULLS				BIT_32(4)
+#define PWR_CR6_VCPUL				BIT_32(8)
+#define PWR_CR6_VCPUH				BIT_32(9)
+
+/* PWR_CR7 register fields */
+#define PWR_CR7_VDDIO2VMEN			BIT_32(0)
+#define PWR_CR7_VDDIO2SV			BIT_32(8)
+#define PWR_CR7_VDDIO2RDY			BIT_32(16)
+#define PWR_CR7_VDDIO2VRSEL			BIT_32(24)
+#define PWR_CR7_VDDIO2VRSTBY			BIT_32(25)
+
+/* PWR_CR8 register fields */
+#define PWR_CR8_VDDIO1VMEN			BIT_32(0)
+#define PWR_CR8_VDDIO1SV			BIT_32(8)
+#define PWR_CR8_VDDIO1RDY			BIT_32(16)
+#define PWR_CR8_VDDIO1VRSEL			BIT_32(24)
+#define PWR_CR8_VDDIO1VRSTBY			BIT_32(25)
+
+/* PWR_CR9 register fields */
+#define PWR_CR9_BKPRBSEN			BIT_32(0)
+#define PWR_CR9_LPR1BSEN			BIT_32(4)
+
+/* PWR_CR10 register fields */
+#define PWR_CR10_RETRBSEN_MASK			GENMASK_32(1, 0)
+#define PWR_CR10_RETRBSEN_SHIFT			U(0)
+
+/* PWR_CR11 register fields */
+#define PWR_CR11_DDRRETDIS			BIT_32(0)
+
+/* PWR_CR12 register fields */
+#define PWR_CR12_GPUVMEN			BIT_32(0)
+#define PWR_CR12_GPULVTEN			BIT_32(1)
+#define PWR_CR12_GPUSV				BIT_32(8)
+#define PWR_CR12_VDDGPURDY			BIT_32(16)
+
+/* PWR_UCPDR register fields */
+#define PWR_UCPDR_UCPD_DBDIS			BIT_32(0)
+#define PWR_UCPDR_UCPD_STBY			BIT_32(1)
+
+/* PWR_BDCR1 register fields */
+#define PWR_BDCR1_DBD3P				BIT_32(0)
+
+/* PWR_BDCR2 register fields */
+#define PWR_BDCR2_DBP				BIT_32(0)
+
+/* PWR_CPU1CR register fields */
+#define PWR_CPU1CR_PDDS_D2			BIT_32(0)
+#define PWR_CPU1CR_PDDS_D1			BIT_32(1)
+#define PWR_CPU1CR_VBF				BIT_32(4)
+#define PWR_CPU1CR_STOPF			BIT_32(5)
+#define PWR_CPU1CR_SBF				BIT_32(6)
+#define PWR_CPU1CR_SBF_D1			BIT_32(7)
+#define PWR_CPU1CR_SBF_D3			BIT_32(8)
+#define PWR_CPU1CR_CSSF				BIT_32(9)
+#define PWR_CPU1CR_STANDBYWFIL2			BIT_32(15)
+#define PWR_CPU1CR_LPDS_D1			BIT_32(16)
+#define PWR_CPU1CR_LVDS_D1			BIT_32(17)
+
+/* PWR_CPU2CR register fields */
+#define PWR_CPU2CR_PDDS_D2			BIT_32(0)
+#define PWR_CPU2CR_VBF				BIT_32(4)
+#define PWR_CPU2CR_STOPF			BIT_32(5)
+#define PWR_CPU2CR_SBF				BIT_32(6)
+#define PWR_CPU2CR_SBF_D2			BIT_32(7)
+#define PWR_CPU2CR_SBF_D3			BIT_32(8)
+#define PWR_CPU2CR_CSSF				BIT_32(9)
+#define PWR_CPU2CR_DEEPSLEEP			BIT_32(15)
+#define PWR_CPU2CR_LPDS_D2			BIT_32(16)
+#define PWR_CPU2CR_LVDS_D2			BIT_32(17)
+
+/* PWR_CPU3CR register fields */
+#define PWR_CPU3CR_VBF				BIT_32(4)
+#define PWR_CPU3CR_SBF_D3			BIT_32(8)
+#define PWR_CPU3CR_CSSF				BIT_32(9)
+#define PWR_CPU3CR_DEEPSLEEP			BIT_32(15)
+
+/* PWR_D1CR register fields */
+#define PWR_D1CR_LPCFG_D1			BIT_32(0)
+#define PWR_D1CR_POPL_D1_MASK			GENMASK_32(12, 8)
+#define PWR_D1CR_POPL_D1_SHIFT			U(8)
+
+/* PWR_D2CR register fields */
+#define PWR_D2CR_LPCFG_D2			BIT_32(0)
+#define PWR_D2CR_POPL_D2_MASK			GENMASK_32(12, 8)
+#define PWR_D2CR_POPL_D2_SHIFT			U(8)
+#define PWR_D2CR_LPLVDLY_D2_MASK		GENMASK_32(18, 16)
+#define PWR_D2CR_LPLVDLY_D2_SHIFT		U(16)
+#define PWR_D2CR_PODH_D2_MASK			GENMASK_32(27, 24)
+#define PWR_D2CR_PODH_D2_SHIFT			U(24)
+
+/* PWR_D3CR register fields */
+#define PWR_D3CR_PDDS_D3			BIT_32(0)
+#define PWR_D3CR_D3RDY				BIT_32(31)
+
+/* PWR_WKUPCR1 register fields */
+#define PWR_WKUPCR1_WKUPC			BIT_32(0)
+#define PWR_WKUPCR1_WKUPP			BIT_32(8)
+#define PWR_WKUPCR1_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR1_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR1_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR1_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR1_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR2 register fields */
+#define PWR_WKUPCR2_WKUPC			BIT_32(0)
+#define PWR_WKUPCR2_WKUPP			BIT_32(8)
+#define PWR_WKUPCR2_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR2_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR2_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR2_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR2_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR3 register fields */
+#define PWR_WKUPCR3_WKUPC			BIT_32(0)
+#define PWR_WKUPCR3_WKUPP			BIT_32(8)
+#define PWR_WKUPCR3_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR3_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR3_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR3_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR3_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR4 register fields */
+#define PWR_WKUPCR4_WKUPC			BIT_32(0)
+#define PWR_WKUPCR4_WKUPP			BIT_32(8)
+#define PWR_WKUPCR4_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR4_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR4_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR4_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR4_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR5 register fields */
+#define PWR_WKUPCR5_WKUPC			BIT_32(0)
+#define PWR_WKUPCR5_WKUPP			BIT_32(8)
+#define PWR_WKUPCR5_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR5_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR5_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR5_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR5_WKUPF			BIT_32(31)
+
+/* PWR_WKUPCR6 register fields */
+#define PWR_WKUPCR6_WKUPC			BIT_32(0)
+#define PWR_WKUPCR6_WKUPP			BIT_32(8)
+#define PWR_WKUPCR6_WKUPPUPD_MASK		GENMASK_32(13, 12)
+#define PWR_WKUPCR6_WKUPPUPD_SHIFT		U(12)
+#define PWR_WKUPCR6_WKUPENCPU1			BIT_32(16)
+#define PWR_WKUPCR6_WKUPENCPU2			BIT_32(17)
+#define PWR_WKUPCR6_WKUPF			BIT_32(31)
+
+/* PWR_D3WKUPENR register fields */
+#define PWR_D3WKUPENR_TAMP_WKUPEN_D3		BIT_32(0)
+
+/* PWR_RSECCFGR register fields */
+#define PWR_RSECCFGR_RSEC0			BIT_32(0)
+#define PWR_RSECCFGR_RSEC1			BIT_32(1)
+#define PWR_RSECCFGR_RSEC2			BIT_32(2)
+#define PWR_RSECCFGR_RSEC3			BIT_32(3)
+#define PWR_RSECCFGR_RSEC4			BIT_32(4)
+#define PWR_RSECCFGR_RSEC5			BIT_32(5)
+#define PWR_RSECCFGR_RSEC6			BIT_32(6)
+
+/* PWR_RPRIVCFGR register fields */
+#define PWR_RPRIVCFGR_RPRIV0			BIT_32(0)
+#define PWR_RPRIVCFGR_RPRIV1			BIT_32(1)
+#define PWR_RPRIVCFGR_RPRIV2			BIT_32(2)
+#define PWR_RPRIVCFGR_RPRIV3			BIT_32(3)
+#define PWR_RPRIVCFGR_RPRIV4			BIT_32(4)
+#define PWR_RPRIVCFGR_RPRIV5			BIT_32(5)
+#define PWR_RPRIVCFGR_RPRIV6			BIT_32(6)
+
+/* PWR_R0CIDCFGR register fields */
+#define PWR_R0CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R0CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R0CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R1CIDCFGR register fields */
+#define PWR_R1CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R1CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R1CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R2CIDCFGR register fields */
+#define PWR_R2CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R2CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R2CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R3CIDCFGR register fields */
+#define PWR_R3CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R3CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R3CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R4CIDCFGR register fields */
+#define PWR_R4CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R4CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R4CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R5CIDCFGR register fields */
+#define PWR_R5CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R5CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R5CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_R6CIDCFGR register fields */
+#define PWR_R6CIDCFGR_CFEN			BIT_32(0)
+#define PWR_R6CIDCFGR_SCID_MASK			GENMASK_32(6, 4)
+#define PWR_R6CIDCFGR_SCID_SHIFT		U(4)
+
+/* PWR_WIOSECCFGR register fields */
+#define PWR_WIOSECCFGR_WIOSEC1			BIT_32(0)
+#define PWR_WIOSECCFGR_WIOSEC2			BIT_32(1)
+#define PWR_WIOSECCFGR_WIOSEC3			BIT_32(2)
+#define PWR_WIOSECCFGR_WIOSEC4			BIT_32(3)
+#define PWR_WIOSECCFGR_WIOSEC5			BIT_32(4)
+#define PWR_WIOSECCFGR_WIOSEC6			BIT_32(5)
+
+/* PWR_WIOPRIVCFGR register fields */
+#define PWR_WIOPRIVCFGR_WIOPRIV1		BIT_32(0)
+#define PWR_WIOPRIVCFGR_WIOPRIV2		BIT_32(1)
+#define PWR_WIOPRIVCFGR_WIOPRIV3		BIT_32(2)
+#define PWR_WIOPRIVCFGR_WIOPRIV4		BIT_32(3)
+#define PWR_WIOPRIVCFGR_WIOPRIV5		BIT_32(4)
+#define PWR_WIOPRIVCFGR_WIOPRIV6		BIT_32(5)
+
+/* PWR_WIO1CIDCFGR register fields */
+#define PWR_WIO1CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO1CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO1CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO1CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO1CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO1CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO1CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO1CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO1CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO1CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO1CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO1CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO1SEMCR register fields */
+#define PWR_WIO1SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO1SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO1SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO2CIDCFGR register fields */
+#define PWR_WIO2CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO2CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO2CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO2CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO2CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO2CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO2CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO2CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO2CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO2CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO2CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO2CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO2SEMCR register fields */
+#define PWR_WIO2SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO2SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO2SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO3CIDCFGR register fields */
+#define PWR_WIO3CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO3CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO3CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO3CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO3CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO3CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO3CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO3CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO3CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO3CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO3CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO3CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO3SEMCR register fields */
+#define PWR_WIO3SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO3SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO3SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO4CIDCFGR register fields */
+#define PWR_WIO4CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO4CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO4CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO4CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO4CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO4CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO4CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO4CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO4CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO4CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO4CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO4CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO4SEMCR register fields */
+#define PWR_WIO4SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO4SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO4SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO5CIDCFGR register fields */
+#define PWR_WIO5CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO5CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO5CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO5CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO5CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO5CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO5CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO5CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO5CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO5CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO5CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO5CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO5SEMCR register fields */
+#define PWR_WIO5SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO5SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO5SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_WIO6CIDCFGR register fields */
+#define PWR_WIO6CIDCFGR_CFEN			BIT_32(0)
+#define PWR_WIO6CIDCFGR_SEM_EN			BIT_32(1)
+#define PWR_WIO6CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO6CIDCFGR_SCID_SHIFT		U(4)
+#define PWR_WIO6CIDCFGR_SEMWLC0			BIT_32(16)
+#define PWR_WIO6CIDCFGR_SEMWLC1			BIT_32(17)
+#define PWR_WIO6CIDCFGR_SEMWLC2			BIT_32(18)
+#define PWR_WIO6CIDCFGR_SEMWLC3			BIT_32(19)
+#define PWR_WIO6CIDCFGR_SEMWLC4			BIT_32(20)
+#define PWR_WIO6CIDCFGR_SEMWLC5			BIT_32(21)
+#define PWR_WIO6CIDCFGR_SEMWLC6			BIT_32(22)
+#define PWR_WIO6CIDCFGR_SEMWLC7			BIT_32(23)
+
+/* PWR_WIO6SEMCR register fields */
+#define PWR_WIO6SEMCR_SEM_MUTEX			BIT_32(0)
+#define PWR_WIO6SEMCR_SEMCID_MASK		GENMASK_32(6, 4)
+#define PWR_WIO6SEMCR_SEMCID_SHIFT		U(4)
+
+/* PWR_CPU1D1SR register fields */
+#define PWR_CPU1D1SR_HOLD_BOOT			BIT_32(0)
+#define PWR_CPU1D1SR_CSTATE_MASK		GENMASK_32(3, 2)
+#define PWR_CPU1D1SR_CSTATE_SHIFT		U(2)
+#define PWR_CPU1D1SR_DSTATE_MASK		GENMASK_32(10, 8)
+#define PWR_CPU1D1SR_DSTATE_SHIFT		U(8)
+
+/* PWR_CPU2D2SR register fields */
+#define PWR_CPU2D2SR_HOLD_BOOT			BIT_32(0)
+#define PWR_CPU2D2SR_WFBEN			BIT_32(1)
+#define PWR_CPU2D2SR_CSTATE_MASK		GENMASK_32(3, 2)
+#define PWR_CPU2D2SR_CSTATE_SHIFT		U(2)
+#define PWR_CPU2D2SR_DSTATE_MASK		GENMASK_32(10, 8)
+#define PWR_CPU2D2SR_DSTATE_SHIFT		U(8)
+
+/* PWR_CPU3D3SR register fields */
+#define PWR_CPU3D3SR_CSTATE_MASK		GENMASK_32(3, 2)
+#define PWR_CPU3D3SR_CSTATE_SHIFT		U(2)
+#define PWR_CPU3D3SR_DSTATE_MASK		GENMASK_32(10, 8)
+#define PWR_CPU3D3SR_DSTATE_SHIFT		U(8)
+
+/* PWR_DBGR register fields */
+#define PWR_DBGR_FD3S				BIT_32(0)
+#define PWR_DBGR_VDDIOKRETRAM			BIT_32(16)
+#define PWR_DBGR_VDDIOKBKPRAM			BIT_32(17)
+#define PWR_DBGR_VDDIOKD3			BIT_32(18)
+#define PWR_DBGR_VDDIOKLPSRAM1			BIT_32(19)
+
+/* PWR_VERR register fields */
+#define PWR_VERR_MINREV_MASK			GENMASK_32(3, 0)
+#define PWR_VERR_MINREV_SHIFT			U(0)
+#define PWR_VERR_MAJREV_MASK			GENMASK_32(7, 4)
+#define PWR_VERR_MAJREV_SHIFT			U(4)
+
+#endif /* STM32MP2_PWR_H */
diff --git a/include/drivers/st/stm32mp2_ram.h b/include/drivers/st/stm32mp2_ram.h
new file mode 100644
index 00000000..b6fa9288
--- /dev/null
+++ b/include/drivers/st/stm32mp2_ram.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_RAM_H
+#define STM32MP2_RAM_H
+
+bool stm32mp2_ddr_is_restored(void);
+int stm32mp2_ddr_probe(void);
+
+#endif /* STM32MP2_RAM_H */
diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h
index 61286b22..8fd5ed14 100644
--- a/include/drivers/st/stm32mp_clkfunc.h
+++ b/include/drivers/st/stm32mp_clkfunc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,8 +29,6 @@ int fdt_get_clock_id(int node);
 unsigned long fdt_get_uart_clock_freq(uintptr_t instance);
 
 void stm32mp_stgen_config(unsigned long rate);
-void stm32mp_stgen_restore_counter(unsigned long long value,
-				   unsigned long long offset_in_ms);
-unsigned long long stm32mp_stgen_get_counter(void);
+void stm32mp_stgen_restore_rate(void);
 
 #endif /* STM32MP_CLKFUNC_H */
diff --git a/include/drivers/st/stm32mp_ddr.h b/include/drivers/st/stm32mp_ddr.h
index 4535e3cb..57b06686 100644
--- a/include/drivers/st/stm32mp_ddr.h
+++ b/include/drivers/st/stm32mp_ddr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -26,9 +26,11 @@ enum stm32mp_ddr_reg_type {
 };
 
 struct stm32mp_ddr_reg_desc {
-	const char *name;
 	uint16_t offset;	/* Offset for base address */
 	uint8_t par_offset;	/* Offset for parameter array */
+#if !STM32MP13 && !STM32MP15
+	bool qd; /* quasi-dynamic register if true */
+#endif
 };
 
 struct stm32mp_ddr_reg_info {
@@ -57,13 +59,26 @@ struct stm32mp_ddr_info {
 	size_t size;    /* Memory size in byte = col * row * width */
 };
 
-#define TIMEOUT_US_1S	1000000U
+#define DDR_DELAY_1US		1U
+#define DDR_DELAY_2US		2U
+#define DDR_DELAY_10US		10U
+#define DDR_DELAY_50US		50U
+#define DDR_TIMEOUT_500US	500U
+#define DDR_TIMEOUT_US_1S	1000000U
 
 void stm32mp_ddr_set_reg(const struct stm32mp_ddr_priv *priv, enum stm32mp_ddr_reg_type type,
 			 const void *param, const struct stm32mp_ddr_reg_info *ddr_registers);
 void stm32mp_ddr_start_sw_done(struct stm32mp_ddrctl *ctl);
 void stm32mp_ddr_wait_sw_done_ack(struct stm32mp_ddrctl *ctl);
 void stm32mp_ddr_enable_axi_port(struct stm32mp_ddrctl *ctl);
+int stm32mp_ddr_disable_axi_port(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_enable_host_interface(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_disable_host_interface(struct stm32mp_ddrctl *ctl);
+int stm32mp_ddr_sw_selfref_entry(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_sw_selfref_exit(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_set_qd3_update_conditions(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_unset_qd3_update_conditions(struct stm32mp_ddrctl *ctl);
+void stm32mp_ddr_wait_refresh_update_done_ack(struct stm32mp_ddrctl *ctl);
 int stm32mp_board_ddr_power_init(enum ddr_type ddr_type);
 
 #endif /* STM32MP_DDR_H */
diff --git a/include/drivers/st/stm32mp_ddrctrl_regs.h b/include/drivers/st/stm32mp_ddrctrl_regs.h
index 79de86b2..f9f46aa4 100644
--- a/include/drivers/st/stm32mp_ddrctrl_regs.h
+++ b/include/drivers/st/stm32mp_ddrctrl_regs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -51,7 +51,8 @@ struct stm32mp_ddrctl {
 	uint32_t init7;		/* 0xec SDRAM Initialization 7 */
 	uint32_t dimmctl;	/* 0xf0 DIMM Control */
 	uint32_t rankctl;	/* 0xf4 Rank Control */
-	uint8_t reserved0f4[0x100 - 0xf8];
+	uint32_t rankctl1;	/* 0xf8 Rank Control 1 */
+	uint8_t reserved0fc[0x100 - 0xfc];
 	uint32_t dramtmg0;	/* 0x100 SDRAM Timing 0 */
 	uint32_t dramtmg1;	/* 0x104 SDRAM Timing 1 */
 	uint32_t dramtmg2;	/* 0x108 SDRAM Timing 2 */
@@ -112,7 +113,9 @@ struct stm32mp_ddrctl {
 	uint32_t perflpr1;	/* 0x264 Low Priority Read CAM 1 */
 	uint32_t reserved268;
 	uint32_t perfwr1;	/* 0x26c Write CAM 1 */
-	uint8_t reserved27c[0x300 - 0x270];
+	uint32_t sched3;	/* 0x270 Scheduler Control 3 */
+	uint32_t sched4;	/* 0x274 Scheduler Control 4 */
+	uint8_t reserved278[0x300 - 0x278];
 	uint32_t dbg0;		/* 0x300 Debug 0 */
 	uint32_t dbg1;		/* 0x304 Debug 1 */
 	uint32_t dbgcam;	/* 0x308 CAM Debug */
@@ -121,7 +124,8 @@ struct stm32mp_ddrctl {
 	uint8_t reserved314[0x320 - 0x314];
 	uint32_t swctl;		/* 0x320 Software Programming Control Enable */
 	uint32_t swstat;	/* 0x324 Software Programming Control Status */
-	uint8_t reserved328[0x36c - 0x328];
+	uint32_t swctlstatic;	/* 0x328 Statics Write Enable */
+	uint8_t reserved32c[0x36c - 0x32c];
 	uint32_t poisoncfg;	/* 0x36c AXI Poison Configuration Register */
 	uint32_t poisonstat;	/* 0x370 AXI Poison Status Register */
 	uint8_t reserved374[0x3f0 - 0x374];
@@ -153,7 +157,7 @@ struct stm32mp_ddrctl {
 	uint32_t pcfgqos1_1;	/* 0x548 Read QoS Configuration 1 */
 	uint32_t pcfgwqos0_1;	/* 0x54c Write QoS Configuration 0 */
 	uint32_t pcfgwqos1_1;	/* 0x550 Write QoS Configuration 1 */
-#endif
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
 
 	uint8_t reserved554[0xff0 - 0x554];
 	uint32_t umctl2_ver_number;	/* 0xff0 UMCTL2 Version Number */
@@ -170,6 +174,7 @@ struct stm32mp_ddrctl {
 #define DDRCTRL_RFSHCTL3			0x060
 #define DDRCTRL_RFSHTMG				0x064
 #define DDRCTRL_INIT0				0x0D0
+#define DDRCTRL_DFILPCFG0			0x198
 #define DDRCTRL_DFIMISC				0x1B0
 #define DDRCTRL_DBG1				0x304
 #define DDRCTRL_DBGCAM				0x308
@@ -181,7 +186,7 @@ struct stm32mp_ddrctl {
 #define DDRCTRL_PCTRL_0				0x490
 #if STM32MP_DDR_DUAL_AXI_PORT
 #define DDRCTRL_PCTRL_1				0x540
-#endif
+#endif /* STM32MP_DDR_DUAL_AXI_PORT */
 
 /* DDR Controller Register fields */
 #define DDRCTRL_MSTR_DDR3			BIT(0)
@@ -201,6 +206,8 @@ struct stm32mp_ddrctl {
 #define DDRCTRL_STAT_SELFREF_TYPE_MASK		GENMASK(5, 4)
 #define DDRCTRL_STAT_SELFREF_TYPE_ASR		(BIT(4) | BIT(5))
 #define DDRCTRL_STAT_SELFREF_TYPE_SR		BIT(5)
+#define DDRCTRL_STAT_SELFREF_STATE_MASK		GENMASK(9, 8)
+#define DDRCTRL_STAT_SELFREF_STATE_SRPD		BIT(9)
 
 #define DDRCTRL_MRCTRL0_MR_TYPE_WRITE		U(0)
 /* Only one rank supported */
@@ -217,6 +224,7 @@ struct stm32mp_ddrctl {
 #define DDRCTRL_PWRCTL_POWERDOWN_EN		BIT(1)
 #define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE	BIT(3)
 #define DDRCTRL_PWRCTL_SELFREF_SW		BIT(5)
+#define DDRCTRL_PWRCTL_STAY_IN_SELFREF		BIT(6)
 
 #define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK	GENMASK(23, 16)
 #define DDRCTRL_PWRTMG_SELFREF_TO_X32_0		BIT(16)
@@ -225,6 +233,9 @@ struct stm32mp_ddrctl {
 #define DDRCTRL_RFSHCTL3_REFRESH_UPDATE_LEVEL	BIT(1)
 
 #define DDRCTRL_HWLPCTL_HW_LP_EN		BIT(0)
+#define DDRCTRL_HWLPCTL_HW_LP_EXIT_IDLE_EN	BIT(1)
+#define DDRCTRL_HWLPCTL_HW_LP_IDLE_X32_MASK	GENMASK(27, 16)
+#define DDRCTRL_HWLPCTL_HW_LP_IDLE_X32_SHIFT	16
 
 #define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK	GENMASK(27, 16)
 #define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT	16
@@ -232,21 +243,31 @@ struct stm32mp_ddrctl {
 #define DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK	GENMASK(31, 30)
 #define DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL	BIT(30)
 
+#define DDRCTRL_DFILPCFG0_DFI_LP_EN_SR		BIT(8)
+
 #define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN	BIT(0)
 #define DDRCTRL_DFIMISC_DFI_INIT_START		BIT(5)
+#define DDRCTRL_DFIMISC_DFI_FREQUENCY		GENMASK(12, 8)
 
 #define DDRCTRL_DFISTAT_DFI_INIT_COMPLETE	BIT(0)
+#define DDRCTRL_DFISTAT_DFI_LP_ACK		BIT(1)
 
+#define DDRCTRL_DBG1_DIS_DQ			BIT(0)
 #define DDRCTRL_DBG1_DIS_HIF			BIT(1)
 
 #define DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY	BIT(29)
 #define DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY	BIT(28)
 #define DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY		BIT(26)
+#define DDRCTRL_DBGCAM_DBG_RD_Q_EMPTY		BIT(25)
 #define DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH		GENMASK(12, 8)
 #define DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH		GENMASK(4, 0)
 #define DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY \
 		(DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY | \
 		 DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY)
+#define DDRCTRL_DBG_Q_AND_DATA_PIPELINE_EMPTY \
+		(DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \
+		 DDRCTRL_DBGCAM_DBG_RD_Q_EMPTY | \
+		 DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY)
 #define DDRCTRL_DBGCAM_DBG_Q_DEPTH \
 		(DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \
 		 DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH | \
diff --git a/include/drivers/st/stm32mp_pmic.h b/include/drivers/st/stm32mp_pmic.h
index 303c5714..73845712 100644
--- a/include/drivers/st/stm32mp_pmic.h
+++ b/include/drivers/st/stm32mp_pmic.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,13 +41,6 @@ static inline void print_pmic_info_and_debug(void)
 }
 #endif
 
-/*
- * pmic_ddr_power_init - Initialize regulators required for DDR
- *
- * Returns 0 on success, and negative values on errors
- */
-int pmic_ddr_power_init(enum ddr_type ddr_type);
-
 /*
  * pmic_voltages_init - Update voltages for platform init
  *
diff --git a/include/drivers/st/stm32mp_pmic2.h b/include/drivers/st/stm32mp_pmic2.h
new file mode 100644
index 00000000..51eba38c
--- /dev/null
+++ b/include/drivers/st/stm32mp_pmic2.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_PMIC2_H
+#define STM32MP_PMIC2_H
+
+#include <stdbool.h>
+#include <drivers/st/regulator.h>
+
+#include <platform_def.h>
+
+/*
+ * dt_pmic_status - Check PMIC status from device tree
+ *
+ * Returns the status of the PMIC (secure, non-secure), or a negative value on
+ * error
+ */
+int dt_pmic_status(void);
+
+/*
+ * initialize_pmic_i2c - Initialize I2C for the PMIC control
+ *
+ * Returns true if PMIC is available, false if not found, panics on errors
+ */
+bool initialize_pmic_i2c(void);
+
+/*
+ * initialize_pmic - Main PMIC initialization function, called at platform init
+ *
+ * Panics on errors
+ */
+void initialize_pmic(void);
+
+/*
+ * stpmic2_set_prop - Set PMIC2 proprietary property
+ *
+ * Returns non zero on errors
+ */
+int stpmic2_set_prop(const struct regul_description *desc, uint16_t prop, uint32_t value);
+
+/*
+ * pmic_switch_off - switch off the platform with PMIC
+ *
+ * Panics on errors
+ */
+void pmic_switch_off(void);
+
+#endif /* STM32MP_PMIC2_H */
diff --git a/include/drivers/st/stm32mp_reset.h b/include/drivers/st/stm32mp_reset.h
index 84448050..a8648b43 100644
--- a/include/drivers/st/stm32mp_reset.h
+++ b/include/drivers/st/stm32mp_reset.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,4 +47,9 @@ static inline void stm32mp_reset_release(uint32_t reset_id)
 	(void)stm32mp_reset_deassert(reset_id, 0U);
 }
 
+/*
+ * Manage system reset control
+ */
+void __dead2 stm32mp_system_reset(void);
+
 #endif /* STM32MP_RESET_H */
diff --git a/include/drivers/st/stm32mp_risab_regs.h b/include/drivers/st/stm32mp_risab_regs.h
new file mode 100644
index 00000000..1f49bf69
--- /dev/null
+++ b/include/drivers/st/stm32mp_risab_regs.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP_RISAB_REGS_H
+#define STM32MP_RISAB_REGS_H
+
+#define RISAB_CR				U(0x00)
+#define RISAB_IASR				U(0x08)
+#define RISAB_IACR				U(0x0C)
+#define RISAB_RIFLOCKR				U(0x10)
+#define RISAB_IAESR				U(0x20)
+#define RISAB_IADDR				U(0x24)
+#define RISAB_PG0_SECCFGR			U(0x100)
+#define RISAB_PG1_SECCFGR			U(0x104)
+#define RISAB_PG2_SECCFGR			U(0x108)
+#define RISAB_PG3_SECCFGR			U(0x10C)
+#define RISAB_PG4_SECCFGR			U(0x110)
+#define RISAB_PG5_SECCFGR			U(0x114)
+#define RISAB_PG6_SECCFGR			U(0x118)
+#define RISAB_PG7_SECCFGR			U(0x11C)
+#define RISAB_PG8_SECCFGR			U(0x120)
+#define RISAB_PG9_SECCFGR			U(0x124)
+#define RISAB_PG10_SECCFGR			U(0x128)
+#define RISAB_PG11_SECCFGR			U(0x12C)
+#define RISAB_PG12_SECCFGR			U(0x130)
+#define RISAB_PG13_SECCFGR			U(0x134)
+#define RISAB_PG14_SECCFGR			U(0x138)
+#define RISAB_PG15_SECCFGR			U(0x13C)
+#define RISAB_PG16_SECCFGR			U(0x140)
+#define RISAB_PG17_SECCFGR			U(0x144)
+#define RISAB_PG18_SECCFGR			U(0x148)
+#define RISAB_PG19_SECCFGR			U(0x14C)
+#define RISAB_PG20_SECCFGR			U(0x150)
+#define RISAB_PG21_SECCFGR			U(0x154)
+#define RISAB_PG22_SECCFGR			U(0x158)
+#define RISAB_PG23_SECCFGR			U(0x15C)
+#define RISAB_PG24_SECCFGR			U(0x160)
+#define RISAB_PG25_SECCFGR			U(0x164)
+#define RISAB_PG26_SECCFGR			U(0x168)
+#define RISAB_PG27_SECCFGR			U(0x16C)
+#define RISAB_PG28_SECCFGR			U(0x170)
+#define RISAB_PG29_SECCFGR			U(0x174)
+#define RISAB_PG30_SECCFGR			U(0x178)
+#define RISAB_PG31_SECCFGR			U(0x17C)
+#define RISAB_PG0_PRIVCFGR			U(0x200)
+#define RISAB_PG1_PRIVCFGR			U(0x204)
+#define RISAB_PG2_PRIVCFGR			U(0x208)
+#define RISAB_PG3_PRIVCFGR			U(0x20C)
+#define RISAB_PG4_PRIVCFGR			U(0x210)
+#define RISAB_PG5_PRIVCFGR			U(0x214)
+#define RISAB_PG6_PRIVCFGR			U(0x218)
+#define RISAB_PG7_PRIVCFGR			U(0x21C)
+#define RISAB_PG8_PRIVCFGR			U(0x220)
+#define RISAB_PG9_PRIVCFGR			U(0x224)
+#define RISAB_PG10_PRIVCFGR			U(0x228)
+#define RISAB_PG11_PRIVCFGR			U(0x22C)
+#define RISAB_PG12_PRIVCFGR			U(0x230)
+#define RISAB_PG13_PRIVCFGR			U(0x234)
+#define RISAB_PG14_PRIVCFGR			U(0x238)
+#define RISAB_PG15_PRIVCFGR			U(0x23C)
+#define RISAB_PG16_PRIVCFGR			U(0x240)
+#define RISAB_PG17_PRIVCFGR			U(0x244)
+#define RISAB_PG18_PRIVCFGR			U(0x248)
+#define RISAB_PG19_PRIVCFGR			U(0x24C)
+#define RISAB_PG20_PRIVCFGR			U(0x250)
+#define RISAB_PG21_PRIVCFGR			U(0x254)
+#define RISAB_PG22_PRIVCFGR			U(0x258)
+#define RISAB_PG23_PRIVCFGR			U(0x25C)
+#define RISAB_PG24_PRIVCFGR			U(0x260)
+#define RISAB_PG25_PRIVCFGR			U(0x264)
+#define RISAB_PG26_PRIVCFGR			U(0x268)
+#define RISAB_PG27_PRIVCFGR			U(0x26C)
+#define RISAB_PG28_PRIVCFGR			U(0x270)
+#define RISAB_PG29_PRIVCFGR			U(0x274)
+#define RISAB_PG30_PRIVCFGR			U(0x278)
+#define RISAB_PG31_PRIVCFGR			U(0x27C)
+#define RISAB_PG0_C2PRIVCFGR			U(0x600)
+#define RISAB_PG1_C2PRIVCFGR			U(0x604)
+#define RISAB_PG2_C2PRIVCFGR			U(0x608)
+#define RISAB_PG3_C2PRIVCFGR			U(0x60C)
+#define RISAB_PG4_C2PRIVCFGR			U(0x610)
+#define RISAB_PG5_C2PRIVCFGR			U(0x614)
+#define RISAB_PG6_C2PRIVCFGR			U(0x618)
+#define RISAB_PG7_C2PRIVCFGR			U(0x61C)
+#define RISAB_PG8_C2PRIVCFGR			U(0x620)
+#define RISAB_PG9_C2PRIVCFGR			U(0x624)
+#define RISAB_PG10_C2PRIVCFGR			U(0x628)
+#define RISAB_PG11_C2PRIVCFGR			U(0x62C)
+#define RISAB_PG12_C2PRIVCFGR			U(0x630)
+#define RISAB_PG13_C2PRIVCFGR			U(0x634)
+#define RISAB_PG14_C2PRIVCFGR			U(0x638)
+#define RISAB_PG15_C2PRIVCFGR			U(0x63C)
+#define RISAB_PG16_C2PRIVCFGR			U(0x640)
+#define RISAB_PG17_C2PRIVCFGR			U(0x644)
+#define RISAB_PG18_C2PRIVCFGR			U(0x648)
+#define RISAB_PG19_C2PRIVCFGR			U(0x64C)
+#define RISAB_PG20_C2PRIVCFGR			U(0x650)
+#define RISAB_PG21_C2PRIVCFGR			U(0x654)
+#define RISAB_PG22_C2PRIVCFGR			U(0x658)
+#define RISAB_PG23_C2PRIVCFGR			U(0x65C)
+#define RISAB_PG24_C2PRIVCFGR			U(0x660)
+#define RISAB_PG25_C2PRIVCFGR			U(0x664)
+#define RISAB_PG26_C2PRIVCFGR			U(0x668)
+#define RISAB_PG27_C2PRIVCFGR			U(0x66C)
+#define RISAB_PG28_C2PRIVCFGR			U(0x670)
+#define RISAB_PG29_C2PRIVCFGR			U(0x674)
+#define RISAB_PG30_C2PRIVCFGR			U(0x678)
+#define RISAB_PG31_C2PRIVCFGR			U(0x67C)
+#define RISAB_CID0PRIVCFGR			U(0x800)
+#define RISAB_CID0RDCFGR			U(0x808)
+#define RISAB_CID0WRCFGR			U(0x810)
+#define RISAB_CID1PRIVCFGR			U(0x820)
+#define RISAB_CID1RDCFGR			U(0x828)
+#define RISAB_CID1WRCFGR			U(0x830)
+#define RISAB_CID2PRIVCFGR			U(0x840)
+#define RISAB_CID2RDCFGR			U(0x848)
+#define RISAB_CID2WRCFGR			U(0x850)
+#define RISAB_CID3PRIVCFGR			U(0x860)
+#define RISAB_CID3RDCFGR			U(0x868)
+#define RISAB_CID3WRCFGR			U(0x870)
+#define RISAB_CID4PRIVCFGR			U(0x880)
+#define RISAB_CID4RDCFGR			U(0x888)
+#define RISAB_CID4WRCFGR			U(0x890)
+#define RISAB_CID5PRIVCFGR			U(0x8A0)
+#define RISAB_CID5RDCFGR			U(0x8A8)
+#define RISAB_CID5WRCFGR			U(0x8B0)
+#define RISAB_CID6PRIVCFGR			U(0x8C0)
+#define RISAB_CID6RDCFGR			U(0x8C8)
+#define RISAB_CID6WRCFGR			U(0x8D0)
+#define RISAB_PG0_CIDCFGR			U(0xA00)
+#define RISAB_PG1_CIDCFGR			U(0xA04)
+#define RISAB_PG2_CIDCFGR			U(0xA08)
+#define RISAB_PG3_CIDCFGR			U(0xA0C)
+#define RISAB_PG4_CIDCFGR			U(0xA10)
+#define RISAB_PG5_CIDCFGR			U(0xA14)
+#define RISAB_PG6_CIDCFGR			U(0xA18)
+#define RISAB_PG7_CIDCFGR			U(0xA1C)
+#define RISAB_PG8_CIDCFGR			U(0xA20)
+#define RISAB_PG9_CIDCFGR			U(0xA24)
+#define RISAB_PG10_CIDCFGR			U(0xA28)
+#define RISAB_PG11_CIDCFGR			U(0xA2C)
+#define RISAB_PG12_CIDCFGR			U(0xA30)
+#define RISAB_PG13_CIDCFGR			U(0xA34)
+#define RISAB_PG14_CIDCFGR			U(0xA38)
+#define RISAB_PG15_CIDCFGR			U(0xA3C)
+#define RISAB_PG16_CIDCFGR			U(0xA40)
+#define RISAB_PG17_CIDCFGR			U(0xA44)
+#define RISAB_PG18_CIDCFGR			U(0xA48)
+#define RISAB_PG19_CIDCFGR			U(0xA4C)
+#define RISAB_PG20_CIDCFGR			U(0xA50)
+#define RISAB_PG21_CIDCFGR			U(0xA54)
+#define RISAB_PG22_CIDCFGR			U(0xA58)
+#define RISAB_PG23_CIDCFGR			U(0xA5C)
+#define RISAB_PG24_CIDCFGR			U(0xA60)
+#define RISAB_PG25_CIDCFGR			U(0xA64)
+#define RISAB_PG26_CIDCFGR			U(0xA68)
+#define RISAB_PG27_CIDCFGR			U(0xA6C)
+#define RISAB_PG28_CIDCFGR			U(0xA70)
+#define RISAB_PG29_CIDCFGR			U(0xA74)
+#define RISAB_PG30_CIDCFGR			U(0xA78)
+#define RISAB_PG31_CIDCFGR			U(0xA7C)
+#define RISAB_HWCFGR3				U(0xFE8)
+#define RISAB_HWCFGR2				U(0xFEC)
+#define RISAB_HWCFGR1				U(0xFF0)
+#define RISAB_VERR				U(0xFF4)
+#define RISAB_IPIDR				U(0xFF8)
+#define RISAB_SIDR				U(0xFFC)
+
+/* RISAB_CR register fields */
+#define RISAB_CR_GLOCK				BIT(0)
+#define RISAB_CR_SRWIAD				BIT(31)
+
+/* RISAB_IASR register fields */
+#define RISAB_IASR_CAEF				BIT(0)
+#define RISAB_IASR_IAEF				BIT(1)
+
+/* RISAB_IACR register fields */
+#define RISAB_IACR_CAEF				BIT(0)
+#define RISAB_IACR_IAEF				BIT(1)
+
+/* RISAB_RIFLOCKR register fields */
+#define RISAB_RIFLOCKR_RLOCK0			BIT(0)
+#define RISAB_RIFLOCKR_RLOCK1			BIT(1)
+#define RISAB_RIFLOCKR_RLOCK2			BIT(2)
+#define RISAB_RIFLOCKR_RLOCK3			BIT(3)
+#define RISAB_RIFLOCKR_RLOCK4			BIT(4)
+#define RISAB_RIFLOCKR_RLOCK5			BIT(5)
+#define RISAB_RIFLOCKR_RLOCK6			BIT(6)
+#define RISAB_RIFLOCKR_RLOCK7			BIT(7)
+#define RISAB_RIFLOCKR_RLOCK8			BIT(8)
+#define RISAB_RIFLOCKR_RLOCK9			BIT(9)
+#define RISAB_RIFLOCKR_RLOCK10			BIT(10)
+#define RISAB_RIFLOCKR_RLOCK11			BIT(11)
+#define RISAB_RIFLOCKR_RLOCK12			BIT(12)
+#define RISAB_RIFLOCKR_RLOCK13			BIT(13)
+#define RISAB_RIFLOCKR_RLOCK14			BIT(14)
+#define RISAB_RIFLOCKR_RLOCK15			BIT(15)
+#define RISAB_RIFLOCKR_RLOCK16			BIT(16)
+#define RISAB_RIFLOCKR_RLOCK17			BIT(17)
+#define RISAB_RIFLOCKR_RLOCK18			BIT(18)
+#define RISAB_RIFLOCKR_RLOCK19			BIT(19)
+#define RISAB_RIFLOCKR_RLOCK20			BIT(20)
+#define RISAB_RIFLOCKR_RLOCK21			BIT(21)
+#define RISAB_RIFLOCKR_RLOCK22			BIT(22)
+#define RISAB_RIFLOCKR_RLOCK23			BIT(23)
+#define RISAB_RIFLOCKR_RLOCK24			BIT(24)
+#define RISAB_RIFLOCKR_RLOCK25			BIT(25)
+#define RISAB_RIFLOCKR_RLOCK26			BIT(26)
+#define RISAB_RIFLOCKR_RLOCK27			BIT(27)
+#define RISAB_RIFLOCKR_RLOCK28			BIT(28)
+#define RISAB_RIFLOCKR_RLOCK29			BIT(29)
+#define RISAB_RIFLOCKR_RLOCK30			BIT(30)
+#define RISAB_RIFLOCKR_RLOCK31			BIT(31)
+
+/* RISAB_IAESR register fields */
+#define RISAB_IAESR_IACID_MASK			GENMASK(2, 0)
+#define RISAB_IAESR_IACID_SHIFT			0
+#define RISAB_IAESR_IAPRIV			BIT(4)
+#define RISAB_IAESR_IASEC			BIT(5)
+#define RISAB_IAESR_IANRW			BIT(7)
+
+/* RISAB_PGx_SECCFGR register fields */
+#define RISAB_PGx_SECCFGR_SEC(_y)		BIT(_y)
+
+/* RISAB_PGx_PRIVCFGR register fields */
+#define RISAB_PGx_PRIVCFGR_PRIV(_y)		BIT(_y)
+
+/* RISAB_PGx_CmPRIVCFGR register fields */
+#define RISAB_PGx_CmPRIVCFGR_PRIV(_y)		BIT(_y)
+
+/* RISAB_CIDxPRIVCFGR register fields */
+#define RISAB_CIDxPRIVCFGR_PPRIV(_y)		BIT(_y)
+
+/* RISAB_CIDxRDCFGR register fields */
+#define RISAB_CIDxRDCFGR_PRDEN(_y)		BIT(_y)
+
+/* RISAB_CIDxWRCFGR register fields */
+#define RISAB_CIDxWRCFGR_PWREN(_y)		BIT(_y)
+
+/* RISAB_PGx_CIDCFGR register fields */
+#define RISAB_PGx_CIDCFGR_CFEN			BIT(0)
+#define RISAB_PGx_CIDCFGR_DCEN			BIT(2)
+#define RISAB_PGx_CIDCFGR_DCCID_MASK		GENMASK(6, 4)
+#define RISAB_PGx_CIDCFGR_DCCID_SHIFT		4
+
+/* RISAB_HWCFGR1 register fields */
+#define RISAB_HWCFGR1_CFG1_MASK			GENMASK(3, 0)
+#define RISAB_HWCFGR1_CFG1_SHIFT		0
+#define RISAB_HWCFGR1_CFG2_MASK			GENMASK(7, 4)
+#define RISAB_HWCFGR1_CFG2_SHIFT		4
+#define RISAB_HWCFGR1_CFG3_MASK			GENMASK(11, 8)
+#define RISAB_HWCFGR1_CFG3_SHIFT		8
+#define RISAB_HWCFGR1_CFG4_MASK			GENMASK(15, 12)
+#define RISAB_HWCFGR1_CFG4_SHIFT		12
+#define RISAB_HWCFGR1_CFG5_MASK			GENMASK(19, 16)
+#define RISAB_HWCFGR1_CFG5_SHIFT		16
+#define RISAB_HWCFGR1_CFG6_MASK			GENMASK(23, 20)
+#define RISAB_HWCFGR1_CFG6_SHIFT		20
+#define RISAB_HWCFGR1_CFG7_MASK			GENMASK(27, 24)
+#define RISAB_HWCFGR1_CFG7_SHIFT		24
+
+/* RISAB_VERR register fields */
+#define RISAB_VERR_MINREV_MASK			GENMASK(3, 0)
+#define RISAB_VERR_MINREV_SHIFT			0
+#define RISAB_VERR_MAJREV_MASK			GENMASK(7, 4)
+#define RISAB_VERR_MAJREV_SHIFT			4
+
+#endif /* STM32MP_RISAB_REGS_H */
diff --git a/include/drivers/st/stpmic2.h b/include/drivers/st/stpmic2.h
new file mode 100644
index 00000000..58ba64ae
--- /dev/null
+++ b/include/drivers/st/stpmic2.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STPMIC2_H
+#define STPMIC2_H
+
+#include <drivers/st/stm32_i2c.h>
+#include <lib/utils_def.h>
+
+enum {
+	STPMIC2_BUCK1 = 0,
+	STPMIC2_BUCK2,
+	STPMIC2_BUCK3,
+	STPMIC2_BUCK4,
+	STPMIC2_BUCK5,
+	STPMIC2_BUCK6,
+	STPMIC2_BUCK7,
+	STPMIC2_REFDDR,
+	STPMIC2_LDO1,
+	STPMIC2_LDO2,
+	STPMIC2_LDO3,
+	STPMIC2_LDO4,
+	STPMIC2_LDO5,
+	STPMIC2_LDO6,
+	STPMIC2_LDO7,
+	STPMIC2_LDO8,
+	STPMIC2_NB_REG
+};
+
+/* Status Registers */
+#define PRODUCT_ID		0x00
+#define VERSION_SR		0x01
+#define TURN_ON_SR		0x02
+#define TURN_OFF_SR		0x03
+#define RESTART_SR		0x04
+#define OCP_SR1			0x05
+#define OCP_SR2			0x06
+#define EN_SR1			0x07
+#define EN_SR2			0x08
+#define FS_CNT_SR1		0x09
+#define FS_CNT_SR2		0x0A
+#define FS_CNT_SR3		0x0B
+#define MODE_SR			0x0C
+/* Control Registers */
+#define MAIN_CR			0x10
+#define VINLOW_CR		0x11
+#define PKEY_LKP_CR		0x12
+#define WDG_CR			0x13
+#define WDG_TMR_CR		0x14
+#define WDG_TMR_SR		0x15
+#define FS_OCP_CR1		0x16
+#define FS_OCP_CR2		0x17
+#define PADS_PULL_CR		0x18
+#define BUCKS_PD_CR1		0x19
+#define BUCKS_PD_CR2		0x1A
+#define LDOS_PD_CR1		0x1B
+#define LDOS_PD_CR2		0x1C
+#define BUCKS_MRST_CR		0x1D
+#define LDOS_MRST_CR		0x1E
+/* Buck CR */
+#define BUCK1_MAIN_CR1		0x20
+#define BUCK1_MAIN_CR2		0x21
+#define BUCK1_ALT_CR1		0x22
+#define BUCK1_ALT_CR2		0x23
+#define BUCK1_PWRCTRL_CR	0x24
+#define BUCK2_MAIN_CR1		0x25
+#define BUCK2_MAIN_CR2		0x26
+#define BUCK2_ALT_CR1		0x27
+#define BUCK2_ALT_CR2		0x28
+#define BUCK2_PWRCTRL_CR	0x29
+#define BUCK3_MAIN_CR1		0x2A
+#define BUCK3_MAIN_CR2		0x2B
+#define BUCK3_ALT_CR1		0x2C
+#define BUCK3_ALT_CR2		0x2D
+#define BUCK3_PWRCTRL_CR	0x2E
+#define BUCK4_MAIN_CR1		0x2F
+#define BUCK4_MAIN_CR2		0x30
+#define BUCK4_ALT_CR1		0x31
+#define BUCK4_ALT_CR2		0x32
+#define BUCK4_PWRCTRL_CR	0x33
+#define BUCK5_MAIN_CR1		0x34
+#define BUCK5_MAIN_CR2		0x35
+#define BUCK5_ALT_CR1		0x36
+#define BUCK5_ALT_CR2		0x37
+#define BUCK5_PWRCTRL_CR	0x38
+#define BUCK6_MAIN_CR1		0x39
+#define BUCK6_MAIN_CR2		0x3A
+#define BUCK6_ALT_CR1		0x3B
+#define BUCK6_ALT_CR2		0x3C
+#define BUCK6_PWRCTRL_CR	0x3D
+#define BUCK7_MAIN_CR1		0x3E
+#define BUCK7_MAIN_CR2		0x3F
+#define BUCK7_ALT_CR1		0x40
+#define BUCK7_ALT_CR2		0x41
+#define BUCK7_PWRCTRL_CR	0x42
+/* LDO CR */
+#define LDO1_MAIN_CR		0x4C
+#define LDO1_ALT_CR		0x4D
+#define LDO1_PWRCTRL_CR		0x4E
+#define LDO2_MAIN_CR		0x4F
+#define LDO2_ALT_CR		0x50
+#define LDO2_PWRCTRL_CR		0x51
+#define LDO3_MAIN_CR		0x52
+#define LDO3_ALT_CR		0x53
+#define LDO3_PWRCTRL_CR		0x54
+#define LDO4_MAIN_CR		0x55
+#define LDO4_ALT_CR		0x56
+#define LDO4_PWRCTRL_CR		0x57
+#define LDO5_MAIN_CR		0x58
+#define LDO5_ALT_CR		0x59
+#define LDO5_PWRCTRL_CR		0x5A
+#define LDO6_MAIN_CR		0x5B
+#define LDO6_ALT_CR		0x5C
+#define LDO6_PWRCTRL_CR		0x5D
+#define LDO7_MAIN_CR		0x5E
+#define LDO7_ALT_CR		0x5F
+#define LDO7_PWRCTRL_CR		0x60
+#define LDO8_MAIN_CR		0x61
+#define LDO8_ALT_CR		0x62
+#define LDO8_PWRCTRL_CR		0x63
+#define REFDDR_MAIN_CR		0x64
+#define REFDDR_ALT_CR		0x65
+#define REFDDR_PWRCTRL_CR	0x66
+/* INTERRUPT CR */
+#define INT_PENDING_R1		0x70
+#define INT_PENDING_R2		0x71
+#define INT_PENDING_R3		0x72
+#define INT_PENDING_R4		0x73
+#define INT_CLEAR_R1		0x74
+#define INT_CLEAR_R2		0x75
+#define INT_CLEAR_R3		0x76
+#define INT_CLEAR_R4		0x77
+#define INT_MASK_R1		0x78
+#define INT_MASK_R2		0x79
+#define INT_MASK_R3		0x7A
+#define INT_MASK_R4		0x7B
+#define INT_SRC_R1		0x7C
+#define INT_SRC_R2		0x7D
+#define INT_SRC_R3		0x7E
+#define INT_SRC_R4		0x7F
+#define INT_DBG_LATCH_R1	0x80
+#define INT_DBG_LATCH_R2	0x81
+#define INT_DBG_LATCH_R3	0x82
+#define INT_DBG_LATCH_R4	0x83
+
+/* BUCKS_MRST_CR bits definition */
+#define BUCK1_MRST		BIT(0)
+#define BUCK2_MRST		BIT(1)
+#define BUCK3_MRST		BIT(2)
+#define BUCK4_MRST		BIT(3)
+#define BUCK5_MRST		BIT(4)
+#define BUCK6_MRST		BIT(5)
+#define BUCK7_MRST		BIT(6)
+#define REFDDR_MRST		BIT(7)
+
+/* LDOS_MRST_CR bits definition */
+#define LDO1_MRST		BIT(0)
+#define LDO2_MRST		BIT(1)
+#define LDO3_MRST		BIT(2)
+#define LDO4_MRST		BIT(3)
+#define LDO5_MRST		BIT(4)
+#define LDO6_MRST		BIT(5)
+#define LDO7_MRST		BIT(6)
+#define LDO8_MRST		BIT(7)
+
+/* LDOx_MAIN_CR */
+#define LDO_VOLT_SHIFT		1
+#define LDO_BYPASS		BIT(6)
+#define LDO1_INPUT_SRC		BIT(7)
+#define LDO3_SNK_SRC		BIT(7)
+#define LDO4_INPUT_SRC_SHIFT	6
+#define LDO4_INPUT_SRC_MASK	GENMASK_32(7, 6)
+
+/* PWRCTRL register bit definition */
+#define PWRCTRL_EN		BIT(0)
+#define PWRCTRL_RS		BIT(1)
+#define PWRCTRL_SEL_SHIFT	2
+#define PWRCTRL_SEL_MASK	GENMASK_32(3, 2)
+
+/* BUCKx_MAIN_CR2 */
+#define PREG_MODE_SHIFT		1
+#define PREG_MODE_MASK		GENMASK_32(2, 1)
+
+/* BUCKS_PD_CR1 */
+#define BUCK1_PD_MASK		GENMASK_32(1, 0)
+#define BUCK2_PD_MASK		GENMASK_32(3, 2)
+#define BUCK3_PD_MASK		GENMASK_32(5, 4)
+#define BUCK4_PD_MASK		GENMASK_32(7, 6)
+
+#define BUCK1_PD_FAST		BIT(1)
+#define BUCK2_PD_FAST		BIT(3)
+#define BUCK3_PD_FAST		BIT(5)
+#define BUCK4_PD_FAST		BIT(7)
+
+/* BUCKS_PD_CR2 */
+#define BUCK5_PD_MASK		GENMASK_32(1, 0)
+#define BUCK6_PD_MASK		GENMASK_32(3, 2)
+#define BUCK7_PD_MASK		GENMASK_32(5, 4)
+
+#define BUCK5_PD_FAST		BIT(1)
+#define BUCK6_PD_FAST		BIT(3)
+#define BUCK7_PD_FAST		BIT(5)
+
+/* LDOS_PD_CR1 */
+#define LDO1_PD			BIT(0)
+#define LDO2_PD			BIT(1)
+#define LDO3_PD			BIT(2)
+#define LDO4_PD			BIT(3)
+#define LDO5_PD			BIT(4)
+#define LDO6_PD			BIT(5)
+#define LDO7_PD			BIT(6)
+#define LDO8_PD			BIT(7)
+
+/* LDOS_PD_CR2 */
+#define REFDDR_PD		BIT(0)
+
+/* FS_OCP_CR1 */
+#define FS_OCP_BUCK1		BIT(0)
+#define FS_OCP_BUCK2		BIT(1)
+#define FS_OCP_BUCK3		BIT(2)
+#define FS_OCP_BUCK4		BIT(3)
+#define FS_OCP_BUCK5		BIT(4)
+#define FS_OCP_BUCK6		BIT(5)
+#define FS_OCP_BUCK7		BIT(6)
+#define FS_OCP_REFDDR		BIT(7)
+
+/* FS_OCP_CR2 */
+#define FS_OCP_LDO1		BIT(0)
+#define FS_OCP_LDO2		BIT(1)
+#define FS_OCP_LDO3		BIT(2)
+#define FS_OCP_LDO4		BIT(3)
+#define FS_OCP_LDO5		BIT(4)
+#define FS_OCP_LDO6		BIT(5)
+#define FS_OCP_LDO7		BIT(6)
+#define FS_OCP_LDO8		BIT(7)
+
+/* IRQ definitions */
+#define IT_PONKEY_F	0
+#define IT_PONKEY_R	1
+#define IT_BUCK1_OCP	16
+#define IT_BUCK2_OCP	17
+#define IT_BUCK3_OCP	18
+#define IT_BUCK4_OCP	19
+#define IT_BUCK5_OCP	20
+#define IT_BUCK6_OCP	21
+#define IT_BUCK7_OCP	22
+#define IT_REFDDR_OCP	23
+#define IT_LDO1_OCP	24
+#define IT_LDO2_OCP	25
+#define IT_LDO3_OCP	26
+#define IT_LDO4_OCP	27
+#define IT_LDO5_OCP	28
+#define IT_LDO6_OCP	29
+#define IT_LDO7_OCP	30
+#define IT_LDO8_OCP	31
+
+enum stpmic2_prop_id {
+	STPMIC2_MASK_RESET = 0,
+	STPMIC2_PULL_DOWN,
+	STPMIC2_BYPASS,		/* arg: 1=set 0=reset */
+	STPMIC2_SINK_SOURCE,
+	STPMIC2_OCP,
+};
+
+struct pmic_handle_s {
+	struct i2c_handle_s *i2c_handle;
+	uint32_t i2c_addr;
+	unsigned int pmic_status;
+};
+
+int stpmic2_register_read(struct pmic_handle_s *pmic,
+			  uint8_t register_id, uint8_t *value);
+int stpmic2_register_write(struct pmic_handle_s *pmic,
+			   uint8_t register_id, uint8_t value);
+int stpmic2_register_update(struct pmic_handle_s *pmic,
+			    uint8_t register_id, uint8_t value, uint8_t mask);
+
+int stpmic2_regulator_set_state(struct pmic_handle_s *pmic,
+				uint8_t id, bool enable);
+int stpmic2_regulator_get_state(struct pmic_handle_s *pmic,
+				uint8_t id, bool *enabled);
+
+int stpmic2_regulator_levels_mv(struct pmic_handle_s *pmic,
+				uint8_t id, const uint16_t **levels,
+				size_t *levels_count);
+int stpmic2_regulator_get_voltage(struct pmic_handle_s *pmic,
+				  uint8_t id, uint16_t *val);
+int stpmic2_regulator_set_voltage(struct pmic_handle_s *pmic,
+				  uint8_t id, uint16_t millivolts);
+
+#if EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE
+void stpmic2_dump_regulators(struct pmic_handle_s *pmic);
+#endif
+
+int stpmic2_get_version(struct pmic_handle_s *pmic, uint8_t *val);
+int stpmic2_get_product_id(struct pmic_handle_s *pmic, uint8_t *val);
+
+int stpmic2_regulator_get_prop(struct pmic_handle_s *pmic, uint8_t id,
+			       enum stpmic2_prop_id prop);
+
+int stpmic2_regulator_set_prop(struct pmic_handle_s *pmic, uint8_t id,
+			       enum stpmic2_prop_id prop, uint32_t arg);
+
+#endif /*STPMIC2_H*/
diff --git a/include/drivers/usb_device.h b/include/drivers/usb_device.h
index 8fdb6ae1..d4c491c4 100644
--- a/include/drivers/usb_device.h
+++ b/include/drivers/usb_device.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #ifndef USB_DEVICE_H
 #define USB_DEVICE_H
 
+#include <stdbool.h>
 #include <stdint.h>
 
 #include <lib/utils_def.h>
diff --git a/include/dt-bindings/clock/stm32mp13-clks.h b/include/dt-bindings/clock/stm32mp13-clks.h
index 1d5bb783..031e4323 100644
--- a/include/dt-bindings/clock/stm32mp13-clks.h
+++ b/include/dt-bindings/clock/stm32mp13-clks.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */
 /*
- * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
+ * Copyright (C) STMicroelectronics 2022-2024 - All Rights Reserved
  * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
  */
 
@@ -193,7 +193,13 @@
 #define SAI1		160
 #define SAI2		161
 
-#define STM32MP1_LAST_CLK 162
+#define SPI1		162
+#define SPI2		163
+#define SPI3		164
+#define SPI4		165
+#define SPI5		166
+
+#define STM32MP1_LAST_CLK 167
 
 /* SCMI clock identifiers */
 #define CK_SCMI0_HSE		0
diff --git a/include/dt-bindings/clock/stm32mp15-clksrc.h b/include/dt-bindings/clock/stm32mp15-clksrc.h
index 3a3792da..e601b484 100644
--- a/include/dt-bindings/clock/stm32mp15-clksrc.h
+++ b/include/dt-bindings/clock/stm32mp15-clksrc.h
@@ -1,273 +1,413 @@
 /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
 /*
- * Copyright (C) 2017-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2017-2024, STMicroelectronics - All Rights Reserved
  */
 
 #ifndef _DT_BINDINGS_CLOCK_STM32MP15_CLKSRC_H_
 #define _DT_BINDINGS_CLOCK_STM32MP15_CLKSRC_H_
 
+#include <lib/utils_def.h>
+
+#define CMD_DIV		0
+#define CMD_MUX		1
+#define CMD_CLK		2
+
+#define CMD_ADDR_BIT	BIT(31)
+
+#define CMD_SHIFT	26
+#define CMD_MASK	GENMASK_32(31, 26)
+#define CMD_DATA_MASK	GENMASK_32(25, 0)
+
+#define DIV_ID_SHIFT	8
+#define DIV_ID_MASK	GENMASK_32(15, 8)
+
+#define DIV_DIVN_SHIFT	0
+#define DIV_DIVN_MASK	GENMASK_32(7, 0)
+
+#define MUX_ID_SHIFT	4
+#define MUX_ID_MASK	GENMASK_32(11, 4)
+
+#define MUX_SEL_SHIFT	0
+#define MUX_SEL_MASK	GENMASK_32(3, 0)
+
+#define CLK_ID_MASK	GENMASK_32(19, 11)
+#define CLK_ID_SHIFT	11
+#define CLK_ON_MASK	0x00000400
+#define CLK_ON_SHIFT	10
+#define CLK_DIV_MASK	GENMASK_32(9, 4)
+#define CLK_DIV_SHIFT	4
+#define CLK_SEL_MASK	GENMASK_32(3, 0)
+#define CLK_SEL_SHIFT	0
+
+#define DIV(div_id, div)	((CMD_DIV << CMD_SHIFT) |\
+				 ((div_id) << DIV_ID_SHIFT) |\
+				 (div))
+
+#define CLKSRC(mux_id, sel)	((CMD_MUX << CMD_SHIFT) |\
+				 ((mux_id) << MUX_ID_SHIFT) |\
+				 (sel))
+
+/* CLK output is enable */
+#define CLK_SRC(clk_id, sel)	((CMD_CLK << CMD_SHIFT) |\
+				 ((clk_id) << CLK_ID_SHIFT) |\
+				 (sel) | CLK_ON_MASK)
+
+#define CLK_DISABLED(clk_id)	((CMD_CLK << CMD_SHIFT) |\
+				 ((clk_id) << CLK_ID_SHIFT))
+
+#define CLK_ADDR_SHIFT		16
+#define CLK_ADDR_MASK		GENMASK_32(30, 16)
+#define CLK_ADDR_VAL_MASK	GENMASK_32(15, 0)
+
+#define DIV_PLL1DIVP	0
+#define DIV_PLL2DIVP	1
+#define DIV_PLL2DIVQ	2
+#define DIV_PLL2DIVR	3
+#define DIV_PLL3DIVP	4
+#define DIV_PLL3DIVQ	5
+#define DIV_PLL3DIVR	6
+#define DIV_PLL4DIVP	7
+#define DIV_PLL4DIVQ	8
+#define DIV_PLL4DIVR	9
+#define DIV_MPU		10
+#define DIV_AXI		11
+#define DIV_MCU		12
+#define DIV_APB1	13
+#define DIV_APB2	14
+#define DIV_APB3	15
+#define DIV_APB4	16
+#define DIV_APB5	17
+#define DIV_RTC		19
+#define DIV_MCO1	20
+#define DIV_MCO2	21
+#define DIV_HSI		22
+#define DIV_TRACE	23
+#define DIV_ETHPTP	24
+#define DIV_NB		25
+
+#define MUX_MPU		0
+#define MUX_AXI		1
+#define MUX_MCU		2
+#define MUX_PLL12	3
+#define MUX_PLL3	4
+#define MUX_PLL4	5
+#define MUX_CKPER	6
+#define MUX_RTC		7
+#define MUX_SDMMC12	8
+#define MUX_SDMMC3	9
+#define MUX_FMC		10
+#define MUX_QSPI	11
+#define MUX_RNG1	12
+#define MUX_RNG2	13
+#define MUX_USBPHY	14
+#define MUX_USBO	15
+#define MUX_STGEN	16
+#define MUX_SPDIF	17
+#define MUX_SPI2S1	18
+#define MUX_SPI2S23	19
+#define MUX_SPI45	20
+#define MUX_SPI6	21
+#define MUX_CEC		22
+#define MUX_I2C12	23
+#define MUX_I2C35	24
+#define MUX_I2C46	25
+#define MUX_LPTIM1	26
+#define MUX_LPTIM23	27
+#define MUX_LPTIM45	28
+#define MUX_UART1	29
+#define MUX_UART24	30
+#define MUX_UART35	31
+#define MUX_UART6	32
+#define MUX_UART78	33
+#define MUX_SAI1	34
+#define MUX_SAI2	35
+#define MUX_SAI3	36
+#define MUX_SAI4	37
+#define MUX_DSI		38
+#define MUX_FDCAN	39
+#define MUX_ADC		40
+#define MUX_ETH		41
+#define MUX_MCO1	42
+#define MUX_MCO2	43
+#define MUX_NB		44
+
 /* PLL output is enable when x=1, with x=p,q or r */
 #define PQR(p, q, r)	(((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
 
-/* st,clksrc: mandatory clock source */
-#define CLK_MPU_HSI		0x00000200
-#define CLK_MPU_HSE		0x00000201
-#define CLK_MPU_PLL1P		0x00000202
-#define CLK_MPU_PLL1P_DIV	0x00000203
-
-#define CLK_AXI_HSI		0x00000240
-#define CLK_AXI_HSE		0x00000241
-#define CLK_AXI_PLL2P		0x00000242
-
-#define CLK_MCU_HSI		0x00000480
-#define CLK_MCU_HSE		0x00000481
-#define CLK_MCU_CSI		0x00000482
-#define CLK_MCU_PLL3P		0x00000483
-
-#define CLK_PLL12_HSI		0x00000280
-#define CLK_PLL12_HSE		0x00000281
-
-#define CLK_PLL3_HSI		0x00008200
-#define CLK_PLL3_HSE		0x00008201
-#define CLK_PLL3_CSI		0x00008202
-
-#define CLK_PLL4_HSI		0x00008240
-#define CLK_PLL4_HSE		0x00008241
-#define CLK_PLL4_CSI		0x00008242
-#define CLK_PLL4_I2SCKIN	0x00008243
-
-#define CLK_RTC_DISABLED	0x00001400
-#define CLK_RTC_LSE		0x00001401
-#define CLK_RTC_LSI		0x00001402
-#define CLK_RTC_HSE		0x00001403
-
-#define CLK_MCO1_HSI		0x00008000
-#define CLK_MCO1_HSE		0x00008001
-#define CLK_MCO1_CSI		0x00008002
-#define CLK_MCO1_LSI		0x00008003
-#define CLK_MCO1_LSE		0x00008004
-#define CLK_MCO1_DISABLED	0x0000800F
-
-#define CLK_MCO2_MPU		0x00008040
-#define CLK_MCO2_AXI		0x00008041
-#define CLK_MCO2_MCU		0x00008042
-#define CLK_MCO2_PLL4P		0x00008043
-#define CLK_MCO2_HSE		0x00008044
-#define CLK_MCO2_HSI		0x00008045
-#define CLK_MCO2_DISABLED	0x0000804F
-
-/* st,pkcs: peripheral kernel clock source */
-
-#define CLK_I2C12_PCLK1		0x00008C00
-#define CLK_I2C12_PLL4R		0x00008C01
-#define CLK_I2C12_HSI		0x00008C02
-#define CLK_I2C12_CSI		0x00008C03
-#define CLK_I2C12_DISABLED	0x00008C07
-
-#define CLK_I2C35_PCLK1		0x00008C40
-#define CLK_I2C35_PLL4R		0x00008C41
-#define CLK_I2C35_HSI		0x00008C42
-#define CLK_I2C35_CSI		0x00008C43
-#define CLK_I2C35_DISABLED	0x00008C47
-
-#define CLK_I2C46_PCLK5		0x00000C00
-#define CLK_I2C46_PLL3Q		0x00000C01
-#define CLK_I2C46_HSI		0x00000C02
-#define CLK_I2C46_CSI		0x00000C03
-#define CLK_I2C46_DISABLED	0x00000C07
-
-#define CLK_SAI1_PLL4Q		0x00008C80
-#define CLK_SAI1_PLL3Q		0x00008C81
-#define CLK_SAI1_I2SCKIN	0x00008C82
-#define CLK_SAI1_CKPER		0x00008C83
-#define CLK_SAI1_PLL3R		0x00008C84
-#define CLK_SAI1_DISABLED	0x00008C87
-
-#define CLK_SAI2_PLL4Q		0x00008CC0
-#define CLK_SAI2_PLL3Q		0x00008CC1
-#define CLK_SAI2_I2SCKIN	0x00008CC2
-#define CLK_SAI2_CKPER		0x00008CC3
-#define CLK_SAI2_SPDIF		0x00008CC4
-#define CLK_SAI2_PLL3R		0x00008CC5
-#define CLK_SAI2_DISABLED	0x00008CC7
-
-#define CLK_SAI3_PLL4Q		0x00008D00
-#define CLK_SAI3_PLL3Q		0x00008D01
-#define CLK_SAI3_I2SCKIN	0x00008D02
-#define CLK_SAI3_CKPER		0x00008D03
-#define CLK_SAI3_PLL3R		0x00008D04
-#define CLK_SAI3_DISABLED	0x00008D07
-
-#define CLK_SAI4_PLL4Q		0x00008D40
-#define CLK_SAI4_PLL3Q		0x00008D41
-#define CLK_SAI4_I2SCKIN	0x00008D42
-#define CLK_SAI4_CKPER		0x00008D43
-#define CLK_SAI4_PLL3R		0x00008D44
-#define CLK_SAI4_DISABLED	0x00008D47
-
-#define CLK_SPI2S1_PLL4P	0x00008D80
-#define CLK_SPI2S1_PLL3Q	0x00008D81
-#define CLK_SPI2S1_I2SCKIN	0x00008D82
-#define CLK_SPI2S1_CKPER	0x00008D83
-#define CLK_SPI2S1_PLL3R	0x00008D84
-#define CLK_SPI2S1_DISABLED	0x00008D87
-
-#define CLK_SPI2S23_PLL4P	0x00008DC0
-#define CLK_SPI2S23_PLL3Q	0x00008DC1
-#define CLK_SPI2S23_I2SCKIN	0x00008DC2
-#define CLK_SPI2S23_CKPER	0x00008DC3
-#define CLK_SPI2S23_PLL3R	0x00008DC4
-#define CLK_SPI2S23_DISABLED	0x00008DC7
-
-#define CLK_SPI45_PCLK2		0x00008E00
-#define CLK_SPI45_PLL4Q		0x00008E01
-#define CLK_SPI45_HSI		0x00008E02
-#define CLK_SPI45_CSI		0x00008E03
-#define CLK_SPI45_HSE		0x00008E04
-#define CLK_SPI45_DISABLED	0x00008E07
-
-#define CLK_SPI6_PCLK5		0x00000C40
-#define CLK_SPI6_PLL4Q		0x00000C41
-#define CLK_SPI6_HSI		0x00000C42
-#define CLK_SPI6_CSI		0x00000C43
-#define CLK_SPI6_HSE		0x00000C44
-#define CLK_SPI6_PLL3Q		0x00000C45
-#define CLK_SPI6_DISABLED	0x00000C47
-
-#define CLK_UART6_PCLK2		0x00008E40
-#define CLK_UART6_PLL4Q		0x00008E41
-#define CLK_UART6_HSI		0x00008E42
-#define CLK_UART6_CSI		0x00008E43
-#define CLK_UART6_HSE		0x00008E44
-#define CLK_UART6_DISABLED	0x00008E47
-
-#define CLK_UART24_PCLK1	0x00008E80
-#define CLK_UART24_PLL4Q	0x00008E81
-#define CLK_UART24_HSI		0x00008E82
-#define CLK_UART24_CSI		0x00008E83
-#define CLK_UART24_HSE		0x00008E84
-#define CLK_UART24_DISABLED	0x00008E87
-
-#define CLK_UART35_PCLK1	0x00008EC0
-#define CLK_UART35_PLL4Q	0x00008EC1
-#define CLK_UART35_HSI		0x00008EC2
-#define CLK_UART35_CSI		0x00008EC3
-#define CLK_UART35_HSE		0x00008EC4
-#define CLK_UART35_DISABLED	0x00008EC7
-
-#define CLK_UART78_PCLK1	0x00008F00
-#define CLK_UART78_PLL4Q	0x00008F01
-#define CLK_UART78_HSI		0x00008F02
-#define CLK_UART78_CSI		0x00008F03
-#define CLK_UART78_HSE		0x00008F04
-#define CLK_UART78_DISABLED	0x00008F07
-
-#define CLK_UART1_PCLK5		0x00000C80
-#define CLK_UART1_PLL3Q		0x00000C81
-#define CLK_UART1_HSI		0x00000C82
-#define CLK_UART1_CSI		0x00000C83
-#define CLK_UART1_PLL4Q		0x00000C84
-#define CLK_UART1_HSE		0x00000C85
-#define CLK_UART1_DISABLED	0x00000C87
-
-#define CLK_SDMMC12_HCLK6	0x00008F40
-#define CLK_SDMMC12_PLL3R	0x00008F41
-#define CLK_SDMMC12_PLL4P	0x00008F42
-#define CLK_SDMMC12_HSI		0x00008F43
-#define CLK_SDMMC12_DISABLED	0x00008F47
-
-#define CLK_SDMMC3_HCLK2	0x00008F80
-#define CLK_SDMMC3_PLL3R	0x00008F81
-#define CLK_SDMMC3_PLL4P	0x00008F82
-#define CLK_SDMMC3_HSI		0x00008F83
-#define CLK_SDMMC3_DISABLED	0x00008F87
-
-#define CLK_ETH_PLL4P		0x00008FC0
-#define CLK_ETH_PLL3Q		0x00008FC1
-#define CLK_ETH_DISABLED	0x00008FC3
-
-#define CLK_QSPI_ACLK		0x00009000
-#define CLK_QSPI_PLL3R		0x00009001
-#define CLK_QSPI_PLL4P		0x00009002
-#define CLK_QSPI_CKPER		0x00009003
-
-#define CLK_FMC_ACLK		0x00009040
-#define CLK_FMC_PLL3R		0x00009041
-#define CLK_FMC_PLL4P		0x00009042
-#define CLK_FMC_CKPER		0x00009043
-
-#define CLK_FDCAN_HSE		0x000090C0
-#define CLK_FDCAN_PLL3Q		0x000090C1
-#define CLK_FDCAN_PLL4Q		0x000090C2
-#define CLK_FDCAN_PLL4R		0x000090C3
-
-#define CLK_SPDIF_PLL4P		0x00009140
-#define CLK_SPDIF_PLL3Q		0x00009141
-#define CLK_SPDIF_HSI		0x00009142
-#define CLK_SPDIF_DISABLED	0x00009143
-
-#define CLK_CEC_LSE		0x00009180
-#define CLK_CEC_LSI		0x00009181
-#define CLK_CEC_CSI_DIV122	0x00009182
-#define CLK_CEC_DISABLED	0x00009183
-
-#define CLK_USBPHY_HSE		0x000091C0
-#define CLK_USBPHY_PLL4R	0x000091C1
-#define CLK_USBPHY_HSE_DIV2	0x000091C2
-#define CLK_USBPHY_DISABLED	0x000091C3
-
-#define CLK_USBO_PLL4R		0x800091C0
-#define CLK_USBO_USBPHY		0x800091C1
-
-#define CLK_RNG1_CSI		0x00000CC0
-#define CLK_RNG1_PLL4R		0x00000CC1
-#define CLK_RNG1_LSE		0x00000CC2
-#define CLK_RNG1_LSI		0x00000CC3
-
-#define CLK_RNG2_CSI		0x00009200
-#define CLK_RNG2_PLL4R		0x00009201
-#define CLK_RNG2_LSE		0x00009202
-#define CLK_RNG2_LSI		0x00009203
-
-#define CLK_CKPER_HSI		0x00000D00
-#define CLK_CKPER_CSI		0x00000D01
-#define CLK_CKPER_HSE		0x00000D02
-#define CLK_CKPER_DISABLED	0x00000D03
-
-#define CLK_STGEN_HSI		0x00000D40
-#define CLK_STGEN_HSE		0x00000D41
-#define CLK_STGEN_DISABLED	0x00000D43
-
-#define CLK_DSI_DSIPLL		0x00009240
-#define CLK_DSI_PLL4P		0x00009241
-
-#define CLK_ADC_PLL4R		0x00009280
-#define CLK_ADC_CKPER		0x00009281
-#define CLK_ADC_PLL3Q		0x00009282
-#define CLK_ADC_DISABLED	0x00009283
-
-#define CLK_LPTIM45_PCLK3	0x000092C0
-#define CLK_LPTIM45_PLL4P	0x000092C1
-#define CLK_LPTIM45_PLL3Q	0x000092C2
-#define CLK_LPTIM45_LSE		0x000092C3
-#define CLK_LPTIM45_LSI		0x000092C4
-#define CLK_LPTIM45_CKPER	0x000092C5
-#define CLK_LPTIM45_DISABLED	0x000092C7
-
-#define CLK_LPTIM23_PCLK3	0x00009300
-#define CLK_LPTIM23_PLL4Q	0x00009301
-#define CLK_LPTIM23_CKPER	0x00009302
-#define CLK_LPTIM23_LSE		0x00009303
-#define CLK_LPTIM23_LSI		0x00009304
-#define CLK_LPTIM23_DISABLED	0x00009307
-
-#define CLK_LPTIM1_PCLK1	0x00009340
-#define CLK_LPTIM1_PLL4P	0x00009341
-#define CLK_LPTIM1_PLL3Q	0x00009342
-#define CLK_LPTIM1_LSE		0x00009343
-#define CLK_LPTIM1_LSI		0x00009344
-#define CLK_LPTIM1_CKPER	0x00009345
-#define CLK_LPTIM1_DISABLED	0x00009347
+/* st,clksrc: clock sources */
+#define CLK_MPU_HSI		CLKSRC(MUX_MPU, 0)
+#define CLK_MPU_HSE		CLKSRC(MUX_MPU, 1)
+#define CLK_MPU_PLL1P		CLKSRC(MUX_MPU, 2)
+#define CLK_MPU_PLL1P_DIV	CLKSRC(MUX_MPU, 3)
+
+#define CLK_AXI_HSI		CLKSRC(MUX_AXI, 0)
+#define CLK_AXI_HSE		CLKSRC(MUX_AXI, 1)
+#define CLK_AXI_PLL2P		CLKSRC(MUX_AXI, 2)
+
+#define CLK_MCU_HSI		CLKSRC(MUX_MCU, 0)
+#define CLK_MCU_HSE		CLKSRC(MUX_MCU, 1)
+#define CLK_MCU_CSI		CLKSRC(MUX_MCU, 2)
+#define CLK_MCU_PLL3P		CLKSRC(MUX_MCU, 3)
+
+#define CLK_PLL12_HSI		CLKSRC(MUX_PLL12, 0)
+#define CLK_PLL12_HSE		CLKSRC(MUX_PLL12, 1)
+
+#define CLK_PLL3_HSI		CLKSRC(MUX_PLL3, 0)
+#define CLK_PLL3_HSE		CLKSRC(MUX_PLL3, 1)
+#define CLK_PLL3_CSI		CLKSRC(MUX_PLL3, 2)
+
+#define CLK_PLL4_HSI		CLKSRC(MUX_PLL4, 0)
+#define CLK_PLL4_HSE		CLKSRC(MUX_PLL4, 1)
+#define CLK_PLL4_CSI		CLKSRC(MUX_PLL4, 2)
+#define CLK_PLL4_I2SCKIN	CLKSRC(MUX_PLL4, 3)
+
+#define CLK_RTC_DISABLED	CLK_DISABLED(RTC)
+#define CLK_RTC_LSE		CLK_SRC(RTC, 1)
+#define CLK_RTC_LSI		CLK_SRC(RTC, 2)
+#define CLK_RTC_HSE		CLK_SRC(RTC, 3)
+
+/* Register addresses of MCO1 & MCO2 */
+#define MCO1			0x800
+#define MCO2			0x804
+
+#define MCO_OFF			0
+#define MCO_ON			1
+#define MCO_STATUS_SHIFT	12
+
+#define MCO_ON_CFG(addr, sel)	(CMD_ADDR_BIT |\
+				((addr) << CLK_ADDR_SHIFT) |\
+				(MCO_ON << MCO_STATUS_SHIFT) |\
+				(sel))
+
+#define MCO_OFF_CFG(addr)	(CMD_ADDR_BIT |\
+				((addr) << CLK_ADDR_SHIFT) |\
+				(MCO_OFF << MCO_STATUS_SHIFT))
+
+#define CLK_MCO1_HSI		MCO_ON_CFG(MCO1, 0)
+#define CLK_MCO1_HSE		MCO_ON_CFG(MCO1, 1)
+#define CLK_MCO1_CSI		MCO_ON_CFG(MCO1, 2)
+#define CLK_MCO1_LSI		MCO_ON_CFG(MCO1, 3)
+#define CLK_MCO1_LSE		MCO_ON_CFG(MCO1, 4)
+#define CLK_MCO1_DISABLED	MCO_OFF_CFG(MCO1)
+
+#define CLK_MCO2_MPU		MCO_ON_CFG(MCO2, 0)
+#define CLK_MCO2_AXI		MCO_ON_CFG(MCO2, 1)
+#define CLK_MCO2_MCU		MCO_ON_CFG(MCO2, 2)
+#define CLK_MCO2_PLL4		MCO_ON_CFG(MCO2, 3)
+#define CLK_MCO2_HSE		MCO_ON_CFG(MCO2, 4)
+#define CLK_MCO2_HSI		MCO_ON_CFG(MCO2, 5)
+#define CLK_MCO2_DISABLED	MCO_OFF_CFG(MCO2)
+
+#define CLK_I2C12_PCLK1		CLKSRC(MUX_I2C12, 0)
+#define CLK_I2C12_PLL4R		CLKSRC(MUX_I2C12, 1)
+#define CLK_I2C12_HSI		CLKSRC(MUX_I2C12, 2)
+#define CLK_I2C12_CSI		CLKSRC(MUX_I2C12, 3)
+#define CLK_I2C12_DISABLED	CLKSRC(MUX_I2C12, 7)
+
+#define CLK_I2C35_PCLK1		CLKSRC(MUX_I2C35, 0)
+#define CLK_I2C35_PLL4R		CLKSRC(MUX_I2C35, 1)
+#define CLK_I2C35_HSI		CLKSRC(MUX_I2C35, 2)
+#define CLK_I2C35_CSI		CLKSRC(MUX_I2C35, 3)
+#define CLK_I2C35_DISABLED	CLKSRC(MUX_I2C35, 7)
+
+#define CLK_I2C46_PCLK5		CLKSRC(MUX_I2C46, 0)
+#define CLK_I2C46_PLL3Q		CLKSRC(MUX_I2C46, 1)
+#define CLK_I2C46_HSI		CLKSRC(MUX_I2C46, 2)
+#define CLK_I2C46_CSI		CLKSRC(MUX_I2C46, 3)
+#define CLK_I2C46_DISABLED	CLKSRC(MUX_I2C46, 7)
+
+#define CLK_SAI1_PLL4Q		CLKSRC(MUX_SAI1, 0)
+#define CLK_SAI1_PLL3Q		CLKSRC(MUX_SAI1, 1)
+#define CLK_SAI1_I2SCKIN	CLKSRC(MUX_SAI1, 2)
+#define CLK_SAI1_CKPER		CLKSRC(MUX_SAI1, 3)
+#define CLK_SAI1_PLL3R		CLKSRC(MUX_SAI1, 4)
+#define CLK_SAI1_DISABLED	CLKSRC(MUX_SAI1, 7)
+
+#define CLK_SAI2_PLL4Q		CLKSRC(MUX_SAI2, 0)
+#define CLK_SAI2_PLL3Q		CLKSRC(MUX_SAI2, 1)
+#define CLK_SAI2_I2SCKIN	CLKSRC(MUX_SAI2, 2)
+#define CLK_SAI2_CKPER		CLKSRC(MUX_SAI2, 3)
+#define CLK_SAI2_SPDIF		CLKSRC(MUX_SAI2, 4)
+#define CLK_SAI2_PLL3R		CLKSRC(MUX_SAI2, 5)
+#define CLK_SAI2_DISABLED	CLKSRC(MUX_SAI2, 7)
+
+#define CLK_SAI3_PLL4Q		CLKSRC(MUX_SAI3, 0)
+#define CLK_SAI3_PLL3Q		CLKSRC(MUX_SAI3, 1)
+#define CLK_SAI3_I2SCKIN	CLKSRC(MUX_SAI3, 2)
+#define CLK_SAI3_CKPER		CLKSRC(MUX_SAI3, 3)
+#define CLK_SAI3_PLL3R		CLKSRC(MUX_SAI3, 4)
+#define CLK_SAI3_DISABLED	CLKSRC(MUX_SAI3, 7)
+
+#define CLK_SAI4_PLL4Q		CLKSRC(MUX_SAI4, 0)
+#define CLK_SAI4_PLL3Q		CLKSRC(MUX_SAI4, 1)
+#define CLK_SAI4_I2SCKIN	CLKSRC(MUX_SAI4, 2)
+#define CLK_SAI4_CKPER		CLKSRC(MUX_SAI4, 3)
+#define CLK_SAI4_PLL3R		CLKSRC(MUX_SAI4, 4)
+#define CLK_SAI4_DISABLED	CLKSRC(MUX_SAI4, 7)
+
+#define CLK_SPI2S1_PLL4P	CLKSRC(MUX_SPI2S1, 0)
+#define CLK_SPI2S1_PLL3Q	CLKSRC(MUX_SPI2S1, 1)
+#define CLK_SPI2S1_I2SCKIN	CLKSRC(MUX_SPI2S1, 2)
+#define CLK_SPI2S1_CKPER	CLKSRC(MUX_SPI2S1, 3)
+#define CLK_SPI2S1_PLL3R	CLKSRC(MUX_SPI2S1, 4)
+#define CLK_SPI2S1_DISABLED	CLKSRC(MUX_SPI2S1, 7)
+
+#define CLK_SPI2S23_PLL4P	CLKSRC(MUX_SPI2S23, 0)
+#define CLK_SPI2S23_PLL3Q	CLKSRC(MUX_SPI2S23, 1)
+#define CLK_SPI2S23_I2SCKIN	CLKSRC(MUX_SPI2S23, 2)
+#define CLK_SPI2S23_CKPER	CLKSRC(MUX_SPI2S23, 3)
+#define CLK_SPI2S23_PLL3R	CLKSRC(MUX_SPI2S23, 4)
+#define CLK_SPI2S23_DISABLED	CLKSRC(MUX_SPI2S23, 7)
+
+#define CLK_SPI45_PCLK2		CLKSRC(MUX_SPI45, 0)
+#define CLK_SPI45_PLL4Q		CLKSRC(MUX_SPI45, 1)
+#define CLK_SPI45_HSI		CLKSRC(MUX_SPI45, 2)
+#define CLK_SPI45_CSI		CLKSRC(MUX_SPI45, 3)
+#define CLK_SPI45_HSE		CLKSRC(MUX_SPI45, 4)
+#define CLK_SPI45_DISABLED	CLKSRC(MUX_SPI45, 7)
+
+#define CLK_SPI6_PCLK5		CLKSRC(MUX_SPI6, 0)
+#define CLK_SPI6_PLL4Q		CLKSRC(MUX_SPI6, 1)
+#define CLK_SPI6_HSI		CLKSRC(MUX_SPI6, 2)
+#define CLK_SPI6_CSI		CLKSRC(MUX_SPI6, 3)
+#define CLK_SPI6_HSE		CLKSRC(MUX_SPI6, 4)
+#define CLK_SPI6_PLL3Q		CLKSRC(MUX_SPI6, 5)
+#define CLK_SPI6_DISABLED	CLKSRC(MUX_SPI6, 7)
+
+#define CLK_UART6_PCLK2		CLKSRC(MUX_UART6, 0)
+#define CLK_UART6_PLL4Q		CLKSRC(MUX_UART6, 1)
+#define CLK_UART6_HSI		CLKSRC(MUX_UART6, 2)
+#define CLK_UART6_CSI		CLKSRC(MUX_UART6, 3)
+#define CLK_UART6_HSE		CLKSRC(MUX_UART6, 4)
+#define CLK_UART6_DISABLED	CLKSRC(MUX_UART6, 7)
+
+#define CLK_UART24_PCLK1	CLKSRC(MUX_UART24, 0)
+#define CLK_UART24_PLL4Q	CLKSRC(MUX_UART24, 1)
+#define CLK_UART24_HSI		CLKSRC(MUX_UART24, 2)
+#define CLK_UART24_CSI		CLKSRC(MUX_UART24, 3)
+#define CLK_UART24_HSE		CLKSRC(MUX_UART24, 4)
+#define CLK_UART24_DISABLED	CLKSRC(MUX_UART24, 7)
+
+#define CLK_UART35_PCLK1	CLKSRC(MUX_UART35, 0)
+#define CLK_UART35_PLL4Q	CLKSRC(MUX_UART35, 1)
+#define CLK_UART35_HSI		CLKSRC(MUX_UART35, 2)
+#define CLK_UART35_CSI		CLKSRC(MUX_UART35, 3)
+#define CLK_UART35_HSE		CLKSRC(MUX_UART35, 4)
+#define CLK_UART35_DISABLED	CLKSRC(MUX_UART35, 7)
+
+#define CLK_UART78_PCLK1	CLKSRC(MUX_UART78, 0)
+#define CLK_UART78_PLL4Q	CLKSRC(MUX_UART78, 1)
+#define CLK_UART78_HSI		CLKSRC(MUX_UART78, 2)
+#define CLK_UART78_CSI		CLKSRC(MUX_UART78, 3)
+#define CLK_UART78_HSE		CLKSRC(MUX_UART78, 4)
+#define CLK_UART78_DISABLED	CLKSRC(MUX_UART78, 7)
+
+#define CLK_UART1_PCLK5		CLKSRC(MUX_UART1, 0)
+#define CLK_UART1_PLL3Q		CLKSRC(MUX_UART1, 1)
+#define CLK_UART1_HSI		CLKSRC(MUX_UART1, 2)
+#define CLK_UART1_CSI		CLKSRC(MUX_UART1, 3)
+#define CLK_UART1_PLL4Q		CLKSRC(MUX_UART1, 4)
+#define CLK_UART1_HSE		CLKSRC(MUX_UART1, 5)
+#define CLK_UART1_DISABLED	CLKSRC(MUX_UART1, 7)
+
+#define CLK_SDMMC12_HCLK6	CLKSRC(MUX_SDMMC12, 0)
+#define CLK_SDMMC12_PLL3R	CLKSRC(MUX_SDMMC12, 1)
+#define CLK_SDMMC12_PLL4P	CLKSRC(MUX_SDMMC12, 2)
+#define CLK_SDMMC12_HSI		CLKSRC(MUX_SDMMC12, 3)
+#define CLK_SDMMC12_DISABLED	CLKSRC(MUX_SDMMC12, 7)
+
+#define CLK_SDMMC3_HCLK2	CLKSRC(MUX_SDMMC3, 0)
+#define CLK_SDMMC3_PLL3R	CLKSRC(MUX_SDMMC3, 1)
+#define CLK_SDMMC3_PLL4P	CLKSRC(MUX_SDMMC3, 2)
+#define CLK_SDMMC3_HSI		CLKSRC(MUX_SDMMC3, 3)
+#define CLK_SDMMC3_DISABLED	CLKSRC(MUX_SDMMC3, 7)
+
+#define CLK_ETH_PLL4P		CLKSRC(MUX_ETH, 0)
+#define CLK_ETH_PLL3Q		CLKSRC(MUX_ETH, 1)
+#define CLK_ETH_DISABLED	CLKSRC(MUX_ETH, 3)
+
+#define CLK_QSPI_ACLK		CLKSRC(MUX_QSPI, 0)
+#define CLK_QSPI_PLL3R		CLKSRC(MUX_QSPI, 1)
+#define CLK_QSPI_PLL4P		CLKSRC(MUX_QSPI, 2)
+#define CLK_QSPI_CKPER		CLKSRC(MUX_QSPI, 3)
+
+#define CLK_FMC_ACLK		CLKSRC(MUX_FMC, 0)
+#define CLK_FMC_PLL3R		CLKSRC(MUX_FMC, 1)
+#define CLK_FMC_PLL4P		CLKSRC(MUX_FMC, 2)
+#define CLK_FMC_CKPER		CLKSRC(MUX_FMC, 3)
+
+#define CLK_FDCAN_HSE		CLKSRC(MUX_FDCAN, 0)
+#define CLK_FDCAN_PLL3Q		CLKSRC(MUX_FDCAN, 1)
+#define CLK_FDCAN_PLL4Q		CLKSRC(MUX_FDCAN, 2)
+#define CLK_FDCAN_PLL4R		CLKSRC(MUX_FDCAN, 3)
+
+#define CLK_SPDIF_PLL4P		CLKSRC(MUX_SPDIF, 0)
+#define CLK_SPDIF_PLL3Q		CLKSRC(MUX_SPDIF, 1)
+#define CLK_SPDIF_HSI		CLKSRC(MUX_SPDIF, 2)
+#define CLK_SPDIF_DISABLED	CLKSRC(MUX_SPDIF, 3)
+
+#define CLK_CEC_LSE		CLKSRC(MUX_CEC, 0)
+#define CLK_CEC_LSI		CLKSRC(MUX_CEC, 1)
+#define CLK_CEC_CSI_DIV122	CLKSRC(MUX_CEC, 2)
+#define CLK_CEC_DISABLED	CLKSRC(MUX_CEC, 3)
+
+#define CLK_USBPHY_HSE		CLKSRC(MUX_USBPHY, 0)
+#define CLK_USBPHY_PLL4R	CLKSRC(MUX_USBPHY, 1)
+#define CLK_USBPHY_HSE_DIV2	CLKSRC(MUX_USBPHY, 2)
+#define CLK_USBPHY_DISABLED	CLKSRC(MUX_USBPHY, 3)
+
+#define CLK_USBO_PLL4R		CLKSRC(MUX_USBO, 0)
+#define CLK_USBO_USBPHY		CLKSRC(MUX_USBO, 1)
+
+#define CLK_RNG1_CSI		CLKSRC(MUX_RNG1, 0)
+#define CLK_RNG1_PLL4R		CLKSRC(MUX_RNG1, 1)
+#define CLK_RNG1_LSE		CLKSRC(MUX_RNG1, 2)
+#define CLK_RNG1_LSI		CLKSRC(MUX_RNG1, 3)
+
+#define CLK_RNG2_CSI		CLKSRC(MUX_RNG2, 0)
+#define CLK_RNG2_PLL4R		CLKSRC(MUX_RNG2, 1)
+#define CLK_RNG2_LSE		CLKSRC(MUX_RNG2, 2)
+#define CLK_RNG2_LSI		CLKSRC(MUX_RNG2, 3)
+
+#define CLK_CKPER_HSI		CLKSRC(MUX_CKPER, 0)
+#define CLK_CKPER_CSI		CLKSRC(MUX_CKPER, 1)
+#define CLK_CKPER_HSE		CLKSRC(MUX_CKPER, 2)
+#define CLK_CKPER_DISABLED	CLKSRC(MUX_CKPER, 3)
+
+#define CLK_STGEN_HSI		CLKSRC(MUX_STGEN, 0)
+#define CLK_STGEN_HSE		CLKSRC(MUX_STGEN, 1)
+#define CLK_STGEN_DISABLED	CLKSRC(MUX_STGEN, 3)
+
+#define CLK_DSI_DSIPLL		CLKSRC(MUX_DSI, 0)
+#define CLK_DSI_PLL4P		CLKSRC(MUX_DSI, 1)
+
+#define CLK_ADC_PLL4R		CLKSRC(MUX_ADC, 0)
+#define CLK_ADC_CKPER		CLKSRC(MUX_ADC, 1)
+#define CLK_ADC_PLL3Q		CLKSRC(MUX_ADC, 2)
+#define CLK_ADC_DISABLED	CLKSRC(MUX_ADC, 3)
+
+#define CLK_LPTIM45_PCLK3	CLKSRC(MUX_LPTIM45, 0)
+#define CLK_LPTIM45_PLL4P	CLKSRC(MUX_LPTIM45, 1)
+#define CLK_LPTIM45_PLL3Q	CLKSRC(MUX_LPTIM45, 2)
+#define CLK_LPTIM45_LSE		CLKSRC(MUX_LPTIM45, 3)
+#define CLK_LPTIM45_LSI		CLKSRC(MUX_LPTIM45, 4)
+#define CLK_LPTIM45_CKPER	CLKSRC(MUX_LPTIM45, 5)
+#define CLK_LPTIM45_DISABLED	CLKSRC(MUX_LPTIM45, 7)
+
+#define CLK_LPTIM23_PCLK3	CLKSRC(MUX_LPTIM23, 0)
+#define CLK_LPTIM23_PLL4Q	CLKSRC(MUX_LPTIM23, 1)
+#define CLK_LPTIM23_CKPER	CLKSRC(MUX_LPTIM23, 2)
+#define CLK_LPTIM23_LSE		CLKSRC(MUX_LPTIM23, 3)
+#define CLK_LPTIM23_LSI		CLKSRC(MUX_LPTIM23, 4)
+#define CLK_LPTIM23_DISABLED	CLKSRC(MUX_LPTIM23, 7)
+
+#define CLK_LPTIM1_PCLK1	CLKSRC(MUX_LPTIM1, 0)
+#define CLK_LPTIM1_PLL4P	CLKSRC(MUX_LPTIM1, 1)
+#define CLK_LPTIM1_PLL3Q	CLKSRC(MUX_LPTIM1, 2)
+#define CLK_LPTIM1_LSE		CLKSRC(MUX_LPTIM1, 3)
+#define CLK_LPTIM1_LSI		CLKSRC(MUX_LPTIM1, 4)
+#define CLK_LPTIM1_CKPER	CLKSRC(MUX_LPTIM1, 5)
+#define CLK_LPTIM1_DISABLED	CLKSRC(MUX_LPTIM1, 7)
 
 /* define for st,pll /csg */
 #define SSCG_MODE_CENTER_SPREAD	0
diff --git a/include/dt-bindings/clock/stm32mp25-clks.h b/include/dt-bindings/clock/stm32mp25-clks.h
index c4ff9cfc..e7ab5b0c 100644
--- a/include/dt-bindings/clock/stm32mp25-clks.h
+++ b/include/dt-bindings/clock/stm32mp25-clks.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
- * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
  */
 
 #ifndef _DT_BINDINGS_STM32MP25_CLKS_H_
@@ -109,7 +109,7 @@
 /* LOW SPEED MCU CLOCK */
 #define CK_ICN_LS_MCU		88
 
-#define CK_BUS_STM500		89
+#define CK_BUS_STM		89
 #define CK_BUS_FMC		90
 #define CK_BUS_GPU		91
 #define CK_BUS_ETH1		92
@@ -233,7 +233,6 @@
 #define CK_BUS_DDRCFG		210
 #define CK_BUS_GICV2M		211
 #define CK_BUS_USBTC		212
-#define CK_BUS_BUSPERFM		213
 #define CK_BUS_USB3PCIEPHY	214
 #define CK_BUS_STGEN		215
 #define CK_BUS_VDEC		216
@@ -272,7 +271,7 @@
 #define CK_BUS_RISAF4		249
 #define CK_BUS_USB2OHCI		250
 #define CK_BUS_USB2EHCI		251
-#define CK_BUS_USB3DRD		252
+#define CK_BUS_USB3DR		252
 #define CK_KER_LPTIM1		253
 #define CK_KER_LPTIM2		254
 #define CK_KER_USART2		255
@@ -364,8 +363,10 @@
 #define CK_BUS_ETHSWACMCFG	341
 #define CK_BUS_ETHSWACMMSG	342
 #define HSE_DIV2_CK		343
+#define CK_KER_ETR		344
+#define CK_KER_STM		345
 
-#define STM32MP25_LAST_CLK	344
+#define STM32MP25_LAST_CLK	346
 
 #define CK_SCMI_ICN_HS_MCU	0
 #define CK_SCMI_ICN_SDMMC	1
@@ -453,8 +454,7 @@
 #define CK_SCMI_TIMG2		83
 #define CK_SCMI_BKPSRAM		84
 #define CK_SCMI_BSEC		85
-#define CK_SCMI_BUSPERFM	86
-#define CK_SCMI_ETR		87
+#define CK_SCMI_BUS_ETR		87
 #define CK_SCMI_FMC		88
 #define CK_SCMI_GPIOA		89
 #define CK_SCMI_GPIOB		90
@@ -489,6 +489,8 @@
 #define CK_SCMI_SYSDBG		119
 #define CK_SCMI_SYSATB		120
 #define CK_SCMI_TSDBG		121
-#define CK_SCMI_STM500		122
+#define CK_SCMI_BUS_STM		122
+#define CK_SCMI_KER_STM		123
+#define CK_SCMI_KER_ETR		124
 
 #endif /* _DT_BINDINGS_STM32MP25_CLKS_H_ */
diff --git a/include/dt-bindings/clock/stm32mp25-clksrc.h b/include/dt-bindings/clock/stm32mp25-clksrc.h
index e6f7154b..319fd824 100644
--- a/include/dt-bindings/clock/stm32mp25-clksrc.h
+++ b/include/dt-bindings/clock/stm32mp25-clksrc.h
@@ -1,6 +1,6 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  */
 
 #ifndef _DT_BINDINGS_CLOCK_STM32MP25_CLKSRC_H_
@@ -108,9 +108,8 @@
 #define MUX_DSIPHY	18
 #define MUX_LVDSPHY	19
 #define MUX_DTS		20
-#define MUX_CPU1	21
-#define MUX_D3PER	22
-#define MUX_NB		23
+#define MUX_D3PER	21
+#define MUX_NB		22
 
 #define MUXSEL_HSI		0
 #define MUXSEL_HSE		1
@@ -144,7 +143,7 @@
 #define MUX_USB3PCIEPHY_FLEX34	0x0
 #define MUX_USB3PCIEPHY_HSE	0x1
 
-#define MUX_DSIBLANE_FLEX28	0x0
+#define MUX_DSIBLANE_DSIPHY	0x0
 #define MUX_DSIBLANE_FLEX27	0x1
 
 #define MUX_DSIPHY_FLEX28	0x0
@@ -219,8 +218,8 @@
 
 /* define for st,drive */
 #define LSEDRV_LOWEST		0
-#define LSEDRV_MEDIUM_LOW	1
-#define LSEDRV_MEDIUM_HIGH	2
+#define LSEDRV_MEDIUM_LOW	2
+#define LSEDRV_MEDIUM_HIGH	1
 #define LSEDRV_HIGHEST		3
 
 #endif /* _DT_BINDINGS_CLOCK_STM32MP25_CLKSRC_H_ */
diff --git a/include/dt-bindings/gpio/stm32-gpio.h b/include/dt-bindings/gpio/stm32-gpio.h
new file mode 100644
index 00000000..2c7a0f15
--- /dev/null
+++ b/include/dt-bindings/gpio/stm32-gpio.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2024 STMicroelectronics - All Rights Reserved
+ * Author: Paillet Pascal <p.paillet@foss.st.com> for STMicroelectronics.
+ */
+
+#ifndef DT_BINDINGS_STM32_GPIO_H
+#define DT_BINDINGS_STM32_GPIO_H
+
+/* Bank IDs used in GPIO driver API */
+#define GPIO_BANK_A			0U
+#define GPIO_BANK_B			1U
+#define GPIO_BANK_C			2U
+#define GPIO_BANK_D			3U
+#define GPIO_BANK_E			4U
+#define GPIO_BANK_F			5U
+#define GPIO_BANK_G			6U
+#define GPIO_BANK_H			7U
+#define GPIO_BANK_I			8U
+#define GPIO_BANK_J			9U
+#define GPIO_BANK_K			10U
+#define GPIO_BANK_Z			25U
+
+/* Bit 0 is used to set GPIO in input mode */
+#define GPIOF_DIR_OUT			0x0
+#define GPIOF_DIR_IN			0x1
+
+/* Bit 1 is used to set GPIO high level during init */
+#define GPIOF_INIT_LOW			0x0
+#define GPIOF_INIT_HIGH			0x2
+
+#define GPIOF_IN			(GPIOF_DIR_IN)
+#define GPIOF_OUT_INIT_LOW		(GPIOF_DIR_OUT | GPIOF_INIT_LOW)
+#define GPIOF_OUT_INIT_HIGH		(GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
+
+/* Bit 2 is used to set GPIO pull up */
+#define GPIOF_PULL_UP			0x4
+/* Bit 3 is used to set GPIO pull down */
+#define GPIOF_PULL_DOWN			0x8
+
+#endif /* DT_BINDINGS_STM32_GPIO_H */
diff --git a/include/dt-bindings/reset/stm32mp25-resets.h b/include/dt-bindings/reset/stm32mp25-resets.h
index c34fe2ae..99b8058e 100644
--- a/include/dt-bindings/reset/stm32mp25-resets.h
+++ b/include/dt-bindings/reset/stm32mp25-resets.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later or BSD-3-Clause */
 /*
- * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
  * Author(s): Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
  */
 
@@ -14,16 +14,16 @@
 #define C2_R		8288
 #define C2_HOLDBOOT_R	8608
 #define C1_HOLDBOOT_R	8609
-#define VSW_R		8703
-#define C1MS_R		8808
-#define IWDG2_KER_R	9074
-#define IWDG4_KER_R	9202
-#define C3_R		9312
-#define DDRCP_R		9856
-#define DDRCAPB_R	9888
-#define DDRPHYCAPB_R	9920
-#define DDRCFG_R	9984
-#define DDR_R		10016
+#define VSW_R		8735
+#define C1MS_R		8840
+#define IWDG2_KER_R	9106
+#define IWDG4_KER_R	9234
+#define C3_R		9344
+#define DDRCP_R		9888
+#define DDRCAPB_R	9920
+#define DDRPHYCAPB_R	9952
+#define DDRCFG_R	10016
+#define DDR_R		10048
 #define OSPI1_R		10400
 #define OSPI1DLL_R	10416
 #define OSPI2_R		10432
@@ -115,7 +115,7 @@
 #define USB2_R		16352
 #define USB2PHY1_R	16384
 #define USB2PHY2_R	16416
-#define USB3DRD_R	16448
+#define USB3DR_R	16448
 #define USB3PCIEPHY_R	16480
 #define PCIE_R		16512
 #define USBTC_R		16544
@@ -143,7 +143,6 @@
 #define CRYP2_R		17440
 #define WWDG1_R		17632
 #define WWDG2_R		17664
-#define BUSPERFM_R	17696
 #define VREF_R		17728
 #define DTS_R		17760
 #define CRC_R		17824
@@ -159,6 +158,9 @@
 #define RST_SCMI_C1_HOLDBOOT_R	2
 #define RST_SCMI_C2_HOLDBOOT_R	3
 #define RST_SCMI_FMC		4
-#define RST_SCMI_PCIE		5
+#define RST_SCMI_OSPI1		5
+#define RST_SCMI_OSPI1DLL	6
+#define RST_SCMI_OSPI2		7
+#define RST_SCMI_OSPI2DLL	8
 
 #endif /* _DT_BINDINGS_STM32MP25_RESET_H_ */
diff --git a/include/lib/cpus/aarch32/cpu_macros.S b/include/lib/cpus/aarch32/cpu_macros.S
index 096e0b14..cfa5831f 100644
--- a/include/lib/cpus/aarch32/cpu_macros.S
+++ b/include/lib/cpus/aarch32/cpu_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -115,11 +115,6 @@
 	  .popsection
 	.endif
 
-	/*
-	 * Mandatory errata status printing function for CPUs of
-	 * this class.
-	 */
-	.word \_name\()_errata_report
 	.word \_name\()_cpu_str
 
 #ifdef IMAGE_BL32
@@ -130,45 +125,6 @@
 #endif
 	.endm
 
-#if REPORT_ERRATA
-	/*
-	 * Print status of a CPU errata
-	 *
-	 * _chosen:
-	 *	Identifier indicating whether or not a CPU errata has been
-	 *	compiled in.
-	 * _cpu:
-	 *	Name of the CPU
-	 * _id:
-	 *	Errata identifier
-	 * _rev_var:
-	 *	Register containing the combined value CPU revision and variant
-	 *	- typically the return value of cpu_get_rev_var
-	 */
-	.macro report_errata _chosen, _cpu, _id, _rev_var=r4
-	/* Stash a string with errata ID */
-	.pushsection .rodata
-	\_cpu\()_errata_\_id\()_str:
-	.asciz	"\_id"
-	.popsection
-
-	/* Check whether errata applies */
-	mov	r0, \_rev_var
-	bl	check_errata_\_id
-
-	.ifeq \_chosen
-	/*
-	 * Errata workaround has not been compiled in. If the errata would have
-	 * applied had it been compiled in, print its status as missing.
-	 */
-	cmp	r0, #0
-	movne	r0, #ERRATA_MISSING
-	.endif
-	ldr	r1, =\_cpu\()_cpu_str
-	ldr	r2, =\_cpu\()_errata_\_id\()_str
-	bl	errata_print_msg
-	.endm
-#endif
 	/*
 	 * Helper macro that reads the part number of the current CPU and jumps
 	 * to the given label if it matches the CPU MIDR provided.
@@ -239,21 +195,4 @@
 	.popsection
 .endm
 
-/*
- * Maintain compatibility with the old scheme of "each cpu has its own reporter".
- * TODO remove entirely once all cpus have been converted. This includes the
- * cpu_ops entry, as print_errata_status can call this directly for all cpus
- */
-.macro errata_report_shim _cpu:req
-	#if REPORT_ERRATA
-	func \_cpu\()_errata_report
-		push	{r12, lr}
-
-		bl generic_errata_report
-
-		pop	{r12, lr}
-		bx	lr
-	endfunc \_cpu\()_errata_report
-	#endif
-.endm
 #endif /* CPU_MACROS_S */
diff --git a/include/lib/cpus/aarch64/cortex_a35.h b/include/lib/cpus/aarch64/cortex_a35.h
index cef2960d..c82b4eb0 100644
--- a/include/lib/cpus/aarch64/cortex_a35.h
+++ b/include/lib/cpus/aarch64/cortex_a35.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,9 @@
 /* Cortex-A35 Main ID register for revision 0 */
 #define CORTEX_A35_MIDR				U(0x410FD040)
 
+/* L2 Extended Control Register */
+#define CORTEX_A35_L2ECTLR_EL1			S3_1_C11_C0_3
+
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
  * CPUECTLR_EL1 is an implementation-specific register.
diff --git a/include/lib/cpus/aarch64/cortex_a520.h b/include/lib/cpus/aarch64/cortex_a520.h
index 41769815..11ddea91 100644
--- a/include/lib/cpus/aarch64/cortex_a520.h
+++ b/include/lib/cpus/aarch64/cortex_a520.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +12,15 @@
 /*******************************************************************************
  * CPU Extended Control register specific definitions
  ******************************************************************************/
+#define CORTEX_A520_CPUACTLR_EL1				S3_0_C15_C1_0
+
 #define CORTEX_A520_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_A520_CPUECTLR_EL1_EXTLLC_BIT			U(0)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 1 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A520_CPUACTLR_EL1				S3_0_C15_C1_0
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
@@ -20,4 +28,15 @@
 #define CORTEX_A520_CPUPWRCTLR_EL1				S3_0_C15_C2_7
 #define CORTEX_A520_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
+#ifndef __ASSEMBLER__
+#if ERRATA_A520_2938996
+long  check_erratum_cortex_a520_2938996(long cpu_rev);
+#else
+static inline long  check_erratum_cortex_a520_2938996(long cpu_rev)
+{
+       return 0;
+}
+#endif /* ERRATA_A520_2938996 */
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_A520_H */
diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h
index 432e17ab..9df8d471 100644
--- a/include/lib/cpus/aarch64/cortex_a710.h
+++ b/include/lib/cpus/aarch64/cortex_a710.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,6 +38,11 @@
 #define CORTEX_A710_CPUACTLR2_EL1_BIT_40			(ULL(1) << 40)
 #define CORTEX_A710_CPUACTLR2_EL1_BIT_36			(ULL(1) << 36)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 3 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A710_CPUACTLR3_EL1				S3_0_C15_C1_2
+
 /*******************************************************************************
  * CPU Auxiliary Control register 5 specific definitions.
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_a715.h b/include/lib/cpus/aarch64/cortex_a715.h
index 950d02f3..c7f50db3 100644
--- a/include/lib/cpus/aarch64/cortex_a715.h
+++ b/include/lib/cpus/aarch64/cortex_a715.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,11 +12,26 @@
 /* Cortex-A715 loop count for CVE-2022-23960 mitigation */
 #define CORTEX_A715_BHB_LOOP_COUNT				U(38)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 1 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A715_CPUACTLR_EL1				S3_0_C15_C1_0
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A715_CPUACTLR2_EL1				S3_0_C15_C1_1
+
 /*******************************************************************************
  * CPU Extended Control register specific definitions
  ******************************************************************************/
 #define CORTEX_A715_CPUECTLR_EL1				S3_0_C15_C1_4
 
+#define CORTEX_A715_CPUPSELR_EL3				S3_6_C15_C8_0
+#define CORTEX_A715_CPUPCR_EL3					S3_6_C15_C8_1
+#define CORTEX_A715_CPUPOR_EL3					S3_6_C15_C8_2
+#define CORTEX_A715_CPUPMR_EL3					S3_6_C15_C8_3
+
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_a720.h b/include/lib/cpus/aarch64/cortex_a720.h
index 47bbbc07..129c1ee3 100644
--- a/include/lib/cpus/aarch64/cortex_a720.h
+++ b/include/lib/cpus/aarch64/cortex_a720.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,21 @@
 /* Cortex A720 loop count for CVE-2022-23960 mitigation */
 #define CORTEX_A720_BHB_LOOP_COUNT				U(132)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 1 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A720_CPUACTLR_EL1				S3_0_C15_C1_0
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A720_CPUACTLR2_EL1				S3_0_C15_C1_1
+
+/*******************************************************************************
+ * CPU Auxiliary Control register 4 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A720_CPUACTLR4_EL1				S3_0_C15_C1_3
+
 /*******************************************************************************
  * CPU Extended Control register specific definitions
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/neoverse_hermes.h b/include/lib/cpus/aarch64/cortex_a720_ae.h
similarity index 57%
rename from include/lib/cpus/aarch64/neoverse_hermes.h
rename to include/lib/cpus/aarch64/cortex_a720_ae.h
index 22492c3d..c88b1f9c 100644
--- a/include/lib/cpus/aarch64/neoverse_hermes.h
+++ b/include/lib/cpus/aarch64/cortex_a720_ae.h
@@ -1,23 +1,23 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef NEOVERSE_HERMES_H
-#define NEOVERSE_HERMES_H
+#ifndef CORTEX_A720_AE_H
+#define CORTEX_A720_AE_H
 
-#define NEOVERSE_HERMES_MIDR				U(0x410FD8E0)
+#define CORTEX_A720_AE_MIDR				U(0x410FD890)
 
 /*******************************************************************************
  * CPU Extended Control register specific definitions
  ******************************************************************************/
-#define NEOVERSE_HERMES_CPUECTLR_EL1			S3_0_C15_C1_4
+#define CORTEX_A720_AE_CPUECTLR_EL1			S3_0_C15_C1_4
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
-#define NEOVERSE_HERMES_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define NEOVERSE_HERMES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+#define CORTEX_A720_AE_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define CORTEX_A720_AE_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
 
-#endif /* NEOVERSE_HERMES_H */
+#endif /* CORTEX_A720_AE_H */
diff --git a/include/lib/cpus/aarch64/cortex_blackhawk.h b/include/lib/cpus/aarch64/cortex_a725.h
similarity index 55%
rename from include/lib/cpus/aarch64/cortex_blackhawk.h
rename to include/lib/cpus/aarch64/cortex_a725.h
index bfb30395..cb1c099c 100644
--- a/include/lib/cpus/aarch64/cortex_blackhawk.h
+++ b/include/lib/cpus/aarch64/cortex_a725.h
@@ -1,23 +1,24 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef CORTEX_BLACKHAWK_H
-#define CORTEX_BLACKHAWK_H
+#ifndef CORTEX_A725_H
+#define CORTEX_A725_H
 
-#define CORTEX_BLACKHAWK_MIDR					U(0x410FD850)
+#define CORTEX_A725_MIDR					U(0x410FD870)
 
 /*******************************************************************************
  * CPU Extended Control register specific definitions
  ******************************************************************************/
-#define CORTEX_BLACKHAWK_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_A725_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_A725_CPUECTLR_EL1_EXTLLC_BIT			U(0)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
-#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+#define CORTEX_A725_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_A725_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
-#endif /* CORTEX_BLACKHAWK_H */
+#endif /* CORTEX_A725_H */
diff --git a/include/lib/cpus/aarch64/cortex_a75.h b/include/lib/cpus/aarch64/cortex_a75.h
index ca79991e..7a97ed11 100644
--- a/include/lib/cpus/aarch64/cortex_a75.h
+++ b/include/lib/cpus/aarch64/cortex_a75.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,6 +50,11 @@ unsigned int cortex_a75_amu_read_cpuamcntenset_el0(void);
 unsigned int cortex_a75_amu_read_cpuamcntenclr_el0(void);
 void cortex_a75_amu_write_cpuamcntenset_el0(unsigned int mask);
 void cortex_a75_amu_write_cpuamcntenclr_el0(unsigned int mask);
+
+#if ERRATA_A75_764081
+long check_erratum_cortex_a75_764081(long cpu_rev);
+#endif /* ERRATA_A75_764081 */
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* CORTEX_A75_H */
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
index 301be69a..d600ecab 100644
--- a/include/lib/cpus/aarch64/cortex_a78c.h
+++ b/include/lib/cpus/aarch64/cortex_a78c.h
@@ -47,4 +47,9 @@
 #define CORTEX_A78C_IMP_CPUPOR_EL3			S3_6_C15_C8_2
 #define CORTEX_A78C_IMP_CPUPMR_EL3			S3_6_C15_C8_3
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 5 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A78C_ACTLR5_EL1				S3_0_C15_C9_0
+
 #endif /* CORTEX_A78C_H */
diff --git a/include/lib/cpus/aarch64/cortex_arcadia.h b/include/lib/cpus/aarch64/cortex_arcadia.h
new file mode 100644
index 00000000..8b74de29
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_arcadia.h
@@ -0,0 +1,24 @@
+/*
+ * 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/cortex_x2.h b/include/lib/cpus/aarch64/cortex_x2.h
index 863b8c8d..0f97b1e1 100644
--- a/include/lib/cpus/aarch64/cortex_x2.h
+++ b/include/lib/cpus/aarch64/cortex_x2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,6 +27,11 @@
 #define CORTEX_X2_CPUECTLR2_EL1_PF_MODE_WIDTH			U(4)
 #define CORTEX_X2_CPUECTLR2_EL1_PF_MODE_CNSRV			ULL(0x9)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 3 specific definitions.
+ ******************************************************************************/
+#define CORTEX_X2_CPUACTLR3_EL1				S3_0_C15_C1_2
+
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_x3.h b/include/lib/cpus/aarch64/cortex_x3.h
index 04548eae..c5f820cf 100644
--- a/include/lib/cpus/aarch64/cortex_x3.h
+++ b/include/lib/cpus/aarch64/cortex_x3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,6 +25,11 @@
 #define CORTEX_X3_CPUPWRCTLR_EL1_WFI_RET_CTRL_BITS_SHIFT	U(4)
 #define CORTEX_X3_CPUPWRCTLR_EL1_WFE_RET_CTRL_BITS_SHIFT	U(7)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_X3_CPUACTLR_EL1			S3_0_C15_C1_0
+
 /*******************************************************************************
  * CPU Auxiliary Control register 2 specific definitions.
  ******************************************************************************/
@@ -38,6 +43,11 @@
 #define CORTEX_X3_CPUACTLR5_EL1_BIT_55		(ULL(1) << 55)
 #define CORTEX_X3_CPUACTLR5_EL1_BIT_56		(ULL(1) << 56)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 6 specific definitions.
+ ******************************************************************************/
+#define CORTEX_X3_CPUACTLR6_EL1			S3_0_C15_C8_1
+
 /*******************************************************************************
  * CPU Extended Control register 2 specific definitions.
  ******************************************************************************/
@@ -47,4 +57,10 @@
 #define CORTEX_X3_CPUECTLR2_EL1_PF_MODE_WIDTH	U(4)
 #define CORTEX_X3_CPUECTLR2_EL1_PF_MODE_CNSRV	ULL(0x9)
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 3 specific definitions.
+ ******************************************************************************/
+#define CORTEX_X3_CPUACTLR3_EL1			S3_0_C15_C1_2
+#define CORTEX_X3_CPUACTLR3_EL1_BIT_47		(ULL(1) << 47)
+
 #endif /* CORTEX_X3_H */
diff --git a/include/lib/cpus/aarch64/cortex_x4.h b/include/lib/cpus/aarch64/cortex_x4.h
index 17d07c8b..f701216b 100644
--- a/include/lib/cpus/aarch64/cortex_x4.h
+++ b/include/lib/cpus/aarch64/cortex_x4.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,4 +23,28 @@
 #define CORTEX_X4_CPUPWRCTLR_EL1			S3_0_C15_C2_7
 #define CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
+/*******************************************************************************
+ * CPU Auxiliary control register specific definitions
+ ******************************************************************************/
+#define CORTEX_X4_CPUACTLR_EL1				S3_0_C15_C1_0
+#define CORTEX_X4_CPUACTLR3_EL1				S3_0_C15_C1_2
+#define CORTEX_X4_CPUACTLR4_EL1				S3_0_C15_C1_3
+
+/*******************************************************************************
+ * CPU Auxiliary control register 5 specific definitions
+ ******************************************************************************/
+#define CORTEX_X4_CPUACTLR5_EL1				S3_0_C15_C8_0
+#define CORTEX_X4_CPUACTLR5_EL1_BIT_14			(ULL(1) << 14)
+
+#ifndef __ASSEMBLER__
+#if ERRATA_X4_2726228
+long check_erratum_cortex_x4_2726228(long cpu_rev);
+#else
+static inline long check_erratum_cortex_x4_2726228(long cpu_rev)
+{
+       return 0;
+}
+#endif /* ERRATA_X4_2726228 */
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_X4_H */
diff --git a/include/lib/cpus/aarch64/cortex_chaberton.h b/include/lib/cpus/aarch64/cortex_x925.h
similarity index 55%
rename from include/lib/cpus/aarch64/cortex_chaberton.h
rename to include/lib/cpus/aarch64/cortex_x925.h
index 8f10b687..b0d0ca4d 100644
--- a/include/lib/cpus/aarch64/cortex_chaberton.h
+++ b/include/lib/cpus/aarch64/cortex_x925.h
@@ -1,23 +1,24 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef CORTEX_CHABERTON_H
-#define CORTEX_CHABERTON_H
+#ifndef CORTEX_X925_H
+#define CORTEX_X925_H
 
-#define CORTEX_CHABERTON_MIDR					U(0x410FD870)
+#define CORTEX_X925_MIDR					U(0x410FD850)
 
 /*******************************************************************************
  * CPU Extended Control register specific definitions
  ******************************************************************************/
-#define CORTEX_CHABERTON_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_X925_CPUECTLR_EL1				S3_0_C15_C1_4
+#define CORTEX_X925_CPUECTLR_EL1_EXTLLC_BIT			U(0)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
-#define CORTEX_CHABERTON_CPUPWRCTLR_EL1				S3_0_C15_C2_7
-#define CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+#define CORTEX_X925_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_X925_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
 
-#endif /* CORTEX_CHABERTON_H */
+#endif /* CORTEX_X925_H */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 6faef5db..5e929344 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -132,12 +132,6 @@
 	  .popsection
 	.endif
 
-
-	/*
-	 * Mandatory errata status printing function for CPUs of
-	 * this class.
-	 */
-	.quad \_name\()_errata_report
 	.quad \_name\()_cpu_str
 
 #ifdef IMAGE_BL31
@@ -171,49 +165,6 @@
 			\_extra1, \_extra2, \_extra3, 0, \_power_down_ops
 	.endm
 
-/* TODO can be deleted once all CPUs have been converted */
-#if REPORT_ERRATA
-	/*
-	 * Print status of a CPU errata
-	 *
-	 * _chosen:
-	 *	Identifier indicating whether or not a CPU errata has been
-	 *	compiled in.
-	 * _cpu:
-	 *	Name of the CPU
-	 * _id:
-	 *	Errata identifier
-	 * _rev_var:
-	 *	Register containing the combined value CPU revision and variant
-	 *	- typically the return value of cpu_get_rev_var
-	 */
-	.macro report_errata _chosen, _cpu, _id, _rev_var=x8
-	/* Stash a string with errata ID */
-	.pushsection .rodata
-	\_cpu\()_errata_\_id\()_str:
-	.asciz	"\_id"
-	.popsection
-
-	/* Check whether errata applies */
-	mov	x0, \_rev_var
-	/* Shall clobber: x0-x7 */
-	bl	check_errata_\_id
-
-	.ifeq \_chosen
-	/*
-	 * Errata workaround has not been compiled in. If the errata would have
-	 * applied had it been compiled in, print its status as missing.
-	 */
-	cbz	x0, 900f
-	mov	x0, #ERRATA_MISSING
-	.endif
-900:
-	adr	x1, \_cpu\()_cpu_str
-	adr	x2, \_cpu\()_errata_\_id\()_str
-	bl	errata_print_msg
-	.endm
-#endif
-
 	/*
 	 * This macro is used on some CPUs to detect if they are vulnerable
 	 * to CVE-2017-5715.
@@ -456,6 +407,14 @@
 	msr	\_reg, x0
 .endm
 
+.macro sysreg_bitfield_insert_from_gpr _reg:req, _gpr:req, _lsb:req, _width:req
+	/* Source value in register for BFI */
+	mov	x1, \_gpr
+	mrs	x0, \_reg
+	bfi	x0, x1, #\_lsb, #\_width
+	msr	\_reg, x0
+.endm
+
 /*
  * Apply erratum
  *
@@ -474,7 +433,7 @@
  *
  * _get_rev:
  *	Optional parameter that determines whether to insert a call to the CPU revision fetching
- *	procedure. Stores the result of this in the temporary register x10.
+ *	procedure. Stores the result of this in the temporary register x10 to allow for chaining
  *
  * clobbers: x0-x10 (PCS compliant)
  */
@@ -614,23 +573,4 @@
 	endfunc \_cpu\()_reset_func
 .endm
 
-/*
- * Maintain compatibility with the old scheme of each cpu has its own reporting.
- * TODO remove entirely once all cpus have been converted. This includes the
- * cpu_ops entry, as print_errata_status can call this directly for all cpus
- */
-.macro errata_report_shim _cpu:req
-	#if REPORT_ERRATA
-	func \_cpu\()_errata_report
-		/* normal stack frame for pretty debugging */
-		stp	x29, x30, [sp, #-16]!
-		mov	x29, sp
-
-		bl	generic_errata_report
-
-		ldp	x29, x30, [sp], #16
-		ret
-	endfunc \_cpu\()_errata_report
-	#endif
-.endm
 #endif /* CPU_MACROS_S */
diff --git a/include/lib/cpus/aarch64/dsu_def.h b/include/lib/cpus/aarch64/dsu_def.h
index 577de619..51fbfd1d 100644
--- a/include/lib/cpus/aarch64/dsu_def.h
+++ b/include/lib/cpus/aarch64/dsu_def.h
@@ -30,6 +30,7 @@
  * DSU Cluster Auxiliary Control registers definitions
  ********************************************************************/
 #define CLUSTERACTLR_EL1	S3_0_C15_C3_3
+#define CLUSTERPWRCTLR_EL1	S3_0_C15_C3_5
 
 #define CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING	(ULL(1) << 15)
 #define CLUSTERACTLR_EL1_DISABLE_SCLK_GATING	(ULL(3) << 15)
@@ -39,4 +40,7 @@
  ********************************************************************/
 #define DSU_ERRATA_936184_MASK	(U(0x3) << 15)
 
+#ifndef __ASSEMBLER__
+void dsu_pwr_dwn(void);
+#endif
 #endif /* DSU_DEF_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n3.h b/include/lib/cpus/aarch64/neoverse_n3.h
new file mode 100644
index 00000000..91963305
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_n3.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_N3_H
+#define NEOVERSE_N3_H
+
+#define NEOVERSE_N3_MIDR				U(0x410FD8E0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_N3_CPUECTLR_EL1			S3_0_C15_C1_4
+#define NEOVERSE_N3_CPUECTLR_EL1_EXTLLC_BIT		(ULL(1) << 0)
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_N3_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEOVERSE_N3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+
+#endif /* NEOVERSE_N3_H */
diff --git a/include/lib/cpus/aarch64/neoverse_poseidon.h b/include/lib/cpus/aarch64/neoverse_poseidon.h
deleted file mode 100644
index 202ef5cb..00000000
--- a/include/lib/cpus/aarch64/neoverse_poseidon.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef NEOVERSE_POSEIDON_H
-#define NEOVERSE_POSEIDON_H
-
-
-#define NEOVERSE_POSEIDON_MIDR                      		U(0x410FD830)
-
-/* Neoverse Poseidon loop count for CVE-2022-23960 mitigation */
-#define NEOVERSE_POSEIDON_BHB_LOOP_COUNT			U(132)
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions.
- ******************************************************************************/
-#define NEOVERSE_POSEIDON_CPUECTLR_EL1				S3_0_C15_C1_4
-
-/*******************************************************************************
- * CPU Power Control register specific definitions
- ******************************************************************************/
-#define NEOVERSE_POSEIDON_CPUPWRCTLR_EL1			S3_0_C15_C2_7
-#define NEOVERSE_POSEIDON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
-
-#endif /* NEOVERSE_POSEIDON_H */
diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h
index d6189942..1e2d7eaf 100644
--- a/include/lib/cpus/aarch64/neoverse_v1.h
+++ b/include/lib/cpus/aarch64/neoverse_v1.h
@@ -47,5 +47,6 @@
 #define NEOVERSE_V1_ACTLR5_EL1					S3_0_C15_C9_0
 #define NEOVERSE_V1_ACTLR5_EL1_BIT_55				(ULL(1) << 55)
 #define NEOVERSE_V1_ACTLR5_EL1_BIT_56				(ULL(1) << 56)
+#define NEOVERSE_V1_ACTLR5_EL1_BIT_61				(ULL(1) << 61)
 
 #endif /* NEOVERSE_V1_H */
diff --git a/include/lib/cpus/aarch64/neoverse_v2.h b/include/lib/cpus/aarch64/neoverse_v2.h
index 68c15587..1171e952 100644
--- a/include/lib/cpus/aarch64/neoverse_v2.h
+++ b/include/lib/cpus/aarch64/neoverse_v2.h
@@ -16,12 +16,17 @@
  * CPU Extended Control register specific definitions
  ******************************************************************************/
 #define NEOVERSE_V2_CPUECTLR_EL1			S3_0_C15_C1_4
+#define NEOVERSE_V2_CPUECTLR_EL1_EXTLLC_BIT		(ULL(1) << 0)
 
 /*******************************************************************************
  * CPU Power Control register specific definitions
  ******************************************************************************/
 #define NEOVERSE_V2_CPUPWRCTLR_EL1			S3_0_C15_C2_7
 #define NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT	U(1)
+#define NEOVERSE_V2_CPUPWRCTLR_EL1_WFI_RET_CTRL_SHIFT	U(4)
+#define NEOVERSE_V2_CPUPWRCTLR_EL1_WFI_RET_CTRL_WIDTH	U(3)
+#define NEOVERSE_V2_CPUPWRCTLR_EL1_WFE_RET_CTRL_SHIFT	U(7)
+#define NEOVERSE_V2_CPUPWRCTLR_EL1_WFE_RET_CTRL_WIDTH	U(3)
 
 /*******************************************************************************
  * CPU Extended Control register 2 specific definitions.
@@ -30,6 +35,9 @@
 #define NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_CNSRV		ULL(9)
 #define NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_LSB		U(11)
 #define NEOVERSE_V2_CPUECTLR2_EL1_PF_MODE_WIDTH		U(4)
+#define NEOVERSE_V2_CPUECTLR2_EL1_TXREQ_STATIC_FULL	ULL(0)
+#define NEOVERSE_V2_CPUECTLR2_EL1_TXREQ_LSB		U(0)
+#define NEOVERSE_V2_CPUECTLR2_EL1_TXREQ_WIDTH		U(3)
 
 /*******************************************************************************
  * CPU Auxiliary Control register 2 specific definitions.
diff --git a/include/lib/cpus/aarch64/neoverse_v3.h b/include/lib/cpus/aarch64/neoverse_v3.h
new file mode 100644
index 00000000..e5f75ba9
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_v3.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_V3_H
+#define NEOVERSE_V3_H
+
+
+#define NEOVERSE_V3_VNAE_MIDR				U(0x410FD830)
+#define NEOVERSE_V3_MIDR				U(0x410FD840)
+
+/* Neoverse V3 loop count for CVE-2022-23960 mitigation */
+#define NEOVERSE_V3_BHB_LOOP_COUNT			U(132)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_V3_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define NEOVERSE_V3_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define NEOVERSE_V3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		U(1)
+
+#endif /* NEOVERSE_V3_H */
diff --git a/include/lib/cpus/cpu_ops.h b/include/lib/cpus/cpu_ops.h
index 8b36ff12..0084189b 100644
--- a/include/lib/cpus/cpu_ops.h
+++ b/include/lib/cpus/cpu_ops.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -57,7 +57,6 @@
 #define CPU_ERRATA_LIST_END_SIZE	CPU_WORD_SIZE
 /* Fields required to print errata status  */
 #if REPORT_ERRATA
-#define CPU_ERRATA_FUNC_SIZE	CPU_WORD_SIZE
 #define CPU_CPU_STR_SIZE	CPU_WORD_SIZE
 /* BL1 doesn't require mutual exclusion and printed flag. */
 #if defined(IMAGE_BL31) || defined(IMAGE_BL32)
@@ -68,7 +67,6 @@
 #define CPU_ERRATA_PRINTED_SIZE	0
 #endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */
 #else
-#define CPU_ERRATA_FUNC_SIZE	0
 #define CPU_CPU_STR_SIZE	0
 #define CPU_ERRATA_LOCK_SIZE	0
 #define CPU_ERRATA_PRINTED_SIZE	0
@@ -98,8 +96,7 @@
 #endif /* __aarch64__ */
 #define CPU_ERRATA_LIST_START	CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE
 #define CPU_ERRATA_LIST_END	CPU_ERRATA_LIST_START + CPU_ERRATA_LIST_START_SIZE
-#define CPU_ERRATA_FUNC		CPU_ERRATA_LIST_END + CPU_ERRATA_LIST_END_SIZE
-#define CPU_CPU_STR		CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE
+#define CPU_CPU_STR		CPU_ERRATA_LIST_END + CPU_ERRATA_LIST_END_SIZE
 #define CPU_ERRATA_LOCK		CPU_CPU_STR + CPU_CPU_STR_SIZE
 #define CPU_ERRATA_PRINTED	CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE
 #if __aarch64__
@@ -130,7 +127,6 @@ struct cpu_ops {
 	void *errata_list_start;
 	void *errata_list_end;
 #if REPORT_ERRATA
-	void (*errata_func)(void);
 	char *cpu_str;
 #if defined(IMAGE_BL31) || defined(IMAGE_BL32)
 	spinlock_t *errata_lock;
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index 20808989..2c31515e 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,11 +25,28 @@
 #define ERRATUM_MITIGATED	ERRATUM_CHOSEN + ERRATUM_CHOSEN_SIZE
 #define ERRATUM_ENTRY_SIZE	ERRATUM_MITIGATED + ERRATUM_MITIGATED_SIZE
 
+/* Errata status */
+#define ERRATA_NOT_APPLIES	0
+#define ERRATA_APPLIES		1
+#define ERRATA_MISSING		2
+
 #ifndef __ASSEMBLER__
 #include <lib/cassert.h>
 
 void print_errata_status(void);
-void errata_print_msg(unsigned int status, const char *cpu, const char *id);
+
+#if ERRATA_A75_764081
+bool errata_a75_764081_applies(void);
+#else
+static inline bool errata_a75_764081_applies(void)
+{
+       return false;
+}
+#endif
+
+#if ERRATA_A520_2938996 || ERRATA_X4_2726228
+unsigned int check_if_affected_core(void);
+#endif
 
 /*
  * NOTE that this structure will be different on AArch32 and AArch64. The
@@ -74,11 +91,6 @@ CASSERT(sizeof(struct erratum_entry) == ERRATUM_ENTRY_SIZE,
 
 #endif /* __ASSEMBLER__ */
 
-/* Errata status */
-#define ERRATA_NOT_APPLIES	0
-#define ERRATA_APPLIES		1
-#define ERRATA_MISSING		2
-
 /* Macro to get CPU revision code for checking errata version compatibility. */
 #define CPU_REV(r, p)		((r << 4) | p)
 
diff --git a/include/lib/debugfs.h b/include/lib/debugfs.h
index 8ed237ae..1fdccb6a 100644
--- a/include/lib/debugfs.h
+++ b/include/lib/debugfs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -61,11 +61,23 @@ int debugfs_smc_setup(void);
 /* Debugfs version returned through SMC interface */
 #define DEBUGFS_VERSION		(0x000000001U)
 
-/* Function ID for accessing the debugfs interface */
-#define DEBUGFS_FID_VALUE	(0x30U)
+/* Function ID for accessing the debugfs interface from
+ * Vendor-Specific EL3 Range.
+ */
+#define DEBUGFS_FID_VALUE	(0x10U)
+
+#define is_debugfs_fid(_fid) \
+	(GET_SMC_NUM(_fid) == DEBUGFS_FID_VALUE)
+
+
+/* Function ID for accessing the debugfs interface from arm sip.
+ * This is now deprecated FID and will be removed after 2.12 release.
+ */
+#define DEBUGFS_FID_VALUE_DEPRECATED	(0x30U)
+
+#define is_debugfs_fid_deprecated(_fid)	\
+	(GET_SMC_NUM(_fid) == DEBUGFS_FID_VALUE_DEPRECATED)
 
-#define is_debugfs_fid(_fid)	\
-	(((_fid) & FUNCID_NUM_MASK) == DEBUGFS_FID_VALUE)
 
 /* Error code for debugfs SMC interface failures */
 #define DEBUGFS_E_INVALID_PARAMS	(-2)
diff --git a/include/lib/dice/dice.h b/include/lib/dice/dice.h
new file mode 100644
index 00000000..cf549422
--- /dev/null
+++ b/include/lib/dice/dice.h
@@ -0,0 +1,166 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#ifndef DICE_DICE_H_
+#define DICE_DICE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DICE_CDI_SIZE 32
+#define DICE_HASH_SIZE 64
+#define DICE_HIDDEN_SIZE 64
+#define DICE_INLINE_CONFIG_SIZE 64
+#define DICE_PRIVATE_KEY_SEED_SIZE 32
+#define DICE_ID_SIZE 20
+
+typedef enum {
+  kDiceResultOk,
+  kDiceResultInvalidInput,
+  kDiceResultBufferTooSmall,
+  kDiceResultPlatformError,
+} DiceResult;
+
+typedef enum {
+  kDiceModeNotInitialized,
+  kDiceModeNormal,
+  kDiceModeDebug,
+  kDiceModeMaintenance,
+} DiceMode;
+
+typedef enum {
+  kDiceConfigTypeInline,
+  kDiceConfigTypeDescriptor,
+} DiceConfigType;
+
+// Contains a full set of input values describing the target program or system.
+// See the Open Profile for DICE specification for a detailed explanation of
+// these inputs.
+//
+// Fields:
+//    code_hash: A hash or similar representation of the target code.
+//    code_descriptor: An optional descriptor to be included in the certificate.
+//        This descriptor is opaque to the DICE flow and is included verbatim
+//        in the certificate with no validation. May be null.
+//    code_descriptor_size: The size in bytes of |code_descriptor|.
+//    config_type: Indicates how to interpret the remaining config-related
+//        fields. If the type is 'inline', then the 64 byte configuration input
+//        value must be provided in |config_value| and |config_descriptor| is
+//        ignored. If the type is 'descriptor', then |config_descriptor| is
+//        hashed to get the configuration input value and |config_value| is
+//        ignored.
+//    config_value: A 64-byte configuration input value when |config_type| is
+//        kDiceConfigTypeInline. Otherwise, this field is ignored.
+//    config_descriptor: A descriptor to be hashed for the configuration input
+//        value when |config_type| is kDiceConfigTypeDescriptor. Otherwise,
+//        this field is ignored and may be null.
+//    config_descriptor_size: The size in bytes of |config_descriptor|.
+//    authority_hash: A hash or similar representation of the authority used to
+//        verify the target code. If the code is not verified or the authority
+//        is implicit, for example hard coded as part of the code currently
+//        executing, then this value should be set to all zero bytes.
+//    authority_descriptor: An optional descriptor to be included in the
+//        certificate. This descriptor is opaque to the DICE flow and is
+//        included verbatim in the certificate with no validation. May be null.
+//    authority_descriptor_size: The size in bytes of |authority_descriptor|.
+//    mode: The current operating mode.
+//    hidden: Additional input which will not appear in certificates. If this is
+//        not used it should be set to all zero bytes.
+typedef struct DiceInputValues_ {
+  uint8_t code_hash[DICE_HASH_SIZE];
+  const uint8_t* code_descriptor;
+  size_t code_descriptor_size;
+  DiceConfigType config_type;
+  uint8_t config_value[DICE_INLINE_CONFIG_SIZE];
+  const uint8_t* config_descriptor;
+  size_t config_descriptor_size;
+  uint8_t authority_hash[DICE_HASH_SIZE];
+  const uint8_t* authority_descriptor;
+  size_t authority_descriptor_size;
+  DiceMode mode;
+  uint8_t hidden[DICE_HIDDEN_SIZE];
+} DiceInputValues;
+
+// Derives a |cdi_private_key_seed| from a |cdi_attest| value. On success
+// populates |cdi_private_key_seed| and returns kDiceResultOk.
+DiceResult DiceDeriveCdiPrivateKeySeed(
+    void* context, const uint8_t cdi_attest[DICE_CDI_SIZE],
+    uint8_t cdi_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE]);
+
+// Derives an |id| from a |cdi_public_key| value. Because public keys can vary
+// in length depending on the algorithm, the |cdi_public_key_size| in bytes must
+// be provided. When interpreted as an integer, |id| is big-endian. On success
+// populates |id| and returns kDiceResultOk.
+DiceResult DiceDeriveCdiCertificateId(void* context,
+                                      const uint8_t* cdi_public_key,
+                                      size_t cdi_public_key_size,
+                                      uint8_t id[DICE_ID_SIZE]);
+
+// Executes the main DICE flow.
+//
+// Given a full set of input values and the current CDI values, computes the
+// next CDI values and a matching certificate. See the Open Profile for DICE
+// specification for a detailed explanation of this flow.
+// In certain cases, the caller may not need to generate the CDI certificate.
+// The caller should signal this by setting the certificate parameters to
+// null/zero values appropriately.
+//
+// Parameters:
+//    context: Context provided by the caller that is opaque to this library
+//        but is passed through to the integration-provided operations in
+//        dice/ops.h. The value is, therefore, integration-specific and may be
+//        null.
+//    current_cdi_attest, current_cdi_seal: The current CDI values as produced
+//        by a previous DICE flow. If this is the first DICE flow in a system,
+//        the Unique Device Secret (UDS) should be used for both of these
+//        arguments.
+//    input_values: A set of input values describing the target program or
+//        system.
+//    next_cdi_certificate_buffer_size: The size in bytes of the buffer pointed
+//        to by the |next_cdi_certificate| argument. This should be set to zero
+//        if next CDI certificate should not be computed.
+//    next_cdi_certificate: On success, will be populated with the generated
+//        certificate, up to |next_cdi_certificate_buffer_size| in size. If the
+//        certificate cannot fit in the buffer, |next_cdi_certificate_size| is
+//        populated with the required size and kDiceResultBufferTooSmall is
+//        returned. This should be set to NULL if next CDI certificate should
+//        not be computed.
+//    next_cdi_certificate_actual_size: On success, will be populated with the
+//        size, in bytes, of the certificate data written to
+//        |next_cdi_certificate|. If kDiceResultBufferTooSmall is returned, will
+//        be populated with the required buffer size. This should be set to NULL
+//        if next CDI certificate should not be computed.
+//    next_cdi_attest: On success, will be populated with the next CDI value for
+//        attestation.
+//    next_cdi_seal: On success, will be populated with the next CDI value for
+//        sealing.
+DiceResult DiceMainFlow(void* context,
+                        const uint8_t current_cdi_attest[DICE_CDI_SIZE],
+                        const uint8_t current_cdi_seal[DICE_CDI_SIZE],
+                        const DiceInputValues* input_values,
+                        size_t next_cdi_certificate_buffer_size,
+                        uint8_t* next_cdi_certificate,
+                        size_t* next_cdi_certificate_actual_size,
+                        uint8_t next_cdi_attest[DICE_CDI_SIZE],
+                        uint8_t next_cdi_seal[DICE_CDI_SIZE]);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // DICE_DICE_H_
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 47d91de0..87f15413 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,18 @@
 #ifndef CONTEXT_H
 #define CONTEXT_H
 
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
+#include <lib/el3_runtime/context_el2.h>
+#else
+/**
+ * El1 context is required either when:
+ * IMAGE_BL1 || ((!CTX_INCLUDE_EL2_REGS) && IMAGE_BL31)
+ */
+#include <lib/el3_runtime/context_el1.h>
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
+
 #include <lib/el3_runtime/cpu_data.h>
+#include <lib/el3_runtime/simd_ctx.h>
 #include <lib/utils_def.h>
 
 /*******************************************************************************
@@ -62,7 +73,7 @@
 #define CTX_ELR_EL3		U(0x20)
 #define CTX_PMCR_EL0		U(0x28)
 #define CTX_IS_IN_EL3		U(0x30)
-#define CTX_MPAM3_EL3		U(0x38)
+#define CTX_MDCR_EL3		U(0x38)
 /* Constants required in supporting nested exception in EL3 */
 #define CTX_SAVED_ELR_EL3	U(0x40)
 /*
@@ -78,250 +89,64 @@
  #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 */
-#endif
-
-/*******************************************************************************
- * Constants that allow assembler code to access members of and the
- * 'el1_sys_regs' structure at their correct offsets. Note that some of the
- * registers are only 32-bits wide but are stored as 64-bit values for
- * convenience
- ******************************************************************************/
-#define CTX_EL1_SYSREGS_OFFSET	(CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
-#define CTX_SPSR_EL1		U(0x0)
-#define CTX_ELR_EL1		U(0x8)
-#define CTX_SCTLR_EL1		U(0x10)
-#define CTX_TCR_EL1		U(0x18)
-#define CTX_CPACR_EL1		U(0x20)
-#define CTX_CSSELR_EL1		U(0x28)
-#define CTX_SP_EL1		U(0x30)
-#define CTX_ESR_EL1		U(0x38)
-#define CTX_TTBR0_EL1		U(0x40)
-#define CTX_TTBR1_EL1		U(0x48)
-#define CTX_MAIR_EL1		U(0x50)
-#define CTX_AMAIR_EL1		U(0x58)
-#define CTX_ACTLR_EL1		U(0x60)
-#define CTX_TPIDR_EL1		U(0x68)
-#define CTX_TPIDR_EL0		U(0x70)
-#define CTX_TPIDRRO_EL0		U(0x78)
-#define CTX_PAR_EL1		U(0x80)
-#define CTX_FAR_EL1		U(0x88)
-#define CTX_AFSR0_EL1		U(0x90)
-#define CTX_AFSR1_EL1		U(0x98)
-#define CTX_CONTEXTIDR_EL1	U(0xa0)
-#define CTX_VBAR_EL1		U(0xa8)
-
-/*
- * If the platform is AArch64-only, there is no need to save and restore these
- * AArch32 registers.
- */
-#if CTX_INCLUDE_AARCH32_REGS
-#define CTX_SPSR_ABT		U(0xb0)	/* Align to the next 16 byte boundary */
-#define CTX_SPSR_UND		U(0xb8)
-#define CTX_SPSR_IRQ		U(0xc0)
-#define CTX_SPSR_FIQ		U(0xc8)
-#define CTX_DACR32_EL2		U(0xd0)
-#define CTX_IFSR32_EL2		U(0xd8)
-#define CTX_AARCH32_END		U(0xe0) /* Align to the next 16 byte boundary */
-#else
-#define CTX_AARCH32_END		U(0xb0)	/* Align to the next 16 byte boundary */
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-
-/*
- * If the timer registers aren't saved and restored, we don't have to reserve
- * space for them in the context
- */
-#if NS_TIMER_SWITCH
-#define CTX_CNTP_CTL_EL0	(CTX_AARCH32_END + U(0x0))
-#define CTX_CNTP_CVAL_EL0	(CTX_AARCH32_END + U(0x8))
-#define CTX_CNTV_CTL_EL0	(CTX_AARCH32_END + U(0x10))
-#define CTX_CNTV_CVAL_EL0	(CTX_AARCH32_END + U(0x18))
-#define CTX_CNTKCTL_EL1		(CTX_AARCH32_END + U(0x20))
-#define CTX_TIMER_SYSREGS_END	(CTX_AARCH32_END + U(0x30)) /* Align to the next 16 byte boundary */
-#else
-#define CTX_TIMER_SYSREGS_END	CTX_AARCH32_END
-#endif /* NS_TIMER_SWITCH */
-
-#if CTX_INCLUDE_MTE_REGS
-#define CTX_TFSRE0_EL1		(CTX_TIMER_SYSREGS_END + U(0x0))
-#define CTX_TFSR_EL1		(CTX_TIMER_SYSREGS_END + U(0x8))
-#define CTX_RGSR_EL1		(CTX_TIMER_SYSREGS_END + U(0x10))
-#define CTX_GCR_EL1		(CTX_TIMER_SYSREGS_END + U(0x18))
-
-/* Align to the next 16 byte boundary */
-#define CTX_MTE_REGS_END	(CTX_TIMER_SYSREGS_END + U(0x20))
-#else
-#define CTX_MTE_REGS_END	CTX_TIMER_SYSREGS_END
-#endif /* CTX_INCLUDE_MTE_REGS */
-
-/*
- * End of system registers.
- */
-#define CTX_EL1_SYSREGS_END		CTX_MTE_REGS_END
+#endif /* FFH_SUPPORT */
 
-/*
- * EL2 register set
- */
-
-#if CTX_INCLUDE_EL2_REGS
-/* For later discussion
- * ICH_AP0R<n>_EL2
- * ICH_AP1R<n>_EL2
- * AMEVCNTVOFF0<n>_EL2
- * AMEVCNTVOFF1<n>_EL2
- * ICH_LR<n>_EL2
- */
-#define CTX_EL2_SYSREGS_OFFSET	(CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
-
-#define CTX_ACTLR_EL2		U(0x0)
-#define CTX_AFSR0_EL2		U(0x8)
-#define CTX_AFSR1_EL2		U(0x10)
-#define CTX_AMAIR_EL2		U(0x18)
-#define CTX_CNTHCTL_EL2		U(0x20)
-#define CTX_CNTVOFF_EL2		U(0x28)
-#define CTX_CPTR_EL2		U(0x30)
-#define CTX_DBGVCR32_EL2	U(0x38)
-#define CTX_ELR_EL2		U(0x40)
-#define CTX_ESR_EL2		U(0x48)
-#define CTX_FAR_EL2		U(0x50)
-#define CTX_HACR_EL2		U(0x58)
-#define CTX_HCR_EL2		U(0x60)
-#define CTX_HPFAR_EL2		U(0x68)
-#define CTX_HSTR_EL2		U(0x70)
-#define CTX_ICC_SRE_EL2		U(0x78)
-#define CTX_ICH_HCR_EL2		U(0x80)
-#define CTX_ICH_VMCR_EL2	U(0x88)
-#define CTX_MAIR_EL2		U(0x90)
-#define CTX_MDCR_EL2		U(0x98)
-#define CTX_PMSCR_EL2		U(0xa0)
-#define CTX_SCTLR_EL2		U(0xa8)
-#define CTX_SPSR_EL2		U(0xb0)
-#define CTX_SP_EL2		U(0xb8)
-#define CTX_TCR_EL2		U(0xc0)
-#define CTX_TPIDR_EL2		U(0xc8)
-#define CTX_TTBR0_EL2		U(0xd0)
-#define CTX_VBAR_EL2		U(0xd8)
-#define CTX_VMPIDR_EL2		U(0xe0)
-#define CTX_VPIDR_EL2		U(0xe8)
-#define CTX_VTCR_EL2		U(0xf0)
-#define CTX_VTTBR_EL2		U(0xf8)
-
-// Only if MTE registers in use
-#define CTX_TFSR_EL2		U(0x100)
-
-#define CTX_MPAM2_EL2		U(0x108)
-#define CTX_MPAMHCR_EL2		U(0x110)
-#define CTX_MPAMVPM0_EL2	U(0x118)
-#define CTX_MPAMVPM1_EL2	U(0x120)
-#define CTX_MPAMVPM2_EL2	U(0x128)
-#define CTX_MPAMVPM3_EL2	U(0x130)
-#define CTX_MPAMVPM4_EL2	U(0x138)
-#define CTX_MPAMVPM5_EL2	U(0x140)
-#define CTX_MPAMVPM6_EL2	U(0x148)
-#define CTX_MPAMVPM7_EL2	U(0x150)
-#define CTX_MPAMVPMV_EL2	U(0x158)
-
-// Starting with Armv8.6
-#define CTX_HDFGRTR_EL2		U(0x160)
-#define CTX_HAFGRTR_EL2		U(0x168)
-#define CTX_HDFGWTR_EL2		U(0x170)
-#define CTX_HFGITR_EL2		U(0x178)
-#define CTX_HFGRTR_EL2		U(0x180)
-#define CTX_HFGWTR_EL2		U(0x188)
-#define CTX_CNTPOFF_EL2		U(0x190)
-
-// Starting with Armv8.4
-#define CTX_CONTEXTIDR_EL2	U(0x198)
-#define CTX_TTBR1_EL2		U(0x1a0)
-#define CTX_VDISR_EL2		U(0x1a8)
-#define CTX_VSESR_EL2		U(0x1b0)
-#define CTX_VNCR_EL2		U(0x1b8)
-#define CTX_TRFCR_EL2		U(0x1c0)
-
-// Starting with Armv8.5
-#define CTX_SCXTNUM_EL2		U(0x1c8)
-
-// Register for FEAT_HCX
-#define CTX_HCRX_EL2            U(0x1d0)
-
-// Starting with Armv8.9
-#define CTX_TCR2_EL2            U(0x1d8)
-#define CTX_POR_EL2             U(0x1e0)
-#define CTX_PIRE0_EL2           U(0x1e8)
-#define CTX_PIR_EL2             U(0x1f0)
-#define CTX_S2PIR_EL2		U(0x1f8)
-#define CTX_GCSCR_EL2           U(0x200)
-#define CTX_GCSPR_EL2           U(0x208)
-
-/* Align to the next 16 byte boundary */
-#define CTX_EL2_SYSREGS_END	U(0x210)
-
-#endif /* CTX_INCLUDE_EL2_REGS */
-
-/*******************************************************************************
- * Constants that allow assembler code to access members of and the 'fp_regs'
- * structure at their correct offsets.
- ******************************************************************************/
-#if CTX_INCLUDE_EL2_REGS
-# define CTX_FPREGS_OFFSET	(CTX_EL2_SYSREGS_OFFSET + CTX_EL2_SYSREGS_END)
-#else
-# define CTX_FPREGS_OFFSET	(CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
-#endif
-#if CTX_INCLUDE_FPREGS
-#define CTX_FP_Q0		U(0x0)
-#define CTX_FP_Q1		U(0x10)
-#define CTX_FP_Q2		U(0x20)
-#define CTX_FP_Q3		U(0x30)
-#define CTX_FP_Q4		U(0x40)
-#define CTX_FP_Q5		U(0x50)
-#define CTX_FP_Q6		U(0x60)
-#define CTX_FP_Q7		U(0x70)
-#define CTX_FP_Q8		U(0x80)
-#define CTX_FP_Q9		U(0x90)
-#define CTX_FP_Q10		U(0xa0)
-#define CTX_FP_Q11		U(0xb0)
-#define CTX_FP_Q12		U(0xc0)
-#define CTX_FP_Q13		U(0xd0)
-#define CTX_FP_Q14		U(0xe0)
-#define CTX_FP_Q15		U(0xf0)
-#define CTX_FP_Q16		U(0x100)
-#define CTX_FP_Q17		U(0x110)
-#define CTX_FP_Q18		U(0x120)
-#define CTX_FP_Q19		U(0x130)
-#define CTX_FP_Q20		U(0x140)
-#define CTX_FP_Q21		U(0x150)
-#define CTX_FP_Q22		U(0x160)
-#define CTX_FP_Q23		U(0x170)
-#define CTX_FP_Q24		U(0x180)
-#define CTX_FP_Q25		U(0x190)
-#define CTX_FP_Q26		U(0x1a0)
-#define CTX_FP_Q27		U(0x1b0)
-#define CTX_FP_Q28		U(0x1c0)
-#define CTX_FP_Q29		U(0x1d0)
-#define CTX_FP_Q30		U(0x1e0)
-#define CTX_FP_Q31		U(0x1f0)
-#define CTX_FP_FPSR		U(0x200)
-#define CTX_FP_FPCR		U(0x208)
-#if CTX_INCLUDE_AARCH32_REGS
-#define CTX_FP_FPEXC32_EL2	U(0x210)
-#define CTX_FPREGS_END		U(0x220) /* Align to the next 16 byte boundary */
-#else
-#define CTX_FPREGS_END		U(0x210) /* Align to the next 16 byte boundary */
-#endif
-#else
-#define CTX_FPREGS_END		U(0)
-#endif
 
 /*******************************************************************************
  * Registers related to CVE-2018-3639
  ******************************************************************************/
-#define CTX_CVE_2018_3639_OFFSET	(CTX_FPREGS_OFFSET + CTX_FPREGS_END)
+#define CTX_CVE_2018_3639_OFFSET	(CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
 #define CTX_CVE_2018_3639_DISABLE	U(0)
 #define CTX_CVE_2018_3639_END		U(0x10) /* Align to the next 16 byte boundary */
 
+/*******************************************************************************
+ * Registers related to ERRATA_SPECULATIVE_AT
+ *
+ * This is essential as with EL1 and EL2 context registers being decoupled,
+ * both will not be present for a given build configuration.
+ * As ERRATA_SPECULATIVE_AT errata requires SCTLR_EL1 and TCR_EL1 registers
+ * independent of the above logic, we need explicit context entries to be
+ * reserved for these registers.
+ *
+ * NOTE: Based on this we end up with following different configurations depending
+ * on the presence of errata and inclusion of EL1 or EL2 context.
+ *
+ * ============================================================================
+ * | ERRATA_SPECULATIVE_AT | EL1 context| Memory allocation(Sctlr_el1,Tcr_el1)|
+ * ============================================================================
+ * |        0              |      0     |            None                     |
+ * |        0              |      1     |    EL1 C-Context structure          |
+ * |        1              |      0     |    Errata Context Offset Entries    |
+ * |        1              |      1     |    Errata Context Offset Entries    |
+ * ============================================================================
+ *
+ * In the above table, when ERRATA_SPECULATIVE_AT=1, EL1_Context=0, it implies
+ * there is only EL2 context and memory for SCTLR_EL1 and TCR_EL1 registers is
+ * reserved explicitly under ERRATA_SPECULATIVE_AT build flag here.
+ *
+ * In situations when EL1_Context=1 and  ERRATA_SPECULATIVE_AT=1, since SCTLR_EL1
+ * and TCR_EL1 registers will be modified under errata and it happens at the
+ * early in the codeflow prior to el1 context (save and restore operations),
+ * context memory still will be reserved under the errata logic here explicitly.
+ * These registers will not be part of EL1 context save & restore routines.
+ *
+ * Only when ERRATA_SPECULATIVE_AT=0, EL1_Context=1, for this combination,
+ * SCTLR_EL1 and TCR_EL1 will be part of EL1 context structure (context_el1.h)
+ * -----------------------------------------------------------------------------
+ ******************************************************************************/
+#define CTX_ERRATA_SPEC_AT_OFFSET	(CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_END)
+#if ERRATA_SPECULATIVE_AT
+#define CTX_ERRATA_SPEC_AT_SCTLR_EL1	U(0x0)
+#define CTX_ERRATA_SPEC_AT_TCR_EL1	U(0x8)
+#define CTX_ERRATA_SPEC_AT_END		U(0x10) /* Align to the next 16 byte boundary */
+#else
+#define CTX_ERRATA_SPEC_AT_END		U(0x0)
+#endif /* ERRATA_SPECULATIVE_AT */
+
 /*******************************************************************************
  * Registers related to ARMv8.3-PAuth.
  ******************************************************************************/
-#define CTX_PAUTH_REGS_OFFSET	(CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_END)
+#define CTX_PAUTH_REGS_OFFSET	(CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_END)
 #if CTX_INCLUDE_PAUTH_REGS
 #define CTX_PACIAKEY_LO		U(0x0)
 #define CTX_PACIAKEY_HI		U(0x8)
@@ -341,9 +166,10 @@
 /*******************************************************************************
  * Registers initialised in a per-world context.
  ******************************************************************************/
-#define CTX_CPTR_EL3		U(0x0)
-#define CTX_ZCR_EL3		U(0x8)
-#define CTX_GLOBAL_EL3STATE_END	U(0x10)
+#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)
 
 #ifndef __ASSEMBLER__
 
@@ -363,15 +189,13 @@
 
 /* Constants to determine the size of individual context structures */
 #define CTX_GPREG_ALL		(CTX_GPREGS_END >> DWORD_SHIFT)
-#define CTX_EL1_SYSREGS_ALL	(CTX_EL1_SYSREGS_END >> DWORD_SHIFT)
-#if CTX_INCLUDE_EL2_REGS
-# define CTX_EL2_SYSREGS_ALL	(CTX_EL2_SYSREGS_END >> DWORD_SHIFT)
-#endif
-#if CTX_INCLUDE_FPREGS
-# define CTX_FPREG_ALL		(CTX_FPREGS_END >> DWORD_SHIFT)
-#endif
+
 #define CTX_EL3STATE_ALL	(CTX_EL3STATE_END >> DWORD_SHIFT)
 #define CTX_CVE_2018_3639_ALL	(CTX_CVE_2018_3639_END >> DWORD_SHIFT)
+
+#if ERRATA_SPECULATIVE_AT
+#define CTX_ERRATA_SPEC_AT_ALL	(CTX_ERRATA_SPEC_AT_END >> DWORD_SHIFT)
+#endif
 #if CTX_INCLUDE_PAUTH_REGS
 # define CTX_PAUTH_REGS_ALL	(CTX_PAUTH_REGS_END >> DWORD_SHIFT)
 #endif
@@ -385,30 +209,6 @@
  */
 DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL);
 
-/*
- * AArch64 EL1 system register context structure for preserving the
- * architectural state during world switches.
- */
-DEFINE_REG_STRUCT(el1_sysregs, CTX_EL1_SYSREGS_ALL);
-
-
-/*
- * AArch64 EL2 system register context structure for preserving the
- * architectural state during world switches.
- */
-#if CTX_INCLUDE_EL2_REGS
-DEFINE_REG_STRUCT(el2_sysregs, CTX_EL2_SYSREGS_ALL);
-#endif
-
-/*
- * AArch64 floating point register context structure for preserving
- * the floating point state during switches from one security state to
- * another.
- */
-#if CTX_INCLUDE_FPREGS
-DEFINE_REG_STRUCT(fp_regs, CTX_FPREG_ALL);
-#endif
-
 /*
  * Miscellaneous registers used by EL3 firmware to maintain its state
  * across exception entries and exits
@@ -418,6 +218,11 @@ DEFINE_REG_STRUCT(el3_state, CTX_EL3STATE_ALL);
 /* Function pointer used by CVE-2018-3639 dynamic mitigation */
 DEFINE_REG_STRUCT(cve_2018_3639, CTX_CVE_2018_3639_ALL);
 
+/* Registers associated to Errata_Speculative */
+#if ERRATA_SPECULATIVE_AT
+DEFINE_REG_STRUCT(errata_speculative_at, CTX_ERRATA_SPEC_AT_ALL);
+#endif
+
 /* Registers associated to ARMv8.3-PAuth */
 #if CTX_INCLUDE_PAUTH_REGS
 DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL);
@@ -442,17 +247,29 @@ DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL);
 typedef struct cpu_context {
 	gp_regs_t gpregs_ctx;
 	el3_state_t el3state_ctx;
-	el1_sysregs_t el1_sysregs_ctx;
-#if CTX_INCLUDE_EL2_REGS
-	el2_sysregs_t el2_sysregs_ctx;
-#endif
-#if CTX_INCLUDE_FPREGS
-	fp_regs_t fpregs_ctx;
-#endif
+
 	cve_2018_3639_t cve_2018_3639_ctx;
+
+#if ERRATA_SPECULATIVE_AT
+	errata_speculative_at_t errata_speculative_at_ctx;
+#endif
+
 #if CTX_INCLUDE_PAUTH_REGS
 	pauth_t pauth_ctx;
 #endif
+
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
+	el2_sysregs_t el2_sysregs_ctx;
+#else
+	/* El1 context should be included only either for IMAGE_BL1,
+	 * or for IMAGE_BL31 when CTX_INCLUDE_EL2_REGS=0:
+	 * When SPMD_SPM_AT_SEL2=1, SPMC at S-EL2 takes care of saving
+	 * and restoring EL1 registers. In this case, BL31 at EL3 can
+	 * exclude save and restore of EL1 context registers.
+	 */
+	el1_sysregs_t el1_sysregs_ctx;
+#endif
+
 } cpu_context_t;
 
 /*
@@ -462,21 +279,27 @@ typedef struct cpu_context {
 typedef struct per_world_context {
 	uint64_t ctx_cptr_el3;
 	uint64_t ctx_zcr_el3;
+	uint64_t ctx_mpam3_el3;
 } per_world_context_t;
 
 extern per_world_context_t per_world_context[CPU_DATA_CONTEXT_NUM];
 
 /* Macros to access members of the 'cpu_context_t' structure */
 #define get_el3state_ctx(h)	(&((cpu_context_t *) h)->el3state_ctx)
-#if CTX_INCLUDE_FPREGS
-# define get_fpregs_ctx(h)	(&((cpu_context_t *) h)->fpregs_ctx)
-#endif
+
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
+#define get_el2_sysregs_ctx(h)	(&((cpu_context_t *) h)->el2_sysregs_ctx)
+#else
 #define get_el1_sysregs_ctx(h)	(&((cpu_context_t *) h)->el1_sysregs_ctx)
-#if CTX_INCLUDE_EL2_REGS
-# define get_el2_sysregs_ctx(h)	(&((cpu_context_t *) h)->el2_sysregs_ctx)
 #endif
+
 #define get_gpregs_ctx(h)	(&((cpu_context_t *) h)->gpregs_ctx)
 #define get_cve_2018_3639_ctx(h)	(&((cpu_context_t *) h)->cve_2018_3639_ctx)
+
+#if ERRATA_SPECULATIVE_AT
+#define get_errata_speculative_at_ctx(h)	(&((cpu_context_t *) h)->errata_speculative_at_ctx)
+#endif
+
 #if CTX_INCLUDE_PAUTH_REGS
 # define get_pauth_ctx(h)	(&((cpu_context_t *) h)->pauth_ctx)
 #endif
@@ -488,24 +311,23 @@ extern per_world_context_t per_world_context[CPU_DATA_CONTEXT_NUM];
  */
 CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx),
 	assert_core_context_gp_offset_mismatch);
-CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx),
-	assert_core_context_el1_sys_offset_mismatch);
-#if CTX_INCLUDE_EL2_REGS
-CASSERT(CTX_EL2_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el2_sysregs_ctx),
-	assert_core_context_el2_sys_offset_mismatch);
-#endif
-#if CTX_INCLUDE_FPREGS
-CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx),
-	assert_core_context_fp_offset_mismatch);
-#endif
+
 CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx),
 	assert_core_context_el3state_offset_mismatch);
+
+
 CASSERT(CTX_CVE_2018_3639_OFFSET == __builtin_offsetof(cpu_context_t, cve_2018_3639_ctx),
 	assert_core_context_cve_2018_3639_offset_mismatch);
+
+#if ERRATA_SPECULATIVE_AT
+CASSERT(CTX_ERRATA_SPEC_AT_OFFSET == __builtin_offsetof(cpu_context_t, errata_speculative_at_ctx),
+	assert_core_context_errata_speculative_at_offset_mismatch);
+#endif
+
 #if CTX_INCLUDE_PAUTH_REGS
 CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx),
 	assert_core_context_pauth_offset_mismatch);
-#endif
+#endif /* CTX_INCLUDE_PAUTH_REGS */
 
 /*
  * Helper macro to set the general purpose registers that correspond to
@@ -546,14 +368,74 @@ CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx),
 /*******************************************************************************
  * Function prototypes
  ******************************************************************************/
-void el1_sysregs_context_save(el1_sysregs_t *regs);
-void el1_sysregs_context_restore(el1_sysregs_t *regs);
-
 #if CTX_INCLUDE_FPREGS
-void fpregs_context_save(fp_regs_t *regs);
-void fpregs_context_restore(fp_regs_t *regs);
+void fpregs_context_save(simd_regs_t *regs);
+void fpregs_context_restore(simd_regs_t *regs);
 #endif
 
+/*******************************************************************************
+ * The next four inline functions are required for IMAGE_BL1, as well as for
+ * IMAGE_BL31 for the below combinations.
+ * ============================================================================
+ * | ERRATA_SPECULATIVE_AT| CTX_INCLUDE_EL2_REGS |   Combination              |
+ * ============================================================================
+ * |       0              |       0              |   Valid (EL1 ctx)          |
+ * |______________________|______________________|____________________________|
+ * |                      |                      | Invalid (No Errata/EL1 Ctx)|
+ * |       0              |       1              | Hence commented out.       |
+ * |______________________|______________________|____________________________|
+ * |                      |                      |                            |
+ * |       1              |       0              |   Valid (Errata ctx)       |
+ * |______________________|______________________|____________________________|
+ * |                      |                      |                            |
+ * |       1              |       1              |   Valid (Errata ctx)       |
+ * |______________________|______________________|____________________________|
+ * ============================================================================
+ ******************************************************************************/
+#if (IMAGE_BL1 || ((ERRATA_SPECULATIVE_AT) || (!CTX_INCLUDE_EL2_REGS)))
+
+static inline void write_ctx_sctlr_el1_reg_errata(cpu_context_t *ctx, u_register_t val)
+{
+#if (ERRATA_SPECULATIVE_AT)
+	write_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_SCTLR_EL1, val);
+#else
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1, val);
+#endif /* ERRATA_SPECULATIVE_AT */
+}
+
+static inline void write_ctx_tcr_el1_reg_errata(cpu_context_t *ctx, u_register_t val)
+{
+#if (ERRATA_SPECULATIVE_AT)
+	write_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_TCR_EL1, val);
+#else
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), tcr_el1, val);
+#endif /* ERRATA_SPECULATIVE_AT */
+}
+
+static inline u_register_t read_ctx_sctlr_el1_reg_errata(cpu_context_t *ctx)
+{
+#if (ERRATA_SPECULATIVE_AT)
+	return read_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_SCTLR_EL1);
+#else
+	return read_el1_ctx_common(get_el1_sysregs_ctx(ctx), sctlr_el1);
+#endif /* ERRATA_SPECULATIVE_AT */
+}
+
+static inline u_register_t read_ctx_tcr_el1_reg_errata(cpu_context_t *ctx)
+{
+#if (ERRATA_SPECULATIVE_AT)
+	return read_ctx_reg(get_errata_speculative_at_ctx(ctx),
+		      CTX_ERRATA_SPEC_AT_TCR_EL1);
+#else
+	return read_el1_ctx_common(get_el1_sysregs_ctx(ctx), tcr_el1);
+#endif /* ERRATA_SPECULATIVE_AT */
+}
+
+#endif /* (IMAGE_BL1 || ((ERRATA_SPECULATIVE_AT) || (!CTX_INCLUDE_EL2_REGS))) */
+
 #endif /* __ASSEMBLER__ */
 
 #endif /* CONTEXT_H */
diff --git a/include/lib/el3_runtime/context_debug.h b/include/lib/el3_runtime/context_debug.h
new file mode 100644
index 00000000..51e77482
--- /dev/null
+++ b/include/lib/el3_runtime/context_debug.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef CONTEXT_DEBUG_H
+#define CONTEXT_DEBUG_H
+
+#if PLATFORM_REPORT_CTX_MEM_USE && defined(__aarch64__)
+/********************************************************************************
+ * Reports the allocated memory for every security state and then reports the
+ * total system-wide allocated memory.
+ *******************************************************************************/
+void report_ctx_memory_usage(void);
+#else
+static inline void report_ctx_memory_usage(void) {}
+#endif /* PLATFORM_REPORT_CTX_MEM_USE */
+
+#endif /* CONTEXT_DEBUG_H */
diff --git a/include/lib/el3_runtime/context_el1.h b/include/lib/el3_runtime/context_el1.h
new file mode 100644
index 00000000..7bc02356
--- /dev/null
+++ b/include/lib/el3_runtime/context_el1.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONTEXT_EL1_H
+#define CONTEXT_EL1_H
+
+#include <lib/extensions/sysreg128.h>
+
+#ifndef __ASSEMBLER__
+
+/*******************************************************************************
+ * EL1 Registers:
+ * AArch64 EL1 system register context structure for preserving the
+ * architectural state during world switches.
+ ******************************************************************************/
+
+typedef struct el1_common_regs {
+	uint64_t spsr_el1;
+	uint64_t elr_el1;
+
+#if (!ERRATA_SPECULATIVE_AT)
+	uint64_t sctlr_el1;
+	uint64_t tcr_el1;
+#endif /* ERRATA_SPECULATIVE_AT=0 */
+
+	uint64_t cpacr_el1;
+	uint64_t csselr_el1;
+	uint64_t sp_el1;
+	uint64_t esr_el1;
+	uint64_t mair_el1;
+	uint64_t amair_el1;
+	uint64_t actlr_el1;
+	uint64_t tpidr_el1;
+	uint64_t tpidr_el0;
+	uint64_t tpidrro_el0;
+	uint64_t far_el1;
+	uint64_t afsr0_el1;
+	uint64_t afsr1_el1;
+	uint64_t contextidr_el1;
+	uint64_t vbar_el1;
+	uint64_t mdccint_el1;
+	uint64_t mdscr_el1;
+	sysreg_t par_el1;
+	sysreg_t ttbr0_el1;
+	sysreg_t ttbr1_el1;
+} el1_common_regs_t;
+
+typedef struct el1_aarch32_regs {
+	uint64_t spsr_abt;
+	uint64_t spsr_und;
+	uint64_t spsr_irq;
+	uint64_t spsr_fiq;
+	uint64_t dacr32_el2;
+	uint64_t ifsr32_el2;
+} el1_aarch32_regs_t;
+
+typedef struct el1_arch_timer_regs {
+	uint64_t cntp_ctl_el0;
+	uint64_t cntp_cval_el0;
+	uint64_t cntv_ctl_el0;
+	uint64_t cntv_cval_el0;
+	uint64_t cntkctl_el1;
+} el1_arch_timer_regs_t;
+
+typedef struct el1_mte2_regs {
+	uint64_t tfsre0_el1;
+	uint64_t tfsr_el1;
+	uint64_t rgsr_el1;
+	uint64_t gcr_el1;
+} el1_mte2_regs_t;
+
+typedef struct el1_ras_regs {
+	uint64_t disr_el1;
+} el1_ras_regs_t;
+
+typedef struct el1_s1pie_regs {
+	uint64_t pire0_el1;
+	uint64_t pir_el1;
+} el1_s1pie_regs_t;
+
+typedef struct el1_s1poe_regs {
+	uint64_t por_el1;
+} el1_s1poe_regs_t;
+
+typedef struct el1_s2poe_regs {
+	uint64_t s2por_el1;
+} el1_s2poe_regs_t;
+
+typedef struct el1_tcr2_regs {
+	uint64_t tcr2_el1;
+} el1_tcr2_regs_t;
+
+typedef struct el1_trf_regs {
+	uint64_t trfcr_el1;
+} el1_trf_regs_t;
+
+typedef struct el1_csv2_2_regs {
+	uint64_t scxtnum_el0;
+	uint64_t scxtnum_el1;
+} el1_csv2_2_regs_t;
+
+typedef struct el1_gcs_regs {
+	uint64_t gcscr_el1;
+	uint64_t gcscre0_el1;
+	uint64_t gcspr_el1;
+	uint64_t gcspr_el0;
+} el1_gcs_regs_t;
+
+typedef struct el1_the_regs {
+	sysreg_t rcwmask_el1;
+	sysreg_t rcwsmask_el1;
+} el1_the_regs_t;
+
+typedef struct el1_sctlr2_regs {
+	uint64_t sctlr2_el1;
+} el1_sctlr2_regs_t;
+
+typedef struct el1_ls64_regs {
+	uint64_t accdata_el1;
+} el1_ls64_regs_t;
+
+typedef struct el1_sysregs {
+
+	el1_common_regs_t common;
+
+#if CTX_INCLUDE_AARCH32_REGS
+	el1_aarch32_regs_t el1_aarch32;
+#endif
+
+#if NS_TIMER_SWITCH
+	el1_arch_timer_regs_t arch_timer;
+#endif
+
+#if ENABLE_FEAT_MTE2
+	el1_mte2_regs_t mte2;
+#endif
+
+#if ENABLE_FEAT_RAS
+	el1_ras_regs_t ras;
+#endif
+
+#if ENABLE_FEAT_S1PIE
+	el1_s1pie_regs_t s1pie;
+#endif
+
+#if ENABLE_FEAT_S1POE
+	el1_s1poe_regs_t s1poe;
+#endif
+
+#if ENABLE_FEAT_S2POE
+	el1_s2poe_regs_t s2poe;
+#endif
+
+#if ENABLE_FEAT_TCR2
+	el1_tcr2_regs_t tcr2;
+#endif
+
+#if ENABLE_TRF_FOR_NS
+	el1_trf_regs_t trf;
+#endif
+
+#if ENABLE_FEAT_CSV2_2
+	el1_csv2_2_regs_t csv2_2;
+#endif
+
+#if ENABLE_FEAT_GCS
+	el1_gcs_regs_t gcs;
+#endif
+
+#if ENABLE_FEAT_THE
+	el1_the_regs_t the;
+#endif
+
+#if ENABLE_FEAT_SCTLR2
+	el1_sctlr2_regs_t sctlr2;
+#endif
+
+#if ENABLE_FEAT_LS64_ACCDATA
+	el1_ls64_regs_t ls64;
+#endif
+} el1_sysregs_t;
+
+
+/*
+ * Macros to access members related to individual features of the el1_sysregs_t
+ * structures.
+ */
+
+#define read_el1_ctx_common(ctx, reg)		(((ctx)->common).reg)
+
+#define write_el1_ctx_common(ctx, reg, val)	((((ctx)->common).reg)	\
+							= (uint64_t) (val))
+
+#if NS_TIMER_SWITCH
+#define read_el1_ctx_arch_timer(ctx, reg)		(((ctx)->arch_timer).reg)
+#define write_el1_ctx_arch_timer(ctx, reg, val)	((((ctx)->arch_timer).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_arch_timer(ctx, reg)		ULL(0)
+#define write_el1_ctx_arch_timer(ctx, reg, val)
+#endif /* NS_TIMER_SWITCH */
+
+#if CTX_INCLUDE_AARCH32_REGS
+#define read_el1_ctx_aarch32(ctx, reg)		(((ctx)->el1_aarch32).reg)
+#define write_el1_ctx_aarch32(ctx, reg, val)	((((ctx)->el1_aarch32).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_aarch32(ctx, reg)		ULL(0)
+#define write_el1_ctx_aarch32(ctx, reg, val)
+#endif /* CTX_INCLUDE_AARCH32_REGS */
+
+#if ENABLE_FEAT_MTE2
+#define read_el1_ctx_mte2(ctx, reg)		(((ctx)->mte2).reg)
+#define write_el1_ctx_mte2(ctx, reg, val)	((((ctx)->mte2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_mte2(ctx, reg)		ULL(0)
+#define write_el1_ctx_mte2(ctx, reg, val)
+#endif /* ENABLE_FEAT_MTE2 */
+
+#if ENABLE_FEAT_RAS
+#define read_el1_ctx_ras(ctx, reg)		(((ctx)->ras).reg)
+#define write_el1_ctx_ras(ctx, reg, val)	((((ctx)->ras).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_ras(ctx, reg)		ULL(0)
+#define write_el1_ctx_ras(ctx, reg, val)
+#endif /* ENABLE_FEAT_RAS */
+
+#if ENABLE_FEAT_S1PIE
+#define read_el1_ctx_s1pie(ctx, reg)		(((ctx)->s1pie).reg)
+#define write_el1_ctx_s1pie(ctx, reg, val)	((((ctx)->s1pie).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_s1pie(ctx, reg)		ULL(0)
+#define write_el1_ctx_s1pie(ctx, reg, val)
+#endif /* ENABLE_FEAT_S1PIE */
+
+#if ENABLE_FEAT_S1POE
+#define read_el1_ctx_s1poe(ctx, reg)		(((ctx)->s1poe).reg)
+#define write_el1_ctx_s1poe(ctx, reg, val)	((((ctx)->s1poe).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_s1poe(ctx, reg)		ULL(0)
+#define write_el1_ctx_s1poe(ctx, reg, val)
+#endif /* ENABLE_FEAT_S1POE */
+
+#if ENABLE_FEAT_S2POE
+#define read_el1_ctx_s2poe(ctx, reg)		(((ctx)->s2poe).reg)
+#define write_el1_ctx_s2poe(ctx, reg, val)	((((ctx)->s2poe).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_s2poe(ctx, reg)		ULL(0)
+#define write_el1_ctx_s2poe(ctx, reg, val)
+#endif /* ENABLE_FEAT_S2POE */
+
+#if ENABLE_FEAT_TCR2
+#define read_el1_ctx_tcr2(ctx, reg)		(((ctx)->tcr2).reg)
+#define write_el1_ctx_tcr2(ctx, reg, val)	((((ctx)->tcr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_tcr2(ctx, reg)		ULL(0)
+#define write_el1_ctx_tcr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_TCR2 */
+
+#if ENABLE_TRF_FOR_NS
+#define read_el1_ctx_trf(ctx, reg)		(((ctx)->trf).reg)
+#define write_el1_ctx_trf(ctx, reg, val)	((((ctx)->trf).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_trf(ctx, reg)		ULL(0)
+#define write_el1_ctx_trf(ctx, reg, val)
+#endif /* ENABLE_TRF_FOR_NS */
+
+#if ENABLE_FEAT_CSV2_2
+#define read_el1_ctx_csv2_2(ctx, reg)		(((ctx)->csv2_2).reg)
+#define write_el1_ctx_csv2_2(ctx, reg, val)	((((ctx)->csv2_2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_csv2_2(ctx, reg)		ULL(0)
+#define write_el1_ctx_csv2_2(ctx, reg, val)
+#endif /* ENABLE_FEAT_CSV2_2 */
+
+#if ENABLE_FEAT_GCS
+#define read_el1_ctx_gcs(ctx, reg)		(((ctx)->gcs).reg)
+#define write_el1_ctx_gcs(ctx, reg, val)	((((ctx)->gcs).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_gcs(ctx, reg)		ULL(0)
+#define write_el1_ctx_gcs(ctx, reg, val)
+#endif /* ENABLE_FEAT_GCS */
+
+#if ENABLE_FEAT_THE
+#define read_el1_ctx_the(ctx, reg)		(((ctx)->the).reg)
+#define write_el1_ctx_the(ctx, reg, val)	((((ctx)->the).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_the(ctx, reg)		ULL(0)
+#define write_el1_ctx_the(ctx, reg, val)
+#endif /* ENABLE_FEAT_THE */
+
+#if ENABLE_FEAT_SCTLR2
+#define read_el1_ctx_sctlr2(ctx, reg)		(((ctx)->sctlr2).reg)
+#define write_el1_ctx_sctlr2(ctx, reg, val)	((((ctx)->sctlr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_sctlr2(ctx, reg)		ULL(0)
+#define write_el1_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
+#if ENABLE_FEAT_LS64_ACCDATA
+#define read_el1_ctx_ls64(ctx, reg)		(((ctx)->ls64).reg)
+#define write_el1_ctx_ls64(ctx, reg, val)	((((ctx)->ls64).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el1_ctx_ls64(ctx, reg)		ULL(0)
+#define write_el1_ctx_ls64(ctx, reg, val)
+#endif /* ENABLE_FEAT_LS64_ACCDATA */
+/******************************************************************************/
+#endif /* __ASSEMBLER__ */
+
+#endif /* CONTEXT_EL1_H */
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
new file mode 100644
index 00000000..7374e39d
--- /dev/null
+++ b/include/lib/el3_runtime/context_el2.h
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONTEXT_EL2_H
+#define CONTEXT_EL2_H
+
+#include <lib/extensions/sysreg128.h>
+
+#ifndef __ASSEMBLER__
+
+/*******************************************************************************
+ * EL2 Registers:
+ * AArch64 EL2 system register context structure for preserving the
+ * architectural state during world switches.
+ ******************************************************************************/
+typedef struct el2_common_regs {
+	uint64_t actlr_el2;
+	uint64_t afsr0_el2;
+	uint64_t afsr1_el2;
+	uint64_t amair_el2;
+	uint64_t cnthctl_el2;
+	uint64_t cntvoff_el2;
+	uint64_t cptr_el2;
+	uint64_t dbgvcr32_el2;
+	uint64_t elr_el2;
+	uint64_t esr_el2;
+	uint64_t far_el2;
+	uint64_t hacr_el2;
+	uint64_t hcr_el2;
+	uint64_t hpfar_el2;
+	uint64_t hstr_el2;
+	uint64_t icc_sre_el2;
+	uint64_t ich_hcr_el2;
+	uint64_t ich_vmcr_el2;
+	uint64_t mair_el2;
+	uint64_t mdcr_el2;
+	uint64_t pmscr_el2;
+	uint64_t sctlr_el2;
+	uint64_t spsr_el2;
+	uint64_t sp_el2;
+	uint64_t tcr_el2;
+	uint64_t tpidr_el2;
+	uint64_t vbar_el2;
+	uint64_t vmpidr_el2;
+	uint64_t vpidr_el2;
+	uint64_t vtcr_el2;
+	sysreg_t vttbr_el2;
+	sysreg_t ttbr0_el2;
+} el2_common_regs_t;
+
+typedef struct el2_mte2_regs {
+	uint64_t tfsr_el2;
+} el2_mte2_regs_t;
+
+typedef struct el2_fgt_regs {
+	uint64_t hdfgrtr_el2;
+	uint64_t hafgrtr_el2;
+	uint64_t hdfgwtr_el2;
+	uint64_t hfgitr_el2;
+	uint64_t hfgrtr_el2;
+	uint64_t hfgwtr_el2;
+} el2_fgt_regs_t;
+
+typedef struct el2_fgt2_regs {
+	uint64_t hdfgrtr2_el2;
+	uint64_t hdfgwtr2_el2;
+	uint64_t hfgitr2_el2;
+	uint64_t hfgrtr2_el2;
+	uint64_t hfgwtr2_el2;
+} el2_fgt2_regs_t;
+
+typedef struct el2_ecv_regs {
+	uint64_t cntpoff_el2;
+} el2_ecv_regs_t;
+
+typedef struct el2_vhe_regs {
+	uint64_t contextidr_el2;
+	sysreg_t ttbr1_el2;
+} el2_vhe_regs_t;
+
+typedef struct el2_ras_regs {
+	uint64_t vdisr_el2;
+	uint64_t vsesr_el2;
+} el2_ras_regs_t;
+
+typedef struct el2_neve_regs {
+	uint64_t vncr_el2;
+} el2_neve_regs_t;
+
+typedef struct el2_trf_regs {
+	uint64_t trfcr_el2;
+} el2_trf_regs_t;
+
+typedef struct el2_csv2_regs {
+	uint64_t scxtnum_el2;
+} el2_csv2_regs_t;
+
+typedef struct el2_hcx_regs {
+	uint64_t hcrx_el2;
+} el2_hcx_regs_t;
+
+typedef struct el2_tcr2_regs {
+	uint64_t tcr2_el2;
+} el2_tcr2_regs_t;
+
+typedef struct el2_sxpoe_regs {
+	uint64_t por_el2;
+} el2_sxpoe_regs_t;
+
+typedef struct el2_sxpie_regs {
+	uint64_t pire0_el2;
+	uint64_t pir_el2;
+} el2_sxpie_regs_t;
+
+typedef struct el2_s2pie_regs {
+	uint64_t s2pir_el2;
+} el2_s2pie_regs_t;
+
+typedef struct el2_gcs_regs {
+	uint64_t gcscr_el2;
+	uint64_t gcspr_el2;
+} el2_gcs_regs_t;
+
+typedef struct el2_mpam_regs {
+	uint64_t mpam2_el2;
+	uint64_t mpamhcr_el2;
+	uint64_t mpamvpm0_el2;
+	uint64_t mpamvpm1_el2;
+	uint64_t mpamvpm2_el2;
+	uint64_t mpamvpm3_el2;
+	uint64_t mpamvpm4_el2;
+	uint64_t mpamvpm5_el2;
+	uint64_t mpamvpm6_el2;
+	uint64_t mpamvpm7_el2;
+	uint64_t mpamvpmv_el2;
+} el2_mpam_regs_t;
+
+typedef struct el2_sctlr2_regs {
+	uint64_t sctlr2_el2;
+} el2_sctlr2_regs_t;
+
+typedef struct el2_sysregs {
+
+	el2_common_regs_t common;
+
+#if ENABLE_FEAT_MTE2
+	el2_mte2_regs_t mte2;
+#endif
+
+#if ENABLE_FEAT_FGT
+	el2_fgt_regs_t fgt;
+#endif
+
+#if ENABLE_FEAT_FGT2
+	el2_fgt2_regs_t fgt2;
+#endif
+
+#if ENABLE_FEAT_ECV
+	el2_ecv_regs_t ecv;
+#endif
+
+#if ENABLE_FEAT_VHE
+	el2_vhe_regs_t vhe;
+#endif
+
+#if ENABLE_FEAT_RAS
+	el2_ras_regs_t ras;
+#endif
+
+#if CTX_INCLUDE_NEVE_REGS
+	el2_neve_regs_t neve;
+#endif
+
+#if ENABLE_TRF_FOR_NS
+	el2_trf_regs_t trf;
+#endif
+
+#if ENABLE_FEAT_CSV2_2
+	el2_csv2_regs_t csv2;
+#endif
+
+#if ENABLE_FEAT_HCX
+	el2_hcx_regs_t hcx;
+#endif
+
+#if ENABLE_FEAT_TCR2
+	el2_tcr2_regs_t tcr2;
+#endif
+
+#if (ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE)
+	el2_sxpoe_regs_t sxpoe;
+#endif
+
+#if (ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE)
+	el2_sxpie_regs_t sxpie;
+#endif
+
+#if ENABLE_FEAT_S2PIE
+	el2_s2pie_regs_t s2pie;
+#endif
+
+#if ENABLE_FEAT_GCS
+	el2_gcs_regs_t gcs;
+#endif
+
+#if CTX_INCLUDE_MPAM_REGS
+	el2_mpam_regs_t mpam;
+#endif
+
+#if ENABLE_FEAT_SCTLR2
+	el2_sctlr2_regs_t sctlr2;
+#endif
+
+} el2_sysregs_t;
+
+/*
+ * Macros to access members related to individual features of the el2_sysregs_t
+ * structures.
+ */
+#define read_el2_ctx_common(ctx, reg)		(((ctx)->common).reg)
+
+#define write_el2_ctx_common(ctx, reg, val)	((((ctx)->common).reg)	\
+							= (uint64_t) (val))
+
+#define write_el2_ctx_sysreg128(ctx, reg, val)	((((ctx)->common).reg)	\
+							= (sysreg_t) (val))
+
+#if ENABLE_FEAT_MTE2
+#define read_el2_ctx_mte2(ctx, reg)		(((ctx)->mte2).reg)
+#define write_el2_ctx_mte2(ctx, reg, val)	((((ctx)->mte2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_mte2(ctx, reg)		ULL(0)
+#define write_el2_ctx_mte2(ctx, reg, val)
+#endif /* ENABLE_FEAT_MTE2 */
+
+#if ENABLE_FEAT_FGT
+#define read_el2_ctx_fgt(ctx, reg)		(((ctx)->fgt).reg)
+#define write_el2_ctx_fgt(ctx, reg, val)	((((ctx)->fgt).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_fgt(ctx, reg)		ULL(0)
+#define write_el2_ctx_fgt(ctx, reg, val)
+#endif /* ENABLE_FEAT_FGT */
+
+#if ENABLE_FEAT_FGT2
+#define read_el2_ctx_fgt2(ctx, reg)		(((ctx)->fgt2).reg)
+#define write_el2_ctx_fgt2(ctx, reg, val)	((((ctx)->fgt2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_fgt2(ctx, reg)		ULL(0)
+#define write_el2_ctx_fgt2(ctx, reg, val)
+#endif /* ENABLE_FEAT_FGT */
+
+#if ENABLE_FEAT_ECV
+#define read_el2_ctx_ecv(ctx, reg)		(((ctx)->ecv).reg)
+#define write_el2_ctx_ecv(ctx, reg, val)	((((ctx)->ecv).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_ecv(ctx, reg)		ULL(0)
+#define write_el2_ctx_ecv(ctx, reg, val)
+#endif /* ENABLE_FEAT_ECV */
+
+#if ENABLE_FEAT_VHE
+#define read_el2_ctx_vhe(ctx, reg)		(((ctx)->vhe).reg)
+#define write_el2_ctx_vhe(ctx, reg, val)	((((ctx)->vhe).reg)	\
+							= (uint64_t) (val))
+
+#define write_el2_ctx_vhe_sysreg128(ctx, reg, val)	((((ctx)->vhe).reg)	\
+								= (sysreg_t) (val))
+#else
+#define read_el2_ctx_vhe(ctx, reg)		ULL(0)
+#define write_el2_ctx_vhe(ctx, reg, val)
+#endif /* ENABLE_FEAT_VHE */
+
+#if ENABLE_FEAT_RAS
+#define read_el2_ctx_ras(ctx, reg)		(((ctx)->ras).reg)
+#define write_el2_ctx_ras(ctx, reg, val)	((((ctx)->ras).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_ras(ctx, reg)		ULL(0)
+#define write_el2_ctx_ras(ctx, reg, val)
+#endif /* ENABLE_FEAT_RAS */
+
+#if CTX_INCLUDE_NEVE_REGS
+#define read_el2_ctx_neve(ctx, reg)		(((ctx)->neve).reg)
+#define write_el2_ctx_neve(ctx, reg, val)	((((ctx)->neve).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_neve(ctx, reg)		ULL(0)
+#define write_el2_ctx_neve(ctx, reg, val)
+#endif /* CTX_INCLUDE_NEVE_REGS */
+
+#if ENABLE_TRF_FOR_NS
+#define read_el2_ctx_trf(ctx, reg)		(((ctx)->trf).reg)
+#define write_el2_ctx_trf(ctx, reg, val)	((((ctx)->trf).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_trf(ctx, reg)		ULL(0)
+#define write_el2_ctx_trf(ctx, reg, val)
+#endif /* ENABLE_TRF_FOR_NS */
+
+#if ENABLE_FEAT_CSV2_2
+#define read_el2_ctx_csv2_2(ctx, reg)		(((ctx)->csv2).reg)
+#define write_el2_ctx_csv2_2(ctx, reg, val)	((((ctx)->csv2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_csv2_2(ctx, reg)		ULL(0)
+#define write_el2_ctx_csv2_2(ctx, reg, val)
+#endif /* ENABLE_FEAT_CSV2_2 */
+
+#if ENABLE_FEAT_HCX
+#define read_el2_ctx_hcx(ctx, reg)		(((ctx)->hcx).reg)
+#define write_el2_ctx_hcx(ctx, reg, val)	((((ctx)->hcx).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_hcx(ctx, reg)		ULL(0)
+#define write_el2_ctx_hcx(ctx, reg, val)
+#endif /* ENABLE_FEAT_HCX */
+
+#if ENABLE_FEAT_TCR2
+#define read_el2_ctx_tcr2(ctx, reg)		(((ctx)->tcr2).reg)
+#define write_el2_ctx_tcr2(ctx, reg, val)	((((ctx)->tcr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_tcr2(ctx, reg)		ULL(0)
+#define write_el2_ctx_tcr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_TCR2 */
+
+#if (ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE)
+#define read_el2_ctx_sxpoe(ctx, reg)		(((ctx)->sxpoe).reg)
+#define write_el2_ctx_sxpoe(ctx, reg, val)	((((ctx)->sxpoe).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_sxpoe(ctx, reg)		ULL(0)
+#define write_el2_ctx_sxpoe(ctx, reg, val)
+#endif /*(ENABLE_FEAT_S1POE || ENABLE_FEAT_S2POE) */
+
+#if (ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE)
+#define read_el2_ctx_sxpie(ctx, reg)		(((ctx)->sxpie).reg)
+#define write_el2_ctx_sxpie(ctx, reg, val)	((((ctx)->sxpie).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_sxpie(ctx, reg)		ULL(0)
+#define write_el2_ctx_sxpie(ctx, reg, val)
+#endif /*(ENABLE_FEAT_S1PIE || ENABLE_FEAT_S2PIE) */
+
+#if ENABLE_FEAT_S2PIE
+#define read_el2_ctx_s2pie(ctx, reg)		(((ctx)->s2pie).reg)
+#define write_el2_ctx_s2pie(ctx, reg, val)	((((ctx)->s2pie).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_s2pie(ctx, reg)		ULL(0)
+#define write_el2_ctx_s2pie(ctx, reg, val)
+#endif /* ENABLE_FEAT_S2PIE */
+
+#if ENABLE_FEAT_GCS
+#define read_el2_ctx_gcs(ctx, reg)		(((ctx)->gcs).reg)
+#define write_el2_ctx_gcs(ctx, reg, val)	((((ctx)->gcs).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_gcs(ctx, reg)		ULL(0)
+#define write_el2_ctx_gcs(ctx, reg, val)
+#endif /* ENABLE_FEAT_GCS */
+
+#if CTX_INCLUDE_MPAM_REGS
+#define read_el2_ctx_mpam(ctx, reg)		(((ctx)->mpam).reg)
+#define write_el2_ctx_mpam(ctx, reg, val)	((((ctx)->mpam).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_mpam(ctx, reg)		ULL(0)
+#define write_el2_ctx_mpam(ctx, reg, val)
+#endif /* CTX_INCLUDE_MPAM_REGS */
+
+#if ENABLE_FEAT_SCTLR2
+#define read_el2_ctx_sctlr2(ctx, reg)		(((ctx)->sctlr2).reg)
+#define write_el2_ctx_sctlr2(ctx, reg, val)	((((ctx)->sctlr2).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_sctlr2(ctx, reg)		ULL(0)
+#define write_el2_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
+/******************************************************************************/
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* CONTEXT_EL2_H */
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index b2bdaf5a..70dbd463 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,24 +30,31 @@ void cm_set_context_by_index(unsigned int cpu_idx,
 void *cm_get_context(uint32_t security_state);
 void cm_set_context(void *context, uint32_t security_state);
 void cm_init_my_context(const struct entry_point_info *ep);
-void cm_init_context_by_index(unsigned int cpu_idx,
-			      const struct entry_point_info *ep);
 void cm_setup_context(cpu_context_t *ctx, const struct entry_point_info *ep);
 void cm_prepare_el3_exit(uint32_t security_state);
 void cm_prepare_el3_exit_ns(void);
 
+#if !IMAGE_BL1
+void cm_init_context_by_index(unsigned int cpu_idx,
+			      const struct entry_point_info *ep);
+#endif /* !IMAGE_BL1 */
+
 #ifdef __aarch64__
 #if IMAGE_BL31
 void cm_manage_extensions_el3(void);
 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);
 #endif
-#if CTX_INCLUDE_EL2_REGS
+
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 void cm_el2_sysregs_context_save(uint32_t security_state);
 void cm_el2_sysregs_context_restore(uint32_t security_state);
-#endif
-
+#else
 void cm_el1_sysregs_context_save(uint32_t security_state);
 void cm_el1_sysregs_context_restore(uint32_t security_state);
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
+
 void cm_set_elr_el3(uint32_t security_state, uintptr_t entrypoint);
 void cm_set_elr_spsr_el3(uint32_t security_state,
 			uintptr_t entrypoint, uint32_t spsr);
@@ -90,6 +97,7 @@ void *cm_get_next_context(void);
 void cm_set_next_context(void *context);
 static inline void cm_manage_extensions_el3(void) {}
 static inline void manage_extensions_nonsecure_per_world(void) {}
+static inline void cm_handle_asymmetric_features(void) {}
 #endif /* __aarch64__ */
 
 #endif /* CONTEXT_MGMT_H */
diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h
index 2c7b6196..8b548067 100644
--- a/include/lib/el3_runtime/cpu_data.h
+++ b/include/lib/el3_runtime/cpu_data.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -59,8 +59,19 @@
 #define CPU_DATA_CRASH_BUF_END		CPU_DATA_CRASH_BUF_OFFSET
 #endif
 
+/* buffer space for EHF data is sizeof(pe_exc_data_t) */
+#define CPU_DATA_EHF_DATA_SIZE		8
+#define CPU_DATA_EHF_DATA_BUF_OFFSET	CPU_DATA_CRASH_BUF_END
+
+#if defined(IMAGE_BL31) && EL3_EXCEPTION_HANDLING
+#define CPU_DATA_EHF_DATA_BUF_END	(CPU_DATA_EHF_DATA_BUF_OFFSET + \
+						CPU_DATA_EHF_DATA_SIZE)
+#else
+#define CPU_DATA_EHF_DATA_BUF_END	CPU_DATA_EHF_DATA_BUF_OFFSET
+#endif	/* EL3_EXCEPTION_HANDLING */
+
 /* cpu_data size is the data size rounded up to the platform cache line size */
-#define CPU_DATA_SIZE			(((CPU_DATA_CRASH_BUF_END + \
+#define CPU_DATA_SIZE			(((CPU_DATA_EHF_DATA_BUF_END + \
 					CACHE_WRITEBACK_GRANULE - 1) / \
 						CACHE_WRITEBACK_GRANULE) * \
 							CACHE_WRITEBACK_GRANULE)
@@ -68,7 +79,7 @@
 #if ENABLE_RUNTIME_INSTRUMENTATION
 /* Temporary space to store PMF timestamps from assembly code */
 #define CPU_DATA_PMF_TS_COUNT		1
-#define CPU_DATA_PMF_TS0_OFFSET		CPU_DATA_CRASH_BUF_END
+#define CPU_DATA_PMF_TS0_OFFSET		CPU_DATA_EHF_DATA_BUF_END
 #define CPU_DATA_PMF_TS0_IDX		0
 #endif
 
@@ -159,6 +170,12 @@ CASSERT(CPU_DATA_CRASH_BUF_OFFSET == __builtin_offsetof
 	assert_cpu_data_crash_stack_offset_mismatch);
 #endif
 
+#if defined(IMAGE_BL31) && EL3_EXCEPTION_HANDLING
+CASSERT(CPU_DATA_EHF_DATA_BUF_OFFSET == __builtin_offsetof
+	(cpu_data_t, ehf_data),
+	assert_cpu_data_ehf_stack_offset_mismatch);
+#endif
+
 CASSERT(CPU_DATA_SIZE == sizeof(cpu_data_t),
 		assert_cpu_data_size_mismatch);
 
diff --git a/include/lib/el3_runtime/simd_ctx.h b/include/lib/el3_runtime/simd_ctx.h
new file mode 100644
index 00000000..fdbe24f3
--- /dev/null
+++ b/include/lib/el3_runtime/simd_ctx.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIMD_CTX_H
+#define SIMD_CTX_H
+
+/*******************************************************************************
+ * Constants that allow assembler code to access members of and the 'simd_context'
+ * structure at their correct offsets.
+ ******************************************************************************/
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+#if CTX_INCLUDE_SVE_REGS
+#define SIMD_VECTOR_LEN_BYTES	(SVE_VECTOR_LEN / 8) /* Length of vector in bytes */
+#elif CTX_INCLUDE_FPREGS
+#define SIMD_VECTOR_LEN_BYTES	U(16) /* 128 bits fixed vector length for FPU */
+#endif /* CTX_INCLUDE_SVE_REGS */
+
+#define CTX_SIMD_VECTORS	U(0)
+/* there are 32 vector registers, each of size SIMD_VECTOR_LEN_BYTES */
+#define CTX_SIMD_FPSR		(CTX_SIMD_VECTORS + (32 * SIMD_VECTOR_LEN_BYTES))
+#define CTX_SIMD_FPCR		(CTX_SIMD_FPSR + 8)
+
+#if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS
+#define CTX_SIMD_FPEXC32	(CTX_SIMD_FPCR + 8)
+#define CTX_SIMD_PREDICATES	(CTX_SIMD_FPEXC32 + 16)
+#else
+#define CTX_SIMD_PREDICATES      (CTX_SIMD_FPCR + 8)
+#endif /* CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS */
+
+/*
+ * Each predicate register is 1/8th the size of a vector register and there are 16
+ * predicate registers
+ */
+#define CTX_SIMD_FFR		(CTX_SIMD_PREDICATES + (16 * (SIMD_VECTOR_LEN_BYTES / 8)))
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+#include <lib/cassert.h>
+
+/*
+ * Please don't change order of fields in this struct as that may violate
+ * alignment requirements and affect how assembly code accesses members of this
+ * struct.
+ */
+typedef struct {
+	uint8_t vectors[32][SIMD_VECTOR_LEN_BYTES];
+	uint8_t fpsr[8];
+	uint8_t fpcr[8];
+#if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS
+	/* 16 bytes to align to next 16 byte boundary when CTX_INCLUDE_SVE_REGS is 0 */
+	uint8_t fpexc32_el2[16];
+#endif
+#if CTX_INCLUDE_SVE_REGS
+	/* FFR and each of predicates is one-eigth of the SVE vector length */
+	uint8_t predicates[16][SIMD_VECTOR_LEN_BYTES / 8];
+	uint8_t ffr[SIMD_VECTOR_LEN_BYTES / 8];
+	/* SMCCCv1.3 FID[16] hint bit state recorded on EL3 entry */
+	bool hint;
+#endif /* CTX_INCLUDE_SVE_REGS */
+} __aligned(16) simd_regs_t;
+
+CASSERT(CTX_SIMD_VECTORS == __builtin_offsetof(simd_regs_t, vectors),
+		assert_vectors_mismatch);
+
+CASSERT(CTX_SIMD_FPSR == __builtin_offsetof(simd_regs_t, fpsr),
+		assert_fpsr_mismatch);
+
+CASSERT(CTX_SIMD_FPCR == __builtin_offsetof(simd_regs_t, fpcr),
+		assert_fpcr_mismatch);
+
+#if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS
+CASSERT(CTX_SIMD_FPEXC32 == __builtin_offsetof(simd_regs_t, fpexc32_el2),
+		assert_fpex32_mismtatch);
+#endif
+
+#if CTX_INCLUDE_SVE_REGS
+CASSERT(CTX_SIMD_PREDICATES == __builtin_offsetof(simd_regs_t, predicates),
+		assert_predicates_mismatch);
+
+CASSERT(CTX_SIMD_FFR == __builtin_offsetof(simd_regs_t, ffr),
+		assert_ffr_mismatch);
+#endif
+
+void simd_ctx_save(uint32_t security_state, bool hint_sve);
+void simd_ctx_restore(uint32_t security_state);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
+
+#endif /* SIMD_CTX_H */
diff --git a/include/lib/extensions/brbe.h b/include/lib/extensions/brbe.h
index 194efba7..425a0377 100644
--- a/include/lib/extensions/brbe.h
+++ b/include/lib/extensions/brbe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,10 +7,12 @@
 #ifndef BRBE_H
 #define BRBE_H
 
+#include <context.h>
+
 #if ENABLE_BRBE_FOR_NS
-void brbe_init_el3(void);
+void brbe_enable(cpu_context_t *ctx);
 #else
-static inline void brbe_init_el3(void)
+static inline void brbe_enable(cpu_context_t *ctx)
 {
 }
 #endif /* ENABLE_BRBE_FOR_NS */
diff --git a/include/lib/extensions/debug_v8p9.h b/include/lib/extensions/debug_v8p9.h
new file mode 100644
index 00000000..d72c9ea7
--- /dev/null
+++ b/include/lib/extensions/debug_v8p9.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEBUG_V8P9_H
+#define DEBUG_V8P9_H
+
+#include <context.h>
+
+#if ENABLE_FEAT_DEBUGV8P9
+void debugv8p9_extended_bp_wp_enable(cpu_context_t *ctx);
+#else
+static inline void debugv8p9_extended_bp_wp_enable(cpu_context_t *ctx)
+{
+}
+#endif /* ENABLE_FEAT_DEBUGV8P9 */
+
+#endif /* DEBUG_V8P9_H */
diff --git a/include/lib/extensions/fgt2.h b/include/lib/extensions/fgt2.h
new file mode 100644
index 00000000..0388d184
--- /dev/null
+++ b/include/lib/extensions/fgt2.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FGT2_H
+#define FGT2_H
+
+#include <context.h>
+
+#if ENABLE_FEAT_FGT2
+void fgt2_enable(cpu_context_t *ctx);
+#else
+static inline void fgt2_enable(cpu_context_t *ctx)
+{
+}
+#endif /* ENABLE_FEAT_FGT2 */
+
+#endif /* FGT2_H */
diff --git a/include/lib/extensions/mpam.h b/include/lib/extensions/mpam.h
index 170f919b..3dd56526 100644
--- a/include/lib/extensions/mpam.h
+++ b/include/lib/extensions/mpam.h
@@ -12,10 +12,10 @@
 #include <context.h>
 
 #if ENABLE_FEAT_MPAM
-void mpam_enable(cpu_context_t *context);
+void mpam_enable_per_world(per_world_context_t *per_world_ctx);
 void mpam_init_el2_unused(void);
 #else
-static inline void mpam_enable(cpu_context_t *context)
+static inline void mpam_enable_per_world(per_world_context_t *per_world_ctx)
 {
 }
 static inline void mpam_init_el2_unused(void)
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
index 7b390378..4801a220 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,19 +8,24 @@
 #define SPE_H
 
 #include <stdbool.h>
+#include <context.h>
 
 #if ENABLE_SPE_FOR_NS
-void spe_init_el3(void);
+void spe_enable(cpu_context_t *ctx);
+void spe_disable(cpu_context_t *ctx);
 void spe_init_el2_unused(void);
-void spe_disable(void);
+void spe_stop(void);
 #else
-static inline void spe_init_el3(void)
+static inline void spe_enable(cpu_context_t *ctx)
+{
+}
+static inline void spe_disable(cpu_context_t *ctx)
 {
 }
 static inline void spe_init_el2_unused(void)
 {
 }
-static inline void spe_disable(void)
+static inline void spe_stop(void)
 {
 }
 #endif /* ENABLE_SPE_FOR_NS */
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index 947c905b..2979efb1 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,7 @@
 #include <context.h>
 
 #if (ENABLE_SME_FOR_NS || ENABLE_SVE_FOR_NS)
+
 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);
@@ -25,4 +26,9 @@ static inline void sve_disable_per_world(per_world_context_t *per_world_ctx)
 }
 #endif /* ( ENABLE_SME_FOR_NS | ENABLE_SVE_FOR_NS ) */
 
+#if CTX_INCLUDE_SVE_REGS
+void sve_context_save(simd_regs_t *regs);
+void sve_context_restore(simd_regs_t *regs);
+#endif
+
 #endif /* SVE_H */
diff --git a/include/lib/extensions/sysreg128.h b/include/lib/extensions/sysreg128.h
new file mode 100644
index 00000000..8854856b
--- /dev/null
+++ b/include/lib/extensions/sysreg128.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SYSREG128_H
+#define SYSREG128_H
+
+#ifndef __ASSEMBLER__
+
+#if ENABLE_FEAT_D128
+#include <stdint.h>
+
+typedef uint128_t sysreg_t;
+
+#define PAR_EL1_D128	(((sysreg_t)(1ULL)) << (64))
+
+#define _DECLARE_SYSREG128_READ_FUNC(_name)	\
+uint128_t read_ ## _name(void);
+
+#define _DECLARE_SYSREG128_WRITE_FUNC(_name)	\
+void write_ ## _name(uint128_t v);
+
+#define DECLARE_SYSREG128_RW_FUNCS(_name)	\
+	_DECLARE_SYSREG128_READ_FUNC(_name)	\
+	_DECLARE_SYSREG128_WRITE_FUNC(_name)
+#else
+
+typedef uint64_t sysreg_t;
+
+#endif /* ENABLE_FEAT_D128 */
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SYSREG128_H */
diff --git a/include/lib/extensions/tcr2.h b/include/lib/extensions/tcr2.h
new file mode 100644
index 00000000..08a2b08c
--- /dev/null
+++ b/include/lib/extensions/tcr2.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TCR2_H
+#define TCR2_H
+
+#include <context.h>
+
+#if ENABLE_FEAT_TCR2
+void tcr2_enable(cpu_context_t *ctx);
+void tcr2_disable(cpu_context_t *ctx);
+#else
+static inline void tcr2_enable(cpu_context_t *ctx)
+{
+}
+static inline void tcr2_disable(cpu_context_t *ctx)
+{
+}
+#endif /* ENABLE_FEAT_TCR2 */
+
+#endif /* TCR2_H */
diff --git a/include/lib/extensions/trbe.h b/include/lib/extensions/trbe.h
index 0bed4337..2c488e09 100644
--- a/include/lib/extensions/trbe.h
+++ b/include/lib/extensions/trbe.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,11 +7,17 @@
 #ifndef TRBE_H
 #define TRBE_H
 
+#include <context.h>
+
 #if ENABLE_TRBE_FOR_NS
-void trbe_init_el3(void);
+void trbe_disable(cpu_context_t *ctx);
+void trbe_enable(cpu_context_t *ctx);
 void trbe_init_el2_unused(void);
 #else
-static inline void trbe_init_el3(void)
+static inline void trbe_disable(cpu_context_t *ctx)
+{
+}
+static inline void trbe_enable(cpu_context_t *ctx)
 {
 }
 static inline void trbe_init_el2_unused(void)
diff --git a/include/lib/extensions/trf.h b/include/lib/extensions/trf.h
index 1ac7cda4..f0a946be 100644
--- a/include/lib/extensions/trf.h
+++ b/include/lib/extensions/trf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,16 +7,32 @@
 #ifndef TRF_H
 #define TRF_H
 
+#include <context.h>
+
 #if ENABLE_TRF_FOR_NS
-void trf_init_el3(void);
+
+#if __aarch64__
+void trf_enable(cpu_context_t *ctx);
 void trf_init_el2_unused(void);
-#else
-static inline void trf_init_el3(void)
+#else /* !__aarch64 */
+void trf_init_el3(void);
+#endif /* __aarch64__ */
+
+#else /* ENABLE_TRF_FOR_NS=0 */
+
+#if __aarch64__
+static inline void trf_enable(cpu_context_t *ctx)
 {
 }
 static inline void trf_init_el2_unused(void)
 {
 }
+#else /* !__aarch64 */
+static inline void trf_init_el3(void)
+{
+}
+#endif /* __aarch64__*/
+
 #endif /* ENABLE_TRF_FOR_NS */
 
 #endif /* TRF_H */
diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h
index 9d901e20..41bf7fc7 100644
--- a/include/lib/pmf/pmf.h
+++ b/include/lib/pmf/pmf.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,19 +36,36 @@
 #define PMF_NO_CACHE_MAINT	U(0)
 
 /*
- * Defines for PMF SMC function ids.
+ * Defines for PMF SMC function ids used with arm-sip
+ * range, this is now deprecated and will be removed.
  */
-#define PMF_SMC_GET_TIMESTAMP_32	U(0x82000010)
-#define PMF_SMC_GET_TIMESTAMP_64	U(0xC2000010)
+#define PMF_SMC_GET_TIMESTAMP_32_DEP	U(0x82000010)
+#define PMF_SMC_GET_TIMESTAMP_64_DEP	U(0xC2000010)
+
+#define PMF_FID_VALUE_DEPRECATED	U(0x10)
+#define is_pmf_fid_deprecated(_fid) \
+	(GET_SMC_NUM(_fid) == PMF_FID_VALUE_DEPRECATED)
+
+/*
+ * Defines for PMF SMC function ids used with Vendor-Specific
+ * EL3 range.
+ */
+#define PMF_SMC_GET_TIMESTAMP_32	U(0x87000020)
+#define PMF_SMC_GET_TIMESTAMP_64	U(0xC7000020)
 #define PMF_NUM_SMC_CALLS		2
 
+#define PMF_SMC_GET_VERSION_32		U(0x87000021)
+#define PMF_SMC_GET_VERSION_64		U(0xC7000021)
+
+#define PMF_SMC_VERSION			U(0x00000001)
+
 /*
  * The macros below are used to identify
  * PMF calls from the SMC function ID.
  */
-#define PMF_FID_MASK	U(0xffe0)
-#define PMF_FID_VALUE	U(0)
-#define is_pmf_fid(_fid)	(((_fid) & PMF_FID_MASK) == PMF_FID_VALUE)
+#define PMF_FID_VALUE		U(0x20)
+#define PMF_ID_MASK		(FUNCID_NUM_MASK & ~(0xf))
+#define is_pmf_fid(_fid)	((GET_SMC_NUM(_fid) & PMF_ID_MASK) == PMF_FID_VALUE)
 
 /* Following are the supported PMF service IDs */
 #define PMF_PSCI_STAT_SVC_ID	0
diff --git a/include/lib/psa/cca_attestation.h b/include/lib/psa/cca_attestation.h
new file mode 100644
index 00000000..4062ddef
--- /dev/null
+++ b/include/lib/psa/cca_attestation.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CCA_ATTESTATION_H
+#define CCA_ATTESTATION_H
+
+#include <stdint.h>
+#include <psa/crypto_types.h>
+
+psa_status_t
+cca_attestation_get_realm_key(uintptr_t buf, size_t *len, unsigned int type);
+
+psa_status_t
+cca_attestation_get_plat_token(uintptr_t buf, size_t *len,
+			       uintptr_t hash, size_t hash_size);
+
+#endif /* CCA_ATTESTATION_H */
diff --git a/include/lib/psa/delegated_attestation.h b/include/lib/psa/delegated_attestation.h
index 7aaceb3e..ec49f5d3 100644
--- a/include/lib/psa/delegated_attestation.h
+++ b/include/lib/psa/delegated_attestation.h
@@ -15,9 +15,9 @@
 
 #include "psa/error.h"
 
-/* RSS Delegated Attestation message types that distinguish its services. */
-#define RSS_DELEGATED_ATTEST_GET_DELEGATED_KEY      1001U
-#define RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN     1002U
+/* RSE Delegated Attestation message types that distinguish its services. */
+#define RSE_DELEGATED_ATTEST_GET_DELEGATED_KEY      1001U
+#define RSE_DELEGATED_ATTEST_GET_PLATFORM_TOKEN     1002U
 
 /**
  * The aim of these APIs to get a derived signing key (private only) for the
@@ -28,13 +28,13 @@
  * key is bind to the platform token (details below).
  *
  * Expected usage model:
- *  - First rss_delegated_attest_get_delegated_key() API need to be called to
+ *  - First rse_delegated_attest_get_delegated_key() API need to be called to
  *    obtain the private part of the delegated attestation key. The public part
  *    of key is computed by the cryptographic library when the key is
  *    registered.
- *  - Secondly the rss_delegated_attest_get_token() must be called to obtain
+ *  - Secondly the rse_delegated_attest_get_token() must be called to obtain
  *    platform attestation token. The hash of the public key (computed by
- *    the hash_algo indicated in the rss_delegated_attest_get_delegated_key()
+ *    the hash_algo indicated in the rse_delegated_attest_get_delegated_key()
  *    call) must be the input of this call. This ensures that nothing but the
  *    previously derived delegated key is bindable to the platform token.
  */
@@ -74,7 +74,7 @@
  *     platform attestation token as they are cryptographically linked together.
  */
 psa_status_t
-rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+rse_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
 				       uint32_t  key_bits,
 				       uint8_t  *key_buf,
 				       size_t    key_buf_size,
@@ -100,7 +100,7 @@ rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
  * code will be returned.
  */
 psa_status_t
-rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+rse_delegated_attest_get_token(const uint8_t *dak_pub_hash,
 			       size_t         dak_pub_hash_size,
 			       uint8_t       *token_buf,
 			       size_t         token_buf_size,
diff --git a/include/lib/psa/dice_protection_environment.h b/include/lib/psa/dice_protection_environment.h
new file mode 100644
index 00000000..53514516
--- /dev/null
+++ b/include/lib/psa/dice_protection_environment.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef DICE_PROTECTION_ENVIRONMENT_H
+#define DICE_PROTECTION_ENVIRONMENT_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <dice.h>
+
+/* Additional defines for max size limit. These limits are set by DPE in RSE. */
+#define DICE_AUTHORITY_DESCRIPTOR_MAX_SIZE	64
+#define DICE_CONFIG_DESCRIPTOR_MAX_SIZE		64
+#define DICE_CODE_DESCRIPTOR_MAX_SIZE		32
+
+typedef int32_t dpe_error_t;
+
+#define DPE_NO_ERROR			((dpe_error_t)0)
+#define DPE_INTERNAL_ERROR		((dpe_error_t)1)
+#define DPE_INVALID_COMMAND		((dpe_error_t)2)
+#define DPE_INVALID_ARGUMENT		((dpe_error_t)3)
+#define DPE_ARGUMENT_NOT_SUPPORTED	((dpe_error_t)4)
+#define DPE_SESSION_EXHAUSTED		((dpe_error_t)5)
+
+/* Custom values in RSE based DPE implementation */
+#define DPE_INSUFFICIENT_MEMORY		((dpe_error_t)128)
+#define DPE_ERR_CBOR_FORMATTING		((dpe_error_t)129)
+
+/**
+ * Client facing API. Parameters are according to the DPE spec version r0.9
+ *
+ * \brief Performs the DICE computation to derive a new context and optionally
+ *        creates an intermediate certificate. Software component measurement
+ *        must be provided in dice_inputs.
+ *
+ * \param[in]  context_handle              Input context handle for the DPE
+ *                                         context.
+ * \param[in]  cert_id                     Logical certificate id to which derived
+ *                                         context belongs to.
+ * \param[in]  retain_parent_context       Flag to indicate whether to retain the
+ *                                         parent context. True only if a client
+ *                                         will call further DPE commands on the
+ *                                         same context.
+ * \param[in]  allow_new_context_to_derive Flag to indicate whether derived context
+ *                                         can derive further. True only if the
+ *                                         new context will load further components.
+ * \param[in]  create_certificate          Flag to indicate whether to create an
+ *                                         intermediate certificate. True only if
+ *                                         it is the last component in the layer.
+ * \param[in]  dice_inputs                 DICE input values.
+ * \param[in]  target_locality             Identifies the locality to which the
+ *                                         derived context will be bound. Could be
+ *                                         MHU id.
+ * \param[in]  return_certificate          Indicates whether to return the generated
+ *                                         certificate when create_certificate is true.
+ * \param[in]  allow_new_context_to_export Indicates whether the DPE permits export of
+ *                                         the CDI from the newly derived context.
+ * \param[in]  export_cdi                  Indicates whether to export derived CDI.
+ * \param[out] new_context_handle          New handle for the derived context.
+ * \param[out] new_parent_context_handle   New handle for the parent context.
+ * \param[out] new_certificate_buf         If create_certificate and return_certificate
+ *                                         are both true, this argument holds the new
+ *                                         certificate generated for the new context
+ * \param[in]  new_certificate_buf_size    Size of the allocated buffer for
+ *                                         new certificate.
+ * \param[out] new_certificate_actual_size Actual size of the new certificate.
+ * \param[out] exported_cdi_buf            If export_cdi is true, this is the
+ *                                         exported CDI value.
+ * \param[in]  exported_cdi_buf_size       Size of the allocated buffer for
+ *                                         exported cdi.
+ * \param[out] exported_cdi_actual_size    Actual size of the exported cdi.
+ *
+ * \return Returns error code of type dpe_error_t
+ */
+dpe_error_t dpe_derive_context(int      context_handle,
+			       uint32_t cert_id,
+			       bool     retain_parent_context,
+			       bool     allow_new_context_to_derive,
+			       bool     create_certificate,
+			       const DiceInputValues *dice_inputs,
+			       int32_t  target_locality,
+			       bool     return_certificate,
+			       bool     allow_new_context_to_export,
+			       bool     export_cdi,
+			       int     *new_context_handle,
+			       int     *new_parent_context_handle,
+			       uint8_t *new_certificate_buf,
+			       size_t   new_certificate_buf_size,
+			       size_t  *new_certificate_actual_size,
+			       uint8_t *exported_cdi_buf,
+			       size_t   exported_cdi_buf_size,
+			       size_t  *exported_cdi_actual_size);
+
+#endif /* DICE_PROTECTION_ENVIRONMENT_H */
diff --git a/include/lib/psa/measured_boot.h b/include/lib/psa/measured_boot.h
index af624a6f..3cc6c95d 100644
--- a/include/lib/psa/measured_boot.h
+++ b/include/lib/psa/measured_boot.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -14,21 +14,6 @@
 
 #include "psa/error.h"
 
-/* Minimum measurement value size that can be requested to store */
-#define MEASUREMENT_VALUE_MIN_SIZE	32U
-/* Maximum measurement value size that can be requested to store */
-#define MEASUREMENT_VALUE_MAX_SIZE	64U
-/* Minimum signer id size that can be requested to store */
-#define SIGNER_ID_MIN_SIZE		MEASUREMENT_VALUE_MIN_SIZE
-/* Maximum signer id size that can be requested to store */
-#define SIGNER_ID_MAX_SIZE		MEASUREMENT_VALUE_MAX_SIZE
-/* The theoretical maximum image version is: "255.255.65535\0" */
-#define VERSION_MAX_SIZE		14U
-/* Example sw_type: "BL_2, BL_33, etc." */
-#define SW_TYPE_MAX_SIZE		20U
-#define NUM_OF_MEASUREMENT_SLOTS	32U
-
-
 /**
  * Extends and stores a measurement to the requested slot.
  *
@@ -58,11 +43,11 @@
  *	- When the requested slot is not accessible to the caller.
  */
 
-/* Not a standard PSA API, just an extension therefore use the 'rss_' prefix
+/* Not a standard PSA API, just an extension therefore use the 'rse_' prefix
  * rather than the usual 'psa_'.
  */
 psa_status_t
-rss_measured_boot_extend_measurement(uint8_t index,
+rse_measured_boot_extend_measurement(uint8_t index,
 				     const uint8_t *signer_id,
 				     size_t signer_id_size,
 				     const uint8_t *version,
@@ -107,7 +92,7 @@ rss_measured_boot_extend_measurement(uint8_t index,
  * PSA_ERROR_DOES_NOT_EXIST
  *	- The requested slot is empty, does not contain a measurement.
  */
-psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+psa_status_t rse_measured_boot_read_measurement(uint8_t index,
 					uint8_t *signer_id,
 					size_t signer_id_size,
 					size_t *signer_id_len,
diff --git a/include/lib/psa/psa/client.h b/include/lib/psa/psa/client.h
index 56fe0288..46fac4a8 100644
--- a/include/lib/psa/psa/client.h
+++ b/include/lib/psa/psa/client.h
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -17,41 +16,57 @@
 #ifndef IOVEC_LEN
 #define IOVEC_LEN(arr) ((uint32_t)(sizeof(arr)/sizeof(arr[0])))
 #endif
+
 /*********************** PSA Client Macros and Types *************************/
+
 /**
  * The version of the PSA Framework API that is being used to build the calling
  * firmware. Only part of features of FF-M v1.1 have been implemented. FF-M v1.1
  * is compatible with v1.0.
  */
 #define PSA_FRAMEWORK_VERSION	(0x0101u)
+
 /**
  * Return value from psa_version() if the requested RoT Service is not present
  * in the system.
  */
 #define PSA_VERSION_NONE	(0u)
+
 /**
  * The zero-value null handle can be assigned to variables used in clients and
  * RoT Services, indicating that there is no current connection or message.
  */
 #define PSA_NULL_HANDLE		((psa_handle_t)0)
+
 /**
  * Tests whether a handle value returned by psa_connect() is valid.
  */
 #define PSA_HANDLE_IS_VALID(handle)	((psa_handle_t)(handle) > 0)
+
 /**
  * Converts the handle value returned from a failed call psa_connect() into
  * an error code.
  */
 #define PSA_HANDLE_TO_ERROR(handle)	((psa_status_t)(handle))
+
 /**
  * Maximum number of input and output vectors for a request to psa_call().
  */
 #define PSA_MAX_IOVEC		(4u)
+
+/**
+ * The minimum and maximum value that can be passed
+ * as the type parameter in a call to psa_call().
+ */
+#define PSA_CALL_TYPE_MIN	(0)
+#define PSA_CALL_TYPE_MAX	(INT16_MAX)
+
 /**
  * An IPC message type that indicates a generic client request.
  */
 #define PSA_IPC_CALL		(0)
 typedef int32_t psa_handle_t;
+
 /**
  * A read-only input memory region provided to an RoT Service.
  */
@@ -59,6 +74,7 @@ typedef struct psa_invec {
 	const void *base;	/*!< the start address of the memory buffer */
 	size_t len;		/*!< the size in bytes                      */
 } psa_invec;
+
 /**
  * A writable output memory region provided to an RoT Service.
  */
diff --git a/include/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h
index 71831124..bb8abe46 100644
--- a/include/lib/psa/psa_manifest/sid.h
+++ b/include/lib/psa/psa_manifest/sid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,16 +8,19 @@
 #ifndef PSA_MANIFEST_SID_H
 #define PSA_MANIFEST_SID_H
 
-/******** RSS_SP_CRYPTO ********/
-#define RSS_CRYPTO_HANDLE				(0x40000100U)
+/******** RSE_SP_CRYPTO ********/
+#define RSE_CRYPTO_HANDLE				(0x40000100U)
 
-/******** RSS_SP_PLATFORM ********/
-#define RSS_PLATFORM_SERVICE_HANDLE			(0x40000105U)
+/******** RSE_SP_PLATFORM ********/
+#define RSE_PLATFORM_SERVICE_HANDLE			(0x40000105U)
 
 /******** PSA_SP_MEASURED_BOOT ********/
-#define RSS_MEASURED_BOOT_HANDLE			(0x40000110U)
+#define RSE_MEASURED_BOOT_HANDLE			(0x40000110U)
 
-/******** PSA_SP_DELAGATED_ATTESTATION ********/
-#define RSS_DELEGATED_SERVICE_HANDLE			(0x40000111U)
+/******** PSA_SP_DELEGATED_ATTESTATION ********/
+#define RSE_DELEGATED_SERVICE_HANDLE			(0x40000111U)
+
+/******** PSA_SP_DICE_PROTECTION_ENVIRONMENT ********/
+#define RSE_DPE_SERVICE_HANDLE				(0x40000112U)
 
 #endif /* PSA_MANIFEST_SID_H */
diff --git a/include/lib/psa/rse_crypto_defs.h b/include/lib/psa/rse_crypto_defs.h
new file mode 100644
index 00000000..b94664fb
--- /dev/null
+++ b/include/lib/psa/rse_crypto_defs.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef RSE_CRYPTO_DEFS_H
+#define RSE_CRYPTO_DEFS_H
+
+/* Declares types that encode errors, algorithms, key types, policies, etc. */
+#include "psa/crypto_types.h"
+
+/*
+ * Value identifying export public key function API, used to dispatch the request
+ * to the corresponding API implementation in the Crypto service backend.
+ *
+ */
+#define RSE_CRYPTO_EXPORT_PUBLIC_KEY_SID	(uint16_t)(0x206)
+
+/*
+ * The persistent key identifiers for RSE builtin keys.
+ */
+enum rse_key_id_builtin_t {
+	RSE_BUILTIN_KEY_ID_HOST_S_ROTPK = 0x7FFF816Cu,
+	RSE_BUILTIN_KEY_ID_HOST_NS_ROTPK,
+	RSE_BUILTIN_KEY_ID_HOST_CCA_ROTPK,
+};
+
+/*
+ * This type is used to overcome a limitation within RSE firmware in the number of maximum
+ * IOVECs it can use especially in psa_aead_encrypt and psa_aead_decrypt.
+ */
+#define RSE_CRYPTO_MAX_NONCE_LENGTH (16u)
+struct rse_crypto_aead_pack_input {
+	uint8_t nonce[RSE_CRYPTO_MAX_NONCE_LENGTH];
+	uint32_t nonce_length;
+};
+
+/*
+ * Structure used to pack non-pointer types in a call to PSA Crypto APIs
+ */
+struct rse_crypto_pack_iovec {
+	psa_key_id_t key_id;		/* !< Key id */
+	psa_algorithm_t alg;		/* !< Algorithm */
+	uint32_t op_handle;		/*
+					 * !< Frontend context handle
+					 * associated to a multipart operation
+					 */
+	uint32_t ad_length;		/*
+					 * !< Additional Data length for
+					 *    multipart AEAD
+					 */
+	uint32_t plaintext_length;	/*
+					 * !< Plaintext length for multipart
+					 *    AEAD
+					 */
+
+	struct rse_crypto_aead_pack_input aead_in; /*
+						    * !< Packs AEAD-related
+						    *    inputs
+						    */
+
+	uint16_t function_id;	/*
+				 * !< Used to identify the function in the
+				 *    API dispatcher to the service backend
+				 *    See rse_crypto_func_sid for detail
+				 */
+	uint16_t step;		/* !< Key derivation step */
+	union {
+		size_t capacity;	/* !< Key derivation capacity */
+		uint64_t value;		/*
+					 * !< Key derivation integer for
+					 *    update
+					 */
+	};
+};
+
+#endif /* RSE_CRYPTO_DEFS_H */
diff --git a/include/lib/psa/rss_platform_api.h b/include/lib/psa/rse_platform_api.h
similarity index 74%
rename from include/lib/psa/rss_platform_api.h
rename to include/lib/psa/rse_platform_api.h
index 8f74a51f..535001bd 100644
--- a/include/lib/psa/rss_platform_api.h
+++ b/include/lib/psa/rse_platform_api.h
@@ -5,16 +5,16 @@
  *
  */
 
-#ifndef RSS_PLATFORM_API_H
-#define RSS_PLATFORM_API_H
+#ifndef RSE_PLATFORM_API_H
+#define RSE_PLATFORM_API_H
 
 #include <stdint.h>
 
 #include "psa/error.h"
-#include <rss_crypto_defs.h>
+#include <rse_crypto_defs.h>
 
-#define RSS_PLATFORM_API_ID_NV_READ       (1010)
-#define RSS_PLATFORM_API_ID_NV_INCREMENT  (1011)
+#define RSE_PLATFORM_API_ID_NV_READ       (1010)
+#define RSE_PLATFORM_API_ID_NV_INCREMENT  (1011)
 
 /*
  * Increments the given non-volatile (NV) counter by one
@@ -25,7 +25,7 @@
  *	it returns a PSA_ERROR.
  */
 psa_status_t
-rss_platform_nv_counter_increment(uint32_t counter_id);
+rse_platform_nv_counter_increment(uint32_t counter_id);
 
 /*
  * Reads the given non-volatile (NV) counter
@@ -39,7 +39,7 @@ rss_platform_nv_counter_increment(uint32_t counter_id);
  *	it returns a PSA_ERROR.
  */
 psa_status_t
-rss_platform_nv_counter_read(uint32_t counter_id,
+rse_platform_nv_counter_read(uint32_t counter_id,
 		uint32_t size, uint8_t *val);
 
 /*
@@ -54,7 +54,7 @@ rss_platform_nv_counter_read(uint32_t counter_id,
  *	it returns a PSA_ERROR.
  */
 psa_status_t
-rss_platform_key_read(enum rss_key_id_builtin_t key, uint8_t *data,
+rse_platform_key_read(enum rse_key_id_builtin_t key, uint8_t *data,
 		size_t data_size, size_t *data_length);
 
-#endif /* RSS_PLATFORM_API_H */
+#endif /* RSE_PLATFORM_API_H */
diff --git a/include/lib/psa/rss_crypto_defs.h b/include/lib/psa/rss_crypto_defs.h
deleted file mode 100644
index b8c74268..00000000
--- a/include/lib/psa/rss_crypto_defs.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef RSS_CRYPTO_DEFS_H
-#define RSS_CRYPTO_DEFS_H
-
-/* Declares types that encode errors, algorithms, key types, policies, etc. */
-#include "psa/crypto_types.h"
-
-/*
- * Value identifying export public key function API, used to dispatch the request
- * to the corresponding API implementation in the Crypto service backend.
- *
- */
-#define RSS_CRYPTO_EXPORT_PUBLIC_KEY_SID	(uint16_t)(0x701)
-
-/*
- * The persistent key identifiers for RSS builtin keys.
- */
-enum rss_key_id_builtin_t {
-	RSS_BUILTIN_KEY_ID_HOST_S_ROTPK = 0x7FFF816Cu,
-	RSS_BUILTIN_KEY_ID_HOST_NS_ROTPK,
-	RSS_BUILTIN_KEY_ID_HOST_CCA_ROTPK,
-};
-
-/*
- * This type is used to overcome a limitation within RSS firmware in the number of maximum
- * IOVECs it can use especially in psa_aead_encrypt and psa_aead_decrypt.
- */
-#define RSS_CRYPTO_MAX_NONCE_LENGTH (16u)
-struct rss_crypto_aead_pack_input {
-	uint8_t nonce[RSS_CRYPTO_MAX_NONCE_LENGTH];
-	uint32_t nonce_length;
-};
-
-/*
- * Structure used to pack non-pointer types in a call
- */
-struct rss_crypto_pack_iovec {
-	psa_key_id_t key_id;	/* Key id */
-	psa_algorithm_t alg;	/* Algorithm */
-	uint32_t op_handle;	/* Frontend context handle associated
-				   to a multipart operation */
-	uint32_t capacity;	/* Key derivation capacity */
-	uint32_t ad_length;	/* Additional Data length for multipart AEAD */
-	uint32_t plaintext_length;	/* Plaintext length for multipart AEAD */
-	struct rss_crypto_aead_pack_input aead_in;	/* Packs AEAD-related inputs */
-	uint16_t function_id;	/* Used to identify the function in the API dispatcher
-				   to the service backend. See rss_crypto_func_sid for
-				   detail */
-	uint16_t step;		/* Key derivation step */
-};
-
-#endif /* RSS_CRYPTO_DEFS_H */
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index 4b244ec3..c50f8cbb 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -94,6 +94,7 @@ int psci_stop_other_cores(unsigned int wait_ms,
 bool psci_is_last_on_cpu_safe(void);
 bool psci_are_all_cpus_on_safe(void);
 void psci_pwrdown_cpu(unsigned int power_level);
+void psci_do_manage_extensions(void);
 
 #endif /* __ASSEMBLER__ */
 
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index 8fd60931..775c2b21 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,7 @@
 						SMCCC_VERSION_MINOR_SHIFT))
 
 #define SMCCC_MAJOR_VERSION U(1)
-#define SMCCC_MINOR_VERSION U(4)
+#define SMCCC_MINOR_VERSION U(5)
 
 /*******************************************************************************
  * Bit definitions inside the function id as per the SMC calling convention
@@ -95,6 +95,8 @@
 #define OEN_STD_HYP_END			U(5)
 #define OEN_VEN_HYP_START		U(6)	/* Vendor Hypervisor Service calls */
 #define OEN_VEN_HYP_END			U(6)
+#define OEN_VEN_EL3_START		U(7)	/* Vendor Specific EL3 Monitor Calls */
+#define OEN_VEN_EL3_END			U(7)
 #define OEN_TAP_START			U(48)	/* Trusted Applications */
 #define OEN_TAP_END			U(49)
 #define OEN_TOS_START			U(50)	/* Trusted OS */
@@ -111,6 +113,8 @@
 #define SMC_OK				ULL(0)
 #define SMC_UNK				-1
 #define SMC_PREEMPTED			-2	/* Not defined by the SMCCC */
+#define SMC_DENIED			-3	/* Not defined by the SMCCC */
+#define SMC_INVALID_PARAM		-4	/* Not defined by the SMCCC */
 
 /* Return codes for Arm Architecture Service SMC calls */
 #define SMC_ARCH_CALL_SUCCESS		0
diff --git a/include/lib/spinlock.h b/include/lib/spinlock.h
index 9fd3fc65..055a911d 100644
--- a/include/lib/spinlock.h
+++ b/include/lib/spinlock.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,15 +15,21 @@ typedef struct spinlock {
 	volatile uint32_t lock;
 } spinlock_t;
 
+typedef struct bitlock {
+	volatile uint8_t lock;
+} bitlock_t;
+
 void spin_lock(spinlock_t *lock);
 void spin_unlock(spinlock_t *lock);
 
+void bit_lock(bitlock_t *lock, uint8_t mask);
+void bit_unlock(bitlock_t *lock, uint8_t mask);
+
 #else
 
 /* Spin lock definitions for use in assembly */
 #define SPINLOCK_ASM_ALIGN	2
 #define SPINLOCK_ASM_SIZE	4
 
-#endif
-
+#endif /* __ASSEMBLER__ */
 #endif /* SPINLOCK_H */
diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h
index 54c86434..1b5ec2d6 100644
--- a/include/lib/transfer_list.h
+++ b/include/lib/transfer_list.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Linaro Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,47 +10,76 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <common/ep_info.h>
 #include <lib/utils_def.h>
 
-#define	TRANSFER_LIST_SIGNATURE		U(0x006ed0ff)
-#define TRANSFER_LIST_VERSION		U(0x0001)
+#define TRANSFER_LIST_SIGNATURE U(0x4a0fb10b)
+#define TRANSFER_LIST_VERSION U(0x0001)
 
-// Init value of maximum alignment required by any TE data in the TL
-// specified as a power of two
-#define TRANSFER_LIST_INIT_MAX_ALIGN	U(3)
+/*
+ * Init value of maximum alignment required by any TE data in the TL
+ * specified as a power of two
+ */
+#define TRANSFER_LIST_INIT_MAX_ALIGN U(3)
 
-// alignment required by TE header start address, in bytes
-#define TRANSFER_LIST_GRANULE		U(8)
+/* Alignment required by TE header start address, in bytes */
+#define TRANSFER_LIST_GRANULE U(8)
 
-// version of the register convention used.
-// Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
-#define REGISTER_CONVENTION_VERSION_MASK (1 << 24)
+/*
+ * Version of the register convention used.
+ * Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
+ */
+#define REGISTER_CONVENTION_VERSION_SHIFT_64	UL(32)
+#define REGISTER_CONVENTION_VERSION_SHIFT_32	UL(24)
+#define REGISTER_CONVENTION_VERSION_MASK	UL(0xff)
+#define REGISTER_CONVENTION_VERSION 	UL(1)
+
+#define TRANSFER_LIST_HANDOFF_X1_VALUE(__version) 	\
+	((TRANSFER_LIST_SIGNATURE &	\
+	((1UL << REGISTER_CONVENTION_VERSION_SHIFT_64) - 1)) | 	\
+	(((__version) & REGISTER_CONVENTION_VERSION_MASK) <<	\
+	 REGISTER_CONVENTION_VERSION_SHIFT_64))
+
+#define TRANSFER_LIST_HANDOFF_R1_VALUE(__version) 	\
+	((TRANSFER_LIST_SIGNATURE &	\
+	((1UL << REGISTER_CONVENTION_VERSION_SHIFT_32) - 1)) | 	\
+	(((__version) & REGISTER_CONVENTION_VERSION_MASK) <<	\
+	 REGISTER_CONVENTION_VERSION_SHIFT_32))
 
 #ifndef __ASSEMBLER__
 
+#define TL_FLAGS_HAS_CHECKSUM BIT(0)
+
 enum transfer_list_tag_id {
 	TL_TAG_EMPTY = 0,
 	TL_TAG_FDT = 1,
 	TL_TAG_HOB_BLOCK = 2,
 	TL_TAG_HOB_LIST = 3,
 	TL_TAG_ACPI_TABLE_AGGREGATE = 4,
+	TL_TAG_OPTEE_PAGABLE_PART = 0x100,
+	TL_TAG_DT_SPMC_MANIFEST = 0x101,
+	TL_TAG_EXEC_EP_INFO64 = 0x102,
+	TL_TAG_TB_FW_CONFIG = 0x103,
+	TL_TAG_SRAM_LAYOUT64 = 0x104,
 };
 
 enum transfer_list_ops {
-	TL_OPS_NON,	// invalid for any operation
-	TL_OPS_ALL,	// valid for all operations
-	TL_OPS_RO,	// valid for read only
-	TL_OPS_CUS,	// either abort or switch to special code to interpret
+	TL_OPS_NON, /* invalid for any operation */
+	TL_OPS_ALL, /* valid for all operations */
+	TL_OPS_RO, /* valid for read only */
+	TL_OPS_CUS, /* abort or switch to special code to interpret */
 };
 
 struct transfer_list_header {
-	uint32_t	signature;
-	uint8_t		checksum;
-	uint8_t		version;
-	uint8_t		hdr_size;
-	uint8_t		alignment;	// max alignment of TE data
-	uint32_t	size;		// TL header + all TEs
-	uint32_t	max_size;
+	uint32_t signature;
+	uint8_t checksum;
+	uint8_t version;
+	uint8_t hdr_size;
+	uint8_t alignment; /* max alignment of TE data */
+	uint32_t size; /* TL header + all TEs */
+	uint32_t max_size;
+	uint32_t flags;
+	uint32_t reserved; /* spare bytes */
 	/*
 	 * Commented out element used to visualize dynamic part of the
 	 * data structure.
@@ -63,11 +92,10 @@ struct transfer_list_header {
 	 */
 };
 
-struct transfer_list_entry {
-	uint16_t	tag_id;
-	uint8_t		reserved0;	// place holder
-	uint8_t		hdr_size;
-	uint32_t	data_size;
+struct __attribute__((packed)) transfer_list_entry {
+	uint32_t tag_id : 24;
+	uint8_t hdr_size;
+	uint32_t data_size;
 	/*
 	 * Commented out element used to visualize dynamic part of the
 	 * data structure.
@@ -79,12 +107,19 @@ struct transfer_list_entry {
 	 */
 };
 
+CASSERT(sizeof(struct transfer_list_entry) == U(0x8), assert_transfer_list_entry_size);
+
 void transfer_list_dump(struct transfer_list_header *tl);
+entry_point_info_t *
+transfer_list_set_handoff_args(struct transfer_list_header *tl,
+			       entry_point_info_t *ep_info);
 struct transfer_list_header *transfer_list_init(void *addr, size_t max_size);
 
-struct transfer_list_header *transfer_list_relocate(struct transfer_list_header *tl,
-						    void *addr, size_t max_size);
-enum transfer_list_ops transfer_list_check_header(const struct transfer_list_header *tl);
+struct transfer_list_header *
+transfer_list_relocate(struct transfer_list_header *tl, void *addr,
+		       size_t max_size);
+enum transfer_list_ops
+transfer_list_check_header(const struct transfer_list_header *tl);
 
 void transfer_list_update_checksum(struct transfer_list_header *tl);
 bool transfer_list_verify_checksum(const struct transfer_list_header *tl);
@@ -94,21 +129,25 @@ bool transfer_list_set_data_size(struct transfer_list_header *tl,
 				 uint32_t new_data_size);
 
 void *transfer_list_entry_data(struct transfer_list_entry *entry);
-bool transfer_list_rem(struct transfer_list_header *tl, struct transfer_list_entry *entry);
+bool transfer_list_rem(struct transfer_list_header *tl,
+		       struct transfer_list_entry *entry);
 
 struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
-					      uint16_t tag_id, uint32_t data_size,
+					      uint32_t tag_id,
+					      uint32_t data_size,
 					      const void *data);
 
-struct transfer_list_entry *transfer_list_add_with_align(struct transfer_list_header *tl,
-							 uint16_t tag_id, uint32_t data_size,
-							 const void *data, uint8_t alignment);
+struct transfer_list_entry *
+transfer_list_add_with_align(struct transfer_list_header *tl, uint32_t tag_id,
+			     uint32_t data_size, const void *data,
+			     uint8_t alignment);
 
-struct transfer_list_entry *transfer_list_next(struct transfer_list_header *tl,
-					       struct transfer_list_entry *last);
+struct transfer_list_entry *
+transfer_list_next(struct transfer_list_header *tl,
+		   struct transfer_list_entry *last);
 
 struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
-					       uint16_t tag_id);
+					       uint32_t tag_id);
 
 #endif /*__ASSEMBLER__*/
 #endif /*__TRANSFER_LIST_H*/
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index a170a09d..c3f767ee 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -19,8 +19,13 @@
 
 #define SIZE_FROM_LOG2_WORDS(n)		(U(4) << (n))
 
+#if defined(__LINKER__) || defined(__ASSEMBLER__)
 #define BIT_32(nr)			(U(1) << (nr))
 #define BIT_64(nr)			(ULL(1) << (nr))
+#else
+#define BIT_32(nr)			(((uint32_t)(1U)) << (nr))
+#define BIT_64(nr)			(((uint64_t)(1ULL)) << (nr))
+#endif
 
 #ifdef __aarch64__
 #define BIT				BIT_64
@@ -29,22 +34,22 @@
 #endif
 
 /*
- * Create a contiguous bitmask starting at bit position @l and ending at
- * position @h. For example
+ * Create a contiguous bitmask starting at bit position @low and ending at
+ * position @high. For example
  * GENMASK_64(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
 #if defined(__LINKER__) || defined(__ASSEMBLER__)
-#define GENMASK_32(h, l) \
-	(((0xFFFFFFFF) << (l)) & (0xFFFFFFFF >> (32 - 1 - (h))))
+#define GENMASK_32(high, low) \
+	(((0xFFFFFFFF) << (low)) & (0xFFFFFFFF >> (32 - 1 - (high))))
 
-#define GENMASK_64(h, l) \
-	((~0 << (l)) & (~0 >> (64 - 1 - (h))))
+#define GENMASK_64(high, low) \
+	((~0 << (low)) & (~0 >> (64 - 1 - (high))))
 #else
-#define GENMASK_32(h, l) \
-	(((~UINT32_C(0)) << (l)) & (~UINT32_C(0) >> (32 - 1 - (h))))
+#define GENMASK_32(high, low) \
+	((~UINT32_C(0) >> (32U - 1U - (high))) ^ ((BIT_32(low) - 1U)))
 
-#define GENMASK_64(h, l) \
-	(((~UINT64_C(0)) << (l)) & (~UINT64_C(0) >> (64 - 1 - (h))))
+#define GENMASK_64(high, low) \
+	((~UINT64_C(0) >> (64U - 1U - (high))) ^ ((BIT_64(low) - 1U)))
 #endif
 
 #ifdef __aarch64__
@@ -53,6 +58,9 @@
 #define GENMASK				GENMASK_32
 #endif
 
+#define HI(addr)			(addr >> 32)
+#define LO(addr)			(addr & 0xffffffff)
+
 /*
  * This variant of div_round_up can be used in macro definition but should not
  * be used in C code as the `div` parameter is evaluated twice.
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 2d0949b5..5434a9a2 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -171,8 +171,10 @@
 #define SHAREABILITY_SHIFT		8
 /* The Access Flag, AF. */
 #define ACCESS_FLAG_SHIFT		10
-/* The not global bit, nG. */
+/* The not global bit, nG */
 #define NOT_GLOBAL_SHIFT		11
+/* The Non-secure Extension bit, NSE */
+#define NSE_SHIFT			11
 /* Contiguous hint bit. */
 #define CONT_HINT_SHIFT			52
 /* Execute-never bits, XN. */
diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h
index 1963bf0c..3bb68ee3 100644
--- a/include/plat/arm/board/common/board_css_def.h
+++ b/include/plat/arm/board/common/board_css_def.h
@@ -67,9 +67,6 @@
 #define PLAT_ARM_RUN_UART_BASE		SOC_CSS_UART1_BASE
 #define PLAT_ARM_RUN_UART_CLK_IN_HZ	SOC_CSS_UART1_CLK_IN_HZ
 
-#define PLAT_ARM_SP_MIN_RUN_UART_BASE		SOC_CSS_UART1_BASE
-#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ	SOC_CSS_UART1_CLK_IN_HZ
-
 #define PLAT_ARM_CRASH_UART_BASE		PLAT_ARM_RUN_UART_BASE
 #define PLAT_ARM_CRASH_UART_CLK_IN_HZ		PLAT_ARM_RUN_UART_CLK_IN_HZ
 
diff --git a/include/plat/arm/board/common/rotpk/rotpk_def.h b/include/plat/arm/board/common/rotpk/rotpk_def.h
new file mode 100644
index 00000000..685c21a6
--- /dev/null
+++ b/include/plat/arm/board/common/rotpk/rotpk_def.h
@@ -0,0 +1,24 @@
+
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROTPK_DEF_H
+#define ROTPK_DEF_H
+
+/*
+ * Definitions related to ROTPK
+ */
+
+/*
+ * Root of trust key lengths
+ */
+#ifndef ARM_ROTPK_HEADER_LEN
+#define ARM_ROTPK_HEADER_LEN		19
+#endif
+#ifndef ARM_ROTPK_HASH_LEN
+#define ARM_ROTPK_HASH_LEN		32
+#endif
+#endif /* ROTPK_DEF_H */
diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h
index cb11dac4..43a77e3c 100644
--- a/include/plat/arm/board/common/v2m_def.h
+++ b/include/plat/arm/board/common/v2m_def.h
@@ -17,6 +17,7 @@
 
 /* V2M motherboard system registers & offsets */
 #define V2M_SYSREGS_BASE		UL(0x1c010000)
+#define V2M_SYSREGS_SIZE		UL(0x00010000)
 #define V2M_SYS_ID			UL(0x0)
 #define V2M_SYS_SWITCH			UL(0x4)
 #define V2M_SYS_LED			UL(0x8)
@@ -78,6 +79,8 @@
 /* NOR Flash */
 #define V2M_FLASH0_BASE			(V2M_OFFSET + UL(0x08000000))
 #define V2M_FLASH0_SIZE			UL(0x04000000)
+#define V2M_FLASH1_BASE			(V2M_OFFSET + UL(0x0c000000))
+#define V2M_FLASH1_SIZE			UL(0x04000000)
 #define V2M_FLASH_BLOCK_SIZE		UL(0x00040000) /* 256 KB */
 
 #define V2M_IOFPGA_BASE			(V2M_OFFSET + UL(0x1c000000))
@@ -126,6 +129,14 @@
 						V2M_FLASH0_SIZE,	\
 						MT_RO_DATA | MT_SECURE)
 
+#define V2M_MAP_FLASH1_RW		MAP_REGION_FLAT(V2M_FLASH1_BASE,\
+						V2M_FLASH1_SIZE,	\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+#define V2M_MAP_FLASH1_RO		MAP_REGION_FLAT(V2M_FLASH1_BASE,\
+						V2M_FLASH1_SIZE,	\
+						MT_RO_DATA | MT_SECURE)
+
 #define V2M_MAP_IOFPGA			MAP_REGION_FLAT(V2M_IOFPGA_BASE,\
 						V2M_IOFPGA_SIZE,		\
 						MT_DEVICE | MT_RW | MT_SECURE)
@@ -136,5 +147,19 @@
 						V2M_IOFPGA_SIZE,	\
 						MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
+#define V2M_MAP_SECURE_SYSTEMREG_EL0		MAP_REGION_FLAT(	\
+						V2M_SYSREGS_BASE,															\
+						V2M_SYSREGS_SIZE,															\
+						MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define V2M_MAP_FLASH0_RW_EL0		MAP_REGION_FLAT(	\
+						V2M_FLASH0_BASE,											\
+						V2M_FLASH0_SIZE,											\
+						MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define V2M_MAP_FLASH1_RW_EL0		MAP_REGION_FLAT(	\
+						V2M_FLASH1_BASE,											\
+						V2M_FLASH1_SIZE,											\
+						MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
 #endif /* V2M_DEF_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index e098c10b..ec5f90bf 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,7 @@
 #include <drivers/arm/gic_common.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/board/common/rotpk/rotpk_def.h>
 #include <plat/arm/common/smccc_def.h>
 #include <plat/common/common_def.h>
 
@@ -19,11 +20,6 @@
  * Definitions common to all ARM standard platforms
  *****************************************************************************/
 
-/*
- * Root of trust key lengths
- */
-#define ARM_ROTPK_HEADER_LEN		19
-#define ARM_ROTPK_HASH_LEN		32
 
 /* Special value used to verify platform parameters from BL2 to BL31 */
 #define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
@@ -154,10 +150,10 @@ MEASURED_BOOT
 #endif /* (SPD_tspd || SPD_opteed || SPD_spmd) && MEASURED_BOOT */
 
 #if ENABLE_RME
-#define ARM_L1_GPT_ADDR_BASE		(ARM_DRAM1_BASE +		\
+#define ARM_L1_GPT_BASE		(ARM_DRAM1_BASE +		\
 					ARM_DRAM1_SIZE -		\
 					ARM_L1_GPT_SIZE)
-#define ARM_L1_GPT_END			(ARM_L1_GPT_ADDR_BASE +		\
+#define ARM_L1_GPT_END			(ARM_L1_GPT_BASE +		\
 					ARM_L1_GPT_SIZE - 1U)
 
 #define ARM_REALM_BASE			(ARM_EL3_RMM_SHARED_BASE -	\
@@ -347,7 +343,7 @@ MEASURED_BOOT
 
 
 #define ARM_MAP_GPT_L1_DRAM	MAP_REGION_FLAT(			\
-					ARM_L1_GPT_ADDR_BASE,		\
+					ARM_L1_GPT_BASE,		\
 					ARM_L1_GPT_SIZE,		\
 					MT_MEMORY | MT_RW | EL3_PAS)
 
@@ -415,6 +411,8 @@ MEASURED_BOOT
 #define ARM_V2M_MAP_MEM_PROTECT		MAP_REGION_FLAT(PLAT_ARM_MEM_PROT_ADDR,	\
 						V2M_FLASH_BLOCK_SIZE,		\
 						MT_DEVICE | MT_RW | MT_SECURE)
+
+#if !TRANSFER_LIST
 /*
  * Map the region for device tree configuration with read and write permissions
  */
@@ -422,11 +420,13 @@ MEASURED_BOOT
 						(ARM_FW_CONFIGS_LIMIT		\
 							- ARM_BL_RAM_BASE),	\
 						MT_MEMORY | MT_RW | EL3_PAS)
+#endif
+
 /*
  * Map L0_GPT with read and write permissions
  */
 #if ENABLE_RME
-#define ARM_MAP_L0_GPT_REGION		MAP_REGION_FLAT(ARM_L0_GPT_ADDR_BASE,	\
+#define ARM_MAP_L0_GPT_REGION		MAP_REGION_FLAT(ARM_L0_GPT_BASE,	\
 						ARM_L0_GPT_SIZE,		\
 						MT_MEMORY | MT_RW | MT_ROOT)
 #endif
@@ -509,6 +509,14 @@ MEASURED_BOOT
  */
 #define CACHE_WRITEBACK_GRANULE		(U(1) << ARM_CACHE_WRITEBACK_SHIFT)
 
+/* Define memory configuration for trusted boot device tree files. */
+#ifdef PLAT_ARM_TB_FW_CONFIG_SIZE
+#define ARM_TB_FW_CONFIG_MAX_SIZE	PLAT_ARM_TB_FW_CONFIG_SIZE
+#else
+#define ARM_TB_FW_CONFIG_MAX_SIZE	U(0x400)
+#endif
+
+#if !TRANSFER_LIST
 /*
  * To enable FW_CONFIG to be loaded by BL1, define the corresponding base
  * and limit. Leave enough space of BL2 meminfo.
@@ -530,6 +538,7 @@ MEASURED_BOOT
  */
 #define ARM_FW_CONFIGS_SIZE		(PAGE_SIZE * 2)
 #define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + ARM_FW_CONFIGS_SIZE)
+#endif
 
 #if ENABLE_RME
 /*
@@ -537,8 +546,8 @@ MEASURED_BOOT
  * configuration memory, 4KB aligned.
  */
 #define ARM_L0_GPT_SIZE			(PAGE_SIZE)
-#define ARM_L0_GPT_ADDR_BASE		(ARM_FW_CONFIGS_LIMIT)
-#define ARM_L0_GPT_LIMIT		(ARM_L0_GPT_ADDR_BASE + ARM_L0_GPT_SIZE)
+#define ARM_L0_GPT_BASE		(ARM_FW_CONFIGS_LIMIT)
+#define ARM_L0_GPT_LIMIT		(ARM_L0_GPT_BASE + ARM_L0_GPT_SIZE)
 #else
 #define ARM_L0_GPT_SIZE			U(0)
 #endif
diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h
index 266092e3..bca224d5 100644
--- a/include/plat/arm/common/arm_sip_svc.h
+++ b/include/plat/arm/common/arm_sip_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019,2021-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019,2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,12 +16,14 @@
 /*					U(0x8200ff02) is reserved */
 #define ARM_SIP_SVC_VERSION		U(0x8200ff03)
 
+/* Deprecated FID's Range and will be removed */
 /* PMF_SMC_GET_TIMESTAMP_32		0x82000010 */
 /* PMF_SMC_GET_TIMESTAMP_64		0xC2000010 */
 
 /* Function ID for requesting state switch of lower EL */
 #define ARM_SIP_SVC_EXE_STATE_SWITCH	U(0x82000020)
 
+/* Deprecated FID's Range and will be removed */
 /* DEBUGFS_SMC_32			0x82000030U */
 /* DEBUGFS_SMC_64			0xC2000030U */
 
@@ -32,8 +34,8 @@
  */
 
 /* ARM SiP Service Calls version numbers */
-#define ARM_SIP_SVC_VERSION_MAJOR		U(0x0)
-#define ARM_SIP_SVC_VERSION_MINOR		U(0x2)
+#define ARM_SIP_SVC_VERSION_MAJOR		U(0x1)
+#define ARM_SIP_SVC_VERSION_MINOR		U(0x0)
 
 /*
  * Arm SiP SMC calls that are primarily used for testing purposes.
@@ -42,6 +44,16 @@
 #define ARM_SIP_SET_INTERRUPT_PENDING	U(0x82000100)
 #endif
 
+/**
+ * Arm SiP Service Call for the SPM to leverage RME to protect a give memory range.
+ * Protected memory range is one whose PAS was made secure.
+ * Unprotect relates to reverting a protect operation.
+ */
+#if SPMD_SPM_AT_SEL2 && ENABLE_RME
+#define PLAT_PROTECT_MEM_SMC64 0xC2000101
+#define PLAT_UNPROTECT_MEM_SMC64 0xC2000102
+#endif
+
 /* SiP handler specific to each Arm platform. */
 uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
 				u_register_t x1,
diff --git a/include/plat/arm/common/arm_tzc_dram.ld.S b/include/plat/arm/common/arm_tzc_dram.ld.S
index c790bb92..08990f61 100644
--- a/include/plat/arm/common/arm_tzc_dram.ld.S
+++ b/include/plat/arm/common/arm_tzc_dram.ld.S
@@ -18,6 +18,9 @@ SECTIONS
 	ASSERT(. == ALIGN(PAGE_SIZE),
 	"ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
 	.el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) {
+	__PLAT_SPMC_SHMEM_DATASTORE_START__ = .;
+	*(.arm_spmc_shmem_datastore)
+	__PLAT_SPMC_SHMEM_DATASTORE_END__ = .;
 	__EL3_SEC_DRAM_START__ = .;
 	*(.arm_el3_tzc_dram)
 	__EL3_SEC_DRAM_UNALIGNED_END__ = .;
diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h
index 96ed9638..d8a332ec 100644
--- a/include/plat/arm/common/fconf_arm_sp_getter.h
+++ b/include/plat/arm/common/fconf_arm_sp_getter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,12 +9,17 @@
 
 #include <common/tbbr/tbbr_img_def.h>
 #include <lib/fconf/fconf.h>
+#include <platform_def.h>
 #include <tools_share/uuid.h>
 
 /* arm_sp getter */
 #define arm__sp_getter(prop)	arm_sp.prop
 
+#ifdef PLAT_ARM_SP_MAX_SIZE
+#define ARM_SP_MAX_SIZE		PLAT_ARM_SP_MAX_SIZE
+#else
 #define ARM_SP_MAX_SIZE		U(0xb0000)
+#endif /* PLAT_ARM_SP_MAX_SIZE */
 #define ARM_SP_OWNER_NAME_LEN	U(8)
 
 struct arm_sp_t {
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 0fb06a66..c3756bf5 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,11 +9,14 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <common/desc_image_load.h>
 #include <drivers/arm/tzc_common.h>
 #include <lib/bakery_lock.h>
 #include <lib/cassert.h>
 #include <lib/el3_runtime/cpu_data.h>
+#include <lib/gpt_rme/gpt_rme.h>
 #include <lib/spinlock.h>
+#include <lib/transfer_list.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 
@@ -31,6 +34,17 @@ typedef struct arm_tzc_regions_info {
 	unsigned int nsaid_permissions;
 } arm_tzc_regions_info_t;
 
+typedef struct arm_gpt_info {
+	pas_region_t *pas_region_base;
+	unsigned int pas_region_count;
+	uintptr_t l0_base;
+	uintptr_t l1_base;
+	size_t l0_size;
+	size_t l1_size;
+	gpccr_pps_e pps;
+	gpccr_pgs_e pgs;
+} arm_gpt_info_t;
+
 /*******************************************************************************
  * Default mapping definition of the TrustZone Controller for ARM standard
  * platforms.
@@ -55,14 +69,16 @@ typedef struct arm_tzc_regions_info {
 
 #if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 #define ARM_TZC_REGIONS_DEF						\
-	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\
-		TZC_REGION_S_RDWR, 0},					\
 	{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
 		PLAT_ARM_TZC_NS_DEV_ACCESS}, 				\
-	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
-		PLAT_ARM_TZC_NS_DEV_ACCESS},				\
+	{ARM_AP_TZC_DRAM1_BASE, (PLAT_SP_IMAGE_NS_BUF_BASE - 1),	\
+		TZC_REGION_S_RDWR, 0},					\
 	{PLAT_SP_IMAGE_NS_BUF_BASE, (PLAT_SP_IMAGE_NS_BUF_BASE +	\
-		PLAT_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
+		PLAT_SP_IMAGE_NS_BUF_SIZE - 1), TZC_REGION_S_NONE,	\
+		PLAT_ARM_TZC_NS_DEV_ACCESS},				\
+	{PLAT_SP_IMAGE_STACK_BASE, ARM_EL3_TZC_DRAM1_END,		\
+		TZC_REGION_S_RDWR, 0},					\
+	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
 		PLAT_ARM_TZC_NS_DEV_ACCESS}
 
 #elif ENABLE_RME
@@ -139,11 +155,10 @@ void arm_setup_romlib(void);
 #define ARM_LOCAL_PSTATE_WIDTH		4
 #define ARM_LOCAL_PSTATE_MASK		((1 << ARM_LOCAL_PSTATE_WIDTH) - 1)
 
-#if PSCI_OS_INIT_MODE
+/* Last in Level for the OS-initiated */
 #define ARM_LAST_AT_PLVL_MASK		(ARM_LOCAL_PSTATE_MASK <<	\
 					 (ARM_LOCAL_PSTATE_WIDTH *	\
 					  (PLAT_MAX_PWR_LVL + 1)))
-#endif /* __PSCI_OS_INIT_MODE__ */
 
 /* Macros to construct the composite power state */
 
@@ -242,10 +257,14 @@ uint32_t arm_get_spsr_for_bl33_entry(void);
 int arm_bl2_plat_handle_post_image_load(unsigned int image_id);
 int arm_bl2_handle_post_image_load(unsigned int image_id);
 struct bl_params *arm_get_next_bl_params(void);
+void arm_bl2_setup_next_ep_info(bl_mem_params_node_t *next_param_node);
 
 /* BL2 at EL3 functions */
 void arm_bl2_el3_early_platform_setup(void);
 void arm_bl2_el3_plat_arch_setup(void);
+#if ARM_FW_CONFIG_LOAD_ENABLE
+void arm_bl2_el3_plat_config_load(void);
+#endif /* ARM_FW_CONFIG_LOAD_ENABLE */
 
 /* BL2U utility functions */
 void arm_bl2u_early_platform_setup(struct meminfo *mem_layout,
@@ -254,12 +273,22 @@ void arm_bl2u_platform_setup(void);
 void arm_bl2u_plat_arch_setup(void);
 
 /* BL31 utility functions */
+#if TRANSFER_LIST
+void arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1,
+				   u_register_t arg2, u_register_t arg3);
+#else
 void arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config,
 				uintptr_t hw_config, void *plat_params_from_bl2);
+#endif
 void arm_bl31_platform_setup(void);
 void arm_bl31_plat_runtime_setup(void);
 void arm_bl31_plat_arch_setup(void);
 
+/* Firmware Handoff utility functions */
+void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl);
+void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,
+					struct transfer_list_header *secure_tl);
+
 /* TSP utility functions */
 void arm_tsp_early_platform_setup(void);
 
@@ -273,11 +302,21 @@ void arm_sp_min_plat_arch_setup(void);
 bool arm_io_is_toc_valid(void);
 
 /* Utility functions for Dynamic Config */
-void arm_bl2_dyn_cfg_init(void);
+
 void arm_bl1_set_mbedtls_heap(void);
 int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
 
+#if IMAGE_BL2
+void arm_bl2_dyn_cfg_init(void);
+#endif /* IMAGE_BL2 */
+
 #if MEASURED_BOOT
+#if DICE_PROTECTION_ENVIRONMENT
+int arm_set_nt_fw_info(int *ctx_handle);
+int arm_set_tb_fw_info(int *ctx_handle);
+int arm_get_tb_fw_info(int *ctx_handle);
+#else
+/* Specific to event log backend */
 int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size);
 int arm_set_nt_fw_info(
 /*
@@ -292,6 +331,7 @@ int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size,
 		       size_t log_max_size);
 int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
 		       size_t *log_max_size);
+#endif /* DICE_PROTECTION_ENVIRONMENT */
 #endif /* MEASURED_BOOT */
 
 /*
@@ -325,6 +365,7 @@ void plat_arm_interconnect_enter_coherency(void);
 void plat_arm_interconnect_exit_coherency(void);
 void plat_arm_program_trusted_mailbox(uintptr_t address);
 bool plat_arm_bl1_fwu_needed(void);
+int plat_arm_ni_setup(uintptr_t global_cfg);
 __dead2 void plat_arm_error_handler(int err);
 __dead2 void plat_arm_system_reset(void);
 
@@ -345,6 +386,8 @@ int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
 unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
 #endif
 
+unsigned int plat_cluster_id_by_mpidr(u_register_t mpidr);
+
 /*
  * This function is called after loading SCP_BL2 image and it is used to perform
  * any platform-specific actions required to handle the SCP firmware.
@@ -362,6 +405,9 @@ int plat_arm_get_alt_image_source(
 unsigned int plat_arm_calc_core_pos(u_register_t mpidr);
 const mmap_region_t *plat_arm_get_mmap(void);
 
+const arm_gpt_info_t *plat_arm_get_gpt_info(void);
+void arm_gpt_setup(void);
+
 /* Allow platform to override psci_pm_ops during runtime */
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops);
 
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index f87f857c..6203937e 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -58,12 +58,12 @@
 	INTR_PROP_DESC(CSS_IRQ_GPU_SMMU_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_TZC, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_LEVEL), \
-	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL)
 
 #define CSS_G1S_IRQ_PROPS(grp) \
 	CSS_G1S_INT_PROPS(grp), \
+	INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL)
 
@@ -75,6 +75,7 @@
  * The SCMI Channel is placed right after the SDS region
  */
 #define CSS_SCMI_PAYLOAD_BASE		(PLAT_ARM_SDS_MEM_BASE + PLAT_ARM_SDS_MEM_SIZE_MAX)
+#define CSS_SCMI_PAYLOAD_SIZE_MAX	0x100 /* 2x128 bytes for bidirectional communication */
 #define CSS_SCMI_MHU_DB_REG_OFF		MHU_CPU_INTR_S_SET_OFFSET
 
 /* Trusted mailbox base address common to all CSS */
diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h
index 1d3ac15f..ecec5bc9 100644
--- a/include/plat/common/common_def.h
+++ b/include/plat/common/common_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,38 @@
 
 #include <platform_def.h>
 
+#ifdef __aarch64__
+#define SZ_32				UL(0x00000020)
+#define SZ_64				UL(0x00000040)
+#define SZ_128				UL(0x00000080)
+#define SZ_256				UL(0x00000100)
+#define SZ_512				UL(0x00000200)
+
+#define SZ_1K				UL(0x00000400)
+#define SZ_2K				UL(0x00000800)
+#define SZ_4K				UL(0x00001000)
+#define SZ_8K				UL(0x00002000)
+#define SZ_16K				UL(0x00004000)
+#define SZ_32K				UL(0x00008000)
+#define SZ_64K				UL(0x00010000)
+#define SZ_128K				UL(0x00020000)
+#define SZ_256K				UL(0x00040000)
+#define SZ_512K				UL(0x00080000)
+
+#define SZ_1M				UL(0x00100000)
+#define SZ_2M				UL(0x00200000)
+#define SZ_4M				UL(0x00400000)
+#define SZ_8M				UL(0x00800000)
+#define SZ_16M				UL(0x01000000)
+#define SZ_32M				UL(0x02000000)
+#define SZ_64M				UL(0x04000000)
+#define SZ_128M				UL(0x08000000)
+#define SZ_256M				UL(0x10000000)
+#define SZ_512M				UL(0x20000000)
+
+#define SZ_1G				UL(0x40000000)
+#define SZ_2G				UL(0x80000000)
+#else /* !__aarch64__ */
 #define SZ_32				U(0x00000020)
 #define SZ_64				U(0x00000040)
 #define SZ_128				U(0x00000080)
@@ -42,6 +74,7 @@
 
 #define SZ_1G				U(0x40000000)
 #define SZ_2G				U(0x80000000)
+#endif /* __aarch64__ */
 
 /******************************************************************************
  * Required platform porting definitions that are expected to be common to
diff --git a/include/plat/common/plat_drtm.h b/include/plat/common/plat_drtm.h
index e96e7195..07545a68 100644
--- a/include/plat/common/plat_drtm.h
+++ b/include/plat/common/plat_drtm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,7 +17,7 @@ typedef struct {
 
 typedef struct {
 	bool tpm_based_hash_support;
-	uint32_t firmware_hash_algorithm;
+	uint16_t firmware_hash_algorithm;
 } plat_drtm_tpm_features_t;
 
 typedef struct {
@@ -26,7 +26,7 @@ typedef struct {
 } __attribute__((packed)) drtm_mem_region_t;
 
 /*
- * Memory region descriptor table structure as per DRTM beta0 section 3.13
+ * Memory region descriptor table structure as per DRTM 1.0 section 3.13
  * Table 11 MEMORY_REGION_DESCRIPTOR_TABLE
  */
 typedef struct {
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 4d1b1c17..118b537e 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,6 +15,7 @@
 #endif
 #if ENABLE_RME
 #include <services/rmm_core_manifest.h>
+#include <services/rmm_el3_token_sign.h>
 #endif
 #include <drivers/fwu/fwu_metadata.h>
 #if TRNG_SUPPORT
@@ -40,6 +41,16 @@ struct sp_res_desc;
 struct rmm_manifest;
 enum fw_enc_status_t;
 
+/*******************************************************************************
+ * Structure populated by platform specific code to export routines which
+ * perform load images functions, and associated pointer to platform ops
+ ******************************************************************************/
+struct plat_try_images_ops {
+	int (*next_instance)(unsigned int image_id);
+};
+
+extern const struct plat_try_images_ops *plat_try_img_ops;
+
 /*******************************************************************************
  * plat_get_rotpk_info() flags
  ******************************************************************************/
@@ -136,6 +147,7 @@ void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
 void plat_ic_set_interrupt_pending(unsigned int id);
 void plat_ic_clear_interrupt_pending(unsigned int id);
 unsigned int plat_ic_set_priority_mask(unsigned int mask);
+unsigned int plat_ic_deactivate_priority(unsigned int mask);
 unsigned int plat_ic_get_interrupt_id(unsigned int raw);
 
 /*******************************************************************************
@@ -153,7 +165,7 @@ void plat_panic_handler(void) __dead2;
 void plat_system_reset(void) __dead2;
 const char *plat_log_get_prefix(unsigned int log_level);
 void bl2_plat_preload_setup(void);
-int plat_try_next_boot_source(void);
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops);
 
 #if MEASURED_BOOT
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data);
@@ -183,6 +195,14 @@ static inline int plat_mboot_measure_key(const void *pk_oid __unused,
 }
 #endif /* MEASURED_BOOT */
 
+#if EARLY_CONSOLE
+void plat_setup_early_console(void);
+#else
+static inline void plat_setup_early_console(void)
+{
+}
+#endif /* EARLY_CONSOLE */
+
 /*******************************************************************************
  * Mandatory BL1 functions
  ******************************************************************************/
@@ -242,6 +262,10 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved);
 int bl1_plat_handle_pre_image_load(unsigned int image_id);
 int bl1_plat_handle_post_image_load(unsigned int image_id);
 
+/* Utility functions */
+void bl1_plat_calc_bl2_layout(const meminfo_t *bl1_mem_layout,
+			      meminfo_t *bl2_mem_layout);
+
 #if MEASURED_BOOT
 void bl1_plat_mboot_init(void);
 void bl1_plat_mboot_finish(void);
@@ -252,7 +276,7 @@ static inline void bl1_plat_mboot_init(void)
 static inline void bl1_plat_mboot_finish(void)
 {
 }
-#endif /* MEASURED_BOOT */
+#endif /* MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT */
 
 /*******************************************************************************
  * Mandatory BL2 functions
@@ -272,7 +296,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id);
 /*******************************************************************************
  * Optional BL2 functions (may be overridden)
  ******************************************************************************/
-#if MEASURED_BOOT
+#if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT)
 void bl2_plat_mboot_init(void);
 void bl2_plat_mboot_finish(void);
 #else
@@ -282,7 +306,7 @@ static inline void bl2_plat_mboot_init(void)
 static inline void bl2_plat_mboot_finish(void)
 {
 }
-#endif /* MEASURED_BOOT */
+#endif /* MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENTs */
 
 /*******************************************************************************
  * Mandatory BL2 at EL3 functions: Must be implemented
@@ -347,10 +371,21 @@ plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
  * Mandatory BL31 functions when ENABLE_RME=1
  ******************************************************************************/
 #if ENABLE_RME
+
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
-				   uintptr_t hash, size_t hash_size);
+				   uintptr_t hash, size_t hash_size,
+				   uint64_t *remaining_len);
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type);
+/* The following 3 functions are to be implement if
+ * RMMD_ENABLE_EL3_TOKEN_SIGN=1.
+ * The following three functions are expected to return E_RMM_* error codes.
+ */
+int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
+					   unsigned int type);
+int plat_rmmd_el3_token_sign_push_req(
+				const struct el3_token_sign_request *req);
+int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp);
 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
 #endif
diff --git a/include/plat/nuvoton/common/npcm845x_arm_def.h b/include/plat/nuvoton/common/npcm845x_arm_def.h
index 5a44907f..df3ad243 100644
--- a/include/plat/nuvoton/common/npcm845x_arm_def.h
+++ b/include/plat/nuvoton/common/npcm845x_arm_def.h
@@ -149,7 +149,16 @@
 			ARM_AP_TZC_DRAM1_SIZE - 1U)
 
 /* Define the Access permissions for Secure peripherals to NS_DRAM */
+#if ARM_CRYPTOCELL_INTEG
+/*
+ * Allow Secure peripheral to read NS DRAM when integrated with CryptoCell.
+ * This is required by CryptoCell to authenticate BL33 which is loaded
+ * into the Non Secure DDR.
+ */
+#define ARM_TZC_NS_DRAM_S_ACCESS	TZC_REGION_S_RD
+#else
 #define ARM_TZC_NS_DRAM_S_ACCESS	TZC_REGION_S_NONE
+#endif /* ARM_CRYPTOCELL_INTEG */
 
 #ifdef SPD_opteed
 /*
@@ -310,7 +319,7 @@
 			BL_RO_DATA_END - BL_RO_DATA_BASE,	\
 			MT_RO_DATA | EL3_PAS)
 #else
-#define ARM_MAP_BL_RO		MAP_REGION_FLAT(	\
+#define ARM_MAP_BL_RO_NOT_USED		MAP_REGION_FLAT(	\
 			BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,	\
 			MT_CODE | EL3_PAS)
 #endif /* SEPARATE_CODE_AND_RODATA */
@@ -474,9 +483,9 @@
 #define NEW_SRAM_ALLOCATION
 
 #ifdef NEW_SRAM_ALLOCATION
-	#define BL31_BASE				0x20001000
+	#define BL31_BASE				0x02000000
 #else
-	#define BL31_BASE				0x20001000
+	#define BL31_BASE				0x02001000
 #endif /* NEW_SRAM_ALLOCATION */
 
 #define BL31_LIMIT			BL2_BASE	/* PLAT_ARM_MAX_BL31_SIZE */
@@ -502,6 +511,7 @@
  * no SPD and no SPM-MM, as they are the only ones that can be used as BL32.
  */
 #if defined(SPD_none) && !SPM_MM
+#error BL32_BASE is not defined
 #undef BL32_BASE
 #endif /* SPD_none && !SPM_MM */
 
diff --git a/include/plat/nuvoton/common/plat_macros.S b/include/plat/nuvoton/common/plat_macros.S
index 08f9feb7..549db395 100644
--- a/include/plat/nuvoton/common/plat_macros.S
+++ b/include/plat/nuvoton/common/plat_macros.S
@@ -41,7 +41,8 @@ arm_print_gic_regs
  * BL31.
  */
 .macro plat_crash_print_regs
-	/* TODO */
+plat_print_gic_regs
+/*print_cci_regs*/
 .endm
 
 #endif /* PLAT_MACROS_S */
diff --git a/include/plat/nuvoton/npcm845x/platform_def.h b/include/plat/nuvoton/npcm845x/platform_def.h
index 09da36ba..c70ef22f 100644
--- a/include/plat/nuvoton/npcm845x/platform_def.h
+++ b/include/plat/nuvoton/npcm845x/platform_def.h
@@ -132,11 +132,6 @@
  */
 #define PLAT_ARM_NS_IMAGE_BASE (ARM_DRAM1_BASE + UL(0x6208000))
 
-#ifdef NPCM845X_DEBUG
-#define COUNTER_FREQUENCY 0x07735940 /* f/4 = 125MHz */
-#endif /* NPCM845X_DEBUG */
-
-#define COUNTER_FREQUENCY 0x0EE6B280 /* f/2 = 250MHz */
 #define PLAT_ARM_NSTIMER_FRAME_ID U(1)
 
 /* GIC parameters */
@@ -162,7 +157,8 @@
 
 /* MMU entry for internal (register) space access */
 #define MAP_DEVICE0                                                            \
-	MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE, MT_DEVICE | MT_RW | MT_NS)
+	MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE,                         \
+			MT_DEVICE | MT_RW | MT_SECURE)
 
 #define MAP_DEVICE1                                                            \
 	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE,                            \
diff --git a/include/services/drtm_svc.h b/include/services/drtm_svc.h
index 69b314f0..f0d3c63b 100644
--- a/include/services/drtm_svc.h
+++ b/include/services/drtm_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -54,10 +54,10 @@
 	(((_fid) >= ARM_DRTM_SVC_VERSION) && ((_fid) <= ARM_DRTM_SVC_LOCK_TCB_HASH))
 
 /* ARM DRTM Service Calls version numbers */
-#define ARM_DRTM_VERSION_MAJOR		U(0)
+#define ARM_DRTM_VERSION_MAJOR		U(1)
 #define ARM_DRTM_VERSION_MAJOR_SHIFT	16
 #define ARM_DRTM_VERSION_MAJOR_MASK	U(0x7FFF)
-#define ARM_DRTM_VERSION_MINOR		U(1)
+#define ARM_DRTM_VERSION_MINOR		U(0)
 #define ARM_DRTM_VERSION_MINOR_SHIFT	0
 #define ARM_DRTM_VERSION_MINOR_MASK	U(0xFFFF)
 
@@ -74,7 +74,7 @@
 #define ARM_DRTM_FEAT_ID_MASK	ULL(0xff)
 
 /*
- * Definitions for DRTM features as per DRTM beta0 section 3.3,
+ * Definitions for DRTM features as per DRTM 1.0 section 3.3,
  * Table 6 DRTM_FEATURES
  */
 #define ARM_DRTM_TPM_FEATURES_PCR_SCHEMA_SHIFT		U(33)
@@ -87,7 +87,7 @@
 #define ARM_DRTM_TPM_FEATURES_TPM_HASH_SUPPORTED	ULL(0x1)
 
 #define ARM_DRTM_TPM_FEATURES_FW_HASH_SHIFT		U(0)
-#define ARM_DRTM_TPM_FEATURES_FW_HASH_MASK		ULL(0xFFFFFFFF)
+#define ARM_DRTM_TPM_FEATURES_FW_HASH_MASK		ULL(0xFFFF)
 #define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA256		ULL(0xB)
 #define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA384		ULL(0xC)
 #define ARM_DRTM_TPM_FEATURES_FW_HASH_SHA512		ULL(0xD)
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index de56638c..01dbea97 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,7 @@
 
 /* The macros below are used to identify FFA calls from the SMC function ID */
 #define FFA_FNUM_MIN_VALUE	U(0x60)
-#define FFA_FNUM_MAX_VALUE	U(0x8C)
+#define FFA_FNUM_MAX_VALUE	U(0x8E)
 #define is_ffa_fid(fid) __extension__ ({		\
 	__typeof__(fid) _fid = (fid);			\
 	((GET_SMC_NUM(_fid) >= FFA_FNUM_MIN_VALUE) &&	\
@@ -34,7 +34,7 @@
 #define FFA_VERSION_MAJOR		U(1)
 #define FFA_VERSION_MAJOR_SHIFT		16
 #define FFA_VERSION_MAJOR_MASK		U(0x7FFF)
-#define FFA_VERSION_MINOR		U(1)
+#define FFA_VERSION_MINOR		U(2)
 #define FFA_VERSION_MINOR_SHIFT		0
 #define FFA_VERSION_MINOR_MASK		U(0xFFFF)
 #define FFA_VERSION_BIT31_MASK 		U(0x1u << 31)
@@ -117,8 +117,16 @@
 #define FFA_FNUM_SPM_ID_GET			U(0x85)
 #define FFA_FNUM_MSG_SEND2			U(0x86)
 #define FFA_FNUM_SECONDARY_EP_REGISTER		U(0x87)
+#define FFA_FNUM_MEM_PERM_GET			U(0x88)
+#define FFA_FNUM_MEM_PERM_SET			U(0x89)
+
+/* FF-A v1.2 */
 #define FFA_FNUM_PARTITION_INFO_GET_REGS	U(0x8B)
 #define FFA_FNUM_EL3_INTR_HANDLE		U(0x8C)
+#define FFA_FNUM_MSG_SEND_DIRECT_REQ2		U(0x8D)
+#define FFA_FNUM_MSG_SEND_DIRECT_RESP2		U(0x8E)
+
+#define FFA_FNUM_CONSOLE_LOG			U(0x8A)
 
 /* FFA SMC32 FIDs */
 #define FFA_ERROR		FFA_FID(SMC_32, FFA_FNUM_ERROR)
@@ -165,6 +173,9 @@
 #define FFA_SPM_ID_GET		FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET)
 #define FFA_NORMAL_WORLD_RESUME	FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME)
 #define FFA_EL3_INTR_HANDLE	FFA_FID(SMC_32, FFA_FNUM_EL3_INTR_HANDLE)
+#define FFA_MEM_PERM_GET	FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_GET)
+#define FFA_MEM_PERM_SET	FFA_FID(SMC_32, FFA_FNUM_MEM_PERM_SET)
+#define FFA_CONSOLE_LOG_SMC32 FFA_FID(SMC_32, FFA_FNUM_CONSOLE_LOG)
 
 /* FFA SMC64 FIDs */
 #define FFA_ERROR_SMC64		FFA_FID(SMC_64, FFA_FNUM_ERROR)
@@ -185,6 +196,11 @@
 	FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET)
 #define FFA_PARTITION_INFO_GET_REGS_SMC64 \
 	FFA_FID(SMC_64, FFA_FNUM_PARTITION_INFO_GET_REGS)
+#define FFA_CONSOLE_LOG_SMC64 FFA_FID(SMC_64, FFA_FNUM_CONSOLE_LOG)
+#define FFA_MSG_SEND_DIRECT_REQ2_SMC64 \
+	FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_REQ2)
+#define FFA_MSG_SEND_DIRECT_RESP2_SMC64	\
+	FFA_FID(SMC_64, FFA_FNUM_MSG_SEND_DIRECT_RESP2)
 
 /*
  * FF-A partition properties values.
diff --git a/include/services/oem/chromeos/widevine_smc_handlers.h b/include/services/oem/chromeos/widevine_smc_handlers.h
new file mode 100644
index 00000000..a5251d76
--- /dev/null
+++ b/include/services/oem/chromeos/widevine_smc_handlers.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2024, The ChromiumOS Authors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CROS_WIDEVINE_SMC_HANDLERS_H
+#define CROS_WIDEVINE_SMC_HANDLERS_H
+
+#include <lib/smccc.h>
+
+/*******************************************************************************
+ * Defines for CrOS OEM Service queries
+ ******************************************************************************/
+
+/* 0xC300C050 - 0xC300C05F are CrOS OEM service calls */
+#define CROS_OEM_SMC_ID 0xC050
+#define CROS_OEM_SMC_CALL_ID(func_num)                                         \
+	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) |                                \
+	 ((SMC_64) << FUNCID_CC_SHIFT) | (OEN_OEM_START << FUNCID_OEN_SHIFT) | \
+	 (CROS_OEM_SMC_ID) | ((func_num) & FUNCID_NUM_MASK))
+
+enum cros_drm_set {
+	CROS_DRM_SET_TPM_AUTH_PUB = 0U,
+	CROS_DRM_SET_HARDWARE_UNIQUE_KEY = 1U,
+	CROS_DRM_SET_ROOT_OF_TRUST = 2U,
+};
+
+/*******************************************************************************
+ * Defines for runtime services func ids
+ ******************************************************************************/
+
+/* Sets the TPM auth public key. The maximum size is 128 bytes.
+ * |x1| is the length of the data, |x2| is the physical address of the data.
+ */
+#define CROS_OEM_SMC_DRM_SET_TPM_AUTH_PUB_FUNC_ID \
+	CROS_OEM_SMC_CALL_ID(CROS_DRM_SET_TPM_AUTH_PUB)
+
+/* Sets the hardware unique key. The maximum size is 32 bytes.
+ * |x1| is the length of the data, |x2| is the physical address of the data.
+ */
+#define CROS_OEM_SMC_DRM_SET_HARDWARE_UNIQUE_KEY_FUNC_ID \
+	CROS_OEM_SMC_CALL_ID(CROS_DRM_SET_HARDWARE_UNIQUE_KEY)
+
+/* Sets the widevine root of trust. The maximum size is 32 bytes.
+ * |x1| is the length of the data, |x2| is the physical address of the data.
+ */
+#define CROS_OEM_SMC_DRM_SET_ROOT_OF_TRUST_FUNC_ID \
+	CROS_OEM_SMC_CALL_ID(CROS_DRM_SET_ROOT_OF_TRUST)
+
+#define is_cros_oem_smc(_call_id) (((_call_id) & 0xFFF0U) == CROS_OEM_SMC_ID)
+
+struct cros_oem_data {
+	uint8_t *buffer;
+	const uint32_t max_length;
+	uint32_t length;
+};
+
+extern struct cros_oem_data cros_oem_tpm_auth_pk;
+
+extern struct cros_oem_data cros_oem_huk;
+
+extern struct cros_oem_data cros_oem_rot;
+
+#endif /* CROS_WIDEVINE_SMC_HANDLERS_H */
diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h
index b89de9f2..6b57267d 100644
--- a/include/services/rmm_core_manifest.h
+++ b/include/services/rmm_core_manifest.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,9 @@
 #include <lib/cassert.h>
 
 #define RMMD_MANIFEST_VERSION_MAJOR		U(0)
-#define RMMD_MANIFEST_VERSION_MINOR		U(2)
+#define RMMD_MANIFEST_VERSION_MINOR		U(3)
+
+#define RMM_CONSOLE_MAX_NAME_LEN		U(8)
 
 /*
  * Manifest version encoding:
@@ -60,12 +62,49 @@ CASSERT(offsetof(struct ns_dram_info, banks) == 8UL,
 CASSERT(offsetof(struct ns_dram_info, checksum) == 16UL,
 			rmm_manifest_checksum_unaligned);
 
-/* Boot manifest core structure as per v0.2 */
+/* Console info structure */
+struct console_info {
+	uintptr_t base;			/* Console base address */
+	uint64_t map_pages;		/* Num of pages to be mapped in RMM for the console MMIO */
+	char name[RMM_CONSOLE_MAX_NAME_LEN];	/* Name of console */
+	uint64_t clk_in_hz;		/* UART clock (in Hz) for the console */
+	uint64_t baud_rate;		/* Baud rate */
+	uint64_t flags;			/* Additional flags RES0 */
+};
+
+CASSERT(offsetof(struct console_info, base) == 0UL,
+			rmm_manifest_console_base_unaligned);
+CASSERT(offsetof(struct console_info, map_pages) == 8UL,
+			rmm_manifest_console_map_pages_unaligned);
+CASSERT(offsetof(struct console_info, name) == 16UL,
+			rmm_manifest_console_name_unaligned);
+CASSERT(offsetof(struct console_info, clk_in_hz) == 24UL,
+			rmm_manifest_console_clk_in_hz_unaligned);
+CASSERT(offsetof(struct console_info, baud_rate) == 32UL,
+			rmm_manifest_console_baud_rate_unaligned);
+CASSERT(offsetof(struct console_info, flags) == 40UL,
+			rmm_manifest_console_flags_unaligned);
+
+struct console_list {
+	uint64_t num_consoles;		/* Number of consoles */
+	struct console_info *consoles;	/* Pointer to console_info[] */
+	uint64_t checksum;		/* Checksum of console_list data */
+};
+
+CASSERT(offsetof(struct console_list, num_consoles) == 0UL,
+			rmm_manifest_num_consoles);
+CASSERT(offsetof(struct console_list, consoles) == 8UL,
+			rmm_manifest_consoles);
+CASSERT(offsetof(struct console_list, checksum) == 16UL,
+			rmm_manifest_console_list_checksum);
+
+/* Boot manifest core structure as per v0.3 */
 struct rmm_manifest {
-	uint32_t version;		/* Manifest version */
-	uint32_t padding;		/* RES0 */
-	uintptr_t plat_data;		/* Manifest platform data */
-	struct ns_dram_info plat_dram;	/* Platform NS DRAM data */
+	uint32_t version;			/* Manifest version */
+	uint32_t padding;			/* RES0 */
+	uintptr_t plat_data;			/* Manifest platform data */
+	struct ns_dram_info plat_dram;		/* Platform NS DRAM data (v0.2) */
+	struct console_list plat_console;	/* Platform console list (v0.3) */
 };
 
 CASSERT(offsetof(struct rmm_manifest, version) == 0UL,
@@ -74,5 +113,7 @@ CASSERT(offsetof(struct rmm_manifest, plat_data) == 8UL,
 			rmm_manifest_plat_data_unaligned);
 CASSERT(offsetof(struct rmm_manifest, plat_dram) == 16UL,
 			rmm_manifest_plat_dram_unaligned);
+CASSERT(offsetof(struct rmm_manifest, plat_console) == 40UL,
+			rmm_manifest_plat_console_unaligned);
 
 #endif /* RMM_CORE_MANIFEST_H */
diff --git a/include/services/rmm_el3_token_sign.h b/include/services/rmm_el3_token_sign.h
new file mode 100644
index 00000000..154940c4
--- /dev/null
+++ b/include/services/rmm_el3_token_sign.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RMM_EL3_TOKEN_SIGN_H
+#define RMM_EL3_TOKEN_SIGN_H
+
+#include <stdint.h>
+#include <lib/cassert.h>
+#include <services/rmmd_svc.h>
+
+/*
+ * Defines member of structure and reserves space
+ * for the next member with specified offset.
+ */
+/* cppcheck-suppress [misra-c2012-20.7] */
+#define SET_MEMBER(member, start, end)	\
+	union {				\
+		member;			\
+		unsigned char reserved##end[((end) - (start))];	\
+	}
+
+#define EL3_TOKEN_RESPONSE_MAX_SIG_LEN U(512)
+
+struct el3_token_sign_request {
+	SET_MEMBER(uint32_t sig_alg_id, 0x0, 0x8);
+	SET_MEMBER(uint64_t rec_granule, 0x8, 0x10);
+	SET_MEMBER(uint64_t req_ticket, 0x10, 0x18);
+	SET_MEMBER(uint32_t hash_alg_id, 0x18, 0x20);
+	SET_MEMBER(uint8_t hash_buf[SHA512_DIGEST_SIZE], 0x20, 0x60);
+};
+
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, sig_alg_id) == 0x0U,
+	assert_el3_token_sign_request_sig_alg_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, rec_granule) == 0x8U,
+	assert_el3_token_sign_request_rec_granule_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, req_ticket) == 0x10U,
+	assert_el3_token_sign_request_req_ticket_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_alg_id) == 0x18U,
+	assert_el3_token_sign_request_hash_alg_id_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_buf) == 0x20U,
+	assert_el3_token_sign_request_hash_buf_mismatch);
+
+
+struct el3_token_sign_response {
+	SET_MEMBER(uint64_t rec_granule, 0x0, 0x8);
+	SET_MEMBER(uint64_t req_ticket, 0x8, 0x10);
+	SET_MEMBER(uint16_t sig_len, 0x10, 0x12);
+	SET_MEMBER(uint8_t signature_buf[EL3_TOKEN_RESPONSE_MAX_SIG_LEN], 0x12, 0x212);
+};
+
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, rec_granule) == 0x0U,
+	assert_el3_token_sign_resp_rec_granule_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, req_ticket) == 0x8U,
+	assert_el3_token_sign_resp_req_ticket_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, sig_len) == 0x10U,
+	assert_el3_token_sign_resp_sig_len_mismatch);
+CASSERT(__builtin_offsetof(struct el3_token_sign_response, signature_buf) == 0x12U,
+	assert_el3_token_sign_resp_sig_buf_mismatch);
+
+#endif /* RMM_EL3_TOKEN_SIGN_H */
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index a567d285..0cc8628a 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #ifndef RMMD_SVC_H
 #define RMMD_SVC_H
 
+#include <common/sha_common_macros.h>
 #include <lib/smccc.h>
 #include <lib/utils_def.h>
 
@@ -90,16 +91,12 @@
 #define E_RMM_BAD_PAS			-3
 #define E_RMM_NOMEM			-4
 #define E_RMM_INVAL			-5
+#define E_RMM_AGAIN			-6
 
 /* Return error codes from RMI SMCs */
 #define RMI_SUCCESS			0
 #define RMI_ERROR_INPUT			1
 
-/* Acceptable SHA sizes for Challenge object */
-#define SHA256_DIGEST_SIZE	32U
-#define SHA384_DIGEST_SIZE	48U
-#define SHA512_DIGEST_SIZE	64U
-
 /*
  * Retrieve Realm attestation key from EL3. Only P-384 ECC curve key is
  * supported. The arguments to this SMC are :
@@ -132,8 +129,43 @@
 					/* 0x1B3 */
 #define RMM_ATTEST_GET_PLAT_TOKEN	SMC64_RMMD_EL3_FID(U(3))
 
+/* Starting RMM-EL3 interface version 0.4 */
+#define RMM_EL3_FEATURES				SMC64_RMMD_EL3_FID(U(4))
+#define RMM_EL3_FEAT_REG_0_IDX				U(0)
+/* Bit 0 of FEAT_REG_0 */
+/* 1 - the feature is present in EL3 , 0 - the feature is absent */
+#define RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK		U(0x1)
+
+/*
+ * Function codes to support attestation where EL3 is used to sign
+ * realm attestation tokens. In this model, the private key is not
+ * exposed to the RMM.
+ * The arguments to this SMC are:
+ *     arg0 - Function ID.
+ *     arg1 - Opcode, one of:
+ *               RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP,
+ *               RMM_EL3_TOKEN_SIGN_PULL_RESP_OP,
+ *               RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ *     arg2 - Pointer to buffer with request/response structures,
+ *            which is in the RMM<->EL3 shared buffer.
+ *     arg3 - Buffer size of memory pointed by arg2.
+ *     arg4 - ECC Curve, when opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ * The return arguments are:
+ *     ret0 - Status/Error
+ *     ret1 - Size of public key if opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
+ */
+#define RMM_EL3_TOKEN_SIGN			SMC64_RMMD_EL3_FID(U(5))
+
+/* Opcodes for RMM_EL3_TOKEN_SIGN  */
+#define RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP          U(1)
+#define RMM_EL3_TOKEN_SIGN_PULL_RESP_OP         U(2)
+#define RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP       U(3)
+
 /* ECC Curve types for attest key generation */
-#define ATTEST_KEY_CURVE_ECC_SECP384R1		0
+#define ATTEST_KEY_CURVE_ECC_SECP384R1		U(0)
+
+/* Identifier for the hash algorithm used for attestation signing */
+#define EL3_TOKEN_SIGN_HASH_ALG_SHA384		U(1)
 
 /*
  * RMM_BOOT_COMPLETE originates on RMM when the boot finishes (either cold
@@ -156,7 +188,7 @@
  * Increase this when a bug is fixed, or a feature is added without
  * breaking compatibility.
  */
-#define RMM_EL3_IFC_VERSION_MINOR	(U(2))
+#define RMM_EL3_IFC_VERSION_MINOR	(U(4))
 
 #define RMM_EL3_INTERFACE_VERSION				\
 	(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) |	\
diff --git a/include/services/spmd_svc.h b/include/services/spmd_svc.h
index 29dfdad3..95f07075 100644
--- a/include/services/spmd_svc.h
+++ b/include/services/spmd_svc.h
@@ -34,7 +34,8 @@ uint64_t spmd_smc_switch_state(uint32_t smc_fid,
 			       uint64_t x2,
 			       uint64_t x3,
 			       uint64_t x4,
-			       void *handle);
+			       void *handle,
+			       uint64_t flags);
 #endif /* __ASSEMBLER__ */
 
 #endif /* SPMD_SVC_H */
diff --git a/include/services/ven_el3_svc.h b/include/services/ven_el3_svc.h
new file mode 100644
index 00000000..e030b68c
--- /dev/null
+++ b/include/services/ven_el3_svc.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef VEN_EL3_SVC_H
+#define VEN_EL3_SVC_H
+
+/*
+ * Function Identifier value ranges for Vendor-Specific
+ * EL3 Monitor Service Calls.
+ */
+/* VEN_EL3_SMC_32		0x87000000U */
+/* VEN_EL3_SMC_64		0xC7000000U */
+
+
+/* Function Identifier values of general queries */
+#define VEN_EL3_SVC_UID		0x8700ff01
+/*				0x8700ff02 is reserved */
+#define VEN_EL3_SVC_VERSION	0x8700ff03
+
+#define VEN_EL3_SVC_VERSION_MAJOR	1
+#define VEN_EL3_SVC_VERSION_MINOR	0
+
+/* DEBUGFS_SMC_32		0x87000010U */
+/* DEBUGFS_SMC_64		0xC7000010U */
+
+/* PMF_SMC_GET_TIMESTAMP_32	0x87000020U */
+/* PMF_SMC_GET_TIMESTAMP_64	0xC7000020U */
+
+#endif /* VEN_EL3_SVC_H */
diff --git a/include/tools_share/cca_oid.h b/include/tools_share/cca_oid.h
index 8c53ef95..6f89c169 100644
--- a/include/tools_share/cca_oid.h
+++ b/include/tools_share/cca_oid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,15 +30,17 @@
 
 /*
  * First undef previous definitions from tbbr_oid.h.
- * CCA ROTPK authenticates BL31 and its configuration image in
+ * CCA ROTPK authenticates BL31, SCP_BL2 and its configuration image in
  * CCA CoT.
  **/
 #undef BL31_IMAGE_KEY_OID
 #undef SOC_FW_CONFIG_KEY_OID
 #undef HW_CONFIG_KEY_OID
+#undef SCP_BL2_IMAGE_KEY_OID
 #define BL31_IMAGE_KEY_OID			ZERO_OID
 #define SOC_FW_CONFIG_KEY_OID			ZERO_OID
 #define HW_CONFIG_KEY_OID			ZERO_OID
+#define SCP_BL2_IMAGE_KEY_OID			ZERO_OID
 #define RMM_IMAGE_KEY_OID			ZERO_OID
 
 #endif /* CCA_OID_H */
diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h
index 9881d1a1..1a2e3553 100644
--- a/include/tools_share/tbbr_oid.h
+++ b/include/tools_share/tbbr_oid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -170,6 +170,12 @@
 #define SOC_FW_CONFIG_KEY_OID			SOC_FW_CONTENT_CERT_PK_OID
 #define HW_CONFIG_KEY_OID			ZERO_OID
 
+#define SCP_BL2_IMAGE_KEY_OID			SCP_FW_CONTENT_CERT_PK_OID
+#define BL32_IMAGE_KEY_OID			TRUSTED_OS_FW_CONTENT_CERT_PK_OID
+#define TOS_FW_CONFIG_KEY_OID			TRUSTED_OS_FW_CONTENT_CERT_PK_OID
+#define BL33_IMAGE_KEY_OID			NON_TRUSTED_FW_CONTENT_CERT_PK_OID
+#define NT_FW_CONFIG_KEY_OID			NON_TRUSTED_FW_CONTENT_CERT_PK_OID
+
 #ifdef PLAT_DEF_OID
 #include <platform_oid.h>
 #endif
diff --git a/lib/aarch64/cache_helpers.S b/lib/aarch64/cache_helpers.S
index 314ed6ef..ff9a4e6b 100644
--- a/lib/aarch64/cache_helpers.S
+++ b/lib/aarch64/cache_helpers.S
@@ -9,6 +9,7 @@
 
 	.globl	flush_dcache_range
 	.globl	flush_dcache_to_popa_range
+	.globl	flush_dcache_to_popa_range_mte2
 	.globl	clean_dcache_range
 	.globl	inv_dcache_range
 	.globl	dcsw_op_louis
@@ -17,6 +18,20 @@
 	.globl	dcsw_op_level2
 	.globl	dcsw_op_level3
 
+/* Opcodes for data cache maintenance by PA instructions. */
+
+/*
+ * sys  #6, c7, c14, #1, x0
+ * DC CIPAPA, X0
+ */
+#define dc_cipapa_x0	0xd50e7e20
+
+/*
+ * sys #6, c7, c14, #3, x0
+ * DC CIDGPAPA, X0
+  */
+#define dc_cigdpapa_x0	0xd50e7ea0
+
 /*
  * This macro can be used for implementing various data cache operations `op`
  */
@@ -37,6 +52,24 @@ exit_loop_\op:
 	ret
 .endm
 
+/* op: the hexadecimal instruction opcode for the cache operation */
+.macro do_dcache_maintenance_instr op
+	/* Exit early if size is zero */
+	cbz	x1, exit_loop_\op
+	dcache_line_size x2, x3
+	sub	x3, x2, #1
+	bic	x0, x0, x3
+	add	x1, x1, x0
+loop_\op:
+	.inst	\op
+	add	x0, x0, x2
+	cmp	x0, x1
+	b.lo	loop_\op
+	dsb	osh
+exit_loop_\op:
+	ret
+.endm
+
 .macro check_plat_can_cmo
 #if CONDITIONAL_CMO
 	mov	x3, x30
@@ -49,10 +82,11 @@ exit_loop_\op:
 	mov	 x0, x2
 #endif
 .endm
-	/* ------------------------------------------
-	 * Clean+Invalidate from base address till
-	 * size. 'x0' = addr, 'x1' = size
-	 * ------------------------------------------
+
+	/* -------------------------------------------
+	 * DCache Clean+Invalidate by MVA from base
+	 * address till size. 'x0' = addr, 'x1' = size
+	 * -------------------------------------------
 	 */
 func flush_dcache_range
 	check_plat_can_cmo
@@ -60,8 +94,8 @@ func flush_dcache_range
 endfunc flush_dcache_range
 
 	/* ------------------------------------------
-	 * Clean from base address till size.
-	 * 'x0' = addr, 'x1' = size
+	 * DCache Clean by MVA from base address till
+	 * size. 'x0' = addr, 'x1' = size
 	 * ------------------------------------------
 	 */
 func clean_dcache_range
@@ -70,8 +104,8 @@ func clean_dcache_range
 endfunc clean_dcache_range
 
 	/* ------------------------------------------
-	 * Invalidate from base address till
-	 * size. 'x0' = addr, 'x1' = size
+	 * DCache Invalidate by MVA from base address
+	 * till size. 'x0' = addr, 'x1' = size
 	 * ------------------------------------------
 	 */
 func inv_dcache_range
@@ -79,37 +113,36 @@ func inv_dcache_range
 	do_dcache_maintenance_by_mva ivac
 endfunc inv_dcache_range
 
-
 	/*
-	 * On implementations with FEAT_MTE2,
-	 * Root firmware must issue DC_CIGDPAPA instead of DC_CIPAPA ,
-	 * in order to additionally clean and invalidate Allocation Tags
-	 * associated with the affected locations.
-	 *
 	 * ------------------------------------------
-	 * Clean+Invalidate by PA to POPA
-	 * from base address till size.
+	 * DCache Clean+Invalidate by PA to POPA from
+	 * base address till size.
 	 * 'x0' = addr, 'x1' = size
 	 * ------------------------------------------
 	 */
 func flush_dcache_to_popa_range
-	/* Exit early if size is zero */
-	cbz	x1, exit_loop_dc_cipapa
 	check_plat_can_cmo
-	dcache_line_size x2, x3
-	sub	x3, x2, #1
-	bic	x0, x0, x3
-	add	x1, x1, x0
-loop_dc_cipapa:
-	sys	#6, c7, c14, #1, x0 /* DC CIPAPA,<Xt> */
-	add	x0, x0, x2
-	cmp	x0, x1
-	b.lo	loop_dc_cipapa
-	dsb	osh
-exit_loop_dc_cipapa:
-	ret
+	/* dc cipapa, x0 */
+	do_dcache_maintenance_instr dc_cipapa_x0
 endfunc	flush_dcache_to_popa_range
 
+	/*
+	 * ------------------------------------------
+	 * Clean+Invalidate by PA to POPA (MTE2)
+	 * from base address till size.
+	 * 'x0' = addr, 'x1' = size
+	 * ------------------------------------------
+	 * On implementations with FEAT_MTE2, Root firmware must issue
+	 * DC_CIGDPAPA instead of DC_CIPAPA, in order to additionally
+	 * clean and invalidate Allocation Tags associated with the
+	 * affected locations.
+	 */
+func flush_dcache_to_popa_range_mte2
+	check_plat_can_cmo
+	/* dc cigdpapa, x0 */
+	do_dcache_maintenance_instr dc_cigdpapa_x0
+endfunc	flush_dcache_to_popa_range_mte2
+
 	/* ---------------------------------------------------------------
 	 * Data cache operations by set/way to the level specified
 	 *
diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S
index f9c4bafd..93771df3 100644
--- a/lib/aarch64/misc_helpers.S
+++ b/lib/aarch64/misc_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,7 +15,6 @@
 	.globl	zero_normalmem
 	.globl	zeromem
 	.globl	memcpy16
-	.globl	gpt_tlbi_by_pa_ll
 
 	.globl	disable_mmu_el1
 	.globl	disable_mmu_el3
@@ -594,20 +593,3 @@ func fixup_gdt_reloc
 	b.lo	1b
 	ret
 endfunc fixup_gdt_reloc
-
-/*
- * TODO: Currently only supports size of 4KB,
- * support other sizes as well.
- */
-func gpt_tlbi_by_pa_ll
-#if ENABLE_ASSERTIONS
-	cmp	x1, #PAGE_SIZE_4KB
-	ASM_ASSERT(eq)
-	tst	x0, #(PAGE_SIZE_MASK)
-	ASM_ASSERT(eq)
-#endif
-	lsr	x0, x0, #FOUR_KB_SHIFT	/* 4KB size encoding is zero */
-	sys	#6, c8, c4, #7, x0 	/* TLBI RPALOS, <Xt> */
-	dsb	sy
-	ret
-endfunc gpt_tlbi_by_pa_ll
diff --git a/lib/compiler-rt/builtins/assembly.h b/lib/compiler-rt/builtins/assembly.h
index 169d4968..8c42fc77 100644
--- a/lib/compiler-rt/builtins/assembly.h
+++ b/lib/compiler-rt/builtins/assembly.h
@@ -260,9 +260,10 @@
   .globl name SEPARATOR                                                        \
   SYMBOL_IS_FUNC(name) SEPARATOR                                               \
   DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) SEPARATOR                          \
-  CFI_START SEPARATOR                                                          \
   DECLARE_FUNC_ENCODING                                                        \
-  name: SEPARATOR BTI_C
+  name:                                                                        \
+  SEPARATOR CFI_START                                                          \
+  SEPARATOR BTI_C
 
 #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target)                         \
   .globl SYMBOL_NAME(name) SEPARATOR                                           \
diff --git a/lib/compiler-rt/builtins/int_lib.h b/lib/compiler-rt/builtins/int_lib.h
index 04ea2d91..f6c1b7cf 100644
--- a/lib/compiler-rt/builtins/int_lib.h
+++ b/lib/compiler-rt/builtins/int_lib.h
@@ -119,14 +119,14 @@ COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem);
 #if defined(_MSC_VER) && !defined(__clang__)
 #include <intrin.h>
 
-int __inline __builtin_ctz(uint32_t value) {
+static int __inline __builtin_ctz(uint32_t value) {
   unsigned long trailing_zero = 0;
   if (_BitScanForward(&trailing_zero, value))
     return trailing_zero;
   return 32;
 }
 
-int __inline __builtin_clz(uint32_t value) {
+static int __inline __builtin_clz(uint32_t value) {
   unsigned long leading_zero = 0;
   if (_BitScanReverse(&leading_zero, value))
     return 31 - leading_zero;
@@ -134,14 +134,14 @@ int __inline __builtin_clz(uint32_t value) {
 }
 
 #if defined(_M_ARM) || defined(_M_X64)
-int __inline __builtin_clzll(uint64_t value) {
+static int __inline __builtin_clzll(uint64_t value) {
   unsigned long leading_zero = 0;
   if (_BitScanReverse64(&leading_zero, value))
     return 63 - leading_zero;
   return 64;
 }
 #else
-int __inline __builtin_clzll(uint64_t value) {
+static int __inline __builtin_clzll(uint64_t value) {
   if (value == 0)
     return 64;
   uint32_t msh = (uint32_t)(value >> 32);
@@ -154,7 +154,7 @@ int __inline __builtin_clzll(uint64_t value) {
 
 #define __builtin_clzl __builtin_clzll
 
-bool __inline __builtin_sadd_overflow(int x, int y, int *result) {
+static bool __inline __builtin_sadd_overflow(int x, int y, int *result) {
   if ((x < 0) != (y < 0)) {
     *result = x + y;
     return false;
diff --git a/lib/compiler-rt/builtins/int_types.h b/lib/compiler-rt/builtins/int_types.h
index 18bf0a7f..48862f36 100644
--- a/lib/compiler-rt/builtins/int_types.h
+++ b/lib/compiler-rt/builtins/int_types.h
@@ -107,8 +107,8 @@ typedef union {
 
 static __inline ti_int make_ti(di_int h, di_int l) {
   twords r;
-  r.s.high = h;
-  r.s.low = l;
+  r.s.high = (du_int)h;
+  r.s.low = (du_int)l;
   return r.all;
 }
 
@@ -139,7 +139,6 @@ typedef union {
   udwords u;
   double f;
 } double_bits;
-#endif
 
 typedef struct {
 #if _YUGA_LITTLE_ENDIAN
@@ -190,12 +189,16 @@ typedef long double tf_float;
 #define CRT_LDBL_IEEE_F128
 #endif
 #define TF_C(x) x##L
-#elif __LDBL_MANT_DIG__ == 113
-// Use long double instead of __float128 if it matches the IEEE 128-bit format.
+#elif __LDBL_MANT_DIG__ == 113 ||                                              \
+    (__FLT_RADIX__ == 16 && __LDBL_MANT_DIG__ == 28)
+// Use long double instead of __float128 if it matches the IEEE 128-bit format
+// or the IBM hexadecimal format.
 #define CRT_LDBL_128BIT
 #define CRT_HAS_F128
+#if __LDBL_MANT_DIG__ == 113
 #define CRT_HAS_IEEE_TF
 #define CRT_LDBL_IEEE_F128
+#endif
 typedef long double tf_float;
 #define TF_C(x) x##L
 #elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
@@ -220,7 +223,6 @@ typedef union {
 #define CRT_HAS_TF_MODE
 #endif
 
-#if CRT_HAS_FLOATING_POINT
 #if __STDC_VERSION__ >= 199901L
 typedef float _Complex Fcomplex;
 typedef double _Complex Dcomplex;
@@ -270,5 +272,5 @@ typedef struct {
 #define COMPLEXTF_IMAGINARY(x) (x).imaginary
 #endif
 
-#endif
+#endif // CRT_HAS_FLOATING_POINT
 #endif // INT_TYPES_H
diff --git a/lib/cpus/aarch32/aem_generic.S b/lib/cpus/aarch32/aem_generic.S
index 9f45e387..f4dc0d17 100644
--- a/lib/cpus/aarch32/aem_generic.S
+++ b/lib/cpus/aarch32/aem_generic.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,14 +40,6 @@ func aem_generic_cluster_pwr_dwn
 	b	dcsw_op_all
 endfunc aem_generic_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for AEM. Must follow AAPCS.
- */
-func aem_generic_errata_report
-	bx	lr
-endfunc aem_generic_errata_report
-#endif
 
 /* cpu_ops for Base AEM FVP */
 declare_cpu_ops aem_generic, BASE_AEM_MIDR, CPU_NO_RESET_FUNC, \
diff --git a/lib/cpus/aarch32/cortex_a12.S b/lib/cpus/aarch32/cortex_a12.S
index 8eec27cb..b95020e6 100644
--- a/lib/cpus/aarch32/cortex_a12.S
+++ b/lib/cpus/aarch32/cortex_a12.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -73,8 +73,6 @@ func cortex_a12_cluster_pwr_dwn
 	b	cortex_a12_disable_smp
 endfunc cortex_a12_cluster_pwr_dwn
 
-errata_report_shim cortex_a12
-
 declare_cpu_ops cortex_a12, CORTEX_A12_MIDR, \
 	cortex_a12_reset_func, \
 	cortex_a12_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a15.S b/lib/cpus/aarch32/cortex_a15.S
index b41676d9..53489ad1 100644
--- a/lib/cpus/aarch32/cortex_a15.S
+++ b/lib/cpus/aarch32/cortex_a15.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -172,8 +172,6 @@ func cortex_a15_cluster_pwr_dwn
 	b	cortex_a15_disable_smp
 endfunc cortex_a15_cluster_pwr_dwn
 
-errata_report_shim cortex_a15
-
 declare_cpu_ops cortex_a15, CORTEX_A15_MIDR, \
 	cortex_a15_reset_func, \
 	cortex_a15_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a17.S b/lib/cpus/aarch32/cortex_a17.S
index 18775708..05e96169 100644
--- a/lib/cpus/aarch32/cortex_a17.S
+++ b/lib/cpus/aarch32/cortex_a17.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -106,8 +106,6 @@ endfunc check_errata_cve_2017_5715
 
 add_erratum_entry cortex_a17, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
 
-errata_report_shim cortex_a17
-
 func cortex_a17_reset_func
 	mov	r5, lr
 	bl	cpu_get_rev_var
diff --git a/lib/cpus/aarch32/cortex_a32.S b/lib/cpus/aarch32/cortex_a32.S
index d08b4ff5..c92a8c1b 100644
--- a/lib/cpus/aarch32/cortex_a32.S
+++ b/lib/cpus/aarch32/cortex_a32.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -117,8 +117,6 @@ func cortex_a32_cluster_pwr_dwn
 	b	cortex_a32_disable_smp
 endfunc cortex_a32_cluster_pwr_dwn
 
-errata_report_shim cortex_a32
-
 declare_cpu_ops cortex_a32, CORTEX_A32_MIDR, \
 	cortex_a32_reset_func, \
 	cortex_a32_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a5.S b/lib/cpus/aarch32/cortex_a5.S
index 625ea7ba..146eb9c5 100644
--- a/lib/cpus/aarch32/cortex_a5.S
+++ b/lib/cpus/aarch32/cortex_a5.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -69,8 +69,6 @@ func cortex_a5_cluster_pwr_dwn
 	b	cortex_a5_disable_smp
 endfunc cortex_a5_cluster_pwr_dwn
 
-errata_report_shim cortex_a5
-
 declare_cpu_ops cortex_a5, CORTEX_A5_MIDR, \
 	cortex_a5_reset_func, \
 	cortex_a5_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a53.S b/lib/cpus/aarch32/cortex_a53.S
index 89b238a6..60be2b33 100644
--- a/lib/cpus/aarch32/cortex_a53.S
+++ b/lib/cpus/aarch32/cortex_a53.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -297,8 +297,6 @@ func cortex_a53_cluster_pwr_dwn
 	b	cortex_a53_disable_smp
 endfunc cortex_a53_cluster_pwr_dwn
 
-errata_report_shim cortex_a53
-
 declare_cpu_ops cortex_a53, CORTEX_A53_MIDR, \
 	cortex_a53_reset_func, \
 	cortex_a53_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a57.S b/lib/cpus/aarch32/cortex_a57.S
index 1e5377b2..d563482d 100644
--- a/lib/cpus/aarch32/cortex_a57.S
+++ b/lib/cpus/aarch32/cortex_a57.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -606,8 +606,6 @@ func cortex_a57_cluster_pwr_dwn
 	b	cortex_a57_disable_ext_debug
 endfunc cortex_a57_cluster_pwr_dwn
 
-errata_report_shim cortex_a57
-
 declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \
 	cortex_a57_reset_func, \
 	cortex_a57_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a7.S b/lib/cpus/aarch32/cortex_a7.S
index 4842ca63..f99ae791 100644
--- a/lib/cpus/aarch32/cortex_a7.S
+++ b/lib/cpus/aarch32/cortex_a7.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -73,8 +73,6 @@ func cortex_a7_cluster_pwr_dwn
 	b	cortex_a7_disable_smp
 endfunc cortex_a7_cluster_pwr_dwn
 
-errata_report_shim cortex_a7
-
 declare_cpu_ops cortex_a7, CORTEX_A7_MIDR, \
 	cortex_a7_reset_func, \
 	cortex_a7_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a72.S b/lib/cpus/aarch32/cortex_a72.S
index 77cf84dd..8d399fd6 100644
--- a/lib/cpus/aarch32/cortex_a72.S
+++ b/lib/cpus/aarch32/cortex_a72.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -256,8 +256,6 @@ func cortex_a72_cluster_pwr_dwn
 	b	cortex_a72_disable_ext_debug
 endfunc cortex_a72_cluster_pwr_dwn
 
-errata_report_shim cortex_a72
-
 declare_cpu_ops cortex_a72, CORTEX_A72_MIDR, \
 	cortex_a72_reset_func, \
 	cortex_a72_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a9.S b/lib/cpus/aarch32/cortex_a9.S
index 1e9757a4..dc5ff270 100644
--- a/lib/cpus/aarch32/cortex_a9.S
+++ b/lib/cpus/aarch32/cortex_a9.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -57,8 +57,6 @@ endfunc check_errata_cve_2017_5715
 
 add_erratum_entry cortex_a9, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
 
-errata_report_shim cortex_a9
-
 func cortex_a9_reset_func
 #if IMAGE_BL32 && WORKAROUND_CVE_2017_5715
 	ldr	r0, =wa_cve_2017_5715_bpiall_vbar
diff --git a/lib/cpus/aarch64/a64fx.S b/lib/cpus/aarch64/a64fx.S
index 54c20c32..4893a44d 100644
--- a/lib/cpus/aarch64/a64fx.S
+++ b/lib/cpus/aarch64/a64fx.S
@@ -16,15 +16,6 @@ endfunc a64fx_core_pwr_dwn
 func a64fx_cluster_pwr_dwn
 endfunc a64fx_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for A64FX. Must follow AAPCS.
- */
-func a64fx_errata_report
-        ret
-endfunc a64fx_errata_report
-#endif
-
         /* ---------------------------------------------
          * This function provides cpu specific
          * register information for crash reporting.
diff --git a/lib/cpus/aarch64/aem_generic.S b/lib/cpus/aarch64/aem_generic.S
index d47279a7..d5634cff 100644
--- a/lib/cpus/aarch64/aem_generic.S
+++ b/lib/cpus/aarch64/aem_generic.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -74,15 +74,6 @@ func aem_generic_cluster_pwr_dwn
 	b	dcsw_op_all
 endfunc aem_generic_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for AEM. Must follow AAPCS.
- */
-func aem_generic_errata_report
-	ret
-endfunc aem_generic_errata_report
-#endif
-
 	/* ---------------------------------------------
 	 * This function provides cpu specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a35.S b/lib/cpus/aarch64/cortex_a35.S
index 6ffb9440..c3d8c8dd 100644
--- a/lib/cpus/aarch64/cortex_a35.S
+++ b/lib/cpus/aarch64/cortex_a35.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -111,8 +111,6 @@ func cortex_a35_cluster_pwr_dwn
 	b	cortex_a35_disable_smp
 endfunc cortex_a35_cluster_pwr_dwn
 
-errata_report_shim cortex_a35
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a35 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index a59b92c1..b49d45a2 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -204,8 +204,6 @@ func cortex_a510_core_pwr_dwn
 	ret
 endfunc cortex_a510_core_pwr_dwn
 
-errata_report_shim cortex_a510
-
 cpu_reset_func_start cortex_a510
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_a520.S b/lib/cpus/aarch64/cortex_a520.S
index 6c2f33e8..811c836a 100644
--- a/lib/cpus/aarch64/cortex_a520.S
+++ b/lib/cpus/aarch64/cortex_a520.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,9 @@
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
+/* .global erratum_cortex_a520_2938996_wa */
+.global check_erratum_cortex_a520_2938996
+
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
 #error "Cortex A520 must be compiled with HW_ASSISTED_COHERENCY enabled"
@@ -21,6 +24,36 @@
 #error "Cortex A520 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+workaround_reset_start cortex_a520, ERRATUM(2630792), ERRATA_A520_2630792
+	sysreg_bit_set CORTEX_A520_CPUACTLR_EL1, BIT(38)
+workaround_reset_end cortex_a520, ERRATUM(2630792)
+
+check_erratum_ls cortex_a520, ERRATUM(2630792), CPU_REV(0, 1)
+
+workaround_reset_start cortex_a520, ERRATUM(2858100), ERRATA_A520_2858100
+	sysreg_bit_set CORTEX_A520_CPUACTLR_EL1, BIT(29)
+workaround_reset_end cortex_a520, ERRATUM(2858100)
+
+check_erratum_ls cortex_a520, ERRATUM(2858100), CPU_REV(0, 1)
+
+workaround_runtime_start cortex_a520, ERRATUM(2938996), ERRATA_A520_2938996, CORTEX_A520_MIDR
+workaround_runtime_end cortex_a520, ERRATUM(2938996)
+
+check_erratum_custom_start cortex_a520, ERRATUM(2938996)
+
+       /* This erratum needs to be enabled for r0p0 and r0p1.
+        * Check if revision is less than or equal to r0p1.
+        */
+
+#if ERRATA_A520_2938996
+       mov     x1, #1
+       b       cpu_rev_var_ls
+#else
+       mov     x0, #ERRATA_MISSING
+#endif
+       ret
+check_erratum_custom_end cortex_a520, ERRATUM(2938996)
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -35,8 +68,6 @@ func cortex_a520_core_pwr_dwn
 	ret
 endfunc cortex_a520_core_pwr_dwn
 
-errata_report_shim cortex_a520
-
 cpu_reset_func_start cortex_a520
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index e6fb08a4..4a5b3181 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -199,8 +199,6 @@ func cortex_a53_cluster_pwr_dwn
 	b	cortex_a53_disable_smp
 endfunc cortex_a53_cluster_pwr_dwn
 
-errata_report_shim cortex_a53
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a53 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index 712b6e0a..d5a74e96 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -116,8 +116,6 @@ add_erratum_entry cortex_a55, ERRATUM(1530923), ERRATA_A55_1530923, NO_APPLY_AT_
 cpu_reset_func_start cortex_a55
 cpu_reset_func_end cortex_a55
 
-errata_report_shim cortex_a55
-
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index 8fafacab..fecb56f4 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -57,7 +57,7 @@ func cortex_a57_disable_ext_debug
 	msr	osdlr_el1, x0
 	isb
 
-	apply_erratum cortex_a57, ERRATUM(817169), ERRATA_A57_817169
+	apply_erratum cortex_a57, ERRATUM(817169), ERRATA_A57_817169, NO_GET_CPU_REV
 
 	dsb	sy
 	ret
@@ -284,8 +284,6 @@ func cortex_a57_cluster_pwr_dwn
 	b	cortex_a57_disable_ext_debug
 endfunc cortex_a57_cluster_pwr_dwn
 
-errata_report_shim cortex_a57
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a57 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a65.S b/lib/cpus/aarch64/cortex_a65.S
index 666324c1..3023ecbe 100644
--- a/lib/cpus/aarch64/cortex_a65.S
+++ b/lib/cpus/aarch64/cortex_a65.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,26 +45,6 @@ func cortex_a65_cpu_pwr_dwn
 	ret
 endfunc cortex_a65_cpu_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Cortex-A65. Must follow AAPCS.
- */
-func cortex_a65_errata_report
-	stp	x8, x30, [sp, #-16]!
-
-	bl	cpu_get_rev_var
-	mov	x8, x0
-
-	/*
-	 * Report all errata. The revision-variant information is passed to
-	 * checking functions of each errata.
-	 */
-	report_errata ERRATA_DSU_936184, cortex_a65, dsu_936184
-
-	ldp	x8, x30, [sp], #16
-	ret
-endfunc cortex_a65_errata_report
-#endif
 
 .section .rodata.cortex_a65_regs, "aS"
 cortex_a65_regs:  /* The ascii list of register names to be reported */
diff --git a/lib/cpus/aarch64/cortex_a65ae.S b/lib/cpus/aarch64/cortex_a65ae.S
index 85d1894e..1cbb06af 100644
--- a/lib/cpus/aarch64/cortex_a65ae.S
+++ b/lib/cpus/aarch64/cortex_a65ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,8 +41,6 @@ func cortex_a65ae_cpu_pwr_dwn
 	ret
 endfunc cortex_a65ae_cpu_pwr_dwn
 
-errata_report_shim cortex_a65ae
-
 .section .rodata.cortex_a65ae_regs, "aS"
 cortex_a65ae_regs:  /* The ascii list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index f3931d74..b9f6081e 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -193,6 +193,12 @@ workaround_runtime_end cortex_a710, ERRATUM(2768515), NO_ISB
 
 check_erratum_ls cortex_a710, ERRATUM(2768515), CPU_REV(2, 1)
 
+workaround_reset_start cortex_a710, ERRATUM(2778471), ERRATA_A710_2778471
+	sysreg_bit_set CORTEX_A710_CPUACTLR3_EL1, BIT(47)
+workaround_reset_end cortex_a710, ERRATUM(2778471)
+
+check_erratum_ls cortex_a710, ERRATUM(2778471), CPU_REV(2, 1)
+
 workaround_reset_start cortex_a710, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -210,7 +216,7 @@ check_erratum_chosen cortex_a710, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 	 * ----------------------------------------------------
 	 */
 func cortex_a710_core_pwr_dwn
-	apply_erratum cortex_a710, ERRATUM(2008768), ERRATA_A710_2008768
+	apply_erratum cortex_a710, ERRATUM(2008768), ERRATA_A710_2008768, NO_GET_CPU_REV
 	apply_erratum cortex_a710, ERRATUM(2291219), ERRATA_A710_2291219, NO_GET_CPU_REV
 
 	/* ---------------------------------------------------
@@ -223,8 +229,6 @@ func cortex_a710_core_pwr_dwn
 	ret
 endfunc cortex_a710_core_pwr_dwn
 
-errata_report_shim cortex_a710
-
 cpu_reset_func_start cortex_a710
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index dd4c307f..8c9988da 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,6 +26,95 @@
 	wa_cve_2022_23960_bhb_vector_table CORTEX_A715_BHB_LOOP_COUNT, cortex_a715
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_reset_start cortex_a715, ERRATUM(2331818), ERRATA_A715_2331818
+        sysreg_bit_set CORTEX_A715_CPUACTLR2_EL1, BIT(20)
+workaround_reset_end cortex_a715, ERRATUM(2331818)
+
+check_erratum_ls cortex_a715, ERRATUM(2331818), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2344187), ERRATA_A715_2344187
+	/* GCR_EL1 is only present with FEAT_MTE2. */
+	mrs x1, ID_AA64PFR1_EL1
+	ubfx x0, x1, ID_AA64PFR1_EL1_MTE_SHIFT, #4
+	cmp x0, #MTE_IMPLEMENTED_ELX
+	bne #1f
+	sysreg_bit_set GCR_EL1, GCR_EL1_RRND_BIT
+
+1:
+	/* Mitigation upon ERETAA and ERETAB. */
+	mov x0, #2
+	msr CORTEX_A715_CPUPSELR_EL3, x0
+	isb
+	ldr x0, =0xd69f0bff
+	msr CORTEX_A715_CPUPOR_EL3, x0
+	ldr x0, =0xfffffbff
+	msr CORTEX_A715_CPUPMR_EL3, x0
+	mov x1, #0
+	orr x1, x1, #(1<<0)
+	orr x1, x1, #(3<<4)
+	orr x1, x1, #(0xf<<6)
+	orr x1, x1, #(1<<13)
+	orr x1, x1, #(1<<53)
+	msr CORTEX_A715_CPUPCR_EL3, x1
+workaround_reset_end cortex_a715, ERRATUM(2344187)
+
+check_erratum_ls cortex_a715, ERRATUM(2344187), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2413290), ERRATA_A715_2413290
+/* Erratum 2413290 workaround is required only if SPE is enabled */
+#if ENABLE_SPE_FOR_NS != 0
+	/* Check if Static profiling extension is implemented or present. */
+	mrs x1, id_aa64dfr0_el1
+	ubfx x0, x1, ID_AA64DFR0_PMS_SHIFT, #4
+	cbz x0, 1f
+	/* Apply the workaround by setting CPUACTLR_EL1[58:57] = 0b11. */
+	sysreg_bit_set CORTEX_A715_CPUACTLR_EL1, BIT(57)
+	sysreg_bit_set CORTEX_A715_CPUACTLR_EL1, BIT(58)
+1:
+#endif
+workaround_reset_end cortex_a715, ERRATUM(2413290)
+
+check_erratum_range cortex_a715, ERRATUM(2413290), CPU_REV(1,0), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2420947), ERRATA_A715_2420947
+        sysreg_bit_set CORTEX_A715_CPUACTLR2_EL1, BIT(33)
+workaround_reset_end cortex_a715, ERRATUM(2420947)
+
+check_erratum_range cortex_a715, ERRATUM(2420947), CPU_REV(1, 0), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2429384), ERRATA_A715_2429384
+        sysreg_bit_set CORTEX_A715_CPUACTLR2_EL1, BIT(27)
+workaround_reset_end cortex_a715, ERRATUM(2429384)
+
+check_erratum_range cortex_a715, ERRATUM(2429384), CPU_REV(1, 0), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2561034), ERRATA_A715_2561034
+	sysreg_bit_set	CORTEX_A715_CPUACTLR2_EL1, BIT(26)
+workaround_reset_end cortex_a715, ERRATUM(2561034)
+
+check_erratum_range cortex_a715, ERRATUM(2561034), CPU_REV(1, 0), CPU_REV(1, 0)
+
+workaround_reset_start cortex_a715, ERRATUM(2728106), ERRATA_A715_2728106
+	mov x0, #3
+	msr CORTEX_A715_CPUPSELR_EL3, x0
+	isb
+	ldr x0, =0xd503339f
+	msr CORTEX_A715_CPUPOR_EL3, x0
+	ldr x0, =0xfffff3ff
+	msr CORTEX_A715_CPUPMR_EL3, x0
+	mov x0, #1
+	orr x0, x0, #(3<<4)
+	orr x0, x0, #(0xf<<6)
+	orr x0, x0, #(1<<13)
+	orr x0, x0, #(1<<20)
+	orr x0, x0, #(1<<22)
+	orr x0, x0, #(1<<31)
+	orr x0, x0, #(1<<50)
+	msr CORTEX_A715_CPUPCR_EL3, x0
+workaround_reset_end cortex_a715, ERRATUM(2728106)
+
+check_erratum_ls cortex_a715, ERRATUM(2728106), CPU_REV(1, 1)
+
 workaround_reset_start cortex_a715, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -59,8 +148,6 @@ func cortex_a715_core_pwr_dwn
 	ret
 endfunc cortex_a715_core_pwr_dwn
 
-errata_report_shim cortex_a715
-
 	/* ---------------------------------------------
 	 * This function provides Cortex-A715 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a72.S b/lib/cpus/aarch64/cortex_a72.S
index 997f261b..c300ea7c 100644
--- a/lib/cpus/aarch64/cortex_a72.S
+++ b/lib/cpus/aarch64/cortex_a72.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -271,8 +271,6 @@ func cortex_a72_cluster_pwr_dwn
 	b	cortex_a72_disable_ext_debug
 endfunc cortex_a72_cluster_pwr_dwn
 
-errata_report_shim cortex_a72
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a72 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a720.S b/lib/cpus/aarch64/cortex_a720.S
index 4b28fdb0..9befb36e 100644
--- a/lib/cpus/aarch64/cortex_a720.S
+++ b/lib/cpus/aarch64/cortex_a720.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,6 +26,40 @@
         wa_cve_2022_23960_bhb_vector_table CORTEX_A720_BHB_LOOP_COUNT, cortex_a720
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_reset_start cortex_a720, ERRATUM(2792132), ERRATA_A720_2792132
+        sysreg_bit_set CORTEX_A720_CPUACTLR2_EL1, BIT(26)
+workaround_reset_end cortex_a720, ERRATUM(2792132)
+
+check_erratum_ls cortex_a720, ERRATUM(2792132), CPU_REV(0, 1)
+
+workaround_reset_start cortex_a720, ERRATUM(2844092), ERRATA_A720_2844092
+        sysreg_bit_set CORTEX_A720_CPUACTLR4_EL1, BIT(11)
+workaround_reset_end cortex_a720, ERRATUM(2844092)
+
+check_erratum_ls cortex_a720, ERRATUM(2844092), CPU_REV(0, 1)
+
+workaround_reset_start cortex_a720, ERRATUM(2926083), ERRATA_A720_2926083
+/* Erratum 2926083 workaround is required only if SPE is enabled */
+#if ENABLE_SPE_FOR_NS != 0
+	/* Check if Static profiling extension is implemented or present. */
+	mrs x1, id_aa64dfr0_el1
+	ubfx x0, x1, ID_AA64DFR0_PMS_SHIFT, #4
+	cbz x0, 1f
+	/* Apply the workaround by setting CPUACTLR_EL1[58:57] = 0b11. */
+	sysreg_bit_set CORTEX_A720_CPUACTLR_EL1, BIT(57)
+	sysreg_bit_set CORTEX_A720_CPUACTLR_EL1, BIT(58)
+1:
+#endif
+workaround_reset_end cortex_a720, ERRATUM(2926083)
+
+check_erratum_ls cortex_a720, ERRATUM(2926083), CPU_REV(0, 1)
+
+workaround_reset_start cortex_a720, ERRATUM(2940794), ERRATA_A720_2940794
+        sysreg_bit_set CORTEX_A720_CPUACTLR2_EL1, BIT(37)
+workaround_reset_end cortex_a720, ERRATUM(2940794)
+
+check_erratum_ls cortex_a720, ERRATUM(2940794), CPU_REV(0, 1)
+
 workaround_reset_start cortex_a720, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -58,8 +92,6 @@ func cortex_a720_core_pwr_dwn
 	ret
 endfunc cortex_a720_core_pwr_dwn
 
-errata_report_shim cortex_a720
-
 	/* ---------------------------------------------
 	 * This function provides Cortex A720-specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/neoverse_hermes.S b/lib/cpus/aarch64/cortex_a720_ae.S
similarity index 52%
rename from lib/cpus/aarch64/neoverse_hermes.S
rename to lib/cpus/aarch64/cortex_a720_ae.S
index cb90b715..42d49c33 100644
--- a/lib/cpus/aarch64/neoverse_hermes.S
+++ b/lib/cpus/aarch64/cortex_a720_ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,43 +7,42 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <common/bl_common.h>
-#include <neoverse_hermes.h>
+#include <cortex_a720_ae.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
-#error "Neoverse Hermes must be compiled with HW_ASSISTED_COHERENCY enabled"
+#error "Cortex-A720AE must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
 /* 64-bit only core */
 #if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Neoverse Hermes supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#error "Cortex-A720AE supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-cpu_reset_func_start neoverse_hermes
+cpu_reset_func_start cortex_a720_ae
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-cpu_reset_func_end neoverse_hermes
+cpu_reset_func_end cortex_a720_ae
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
 	 */
-func neoverse_hermes_core_pwr_dwn
+func cortex_a720_ae_core_pwr_dwn
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	sysreg_bit_set NEOVERSE_HERMES_CPUPWRCTLR_EL1, NEOVERSE_HERMES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	sysreg_bit_set CORTEX_A720_AE_CPUPWRCTLR_EL1, CORTEX_A720_AE_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
 	isb
 	ret
-endfunc neoverse_hermes_core_pwr_dwn
-
-errata_report_shim neoverse_hermes
+endfunc cortex_a720_ae_core_pwr_dwn
 
 	/* ---------------------------------------------
-	 * This function provides Neoverse Hermes specific
+	 * This function provides Cortex-A720AE specific
 	 * register information for crash reporting.
 	 * It needs to return with x6 pointing to
 	 * a list of register names in ascii and
@@ -51,16 +50,16 @@ errata_report_shim neoverse_hermes
 	 * reported.
 	 * ---------------------------------------------
 	 */
-.section .rodata.neoverse_hermes_regs, "aS"
-neoverse_hermes_regs:  /* The ascii list of register names to be reported */
+.section .rodata.cortex_a720_ae_regs, "aS"
+cortex_a720_ae_regs:  /* The ascii list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
 
-func neoverse_hermes_cpu_reg_dump
-	adr	x6, neoverse_hermes_regs
-	mrs	x8, NEOVERSE_HERMES_CPUECTLR_EL1
+func cortex_a720_ae_cpu_reg_dump
+	adr	x6, cortex_a720_ae_regs
+	mrs	x8, CORTEX_A720_AE_CPUECTLR_EL1
 	ret
-endfunc neoverse_hermes_cpu_reg_dump
+endfunc cortex_a720_ae_cpu_reg_dump
 
-declare_cpu_ops neoverse_hermes, NEOVERSE_HERMES_MIDR, \
-	neoverse_hermes_reset_func, \
-	neoverse_hermes_core_pwr_dwn
+declare_cpu_ops cortex_a720_ae, CORTEX_A720_AE_MIDR, \
+	cortex_a720_ae_reset_func, \
+	cortex_a720_ae_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_blackhawk.S b/lib/cpus/aarch64/cortex_a725.S
similarity index 51%
rename from lib/cpus/aarch64/cortex_blackhawk.S
rename to lib/cpus/aarch64/cortex_a725.S
index b7b7a2dd..af98d145 100644
--- a/lib/cpus/aarch64/cortex_blackhawk.S
+++ b/lib/cpus/aarch64/cortex_a725.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,43 +7,41 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <common/bl_common.h>
-#include <cortex_blackhawk.h>
+#include <cortex_a725.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
-#error "Cortex blackhawk must be compiled with HW_ASSISTED_COHERENCY enabled"
+#error "Cortex-A725 must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
 /* 64-bit only core */
 #if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex blackhawk supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#error "Cortex-A725 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-cpu_reset_func_start cortex_blackhawk
+cpu_reset_func_start cortex_a725
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-cpu_reset_func_end cortex_blackhawk
+cpu_reset_func_end cortex_a725
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
 	 */
-func cortex_blackhawk_core_pwr_dwn
+func cortex_a725_core_pwr_dwn
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	sysreg_bit_set CORTEX_BLACKHAWK_CPUPWRCTLR_EL1, CORTEX_BLACKHAWK_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	sysreg_bit_set CORTEX_A725_CPUPWRCTLR_EL1, CORTEX_A725_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	isb
 	ret
-endfunc cortex_blackhawk_core_pwr_dwn
-
-errata_report_shim cortex_blackhawk
+endfunc cortex_a725_core_pwr_dwn
 
 	/* ---------------------------------------------
-	 * This function provides Cortex Blackhawk specific
+	 * This function provides Cortex-A725 specific
 	 * register information for crash reporting.
 	 * It needs to return with x6 pointing to
 	 * a list of register names in ascii and
@@ -51,16 +49,16 @@ errata_report_shim cortex_blackhawk
 	 * reported.
 	 * ---------------------------------------------
 	 */
-.section .rodata.cortex_blackhawk_regs, "aS"
-cortex_blackhawk_regs:  /* The ascii list of register names to be reported */
+.section .rodata.cortex_a725_regs, "aS"
+cortex_a725_regs:  /* The ascii list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
 
-func cortex_blackhawk_cpu_reg_dump
-	adr	x6, cortex_blackhawk_regs
-	mrs	x8, CORTEX_BLACKHAWK_CPUECTLR_EL1
+func cortex_a725_cpu_reg_dump
+	adr	x6, cortex_a725_regs
+	mrs	x8, CORTEX_A725_CPUECTLR_EL1
 	ret
-endfunc cortex_blackhawk_cpu_reg_dump
+endfunc cortex_a725_cpu_reg_dump
 
-declare_cpu_ops cortex_blackhawk, CORTEX_BLACKHAWK_MIDR, \
-	cortex_blackhawk_reset_func, \
-	cortex_blackhawk_core_pwr_dwn
+declare_cpu_ops cortex_a725, CORTEX_A725_MIDR, \
+	cortex_a725_reset_func, \
+	cortex_a725_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a73.S b/lib/cpus/aarch64/cortex_a73.S
index 3a6b9226..2130ceb1 100644
--- a/lib/cpus/aarch64/cortex_a73.S
+++ b/lib/cpus/aarch64/cortex_a73.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -178,9 +178,6 @@ func cortex_a73_cluster_pwr_dwn
 	b	cortex_a73_disable_smp
 endfunc cortex_a73_cluster_pwr_dwn
 
-
-errata_report_shim cortex_a73
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a73 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index c90be679..152c81f6 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,8 @@
 #include <cpuamu.h>
 #include <cpu_macros.S>
 
+.global check_erratum_cortex_a75_764081
+
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
 #error "Cortex-A75 must be compiled with HW_ASSISTED_COHERENCY enabled"
@@ -146,8 +148,6 @@ func cortex_a75_core_pwr_dwn
 	ret
 endfunc cortex_a75_core_pwr_dwn
 
-errata_report_shim cortex_a75
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a75 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 8b3d7300..017086aa 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -505,14 +505,12 @@ func cortex_a76_core_pwr_dwn
 	 */
 	sysreg_bit_set CORTEX_A76_CPUPWRCTLR_EL1, CORTEX_A76_CORE_PWRDN_EN_MASK
 
-	apply_erratum cortex_a76, ERRATUM(2743102), ERRATA_A76_2743102
+	apply_erratum cortex_a76, ERRATUM(2743102), ERRATA_A76_2743102, NO_GET_CPU_REV
 
 	isb
 	ret
 endfunc cortex_a76_core_pwr_dwn
 
-errata_report_shim cortex_a76
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a76 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S
index 08a6ef91..2fe3dbcf 100644
--- a/lib/cpus/aarch64/cortex_a76ae.S
+++ b/lib/cpus/aarch64/cortex_a76ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,8 +41,6 @@ workaround_reset_end cortex_a76ae, CVE(2022, 23960)
 cpu_reset_func_start cortex_a76ae
 cpu_reset_func_end cortex_a76ae
 
-errata_report_shim cortex_a76ae
-
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index 86c25615..f53b6467 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -161,13 +161,12 @@ func cortex_a77_core_pwr_dwn
 	sysreg_bit_set CORTEX_A77_CPUPWRCTLR_EL1, \
 		CORTEX_A77_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 
-	apply_erratum cortex_a77, ERRATUM(2743100), ERRATA_A77_2743100
+	apply_erratum cortex_a77, ERRATUM(2743100), ERRATA_A77_2743100, NO_GET_CPU_REV
 
 	isb
 	ret
 endfunc cortex_a77_core_pwr_dwn
 
-errata_report_shim cortex_a77
 	/* ---------------------------------------------
 	 * This function provides Cortex-A77 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S
index b5c24e14..1de570a0 100644
--- a/lib/cpus/aarch64/cortex_a78.S
+++ b/lib/cpus/aarch64/cortex_a78.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -192,14 +192,12 @@ cpu_reset_func_end cortex_a78
 func cortex_a78_core_pwr_dwn
 	sysreg_bit_set CORTEX_A78_CPUPWRCTLR_EL1, CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 
-	apply_erratum cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019
+	apply_erratum cortex_a78, ERRATUM(2772019), ERRATA_A78_2772019, NO_GET_CPU_REV
 
 	isb
 	ret
 endfunc cortex_a78_core_pwr_dwn
 
-errata_report_shim cortex_a78
-
 	/* ---------------------------------------------
 	 * This function provides cortex_a78 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index d3a3e5d8..bc10186f 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2021-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -128,8 +128,6 @@ func cortex_a78_ae_core_pwr_dwn
 	ret
 endfunc cortex_a78_ae_core_pwr_dwn
 
-errata_report_shim cortex_a78_ae
-
 	/* -------------------------------------------------------
 	 * This function provides cortex_a78_ae specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index d19c6938..260cc73a 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -72,6 +72,27 @@ workaround_reset_end cortex_a78c, ERRATUM(2395411)
 
 check_erratum_range cortex_a78c, ERRATUM(2395411), CPU_REV(0, 1), CPU_REV(0, 2)
 
+workaround_reset_start cortex_a78c, ERRATUM(2683027), ERRATA_A78C_2683027
+	ldr	x0, =0x3
+	msr	CORTEX_A78C_IMP_CPUPSELR_EL3, x0
+	ldr	x0, =0xEE010F10
+	msr	CORTEX_A78C_IMP_CPUPOR_EL3, x0
+	ldr	x0, =0xFF1F0FFE
+	msr	CORTEX_A78C_IMP_CPUPMR_EL3, x0
+	ldr	x0, =0x100000004003FF
+	msr	CORTEX_A78C_IMP_CPUPCR_EL3, x0
+workaround_reset_end cortex_a78c, ERRATUM(2683027)
+
+check_erratum_range cortex_a78c, ERRATUM(2683027), CPU_REV(0, 1), CPU_REV(0, 2)
+
+workaround_reset_start cortex_a78c, ERRATUM(2743232), ERRATA_A78C_2743232
+	/* Set CPUACTLR5_EL1[56:55] to 2'b01 */
+	sysreg_bit_set CORTEX_A78C_ACTLR5_EL1, BIT(55)
+	sysreg_bit_clear CORTEX_A78C_ACTLR5_EL1, BIT(56)
+workaround_reset_end cortex_a78c, ERRATUM(2743232)
+
+check_erratum_range cortex_a78c, ERRATUM(2743232), CPU_REV(0, 1), CPU_REV(0, 2)
+
 workaround_runtime_start cortex_a78c, ERRATUM(2772121), ERRATA_A78C_2772121
 	/* dsb before isb of power down sequence */
 	dsb	sy
@@ -100,8 +121,6 @@ workaround_reset_end cortex_a78c, CVE(2022, 23960)
 cpu_reset_func_start cortex_a78c
 cpu_reset_func_end cortex_a78c
 
-errata_report_shim cortex_a78c
-
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -113,7 +132,7 @@ func cortex_a78c_core_pwr_dwn
 	 */
 	sysreg_bit_set CORTEX_A78C_CPUPWRCTLR_EL1, CORTEX_A78C_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
 
-	apply_erratum cortex_a78c, ERRATUM(2772121), ERRATA_A78C_2772121
+	apply_erratum cortex_a78c, ERRATUM(2772121), ERRATA_A78C_2772121, NO_GET_CPU_REV
 
 	isb
 	ret
diff --git a/lib/cpus/aarch64/cortex_chaberton.S b/lib/cpus/aarch64/cortex_arcadia.S
similarity index 51%
rename from lib/cpus/aarch64/cortex_chaberton.S
rename to lib/cpus/aarch64/cortex_arcadia.S
index 596fe4a6..c97d87db 100644
--- a/lib/cpus/aarch64/cortex_chaberton.S
+++ b/lib/cpus/aarch64/cortex_arcadia.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,43 +7,41 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <common/bl_common.h>
-#include <cortex_chaberton.h>
+#include <cortex_arcadia.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
-#error "Cortex Chaberton must be compiled with HW_ASSISTED_COHERENCY enabled"
+#error "Cortex-ARCADIA must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
 /* 64-bit only core */
 #if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Cortex Chaberton supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#error "Cortex-ARCADIA supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-cpu_reset_func_start cortex_chaberton
+cpu_reset_func_start cortex_arcadia
 	/* Disable speculative loads */
 	msr	SSBS, xzr
-cpu_reset_func_end cortex_chaberton
+cpu_reset_func_end cortex_arcadia
 
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
 	 */
-func cortex_chaberton_core_pwr_dwn
+func cortex_arcadia_core_pwr_dwn
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
-	sysreg_bit_set CORTEX_CHABERTON_CPUPWRCTLR_EL1, CORTEX_CHABERTON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	sysreg_bit_set CORTEX_ARCADIA_CPUPWRCTLR_EL1, CORTEX_ARCADIA_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 	isb
 	ret
-endfunc cortex_chaberton_core_pwr_dwn
-
-errata_report_shim cortex_chaberton
+endfunc cortex_arcadia_core_pwr_dwn
 
 	/* ---------------------------------------------
-	 * This function provides Cortex Chaberton specific
+	 * 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
@@ -51,16 +49,16 @@ errata_report_shim cortex_chaberton
 	 * reported.
 	 * ---------------------------------------------
 	 */
-.section .rodata.cortex_chaberton_regs, "aS"
-cortex_chaberton_regs:  /* The ascii list of register names 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_chaberton_cpu_reg_dump
-	adr	x6, cortex_chaberton_regs
-	mrs	x8, CORTEX_CHABERTON_CPUECTLR_EL1
+func cortex_arcadia_cpu_reg_dump
+	adr	x6, cortex_arcadia_regs
+	mrs	x8, CORTEX_ARCADIA_CPUECTLR_EL1
 	ret
-endfunc cortex_chaberton_cpu_reg_dump
+endfunc cortex_arcadia_cpu_reg_dump
 
-declare_cpu_ops cortex_chaberton, CORTEX_CHABERTON_MIDR, \
-	cortex_chaberton_reset_func, \
-	cortex_chaberton_core_pwr_dwn
+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 dc704f20..891e9a65 100644
--- a/lib/cpus/aarch64/cortex_gelas.S
+++ b/lib/cpus/aarch64/cortex_gelas.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,7 +42,7 @@ func cortex_gelas_core_pwr_dwn
 	mrs     x0, ID_AA64PFR1_EL1
 	ubfx	x0, x0, #ID_AA64PFR1_EL1_SME_SHIFT, \
 		#ID_AA64PFR1_EL1_SME_WIDTH
-        cmp     x0, #ID_AA64PFR1_EL1_SME_NOT_SUPPORTED
+        cmp     x0, #SME_NOT_IMPLEMENTED
 	b.eq	1f
 	msr	CORTEX_GELAS_SVCRSM, xzr
 	msr	CORTEX_GELAS_SVCRZA, xzr
@@ -58,8 +58,6 @@ func cortex_gelas_core_pwr_dwn
 	ret
 endfunc cortex_gelas_core_pwr_dwn
 
-errata_report_shim cortex_gelas
-
 	/* ---------------------------------------------
 	 * This function provides Gelas specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_x1.S b/lib/cpus/aarch64/cortex_x1.S
index 42634f1a..ca6cac99 100644
--- a/lib/cpus/aarch64/cortex_x1.S
+++ b/lib/cpus/aarch64/cortex_x1.S
@@ -66,8 +66,6 @@ func cortex_x1_core_pwr_dwn
 	ret
 endfunc cortex_x1_core_pwr_dwn
 
-errata_report_shim cortex_x1
-
        /* ---------------------------------------------
 	* This function provides Cortex X1 specific
 	* register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 258288c6..ac60903a 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -126,13 +126,19 @@ workaround_reset_end cortex_x2, ERRATUM(2742423)
 
 check_erratum_ls cortex_x2, ERRATUM(2742423), CPU_REV(2, 1)
 
-workaround_reset_start cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515
+workaround_runtime_start cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515
 	/* dsb before isb of power down sequence */
 	dsb	sy
-workaround_reset_end cortex_x2, ERRATUM(2768515)
+workaround_runtime_end cortex_x2, ERRATUM(2768515)
 
 check_erratum_ls cortex_x2, ERRATUM(2768515), CPU_REV(2, 1)
 
+workaround_reset_start cortex_x2, ERRATUM(2778471), ERRATA_X2_2778471
+	sysreg_bit_set CORTEX_X2_CPUACTLR3_EL1, BIT(47)
+workaround_reset_end cortex_x2, ERRATUM(2778471)
+
+check_erratum_ls cortex_x2, ERRATUM(2778471), CPU_REV(2, 1)
+
 workaround_reset_start cortex_x2, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -166,18 +172,11 @@ func cortex_x2_core_pwr_dwn
 	 */
 	sysreg_bit_set CORTEX_X2_CPUPWRCTLR_EL1, CORTEX_X2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
 
-#if ERRATA_X2_2768515
-	mov	x15, x30
-	bl	cpu_get_rev_var
-	bl	erratum_cortex_x2_2768515_wa
-	mov	x30, x15
-#endif /* ERRATA_X2_2768515 */
+	apply_erratum cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515, NO_GET_CPU_REV
 	isb
 	ret
 endfunc cortex_x2_core_pwr_dwn
 
-errata_report_shim cortex_x2
-
 cpu_reset_func_start cortex_x2
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S
index 0cb3b976..a81c4cf9 100644
--- a/lib/cpus/aarch64/cortex_x3.S
+++ b/lib/cpus/aarch64/cortex_x3.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,12 +33,31 @@ workaround_reset_end cortex_x3, ERRATUM(2070301)
 
 check_erratum_ls cortex_x3, ERRATUM(2070301), CPU_REV(1, 2)
 
+workaround_reset_start cortex_x3, ERRATUM(2266875), ERRATA_X3_2266875
+        sysreg_bit_set CORTEX_X3_CPUACTLR_EL1, BIT(22)
+workaround_reset_end cortex_x3, ERRATUM(2266875)
+
+check_erratum_ls cortex_x3, ERRATUM(2266875), CPU_REV(1, 0)
+
+workaround_runtime_start cortex_x3, ERRATUM(2302506), ERRATA_X3_2302506
+	sysreg_bit_set	CORTEX_X3_CPUACTLR2_EL1, BIT(0)
+workaround_runtime_end cortex_x3, ERRATUM(2302506), NO_ISB
+
+check_erratum_ls cortex_x3, ERRATUM(2302506), CPU_REV(1, 1)
+
 workaround_runtime_start cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909
 	sysreg_bit_set	CORTEX_X3_CPUACTLR2_EL1, CORTEX_X3_CPUACTLR2_EL1_BIT_36
 workaround_runtime_end cortex_x3, ERRATUM(2313909), NO_ISB
 
 check_erratum_ls cortex_x3, ERRATUM(2313909), CPU_REV(1, 0)
 
+workaround_reset_start cortex_x3, ERRATUM(2372204), ERRATA_X3_2372204
+	/* Set bit 40 in CPUACTLR2_EL1 */
+	sysreg_bit_set CORTEX_X3_CPUACTLR2_EL1, BIT(40)
+workaround_reset_end cortex_x3, ERRATUM(2372204)
+
+check_erratum_ls cortex_x3, ERRATUM(2372204), CPU_REV(1, 0)
+
 workaround_reset_start cortex_x3, ERRATUM(2615812), ERRATA_X3_2615812
 	/* Disable retention control for WFI and WFE. */
 	mrs	x0, CORTEX_X3_CPUPWRCTLR_EL1
@@ -49,6 +68,12 @@ workaround_reset_end cortex_x3, ERRATUM(2615812)
 
 check_erratum_ls cortex_x3, ERRATUM(2615812), CPU_REV(1, 1)
 
+workaround_runtime_start cortex_x3, ERRATUM(2641945), ERRATA_X3_2641945
+	sysreg_bit_set	CORTEX_X3_CPUACTLR6_EL1, BIT(41)
+workaround_runtime_end cortex_x3, ERRATUM(2641945), NO_ISB
+
+check_erratum_ls cortex_x3, ERRATUM(2641945), CPU_REV(1, 0)
+
 workaround_reset_start cortex_x3, ERRATUM(2742421), ERRATA_X3_2742421
 	/* Set CPUACTLR5_EL1[56:55] to 2'b01 */
 	sysreg_bit_set CORTEX_X3_CPUACTLR5_EL1, CORTEX_X3_CPUACTLR5_EL1_BIT_55
@@ -57,6 +82,20 @@ workaround_reset_end cortex_x3, ERRATUM(2742421)
 
 check_erratum_ls cortex_x3, ERRATUM(2742421), CPU_REV(1, 1)
 
+workaround_runtime_start cortex_x3, ERRATUM(2743088), ERRATA_X3_2743088
+	/* dsb before isb of power down sequence */
+	dsb sy
+workaround_runtime_end cortex_x3, ERRATUM(2743088), NO_ISB
+
+check_erratum_ls cortex_x3, ERRATUM(2743088), CPU_REV(1, 1)
+
+workaround_reset_start cortex_x3, ERRATUM(2779509), ERRATA_X3_2779509
+	/* Set CPUACTLR3_EL1 bit 47 */
+	sysreg_bit_set CORTEX_X3_CPUACTLR3_EL1, CORTEX_X3_CPUACTLR3_EL1_BIT_47
+workaround_reset_end cortex_x3, ERRATUM(2779509)
+
+check_erratum_ls cortex_x3, ERRATUM(2779509), CPU_REV(1, 1)
+
 workaround_reset_start cortex_x3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	override_vector_table wa_cve_vbar_cortex_x3
@@ -75,18 +114,17 @@ cpu_reset_func_end cortex_x3
 	 * ----------------------------------------------------
 	 */
 func cortex_x3_core_pwr_dwn
-apply_erratum cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909
+	apply_erratum cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909, NO_GET_CPU_REV
 	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
 	 * ---------------------------------------------------
 	 */
 	sysreg_bit_set CORTEX_X3_CPUPWRCTLR_EL1, CORTEX_X3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	apply_erratum cortex_x3, ERRATUM(2743088), ERRATA_X3_2743088, NO_GET_CPU_REV
 	isb
 	ret
 endfunc cortex_x3_core_pwr_dwn
 
-errata_report_shim cortex_x3
-
 	/* ---------------------------------------------
 	 * This function provides Cortex-X3-
 	 * specific register information for crash
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index 7619f9cf..320fd90b 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,10 +22,67 @@
 #error "Cortex X4 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+.global check_erratum_cortex_x4_2726228
+
 #if WORKAROUND_CVE_2022_23960
         wa_cve_2022_23960_bhb_vector_table CORTEX_X4_BHB_LOOP_COUNT, cortex_x4
 #endif /* WORKAROUND_CVE_2022_23960 */
 
+workaround_runtime_start cortex_x4, ERRATUM(2726228), ERRATA_X4_2726228, CORTEX_X4_MIDR
+workaround_runtime_end cortex_x4, ERRATUM(2726228)
+
+check_erratum_custom_start cortex_x4, ERRATUM(2726228)
+
+	/* This erratum needs to be enabled for r0p0 and r0p1.
+	 * Check if revision is less than or equal to r0p1.
+	 */
+
+#if ERRATA_X4_2726228
+	mov	x1, #1
+	b	cpu_rev_var_ls
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+check_erratum_custom_end cortex_x4, ERRATUM(2726228)
+
+workaround_runtime_start cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089
+	/* dsb before isb of power down sequence */
+	dsb	sy
+workaround_runtime_end cortex_x4, ERRATUM(2740089)
+
+check_erratum_ls cortex_x4, ERRATUM(2740089), CPU_REV(0, 1)
+
+workaround_reset_start cortex_x4, ERRATUM(2763018), ERRATA_X4_2763018
+	sysreg_bit_set	CORTEX_X4_CPUACTLR3_EL1, BIT(47)
+workaround_reset_end cortex_x4, ERRATUM(2763018)
+
+check_erratum_ls cortex_x4, ERRATUM(2763018), CPU_REV(0, 1)
+
+workaround_reset_start cortex_x4, ERRATUM(2816013), ERRATA_X4_2816013
+	mrs x1, id_aa64pfr1_el1
+	ubfx x2, x1, ID_AA64PFR1_EL1_MTE_SHIFT, #4
+	cbz x2, #1f
+	sysreg_bit_set CORTEX_X4_CPUACTLR5_EL1, BIT(14)
+1:
+workaround_reset_end cortex_x4, ERRATUM(2816013)
+
+check_erratum_ls cortex_x4, ERRATUM(2816013), CPU_REV(0, 1)
+
+workaround_reset_start cortex_x4, ERRATUM(2897503), ERRATA_X4_2897503
+	sysreg_bit_set	CORTEX_X4_CPUACTLR4_EL1, BIT(8)
+workaround_reset_end cortex_x4, ERRATUM(2897503)
+
+check_erratum_ls cortex_x4, ERRATUM(2897503), CPU_REV(0, 1)
+
+workaround_reset_start cortex_x4, ERRATUM(3076789), ERRATA_X4_3076789
+	sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(14)
+	sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(13)
+	sysreg_bit_set CORTEX_X4_CPUACTLR_EL1, BIT(52)
+workaround_reset_end cortex_x4, ERRATUM(3076789)
+
+check_erratum_ls cortex_x4, ERRATUM(3076789), CPU_REV(0, 1)
+
 workaround_reset_start cortex_x4, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -53,12 +110,13 @@ func cortex_x4_core_pwr_dwn
 	 * ---------------------------------------------------
 	 */
 	sysreg_bit_set CORTEX_X4_CPUPWRCTLR_EL1, CORTEX_X4_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
+	apply_erratum cortex_x4, ERRATUM(2740089), ERRATA_X4_2740089, NO_GET_CPU_REV
+
 	isb
 	ret
 endfunc cortex_x4_core_pwr_dwn
 
-errata_report_shim cortex_x4
-
 	/* ---------------------------------------------
 	 * This function provides Cortex X4-specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_x925.S b/lib/cpus/aarch64/cortex_x925.S
new file mode 100644
index 00000000..8109ffba
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_x925.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2023-2024, 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_x925.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-X925 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Cortex-X925 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start cortex_x925
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end cortex_x925
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func cortex_x925_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set CORTEX_X925_CPUPWRCTLR_EL1, CORTEX_X925_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc cortex_x925_core_pwr_dwn
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-X925 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_x925_regs, "aS"
+cortex_x925_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_x925_cpu_reg_dump
+	adr	x6, cortex_x925_regs
+	mrs	x8, CORTEX_X925_CPUECTLR_EL1
+	ret
+endfunc cortex_x925_cpu_reg_dump
+
+declare_cpu_ops cortex_x925, CORTEX_X925_MIDR, \
+	cortex_x925_reset_func, \
+	cortex_x925_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 1ae31803..3aa4f155 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -165,13 +165,13 @@ func get_cpu_ops_ptr
 	and	w2, w2, w3
 
 	/* Get the cpu_ops end location */
-	adr	x5, (__CPU_OPS_END__ + CPU_MIDR)
+	adr_l	x5, (__CPU_OPS_END__ + CPU_MIDR)
 
 	/* Initialize the return parameter */
 	mov	x0, #0
 1:
 	/* Get the cpu_ops start location */
-	adr	x4, (__CPU_OPS_START__ + CPU_MIDR)
+	adr_l	x4, (__CPU_OPS_START__ + CPU_MIDR)
 
 2:
 	/* Check if we have reached end of list */
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index 884281d3..ca250d37 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -296,8 +296,6 @@ func denver_cluster_pwr_dwn
 	ret
 endfunc denver_cluster_pwr_dwn
 
-errata_report_shim denver
-
 	/* ---------------------------------------------
 	 * This function provides Denver specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
index a34b9a67..3c5bf2ea 100644
--- a/lib/cpus/aarch64/dsu_helpers.S
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -24,6 +24,7 @@
 	 */
 	.globl	check_errata_dsu_798953
 	.globl	errata_dsu_798953_wa
+	.globl	dsu_pwr_dwn
 
 func check_errata_dsu_798953
 	mov	x2, #ERRATA_APPLIES
@@ -151,13 +152,22 @@ endfunc errata_dsu_936184_wa
 	 * This function is called from both assembly and C environment. So it
 	 * follows AAPCS.
 	 *
-	 * Clobbers: x0-x3
+	 * Clobbers: x0-x4
 	 * -----------------------------------------------------------------------
 	 */
 	.globl	check_errata_dsu_2313941
 	.globl	errata_dsu_2313941_wa
 
 func check_errata_dsu_2313941
+	mov	x4, x30
+	bl	is_scu_present_in_dsu
+	cmp	x0, xzr
+	/* Default error status */
+	mov	x0, #ERRATA_NOT_APPLIES
+
+	/* If SCU is not present, return without applying patch */
+	b.eq	1f
+
 	mov	x2, #ERRATA_APPLIES
 	mov	x3, #ERRATA_NOT_APPLIES
 
@@ -170,7 +180,8 @@ func check_errata_dsu_2313941
 	mov	x1, #(0x31 << CLUSTERIDR_REV_SHIFT)
 	cmp	x0, x1
 	csel	x0, x2, x3, LS
-	ret
+1:
+	ret	x4
 endfunc check_errata_dsu_2313941
 
 	/* --------------------------------------------------
@@ -192,3 +203,15 @@ func errata_dsu_2313941_wa
 1:
 	ret	x8
 endfunc errata_dsu_2313941_wa
+
+	/* ---------------------------------------------
+	 * controls power features of the cluster
+	 * 1. Cache portion power not request
+	 * 2. Disable the retention circuit
+	 * ---------------------------------------------
+	 */
+func dsu_pwr_dwn
+	msr	CLUSTERPWRCTLR_EL1, xzr
+	isb
+	ret
+endfunc dsu_pwr_dwn
diff --git a/lib/cpus/aarch64/generic.S b/lib/cpus/aarch64/generic.S
index ef1f048a..5d7a857e 100644
--- a/lib/cpus/aarch64/generic.S
+++ b/lib/cpus/aarch64/generic.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -79,7 +79,6 @@ endfunc generic_cluster_pwr_dwn
  * Unimplemented functions.
  * ---------------------------------------------
  */
-.equ	generic_errata_report,		0
 .equ	generic_cpu_reg_dump,		0
 .equ	generic_reset_func,		0
 
diff --git a/lib/cpus/aarch64/neoverse_e1.S b/lib/cpus/aarch64/neoverse_e1.S
index 45bd8d31..4bc95d05 100644
--- a/lib/cpus/aarch64/neoverse_e1.S
+++ b/lib/cpus/aarch64/neoverse_e1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,8 +42,6 @@ func neoverse_e1_cpu_pwr_dwn
 	ret
 endfunc neoverse_e1_cpu_pwr_dwn
 
-errata_report_shim neoverse_e1
-
 .section .rodata.neoverse_e1_regs, "aS"
 neoverse_e1_regs:  /* The ascii list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index 36a7ee75..f727226b 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -236,14 +236,12 @@ func neoverse_n1_core_pwr_dwn
 	 */
 	sysreg_bit_set NEOVERSE_N1_CPUPWRCTLR_EL1, NEOVERSE_N1_CORE_PWRDN_EN_MASK
 
-	apply_erratum neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102
+	apply_erratum neoverse_n1, ERRATUM(2743102), ERRATA_N1_2743102, NO_GET_CPU_REV
 
 	isb
 	ret
 endfunc neoverse_n1_core_pwr_dwn
 
-errata_report_shim neoverse_n1
-
 /*
  * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB
  * inner-shareable invalidation to an arbitrary address followed by a DSB.
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 477522fe..d2237f1c 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -252,9 +252,9 @@ cpu_reset_func_start neoverse_n2
 
 #if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
-	sysreg_bit_set cptr_el3, TAM_BIT
+	sysreg_bit_clear cptr_el3, TAM_BIT
 	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
-	sysreg_bit_set cptr_el2, TAM_BIT
+	sysreg_bit_clear cptr_el2, TAM_BIT
 	/* No need to enable the counters as this would be done at el3 exit */
 #endif
 
@@ -265,8 +265,7 @@ cpu_reset_func_start neoverse_n2
 cpu_reset_func_end neoverse_n2
 
 func neoverse_n2_core_pwr_dwn
-
-	apply_erratum neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478
+	apply_erratum neoverse_n2, ERRATUM(2009478), ERRATA_N2_2009478, NO_GET_CPU_REV
 	apply_erratum neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639, NO_GET_CPU_REV
 
 	/* ---------------------------------------------------
@@ -276,14 +275,12 @@ func neoverse_n2_core_pwr_dwn
 	 */
 	sysreg_bit_set NEOVERSE_N2_CPUPWRCTLR_EL1, NEOVERSE_N2_CORE_PWRDN_EN_BIT
 
-	apply_erratum neoverse_n2, ERRATUM(2743089), ERRATA_N2_2743089
+	apply_erratum neoverse_n2, ERRATUM(2743089), ERRATA_N2_2743089, NO_GET_CPU_REV
 
 	isb
 	ret
 endfunc neoverse_n2_core_pwr_dwn
 
-errata_report_shim neoverse_n2
-
 	/* ---------------------------------------------
 	 * This function provides Neoverse N2 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/neoverse_n3.S b/lib/cpus/aarch64/neoverse_n3.S
new file mode 100644
index 00000000..d96c9d46
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_n3.S
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <neoverse_n3.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse-N3 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Neoverse-N3 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start neoverse_n3
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+
+#if NEOVERSE_Nx_EXTERNAL_LLC
+	/* Some systems may have External LLC, core needs to be made aware */
+	sysreg_bit_set NEOVERSE_N3_CPUECTLR_EL1, NEOVERSE_N3_CPUECTLR_EL1_EXTLLC_BIT
+#endif
+cpu_reset_func_end neoverse_n3
+
+	/* ----------------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ----------------------------------------------------
+	 */
+func neoverse_n3_core_pwr_dwn
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set NEOVERSE_N3_CPUPWRCTLR_EL1, NEOVERSE_N3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	isb
+	ret
+endfunc neoverse_n3_core_pwr_dwn
+
+	/* ---------------------------------------------
+	 * This function provides Neoverse-N3 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.neoverse_n3_regs, "aS"
+neoverse_n3_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func neoverse_n3_cpu_reg_dump
+	adr	x6, neoverse_n3_regs
+	mrs	x8, NEOVERSE_N3_CPUECTLR_EL1
+	ret
+endfunc neoverse_n3_cpu_reg_dump
+
+declare_cpu_ops neoverse_n3, NEOVERSE_N3_MIDR, \
+	neoverse_n3_reset_func, \
+	neoverse_n3_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_poseidon.S b/lib/cpus/aarch64/neoverse_poseidon.S
deleted file mode 100644
index 3b3245d8..00000000
--- a/lib/cpus/aarch64/neoverse_poseidon.S
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <neoverse_poseidon.h>
-#include <cpu_macros.S>
-#include <plat_macros.S>
-#include "wa_cve_2022_23960_bhb_vector.S"
-
-/* Hardware handled coherency */
-#if HW_ASSISTED_COHERENCY == 0
-#error "Neoverse Poseidon must be compiled with HW_ASSISTED_COHERENCY enabled"
-#endif
-
-/* 64-bit only core */
-#if CTX_INCLUDE_AARCH32_REGS == 1
-#error "Neoverse Poseidon supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
-#endif
-
-#if WORKAROUND_CVE_2022_23960
-	wa_cve_2022_23960_bhb_vector_table NEOVERSE_POSEIDON_BHB_LOOP_COUNT, neoverse_poseidon
-#endif /* WORKAROUND_CVE_2022_23960 */
-
-workaround_reset_start neoverse_poseidon, CVE(2022,23960), WORKAROUND_CVE_2022_23960
-#if IMAGE_BL31
-	/*
-	 * The Neoverse-poseidon generic vectors are overridden to apply errata
-         * mitigation on exception entry from lower ELs.
-	 */
-	override_vector_table wa_cve_vbar_neoverse_poseidon
-
-#endif /* IMAGE_BL31 */
-workaround_reset_end neoverse_poseidon, CVE(2022,23960)
-
-check_erratum_chosen neoverse_poseidon, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
-
-	/* ---------------------------------------------
-	 * HW will do the cache maintenance while powering down
-	 * ---------------------------------------------
-	 */
-func neoverse_poseidon_core_pwr_dwn
-	/* ---------------------------------------------
-	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------
-	 */
-	sysreg_bit_set NEOVERSE_POSEIDON_CPUPWRCTLR_EL1, \
-		NEOVERSE_POSEIDON_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-
-	isb
-	ret
-endfunc neoverse_poseidon_core_pwr_dwn
-
-cpu_reset_func_start neoverse_poseidon
-	/* Disable speculative loads */
-	msr	SSBS, xzr
-cpu_reset_func_end neoverse_poseidon
-
-errata_report_shim neoverse_poseidon
-
-	/* ---------------------------------------------
-	 * This function provides Neoverse-Poseidon specific
-	 * register information for crash reporting.
-	 * It needs to return with x6 pointing to
-	 * a list of register names in ascii and
-	 * x8 - x15 having values of registers to be
-	 * reported.
-	 * ---------------------------------------------
-	 */
-.section .rodata.neoverse_poseidon_regs, "aS"
-neoverse_poseidon_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", ""
-
-func neoverse_poseidon_cpu_reg_dump
-	adr	x6, neoverse_poseidon_regs
-	mrs	x8, NEOVERSE_POSEIDON_CPUECTLR_EL1
-	ret
-endfunc neoverse_poseidon_cpu_reg_dump
-
-declare_cpu_ops neoverse_poseidon, NEOVERSE_POSEIDON_MIDR, \
-	neoverse_poseidon_reset_func, \
-	neoverse_poseidon_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 2a49134f..1ec3e944 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -196,6 +196,13 @@ workaround_reset_end neoverse_v1, ERRATUM(2294912)
 
 check_erratum_ls neoverse_v1, ERRATUM(2294912), CPU_REV(1, 2)
 
+workaround_runtime_start neoverse_v1, ERRATUM(2348377), ERRATA_V1_2348377
+	/* Set bit 61 in CPUACTLR5_EL1 */
+	sysreg_bit_set NEOVERSE_V1_ACTLR5_EL1, NEOVERSE_V1_ACTLR5_EL1_BIT_61
+workaround_runtime_end neoverse_v1, ERRATUM(2348377)
+
+check_erratum_ls neoverse_v1, ERRATUM(2348377), CPU_REV(1, 1)
+
 workaround_reset_start neoverse_v1, ERRATUM(2372203), ERRATA_V1_2372203
 	/* Set bit 40 in ACTLR2_EL1 */
 	sysreg_bit_set NEOVERSE_V1_ACTLR2_EL1, NEOVERSE_V1_ACTLR2_EL1_BIT_40
@@ -246,14 +253,12 @@ func neoverse_v1_core_pwr_dwn
 	 * ---------------------------------------------
 	 */
 	sysreg_bit_set NEOVERSE_V1_CPUPWRCTLR_EL1, NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	apply_erratum neoverse_v1, ERRATUM(2743093), ERRATA_V1_2743093
+	apply_erratum neoverse_v1, ERRATUM(2743093), ERRATA_V1_2743093, NO_GET_CPU_REV
 
 	isb
 	ret
 endfunc neoverse_v1_core_pwr_dwn
 
-errata_report_shim neoverse_v1
-
 cpu_reset_func_start neoverse_v1
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/aarch64/neoverse_v2.S b/lib/cpus/aarch64/neoverse_v2.S
index bfd088d5..ca66f8dd 100644
--- a/lib/cpus/aarch64/neoverse_v2.S
+++ b/lib/cpus/aarch64/neoverse_v2.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,6 +29,25 @@ workaround_reset_end neoverse_v2, ERRATUM(2331132)
 
 check_erratum_ls neoverse_v2, ERRATUM(2331132), CPU_REV(0, 2)
 
+workaround_reset_start neoverse_v2, ERRATUM(2618597), ERRATA_V2_2618597
+        /* Disable retention control for WFI and WFE. */
+        mrs     x0, NEOVERSE_V2_CPUPWRCTLR_EL1
+        bfi     x0, xzr, #NEOVERSE_V2_CPUPWRCTLR_EL1_WFI_RET_CTRL_SHIFT, \
+		#NEOVERSE_V2_CPUPWRCTLR_EL1_WFI_RET_CTRL_WIDTH
+        bfi     x0, xzr, #NEOVERSE_V2_CPUPWRCTLR_EL1_WFE_RET_CTRL_SHIFT, \
+		#NEOVERSE_V2_CPUPWRCTLR_EL1_WFE_RET_CTRL_WIDTH
+        msr     NEOVERSE_V2_CPUPWRCTLR_EL1, x0
+workaround_reset_end neoverse_v2, ERRATUM(2618597)
+
+check_erratum_ls neoverse_v2, ERRATUM(2618597), CPU_REV(0, 1)
+
+workaround_reset_start neoverse_v2, ERRATUM(2662553), ERRATA_V2_2662553
+	sysreg_bitfield_insert NEOVERSE_V2_CPUECTLR2_EL1, NEOVERSE_V2_CPUECTLR2_EL1_TXREQ_STATIC_FULL, \
+		NEOVERSE_V2_CPUECTLR2_EL1_TXREQ_LSB, NEOVERSE_V2_CPUECTLR2_EL1_TXREQ_WIDTH
+workaround_reset_end neoverse_v2, ERRATUM(2662553)
+
+check_erratum_ls neoverse_v2, ERRATUM(2662553), CPU_REV(0, 1)
+
 workaround_reset_start neoverse_v2, ERRATUM(2719105), ERRATA_V2_2719105
 	sysreg_bit_set NEOVERSE_V2_CPUACTLR2_EL1, NEOVERSE_V2_CPUACTLR2_EL1_BIT_0
 workaround_reset_end neoverse_v2, ERRATUM(2719105)
@@ -81,7 +100,7 @@ func neoverse_v2_core_pwr_dwn
 	 * ---------------------------------------------------
 	 */
 	sysreg_bit_set NEOVERSE_V2_CPUPWRCTLR_EL1, NEOVERSE_V2_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
-	apply_erratum neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372
+	apply_erratum neoverse_v2, ERRATUM(2801372), ERRATA_V2_2801372, NO_GET_CPU_REV
 
 	isb
 	ret
@@ -90,9 +109,13 @@ endfunc neoverse_v2_core_pwr_dwn
 cpu_reset_func_start neoverse_v2
 	/* Disable speculative loads */
 	msr	SSBS, xzr
+
+#if NEOVERSE_Vx_EXTERNAL_LLC
+	/* Some systems may have External LLC, core needs to be made aware */
+	sysreg_bit_set NEOVERSE_V2_CPUECTLR_EL1, NEOVERSE_V2_CPUECTLR_EL1_EXTLLC_BIT
+#endif
 cpu_reset_func_end neoverse_v2
 
-errata_report_shim neoverse_v2
 	/* ---------------------------------------------
 	 * This function provides Neoverse V2-
 	 * specific register information for crash
diff --git a/lib/cpus/aarch64/neoverse_v3.S b/lib/cpus/aarch64/neoverse_v3.S
new file mode 100644
index 00000000..01ac38f1
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_v3.S
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <neoverse_v3.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse V3 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Neoverse V3 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table NEOVERSE_V3_BHB_LOOP_COUNT, neoverse_v3
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+workaround_reset_start neoverse_v3, CVE(2022,23960), WORKAROUND_CVE_2022_23960
+#if IMAGE_BL31
+	/*
+	 * The Neoverse V3 generic vectors are overridden to apply errata
+         * mitigation on exception entry from lower ELs.
+	 */
+	override_vector_table wa_cve_vbar_neoverse_v3
+
+#endif /* IMAGE_BL31 */
+workaround_reset_end neoverse_v3, CVE(2022,23960)
+
+check_erratum_chosen neoverse_v3, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
+
+	/* ---------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ---------------------------------------------
+	 */
+func neoverse_v3_core_pwr_dwn
+	/* ---------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------
+	 */
+	sysreg_bit_set NEOVERSE_V3_CPUPWRCTLR_EL1, \
+		NEOVERSE_V3_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+
+	isb
+	ret
+endfunc neoverse_v3_core_pwr_dwn
+
+cpu_reset_func_start neoverse_v3
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+cpu_reset_func_end neoverse_v3
+
+	/* ---------------------------------------------
+	 * This function provides Neoverse V3 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.neoverse_v3_regs, "aS"
+neoverse_v3_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func neoverse_v3_cpu_reg_dump
+	adr	x6, neoverse_v3_regs
+	mrs	x8, NEOVERSE_V3_CPUECTLR_EL1
+	ret
+endfunc neoverse_v3_cpu_reg_dump
+
+declare_cpu_ops neoverse_v3, NEOVERSE_V3_VNAE_MIDR, \
+	neoverse_v3_reset_func, \
+	neoverse_v3_core_pwr_dwn
+
+declare_cpu_ops neoverse_v3, NEOVERSE_V3_MIDR, \
+	neoverse_v3_reset_func, \
+	neoverse_v3_core_pwr_dwn
diff --git a/lib/cpus/aarch64/nevis.S b/lib/cpus/aarch64/nevis.S
index 36830a9b..0180ab7d 100644
--- a/lib/cpus/aarch64/nevis.S
+++ b/lib/cpus/aarch64/nevis.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -40,8 +40,6 @@ func nevis_core_pwr_dwn
 	ret
 endfunc nevis_core_pwr_dwn
 
-errata_report_shim nevis
-
 .section .rodata.nevis_regs, "aS"
 nevis_regs: /* The ASCII list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
diff --git a/lib/cpus/aarch64/qemu_max.S b/lib/cpus/aarch64/qemu_max.S
index 00963bc3..fb03cf15 100644
--- a/lib/cpus/aarch64/qemu_max.S
+++ b/lib/cpus/aarch64/qemu_max.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,8 +47,6 @@ func qemu_max_cluster_pwr_dwn
 	b	dcsw_op_all
 endfunc qemu_max_cluster_pwr_dwn
 
-errata_report_shim qemu_max
-
 	/* ---------------------------------------------
 	 * This function provides cpu specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/rainier.S b/lib/cpus/aarch64/rainier.S
index c770f54f..ea687be6 100644
--- a/lib/cpus/aarch64/rainier.S
+++ b/lib/cpus/aarch64/rainier.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,8 +80,6 @@ func rainier_core_pwr_dwn
 	ret
 endfunc rainier_core_pwr_dwn
 
-errata_report_shim rainier
-
 	/* ---------------------------------------------
 	 * This function provides Rainier specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/travis.S b/lib/cpus/aarch64/travis.S
index 2abefe94..e8b3860b 100644
--- a/lib/cpus/aarch64/travis.S
+++ b/lib/cpus/aarch64/travis.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,7 +38,7 @@ func travis_core_pwr_dwn
 	mrs     x0, ID_AA64PFR1_EL1
 	ubfx	x0, x0, #ID_AA64PFR1_EL1_SME_SHIFT, \
 		#ID_AA64PFR1_EL1_SME_WIDTH
-        cmp     x0, #ID_AA64PFR1_EL1_SME_NOT_SUPPORTED
+        cmp     x0, #SME_NOT_IMPLEMENTED
 	b.eq	1f
 	msr	TRAVIS_SVCRSM, xzr
 	msr	TRAVIS_SVCRZA, xzr
@@ -54,8 +54,6 @@ func travis_core_pwr_dwn
 	ret
 endfunc travis_core_pwr_dwn
 
-errata_report_shim travis
-
 .section .rodata.travis_regs, "aS"
 travis_regs: /* The ASCII list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 434ee081..4c207850 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -388,11 +388,19 @@ CPU_FLAG_LIST += ERRATA_A78C_2376749
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
 CPU_FLAG_LIST += ERRATA_A78C_2395411
 
+# Flag to apply erratum 2683027 workaround during reset. This erratum applies
+# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
+CPU_FLAG_LIST += ERRATA_A78C_2683027
+
 # Flag to apply erratum 2712575 workaround for non-arm interconnect ip. This
 # erratum applies to revisions r0p1 and r0p2 of the A78C cpu.
 # It is still open.
 CPU_FLAG_LIST += ERRATA_A78C_2712575
 
+# Flag to apply erratum 2743232 workaround during reset. This erratum applies
+# to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
+CPU_FLAG_LIST += ERRATA_A78C_2743232
+
 # Flag to apply erratum 2772121 workaround during powerdown. This erratum
 # applies to revisions r0p0, r0p1 and r0p2 of the A78C cpu. It is still open.
 CPU_FLAG_LIST += ERRATA_A78C_2772121
@@ -520,6 +528,10 @@ CPU_FLAG_LIST += ERRATA_V1_2216392
 # to revisions r0p0, r1p0, and r1p1 and r1p2 of the Neoverse V1 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_V1_2294912
 
+# Flag to apply erratum 2348377 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0 and r1p1 of the Neoverse V1 cpu and is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_V1_2348377
+
 # Flag to apply erratum 2372203 workaround during reset. This erratum applies
 # to revisions r0p0, r1p0 and r1p1 of the Neoverse V1 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_V1_2372203
@@ -617,6 +629,11 @@ CPU_FLAG_LIST += ERRATA_A710_2742423
 # still open.
 CPU_FLAG_LIST += ERRATA_A710_2768515
 
+# Flag to apply erratum 2778471 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r2p0, r2p1 of the Cortex-A710 cpu and is still
+# open.
+CPU_FLAG_LIST += ERRATA_A710_2778471
+
 # Flag to apply erratum 2002655 workaround during reset. This erratum applies
 # to revisions r0p0 of the Neoverse-N2 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2002655
@@ -752,23 +769,84 @@ CPU_FLAG_LIST += ERRATA_X2_2742423
 # still open.
 CPU_FLAG_LIST += ERRATA_X2_2768515
 
+# Flag to apply erratum 2778471 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r2p0, r2p1 of the Cortex-X2 cpu and it is still open.
+CPU_FLAG_LIST += ERRATA_X2_2778471
+
 # Flag to apply erratum 2070301 workaround on reset. This erratum applies
 # to revisions r0p0, r1p0, r1p1 and r1p2 of the Cortex-X3 cpu and is
 # still open.
 CPU_FLAG_LIST += ERRATA_X3_2070301
 
+# Flag to apply erratum 2266875 workaround during reset. This erratum applies
+# to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_X3_2266875
+
+# Flag to apply erratum 2302506 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0 and r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_X3_2302506
+
 # Flag to apply erratum 2313909 workaround on powerdown. This erratum applies
 # to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
 CPU_FLAG_LIST += ERRATA_X3_2313909
 
+# Flag to apply erratum 2372204 workaround during reset. This erratum applies
+# to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_X3_2372204
+
 # Flag to apply erratum 2615812 workaround on powerdown. This erratum applies
-# to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is still open.
+# to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_X3_2615812
 
+# Flag to apply erratum 2641945 workaround on reset. This erratum applies
+# to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_X3_2641945
+
+# Flag to apply erratum 2701951 workaround for non-arm interconnect ip.
+# This erratum applies to revisions r0p0, r1p0, and r1p1. Its is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_X3_2701951
+
 # Flag to apply erratum 2742421 workaround on reset. This erratum applies
 # to revisions r0p0, r1p0 and r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_X3_2742421
 
+# Flag to apply erratum 2743088 workaround on powerdown. This erratum applies
+# to revisions r0p0, r1p0 and r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_X3_2743088
+
+# Flag to apply erratum 2779509 workaround on reset. This erratum applies
+# to revisions r0p0, r1p0, r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_X3_2779509
+
+# Flag to apply erratum 2701112 workaround for platforms that do not use an
+# Arm interconnect IP. This erratum applies to revisions r0p0 of the Cortex-X4
+# cpu and is fixed in r0p1.
+CPU_FLAG_LIST += ERRATA_X4_2701112
+
+# Flag to apply erratum 2726228 workaround during warmboot. This erratum
+# applies to all revisions <= r0p1 of the Cortex-X4 cpu, it is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2726228
+
+# Flag to apply erratum 2740089 workaround during powerdown. This erratum
+# applies to all revisions <= r0p1 of the Cortex-X4 cpu, it is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2740089
+
+# Flag to apply erratum 2763018 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2763018
+
+# Flag to apply erratum 2816013 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2816013
+
+# Flag to apply erratum 2897503 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2897503
+
+# Flag to apply erratum 3076789 workaround on reset. This erratum applies
+# to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_3076789
+
 # Flag to apply erratum 1922240 workaround during reset. This erratum applies
 # to revision r0p0 of the Cortex-A510 cpu and is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_A510_1922240
@@ -822,10 +900,30 @@ CPU_FLAG_LIST += ERRATA_A510_2666669
 # Cortex-A510 cpu and is fixed in r1p3.
 CPU_FLAG_LIST += ERRATA_A510_2684597
 
+# Flag to apply erratum 2630792 workaround during reset. This erratum applies
+# to revisions r0p0, r0p1 of the Cortex-A520 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_A520_2630792
+
+# Flag to apply erratum 2858100 workaround during reset. This erratum
+# applies to revision r0p0 and r0p1 of the Cortex-A520 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_A520_2858100
+
+# Flag to apply erratum 2938996 workaround during reset. This erratum
+# applies to revision r0p0 and r0p1 of the Cortex-A520 cpu and is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A520_2938996
+
 # Flag to apply erratum 2331132 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1 and r0p2. It is still open.
 CPU_FLAG_LIST += ERRATA_V2_2331132
 
+# Flag to apply erratum 2618597 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_V2_2618597
+
+# Flag to apply erratum 2662553 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_V2_2662553
+
 # Flag to apply erratum 2719103 workaround for non-arm interconnect ip. This
 # erratum applies to revisions r0p0, rop1. Fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_V2_2719103
@@ -846,9 +944,49 @@ CPU_FLAG_LIST += ERRATA_V2_2779510
 # This erratum applies to revisions r0p0, r0p1. Fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_V2_2801372
 
-# Flag to apply erratum 2701951 workaround for non-arm interconnect ip.
-# This erratum applies to revisions r0p0, r1p0, and r1p1. Its is fixed in r1p2.
-CPU_FLAG_LIST += ERRATA_A715_2701951
+# Flag to apply erratum 2331818 workaround during reset. This erratum applies
+# to revisions r0p0 and r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2331818
+
+# Flag to apply erratum 2344187 workaround during reset. This erratum applies
+# to revisions r0p0, and r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2344187
+
+# Flag to apply erratum 2413290 workaround during reset. This erratum applies
+# only to revision r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2413290
+
+# Flag to apply erratum 2420947 workaround during reset. This erratum applies
+# only to revision r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2420947
+
+# Flag to apply erratum 2429384 workaround during reset. This erratum applies
+# to revision r1p0. There is no workaround for r0p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2429384
+
+# Flag to apply erratum 2561034 workaround during reset. This erratum applies
+# only to revision r1p0. It is fixed in r1p1.
+CPU_FLAG_LIST += ERRATA_A715_2561034
+
+# Flag to apply erratum 2728106 workaround during reset. This erratum applies
+# only to revision r0p0, r1p0 and r1p1. It is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_A715_2728106
+
+# Flag to apply erratum 2792132 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A720_2792132
+
+# Flag to apply erratum 2844092 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A720_2844092
+
+# Flag to apply erratum 2926083 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A720_2926083
+
+# Flag to apply erratum 2940794 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1. It is fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_A720_2940794
 
 # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
 # Applying the workaround results in higher DSU power consumption on idle.
diff --git a/lib/cpus/errata_common.c b/lib/cpus/errata_common.c
new file mode 100644
index 00000000..a4515a9e
--- /dev/null
+++ b/lib/cpus/errata_common.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Runtime C routines for errata workarounds and common routines */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <cortex_a520.h>
+#include <cortex_x4.h>
+#include <cortex_a75.h>
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
+
+#if ERRATA_A520_2938996 || ERRATA_X4_2726228
+unsigned int check_if_affected_core(void)
+{
+	uint32_t midr_val = read_midr();
+	long rev_var  = cpu_get_rev_var();
+
+	if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(CORTEX_A520_MIDR)) {
+		return check_erratum_cortex_a520_2938996(rev_var);
+	} else if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(CORTEX_X4_MIDR)) {
+		return check_erratum_cortex_x4_2726228(rev_var);
+	}
+
+	return ERRATA_NOT_APPLIES;
+}
+#endif
+
+#if ERRATA_A75_764081
+bool errata_a75_764081_applies(void)
+{
+	long rev_var = cpu_get_rev_var();
+	if (check_erratum_cortex_a75_764081(rev_var) == ERRATA_APPLIES) {
+		return true;
+	}
+	return false;
+}
+#endif /* ERRATA_A75_764081 */
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index 4e9bdfc5..e0a9076e 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -51,9 +51,9 @@ static __unused void print_status(int status, char *cpu_str, uint16_t cve, uint3
 		}
 	} else {
 		if (cve) {
-			VERBOSE(CVE_FORMAT, BL_STRING, cpu_str, cve, id, "not applied");
+			VERBOSE(CVE_FORMAT, BL_STRING, cpu_str, cve, id, "not applicable");
 		}  else {
-			VERBOSE(ERRATUM_FORMAT, BL_STRING, cpu_str, id, "not applied");
+			VERBOSE(ERRATUM_FORMAT, BL_STRING, cpu_str, id, "not applicable");
 		}
 	}
 }
@@ -67,7 +67,7 @@ void print_errata_status(void) {}
  * save space. This functionality is only useful on development and platform
  * bringup builds, when FEATURE_DETECTION should be used anyway
  */
-void __unused generic_errata_report(void)
+void generic_errata_report(void)
 {
 	struct cpu_ops *cpu_ops = get_cpu_ops_ptr();
 	struct erratum_entry *entry = cpu_ops->errata_list_start;
@@ -159,70 +159,16 @@ static __unused int errata_needs_reporting(spinlock_t *lock, uint32_t *reported)
  */
 void print_errata_status(void)
 {
-	struct cpu_ops *cpu_ops;
 #ifdef IMAGE_BL1
-	/*
-	 * BL1 doesn't have per-CPU data. So retrieve the CPU operations
-	 * directly.
-	 */
-	cpu_ops = get_cpu_ops_ptr();
-
-	if (cpu_ops->errata_func != NULL) {
-		cpu_ops->errata_func();
-	}
+	generic_errata_report();
 #else /* IMAGE_BL1 */
-	cpu_ops = (void *) get_cpu_data(cpu_ops_ptr);
+	struct cpu_ops *cpu_ops = (void *) get_cpu_data(cpu_ops_ptr);
 
 	assert(cpu_ops != NULL);
 
-	if (cpu_ops->errata_func == NULL) {
-		return;
-	}
-
 	if (errata_needs_reporting(cpu_ops->errata_lock, cpu_ops->errata_reported)) {
-		cpu_ops->errata_func();
+		generic_errata_report();
 	}
 #endif /* IMAGE_BL1 */
 }
-
-/*
- * Old errata status message printer
- * TODO: remove once all cpus have been converted to the new printing method
- */
-void __unused errata_print_msg(unsigned int status, const char *cpu, const char *id)
-{
-	/* Errata status strings */
-	static const char *const errata_status_str[] = {
-		[ERRATA_NOT_APPLIES] = "not applied",
-		[ERRATA_APPLIES] = "applied",
-		[ERRATA_MISSING] = "missing!"
-	};
-	static const char *const __unused bl_str = BL_STRING;
-	const char *msg __unused;
-
-
-	assert(status < ARRAY_SIZE(errata_status_str));
-	assert(cpu != NULL);
-	assert(id != NULL);
-
-	msg = errata_status_str[status];
-
-	switch (status) {
-	case ERRATA_NOT_APPLIES:
-		VERBOSE(ERRATA_FORMAT, bl_str, cpu, id, msg);
-		break;
-
-	case ERRATA_APPLIES:
-		INFO(ERRATA_FORMAT, bl_str, cpu, id, msg);
-		break;
-
-	case ERRATA_MISSING:
-		WARN(ERRATA_FORMAT, bl_str, cpu, id, msg);
-		break;
-
-	default:
-		WARN(ERRATA_FORMAT, bl_str, cpu, id, "unknown");
-		break;
-	}
-}
 #endif /* !REPORT_ERRATA */
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index b60b8e0f..132888cf 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -149,14 +149,13 @@ static void enable_extensions_nonsecure(bool el2_unused)
 		trf_init_el3();
 	}
 
-	/*
-	 * Also applies to PMU < v3. The PMU is only disabled for EL3 and Secure
-	 * state execution. This does not affect lower NS ELs.
-	 */
-	pmuv3_init_el3();
+	if (is_feat_pmuv3_present()) {
+		pmuv3_init_el3();
+	}
 #endif /*  IMAGE_BL32 */
 }
 
+#if !IMAGE_BL1
 /*******************************************************************************
  * The following function initializes the cpu_context for a CPU specified by
  * its `cpu_idx` for first use, and sets the initial entrypoint state as
@@ -169,6 +168,7 @@ void cm_init_context_by_index(unsigned int cpu_idx,
 	ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr));
 	cm_setup_context(ctx, ep);
 }
+#endif /* !IMAGE_BL1 */
 
 /*******************************************************************************
  * The following function initializes the cpu_context for the current CPU
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 631094f7..a353a87d 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,216 +9,55 @@
 #include <assert_macros.S>
 #include <context.h>
 #include <el3_common_macros.S>
+#include <platform_def.h>
 
-	.global	el1_sysregs_context_save
-	.global	el1_sysregs_context_restore
 #if CTX_INCLUDE_FPREGS
 	.global	fpregs_context_save
 	.global	fpregs_context_restore
 #endif /* CTX_INCLUDE_FPREGS */
-	.global	prepare_el3_entry
-	.global	restore_gp_pmcr_pauth_regs
-	.global save_and_update_ptw_el1_sys_regs
-	.global	el3_exit
 
+#if CTX_INCLUDE_SVE_REGS
+	.global sve_context_save
+	.global sve_context_restore
+#endif /* CTX_INCLUDE_SVE_REGS */
 
-/* ------------------------------------------------------------------
- * The following function strictly follows the AArch64 PCS to use
- * x9-x17 (temporary caller-saved registers) to save EL1 system
- * register context. It assumes that 'x0' is pointing to a
- * 'el1_sys_regs' structure where the register context will be saved.
- * ------------------------------------------------------------------
- */
-func el1_sysregs_context_save
+#if ERRATA_SPECULATIVE_AT
+	.global save_and_update_ptw_el1_sys_regs
+#endif /* ERRATA_SPECULATIVE_AT */
 
-	mrs	x9, spsr_el1
-	mrs	x10, elr_el1
-	stp	x9, x10, [x0, #CTX_SPSR_EL1]
+	.global	prepare_el3_entry
+	.global	restore_gp_pmcr_pauth_regs
+	.global	el3_exit
 
-#if !ERRATA_SPECULATIVE_AT
-	mrs	x15, sctlr_el1
-	mrs	x16, tcr_el1
-	stp	x15, x16, [x0, #CTX_SCTLR_EL1]
-#endif /* ERRATA_SPECULATIVE_AT */
+/* Following macros will be used if any of CTX_INCLUDE_FPREGS or CTX_INCLUDE_SVE_REGS is enabled */
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+.macro fpregs_state_save base:req hold:req
+	mrs	\hold, fpsr
+	str	\hold, [\base, #CTX_SIMD_FPSR]
 
-	mrs	x17, cpacr_el1
-	mrs	x9, csselr_el1
-	stp	x17, x9, [x0, #CTX_CPACR_EL1]
-
-	mrs	x10, sp_el1
-	mrs	x11, esr_el1
-	stp	x10, x11, [x0, #CTX_SP_EL1]
-
-	mrs	x12, ttbr0_el1
-	mrs	x13, ttbr1_el1
-	stp	x12, x13, [x0, #CTX_TTBR0_EL1]
-
-	mrs	x14, mair_el1
-	mrs	x15, amair_el1
-	stp	x14, x15, [x0, #CTX_MAIR_EL1]
-
-	mrs	x16, actlr_el1
-	mrs	x17, tpidr_el1
-	stp	x16, x17, [x0, #CTX_ACTLR_EL1]
-
-	mrs	x9, tpidr_el0
-	mrs	x10, tpidrro_el0
-	stp	x9, x10, [x0, #CTX_TPIDR_EL0]
-
-	mrs	x13, par_el1
-	mrs	x14, far_el1
-	stp	x13, x14, [x0, #CTX_PAR_EL1]
-
-	mrs	x15, afsr0_el1
-	mrs	x16, afsr1_el1
-	stp	x15, x16, [x0, #CTX_AFSR0_EL1]
-
-	mrs	x17, contextidr_el1
-	mrs	x9, vbar_el1
-	stp	x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
-
-	/* Save AArch32 system registers if the build has instructed so */
-#if CTX_INCLUDE_AARCH32_REGS
-	mrs	x11, spsr_abt
-	mrs	x12, spsr_und
-	stp	x11, x12, [x0, #CTX_SPSR_ABT]
-
-	mrs	x13, spsr_irq
-	mrs	x14, spsr_fiq
-	stp	x13, x14, [x0, #CTX_SPSR_IRQ]
-
-	mrs	x15, dacr32_el2
-	mrs	x16, ifsr32_el2
-	stp	x15, x16, [x0, #CTX_DACR32_EL2]
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-
-	/* Save NS timer registers if the build has instructed so */
-#if NS_TIMER_SWITCH
-	mrs	x10, cntp_ctl_el0
-	mrs	x11, cntp_cval_el0
-	stp	x10, x11, [x0, #CTX_CNTP_CTL_EL0]
-
-	mrs	x12, cntv_ctl_el0
-	mrs	x13, cntv_cval_el0
-	stp	x12, x13, [x0, #CTX_CNTV_CTL_EL0]
-
-	mrs	x14, cntkctl_el1
-	str	x14, [x0, #CTX_CNTKCTL_EL1]
-#endif /* NS_TIMER_SWITCH */
-
-	/* Save MTE system registers if the build has instructed so */
-#if CTX_INCLUDE_MTE_REGS
-	mrs	x15, TFSRE0_EL1
-	mrs	x16, TFSR_EL1
-	stp	x15, x16, [x0, #CTX_TFSRE0_EL1]
-
-	mrs	x9, RGSR_EL1
-	mrs	x10, GCR_EL1
-	stp	x9, x10, [x0, #CTX_RGSR_EL1]
-#endif /* CTX_INCLUDE_MTE_REGS */
+	mrs	\hold, fpcr
+	str	\hold, [\base, #CTX_SIMD_FPCR]
 
-	ret
-endfunc el1_sysregs_context_save
+#if CTX_INCLUDE_AARCH32_REGS && CTX_INCLUDE_FPREGS
+	mrs	\hold, fpexc32_el2
+	str	\hold, [\base, #CTX_SIMD_FPEXC32]
+#endif
+.endm
 
-/* ------------------------------------------------------------------
- * The following function strictly follows the AArch64 PCS to use
- * x9-x17 (temporary caller-saved registers) to restore EL1 system
- * register context.  It assumes that 'x0' is pointing to a
- * 'el1_sys_regs' structure from where the register context will be
- * restored
- * ------------------------------------------------------------------
- */
-func el1_sysregs_context_restore
+.macro fpregs_state_restore base:req hold:req
+	ldr	\hold, [\base, #CTX_SIMD_FPSR]
+	msr	fpsr, \hold
 
-	ldp	x9, x10, [x0, #CTX_SPSR_EL1]
-	msr	spsr_el1, x9
-	msr	elr_el1, x10
+	ldr	\hold, [\base, #CTX_SIMD_FPCR]
+	msr	fpcr, \hold
 
-#if !ERRATA_SPECULATIVE_AT
-	ldp	x15, x16, [x0, #CTX_SCTLR_EL1]
-	msr	sctlr_el1, x15
-	msr	tcr_el1, x16
-#endif /* ERRATA_SPECULATIVE_AT */
+#if CTX_INCLUDE_AARCH32_REGS && CTX_INCLUDE_FPREGS
+	ldr	\hold, [\base, #CTX_SIMD_FPEXC32]
+	msr	fpexc32_el2, \hold
+#endif
+.endm
 
-	ldp	x17, x9, [x0, #CTX_CPACR_EL1]
-	msr	cpacr_el1, x17
-	msr	csselr_el1, x9
-
-	ldp	x10, x11, [x0, #CTX_SP_EL1]
-	msr	sp_el1, x10
-	msr	esr_el1, x11
-
-	ldp	x12, x13, [x0, #CTX_TTBR0_EL1]
-	msr	ttbr0_el1, x12
-	msr	ttbr1_el1, x13
-
-	ldp	x14, x15, [x0, #CTX_MAIR_EL1]
-	msr	mair_el1, x14
-	msr	amair_el1, x15
-
-	ldp 	x16, x17, [x0, #CTX_ACTLR_EL1]
-	msr	actlr_el1, x16
-	msr	tpidr_el1, x17
-
-	ldp	x9, x10, [x0, #CTX_TPIDR_EL0]
-	msr	tpidr_el0, x9
-	msr	tpidrro_el0, x10
-
-	ldp	x13, x14, [x0, #CTX_PAR_EL1]
-	msr	par_el1, x13
-	msr	far_el1, x14
-
-	ldp	x15, x16, [x0, #CTX_AFSR0_EL1]
-	msr	afsr0_el1, x15
-	msr	afsr1_el1, x16
-
-	ldp	x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
-	msr	contextidr_el1, x17
-	msr	vbar_el1, x9
-
-	/* Restore AArch32 system registers if the build has instructed so */
-#if CTX_INCLUDE_AARCH32_REGS
-	ldp	x11, x12, [x0, #CTX_SPSR_ABT]
-	msr	spsr_abt, x11
-	msr	spsr_und, x12
-
-	ldp	x13, x14, [x0, #CTX_SPSR_IRQ]
-	msr	spsr_irq, x13
-	msr	spsr_fiq, x14
-
-	ldp	x15, x16, [x0, #CTX_DACR32_EL2]
-	msr	dacr32_el2, x15
-	msr	ifsr32_el2, x16
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-
-	/* Restore NS timer registers if the build has instructed so */
-#if NS_TIMER_SWITCH
-	ldp	x10, x11, [x0, #CTX_CNTP_CTL_EL0]
-	msr	cntp_ctl_el0, x10
-	msr	cntp_cval_el0, x11
-
-	ldp	x12, x13, [x0, #CTX_CNTV_CTL_EL0]
-	msr	cntv_ctl_el0, x12
-	msr	cntv_cval_el0, x13
-
-	ldr	x14, [x0, #CTX_CNTKCTL_EL1]
-	msr	cntkctl_el1, x14
-#endif /* NS_TIMER_SWITCH */
-
-	/* Restore MTE system registers if the build has instructed so */
-#if CTX_INCLUDE_MTE_REGS
-	ldp	x11, x12, [x0, #CTX_TFSRE0_EL1]
-	msr	TFSRE0_EL1, x11
-	msr	TFSR_EL1, x12
-
-	ldp	x13, x14, [x0, #CTX_RGSR_EL1]
-	msr	RGSR_EL1, x13
-	msr	GCR_EL1, x14
-#endif /* CTX_INCLUDE_MTE_REGS */
-
-	/* No explict ISB required here as ERET covers it */
-	ret
-endfunc el1_sysregs_context_restore
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
 
 /* ------------------------------------------------------------------
  * The following function follows the aapcs_64 strictly to use
@@ -236,33 +75,25 @@ endfunc el1_sysregs_context_restore
  */
 #if CTX_INCLUDE_FPREGS
 func fpregs_context_save
-	stp	q0, q1, [x0, #CTX_FP_Q0]
-	stp	q2, q3, [x0, #CTX_FP_Q2]
-	stp	q4, q5, [x0, #CTX_FP_Q4]
-	stp	q6, q7, [x0, #CTX_FP_Q6]
-	stp	q8, q9, [x0, #CTX_FP_Q8]
-	stp	q10, q11, [x0, #CTX_FP_Q10]
-	stp	q12, q13, [x0, #CTX_FP_Q12]
-	stp	q14, q15, [x0, #CTX_FP_Q14]
-	stp	q16, q17, [x0, #CTX_FP_Q16]
-	stp	q18, q19, [x0, #CTX_FP_Q18]
-	stp	q20, q21, [x0, #CTX_FP_Q20]
-	stp	q22, q23, [x0, #CTX_FP_Q22]
-	stp	q24, q25, [x0, #CTX_FP_Q24]
-	stp	q26, q27, [x0, #CTX_FP_Q26]
-	stp	q28, q29, [x0, #CTX_FP_Q28]
-	stp	q30, q31, [x0, #CTX_FP_Q30]
-
-	mrs	x9, fpsr
-	str	x9, [x0, #CTX_FP_FPSR]
-
-	mrs	x10, fpcr
-	str	x10, [x0, #CTX_FP_FPCR]
-
-#if CTX_INCLUDE_AARCH32_REGS
-	mrs	x11, fpexc32_el2
-	str	x11, [x0, #CTX_FP_FPEXC32_EL2]
-#endif /* CTX_INCLUDE_AARCH32_REGS */
+	stp	q0, q1, [x0], #32
+	stp	q2, q3, [x0], #32
+	stp	q4, q5, [x0], #32
+	stp	q6, q7, [x0], #32
+	stp	q8, q9, [x0], #32
+	stp	q10, q11, [x0], #32
+	stp	q12, q13, [x0], #32
+	stp	q14, q15, [x0], #32
+	stp	q16, q17, [x0], #32
+	stp	q18, q19, [x0], #32
+	stp	q20, q21, [x0], #32
+	stp	q22, q23, [x0], #32
+	stp	q24, q25, [x0], #32
+	stp	q26, q27, [x0], #32
+	stp	q28, q29, [x0], #32
+	stp	q30, q31, [x0], #32
+
+	fpregs_state_save x0, x9
+
 	ret
 endfunc fpregs_context_save
 
@@ -281,51 +112,196 @@ endfunc fpregs_context_save
  * ------------------------------------------------------------------
  */
 func fpregs_context_restore
-	ldp	q0, q1, [x0, #CTX_FP_Q0]
-	ldp	q2, q3, [x0, #CTX_FP_Q2]
-	ldp	q4, q5, [x0, #CTX_FP_Q4]
-	ldp	q6, q7, [x0, #CTX_FP_Q6]
-	ldp	q8, q9, [x0, #CTX_FP_Q8]
-	ldp	q10, q11, [x0, #CTX_FP_Q10]
-	ldp	q12, q13, [x0, #CTX_FP_Q12]
-	ldp	q14, q15, [x0, #CTX_FP_Q14]
-	ldp	q16, q17, [x0, #CTX_FP_Q16]
-	ldp	q18, q19, [x0, #CTX_FP_Q18]
-	ldp	q20, q21, [x0, #CTX_FP_Q20]
-	ldp	q22, q23, [x0, #CTX_FP_Q22]
-	ldp	q24, q25, [x0, #CTX_FP_Q24]
-	ldp	q26, q27, [x0, #CTX_FP_Q26]
-	ldp	q28, q29, [x0, #CTX_FP_Q28]
-	ldp	q30, q31, [x0, #CTX_FP_Q30]
-
-	ldr	x9, [x0, #CTX_FP_FPSR]
-	msr	fpsr, x9
-
-	ldr	x10, [x0, #CTX_FP_FPCR]
-	msr	fpcr, x10
-
-#if CTX_INCLUDE_AARCH32_REGS
-	ldr	x11, [x0, #CTX_FP_FPEXC32_EL2]
-	msr	fpexc32_el2, x11
-#endif /* CTX_INCLUDE_AARCH32_REGS */
-
-	/*
-	 * No explict ISB required here as ERET to
-	 * switch to secure EL1 or non-secure world
-	 * covers it
-	 */
+	ldp	q0, q1, [x0], #32
+	ldp	q2, q3, [x0], #32
+	ldp	q4, q5, [x0], #32
+	ldp	q6, q7, [x0], #32
+	ldp	q8, q9, [x0], #32
+	ldp	q10, q11, [x0], #32
+	ldp	q12, q13, [x0], #32
+	ldp	q14, q15, [x0], #32
+	ldp	q16, q17, [x0], #32
+	ldp	q18, q19, [x0], #32
+	ldp	q20, q21, [x0], #32
+	ldp	q22, q23, [x0], #32
+	ldp	q24, q25, [x0], #32
+	ldp	q26, q27, [x0], #32
+	ldp	q28, q29, [x0], #32
+	ldp	q30, q31, [x0], #32
+
+	fpregs_state_restore x0, x9
 
 	ret
 endfunc fpregs_context_restore
 #endif /* CTX_INCLUDE_FPREGS */
 
+#if CTX_INCLUDE_SVE_REGS
+/*
+ * Helper macros for SVE predicates save/restore operations.
+ */
+.macro sve_predicate_op op:req reg:req
+	\op p0, [\reg, #0, MUL VL]
+	\op p1, [\reg, #1, MUL VL]
+	\op p2, [\reg, #2, MUL VL]
+	\op p3, [\reg, #3, MUL VL]
+	\op p4, [\reg, #4, MUL VL]
+	\op p5, [\reg, #5, MUL VL]
+	\op p6, [\reg, #6, MUL VL]
+	\op p7, [\reg, #7, MUL VL]
+	\op p8, [\reg, #8, MUL VL]
+	\op p9, [\reg, #9, MUL VL]
+	\op p10, [\reg, #10, MUL VL]
+	\op p11, [\reg, #11, MUL VL]
+	\op p12, [\reg, #12, MUL VL]
+	\op p13, [\reg, #13, MUL VL]
+	\op p14, [\reg, #14, MUL VL]
+	\op p15, [\reg, #15, MUL VL]
+.endm
+
+.macro sve_vectors_op op:req reg:req
+	\op z0, [\reg, #0, MUL VL]
+	\op z1, [\reg, #1, MUL VL]
+	\op z2, [\reg, #2, MUL VL]
+	\op z3, [\reg, #3, MUL VL]
+	\op z4, [\reg, #4, MUL VL]
+	\op z5, [\reg, #5, MUL VL]
+	\op z6, [\reg, #6, MUL VL]
+	\op z7, [\reg, #7, MUL VL]
+	\op z8, [\reg, #8, MUL VL]
+	\op z9, [\reg, #9, MUL VL]
+	\op z10, [\reg, #10, MUL VL]
+	\op z11, [\reg, #11, MUL VL]
+	\op z12, [\reg, #12, MUL VL]
+	\op z13, [\reg, #13, MUL VL]
+	\op z14, [\reg, #14, MUL VL]
+	\op z15, [\reg, #15, MUL VL]
+	\op z16, [\reg, #16, MUL VL]
+	\op z17, [\reg, #17, MUL VL]
+	\op z18, [\reg, #18, MUL VL]
+	\op z19, [\reg, #19, MUL VL]
+	\op z20, [\reg, #20, MUL VL]
+	\op z21, [\reg, #21, MUL VL]
+	\op z22, [\reg, #22, MUL VL]
+	\op z23, [\reg, #23, MUL VL]
+	\op z24, [\reg, #24, MUL VL]
+	\op z25, [\reg, #25, MUL VL]
+	\op z26, [\reg, #26, MUL VL]
+	\op z27, [\reg, #27, MUL VL]
+	\op z28, [\reg, #28, MUL VL]
+	\op z29, [\reg, #29, MUL VL]
+	\op z30, [\reg, #30, MUL VL]
+	\op z31, [\reg, #31, MUL VL]
+.endm
+
+/* ------------------------------------------------------------------
+ * The following function follows the aapcs_64 strictly to use x9-x17
+ * (temporary caller-saved registers according to AArch64 PCS) to
+ * restore SVE register context. It assumes that 'x0' is
+ * pointing to a 'sve_regs_t' structure to which the register context
+ * will be saved.
+ * ------------------------------------------------------------------
+ */
+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
+	sve_predicate_op str, x9
+
+	/* Save FFR after predicates */
+	mov x13, #CTX_SIMD_FFR
+	add	x9, x0, x13
+	rdffr   p0.b
+	str	p0, [x9]
+
+	/* Save vector registers */
+	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 */
+	fpregs_state_save x0, x9
+
+	ret
+endfunc sve_context_save
+
+/* ------------------------------------------------------------------
+ * The following function follows the aapcs_64 strictly to use x9-x17
+ * (temporary caller-saved registers according to AArch64 PCS) to
+ * restore SVE register context. It assumes that 'x0' is pointing to
+ * a 'sve_regs_t' structure from where the register context will be
+ * restored.
+ * ------------------------------------------------------------------
+ */
+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
+	ldr	p0, [x9]
+	wrffr	p0.b
+
+	/* Restore predicate registers */
+	mov x13, #CTX_SIMD_PREDICATES
+	add	x9, x0, x13
+	sve_predicate_op ldr, x9
+
+	/* Restore vector registers */
+	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 */
+	fpregs_state_restore x0, x9
+	ret
+endfunc sve_context_restore
+#endif /* CTX_INCLUDE_SVE_REGS */
+
 	/*
 	 * Set SCR_EL3.EA bit to enable SErrors at EL3
 	 */
 	.macro enable_serror_at_el3
-	mrs     x8, scr_el3
-	orr     x8, x8, #SCR_EA_BIT
-	msr     scr_el3, x8
+	mrs	x8, scr_el3
+	orr	x8, x8, #SCR_EA_BIT
+	msr	scr_el3, x8
 	.endm
 
 	/*
@@ -339,13 +315,13 @@ endfunc fpregs_context_restore
 	 * always enable DIT in EL3
 	 */
 #if ENABLE_FEAT_DIT
-#if ENABLE_FEAT_DIT == 2
+#if ENABLE_FEAT_DIT >= 2
 	mrs	x8, id_aa64pfr0_el1
 	and	x8, x8, #(ID_AA64PFR0_DIT_MASK << ID_AA64PFR0_DIT_SHIFT)
 	cbz	x8, 1f
 #endif
-	mov     x8, #DIT_BIT
-	msr     DIT, x8
+	mov	x8, #DIT_BIT
+	msr	DIT, x8
 1:
 #endif /* ENABLE_FEAT_DIT */
 	.endm /* set_unset_pstate_bits */
@@ -363,8 +339,7 @@ endfunc fpregs_context_restore
 
 	.macro	restore_mpam3_el3
 #if ENABLE_FEAT_MPAM
-#if ENABLE_FEAT_MPAM == 2
-
+#if ENABLE_FEAT_MPAM >= 2
 	mrs x8, id_aa64pfr0_el1
 	lsr x8, x8, #(ID_AA64PFR0_MPAM_SHIFT)
 	and x8, x8, #(ID_AA64PFR0_MPAM_MASK)
@@ -378,9 +353,11 @@ endfunc fpregs_context_restore
 	 * Restore MPAM3_EL3 register as per context state
 	 * Currently we only enable MPAM for NS world and trap to EL3
 	 * for MPAM access in lower ELs of Secure and Realm world
+	 * x9 holds address of the per_world context
 	 * -----------------------------------------------------------
 	 */
-	ldr	x17, [sp, #CTX_EL3STATE_OFFSET + CTX_MPAM3_EL3]
+
+	ldr	x17, [x9, #CTX_MPAM3_EL3]
 	msr	S3_6_C10_C5_0, x17 /* mpam3_el3 */
 
 no_mpam:
@@ -423,9 +400,6 @@ no_mpam:
 	/* PMUv3 is presumed to be always present */
 	mrs	x9, pmcr_el0
 	str	x9, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0]
-	/* Disable cycle counter when event counting is prohibited */
-	orr	x9, x9, #PMCR_EL0_DP_BIT
-	msr	pmcr_el0, x9
 	isb
 #if CTX_INCLUDE_PAUTH_REGS
 	/* ----------------------------------------------------------
@@ -467,12 +441,7 @@ no_mpam:
  */
 func prepare_el3_entry
 	save_gp_pmcr_pauth_regs
-	enable_serror_at_el3
-	/*
-	 * Set the PSTATE bits not described in the Aarch64.TakeException
-	 * pseudocode to their default values.
-	 */
-	set_unset_pstate_bits
+	setup_el3_execution_context
 	ret
 endfunc prepare_el3_entry
 
@@ -528,10 +497,12 @@ func restore_gp_pmcr_pauth_regs
 	ret
 endfunc restore_gp_pmcr_pauth_regs
 
-/*
+#if ERRATA_SPECULATIVE_AT
+/* --------------------------------------------------------------------
  * In case of ERRATA_SPECULATIVE_AT, save SCTLR_EL1 and TCR_EL1
  * registers and update EL1 registers to disable stage1 and stage2
- * page table walk
+ * page table walk.
+ * --------------------------------------------------------------------
  */
 func save_and_update_ptw_el1_sys_regs
 	/* ----------------------------------------------------------
@@ -539,9 +510,9 @@ func save_and_update_ptw_el1_sys_regs
 	 * ----------------------------------------------------------
 	 */
 	mrs	x29, sctlr_el1
-	str	x29, [sp, #(CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1)]
+	str	x29, [sp, #(CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_SCTLR_EL1)]
 	mrs	x29, tcr_el1
-	str	x29, [sp, #(CTX_EL1_SYSREGS_OFFSET + CTX_TCR_EL1)]
+	str	x29, [sp, #(CTX_ERRATA_SPEC_AT_OFFSET + CTX_ERRATA_SPEC_AT_TCR_EL1)]
 
 	/* ------------------------------------------------------------
 	 * Must follow below order in order to disable page table
@@ -566,10 +537,11 @@ func save_and_update_ptw_el1_sys_regs
 	orr	x29, x29, #SCTLR_M_BIT
 	msr	sctlr_el1, x29
 	isb
-
 	ret
 endfunc save_and_update_ptw_el1_sys_regs
 
+#endif /* ERRATA_SPECULATIVE_AT */
+
 /* -----------------------------------------------------------------
 * The below macro returns the address of the per_world context for
 * the security state, retrieved through "get_security_state" macro.
@@ -581,7 +553,7 @@ endfunc save_and_update_ptw_el1_sys_regs
 .macro get_per_world_context _reg:req
 	ldr 	x10, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
 	get_security_state x9, x10
-	mov_imm	x10, (CTX_GLOBAL_EL3STATE_END - CTX_CPTR_EL3)
+	mov_imm	x10, (CTX_PERWORLD_EL3STATE_END - CTX_CPTR_EL3)
 	mul	x9, x9, x10
 	adrp	x10, per_world_context
 	add	x10, x10, :lo12:per_world_context
@@ -653,15 +625,17 @@ sve_not_enabled:
 	synchronize_errors
 #endif /* IMAGE_BL31 */
 
-	/* ----------------------------------------------------------
-	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
-	 * ----------------------------------------------------------
+	/* --------------------------------------------------------------
+	 * Restore MDCR_EL3, SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
+	 * --------------------------------------------------------------
 	 */
-	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
 	ldp	x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-	msr	scr_el3, x18
+	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+	ldr	x19, [sp, #CTX_EL3STATE_OFFSET + CTX_MDCR_EL3]
 	msr	spsr_el3, x16
 	msr	elr_el3, x17
+	msr	scr_el3, x18
+	msr	mdcr_el3, x19
 
 	restore_ptw_el1_sys_regs
 
diff --git a/lib/el3_runtime/aarch64/context_debug.c b/lib/el3_runtime/aarch64/context_debug.c
new file mode 100644
index 00000000..b37bcb75
--- /dev/null
+++ b/lib/el3_runtime/aarch64/context_debug.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <common/debug.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/el3_runtime/cpu_data.h>
+
+/********************************************************************************
+ * Function that returns the corresponding string constant for a security state
+ * index.
+ *******************************************************************************/
+static const char *get_context_name_by_idx(unsigned int security_state_idx)
+{
+	assert(security_state_idx < CPU_CONTEXT_NUM);
+	static const char * const state_names[] = {
+		"Secure",
+		"Non Secure"
+#if ENABLE_RME
+		, "Realm"
+#endif /* ENABLE_RME */
+	};
+	return state_names[security_state_idx];
+}
+
+#define PRINT_MEM_USAGE_SEPARATOR()					\
+	do {								\
+		printf("+-----------+-----------+-----------"		\
+		"+-----------+-----------+-----------+\n");		\
+	} while (false)
+
+#define NAME_PLACEHOLDER_LEN 14
+
+#define PRINT_DASH(n)							\
+	for (; n > 0; n--) {						\
+		putchar('-');						\
+	}
+
+#define PRINT_SINGLE_MEM_USAGE_SEP_BLOCK()				\
+	do {								\
+		printf("+-----------");					\
+	} while (false)
+
+/********************************************************************************
+ * This function prints the allocated memory for a specific security state.
+ * Values are grouped by exception level and core. The memory usage for the
+ * global context and the total memory for the security state are also computed.
+ *******************************************************************************/
+static size_t report_allocated_memory(unsigned int security_state_idx)
+{
+	size_t core_total = 0U;
+	size_t gp_total = 0U;
+	size_t el3_total = 0U;
+	size_t other_total = 0U;
+	size_t total = 0U;
+	size_t per_world_ctx_size = 0U;
+
+#if CTX_INCLUDE_EL2_REGS
+	size_t el2_total = 0U;
+#else
+	size_t el1_total = 0U;
+#endif /* CTX_INCLUDE_EL2_REGS */
+
+#if CTX_INCLUDE_PAUTH_REGS
+	size_t pauth_total = 0U;
+	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
+
+	PRINT_MEM_USAGE_SEPARATOR();
+
+	printf("|    Core   |     GP    |    EL3    ");
+#if CTX_INCLUDE_EL2_REGS
+	printf("|    EL2    ");
+#else
+	printf("|    EL1    ");
+#endif /* CTX_INCLUDE_EL2_REGS */
+
+#if CTX_INCLUDE_PAUTH_REGS
+	printf("|   PAUTH   ");
+#endif
+
+	printf("|   Other   |   Total   |\n");
+
+	/* Compute memory usage for each core's context */
+	for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+		size_t size_other = 0U;
+		size_t el3_size = 0U;
+		size_t gp_size = 0U;
+#if CTX_INCLUDE_EL2_REGS
+		size_t el2_size = 0U;
+#else
+		size_t el1_size = 0U;
+#endif /* CTX_INCLUDE_EL2_REGS */
+
+#if CTX_INCLUDE_PAUTH_REGS
+		size_t pauth_size = 0U;
+		PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
+
+		PRINT_MEM_USAGE_SEPARATOR();
+
+		cpu_context_t *ctx = (cpu_context_t *)cm_get_context_by_index(i,
+			security_state_idx);
+		core_total = sizeof(*ctx);
+		el3_size = sizeof(ctx->el3state_ctx);
+		gp_size = sizeof(ctx->gpregs_ctx);
+		size_other = core_total - (el3_size + gp_size);
+		printf("| %9u | %8luB | %8luB ", i, gp_size, el3_size);
+
+#if CTX_INCLUDE_EL2_REGS
+		el2_size = sizeof(ctx->el2_sysregs_ctx);
+		size_other -= el2_size;
+		el2_total += el2_size;
+		printf("| %8luB ", el2_size);
+#else
+		el1_size = sizeof(ctx->el1_sysregs_ctx);
+		size_other -= el1_size;
+		el1_total += el1_size;
+		printf("| %8luB ", el1_size);
+#endif /* CTX_INCLUDE_EL2_REGS */
+
+#if CTX_INCLUDE_PAUTH_REGS
+		pauth_size = sizeof(ctx->pauth_ctx);
+		size_other -= pauth_size;
+		pauth_total += pauth_size;
+		printf("| %8luB ", pauth_size);
+#endif
+		printf("| %8luB | %8luB |\n", size_other, core_total);
+
+		gp_total += gp_size;
+		el3_total += el3_size;
+		other_total += size_other;
+		total += core_total;
+	}
+
+#if CTX_INCLUDE_PAUTH_REGS
+	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
+
+	PRINT_MEM_USAGE_SEPARATOR();
+
+#if CTX_INCLUDE_PAUTH_REGS
+	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
+
+	PRINT_MEM_USAGE_SEPARATOR();
+
+	printf("|    All    | %8luB | %8luB ", gp_total, el3_total);
+
+#if CTX_INCLUDE_EL2_REGS
+	printf("| %8luB ", el2_total);
+#else
+	printf("| %8luB ", el1_total);
+#endif /* CTX_INCLUDE_EL2_REGS */
+
+#if CTX_INCLUDE_PAUTH_REGS
+	printf("| %8luB ", pauth_total);
+#endif
+
+	printf("| %8luB | %8luB |\n", other_total, total);
+
+#if CTX_INCLUDE_PAUTH_REGS
+	PRINT_SINGLE_MEM_USAGE_SEP_BLOCK();
+#endif
+	PRINT_MEM_USAGE_SEPARATOR();
+	printf("\n");
+
+	/* Compute memory usage for the global context */
+	per_world_ctx_size = sizeof(per_world_context[security_state_idx]);
+
+	total += per_world_ctx_size;
+
+	printf("Per-world context: %luB\n\n", per_world_ctx_size);
+
+	printf("TOTAL: %luB\n", total);
+
+	return total;
+}
+
+/********************************************************************************
+ * Reports the allocated memory for every security state and then reports the
+ * total system-wide allocated memory.
+ *******************************************************************************/
+void report_ctx_memory_usage(void)
+{
+	INFO("Context memory allocation:\n");
+
+	size_t total = 0U;
+
+	for (unsigned int i = 0U; i < CPU_CONTEXT_NUM; i++) {
+		const char *context_name = get_context_name_by_idx(i);
+		size_t len = 0U;
+
+		printf("Memory usage for %s:\n", context_name);
+		total += report_allocated_memory(i);
+			printf("------------------------");
+			len = NAME_PLACEHOLDER_LEN - printf("End %s", context_name);
+			PRINT_DASH(len);
+			printf("-----------------------\n\n");
+	}
+
+	printf("Total context memory allocated: %luB\n\n", total);
+}
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index fdd1388c..4ae13061 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -19,17 +19,23 @@
 #include <common/debug.h>
 #include <context.h>
 #include <drivers/arm/gicv3.h>
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/el3_runtime/cpu_data.h>
 #include <lib/el3_runtime/pubsub_events.h>
 #include <lib/extensions/amu.h>
 #include <lib/extensions/brbe.h>
+#include <lib/extensions/debug_v8p9.h>
+#include <lib/extensions/fgt2.h>
 #include <lib/extensions/mpam.h>
 #include <lib/extensions/pmuv3.h>
 #include <lib/extensions/sme.h>
 #include <lib/extensions/spe.h>
 #include <lib/extensions/sve.h>
+#include <lib/extensions/sysreg128.h>
 #include <lib/extensions/sys_reg_trace.h>
+#include <lib/extensions/tcr2.h>
 #include <lib/extensions/trbe.h>
 #include <lib/extensions/trf.h>
 #include <lib/utils.h>
@@ -42,10 +48,12 @@ CASSERT(((TWED_DELAY & ~SCR_TWEDEL_MASK) == 0U), assert_twed_delay_value_check);
 per_world_context_t per_world_context[CPU_DATA_CONTEXT_NUM];
 static bool has_secure_perworld_init;
 
+static void manage_extensions_common(cpu_context_t *ctx);
 static void manage_extensions_nonsecure(cpu_context_t *ctx);
 static void manage_extensions_secure(cpu_context_t *ctx);
 static void manage_extensions_secure_per_world(void);
 
+#if ((IMAGE_BL1) || (IMAGE_BL31 && (!CTX_INCLUDE_EL2_REGS)))
 static void setup_el1_context(cpu_context_t *ctx, const struct entry_point_info *ep)
 {
 	u_register_t sctlr_elx, actlr_elx;
@@ -82,15 +90,16 @@ static void setup_el1_context(cpu_context_t *ctx, const struct entry_point_info
 					| SCTLR_NTWI_BIT | SCTLR_NTWE_BIT;
 	}
 
-#if ERRATA_A75_764081
 	/*
 	 * If workaround of errata 764081 for Cortex-A75 is used then set
 	 * SCTLR_EL1.IESB to enable Implicit Error Synchronization Barrier.
 	 */
-	sctlr_elx |= SCTLR_IESB_BIT;
-#endif
+	if (errata_a75_764081_applies()) {
+		sctlr_elx |= SCTLR_IESB_BIT;
+	}
+
 	/* Store the initialised SCTLR_EL1 value in the cpu_context */
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
+	write_ctx_sctlr_el1_reg_errata(ctx, sctlr_elx);
 
 	/*
 	 * Base the context ACTLR_EL1 on the current value, as it is
@@ -100,8 +109,9 @@ static void setup_el1_context(cpu_context_t *ctx, const struct entry_point_info
 	 * be zero.
 	 */
 	actlr_elx = read_actlr_el1();
-	write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), actlr_el1, actlr_elx);
 }
+#endif /* (IMAGE_BL1) || (IMAGE_BL31 && (!CTX_INCLUDE_EL2_REGS)) */
 
 /******************************************************************************
  * This function performs initializations that are specific to SECURE state
@@ -123,22 +133,10 @@ static void setup_secure_context(cpu_context_t *ctx, const struct entry_point_in
 	scr_el3 |= get_scr_el3_from_routing_model(SECURE);
 #endif
 
-#if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS
-	/* Get Memory Tagging Extension support level */
-	unsigned int mte = get_armv8_5_mte_support();
-#endif
-	/*
-	 * Allow access to Allocation Tags when CTX_INCLUDE_MTE_REGS
-	 * is set, or when MTE is only implemented at EL0.
-	 */
-#if CTX_INCLUDE_MTE_REGS
-	assert((mte == MTE_IMPLEMENTED_ELX) || (mte == MTE_IMPLEMENTED_ASY));
-	scr_el3 |= SCR_ATA_BIT;
-#else
-	if (mte == MTE_IMPLEMENTED_EL0) {
+	/* Allow access to Allocation Tags when FEAT_MTE2 is implemented and enabled. */
+	if (is_feat_mte2_supported()) {
 		scr_el3 |= SCR_ATA_BIT;
 	}
-#endif /* CTX_INCLUDE_MTE_REGS */
 
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 
@@ -146,7 +144,7 @@ static void setup_secure_context(cpu_context_t *ctx, const struct entry_point_in
 	 * Initialize EL1 context registers unless SPMC is running
 	 * at S-EL2.
 	 */
-#if !SPMD_SPM_AT_SEL2
+#if (!SPMD_SPM_AT_SEL2)
 	setup_el1_context(ctx, ep);
 #endif
 
@@ -162,7 +160,6 @@ static void setup_secure_context(cpu_context_t *ctx, const struct entry_point_in
 	if (!has_secure_perworld_init) {
 		manage_extensions_secure_per_world();
 	}
-
 }
 
 #if ENABLE_RME
@@ -180,11 +177,19 @@ static void setup_realm_context(cpu_context_t *ctx, const struct entry_point_inf
 
 	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT;
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		/* Enable access to the SCXTNUM_ELx registers. */
 		scr_el3 |= SCR_EnSCXT_BIT;
 	}
 
+	if (is_feat_sctlr2_supported()) {
+		/* Set the SCTLR2En bit in SCR_EL3 to enable access to
+		 * SCTLR2_ELx registers.
+		 */
+		scr_el3 |= SCR_SCTLR2En_BIT;
+	}
+
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 }
 #endif /* ENABLE_RME */
@@ -204,8 +209,10 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
 	/* SCR_NS: Set the NS bit */
 	scr_el3 |= SCR_NS_BIT;
 
-	/* Allow access to Allocation Tags when MTE is implemented. */
-	scr_el3 |= SCR_ATA_BIT;
+	/* Allow access to Allocation Tags when FEAT_MTE2 is implemented and enabled. */
+	if (is_feat_mte2_supported()) {
+		scr_el3 |= SCR_ATA_BIT;
+	}
 
 #if !CTX_INCLUDE_PAUTH_REGS
 	/*
@@ -248,6 +255,7 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
 	scr_el3 |= SCR_TERR_BIT;
 #endif
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		/* Enable access to the SCXTNUM_ELx registers. */
 		scr_el3 |= SCR_EnSCXT_BIT;
@@ -260,22 +268,38 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
 	 */
 	scr_el3 |= get_scr_el3_from_routing_model(NON_SECURE);
 #endif
-	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 
-	/* Initialize EL1 context registers */
-	setup_el1_context(ctx, ep);
+	if (is_feat_the_supported()) {
+		/* Set the RCWMASKEn bit in SCR_EL3 to enable access to
+		 * RCWMASK_EL1 and RCWSMASK_EL1 registers.
+		 */
+		scr_el3 |= SCR_RCWMASKEn_BIT;
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		/* Set the SCTLR2En bit in SCR_EL3 to enable access to
+		 * SCTLR2_ELx registers.
+		 */
+		scr_el3 |= SCR_SCTLR2En_BIT;
+	}
+
+	if (is_feat_d128_supported()) {
+		/* Set the D128En bit in SCR_EL3 to enable access to 128-bit
+		 * versions of TTBR0_EL1, TTBR1_EL1, RCWMASK_EL1, RCWSMASK_EL1,
+		 * PAR_EL1 and TTBR1_EL2, TTBR0_EL2 and VTTBR_EL2 registers.
+		 */
+		scr_el3 |= SCR_D128En_BIT;
+	}
+
+	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 
 	/* Initialize EL2 context registers */
-#if CTX_INCLUDE_EL2_REGS
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 
 	/*
-	 * Initialize SCTLR_EL2 context register using Endianness value
-	 * taken from the entrypoint attribute.
+	 * Initialize SCTLR_EL2 context register with reset value.
 	 */
-	u_register_t sctlr_el2 = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0UL;
-	sctlr_el2 |= SCTLR_EL2_RES1;
-	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_SCTLR_EL2,
-			sctlr_el2);
+	write_el2_ctx_common(get_el2_sysregs_ctx(ctx), sctlr_el2, SCTLR_EL2_RES1);
 
 	if (is_feat_hcx_supported()) {
 		/*
@@ -286,7 +310,7 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
 		 * this feature if not properly initialized, especially when
 		 * it comes to those bits that enable/disable traps.
 		 */
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HCRX_EL2,
+		write_el2_ctx_hcx(get_el2_sysregs_ctx(ctx), hcrx_el2,
 			HCRX_EL2_INIT_VAL);
 	}
 
@@ -296,14 +320,17 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
 		 * systems unaware of FEAT_FGT do not get trapped due to their lack
 		 * of initialization for this feature.
 		 */
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGITR_EL2,
+		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgitr_el2,
 			HFGITR_EL2_INIT_VAL);
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGRTR_EL2,
+		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgrtr_el2,
 			HFGRTR_EL2_INIT_VAL);
-		write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_HFGWTR_EL2,
+		write_el2_ctx_fgt(get_el2_sysregs_ctx(ctx), hfgwtr_el2,
 			HFGWTR_EL2_INIT_VAL);
 	}
-#endif /* CTX_INCLUDE_EL2_REGS */
+#else
+	/* Initialize EL1 context registers */
+	setup_el1_context(ctx, ep);
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 
 	manage_extensions_nonsecure(ctx);
 }
@@ -319,6 +346,7 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
 static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *ep)
 {
 	u_register_t scr_el3;
+	u_register_t mdcr_el3;
 	el3_state_t *state;
 	gp_regs_t *gp_regs;
 
@@ -333,17 +361,23 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
 	 * to boot correctly. However, there are very few registers where this
 	 * is not true and some values need to be recreated.
 	 */
-#if CTX_INCLUDE_EL2_REGS
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 	el2_sysregs_t *el2_ctx = get_el2_sysregs_ctx(ctx);
 
 	/*
 	 * These bits are set in the gicv3 driver. Losing them (especially the
 	 * SRE bit) is problematic for all worlds. Henceforth recreate them.
 	 */
-	u_register_t icc_sre_el2 = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
+	u_register_t icc_sre_el2_val = ICC_SRE_DIB_BIT | ICC_SRE_DFB_BIT |
 				   ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT;
-	write_ctx_reg(el2_ctx, CTX_ICC_SRE_EL2, icc_sre_el2);
-#endif /* CTX_INCLUDE_EL2_REGS */
+	write_el2_ctx_common(el2_ctx, icc_sre_el2, icc_sre_el2_val);
+
+	/*
+	 * The actlr_el2 register can be initialized in platform's reset handler
+	 * and it may contain access control bits (e.g. CLUSTERPMUEN bit).
+	 */
+	write_el2_ctx_common(el2_ctx, actlr_el2, read_actlr_el2());
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 
 	/* Start with a clean SCR_EL3 copy as all relevant values are set */
 	scr_el3 = SCR_RESET_VAL;
@@ -392,6 +426,15 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
 		scr_el3 |= SCR_HXEn_BIT;
 	}
 
+	/*
+	 * If FEAT_LS64_ACCDATA is enabled, enable access to ACCDATA_EL1 by
+	 * setting SCR_EL3.ADEn and allow the ST64BV0 instruction by setting
+	 * SCR_EL3.EnAS0.
+	 */
+	if (is_feat_ls64_accdata_supported()) {
+		scr_el3 |= SCR_ADEn_BIT | SCR_EnAS0_BIT;
+	}
+
 	/*
 	 * If FEAT_RNG_TRAP is enabled, all reads of the RNDR and RNDRRS
 	 * registers are trapped to EL3.
@@ -483,11 +526,6 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
 	}
 #endif /* (IMAGE_BL31 && defined(SPD_spmd) && SPMD_SPM_AT_SEL2) */
 
-	if (is_feat_mpam_supported()) {
-		write_ctx_reg(get_el3state_ctx(ctx), CTX_MPAM3_EL3, \
-				MPAM3_EL3_RESET_VAL);
-	}
-
 	/*
 	 * Populate EL3 state so that we've the right context
 	 * before doing ERET
@@ -496,6 +534,37 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
 	write_ctx_reg(state, CTX_ELR_EL3, ep->pc);
 	write_ctx_reg(state, CTX_SPSR_EL3, ep->spsr);
 
+	/* Start with a clean MDCR_EL3 copy as all relevant values are set */
+	mdcr_el3 = MDCR_EL3_RESET_VAL;
+
+	/* ---------------------------------------------------------------------
+	 * Initialise MDCR_EL3, setting all fields rather than relying on hw.
+	 * Some fields are architecturally UNKNOWN on reset.
+	 *
+	 * MDCR_EL3.SDD: Set to one to disable AArch64 Secure self-hosted debug.
+	 *  Debug exceptions, other than Breakpoint Instruction exceptions, are
+	 *  disabled from all ELs in Secure state.
+	 *
+	 * MDCR_EL3.SPD32: Set to 0b10 to disable AArch32 Secure self-hosted
+	 *  privileged debug from S-EL1.
+	 *
+	 * MDCR_EL3.TDOSA: Set to zero so that EL2 and EL2 System register
+	 *  access to the powerdown debug registers do not trap to EL3.
+	 *
+	 * MDCR_EL3.TDA: Set to zero to allow EL0, EL1 and EL2 access to the
+	 *  debug registers, other than those registers that are controlled by
+	 *  MDCR_EL3.TDOSA.
+	 */
+	mdcr_el3 |= ((MDCR_SDD_BIT | MDCR_SPD32(MDCR_SPD32_DISABLE))
+			& ~(MDCR_TDA_BIT | MDCR_TDOSA_BIT)) ;
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3);
+
+	/*
+	 * Configure MDCR_EL3 register as applicable for each world
+	 * (NS/Secure/Realm) context.
+	 */
+	manage_extensions_common(ctx);
+
 	/*
 	 * Store the X0-X7 value from the entrypoint into the context
 	 * Use memcpy as we are in control of the layout of the structures
@@ -572,10 +641,6 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
 #if IMAGE_BL31
 void cm_manage_extensions_el3(void)
 {
-	if (is_feat_spe_supported()) {
-		spe_init_el3();
-	}
-
 	if (is_feat_amu_supported()) {
 		amu_init_el3();
 	}
@@ -584,19 +649,39 @@ void cm_manage_extensions_el3(void)
 		sme_init_el3();
 	}
 
-	if (is_feat_trbe_supported()) {
-		trbe_init_el3();
-	}
+	pmuv3_init_el3();
+}
+#endif /* IMAGE_BL31 */
 
-	if (is_feat_brbe_supported()) {
-		brbe_init_el3();
-	}
+/******************************************************************************
+ * Function to initialise the registers with the RESET values in the context
+ * memory, which are maintained per world.
+ ******************************************************************************/
+#if IMAGE_BL31
+void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx)
+{
+	/*
+	 * Initialise CPTR_EL3, setting all fields rather than relying on hw.
+	 *
+	 * CPTR_EL3.TFP: Set to zero so that accesses to the V- or Z- registers
+	 *  by Advanced SIMD, floating-point or SVE instructions (if
+	 *  implemented) do not trap to EL3.
+	 *
+	 * CPTR_EL3.TCPAC: Set to zero so that accesses to CPACR_EL1,
+	 *  CPTR_EL2,CPACR, or HCPTR do not trap to EL3.
+	 */
+	uint64_t cptr_el3 = CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TFP_BIT);
 
-	if (is_feat_trf_supported()) {
-		trf_init_el3();
-	}
+	per_world_ctx->ctx_cptr_el3 = cptr_el3;
 
-	pmuv3_init_el3();
+	/*
+	 * Initialize MPAM3_EL3 to its default reset value
+	 *
+	 * MPAM3_EL3_RESET_VAL sets the MPAM3_EL3.TRAPLOWER bit that forces
+	 * all lower ELn MPAM3_EL3 register access to, trap to EL3
+	 */
+
+	per_world_ctx->ctx_mpam3_el3 = MPAM3_EL3_RESET_VAL;
 }
 #endif /* IMAGE_BL31 */
 
@@ -608,6 +693,8 @@ void cm_manage_extensions_el3(void)
 #if IMAGE_BL31
 void manage_extensions_nonsecure_per_world(void)
 {
+	cm_el3_arch_init_per_world(&per_world_context[CPU_CONTEXT_NS]);
+
 	if (is_feat_sme_supported()) {
 		sme_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
 	}
@@ -623,6 +710,10 @@ void manage_extensions_nonsecure_per_world(void)
 	if (is_feat_sys_reg_trace_supported()) {
 		sys_reg_trace_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
 	}
+
+	if (is_feat_mpam_supported()) {
+		mpam_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
+	}
 }
 #endif /* IMAGE_BL31 */
 
@@ -631,10 +722,11 @@ void manage_extensions_nonsecure_per_world(void)
  * This function enables the architecture extensions, which have same value
  * across the cores for the secure world.
  ******************************************************************************/
-
 static void manage_extensions_secure_per_world(void)
 {
 #if IMAGE_BL31
+	cm_el3_arch_init_per_world(&per_world_context[CPU_CONTEXT_SECURE]);
+
 	if (is_feat_sme_supported()) {
 
 		if (ENABLE_SME_FOR_SWD) {
@@ -676,6 +768,41 @@ static void manage_extensions_secure_per_world(void)
 #endif /* IMAGE_BL31 */
 }
 
+/*******************************************************************************
+ * Enable architecture extensions on first entry to Non-secure world only
+ * and disable for secure world.
+ *
+ * NOTE: Arch features which have been provided with the capability of getting
+ * enabled only for non-secure world and being disabled for secure world are
+ * grouped here, as the MDCR_EL3 context value remains same across the worlds.
+ ******************************************************************************/
+static void manage_extensions_common(cpu_context_t *ctx)
+{
+#if IMAGE_BL31
+	if (is_feat_spe_supported()) {
+		/*
+		 * Enable FEAT_SPE for Non-Secure and prohibit for Secure state.
+		 */
+		spe_enable(ctx);
+	}
+
+	if (is_feat_trbe_supported()) {
+		/*
+		 * Enable FEAT_TRBE for Non-Secure and prohibit for Secure and
+		 * Realm state.
+		 */
+		trbe_enable(ctx);
+	}
+
+	if (is_feat_trf_supported()) {
+		/*
+		 * Enable FEAT_TRF for Non-Secure and prohibit for Secure state.
+		 */
+		trf_enable(ctx);
+	}
+#endif /* IMAGE_BL31 */
+}
+
 /*******************************************************************************
  * Enable architecture extensions on first entry to Non-secure world.
  ******************************************************************************/
@@ -690,9 +817,18 @@ static void manage_extensions_nonsecure(cpu_context_t *ctx)
 		sme_enable(ctx);
 	}
 
-	if (is_feat_mpam_supported()) {
-		mpam_enable(ctx);
+	if (is_feat_fgt2_supported()) {
+		fgt2_enable(ctx);
+	}
+
+	if (is_feat_debugv8p9_supported()) {
+		debugv8p9_extended_bp_wp_enable(ctx);
 	}
+
+	if (is_feat_brbe_supported()) {
+		brbe_enable(ctx);
+	}
+
 	pmuv3_enable(ctx);
 #endif /* IMAGE_BL31 */
 }
@@ -785,6 +921,7 @@ static void manage_extensions_secure(cpu_context_t *ctx)
 #endif /* IMAGE_BL31 */
 }
 
+#if !IMAGE_BL1
 /*******************************************************************************
  * The following function initializes the cpu_context for a CPU specified by
  * its `cpu_idx` for first use, and sets the initial entrypoint state as
@@ -797,6 +934,7 @@ void cm_init_context_by_index(unsigned int cpu_idx,
 	ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr));
 	cm_setup_context(ctx, ep);
 }
+#endif /* !IMAGE_BL1 */
 
 /*******************************************************************************
  * The following function initializes the cpu_context for the current CPU
@@ -926,7 +1064,7 @@ static void init_nonsecure_el2_unused(cpu_context_t *ctx)
  ******************************************************************************/
 void cm_prepare_el3_exit(uint32_t security_state)
 {
-	u_register_t sctlr_elx, scr_el3;
+	u_register_t sctlr_el2, scr_el3;
 	cpu_context_t *ctx = cm_get_context(security_state);
 
 	assert(ctx != NULL);
@@ -937,8 +1075,8 @@ void cm_prepare_el3_exit(uint32_t security_state)
 		scr_el3 = read_ctx_reg(get_el3state_ctx(ctx),
 						 CTX_SCR_EL3);
 
-		if (((scr_el3 & SCR_HCE_BIT) != 0U)
-			|| (el2_implemented != EL_IMPL_NONE)) {
+		if (el2_implemented != EL_IMPL_NONE) {
+
 			/*
 			 * If context is not being used for EL2, initialize
 			 * HCRX_EL2 with its init value here.
@@ -964,64 +1102,87 @@ void cm_prepare_el3_exit(uint32_t security_state)
 				write_hfgrtr_el2(HFGRTR_EL2_INIT_VAL);
 				write_hfgwtr_el2(HFGWTR_EL2_INIT_VAL);
 			}
-		}
 
+			/* Condition to ensure EL2 is being used. */
+			if ((scr_el3 & SCR_HCE_BIT) != 0U) {
+				/* Initialize SCTLR_EL2 register with reset value. */
+				sctlr_el2 = SCTLR_EL2_RES1;
 
-		if ((scr_el3 & SCR_HCE_BIT) != 0U) {
-			/* Use SCTLR_EL1.EE value to initialise sctlr_el2 */
-			sctlr_elx = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-							   CTX_SCTLR_EL1);
-			sctlr_elx &= SCTLR_EE_BIT;
-			sctlr_elx |= SCTLR_EL2_RES1;
-#if ERRATA_A75_764081
-			/*
-			 * If workaround of errata 764081 for Cortex-A75 is used
-			 * then set SCTLR_EL2.IESB to enable Implicit Error
-			 * Synchronization Barrier.
-			 */
-			sctlr_elx |= SCTLR_IESB_BIT;
-#endif
-			write_sctlr_el2(sctlr_elx);
-		} else if (el2_implemented != EL_IMPL_NONE) {
-			init_nonsecure_el2_unused(ctx);
+				/*
+				 * If workaround of errata 764081 for Cortex-A75
+				 * is used then set SCTLR_EL2.IESB to enable
+				 * Implicit Error Synchronization Barrier.
+				 */
+				if (errata_a75_764081_applies()) {
+					sctlr_el2 |= SCTLR_IESB_BIT;
+				}
+
+				write_sctlr_el2(sctlr_el2);
+			} else {
+				/*
+				 * (scr_el3 & SCR_HCE_BIT==0)
+				 * EL2 implemented but unused.
+				 */
+				init_nonsecure_el2_unused(ctx);
+			}
 		}
 	}
-
+#if (!CTX_INCLUDE_EL2_REGS)
+	/* Restore EL1 system registers, only when CTX_INCLUDE_EL2_REGS=0 */
 	cm_el1_sysregs_context_restore(security_state);
+#endif
 	cm_set_next_eret_context(security_state);
 }
 
-#if CTX_INCLUDE_EL2_REGS
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 
 static void el2_sysregs_context_save_fgt(el2_sysregs_t *ctx)
 {
-	write_ctx_reg(ctx, CTX_HDFGRTR_EL2, read_hdfgrtr_el2());
+	write_el2_ctx_fgt(ctx, hdfgrtr_el2, read_hdfgrtr_el2());
 	if (is_feat_amu_supported()) {
-		write_ctx_reg(ctx, CTX_HAFGRTR_EL2, read_hafgrtr_el2());
+		write_el2_ctx_fgt(ctx, hafgrtr_el2, read_hafgrtr_el2());
 	}
-	write_ctx_reg(ctx, CTX_HDFGWTR_EL2, read_hdfgwtr_el2());
-	write_ctx_reg(ctx, CTX_HFGITR_EL2, read_hfgitr_el2());
-	write_ctx_reg(ctx, CTX_HFGRTR_EL2, read_hfgrtr_el2());
-	write_ctx_reg(ctx, CTX_HFGWTR_EL2, read_hfgwtr_el2());
+	write_el2_ctx_fgt(ctx, hdfgwtr_el2, read_hdfgwtr_el2());
+	write_el2_ctx_fgt(ctx, hfgitr_el2, read_hfgitr_el2());
+	write_el2_ctx_fgt(ctx, hfgrtr_el2, read_hfgrtr_el2());
+	write_el2_ctx_fgt(ctx, hfgwtr_el2, read_hfgwtr_el2());
 }
 
 static void el2_sysregs_context_restore_fgt(el2_sysregs_t *ctx)
 {
-	write_hdfgrtr_el2(read_ctx_reg(ctx, CTX_HDFGRTR_EL2));
+	write_hdfgrtr_el2(read_el2_ctx_fgt(ctx, hdfgrtr_el2));
 	if (is_feat_amu_supported()) {
-		write_hafgrtr_el2(read_ctx_reg(ctx, CTX_HAFGRTR_EL2));
+		write_hafgrtr_el2(read_el2_ctx_fgt(ctx, hafgrtr_el2));
 	}
-	write_hdfgwtr_el2(read_ctx_reg(ctx, CTX_HDFGWTR_EL2));
-	write_hfgitr_el2(read_ctx_reg(ctx, CTX_HFGITR_EL2));
-	write_hfgrtr_el2(read_ctx_reg(ctx, CTX_HFGRTR_EL2));
-	write_hfgwtr_el2(read_ctx_reg(ctx, CTX_HFGWTR_EL2));
+	write_hdfgwtr_el2(read_el2_ctx_fgt(ctx, hdfgwtr_el2));
+	write_hfgitr_el2(read_el2_ctx_fgt(ctx, hfgitr_el2));
+	write_hfgrtr_el2(read_el2_ctx_fgt(ctx, hfgrtr_el2));
+	write_hfgwtr_el2(read_el2_ctx_fgt(ctx, hfgwtr_el2));
+}
+
+static void el2_sysregs_context_save_fgt2(el2_sysregs_t *ctx)
+{
+	write_el2_ctx_fgt2(ctx, hdfgrtr2_el2, read_hdfgrtr2_el2());
+	write_el2_ctx_fgt2(ctx, hdfgwtr2_el2, read_hdfgwtr2_el2());
+	write_el2_ctx_fgt2(ctx, hfgitr2_el2, read_hfgitr2_el2());
+	write_el2_ctx_fgt2(ctx, hfgrtr2_el2, read_hfgrtr2_el2());
+	write_el2_ctx_fgt2(ctx, hfgwtr2_el2, read_hfgwtr2_el2());
+}
+
+static void el2_sysregs_context_restore_fgt2(el2_sysregs_t *ctx)
+{
+	write_hdfgrtr2_el2(read_el2_ctx_fgt2(ctx, hdfgrtr2_el2));
+	write_hdfgwtr2_el2(read_el2_ctx_fgt2(ctx, hdfgwtr2_el2));
+	write_hfgitr2_el2(read_el2_ctx_fgt2(ctx, hfgitr2_el2));
+	write_hfgrtr2_el2(read_el2_ctx_fgt2(ctx, hfgrtr2_el2));
+	write_hfgwtr2_el2(read_el2_ctx_fgt2(ctx, hfgwtr2_el2));
 }
 
 static void el2_sysregs_context_save_mpam(el2_sysregs_t *ctx)
 {
 	u_register_t mpam_idr = read_mpamidr_el1();
 
-	write_ctx_reg(ctx, CTX_MPAM2_EL2, read_mpam2_el2());
+	write_el2_ctx_mpam(ctx, mpam2_el2, read_mpam2_el2());
 
 	/*
 	 * The context registers that we intend to save would be part of the
@@ -1035,9 +1196,9 @@ static void el2_sysregs_context_save_mpam(el2_sysregs_t *ctx)
 	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 are always present if
 	 * MPAMIDR_HAS_HCR_BIT == 1.
 	 */
-	write_ctx_reg(ctx, CTX_MPAMHCR_EL2, read_mpamhcr_el2());
-	write_ctx_reg(ctx, CTX_MPAMVPM0_EL2, read_mpamvpm0_el2());
-	write_ctx_reg(ctx, CTX_MPAMVPMV_EL2, read_mpamvpmv_el2());
+	write_el2_ctx_mpam(ctx, mpamhcr_el2, read_mpamhcr_el2());
+	write_el2_ctx_mpam(ctx, mpamvpm0_el2, read_mpamvpm0_el2());
+	write_el2_ctx_mpam(ctx, mpamvpmv_el2, read_mpamvpmv_el2());
 
 	/*
 	 * The number of MPAMVPM registers is implementation defined, their
@@ -1045,25 +1206,25 @@ static void el2_sysregs_context_save_mpam(el2_sysregs_t *ctx)
 	 */
 	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
 	case 7:
-		write_ctx_reg(ctx, CTX_MPAMVPM7_EL2, read_mpamvpm7_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm7_el2, read_mpamvpm7_el2());
 		__fallthrough;
 	case 6:
-		write_ctx_reg(ctx, CTX_MPAMVPM6_EL2, read_mpamvpm6_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm6_el2, read_mpamvpm6_el2());
 		__fallthrough;
 	case 5:
-		write_ctx_reg(ctx, CTX_MPAMVPM5_EL2, read_mpamvpm5_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm5_el2, read_mpamvpm5_el2());
 		__fallthrough;
 	case 4:
-		write_ctx_reg(ctx, CTX_MPAMVPM4_EL2, read_mpamvpm4_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm4_el2, read_mpamvpm4_el2());
 		__fallthrough;
 	case 3:
-		write_ctx_reg(ctx, CTX_MPAMVPM3_EL2, read_mpamvpm3_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm3_el2, read_mpamvpm3_el2());
 		__fallthrough;
 	case 2:
-		write_ctx_reg(ctx, CTX_MPAMVPM2_EL2, read_mpamvpm2_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm2_el2, read_mpamvpm2_el2());
 		__fallthrough;
 	case 1:
-		write_ctx_reg(ctx, CTX_MPAMVPM1_EL2, read_mpamvpm1_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm1_el2, read_mpamvpm1_el2());
 		break;
 	}
 }
@@ -1072,148 +1233,161 @@ static void el2_sysregs_context_restore_mpam(el2_sysregs_t *ctx)
 {
 	u_register_t mpam_idr = read_mpamidr_el1();
 
-	write_mpam2_el2(read_ctx_reg(ctx, CTX_MPAM2_EL2));
+	write_mpam2_el2(read_el2_ctx_mpam(ctx, mpam2_el2));
 
 	if ((mpam_idr & MPAMIDR_HAS_HCR_BIT) == 0U) {
 		return;
 	}
 
-	write_mpamhcr_el2(read_ctx_reg(ctx, CTX_MPAMHCR_EL2));
-	write_mpamvpm0_el2(read_ctx_reg(ctx, CTX_MPAMVPM0_EL2));
-	write_mpamvpmv_el2(read_ctx_reg(ctx, CTX_MPAMVPMV_EL2));
+	write_mpamhcr_el2(read_el2_ctx_mpam(ctx, mpamhcr_el2));
+	write_mpamvpm0_el2(read_el2_ctx_mpam(ctx, mpamvpm0_el2));
+	write_mpamvpmv_el2(read_el2_ctx_mpam(ctx, mpamvpmv_el2));
 
 	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
 	case 7:
-		write_mpamvpm7_el2(read_ctx_reg(ctx, CTX_MPAMVPM7_EL2));
+		write_mpamvpm7_el2(read_el2_ctx_mpam(ctx, mpamvpm7_el2));
 		__fallthrough;
 	case 6:
-		write_mpamvpm6_el2(read_ctx_reg(ctx, CTX_MPAMVPM6_EL2));
+		write_mpamvpm6_el2(read_el2_ctx_mpam(ctx, mpamvpm6_el2));
 		__fallthrough;
 	case 5:
-		write_mpamvpm5_el2(read_ctx_reg(ctx, CTX_MPAMVPM5_EL2));
+		write_mpamvpm5_el2(read_el2_ctx_mpam(ctx, mpamvpm5_el2));
 		__fallthrough;
 	case 4:
-		write_mpamvpm4_el2(read_ctx_reg(ctx, CTX_MPAMVPM4_EL2));
+		write_mpamvpm4_el2(read_el2_ctx_mpam(ctx, mpamvpm4_el2));
 		__fallthrough;
 	case 3:
-		write_mpamvpm3_el2(read_ctx_reg(ctx, CTX_MPAMVPM3_EL2));
+		write_mpamvpm3_el2(read_el2_ctx_mpam(ctx, mpamvpm3_el2));
 		__fallthrough;
 	case 2:
-		write_mpamvpm2_el2(read_ctx_reg(ctx, CTX_MPAMVPM2_EL2));
+		write_mpamvpm2_el2(read_el2_ctx_mpam(ctx, mpamvpm2_el2));
 		__fallthrough;
 	case 1:
-		write_mpamvpm1_el2(read_ctx_reg(ctx, CTX_MPAMVPM1_EL2));
+		write_mpamvpm1_el2(read_el2_ctx_mpam(ctx, mpamvpm1_el2));
 		break;
 	}
 }
 
-/* -----------------------------------------------------
+/* ---------------------------------------------------------------------------
  * The following registers are not added:
- * AMEVCNTVOFF0<n>_EL2
- * AMEVCNTVOFF1<n>_EL2
  * ICH_AP0R<n>_EL2
  * ICH_AP1R<n>_EL2
  * ICH_LR<n>_EL2
- * -----------------------------------------------------
+ *
+ * NOTE: For a system with S-EL2 present but not enabled, accessing
+ * ICC_SRE_EL2 is undefined from EL3. To workaround this change the
+ * SCR_EL3.NS = 1 before accessing this register.
+ * ---------------------------------------------------------------------------
  */
-static void el2_sysregs_context_save_common(el2_sysregs_t *ctx)
+static void el2_sysregs_context_save_gic(el2_sysregs_t *ctx)
 {
-	write_ctx_reg(ctx, CTX_ACTLR_EL2, read_actlr_el2());
-	write_ctx_reg(ctx, CTX_AFSR0_EL2, read_afsr0_el2());
-	write_ctx_reg(ctx, CTX_AFSR1_EL2, read_afsr1_el2());
-	write_ctx_reg(ctx, CTX_AMAIR_EL2, read_amair_el2());
-	write_ctx_reg(ctx, CTX_CNTHCTL_EL2, read_cnthctl_el2());
-	write_ctx_reg(ctx, CTX_CNTVOFF_EL2, read_cntvoff_el2());
-	write_ctx_reg(ctx, CTX_CPTR_EL2, read_cptr_el2());
-	if (CTX_INCLUDE_AARCH32_REGS) {
-		write_ctx_reg(ctx, CTX_DBGVCR32_EL2, read_dbgvcr32_el2());
-	}
-	write_ctx_reg(ctx, CTX_ELR_EL2, read_elr_el2());
-	write_ctx_reg(ctx, CTX_ESR_EL2, read_esr_el2());
-	write_ctx_reg(ctx, CTX_FAR_EL2, read_far_el2());
-	write_ctx_reg(ctx, CTX_HACR_EL2, read_hacr_el2());
-	write_ctx_reg(ctx, CTX_HCR_EL2, read_hcr_el2());
-	write_ctx_reg(ctx, CTX_HPFAR_EL2, read_hpfar_el2());
-	write_ctx_reg(ctx, CTX_HSTR_EL2, read_hstr_el2());
-
-	/*
-	 * Set the NS bit to be able to access the ICC_SRE_EL2 register
-	 * TODO: remove with root context
-	 */
+#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+	write_el2_ctx_common(ctx, icc_sre_el2, read_icc_sre_el2());
+#else
 	u_register_t scr_el3 = read_scr_el3();
-
 	write_scr_el3(scr_el3 | SCR_NS_BIT);
 	isb();
-	write_ctx_reg(ctx, CTX_ICC_SRE_EL2, read_icc_sre_el2());
+
+	write_el2_ctx_common(ctx, icc_sre_el2, read_icc_sre_el2());
 
 	write_scr_el3(scr_el3);
 	isb();
-
-	write_ctx_reg(ctx, CTX_ICH_HCR_EL2, read_ich_hcr_el2());
-	write_ctx_reg(ctx, CTX_ICH_VMCR_EL2, read_ich_vmcr_el2());
-	write_ctx_reg(ctx, CTX_MAIR_EL2, read_mair_el2());
-	write_ctx_reg(ctx, CTX_MDCR_EL2, read_mdcr_el2());
-	write_ctx_reg(ctx, CTX_SCTLR_EL2, read_sctlr_el2());
-	write_ctx_reg(ctx, CTX_SPSR_EL2, read_spsr_el2());
-	write_ctx_reg(ctx, CTX_SP_EL2, read_sp_el2());
-	write_ctx_reg(ctx, CTX_TCR_EL2, read_tcr_el2());
-	write_ctx_reg(ctx, CTX_TPIDR_EL2, read_tpidr_el2());
-	write_ctx_reg(ctx, CTX_TTBR0_EL2, read_ttbr0_el2());
-	write_ctx_reg(ctx, CTX_VBAR_EL2, read_vbar_el2());
-	write_ctx_reg(ctx, CTX_VMPIDR_EL2, read_vmpidr_el2());
-	write_ctx_reg(ctx, CTX_VPIDR_EL2, read_vpidr_el2());
-	write_ctx_reg(ctx, CTX_VTCR_EL2, read_vtcr_el2());
-	write_ctx_reg(ctx, CTX_VTTBR_EL2, read_vttbr_el2());
+#endif
+	write_el2_ctx_common(ctx, ich_hcr_el2, read_ich_hcr_el2());
+	write_el2_ctx_common(ctx, ich_vmcr_el2, read_ich_vmcr_el2());
 }
 
-static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
+static void el2_sysregs_context_restore_gic(el2_sysregs_t *ctx)
 {
-	write_actlr_el2(read_ctx_reg(ctx, CTX_ACTLR_EL2));
-	write_afsr0_el2(read_ctx_reg(ctx, CTX_AFSR0_EL2));
-	write_afsr1_el2(read_ctx_reg(ctx, CTX_AFSR1_EL2));
-	write_amair_el2(read_ctx_reg(ctx, CTX_AMAIR_EL2));
-	write_cnthctl_el2(read_ctx_reg(ctx, CTX_CNTHCTL_EL2));
-	write_cntvoff_el2(read_ctx_reg(ctx, CTX_CNTVOFF_EL2));
-	write_cptr_el2(read_ctx_reg(ctx, CTX_CPTR_EL2));
-	if (CTX_INCLUDE_AARCH32_REGS) {
-		write_dbgvcr32_el2(read_ctx_reg(ctx, CTX_DBGVCR32_EL2));
-	}
-	write_elr_el2(read_ctx_reg(ctx, CTX_ELR_EL2));
-	write_esr_el2(read_ctx_reg(ctx, CTX_ESR_EL2));
-	write_far_el2(read_ctx_reg(ctx, CTX_FAR_EL2));
-	write_hacr_el2(read_ctx_reg(ctx, CTX_HACR_EL2));
-	write_hcr_el2(read_ctx_reg(ctx, CTX_HCR_EL2));
-	write_hpfar_el2(read_ctx_reg(ctx, CTX_HPFAR_EL2));
-	write_hstr_el2(read_ctx_reg(ctx, CTX_HSTR_EL2));
-
-	/*
-	 * Set the NS bit to be able to access the ICC_SRE_EL2 register
-	 * TODO: remove with root context
-	 */
+#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2
+	write_icc_sre_el2(read_el2_ctx_common(ctx, icc_sre_el2));
+#else
 	u_register_t scr_el3 = read_scr_el3();
-
 	write_scr_el3(scr_el3 | SCR_NS_BIT);
 	isb();
-	write_icc_sre_el2(read_ctx_reg(ctx, CTX_ICC_SRE_EL2));
+
+	write_icc_sre_el2(read_el2_ctx_common(ctx, icc_sre_el2));
 
 	write_scr_el3(scr_el3);
 	isb();
+#endif
+	write_ich_hcr_el2(read_el2_ctx_common(ctx, ich_hcr_el2));
+	write_ich_vmcr_el2(read_el2_ctx_common(ctx, ich_vmcr_el2));
+}
+
+/* -----------------------------------------------------
+ * The following registers are not added:
+ * AMEVCNTVOFF0<n>_EL2
+ * AMEVCNTVOFF1<n>_EL2
+ * -----------------------------------------------------
+ */
+static void el2_sysregs_context_save_common(el2_sysregs_t *ctx)
+{
+	write_el2_ctx_common(ctx, actlr_el2, read_actlr_el2());
+	write_el2_ctx_common(ctx, afsr0_el2, read_afsr0_el2());
+	write_el2_ctx_common(ctx, afsr1_el2, read_afsr1_el2());
+	write_el2_ctx_common(ctx, amair_el2, read_amair_el2());
+	write_el2_ctx_common(ctx, cnthctl_el2, read_cnthctl_el2());
+	write_el2_ctx_common(ctx, cntvoff_el2, read_cntvoff_el2());
+	write_el2_ctx_common(ctx, cptr_el2, read_cptr_el2());
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		write_el2_ctx_common(ctx, dbgvcr32_el2, read_dbgvcr32_el2());
+	}
+	write_el2_ctx_common(ctx, elr_el2, read_elr_el2());
+	write_el2_ctx_common(ctx, esr_el2, read_esr_el2());
+	write_el2_ctx_common(ctx, far_el2, read_far_el2());
+	write_el2_ctx_common(ctx, hacr_el2, read_hacr_el2());
+	write_el2_ctx_common(ctx, hcr_el2, read_hcr_el2());
+	write_el2_ctx_common(ctx, hpfar_el2, read_hpfar_el2());
+	write_el2_ctx_common(ctx, hstr_el2, read_hstr_el2());
+	write_el2_ctx_common(ctx, mair_el2, read_mair_el2());
+	write_el2_ctx_common(ctx, mdcr_el2, read_mdcr_el2());
+	write_el2_ctx_common(ctx, sctlr_el2, read_sctlr_el2());
+	write_el2_ctx_common(ctx, spsr_el2, read_spsr_el2());
+	write_el2_ctx_common(ctx, sp_el2, read_sp_el2());
+	write_el2_ctx_common(ctx, tcr_el2, read_tcr_el2());
+	write_el2_ctx_common(ctx, tpidr_el2, read_tpidr_el2());
+	write_el2_ctx_common(ctx, vbar_el2, read_vbar_el2());
+	write_el2_ctx_common(ctx, vmpidr_el2, read_vmpidr_el2());
+	write_el2_ctx_common(ctx, vpidr_el2, read_vpidr_el2());
+	write_el2_ctx_common(ctx, vtcr_el2, read_vtcr_el2());
+
+	write_el2_ctx_sysreg128(ctx, ttbr0_el2, read_ttbr0_el2());
+	write_el2_ctx_sysreg128(ctx, vttbr_el2, read_vttbr_el2());
+}
 
-	write_ich_hcr_el2(read_ctx_reg(ctx, CTX_ICH_HCR_EL2));
-	write_ich_vmcr_el2(read_ctx_reg(ctx, CTX_ICH_VMCR_EL2));
-	write_mair_el2(read_ctx_reg(ctx, CTX_MAIR_EL2));
-	write_mdcr_el2(read_ctx_reg(ctx, CTX_MDCR_EL2));
-	write_sctlr_el2(read_ctx_reg(ctx, CTX_SCTLR_EL2));
-	write_spsr_el2(read_ctx_reg(ctx, CTX_SPSR_EL2));
-	write_sp_el2(read_ctx_reg(ctx, CTX_SP_EL2));
-	write_tcr_el2(read_ctx_reg(ctx, CTX_TCR_EL2));
-	write_tpidr_el2(read_ctx_reg(ctx, CTX_TPIDR_EL2));
-	write_ttbr0_el2(read_ctx_reg(ctx, CTX_TTBR0_EL2));
-	write_vbar_el2(read_ctx_reg(ctx, CTX_VBAR_EL2));
-	write_vmpidr_el2(read_ctx_reg(ctx, CTX_VMPIDR_EL2));
-	write_vpidr_el2(read_ctx_reg(ctx, CTX_VPIDR_EL2));
-	write_vtcr_el2(read_ctx_reg(ctx, CTX_VTCR_EL2));
-	write_vttbr_el2(read_ctx_reg(ctx, CTX_VTTBR_EL2));
+static void el2_sysregs_context_restore_common(el2_sysregs_t *ctx)
+{
+	write_actlr_el2(read_el2_ctx_common(ctx, actlr_el2));
+	write_afsr0_el2(read_el2_ctx_common(ctx, afsr0_el2));
+	write_afsr1_el2(read_el2_ctx_common(ctx, afsr1_el2));
+	write_amair_el2(read_el2_ctx_common(ctx, amair_el2));
+	write_cnthctl_el2(read_el2_ctx_common(ctx, cnthctl_el2));
+	write_cntvoff_el2(read_el2_ctx_common(ctx, cntvoff_el2));
+	write_cptr_el2(read_el2_ctx_common(ctx, cptr_el2));
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		write_dbgvcr32_el2(read_el2_ctx_common(ctx, dbgvcr32_el2));
+	}
+	write_elr_el2(read_el2_ctx_common(ctx, elr_el2));
+	write_esr_el2(read_el2_ctx_common(ctx, esr_el2));
+	write_far_el2(read_el2_ctx_common(ctx, far_el2));
+	write_hacr_el2(read_el2_ctx_common(ctx, hacr_el2));
+	write_hcr_el2(read_el2_ctx_common(ctx, hcr_el2));
+	write_hpfar_el2(read_el2_ctx_common(ctx, hpfar_el2));
+	write_hstr_el2(read_el2_ctx_common(ctx, hstr_el2));
+	write_mair_el2(read_el2_ctx_common(ctx, mair_el2));
+	write_mdcr_el2(read_el2_ctx_common(ctx, mdcr_el2));
+	write_sctlr_el2(read_el2_ctx_common(ctx, sctlr_el2));
+	write_spsr_el2(read_el2_ctx_common(ctx, spsr_el2));
+	write_sp_el2(read_el2_ctx_common(ctx, sp_el2));
+	write_tcr_el2(read_el2_ctx_common(ctx, tcr_el2));
+	write_tpidr_el2(read_el2_ctx_common(ctx, tpidr_el2));
+	write_ttbr0_el2(read_el2_ctx_common(ctx, ttbr0_el2));
+	write_vbar_el2(read_el2_ctx_common(ctx, vbar_el2));
+	write_vmpidr_el2(read_el2_ctx_common(ctx, vmpidr_el2));
+	write_vpidr_el2(read_el2_ctx_common(ctx, vpidr_el2));
+	write_vtcr_el2(read_el2_ctx_common(ctx, vtcr_el2));
+	write_vttbr_el2(read_el2_ctx_common(ctx, vttbr_el2));
 }
 
 /*******************************************************************************
@@ -1230,9 +1404,12 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
 	el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
 
 	el2_sysregs_context_save_common(el2_sysregs_ctx);
-#if CTX_INCLUDE_MTE_REGS
-	write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
-#endif
+	el2_sysregs_context_save_gic(el2_sysregs_ctx);
+
+	if (is_feat_mte2_supported()) {
+		write_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2, read_tfsr_el2());
+	}
+
 	if (is_feat_mpam_supported()) {
 		el2_sysregs_context_save_mpam(el2_sysregs_ctx);
 	}
@@ -1241,51 +1418,66 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
 		el2_sysregs_context_save_fgt(el2_sysregs_ctx);
 	}
 
+	if (is_feat_fgt2_supported()) {
+		el2_sysregs_context_save_fgt2(el2_sysregs_ctx);
+	}
+
 	if (is_feat_ecv_v2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2, read_cntpoff_el2());
+		write_el2_ctx_ecv(el2_sysregs_ctx, cntpoff_el2, read_cntpoff_el2());
 	}
 
 	if (is_feat_vhe_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2, read_contextidr_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2, read_ttbr1_el2());
+		write_el2_ctx_vhe(el2_sysregs_ctx, contextidr_el2,
+					read_contextidr_el2());
+		write_el2_ctx_vhe_sysreg128(el2_sysregs_ctx, ttbr1_el2, read_ttbr1_el2());
 	}
 
 	if (is_feat_ras_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2, read_vdisr_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2, read_vsesr_el2());
+		write_el2_ctx_ras(el2_sysregs_ctx, vdisr_el2, read_vdisr_el2());
+		write_el2_ctx_ras(el2_sysregs_ctx, vsesr_el2, read_vsesr_el2());
 	}
 
 	if (is_feat_nv2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2, read_vncr_el2());
+		write_el2_ctx_neve(el2_sysregs_ctx, vncr_el2, read_vncr_el2());
 	}
 
 	if (is_feat_trf_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
+		write_el2_ctx_trf(el2_sysregs_ctx, trfcr_el2, read_trfcr_el2());
 	}
 
 	if (is_feat_csv2_2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2, read_scxtnum_el2());
+		write_el2_ctx_csv2_2(el2_sysregs_ctx, scxtnum_el2,
+					read_scxtnum_el2());
 	}
 
 	if (is_feat_hcx_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2());
+		write_el2_ctx_hcx(el2_sysregs_ctx, hcrx_el2, read_hcrx_el2());
 	}
+
 	if (is_feat_tcr2_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2, read_tcr2_el2());
+		write_el2_ctx_tcr2(el2_sysregs_ctx, tcr2_el2, read_tcr2_el2());
 	}
+
 	if (is_feat_sxpie_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2, read_pire0_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2, read_pir_el2());
-	}
-	if (is_feat_s2pie_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2, read_s2pir_el2());
+		write_el2_ctx_sxpie(el2_sysregs_ctx, pire0_el2, read_pire0_el2());
+		write_el2_ctx_sxpie(el2_sysregs_ctx, pir_el2, read_pir_el2());
 	}
+
 	if (is_feat_sxpoe_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2, read_por_el2());
+		write_el2_ctx_sxpoe(el2_sysregs_ctx, por_el2, read_por_el2());
 	}
+
+	if (is_feat_s2pie_supported()) {
+		write_el2_ctx_s2pie(el2_sysregs_ctx, s2pir_el2, read_s2pir_el2());
+	}
+
 	if (is_feat_gcs_supported()) {
-		write_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2, read_gcspr_el2());
-		write_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2, read_gcscr_el2());
+		write_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2, read_gcscr_el2());
+		write_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2, read_gcspr_el2());
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_el2_ctx_sctlr2(el2_sysregs_ctx, sctlr2_el2, read_sctlr2_el2());
 	}
 }
 
@@ -1303,9 +1495,12 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
 	el2_sysregs_ctx = get_el2_sysregs_ctx(ctx);
 
 	el2_sysregs_context_restore_common(el2_sysregs_ctx);
-#if CTX_INCLUDE_MTE_REGS
-	write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
-#endif
+	el2_sysregs_context_restore_gic(el2_sysregs_ctx);
+
+	if (is_feat_mte2_supported()) {
+		write_tfsr_el2(read_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2));
+	}
+
 	if (is_feat_mpam_supported()) {
 		el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
 	}
@@ -1314,53 +1509,117 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
 		el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
 	}
 
+	if (is_feat_fgt2_supported()) {
+		el2_sysregs_context_restore_fgt2(el2_sysregs_ctx);
+	}
+
 	if (is_feat_ecv_v2_supported()) {
-		write_cntpoff_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CNTPOFF_EL2));
+		write_cntpoff_el2(read_el2_ctx_ecv(el2_sysregs_ctx, cntpoff_el2));
 	}
 
 	if (is_feat_vhe_supported()) {
-		write_contextidr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2));
-		write_ttbr1_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2));
+		write_contextidr_el2(read_el2_ctx_vhe(el2_sysregs_ctx,
+					contextidr_el2));
+		write_ttbr1_el2(read_el2_ctx_vhe(el2_sysregs_ctx, ttbr1_el2));
 	}
 
 	if (is_feat_ras_supported()) {
-		write_vdisr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VDISR_EL2));
-		write_vsesr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VSESR_EL2));
+		write_vdisr_el2(read_el2_ctx_ras(el2_sysregs_ctx, vdisr_el2));
+		write_vsesr_el2(read_el2_ctx_ras(el2_sysregs_ctx, vsesr_el2));
 	}
 
 	if (is_feat_nv2_supported()) {
-		write_vncr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_VNCR_EL2));
+		write_vncr_el2(read_el2_ctx_neve(el2_sysregs_ctx, vncr_el2));
 	}
+
 	if (is_feat_trf_supported()) {
-		write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
+		write_trfcr_el2(read_el2_ctx_trf(el2_sysregs_ctx, trfcr_el2));
 	}
 
 	if (is_feat_csv2_2_supported()) {
-		write_scxtnum_el2(read_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2));
+		write_scxtnum_el2(read_el2_ctx_csv2_2(el2_sysregs_ctx,
+					scxtnum_el2));
 	}
 
 	if (is_feat_hcx_supported()) {
-		write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2));
+		write_hcrx_el2(read_el2_ctx_hcx(el2_sysregs_ctx, hcrx_el2));
 	}
+
 	if (is_feat_tcr2_supported()) {
-		write_tcr2_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TCR2_EL2));
+		write_tcr2_el2(read_el2_ctx_tcr2(el2_sysregs_ctx, tcr2_el2));
 	}
+
 	if (is_feat_sxpie_supported()) {
-		write_pire0_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIRE0_EL2));
-		write_pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_PIR_EL2));
-	}
-	if (is_feat_s2pie_supported()) {
-		write_s2pir_el2(read_ctx_reg(el2_sysregs_ctx, CTX_S2PIR_EL2));
+		write_pire0_el2(read_el2_ctx_sxpie(el2_sysregs_ctx, pire0_el2));
+		write_pir_el2(read_el2_ctx_sxpie(el2_sysregs_ctx, pir_el2));
 	}
+
 	if (is_feat_sxpoe_supported()) {
-		write_por_el2(read_ctx_reg(el2_sysregs_ctx, CTX_POR_EL2));
+		write_por_el2(read_el2_ctx_sxpoe(el2_sysregs_ctx, por_el2));
 	}
+
+	if (is_feat_s2pie_supported()) {
+		write_s2pir_el2(read_el2_ctx_s2pie(el2_sysregs_ctx, s2pir_el2));
+	}
+
 	if (is_feat_gcs_supported()) {
-		write_gcscr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSCR_EL2));
-		write_gcspr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_GCSPR_EL2));
+		write_gcscr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcscr_el2));
+		write_gcspr_el2(read_el2_ctx_gcs(el2_sysregs_ctx, gcspr_el2));
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_sctlr2_el2(read_el2_ctx_sctlr2(el2_sysregs_ctx, sctlr2_el2));
 	}
 }
-#endif /* CTX_INCLUDE_EL2_REGS */
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
+
+#if IMAGE_BL31
+/*********************************************************************************
+* This function allows Architecture features asymmetry among cores.
+* TF-A assumes that all the cores in the platform has architecture feature parity
+* and hence the context is setup on different core (e.g. primary sets up the
+* context for secondary cores).This assumption may not be true for systems where
+* cores are not conforming to same Arch version or there is CPU Erratum which
+* requires certain feature to be be disabled only on a given core.
+*
+* This function is called on secondary cores to override any disparity in context
+* setup by primary, this would be called during warmboot path.
+*********************************************************************************/
+void cm_handle_asymmetric_features(void)
+{
+	cpu_context_t *ctx __maybe_unused = cm_get_context(NON_SECURE);
+
+	assert(ctx != NULL);
+
+#if ENABLE_SPE_FOR_NS == FEAT_STATE_CHECK_ASYMMETRIC
+	if (is_feat_spe_supported()) {
+		spe_enable(ctx);
+	} else {
+		spe_disable(ctx);
+	}
+#endif
+
+#if ERRATA_A520_2938996 || ERRATA_X4_2726228
+	if (check_if_affected_core() == ERRATA_APPLIES) {
+		if (is_feat_trbe_supported()) {
+			trbe_disable(ctx);
+		}
+	}
+#endif
+
+#if ENABLE_FEAT_TCR2 == FEAT_STATE_CHECK_ASYMMETRIC
+	el3_state_t *el3_state = get_el3state_ctx(ctx);
+	u_register_t spsr = read_ctx_reg(el3_state, CTX_SPSR_EL3);
+
+	if (is_feat_tcr2_supported() && (GET_RW(spsr) == MODE_RW_64)) {
+		tcr2_enable(ctx);
+	} else {
+		tcr2_disable(ctx);
+	}
+#endif
+
+}
+#endif
 
 /*******************************************************************************
  * This function is used to exit to Non-secure world. If CTX_INCLUDE_EL2_REGS
@@ -1370,7 +1629,19 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
  ******************************************************************************/
 void cm_prepare_el3_exit_ns(void)
 {
-#if CTX_INCLUDE_EL2_REGS
+#if IMAGE_BL31
+	/*
+	 * Check and handle Architecture feature asymmetry among cores.
+	 *
+	 * In warmboot path secondary cores context is initialized on core which
+	 * did CPU_ON SMC call, if there is feature asymmetry in these cores handle
+	 * it in this function call.
+	 * For Symmetric cores this is an empty function.
+	 */
+	cm_handle_asymmetric_features();
+#endif
+
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
 #if ENABLE_ASSERTIONS
 	cpu_context_t *ctx = cm_get_context(NON_SECURE);
 	assert(ctx != NULL);
@@ -1381,19 +1652,238 @@ void cm_prepare_el3_exit_ns(void)
 			(el_implemented(2U) != EL_IMPL_NONE));
 #endif /* ENABLE_ASSERTIONS */
 
-	/* Restore EL2 and EL1 sysreg contexts */
+	/* Restore EL2 sysreg contexts */
 	cm_el2_sysregs_context_restore(NON_SECURE);
-	cm_el1_sysregs_context_restore(NON_SECURE);
 	cm_set_next_eret_context(NON_SECURE);
 #else
 	cm_prepare_el3_exit(NON_SECURE);
-#endif /* CTX_INCLUDE_EL2_REGS */
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 }
 
+#if ((IMAGE_BL1) || (IMAGE_BL31 && (!CTX_INCLUDE_EL2_REGS)))
 /*******************************************************************************
- * The next four functions are used by runtime services to save and restore
- * EL1 context on the 'cpu_context' structure for the specified security
- * state.
+ * The next set of six functions are used by runtime services to save and restore
+ * EL1 context on the 'cpu_context' structure for the specified security state.
+ ******************************************************************************/
+static void el1_sysregs_context_save(el1_sysregs_t *ctx)
+{
+	write_el1_ctx_common(ctx, spsr_el1, read_spsr_el1());
+	write_el1_ctx_common(ctx, elr_el1, read_elr_el1());
+
+#if (!ERRATA_SPECULATIVE_AT)
+	write_el1_ctx_common(ctx, sctlr_el1, read_sctlr_el1());
+	write_el1_ctx_common(ctx, tcr_el1, read_tcr_el1());
+#endif /* (!ERRATA_SPECULATIVE_AT) */
+
+	write_el1_ctx_common(ctx, cpacr_el1, read_cpacr_el1());
+	write_el1_ctx_common(ctx, csselr_el1, read_csselr_el1());
+	write_el1_ctx_common(ctx, sp_el1, read_sp_el1());
+	write_el1_ctx_common(ctx, esr_el1, read_esr_el1());
+	write_el1_ctx_common(ctx, ttbr0_el1, read_ttbr0_el1());
+	write_el1_ctx_common(ctx, ttbr1_el1, read_ttbr1_el1());
+	write_el1_ctx_common(ctx, mair_el1, read_mair_el1());
+	write_el1_ctx_common(ctx, amair_el1, read_amair_el1());
+	write_el1_ctx_common(ctx, actlr_el1, read_actlr_el1());
+	write_el1_ctx_common(ctx, tpidr_el1, read_tpidr_el1());
+	write_el1_ctx_common(ctx, tpidr_el0, read_tpidr_el0());
+	write_el1_ctx_common(ctx, tpidrro_el0, read_tpidrro_el0());
+	write_el1_ctx_common(ctx, par_el1, read_par_el1());
+	write_el1_ctx_common(ctx, far_el1, read_far_el1());
+	write_el1_ctx_common(ctx, afsr0_el1, read_afsr0_el1());
+	write_el1_ctx_common(ctx, afsr1_el1, read_afsr1_el1());
+	write_el1_ctx_common(ctx, contextidr_el1, read_contextidr_el1());
+	write_el1_ctx_common(ctx, vbar_el1, read_vbar_el1());
+	write_el1_ctx_common(ctx, mdccint_el1, read_mdccint_el1());
+	write_el1_ctx_common(ctx, mdscr_el1, read_mdscr_el1());
+
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		/* Save Aarch32 registers */
+		write_el1_ctx_aarch32(ctx, spsr_abt, read_spsr_abt());
+		write_el1_ctx_aarch32(ctx, spsr_und, read_spsr_und());
+		write_el1_ctx_aarch32(ctx, spsr_irq, read_spsr_irq());
+		write_el1_ctx_aarch32(ctx, spsr_fiq, read_spsr_fiq());
+		write_el1_ctx_aarch32(ctx, dacr32_el2, read_dacr32_el2());
+		write_el1_ctx_aarch32(ctx, ifsr32_el2, read_ifsr32_el2());
+	}
+
+	if (NS_TIMER_SWITCH) {
+		/* Save NS Timer registers */
+		write_el1_ctx_arch_timer(ctx, cntp_ctl_el0, read_cntp_ctl_el0());
+		write_el1_ctx_arch_timer(ctx, cntp_cval_el0, read_cntp_cval_el0());
+		write_el1_ctx_arch_timer(ctx, cntv_ctl_el0, read_cntv_ctl_el0());
+		write_el1_ctx_arch_timer(ctx, cntv_cval_el0, read_cntv_cval_el0());
+		write_el1_ctx_arch_timer(ctx, cntkctl_el1, read_cntkctl_el1());
+	}
+
+	if (is_feat_mte2_supported()) {
+		write_el1_ctx_mte2(ctx, tfsre0_el1, read_tfsre0_el1());
+		write_el1_ctx_mte2(ctx, tfsr_el1, read_tfsr_el1());
+		write_el1_ctx_mte2(ctx, rgsr_el1, read_rgsr_el1());
+		write_el1_ctx_mte2(ctx, gcr_el1, read_gcr_el1());
+	}
+
+	if (is_feat_ras_supported()) {
+		write_el1_ctx_ras(ctx, disr_el1, read_disr_el1());
+	}
+
+	if (is_feat_s1pie_supported()) {
+		write_el1_ctx_s1pie(ctx, pire0_el1, read_pire0_el1());
+		write_el1_ctx_s1pie(ctx, pir_el1, read_pir_el1());
+	}
+
+	if (is_feat_s1poe_supported()) {
+		write_el1_ctx_s1poe(ctx, por_el1, read_por_el1());
+	}
+
+	if (is_feat_s2poe_supported()) {
+		write_el1_ctx_s2poe(ctx, s2por_el1, read_s2por_el1());
+	}
+
+	if (is_feat_tcr2_supported()) {
+		write_el1_ctx_tcr2(ctx, tcr2_el1, read_tcr2_el1());
+	}
+
+	if (is_feat_trf_supported()) {
+		write_el1_ctx_trf(ctx, trfcr_el1, read_trfcr_el1());
+	}
+
+	if (is_feat_csv2_2_supported()) {
+		write_el1_ctx_csv2_2(ctx, scxtnum_el0, read_scxtnum_el0());
+		write_el1_ctx_csv2_2(ctx, scxtnum_el1, read_scxtnum_el1());
+	}
+
+	if (is_feat_gcs_supported()) {
+		write_el1_ctx_gcs(ctx, gcscr_el1, read_gcscr_el1());
+		write_el1_ctx_gcs(ctx, gcscre0_el1, read_gcscre0_el1());
+		write_el1_ctx_gcs(ctx, gcspr_el1, read_gcspr_el1());
+		write_el1_ctx_gcs(ctx, gcspr_el0, read_gcspr_el0());
+	}
+
+	if (is_feat_the_supported()) {
+		write_el1_ctx_the(ctx, rcwmask_el1, read_rcwmask_el1());
+		write_el1_ctx_the(ctx, rcwsmask_el1, read_rcwsmask_el1());
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_el1_ctx_sctlr2(ctx, sctlr2_el1, read_sctlr2_el1());
+	}
+
+	if (is_feat_ls64_accdata_supported()) {
+		write_el1_ctx_ls64(ctx, accdata_el1, read_accdata_el1());
+	}
+}
+
+static void el1_sysregs_context_restore(el1_sysregs_t *ctx)
+{
+	write_spsr_el1(read_el1_ctx_common(ctx, spsr_el1));
+	write_elr_el1(read_el1_ctx_common(ctx, elr_el1));
+
+#if (!ERRATA_SPECULATIVE_AT)
+	write_sctlr_el1(read_el1_ctx_common(ctx, sctlr_el1));
+	write_tcr_el1(read_el1_ctx_common(ctx, tcr_el1));
+#endif /* (!ERRATA_SPECULATIVE_AT) */
+
+	write_cpacr_el1(read_el1_ctx_common(ctx, cpacr_el1));
+	write_csselr_el1(read_el1_ctx_common(ctx, csselr_el1));
+	write_sp_el1(read_el1_ctx_common(ctx, sp_el1));
+	write_esr_el1(read_el1_ctx_common(ctx, esr_el1));
+	write_ttbr0_el1(read_el1_ctx_common(ctx, ttbr0_el1));
+	write_ttbr1_el1(read_el1_ctx_common(ctx, ttbr1_el1));
+	write_mair_el1(read_el1_ctx_common(ctx, mair_el1));
+	write_amair_el1(read_el1_ctx_common(ctx, amair_el1));
+	write_actlr_el1(read_el1_ctx_common(ctx, actlr_el1));
+	write_tpidr_el1(read_el1_ctx_common(ctx, tpidr_el1));
+	write_tpidr_el0(read_el1_ctx_common(ctx, tpidr_el0));
+	write_tpidrro_el0(read_el1_ctx_common(ctx, tpidrro_el0));
+	write_par_el1(read_el1_ctx_common(ctx, par_el1));
+	write_far_el1(read_el1_ctx_common(ctx, far_el1));
+	write_afsr0_el1(read_el1_ctx_common(ctx, afsr0_el1));
+	write_afsr1_el1(read_el1_ctx_common(ctx, afsr1_el1));
+	write_contextidr_el1(read_el1_ctx_common(ctx, contextidr_el1));
+	write_vbar_el1(read_el1_ctx_common(ctx, vbar_el1));
+	write_mdccint_el1(read_el1_ctx_common(ctx, mdccint_el1));
+	write_mdscr_el1(read_el1_ctx_common(ctx, mdscr_el1));
+
+	if (CTX_INCLUDE_AARCH32_REGS) {
+		/* Restore Aarch32 registers */
+		write_spsr_abt(read_el1_ctx_aarch32(ctx, spsr_abt));
+		write_spsr_und(read_el1_ctx_aarch32(ctx, spsr_und));
+		write_spsr_irq(read_el1_ctx_aarch32(ctx, spsr_irq));
+		write_spsr_fiq(read_el1_ctx_aarch32(ctx, spsr_fiq));
+		write_dacr32_el2(read_el1_ctx_aarch32(ctx, dacr32_el2));
+		write_ifsr32_el2(read_el1_ctx_aarch32(ctx, ifsr32_el2));
+	}
+
+	if (NS_TIMER_SWITCH) {
+		/* Restore NS Timer registers */
+		write_cntp_ctl_el0(read_el1_ctx_arch_timer(ctx, cntp_ctl_el0));
+		write_cntp_cval_el0(read_el1_ctx_arch_timer(ctx, cntp_cval_el0));
+		write_cntv_ctl_el0(read_el1_ctx_arch_timer(ctx, cntv_ctl_el0));
+		write_cntv_cval_el0(read_el1_ctx_arch_timer(ctx, cntv_cval_el0));
+		write_cntkctl_el1(read_el1_ctx_arch_timer(ctx, cntkctl_el1));
+	}
+
+	if (is_feat_mte2_supported()) {
+		write_tfsre0_el1(read_el1_ctx_mte2(ctx, tfsre0_el1));
+		write_tfsr_el1(read_el1_ctx_mte2(ctx, tfsr_el1));
+		write_rgsr_el1(read_el1_ctx_mte2(ctx, rgsr_el1));
+		write_gcr_el1(read_el1_ctx_mte2(ctx, gcr_el1));
+	}
+
+	if (is_feat_ras_supported()) {
+		write_disr_el1(read_el1_ctx_ras(ctx, disr_el1));
+	}
+
+	if (is_feat_s1pie_supported()) {
+		write_pire0_el1(read_el1_ctx_s1pie(ctx, pire0_el1));
+		write_pir_el1(read_el1_ctx_s1pie(ctx, pir_el1));
+	}
+
+	if (is_feat_s1poe_supported()) {
+		write_por_el1(read_el1_ctx_s1poe(ctx, por_el1));
+	}
+
+	if (is_feat_s2poe_supported()) {
+		write_s2por_el1(read_el1_ctx_s2poe(ctx, s2por_el1));
+	}
+
+	if (is_feat_tcr2_supported()) {
+		write_tcr2_el1(read_el1_ctx_tcr2(ctx, tcr2_el1));
+	}
+
+	if (is_feat_trf_supported()) {
+		write_trfcr_el1(read_el1_ctx_trf(ctx, trfcr_el1));
+	}
+
+	if (is_feat_csv2_2_supported()) {
+		write_scxtnum_el0(read_el1_ctx_csv2_2(ctx, scxtnum_el0));
+		write_scxtnum_el1(read_el1_ctx_csv2_2(ctx, scxtnum_el1));
+	}
+
+	if (is_feat_gcs_supported()) {
+		write_gcscr_el1(read_el1_ctx_gcs(ctx, gcscr_el1));
+		write_gcscre0_el1(read_el1_ctx_gcs(ctx, gcscre0_el1));
+		write_gcspr_el1(read_el1_ctx_gcs(ctx, gcspr_el1));
+		write_gcspr_el0(read_el1_ctx_gcs(ctx, gcspr_el0));
+	}
+
+	if (is_feat_the_supported()) {
+		write_rcwmask_el1(read_el1_ctx_the(ctx, rcwmask_el1));
+		write_rcwsmask_el1(read_el1_ctx_the(ctx, rcwsmask_el1));
+	}
+
+	if (is_feat_sctlr2_supported()) {
+		write_sctlr2_el1(read_el1_ctx_sctlr2(ctx, sctlr2_el1));
+	}
+
+	if (is_feat_ls64_accdata_supported()) {
+		write_accdata_el1(read_el1_ctx_ls64(ctx, accdata_el1));
+	}
+}
+
+/*******************************************************************************
+ * The next couple of functions are used by runtime services to save and restore
+ * EL1 context on the 'cpu_context' structure for the specified security state.
  ******************************************************************************/
 void cm_el1_sysregs_context_save(uint32_t security_state)
 {
@@ -1429,6 +1919,8 @@ void cm_el1_sysregs_context_restore(uint32_t security_state)
 #endif
 }
 
+#endif /* ((IMAGE_BL1) || (IMAGE_BL31 && (!CTX_INCLUDE_EL2_REGS))) */
+
 /*******************************************************************************
  * This function populates ELR_EL3 member of 'cpu_context' pertaining to the
  * given security state with the given entrypoint
diff --git a/lib/el3_runtime/simd_ctx.c b/lib/el3_runtime/simd_ctx.c
new file mode 100644
index 00000000..f7a87dfe
--- /dev/null
+++ b/lib/el3_runtime/simd_ctx.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <lib/el3_runtime/aarch64/context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/el3_runtime/cpu_data.h>
+#include <lib/el3_runtime/simd_ctx.h>
+#include <lib/extensions/sve.h>
+#include <plat/common/platform.h>
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+
+/* SIMD context managed for Secure and Normal Worlds. */
+#define SIMD_CTXT_COUNT	2
+
+#if SEPARATE_SIMD_SECTION
+__section(".simd_context")
+#else
+__section(".bss.simd_context")
+#endif
+static simd_regs_t simd_context[SIMD_CTXT_COUNT][PLATFORM_CORE_COUNT];
+
+void simd_ctx_save(uint32_t security_state, bool hint_sve)
+{
+	simd_regs_t *regs;
+
+	if (security_state != NON_SECURE && security_state != SECURE) {
+		ERROR("Unsupported security state specified for SIMD context: %u\n",
+		      security_state);
+		panic();
+	}
+
+	regs = &simd_context[security_state][plat_my_core_pos()];
+
+#if CTX_INCLUDE_SVE_REGS
+	regs->hint = hint_sve;
+
+	if (hint_sve) {
+		/*
+		 * Hint bit denoting absence of SVE live state. Hence, only
+		 * save FP context.
+		 */
+		fpregs_context_save(regs);
+	} else {
+		sve_context_save(regs);
+	}
+#elif CTX_INCLUDE_FPREGS
+	fpregs_context_save(regs);
+#endif
+}
+
+void simd_ctx_restore(uint32_t security_state)
+{
+	simd_regs_t *regs;
+
+	if (security_state != NON_SECURE && security_state != SECURE) {
+		ERROR("Unsupported security state specified for SIMD context: %u\n",
+		      security_state);
+		panic();
+	}
+
+	regs = &simd_context[security_state][plat_my_core_pos()];
+
+#if CTX_INCLUDE_SVE_REGS
+	if (regs->hint) {
+		fpregs_context_restore(regs);
+	} else {
+		sve_context_restore(regs);
+	}
+#elif CTX_INCLUDE_FPREGS
+	fpregs_context_restore(regs);
+#endif
+}
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
diff --git a/lib/extensions/brbe/brbe.c b/lib/extensions/brbe/brbe.c
index 37bd8349..fef66478 100644
--- a/lib/extensions/brbe/brbe.c
+++ b/lib/extensions/brbe/brbe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,18 +9,20 @@
 #include <arch_helpers.h>
 #include <lib/extensions/brbe.h>
 
-void brbe_init_el3(void)
+void brbe_enable(cpu_context_t *ctx)
 {
-	uint64_t val;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.SBRBE = 0b01
-	 *
 	 * Allows BRBE usage in non-secure world and prohibited in
 	 * secure world.
+	 *
+	 * MDCR_EL3.{E3BREW, E3BREC} = 0b00
+	 * Branch recording at EL3 is disabled
 	 */
-	val = read_mdcr_el3();
-	val &= ~(MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT);
-	val |= (0x1UL << MDCR_SBRBE_SHIFT);
-	write_mdcr_el3(val);
+	mdcr_el3_val &= ~((MDCR_SBRBE_MASK << MDCR_SBRBE_SHIFT) | MDCR_E3BREW | MDCR_E3BREC);
+	mdcr_el3_val |= (0x1UL << MDCR_SBRBE_SHIFT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
diff --git a/lib/extensions/debug/debugv8p9.c b/lib/extensions/debug/debugv8p9.c
new file mode 100644
index 00000000..f3cffa73
--- /dev/null
+++ b/lib/extensions/debug/debugv8p9.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/extensions/debug_v8p9.h>
+
+void debugv8p9_extended_bp_wp_enable(cpu_context_t *ctx)
+{
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
+
+	/* When FEAT_Debugv8p9 is implemented:
+	 *
+	 * MDCR_EL3.EBWE: Set to 0b1
+	 * Enables use of additional breakpoints or watchpoints,
+	 * and disables trap to EL3 on accesses to debug register.
+	 */
+
+	mdcr_el3_val |= MDCR_EBWE_BIT;
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
+}
diff --git a/lib/extensions/fgt/fgt2.c b/lib/extensions/fgt/fgt2.c
new file mode 100644
index 00000000..78f1a822
--- /dev/null
+++ b/lib/extensions/fgt/fgt2.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/extensions/fgt2.h>
+
+void fgt2_enable(cpu_context_t *context)
+{
+	u_register_t reg;
+	el3_state_t *state;
+
+	state = get_el3state_ctx(context);
+
+	/* Set the FGTEN2 bit in SCR_EL3 to enable access to HFGITR2_EL2,
+	 * HFGRTR2_EL2, HFGWTR_EL2, HDFGRTR2_EL2, and HDFGWTR2_EL2.
+	 */
+
+	reg = read_ctx_reg(state, CTX_SCR_EL3);
+	reg |= SCR_FGTEN2_BIT;
+	write_ctx_reg(state, CTX_SCR_EL3, reg);
+}
+
diff --git a/lib/extensions/mpam/mpam.c b/lib/extensions/mpam/mpam.c
index 875ad9c2..5285b96d 100644
--- a/lib/extensions/mpam/mpam.c
+++ b/lib/extensions/mpam/mpam.c
@@ -11,19 +11,19 @@
 #include <arch_helpers.h>
 #include <lib/extensions/mpam.h>
 
-void mpam_enable(cpu_context_t *context)
+void mpam_enable_per_world(per_world_context_t *per_world_ctx)
 {
 	u_register_t mpam3_el3;
 
-	mpam3_el3 = read_ctx_reg(get_el3state_ctx(context), CTX_MPAM3_EL3);
-
 	/*
 	 * Enable MPAM, and disable trapping to EL3 when lower ELs access their
 	 * own MPAM registers
 	 */
+	mpam3_el3 = per_world_ctx->ctx_mpam3_el3;
 	mpam3_el3 = (mpam3_el3 | MPAM3_EL3_MPAMEN_BIT) &
 				~(MPAM3_EL3_TRAPLOWER_BIT);
-	write_ctx_reg(get_el3state_ctx(context), CTX_MPAM3_EL3, mpam3_el3);
+
+	per_world_ctx->ctx_mpam3_el3 = mpam3_el3;
 }
 
 /*
diff --git a/lib/extensions/pmuv3/aarch32/pmuv3.c b/lib/extensions/pmuv3/aarch32/pmuv3.c
index effb7e02..456a48ef 100644
--- a/lib/extensions/pmuv3/aarch32/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch32/pmuv3.c
@@ -25,10 +25,6 @@ static u_register_t mtpmu_disable_el3(u_register_t sdcr)
 	return sdcr;
 }
 
-/*
- * Applies to all PMU versions. Name is PMUv3 for compatibility with aarch64 and
- * to not clash with platforms which reuse the PMU name
- */
 void pmuv3_init_el3(void)
 {
 	u_register_t sdcr = read_sdcr();
diff --git a/lib/extensions/pmuv3/aarch64/pmuv3.c b/lib/extensions/pmuv3/aarch64/pmuv3.c
index 61fc47dc..f9e32cad 100644
--- a/lib/extensions/pmuv3/aarch64/pmuv3.c
+++ b/lib/extensions/pmuv3/aarch64/pmuv3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,13 +23,13 @@ static u_register_t init_mdcr_el2_hpmn(u_register_t mdcr_el2)
 
 void pmuv3_enable(cpu_context_t *ctx)
 {
-#if CTX_INCLUDE_EL2_REGS
-	u_register_t mdcr_el2;
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
+	u_register_t mdcr_el2_val;
 
-	mdcr_el2 = read_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2);
-	mdcr_el2 = init_mdcr_el2_hpmn(mdcr_el2);
-	write_ctx_reg(get_el2_sysregs_ctx(ctx), CTX_MDCR_EL2, mdcr_el2);
-#endif /* CTX_INCLUDE_EL2_REGS */
+	mdcr_el2_val = read_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2);
+	mdcr_el2_val = init_mdcr_el2_hpmn(mdcr_el2_val);
+	write_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2, mdcr_el2_val);
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 }
 
 static u_register_t mtpmu_disable_el3(u_register_t mdcr_el3)
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index b1409b95..98d57e92 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -53,7 +53,7 @@ void sme_init_el3(void)
 	 * using SMCR_EL2 and SMCR_EL1.
 	 */
 	smcr_el3 = SMCR_ELX_LEN_MAX;
-	if (read_feat_sme_fa64_id_field() != 0U) {
+	if (is_feat_sme_fa64_present()) {
 		VERBOSE("[SME] FA64 enabled\n");
 		smcr_el3 |= SMCR_ELX_FA64_BIT;
 	}
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index 2c25a9db..d6532224 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,14 @@
 #include <lib/el3_runtime/pubsub.h>
 #include <lib/extensions/spe.h>
 
+#include <plat/common/platform.h>
+
+typedef struct spe_ctx {
+	u_register_t pmblimitr_el1;
+} spe_ctx_t;
+
+static struct spe_ctx spe_ctxs[PLATFORM_CORE_COUNT];
+
 static inline void psb_csync(void)
 {
 	/*
@@ -21,9 +29,10 @@ static inline void psb_csync(void)
 	__asm__ volatile("hint #17");
 }
 
-void spe_init_el3(void)
+void spe_enable(cpu_context_t *ctx)
 {
-	uint64_t v;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.NSPB (ARM v8.2): SPE enabled in Non-secure state
@@ -38,10 +47,30 @@ void spe_init_el3(void)
 	 * Setting this bit to 1 doesn't have any effect on it when
 	 * FEAT_SPEv1p2 not implemented.
 	 */
-	v = read_mdcr_el3();
-	v |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT;
-	v &= ~(MDCR_NSPBE_BIT);
-	write_mdcr_el3(v);
+	mdcr_el3_val |= MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT;
+	mdcr_el3_val &= ~(MDCR_NSPBE_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
+}
+
+void spe_disable(cpu_context_t *ctx)
+{
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
+
+	/*
+	 * MDCR_EL3.NSPB: Clear these bits to disable SPE feature, as it was enabled
+	 * for Non-secure state only. After clearing these bits Secure state owns
+	 * the Profiling Buffer and accesses to Statistical Profiling and Profiling
+	 * Buffer control registers at EL2 and EL1 generate Trap exceptions to EL3
+	 *
+	 * MDCR_EL3.NSPBE: Don't care as it was cleared during spe_enable and setting
+	 * this to 1 does not make sense as NSPBE{1} and NSPB{0b0x} is RESERVED.
+	 *
+	 * MDCR_EL3.EnPMSN (ARM v8.7): Clear the bit to trap access of PMSNEVFR_EL1
+	 * from EL2/EL1 to EL3.
+	 */
+	mdcr_el3_val &= ~(MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
 void spe_init_el2_unused(void)
@@ -62,7 +91,7 @@ void spe_init_el2_unused(void)
 	write_mdcr_el2(v);
 }
 
-void spe_disable(void)
+void spe_stop(void)
 {
 	uint64_t v;
 
@@ -89,4 +118,35 @@ static void *spe_drain_buffers_hook(const void *arg)
 	return (void *)0;
 }
 
+static void *spe_context_save(const void *arg)
+{
+	unsigned int core_pos;
+	struct spe_ctx *ctx;
+
+	if (is_feat_spe_supported()) {
+		core_pos = plat_my_core_pos();
+		ctx = &spe_ctxs[core_pos];
+		ctx->pmblimitr_el1 = read_pmblimitr_el1();
+	}
+
+	return NULL;
+}
+
+static void *spe_context_restore(const void *arg)
+{
+	unsigned int core_pos;
+	struct spe_ctx *ctx;
+
+	if (is_feat_spe_supported()) {
+		core_pos = plat_my_core_pos();
+		ctx = &spe_ctxs[core_pos];
+		write_pmblimitr_el1(ctx->pmblimitr_el1);
+	}
+
+	return NULL;
+}
+
 SUBSCRIBE_TO_EVENT(cm_entering_secure_world, spe_drain_buffers_hook);
+
+SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, spe_context_save);
+SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_finish, spe_context_restore);
diff --git a/lib/extensions/sysreg128/sysreg128.S b/lib/extensions/sysreg128/sysreg128.S
new file mode 100644
index 00000000..08cff2fb
--- /dev/null
+++ b/lib/extensions/sysreg128/sysreg128.S
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <lib/extensions/sysreg128.h>
+
+        .global read_par_el1
+        .global write_par_el1
+        .global read_ttbr0_el1
+        .global write_ttbr0_el1
+        .global read_ttbr1_el1
+        .global write_ttbr1_el1
+        .global read_ttbr0_el2
+        .global write_ttbr0_el2
+        .global read_ttbr1_el2
+        .global write_ttbr1_el2
+        .global read_vttbr_el2
+        .global write_vttbr_el2
+        .global read_rcwmask_el1
+        .global write_rcwmask_el1
+        .global read_rcwsmask_el1
+        .global write_rcwsmask_el1
+
+/*
+ * _mrrs - Move System register to two adjacent general-purpose
+ * registers.
+ * Instruction: MRRS <Xt>, <Xt+1>, (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>)
+ *
+ * Arguments/Opcode bit field:
+ * regins: System register opcode.
+ *
+ * Clobbers: x0,x1,x2
+ */
+.macro _mrrs regins:req
+#if ENABLE_FEAT_D128 == 2
+        mrs     x0, ID_AA64MMFR3_EL1
+        tst     x0, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT)
+        bne     1f
+        /* If FEAT_D128 is not implemented then use mrs */
+        .inst   0xD5300000 | (\regins)
+        ret
+#endif
+1:
+        .inst   0xD5700000 | (\regins)
+        ret
+.endm
+
+/*
+ * _msrr - Move two adjacent general-purpose registers to System register.
+ * Instruction: MSRR (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>), <Xt>, <Xt+1>
+ *
+ * Arguments/Opcode bit field:
+ * regins: System register opcode.
+ *
+ * Clobbers: x0,x1,x2
+ */
+.macro _msrr regins:req
+        /* If FEAT_D128 is not implemented use msr, dont tamper
+         * x0, x1 as they maybe used for mrrs */
+#if ENABLE_FEAT_D128 == 2
+        mrs     x2, ID_AA64MMFR3_EL1
+        tst     x2, #(ID_AA64MMFR3_EL1_D128_MASK << ID_AA64MMFR3_EL1_D128_SHIFT)
+        bne     1f
+        /* If FEAT_D128 is not implemented then use msr */
+        .inst   0xD5100000 | (\regins)
+        ret
+#endif
+1:
+        .inst   0xD5500000 | (\regins)
+        ret
+.endm
+
+func read_par_el1
+        _mrrs   0x87400 /* S3_0_C7_C4_0 */
+endfunc read_par_el1
+
+func write_par_el1
+        _msrr   0x87400
+endfunc write_par_el1
+
+func read_ttbr0_el1
+        _mrrs   0x82000 /* S3_0_C2_C0_0 */
+endfunc read_ttbr0_el1
+
+func write_ttbr0_el1
+        _msrr 0x82000
+endfunc write_ttbr0_el1
+
+func read_ttbr1_el1
+        _mrrs 0x82020 /* S3_0_C2_C0_1 */
+endfunc read_ttbr1_el1
+
+func write_ttbr1_el1
+        _msrr 0x82020
+endfunc write_ttbr1_el1
+
+func read_ttbr0_el2
+        _mrrs 0xC2000 /* S3_4_C2_C0_0 */
+endfunc read_ttbr0_el2
+
+func write_ttbr0_el2
+        _msrr 0xC2000
+endfunc write_ttbr0_el2
+
+func read_ttbr1_el2
+        _mrrs 0xC2020 /* S3_4_C2_C0_1 */
+endfunc read_ttbr1_el2
+
+func write_ttbr1_el2
+        _msrr 0xC2020
+endfunc write_ttbr1_el2
+
+func read_vttbr_el2
+        _mrrs 0xC2100 /* S3_4_C2_C1_0 */
+endfunc read_vttbr_el2
+
+func write_vttbr_el2
+        _msrr 0xC2100
+endfunc write_vttbr_el2
+
+func read_rcwmask_el1
+        _mrrs 0x8D0C0 /* S3_0_C13_C0_6 */
+endfunc read_rcwmask_el1
+
+func write_rcwmask_el1
+        _msrr 0x8D0C0
+endfunc write_rcwmask_el1
+
+func read_rcwsmask_el1
+        _mrrs 0x8D060 /* S3_0_C13_C0_3 */
+endfunc read_rcwsmask_el1
+
+func write_rcwsmask_el1
+        _msrr 0x8D060
+endfunc write_rcwsmask_el1
diff --git a/lib/extensions/tcr/tcr2.c b/lib/extensions/tcr/tcr2.c
new file mode 100644
index 00000000..70bc5f8a
--- /dev/null
+++ b/lib/extensions/tcr/tcr2.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_features.h>
+#include <arch_helpers.h>
+#include <lib/extensions/tcr2.h>
+
+void tcr2_enable(cpu_context_t *ctx)
+{
+	u_register_t reg;
+	el3_state_t *state;
+
+	state = get_el3state_ctx(ctx);
+
+	/* Set the TCR2EN bit in SCR_EL3 to enable access to TCR2_EL1,
+	 * and TCR2_EL2 registers .
+	 */
+
+	reg = read_ctx_reg(state, CTX_SCR_EL3);
+	reg |= SCR_TCR2EN_BIT;
+	write_ctx_reg(state, CTX_SCR_EL3, reg);
+}
+
+void tcr2_disable(cpu_context_t *ctx)
+{
+	u_register_t reg;
+	el3_state_t *state;
+
+	state = get_el3state_ctx(ctx);
+
+	/* Clear the TCR2EN bit in SCR_EL3 to disable access to TCR2_EL1,
+	 * and TCR2_EL2 registers .
+	 */
+
+	reg = read_ctx_reg(state, CTX_SCR_EL3);
+	reg &= ~SCR_TCR2EN_BIT;
+	write_ctx_reg(state, CTX_SCR_EL3, reg);
+}
diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c
index d4fbdfbc..8c1c4218 100644
--- a/lib/extensions/trbe/trbe.c
+++ b/lib/extensions/trbe/trbe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,9 +19,10 @@ static void tsb_csync(void)
 	__asm__ volatile("hint #18");
 }
 
-void trbe_init_el3(void)
+void trbe_enable(cpu_context_t *ctx)
 {
-	u_register_t val;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.NSTBE = 0b0
@@ -33,10 +34,28 @@ void trbe_init_el3(void)
 	 *  NS-EL2, tracing is prohibited in Secure and Realm state (if
 	 *  implemented).
 	 */
-	val = read_mdcr_el3();
-	val |= MDCR_NSTB(MDCR_NSTB_EL1);
-	val &= ~(MDCR_NSTBE_BIT);
-	write_mdcr_el3(val);
+	mdcr_el3_val |= MDCR_NSTB(MDCR_NSTB_EL1);
+	mdcr_el3_val &= ~(MDCR_NSTBE_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
+}
+
+void trbe_disable(cpu_context_t *ctx)
+{
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
+
+	/*
+	 * MDCR_EL3.NSTBE = 0b0
+	 *  Trace Buffer owning Security state is secure state. If FEAT_RME
+	 *  is not implemented, this field is RES0.
+	 *
+	 * MDCR_EL3.NSTB = 0b00
+	 *  Clear these bits to disable access of trace buffer control registers
+	 *  from lower ELs in any security state.
+	 */
+	mdcr_el3_val &= ~(MDCR_NSTB(MDCR_NSTB_EL1));
+	mdcr_el3_val &= ~(MDCR_NSTBE_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
 void trbe_init_el2_unused(void)
diff --git a/lib/extensions/trf/aarch64/trf.c b/lib/extensions/trf/aarch64/trf.c
index 83fbf859..d36853a5 100644
--- a/lib/extensions/trf/aarch64/trf.c
+++ b/lib/extensions/trf/aarch64/trf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,10 @@
 #include <arch_helpers.h>
 #include <lib/extensions/trf.h>
 
-void trf_init_el3(void)
+void trf_enable(cpu_context_t *ctx)
 {
-	u_register_t val;
+	el3_state_t *state = get_el3state_ctx(ctx);
+	u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
 
 	/*
 	 * MDCR_EL3.STE = b0
@@ -22,9 +23,8 @@ void trf_init_el3(void)
 	 * Allow access of trace filter control registers from NS-EL2
 	 * and NS-EL1 when NS-EL2 is implemented but not used
 	 */
-	val = read_mdcr_el3();
-	val &= ~(MDCR_STE_BIT | MDCR_TTRF_BIT);
-	write_mdcr_el3(val);
+	mdcr_el3_val &= ~(MDCR_STE_BIT | MDCR_TTRF_BIT);
+	write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
 }
 
 void trf_init_el2_unused(void)
diff --git a/lib/fconf/fconf_cot_getter.c b/lib/fconf/fconf_cot_getter.c
index 1033018d..b9bc9de0 100644
--- a/lib/fconf/fconf_cot_getter.c
+++ b/lib/fconf/fconf_cot_getter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -237,13 +237,17 @@ static int populate_and_set_auth_methods(const void *dtb, int node,
 	 * verified by signature and images are verified by hash.
 	 */
 	if (type == IMG_CERT) {
-		if (root_certificate) {
-			oid = NULL;
-		} else {
-			rc = get_oid(dtb, node, "signing-key", &oid);
-			if (rc < 0) {
+		rc = get_oid(dtb, node, "signing-key", &oid);
+		if (rc < 0) {
+			/*
+			 * The signing-key property is optional in root
+			 * certificates, mandatory otherwise.
+			 */
+			if (root_certificate) {
+				oid = NULL;
+			} else {
 				ERROR("FCONF: Can't read %s property\n",
-					"signing-key");
+						"signing-key");
 				return rc;
 			}
 		}
diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index f5353cb1..79c4ea5d 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 #include <stdint.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include "gpt_rme_private.h"
@@ -20,7 +21,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 #if !ENABLE_RME
-#error "ENABLE_RME must be enabled to use the GPT library."
+#error "ENABLE_RME must be enabled to use the GPT library"
 #endif
 
 /*
@@ -56,8 +57,15 @@ static const gpt_t_val_e gpt_t_lookup[] = {PPS_4GB_T, PPS_64GB_T,
  */
 static const gpt_p_val_e gpt_p_lookup[] = {PGS_4KB_P, PGS_64KB_P, PGS_16KB_P};
 
+static void shatter_2mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc);
+static void shatter_32mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc);
+static void shatter_512mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc);
+
 /*
- * This structure contains GPT configuration data.
+ * This structure contains GPT configuration data
  */
 typedef struct {
 	uintptr_t plat_gpt_l0_base;
@@ -69,10 +77,187 @@ typedef struct {
 
 static gpt_config_t gpt_config;
 
-/* These variables are used during initialization of the L1 tables. */
-static unsigned int gpt_next_l1_tbl_idx;
+/*
+ * Number of L1 entries in 2MB, depending on GPCCR_EL3.PGS:
+ * +-------+------------+
+ * |  PGS  | L1 entries |
+ * +-------+------------+
+ * |  4KB  |     32     |
+ * +-------+------------+
+ * |  16KB |     8      |
+ * +-------+------------+
+ * |  64KB |     2      |
+ * +-------+------------+
+ */
+static unsigned int gpt_l1_cnt_2mb;
+
+/*
+ * Mask for the L1 index field, depending on
+ * GPCCR_EL3.L0GPTSZ and GPCCR_EL3.PGS:
+ * +---------+-------------------------------+
+ * |         |             PGS               |
+ * +---------+----------+----------+---------+
+ * | L0GPTSZ |   4KB    |   16KB   |   64KB  |
+ * +---------+----------+----------+---------+
+ * |  1GB    |  0x3FFF  |  0xFFF   |  0x3FF  |
+ * +---------+----------+----------+---------+
+ * |  16GB   | 0x3FFFF  |  0xFFFF  | 0x3FFF  |
+ * +---------+----------+----------+---------+
+ * |  64GB   | 0xFFFFF  | 0x3FFFF  | 0xFFFF  |
+ * +---------+----------+----------+---------+
+ * |  512GB  | 0x7FFFFF | 0x1FFFFF | 0x7FFFF |
+ * +---------+----------+----------+---------+
+ */
+static uint64_t gpt_l1_index_mask;
+
+/* Number of 128-bit L1 entries in 2MB, 32MB and 512MB */
+#define L1_QWORDS_2MB	(gpt_l1_cnt_2mb / 2U)
+#define L1_QWORDS_32MB	(L1_QWORDS_2MB * 16U)
+#define L1_QWORDS_512MB	(L1_QWORDS_32MB * 16U)
+
+/* Size in bytes of L1 entries in 2MB, 32MB */
+#define L1_BYTES_2MB	(gpt_l1_cnt_2mb * sizeof(uint64_t))
+#define L1_BYTES_32MB	(L1_BYTES_2MB * 16U)
+
+/* Get the index into the L1 table from a physical address */
+#define GPT_L1_INDEX(_pa)	\
+	(((_pa) >> (unsigned int)GPT_L1_IDX_SHIFT(gpt_config.p)) & gpt_l1_index_mask)
+
+/* These variables are used during initialization of the L1 tables */
 static uintptr_t gpt_l1_tbl;
 
+/* These variable is used during runtime */
+#if (RME_GPT_BITLOCK_BLOCK == 0)
+/*
+ * The GPTs are protected by a global spinlock to ensure
+ * that multiple CPUs do not attempt to change the descriptors at once.
+ */
+static spinlock_t gpt_lock;
+#else
+
+/* Bitlocks base address */
+static bitlock_t *gpt_bitlock_base;
+#endif
+
+/* Lock/unlock macros for GPT entries */
+#if (RME_GPT_BITLOCK_BLOCK == 0)
+/*
+ * Access to GPT is controlled by a global lock to ensure
+ * that no more than one CPU is allowed to make changes at any
+ * given time.
+ */
+#define GPT_LOCK	spin_lock(&gpt_lock)
+#define GPT_UNLOCK	spin_unlock(&gpt_lock)
+#else
+/*
+ * Access to a block of memory is controlled by a bitlock.
+ * Size of block = RME_GPT_BITLOCK_BLOCK * 512MB.
+ */
+#define GPT_LOCK	bit_lock(gpi_info.lock, gpi_info.mask)
+#define GPT_UNLOCK	bit_unlock(gpi_info.lock, gpi_info.mask)
+#endif
+
+static void tlbi_page_dsbosh(uintptr_t base)
+{
+	/* Look-up table for invalidation TLBs for 4KB, 16KB and 64KB pages */
+	static const gpt_tlbi_lookup_t tlbi_page_lookup[] = {
+		{ tlbirpalos_4k, ~(SZ_4K - 1UL) },
+		{ tlbirpalos_64k, ~(SZ_64K - 1UL) },
+		{ tlbirpalos_16k, ~(SZ_16K - 1UL) }
+	};
+
+	tlbi_page_lookup[gpt_config.pgs].function(
+			base & tlbi_page_lookup[gpt_config.pgs].mask);
+	dsbosh();
+}
+
+/*
+ * Helper function to fill out GPI entries in a single L1 table
+ * with Granules or Contiguous descriptor.
+ *
+ * Parameters
+ *   l1			Pointer to 2MB, 32MB or 512MB aligned L1 table entry to fill out
+ *   l1_desc		GPT Granules or Contiguous descriptor set this range to
+ *   cnt		Number of double 128-bit L1 entries to fill
+ *
+ */
+static void fill_desc(uint64_t *l1, uint64_t l1_desc, unsigned int cnt)
+{
+	uint128_t *l1_quad = (uint128_t *)l1;
+	uint128_t l1_quad_desc = (uint128_t)l1_desc | ((uint128_t)l1_desc << 64);
+
+	VERBOSE("GPT: %s(%p 0x%"PRIx64" %u)\n", __func__, l1, l1_desc, cnt);
+
+	for (unsigned int i = 0U; i < cnt; i++) {
+		*l1_quad++ = l1_quad_desc;
+	}
+}
+
+static void shatter_2mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	unsigned long idx = GPT_L1_INDEX(ALIGN_2MB(base));
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n",
+				__func__, base, l1_desc);
+
+	/* Convert 2MB Contiguous block to Granules */
+	fill_desc(&gpi_info->gpt_l1_addr[idx], l1_desc, L1_QWORDS_2MB);
+}
+
+static void shatter_32mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	unsigned long idx = GPT_L1_INDEX(ALIGN_2MB(base));
+	const uint64_t *l1_gran = &gpi_info->gpt_l1_addr[idx];
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 2MB);
+	uint64_t *l1;
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n",
+				__func__, base, l1_desc);
+
+	/* Get index corresponding to 32MB aligned address */
+	idx = GPT_L1_INDEX(ALIGN_32MB(base));
+	l1 = &gpi_info->gpt_l1_addr[idx];
+
+	/* 16 x 2MB blocks in 32MB */
+	for (unsigned int i = 0U; i < 16U; i++) {
+		/* Fill with Granules or Contiguous descriptors */
+		fill_desc(l1, (l1 == l1_gran) ? l1_desc : l1_cont_desc,
+							L1_QWORDS_2MB);
+		l1 = (uint64_t *)((uintptr_t)l1 + L1_BYTES_2MB);
+	}
+}
+
+static void shatter_512mb(uintptr_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	unsigned long idx = GPT_L1_INDEX(ALIGN_32MB(base));
+	const uint64_t *l1_32mb = &gpi_info->gpt_l1_addr[idx];
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 32MB);
+	uint64_t *l1;
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n",
+				__func__, base, l1_desc);
+
+	/* Get index corresponding to 512MB aligned address */
+	idx = GPT_L1_INDEX(ALIGN_512MB(base));
+	l1 = &gpi_info->gpt_l1_addr[idx];
+
+	/* 16 x 32MB blocks in 512MB */
+	for (unsigned int i = 0U; i < 16U; i++) {
+		if (l1 == l1_32mb) {
+			/* Shatter this 32MB block */
+			shatter_32mb(base, gpi_info, l1_desc);
+		} else {
+			/* Fill 32MB with Contiguous descriptors */
+			fill_desc(l1, l1_cont_desc, L1_QWORDS_32MB);
+		}
+
+		l1 = (uint64_t *)((uintptr_t)l1 + L1_BYTES_32MB);
+	}
+}
+
 /*
  * This function checks to see if a GPI value is valid.
  *
@@ -90,7 +275,7 @@ static uintptr_t gpt_l1_tbl;
  * Return
  *   true for a valid GPI, false for an invalid one.
  */
-static bool gpt_is_gpi_valid(unsigned int gpi)
+static bool is_gpi_valid(unsigned int gpi)
 {
 	if ((gpi == GPT_GPI_NO_ACCESS) || (gpi == GPT_GPI_ANY) ||
 	    ((gpi >= GPT_GPI_SECURE) && (gpi <= GPT_GPI_REALM))) {
@@ -111,8 +296,8 @@ static bool gpt_is_gpi_valid(unsigned int gpi)
  * Return
  *   True if PAS regions overlap, false if they do not.
  */
-static bool gpt_check_pas_overlap(uintptr_t base_1, size_t size_1,
-				  uintptr_t base_2, size_t size_2)
+static bool check_pas_overlap(uintptr_t base_1, size_t size_1,
+			      uintptr_t base_2, size_t size_2)
 {
 	if (((base_1 + size_1) > base_2) && ((base_2 + size_2) > base_1)) {
 		return true;
@@ -132,13 +317,13 @@ static bool gpt_check_pas_overlap(uintptr_t base_1, size_t size_1,
  * Return
  *   True if a PAS region occupies the L0 region in question, false if not.
  */
-static bool gpt_does_previous_pas_exist_here(unsigned int l0_idx,
-					     pas_region_t *pas_regions,
-					     unsigned int pas_idx)
+static bool does_previous_pas_exist_here(unsigned int l0_idx,
+					 pas_region_t *pas_regions,
+					 unsigned int pas_idx)
 {
-	/* Iterate over PAS regions up to pas_idx. */
+	/* Iterate over PAS regions up to pas_idx */
 	for (unsigned int i = 0U; i < pas_idx; i++) {
-		if (gpt_check_pas_overlap((GPT_L0GPTSZ_ACTUAL_SIZE * l0_idx),
+		if (check_pas_overlap((GPT_L0GPTSZ_ACTUAL_SIZE * l0_idx),
 		    GPT_L0GPTSZ_ACTUAL_SIZE,
 		    pas_regions[i].base_pa, pas_regions[i].size)) {
 			return true;
@@ -163,8 +348,8 @@ static bool gpt_does_previous_pas_exist_here(unsigned int l0_idx,
  *   Negative Linux error code in the event of a failure, number of L1 regions
  *   required when successful.
  */
-static int gpt_validate_pas_mappings(pas_region_t *pas_regions,
-				     unsigned int pas_region_cnt)
+static int validate_pas_mappings(pas_region_t *pas_regions,
+				 unsigned int pas_region_cnt)
 {
 	unsigned int idx;
 	unsigned int l1_cnt = 0U;
@@ -175,18 +360,18 @@ static int gpt_validate_pas_mappings(pas_region_t *pas_regions,
 	assert(pas_region_cnt != 0U);
 
 	for (idx = 0U; idx < pas_region_cnt; idx++) {
-		/* Check for arithmetic overflow in region. */
+		/* Check for arithmetic overflow in region */
 		if ((ULONG_MAX - pas_regions[idx].base_pa) <
 		    pas_regions[idx].size) {
-			ERROR("[GPT] Address overflow in PAS[%u]!\n", idx);
+			ERROR("GPT: Address overflow in PAS[%u]!\n", idx);
 			return -EOVERFLOW;
 		}
 
-		/* Initial checks for PAS validity. */
+		/* Initial checks for PAS validity */
 		if (((pas_regions[idx].base_pa + pas_regions[idx].size) >
 		    GPT_PPS_ACTUAL_SIZE(gpt_config.t)) ||
-		    !gpt_is_gpi_valid(GPT_PAS_ATTR_GPI(pas_regions[idx].attrs))) {
-			ERROR("[GPT] PAS[%u] is invalid!\n", idx);
+		    !is_gpi_valid(GPT_PAS_ATTR_GPI(pas_regions[idx].attrs))) {
+			ERROR("GPT: PAS[%u] is invalid!\n", idx);
 			return -EFAULT;
 		}
 
@@ -195,12 +380,12 @@ static int gpt_validate_pas_mappings(pas_region_t *pas_regions,
 		 * start from idx + 1 instead of 0 since prior PAS mappings will
 		 * have already checked themselves against this one.
 		 */
-		for (unsigned int i = idx + 1; i < pas_region_cnt; i++) {
-			if (gpt_check_pas_overlap(pas_regions[idx].base_pa,
+		for (unsigned int i = idx + 1U; i < pas_region_cnt; i++) {
+			if (check_pas_overlap(pas_regions[idx].base_pa,
 			    pas_regions[idx].size,
 			    pas_regions[i].base_pa,
 			    pas_regions[i].size)) {
-				ERROR("[GPT] PAS[%u] overlaps with PAS[%u]\n",
+				ERROR("GPT: PAS[%u] overlaps with PAS[%u]\n",
 					i, idx);
 				return -EFAULT;
 			}
@@ -212,12 +397,14 @@ static int gpt_validate_pas_mappings(pas_region_t *pas_regions,
 		 * to see if this PAS would fall into one that has already been
 		 * initialized.
 		 */
-		for (unsigned int i = GPT_L0_IDX(pas_regions[idx].base_pa);
-		     i <= GPT_L0_IDX(pas_regions[idx].base_pa + pas_regions[idx].size - 1);
-		     i++) {
+		for (unsigned int i =
+			(unsigned int)GPT_L0_IDX(pas_regions[idx].base_pa);
+			i <= GPT_L0_IDX(pas_regions[idx].base_pa +
+					pas_regions[idx].size - 1UL);
+			i++) {
 			if ((GPT_L0_TYPE(l0_desc[i]) == GPT_L0_TYPE_BLK_DESC) &&
 			    (GPT_L0_BLKD_GPI(l0_desc[i]) == GPT_GPI_ANY)) {
-				/* This descriptor is unused so continue. */
+				/* This descriptor is unused so continue */
 				continue;
 			}
 
@@ -225,18 +412,18 @@ static int gpt_validate_pas_mappings(pas_region_t *pas_regions,
 			 * This descriptor has been initialized in a previous
 			 * call to this function so cannot be initialized again.
 			 */
-			ERROR("[GPT] PAS[%u] overlaps with previous L0[%d]!\n",
+			ERROR("GPT: PAS[%u] overlaps with previous L0[%u]!\n",
 			      idx, i);
 			return -EFAULT;
 		}
 
-		/* Check for block mapping (L0) type. */
+		/* Check for block mapping (L0) type */
 		if (GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs) ==
 		    GPT_PAS_ATTR_MAP_TYPE_BLOCK) {
-			/* Make sure base and size are block-aligned. */
+			/* Make sure base and size are block-aligned */
 			if (!GPT_IS_L0_ALIGNED(pas_regions[idx].base_pa) ||
 			    !GPT_IS_L0_ALIGNED(pas_regions[idx].size)) {
-				ERROR("[GPT] PAS[%u] is not block-aligned!\n",
+				ERROR("GPT: PAS[%u] is not block-aligned!\n",
 				      idx);
 				return -EFAULT;
 			}
@@ -244,21 +431,21 @@ static int gpt_validate_pas_mappings(pas_region_t *pas_regions,
 			continue;
 		}
 
-		/* Check for granule mapping (L1) type. */
+		/* Check for granule mapping (L1) type */
 		if (GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs) ==
 		    GPT_PAS_ATTR_MAP_TYPE_GRANULE) {
-			/* Make sure base and size are granule-aligned. */
+			/* Make sure base and size are granule-aligned */
 			if (!GPT_IS_L1_ALIGNED(gpt_config.p, pas_regions[idx].base_pa) ||
 			    !GPT_IS_L1_ALIGNED(gpt_config.p, pas_regions[idx].size)) {
-				ERROR("[GPT] PAS[%u] is not granule-aligned!\n",
+				ERROR("GPT: PAS[%u] is not granule-aligned!\n",
 				      idx);
 				return -EFAULT;
 			}
 
-			/* Find how many L1 tables this PAS occupies. */
+			/* Find how many L1 tables this PAS occupies */
 			pas_l1_cnt = (GPT_L0_IDX(pas_regions[idx].base_pa +
-				     pas_regions[idx].size - 1) -
-				     GPT_L0_IDX(pas_regions[idx].base_pa) + 1);
+				     pas_regions[idx].size - 1UL) -
+				     GPT_L0_IDX(pas_regions[idx].base_pa) + 1U);
 
 			/*
 			 * This creates a situation where, if multiple PAS
@@ -276,26 +463,26 @@ static int gpt_validate_pas_mappings(pas_region_t *pas_regions,
 			 * both for overlap against other PAS.
 			 */
 			if (pas_l1_cnt > 1) {
-				if (gpt_does_previous_pas_exist_here(
+				if (does_previous_pas_exist_here(
 				    GPT_L0_IDX(pas_regions[idx].base_pa +
-				    pas_regions[idx].size - 1),
+				    pas_regions[idx].size - 1UL),
 				    pas_regions, idx)) {
-					pas_l1_cnt = pas_l1_cnt - 1;
+					pas_l1_cnt--;
 				}
 			}
 
-			if (gpt_does_previous_pas_exist_here(
+			if (does_previous_pas_exist_here(
 			    GPT_L0_IDX(pas_regions[idx].base_pa),
 			    pas_regions, idx)) {
-				pas_l1_cnt = pas_l1_cnt - 1;
+				pas_l1_cnt--;
 			}
 
 			l1_cnt += pas_l1_cnt;
 			continue;
 		}
 
-		/* If execution reaches this point, mapping type is invalid. */
-		ERROR("[GPT] PAS[%u] has invalid mapping type 0x%x.\n", idx,
+		/* If execution reaches this point, mapping type is invalid */
+		ERROR("GPT: PAS[%u] has invalid mapping type 0x%x.\n", idx,
 		      GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs));
 		return -EINVAL;
 	}
@@ -308,44 +495,62 @@ static int gpt_validate_pas_mappings(pas_region_t *pas_regions,
  *
  * Parameters
  *   l0_mem_base	Base address of memory used for L0 tables.
- *   l1_mem_size	Size of memory available for L0 tables.
+ *   l0_mem_size	Size of memory available for L0 tables.
  *
  * Return
  *   Negative Linux error code in the event of a failure, 0 for success.
  */
-static int gpt_validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base,
-				  size_t l0_mem_size)
+static int validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base,
+				size_t l0_mem_size)
 {
-	size_t l0_alignment;
+	size_t l0_alignment, locks_size = 0;
 
 	/*
 	 * Make sure PPS is valid and then store it since macros need this value
 	 * to work.
 	 */
 	if (pps > GPT_PPS_MAX) {
-		ERROR("[GPT] Invalid PPS: 0x%x\n", pps);
+		ERROR("GPT: Invalid PPS: 0x%x\n", pps);
 		return -EINVAL;
 	}
 	gpt_config.pps = pps;
 	gpt_config.t = gpt_t_lookup[pps];
 
-	/* Alignment must be the greater of 4k or l0 table size. */
+	/* Alignment must be the greater of 4KB or l0 table size */
 	l0_alignment = PAGE_SIZE_4KB;
 	if (l0_alignment < GPT_L0_TABLE_SIZE(gpt_config.t)) {
 		l0_alignment = GPT_L0_TABLE_SIZE(gpt_config.t);
 	}
 
-	/* Check base address. */
-	if ((l0_mem_base == 0U) || ((l0_mem_base & (l0_alignment - 1)) != 0U)) {
-		ERROR("[GPT] Invalid L0 base address: 0x%lx\n", l0_mem_base);
+	/* Check base address */
+	if ((l0_mem_base == 0UL) ||
+	   ((l0_mem_base & (l0_alignment - 1UL)) != 0UL)) {
+		ERROR("GPT: Invalid L0 base address: 0x%lx\n", l0_mem_base);
 		return -EFAULT;
 	}
 
-	/* Check size. */
-	if (l0_mem_size < GPT_L0_TABLE_SIZE(gpt_config.t)) {
-		ERROR("[GPT] Inadequate L0 memory: need 0x%lx, have 0x%lx)\n",
-		      GPT_L0_TABLE_SIZE(gpt_config.t),
-		      l0_mem_size);
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/*
+	 * Size of bitlocks in bytes for the protected address space
+	 * with RME_GPT_BITLOCK_BLOCK * 512MB per bitlock.
+	 */
+	locks_size = GPT_PPS_ACTUAL_SIZE(gpt_config.t) /
+			(RME_GPT_BITLOCK_BLOCK * SZ_512M * 8U);
+
+	/*
+	 * If protected space size is less than the size covered
+	 * by 'bitlock' structure, check for a single bitlock.
+	 */
+	if (locks_size < LOCK_SIZE) {
+		locks_size = LOCK_SIZE;
+	}
+#endif
+	/* Check size for L0 tables and bitlocks */
+	if (l0_mem_size < (GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size)) {
+		ERROR("GPT: Inadequate L0 memory\n");
+		ERROR("      Expected 0x%lx bytes, got 0x%lx bytes\n",
+			GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size,
+			l0_mem_size);
 		return -ENOMEM;
 	}
 
@@ -364,8 +569,8 @@ static int gpt_validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base,
  * Return
  *   Negative Linux error code in the event of a failure, 0 for success.
  */
-static int gpt_validate_l1_params(uintptr_t l1_mem_base, size_t l1_mem_size,
-				  unsigned int l1_gpt_cnt)
+static int validate_l1_params(uintptr_t l1_mem_base, size_t l1_mem_size,
+				unsigned int l1_gpt_cnt)
 {
 	size_t l1_gpt_mem_sz;
 
@@ -375,31 +580,32 @@ static int gpt_validate_l1_params(uintptr_t l1_mem_base, size_t l1_mem_size,
 		return -EPERM;
 	}
 
-	/* Make sure L1 tables are aligned to their size. */
-	if ((l1_mem_base & (GPT_L1_TABLE_SIZE(gpt_config.p) - 1)) != 0U) {
-		ERROR("[GPT] Unaligned L1 GPT base address: 0x%lx\n",
+	/* Make sure L1 tables are aligned to their size */
+	if ((l1_mem_base & (GPT_L1_TABLE_SIZE(gpt_config.p) - 1UL)) != 0UL) {
+		ERROR("GPT: Unaligned L1 GPT base address: 0x%"PRIxPTR"\n",
 		      l1_mem_base);
 		return -EFAULT;
 	}
 
-	/* Get total memory needed for L1 tables. */
+	/* Get total memory needed for L1 tables */
 	l1_gpt_mem_sz = l1_gpt_cnt * GPT_L1_TABLE_SIZE(gpt_config.p);
 
-	/* Check for overflow. */
+	/* Check for overflow */
 	if ((l1_gpt_mem_sz / GPT_L1_TABLE_SIZE(gpt_config.p)) != l1_gpt_cnt) {
-		ERROR("[GPT] Overflow calculating L1 memory size.\n");
+		ERROR("GPT: Overflow calculating L1 memory size\n");
 		return -ENOMEM;
 	}
 
-	/* Make sure enough space was supplied. */
+	/* Make sure enough space was supplied */
 	if (l1_mem_size < l1_gpt_mem_sz) {
-		ERROR("[GPT] Inadequate memory for L1 GPTs. ");
-		ERROR("      Expected 0x%lx bytes. Got 0x%lx bytes\n",
-		      l1_gpt_mem_sz, l1_mem_size);
+		ERROR("%sL1 GPTs%s", (const char *)"GPT: Inadequate ",
+			(const char *)" memory\n");
+		ERROR("      Expected 0x%lx bytes, got 0x%lx bytes\n",
+			l1_gpt_mem_sz, l1_mem_size);
 		return -ENOMEM;
 	}
 
-	VERBOSE("[GPT] Requested 0x%lx bytes for L1 GPTs.\n", l1_gpt_mem_sz);
+	VERBOSE("GPT: Requested 0x%lx bytes for L1 GPTs\n", l1_gpt_mem_sz);
 	return 0;
 }
 
@@ -411,11 +617,10 @@ static int gpt_validate_l1_params(uintptr_t l1_mem_base, size_t l1_mem_size,
  *   *pas		Pointer to the structure defining the PAS region to
  *			initialize.
  */
-static void gpt_generate_l0_blk_desc(pas_region_t *pas)
+static void generate_l0_blk_desc(pas_region_t *pas)
 {
 	uint64_t gpt_desc;
-	unsigned int end_idx;
-	unsigned int idx;
+	unsigned long idx, end_idx;
 	uint64_t *l0_gpt_arr;
 
 	assert(gpt_config.plat_gpt_l0_base != 0U);
@@ -423,7 +628,7 @@ static void gpt_generate_l0_blk_desc(pas_region_t *pas)
 
 	/*
 	 * Checking of PAS parameters has already been done in
-	 * gpt_validate_pas_mappings so no need to check the same things again.
+	 * validate_pas_mappings so no need to check the same things again.
 	 */
 
 	l0_gpt_arr = (uint64_t *)gpt_config.plat_gpt_l0_base;
@@ -441,10 +646,10 @@ static void gpt_generate_l0_blk_desc(pas_region_t *pas)
 	 */
 	end_idx = GPT_L0_IDX(pas->base_pa + pas->size);
 
-	/* Generate the needed block descriptors. */
+	/* Generate the needed block descriptors */
 	for (; idx < end_idx; idx++) {
 		l0_gpt_arr[idx] = gpt_desc;
-		VERBOSE("[GPT] L0 entry (BLOCK) index %u [%p]: GPI = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
+		VERBOSE("GPT: L0 entry (BLOCK) index %lu [%p]: GPI = 0x%"PRIx64" (0x%"PRIx64")\n",
 			idx, &l0_gpt_arr[idx],
 			(gpt_desc >> GPT_L0_BLK_DESC_GPI_SHIFT) &
 			GPT_L0_BLK_DESC_GPI_MASK, l0_gpt_arr[idx]);
@@ -464,7 +669,7 @@ static void gpt_generate_l0_blk_desc(pas_region_t *pas)
  * Return
  *   The PA of the end of the current range.
  */
-static uintptr_t gpt_get_l1_end_pa(uintptr_t cur_pa, uintptr_t end_pa)
+static uintptr_t get_l1_end_pa(uintptr_t cur_pa, uintptr_t end_pa)
 {
 	uintptr_t cur_idx;
 	uintptr_t end_idx;
@@ -478,51 +683,205 @@ static uintptr_t gpt_get_l1_end_pa(uintptr_t cur_pa, uintptr_t end_pa)
 		return end_pa;
 	}
 
-	return (cur_idx + 1U) << GPT_L0_IDX_SHIFT;
+	return (cur_idx + 1UL) << GPT_L0_IDX_SHIFT;
 }
 
 /*
- * Helper function to fill out GPI entries in a single L1 table. This function
- * fills out entire L1 descriptors at a time to save memory writes.
+ * Helper function to fill out GPI entries from 'first' granule address of
+ * the specified 'length' in a single L1 table with 'l1_desc' Contiguous
+ * descriptor.
  *
  * Parameters
- *   gpi		GPI to set this range to
  *   l1			Pointer to L1 table to fill out
- *   first		Address of first granule in range.
- *   last		Address of last granule in range (inclusive).
+ *   first		Address of first granule in range
+ *   length		Length of the range in bytes
+ *   gpi		GPI set this range to
+ *
+ * Return
+ *   Address of next granule in range.
  */
-static void gpt_fill_l1_tbl(uint64_t gpi, uint64_t *l1, uintptr_t first,
-			    uintptr_t last)
+__unused static uintptr_t fill_l1_cont_desc(uint64_t *l1, uintptr_t first,
+					    size_t length, unsigned int gpi)
 {
-	uint64_t gpi_field = GPT_BUILD_L1_DESC(gpi);
-	uint64_t gpi_mask = 0xFFFFFFFFFFFFFFFF;
+	/*
+	 * Look up table for contiguous blocks and descriptors.
+	 * Entries should be defined in descending block sizes:
+	 * 512MB, 32MB and 2MB.
+	 */
+	static const gpt_fill_lookup_t gpt_fill_lookup[] = {
+#if (RME_GPT_MAX_BLOCK == 512)
+		{ SZ_512M, GPT_L1_CONT_DESC_512MB },
+#endif
+#if (RME_GPT_MAX_BLOCK >= 32)
+		{ SZ_32M, GPT_L1_CONT_DESC_32MB },
+#endif
+#if (RME_GPT_MAX_BLOCK != 0)
+		{ SZ_2M, GPT_L1_CONT_DESC_2MB }
+#endif
+	};
 
-	assert(first <= last);
-	assert((first & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) == 0U);
-	assert((last & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) == 0U);
-	assert(GPT_L0_IDX(first) == GPT_L0_IDX(last));
-	assert(l1 != NULL);
+	/*
+	 * Iterate through all block sizes (512MB, 32MB and 2MB)
+	 * starting with maximum supported.
+	 */
+	for (unsigned long i = 0UL; i < ARRAY_SIZE(gpt_fill_lookup); i++) {
+		/* Calculate index */
+		unsigned long idx = GPT_L1_INDEX(first);
+
+		/* Contiguous block size */
+		size_t cont_size = gpt_fill_lookup[i].size;
+
+		if (GPT_REGION_IS_CONT(length, first, cont_size)) {
+
+			/* Generate Contiguous descriptor */
+			uint64_t l1_desc = GPT_L1_GPI_CONT_DESC(gpi,
+						gpt_fill_lookup[i].desc);
+
+			/* Number of 128-bit L1 entries in block */
+			unsigned int cnt;
+
+			switch (cont_size) {
+			case SZ_512M:
+				cnt = L1_QWORDS_512MB;
+				break;
+			case SZ_32M:
+				cnt = L1_QWORDS_32MB;
+				break;
+			default:			/* SZ_2MB */
+				cnt = L1_QWORDS_2MB;
+			}
+
+			VERBOSE("GPT: Contiguous descriptor 0x%"PRIxPTR" %luMB\n",
+				first, cont_size / SZ_1M);
+
+			/* Fill Contiguous descriptors */
+			fill_desc(&l1[idx], l1_desc, cnt);
+			first += cont_size;
+			length -= cont_size;
 
-	/* Shift the mask if we're starting in the middle of an L1 entry. */
-	gpi_mask = gpi_mask << (GPT_L1_GPI_IDX(gpt_config.p, first) << 2);
+			if (length == 0UL) {
+				break;
+			}
+		}
+	}
+
+	return first;
+}
 
-	/* Fill out each L1 entry for this region. */
-	for (unsigned int i = GPT_L1_IDX(gpt_config.p, first);
-	     i <= GPT_L1_IDX(gpt_config.p, last); i++) {
-		/* Account for stopping in the middle of an L1 entry. */
-		if (i == GPT_L1_IDX(gpt_config.p, last)) {
-			gpi_mask &= (gpi_mask >> ((15 -
+/* Build Granules descriptor with the same 'gpi' for every GPI entry */
+static uint64_t build_l1_desc(unsigned int gpi)
+{
+	uint64_t l1_desc = (uint64_t)gpi | ((uint64_t)gpi << 4);
+
+	l1_desc |= (l1_desc << 8);
+	l1_desc |= (l1_desc << 16);
+	return (l1_desc | (l1_desc << 32));
+}
+
+/*
+ * Helper function to fill out GPI entries from 'first' to 'last' granule
+ * address in a single L1 table with 'l1_desc' Granules descriptor.
+ *
+ * Parameters
+ *   l1			Pointer to L1 table to fill out
+ *   first		Address of first granule in range
+ *   last		Address of last granule in range (inclusive)
+ *   gpi		GPI set this range to
+ *
+ * Return
+ *   Address of next granule in range.
+ */
+static uintptr_t fill_l1_gran_desc(uint64_t *l1, uintptr_t first,
+				   uintptr_t last, unsigned int gpi)
+{
+	uint64_t gpi_mask;
+	unsigned long i;
+
+	/* Generate Granules descriptor */
+	uint64_t l1_desc = build_l1_desc(gpi);
+
+	/* Shift the mask if we're starting in the middle of an L1 entry */
+	gpi_mask = ULONG_MAX << (GPT_L1_GPI_IDX(gpt_config.p, first) << 2);
+
+	/* Fill out each L1 entry for this region */
+	for (i = GPT_L1_INDEX(first); i <= GPT_L1_INDEX(last); i++) {
+
+		/* Account for stopping in the middle of an L1 entry */
+		if (i == GPT_L1_INDEX(last)) {
+			gpi_mask &= (gpi_mask >> ((15U -
 				    GPT_L1_GPI_IDX(gpt_config.p, last)) << 2));
 		}
 
-		/* Write GPI values. */
-		assert((l1[i] & gpi_mask) ==
-		       (GPT_BUILD_L1_DESC(GPT_GPI_ANY) & gpi_mask));
-		l1[i] = (l1[i] & ~gpi_mask) | (gpi_mask & gpi_field);
+		assert((l1[i] & gpi_mask) == (GPT_L1_ANY_DESC & gpi_mask));
+
+		/* Write GPI values */
+		l1[i] = (l1[i] & ~gpi_mask) | (l1_desc & gpi_mask);
+
+		/* Reset mask */
+		gpi_mask = ULONG_MAX;
+	}
+
+	return last + GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+}
+
+/*
+ * Helper function to fill out GPI entries in a single L1 table.
+ * This function fills out an entire L1 table with either Granules or Contiguous
+ * (RME_GPT_MAX_BLOCK != 0) descriptors depending on region length and alignment.
+ * Note. If RME_GPT_MAX_BLOCK == 0, then the L1 tables are filled with regular
+ * Granules descriptors.
+ *
+ * Parameters
+ *   l1			Pointer to L1 table to fill out
+ *   first		Address of first granule in range
+ *   last		Address of last granule in range (inclusive)
+ *   gpi		GPI set this range to
+ */
+static void fill_l1_tbl(uint64_t *l1, uintptr_t first, uintptr_t last,
+			unsigned int gpi)
+{
+	assert(l1 != NULL);
+	assert(first <= last);
+	assert((first & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) == 0UL);
+	assert((last & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) == 0UL);
+	assert(GPT_L0_IDX(first) == GPT_L0_IDX(last));
+
+#if (RME_GPT_MAX_BLOCK != 0)
+	while (first <= last) {
+		/* Region length */
+		size_t length = last - first + GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+
+		if (length < SZ_2M) {
+			/*
+			 * Fill with Granule descriptors in case of
+			 * region length < 2MB.
+			 */
+			first = fill_l1_gran_desc(l1, first, last, gpi);
+
+		} else if ((first & (SZ_2M - UL(1))) == UL(0)) {
+			/*
+			 * For region length >= 2MB and at least 2MB aligned
+			 * call to fill_l1_cont_desc will iterate through
+			 * all block sizes (512MB, 32MB and 2MB) supported and
+			 * fill corresponding Contiguous descriptors.
+			 */
+			first = fill_l1_cont_desc(l1, first, length, gpi);
+		} else {
+			/*
+			 * For not aligned region >= 2MB fill with Granules
+			 * descriptors up to the next 2MB aligned address.
+			 */
+			uintptr_t new_last = ALIGN_2MB(first + SZ_2M) -
+					GPT_PGS_ACTUAL_SIZE(gpt_config.p);
 
-		/* Reset mask. */
-		gpi_mask = 0xFFFFFFFFFFFFFFFF;
+			first = fill_l1_gran_desc(l1, first, new_last, gpi);
+		}
 	}
+#else
+	/* Fill with Granule descriptors */
+	first = fill_l1_gran_desc(l1, first, last, gpi);
+#endif
+	assert(first == (last + GPT_PGS_ACTUAL_SIZE(gpt_config.p)));
 }
 
 /*
@@ -536,19 +895,17 @@ static void gpt_fill_l1_tbl(uint64_t gpi, uint64_t *l1, uintptr_t first,
  * Return
  *   Pointer to the next available L1 table.
  */
-static uint64_t *gpt_get_new_l1_tbl(void)
+static uint64_t *get_new_l1_tbl(void)
 {
-	/* Retrieve the next L1 table. */
-	uint64_t *l1 = (uint64_t *)((uint64_t)(gpt_l1_tbl) +
-		       (GPT_L1_TABLE_SIZE(gpt_config.p) *
-		       gpt_next_l1_tbl_idx));
+	/* Retrieve the next L1 table */
+	uint64_t *l1 = (uint64_t *)gpt_l1_tbl;
 
-	/* Increment L1 counter. */
-	gpt_next_l1_tbl_idx++;
+	/* Increment L1 GPT address */
+	gpt_l1_tbl += GPT_L1_TABLE_SIZE(gpt_config.p);
 
 	/* Initialize all GPIs to GPT_GPI_ANY */
 	for (unsigned int i = 0U; i < GPT_L1_ENTRY_COUNT(gpt_config.p); i++) {
-		l1[i] = GPT_BUILD_L1_DESC(GPT_GPI_ANY);
+		l1[i] = GPT_L1_ANY_DESC;
 	}
 
 	return l1;
@@ -562,58 +919,57 @@ static uint64_t *gpt_get_new_l1_tbl(void)
  * Parameters
  *   *pas		Pointer to the structure defining the PAS region.
  */
-static void gpt_generate_l0_tbl_desc(pas_region_t *pas)
+static void generate_l0_tbl_desc(pas_region_t *pas)
 {
 	uintptr_t end_pa;
 	uintptr_t cur_pa;
 	uintptr_t last_gran_pa;
 	uint64_t *l0_gpt_base;
 	uint64_t *l1_gpt_arr;
-	unsigned int l0_idx;
+	unsigned int l0_idx, gpi;
 
 	assert(gpt_config.plat_gpt_l0_base != 0U);
 	assert(pas != NULL);
 
 	/*
 	 * Checking of PAS parameters has already been done in
-	 * gpt_validate_pas_mappings so no need to check the same things again.
+	 * validate_pas_mappings so no need to check the same things again.
 	 */
-
 	end_pa = pas->base_pa + pas->size;
 	l0_gpt_base = (uint64_t *)gpt_config.plat_gpt_l0_base;
 
 	/* We start working from the granule at base PA */
 	cur_pa = pas->base_pa;
 
-	/* Iterate over each L0 region in this memory range. */
-	for (l0_idx = GPT_L0_IDX(pas->base_pa);
-	     l0_idx <= GPT_L0_IDX(end_pa - 1U);
-	     l0_idx++) {
+	/* Get GPI */
+	gpi = GPT_PAS_ATTR_GPI(pas->attrs);
 
+	/* Iterate over each L0 region in this memory range */
+	for (l0_idx = (unsigned int)GPT_L0_IDX(pas->base_pa);
+	     l0_idx <= (unsigned int)GPT_L0_IDX(end_pa - 1UL);
+	     l0_idx++) {
 		/*
 		 * See if the L0 entry is already a table descriptor or if we
 		 * need to create one.
 		 */
 		if (GPT_L0_TYPE(l0_gpt_base[l0_idx]) == GPT_L0_TYPE_TBL_DESC) {
-			/* Get the L1 array from the L0 entry. */
+			/* Get the L1 array from the L0 entry */
 			l1_gpt_arr = GPT_L0_TBLD_ADDR(l0_gpt_base[l0_idx]);
 		} else {
-			/* Get a new L1 table from the L1 memory space. */
-			l1_gpt_arr = gpt_get_new_l1_tbl();
+			/* Get a new L1 table from the L1 memory space */
+			l1_gpt_arr = get_new_l1_tbl();
 
-			/* Fill out the L0 descriptor and flush it. */
+			/* Fill out the L0 descriptor and flush it */
 			l0_gpt_base[l0_idx] = GPT_L0_TBL_DESC(l1_gpt_arr);
 		}
 
-		VERBOSE("[GPT] L0 entry (TABLE) index %u [%p] ==> L1 Addr 0x%llx (0x%" PRIx64 ")\n",
-			l0_idx, &l0_gpt_base[l0_idx],
-			(unsigned long long)(l1_gpt_arr),
-			l0_gpt_base[l0_idx]);
+		VERBOSE("GPT: L0 entry (TABLE) index %u [%p] ==> L1 Addr %p (0x%"PRIx64")\n",
+			l0_idx, &l0_gpt_base[l0_idx], l1_gpt_arr, l0_gpt_base[l0_idx]);
 
 		/*
 		 * Determine the PA of the last granule in this L0 descriptor.
 		 */
-		last_gran_pa = gpt_get_l1_end_pa(cur_pa, end_pa) -
+		last_gran_pa = get_l1_end_pa(cur_pa, end_pa) -
 			       GPT_PGS_ACTUAL_SIZE(gpt_config.p);
 
 		/*
@@ -621,11 +977,10 @@ static void gpt_generate_l0_tbl_desc(pas_region_t *pas)
 		 * function needs the addresses of the first granule and last
 		 * granule in the range.
 		 */
-		gpt_fill_l1_tbl(GPT_PAS_ATTR_GPI(pas->attrs), l1_gpt_arr,
-				cur_pa, last_gran_pa);
+		fill_l1_tbl(l1_gpt_arr, cur_pa, last_gran_pa, gpi);
 
-		/* Advance cur_pa to first granule in next L0 region. */
-		cur_pa = gpt_get_l1_end_pa(cur_pa, end_pa);
+		/* Advance cur_pa to first granule in next L0 region */
+		cur_pa = get_l1_end_pa(cur_pa, end_pa);
 	}
 }
 
@@ -642,25 +997,25 @@ static void gpt_generate_l0_tbl_desc(pas_region_t *pas)
  */
 static void flush_l0_for_pas_array(pas_region_t *pas, unsigned int pas_count)
 {
-	unsigned int idx;
-	unsigned int start_idx;
-	unsigned int end_idx;
+	unsigned long idx;
+	unsigned long start_idx;
+	unsigned long end_idx;
 	uint64_t *l0 = (uint64_t *)gpt_config.plat_gpt_l0_base;
 
 	assert(pas != NULL);
-	assert(pas_count > 0);
+	assert(pas_count != 0U);
 
-	/* Initial start and end values. */
+	/* Initial start and end values */
 	start_idx = GPT_L0_IDX(pas[0].base_pa);
-	end_idx = GPT_L0_IDX(pas[0].base_pa + pas[0].size - 1);
+	end_idx = GPT_L0_IDX(pas[0].base_pa + pas[0].size - 1UL);
 
-	/* Find lowest and highest L0 indices used in this PAS array. */
-	for (idx = 1; idx < pas_count; idx++) {
+	/* Find lowest and highest L0 indices used in this PAS array */
+	for (idx = 1UL; idx < pas_count; idx++) {
 		if (GPT_L0_IDX(pas[idx].base_pa) < start_idx) {
 			start_idx = GPT_L0_IDX(pas[idx].base_pa);
 		}
-		if (GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1) > end_idx) {
-			end_idx = GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1);
+		if (GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1UL) > end_idx) {
+			end_idx = GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1UL);
 		}
 	}
 
@@ -669,7 +1024,7 @@ static void flush_l0_for_pas_array(pas_region_t *pas, unsigned int pas_count)
 	 * the end index value.
 	 */
 	flush_dcache_range((uintptr_t)&l0[start_idx],
-			   ((end_idx + 1) - start_idx) * sizeof(uint64_t));
+			   ((end_idx + 1UL) - start_idx) * sizeof(uint64_t));
 }
 
 /*
@@ -688,8 +1043,8 @@ int gpt_enable(void)
 	 * Granule tables must be initialised before enabling
 	 * granule protection.
 	 */
-	if (gpt_config.plat_gpt_l0_base == 0U) {
-		ERROR("[GPT] Tables have not been initialized!\n");
+	if (gpt_config.plat_gpt_l0_base == 0UL) {
+		ERROR("GPT: Tables have not been initialized!\n");
 		return -EPERM;
 	}
 
@@ -710,7 +1065,7 @@ int gpt_enable(void)
 	 */
 	gpccr_el3 |= SET_GPCCR_SH(GPCCR_SH_IS);
 
-	/* Outer and Inner cacheability set to Normal memory, WB, RA, WA. */
+	/* Outer and Inner cacheability set to Normal memory, WB, RA, WA */
 	gpccr_el3 |= SET_GPCCR_ORGN(GPCCR_ORGN_WB_RA_WA);
 	gpccr_el3 |= SET_GPCCR_IRGN(GPCCR_IRGN_WB_RA_WA);
 
@@ -726,7 +1081,7 @@ int gpt_enable(void)
 	/* Enable GPT */
 	gpccr_el3 |= GPCCR_GPC_BIT;
 
-	/* TODO: Configure GPCCR_EL3_GPCP for Fault control. */
+	/* TODO: Configure GPCCR_EL3_GPCP for Fault control */
 	write_gpccr_el3(gpccr_el3);
 	isb();
 	tlbipaallos();
@@ -765,19 +1120,21 @@ void gpt_disable(void)
 int gpt_init_l0_tables(gpccr_pps_e pps, uintptr_t l0_mem_base,
 		       size_t l0_mem_size)
 {
-	int ret;
 	uint64_t gpt_desc;
+	size_t locks_size = 0;
+	__unused bitlock_t *bit_locks;
+	int ret;
 
-	/* Ensure that MMU and Data caches are enabled. */
+	/* Ensure that MMU and Data caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
 
-	/* Validate other parameters. */
-	ret = gpt_validate_l0_params(pps, l0_mem_base, l0_mem_size);
+	/* Validate other parameters */
+	ret = validate_l0_params(pps, l0_mem_base, l0_mem_size);
 	if (ret != 0) {
 		return ret;
 	}
 
-	/* Create the descriptor to initialize L0 entries with. */
+	/* Create the descriptor to initialize L0 entries with */
 	gpt_desc = GPT_L0_BLK_DESC(GPT_GPI_ANY);
 
 	/* Iterate through all L0 entries */
@@ -785,11 +1142,33 @@ int gpt_init_l0_tables(gpccr_pps_e pps, uintptr_t l0_mem_base,
 		((uint64_t *)l0_mem_base)[i] = gpt_desc;
 	}
 
-	/* Flush updated L0 tables to memory. */
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/* Initialise bitlocks at the end of L0 table */
+	bit_locks = (bitlock_t *)(l0_mem_base +
+					GPT_L0_TABLE_SIZE(gpt_config.t));
+
+	/* Size of bitlocks in bytes */
+	locks_size = GPT_PPS_ACTUAL_SIZE(gpt_config.t) /
+					(RME_GPT_BITLOCK_BLOCK * SZ_512M * 8U);
+
+	/*
+	 * If protected space size is less than the size covered
+	 * by 'bitlock' structure, initialise a single bitlock.
+	 */
+	if (locks_size < LOCK_SIZE) {
+		locks_size = LOCK_SIZE;
+	}
+
+	for (size_t i = 0UL; i < (locks_size/LOCK_SIZE); i++) {
+		bit_locks[i].lock = 0U;
+	}
+#endif
+
+	/* Flush updated L0 tables and bitlocks to memory */
 	flush_dcache_range((uintptr_t)l0_mem_base,
-			   (size_t)GPT_L0_TABLE_SIZE(gpt_config.t));
+				GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size);
 
-	/* Stash the L0 base address once initial setup is complete. */
+	/* Stash the L0 base address once initial setup is complete */
 	gpt_config.plat_gpt_l0_base = l0_mem_base;
 
 	return 0;
@@ -804,7 +1183,7 @@ int gpt_init_l0_tables(gpccr_pps_e pps, uintptr_t l0_mem_base,
  * This function can be called multiple times with different L1 memory ranges
  * and PAS regions if it is desirable to place L1 tables in different locations
  * in memory. (ex: you have multiple DDR banks and want to place the L1 tables
- * in the DDR bank that they control)
+ * in the DDR bank that they control).
  *
  * Parameters
  *   pgs		PGS value to use for table generation.
@@ -820,82 +1199,86 @@ int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, uintptr_t l1_mem_base,
 			   size_t l1_mem_size, pas_region_t *pas_regions,
 			   unsigned int pas_count)
 {
-	int ret;
-	int l1_gpt_cnt;
+	int l1_gpt_cnt, ret;
 
-	/* Ensure that MMU and Data caches are enabled. */
+	/* Ensure that MMU and Data caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
 
-	/* PGS is needed for gpt_validate_pas_mappings so check it now. */
+	/* PGS is needed for validate_pas_mappings so check it now */
 	if (pgs > GPT_PGS_MAX) {
-		ERROR("[GPT] Invalid PGS: 0x%x\n", pgs);
+		ERROR("GPT: Invalid PGS: 0x%x\n", pgs);
 		return -EINVAL;
 	}
 	gpt_config.pgs = pgs;
 	gpt_config.p = gpt_p_lookup[pgs];
 
-	/* Make sure L0 tables have been initialized. */
+	/* Make sure L0 tables have been initialized */
 	if (gpt_config.plat_gpt_l0_base == 0U) {
-		ERROR("[GPT] L0 tables must be initialized first!\n");
+		ERROR("GPT: L0 tables must be initialized first!\n");
 		return -EPERM;
 	}
 
-	/* Check if L1 GPTs are required and how many. */
-	l1_gpt_cnt = gpt_validate_pas_mappings(pas_regions, pas_count);
+	/* Check if L1 GPTs are required and how many */
+	l1_gpt_cnt = validate_pas_mappings(pas_regions, pas_count);
 	if (l1_gpt_cnt < 0) {
 		return l1_gpt_cnt;
 	}
 
-	VERBOSE("[GPT] %u L1 GPTs requested.\n", l1_gpt_cnt);
+	VERBOSE("GPT: %i L1 GPTs requested\n", l1_gpt_cnt);
 
-	/* If L1 tables are needed then validate the L1 parameters. */
+	/* If L1 tables are needed then validate the L1 parameters */
 	if (l1_gpt_cnt > 0) {
-		ret = gpt_validate_l1_params(l1_mem_base, l1_mem_size,
-		      l1_gpt_cnt);
+		ret = validate_l1_params(l1_mem_base, l1_mem_size,
+					(unsigned int)l1_gpt_cnt);
 		if (ret != 0) {
 			return ret;
 		}
 
-		/* Set up parameters for L1 table generation. */
+		/* Set up parameters for L1 table generation */
 		gpt_l1_tbl = l1_mem_base;
-		gpt_next_l1_tbl_idx = 0U;
 	}
 
-	INFO("[GPT] Boot Configuration\n");
+	/* Number of L1 entries in 2MB depends on GPCCR_EL3.PGS value */
+	gpt_l1_cnt_2mb = (unsigned int)GPT_L1_ENTRY_COUNT_2MB(gpt_config.p);
+
+	/* Mask for the L1 index field */
+	gpt_l1_index_mask = GPT_L1_IDX_MASK(gpt_config.p);
+
+	INFO("GPT: Boot Configuration\n");
 	INFO("  PPS/T:     0x%x/%u\n", gpt_config.pps, gpt_config.t);
 	INFO("  PGS/P:     0x%x/%u\n", gpt_config.pgs, gpt_config.p);
 	INFO("  L0GPTSZ/S: 0x%x/%u\n", GPT_L0GPTSZ, GPT_S_VAL);
-	INFO("  PAS count: 0x%x\n", pas_count);
-	INFO("  L0 base:   0x%lx\n", gpt_config.plat_gpt_l0_base);
+	INFO("  PAS count: %u\n", pas_count);
+	INFO("  L0 base:   0x%"PRIxPTR"\n", gpt_config.plat_gpt_l0_base);
 
-	/* Generate the tables in memory. */
+	/* Generate the tables in memory */
 	for (unsigned int idx = 0U; idx < pas_count; idx++) {
-		INFO("[GPT] PAS[%u]: base 0x%lx, size 0x%lx, GPI 0x%x, type 0x%x\n",
-		     idx, pas_regions[idx].base_pa, pas_regions[idx].size,
-		     GPT_PAS_ATTR_GPI(pas_regions[idx].attrs),
-		     GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs));
+		VERBOSE("GPT: PAS[%u]: base 0x%"PRIxPTR"\tsize 0x%lx\tGPI 0x%x\ttype 0x%x\n",
+			idx, pas_regions[idx].base_pa, pas_regions[idx].size,
+			GPT_PAS_ATTR_GPI(pas_regions[idx].attrs),
+			GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs));
 
 		/* Check if a block or table descriptor is required */
 		if (GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs) ==
 		    GPT_PAS_ATTR_MAP_TYPE_BLOCK) {
-			gpt_generate_l0_blk_desc(&pas_regions[idx]);
+			generate_l0_blk_desc(&pas_regions[idx]);
 
 		} else {
-			gpt_generate_l0_tbl_desc(&pas_regions[idx]);
+			generate_l0_tbl_desc(&pas_regions[idx]);
 		}
 	}
 
-	/* Flush modified L0 tables. */
+	/* Flush modified L0 tables */
 	flush_l0_for_pas_array(pas_regions, pas_count);
 
-	/* Flush L1 tables if needed. */
+	/* Flush L1 tables if needed */
 	if (l1_gpt_cnt > 0) {
 		flush_dcache_range(l1_mem_base,
 				   GPT_L1_TABLE_SIZE(gpt_config.p) *
-				   l1_gpt_cnt);
+				   (size_t)l1_gpt_cnt);
 	}
 
-	/* Make sure that all the entries are written to the memory. */
+	/* Make sure that all the entries are written to the memory */
 	dsbishst();
 	tlbipaallos();
 	dsb();
@@ -919,12 +1302,12 @@ int gpt_runtime_init(void)
 {
 	u_register_t reg;
 
-	/* Ensure that MMU and Data caches are enabled. */
+	/* Ensure that MMU and Data caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
 
-	/* Ensure GPC are already enabled. */
+	/* Ensure GPC are already enabled */
 	if ((read_gpccr_el3() & GPCCR_GPC_BIT) == 0U) {
-		ERROR("[GPT] Granule protection checks are not enabled!\n");
+		ERROR("GPT: Granule protection checks are not enabled!\n");
 		return -EPERM;
 	}
 
@@ -937,32 +1320,38 @@ int gpt_runtime_init(void)
 				      GPTBR_BADDR_MASK) <<
 				      GPTBR_BADDR_VAL_SHIFT;
 
-	/* Read GPCCR to get PGS and PPS values. */
+	/* Read GPCCR to get PGS and PPS values */
 	reg = read_gpccr_el3();
 	gpt_config.pps = (reg >> GPCCR_PPS_SHIFT) & GPCCR_PPS_MASK;
 	gpt_config.t = gpt_t_lookup[gpt_config.pps];
 	gpt_config.pgs = (reg >> GPCCR_PGS_SHIFT) & GPCCR_PGS_MASK;
 	gpt_config.p = gpt_p_lookup[gpt_config.pgs];
 
-	VERBOSE("[GPT] Runtime Configuration\n");
+	/* Number of L1 entries in 2MB depends on GPCCR_EL3.PGS value */
+	gpt_l1_cnt_2mb = (unsigned int)GPT_L1_ENTRY_COUNT_2MB(gpt_config.p);
+
+	/* Mask for the L1 index field */
+	gpt_l1_index_mask = GPT_L1_IDX_MASK(gpt_config.p);
+
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/* Bitlocks at the end of L0 table */
+	gpt_bitlock_base = (bitlock_t *)(gpt_config.plat_gpt_l0_base +
+					GPT_L0_TABLE_SIZE(gpt_config.t));
+#endif
+	VERBOSE("GPT: Runtime Configuration\n");
 	VERBOSE("  PPS/T:     0x%x/%u\n", gpt_config.pps, gpt_config.t);
 	VERBOSE("  PGS/P:     0x%x/%u\n", gpt_config.pgs, gpt_config.p);
 	VERBOSE("  L0GPTSZ/S: 0x%x/%u\n", GPT_L0GPTSZ, GPT_S_VAL);
-	VERBOSE("  L0 base:   0x%lx\n", gpt_config.plat_gpt_l0_base);
-
+	VERBOSE("  L0 base:   0x%"PRIxPTR"\n", gpt_config.plat_gpt_l0_base);
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	VERBOSE("  Bitlocks:  0x%"PRIxPTR"\n", (uintptr_t)gpt_bitlock_base);
+#endif
 	return 0;
 }
 
-/*
- * The L1 descriptors are protected by a spinlock to ensure that multiple
- * CPUs do not attempt to change the descriptors at once. In the future it
- * would be better to have separate spinlocks for each L1 descriptor.
- */
-static spinlock_t gpt_lock;
-
 /*
  * A helper to write the value (target_pas << gpi_shift) to the index of
- * the gpt_l1_addr
+ * the gpt_l1_addr.
  */
 static inline void write_gpt(uint64_t *gpt_l1_desc, uint64_t *gpt_l1_addr,
 			     unsigned int gpi_shift, unsigned int idx,
@@ -971,39 +1360,334 @@ static inline void write_gpt(uint64_t *gpt_l1_desc, uint64_t *gpt_l1_addr,
 	*gpt_l1_desc &= ~(GPT_L1_GRAN_DESC_GPI_MASK << gpi_shift);
 	*gpt_l1_desc |= ((uint64_t)target_pas << gpi_shift);
 	gpt_l1_addr[idx] = *gpt_l1_desc;
+
+	dsboshst();
 }
 
 /*
  * Helper to retrieve the gpt_l1_* information from the base address
- * returned in gpi_info
+ * returned in gpi_info.
  */
 static int get_gpi_params(uint64_t base, gpi_info_t *gpi_info)
 {
 	uint64_t gpt_l0_desc, *gpt_l0_base;
+	__unused unsigned int block_idx;
 
 	gpt_l0_base = (uint64_t *)gpt_config.plat_gpt_l0_base;
 	gpt_l0_desc = gpt_l0_base[GPT_L0_IDX(base)];
 	if (GPT_L0_TYPE(gpt_l0_desc) != GPT_L0_TYPE_TBL_DESC) {
-		VERBOSE("[GPT] Granule is not covered by a table descriptor!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Granule is not covered by a table descriptor!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		return -EINVAL;
 	}
 
-	/* Get the table index and GPI shift from PA. */
+	/* Get the table index and GPI shift from PA */
 	gpi_info->gpt_l1_addr = GPT_L0_TBLD_ADDR(gpt_l0_desc);
-	gpi_info->idx = GPT_L1_IDX(gpt_config.p, base);
+	gpi_info->idx = (unsigned int)GPT_L1_INDEX(base);
 	gpi_info->gpi_shift = GPT_L1_GPI_IDX(gpt_config.p, base) << 2;
 
-	gpi_info->gpt_l1_desc = (gpi_info->gpt_l1_addr)[gpi_info->idx];
-	gpi_info->gpi = (gpi_info->gpt_l1_desc >> gpi_info->gpi_shift) &
-		GPT_L1_GRAN_DESC_GPI_MASK;
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	/* Block index */
+	block_idx = (unsigned int)(base / (RME_GPT_BITLOCK_BLOCK * SZ_512M));
+
+	/* Bitlock address and mask */
+	gpi_info->lock = &gpt_bitlock_base[block_idx / LOCK_BITS];
+	gpi_info->mask = 1U << (block_idx & (LOCK_BITS - 1U));
+#endif
 	return 0;
 }
 
+/*
+ * Helper to retrieve the gpt_l1_desc and GPI information from gpi_info.
+ * This function is called with bitlock or spinlock acquired.
+ */
+static void read_gpi(gpi_info_t *gpi_info)
+{
+	gpi_info->gpt_l1_desc = (gpi_info->gpt_l1_addr)[gpi_info->idx];
+
+	if ((gpi_info->gpt_l1_desc & GPT_L1_TYPE_CONT_DESC_MASK) ==
+				 GPT_L1_TYPE_CONT_DESC) {
+		/* Read GPI from Contiguous descriptor */
+		gpi_info->gpi = (unsigned int)GPT_L1_CONT_GPI(gpi_info->gpt_l1_desc);
+	} else {
+		/* Read GPI from Granules descriptor */
+		gpi_info->gpi = (unsigned int)((gpi_info->gpt_l1_desc >> gpi_info->gpi_shift) &
+						GPT_L1_GRAN_DESC_GPI_MASK);
+	}
+}
+
+static void flush_page_to_popa(uintptr_t addr)
+{
+	size_t size = GPT_PGS_ACTUAL_SIZE(gpt_config.p);
+
+	if (is_feat_mte2_supported()) {
+		flush_dcache_to_popa_range_mte2(addr, size);
+	} else {
+		flush_dcache_to_popa_range(addr, size);
+	}
+}
+
+/*
+ * Helper function to check if all L1 entries in 2MB block have
+ * the same Granules descriptor value.
+ *
+ * Parameters
+ *   base		Base address of the region to be checked
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor with all entries
+ *			set to the same GPI.
+ *
+ * Return
+ *   true if L1 all entries have the same descriptor value, false otherwise.
+ */
+__unused static bool check_fuse_2mb(uint64_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc)
+{
+	/* Last L1 entry index in 2MB block */
+	unsigned int long idx = GPT_L1_INDEX(ALIGN_2MB(base)) +
+						gpt_l1_cnt_2mb - 1UL;
+
+	/* Number of L1 entries in 2MB block */
+	unsigned int cnt = gpt_l1_cnt_2mb;
+
+	/*
+	 * Start check from the last L1 entry and continue until the first
+	 * non-matching to the passed Granules descriptor value is found.
+	 */
+	while (cnt-- != 0U) {
+		if (gpi_info->gpt_l1_addr[idx--] != l1_desc) {
+			/* Non-matching L1 entry found */
+			return false;
+		}
+	}
+
+	return true;
+}
+
+__unused static void fuse_2mb(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* L1 entry index of the start of 2MB block */
+	unsigned long idx_2 = GPT_L1_INDEX(ALIGN_2MB(base));
+
+	/* 2MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 2MB);
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n", __func__, base, l1_desc);
+
+	fill_desc(&gpi_info->gpt_l1_addr[idx_2], l1_cont_desc, L1_QWORDS_2MB);
+}
+
+/*
+ * Helper function to check if all 1st L1 entries of 2MB blocks
+ * in 32MB have the same 2MB Contiguous descriptor value.
+ *
+ * Parameters
+ *   base		Base address of the region to be checked
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor.
+ *
+ * Return
+ *   true if all L1 entries have the same descriptor value, false otherwise.
+ */
+__unused static bool check_fuse_32mb(uint64_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc)
+{
+	/* The 1st L1 entry index of the last 2MB block in 32MB */
+	unsigned long idx = GPT_L1_INDEX(ALIGN_32MB(base)) +
+					(15UL * gpt_l1_cnt_2mb);
+
+	/* 2MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 2MB);
+
+	/* Number of 2MB blocks in 32MB */
+	unsigned int cnt = 16U;
+
+	/* Set the first L1 entry to 2MB Contiguous descriptor */
+	gpi_info->gpt_l1_addr[GPT_L1_INDEX(ALIGN_2MB(base))] = l1_cont_desc;
+
+	/*
+	 * Start check from the 1st L1 entry of the last 2MB block and
+	 * continue until the first non-matching to 2MB Contiguous descriptor
+	 * value is found.
+	 */
+	while (cnt-- != 0U) {
+		if (gpi_info->gpt_l1_addr[idx] != l1_cont_desc) {
+			/* Non-matching L1 entry found */
+			return false;
+		}
+		idx -= gpt_l1_cnt_2mb;
+	}
+
+	return true;
+}
+
+__unused static void fuse_32mb(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* L1 entry index of the start of 32MB block */
+	unsigned long idx_32 = GPT_L1_INDEX(ALIGN_32MB(base));
+
+	/* 32MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 32MB);
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n", __func__, base, l1_desc);
+
+	fill_desc(&gpi_info->gpt_l1_addr[idx_32], l1_cont_desc, L1_QWORDS_32MB);
+}
+
+/*
+ * Helper function to check if all 1st L1 entries of 32MB blocks
+ * in 512MB have the same 32MB Contiguous descriptor value.
+ *
+ * Parameters
+ *   base		Base address of the region to be checked
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor.
+ *
+ * Return
+ *   true if all L1 entries have the same descriptor value, false otherwise.
+ */
+__unused static bool check_fuse_512mb(uint64_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc)
+{
+	/* The 1st L1 entry index of the last 32MB block in 512MB */
+	unsigned long idx = GPT_L1_INDEX(ALIGN_512MB(base)) +
+					(15UL * 16UL * gpt_l1_cnt_2mb);
+
+	/* 32MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 32MB);
+
+	/* Number of 32MB blocks in 512MB */
+	unsigned int cnt = 16U;
+
+	/* Set the first L1 entry to 2MB Contiguous descriptor */
+	gpi_info->gpt_l1_addr[GPT_L1_INDEX(ALIGN_32MB(base))] = l1_cont_desc;
+
+	/*
+	 * Start check from the 1st L1 entry of the last 32MB block and
+	 * continue until the first non-matching to 32MB Contiguous descriptor
+	 * value is found.
+	 */
+	while (cnt-- != 0U) {
+		if (gpi_info->gpt_l1_addr[idx] != l1_cont_desc) {
+			/* Non-matching L1 entry found */
+			return false;
+		}
+		idx -= 16UL * gpt_l1_cnt_2mb;
+	}
+
+	return true;
+}
+
+__unused static void fuse_512mb(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* L1 entry index of the start of 512MB block */
+	unsigned long idx_512 = GPT_L1_INDEX(ALIGN_512MB(base));
+
+	/* 512MB Contiguous descriptor */
+	uint64_t l1_cont_desc = GPT_L1_CONT_DESC(l1_desc, 512MB);
+
+	VERBOSE("GPT: %s(0x%"PRIxPTR" 0x%"PRIx64")\n", __func__, base, l1_desc);
+
+	fill_desc(&gpi_info->gpt_l1_addr[idx_512], l1_cont_desc, L1_QWORDS_512MB);
+}
+
+/*
+ * Helper function to convert GPI entries in a single L1 table
+ * from Granules to Contiguous descriptor.
+ *
+ * Parameters
+ *   base		Base address of the region to be written
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor with all entries
+ *			set to the same GPI.
+ */
+__unused static void fuse_block(uint64_t base, const gpi_info_t *gpi_info,
+				uint64_t l1_desc)
+{
+	/* Start with check for 2MB block */
+	if (!check_fuse_2mb(base, gpi_info, l1_desc)) {
+		/* Check for 2MB fusing failed */
+		return;
+	}
+
+#if (RME_GPT_MAX_BLOCK == 2)
+	fuse_2mb(base, gpi_info, l1_desc);
+#else
+	/* Check for 32MB block */
+	if (!check_fuse_32mb(base, gpi_info, l1_desc)) {
+		/* Check for 32MB fusing failed, fuse to 2MB */
+		fuse_2mb(base, gpi_info, l1_desc);
+		return;
+	}
+
+#if (RME_GPT_MAX_BLOCK == 32)
+	fuse_32mb(base, gpi_info, l1_desc);
+#else
+	/* Check for 512MB block */
+	if (!check_fuse_512mb(base, gpi_info, l1_desc)) {
+		/* Check for 512MB fusing failed, fuse to 32MB */
+		fuse_32mb(base, gpi_info, l1_desc);
+		return;
+	}
+
+	/* Fuse to 512MB */
+	fuse_512mb(base, gpi_info, l1_desc);
+
+#endif	/* RME_GPT_MAX_BLOCK == 32 */
+#endif	/* RME_GPT_MAX_BLOCK == 2 */
+}
+
+/*
+ * Helper function to convert GPI entries in a single L1 table
+ * from Contiguous to Granules descriptor. This function updates
+ * descriptor to Granules in passed 'gpt_config_t' structure as
+ * the result of shuttering.
+ *
+ * Parameters
+ *   base		Base address of the region to be written
+ *   gpi_info		Pointer to 'gpt_config_t' structure
+ *   l1_desc		GPT Granules descriptor set this range to.
+ */
+__unused static void shatter_block(uint64_t base, gpi_info_t *gpi_info,
+				   uint64_t l1_desc)
+{
+	/* Look-up table for 2MB, 32MB and 512MB locks shattering */
+	static const gpt_shatter_func gpt_shatter_lookup[] = {
+		shatter_2mb,
+		shatter_32mb,
+		shatter_512mb
+	};
+
+	/* Look-up table for invalidation TLBs for 2MB, 32MB and 512MB blocks */
+	static const gpt_tlbi_lookup_t tlbi_lookup[] = {
+		{ tlbirpalos_2m, ~(SZ_2M - 1UL) },
+		{ tlbirpalos_32m, ~(SZ_32M - 1UL) },
+		{ tlbirpalos_512m, ~(SZ_512M - 1UL) }
+	};
+
+	/* Get shattering level from Contig field of Contiguous descriptor */
+	unsigned long level = GPT_L1_CONT_CONTIG(gpi_info->gpt_l1_desc) - 1UL;
+
+	/* Shatter contiguous block */
+	gpt_shatter_lookup[level](base, gpi_info, l1_desc);
+
+	tlbi_lookup[level].function(base & tlbi_lookup[level].mask);
+	dsbosh();
+
+	/*
+	 * Update 'gpt_config_t' structure's descriptor to Granules to reflect
+	 * the shattered GPI back to caller.
+	 */
+	gpi_info->gpt_l1_desc = l1_desc;
+}
+
 /*
  * This function is the granule transition delegate service. When a granule
  * transition request occurs it is routed to this function to have the request,
- * if valid, fulfilled following A1.1.1 Delegate of RME supplement
+ * if valid, fulfilled following A1.1.1 Delegate of RME supplement.
  *
  * TODO: implement support for transitioning multiple granules at once.
  *
@@ -1020,104 +1704,120 @@ static int get_gpi_params(uint64_t base, gpi_info_t *gpi_info)
 int gpt_delegate_pas(uint64_t base, size_t size, unsigned int src_sec_state)
 {
 	gpi_info_t gpi_info;
-	uint64_t nse;
-	int res;
+	uint64_t nse, __unused l1_desc;
 	unsigned int target_pas;
+	int res;
 
-	/* Ensure that the tables have been set up before taking requests. */
+	/* Ensure that the tables have been set up before taking requests */
 	assert(gpt_config.plat_gpt_l0_base != 0UL);
 
-	/* Ensure that caches are enabled. */
+	/* Ensure that caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0UL);
 
-	/* Delegate request can only come from REALM or SECURE */
-	assert(src_sec_state == SMC_FROM_REALM ||
-	       src_sec_state == SMC_FROM_SECURE);
-
-	/* See if this is a single or a range of granule transition. */
+	/* See if this is a single or a range of granule transition */
 	if (size != GPT_PGS_ACTUAL_SIZE(gpt_config.p)) {
 		return -EINVAL;
 	}
 
 	/* Check that base and size are valid */
 	if ((ULONG_MAX - base) < size) {
-		VERBOSE("[GPT] Transition request address overflow!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Transition request address overflow!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
 
-	/* Make sure base and size are valid. */
-	if (((base & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0UL) ||
-	    ((size & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0UL) ||
+	/* Make sure base and size are valid */
+	if (((base & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) != 0UL) ||
+	    ((size & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) != 0UL) ||
 	    (size == 0UL) ||
 	    ((base + size) >= GPT_PPS_ACTUAL_SIZE(gpt_config.t))) {
-		VERBOSE("[GPT] Invalid granule transition address range!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Invalid granule transition address range!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
 
-	target_pas = GPT_GPI_REALM;
-	if (src_sec_state == SMC_FROM_SECURE) {
+	/* Delegate request can only come from REALM or SECURE */
+	if ((src_sec_state != SMC_FROM_REALM) &&
+	    (src_sec_state != SMC_FROM_SECURE)) {
+		VERBOSE("GPT: Invalid caller security state 0x%x\n",
+							src_sec_state);
+		return -EINVAL;
+	}
+
+	if (src_sec_state == SMC_FROM_REALM) {
+		target_pas = GPT_GPI_REALM;
+		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
+		l1_desc = GPT_L1_REALM_DESC;
+	} else {
 		target_pas = GPT_GPI_SECURE;
+		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
+		l1_desc = GPT_L1_SECURE_DESC;
 	}
 
-	/*
-	 * Access to L1 tables is controlled by a global lock to ensure
-	 * that no more than one CPU is allowed to make changes at any
-	 * given time.
-	 */
-	spin_lock(&gpt_lock);
 	res = get_gpi_params(base, &gpi_info);
 	if (res != 0) {
-		spin_unlock(&gpt_lock);
 		return res;
 	}
 
+	/*
+	 * Access to GPT is controlled by a lock to ensure that no more
+	 * than one CPU is allowed to make changes at any given time.
+	 */
+	GPT_LOCK;
+	read_gpi(&gpi_info);
+
 	/* Check that the current address is in NS state */
 	if (gpi_info.gpi != GPT_GPI_NS) {
-		VERBOSE("[GPT] Only Granule in NS state can be delegated.\n");
+		VERBOSE("GPT: Only Granule in NS state can be delegated.\n");
 		VERBOSE("      Caller: %u, Current GPI: %u\n", src_sec_state,
 			gpi_info.gpi);
-		spin_unlock(&gpt_lock);
+		GPT_UNLOCK;
 		return -EPERM;
 	}
 
-	if (src_sec_state == SMC_FROM_SECURE) {
-		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
-	} else {
-		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
+#if (RME_GPT_MAX_BLOCK != 0)
+	/* Check for Contiguous descriptor */
+	if ((gpi_info.gpt_l1_desc & GPT_L1_TYPE_CONT_DESC_MASK) ==
+					GPT_L1_TYPE_CONT_DESC) {
+		shatter_block(base, &gpi_info, GPT_L1_NS_DESC);
 	}
-
+#endif
 	/*
 	 * In order to maintain mutual distrust between Realm and Secure
 	 * states, remove any data speculatively fetched into the target
-	 * physical address space. Issue DC CIPAPA over address range
+	 * physical address space.
+	 * Issue DC CIPAPA or DC_CIGDPAPA on implementations with FEAT_MTE2.
 	 */
-	flush_dcache_to_popa_range(nse | base,
-				   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
+	flush_page_to_popa(base | nse);
 
 	write_gpt(&gpi_info.gpt_l1_desc, gpi_info.gpt_l1_addr,
 		  gpi_info.gpi_shift, gpi_info.idx, target_pas);
-	dsboshst();
 
-	gpt_tlbi_by_pa_ll(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	dsbosh();
+	/* Ensure that all agents observe the new configuration */
+	tlbi_page_dsbosh(base);
 
 	nse = (uint64_t)GPT_NSE_NS << GPT_NSE_SHIFT;
 
-	flush_dcache_to_popa_range(nse | base,
-				   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
+	/* Ensure that the scrubbed data have made it past the PoPA */
+	flush_page_to_popa(base | nse);
+
+#if (RME_GPT_MAX_BLOCK != 0)
+	if (gpi_info.gpt_l1_desc == l1_desc) {
+		/* Try to fuse */
+		fuse_block(base, &gpi_info, l1_desc);
+	}
+#endif
 
-	/* Unlock access to the L1 tables. */
-	spin_unlock(&gpt_lock);
+	/* Unlock the lock to GPT */
+	GPT_UNLOCK;
 
 	/*
 	 * The isb() will be done as part of context
-	 * synchronization when returning to lower EL
+	 * synchronization when returning to lower EL.
 	 */
-	VERBOSE("[GPT] Granule 0x%" PRIx64 ", GPI 0x%x->0x%x\n",
+	VERBOSE("GPT: Granule 0x%"PRIx64" GPI 0x%x->0x%x\n",
 		base, gpi_info.gpi, target_pas);
 
 	return 0;
@@ -1143,117 +1843,119 @@ int gpt_delegate_pas(uint64_t base, size_t size, unsigned int src_sec_state)
 int gpt_undelegate_pas(uint64_t base, size_t size, unsigned int src_sec_state)
 {
 	gpi_info_t gpi_info;
-	uint64_t nse;
+	uint64_t nse, __unused l1_desc;
 	int res;
 
-	/* Ensure that the tables have been set up before taking requests. */
+	/* Ensure that the tables have been set up before taking requests */
 	assert(gpt_config.plat_gpt_l0_base != 0UL);
 
-	/* Ensure that MMU and caches are enabled. */
+	/* Ensure that MMU and caches are enabled */
 	assert((read_sctlr_el3() & SCTLR_C_BIT) != 0UL);
 
-	/* Delegate request can only come from REALM or SECURE */
-	assert(src_sec_state == SMC_FROM_REALM ||
-	       src_sec_state == SMC_FROM_SECURE);
-
-	/* See if this is a single or a range of granule transition. */
+	/* See if this is a single or a range of granule transition */
 	if (size != GPT_PGS_ACTUAL_SIZE(gpt_config.p)) {
 		return -EINVAL;
 	}
 
 	/* Check that base and size are valid */
 	if ((ULONG_MAX - base) < size) {
-		VERBOSE("[GPT] Transition request address overflow!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Transition request address overflow!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
 
-	/* Make sure base and size are valid. */
-	if (((base & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0UL) ||
-	    ((size & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0UL) ||
+	/* Make sure base and size are valid */
+	if (((base & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) != 0UL) ||
+	    ((size & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) != 0UL) ||
 	    (size == 0UL) ||
 	    ((base + size) >= GPT_PPS_ACTUAL_SIZE(gpt_config.t))) {
-		VERBOSE("[GPT] Invalid granule transition address range!\n");
-		VERBOSE("      Base=0x%" PRIx64 "\n", base);
+		VERBOSE("GPT: Invalid granule transition address range!\n");
+		VERBOSE("      Base=0x%"PRIx64"\n", base);
 		VERBOSE("      Size=0x%lx\n", size);
 		return -EINVAL;
 	}
 
-	/*
-	 * Access to L1 tables is controlled by a global lock to ensure
-	 * that no more than one CPU is allowed to make changes at any
-	 * given time.
-	 */
-	spin_lock(&gpt_lock);
-
 	res = get_gpi_params(base, &gpi_info);
 	if (res != 0) {
-		spin_unlock(&gpt_lock);
 		return res;
 	}
 
+	/*
+	 * Access to GPT is controlled by a lock to ensure that no more
+	 * than one CPU is allowed to make changes at any given time.
+	 */
+	GPT_LOCK;
+	read_gpi(&gpi_info);
+
 	/* Check that the current address is in the delegated state */
-	if ((src_sec_state == SMC_FROM_REALM  &&
-	     gpi_info.gpi != GPT_GPI_REALM) ||
-	    (src_sec_state == SMC_FROM_SECURE &&
-	     gpi_info.gpi != GPT_GPI_SECURE)) {
-		VERBOSE("[GPT] Only Granule in REALM or SECURE state can be undelegated.\n");
-		VERBOSE("      Caller: %u, Current GPI: %u\n", src_sec_state,
+	if ((src_sec_state == SMC_FROM_REALM) &&
+		(gpi_info.gpi == GPT_GPI_REALM)) {
+		l1_desc = GPT_L1_REALM_DESC;
+		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
+	} else if ((src_sec_state == SMC_FROM_SECURE) &&
+		(gpi_info.gpi == GPT_GPI_SECURE)) {
+		l1_desc = GPT_L1_SECURE_DESC;
+		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
+	} else {
+		VERBOSE("GPT: Only Granule in REALM or SECURE state can be undelegated\n");
+		VERBOSE("      Caller: %u Current GPI: %u\n", src_sec_state,
 			gpi_info.gpi);
-		spin_unlock(&gpt_lock);
+		GPT_UNLOCK;
 		return -EPERM;
 	}
 
-
-	/* In order to maintain mutual distrust between Realm and Secure
+#if (RME_GPT_MAX_BLOCK != 0)
+	/* Check for Contiguous descriptor */
+	if ((gpi_info.gpt_l1_desc & GPT_L1_TYPE_CONT_DESC_MASK) ==
+					GPT_L1_TYPE_CONT_DESC) {
+		shatter_block(base, &gpi_info, l1_desc);
+	}
+#endif
+	/*
+	 * In order to maintain mutual distrust between Realm and Secure
 	 * states, remove access now, in order to guarantee that writes
 	 * to the currently-accessible physical address space will not
 	 * later become observable.
 	 */
 	write_gpt(&gpi_info.gpt_l1_desc, gpi_info.gpt_l1_addr,
 		  gpi_info.gpi_shift, gpi_info.idx, GPT_GPI_NO_ACCESS);
-	dsboshst();
 
-	gpt_tlbi_by_pa_ll(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	dsbosh();
-
-	if (src_sec_state == SMC_FROM_SECURE) {
-		nse = (uint64_t)GPT_NSE_SECURE << GPT_NSE_SHIFT;
-	} else {
-		nse = (uint64_t)GPT_NSE_REALM << GPT_NSE_SHIFT;
-	}
+	/* Ensure that all agents observe the new NO_ACCESS configuration */
+	tlbi_page_dsbosh(base);
 
-	/* Ensure that the scrubbed data has made it past the PoPA */
-	flush_dcache_to_popa_range(nse | base,
-				   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
+	/* Ensure that the scrubbed data have made it past the PoPA */
+	flush_page_to_popa(base | nse);
 
 	/*
-	 * Remove any data loaded speculatively
-	 * in NS space from before the scrubbing
+	 * Remove any data loaded speculatively in NS space from before
+	 * the scrubbing.
 	 */
 	nse = (uint64_t)GPT_NSE_NS << GPT_NSE_SHIFT;
 
-	flush_dcache_to_popa_range(nse | base,
-				   GPT_PGS_ACTUAL_SIZE(gpt_config.p));
+	flush_page_to_popa(base | nse);
 
-	/* Clear existing GPI encoding and transition granule. */
+	/* Clear existing GPI encoding and transition granule */
 	write_gpt(&gpi_info.gpt_l1_desc, gpi_info.gpt_l1_addr,
 		  gpi_info.gpi_shift, gpi_info.idx, GPT_GPI_NS);
-	dsboshst();
 
 	/* Ensure that all agents observe the new NS configuration */
-	gpt_tlbi_by_pa_ll(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p));
-	dsbosh();
+	tlbi_page_dsbosh(base);
 
-	/* Unlock access to the L1 tables. */
-	spin_unlock(&gpt_lock);
+#if (RME_GPT_MAX_BLOCK != 0)
+	if (gpi_info.gpt_l1_desc == GPT_L1_NS_DESC) {
+		/* Try to fuse */
+		fuse_block(base, &gpi_info, GPT_L1_NS_DESC);
+	}
+#endif
+	/* Unlock the lock to GPT */
+	GPT_UNLOCK;
 
 	/*
 	 * The isb() will be done as part of context
-	 * synchronization when returning to lower EL
+	 * synchronization when returning to lower EL.
 	 */
-	VERBOSE("[GPT] Granule 0x%" PRIx64 ", GPI 0x%x->0x%x\n",
+	VERBOSE("GPT: Granule 0x%"PRIx64" GPI 0x%x->0x%x\n",
 		base, gpi_info.gpi, GPT_GPI_NS);
 
 	return 0;
diff --git a/lib/gpt_rme/gpt_rme.mk b/lib/gpt_rme/gpt_rme.mk
index 60176f4e..7d6b61f9 100644
--- a/lib/gpt_rme/gpt_rme.mk
+++ b/lib/gpt_rme/gpt_rme.mk
@@ -1,8 +1,22 @@
 #
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# Process RME_GPT_BITLOCK_BLOCK value
+ifeq ($(filter 0 1 2 4 8 16 32 64 128 256 512, ${RME_GPT_BITLOCK_BLOCK}),)
+    $(error "Invalid value for RME_GPT_BITLOCK_BLOCK: ${RME_GPT_BITLOCK_BLOCK}")
+endif
+
+ifeq (${RME_GPT_BITLOCK_BLOCK},0)
+    $(warning "GPT library uses global spinlock")
+endif
+
+# Process RME_GPT_MAX_BLOCK value
+ifeq ($(filter 0 2 32 512, ${RME_GPT_MAX_BLOCK}),)
+    $(error "Invalid value for RME_GPT_MAX_BLOCK: ${RME_GPT_MAX_BLOCK}")
+endif
+
 GPT_LIB_SRCS	:=	$(addprefix lib/gpt_rme/,        \
 			gpt_rme.c)
diff --git a/lib/gpt_rme/gpt_rme_private.h b/lib/gpt_rme/gpt_rme_private.h
index 3c817f3e..31dad20c 100644
--- a/lib/gpt_rme/gpt_rme_private.h
+++ b/lib/gpt_rme/gpt_rme_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,19 +9,20 @@
 
 #include <arch.h>
 #include <lib/gpt_rme/gpt_rme.h>
+#include <lib/spinlock.h>
 #include <lib/utils_def.h>
 
 /******************************************************************************/
 /* GPT descriptor definitions                                                 */
 /******************************************************************************/
 
-/* GPT level 0 descriptor bit definitions. */
+/* GPT level 0 descriptor bit definitions */
 #define GPT_L0_TYPE_MASK		UL(0xF)
 #define GPT_L0_TYPE_SHIFT		U(0)
 
-/* For now, we don't support contiguous descriptors, only table and block. */
-#define GPT_L0_TYPE_TBL_DESC		UL(0x3)
-#define GPT_L0_TYPE_BLK_DESC		UL(0x1)
+/* GPT level 0 table and block descriptors */
+#define GPT_L0_TYPE_TBL_DESC		UL(3)
+#define GPT_L0_TYPE_BLK_DESC		UL(1)
 
 #define GPT_L0_TBL_DESC_L1ADDR_MASK	UL(0xFFFFFFFFFF)
 #define GPT_L0_TBL_DESC_L1ADDR_SHIFT	U(12)
@@ -29,35 +30,69 @@
 #define GPT_L0_BLK_DESC_GPI_MASK	UL(0xF)
 #define GPT_L0_BLK_DESC_GPI_SHIFT	U(4)
 
-/* GPT level 1 descriptor bit definitions */
+/* GPT level 1 Contiguous descriptor */
+#define GPT_L1_TYPE_CONT_DESC_MASK	UL(0xF)
+#define GPT_L1_TYPE_CONT_DESC		UL(1)
+
+/* GPT level 1 Contiguous descriptor definitions */
+#define GPT_L1_CONTIG_2MB		UL(1)
+#define GPT_L1_CONTIG_32MB		UL(2)
+#define GPT_L1_CONTIG_512MB		UL(3)
+
+#define GPT_L1_CONT_DESC_GPI_SHIFT	U(4)
+#define GPT_L1_CONT_DESC_GPI_MASK	UL(0xF)
+#define GPT_L1_CONT_DESC_CONTIG_SHIFT	U(8)
+#define GPT_L1_CONT_DESC_CONTIG_MASK	UL(3)
+
+/* GPT level 1 Granules descriptor bit definitions */
 #define GPT_L1_GRAN_DESC_GPI_MASK	UL(0xF)
 
+/* L1 Contiguous descriptors templates */
+#define GPT_L1_CONT_DESC_2MB	\
+			(GPT_L1_TYPE_CONT_DESC |	\
+			(GPT_L1_CONTIG_2MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
+#define GPT_L1_CONT_DESC_32MB	\
+			(GPT_L1_TYPE_CONT_DESC |	\
+			(GPT_L1_CONTIG_32MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
+#define GPT_L1_CONT_DESC_512MB	\
+			(GPT_L1_TYPE_CONT_DESC |	\
+			(GPT_L1_CONTIG_512MB << GPT_L1_CONT_DESC_CONTIG_SHIFT))
+
+/* Create L1 Contiguous descriptor from GPI and template */
+#define GPT_L1_GPI_CONT_DESC(_gpi, _desc)	\
+			((_desc) | ((uint64_t)(_gpi) << GPT_L1_CONT_DESC_GPI_SHIFT))
+
+/* Create L1 Contiguous descriptor from Granules descriptor and size */
+#define GPT_L1_CONT_DESC(_desc, _size) \
+				(GPT_L1_CONT_DESC_##_size	| \
+				(((_desc) & GPT_L1_GRAN_DESC_GPI_MASK) << \
+				GPT_L1_CONT_DESC_GPI_SHIFT))
+
+/* Create L1 Contiguous descriptor from GPI and size */
+#define GPT_L1_CONT_DESC_SIZE(_gpi, _size) \
+				(GPT_L1_CONT_DESC_##_size	| \
+				(((uint64_t)(_gpi) << GPT_L1_CONT_DESC_GPI_SHIFT))
+
+#define GPT_L1_GPI_BYTE(_gpi)		(uint64_t)((_gpi) | ((_gpi) << 4))
+#define GPT_L1_GPI_HALF(_gpi)		(GPT_L1_GPI_BYTE(_gpi) | (GPT_L1_GPI_BYTE(_gpi) << 8))
+#define GPT_L1_GPI_WORD(_gpi)		(GPT_L1_GPI_HALF(_gpi) | (GPT_L1_GPI_HALF(_gpi) << 16))
+
 /*
- * This macro fills out every GPI entry in a granules descriptor to the same
- * value.
+ * This macro generates a Granules descriptor
+ * with the same value for every GPI entry.
  */
-#define GPT_BUILD_L1_DESC(_gpi)		(((uint64_t)(_gpi) << 4*0) | \
-					 ((uint64_t)(_gpi) << 4*1) | \
-					 ((uint64_t)(_gpi) << 4*2) | \
-					 ((uint64_t)(_gpi) << 4*3) | \
-					 ((uint64_t)(_gpi) << 4*4) | \
-					 ((uint64_t)(_gpi) << 4*5) | \
-					 ((uint64_t)(_gpi) << 4*6) | \
-					 ((uint64_t)(_gpi) << 4*7) | \
-					 ((uint64_t)(_gpi) << 4*8) | \
-					 ((uint64_t)(_gpi) << 4*9) | \
-					 ((uint64_t)(_gpi) << 4*10) | \
-					 ((uint64_t)(_gpi) << 4*11) | \
-					 ((uint64_t)(_gpi) << 4*12) | \
-					 ((uint64_t)(_gpi) << 4*13) | \
-					 ((uint64_t)(_gpi) << 4*14) | \
-					 ((uint64_t)(_gpi) << 4*15))
+#define GPT_BUILD_L1_DESC(_gpi)		(GPT_L1_GPI_WORD(_gpi) | (GPT_L1_GPI_WORD(_gpi) << 32))
+
+#define GPT_L1_SECURE_DESC	GPT_BUILD_L1_DESC(GPT_GPI_SECURE)
+#define GPT_L1_NS_DESC		GPT_BUILD_L1_DESC(GPT_GPI_NS)
+#define GPT_L1_REALM_DESC	GPT_BUILD_L1_DESC(GPT_GPI_REALM)
+#define GPT_L1_ANY_DESC		GPT_BUILD_L1_DESC(GPT_GPI_ANY)
 
 /******************************************************************************/
 /* GPT platform configuration                                                 */
 /******************************************************************************/
 
-/* This value comes from GPCCR_EL3 so no externally supplied definition. */
+/* This value comes from GPCCR_EL3 so no externally supplied definition */
 #define GPT_L0GPTSZ		((unsigned int)((read_gpccr_el3() >> \
 				GPCCR_L0GPTSZ_SHIFT) & GPCCR_L0GPTSZ_MASK))
 
@@ -106,21 +141,50 @@ typedef enum {
 	PGS_64KB_P =	16U
 } gpt_p_val_e;
 
+#define LOCK_SIZE	sizeof(((bitlock_t *)NULL)->lock)
+#define LOCK_TYPE	typeof(((bitlock_t *)NULL)->lock)
+#define LOCK_BITS	(LOCK_SIZE * 8U)
+
 /*
- * Internal structure to retrieve the values from get_gpi_info();
+ * Internal structure to retrieve the values from get_gpi_params();
  */
-typedef struct gpi_info {
+typedef struct {
 	uint64_t gpt_l1_desc;
 	uint64_t *gpt_l1_addr;
 	unsigned int idx;
 	unsigned int gpi_shift;
 	unsigned int gpi;
+#if (RME_GPT_BITLOCK_BLOCK != 0)
+	bitlock_t *lock;
+	LOCK_TYPE mask;
+#endif
 } gpi_info_t;
 
-/* Max valid value for PGS. */
+/*
+ * Look up structure for contiguous blocks and descriptors
+ */
+typedef struct {
+	size_t size;
+	unsigned int desc;
+} gpt_fill_lookup_t;
+
+typedef void (*gpt_shatter_func)(uintptr_t base, const gpi_info_t *gpi_info,
+					uint64_t l1_desc);
+typedef void (*gpt_tlbi_func)(uintptr_t base);
+
+/*
+ * Look-up structure for
+ * invalidating TLBs of GPT entries by Physical address, last level.
+ */
+typedef struct {
+	gpt_tlbi_func function;
+	size_t mask;
+} gpt_tlbi_lookup_t;
+
+/* Max valid value for PGS */
 #define GPT_PGS_MAX			(2U)
 
-/* Max valid value for PPS. */
+/* Max valid value for PPS */
 #define GPT_PPS_MAX			(6U)
 
 /******************************************************************************/
@@ -136,10 +200,10 @@ typedef struct gpi_info {
  * special case we'll get a negative width value which does not make sense and
  * would cause problems.
  */
-#define GPT_L0_IDX_WIDTH(_t)		(((_t) > GPT_S_VAL) ? \
-					((_t) - GPT_S_VAL) : (0U))
+#define GPT_L0_IDX_WIDTH(_t)		(((unsigned int)(_t) > GPT_S_VAL) ? \
+					((unsigned int)(_t) - GPT_S_VAL) : (0U))
 
-/* Bit shift for the L0 index field in a PA. */
+/* Bit shift for the L0 index field in a PA */
 #define GPT_L0_IDX_SHIFT		(GPT_S_VAL)
 
 /*
@@ -153,13 +217,13 @@ typedef struct gpi_info {
 #define GPT_L0_IDX_MASK(_t)		(0x3FFFFFUL >> (22U - \
 					(GPT_L0_IDX_WIDTH(_t))))
 
-/* Total number of L0 regions. */
+/* Total number of L0 regions */
 #define GPT_L0_REGION_COUNT(_t)		((GPT_L0_IDX_MASK(_t)) + 1U)
 
-/* Total size of each GPT L0 region in bytes. */
+/* Total size of each GPT L0 region in bytes */
 #define GPT_L0_REGION_SIZE		(1UL << (GPT_L0_IDX_SHIFT))
 
-/* Total size in bytes of the whole L0 table. */
+/* Total size in bytes of the whole L0 table */
 #define GPT_L0_TABLE_SIZE(_t)		((GPT_L0_REGION_COUNT(_t)) << 3U)
 
 /******************************************************************************/
@@ -173,89 +237,124 @@ typedef struct gpi_info {
  * the L0 index field above since all valid combinations of PGS (p) and L0GPTSZ
  * (s) will result in a positive width value.
  */
-#define GPT_L1_IDX_WIDTH(_p)		((GPT_S_VAL - 1U) - ((_p) + 3U))
+#define GPT_L1_IDX_WIDTH(_p)		((GPT_S_VAL - 1U) - \
+					((unsigned int)(_p) + 3U))
 
-/* Bit shift for the L1 index field. */
-#define GPT_L1_IDX_SHIFT(_p)		((_p) + 4U)
+/* Bit shift for the L1 index field */
+#define GPT_L1_IDX_SHIFT(_p)		((unsigned int)(_p) + 4U)
 
 /*
  * Mask for the L1 index field, must be shifted.
  *
  * The value 0x7FFFFF is 23 bits wide and is the maximum possible width of the
  * L1 index within a physical address. It is calculated by
- * ((s_max - 1) - (p_min + 4) + 1) where s_max is 39 for 512gb, the largest
+ * ((s_max - 1) - (p_min + 4) + 1) where s_max is 39 for 512GB, the largest
  * L0GPTSZ, and p_min is 12 for 4KB granules, the smallest PGS.
  */
 #define GPT_L1_IDX_MASK(_p)		(0x7FFFFFUL >> (23U - \
 					(GPT_L1_IDX_WIDTH(_p))))
 
-/* Bit shift for the index of the L1 GPI in a PA. */
+/* Bit shift for the index of the L1 GPI in a PA */
 #define GPT_L1_GPI_IDX_SHIFT(_p)	(_p)
 
-/* Mask for the index of the L1 GPI in a PA. */
+/* Mask for the index of the L1 GPI in a PA */
 #define GPT_L1_GPI_IDX_MASK		(0xF)
 
-/* Total number of entries in each L1 table. */
-#define GPT_L1_ENTRY_COUNT(_p)		((GPT_L1_IDX_MASK(_p)) + 1U)
+/* Total number of entries in each L1 table */
+#define GPT_L1_ENTRY_COUNT(_p)		((GPT_L1_IDX_MASK(_p)) + 1UL)
+
+/* Number of L1 entries in 2MB block */
+#define GPT_L1_ENTRY_COUNT_2MB(_p)	(SZ_2M >> GPT_L1_IDX_SHIFT(_p))
 
-/* Total size in bytes of each L1 table. */
+/* Total size in bytes of each L1 table */
 #define GPT_L1_TABLE_SIZE(_p)		((GPT_L1_ENTRY_COUNT(_p)) << 3U)
 
 /******************************************************************************/
 /* General helper macros                                                      */
 /******************************************************************************/
 
-/* Protected space actual size in bytes. */
-#define GPT_PPS_ACTUAL_SIZE(_t)	(1UL << (_t))
+/* Protected space actual size in bytes */
+#define GPT_PPS_ACTUAL_SIZE(_t)	(1UL << (unsigned int)(_t))
 
-/* Granule actual size in bytes. */
-#define GPT_PGS_ACTUAL_SIZE(_p)	(1UL << (_p))
+/* Granule actual size in bytes */
+#define GPT_PGS_ACTUAL_SIZE(_p)	(1UL << (unsigned int)(_p))
 
-/* L0 GPT region size in bytes. */
+/* Number of granules in 2MB block */
+#define GPT_PGS_COUNT_2MB(_p)	(1UL << (21U - (unsigned int)(_p)))
+
+/* L0 GPT region size in bytes */
 #define GPT_L0GPTSZ_ACTUAL_SIZE	(1UL << GPT_S_VAL)
 
-/* Get the index of the L0 entry from a physical address. */
+/* Get the index of the L0 entry from a physical address */
 #define GPT_L0_IDX(_pa)		((_pa) >> GPT_L0_IDX_SHIFT)
 
 /*
  * This definition is used to determine if a physical address lies on an L0
  * region boundary.
  */
-#define GPT_IS_L0_ALIGNED(_pa)	(((_pa) & (GPT_L0_REGION_SIZE - U(1))) == U(0))
+#define GPT_IS_L0_ALIGNED(_pa)	\
+	(((_pa) & (GPT_L0_REGION_SIZE - UL(1))) == UL(0))
 
-/* Get the type field from an L0 descriptor. */
+/* Get the type field from an L0 descriptor */
 #define GPT_L0_TYPE(_desc)	(((_desc) >> GPT_L0_TYPE_SHIFT) & \
 				GPT_L0_TYPE_MASK)
 
-/* Create an L0 block descriptor. */
+/* Create an L0 block descriptor */
 #define GPT_L0_BLK_DESC(_gpi)	(GPT_L0_TYPE_BLK_DESC | \
 				(((_gpi) & GPT_L0_BLK_DESC_GPI_MASK) << \
 				GPT_L0_BLK_DESC_GPI_SHIFT))
 
-/* Create an L0 table descriptor with an L1 table address. */
+/* Create an L0 table descriptor with an L1 table address */
 #define GPT_L0_TBL_DESC(_pa)	(GPT_L0_TYPE_TBL_DESC | ((uint64_t)(_pa) & \
 				(GPT_L0_TBL_DESC_L1ADDR_MASK << \
 				GPT_L0_TBL_DESC_L1ADDR_SHIFT)))
 
-/* Get the GPI from an L0 block descriptor. */
+/* Get the GPI from an L0 block descriptor */
 #define GPT_L0_BLKD_GPI(_desc)	(((_desc) >> GPT_L0_BLK_DESC_GPI_SHIFT) & \
 				GPT_L0_BLK_DESC_GPI_MASK)
 
-/* Get the L1 address from an L0 table descriptor. */
+/* Get the L1 address from an L0 table descriptor */
 #define GPT_L0_TBLD_ADDR(_desc)	((uint64_t *)(((_desc) & \
 				(GPT_L0_TBL_DESC_L1ADDR_MASK << \
 				GPT_L0_TBL_DESC_L1ADDR_SHIFT))))
 
-/* Get the index into the L1 table from a physical address. */
-#define GPT_L1_IDX(_p, _pa)	(((_pa) >> GPT_L1_IDX_SHIFT(_p)) & \
-				GPT_L1_IDX_MASK(_p))
+/* Get the GPI from L1 Contiguous descriptor */
+#define GPT_L1_CONT_GPI(_desc)		\
+	(((_desc) >> GPT_L1_CONT_DESC_GPI_SHIFT) & GPT_L1_CONT_DESC_GPI_MASK)
+
+/* Get the GPI from L1 Granules descriptor */
+#define GPT_L1_GRAN_GPI(_desc)	((_desc) & GPT_L1_GRAN_DESC_GPI_MASK)
+
+/* Get the Contig from L1 Contiguous descriptor */
+#define GPT_L1_CONT_CONTIG(_desc)	\
+	(((_desc) >> GPT_L1_CONT_DESC_CONTIG_SHIFT) & \
+					GPT_L1_CONT_DESC_CONTIG_MASK)
+
+/* Get the index into the L1 table from a physical address */
+#define GPT_L1_IDX(_p, _pa)		\
+	(((_pa) >> GPT_L1_IDX_SHIFT(_p)) & GPT_L1_IDX_MASK(_p))
+
+/* Get the index of the GPI within an L1 table entry from a physical address */
+#define GPT_L1_GPI_IDX(_p, _pa)		\
+	(((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & GPT_L1_GPI_IDX_MASK)
+
+/* Determine if an address is granule-aligned */
+#define GPT_IS_L1_ALIGNED(_p, _pa)	\
+	(((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - UL(1))) == UL(0))
+
+/* Get aligned addresses */
+#define ALIGN_2MB(_addr)	((_addr) & ~(SZ_2M - 1UL))
+#define ALIGN_32MB(_addr)	((_addr) & ~(SZ_32M - 1UL))
+#define ALIGN_512MB(_addr)	((_addr) & ~(SZ_512M - 1UL))
+
+/* Determine if region is contiguous */
+#define GPT_REGION_IS_CONT(_len, _addr, _size)	\
+	(((_len) >= (_size)) && (((_addr) & ((_size) - UL(1))) == UL(0)))
 
-/* Get the index of the GPI within an L1 table entry from a physical address. */
-#define GPT_L1_GPI_IDX(_p, _pa)	(((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & \
-				GPT_L1_GPI_IDX_MASK)
+/* Get 32MB block number in 512MB block: 0-15 */
+#define GET_32MB_NUM(_addr)	((_addr >> 25) & 0xF)
 
-/* Determine if an address is granule-aligned. */
-#define GPT_IS_L1_ALIGNED(_p, _pa) (((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - U(1))) \
-				   == U(0))
+/* Get 2MB block number in 32MB block: 0-15 */
+#define GET_2MB_NUM(_addr)	((_addr >> 21) & 0xF)
 
 #endif /* GPT_RME_PRIVATE_H */
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
index 95da68c7..03e1fb31 100644
--- a/lib/libc/libc.mk
+++ b/lib/libc/libc.mk
@@ -1,42 +1,11 @@
 #
-# Copyright (c) 2016-2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
+#
 
-LIBC_SRCS	:=	$(addprefix lib/libc/,		\
-			abort.c				\
-			assert.c			\
-			exit.c				\
-			memchr.c			\
-			memcmp.c			\
-			memcpy.c			\
-			memcpy_s.c			\
-			memmove.c			\
-			memrchr.c			\
-			memset.c			\
-			printf.c			\
-			putchar.c			\
-			puts.c				\
-			snprintf.c			\
-			strchr.c			\
-			strcmp.c			\
-			strlcat.c			\
-			strlcpy.c			\
-			strlen.c			\
-			strncmp.c			\
-			strnlen.c			\
-			strrchr.c			\
-			strtok.c			\
-			strtoul.c			\
-			strtoll.c			\
-			strtoull.c			\
-			strtol.c)
-
-ifeq (${ARCH},aarch64)
-LIBC_SRCS	+=	$(addprefix lib/libc/aarch64/,	\
-			setjmp.S)
-endif
+include lib/libc/libc_common.mk
 
-INCLUDES	+=	-Iinclude/lib/libc		\
-			-Iinclude/lib/libc/$(ARCH)	\
+LIBC_SRCS	+=	$(addprefix lib/libc/,		\
+			memset.c)
diff --git a/lib/libc/libc_asm.mk b/lib/libc/libc_asm.mk
index 2f272651..6d9bb9de 100644
--- a/lib/libc/libc_asm.mk
+++ b/lib/libc/libc_asm.mk
@@ -1,44 +1,15 @@
 #
-# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-LIBC_SRCS	:=	$(addprefix lib/libc/,		\
-			abort.c				\
-			assert.c			\
-			exit.c				\
-			memchr.c			\
-			memcmp.c			\
-			memcpy.c			\
-			memmove.c			\
-			memrchr.c			\
-			printf.c			\
-			putchar.c			\
-			puts.c				\
-			snprintf.c			\
-			strchr.c			\
-			strcmp.c			\
-			strlcat.c			\
-			strlcpy.c			\
-			strlen.c			\
-			strncmp.c			\
-			strnlen.c			\
-			strrchr.c			\
-			strtok.c			\
-			strtoul.c			\
-			strtoll.c			\
-			strtoull.c			\
-			strtol.c)
+include lib/libc/libc_common.mk
 
 ifeq (${ARCH},aarch64)
 LIBC_SRCS	+=	$(addprefix lib/libc/aarch64/,	\
-			memset.S			\
-			setjmp.S)
+			memset.S)
 else
 LIBC_SRCS	+=	$(addprefix lib/libc/aarch32/,	\
 			memset.S)
 endif
-
-INCLUDES	+=	-Iinclude/lib/libc		\
-			-Iinclude/lib/libc/$(ARCH)	\
diff --git a/lib/libc/libc_common.mk b/lib/libc/libc_common.mk
new file mode 100644
index 00000000..4879818d
--- /dev/null
+++ b/lib/libc/libc_common.mk
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LIBC_SRCS	:=	$(addprefix lib/libc/,		\
+			abort.c				\
+			assert.c			\
+			exit.c				\
+			memchr.c			\
+			memcmp.c			\
+			memcpy.c			\
+			memcpy_s.c			\
+			memmove.c			\
+			memrchr.c			\
+			printf.c			\
+			putchar.c			\
+			puts.c				\
+			snprintf.c			\
+			strchr.c			\
+			strcmp.c			\
+			strlcat.c			\
+			strlcpy.c			\
+			strlen.c			\
+			strncmp.c			\
+			strnlen.c			\
+			strrchr.c			\
+			strtok.c			\
+			strtoul.c			\
+			strtoll.c			\
+			strtoull.c			\
+			strtol.c)
+
+ifeq (${ARCH},aarch64)
+LIBC_SRCS	+=	$(addprefix lib/libc/aarch64/,	\
+			setjmp.S)
+endif
+
+INCLUDES	+=	-Iinclude/lib/libc		\
+			-Iinclude/lib/libc/$(ARCH)	\
+
diff --git a/lib/libc/printf.c b/lib/libc/printf.c
index 6931a7ea..a8563456 100644
--- a/lib/libc/printf.c
+++ b/lib/libc/printf.c
@@ -95,6 +95,7 @@ static int unsigned_num_print(unsigned long long int unum, unsigned int radix,
  *
  * The following padding specifiers are supported by this print
  * %0NN - Left-pad the number with 0s (NN is a decimal number)
+ * %NN - Left-pad the number with spaces (NN is a decimal number)
  *
  * The print exits on all other formats specifiers other than valid
  * combinations of the above specifiers.
@@ -182,6 +183,27 @@ loop:
 				padn = 0;
 				fmt++;
 
+				for (;;) {
+					char ch = *fmt;
+					if ((ch < '0') || (ch > '9')) {
+						goto loop;
+					}
+					padn = (padn * 10) + (ch - '0');
+					fmt++;
+				}
+				assert(0); /* Unreachable */
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+				padc = ' ';
+				padn = 0;
+
 				for (;;) {
 					char ch = *fmt;
 					if ((ch < '0') || (ch > '9')) {
diff --git a/lib/libfdt/libfdt.mk b/lib/libfdt/libfdt.mk
index 812057d3..c7f54049 100644
--- a/lib/libfdt/libfdt.mk
+++ b/lib/libfdt/libfdt.mk
@@ -1,19 +1,23 @@
 #
-# Copyright (c) 2016, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-LIBFDT_SRCS	:=	$(addprefix lib/libfdt/,	\
-			fdt.c				\
-			fdt_addresses.c			\
-			fdt_empty_tree.c		\
-			fdt_ro.c			\
-			fdt_rw.c			\
-			fdt_strerror.c			\
-			fdt_sw.c			\
-			fdt_wip.c)			\
+ifndef libfdt-mk
+        libfdt-mk := 1
 
-INCLUDES	+=	-Iinclude/lib/libfdt
+        LIBFDT_SRCS := $(addprefix lib/libfdt/, \
+                fdt.c \
+                fdt_addresses.c \
+                fdt_empty_tree.c \
+                fdt_ro.c \
+                fdt_rw.c \
+                fdt_strerror.c \
+                fdt_sw.c \
+                fdt_wip.c)
 
-$(eval $(call MAKE_LIB,fdt))
+        INCLUDES += -Iinclude/lib/libfdt
+
+        $(eval $(call MAKE_LIB,fdt))
+endif
diff --git a/lib/locks/exclusive/aarch64/spinlock.S b/lib/locks/exclusive/aarch64/spinlock.S
index 5144bf7a..77bb7fe4 100644
--- a/lib/locks/exclusive/aarch64/spinlock.S
+++ b/lib/locks/exclusive/aarch64/spinlock.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,8 @@
 
 	.globl	spin_lock
 	.globl	spin_unlock
+	.globl	bit_lock
+	.globl	bit_unlock
 
 #if USE_SPINLOCK_CAS
 #if !ARM_ARCH_AT_LEAST(8, 1)
@@ -73,3 +75,43 @@ func spin_unlock
 	stlr	wzr, [x0]
 	ret
 endfunc spin_unlock
+
+/*
+ * Atomic bit clear and set instructions require FEAT_LSE which is
+ * mandatory from Armv8.1.
+ */
+#if ARM_ARCH_AT_LEAST(8, 1)
+
+/*
+ * Acquire bitlock using atomic bit set on byte. If the original read value
+ * has the bit set, use load exclusive semantics to monitor the address and
+ * enter WFE.
+ *
+ * void bit_lock(bitlock_t *lock, uint8_t mask);
+ */
+func bit_lock
+1:	ldsetab	w1, w2, [x0]
+	tst	w2, w1
+	b.eq	2f
+	ldxrb	w2, [x0]
+	tst	w2, w1
+	b.eq	1b
+	wfe
+	b	1b
+2:
+	ret
+endfunc bit_lock
+
+/*
+ * Use atomic bit clear store-release to unconditionally clear bitlock variable.
+ * Store operation generates an event to all cores waiting in WFE when address
+ * is monitored by the global monitor.
+ *
+ * void bit_unlock(bitlock_t *lock, uint8_t mask);
+ */
+func bit_unlock
+	stclrlb	w1, [x0]
+	ret
+endfunc bit_unlock
+
+#endif /* ARM_ARCH_AT_LEAST(8, 1) */
diff --git a/lib/pmf/pmf_smc.c b/lib/pmf/pmf_smc.c
index f3dd1127..ac7f53a8 100644
--- a/lib/pmf/pmf_smc.c
+++ b/lib/pmf/pmf_smc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,7 +36,8 @@ uintptr_t pmf_smc_handler(unsigned int smc_fid,
 		x2 = (uint32_t)x2;
 		x3 = (uint32_t)x3;
 
-		if (smc_fid == PMF_SMC_GET_TIMESTAMP_32) {
+		if (smc_fid == PMF_SMC_GET_TIMESTAMP_32 ||
+		   smc_fid == PMF_SMC_GET_TIMESTAMP_32_DEP) {
 			/*
 			 * Return error code and the captured
 			 * time-stamp to the caller.
@@ -48,8 +49,13 @@ uintptr_t pmf_smc_handler(unsigned int smc_fid,
 			SMC_RET3(handle, rc, (uint32_t)ts_value,
 					(uint32_t)(ts_value >> 32));
 		}
+
+		if (smc_fid == PMF_SMC_GET_VERSION_32) {
+			SMC_RET2(handle, SMC_OK, PMF_SMC_VERSION);
+		}
 	} else {
-		if (smc_fid == PMF_SMC_GET_TIMESTAMP_64) {
+		if (smc_fid == PMF_SMC_GET_TIMESTAMP_64 ||
+		    smc_fid == PMF_SMC_GET_TIMESTAMP_64_DEP) {
 			/*
 			 * Return error code and the captured
 			 * time-stamp to the caller.
@@ -60,6 +66,10 @@ uintptr_t pmf_smc_handler(unsigned int smc_fid,
 					(unsigned int)x3, &ts_value);
 			SMC_RET2(handle, rc, ts_value);
 		}
+
+		if (smc_fid == PMF_SMC_GET_VERSION_64) {
+			SMC_RET2(handle, SMC_OK, PMF_SMC_VERSION);
+		}
 	}
 
 	WARN("Unimplemented PMF Call: 0x%x \n", smc_fid);
diff --git a/lib/psa/cca_attestation.c b/lib/psa/cca_attestation.c
new file mode 100644
index 00000000..9e9e0c11
--- /dev/null
+++ b/lib/psa/cca_attestation.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <psa/crypto_sizes.h>
+#include <psa/crypto_types.h>
+#include <psa/crypto_values.h>
+
+#include <cca_attestation.h>
+#include <delegated_attestation.h>
+#include <services/rmmd_svc.h>
+
+psa_status_t
+cca_attestation_get_realm_key(uintptr_t buf, size_t *len, unsigned int type)
+{
+	size_t dak_len;
+	psa_status_t ret = PSA_SUCCESS;
+
+	/*
+	 * Current RMM implementations only support the public key size for
+	 * ECC-P384, i.e. ATTEST_KEY_CURVE_ECC_SECP384R1 attestation key.
+	 *
+	 * This ECC key has following properties:
+	 * ecc_curve:	0x12 (PSA_ECC_FAMILY_SECP_R1)
+	 * key_bits:	384
+	 * hash_alg:	0x02000009 (PSA_ALG_SHA_256)
+	 */
+	assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
+
+	ret = rse_delegated_attest_get_delegated_key(PSA_ECC_FAMILY_SECP_R1,
+						     384, (uint8_t *)buf, *len,
+						     &dak_len, PSA_ALG_SHA_256);
+	if (ret != PSA_SUCCESS) {
+		return ret;
+	}
+
+	if (dak_len != PSA_BITS_TO_BYTES(384)) {
+		return PSA_ERROR_INVALID_ARGUMENT;
+	}
+
+	*len = dak_len;
+
+	return ret;
+}
+
+psa_status_t
+cca_attestation_get_plat_token(uintptr_t buf, size_t *len,
+			       uintptr_t hash, size_t hash_size)
+{
+	size_t token_len = 0;
+	psa_status_t ret = PSA_SUCCESS;
+
+	ret = rse_delegated_attest_get_token((const uint8_t *)hash, hash_size,
+					     (uint8_t *)buf, *len, &token_len);
+	if (ret != PSA_SUCCESS) {
+		return ret;
+	}
+
+	*len = token_len;
+
+	return ret;
+}
diff --git a/lib/psa/delegated_attestation.c b/lib/psa/delegated_attestation.c
index 81e26215..805a9416 100644
--- a/lib/psa/delegated_attestation.c
+++ b/lib/psa/delegated_attestation.c
@@ -10,7 +10,7 @@
 #include <psa_manifest/sid.h>
 
 psa_status_t
-rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
+rse_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
 				       uint32_t  key_bits,
 				       uint8_t  *key_buf,
 				       size_t    key_buf_size,
@@ -31,8 +31,8 @@ rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
 		return PSA_ERROR_INVALID_ARGUMENT;
 	}
 
-	status = psa_call(RSS_DELEGATED_SERVICE_HANDLE,
-			  RSS_DELEGATED_ATTEST_GET_DELEGATED_KEY,
+	status = psa_call(RSE_DELEGATED_SERVICE_HANDLE,
+			  RSE_DELEGATED_ATTEST_GET_DELEGATED_KEY,
 			  in_vec,  IOVEC_LEN(in_vec),
 			  out_vec, IOVEC_LEN(out_vec));
 	if (status == PSA_SUCCESS) {
@@ -43,7 +43,7 @@ rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
 }
 
 psa_status_t
-rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
+rse_delegated_attest_get_token(const uint8_t *dak_pub_hash,
 			       size_t         dak_pub_hash_size,
 			       uint8_t       *token_buf,
 			       size_t         token_buf_size,
@@ -61,8 +61,8 @@ rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
 		return PSA_ERROR_INVALID_ARGUMENT;
 	}
 
-	status = psa_call(RSS_DELEGATED_SERVICE_HANDLE,
-			  RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN,
+	status = psa_call(RSE_DELEGATED_SERVICE_HANDLE,
+			  RSE_DELEGATED_ATTEST_GET_PLATFORM_TOKEN,
 			  in_vec, IOVEC_LEN(in_vec),
 			  out_vec, IOVEC_LEN(out_vec));
 	if (status == PSA_SUCCESS) {
diff --git a/lib/psa/dice_protection_environment.c b/lib/psa/dice_protection_environment.c
new file mode 100644
index 00000000..21456117
--- /dev/null
+++ b/lib/psa/dice_protection_environment.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <qcbor/qcbor_decode.h>
+#include <qcbor/qcbor_encode.h>
+#include <qcbor/qcbor_spiffy_decode.h>
+
+#include <common/debug.h>
+#include <dice.h>
+#include <dice_protection_environment.h>
+#include <psa/client.h>
+#include <psa_manifest/sid.h>
+
+enum dpe_command_id_t {
+	/* Standard commands */
+	DPE_GET_PROFILE = 1,
+	DPE_OPEN_SESSION = 2,
+	DPE_CLOSE_SESSION = 3,
+	DPE_SYNC_SESSION = 4,
+	DPE_EXPORT_SESSION = 5,
+	DPE_IMPORT_SESSION = 6,
+	DPE_INITIALIZE_CONTEXT = 7,
+	DPE_DERIVE_CONTEXT = 8,
+	DPE_CERTIFY_KEY = 9,
+	DPE_SIGN = 10,
+	DPE_SEAL = 11,
+	DPE_UNSEAL = 12,
+	DPE_DERIVE_SEALING_PUBLIC_KEY = 13,
+	DPE_ROTATE_CONTEXT_HANDLE = 14,
+	DPE_DESTROY_CONTEXT = 15,
+};
+
+enum dice_input_labels_t {
+	DICE_CODE_HASH = 1,
+	DICE_CODE_DESCRIPTOR = 2,
+	DICE_CONFIG_TYPE = 3,
+	DICE_CONFIG_VALUE = 4,
+	DICE_CONFIG_DESCRIPTOR = 5,
+	DICE_AUTHORITY_HASH = 6,
+	DICE_AUTHORITY_DESCRIPTOR = 7,
+	DICE_MODE = 8,
+	DICE_HIDDEN = 9,
+};
+
+enum dpe_derive_context_input_labels_t {
+	DPE_DERIVE_CONTEXT_CONTEXT_HANDLE = 1,
+	DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT = 2,
+	DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE = 3,
+	DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE = 4,
+	DPE_DERIVE_CONTEXT_NEW_SESSION_INITIATOR_HANDSHAKE = 5,
+	DPE_DERIVE_CONTEXT_INPUT_DATA = 6,
+	DPE_DERIVE_CONTEXT_INTERNAL_INPUTS = 7,
+	DPE_DERIVE_CONTEXT_TARGET_LOCALITY = 8,
+	DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE = 9,
+	DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT = 10,
+	DPE_DERIVE_CONTEXT_EXPORT_CDI = 11,
+	/* enum values 256 and onwards are reserved for custom arguments */
+	DPE_DERIVE_CONTEXT_CERT_ID = 256,
+};
+
+enum dpe_derive_context_output_labels_t {
+	DPE_DERIVE_CONTEXT_NEW_CONTEXT_HANDLE = 1,
+	DPE_DERIVE_CONTEXT_NEW_SESSION_RESPONDER_HANDSHAKE = 2,
+	DPE_DERIVE_CONTEXT_PARENT_CONTEXT_HANDLE = 3,
+	DPE_DERIVE_CONTEXT_NEW_CERTIFICATE = 4,
+	DPE_DERIVE_CONTEXT_EXPORTED_CDI = 5,
+};
+
+struct derive_context_input_t {
+	int context_handle;
+	uint32_t cert_id;
+	bool retain_parent_context;
+	bool allow_new_context_to_derive;
+	bool create_certificate;
+	const DiceInputValues *dice_inputs;
+	int32_t target_locality;
+	bool return_certificate;
+	bool allow_new_context_to_export;
+	bool export_cdi;
+};
+
+struct derive_context_output_t {
+	int new_context_handle;
+	int new_parent_context_handle;
+	const uint8_t *new_certificate;
+	size_t new_certificate_size;
+	const uint8_t *exported_cdi;
+	size_t exported_cdi_size;
+};
+
+static void encode_dice_inputs(QCBOREncodeContext *encode_ctx,
+			       const DiceInputValues *input)
+{
+	/* Wrap the DICE inputs into a byte string */
+	QCBOREncode_BstrWrapInMapN(encode_ctx, DPE_DERIVE_CONTEXT_INPUT_DATA);
+
+	/* Inside the byte string the DICE inputs are encoded as a map */
+	QCBOREncode_OpenMap(encode_ctx);
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CODE_HASH,
+				  (UsefulBufC) { input->code_hash,
+						 sizeof(input->code_hash) });
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CODE_DESCRIPTOR,
+				   (UsefulBufC) { input->code_descriptor,
+						  input->code_descriptor_size });
+
+	QCBOREncode_AddInt64ToMapN(encode_ctx, DICE_CONFIG_TYPE,
+				   input->config_type);
+
+	if (input->config_type == kDiceConfigTypeInline) {
+		QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CONFIG_VALUE,
+					   (UsefulBufC) { input->config_value,
+							  sizeof(input->config_value) });
+	} else {
+		QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CONFIG_DESCRIPTOR,
+					   (UsefulBufC) { input->config_descriptor,
+							  input->config_descriptor_size });
+	}
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_AUTHORITY_HASH,
+				   (UsefulBufC) { input->authority_hash,
+						  sizeof(input->authority_hash) });
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_AUTHORITY_DESCRIPTOR,
+				   (UsefulBufC) { input->authority_descriptor,
+						  input->authority_descriptor_size });
+
+	QCBOREncode_AddInt64ToMapN(encode_ctx, DICE_MODE, input->mode);
+
+	QCBOREncode_AddBytesToMapN(encode_ctx, DICE_HIDDEN,
+				   (UsefulBufC) { input->hidden,
+						  sizeof(input->hidden) });
+
+	QCBOREncode_CloseMap(encode_ctx);
+	QCBOREncode_CloseBstrWrap2(encode_ctx, true, NULL);
+}
+
+static QCBORError encode_derive_context(const struct derive_context_input_t *args,
+					UsefulBuf buf,
+					UsefulBufC *encoded_buf)
+{
+	QCBOREncodeContext encode_ctx;
+
+	QCBOREncode_Init(&encode_ctx, buf);
+
+	QCBOREncode_OpenArray(&encode_ctx);
+	QCBOREncode_AddUInt64(&encode_ctx, DPE_DERIVE_CONTEXT);
+
+	/* Encode DeriveContext command */
+	QCBOREncode_OpenMap(&encode_ctx);
+	QCBOREncode_AddBytesToMapN(&encode_ctx,
+				   DPE_DERIVE_CONTEXT_CONTEXT_HANDLE,
+				   (UsefulBufC) { &args->context_handle,
+						  sizeof(args->context_handle) });
+	QCBOREncode_AddUInt64ToMapN(&encode_ctx,
+				    DPE_DERIVE_CONTEXT_CERT_ID,
+				    args->cert_id);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT,
+				  args->retain_parent_context);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE,
+				  args->allow_new_context_to_derive);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE,
+				  args->create_certificate);
+	encode_dice_inputs(&encode_ctx, args->dice_inputs);
+	QCBOREncode_AddBytesToMapN(&encode_ctx,
+				   DPE_DERIVE_CONTEXT_TARGET_LOCALITY,
+				   (UsefulBufC) { &args->target_locality,
+						  sizeof(args->target_locality) });
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE,
+				  args->return_certificate);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT,
+				  args->allow_new_context_to_export);
+	QCBOREncode_AddBoolToMapN(&encode_ctx,
+				  DPE_DERIVE_CONTEXT_EXPORT_CDI,
+				  args->export_cdi);
+	QCBOREncode_CloseMap(&encode_ctx);
+
+	QCBOREncode_CloseArray(&encode_ctx);
+
+	return QCBOREncode_Finish(&encode_ctx, encoded_buf);
+}
+
+static QCBORError decode_derive_context_response(UsefulBufC encoded_buf,
+						 struct derive_context_output_t *args,
+						 dpe_error_t *dpe_err)
+{
+	QCBORDecodeContext decode_ctx;
+	UsefulBufC out;
+	int64_t response_dpe_err;
+
+	QCBORDecode_Init(&decode_ctx, encoded_buf, QCBOR_DECODE_MODE_NORMAL);
+
+	QCBORDecode_EnterArray(&decode_ctx, NULL);
+
+	/* Get the error code from the response. DPE returns int32_t */
+	QCBORDecode_GetInt64(&decode_ctx, &response_dpe_err);
+	*dpe_err = (dpe_error_t)response_dpe_err;
+
+	/* Decode DeriveContext response if successful */
+	if (*dpe_err == DPE_NO_ERROR) {
+		QCBORDecode_EnterMap(&decode_ctx, NULL);
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_NEW_CONTEXT_HANDLE,
+						&out);
+		if (out.len != sizeof(args->new_context_handle)) {
+			return QCBORDecode_Finish(&decode_ctx);
+		}
+		memcpy(&args->new_context_handle, out.ptr, out.len);
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_PARENT_CONTEXT_HANDLE,
+						&out);
+		if (out.len != sizeof(args->new_parent_context_handle)) {
+			return QCBORDecode_Finish(&decode_ctx);
+		}
+		memcpy(&args->new_parent_context_handle, out.ptr, out.len);
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_NEW_CERTIFICATE,
+						&out);
+		args->new_certificate = out.ptr;
+		args->new_certificate_size = out.len;
+
+		QCBORDecode_GetByteStringInMapN(&decode_ctx,
+						DPE_DERIVE_CONTEXT_EXPORTED_CDI,
+						&out);
+		args->exported_cdi = out.ptr;
+		args->exported_cdi_size = out.len;
+
+		QCBORDecode_ExitMap(&decode_ctx);
+	}
+
+	QCBORDecode_ExitArray(&decode_ctx);
+
+	return QCBORDecode_Finish(&decode_ctx);
+}
+
+static int32_t dpe_client_call(const char *cmd_input, size_t cmd_input_size,
+			       char *cmd_output, size_t *cmd_output_size)
+{
+	int32_t err;
+
+	psa_invec in_vec[] = {
+		{ cmd_input, cmd_input_size },
+	};
+	psa_outvec out_vec[] = {
+		{ cmd_output, *cmd_output_size },
+	};
+
+	err = psa_call(RSE_DPE_SERVICE_HANDLE, 0,
+			in_vec, IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
+
+	if (err == PSA_SUCCESS) {
+		*cmd_output_size = out_vec[0].len;
+	}
+
+	return err;
+}
+
+dpe_error_t dpe_derive_context(int context_handle,
+			       uint32_t cert_id,
+			       bool retain_parent_context,
+			       bool allow_new_context_to_derive,
+			       bool create_certificate,
+			       const DiceInputValues *dice_inputs,
+			       int32_t target_locality,
+			       bool return_certificate,
+			       bool allow_new_context_to_export,
+			       bool export_cdi,
+			       int *new_context_handle,
+			       int *new_parent_context_handle,
+			       uint8_t *new_certificate_buf,
+			       size_t new_certificate_buf_size,
+			       size_t *new_certificate_actual_size,
+			       uint8_t *exported_cdi_buf,
+			       size_t exported_cdi_buf_size,
+			       size_t *exported_cdi_actual_size)
+{
+	int32_t service_err;
+	dpe_error_t dpe_err;
+	QCBORError qcbor_err;
+	UsefulBufC encoded_buf;
+	UsefulBuf_MAKE_STACK_UB(cmd_buf, 612);
+
+	const struct derive_context_input_t in_args = {
+		context_handle,
+		cert_id,
+		retain_parent_context,
+		allow_new_context_to_derive,
+		create_certificate,
+		dice_inputs,
+		target_locality,
+		return_certificate,
+		allow_new_context_to_export,
+		export_cdi,
+	};
+	struct derive_context_output_t out_args;
+
+	/*
+	 * Validate the output params here because they are not sent to the
+	 * service. Input params are validated by the DPE service.
+	 */
+	if ((new_context_handle == NULL) ||
+	    (retain_parent_context == true && new_parent_context_handle == NULL) ||
+	    (return_certificate == true &&
+		(new_certificate_buf == NULL || new_certificate_actual_size == NULL)) ||
+	    (export_cdi == true &&
+		(exported_cdi_buf == NULL || exported_cdi_actual_size == NULL))) {
+		return DPE_INVALID_ARGUMENT;
+	}
+
+	qcbor_err = encode_derive_context(&in_args, cmd_buf, &encoded_buf);
+	if (qcbor_err != QCBOR_SUCCESS) {
+		return DPE_INTERNAL_ERROR;
+	}
+
+	service_err = dpe_client_call(encoded_buf.ptr, encoded_buf.len,
+				      cmd_buf.ptr, &cmd_buf.len);
+	if (service_err != 0) {
+		return DPE_INTERNAL_ERROR;
+	}
+
+	qcbor_err = decode_derive_context_response(UsefulBuf_Const(cmd_buf),
+						   &out_args, &dpe_err);
+	if (qcbor_err != QCBOR_SUCCESS) {
+		return DPE_INTERNAL_ERROR;
+	} else if (dpe_err != DPE_NO_ERROR) {
+		return dpe_err;
+	}
+
+	/* Copy returned values into caller's memory */
+	*new_context_handle = out_args.new_context_handle;
+
+	if (retain_parent_context == true) {
+		*new_parent_context_handle = out_args.new_parent_context_handle;
+	}
+
+	if (return_certificate == true) {
+		if (out_args.new_certificate_size > new_certificate_buf_size) {
+			return DPE_INVALID_ARGUMENT;
+		}
+
+		memcpy(new_certificate_buf, out_args.new_certificate,
+			out_args.new_certificate_size);
+		*new_certificate_actual_size = out_args.new_certificate_size;
+	}
+
+	if (export_cdi == true) {
+		if (out_args.exported_cdi_size > exported_cdi_buf_size) {
+			return DPE_INVALID_ARGUMENT;
+		}
+
+		memcpy(exported_cdi_buf, out_args.exported_cdi,
+			out_args.exported_cdi_size);
+		*exported_cdi_actual_size = out_args.exported_cdi_size;
+	}
+
+	return DPE_NO_ERROR;
+}
diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c
index c359e9f8..c66b8dae 100644
--- a/lib/psa/measured_boot.c
+++ b/lib/psa/measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,6 +8,7 @@
 #include <string.h>
 
 #include <common/debug.h>
+#include <drivers/measured_boot/metadata.h>
 #include <measured_boot.h>
 #include <psa/client.h>
 #include <psa_manifest/sid.h>
@@ -61,9 +62,8 @@ static void log_measurement(uint8_t index,
 	INFO(" - locking     : %s\n", lock_measurement ? "true" : "false");
 }
 
-#if !PLAT_RSS_NOT_SUPPORTED
 psa_status_t
-rss_measured_boot_extend_measurement(uint8_t index,
+rse_measured_boot_extend_measurement(uint8_t index,
 				     const uint8_t *signer_id,
 				     size_t signer_id_size,
 				     const uint8_t *version,
@@ -115,13 +115,13 @@ rss_measured_boot_extend_measurement(uint8_t index,
 			measurement_algo, measurement_value,
 			measurement_value_size, lock_measurement);
 
-	return psa_call(RSS_MEASURED_BOOT_HANDLE,
-			RSS_MEASURED_BOOT_EXTEND,
+	return psa_call(RSE_MEASURED_BOOT_HANDLE,
+			RSE_MEASURED_BOOT_EXTEND,
 			in_vec, IOVEC_LEN(in_vec),
 			NULL, 0);
 }
 
-psa_status_t rss_measured_boot_read_measurement(uint8_t index,
+psa_status_t rse_measured_boot_read_measurement(uint8_t index,
 					uint8_t *signer_id,
 					size_t signer_id_size,
 					size_t *signer_id_len,
@@ -158,7 +158,7 @@ psa_status_t rss_measured_boot_read_measurement(uint8_t index,
 		{.base = measurement_value, .len = measurement_value_size}
 	};
 
-	status = psa_call(RSS_MEASURED_BOOT_HANDLE, RSS_MEASURED_BOOT_READ,
+	status = psa_call(RSE_MEASURED_BOOT_HANDLE, RSE_MEASURED_BOOT_READ,
 					  in_vec, IOVEC_LEN(in_vec),
 					  out_vec, IOVEC_LEN(out_vec));
 
@@ -175,47 +175,3 @@ psa_status_t rss_measured_boot_read_measurement(uint8_t index,
 
 	return status;
 }
-
-#else /* !PLAT_RSS_NOT_SUPPORTED */
-
-psa_status_t
-rss_measured_boot_extend_measurement(uint8_t index,
-				     const uint8_t *signer_id,
-				     size_t signer_id_size,
-				     const uint8_t *version,
-				     size_t version_size,
-				     uint32_t measurement_algo,
-				     const uint8_t *sw_type,
-				     size_t sw_type_size,
-				     const uint8_t *measurement_value,
-				     size_t measurement_value_size,
-				     bool lock_measurement)
-{
-	log_measurement(index, signer_id, signer_id_size,
-			version, version_size, sw_type, sw_type_size,
-			measurement_algo, measurement_value,
-			measurement_value_size, lock_measurement);
-
-	return PSA_SUCCESS;
-}
-
-psa_status_t rss_measured_boot_read_measurement(uint8_t index,
-					uint8_t *signer_id,
-					size_t signer_id_size,
-					size_t *signer_id_len,
-					uint8_t *version,
-					size_t version_size,
-					size_t *version_len,
-					uint32_t *measurement_algo,
-					uint8_t *sw_type,
-					size_t sw_type_size,
-					size_t *sw_type_len,
-					uint8_t *measurement_value,
-					size_t measurement_value_size,
-					size_t *measurement_value_len,
-					bool *is_locked)
-{
-	return PSA_SUCCESS;
-}
-
-#endif /* !PLAT_RSS_NOT_SUPPORTED */
diff --git a/lib/psa/measured_boot_private.h b/lib/psa/measured_boot_private.h
index 80d2c19f..bf2ae48a 100644
--- a/lib/psa/measured_boot_private.h
+++ b/lib/psa/measured_boot_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -10,9 +10,11 @@
 
 #include <stdint.h>
 
+#include <drivers/measured_boot/metadata.h>
+
 /* Measured boot message types that distinguish its services */
-#define RSS_MEASURED_BOOT_READ		1001U
-#define RSS_MEASURED_BOOT_EXTEND	1002U
+#define RSE_MEASURED_BOOT_READ		1001U
+#define RSE_MEASURED_BOOT_EXTEND	1002U
 
 struct measured_boot_read_iovec_in_t {
     uint8_t index;
diff --git a/lib/psa/rss_platform.c b/lib/psa/rse_platform.c
similarity index 59%
rename from lib/psa/rss_platform.c
rename to lib/psa/rse_platform.c
index 7d90bfce..7fc23820 100644
--- a/lib/psa/rss_platform.c
+++ b/lib/psa/rse_platform.c
@@ -7,24 +7,24 @@
 
 #include <psa/client.h>
 #include <psa_manifest/sid.h>
-#include <rss_crypto_defs.h>
-#include <rss_platform_api.h>
+#include <rse_crypto_defs.h>
+#include <rse_platform_api.h>
 
 psa_status_t
-rss_platform_nv_counter_increment(uint32_t counter_id)
+rse_platform_nv_counter_increment(uint32_t counter_id)
 {
 	struct psa_invec in_vec[1];
 
 	in_vec[0].base = &counter_id;
 	in_vec[0].len = sizeof(counter_id);
 
-	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
-			RSS_PLATFORM_API_ID_NV_INCREMENT,
+	return psa_call(RSE_PLATFORM_SERVICE_HANDLE,
+			RSE_PLATFORM_API_ID_NV_INCREMENT,
 			in_vec, 1, NULL, 0);
 }
 
 psa_status_t
-rss_platform_nv_counter_read(uint32_t counter_id,
+rse_platform_nv_counter_read(uint32_t counter_id,
 		uint32_t size, uint8_t *val)
 {
 	struct psa_invec in_vec[1];
@@ -36,30 +36,30 @@ rss_platform_nv_counter_read(uint32_t counter_id,
 	out_vec[0].base = val;
 	out_vec[0].len = size;
 
-	return psa_call(RSS_PLATFORM_SERVICE_HANDLE,
-			RSS_PLATFORM_API_ID_NV_READ,
+	return psa_call(RSE_PLATFORM_SERVICE_HANDLE,
+			RSE_PLATFORM_API_ID_NV_READ,
 			in_vec, 1, out_vec, 1);
 }
 
 psa_status_t
-rss_platform_key_read(enum rss_key_id_builtin_t key, uint8_t *data,
+rse_platform_key_read(enum rse_key_id_builtin_t key, uint8_t *data,
 		size_t data_size, size_t *data_length)
 {
 	psa_status_t status;
 
-	struct rss_crypto_pack_iovec iov = {
-		.function_id = RSS_CRYPTO_EXPORT_PUBLIC_KEY_SID,
+	struct rse_crypto_pack_iovec iov = {
+		.function_id = RSE_CRYPTO_EXPORT_PUBLIC_KEY_SID,
 		.key_id = key,
 	};
 
 	psa_invec in_vec[] = {
-		{.base = &iov, .len = sizeof(struct rss_crypto_pack_iovec)},
+		{.base = &iov, .len = sizeof(struct rse_crypto_pack_iovec)},
 	};
 	psa_outvec out_vec[] = {
 		{.base = data, .len = data_size}
 	};
 
-	status = psa_call(RSS_CRYPTO_HANDLE, PSA_IPC_CALL,
+	status = psa_call(RSE_CRYPTO_HANDLE, PSA_IPC_CALL,
 			in_vec, IOVEC_LEN(in_vec),
 			out_vec, IOVEC_LEN(out_vec));
 
diff --git a/lib/psci/aarch64/psci_helpers.S b/lib/psci/aarch64/psci_helpers.S
index 3b77ab23..cca08c13 100644
--- a/lib/psci/aarch64/psci_helpers.S
+++ b/lib/psci/aarch64/psci_helpers.S
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <asm_macros.S>
 #include <assert_macros.S>
+#include <cpu_macros.S>
 #include <lib/psci/psci.h>
 #include <platform_def.h>
 
@@ -124,9 +125,8 @@ endfunc psci_do_pwrup_cache_maintenance
  * -----------------------------------------------------------------------
  */
 func psci_power_down_wfi
-#if ERRATA_A510_2684597
-	bl apply_cpu_pwr_dwn_errata
-#endif
+	apply_erratum cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597
+
 	dsb	sy		// ensure write buffer empty
 1:
 	wfi
diff --git a/lib/psci/aarch64/runtime_errata.S b/lib/psci/aarch64/runtime_errata.S
deleted file mode 100644
index 89e3e12b..00000000
--- a/lib/psci/aarch64/runtime_errata.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <asm_macros.S>
-#include <cortex_a510.h>
-#include <cpu_macros.S>
-
-/*
- * void apply_cpu_pwr_dwn_errata(void);
- *
- * This function applies various CPU errata during power down.
- */
-	.globl apply_cpu_pwr_dwn_errata
-func apply_cpu_pwr_dwn_errata
-	mov	x19, x30
-	bl      cpu_get_rev_var
-	mov	x18, x0
-
-#if ERRATA_A510_2684597
-	bl erratum_cortex_a510_2684597_wa
-#endif
-
-	ret	x19
-endfunc apply_cpu_pwr_dwn_errata
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index f9de432b..375cdbab 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,12 +8,14 @@
 #include <string.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
 #include <drivers/delay_timer.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/extensions/spe.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 
@@ -170,7 +172,8 @@ void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info)
  ******************************************************************************/
 static bool psci_is_last_cpu_to_idle_at_pwrlvl(unsigned int end_pwrlvl)
 {
-	unsigned int my_idx, lvl, parent_idx;
+	unsigned int my_idx, lvl;
+	unsigned int parent_idx = 0;
 	unsigned int cpu_start_idx, ncpus, cpu_idx;
 	plat_local_state_t local_state;
 
@@ -179,9 +182,9 @@ static bool psci_is_last_cpu_to_idle_at_pwrlvl(unsigned int end_pwrlvl)
 	}
 
 	my_idx = plat_my_core_pos();
-
-	for (lvl = PSCI_CPU_PWR_LVL; lvl <= end_pwrlvl; lvl++) {
-		parent_idx = psci_cpu_pd_nodes[my_idx].parent_node;
+	parent_idx = psci_cpu_pd_nodes[my_idx].parent_node;
+	for (lvl = PSCI_CPU_PWR_LVL + U(1); lvl < end_pwrlvl; lvl++) {
+		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 	}
 
 	cpu_start_idx = psci_non_cpu_pd_nodes[parent_idx].cpu_start_idx;
@@ -662,6 +665,8 @@ int psci_validate_state_coordination(unsigned int end_pwrlvl,
 			}
 			goto exit;
 		}
+
+		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 	}
 
 	/*
@@ -1164,6 +1169,8 @@ int psci_secondaries_brought_up(void)
  ******************************************************************************/
 void psci_pwrdown_cpu(unsigned int power_level)
 {
+	psci_do_manage_extensions();
+
 #if HW_ASSISTED_COHERENCY
 	/*
 	 * With hardware-assisted coherency, the CPU drivers only initiate the
@@ -1283,3 +1290,20 @@ bool psci_are_all_cpus_on_safe(void)
 
 	return true;
 }
+
+/*******************************************************************************
+ * This function performs architectural feature specific management.
+ * It ensures the architectural features are disabled during cpu
+ * power off/suspend operations.
+ ******************************************************************************/
+void psci_do_manage_extensions(void)
+{
+	/*
+	 * On power down we need to disable statistical profiling extensions
+	 * before exiting coherency.
+	 */
+	if (is_feat_spe_supported()) {
+		spe_stop();
+	}
+
+}
diff --git a/lib/psci/psci_lib.mk b/lib/psci/psci_lib.mk
index c71580f9..527ad3a1 100644
--- a/lib/psci/psci_lib.mk
+++ b/lib/psci/psci_lib.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -21,8 +21,7 @@ PSCI_LIB_SOURCES	:=	lib/el3_runtime/cpu_data_array.c	\
 				lib/psci/${ARCH}/psci_helpers.S
 
 ifeq (${ARCH}, aarch64)
-PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S	\
-				lib/psci/aarch64/runtime_errata.S
+PSCI_LIB_SOURCES	+=	lib/el3_runtime/aarch64/context.S
 endif
 
 ifeq (${USE_COHERENT_MEM}, 1)
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index c3ddc5af..367487ad 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -1,14 +1,13 @@
 #
-# Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-AS          = $(CROSS_COMPILE)as
-AR          = $(CROSS_COMPILE)ar
-LD          = $(CROSS_COMPILE)ld
-OC          = $(CROSS_COMPILE)objcopy
-CPP         = $(CROSS_COMPILE)cpp
+include ../../make_helpers/build-rules.mk
+include ../../make_helpers/common.mk
+include ../../make_helpers/toolchain.mk
+
 ROMLIB_GEN  = ./romlib_generator.py
 BUILD_DIR   = $(BUILD_PLAT)/romlib
 LIB_DIR     = $(BUILD_PLAT)/lib
@@ -20,20 +19,16 @@ OBJS        = $(BUILD_DIR)/jmptbl.o $(BUILD_DIR)/init.o
 MAPFILE     = $(BUILD_PLAT)/romlib/romlib.map
 
 ifneq ($(PLAT_DIR),)
-  WRAPPER_SOURCES   = $(shell $(ROMLIB_GEN) genwrappers -b $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i)
-  WRAPPER_OBJS      = $(WRAPPER_SOURCES:.s=.o)
-endif
+        WRAPPER_SOURCES = $(sort $(shell $(ROMLIB_GEN) genwrappers -b $\
+                $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i))
 
-V ?= 0
-ifeq ($(V),0)
-  Q := @
-else
-  Q :=
+        WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
 endif
 
-LDFLAGS := --gc-sections -O1
+LDFLAGS := -Wl,--gc-sections -nostdlib
+
 ifeq ($(DEBUG),1)
-   LDFLAGS += -Map=$(MAPFILE)
+   LDFLAGS += -Wl,-Map=$(MAPFILE)
 endif
 
 ifeq (${ARM_ARCH_MINOR},0)
@@ -44,55 +39,56 @@ endif
 
 .PHONY: all clean distclean
 
-all: $(BUILD_DIR)/romlib.bin $(LIB_DIR)/libwrappers.a
+all: $(BUILD_DIR)/romlib.bin $(BUILD_DIR)/romlib.ldflags $(LIB_DIR)/libwrappers.a
 
-%.o: %.s
-	@echo "  AS      $@"
-	$(Q)$(AS) $(ASFLAGS) -o $@ $<
+%.o: %.s | $$(@D)/
+	$(s)echo "  AS      $@"
+	$(q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
 
-$(BUILD_DIR)/%.o: %.s
-	@echo "  AS      $@"
-	$(Q)$(AS) $(ASFLAGS) -o $@ $<
+$(BUILD_DIR)/%.o: %.s | $$(@D)/
+	$(s)echo "  AS      $@"
+	$(q)$(aarch64-as) -c $(ASFLAGS) -o $@ $<
 
-$(BUILD_DIR)/romlib.ld: romlib.ld.S
-	@echo "  PP      $@"
-	$(Q)$(CPP) $(PPFLAGS) -o $@ romlib.ld.S
+$(BUILD_DIR)/romlib.ld: romlib.ld.S | $$(@D)/
+	$(s)echo "  PP      $@"
+	$(q)$(aarch64-cpp) -E $(PPFLAGS) -o $@ romlib.ld.S
 
-$(BUILD_DIR)/romlib.elf: $(OBJS) $(BUILD_DIR)/romlib.ld
-	@echo "  LD      $@"
-	$(Q)$(LD) -T $(BUILD_DIR)/romlib.ld -L$(LIB_DIR) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+$(BUILD_DIR)/romlib.elf: $(OBJS) $(BUILD_DIR)/romlib.ld | $$(@D)/
+	$(s)echo "  LD      $@"
+	$(q)$(aarch64-ld) -T $(BUILD_DIR)/romlib.ld -L$(LIB_DIR) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
 
-$(BUILD_DIR)/romlib.bin: $(BUILD_DIR)/romlib.elf
-	@echo "  BIN     $@"
-	$(Q)$(OC) -O binary $(BUILD_DIR)/romlib.elf $@
+$(BUILD_DIR)/romlib.bin: $(BUILD_DIR)/romlib.elf | $$(@D)/
+	$(s)echo "  BIN     $@"
+	$(q)$(aarch64-oc) -O binary $(BUILD_DIR)/romlib.elf $@
 
-$(WRAPPER_DIR)/jmpvar.s: $(BUILD_DIR)/romlib.elf
-	@echo "  VAR     $@"
-	$(Q)$(ROMLIB_GEN) genvar --output $@ $<
+$(WRAPPER_DIR)/jmpvar.s: $(BUILD_DIR)/romlib.elf | $$(@D)/
+	$(s)echo "  VAR     $@"
+	$(q)$(ROMLIB_GEN) genvar --output $@ $<
 
-$(LIB_DIR)/libwrappers.a: $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
-	@echo "  AR      $@"
-	$(Q)$(AR) -rc $@ $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
+$(LIB_DIR)/libwrappers.a: $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS) | $$(@D)/
+	$(s)echo "  AR      $@"
+	$(q)$(aarch64-ar) -rc $@ $(WRAPPER_DIR)/jmpvar.o $(WRAPPER_OBJS)
 
-$(BUILD_DIR)/jmptbl.i: ../../$(PLAT_DIR)/jmptbl.i
-	@echo "  PRE     $@"
-	$(Q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
+$(BUILD_DIR)/jmptbl.i: ../../$(PLAT_DIR)/jmptbl.i | $$(@D)/
+	$(s)echo "  PRE     $@"
+	$(q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
 
-$(BUILD_DIR)/wrappers.stamp: $(BUILD_DIR)/jmptbl.i
-	@echo "  WRP     $<"
-	$(Q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
-	@touch $@
+$(WRAPPER_SOURCES) $&: $(BUILD_DIR)/jmptbl.i | $$(@D)/
+	$(s)echo "  WRP     $<"
+	$(q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
 
-$(WRAPPER_SOURCES): $(BUILD_DIR)/wrappers.stamp
+$(WRAPPER_OBJS): $(WRAPPER_DIR)/%.o: $(WRAPPER_DIR)/%.s | $$(@D)/
 
-$(WRAPPER_OBJS): $(WRAPPER_SOURCES) $(BUILD_DIR)/wrappers.stamp
+$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i | $$(@D)/
+	$(s)echo "  TBL     $@"
+	$(q)$(ROMLIB_GEN) gentbl --output $@ --bti=$(ENABLE_BTI) $<
 
-$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i
-	@echo "  TBL     $@"
-	$(Q)$(ROMLIB_GEN) gentbl --output $@ --bti=$(ENABLE_BTI) $<
+$(BUILD_DIR)/romlib.ldflags: ../../$(PLAT_DIR)/jmptbl.i | $$(@D)/
+	$(s)echo "  LDFLAGS $@"
+	$(q)$(ROMLIB_GEN) link-flags $< > $@
 
 clean:
-	@rm -f $(BUILD_DIR)/*
+	$(q)rm -f $(BUILD_DIR)/*
 
 -include $(BUILD_DIR)/romlib.d
 -include $(BUILD_DIR)/jmptbl.d
diff --git a/lib/romlib/romlib_generator.py b/lib/romlib/romlib_generator.py
index 0682dd49..8d2e88d5 100755
--- a/lib/romlib/romlib_generator.py
+++ b/lib/romlib/romlib_generator.py
@@ -182,6 +182,22 @@ class TableGenerator(RomlibApplication):
                 template_name = "jmptbl_entry_" + item["type"] + bti + ".S"
                 output_file.write(self.build_template(template_name, item, True))
 
+class LinkArgs(RomlibApplication):
+    """ Generates the link arguments to wrap functions. """
+
+    def __init__(self, prog):
+        RomlibApplication.__init__(self, prog)
+        self.args.add_argument("file", help="Input file")
+
+    def main(self):
+        index_file_parser = IndexFileParser()
+        index_file_parser.parse(self.config.file)
+
+        fns = [item["function_name"] for item in index_file_parser.items
+               if not item["patch"] and item["type"] != "reserved"]
+
+        print(" ".join("-Wl,--wrap " + f for f in fns))
+
 class WrapperGenerator(RomlibApplication):
     """
     Generates a wrapper function for each entry in the index file except for the ones that contain
@@ -214,21 +230,19 @@ class WrapperGenerator(RomlibApplication):
             if item["type"] == "reserved" or item["patch"]:
                 continue
 
-            asm = self.config.b + "/" + item["function_name"] + ".s"
-            if self.config.list:
-                # Only listing files
-                files.append(asm)
-            else:
-                with open(asm, "w") as asm_file:
-                    # The jump instruction is 4 bytes but BTI requires and extra instruction so
-                    # this makes it 8 bytes per entry.
-                    function_offset = item_index * (8 if self.config.bti else 4)
+            if not self.config.list:
+                # The jump instruction is 4 bytes but BTI requires and extra instruction so
+                # this makes it 8 bytes per entry.
+                function_offset = item_index * (8 if self.config.bti else 4)
 
-                    item["function_offset"] = function_offset
-                    asm_file.write(self.build_template("wrapper" + bti + ".S", item))
+                item["function_offset"] = function_offset
+                files.append(self.build_template("wrapper" + bti + ".S", item))
 
         if self.config.list:
-            print(" ".join(files))
+            print(self.config.b + "/wrappers.s")
+        else:
+            with open(self.config.b + "/wrappers.s", "w") as asm_file:
+                asm_file.write("\n".join(files))
 
 class VariableGenerator(RomlibApplication):
     """ Generates the jump table global variable with the absolute address in ROM. """
@@ -258,7 +272,8 @@ class VariableGenerator(RomlibApplication):
 
 if __name__ == "__main__":
     APPS = {"genvar": VariableGenerator, "pre": IndexPreprocessor,
-            "gentbl": TableGenerator, "genwrappers": WrapperGenerator}
+            "gentbl": TableGenerator, "genwrappers": WrapperGenerator,
+            "link-flags": LinkArgs}
 
     if len(sys.argv) < 2 or sys.argv[1] not in APPS:
         print("usage: romlib_generator.py [%s] [args]" % "|".join(APPS.keys()), file=sys.stderr)
diff --git a/lib/romlib/templates/wrapper.S b/lib/romlib/templates/wrapper.S
index 734a68a2..576474a6 100644
--- a/lib/romlib/templates/wrapper.S
+++ b/lib/romlib/templates/wrapper.S
@@ -3,8 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-	.globl	${function_name}
-${function_name}:
+	.section .text.__wrap_${function_name}
+	.globl	__wrap_${function_name}
+__wrap_${function_name}:
 	ldr	x17, =jmptbl
 	mov	x16, #${function_offset}
 	ldr	x17, [x17]
diff --git a/lib/romlib/templates/wrapper_bti.S b/lib/romlib/templates/wrapper_bti.S
index ba9b11ce..0dc316cb 100644
--- a/lib/romlib/templates/wrapper_bti.S
+++ b/lib/romlib/templates/wrapper_bti.S
@@ -3,8 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-	.globl	${function_name}
-${function_name}:
+	.section .text.__wrap_${function_name}
+	.globl	__wrap_${function_name}
+__wrap_${function_name}:
 	bti	jc
 	ldr	x17, =jmptbl
 	mov	x16, #${function_offset}
diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c
index e38bf742..8d82d259 100644
--- a/lib/transfer_list/transfer_list.c
+++ b/lib/transfer_list/transfer_list.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arch.h>
 #include <assert.h>
 #include <inttypes.h>
 #include <string.h>
@@ -20,28 +21,66 @@ void transfer_list_dump(struct transfer_list_header *tl)
 	if (!tl) {
 		return;
 	}
-	NOTICE("Dump transfer list:\n");
-	NOTICE("signature  0x%x\n", tl->signature);
-	NOTICE("checksum   0x%x\n", tl->checksum);
-	NOTICE("version    0x%x\n", tl->version);
-	NOTICE("hdr_size   0x%x\n", tl->hdr_size);
-	NOTICE("alignment  0x%x\n", tl->alignment);
-	NOTICE("size       0x%x\n", tl->size);
-	NOTICE("max_size   0x%x\n", tl->max_size);
+	INFO("Dump transfer list:\n");
+	INFO("signature  0x%x\n", tl->signature);
+	INFO("checksum   0x%x\n", tl->checksum);
+	INFO("version    0x%x\n", tl->version);
+	INFO("hdr_size   0x%x\n", tl->hdr_size);
+	INFO("alignment  0x%x\n", tl->alignment);
+	INFO("size       0x%x\n", tl->size);
+	INFO("max_size   0x%x\n", tl->max_size);
+	INFO("flags      0x%x\n", tl->flags);
 	while (true) {
 		te = transfer_list_next(tl, te);
 		if (!te) {
 			break;
 		}
-		NOTICE("Entry %d:\n", i++);
-		NOTICE("tag_id     0x%x\n", te->tag_id);
-		NOTICE("hdr_size   0x%x\n", te->hdr_size);
-		NOTICE("data_size  0x%x\n", te->data_size);
-		NOTICE("data_addr  0x%lx\n",
-		(unsigned long)transfer_list_entry_data(te));
+		INFO("Entry %d:\n", i++);
+		INFO("tag_id     0x%x\n", te->tag_id);
+		INFO("hdr_size   0x%x\n", te->hdr_size);
+		INFO("data_size  0x%x\n", te->data_size);
+		INFO("data_addr  0x%lx\n",
+		     (unsigned long)transfer_list_entry_data(te));
 	}
 }
 
+/*******************************************************************************
+ * Set the handoff arguments according to the transfer list payload
+ * Return pointer to the entry point info if arguments are set properly
+ * or NULL if not
+ ******************************************************************************/
+entry_point_info_t *
+transfer_list_set_handoff_args(struct transfer_list_header *tl,
+			       entry_point_info_t *ep_info)
+{
+	struct transfer_list_entry *te = NULL;
+	void *dt = NULL;
+
+	if (!ep_info || !tl || transfer_list_check_header(tl) == TL_OPS_NON) {
+		return NULL;
+	}
+
+	te = transfer_list_find(tl, TL_TAG_FDT);
+	dt = transfer_list_entry_data(te);
+
+#ifdef __aarch64__
+	if (GET_RW(ep_info->spsr) == MODE_RW_64) {
+		ep_info->args.arg0 = (uintptr_t)dt;
+		ep_info->args.arg1 = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
+		ep_info->args.arg2 = 0;
+	} else
+#endif
+	{
+		ep_info->args.arg0 = 0;
+		ep_info->args.arg1 = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+		ep_info->args.arg2 = (uintptr_t)dt;
+	}
+
+	ep_info->args.arg3 = (uintptr_t)tl;
+
+	return ep_info;
+}
+
 /*******************************************************************************
  * Creating a transfer list in a reserved memory region specified
  * Compliant to 2.4.5 of Firmware handoff specification (v0.9)
@@ -65,9 +104,10 @@ struct transfer_list_header *transfer_list_init(void *addr, size_t max_size)
 	tl->signature = TRANSFER_LIST_SIGNATURE;
 	tl->version = TRANSFER_LIST_VERSION;
 	tl->hdr_size = sizeof(*tl);
-	tl->alignment = TRANSFER_LIST_INIT_MAX_ALIGN; // initial max align
-	tl->size = sizeof(*tl); // initial size is the size of header
+	tl->alignment = TRANSFER_LIST_INIT_MAX_ALIGN; /* initial max align */
+	tl->size = sizeof(*tl); /* initial size is the size of header */
 	tl->max_size = max_size;
+	tl->flags = TL_FLAGS_HAS_CHECKSUM;
 
 	transfer_list_update_checksum(tl);
 
@@ -77,11 +117,11 @@ struct transfer_list_header *transfer_list_init(void *addr, size_t max_size)
 /*******************************************************************************
  * Relocating a transfer list to a reserved memory region specified
  * Compliant to 2.4.6 of Firmware handoff specification (v0.9)
- * Return true on success or false on error
+ * Return pointer to the relocated transfer list or NULL on error
  ******************************************************************************/
-struct transfer_list_header *transfer_list_relocate(
-						struct transfer_list_header *tl,
-						void *addr, size_t max_size)
+struct transfer_list_header *
+transfer_list_relocate(struct transfer_list_header *tl, void *addr,
+		       size_t max_size)
 {
 	uintptr_t new_addr, align_mask, align_off;
 	struct transfer_list_header *new_tl;
@@ -101,7 +141,7 @@ struct transfer_list_header *transfer_list_relocate(
 
 	new_max_size = max_size - (new_addr - (uintptr_t)addr);
 
-	// the new space is not sufficient for the tl
+	/* the new space is not sufficient for the tl */
 	if (tl->size > new_max_size) {
 		return NULL;
 	}
@@ -120,37 +160,39 @@ struct transfer_list_header *transfer_list_relocate(
  * Compliant to 2.4.1 of Firmware handoff specification (v0.9)
  * Return transfer list operation status code
  ******************************************************************************/
-enum transfer_list_ops transfer_list_check_header(
-					const struct transfer_list_header *tl)
+enum transfer_list_ops
+transfer_list_check_header(const struct transfer_list_header *tl)
 {
 	if (!tl) {
 		return TL_OPS_NON;
 	}
 
 	if (tl->signature != TRANSFER_LIST_SIGNATURE) {
-		ERROR("Bad transfer list signature %#"PRIx32"\n",
+		ERROR("Bad transfer list signature %#" PRIx32 "\n",
 		      tl->signature);
 		return TL_OPS_NON;
 	}
 
 	if (!tl->max_size) {
-		ERROR("Bad transfer list max size %#"PRIx32"\n",
+		ERROR("Bad transfer list max size %#" PRIx32 "\n",
 		      tl->max_size);
 		return TL_OPS_NON;
 	}
 
 	if (tl->size > tl->max_size) {
-		ERROR("Bad transfer list size %#"PRIx32"\n", tl->size);
+		ERROR("Bad transfer list size %#" PRIx32 "\n", tl->size);
 		return TL_OPS_NON;
 	}
 
 	if (tl->hdr_size != sizeof(struct transfer_list_header)) {
-		ERROR("Bad transfer list header size %#"PRIx32"\n", tl->hdr_size);
+		ERROR("Bad transfer list header size %#" PRIx32 "\n",
+		      tl->hdr_size);
 		return TL_OPS_NON;
 	}
 
 	if (!transfer_list_verify_checksum(tl)) {
-		ERROR("Bad transfer list checksum %#"PRIx32"\n", tl->checksum);
+		ERROR("Bad transfer list checksum %#" PRIx32 "\n",
+		      tl->checksum);
 		return TL_OPS_NON;
 	}
 
@@ -190,14 +232,13 @@ struct transfer_list_entry *transfer_list_next(struct transfer_list_header *tl,
 
 	if (last) {
 		va = (uintptr_t)last;
-		// check if the total size overflow
-		if (add_overflow(last->hdr_size,
-			last->data_size, &sz)) {
+		/* check if the total size overflow */
+		if (add_overflow(last->hdr_size, last->data_size, &sz)) {
 			return NULL;
 		}
-		// roundup to the next entry
-		if (add_with_round_up_overflow(va, sz,
-			TRANSFER_LIST_GRANULE, &va)) {
+		/* roundup to the next entry */
+		if (add_with_round_up_overflow(va, sz, TRANSFER_LIST_GRANULE,
+					       &va)) {
 			return NULL;
 		}
 	} else {
@@ -207,9 +248,8 @@ struct transfer_list_entry *transfer_list_next(struct transfer_list_header *tl,
 	te = (struct transfer_list_entry *)va;
 
 	if (va + sizeof(*te) > tl_ev || te->hdr_size < sizeof(*te) ||
-		add_overflow(te->hdr_size, te->data_size, &sz) ||
-		add_overflow(va, sz, &ev) ||
-		ev > tl_ev) {
+	    add_overflow(te->hdr_size, te->data_size, &sz) ||
+	    add_overflow(va, sz, &ev) || ev > tl_ev) {
 		return NULL;
 	}
 
@@ -226,10 +266,6 @@ static uint8_t calc_byte_sum(const struct transfer_list_header *tl)
 	uint8_t cs = 0;
 	size_t n = 0;
 
-	if (!tl) {
-		return 0;
-	}
-
 	for (n = 0; n < tl->size; n++) {
 		cs += b[n];
 	}
@@ -245,7 +281,7 @@ void transfer_list_update_checksum(struct transfer_list_header *tl)
 {
 	uint8_t cs;
 
-	if (!tl) {
+	if (!tl || !(tl->flags & TL_FLAGS_HAS_CHECKSUM)) {
 		return;
 	}
 
@@ -262,6 +298,14 @@ void transfer_list_update_checksum(struct transfer_list_header *tl)
  ******************************************************************************/
 bool transfer_list_verify_checksum(const struct transfer_list_header *tl)
 {
+	if (!tl) {
+		return false;
+	}
+
+	if (!(tl->flags & TL_FLAGS_HAS_CHECKSUM)) {
+		return true;
+	}
+
 	return !calc_byte_sum(tl);
 }
 
@@ -284,27 +328,31 @@ bool transfer_list_set_data_size(struct transfer_list_header *tl,
 	}
 	tl_old_ev = (uintptr_t)tl + tl->size;
 
-	// calculate the old and new end of TE
-	// both must be roundup to align with TRANSFER_LIST_GRANULE
+	/*
+	 * calculate the old and new end of TE
+	 * both must be roundup to align with TRANSFER_LIST_GRANULE
+	 */
 	if (add_overflow(te->hdr_size, te->data_size, &sz) ||
-		add_with_round_up_overflow((uintptr_t)te, sz,
-		TRANSFER_LIST_GRANULE, &old_ev)) {
+	    add_with_round_up_overflow((uintptr_t)te, sz, TRANSFER_LIST_GRANULE,
+				       &old_ev)) {
 		return false;
 	}
 	if (add_overflow(te->hdr_size, new_data_size, &sz) ||
-		add_with_round_up_overflow((uintptr_t)te, sz,
-		TRANSFER_LIST_GRANULE, &new_ev)) {
+	    add_with_round_up_overflow((uintptr_t)te, sz, TRANSFER_LIST_GRANULE,
+				       &new_ev)) {
 		return false;
 	}
 
 	if (new_ev > old_ev) {
-		// move distance should be roundup
-		// to meet the requirement of TE data max alignment
-		// ensure that the increased size doesn't exceed
-		// the max size of TL
+		/*
+		 * move distance should be roundup
+		 * to meet the requirement of TE data max alignment
+		 * ensure that the increased size doesn't exceed
+		 * the max size of TL
+		 */
 		mov_dis = new_ev - old_ev;
-		if (round_up_overflow(mov_dis, 1 << tl->alignment,
-			&mov_dis) || tl->size + mov_dis > tl->max_size) {
+		if (round_up_overflow(mov_dis, 1 << tl->alignment, &mov_dis) ||
+		    tl->size + mov_dis > tl->max_size) {
 			return false;
 		}
 		ru_new_ev = old_ev + mov_dis;
@@ -316,10 +364,9 @@ bool transfer_list_set_data_size(struct transfer_list_header *tl,
 	}
 
 	if (gap >= sizeof(*dummy_te)) {
-		// create a dummy TE to fill up the gap
+		/* create a dummy TE to fill up the gap */
 		dummy_te = (struct transfer_list_entry *)new_ev;
 		dummy_te->tag_id = TL_TAG_EMPTY;
-		dummy_te->reserved0 = 0;
 		dummy_te->hdr_size = sizeof(*dummy_te);
 		dummy_te->data_size = gap - sizeof(*dummy_te);
 	}
@@ -335,13 +382,12 @@ bool transfer_list_set_data_size(struct transfer_list_header *tl,
  * Return true on success or false on error
  ******************************************************************************/
 bool transfer_list_rem(struct transfer_list_header *tl,
-			struct transfer_list_entry *te)
+		       struct transfer_list_entry *te)
 {
 	if (!tl || !te || (uintptr_t)te > (uintptr_t)tl + tl->size) {
 		return false;
 	}
 	te->tag_id = TL_TAG_EMPTY;
-	te->reserved0 = 0;
 	transfer_list_update_checksum(tl);
 	return true;
 }
@@ -352,7 +398,7 @@ bool transfer_list_rem(struct transfer_list_header *tl,
  * Return pointer to the added transfer entry or NULL on error
  ******************************************************************************/
 struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
-					      uint16_t tag_id,
+					      uint32_t tag_id,
 					      uint32_t data_size,
 					      const void *data)
 {
@@ -369,23 +415,24 @@ struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
 	tl_ev = (uintptr_t)tl + tl->size;
 	ev = tl_ev;
 
-	// skip the step 1 (optional step)
-	// new TE will be added into the tail
+	/*
+	 * skip the step 1 (optional step)
+	 * new TE will be added into the tail
+	 */
 	if (add_overflow(sizeof(*te), data_size, &sz) ||
-		add_with_round_up_overflow(ev, sz,
-		TRANSFER_LIST_GRANULE, &ev) || ev > max_tl_ev) {
+	    add_with_round_up_overflow(ev, sz, TRANSFER_LIST_GRANULE, &ev) ||
+	    ev > max_tl_ev) {
 		return NULL;
 	}
 
 	te = (struct transfer_list_entry *)tl_ev;
 	te->tag_id = tag_id;
-	te->reserved0 = 0;
 	te->hdr_size = sizeof(*te);
 	te->data_size = data_size;
 	tl->size += ev - tl_ev;
 
 	if (data) {
-		// get TE data pointer
+		/* get TE data pointer */
 		te_data = transfer_list_entry_data(te);
 		if (!te_data) {
 			return NULL;
@@ -404,10 +451,10 @@ struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
  * Compliant to 2.4.4 of Firmware handoff specification (v0.9)
  * Return pointer to the added transfer entry or NULL on error
  ******************************************************************************/
-struct transfer_list_entry *transfer_list_add_with_align(
-					struct transfer_list_header *tl,
-					uint16_t tag_id, uint32_t data_size,
-					const void *data, uint8_t alignment)
+struct transfer_list_entry *
+transfer_list_add_with_align(struct transfer_list_header *tl, uint32_t tag_id,
+			     uint32_t data_size, const void *data,
+			     uint8_t alignment)
 {
 	struct transfer_list_entry *te = NULL;
 	uintptr_t tl_ev, ev, new_tl_ev;
@@ -421,15 +468,17 @@ struct transfer_list_entry *transfer_list_add_with_align(
 	ev = tl_ev + sizeof(struct transfer_list_entry);
 
 	if (!is_aligned(ev, 1 << alignment)) {
-		// TE data address is not aligned to the new alignment
-		// fill the gap with an empty TE as a placeholder before
-		// adding the desire TE
+		/*
+		 * TE data address is not aligned to the new alignment
+		 * fill the gap with an empty TE as a placeholder before
+		 * adding the desire TE
+		 */
 		new_tl_ev = round_up(ev, 1 << alignment) -
-				sizeof(struct transfer_list_entry);
-		dummy_te_data_sz = new_tl_ev - tl_ev -
-					sizeof(struct transfer_list_entry);
+			    sizeof(struct transfer_list_entry);
+		dummy_te_data_sz =
+			new_tl_ev - tl_ev - sizeof(struct transfer_list_entry);
 		if (!transfer_list_add(tl, TL_TAG_EMPTY, dummy_te_data_sz,
-					NULL)) {
+				       NULL)) {
 			return NULL;
 		}
 	}
@@ -450,13 +499,13 @@ struct transfer_list_entry *transfer_list_add_with_align(
  * Return pointer to the found transfer entry or NULL on error
  ******************************************************************************/
 struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
-					       uint16_t tag_id)
+					       uint32_t tag_id)
 {
 	struct transfer_list_entry *te = NULL;
 
 	do {
 		te = transfer_list_next(tl, te);
-	} while (te && (te->tag_id != tag_id || te->reserved0 != 0));
+	} while (te && (te->tag_id != tag_id));
 
 	return te;
 }
diff --git a/lib/transfer_list/transfer_list.mk b/lib/transfer_list/transfer_list.mk
index 42574e85..3ec4df23 100644
--- a/lib/transfer_list/transfer_list.mk
+++ b/lib/transfer_list/transfer_list.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -15,6 +15,7 @@ TRANSFER_LIST_SOURCES	+=	$(addprefix lib/transfer_list/,	\
 
 BL31_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
 BL2_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
+BL1_SOURCES	+=	$(TRANSFER_LIST_SOURCES)
 
 endif	# TRANSFER_LIST
 
diff --git a/lib/xlat_mpu/aarch64/xlat_mpu_arch.c b/lib/xlat_mpu/aarch64/xlat_mpu_arch.c
index 5a2120bc..b462de0d 100644
--- a/lib/xlat_mpu/aarch64/xlat_mpu_arch.c
+++ b/lib/xlat_mpu/aarch64/xlat_mpu_arch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +27,7 @@ uintptr_t xlat_get_min_virt_addr_space_size(void)
 {
 	uintptr_t ret;
 
-	if (is_armv8_4_ttst_present()) {
+	if (is_feat_ttst_present()) {
 		ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
 	} else {
 		ret = MIN_VIRT_ADDR_SPACE_SIZE;
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index 4dbfc118..f2072662 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -66,7 +66,7 @@ static unsigned long long calc_physical_addr_size_bits(
  */
 static const unsigned int pa_range_bits_arr[] = {
 	PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
-	PARANGE_0101, PARANGE_0110
+	PARANGE_0101, PARANGE_0110, PARANGE_0111
 };
 
 static unsigned long long get_max_supported_pa(void)
@@ -87,7 +87,7 @@ static uintptr_t xlat_get_min_virt_addr_space_size(void)
 {
 	uintptr_t ret;
 
-	if (is_armv8_4_ttst_present())
+	if (is_feat_ttst_present())
 		ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
 	else
 		ret = MIN_VIRT_ADDR_SPACE_SIZE;
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 920754b4..b63543c9 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -248,7 +248,7 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags,
 	/* Set TTBR0 bits as well */
 	ttbr0 = (uint64_t)(uintptr_t) base_table;
 
-	if (is_armv8_2_ttcnp_present()) {
+	if (is_feat_ttcnp_present()) {
 		/* Enable CnP bit so as to share page tables with all PEs. */
 		ttbr0 |= TTBR_CNP_BIT;
 	}
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index bb6a35cf..7321fd72 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,19 +22,14 @@
  */
 bool xlat_arch_is_granule_size_supported(size_t size)
 {
-	unsigned int tgranx;
-
 	if (size == PAGE_SIZE_4KB) {
-		tgranx = read_id_aa64mmfr0_el0_tgran4_field();
 		/* MSB of TGRAN4 field will be '1' for unsupported feature */
-		return (tgranx < 8U);
+		return is_feat_tgran4K_present();
 	} else if (size == PAGE_SIZE_16KB) {
-		tgranx = read_id_aa64mmfr0_el0_tgran16_field();
-		return (tgranx >= ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED);
+		return is_feat_tgran16K_present();
 	} else if (size == PAGE_SIZE_64KB) {
-		tgranx = read_id_aa64mmfr0_el0_tgran64_field();
 		/* MSB of TGRAN64 field will be '1' for unsupported feature */
-		return (tgranx < 8U);
+		return is_feat_tgran64K_present();
 	} else {
 		return false;
 	}
@@ -114,7 +109,7 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr)
  */
 static const unsigned int pa_range_bits_arr[] = {
 	PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
-	PARANGE_0101, PARANGE_0110
+	PARANGE_0101, PARANGE_0110, PARANGE_0111
 };
 
 unsigned long long xlat_arch_get_max_supported_pa(void)
@@ -135,7 +130,7 @@ uintptr_t xlat_get_min_virt_addr_space_size(void)
 {
 	uintptr_t ret;
 
-	if (is_armv8_4_ttst_present())
+	if (is_feat_ttst_present())
 		ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
 	else
 		ret = MIN_VIRT_ADDR_SPACE_SIZE;
@@ -312,7 +307,7 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags,
 	/* Set TTBR bits as well */
 	ttbr0 = (uint64_t) base_table;
 
-	if (is_armv8_2_ttcnp_present()) {
+	if (is_feat_ttcnp_present()) {
 		/* Enable CnP bit so as to share page tables with all PEs. */
 		ttbr0 |= TTBR_CNP_BIT;
 	}
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index 3a9c0588..971dba48 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -214,7 +214,7 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
 			/* Set GP bit for block and page code entries
 			 * if BTI mechanism is implemented.
 			 */
-			if (is_armv8_5_bti_present() &&
+			if (is_feat_bti_present() &&
 			   ((attr & (MT_TYPE_MASK | MT_RW |
 				MT_EXECUTE_NEVER)) == MT_CODE)) {
 				desc |= GP;
diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c
index f3a53ccd..a3b913c2 100644
--- a/lib/xlat_tables_v2/xlat_tables_utils.c
+++ b/lib/xlat_tables_v2/xlat_tables_utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 
 #include <platform_def.h>
 
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/utils_def.h>
@@ -419,10 +420,59 @@ static int xlat_get_mem_attributes_internal(const xlat_ctx_t *ctx,
 			*attributes |= MT_USER;
 	}
 
-	uint64_t ns_bit = (desc >> NS_SHIFT) & 1U;
+	uint64_t ns_bit = (desc >> NS_SHIFT) & 1ULL;
 
-	if (ns_bit == 1U)
+#if ENABLE_RME
+	uint64_t nse_bit = (desc >> NSE_SHIFT) & 1ULL;
+	uint32_t sec_state = (uint32_t)(ns_bit | (nse_bit << 1ULL));
+
+/*
+ * =========================================================
+ *  NSE    NS  |  Output PA space
+ * =========================================================
+ *    0    0   |  Secure (if S-EL2 is present, else invalid)
+ *    0    1   |  Non-secure
+ *    1    0   |  Root
+ *    1    1   |  Realm
+ *==========================================================
+ */
+	switch (sec_state) {
+	case 0U:
+		/*
+		 * We expect to get Secure mapping on an RME system only if
+		 * S-EL2 is enabled.
+		 * Hence panic() if we hit the case without EEL2 being enabled.
+		 */
+		if ((read_scr_el3() & SCR_EEL2_BIT) == 0ULL) {
+			ERROR("A secure descriptor is not supported when"
+			      "FEAT_RME is implemented and FEAT_SEL2 is"
+			      "not enabled\n");
+			panic();
+		} else {
+			*attributes |= MT_SECURE;
+		}
+		break;
+	case 1U:
 		*attributes |= MT_NS;
+		break;
+	case 2U:
+		*attributes |= MT_ROOT;
+		break;
+	case 3U:
+		*attributes |= MT_REALM;
+		break;
+	default:
+		/* unreachable code */
+		assert(false);
+		break;
+	}
+#else /* !ENABLE_RME */
+	if (ns_bit == 1ULL) {
+		*attributes |= MT_NS;
+	} else {
+		*attributes |= MT_SECURE;
+	}
+#endif /* ENABLE_RME */
 
 	uint64_t xn_mask = xlat_arch_regime_get_xn_desc(ctx->xlat_regime);
 
diff --git a/licenses/LICENSE-APACHE-2.0.txt b/licenses/LICENSE-APACHE-2.0.txt
new file mode 100644
index 00000000..d6456956
--- /dev/null
+++ b/licenses/LICENSE-APACHE-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index a337e767..57609d51 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2022-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,65 +8,129 @@
 # and enables them based on the configured architecture version.
 
 # This file follows the following format:
-#   - Enable mandatory feature if applicable to an Arch Version.
+#   - Enable mandatory feature if not updated, as applicable to an Arch Version.
 #   - By default disable any mandatory features if they have not been defined yet.
 #   - Disable or enable any optional feature this would be enabled/disabled if needed by platform.
 
 #
 ################################################################################
-# Enable Mandatory features based on Arch versions.
+# Enable Mandatory features if not updated yet, based on Arch versions.
 ################################################################################
 #
 
 # Enable the features which are mandatory from ARCH version 8.1 and upwards.
 ifeq "8.1" "$(word 1, $(sort 8.1 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_PAN				:=	1
-ENABLE_FEAT_VHE				:=	1
+armv8-1-a-feats         := ENABLE_FEAT_PAN ENABLE_FEAT_VHE
+
+FEAT_LIST               := ${armv8-1-a-feats}
 endif
 
 # Enable the features which are mandatory from ARCH version 8.2 and upwards.
 ifeq "8.2" "$(word 1, $(sort 8.2 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_RAS				:=	1
+armv8-2-a-feats         := ENABLE_FEAT_RAS
+# 8.1 Compliant
+armv8-2-a-feats         += ${armv8-1-a-feats}
+
+FEAT_LIST               := ${armv8-2-a-feats}
+endif
+
+# Enable the features which are mandatory from ARCH version 8.3 and upwards.
+ifeq "8.3" "$(word 1, $(sort 8.3 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+# 8.2 Compliant
+armv8-3-a-feats         += ${armv8-2-a-feats}
+
+FEAT_LIST               := ${armv8-3-a-feats}
 endif
 
 # Enable the features which are mandatory from ARCH version 8.4 and upwards.
 ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_SEL2			:=	1
-ENABLE_TRF_FOR_NS			:=	1
-ENABLE_FEAT_DIT				:=	1
+armv8-4-a-feats         := ENABLE_FEAT_SEL2 ENABLE_TRF_FOR_NS ENABLE_FEAT_DIT
+# 8.3 Compliant
+armv8-4-a-feats         += ${armv8-3-a-feats}
+
+FEAT_LIST               := ${armv8-4-a-feats}
 endif
 
 # Enable the features which are mandatory from ARCH version 8.5 and upwards.
 ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_RNG				:=	1
-ENABLE_FEAT_SB				:=	1
+armv8-5-a-feats         := ENABLE_FEAT_RNG ENABLE_FEAT_SB
+# 8.4 Compliant
+armv8-5-a-feats         += ${armv8-4-a-feats}
 
+FEAT_LIST               := ${armv8-5-a-feats}
 # Enable Memory tagging, Branch Target Identification for aarch64 only.
 ifeq ($(ARCH), aarch64)
-	mem_tag_arch_support		:= 	yes
+	mem_tag_arch_support		?= 	yes
 endif #(ARCH=aarch64)
 
 endif
 
 # Enable the features which are mandatory from ARCH version 8.6 and upwards.
 ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_ECV				:=	1
-ENABLE_FEAT_FGT				:=	1
+armv8-6-a-feats         := ENABLE_FEAT_ECV ENABLE_FEAT_FGT
+# 8.5 Compliant
+armv8-6-a-feats         += ${armv8-5-a-feats}
+FEAT_LIST               := ${armv8-6-a-feats}
 endif
 
 # Enable the features which are mandatory from ARCH version 8.7 and upwards.
 ifeq "8.7" "$(word 1, $(sort 8.7 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_HCX				:=	1
+armv8-7-a-feats         := ENABLE_FEAT_HCX
+# 8.6 Compliant
+armv8-7-a-feats         += ${armv8-6-a-feats}
+FEAT_LIST               := ${armv8-7-a-feats}
+endif
+
+# Enable the features which are mandatory from ARCH version 8.8 and upwards.
+ifeq "8.8" "$(word 1, $(sort 8.8 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+# 8.7 Compliant
+armv8-8-a-feats         += ${armv8-7-a-feats}
+FEAT_LIST               := ${armv8-8-a-feats}
 endif
 
 # Enable the features which are mandatory from ARCH version 8.9 and upwards.
 ifeq "8.9" "$(word 1, $(sort 8.9 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_TCR2			:=	1
+armv8-9-a-feats         := ENABLE_FEAT_TCR2 ENABLE_FEAT_DEBUGV8P9 ENABLE_FEAT_SCTLR2
+# 8.8 Compliant
+armv8-9-a-feats         += ${armv8-8-a-feats}
+FEAT_LIST               := ${armv8-9-a-feats}
+endif
+
+# Enable the features which are mandatory from ARCH version 9.0 and upwards.
+ifeq "9.0" "$(word 1, $(sort 9.0 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+# 8.5 Compliant
+armv9-0-a-feats         += ${armv8-5-a-feats}
+FEAT_LIST               := ${armv9-0-a-feats}
+endif
+
+# Enable the features which are mandatory from ARCH version 9.1 and upwards.
+ifeq "9.1" "$(word 1, $(sort 9.1 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+# 8.6 and 9.0 Compliant
+armv9-1-a-feats         += ${armv8-6-a-feats} ${armv9-0-a-feats}
+FEAT_LIST               := ${armv9-1-a-feats}
+endif
+
+# Enable the features which are mandatory from ARCH version 9.2 and upwards.
+ifeq "9.2" "$(word 1, $(sort 9.2 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+# 8.7 and 9.1 Compliant
+armv9-2-a-feats         += ${armv8-7-a-feats} ${armv9-1-a-feats}
+FEAT_LIST               := ${armv9-2-a-feats}
 endif
 
+# Enable the features which are mandatory from ARCH version 9.3 and upwards.
+ifeq "9.3" "$(word 1, $(sort 9.3 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+# 8.8 and 9.2 Compliant
+armv9-3-a-feats         += ${armv8-8-a-feats} ${armv9-2-a-feats}
+FEAT_LIST               := ${armv9-3-a-feats}
+endif
+
+# Set all FEAT_* in FEAT_LIST to '1' if they are not yet defined or set
+# from build commandline options or platform makefile.
+$(eval $(call default_ones, ${sort ${FEAT_LIST}}))
+
 #
 ################################################################################
-# Set mandatory features by default to zero.
+# Set mandatory features by default to zero, if they are not already updated.
 ################################################################################
 #
 
@@ -155,6 +219,9 @@ ENABLE_FEAT_HCX			?=	0
 # Flag to enable access to TCR2 (FEAT_TCR2).
 ENABLE_FEAT_TCR2		?=	0
 
+# Flag to enable access to SCTLR2 (FEAT_SCTLR2).
+ENABLE_FEAT_SCTLR2		?=	0
+
 #
 ################################################################################
 # Optional Features defaulted to 0 or 2, if they are not enabled from
@@ -169,6 +236,10 @@ ENABLE_FEAT_TCR2		?=	0
 # Flag to enable CSV2_2 extension.
 ENABLE_FEAT_CSV2_2			?=	0
 
+# Flag to enable CSV2_3 extension. FEAT_CSV2_3 enables access to the
+# SCXTNUM_ELx register.
+ENABLE_FEAT_CSV2_3			?=	0
+
 # By default, disable access of trace system registers from NS lower
 # ELs  i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
 # system register trace is implemented. This feature is available if
@@ -212,7 +283,7 @@ endif
 ENABLE_FEAT_AMU				?=	0
 ENABLE_AMU_AUXILIARY_COUNTERS		?=	0
 ENABLE_AMU_FCONF			?=	0
-AMU_RESTRICT_COUNTERS			?=	0
+AMU_RESTRICT_COUNTERS			?=	1
 
 # Build option to enable MPAM for lower ELs.
 # Enabling it by default
@@ -239,10 +310,9 @@ CTX_INCLUDE_NEVE_REGS			?=	0
 # registers, by setting SCR_EL3.TRNDR.
 ENABLE_FEAT_RNG_TRAP			?=	0
 
-# Include Memory Tagging Extension registers in cpu context. This must be set
-# to 1 if the platform wants to use this feature in the Secure world and MTE is
-# enabled at ELX.
-CTX_INCLUDE_MTE_REGS			?=	0
+# Enable FEAT_MTE2. This must be set to 1 if the platform wants
+# to use this feature and is enabled at ELX.
+ENABLE_FEAT_MTE2		        ?=	0
 
 #----
 # 8.6
@@ -263,12 +333,22 @@ TWED_DELAY				?=	0
 # Disable MTPMU if FEAT_MTPMU is supported.
 DISABLE_MTPMU				?=	0
 
+# Flag to enable FEAT_FGT2 (Fine Granular Traps 2)
+ENABLE_FEAT_FGT2			?=	0
+
+# LoadStore64Bytes extension using the ACCDATA_EL1 system register
+ENABLE_FEAT_LS64_ACCDATA		?=	0
+
 #----
-# 8.9
+# 8.8
 #----
 
-# Flag to enable NoTagAccess memory region attribute for stage 2 of translation.
-ENABLE_FEAT_MTE_PERM			?=	0
+# Flag to enable FEAT_THE (Translation Hardening Extension)
+ENABLE_FEAT_THE				?=	0
+
+#----
+# 8.9
+#----
 
 # Flag to enable access to Stage 2 Permission Indirection (FEAT_S2PIE).
 ENABLE_FEAT_S2PIE			?=	0
@@ -282,13 +362,13 @@ ENABLE_FEAT_S2POE			?=	0
 # Flag to enable access to Stage 1 Permission Overlay (FEAT_S1POE).
 ENABLE_FEAT_S1POE			?=	0
 
+# Flag to enable access to Arm v8.9 Debug extension
+ENABLE_FEAT_DEBUGV8P9			?=	0
+
 #----
 # 9.0
 #----
 
-# Flag to enable Realm Management Extension (FEAT_RME).
-ENABLE_RME				?=	0
-
 # Scalable Matrix Extension for non-secure world.
 ENABLE_SME_FOR_NS			?=	0
 
@@ -314,6 +394,9 @@ endif
 # 9.2
 #----
 
+# Flag to enable Realm Management Extension (FEAT_RME).
+ENABLE_RME				?=	0
+
 # Scalable Matrix Extension version 2 for non-secure world.
 ENABLE_SME2_FOR_NS			?=	0
 
@@ -325,6 +408,12 @@ ENABLE_SME_FOR_SWD			?=	0
 # if FEAT_BRBE is implemented.
 ENABLE_BRBE_FOR_NS			?=	0
 
+#----
+# 9.3
+#----
+# Flag to enable access to Arm v9.3 FEAT_D128 extension
+ENABLE_FEAT_D128			?=	0
+
 #----
 #9.4
 #----
diff --git a/make_helpers/build-rules.mk b/make_helpers/build-rules.mk
new file mode 100644
index 00000000..d325b3a8
--- /dev/null
+++ b/make_helpers/build-rules.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifndef build-rules-mk
+        build-rules-mk := $(lastword $(MAKEFILE_LIST))
+
+        include $(dir $(build-rules-mk))common.mk
+        include $(dir $(build-rules-mk))utilities.mk
+
+        .SECONDEXPANSION:
+
+        %/:
+		$(s)echo '  MD      '$(call escape-shell,$(abspath $@))
+		$(q)mkdir -p $(call escape-shell,$@)
+endif
diff --git a/make_helpers/build_env.mk b/make_helpers/build_env.mk
index 83093bd6..13acaae4 100644
--- a/make_helpers/build_env.mk
+++ b/make_helpers/build_env.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -15,8 +15,6 @@ ifndef BUILD_ENV_MK
     COPY                :=      $$(error "Replace COPY with call to SHELL_COPY or SHELL_COPY_TREE.")
     CP                  :=      $$(error "Replace CP with call to SHELL_COPY or SHELL_COPY_TREE.")
     DEL                 :=      $$(error "Replace DEL with call to SHELL_DELETE.")
-    MD                  :=      $$(error "Replace MD with call to MAKE_PREREQ_DIR.")
-    MKDIR               :=      $$(error "Replace MKDIR with call to MAKE_PREREQ_DIR.")
     RD                  :=      $$(error "Replace RD with call to SHELL_REMOVE_DIR.")
     RM                  :=      $$(error "Replace RM with call to SHELL_DELETE.")
     RMDIR               :=      $$(error "Replace RMDIR with call to SHELL_REMOVE_DIR.")
@@ -47,7 +45,7 @@ ifndef BUILD_ENV_MK
             endif
         endif
     endif
-    include ${MAKE_HELPERS_DIRECTORY}${ENV_FILE_TO_INCLUDE}
+    include $(dir $(lastword $(MAKEFILE_LIST)))${ENV_FILE_TO_INCLUDE}
     ENV_FILE_TO_INCLUDE :=
 
     ifndef SHELL_COPY
@@ -62,9 +60,6 @@ ifndef BUILD_ENV_MK
     ifndef SHELL_DELETE
         $(error "SHELL_DELETE not defined for build environment.")
     endif
-    ifndef MAKE_PREREQ_DIR
-        $(error "MAKE_PREREQ_DIR not defined for build environment.")
-    endif
     ifndef SHELL_REMOVE_DIR
         $(error "SHELL_REMOVE_DIR not defined for build environment.")
     endif
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 71cf18b0..d454efd9 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -10,11 +10,6 @@ ifneq (${eval_available},T)
     $(error This makefile only works with a Make program that supports $$(eval))
 endif
 
-# Some utility macros for manipulating awkward (whitespace) characters.
-blank			:=
-space			:=${blank} ${blank}
-comma			:= ,
-
 # A user defined function to recursively search for a filename below a directory
 #    $1 is the directory root of the recursive search (blank for current directory).
 #    $2 is the file name to search for.
@@ -22,22 +17,6 @@ define rwildcard
 $(strip $(foreach d,$(wildcard ${1}*),$(call rwildcard,${d}/,${2}) $(filter $(subst *,%,%${2}),${d})))
 endef
 
-# This table is used in converting lower case to upper case.
-uppercase_table:=a,A b,B c,C d,D e,E f,F g,G h,H i,I j,J k,K l,L m,M n,N o,O p,P q,Q r,R s,S t,T u,U v,V w,W x,X y,Y z,Z
-
-# Internal macro used for converting lower case to upper case.
-#   $(1) = upper case table
-#   $(2) = String to convert
-define uppercase_internal
-$(if $(1),$$(subst $(firstword $(1)),$(call uppercase_internal,$(wordlist 2,$(words $(1)),$(1)),$(2))),$(2))
-endef
-
-# A macro for converting a string to upper case
-#   $(1) = String to convert
-define uppercase
-$(eval uppercase_result:=$(call uppercase_internal,$(uppercase_table),$(1)))$(uppercase_result)
-endef
-
 # Convenience function for setting a variable to 0 if not previously set
 # $(eval $(call default_zero,FOO))
 define default_zero
@@ -50,6 +29,18 @@ define default_zeros
 	$(foreach var,$1,$(eval $(call default_zero,$(var))))
 endef
 
+# Convenience function for setting a variable to 1 if not previously set
+# $(eval $(call default_one,FOO))
+define default_one
+	$(eval $(1) ?= 1)
+endef
+
+# Convenience function for setting a list of variables to 1 if not previously set
+# $(eval $(call default_ones,FOO BAR))
+define default_ones
+	$(foreach var,$1,$(eval $(call default_one,$(var))))
+endef
+
 # Convenience function for adding build definitions
 # $(eval $(call add_define,FOO)) will have:
 # -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise
@@ -101,14 +92,16 @@ endef
 
 # Convenience function to check for a given linker option. An call to
 # $(call ld_option, --no-XYZ) will return --no-XYZ if supported by the linker
-define ld_option
-	$(shell if $(LD) $(1) -v >/dev/null 2>&1; then echo $(1); fi )
-endef
+ld_option = $(shell $($(ARCH)-ld) $(1) -Wl,--version >/dev/null 2>&1 || $($(ARCH)-ld) $(1) -v >/dev/null 2>&1 && echo $(1))
 
 # Convenience function to check for a given compiler option. A call to
 # $(call cc_option, --no-XYZ) will return --no-XYZ if supported by the compiler
+# NOTE: consider assigning to an immediately expanded temporary variable before
+# assigning. This is because variables like TF_CFLAGS are recursively expanded
+# and assigning this directly will cause it to be expanded every time the
+# variable is used, potentially thrashing multicore performance.
 define cc_option
-	$(shell if $(CC) $(1) -c -x c /dev/null -o /dev/null >/dev/null 2>&1; then echo $(1); fi )
+	$(shell if $($(ARCH)-cc) $(1) -c -x c /dev/null -o /dev/null >/dev/null 2>&1; then echo $(1); fi )
 endef
 
 # CREATE_SEQ is a recursive function to create sequence of numbers from 1 to
@@ -159,8 +152,8 @@ endef
 #   $(2) = output encrypted firmware binary
 define ENCRYPT_FW
 $(2): $(1) enctool
-	$$(ECHO) "  ENC     $$<"
-	$$(Q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
+	$$(s)echo "  ENC     $$<"
+	$$(q)$$(ENCTOOL) $$(ENC_ARGS) -i $$< -o $$@
 endef
 
 # TOOL_ADD_PAYLOAD appends the command line arguments required by fiptool to
@@ -194,7 +187,7 @@ endef
 
 define TOOL_ADD_IMG_PAYLOAD
 
-$(eval PRE_TOOL_FILTER := $($(call uppercase,$(1))_PRE_TOOL_FILTER))
+$(eval PRE_TOOL_FILTER := $($(1)_PRE_TOOL_FILTER))
 
 ifneq ($(PRE_TOOL_FILTER),)
 
@@ -231,7 +224,8 @@ endef
 define TOOL_ADD_IMG
     # Build option to specify the image filename (SCP_BL2, BL33, etc)
     # This is the uppercase form of the first parameter
-    $(eval _V := $(call uppercase,$(1)))
+    $(eval BL := $(call uppercase,$(1)))
+    $(eval _V := $(BL))
 
     # $(check_$(1)_cmd) variable is executed in the check_$(1) target and also
     # is put into the ${CHECK_$(3)FIP_CMD} variable which is executed by the
@@ -246,10 +240,10 @@ define TOOL_ADD_IMG
 ifeq ($(4),1)
     $(eval ENC_BIN := ${BUILD_PLAT}/$(1)_enc.bin)
     $(call ENCRYPT_FW,$(value $(_V)),$(ENC_BIN))
-    $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(ENC_BIN),$(3), \
+    $(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(value $(_V)),$(2),$(ENC_BIN),$(3), \
 		$(ENC_BIN))
 else
-    $(call TOOL_ADD_IMG_PAYLOAD,$(1),$(value $(_V)),$(2),$(if $(wildcard $(value $(_V))),$(value $(_V)),FORCE),$(3))
+    $(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(value $(_V)),$(2),$(if $(wildcard $(value $(_V))),$(value $(_V)),FORCE),$(3))
 endif
 
 .PHONY: check_$(1)
@@ -278,8 +272,8 @@ endef
 # GZIP
 define GZIP_RULE
 $(1): $(2)
-	$(ECHO) "  GZIP    $$@"
-	$(Q)gzip -n -f -9 $$< --stdout > $$@
+	$(s)echo "  GZIP    $$@"
+	$(q)gzip -n -f -9 $$< --stdout > $$@
 endef
 
 GZIP_SUFFIX := .gz
@@ -295,14 +289,15 @@ MAKE_DEP = -Wp,-MD,$(DEP) -MT $$@ -MP
 #   $(1) = output directory
 #   $(2) = source file (%.c)
 #   $(3) = library name
+#   $(4) = uppercase name of the library
 define MAKE_C_LIB
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
-$(eval LIB := $(call uppercase, $(notdir $(1))))
+$(eval LIB := $(notdir $(1)))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
-	$$(ECHO) "  CC      $$<"
-	$$(Q)$$(CC) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
+	$$(s)echo "  CC      $$<"
+	$$(q)$($(ARCH)-cc) $$($(LIB)_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -312,13 +307,14 @@ endef
 #   $(1) = output directory
 #   $(2) = source file (%.S)
 #   $(3) = library name
+#   $(4) = uppercase name of the library
 define MAKE_S_LIB
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
-	$$(ECHO) "  AS      $$<"
-	$$(Q)$$(AS) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
+	$$(s)echo "  AS      $$<"
+	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -329,19 +325,20 @@ endef
 #   $(1) = output directory
 #   $(2) = source file (%.c)
 #   $(3) = BL stage
+#   $(4) = uppercase BL stage
 define MAKE_C
 
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
-$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
-$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
-$(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS) $(PLAT_BL_COMMON_CFLAGS))
+$(eval BL_DEFINES := IMAGE_$(4) $($(4)_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_CFLAGS := $($(4)_CFLAGS) $(PLAT_BL_COMMON_CFLAGS))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  CC      $$<"
-	$$(Q)$$(CC) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
+	$$(s)echo "  CC      $$<"
+	$$(q)$($(ARCH)-cc) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -352,19 +349,20 @@ endef
 #   $(1) = output directory
 #   $(2) = assembly file (%.S)
 #   $(3) = BL stage
+#   $(4) = uppercase BL stage
 define MAKE_S
 
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 
-$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
-$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
-$(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS) $(PLAT_BL_COMMON_ASFLAGS))
+$(eval BL_DEFINES := IMAGE_$(4) $($(4)_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_ASFLAGS := $($(4)_ASFLAGS) $(PLAT_BL_COMMON_ASFLAGS))
 
-$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  AS      $$<"
-	$$(Q)$$(AS) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
+	$$(s)echo "  AS      $$<"
+	$$(q)$($(ARCH)-as) -x assembler-with-cpp $$(TF_CFLAGS_$(ARCH)) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -375,17 +373,18 @@ endef
 #   $(1) = output linker script
 #   $(2) = input template
 #   $(3) = BL stage
+#   $(4) = uppercase BL stage
 define MAKE_LD
 
 $(eval DEP := $(1).d)
 
-$(eval BL_DEFINES := IMAGE_$(call uppercase,$(3)) $($(call uppercase,$(3))_DEFINES) $(PLAT_BL_COMMON_DEFINES))
-$(eval BL_INCLUDE_DIRS := $($(call uppercase,$(3))_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
-$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
+$(eval BL_DEFINES := IMAGE_$(4) $($(4)_DEFINES) $(PLAT_BL_COMMON_DEFINES))
+$(eval BL_INCLUDE_DIRS := $($(4)_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS))
+$(eval BL_CPPFLAGS := $($(4)_CPPFLAGS) $(addprefix -D,$(BL_DEFINES)) $(addprefix -I,$(BL_INCLUDE_DIRS)) $(PLAT_BL_COMMON_CPPFLAGS))
 
-$(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
-	$$(ECHO) "  PP      $$<"
-	$$(Q)$$(CPP) $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
+$(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
+	$$(s)echo "  PP      $$<"
+	$$(q)$($(ARCH)-cpp) -E $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
 
 -include $(DEP)
 
@@ -395,14 +394,15 @@ endef
 #   $(1) = output directory
 #   $(2) = list of source files
 #   $(3) = name of the library
+#   $(4) = uppercase name of the library
 define MAKE_LIB_OBJS
         $(eval C_OBJS := $(filter %.c,$(2)))
         $(eval REMAIN := $(filter-out %.c,$(2)))
-        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C_LIB,$(1),$(obj),$(3))))
+        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C_LIB,$(1),$(obj),$(3),$(4))))
 
         $(eval S_OBJS := $(filter %.S,$(REMAIN)))
         $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
-        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S_LIB,$(1),$(obj),$(3))))
+        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S_LIB,$(1),$(obj),$(3),$(4))))
 
         $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
 endef
@@ -412,14 +412,15 @@ endef
 #   $(1) = output directory
 #   $(2) = list of source files (both C and assembly)
 #   $(3) = BL stage
+#   $(4) = uppercase BL stage
 define MAKE_OBJS
         $(eval C_OBJS := $(filter %.c,$(2)))
         $(eval REMAIN := $(filter-out %.c,$(2)))
-        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3))))
+        $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3),$(4))))
 
         $(eval S_OBJS := $(filter %.S,$(REMAIN)))
         $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
-        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3))))
+        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3),$(4))))
 
         $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
 endef
@@ -433,41 +434,23 @@ define SOURCES_TO_OBJS
         $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
 endef
 
-# Allow overriding the timestamp, for example for reproducible builds, or to
-# synchronize timestamps across multiple projects.
-# This must be set to a C string (including quotes where applicable).
-BUILD_MESSAGE_TIMESTAMP ?= __TIME__", "__DATE__
-
 .PHONY: libraries
 
-# MAKE_LIB_DIRS macro defines the target for the directory where
-# libraries are created
-define MAKE_LIB_DIRS
-        $(eval LIB_DIR    := ${BUILD_PLAT}/lib)
-        $(eval ROMLIB_DIR    := ${BUILD_PLAT}/romlib)
-        $(eval LIBWRAPPER_DIR := ${BUILD_PLAT}/libwrapper)
-        $(eval $(call MAKE_PREREQ_DIR,${LIB_DIR},${BUILD_PLAT}))
-        $(eval $(call MAKE_PREREQ_DIR,${ROMLIB_DIR},${BUILD_PLAT}))
-        $(eval $(call MAKE_PREREQ_DIR,${LIBWRAPPER_DIR},${BUILD_PLAT}))
-endef
-
 # MAKE_LIB macro defines the targets and options to build each BL image.
 # Arguments:
 #   $(1) = Library name
 define MAKE_LIB
+        $(eval BL         := $(call uppercase,$(1)))
         $(eval BUILD_DIR  := ${BUILD_PLAT}/lib$(1))
         $(eval LIB_DIR    := ${BUILD_PLAT}/lib)
         $(eval ROMLIB_DIR    := ${BUILD_PLAT}/romlib)
-        $(eval SOURCES    := $(LIB$(call uppercase,$(1))_SRCS))
+        $(eval SOURCES    := $(LIB$(BL)_SRCS))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
 
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
-$(eval $(call MAKE_LIB_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+$(eval $(call MAKE_LIB_OBJS,$(BUILD_DIR),$(SOURCES),$(1),$(BL)))
 
-.PHONY : lib${1}_dirs
-lib${1}_dirs: | ${BUILD_DIR} ${LIB_DIR}  ${ROMLIB_DIR} ${LIBWRAPPER_DIR}
 libraries: ${LIB_DIR}/lib$(1).a
-ifneq ($(findstring armlink,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),arm-link)
 LDPATHS = --userlibpath=${LIB_DIR}
 LDLIBS += --library=$(1)
 else
@@ -481,9 +464,9 @@ endif
 
 all: ${LIB_DIR}/lib$(1).a
 
-${LIB_DIR}/lib$(1).a: $(OBJS)
-	$$(ECHO) "  AR      $$@"
-	$$(Q)$$(AR) cr $$@ $$?
+${LIB_DIR}/lib$(1).a: $(OBJS) | $$$$(@D)/
+	$$(s)echo "  AR      $$@"
+	$$(q)$($(ARCH)-ar) cr $$@ $$?
 endef
 
 # Generate the path to one or more preprocessed linker scripts given the paths
@@ -495,6 +478,10 @@ define linker_script_path
         $(patsubst %.S,$(BUILD_DIR)/%,$(1))
 endef
 
+ifeq ($(USE_ROMLIB),1)
+WRAPPER_FLAGS := @${BUILD_PLAT}/romlib/romlib.ldflags
+endif
+
 # MAKE_BL macro defines the targets and options to build each BL image.
 # Arguments:
 #   $(1) = BL stage
@@ -502,8 +489,9 @@ endef
 #   $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
 #   $(4) = BL encryption flag (optional) (0, 1)
 define MAKE_BL
+        $(eval BL         := $(call uppercase,$(1)))
         $(eval BUILD_DIR  := ${BUILD_PLAT}/$(1))
-        $(eval BL_SOURCES := $($(call uppercase,$(1))_SOURCES))
+        $(eval BL_SOURCES := $($(BL)_SOURCES))
         $(eval SOURCES    := $(sort $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES)))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
         $(eval MAPFILE    := $(call IMG_MAPFILE,$(1)))
@@ -511,94 +499,63 @@ define MAKE_BL
         $(eval DUMP       := $(call IMG_DUMP,$(1)))
         $(eval BIN        := $(call IMG_BIN,$(1)))
         $(eval ENC_BIN    := $(call IMG_ENC_BIN,$(1)))
-        $(eval BL_LIBS    := $($(call uppercase,$(1))_LIBS))
+        $(eval BL_LIBS    := $($(BL)_LIBS))
 
-        $(eval DEFAULT_LINKER_SCRIPT_SOURCE := $($(call uppercase,$(1))_DEFAULT_LINKER_SCRIPT_SOURCE))
+        $(eval DEFAULT_LINKER_SCRIPT_SOURCE := $($(BL)_DEFAULT_LINKER_SCRIPT_SOURCE))
         $(eval DEFAULT_LINKER_SCRIPT := $(call linker_script_path,$(DEFAULT_LINKER_SCRIPT_SOURCE)))
 
-        $(eval LINKER_SCRIPT_SOURCES := $($(call uppercase,$(1))_LINKER_SCRIPT_SOURCES))
+        $(eval LINKER_SCRIPT_SOURCES := $($(BL)_LINKER_SCRIPT_SOURCES))
         $(eval LINKER_SCRIPTS := $(call linker_script_path,$(LINKER_SCRIPT_SOURCES)))
 
-        # We use sort only to get a list of unique object directory names.
-        # ordering is not relevant but sort removes duplicates.
-        $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${DEFAULT_LINKER_SCRIPT} ${LINKER_SCRIPTS})))
-        # The $(dir ) function leaves a trailing / on the directory names
-        # Rip off the / to match directory names with make rule targets.
-        $(eval OBJ_DIRS   := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
-
-# Create generators for object directory structure
-
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
-
-$(eval $(foreach objd,${OBJ_DIRS},
-        $(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
-
-.PHONY : ${1}_dirs
-
-# We use order-only prerequisites to ensure that directories are created,
-# but do not cause re-builds every time a file is written.
-${1}_dirs: | ${OBJ_DIRS}
-
-$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1),$(BL)))
 
 # Generate targets to preprocess each required linker script
 $(eval $(foreach source,$(DEFAULT_LINKER_SCRIPT_SOURCE) $(LINKER_SCRIPT_SOURCES), \
-        $(call MAKE_LD,$(call linker_script_path,$(source)),$(source),$(1))))
+        $(call MAKE_LD,$(call linker_script_path,$(source)),$(source),$(1),$(BL))))
 
-$(eval BL_LDFLAGS := $($(call uppercase,$(1))_LDFLAGS))
+$(eval BL_LDFLAGS := $($(BL)_LDFLAGS))
 
 ifeq ($(USE_ROMLIB),1)
-$(ELF): romlib.bin
+$(ELF): romlib.bin | $$$$(@D)/
 endif
 
 # MODULE_OBJS can be assigned by vendors with different compiled
 # object file path, and prebuilt object file path.
 $(eval OBJS += $(MODULE_OBJS))
 
-$(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $(1)_dirs libraries $(BL_LIBS)
-	$$(ECHO) "  LD      $$@"
-ifdef MAKE_BUILD_STRINGS
-	$(call MAKE_BUILD_STRINGS,$(BUILD_DIR)/build_message.o)
-else
-	@echo 'const char build_message[] = "Built : "$(BUILD_MESSAGE_TIMESTAMP); \
-	       const char version_string[] = "${VERSION_STRING}"; \
-	       const char version[] = "${VERSION}";' | \
-		$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o
-endif
-ifneq ($(findstring armlink,$(notdir $(LD))),)
-	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
-		--predefine="-D__LINKER__=$(__LINKER__)" \
-		--predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \
+$(ELF): $(OBJS) $(DEFAULT_LINKER_SCRIPT) $(LINKER_SCRIPTS) | $$$$(@D)/ libraries $(BL_LIBS)
+	$$(s)echo "  LD      $$@"
+ifeq ($($(ARCH)-ld-id),arm-link)
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
+		--predefine=$(call escape-shell,-D__LINKER__=$(__LINKER__)) \
+		--predefine=$(call escape-shell,-DTF_CFLAGS=$(TF_CFLAGS)) \
 		--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \
-		$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \
-		$(BUILD_DIR)/build_message.o $(OBJS)
-else ifneq ($(findstring gcc,$(notdir $(LD))),)
-	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
+		$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) $(OBJS)
+else ifeq ($($(ARCH)-ld-id),gnu-gcc)
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $$(WRAPPER_FLAGS) $(BL_LDFLAGS) -Wl,-Map=$(MAPFILE) \
 		$(addprefix -Wl$(comma)--script$(comma),$(LINKER_SCRIPTS)) -Wl,--script,$(DEFAULT_LINKER_SCRIPT) \
-		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 else
-	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
+	$$(q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $$(WRAPPER_FLAGS) $(BL_LDFLAGS) -Map=$(MAPFILE) \
 		$(addprefix -T ,$(LINKER_SCRIPTS)) --script $(DEFAULT_LINKER_SCRIPT) \
-		$(BUILD_DIR)/build_message.o \
 		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 endif
 ifeq ($(DISABLE_BIN_GENERATION),1)
-	@${ECHO_BLANK_LINE}
-	@echo "Built $$@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built $$@ successfully"
+	$(s)echo
 endif
 
-$(DUMP): $(ELF)
-	$${ECHO} "  OD      $$@"
-	$${Q}$${OD} -dx $$< > $$@
+$(DUMP): $(ELF) | $$$$(@D)/
+	$$(s)echo "  OD      $$@"
+	$$(q)$($(ARCH)-od) -dx $$< > $$@
 
-$(BIN): $(ELF)
-	$${ECHO} "  BIN     $$@"
-	$$(Q)$$(OC) -O binary $$< $$@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $$@ successfully"
-	@${ECHO_BLANK_LINE}
+$(BIN): $(ELF) | $$$$(@D)/
+	$$(s)echo "  BIN     $$@"
+	$$(q)$($(ARCH)-oc) -O binary $$< $$@
+	$(s)echo
+	$(s)echo "Built $$@ successfully"
+	$(s)echo
 
 .PHONY: $(1)
 ifeq ($(DISABLE_BIN_GENERATION),1)
@@ -611,10 +568,10 @@ all: $(1)
 
 ifeq ($(4),1)
 $(call ENCRYPT_FW,$(BIN),$(ENC_BIN))
-$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \
+$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(BIN),--$(2),$(ENC_BIN),$(3), \
 		$(ENC_BIN)))
 else
-$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(BIN),$(3)))
+$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(BL),$(BIN),--$(2),$(BIN),$(3)))
 endif
 
 endef
@@ -625,22 +582,6 @@ define SOURCES_TO_DTBS
         $(notdir $(patsubst %.dts,%.dtb,$(filter %.dts,$(1))))
 endef
 
-# MAKE_FDT_DIRS macro creates the prerequisite directories that host the
-# FDT binaries
-#   $(1) = output directory
-#   $(2) = input dts
-define MAKE_FDT_DIRS
-        $(eval DTBS       := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
-        $(eval TEMP_DTB_DIRS := $(sort $(dir ${DTBS})))
-        # The $(dir ) function leaves a trailing / on the directory names
-        # Rip off the / to match directory names with make rule targets.
-        $(eval DTB_DIRS   := $(patsubst %/,%,$(TEMP_DTB_DIRS)))
-
-$(eval $(foreach objd,${DTB_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
-
-fdt_dirs: ${DTB_DIRS}
-endef
-
 # MAKE_DTB generate the Flattened device tree binary
 #   $(1) = output directory
 #   $(2) = input dts
@@ -655,12 +596,14 @@ $(eval DTSDEP := $(patsubst %.dtb,%.o.d,$(DOBJ)))
 # Dependencies of the DT compilation on its pre-compiled DTS
 $(eval DTBDEP := $(patsubst %.dtb,%.d,$(DOBJ)))
 
-$(DOBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
-	$${ECHO} "  CPP     $$<"
+$(DPRE): $(2) | $$$$(@D)/
+	$$(s)echo "  CPP     $$<"
 	$(eval DTBS       := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
-	$$(Q)$$(PP) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
-	$${ECHO} "  DTC     $$<"
-	$$(Q)$$(DTC) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $(DPRE)
+	$$(q)$($(ARCH)-cpp) -E $$(TF_CFLAGS_$(ARCH)) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
+
+$(DOBJ): $(DPRE) $(filter-out %.d,$(MAKEFILE_LIST)) | $$$$(@D)/
+	$$(s)echo "  DTC     $$<"
+	$$(q)$($(ARCH)-dtc) $$(DTC_FLAGS) -d $(DTBDEP) -o $$@ $$<
 
 -include $(DTBDEP)
 -include $(DTSDEP)
@@ -676,8 +619,6 @@ define MAKE_DTBS
         $(and $(REMAIN),$(error FDT_SOURCES contain non-DTS files: $(REMAIN)))
         $(eval $(foreach obj,$(DOBJS),$(call MAKE_DTB,$(1),$(obj))))
 
-        $(eval $(call MAKE_FDT_DIRS,$(1),$(2)))
-
-dtbs: $(DTBS)
+dtbs: $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2)))
 all: dtbs
 endef
diff --git a/make_helpers/common.mk b/make_helpers/common.mk
new file mode 100644
index 00000000..848e4e94
--- /dev/null
+++ b/make_helpers/common.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifndef common-mk
+        common-mk := $(lastword $(MAKEFILE_LIST))
+
+        include $(dir $(common-mk))utilities.mk
+
+        silent := $(call bool,$(findstring s,$(firstword ~$(MAKEFLAGS))))
+        verbose := $(if $(silent),,$(call bool,$(V)))
+
+        s := @$(if $(or $(verbose),$(silent)),: )
+        q := $(if $(verbose),,@)
+endif
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index f0f157c1..d6c09de6 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -63,6 +63,9 @@ CTX_INCLUDE_AARCH32_REGS	:= 1
 # Include FP registers in cpu context
 CTX_INCLUDE_FPREGS		:= 0
 
+# Include SVE registers in cpu context
+CTX_INCLUDE_SVE_REGS		:= 0
+
 # Debug build
 DEBUG				:= 0
 
@@ -139,6 +142,12 @@ FW_ENC_STATUS			:= 0
 # For Chain of Trust
 GENERATE_COT			:= 0
 
+# Default number of 512 blocks per bitlock
+RME_GPT_BITLOCK_BLOCK		:= 1
+
+# Default maximum size of GPT contiguous block
+RME_GPT_MAX_BLOCK		:= 512
+
 # Hint platform interrupt control layer that Group 0 interrupts are for EL3. By
 # default, they are for Secure EL1.
 GICV2_G0_FOR_EL3		:= 0
@@ -150,6 +159,10 @@ HANDLE_EA_EL3_FIRST_NS		:= 0
 # Enable Handoff protocol using transfer lists
 TRANSFER_LIST			:= 0
 
+# Enables support for the gcc compiler option "-mharden-sls=all".
+# By default, disables all SLS hardening.
+HARDEN_SLS			:= 0
+
 # Secure hash algorithm flag, accepts 3 values: sha256, sha384 and sha512.
 # The default value is sha256.
 HASH_ALG			:= sha256
@@ -172,6 +185,9 @@ endif
 # Option to build TF with Measured Boot support
 MEASURED_BOOT			:= 0
 
+# Option to enable the DICE Protection Environmnet as a Measured Boot backend
+DICE_PROTECTION_ENVIRONMENT	:=0
+
 # NS timer register save and restore
 NS_TIMER_SWITCH			:= 0
 
@@ -224,6 +240,14 @@ SEPARATE_NOBITS_REGION		:= 0
 # region, platform Makefile is free to override this value.
 SEPARATE_BL2_NOLOAD_REGION	:= 0
 
+# Put RW DATA sections (.rwdata) in a separate memory region, which may be
+# discontiguous from the rest of BL31.
+SEPARATE_RWDATA_REGION		:= 0
+
+# Put SIMD context data structures in a separate memory region. Platforms
+# have the choice to put it outside of default BSS region of EL3 firmware.
+SEPARATE_SIMD_SECTION		:= 0
+
 # If the BL31 image initialisation code is recalimed after use for the secondary
 # cores stack
 RECLAIM_INIT_CODE		:= 0
@@ -281,9 +305,6 @@ COT				:= tbbr
 # Use tbbr_oid.h instead of platform_oid.h
 USE_TBBR_DEFS			:= 1
 
-# Build verbosity
-V				:= 0
-
 # Whether to enable D-Cache early during warm boot. This is usually
 # applicable for platforms wherein interconnect programming is not
 # required to enable cache coherency after warm reset (eg: single cluster
@@ -347,8 +368,13 @@ NR_OF_IMAGES_IN_FW_BANK		:= 1
 # Disable Firmware update support by default
 PSA_FWU_SUPPORT			:= 0
 
-# By default, disable the mocking of RSS provided services
-PLAT_RSS_NOT_SUPPORTED		:= 0
+# Enable image description in FWU metadata by default when PSA_FWU_SUPPORT
+# is enabled.
+ifeq ($(PSA_FWU_SUPPORT),1)
+PSA_FWU_METADATA_FW_STORE_DESC	:= 1
+else
+PSA_FWU_METADATA_FW_STORE_DESC	:= 0
+endif
 
 # Dynamic Root of Trust for Measurement support
 DRTM_SUPPORT			:= 0
@@ -373,3 +399,20 @@ ENABLE_CONSOLE_GETC		:= 0
 # functions must be enabled by platforms if they require it.
 # Disabled by default.
 INIT_UNUSED_NS_EL2		:= 0
+
+# Disable including MPAM EL2 registers in context by default since currently
+# it's only enabled for NS world
+CTX_INCLUDE_MPAM_REGS		:= 0
+
+# Enable context memory usage reporting during BL31 setup.
+PLATFORM_REPORT_CTX_MEM_USE	:= 0
+
+# Enable early console
+EARLY_CONSOLE			:= 0
+
+# Allow platforms to save/restore DSU PMU registers over a power cycle.
+# Disabled by default and must be enabled by individual platforms.
+PRESERVE_DSU_PMU_REGS		:= 0
+
+# Enable RMMD to forward attestation requests from RMM to EL3.
+RMMD_ENABLE_EL3_TOKEN_SIGN	:= 0
diff --git a/make_helpers/march.mk b/make_helpers/march.mk
index 2417709c..8e73116a 100644
--- a/make_helpers/march.mk
+++ b/make_helpers/march.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -21,7 +21,7 @@
 # armv8.6-a armv8.7-a armv8.8-a armv8-r armv9-a
 # [...]
 #
-GCC_MARCH_OUTPUT := $(shell $(CC) -march=foo -Q --help=target -v 2>&1)
+GCC_MARCH_OUTPUT := $(if $($(ARCH)-cc),$(shell $($(ARCH)-cc) -march=foo -Q --help=target -v 2>&1))
 
 # This function is used to find the best march value supported by the given compiler.
 # We try to use `GCC_MARCH_OUTPUT` which has verbose message with supported march values we filter that
@@ -54,7 +54,7 @@ else
     provided-march = armv${ARM_ARCH_MAJOR}.${ARM_ARCH_MINOR}-a
 endif
 
-ifeq ($(findstring clang,$(notdir $(CC))),)
+ifeq ($(filter %-clang,$($(ARCH)-cc-id)),)
 
 # We expect from Platform to provide a correct Major/Minor value but expecting something
 # from compiler with unsupported march means we shouldn't fail without trying anything,
@@ -82,4 +82,13 @@ endif # not clang
 
 march-directive := -march=${provided-march}
 
+# Set the compiler's architecture feature modifiers
+ifneq ($(arch-features), none)
+	# Strip "none+" from arch-features
+	arch-features	:=	$(subst none+,,$(arch-features))
+	march-directive	:=	$(march-directive)+$(arch-features)
+# Print features
+        $(info Arm Architecture Features specified: $(subst +, ,$(arch-features)))
+endif #(arch-features)
+
 endif # MARCH_DIRECTIVE
diff --git a/make_helpers/plat_helpers.mk b/make_helpers/plat_helpers.mk
index a7ae9a27..bc02a207 100644
--- a/make_helpers/plat_helpers.mk
+++ b/make_helpers/plat_helpers.mk
@@ -11,6 +11,7 @@
 ifndef PLAT_HELPERS_MK
     PLAT_HELPERS_MK := $(lastword $(MAKEFILE_LIST))
 
+    PLAT:= ${DEFAULT_PLAT}
     ifeq (${PLAT},)
         $(error "Error: Unknown platform. Please use PLAT=<platform name> to specify the platform")
     endif
@@ -18,15 +19,18 @@ ifndef PLAT_HELPERS_MK
     # TF_PLATFORM_ROOT can be overridden for when building tools directly
     TF_PLATFORM_ROOT               ?= plat/
     PLAT_MAKEFILE               := platform.mk
+    PLAT_DEFAULTS_MAKEFILE      := platform_defaults.mk
 
     # Generate the platforms list by recursively searching for all directories
     # under /plat containing a PLAT_MAKEFILE. Append each platform with a `|`
     # char and strip out the final '|'.
     ALL_PLATFORM_MK_FILES       := $(call rwildcard,${TF_PLATFORM_ROOT},${PLAT_MAKEFILE})
+    ALL_PLATFORM_MK_DEF_FILES   := $(call rwildcard,${TF_PLATFORM_ROOT},${PLAT_DEFAULTS_MAKEFILE})
     ALL_PLATFORM_DIRS           := $(patsubst %/,%,$(dir ${ALL_PLATFORM_MK_FILES}))
     ALL_PLATFORMS               := $(sort $(notdir ${ALL_PLATFORM_DIRS}))
 
     PLAT_MAKEFILE_FULL          := $(filter %/${PLAT}/${PLAT_MAKEFILE},${ALL_PLATFORM_MK_FILES})
+    PLAT_DEFAULTS_MAKEFILE_FULL := $(filter %/${PLAT}/${PLAT_DEFAULTS_MAKEFILE},${ALL_PLATFORM_MK_DEF_FILES})
     PLATFORM_LIST               := $(subst ${space},|,${ALL_PLATFORMS})
     ifeq ($(PLAT_MAKEFILE_FULL),)
         $(error "Error: Invalid platform. The following platforms are available: ${PLATFORM_LIST}")
diff --git a/make_helpers/toolchain.mk b/make_helpers/toolchain.mk
new file mode 100644
index 00000000..2ab577cd
--- /dev/null
+++ b/make_helpers/toolchain.mk
@@ -0,0 +1,436 @@
+#
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+#
+# TF-A uses three toolchains:
+#
+#   - The host toolchain (`host`) for building native tools
+#   - The AArch32 toolchain (`aarch32`) for building Arm AArch32 images
+#   - The AArch64 toolchain (`aarch64`) for building Arm AArch64 images
+#
+# In the main Makefile only one of the two Arm toolchains is enabled in any
+# given build, but individual tools and libraries may need access to both.
+#
+
+ifndef toolchain-mk
+        toolchain-mk := $(lastword $(MAKEFILE_LIST))
+
+        include $(dir $(toolchain-mk))build_env.mk
+        include $(dir $(toolchain-mk))utilities.mk
+
+        #
+        # Make assigns generic default values to `CC`, `CPP`, `AS`, etc. if they
+        # are not explicitly assigned values by the user. These are usually okay
+        # for very simple programs when building for the host system, but we
+        # need greater control over the toolchain flow.
+        #
+        # Therefore, we undefine these built-in variables if they have default
+        # values, so that we can provide our own default values later instead.
+        #
+
+        ifeq ($(origin CC),default)
+                undefine CC
+        endif
+
+        ifeq ($(origin CPP),default)
+                undefine CPP
+        endif
+
+        ifeq ($(origin AS),default)
+                undefine AS
+        endif
+
+        ifeq ($(origin AR),default)
+                undefine AR
+        endif
+
+        ifeq ($(origin LD),default)
+                undefine LD
+        endif
+
+        #
+        # The full list of toolchains supported by TF-A.
+        #
+        # Each of these toolchains defines a file of the same name in the
+        # `toolchains` directory, which must configure the following variables:
+        #
+        #   - <toolchain>-name
+        #
+        #     A human-readable name for the toolchain,
+        #
+        # Additionally, for every tool class, it must also define:
+        #
+        #   - <toolchain>-<tool-class>-parameter
+        #
+        #     The command line or environment variable used to set the tool for
+        #     for the given tool class.
+        #
+        #   - <toolchain>-<tool-class>-default-id
+        #
+        #     The default tool identifier used if the tool for the given tool
+        #     class cannot be identified.
+        #
+        #   - <toolchain>-<tool-class>-default
+        #
+        #     The default commands to try, in the order defined, for the given
+        #     tool class if the user does not explicitly provide one, and if the
+        #     command could not be derived from the C compiler.
+        #
+
+        toolchains := host # Used for host targets
+        toolchains += aarch32 # Used for AArch32 targets
+        toolchains += aarch64 # Used for AArch64 targets
+        toolchains += rk3399-m0 # Used for RK3399 Cortex-M0 targets
+
+        include $(toolchains:%=$(dir $(toolchain-mk))toolchains/%.mk)
+
+        #
+        # Configure tool classes that we recognize.
+        #
+        # In the context of this build system, a tool class identifies a
+        # specific role or type of tool in the toolchain.
+        #
+
+        toolchain-tool-classes := cc
+        toolchain-tool-class-name-cc := C compiler
+
+        toolchain-tool-classes += cpp
+        toolchain-tool-class-name-cpp := C preprocessor
+
+        toolchain-tool-classes += as
+        toolchain-tool-class-name-as := assembler
+
+        toolchain-tool-classes += ld
+        toolchain-tool-class-name-ld := linker
+
+        toolchain-tool-classes += oc
+        toolchain-tool-class-name-oc := object copier
+
+        toolchain-tool-classes += od
+        toolchain-tool-class-name-od := object dumper
+
+        toolchain-tool-classes += ar
+        toolchain-tool-class-name-ar := archiver
+
+        toolchain-tool-classes += dtc
+        toolchain-tool-class-name-dtc := device tree compiler
+
+        toolchain-tool-classes += poetry
+        toolchain-tool-class-name-poetry := Python Poetry package manager
+
+        #
+        # Configure tools that we recognize.
+        #
+        # Here we declare the list of specific toolchain tools that we know how
+        # to interact with. We don't organize these into tool classes yet - that
+        # happens further down.
+        #
+
+        # Arm® Compiler for Embedded
+        toolchain-tools := arm-clang
+        toolchain-tool-name-arm-clang := Arm® Compiler for Embedded `armclang`
+
+        toolchain-tools += arm-link
+        toolchain-tool-name-arm-link := Arm® Compiler for Embedded `armlink`
+
+        toolchain-tools += arm-ar
+        toolchain-tool-name-arm-ar := Arm® Compiler for Embedded `armar`
+
+        toolchain-tools += arm-fromelf
+        toolchain-tool-name-arm-fromelf := Arm® Compiler for Embedded `fromelf`
+
+        # LLVM Project
+        toolchain-tools += llvm-clang
+        toolchain-tool-name-llvm-clang := LLVM Clang (`clang`)
+
+        toolchain-tools += llvm-lld
+        toolchain-tool-name-llvm-lld := LLVM LLD (`lld`)
+
+        toolchain-tools += llvm-objcopy
+        toolchain-tool-name-llvm-objcopy := LLVM `llvm-objcopy`
+
+        toolchain-tools += llvm-objdump
+        toolchain-tool-name-llvm-objdump := LLVM `llvm-objdump`
+
+        toolchain-tools += llvm-ar
+        toolchain-tool-name-llvm-ar := LLVM `llvm-ar`
+
+        # GNU Compiler Collection & GNU Binary Utilities
+        toolchain-tools += gnu-gcc
+        toolchain-tool-name-gnu-gcc := GNU GCC (`gcc`)
+
+        toolchain-tools += gnu-ld
+        toolchain-tool-name-gnu-ld := GNU LD (`ld.bfd`)
+
+        toolchain-tools += gnu-objcopy
+        toolchain-tool-name-gnu-objcopy := GNU `objcopy`
+
+        toolchain-tools += gnu-objdump
+        toolchain-tool-name-gnu-objdump := GNU `objdump`
+
+        toolchain-tools += gnu-ar
+        toolchain-tool-name-gnu-ar := GNU `ar`
+
+        # Other tools
+        toolchain-tools += generic-dtc
+        toolchain-tool-name-generic-dtc := Device Tree Compiler (`dtc`)
+
+        toolchain-tools += generic-poetry
+        toolchain-tool-name-generic-poetry := Poetry (`poetry`)
+
+        #
+        # Assign tools to tool classes.
+        #
+        # Multifunctional tools, i.e. tools which can perform multiple roles in
+        # a toolchain, may be specified in multiple tool class lists. For
+        # example, a C compiler which can also perform the role of a linker may
+        # be placed in both `toolchain-tools-cc` and `toolchain-tools-ld`.
+        #
+
+        # C-related tools
+        toolchain-tools-cc := arm-clang llvm-clang gnu-gcc # C compilers
+        toolchain-tools-cpp := arm-clang llvm-clang gnu-gcc # C preprocessors
+
+        # Assembly-related tools
+        toolchain-tools-as := arm-clang llvm-clang gnu-gcc # Assemblers
+
+        # Linking and object-handling tools
+        toolchain-tools-ld := arm-clang arm-link llvm-clang llvm-lld gnu-gcc gnu-ld # Linkers
+        toolchain-tools-oc := arm-fromelf llvm-objcopy gnu-objcopy # Object copiers
+        toolchain-tools-od := arm-fromelf llvm-objdump gnu-objdump # Object dumpers
+        toolchain-tools-ar := arm-ar llvm-ar gnu-ar # Archivers
+
+        # Other tools
+        toolchain-tools-dtc := generic-dtc # Device tree compilers
+        toolchain-tools-poetry := generic-poetry # Python Poetry package manager
+
+        #
+        # Helper functions to identify toolchain tools.
+        #
+        # The functions defined in this section return a tool identifier when
+        # given a path to a binary. We generally check a help or version string
+        # to more reliably identify tools than by looking at the path alone
+        # (e.g. `gcc` on macOS is actually Apple Clang).
+        #
+        # Each tool-guessing function (`toolchain-guess-tool-$(tool)`) takes a
+        # single argument giving the path to the tool to guess, and returns a
+        # non-empty value if the tool corresponds to the tool identifier
+        # `$(tool)`:
+        #
+        #     $(call toolchain-guess-tool-llvm-clang,aarch64-none-elf-gcc) # <empty>
+        #     $(call toolchain-guess-tool-gnu-gcc,aarch64-none-elf-gcc) # <non-empty>
+        #
+        # The `toolchain-guess-tool` function tries to find the corresponding tool
+        # identifier for a tool given its path. It takes two arguments:
+        #
+        #   - $(1): a list of candidate tool identifiers to check
+        #   - $(2): the path to the tool to identify
+        #
+        # If any of the guess functions corresponding to candidate tool
+        # identifiers return a non-empty value then the tool identifier of the
+        # first function to do so is returned:
+        #
+        #     $(call toolchain-guess-tool,gnu-gcc llvm-clang,armclang) # <empty>
+        #     $(call toolchain-guess-tool,gnu-gcc llvm-clang,clang-14) # llvm-clang
+        #     $(call toolchain-guess-tool,gnu-gcc llvm-clang,aarch64-none-elf-gcc-12) # gnu-gcc
+        #
+        # Tools are checked in the order that they are provided, and the first
+        # match is returned.
+        #
+
+        # Arm Compiler for Embedded
+        toolchain-guess-tool-arm-clang = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armclang")
+        toolchain-guess-tool-arm-link = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: armlink")
+        toolchain-guess-tool-arm-fromelf = $(shell $(1) --help 2>&1 <$(nul) | grep -o "Tool: fromelf")
+        toolchain-guess-tool-arm-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Tool: armar")
+
+        # LLVM Project
+        toolchain-guess-tool-llvm-clang = $(shell $(1) -v 2>&1 <$(nul) | grep -o "clang version")
+        toolchain-guess-tool-llvm-lld = $(shell $(1) --help 2>&1 <$(nul) | grep -o "OVERVIEW: lld")
+        toolchain-guess-tool-llvm-objcopy = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm-objcopy tool")
+        toolchain-guess-tool-llvm-objdump = $(shell $(1) --help 2>&1 <$(nul) | grep -o "llvm object file dumper")
+        toolchain-guess-tool-llvm-ar = $(shell $(1) --help 2>&1 <$(nul) | grep -o "LLVM Archiver")
+
+        # GNU Compiler Collection & GNU Binary Utilities
+        toolchain-guess-tool-gnu-gcc = $(shell $(1) -v 2>&1 <$(nul) | grep -o "gcc version")
+        toolchain-guess-tool-gnu-ld = $(shell $(1) -v 2>&1 <$(nul) | grep -o "GNU ld")
+        toolchain-guess-tool-gnu-objcopy = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objcopy")
+        toolchain-guess-tool-gnu-objdump = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU objdump")
+        toolchain-guess-tool-gnu-ar = $(shell $(1) --version 2>&1 <$(nul) | grep -o "GNU ar")
+
+        # Other tools
+        toolchain-guess-tool-generic-dtc = $(shell $(1) --version 2>&1 <$(nul) | grep -o "Version: DTC")
+        toolchain-guess-tool-generic-poetry = $(shell $(1) --version 2>&1 <$(nul))
+
+        toolchain-guess-tool = $(if $(2),$(firstword $(foreach candidate,$(1),$\
+                $(if $(call toolchain-guess-tool-$(candidate),$(2)),$(candidate)))))
+
+        #
+        # Warn the user that a tool could not be identified.
+        #
+        # Parameters:
+        #
+        # - $1: The toolchain that the tool belongs to.
+        # - $2: The tool class that the tool belongs to.
+        #
+
+        define toolchain-warn-unrecognized
+                $(warning )
+                $(warning The configured $($(1)-name) $(toolchain-tool-class-name-$(2)) could not be identified:)
+                $(warning )
+                $(warning $(space)   $($(1)-$(2))$(if $($(1)-$(2)-parameter), (via `$($(1)-$(2)-parameter)`)))
+                $(warning )
+                $(warning The following tools were tried, but either did not exist or could not be identified:)
+                $(warning )
+
+                $(foreach default,$($(1)-$(2)-default), \
+                        $(warning $(space) - $(default)))
+
+                $(warning )
+                $(warning The following tools are supported:)
+                $(warning )
+
+                $(foreach tool,$(toolchain-tools-$(2)), \
+                        $(warning $(space) - $(toolchain-tool-name-$(tool))))
+
+                $(warning )
+                $(warning The build system will treat this $(toolchain-tool-class-name-$(2)) as $(toolchain-tool-name-$($(1)-$(2)-default-id)).)
+                $(warning )
+        endef
+
+        #
+        # Locate and identify tools belonging to each toolchain.
+        #
+        # Each tool class in each toolchain receives a variable of the form
+        # `$(toolchain)-$(tool)` giving the associated path to the program. For
+        # example:
+        #
+        #   - `aarch64-ld` gives the linker for the AArch64 toolchain,
+        #   - `aarch32-oc` gives the object copier for the AArch32 toolchain, and
+        #   - `host-cc` gives the C compiler for the host toolchain.
+        #
+        # For each of these variables, if no program path is explicitly provided
+        # by the parent Makefile then the C compiler is queried (if supported)
+        # for its location.
+        #
+        # If the C compiler cannot provide the location (or the tool class *is*
+        # the C compiler), then it is assigned a default value specific for that
+        # toolchain.
+        #
+
+        toolchain-derive-arm-clang-cpp = $(1)
+        toolchain-derive-arm-clang-as = $(1)
+        toolchain-derive-arm-clang-ld = # Fall back to `$(toolchain)-ld-default`
+        toolchain-derive-arm-clang-oc = # Fall back to `$(toolchain)-oc-default`
+        toolchain-derive-arm-clang-od = # Fall back to `$(toolchain)-od-default`
+        toolchain-derive-arm-clang-ar = # Fall back to `$(toolchain)-ar-default`
+
+        toolchain-derive-llvm-clang-cpp = $(1)
+        toolchain-derive-llvm-clang-as = $(1)
+        toolchain-derive-llvm-clang-ld = $(shell $(1) --print-prog-name ld.lld 2>$(nul))
+        toolchain-derive-llvm-clang-oc = $(shell $(1) --print-prog-name llvm-objcopy 2>$(nul))
+        toolchain-derive-llvm-clang-od = $(shell $(1) --print-prog-name llvm-objdump 2>$(nul))
+        toolchain-derive-llvm-clang-ar = $(shell $(1) --print-prog-name llvm-ar 2>$(nul))
+
+        toolchain-derive-gnu-gcc-cpp = $(1)
+        toolchain-derive-gnu-gcc-as = $(1)
+        toolchain-derive-gnu-gcc-ld = $(1)
+        toolchain-derive-gnu-gcc-oc = $(shell $(1) --print-prog-name objcopy 2>$(nul))
+        toolchain-derive-gnu-gcc-od = $(shell $(1) --print-prog-name objdump 2>$(nul))
+        toolchain-derive-gnu-gcc-ar = $(shell $(1) --print-prog-name ar 2>$(nul))
+
+        toolchain-derive = $(if $3,$(call toolchain-derive-$1-$2,$3))
+
+        #
+        # Configure a toolchain.
+        #
+        # Parameters:
+        #
+        #   - $1: The toolchain to configure.
+        #
+        # This function iterates over all tool classes and configures them for
+        # the provided toolchain. Toolchain tools are initialized lazily and
+        # on-demand based on the first read of the tool path or identifier
+        # variables.
+        #
+
+        define toolchain-configure
+                $$(foreach tool-class,$$(toolchain-tool-classes), \
+                        $$(eval $$(call toolchain-configure-tool,$1,$$(tool-class))))
+        endef
+
+        #
+        # Configure a specific tool within a toolchain.
+        #
+        # Parameters:
+        #
+        #   - $1: The toolchain to configure.
+        #   - $2: The tool class to configure.
+        #
+
+        define toolchain-configure-tool
+                $1-$2-configure = $\
+                        $$(eval $$(call toolchain-determine-tool,$1,$2))
+
+                #
+                # When either of the following variables are read for the first
+                # time, the appropriate tool is determined and *both* variables
+                # are overwritten with their final values.
+                #
+
+                $1-$2 = $$($1-$2-configure)$$($1-$2)
+                $1-$2-id = $$($1-$2-configure)$$($1-$2-id)
+        endef
+
+        #
+        # Determines and identifies a tool.
+        #
+        # Parameters:
+        #
+        #   - $1: The toolchain identifier.
+        #   - $2: The tool class.
+        #
+        # Tool identification happens by reading the designated tool parameter
+        # to get the user-specified command for the tool (e.g. `CC` or `LD`). If
+        # no tool parameter is defined then try to derive the tool from the C
+        # compiler.
+        #
+        # If all else fails, fall back to the default command defined by the
+        # toolchain makefile.
+        #
+
+        define toolchain-determine-tool
+                toolchain-$1-$2-derive-from-cc = $$(if $$(filter-out cc,$2),$\
+                        $$(call toolchain-derive,$$($1-cc-id),$2,$$($1-cc)))
+
+                toolchain-$1-$2-shell = $\
+                        $$(if $$(call defined,$$($1-$2-parameter)),$\
+                                $$($$($1-$2-parameter)),$\
+                                $$(or $$(toolchain-$1-$2-derive-from-cc),$\
+                                        $$(toolchain-$1-$2-default)))
+
+                toolchain-$1-$2-default = $$(firstword $\
+                        $$(foreach default,$$($1-$2-default),$\
+                                $$(if $$(call which,$$(default)),$$(default))) $\
+                        $$($1-$2-default))
+
+                $1-$2 := $$(if $$(call which,$$(toolchain-$1-$2-shell)),$\
+                        $$(call escape-shell,$$(toolchain-$1-$2-shell)),$\
+                        $$(toolchain-$1-$2-shell))
+
+                $1-$2-id := $$(if $$($1-$2),$$(or $\
+                        $$(call toolchain-guess-tool,$$\
+                                $$(toolchain-tools-$2),$$($1-$2)),$\
+                        $$($1-$2-default-id)))
+
+                ifeq ($$(or $$($1-$2-id),$$(call bool,$$($1-$2-optional))),)
+                        $$(call toolchain-warn-unrecognized,$1,$2)
+                endif
+        endef
+
+        $(foreach toolchain,$(toolchains), \
+                $(eval $(call toolchain-configure,$(toolchain))))
+endif
diff --git a/make_helpers/toolchains/aarch32.mk b/make_helpers/toolchains/aarch32.mk
new file mode 100644
index 00000000..4063ed92
--- /dev/null
+++ b/make_helpers/toolchains/aarch32.mk
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+aarch32-name := AArch32
+
+aarch32-cc-parameter := CC
+aarch32-cc-default-id := gnu-gcc
+aarch32-cc-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
+
+aarch32-cpp-parameter := CPP
+aarch32-cpp-default-id := gnu-gcc
+aarch32-cpp-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
+
+aarch32-as-parameter := AS
+aarch32-as-default-id := gnu-gcc
+aarch32-as-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
+
+aarch32-ld-parameter := LD
+aarch32-ld-default-id := gnu-gcc
+aarch32-ld-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc
+
+aarch32-oc-parameter := OC
+aarch32-oc-default-id := gnu-objcopy
+aarch32-oc-default := $(or $(CROSS_COMPILE),arm-none-eabi-)objcopy
+
+aarch32-od-parameter := OD
+aarch32-od-default-id := gnu-objdump
+aarch32-od-default := $(or $(CROSS_COMPILE),arm-none-eabi-)objdump
+
+aarch32-ar-parameter := AR
+aarch32-ar-default-id := gnu-ar
+aarch32-ar-default := $(or $(CROSS_COMPILE),arm-none-eabi-)gcc-ar
+
+aarch32-dtc-parameter := DTC
+aarch32-dtc-default-id := generic-dtc
+aarch32-dtc-default := dtc
diff --git a/make_helpers/toolchains/aarch64.mk b/make_helpers/toolchains/aarch64.mk
new file mode 100644
index 00000000..476fbf3c
--- /dev/null
+++ b/make_helpers/toolchains/aarch64.mk
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+aarch64-name := AArch64
+
+aarch64-cc-parameter := CC
+aarch64-cc-default-id := gnu-gcc
+aarch64-cc-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
+aarch64-cc-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc)
+
+aarch64-cpp-parameter := CPP
+aarch64-cpp-default-id := gnu-gcc
+aarch64-cpp-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
+aarch64-cpp-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc)
+
+aarch64-as-parameter := AS
+aarch64-as-default-id := gnu-gcc
+aarch64-as-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
+aarch64-as-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc)
+
+aarch64-ld-parameter := LD
+aarch64-ld-default-id := gnu-gcc
+aarch64-ld-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc
+aarch64-ld-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc)
+
+aarch64-oc-parameter := OC
+aarch64-oc-default-id := gnu-objcopy
+aarch64-oc-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)objcopy
+aarch64-oc-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-objcopy)
+
+aarch64-od-parameter := OD
+aarch64-od-default-id := gnu-objdump
+aarch64-od-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)objdump
+aarch64-od-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-objdump)
+
+aarch64-ar-parameter := AR
+aarch64-ar-default-id := gnu-ar
+aarch64-ar-default := $(or $(CROSS_COMPILE),aarch64-none-elf-)gcc-ar
+aarch64-ar-default += $(if $(CROSS_COMPILE),,aarch64-linux-gnu-gcc-ar)
+
+aarch64-dtc-parameter := DTC
+aarch64-dtc-default-id := generic-dtc
+aarch64-dtc-default := dtc
diff --git a/make_helpers/toolchains/host.mk b/make_helpers/toolchains/host.mk
new file mode 100644
index 00000000..dc538c64
--- /dev/null
+++ b/make_helpers/toolchains/host.mk
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+host-name := host
+
+host-cc-parameter := HOSTCC
+host-cc-default-id := gnu-gcc
+host-cc-default := gcc
+
+host-cpp-parameter := HOSTCPP
+host-cpp-default-id := gnu-gcc
+host-cpp-default := gcc
+
+host-as-parameter := HOSTAS
+host-as-default-id := gnu-gcc
+host-as-default := gcc
+
+host-ld-parameter := HOSTLD
+host-ld-default-id := gnu-gcc
+host-ld-default := gcc
+
+host-oc-parameter := HOSTOC
+host-oc-default-id := gnu-objcopy
+host-oc-default := objcopy
+
+host-od-parameter := HOSTOD
+host-od-default-id := gnu-objdump
+host-od-default := objdump
+
+host-ar-parameter := HOSTAR
+host-ar-default-id := gnu-ar
+host-ar-default := gcc-ar
+
+host-dtc-parameter := HOSTDTC
+host-dtc-default-id := generic-dtc
+host-dtc-default := dtc
+
+host-poetry-parameter := POETRY
+host-poetry-optional := yes
+host-poetry-default-id := generic-poetry
+host-poetry-default := poetry
diff --git a/make_helpers/toolchains/rk3399-m0.mk b/make_helpers/toolchains/rk3399-m0.mk
new file mode 100644
index 00000000..3a7f173a
--- /dev/null
+++ b/make_helpers/toolchains/rk3399-m0.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+rk3399-m0-name := RK3399 M0
+
+rk3399-m0-cc-default-id := gnu-gcc
+rk3399-m0-cc-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
+
+rk3399-m0-cpp-default-id := gnu-gcc
+rk3399-m0-cpp-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
+
+rk3399-m0-as-default-id := gnu-gcc
+rk3399-m0-as-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
+
+rk3399-m0-ld-default-id := gnu-gcc
+rk3399-m0-ld-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc
+
+rk3399-m0-oc-default-id := gnu-objcopy
+rk3399-m0-oc-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)objcopy
+
+rk3399-m0-od-default-id := gnu-objdump
+rk3399-m0-od-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)objdump
+
+rk3399-m0-ar-default-id := gnu-ar
+rk3399-m0-ar-default := $(or $(M0_CROSS_COMPILE),arm-none-eabi-)gcc-ar
+
+rk3399-m0-dtc-default-id := generic-dtc
+rk3399-m0-dtc-default := dtc
diff --git a/make_helpers/unix.mk b/make_helpers/unix.mk
index 545ddfde..fa7722a6 100644
--- a/make_helpers/unix.mk
+++ b/make_helpers/unix.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,9 +9,6 @@
 ifndef UNIX_MK
     UNIX_MK := $(lastword $(MAKEFILE_LIST))
 
-    ECHO_BLANK_LINE := echo
-    ECHO_QUIET := @\#
-
     DIR_DELIM := /
     PATH_SEP := :
 
@@ -21,40 +18,31 @@ ifndef UNIX_MK
     # ${1} is the file to be copied.
     # ${2} is the destination file name.
     define SHELL_COPY
-	${Q}cp -f  "${1}"  "${2}"
+	$(q)cp -f  "${1}"  "${2}"
     endef
 
     # ${1} is the directory to be copied.
     # ${2} is the destination directory path.
     define SHELL_COPY_TREE
-	${Q}cp -rf  "${1}"  "${2}"
+	$(q)cp -rf  "${1}"  "${2}"
     endef
 
     # ${1} is the file to be deleted.
     define SHELL_DELETE
-	-${Q}rm -f  "${1}"
+	-$(q)rm -f  "${1}"
     endef
 
     # ${1} is a space delimited list of files to be deleted.
     # Note that we do not quote ${1}, as multiple parameters may be passed.
     define SHELL_DELETE_ALL
-	-${Q}rm -rf  ${1}
-    endef
-
-    # ${1} is the directory to be generated.
-    # ${2} is optional, and allows a prerequisite to be specified.
-    # Do nothing if $1 == $2, to ignore self dependencies.
-    define MAKE_PREREQ_DIR
-        ifneq (${1},${2})
-
-${1} : ${2}
-	${Q}mkdir -p  "${1}"
-
-        endif
+	-$(q)rm -rf  ${1}
     endef
 
     define SHELL_REMOVE_DIR
-	-${Q}rm -rf  "${1}"
+	-$(q)rm -rf  "${1}"
     endef
 
+    nul := /dev/null
+
+    which = $(shell command -v $(call escape-shell,$(1)) 2>$(nul))
 endif
diff --git a/make_helpers/utilities.mk b/make_helpers/utilities.mk
new file mode 100644
index 00000000..fcccd240
--- /dev/null
+++ b/make_helpers/utilities.mk
@@ -0,0 +1,129 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+space :=
+space := $(space) $(space)
+comma := ,
+
+null := �
+
+compat-path = $(subst $(space),$(null),$(1))
+decompat-path = $(subst $(null), ,$(1))
+
+absolute-path = $(call decompat-path,$(abspath $(call compat-path,$(1))))
+real-path = $(call decompat-path,$(realpath $(call compat-path,$(1))))
+
+file-name = $(call decompat-path,$(notdir $(call compat-path,$(1))))
+directory-name = $(call decompat-path,$(dir $(call compat-path,$(1))))
+
+escape-shell = '$(subst ','\'',$(1))'
+
+#
+# The grouped-target symbol. Grouped targets are not supported on versions of
+# GNU Make <= 4.2, which was most recently packaged with Ubuntu 20.04.
+#
+
+& := $(if $(filter grouped-target,$(.FEATURES)),&)
+
+#
+# Upper-case a string value.
+#
+# Parameters:
+#
+#   - $(1): The string to upper-case.
+#
+# Example usage:
+#
+#     $(call uppercase,HeLlO wOrLd) # "HELLO WORLD"
+#
+
+uppercase = $(shell echo $(call escape-shell,$(1)) | tr '[:lower:]' '[:upper:]')
+
+#
+# Lower-case a string value.
+#
+# Parameters:
+#
+#   - $(1): The string to lower-case.
+#
+# Example usage:
+#
+#     $(call lowercase,HeLlO wOrLd) # "hello world"
+#
+
+lowercase = $(shell echo $(call escape-shell,$(1)) | tr '[:upper:]' '[:lower:]')
+
+#
+# Determine the "truthiness" of a value.
+#
+# Parameters:
+#
+#   - $(1): The value to determine the truthiness of.
+#
+# A value is considered to be falsy if it is:
+#
+#   - empty, or
+#   - equal to "0", "N", "NO", "F" or "FALSE" after upper-casing.
+#
+# If the value is truthy then the value is returned as-is, otherwise no value
+# is returned.
+#
+# Example usage:
+#
+#     truthy := y
+#     truthy-bool := $(call bool,$(truthy)) # "y"
+#
+#     falsy := n
+#     falsy-bool := $(call bool,$(falsy)) # <empty>
+#
+
+bool = $(filter-out 0 n no f false,$(call lowercase,$(1)))
+
+#
+# Determine the "truthiness" of a value, returning 0 or 1.
+#
+# Parameters:
+#
+#   - $(1): The value to determine the truthiness of.
+#
+# A value is considered to be falsy if it is:
+#
+#   - empty, or
+#   - equal to "0", "N", "NO", "F" or "FALSE" after upper-casing.
+#
+# If the value is truthy then the value is returned as-is, otherwise no value
+# is returned.
+#
+# Example usage:
+#
+#     truthy := y
+#     truthy-bool := $(call bool,$(truthy)) # "1"
+#
+#     falsy := n
+#     falsy-bool := $(call bool,$(falsy)) # "0"
+#
+
+bool-01 = $(if $(call bool,$(1)),1,0)
+
+#
+# Determine whether a variable is defined or not.
+#
+# Parameters:
+#
+#   - $(1): The variable to check.
+#
+# Example usage:
+#
+#     xyz-defined := $(call defined,xyz) # <empty>
+#
+#     xyz :=
+#     xyz-defined := $(call defined,xyz) # <non-empty>
+#
+#     xyz := hello
+#     xyz-defined := $(call defined,xyz) # <non-empty>
+#
+
+defined = $(call bool,$(filter-out undefined,$(origin $(1))))
diff --git a/make_helpers/windows.mk b/make_helpers/windows.mk
index ac0f9404..c24aa084 100644
--- a/make_helpers/windows.mk
+++ b/make_helpers/windows.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,8 +12,6 @@
 ifndef WINDOWS_MK
     WINDOWS_MK := $(lastword $(MAKEFILE_LIST))
 
-    ECHO_BLANK_LINE := @cmd /c echo.
-    ECHO_QUIET := @rem
     DIR_DELIM := $(strip \)
     BIN_EXT   := .exe
     PATH_SEP  := ;
@@ -49,25 +47,15 @@ ifndef WINDOWS_MK
 	$(eval $(foreach filename,$(wildcard ${1}),$(call DELETE_IF_THERE,${filename})))
     endef
 
-    # ${1} is the directory to be generated.
-    # ${2} is optional, and allows prerequisites to be specified.
-    # Do nothing if $1 == $2, to ignore self dependencies.
-    define MAKE_PREREQ_DIR
-        ifneq (${1},${2})
-
-${1} : ${2}
-	$(eval tmp_dir:=$(subst /,\,${1}))
-	-@if not exist "$(tmp_dir)"  mkdir "${tmp_dir}"
-
-        endif
-    endef
-
     # ${1} is the directory to be removed.
     define SHELL_REMOVE_DIR
 	$(eval tmp_dir:=$(subst /,\,${1}))
 	-@if exist "$(tmp_dir)"  rd /Q /S "$(tmp_dir)"
     endef
 
+    nul := nul
+
+    which = $(shell where "$(1)" 2>$(nul))
 endif
 
 # Because git is not available from CMD.EXE, we need to avoid
@@ -76,17 +64,4 @@ endif
 # This can be overridden from the command line or environment.
 BUILD_STRING ?= development build
 
-# The DOS echo shell command does not strip ' characters from the command
-# parameters before printing. We therefore use an alternative method invoked
-# by defining the MAKE_BUILD_STRINGS macro.
-BUILT_TIME_DATE_STRING = const char build_message[] = "Built : "${BUILD_MESSAGE_TIMESTAMP};
-VERSION_STRING_MESSAGE = const char version_string[] = "${VERSION_STRING}";
-VERSION_MESSAGE = const char version[] = "${VERSION}";
-define MAKE_BUILD_STRINGS
-	$$(file >$1.in,$$(TF_CFLAGS) $$(CFLAGS))
-	@echo $$(BUILT_TIME_DATE_STRING) $$(VERSION_STRING_MESSAGE) $$(VERSION_MESSAGE) | \
-		$$(CC) @$1.in -x c -c - -o $1
-endef
-
 MSVC_NMAKE := nmake.exe
-
diff --git a/package-lock.json b/package-lock.json
index e43fa657..dd115597 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,57 +1,119 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.10.0",
-  "lockfileVersion": 2,
+  "version": "2.12.0",
+  "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "trusted-firmware-a",
-      "version": "2.10.0",
-      "hasInstallScript": true,
+      "version": "2.12.0",
       "license": "BSD-3-Clause",
       "devDependencies": {
-        "@commitlint/cli": "^16.1.0",
-        "@commitlint/config-conventional": "^16.0.0",
-        "@commitlint/cz-commitlint": "^16.1.0",
-        "commitizen": "^4.2.4",
+        "@commitlint/cli": "^19.0.0",
+        "@commitlint/config-conventional": "^19.0.0",
+        "@commitlint/cz-commitlint": "^19.0.0",
+        "commitizen": "^4.3.0",
         "conventional-changelog-tf-a": "file:tools/conventional-changelog-tf-a",
-        "husky": "^7.0.4",
+        "husky": "^9.0.11",
         "js-yaml": "^4.1.0",
-        "standard-version": "^9.3.2"
+        "standard-version": "^9.5.0"
       },
       "engines": {
-        "node": ">=16.0.0"
+        "node": ">=20"
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
-      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+      "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
       "dev": true,
       "dependencies": {
-        "@babel/highlight": "^7.18.6"
+        "@babel/highlight": "^7.23.4",
+        "chalk": "^2.4.2"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/code-frame/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@babel/code-frame/node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@babel/code-frame/node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/@babel/code-frame/node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
+    },
+    "node_modules/@babel/code-frame/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@babel/code-frame/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.19.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
-      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+      "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
-      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+      "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.18.6",
-        "chalk": "^2.0.0",
+        "@babel/helper-validator-identifier": "^7.22.20",
+        "chalk": "^2.4.2",
         "js-tokens": "^4.0.0"
       },
       "engines": {
@@ -121,4525 +183,1219 @@
       }
     },
     "node_modules/@commitlint/cli": {
-      "version": "16.3.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.3.0.tgz",
-      "integrity": "sha512-P+kvONlfsuTMnxSwWE1H+ZcPMY3STFaHb2kAacsqoIkNx66O0T7sTpBxpxkMrFPyhkJiLJnJWMhk4bbvYD3BMA==",
-      "dev": true,
-      "dependencies": {
-        "@commitlint/format": "^16.2.1",
-        "@commitlint/lint": "^16.2.4",
-        "@commitlint/load": "^16.3.0",
-        "@commitlint/read": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "lodash": "^4.17.19",
-        "resolve-from": "5.0.0",
-        "resolve-global": "1.0.0",
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.0.0.tgz",
+      "integrity": "sha512-SVBQG6k+eOOmlejYTtxnqJGmhrzy/m0qH3bVeoHY3gtlJBK3Kb32RjJioteBYk8Vuo58x5ehAjXwsQFX58X+xw==",
+      "dev": true,
+      "dependencies": {
+        "@commitlint/format": "^19.0.0",
+        "@commitlint/lint": "^19.0.0",
+        "@commitlint/load": "^19.0.0",
+        "@commitlint/read": "^19.0.0",
+        "@commitlint/types": "^19.0.0",
+        "execa": "^8.0.1",
+        "resolve-from": "^5.0.0",
+        "resolve-global": "^2.0.0",
         "yargs": "^17.0.0"
       },
       "bin": {
         "commitlint": "cli.js"
       },
       "engines": {
-        "node": ">=v12"
+        "node": ">=v18"
       }
     },
-    "node_modules/@commitlint/config-conventional": {
-      "version": "16.2.4",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.2.4.tgz",
-      "integrity": "sha512-av2UQJa3CuE5P0dzxj/o/B9XVALqYzEViHrMXtDrW9iuflrqCStWBAioijppj9URyz6ONpohJKAtSdgAOE0gkA==",
+    "node_modules/@commitlint/cli/node_modules/execa": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+      "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
       "dev": true,
       "dependencies": {
-        "conventional-changelog-conventionalcommits": "^4.3.1"
+        "cross-spawn": "^7.0.3",
+        "get-stream": "^8.0.1",
+        "human-signals": "^5.0.0",
+        "is-stream": "^3.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^5.1.0",
+        "onetime": "^6.0.0",
+        "signal-exit": "^4.1.0",
+        "strip-final-newline": "^3.0.0"
       },
       "engines": {
-        "node": ">=v12"
+        "node": ">=16.17"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
       }
     },
-    "node_modules/@commitlint/config-validator": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.2.1.tgz",
-      "integrity": "sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw==",
+    "node_modules/@commitlint/cli/node_modules/get-stream": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+      "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
       "dev": true,
-      "dependencies": {
-        "@commitlint/types": "^16.2.1",
-        "ajv": "^6.12.6"
-      },
       "engines": {
-        "node": ">=v12"
+        "node": ">=16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@commitlint/cz-commitlint": {
-      "version": "16.3.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-16.3.0.tgz",
-      "integrity": "sha512-Q+QLQmSIHEgzI18F3/7mqq3vwL0IN9k+Tjp9Um4adFnRXMtUTnEa0er0CXAXxWvoA/x/6nt3t7faAv2HugDIGg==",
+    "node_modules/@commitlint/cli/node_modules/human-signals": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+      "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
       "dev": true,
-      "dependencies": {
-        "@commitlint/ensure": "^16.2.1",
-        "@commitlint/load": "^16.3.0",
-        "@commitlint/types": "^16.2.1",
-        "chalk": "^4.1.0",
-        "lodash": "^4.17.21",
-        "word-wrap": "^1.2.3"
-      },
       "engines": {
-        "node": ">=v12"
-      },
-      "peerDependencies": {
-        "commitizen": "^4.0.3",
-        "inquirer": "^8.0.0"
+        "node": ">=16.17.0"
       }
     },
-    "node_modules/@commitlint/ensure": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.2.1.tgz",
-      "integrity": "sha512-/h+lBTgf1r5fhbDNHOViLuej38i3rZqTQnBTk+xEg+ehOwQDXUuissQ5GsYXXqI5uGy+261ew++sT4EA3uBJ+A==",
+    "node_modules/@commitlint/cli/node_modules/is-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+      "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
       "dev": true,
-      "dependencies": {
-        "@commitlint/types": "^16.2.1",
-        "lodash": "^4.17.19"
-      },
       "engines": {
-        "node": ">=v12"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@commitlint/execute-rule": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.2.1.tgz",
-      "integrity": "sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g==",
+    "node_modules/@commitlint/cli/node_modules/mimic-fn": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+      "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
       "dev": true,
       "engines": {
-        "node": ">=v12"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@commitlint/format": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.2.1.tgz",
-      "integrity": "sha512-Yyio9bdHWmNDRlEJrxHKglamIk3d6hC0NkEUW6Ti6ipEh2g0BAhy8Od6t4vLhdZRa1I2n+gY13foy+tUgk0i1Q==",
+    "node_modules/@commitlint/cli/node_modules/npm-run-path": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
+      "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.2.1",
-        "chalk": "^4.0.0"
+        "path-key": "^4.0.0"
       },
       "engines": {
-        "node": ">=v12"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@commitlint/is-ignored": {
-      "version": "16.2.4",
-      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.2.4.tgz",
-      "integrity": "sha512-Lxdq9aOAYCOOOjKi58ulbwK/oBiiKz+7Sq0+/SpFIEFwhHkIVugvDvWjh2VRBXmRC/x5lNcjDcYEwS/uYUvlYQ==",
+    "node_modules/@commitlint/cli/node_modules/onetime": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+      "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.2.1",
-        "semver": "7.3.7"
+        "mimic-fn": "^4.0.0"
       },
       "engines": {
-        "node": ">=v12"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@commitlint/lint": {
-      "version": "16.2.4",
-      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.2.4.tgz",
-      "integrity": "sha512-AUDuwOxb2eGqsXbTMON3imUGkc1jRdtXrbbohiLSCSk3jFVXgJLTMaEcr39pR00N8nE9uZ+V2sYaiILByZVmxQ==",
+    "node_modules/@commitlint/cli/node_modules/path-key": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+      "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
       "dev": true,
-      "dependencies": {
-        "@commitlint/is-ignored": "^16.2.4",
-        "@commitlint/parse": "^16.2.1",
-        "@commitlint/rules": "^16.2.4",
-        "@commitlint/types": "^16.2.1"
-      },
       "engines": {
-        "node": ">=v12"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@commitlint/load": {
-      "version": "16.3.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.3.0.tgz",
-      "integrity": "sha512-3tykjV/iwbkv2FU9DG+NZ/JqmP0Nm3b7aDwgCNQhhKV5P74JAuByULkafnhn+zsFGypG1qMtI5u+BZoa9APm0A==",
-      "dev": true,
-      "dependencies": {
-        "@commitlint/config-validator": "^16.2.1",
-        "@commitlint/execute-rule": "^16.2.1",
-        "@commitlint/resolve-extends": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "@types/node": ">=12",
-        "chalk": "^4.0.0",
-        "cosmiconfig": "^7.0.0",
-        "cosmiconfig-typescript-loader": "^2.0.0",
-        "lodash": "^4.17.19",
-        "resolve-from": "^5.0.0",
-        "typescript": "^4.4.3"
-      },
+    "node_modules/@commitlint/cli/node_modules/signal-exit": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+      "dev": true,
       "engines": {
-        "node": ">=v12"
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/@commitlint/message": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.2.1.tgz",
-      "integrity": "sha512-2eWX/47rftViYg7a3axYDdrgwKv32mxbycBJT6OQY/MJM7SUfYNYYvbMFOQFaA4xIVZt7t2Alyqslbl6blVwWw==",
+    "node_modules/@commitlint/cli/node_modules/strip-final-newline": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+      "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
       "dev": true,
       "engines": {
-        "node": ">=v12"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@commitlint/parse": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.2.1.tgz",
-      "integrity": "sha512-2NP2dDQNL378VZYioLrgGVZhWdnJO4nAxQl5LXwYb08nEcN+cgxHN1dJV8OLJ5uxlGJtDeR8UZZ1mnQ1gSAD/g==",
+    "node_modules/@commitlint/config-conventional": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.0.0.tgz",
+      "integrity": "sha512-d8lPm+slPUdA8Zof2Y36RqAm/MmAYx/QQIEd2gKbpfLThQK1oYLs+0C3sMPD+4LIq2kh4cnbV9WnPA0P5sN8Ig==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.2.1",
-        "conventional-changelog-angular": "^5.0.11",
-        "conventional-commits-parser": "^3.2.2"
+        "@commitlint/types": "^19.0.0",
+        "conventional-changelog-conventionalcommits": "^7.0.2"
       },
       "engines": {
-        "node": ">=v12"
+        "node": ">=v18"
       }
     },
-    "node_modules/@commitlint/read": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.2.1.tgz",
-      "integrity": "sha512-tViXGuaxLTrw2r7PiYMQOFA2fueZxnnt0lkOWqKyxT+n2XdEMGYcI9ID5ndJKXnfPGPppD0w/IItKsIXlZ+alw==",
+    "node_modules/@commitlint/config-conventional/node_modules/conventional-changelog-conventionalcommits": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz",
+      "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==",
       "dev": true,
       "dependencies": {
-        "@commitlint/top-level": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "fs-extra": "^10.0.0",
-        "git-raw-commits": "^2.0.0"
+        "compare-func": "^2.0.0"
       },
       "engines": {
-        "node": ">=v12"
+        "node": ">=16"
       }
     },
-    "node_modules/@commitlint/resolve-extends": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.2.1.tgz",
-      "integrity": "sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg==",
+    "node_modules/@commitlint/config-validator": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.0.0.tgz",
+      "integrity": "sha512-oxJ2k+jBPRyWzv1ixfxwGZO5DJ1S+v3D8u/QESMwuPh3kQmeOYBRxGI+5FDWMwiVSHpztlhvvxDAU9SFXeMqUA==",
       "dev": true,
       "dependencies": {
-        "@commitlint/config-validator": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "import-fresh": "^3.0.0",
-        "lodash": "^4.17.19",
-        "resolve-from": "^5.0.0",
-        "resolve-global": "^1.0.0"
+        "@commitlint/types": "^19.0.0",
+        "ajv": "^8.11.0"
       },
       "engines": {
-        "node": ">=v12"
+        "node": ">=v18"
       }
     },
-    "node_modules/@commitlint/rules": {
-      "version": "16.2.4",
-      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.2.4.tgz",
-      "integrity": "sha512-rK5rNBIN2ZQNQK+I6trRPK3dWa0MtaTN4xnwOma1qxa4d5wQMQJtScwTZjTJeallFxhOgbNOgr48AMHkdounVg==",
+    "node_modules/@commitlint/cz-commitlint": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-19.0.0.tgz",
+      "integrity": "sha512-hIWExZOycAuq0fW7rBq23AuBMJAmvTuM3GSlAX5kSV8gvASwXSrHRKgxrHQCcozV/ZnLlbFEvfVgBRi+UbH8pA==",
       "dev": true,
       "dependencies": {
-        "@commitlint/ensure": "^16.2.1",
-        "@commitlint/message": "^16.2.1",
-        "@commitlint/to-lines": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "execa": "^5.0.0"
+        "@commitlint/ensure": "^19.0.0",
+        "@commitlint/load": "^19.0.0",
+        "@commitlint/types": "^19.0.0",
+        "chalk": "^5.3.0",
+        "lodash.isplainobject": "^4.0.6",
+        "word-wrap": "^1.2.5"
       },
       "engines": {
-        "node": ">=v12"
+        "node": ">=v18"
+      },
+      "peerDependencies": {
+        "commitizen": "^4.0.3",
+        "inquirer": "^9.0.0"
       }
     },
-    "node_modules/@commitlint/to-lines": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.2.1.tgz",
-      "integrity": "sha512-9/VjpYj5j1QeY3eiog1zQWY6axsdWAc0AonUUfyZ7B0MVcRI0R56YsHAfzF6uK/g/WwPZaoe4Lb1QCyDVnpVaQ==",
+    "node_modules/@commitlint/cz-commitlint/node_modules/chalk": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+      "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
       "dev": true,
       "engines": {
-        "node": ">=v12"
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "node_modules/@commitlint/top-level": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.2.1.tgz",
-      "integrity": "sha512-lS6GSieHW9y6ePL73ied71Z9bOKyK+Ib9hTkRsB8oZFAyQZcyRwq2w6nIa6Fngir1QW51oKzzaXfJL94qwImyw==",
+    "node_modules/@commitlint/ensure": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.0.0.tgz",
+      "integrity": "sha512-G0avCIwjKplTP1Oc9MlDhsYqi1yOWORtJSBpyMbQEnalQAW1tuRxG4LOLRZVKfFqlDWs2SfVQPN0Uw51Ge0f6w==",
       "dev": true,
       "dependencies": {
-        "find-up": "^5.0.0"
+        "@commitlint/types": "^19.0.0",
+        "lodash.camelcase": "^4.3.0",
+        "lodash.kebabcase": "^4.1.1",
+        "lodash.snakecase": "^4.1.1",
+        "lodash.startcase": "^4.4.0",
+        "lodash.upperfirst": "^4.3.1"
       },
       "engines": {
-        "node": ">=v12"
+        "node": ">=v18"
       }
     },
-    "node_modules/@commitlint/types": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.2.1.tgz",
-      "integrity": "sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA==",
+    "node_modules/@commitlint/execute-rule": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.0.0.tgz",
+      "integrity": "sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==",
       "dev": true,
-      "dependencies": {
-        "chalk": "^4.0.0"
-      },
       "engines": {
-        "node": ">=v12"
+        "node": ">=v18"
       }
     },
-    "node_modules/@cspotcode/source-map-support": {
-      "version": "0.8.1",
-      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
-      "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+    "node_modules/@commitlint/format": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.0.0.tgz",
+      "integrity": "sha512-36P4/2tpGSGQsYoSZEso5fTSTaMSArIK9fszy+5B8hwwAvOfnD4kQtrwfMhiXnf7PCgeX2lx5Jma+pY3Bq326A==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/trace-mapping": "0.3.9"
+        "@commitlint/types": "^19.0.0",
+        "chalk": "^5.3.0"
       },
       "engines": {
-        "node": ">=12"
+        "node": ">=v18"
       }
     },
-    "node_modules/@hutson/parse-repository-url": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz",
-      "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==",
+    "node_modules/@commitlint/format/node_modules/chalk": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+      "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
       "dev": true,
       "engines": {
-        "node": ">=6.9.0"
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "node_modules/@jridgewell/resolve-uri": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
-      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+    "node_modules/@commitlint/is-ignored": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.0.0.tgz",
+      "integrity": "sha512-5b2nIrl8GEjzYAnOK2ZAUxBXvUonYrp3+8kJkUMl8QOtjt2O1gsd71jar7UtoDEqTWJhc+n7lG6lQYMXtcQJAw==",
       "dev": true,
+      "dependencies": {
+        "@commitlint/types": "^19.0.0",
+        "semver": "^7.6.0"
+      },
       "engines": {
-        "node": ">=6.0.0"
+        "node": ">=v18"
       }
     },
-    "node_modules/@jridgewell/sourcemap-codec": {
-      "version": "1.4.14",
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
-      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
-      "dev": true
-    },
-    "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.9",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
-      "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+    "node_modules/@commitlint/lint": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.0.0.tgz",
+      "integrity": "sha512-rAAisSpxhA+z4uhsveSt1CuTB+Jld5d7zyNSEK2UWjQaOxicwDP+LFiOdM32n/vwsLlOJqhrInA50UcbRSVaGg==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/resolve-uri": "^3.0.3",
-        "@jridgewell/sourcemap-codec": "^1.4.10"
+        "@commitlint/is-ignored": "^19.0.0",
+        "@commitlint/parse": "^19.0.0",
+        "@commitlint/rules": "^19.0.0",
+        "@commitlint/types": "^19.0.0"
+      },
+      "engines": {
+        "node": ">=v18"
       }
     },
-    "node_modules/@tsconfig/node10": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
-      "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
-      "dev": true
-    },
-    "node_modules/@tsconfig/node12": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
-      "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
-      "dev": true
-    },
-    "node_modules/@tsconfig/node14": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
-      "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
-      "dev": true
-    },
-    "node_modules/@tsconfig/node16": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
-      "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
-      "dev": true
-    },
-    "node_modules/@types/minimist": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
-      "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
-      "dev": true
-    },
-    "node_modules/@types/node": {
-      "version": "18.8.3",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.3.tgz",
-      "integrity": "sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==",
-      "dev": true
+    "node_modules/@commitlint/load": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.0.0.tgz",
+      "integrity": "sha512-pC/6xDjkWPWgqfILY0KMMpxz0dTZqC7fUpxyWMLRrlbZCC9S54/gsg/8UltFrUH+C+F1zz4Ip8CQgzKonpH6rg==",
+      "dev": true,
+      "dependencies": {
+        "@commitlint/config-validator": "^19.0.0",
+        "@commitlint/execute-rule": "^19.0.0",
+        "@commitlint/resolve-extends": "^19.0.0",
+        "@commitlint/types": "^19.0.0",
+        "chalk": "^5.3.0",
+        "cosmiconfig": "^8.3.6",
+        "cosmiconfig-typescript-loader": "^5.0.0",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.merge": "^4.6.2",
+        "lodash.uniq": "^4.5.0"
+      },
+      "engines": {
+        "node": ">=v18"
+      }
     },
-    "node_modules/@types/normalize-package-data": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
-      "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
-      "dev": true
+    "node_modules/@commitlint/load/node_modules/chalk": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+      "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+      "dev": true,
+      "engines": {
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
     },
-    "node_modules/@types/parse-json": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
-      "dev": true
+    "node_modules/@commitlint/message": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.0.0.tgz",
+      "integrity": "sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==",
+      "dev": true,
+      "engines": {
+        "node": ">=v18"
+      }
     },
-    "node_modules/acorn": {
-      "version": "8.8.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
-      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
+    "node_modules/@commitlint/parse": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.0.0.tgz",
+      "integrity": "sha512-/2hT08V/2Lh+aQ5cSAw5vO74FlA3LJGYzLfsNMcx6aW8Kmrsa9W7chNNY5hMWbucCF92s/JE3eVIHnzoEBKTTA==",
       "dev": true,
-      "bin": {
-        "acorn": "bin/acorn"
+      "dependencies": {
+        "@commitlint/types": "^19.0.0",
+        "conventional-changelog-angular": "^7.0.0",
+        "conventional-commits-parser": "^5.0.0"
       },
       "engines": {
-        "node": ">=0.4.0"
+        "node": ">=v18"
       }
     },
-    "node_modules/acorn-walk": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
-      "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+    "node_modules/@commitlint/parse/node_modules/conventional-changelog-angular": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
+      "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==",
       "dev": true,
+      "dependencies": {
+        "compare-func": "^2.0.0"
+      },
       "engines": {
-        "node": ">=0.4.0"
+        "node": ">=16"
       }
     },
-    "node_modules/add-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz",
-      "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==",
-      "dev": true
-    },
-    "node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+    "node_modules/@commitlint/parse/node_modules/conventional-commits-parser": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
+      "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
       "dev": true,
       "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
+        "is-text-path": "^2.0.0",
+        "JSONStream": "^1.3.5",
+        "meow": "^12.0.1",
+        "split2": "^4.0.0"
       },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
+      "bin": {
+        "conventional-commits-parser": "cli.mjs"
+      },
+      "engines": {
+        "node": ">=16"
       }
     },
-    "node_modules/ansi-escapes": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
-      "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+    "node_modules/@commitlint/parse/node_modules/is-text-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
+      "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
       "dev": true,
       "dependencies": {
-        "type-fest": "^0.21.3"
+        "text-extensions": "^2.0.0"
       },
       "engines": {
         "node": ">=8"
+      }
+    },
+    "node_modules/@commitlint/parse/node_modules/meow": {
+      "version": "12.1.1",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+      "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+      "dev": true,
+      "engines": {
+        "node": ">=16.10"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/ansi-regex": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+    "node_modules/@commitlint/parse/node_modules/split2": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+      "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
       "dev": true,
       "engines": {
-        "node": ">=8"
+        "node": ">= 10.x"
       }
     },
-    "node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+    "node_modules/@commitlint/parse/node_modules/text-extensions": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
+      "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
       "dev": true,
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
       "engines": {
         "node": ">=8"
       },
       "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/arg": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
-      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
-      "dev": true
-    },
-    "node_modules/argparse": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-      "dev": true
-    },
-    "node_modules/array-ify": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
-      "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
-      "dev": true
+    "node_modules/@commitlint/read": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.0.0.tgz",
+      "integrity": "sha512-AbK/fQjWrXGAAHl+KeOtZtWJryhzkTnynhkABF4IUFZqK71JSviSIPHYuUQjdwNrD0PJGs5f19ORjY8LOXP08w==",
+      "dev": true,
+      "dependencies": {
+        "@commitlint/top-level": "^19.0.0",
+        "@commitlint/types": "^19.0.0",
+        "git-raw-commits": "^4.0.0",
+        "minimist": "^1.2.8"
+      },
+      "engines": {
+        "node": ">=v18"
+      }
     },
-    "node_modules/arrify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-      "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
+    "node_modules/@commitlint/read/node_modules/dargs": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
+      "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
       "dev": true,
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/at-least-node": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
-      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+    "node_modules/@commitlint/read/node_modules/git-raw-commits": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
+      "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
       "dev": true,
+      "dependencies": {
+        "dargs": "^8.0.0",
+        "meow": "^12.0.1",
+        "split2": "^4.0.0"
+      },
+      "bin": {
+        "git-raw-commits": "cli.mjs"
+      },
       "engines": {
-        "node": ">= 4.0.0"
+        "node": ">=16"
       }
     },
-    "node_modules/balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
-      "dev": true
+    "node_modules/@commitlint/read/node_modules/meow": {
+      "version": "12.1.1",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+      "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+      "dev": true,
+      "engines": {
+        "node": ">=16.10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "node_modules/base64-js": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
-      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+    "node_modules/@commitlint/read/node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
       "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
-    "node_modules/bl": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
-      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+    "node_modules/@commitlint/read/node_modules/split2": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+      "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
       "dev": true,
-      "dependencies": {
-        "buffer": "^5.5.0",
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.4.0"
+      "engines": {
+        "node": ">= 10.x"
       }
     },
-    "node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+    "node_modules/@commitlint/resolve-extends": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.0.0.tgz",
+      "integrity": "sha512-ej0fALn5yZQOYKH8wPZnzw5LGvD0n5gJBPvV6DnMiSYudqgwYwhdNJ//MukZCXNpLIM1yMA8KUyrCP6D4WnUbg==",
       "dev": true,
       "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
+        "@commitlint/config-validator": "^19.0.0",
+        "@commitlint/types": "^19.0.0",
+        "import-fresh": "^3.0.0",
+        "import-meta-resolve": "^4.0.0",
+        "lodash.mergewith": "^4.6.2",
+        "resolve-global": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=v18"
       }
     },
-    "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+    "node_modules/@commitlint/rules": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.0.0.tgz",
+      "integrity": "sha512-uwb5Ro5vvJlEjnWPezL3AcdlbLdJz24SD5VembgA6IXqqunphZr5LFsQL1z5efP7p3MUdJEXFynIx8o62+j2lA==",
       "dev": true,
       "dependencies": {
-        "fill-range": "^7.0.1"
+        "@commitlint/ensure": "^19.0.0",
+        "@commitlint/message": "^19.0.0",
+        "@commitlint/to-lines": "^19.0.0",
+        "@commitlint/types": "^19.0.0",
+        "execa": "^8.0.1"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=v18"
       }
     },
-    "node_modules/buffer": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+    "node_modules/@commitlint/rules/node_modules/execa": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+      "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
       "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
       "dependencies": {
-        "base64-js": "^1.3.1",
-        "ieee754": "^1.1.13"
+        "cross-spawn": "^7.0.3",
+        "get-stream": "^8.0.1",
+        "human-signals": "^5.0.0",
+        "is-stream": "^3.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^5.1.0",
+        "onetime": "^6.0.0",
+        "signal-exit": "^4.1.0",
+        "strip-final-newline": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=16.17"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
       }
     },
-    "node_modules/buffer-from": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
-      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
-      "dev": true
+    "node_modules/@commitlint/rules/node_modules/get-stream": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+      "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+      "dev": true,
+      "engines": {
+        "node": ">=16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "node_modules/cachedir": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
-      "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==",
+    "node_modules/@commitlint/rules/node_modules/human-signals": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+      "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
       "dev": true,
       "engines": {
-        "node": ">=6"
+        "node": ">=16.17.0"
       }
     },
-    "node_modules/callsites": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
-      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+    "node_modules/@commitlint/rules/node_modules/is-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+      "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
       "dev": true,
       "engines": {
-        "node": ">=6"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/camelcase": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
-      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+    "node_modules/@commitlint/rules/node_modules/mimic-fn": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+      "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
       "dev": true,
       "engines": {
-        "node": ">=6"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/camelcase-keys": {
-      "version": "6.2.2",
-      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
-      "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
+    "node_modules/@commitlint/rules/node_modules/npm-run-path": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
+      "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
       "dev": true,
       "dependencies": {
-        "camelcase": "^5.3.1",
-        "map-obj": "^4.0.0",
-        "quick-lru": "^4.0.1"
+        "path-key": "^4.0.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+    "node_modules/@commitlint/rules/node_modules/onetime": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+      "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
       "dev": true,
       "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
+        "mimic-fn": "^4.0.0"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">=12"
       },
       "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/chardet": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
-      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
-      "dev": true
-    },
-    "node_modules/cli-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
-      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+    "node_modules/@commitlint/rules/node_modules/path-key": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+      "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
       "dev": true,
-      "dependencies": {
-        "restore-cursor": "^3.1.0"
+      "engines": {
+        "node": ">=12"
       },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@commitlint/rules/node_modules/signal-exit": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+      "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+      "dev": true,
       "engines": {
-        "node": ">=8"
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/cli-spinners": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz",
-      "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==",
+    "node_modules/@commitlint/rules/node_modules/strip-final-newline": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+      "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
       "dev": true,
       "engines": {
-        "node": ">=6"
+        "node": ">=12"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/cli-width": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
-      "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+    "node_modules/@commitlint/to-lines": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.0.0.tgz",
+      "integrity": "sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==",
       "dev": true,
       "engines": {
-        "node": ">= 10"
+        "node": ">=v18"
       }
     },
-    "node_modules/cliui": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
-      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+    "node_modules/@commitlint/top-level": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.0.0.tgz",
+      "integrity": "sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==",
       "dev": true,
       "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.1",
-        "wrap-ansi": "^7.0.0"
+        "find-up": "^7.0.0"
       },
       "engines": {
-        "node": ">=12"
+        "node": ">=v18"
       }
     },
-    "node_modules/clone": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
-      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+    "node_modules/@commitlint/top-level/node_modules/find-up": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
+      "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==",
       "dev": true,
+      "dependencies": {
+        "locate-path": "^7.2.0",
+        "path-exists": "^5.0.0",
+        "unicorn-magic": "^0.1.0"
+      },
       "engines": {
-        "node": ">=0.8"
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+    "node_modules/@commitlint/top-level/node_modules/locate-path": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
+      "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
       "dev": true,
       "dependencies": {
-        "color-name": "~1.1.4"
+        "p-locate": "^6.0.0"
       },
       "engines": {
-        "node": ">=7.0.0"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true
-    },
-    "node_modules/commitizen": {
-      "version": "4.2.5",
-      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.2.5.tgz",
-      "integrity": "sha512-9sXju8Qrz1B4Tw7kC5KhnvwYQN88qs2zbiB8oyMsnXZyJ24PPGiNM3nHr73d32dnE3i8VJEXddBFIbOgYSEXtQ==",
+    "node_modules/@commitlint/top-level/node_modules/p-limit": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
+      "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
       "dev": true,
       "dependencies": {
-        "cachedir": "2.3.0",
-        "cz-conventional-changelog": "3.3.0",
-        "dedent": "0.7.0",
-        "detect-indent": "6.1.0",
-        "find-node-modules": "^2.1.2",
-        "find-root": "1.1.0",
-        "fs-extra": "9.1.0",
-        "glob": "7.2.3",
-        "inquirer": "8.2.4",
-        "is-utf8": "^0.2.1",
-        "lodash": "4.17.21",
-        "minimist": "1.2.6",
-        "strip-bom": "4.0.0",
-        "strip-json-comments": "3.1.1"
-      },
-      "bin": {
-        "commitizen": "bin/commitizen",
-        "cz": "bin/git-cz",
-        "git-cz": "bin/git-cz"
-      },
-      "engines": {
-        "node": ">= 12"
-      }
-    },
-    "node_modules/commitizen/node_modules/fs-extra": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
-      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
-      "dev": true,
-      "dependencies": {
-        "at-least-node": "^1.0.0",
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/compare-func": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
-      "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
-      "dev": true,
-      "dependencies": {
-        "array-ify": "^1.0.0",
-        "dot-prop": "^5.1.0"
-      }
-    },
-    "node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
-      "dev": true
-    },
-    "node_modules/concat-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
-      "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
-      "dev": true,
-      "engines": [
-        "node >= 6.0"
-      ],
-      "dependencies": {
-        "buffer-from": "^1.0.0",
-        "inherits": "^2.0.3",
-        "readable-stream": "^3.0.2",
-        "typedarray": "^0.0.6"
-      }
-    },
-    "node_modules/conventional-changelog": {
-      "version": "3.1.25",
-      "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz",
-      "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==",
-      "dev": true,
-      "dependencies": {
-        "conventional-changelog-angular": "^5.0.12",
-        "conventional-changelog-atom": "^2.0.8",
-        "conventional-changelog-codemirror": "^2.0.8",
-        "conventional-changelog-conventionalcommits": "^4.5.0",
-        "conventional-changelog-core": "^4.2.1",
-        "conventional-changelog-ember": "^2.0.9",
-        "conventional-changelog-eslint": "^3.0.9",
-        "conventional-changelog-express": "^2.0.6",
-        "conventional-changelog-jquery": "^3.0.11",
-        "conventional-changelog-jshint": "^2.0.9",
-        "conventional-changelog-preset-loader": "^2.3.4"
+        "yocto-queue": "^1.0.0"
       },
       "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-angular": {
-      "version": "5.0.13",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz",
-      "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==",
-      "dev": true,
-      "dependencies": {
-        "compare-func": "^2.0.0",
-        "q": "^1.5.1"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       },
-      "engines": {
-        "node": ">=10"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/conventional-changelog-atom": {
-      "version": "2.0.8",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz",
-      "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==",
+    "node_modules/@commitlint/top-level/node_modules/p-locate": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
+      "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
       "dev": true,
       "dependencies": {
-        "q": "^1.5.1"
+        "p-limit": "^4.0.0"
       },
       "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-codemirror": {
-      "version": "2.0.8",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz",
-      "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==",
-      "dev": true,
-      "dependencies": {
-        "q": "^1.5.1"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       },
-      "engines": {
-        "node": ">=10"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/conventional-changelog-config-spec": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz",
-      "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==",
-      "dev": true
-    },
-    "node_modules/conventional-changelog-conventionalcommits": {
-      "version": "4.6.3",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz",
-      "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==",
+    "node_modules/@commitlint/top-level/node_modules/path-exists": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
+      "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
       "dev": true,
-      "dependencies": {
-        "compare-func": "^2.0.0",
-        "lodash": "^4.17.15",
-        "q": "^1.5.1"
-      },
       "engines": {
-        "node": ">=10"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       }
     },
-    "node_modules/conventional-changelog-core": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz",
-      "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==",
+    "node_modules/@commitlint/top-level/node_modules/yocto-queue": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
+      "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
       "dev": true,
-      "dependencies": {
-        "add-stream": "^1.0.0",
-        "conventional-changelog-writer": "^5.0.0",
-        "conventional-commits-parser": "^3.2.0",
-        "dateformat": "^3.0.0",
-        "get-pkg-repo": "^4.0.0",
-        "git-raw-commits": "^2.0.8",
-        "git-remote-origin-url": "^2.0.0",
-        "git-semver-tags": "^4.1.1",
-        "lodash": "^4.17.15",
-        "normalize-package-data": "^3.0.0",
-        "q": "^1.5.1",
-        "read-pkg": "^3.0.0",
-        "read-pkg-up": "^3.0.0",
-        "through2": "^4.0.0"
-      },
       "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-core/node_modules/find-up": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
-      "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^2.0.0"
+        "node": ">=12.20"
       },
-      "engines": {
-        "node": ">=4"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/conventional-changelog-core/node_modules/hosted-git-info": {
-      "version": "2.8.9",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
-      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
-      "dev": true
-    },
-    "node_modules/conventional-changelog-core/node_modules/locate-path": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
-      "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+    "node_modules/@commitlint/types": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.0.0.tgz",
+      "integrity": "sha512-qLjLUdYXKi0TIavONrjBkxrElp7KguqDbvzIRbqTdJBV/cAAr8QEhHe1qUq8OcCM3gFWTlUrDz3ISZbkRoGsAg==",
       "dev": true,
       "dependencies": {
-        "p-locate": "^2.0.0",
-        "path-exists": "^3.0.0"
+        "chalk": "^5.3.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=v18"
       }
     },
-    "node_modules/conventional-changelog-core/node_modules/p-limit": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
-      "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+    "node_modules/@commitlint/types/node_modules/chalk": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+      "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
       "dev": true,
-      "dependencies": {
-        "p-try": "^1.0.0"
-      },
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/conventional-changelog-core/node_modules/p-locate": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
-      "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^1.1.0"
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
       },
-      "engines": {
-        "node": ">=4"
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "node_modules/conventional-changelog-core/node_modules/path-exists": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-      "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+    "node_modules/@hutson/parse-repository-url": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz",
+      "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==",
       "dev": true,
       "engines": {
-        "node": ">=4"
+        "node": ">=6.9.0"
       }
     },
-    "node_modules/conventional-changelog-core/node_modules/path-type": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
-      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+    "node_modules/@ljharb/through": {
+      "version": "2.3.12",
+      "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.12.tgz",
+      "integrity": "sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==",
       "dev": true,
+      "peer": true,
       "dependencies": {
-        "pify": "^3.0.0"
+        "call-bind": "^1.0.5"
       },
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/conventional-changelog-core/node_modules/pify": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-      "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/conventional-changelog-core/node_modules/read-pkg": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
-      "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
-      "dev": true,
-      "dependencies": {
-        "load-json-file": "^4.0.0",
-        "normalize-package-data": "^2.3.2",
-        "path-type": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
+    "node_modules/@types/minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
+      "dev": true
     },
-    "node_modules/conventional-changelog-core/node_modules/read-pkg-up": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
-      "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==",
+    "node_modules/@types/node": {
+      "version": "20.11.20",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz",
+      "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==",
       "dev": true,
-      "dependencies": {
-        "find-up": "^2.0.0",
-        "read-pkg": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/conventional-changelog-core/node_modules/read-pkg/node_modules/normalize-package-data": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
-      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
-      "dev": true,
-      "dependencies": {
-        "hosted-git-info": "^2.1.4",
-        "resolve": "^1.10.0",
-        "semver": "2 || 3 || 4 || 5",
-        "validate-npm-package-license": "^3.0.1"
-      }
-    },
-    "node_modules/conventional-changelog-core/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/conventional-changelog-ember": {
-      "version": "2.0.9",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz",
-      "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==",
-      "dev": true,
-      "dependencies": {
-        "q": "^1.5.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-eslint": {
-      "version": "3.0.9",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz",
-      "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==",
-      "dev": true,
-      "dependencies": {
-        "q": "^1.5.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-express": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz",
-      "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==",
-      "dev": true,
-      "dependencies": {
-        "q": "^1.5.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-jquery": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz",
-      "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==",
-      "dev": true,
-      "dependencies": {
-        "q": "^1.5.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-jshint": {
-      "version": "2.0.9",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz",
-      "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==",
-      "dev": true,
-      "dependencies": {
-        "compare-func": "^2.0.0",
-        "q": "^1.5.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-preset-loader": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz",
-      "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-tf-a": {
-      "resolved": "tools/conventional-changelog-tf-a",
-      "link": true
-    },
-    "node_modules/conventional-changelog-writer": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz",
-      "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==",
-      "dev": true,
-      "dependencies": {
-        "conventional-commits-filter": "^2.0.7",
-        "dateformat": "^3.0.0",
-        "handlebars": "^4.7.7",
-        "json-stringify-safe": "^5.0.1",
-        "lodash": "^4.17.15",
-        "meow": "^8.0.0",
-        "semver": "^6.0.0",
-        "split": "^1.0.0",
-        "through2": "^4.0.0"
-      },
-      "bin": {
-        "conventional-changelog-writer": "cli.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-changelog-writer/node_modules/semver": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/conventional-commit-types": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz",
-      "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==",
-      "dev": true
-    },
-    "node_modules/conventional-commits-filter": {
-      "version": "2.0.7",
-      "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz",
-      "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==",
-      "dev": true,
-      "dependencies": {
-        "lodash.ismatch": "^4.4.0",
-        "modify-values": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-commits-parser": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz",
-      "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==",
-      "dev": true,
-      "dependencies": {
-        "is-text-path": "^1.0.1",
-        "JSONStream": "^1.0.4",
-        "lodash": "^4.17.15",
-        "meow": "^8.0.0",
-        "split2": "^3.0.0",
-        "through2": "^4.0.0"
-      },
-      "bin": {
-        "conventional-commits-parser": "cli.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/conventional-recommended-bump": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz",
-      "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==",
-      "dev": true,
-      "dependencies": {
-        "concat-stream": "^2.0.0",
-        "conventional-changelog-preset-loader": "^2.3.4",
-        "conventional-commits-filter": "^2.0.7",
-        "conventional-commits-parser": "^3.2.0",
-        "git-raw-commits": "^2.0.8",
-        "git-semver-tags": "^4.1.1",
-        "meow": "^8.0.0",
-        "q": "^1.5.1"
-      },
-      "bin": {
-        "conventional-recommended-bump": "cli.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/core-util-is": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
-      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
-      "dev": true
-    },
-    "node_modules/cosmiconfig": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
-      "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/parse-json": "^4.0.0",
-        "import-fresh": "^3.2.1",
-        "parse-json": "^5.0.0",
-        "path-type": "^4.0.0",
-        "yaml": "^1.10.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/cosmiconfig-typescript-loader": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-2.0.2.tgz",
-      "integrity": "sha512-KmE+bMjWMXJbkWCeY4FJX/npHuZPNr9XF9q9CIQ/bpFwi1qHfCmSiKarrCcRa0LO4fWjk93pVoeRtJAkTGcYNw==",
-      "dev": true,
-      "dependencies": {
-        "cosmiconfig": "^7",
-        "ts-node": "^10.8.1"
-      },
-      "engines": {
-        "node": ">=12",
-        "npm": ">=6"
-      },
-      "peerDependencies": {
-        "@types/node": "*",
-        "cosmiconfig": ">=7",
-        "typescript": ">=3"
-      }
-    },
-    "node_modules/create-require": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
-      "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
-      "dev": true
-    },
-    "node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/cz-conventional-changelog": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz",
-      "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^2.4.1",
-        "commitizen": "^4.0.3",
-        "conventional-commit-types": "^3.0.0",
-        "lodash.map": "^4.5.1",
-        "longest": "^2.0.1",
-        "word-wrap": "^1.0.3"
-      },
-      "engines": {
-        "node": ">= 10"
-      },
-      "optionalDependencies": {
-        "@commitlint/load": ">6.1.1"
-      }
-    },
-    "node_modules/cz-conventional-changelog/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/cz-conventional-changelog/node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/cz-conventional-changelog/node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "dev": true,
-      "dependencies": {
-        "color-name": "1.1.3"
-      }
-    },
-    "node_modules/cz-conventional-changelog/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
-      "dev": true
-    },
-    "node_modules/cz-conventional-changelog/node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/cz-conventional-changelog/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/dargs": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz",
-      "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/dateformat": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
-      "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
-      "dev": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/decamelize": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/decamelize-keys": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
-      "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==",
-      "dev": true,
-      "dependencies": {
-        "decamelize": "^1.1.0",
-        "map-obj": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/decamelize-keys/node_modules/map-obj": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
-      "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/dedent": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
-      "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
-      "dev": true
-    },
-    "node_modules/defaults": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
-      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
-      "dev": true,
-      "dependencies": {
-        "clone": "^1.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/detect-file": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
-      "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/detect-indent": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
-      "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/detect-newline": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
-      "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/diff": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.3.1"
-      }
-    },
-    "node_modules/dot-prop": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
-      "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
-      "dev": true,
-      "dependencies": {
-        "is-obj": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/dotgitignore": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz",
-      "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==",
-      "dev": true,
-      "dependencies": {
-        "find-up": "^3.0.0",
-        "minimatch": "^3.0.4"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/dotgitignore/node_modules/find-up": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
-      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/dotgitignore/node_modules/locate-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
-      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^3.0.0",
-        "path-exists": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/dotgitignore/node_modules/p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "dev": true,
-      "dependencies": {
-        "p-try": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/dotgitignore/node_modules/p-locate": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
-      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/dotgitignore/node_modules/p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/dotgitignore/node_modules/path-exists": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-      "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true
-    },
-    "node_modules/error-ex": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
-      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
-      "dev": true,
-      "dependencies": {
-        "is-arrayish": "^0.2.1"
-      }
-    },
-    "node_modules/escalade": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/expand-tilde": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
-      "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
-      "dev": true,
-      "dependencies": {
-        "homedir-polyfill": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/external-editor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
-      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
-      "dev": true,
-      "dependencies": {
-        "chardet": "^0.7.0",
-        "iconv-lite": "^0.4.24",
-        "tmp": "^0.0.33"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true
-    },
-    "node_modules/fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true
-    },
-    "node_modules/figures": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
-      "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
-      "dev": true,
-      "dependencies": {
-        "escape-string-regexp": "^1.0.5"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-      "dev": true,
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/find-node-modules": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz",
-      "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==",
-      "dev": true,
-      "dependencies": {
-        "findup-sync": "^4.0.0",
-        "merge": "^2.1.1"
-      }
-    },
-    "node_modules/find-root": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
-      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
-      "dev": true
-    },
-    "node_modules/find-up": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
-      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^6.0.0",
-        "path-exists": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/findup-sync": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz",
-      "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==",
-      "dev": true,
-      "dependencies": {
-        "detect-file": "^1.0.0",
-        "is-glob": "^4.0.0",
-        "micromatch": "^4.0.2",
-        "resolve-dir": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
-      "dev": true
-    },
-    "node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
-    },
-    "node_modules/get-caller-file": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
-      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "dev": true,
-      "engines": {
-        "node": "6.* || 8.* || >= 10.*"
-      }
-    },
-    "node_modules/get-pkg-repo": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz",
-      "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==",
-      "dev": true,
-      "dependencies": {
-        "@hutson/parse-repository-url": "^3.0.0",
-        "hosted-git-info": "^4.0.0",
-        "through2": "^2.0.0",
-        "yargs": "^16.2.0"
-      },
-      "bin": {
-        "get-pkg-repo": "src/cli.js"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/get-pkg-repo/node_modules/cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^7.0.0"
-      }
-    },
-    "node_modules/get-pkg-repo/node_modules/readable-stream": {
-      "version": "2.3.7",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
-      "dev": true,
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
-      }
-    },
-    "node_modules/get-pkg-repo/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "dev": true
-    },
-    "node_modules/get-pkg-repo/node_modules/string_decoder": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/get-pkg-repo/node_modules/through2": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
-      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "~2.3.6",
-        "xtend": "~4.0.1"
-      }
-    },
-    "node_modules/get-pkg-repo/node_modules/yargs": {
-      "version": "16.2.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
-      "dev": true,
-      "dependencies": {
-        "cliui": "^7.0.2",
-        "escalade": "^3.1.1",
-        "get-caller-file": "^2.0.5",
-        "require-directory": "^2.1.1",
-        "string-width": "^4.2.0",
-        "y18n": "^5.0.5",
-        "yargs-parser": "^20.2.2"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/get-stream": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
-      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/git-raw-commits": {
-      "version": "2.0.11",
-      "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz",
-      "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==",
-      "dev": true,
-      "dependencies": {
-        "dargs": "^7.0.0",
-        "lodash": "^4.17.15",
-        "meow": "^8.0.0",
-        "split2": "^3.0.0",
-        "through2": "^4.0.0"
-      },
-      "bin": {
-        "git-raw-commits": "cli.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/git-remote-origin-url": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz",
-      "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==",
-      "dev": true,
-      "dependencies": {
-        "gitconfiglocal": "^1.0.0",
-        "pify": "^2.3.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/git-semver-tags": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz",
-      "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==",
-      "dev": true,
-      "dependencies": {
-        "meow": "^8.0.0",
-        "semver": "^6.0.0"
-      },
-      "bin": {
-        "git-semver-tags": "cli.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/git-semver-tags/node_modules/semver": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/gitconfiglocal": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz",
-      "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==",
-      "dev": true,
-      "dependencies": {
-        "ini": "^1.3.2"
-      }
-    },
-    "node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-      "dev": true,
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/global-dirs": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
-      "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==",
-      "dev": true,
-      "dependencies": {
-        "ini": "^1.3.4"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/global-modules": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
-      "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
-      "dev": true,
-      "dependencies": {
-        "global-prefix": "^1.0.1",
-        "is-windows": "^1.0.1",
-        "resolve-dir": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/global-prefix": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
-      "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
-      "dev": true,
-      "dependencies": {
-        "expand-tilde": "^2.0.2",
-        "homedir-polyfill": "^1.0.1",
-        "ini": "^1.3.4",
-        "is-windows": "^1.0.1",
-        "which": "^1.2.14"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/global-prefix/node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/graceful-fs": {
-      "version": "4.2.10",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
-      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
-      "dev": true
-    },
-    "node_modules/handlebars": {
-      "version": "4.7.7",
-      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
-      "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
-      "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.5",
-        "neo-async": "^2.6.0",
-        "source-map": "^0.6.1",
-        "wordwrap": "^1.0.0"
-      },
-      "bin": {
-        "handlebars": "bin/handlebars"
-      },
-      "engines": {
-        "node": ">=0.4.7"
-      },
-      "optionalDependencies": {
-        "uglify-js": "^3.1.4"
-      }
-    },
-    "node_modules/hard-rejection": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
-      "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/homedir-polyfill": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
-      "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
-      "dev": true,
-      "dependencies": {
-        "parse-passwd": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/hosted-git-info": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
-      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/human-signals": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
-      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
-      "dev": true,
-      "engines": {
-        "node": ">=10.17.0"
-      }
-    },
-    "node_modules/husky": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz",
-      "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==",
-      "dev": true,
-      "bin": {
-        "husky": "lib/bin.js"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/typicode"
-      }
-    },
-    "node_modules/iconv-lite": {
-      "version": "0.4.24",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
-      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "dev": true,
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ieee754": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
-      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/import-fresh": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
-      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
-      "dev": true,
-      "dependencies": {
-        "parent-module": "^1.0.0",
-        "resolve-from": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/import-fresh/node_modules/resolve-from": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/indent-string": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
-      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
-      "dev": true,
-      "dependencies": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "node_modules/inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true
-    },
-    "node_modules/ini": {
-      "version": "1.3.8",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
-      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
-      "dev": true
-    },
-    "node_modules/inquirer": {
-      "version": "8.2.4",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz",
-      "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==",
-      "dev": true,
-      "dependencies": {
-        "ansi-escapes": "^4.2.1",
-        "chalk": "^4.1.1",
-        "cli-cursor": "^3.1.0",
-        "cli-width": "^3.0.0",
-        "external-editor": "^3.0.3",
-        "figures": "^3.0.0",
-        "lodash": "^4.17.21",
-        "mute-stream": "0.0.8",
-        "ora": "^5.4.1",
-        "run-async": "^2.4.0",
-        "rxjs": "^7.5.5",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0",
-        "through": "^2.3.6",
-        "wrap-ansi": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
-    "node_modules/is-arrayish": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
-      "dev": true
-    },
-    "node_modules/is-core-module": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
-      "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
-      "dev": true,
-      "dependencies": {
-        "has": "^1.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dev": true,
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-interactive": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
-      "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/is-obj": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
-      "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-plain-obj": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-      "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-text-path": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz",
-      "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==",
-      "dev": true,
-      "dependencies": {
-        "text-extensions": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-unicode-supported": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
-      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-utf8": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
-      "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==",
-      "dev": true
-    },
-    "node_modules/is-windows": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
-      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
-      "dev": true
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
-      "dev": true
-    },
-    "node_modules/js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
-    },
-    "node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-      "dev": true,
-      "dependencies": {
-        "argparse": "^2.0.1"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/json-parse-better-errors": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
-      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
-      "dev": true
-    },
-    "node_modules/json-parse-even-better-errors": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
-      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
-      "dev": true
-    },
-    "node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
-    },
-    "node_modules/json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
-      "dev": true
-    },
-    "node_modules/jsonfile": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
-      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
-      "dev": true,
-      "dependencies": {
-        "universalify": "^2.0.0"
-      },
-      "optionalDependencies": {
-        "graceful-fs": "^4.1.6"
-      }
-    },
-    "node_modules/jsonparse": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
-      "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
-      "dev": true,
-      "engines": [
-        "node >= 0.2.0"
-      ]
-    },
-    "node_modules/JSONStream": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
-      "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
-      "dev": true,
-      "dependencies": {
-        "jsonparse": "^1.2.0",
-        "through": ">=2.2.7 <3"
-      },
-      "bin": {
-        "JSONStream": "bin.js"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/kind-of": {
-      "version": "6.0.3",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
-      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/lines-and-columns": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
-      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
-      "dev": true
-    },
-    "node_modules/load-json-file": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
-      "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
-      "dev": true,
-      "dependencies": {
-        "graceful-fs": "^4.1.2",
-        "parse-json": "^4.0.0",
-        "pify": "^3.0.0",
-        "strip-bom": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/load-json-file/node_modules/parse-json": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
-      "dev": true,
-      "dependencies": {
-        "error-ex": "^1.3.1",
-        "json-parse-better-errors": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/load-json-file/node_modules/pify": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-      "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/load-json-file/node_modules/strip-bom": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-      "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/locate-path": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
-      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lodash": {
-      "version": "4.17.21",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
-      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
-      "dev": true
-    },
-    "node_modules/lodash.ismatch": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz",
-      "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==",
-      "dev": true
-    },
-    "node_modules/lodash.map": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
-      "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==",
-      "dev": true
-    },
-    "node_modules/log-symbols": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^4.1.0",
-        "is-unicode-supported": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/longest": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz",
-      "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-      "dev": true,
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/make-error": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
-      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
-      "dev": true
-    },
-    "node_modules/map-obj": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
-      "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/meow": {
-      "version": "8.1.2",
-      "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz",
-      "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==",
-      "dev": true,
-      "dependencies": {
-        "@types/minimist": "^1.2.0",
-        "camelcase-keys": "^6.2.2",
-        "decamelize-keys": "^1.1.0",
-        "hard-rejection": "^2.1.0",
-        "minimist-options": "4.1.0",
-        "normalize-package-data": "^3.0.0",
-        "read-pkg-up": "^7.0.1",
-        "redent": "^3.0.0",
-        "trim-newlines": "^3.0.0",
-        "type-fest": "^0.18.0",
-        "yargs-parser": "^20.2.3"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/meow/node_modules/type-fest": {
-      "version": "0.18.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
-      "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/merge": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz",
-      "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==",
-      "dev": true
-    },
-    "node_modules/merge-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
-      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
-      "dev": true
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
-      "dev": true,
-      "dependencies": {
-        "braces": "^3.0.2",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/min-indent": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
-      "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/minimist": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
-      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
-      "dev": true
-    },
-    "node_modules/minimist-options": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
-      "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
-      "dev": true,
-      "dependencies": {
-        "arrify": "^1.0.1",
-        "is-plain-obj": "^1.1.0",
-        "kind-of": "^6.0.3"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/modify-values": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
-      "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/mute-stream": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
-      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
-      "dev": true
-    },
-    "node_modules/neo-async": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
-      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
-      "dev": true
-    },
-    "node_modules/normalize-package-data": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
-      "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
-      "dev": true,
-      "dependencies": {
-        "hosted-git-info": "^4.0.1",
-        "is-core-module": "^2.5.0",
-        "semver": "^7.3.4",
-        "validate-npm-package-license": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
-      "dev": true,
-      "dependencies": {
-        "wrappy": "1"
-      }
-    },
-    "node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "dev": true,
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/ora": {
-      "version": "5.4.1",
-      "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
-      "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
-      "dev": true,
-      "dependencies": {
-        "bl": "^4.1.0",
-        "chalk": "^4.1.0",
-        "cli-cursor": "^3.1.0",
-        "cli-spinners": "^2.5.0",
-        "is-interactive": "^1.0.0",
-        "is-unicode-supported": "^0.1.0",
-        "log-symbols": "^4.1.0",
-        "strip-ansi": "^6.0.0",
-        "wcwidth": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/os-tmpdir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/p-limit": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
-      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
-      "dev": true,
-      "dependencies": {
-        "yocto-queue": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/p-locate": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
-      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/p-try": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
-      "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/parent-module": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
-      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
-      "dev": true,
-      "dependencies": {
-        "callsites": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/parse-json": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
-      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
-      "dev": true,
-      "dependencies": {
-        "@babel/code-frame": "^7.0.0",
-        "error-ex": "^1.3.1",
-        "json-parse-even-better-errors": "^2.3.0",
-        "lines-and-columns": "^1.1.6"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/parse-passwd": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
-      "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/path-exists": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/path-parse": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
-      "dev": true
-    },
-    "node_modules/path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/process-nextick-args": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
-      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-      "dev": true
-    },
-    "node_modules/punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/q": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
-      "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.6.0",
-        "teleport": ">=0.2.0"
-      }
-    },
-    "node_modules/quick-lru": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
-      "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/read-pkg": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
-      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
-      "dev": true,
-      "dependencies": {
-        "@types/normalize-package-data": "^2.4.0",
-        "normalize-package-data": "^2.5.0",
-        "parse-json": "^5.0.0",
-        "type-fest": "^0.6.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/read-pkg-up": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
-      "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
-      "dev": true,
-      "dependencies": {
-        "find-up": "^4.1.0",
-        "read-pkg": "^5.2.0",
-        "type-fest": "^0.8.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/read-pkg-up/node_modules/find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^5.0.0",
-        "path-exists": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/read-pkg-up/node_modules/locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/read-pkg-up/node_modules/p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "dev": true,
-      "dependencies": {
-        "p-try": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/read-pkg-up/node_modules/p-locate": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/read-pkg-up/node_modules/p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/read-pkg-up/node_modules/type-fest": {
-      "version": "0.8.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
-      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/read-pkg/node_modules/hosted-git-info": {
-      "version": "2.8.9",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
-      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
-      "dev": true
-    },
-    "node_modules/read-pkg/node_modules/normalize-package-data": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
-      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
-      "dev": true,
-      "dependencies": {
-        "hosted-git-info": "^2.1.4",
-        "resolve": "^1.10.0",
-        "semver": "2 || 3 || 4 || 5",
-        "validate-npm-package-license": "^3.0.1"
-      }
-    },
-    "node_modules/read-pkg/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver"
-      }
-    },
-    "node_modules/read-pkg/node_modules/type-fest": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
-      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/readable-stream": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/redent": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
-      "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
-      "dev": true,
-      "dependencies": {
-        "indent-string": "^4.0.0",
-        "strip-indent": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/require-directory": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/resolve": {
-      "version": "1.22.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
-      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
-      "dev": true,
-      "dependencies": {
-        "is-core-module": "^2.9.0",
-        "path-parse": "^1.0.7",
-        "supports-preserve-symlinks-flag": "^1.0.0"
-      },
-      "bin": {
-        "resolve": "bin/resolve"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/resolve-dir": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
-      "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
-      "dev": true,
-      "dependencies": {
-        "expand-tilde": "^2.0.0",
-        "global-modules": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/resolve-from": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
-      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/resolve-global": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz",
-      "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==",
-      "dev": true,
-      "dependencies": {
-        "global-dirs": "^0.1.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/restore-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
-      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
-      "dev": true,
-      "dependencies": {
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/run-async": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
-      "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/rxjs": {
-      "version": "7.5.7",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz",
-      "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==",
-      "dev": true,
-      "dependencies": {
-        "tslib": "^2.1.0"
-      }
-    },
-    "node_modules/safe-buffer": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true
-    },
-    "node_modules/semver": {
-      "version": "7.3.7",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
-      "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
-      "dependencies": {
-        "shebang-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/signal-exit": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
-      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
-      "dev": true
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/spdx-correct": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
-      "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
-      "dev": true,
-      "dependencies": {
-        "spdx-expression-parse": "^3.0.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "node_modules/spdx-exceptions": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
-      "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
-      "dev": true
-    },
-    "node_modules/spdx-expression-parse": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
-      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
-      "dev": true,
-      "dependencies": {
-        "spdx-exceptions": "^2.1.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "node_modules/spdx-license-ids": {
-      "version": "3.0.12",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
-      "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
-      "dev": true
-    },
-    "node_modules/split": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
-      "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
-      "dev": true,
-      "dependencies": {
-        "through": "2"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/split2": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
-      "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "^3.0.0"
-      }
-    },
-    "node_modules/standard-version": {
-      "version": "9.5.0",
-      "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz",
-      "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==",
-      "dev": true,
-      "dependencies": {
-        "chalk": "^2.4.2",
-        "conventional-changelog": "3.1.25",
-        "conventional-changelog-config-spec": "2.1.0",
-        "conventional-changelog-conventionalcommits": "4.6.3",
-        "conventional-recommended-bump": "6.1.0",
-        "detect-indent": "^6.0.0",
-        "detect-newline": "^3.1.0",
-        "dotgitignore": "^2.1.0",
-        "figures": "^3.1.0",
-        "find-up": "^5.0.0",
-        "git-semver-tags": "^4.0.0",
-        "semver": "^7.1.1",
-        "stringify-package": "^1.0.1",
-        "yargs": "^16.0.0"
-      },
-      "bin": {
-        "standard-version": "bin/cli.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/standard-version/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/standard-version/node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/standard-version/node_modules/cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^7.0.0"
-      }
-    },
-    "node_modules/standard-version/node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "dev": true,
-      "dependencies": {
-        "color-name": "1.1.3"
-      }
-    },
-    "node_modules/standard-version/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
-      "dev": true
-    },
-    "node_modules/standard-version/node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/standard-version/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/standard-version/node_modules/yargs": {
-      "version": "16.2.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
-      "dev": true,
-      "dependencies": {
-        "cliui": "^7.0.2",
-        "escalade": "^3.1.1",
-        "get-caller-file": "^2.0.5",
-        "require-directory": "^2.1.1",
-        "string-width": "^4.2.0",
-        "y18n": "^5.0.5",
-        "yargs-parser": "^20.2.2"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/string_decoder": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "~5.2.0"
-      }
-    },
-    "node_modules/string-width": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-      "dev": true,
-      "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/stringify-package": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz",
-      "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==",
-      "dev": true
-    },
-    "node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-bom": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
-      "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-final-newline": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
-      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/strip-indent": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
-      "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
-      "dev": true,
-      "dependencies": {
-        "min-indent": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-json-comments": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
-      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/supports-preserve-symlinks-flag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
-      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/text-extensions": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz",
-      "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/through": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
-      "dev": true
-    },
-    "node_modules/through2": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
-      "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "3"
-      }
-    },
-    "node_modules/tmp": {
-      "version": "0.0.33",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
-      "dev": true,
-      "dependencies": {
-        "os-tmpdir": "~1.0.2"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dev": true,
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/trim-newlines": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
-      "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/ts-node": {
-      "version": "10.9.1",
-      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
-      "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
-      "dev": true,
-      "dependencies": {
-        "@cspotcode/source-map-support": "^0.8.0",
-        "@tsconfig/node10": "^1.0.7",
-        "@tsconfig/node12": "^1.0.7",
-        "@tsconfig/node14": "^1.0.0",
-        "@tsconfig/node16": "^1.0.2",
-        "acorn": "^8.4.1",
-        "acorn-walk": "^8.1.1",
-        "arg": "^4.1.0",
-        "create-require": "^1.1.0",
-        "diff": "^4.0.1",
-        "make-error": "^1.1.1",
-        "v8-compile-cache-lib": "^3.0.1",
-        "yn": "3.1.1"
-      },
-      "bin": {
-        "ts-node": "dist/bin.js",
-        "ts-node-cwd": "dist/bin-cwd.js",
-        "ts-node-esm": "dist/bin-esm.js",
-        "ts-node-script": "dist/bin-script.js",
-        "ts-node-transpile-only": "dist/bin-transpile.js",
-        "ts-script": "dist/bin-script-deprecated.js"
-      },
-      "peerDependencies": {
-        "@swc/core": ">=1.2.50",
-        "@swc/wasm": ">=1.2.50",
-        "@types/node": "*",
-        "typescript": ">=2.7"
-      },
-      "peerDependenciesMeta": {
-        "@swc/core": {
-          "optional": true
-        },
-        "@swc/wasm": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/tslib": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
-      "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
-      "dev": true
-    },
-    "node_modules/type-fest": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
-      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/typedarray": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-      "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
-      "dev": true
-    },
-    "node_modules/typescript": {
-      "version": "4.8.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
-      "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
-    "node_modules/uglify-js": {
-      "version": "3.17.3",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz",
-      "integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==",
-      "dev": true,
-      "optional": true,
-      "bin": {
-        "uglifyjs": "bin/uglifyjs"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/universalify": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
-      "dev": true,
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/uri-js": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
-      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
-      "dev": true,
-      "dependencies": {
-        "punycode": "^2.1.0"
-      }
-    },
-    "node_modules/util-deprecate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
-      "dev": true
-    },
-    "node_modules/v8-compile-cache-lib": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
-      "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
-      "dev": true
-    },
-    "node_modules/validate-npm-package-license": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
-      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
-      "dev": true,
-      "dependencies": {
-        "spdx-correct": "^3.0.0",
-        "spdx-expression-parse": "^3.0.0"
-      }
-    },
-    "node_modules/wcwidth": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
-      "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
-      "dev": true,
-      "dependencies": {
-        "defaults": "^1.0.3"
-      }
-    },
-    "node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/word-wrap": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
-      "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/wordwrap": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
-      "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
-      "dev": true
-    },
-    "node_modules/wrap-ansi": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
-    "node_modules/wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
-      "dev": true
-    },
-    "node_modules/xtend": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
-      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4"
-      }
-    },
-    "node_modules/y18n": {
-      "version": "5.0.8",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-      "dev": true
-    },
-    "node_modules/yaml": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
-      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/yargs": {
-      "version": "17.6.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
-      "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
-      "dev": true,
-      "dependencies": {
-        "cliui": "^8.0.1",
-        "escalade": "^3.1.1",
-        "get-caller-file": "^2.0.5",
-        "require-directory": "^2.1.1",
-        "string-width": "^4.2.3",
-        "y18n": "^5.0.5",
-        "yargs-parser": "^21.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/yargs-parser": {
-      "version": "20.2.9",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
-      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/yargs/node_modules/yargs-parser": {
-      "version": "21.1.1",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
-      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/yn": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
-      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yocto-queue": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
-      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "tools/conventional-changelog-tf-a": {
-      "version": "2.9.0",
-      "dev": true,
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "conventional-changelog-conventionalcommits": "^4.6.1",
-        "execa": "^5.1.1",
-        "lodash": "^4.17.21",
-        "q": "^1.5.1"
-      }
-    }
-  },
-  "dependencies": {
-    "@babel/code-frame": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
-      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
-      "dev": true,
-      "requires": {
-        "@babel/highlight": "^7.18.6"
-      }
-    },
-    "@babel/helper-validator-identifier": {
-      "version": "7.19.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
-      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
-      "dev": true
-    },
-    "@babel/highlight": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
-      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-validator-identifier": "^7.18.6",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        }
-      }
-    },
-    "@commitlint/cli": {
-      "version": "16.3.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.3.0.tgz",
-      "integrity": "sha512-P+kvONlfsuTMnxSwWE1H+ZcPMY3STFaHb2kAacsqoIkNx66O0T7sTpBxpxkMrFPyhkJiLJnJWMhk4bbvYD3BMA==",
-      "dev": true,
-      "requires": {
-        "@commitlint/format": "^16.2.1",
-        "@commitlint/lint": "^16.2.4",
-        "@commitlint/load": "^16.3.0",
-        "@commitlint/read": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "lodash": "^4.17.19",
-        "resolve-from": "5.0.0",
-        "resolve-global": "1.0.0",
-        "yargs": "^17.0.0"
-      }
-    },
-    "@commitlint/config-conventional": {
-      "version": "16.2.4",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.2.4.tgz",
-      "integrity": "sha512-av2UQJa3CuE5P0dzxj/o/B9XVALqYzEViHrMXtDrW9iuflrqCStWBAioijppj9URyz6ONpohJKAtSdgAOE0gkA==",
-      "dev": true,
-      "requires": {
-        "conventional-changelog-conventionalcommits": "^4.3.1"
-      }
-    },
-    "@commitlint/config-validator": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.2.1.tgz",
-      "integrity": "sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw==",
-      "dev": true,
-      "requires": {
-        "@commitlint/types": "^16.2.1",
-        "ajv": "^6.12.6"
-      }
-    },
-    "@commitlint/cz-commitlint": {
-      "version": "16.3.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/cz-commitlint/-/cz-commitlint-16.3.0.tgz",
-      "integrity": "sha512-Q+QLQmSIHEgzI18F3/7mqq3vwL0IN9k+Tjp9Um4adFnRXMtUTnEa0er0CXAXxWvoA/x/6nt3t7faAv2HugDIGg==",
-      "dev": true,
-      "requires": {
-        "@commitlint/ensure": "^16.2.1",
-        "@commitlint/load": "^16.3.0",
-        "@commitlint/types": "^16.2.1",
-        "chalk": "^4.1.0",
-        "lodash": "^4.17.21",
-        "word-wrap": "^1.2.3"
-      }
-    },
-    "@commitlint/ensure": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.2.1.tgz",
-      "integrity": "sha512-/h+lBTgf1r5fhbDNHOViLuej38i3rZqTQnBTk+xEg+ehOwQDXUuissQ5GsYXXqI5uGy+261ew++sT4EA3uBJ+A==",
-      "dev": true,
-      "requires": {
-        "@commitlint/types": "^16.2.1",
-        "lodash": "^4.17.19"
-      }
-    },
-    "@commitlint/execute-rule": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.2.1.tgz",
-      "integrity": "sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g==",
-      "dev": true
-    },
-    "@commitlint/format": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.2.1.tgz",
-      "integrity": "sha512-Yyio9bdHWmNDRlEJrxHKglamIk3d6hC0NkEUW6Ti6ipEh2g0BAhy8Od6t4vLhdZRa1I2n+gY13foy+tUgk0i1Q==",
-      "dev": true,
-      "requires": {
-        "@commitlint/types": "^16.2.1",
-        "chalk": "^4.0.0"
-      }
-    },
-    "@commitlint/is-ignored": {
-      "version": "16.2.4",
-      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.2.4.tgz",
-      "integrity": "sha512-Lxdq9aOAYCOOOjKi58ulbwK/oBiiKz+7Sq0+/SpFIEFwhHkIVugvDvWjh2VRBXmRC/x5lNcjDcYEwS/uYUvlYQ==",
-      "dev": true,
-      "requires": {
-        "@commitlint/types": "^16.2.1",
-        "semver": "7.3.7"
-      }
-    },
-    "@commitlint/lint": {
-      "version": "16.2.4",
-      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.2.4.tgz",
-      "integrity": "sha512-AUDuwOxb2eGqsXbTMON3imUGkc1jRdtXrbbohiLSCSk3jFVXgJLTMaEcr39pR00N8nE9uZ+V2sYaiILByZVmxQ==",
-      "dev": true,
-      "requires": {
-        "@commitlint/is-ignored": "^16.2.4",
-        "@commitlint/parse": "^16.2.1",
-        "@commitlint/rules": "^16.2.4",
-        "@commitlint/types": "^16.2.1"
-      }
-    },
-    "@commitlint/load": {
-      "version": "16.3.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.3.0.tgz",
-      "integrity": "sha512-3tykjV/iwbkv2FU9DG+NZ/JqmP0Nm3b7aDwgCNQhhKV5P74JAuByULkafnhn+zsFGypG1qMtI5u+BZoa9APm0A==",
-      "dev": true,
-      "requires": {
-        "@commitlint/config-validator": "^16.2.1",
-        "@commitlint/execute-rule": "^16.2.1",
-        "@commitlint/resolve-extends": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "@types/node": ">=12",
-        "chalk": "^4.0.0",
-        "cosmiconfig": "^7.0.0",
-        "cosmiconfig-typescript-loader": "^2.0.0",
-        "lodash": "^4.17.19",
-        "resolve-from": "^5.0.0",
-        "typescript": "^4.4.3"
-      }
-    },
-    "@commitlint/message": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.2.1.tgz",
-      "integrity": "sha512-2eWX/47rftViYg7a3axYDdrgwKv32mxbycBJT6OQY/MJM7SUfYNYYvbMFOQFaA4xIVZt7t2Alyqslbl6blVwWw==",
-      "dev": true
-    },
-    "@commitlint/parse": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.2.1.tgz",
-      "integrity": "sha512-2NP2dDQNL378VZYioLrgGVZhWdnJO4nAxQl5LXwYb08nEcN+cgxHN1dJV8OLJ5uxlGJtDeR8UZZ1mnQ1gSAD/g==",
-      "dev": true,
-      "requires": {
-        "@commitlint/types": "^16.2.1",
-        "conventional-changelog-angular": "^5.0.11",
-        "conventional-commits-parser": "^3.2.2"
-      }
-    },
-    "@commitlint/read": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.2.1.tgz",
-      "integrity": "sha512-tViXGuaxLTrw2r7PiYMQOFA2fueZxnnt0lkOWqKyxT+n2XdEMGYcI9ID5ndJKXnfPGPppD0w/IItKsIXlZ+alw==",
-      "dev": true,
-      "requires": {
-        "@commitlint/top-level": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "fs-extra": "^10.0.0",
-        "git-raw-commits": "^2.0.0"
-      }
-    },
-    "@commitlint/resolve-extends": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.2.1.tgz",
-      "integrity": "sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg==",
-      "dev": true,
-      "requires": {
-        "@commitlint/config-validator": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "import-fresh": "^3.0.0",
-        "lodash": "^4.17.19",
-        "resolve-from": "^5.0.0",
-        "resolve-global": "^1.0.0"
-      }
-    },
-    "@commitlint/rules": {
-      "version": "16.2.4",
-      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.2.4.tgz",
-      "integrity": "sha512-rK5rNBIN2ZQNQK+I6trRPK3dWa0MtaTN4xnwOma1qxa4d5wQMQJtScwTZjTJeallFxhOgbNOgr48AMHkdounVg==",
-      "dev": true,
-      "requires": {
-        "@commitlint/ensure": "^16.2.1",
-        "@commitlint/message": "^16.2.1",
-        "@commitlint/to-lines": "^16.2.1",
-        "@commitlint/types": "^16.2.1",
-        "execa": "^5.0.0"
-      }
-    },
-    "@commitlint/to-lines": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.2.1.tgz",
-      "integrity": "sha512-9/VjpYj5j1QeY3eiog1zQWY6axsdWAc0AonUUfyZ7B0MVcRI0R56YsHAfzF6uK/g/WwPZaoe4Lb1QCyDVnpVaQ==",
-      "dev": true
-    },
-    "@commitlint/top-level": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.2.1.tgz",
-      "integrity": "sha512-lS6GSieHW9y6ePL73ied71Z9bOKyK+Ib9hTkRsB8oZFAyQZcyRwq2w6nIa6Fngir1QW51oKzzaXfJL94qwImyw==",
-      "dev": true,
-      "requires": {
-        "find-up": "^5.0.0"
-      }
-    },
-    "@commitlint/types": {
-      "version": "16.2.1",
-      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.2.1.tgz",
-      "integrity": "sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA==",
-      "dev": true,
-      "requires": {
-        "chalk": "^4.0.0"
-      }
-    },
-    "@cspotcode/source-map-support": {
-      "version": "0.8.1",
-      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
-      "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
-      "dev": true,
-      "requires": {
-        "@jridgewell/trace-mapping": "0.3.9"
-      }
-    },
-    "@hutson/parse-repository-url": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz",
-      "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==",
-      "dev": true
-    },
-    "@jridgewell/resolve-uri": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
-      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
-      "dev": true
-    },
-    "@jridgewell/sourcemap-codec": {
-      "version": "1.4.14",
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
-      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
-      "dev": true
-    },
-    "@jridgewell/trace-mapping": {
-      "version": "0.3.9",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
-      "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
-      "dev": true,
-      "requires": {
-        "@jridgewell/resolve-uri": "^3.0.3",
-        "@jridgewell/sourcemap-codec": "^1.4.10"
-      }
-    },
-    "@tsconfig/node10": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
-      "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
-      "dev": true
-    },
-    "@tsconfig/node12": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
-      "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
-      "dev": true
-    },
-    "@tsconfig/node14": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
-      "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
-      "dev": true
-    },
-    "@tsconfig/node16": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
-      "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
-      "dev": true
-    },
-    "@types/minimist": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
-      "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
-      "dev": true
-    },
-    "@types/node": {
-      "version": "18.8.3",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.3.tgz",
-      "integrity": "sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==",
-      "dev": true
-    },
-    "@types/normalize-package-data": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
-      "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
-      "dev": true
-    },
-    "@types/parse-json": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
-      "dev": true
-    },
-    "acorn": {
-      "version": "8.8.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
-      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
-      "dev": true
+      "peer": true,
+      "dependencies": {
+        "undici-types": "~5.26.4"
+      }
     },
-    "acorn-walk": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
-      "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+    "node_modules/@types/normalize-package-data": {
+      "version": "2.4.4",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+      "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
       "dev": true
     },
-    "add-stream": {
+    "node_modules/add-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz",
       "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==",
       "dev": true
     },
-    "ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+    "node_modules/ajv": {
+      "version": "8.12.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+      "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2",
         "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
       }
     },
-    "ansi-escapes": {
+    "node_modules/ansi-escapes": {
       "version": "4.3.2",
       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
       "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "type-fest": "^0.21.3"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "ansi-regex": {
+    "node_modules/ansi-regex": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
       "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "ansi-styles": {
+    "node_modules/ansi-styles": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
       "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
-    "arg": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
-      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
-      "dev": true
-    },
-    "argparse": {
+    "node_modules/argparse": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
       "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
       "dev": true
     },
-    "array-ify": {
+    "node_modules/array-ify": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
       "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
       "dev": true
     },
-    "arrify": {
+    "node_modules/arrify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
       "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "at-least-node": {
+    "node_modules/at-least-node": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
       "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
     },
-    "balanced-match": {
+    "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
-    "base64-js": {
+    "node_modules/base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
       "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "dev": true
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
     },
-    "bl": {
+    "node_modules/bl": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
       "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "buffer": "^5.5.0",
         "inherits": "^2.0.4",
         "readable-stream": "^3.4.0"
       }
     },
-    "brace-expansion": {
+    "node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "balanced-match": "^1.0.0",
         "concat-map": "0.0.1"
       }
     },
-    "braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+    "node_modules/braces": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
       "dev": true,
-      "requires": {
-        "fill-range": "^7.0.1"
+      "dependencies": {
+        "fill-range": "^7.1.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "buffer": {
+    "node_modules/buffer": {
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
       "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
       "dev": true,
-      "requires": {
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
         "base64-js": "^1.3.1",
         "ieee754": "^1.1.13"
       }
     },
-    "buffer-from": {
+    "node_modules/buffer-from": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
       "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
       "dev": true
     },
-    "cachedir": {
+    "node_modules/cachedir": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
       "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+      "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "es-define-property": "^1.0.0",
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2",
+        "get-intrinsic": "^1.2.4",
+        "set-function-length": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
-    "callsites": {
+    "node_modules/callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
       "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "camelcase": {
+    "node_modules/camelcase": {
       "version": "5.3.1",
       "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
       "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "camelcase-keys": {
+    "node_modules/camelcase-keys": {
       "version": "6.2.2",
       "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
       "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "camelcase": "^5.3.1",
         "map-obj": "^4.0.0",
         "quick-lru": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "chalk": {
+    "node_modules/chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
       "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "ansi-styles": "^4.1.0",
         "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "chardet": {
+    "node_modules/chardet": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
       "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
       "dev": true
     },
-    "cli-cursor": {
+    "node_modules/cli-cursor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
       "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "restore-cursor": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "cli-spinners": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz",
-      "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==",
-      "dev": true
+    "node_modules/cli-spinners": {
+      "version": "2.9.2",
+      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+      "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "cli-width": {
+    "node_modules/cli-width": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
       "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">= 10"
+      }
     },
-    "cliui": {
+    "node_modules/cliui": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
       "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "string-width": "^4.2.0",
         "strip-ansi": "^6.0.1",
         "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/cliui/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
       }
     },
-    "clone": {
+    "node_modules/clone": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
       "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.8"
+      }
     },
-    "color-convert": {
+    "node_modules/color-convert": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
       "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
       }
     },
-    "color-name": {
+    "node_modules/color-name": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
-    "commitizen": {
-      "version": "4.2.5",
-      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.2.5.tgz",
-      "integrity": "sha512-9sXju8Qrz1B4Tw7kC5KhnvwYQN88qs2zbiB8oyMsnXZyJ24PPGiNM3nHr73d32dnE3i8VJEXddBFIbOgYSEXtQ==",
+    "node_modules/commitizen": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.0.tgz",
+      "integrity": "sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "cachedir": "2.3.0",
         "cz-conventional-changelog": "3.3.0",
         "dedent": "0.7.0",
@@ -4648,62 +1404,117 @@
         "find-root": "1.1.0",
         "fs-extra": "9.1.0",
         "glob": "7.2.3",
-        "inquirer": "8.2.4",
+        "inquirer": "8.2.5",
         "is-utf8": "^0.2.1",
         "lodash": "4.17.21",
-        "minimist": "1.2.6",
+        "minimist": "1.2.7",
         "strip-bom": "4.0.0",
         "strip-json-comments": "3.1.1"
       },
+      "bin": {
+        "commitizen": "bin/commitizen",
+        "cz": "bin/git-cz",
+        "git-cz": "bin/git-cz"
+      },
+      "engines": {
+        "node": ">= 12"
+      }
+    },
+    "node_modules/commitizen/node_modules/fs-extra": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+      "dev": true,
+      "dependencies": {
+        "at-least-node": "^1.0.0",
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/commitizen/node_modules/inquirer": {
+      "version": "8.2.5",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz",
+      "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==",
+      "dev": true,
       "dependencies": {
-        "fs-extra": {
-          "version": "9.1.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
-          "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
-          "dev": true,
-          "requires": {
-            "at-least-node": "^1.0.0",
-            "graceful-fs": "^4.2.0",
-            "jsonfile": "^6.0.1",
-            "universalify": "^2.0.0"
-          }
-        }
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^4.1.1",
+        "cli-cursor": "^3.1.0",
+        "cli-width": "^3.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^3.0.0",
+        "lodash": "^4.17.21",
+        "mute-stream": "0.0.8",
+        "ora": "^5.4.1",
+        "run-async": "^2.4.0",
+        "rxjs": "^7.5.5",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "through": "^2.3.6",
+        "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/commitizen/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
       }
     },
-    "compare-func": {
+    "node_modules/compare-func": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
       "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "array-ify": "^1.0.0",
         "dot-prop": "^5.1.0"
       }
     },
-    "concat-map": {
+    "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
       "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
       "dev": true
     },
-    "concat-stream": {
+    "node_modules/concat-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
       "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
       "dev": true,
-      "requires": {
+      "engines": [
+        "node >= 6.0"
+      ],
+      "dependencies": {
         "buffer-from": "^1.0.0",
         "inherits": "^2.0.3",
         "readable-stream": "^3.0.2",
         "typedarray": "^0.0.6"
       }
     },
-    "conventional-changelog": {
+    "node_modules/conventional-changelog": {
       "version": "3.1.25",
       "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz",
       "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "conventional-changelog-angular": "^5.0.12",
         "conventional-changelog-atom": "^2.0.8",
         "conventional-changelog-codemirror": "^2.0.8",
@@ -4715,59 +1526,74 @@
         "conventional-changelog-jquery": "^3.0.11",
         "conventional-changelog-jshint": "^2.0.9",
         "conventional-changelog-preset-loader": "^2.3.4"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-angular": {
+    "node_modules/conventional-changelog-angular": {
       "version": "5.0.13",
       "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz",
       "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "compare-func": "^2.0.0",
         "q": "^1.5.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-atom": {
+    "node_modules/conventional-changelog-atom": {
       "version": "2.0.8",
       "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz",
       "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "q": "^1.5.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-codemirror": {
+    "node_modules/conventional-changelog-codemirror": {
       "version": "2.0.8",
       "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz",
       "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "q": "^1.5.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-config-spec": {
+    "node_modules/conventional-changelog-config-spec": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz",
       "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==",
       "dev": true
     },
-    "conventional-changelog-conventionalcommits": {
+    "node_modules/conventional-changelog-conventionalcommits": {
       "version": "4.6.3",
       "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz",
       "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "compare-func": "^2.0.0",
         "lodash": "^4.17.15",
         "q": "^1.5.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-core": {
+    "node_modules/conventional-changelog-core": {
       "version": "4.2.4",
       "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz",
       "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "add-stream": "^1.0.0",
         "conventional-changelog-writer": "^5.0.0",
         "conventional-commits-parser": "^3.2.0",
@@ -4783,181 +1609,223 @@
         "read-pkg-up": "^3.0.0",
         "through2": "^4.0.0"
       },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/find-up": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+      "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+      "dev": true,
       "dependencies": {
-        "find-up": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
-          "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
-          "dev": true,
-          "requires": {
-            "locate-path": "^2.0.0"
-          }
-        },
-        "hosted-git-info": {
-          "version": "2.8.9",
-          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
-          "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
-          "dev": true
-        },
-        "locate-path": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
-          "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
-          "dev": true,
-          "requires": {
-            "p-locate": "^2.0.0",
-            "path-exists": "^3.0.0"
-          }
-        },
-        "p-limit": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
-          "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
-          "dev": true,
-          "requires": {
-            "p-try": "^1.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
-          "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
-          "dev": true,
-          "requires": {
-            "p-limit": "^1.1.0"
-          }
-        },
-        "path-exists": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-          "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
-          "dev": true
-        },
-        "path-type": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
-          "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
-          "dev": true,
-          "requires": {
-            "pify": "^3.0.0"
-          }
-        },
-        "pify": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-          "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
-          "dev": true
-        },
-        "read-pkg": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
-          "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
-          "dev": true,
-          "requires": {
-            "load-json-file": "^4.0.0",
-            "normalize-package-data": "^2.3.2",
-            "path-type": "^3.0.0"
-          },
-          "dependencies": {
-            "normalize-package-data": {
-              "version": "2.5.0",
-              "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
-              "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
-              "dev": true,
-              "requires": {
-                "hosted-git-info": "^2.1.4",
-                "resolve": "^1.10.0",
-                "semver": "2 || 3 || 4 || 5",
-                "validate-npm-package-license": "^3.0.1"
-              }
-            }
-          }
-        },
-        "read-pkg-up": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
-          "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==",
-          "dev": true,
-          "requires": {
-            "find-up": "^2.0.0",
-            "read-pkg": "^3.0.0"
-          }
-        },
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        }
+        "locate-path": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "dev": true
+    },
+    "node_modules/conventional-changelog-core/node_modules/locate-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+      "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^2.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/p-limit": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+      "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/p-locate": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+      "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/path-type": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+      "dev": true,
+      "dependencies": {
+        "pify": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/read-pkg": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+      "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
+      "dev": true,
+      "dependencies": {
+        "load-json-file": "^4.0.0",
+        "normalize-package-data": "^2.3.2",
+        "path-type": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/read-pkg-up": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
+      "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==",
+      "dev": true,
+      "dependencies": {
+        "find-up": "^2.0.0",
+        "read-pkg": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
       }
     },
-    "conventional-changelog-ember": {
+    "node_modules/conventional-changelog-core/node_modules/read-pkg/node_modules/normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/conventional-changelog-core/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/conventional-changelog-ember": {
       "version": "2.0.9",
       "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz",
       "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "q": "^1.5.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-eslint": {
+    "node_modules/conventional-changelog-eslint": {
       "version": "3.0.9",
       "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz",
       "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "q": "^1.5.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-express": {
+    "node_modules/conventional-changelog-express": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz",
       "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "q": "^1.5.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-jquery": {
+    "node_modules/conventional-changelog-jquery": {
       "version": "3.0.11",
       "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz",
       "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "q": "^1.5.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-jshint": {
+    "node_modules/conventional-changelog-jshint": {
       "version": "2.0.9",
       "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz",
       "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "compare-func": "^2.0.0",
         "q": "^1.5.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-preset-loader": {
+    "node_modules/conventional-changelog-preset-loader": {
       "version": "2.3.4",
       "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz",
       "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==",
-      "dev": true
-    },
-    "conventional-changelog-tf-a": {
-      "version": "file:tools/conventional-changelog-tf-a",
-      "requires": {
-        "conventional-changelog-conventionalcommits": "^4.6.1",
-        "execa": "^5.1.1",
-        "lodash": "^4.17.21",
-        "q": "^1.5.1"
+      "dev": true,
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-changelog-writer": {
+    "node_modules/conventional-changelog-tf-a": {
+      "resolved": "tools/conventional-changelog-tf-a",
+      "link": true
+    },
+    "node_modules/conventional-changelog-writer": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz",
       "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "conventional-commits-filter": "^2.0.7",
         "dateformat": "^3.0.0",
         "handlebars": "^4.7.7",
@@ -4968,51 +1836,67 @@
         "split": "^1.0.0",
         "through2": "^4.0.0"
       },
-      "dependencies": {
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "dev": true
-        }
+      "bin": {
+        "conventional-changelog-writer": "cli.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/conventional-changelog-writer/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
       }
     },
-    "conventional-commit-types": {
+    "node_modules/conventional-commit-types": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz",
       "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==",
       "dev": true
     },
-    "conventional-commits-filter": {
+    "node_modules/conventional-commits-filter": {
       "version": "2.0.7",
       "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz",
       "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "lodash.ismatch": "^4.4.0",
         "modify-values": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-commits-parser": {
+    "node_modules/conventional-commits-parser": {
       "version": "3.2.4",
       "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz",
       "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "is-text-path": "^1.0.1",
         "JSONStream": "^1.0.4",
         "lodash": "^4.17.15",
         "meow": "^8.0.0",
         "split2": "^3.0.0",
         "through2": "^4.0.0"
+      },
+      "bin": {
+        "conventional-commits-parser": "cli.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "conventional-recommended-bump": {
+    "node_modules/conventional-recommended-bump": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz",
       "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "concat-stream": "^2.0.0",
         "conventional-changelog-preset-loader": "^2.3.4",
         "conventional-commits-filter": "^2.0.7",
@@ -5021,61 +1905,83 @@
         "git-semver-tags": "^4.1.1",
         "meow": "^8.0.0",
         "q": "^1.5.1"
+      },
+      "bin": {
+        "conventional-recommended-bump": "cli.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "core-util-is": {
+    "node_modules/core-util-is": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
       "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
       "dev": true
     },
-    "cosmiconfig": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
-      "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
+    "node_modules/cosmiconfig": {
+      "version": "8.3.6",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
+      "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
       "dev": true,
-      "requires": {
-        "@types/parse-json": "^4.0.0",
-        "import-fresh": "^3.2.1",
-        "parse-json": "^5.0.0",
-        "path-type": "^4.0.0",
-        "yaml": "^1.10.0"
+      "dependencies": {
+        "import-fresh": "^3.3.0",
+        "js-yaml": "^4.1.0",
+        "parse-json": "^5.2.0",
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/d-fischer"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.9.5"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
       }
     },
-    "cosmiconfig-typescript-loader": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-2.0.2.tgz",
-      "integrity": "sha512-KmE+bMjWMXJbkWCeY4FJX/npHuZPNr9XF9q9CIQ/bpFwi1qHfCmSiKarrCcRa0LO4fWjk93pVoeRtJAkTGcYNw==",
+    "node_modules/cosmiconfig-typescript-loader": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz",
+      "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==",
       "dev": true,
-      "requires": {
-        "cosmiconfig": "^7",
-        "ts-node": "^10.8.1"
+      "dependencies": {
+        "jiti": "^1.19.1"
+      },
+      "engines": {
+        "node": ">=v16"
+      },
+      "peerDependencies": {
+        "@types/node": "*",
+        "cosmiconfig": ">=8.2",
+        "typescript": ">=4"
       }
     },
-    "create-require": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
-      "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
-      "dev": true
-    },
-    "cross-spawn": {
+    "node_modules/cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
       "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "path-key": "^3.1.0",
         "shebang-command": "^2.0.0",
         "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "cz-conventional-changelog": {
+    "node_modules/cz-conventional-changelog": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz",
       "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==",
       "dev": true,
-      "requires": {
-        "@commitlint/load": ">6.1.1",
+      "dependencies": {
         "chalk": "^2.4.1",
         "commitizen": "^4.0.3",
         "conventional-commit-types": "^3.0.0",
@@ -5083,237 +1989,347 @@
         "longest": "^2.0.1",
         "word-wrap": "^1.0.3"
       },
+      "engines": {
+        "node": ">= 10"
+      },
+      "optionalDependencies": {
+        "@commitlint/load": ">6.1.1"
+      }
+    },
+    "node_modules/cz-conventional-changelog/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
       "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        }
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/cz-conventional-changelog/node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/cz-conventional-changelog/node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/cz-conventional-changelog/node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
+    },
+    "node_modules/cz-conventional-changelog/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/cz-conventional-changelog/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
       }
     },
-    "dargs": {
+    "node_modules/dargs": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz",
       "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "dateformat": {
+    "node_modules/dateformat": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
       "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
     },
-    "decamelize": {
+    "node_modules/decamelize": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
       "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "decamelize-keys": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
-      "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==",
+    "node_modules/decamelize-keys": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
+      "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "decamelize": "^1.1.0",
         "map-obj": "^1.0.0"
       },
-      "dependencies": {
-        "map-obj": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
-          "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
-          "dev": true
-        }
+      "engines": {
+        "node": ">=0.10.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/decamelize-keys/node_modules/map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "dedent": {
+    "node_modules/dedent": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
       "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
       "dev": true
     },
-    "defaults": {
+    "node_modules/defaults": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
       "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "clone": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/define-data-property": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+      "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "es-define-property": "^1.0.0",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "detect-file": {
+    "node_modules/detect-file": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
       "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "detect-indent": {
+    "node_modules/detect-indent": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
       "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "detect-newline": {
+    "node_modules/detect-newline": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
       "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
-      "dev": true
-    },
-    "diff": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "dot-prop": {
+    "node_modules/dot-prop": {
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
       "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "is-obj": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "dotgitignore": {
+    "node_modules/dotgitignore": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz",
       "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "find-up": "^3.0.0",
         "minimatch": "^3.0.4"
       },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/dotgitignore/node_modules/find-up": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/dotgitignore/node_modules/locate-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+      "dev": true,
       "dependencies": {
-        "find-up": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
-          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
-          "dev": true,
-          "requires": {
-            "locate-path": "^3.0.0"
-          }
-        },
-        "locate-path": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
-          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
-          "dev": true,
-          "requires": {
-            "p-locate": "^3.0.0",
-            "path-exists": "^3.0.0"
-          }
-        },
-        "p-limit": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-          "dev": true,
-          "requires": {
-            "p-try": "^2.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
-          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
-          "dev": true,
-          "requires": {
-            "p-limit": "^2.0.0"
-          }
-        },
-        "p-try": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-          "dev": true
-        },
-        "path-exists": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-          "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
-          "dev": true
-        }
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/dotgitignore/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/dotgitignore/node_modules/p-locate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/dotgitignore/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
       }
     },
-    "emoji-regex": {
+    "node_modules/dotgitignore/node_modules/path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/emoji-regex": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
       "dev": true
     },
-    "error-ex": {
+    "node_modules/error-ex": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
       "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "is-arrayish": "^0.2.1"
       }
     },
-    "escalade": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
-      "dev": true
+    "node_modules/es-define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+      "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "get-intrinsic": "^1.2.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+      "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "escape-string-regexp": {
+    "node_modules/escape-string-regexp": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
       "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
     },
-    "execa": {
+    "node_modules/execa": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
       "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "cross-spawn": "^7.0.3",
         "get-stream": "^6.0.0",
         "human-signals": "^2.1.0",
@@ -5323,761 +2339,1195 @@
         "onetime": "^5.1.2",
         "signal-exit": "^3.0.3",
         "strip-final-newline": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
       }
     },
-    "expand-tilde": {
+    "node_modules/expand-tilde": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
       "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "homedir-polyfill": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "external-editor": {
+    "node_modules/external-editor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
       "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "chardet": "^0.7.0",
         "iconv-lite": "^0.4.24",
         "tmp": "^0.0.33"
+      },
+      "engines": {
+        "node": ">=4"
       }
     },
-    "fast-deep-equal": {
+    "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
       "dev": true
     },
-    "fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true
-    },
-    "figures": {
+    "node_modules/figures": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
       "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "escape-string-regexp": "^1.0.5"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+    "node_modules/fill-range": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "find-node-modules": {
+    "node_modules/find-node-modules": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz",
       "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "findup-sync": "^4.0.0",
         "merge": "^2.1.1"
       }
     },
-    "find-root": {
+    "node_modules/find-root": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
       "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
       "dev": true
     },
-    "find-up": {
+    "node_modules/find-up": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
       "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "locate-path": "^6.0.0",
         "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "findup-sync": {
+    "node_modules/findup-sync": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz",
       "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "detect-file": "^1.0.0",
         "is-glob": "^4.0.0",
         "micromatch": "^4.0.2",
         "resolve-dir": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "fs-extra": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "^4.2.0",
-        "jsonfile": "^6.0.1",
-        "universalify": "^2.0.0"
-      }
-    },
-    "fs.realpath": {
+    "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
       "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
       "dev": true
     },
-    "function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
-    "get-caller-file": {
+    "node_modules/get-caller-file": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
       "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
+      "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3",
+        "hasown": "^2.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
-    "get-pkg-repo": {
+    "node_modules/get-pkg-repo": {
       "version": "4.2.1",
       "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz",
       "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@hutson/parse-repository-url": "^3.0.0",
         "hosted-git-info": "^4.0.0",
         "through2": "^2.0.0",
         "yargs": "^16.2.0"
       },
+      "bin": {
+        "get-pkg-repo": "src/cli.js"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/get-pkg-repo/node_modules/cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "dev": true,
       "dependencies": {
-        "cliui": {
-          "version": "7.0.4",
-          "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-          "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-          "dev": true,
-          "requires": {
-            "string-width": "^4.2.0",
-            "strip-ansi": "^6.0.0",
-            "wrap-ansi": "^7.0.0"
-          }
-        },
-        "readable-stream": {
-          "version": "2.3.7",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "safe-buffer": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-          "dev": true
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        },
-        "through2": {
-          "version": "2.0.5",
-          "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
-          "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
-          "dev": true,
-          "requires": {
-            "readable-stream": "~2.3.6",
-            "xtend": "~4.0.1"
-          }
-        },
-        "yargs": {
-          "version": "16.2.0",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-          "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
-          "dev": true,
-          "requires": {
-            "cliui": "^7.0.2",
-            "escalade": "^3.1.1",
-            "get-caller-file": "^2.0.5",
-            "require-directory": "^2.1.1",
-            "string-width": "^4.2.0",
-            "y18n": "^5.0.5",
-            "yargs-parser": "^20.2.2"
-          }
-        }
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
+    "node_modules/get-pkg-repo/node_modules/readable-stream": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/get-pkg-repo/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "dev": true
+    },
+    "node_modules/get-pkg-repo/node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/get-pkg-repo/node_modules/through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "dev": true,
+      "dependencies": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      }
+    },
+    "node_modules/get-pkg-repo/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/get-pkg-repo/node_modules/yargs": {
+      "version": "16.2.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^7.0.2",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.0",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^20.2.2"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "get-stream": {
+    "node_modules/get-stream": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
       "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "git-raw-commits": {
+    "node_modules/git-raw-commits": {
       "version": "2.0.11",
       "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz",
       "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "dargs": "^7.0.0",
         "lodash": "^4.17.15",
         "meow": "^8.0.0",
         "split2": "^3.0.0",
         "through2": "^4.0.0"
+      },
+      "bin": {
+        "git-raw-commits": "cli.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "git-remote-origin-url": {
+    "node_modules/git-remote-origin-url": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz",
       "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "gitconfiglocal": "^1.0.0",
         "pify": "^2.3.0"
+      },
+      "engines": {
+        "node": ">=4"
       }
     },
-    "git-semver-tags": {
+    "node_modules/git-semver-tags": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz",
       "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "meow": "^8.0.0",
         "semver": "^6.0.0"
       },
-      "dependencies": {
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "dev": true
-        }
+      "bin": {
+        "git-semver-tags": "cli.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/git-semver-tags/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
       }
     },
-    "gitconfiglocal": {
+    "node_modules/gitconfiglocal": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz",
       "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "ini": "^1.3.2"
       }
     },
-    "glob": {
+    "node_modules/glob": {
       "version": "7.2.3",
       "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
       "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
         "minimatch": "^3.1.1",
         "once": "^1.3.0",
         "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/global-directory": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
+      "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
+      "dev": true,
+      "dependencies": {
+        "ini": "4.1.1"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "global-dirs": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
-      "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==",
+    "node_modules/global-directory/node_modules/ini": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
+      "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
       "dev": true,
-      "requires": {
-        "ini": "^1.3.4"
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
       }
     },
-    "global-modules": {
+    "node_modules/global-modules": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
       "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "global-prefix": "^1.0.1",
         "is-windows": "^1.0.1",
         "resolve-dir": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "global-prefix": {
+    "node_modules/global-prefix": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
       "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "expand-tilde": "^2.0.2",
         "homedir-polyfill": "^1.0.1",
         "ini": "^1.3.4",
         "is-windows": "^1.0.1",
         "which": "^1.2.14"
       },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/global-prefix/node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/gopd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+      "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+      "dev": true,
+      "peer": true,
       "dependencies": {
-        "which": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-          "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-          "dev": true,
-          "requires": {
-            "isexe": "^2.0.0"
-          }
-        }
+        "get-intrinsic": "^1.1.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "graceful-fs": {
-      "version": "4.2.10",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
-      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
       "dev": true
     },
-    "handlebars": {
-      "version": "4.7.7",
-      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
-      "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
+    "node_modules/handlebars": {
+      "version": "4.7.8",
+      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+      "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "minimist": "^1.2.5",
-        "neo-async": "^2.6.0",
+        "neo-async": "^2.6.2",
         "source-map": "^0.6.1",
-        "uglify-js": "^3.1.4",
         "wordwrap": "^1.0.0"
+      },
+      "bin": {
+        "handlebars": "bin/handlebars"
+      },
+      "engines": {
+        "node": ">=0.4.7"
+      },
+      "optionalDependencies": {
+        "uglify-js": "^3.1.4"
       }
     },
-    "hard-rejection": {
+    "node_modules/hard-rejection": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
       "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
-      "dev": true
-    },
-    "has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
       "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1"
+      "engines": {
+        "node": ">=6"
       }
     },
-    "has-flag": {
+    "node_modules/has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/has-property-descriptors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+      "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "es-define-property": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-proto": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+      "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hasown": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
+      "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
     },
-    "homedir-polyfill": {
+    "node_modules/homedir-polyfill": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
       "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "parse-passwd": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "hosted-git-info": {
+    "node_modules/hosted-git-info": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
       "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "lru-cache": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "human-signals": {
+    "node_modules/human-signals": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
       "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10.17.0"
+      }
     },
-    "husky": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz",
-      "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==",
-      "dev": true
+    "node_modules/husky": {
+      "version": "9.0.11",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz",
+      "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
+      "dev": true,
+      "bin": {
+        "husky": "bin.mjs"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/typicode"
+      }
     },
-    "iconv-lite": {
+    "node_modules/iconv-lite": {
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
       "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "ieee754": {
+    "node_modules/ieee754": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
       "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
     },
-    "import-fresh": {
+    "node_modules/import-fresh": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
       "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "parent-module": "^1.0.0",
         "resolve-from": "^4.0.0"
       },
-      "dependencies": {
-        "resolve-from": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-          "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-          "dev": true
-        }
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/import-fresh/node_modules/resolve-from": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
       }
     },
-    "indent-string": {
+    "node_modules/import-meta-resolve": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz",
+      "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==",
+      "dev": true,
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/indent-string": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
       "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "inflight": {
+    "node_modules/inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
       "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "once": "^1.3.0",
         "wrappy": "1"
       }
     },
-    "inherits": {
+    "node_modules/inherits": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
       "dev": true
     },
-    "ini": {
+    "node_modules/ini": {
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
       "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
       "dev": true
     },
-    "inquirer": {
-      "version": "8.2.4",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz",
-      "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==",
+    "node_modules/inquirer": {
+      "version": "9.2.15",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.15.tgz",
+      "integrity": "sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==",
       "dev": true,
-      "requires": {
-        "ansi-escapes": "^4.2.1",
-        "chalk": "^4.1.1",
+      "peer": true,
+      "dependencies": {
+        "@ljharb/through": "^2.3.12",
+        "ansi-escapes": "^4.3.2",
+        "chalk": "^5.3.0",
         "cli-cursor": "^3.1.0",
-        "cli-width": "^3.0.0",
-        "external-editor": "^3.0.3",
-        "figures": "^3.0.0",
+        "cli-width": "^4.1.0",
+        "external-editor": "^3.1.0",
+        "figures": "^3.2.0",
         "lodash": "^4.17.21",
-        "mute-stream": "0.0.8",
+        "mute-stream": "1.0.0",
         "ora": "^5.4.1",
-        "run-async": "^2.4.0",
-        "rxjs": "^7.5.5",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0",
-        "through": "^2.3.6",
-        "wrap-ansi": "^7.0.0"
+        "run-async": "^3.0.0",
+        "rxjs": "^7.8.1",
+        "string-width": "^4.2.3",
+        "strip-ansi": "^6.0.1",
+        "wrap-ansi": "^6.2.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/inquirer/node_modules/chalk": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+      "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/inquirer/node_modules/cli-width": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
+      "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">= 12"
       }
     },
-    "is-arrayish": {
+    "node_modules/inquirer/node_modules/mute-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz",
+      "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/inquirer/node_modules/run-async": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz",
+      "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
       "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
       "dev": true
     },
-    "is-core-module": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
-      "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
+    "node_modules/is-core-module": {
+      "version": "2.13.1",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
+      "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
       "dev": true,
-      "requires": {
-        "has": "^1.0.3"
+      "dependencies": {
+        "hasown": "^2.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "is-extglob": {
+    "node_modules/is-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
       "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "is-fullwidth-code-point": {
+    "node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
       "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "is-glob": {
+    "node_modules/is-glob": {
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
       "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "is-interactive": {
+    "node_modules/is-interactive": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
       "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "is-number": {
+    "node_modules/is-number": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
     },
-    "is-obj": {
+    "node_modules/is-obj": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
       "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "is-plain-obj": {
+    "node_modules/is-plain-obj": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
       "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "is-stream": {
+    "node_modules/is-stream": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
       "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "is-text-path": {
+    "node_modules/is-text-path": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz",
       "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "text-extensions": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "is-unicode-supported": {
+    "node_modules/is-unicode-supported": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
       "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "is-utf8": {
+    "node_modules/is-utf8": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
       "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==",
       "dev": true
     },
-    "is-windows": {
+    "node_modules/is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
       "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "isarray": {
+    "node_modules/isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
       "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
       "dev": true
     },
-    "isexe": {
+    "node_modules/isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
       "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
     },
-    "js-tokens": {
+    "node_modules/jiti": {
+      "version": "1.21.0",
+      "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
+      "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
+      "dev": true,
+      "bin": {
+        "jiti": "bin/jiti.js"
+      }
+    },
+    "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
       "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
       "dev": true
     },
-    "js-yaml": {
+    "node_modules/js-yaml": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
       "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
       }
     },
-    "json-parse-better-errors": {
+    "node_modules/json-parse-better-errors": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
       "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
       "dev": true
     },
-    "json-parse-even-better-errors": {
+    "node_modules/json-parse-even-better-errors": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
       "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
       "dev": true
     },
-    "json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+    "node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
       "dev": true
     },
-    "json-stringify-safe": {
+    "node_modules/json-stringify-safe": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
       "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
       "dev": true
     },
-    "jsonfile": {
+    "node_modules/jsonfile": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
       "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
       "dev": true,
-      "requires": {
-        "graceful-fs": "^4.1.6",
+      "dependencies": {
         "universalify": "^2.0.0"
+      },
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
       }
     },
-    "jsonparse": {
+    "node_modules/jsonparse": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
       "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
-      "dev": true
+      "dev": true,
+      "engines": [
+        "node >= 0.2.0"
+      ]
     },
-    "JSONStream": {
+    "node_modules/JSONStream": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
       "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "jsonparse": "^1.2.0",
         "through": ">=2.2.7 <3"
+      },
+      "bin": {
+        "JSONStream": "bin.js"
+      },
+      "engines": {
+        "node": "*"
       }
     },
-    "kind-of": {
+    "node_modules/kind-of": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
       "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "lines-and-columns": {
+    "node_modules/lines-and-columns": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
       "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
       "dev": true
     },
-    "load-json-file": {
+    "node_modules/load-json-file": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
       "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "graceful-fs": "^4.1.2",
         "parse-json": "^4.0.0",
         "pify": "^3.0.0",
         "strip-bom": "^3.0.0"
       },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/load-json-file/node_modules/parse-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+      "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+      "dev": true,
       "dependencies": {
-        "parse-json": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
-          "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
-          "dev": true,
-          "requires": {
-            "error-ex": "^1.3.1",
-            "json-parse-better-errors": "^1.0.1"
-          }
-        },
-        "pify": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-          "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
-          "dev": true
-        },
-        "strip-bom": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-          "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
-          "dev": true
-        }
+        "error-ex": "^1.3.1",
+        "json-parse-better-errors": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/load-json-file/node_modules/pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/load-json-file/node_modules/strip-bom": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+      "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
       }
     },
-    "locate-path": {
+    "node_modules/locate-path": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
       "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "p-locate": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "lodash": {
+    "node_modules/lodash": {
       "version": "4.17.21",
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
-    "lodash.ismatch": {
+    "node_modules/lodash.camelcase": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+      "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
+      "dev": true
+    },
+    "node_modules/lodash.ismatch": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz",
       "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==",
       "dev": true
     },
-    "lodash.map": {
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+      "dev": true
+    },
+    "node_modules/lodash.kebabcase": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+      "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==",
+      "dev": true
+    },
+    "node_modules/lodash.map": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
       "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==",
       "dev": true
     },
-    "log-symbols": {
+    "node_modules/lodash.merge": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+      "dev": true
+    },
+    "node_modules/lodash.mergewith": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+      "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
+      "dev": true
+    },
+    "node_modules/lodash.snakecase": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
+      "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
+      "dev": true
+    },
+    "node_modules/lodash.startcase": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz",
+      "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==",
+      "dev": true
+    },
+    "node_modules/lodash.uniq": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+      "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+      "dev": true
+    },
+    "node_modules/lodash.upperfirst": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
+      "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==",
+      "dev": true
+    },
+    "node_modules/log-symbols": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
       "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "chalk": "^4.1.0",
         "is-unicode-supported": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "longest": {
+    "node_modules/longest": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz",
       "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "lru-cache": {
+    "node_modules/lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
       "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "make-error": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
-      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
-      "dev": true
-    },
-    "map-obj": {
+    "node_modules/map-obj": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
       "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "meow": {
+    "node_modules/meow": {
       "version": "8.1.2",
       "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz",
       "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@types/minimist": "^1.2.0",
         "camelcase-keys": "^6.2.2",
         "decamelize-keys": "^1.1.0",
@@ -6090,138 +3540,181 @@
         "type-fest": "^0.18.0",
         "yargs-parser": "^20.2.3"
       },
-      "dependencies": {
-        "type-fest": {
-          "version": "0.18.1",
-          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
-          "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
-          "dev": true
-        }
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "merge": {
+    "node_modules/meow/node_modules/type-fest": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
+      "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/merge": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz",
       "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==",
       "dev": true
     },
-    "merge-stream": {
+    "node_modules/merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
       "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
       "dev": true
     },
-    "micromatch": {
+    "node_modules/micromatch": {
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
       "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "braces": "^3.0.2",
         "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
       }
     },
-    "mimic-fn": {
+    "node_modules/mimic-fn": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
       "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "min-indent": {
+    "node_modules/min-indent": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
       "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
     },
-    "minimatch": {
+    "node_modules/minimatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
       "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
       }
     },
-    "minimist": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
-      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
-      "dev": true
+    "node_modules/minimist": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+      "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
-    "minimist-options": {
+    "node_modules/minimist-options": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
       "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "arrify": "^1.0.1",
         "is-plain-obj": "^1.1.0",
         "kind-of": "^6.0.3"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
-    "modify-values": {
+    "node_modules/modify-values": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
       "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "mute-stream": {
+    "node_modules/mute-stream": {
       "version": "0.0.8",
       "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
       "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
       "dev": true
     },
-    "neo-async": {
+    "node_modules/neo-async": {
       "version": "2.6.2",
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
       "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
       "dev": true
     },
-    "normalize-package-data": {
+    "node_modules/normalize-package-data": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
       "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "hosted-git-info": "^4.0.1",
         "is-core-module": "^2.5.0",
         "semver": "^7.3.4",
         "validate-npm-package-license": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "npm-run-path": {
+    "node_modules/npm-run-path": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
       "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "path-key": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "once": {
+    "node_modules/once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
       "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "wrappy": "1"
       }
     },
-    "onetime": {
+    "node_modules/onetime": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
       "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "mimic-fn": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "ora": {
+    "node_modules/ora": {
       "version": "5.4.1",
       "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
       "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "bl": "^4.1.0",
         "chalk": "^4.1.0",
         "cli-cursor": "^3.1.0",
@@ -6231,429 +3724,620 @@
         "log-symbols": "^4.1.0",
         "strip-ansi": "^6.0.0",
         "wcwidth": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "os-tmpdir": {
+    "node_modules/os-tmpdir": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
       "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "p-limit": {
+    "node_modules/p-limit": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
       "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "yocto-queue": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "p-locate": {
+    "node_modules/p-locate": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
       "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "p-limit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "p-try": {
+    "node_modules/p-try": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
       "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
     },
-    "parent-module": {
+    "node_modules/parent-module": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
       "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "callsites": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
       }
     },
-    "parse-json": {
+    "node_modules/parse-json": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
       "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@babel/code-frame": "^7.0.0",
         "error-ex": "^1.3.1",
         "json-parse-even-better-errors": "^2.3.0",
         "lines-and-columns": "^1.1.6"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "parse-passwd": {
+    "node_modules/parse-passwd": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
       "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "path-exists": {
+    "node_modules/path-exists": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
       "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "path-is-absolute": {
+    "node_modules/path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
       "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "path-key": {
+    "node_modules/path-key": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
       "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "path-parse": {
+    "node_modules/path-parse": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
       "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
       "dev": true
     },
-    "path-type": {
+    "node_modules/path-type": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
       "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "picomatch": {
+    "node_modules/picomatch": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
     },
-    "pify": {
+    "node_modules/pify": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
       "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "process-nextick-args": {
+    "node_modules/process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
       "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
       "dev": true
     },
-    "punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-      "dev": true
+    "node_modules/punycode": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "q": {
+    "node_modules/q": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
       "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.6.0",
+        "teleport": ">=0.2.0"
+      }
     },
-    "quick-lru": {
+    "node_modules/quick-lru": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
       "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "read-pkg": {
+    "node_modules/read-pkg": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
       "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@types/normalize-package-data": "^2.4.0",
         "normalize-package-data": "^2.5.0",
         "parse-json": "^5.0.0",
         "type-fest": "^0.6.0"
       },
-      "dependencies": {
-        "hosted-git-info": {
-          "version": "2.8.9",
-          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
-          "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
-          "dev": true
-        },
-        "normalize-package-data": {
-          "version": "2.5.0",
-          "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
-          "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
-          "dev": true,
-          "requires": {
-            "hosted-git-info": "^2.1.4",
-            "resolve": "^1.10.0",
-            "semver": "2 || 3 || 4 || 5",
-            "validate-npm-package-license": "^3.0.1"
-          }
-        },
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        },
-        "type-fest": {
-          "version": "0.6.0",
-          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
-          "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
-          "dev": true
-        }
+      "engines": {
+        "node": ">=8"
       }
     },
-    "read-pkg-up": {
+    "node_modules/read-pkg-up": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
       "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "find-up": "^4.1.0",
         "read-pkg": "^5.2.0",
         "type-fest": "^0.8.1"
       },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
       "dependencies": {
-        "find-up": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
-          "dev": true,
-          "requires": {
-            "locate-path": "^5.0.0",
-            "path-exists": "^4.0.0"
-          }
-        },
-        "locate-path": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
-          "dev": true,
-          "requires": {
-            "p-locate": "^4.1.0"
-          }
-        },
-        "p-limit": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-          "dev": true,
-          "requires": {
-            "p-try": "^2.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
-          "dev": true,
-          "requires": {
-            "p-limit": "^2.2.0"
-          }
-        },
-        "p-try": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-          "dev": true
-        },
-        "type-fest": {
-          "version": "0.8.1",
-          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
-          "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
-          "dev": true
-        }
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/type-fest": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg/node_modules/hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "dev": true
+    },
+    "node_modules/read-pkg/node_modules/normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/read-pkg/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/read-pkg/node_modules/type-fest": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
       }
     },
-    "readable-stream": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+    "node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "inherits": "^2.0.3",
         "string_decoder": "^1.1.1",
         "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
-    "redent": {
+    "node_modules/redent": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
       "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "indent-string": "^4.0.0",
         "strip-indent": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "require-directory": {
+    "node_modules/require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
       "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "resolve": {
-      "version": "1.22.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
-      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+    "node_modules/resolve": {
+      "version": "1.22.8",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+      "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
       "dev": true,
-      "requires": {
-        "is-core-module": "^2.9.0",
+      "dependencies": {
+        "is-core-module": "^2.13.0",
         "path-parse": "^1.0.7",
         "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "resolve-dir": {
+    "node_modules/resolve-dir": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
       "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "expand-tilde": "^2.0.0",
         "global-modules": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "resolve-from": {
+    "node_modules/resolve-from": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
       "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "resolve-global": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz",
-      "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==",
+    "node_modules/resolve-global": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-2.0.0.tgz",
+      "integrity": "sha512-gnAQ0Q/KkupGkuiMyX4L0GaBV8iFwlmoXsMtOz+DFTaKmHhOO/dSlP1RMKhpvHv/dh6K/IQkowGJBqUG0NfBUw==",
       "dev": true,
-      "requires": {
-        "global-dirs": "^0.1.1"
+      "dependencies": {
+        "global-directory": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "restore-cursor": {
+    "node_modules/restore-cursor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
       "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "onetime": "^5.1.0",
         "signal-exit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "run-async": {
+    "node_modules/run-async": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
       "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
     },
-    "rxjs": {
-      "version": "7.5.7",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz",
-      "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==",
+    "node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "tslib": "^2.1.0"
       }
     },
-    "safe-buffer": {
+    "node_modules/safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
       "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
-      "dev": true
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
     },
-    "safer-buffer": {
+    "node_modules/safer-buffer": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
       "dev": true
     },
-    "semver": {
-      "version": "7.3.7",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
-      "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+    "node_modules/semver": {
+      "version": "7.6.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+      "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/set-function-length": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
+      "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "define-data-property": "^1.1.2",
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2",
+        "get-intrinsic": "^1.2.3",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
       }
     },
-    "shebang-command": {
+    "node_modules/shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
       "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "shebang-regex": {
+    "node_modules/shebang-regex": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
       "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "signal-exit": {
+    "node_modules/signal-exit": {
       "version": "3.0.7",
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
       "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "dev": true
     },
-    "source-map": {
+    "node_modules/source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "spdx-correct": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
-      "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+    "node_modules/spdx-correct": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "spdx-expression-parse": "^3.0.0",
         "spdx-license-ids": "^3.0.0"
       }
     },
-    "spdx-exceptions": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
-      "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+    "node_modules/spdx-exceptions": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+      "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
       "dev": true
     },
-    "spdx-expression-parse": {
+    "node_modules/spdx-expression-parse": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
       "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "spdx-exceptions": "^2.1.0",
         "spdx-license-ids": "^3.0.0"
       }
     },
-    "spdx-license-ids": {
-      "version": "3.0.12",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz",
-      "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
+    "node_modules/spdx-license-ids": {
+      "version": "3.0.17",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz",
+      "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==",
       "dev": true
     },
-    "split": {
+    "node_modules/split": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
       "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "through": "2"
+      },
+      "engines": {
+        "node": "*"
       }
     },
-    "split2": {
+    "node_modules/split2": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
       "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "readable-stream": "^3.0.0"
       }
     },
-    "standard-version": {
+    "node_modules/standard-version": {
       "version": "9.5.0",
       "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz",
       "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "chalk": "^2.4.2",
         "conventional-changelog": "3.1.25",
         "conventional-changelog-config-spec": "2.1.0",
@@ -6669,407 +4353,565 @@
         "stringify-package": "^1.0.1",
         "yargs": "^16.0.0"
       },
+      "bin": {
+        "standard-version": "bin/cli.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/standard-version/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/standard-version/node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/standard-version/node_modules/cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
+    "node_modules/standard-version/node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/standard-version/node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
+    },
+    "node_modules/standard-version/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/standard-version/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/standard-version/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/standard-version/node_modules/wrap-ansi/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/standard-version/node_modules/wrap-ansi/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/standard-version/node_modules/wrap-ansi/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "node_modules/standard-version/node_modules/yargs": {
+      "version": "16.2.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+      "dev": true,
       "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "cliui": {
-          "version": "7.0.4",
-          "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-          "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-          "dev": true,
-          "requires": {
-            "string-width": "^4.2.0",
-            "strip-ansi": "^6.0.0",
-            "wrap-ansi": "^7.0.0"
-          }
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        },
-        "yargs": {
-          "version": "16.2.0",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-          "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
-          "dev": true,
-          "requires": {
-            "cliui": "^7.0.2",
-            "escalade": "^3.1.1",
-            "get-caller-file": "^2.0.5",
-            "require-directory": "^2.1.1",
-            "string-width": "^4.2.0",
-            "y18n": "^5.0.5",
-            "yargs-parser": "^20.2.2"
-          }
-        }
+        "cliui": "^7.0.2",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.0",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^20.2.2"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "string_decoder": {
+    "node_modules/string_decoder": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
       "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "safe-buffer": "~5.2.0"
       }
     },
-    "string-width": {
+    "node_modules/string-width": {
       "version": "4.2.3",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
       "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "emoji-regex": "^8.0.0",
         "is-fullwidth-code-point": "^3.0.0",
         "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "stringify-package": {
+    "node_modules/stringify-package": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz",
       "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==",
+      "deprecated": "This module is not used anymore, and has been replaced by @npmcli/package-json",
       "dev": true
     },
-    "strip-ansi": {
+    "node_modules/strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "strip-bom": {
+    "node_modules/strip-bom": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
       "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "strip-final-newline": {
+    "node_modules/strip-final-newline": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
       "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "strip-indent": {
+    "node_modules/strip-indent": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
       "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "min-indent": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "strip-json-comments": {
+    "node_modules/strip-json-comments": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
       "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "supports-color": {
+    "node_modules/supports-color": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
       "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "supports-preserve-symlinks-flag": {
+    "node_modules/supports-preserve-symlinks-flag": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
       "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
-    "text-extensions": {
+    "node_modules/text-extensions": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz",
       "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10"
+      }
     },
-    "through": {
+    "node_modules/through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
       "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
       "dev": true
     },
-    "through2": {
+    "node_modules/through2": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
       "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "readable-stream": "3"
       }
     },
-    "tmp": {
+    "node_modules/tmp": {
       "version": "0.0.33",
       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
       "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
       }
     },
-    "to-regex-range": {
+    "node_modules/to-regex-range": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
       }
     },
-    "trim-newlines": {
+    "node_modules/trim-newlines": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
       "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "ts-node": {
-      "version": "10.9.1",
-      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
-      "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
-      "dev": true,
-      "requires": {
-        "@cspotcode/source-map-support": "^0.8.0",
-        "@tsconfig/node10": "^1.0.7",
-        "@tsconfig/node12": "^1.0.7",
-        "@tsconfig/node14": "^1.0.0",
-        "@tsconfig/node16": "^1.0.2",
-        "acorn": "^8.4.1",
-        "acorn-walk": "^8.1.1",
-        "arg": "^4.1.0",
-        "create-require": "^1.1.0",
-        "diff": "^4.0.1",
-        "make-error": "^1.1.1",
-        "v8-compile-cache-lib": "^3.0.1",
-        "yn": "3.1.1"
-      }
-    },
-    "tslib": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
-      "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+    "node_modules/tslib": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
       "dev": true
     },
-    "type-fest": {
+    "node_modules/type-fest": {
       "version": "0.21.3",
       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
       "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "typedarray": {
+    "node_modules/typedarray": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
       "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
       "dev": true
     },
-    "typescript": {
-      "version": "4.8.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
-      "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
-      "dev": true
+    "node_modules/typescript": {
+      "version": "5.3.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
+      "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+      "dev": true,
+      "peer": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
+    "node_modules/uglify-js": {
+      "version": "3.17.4",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
+      "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "uglifyjs": "bin/uglifyjs"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
     },
-    "uglify-js": {
-      "version": "3.17.3",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz",
-      "integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==",
+    "node_modules/undici-types": {
+      "version": "5.26.5",
+      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
       "dev": true,
-      "optional": true
+      "peer": true
     },
-    "universalify": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
-      "dev": true
+    "node_modules/unicorn-magic": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
+      "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/universalify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.0.0"
+      }
     },
-    "uri-js": {
+    "node_modules/uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
       "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "punycode": "^2.1.0"
       }
     },
-    "util-deprecate": {
+    "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
       "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
       "dev": true
     },
-    "v8-compile-cache-lib": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
-      "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
-      "dev": true
-    },
-    "validate-npm-package-license": {
+    "node_modules/validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
       "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "spdx-correct": "^3.0.0",
         "spdx-expression-parse": "^3.0.0"
       }
     },
-    "wcwidth": {
+    "node_modules/wcwidth": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
       "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "defaults": "^1.0.3"
       }
     },
-    "which": {
+    "node_modules/which": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
       "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "word-wrap": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
-      "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
-      "dev": true
+    "node_modules/word-wrap": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+      "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "wordwrap": {
+    "node_modules/wordwrap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
       "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
       "dev": true
     },
-    "wrap-ansi": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+    "node_modules/wrap-ansi": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
       "dev": true,
-      "requires": {
+      "peer": true,
+      "dependencies": {
         "ansi-styles": "^4.0.0",
         "string-width": "^4.1.0",
         "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "wrappy": {
+    "node_modules/wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
       "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
-    "xtend": {
+    "node_modules/xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
       "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
     },
-    "y18n": {
+    "node_modules/y18n": {
       "version": "5.0.8",
       "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
       "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
     },
-    "yallist": {
+    "node_modules/yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
       "dev": true
     },
-    "yaml": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
-      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
-      "dev": true
-    },
-    "yargs": {
-      "version": "17.6.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz",
-      "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==",
+    "node_modules/yargs": {
+      "version": "17.7.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "cliui": "^8.0.1",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
         "string-width": "^4.2.3",
         "y18n": "^5.0.5",
-        "yargs-parser": "^21.0.0"
+        "yargs-parser": "^21.1.1"
       },
-      "dependencies": {
-        "yargs-parser": {
-          "version": "21.1.1",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
-          "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
-          "dev": true
-        }
+      "engines": {
+        "node": ">=12"
       }
     },
-    "yargs-parser": {
+    "node_modules/yargs-parser": {
       "version": "20.2.9",
       "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
       "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
     },
-    "yn": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
-      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
-      "dev": true
+    "node_modules/yargs/node_modules/yargs-parser": {
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      }
     },
-    "yocto-queue": {
+    "node_modules/yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
       "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "tools/conventional-changelog-tf-a": {
+      "version": "2.11.0",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "conventional-changelog-conventionalcommits": "^4.6.1",
+        "execa": "^5.1.1",
+        "lodash": "^4.17.21",
+        "q": "^1.5.1"
+      }
     }
   }
 }
diff --git a/package.json b/package.json
index 1c557fda..0908528f 100644
--- a/package.json
+++ b/package.json
@@ -1,23 +1,24 @@
 {
   "name": "trusted-firmware-a",
-  "version": "2.10.0",
+  "version": "2.12.0",
   "license": "BSD-3-Clause",
+  "type": "module",
   "private": true,
   "scripts": {
-    "postinstall": "husky install",
+    "prepare": "husky",
     "release": "standard-version"
   },
   "engines": {
-    "node": ">=16.0.0"
+    "node": ">=20"
   },
   "devDependencies": {
-    "@commitlint/cli": "^16.1.0",
-    "@commitlint/config-conventional": "^16.0.0",
-    "@commitlint/cz-commitlint": "^16.1.0",
-    "commitizen": "^4.2.4",
+    "@commitlint/cli": "^19.0.0",
+    "@commitlint/config-conventional": "^19.0.0",
+    "@commitlint/cz-commitlint": "^19.0.0",
+    "commitizen": "^4.3.0",
     "conventional-changelog-tf-a": "file:tools/conventional-changelog-tf-a",
-    "husky": "^7.0.4",
+    "husky": "^9.0.11",
     "js-yaml": "^4.1.0",
-    "standard-version": "^9.3.2"
+    "standard-version": "^9.5.0"
   }
 }
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 6a386574..b9ca3f60 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -58,4 +58,12 @@ static inline void sunxi_prepare_dtb(void *fdt)
 }
 #endif
 
+#ifdef PLAT_sun50i_h616
+void sunxi_soc_fdt_fixup(void *dtb);
+#else
+static inline void sunxi_soc_fdt_fixup(void *dtb)
+{
+}
+#endif
+
 #endif /* SUNXI_PRIVATE_H */
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index a32124a1..263083bb 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,6 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/fdt_fixup.h>
-#include <common/fdt_wrappers.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/console.h>
 #include <drivers/generic_delay_timer.h>
@@ -186,8 +185,6 @@ void bl31_plat_runtime_setup(void)
 {
 	/* Change the DTB if the configuration requires so. */
 	sunxi_prepare_dtb(fdt);
-
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
diff --git a/plat/allwinner/common/sunxi_prepare_dtb.c b/plat/allwinner/common/sunxi_prepare_dtb.c
index 66af35ab..0f689744 100644
--- a/plat/allwinner/common/sunxi_prepare_dtb.c
+++ b/plat/allwinner/common/sunxi_prepare_dtb.c
@@ -34,6 +34,8 @@ void sunxi_prepare_dtb(void *fdt)
 	}
 #endif
 
+	sunxi_soc_fdt_fixup(fdt);
+
 	if (sunxi_psci_is_scpi()) {
 		ret = fdt_add_cpu_idle_states(fdt, sunxi_idle_states);
 		if (ret < 0) {
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index e3c7c529..cced7f0b 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# To report supported idle states
+# this has to be defined before allwinner-common.mk
+SUNXI_AMEND_DTB		:=	1
+
 # The differences between the platform are covered by the include files.
 include plat/allwinner/common/allwinner-common.mk
 
diff --git a/plat/allwinner/sun50i_a64/platform_defaults.mk b/plat/allwinner/sun50i_a64/platform_defaults.mk
new file mode 100644
index 00000000..5b61029c
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/platform_defaults.mk
@@ -0,0 +1,9 @@
+#
+# Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# LTO has to be enabled on this platform due to memory constraints
+ENABLE_LTO			:= 1
+
diff --git a/plat/allwinner/sun50i_h616/platform.mk b/plat/allwinner/sun50i_h616/platform.mk
index de494a2f..6f44e8c2 100644
--- a/plat/allwinner/sun50i_h616/platform.mk
+++ b/plat/allwinner/sun50i_h616/platform.mk
@@ -18,5 +18,8 @@ ifeq (${SUNXI_PSCI_USE_SCPI}, 1)
     $(error "H616 does not support SCPI PSCI ops")
 endif
 
-BL31_SOURCES		+=	drivers/allwinner/axp/axp805.c		\
+BL31_SOURCES		+=	common/fdt_wrappers.c			\
+				drivers/allwinner/axp/axp805.c		\
 				drivers/allwinner/sunxi_rsb.c		\
+				drivers/mentor/i2c/mi2cv.c		\
+				${AW_PLAT}/${PLAT}/sunxi_h616_dtb.c
diff --git a/plat/allwinner/sun50i_h616/sunxi_h616_dtb.c b/plat/allwinner/sun50i_h616/sunxi_h616_dtb.c
new file mode 100644
index 00000000..58bad539
--- /dev/null
+++ b/plat/allwinner/sun50i_h616/sunxi_h616_dtb.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2024, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Amend the device tree to adjust the L2 cache size, which is different
+ * between the revisions of the H616 chips: earlier versions have 256 KB of L2,
+ * later versions 1 MB.
+ * Read the cache ID registers and adjust the size and number of sets entries
+ * in the L2 cache DT node.
+ */
+
+#include <common/fdt_wrappers.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
+
+#define CACHE_L1D		0x0
+#define CACHE_L1I		0x1
+#define CACHE_L2U		0x2
+
+#define CCSIDR_SETS_SHIFT	13
+#define CCSIDR_SETS_MASK	GENMASK(14, 0)
+#define CCSIDR_ASSOC_SHIFT	3
+#define CCSIDR_ASSOC_MASK	GENMASK(9, 0)
+#define CCSIDR_LSIZE_SHIFT	0
+#define CCSIDR_LSIZE_MASK	GENMASK(2, 0)
+
+static uint32_t armv8_get_ccsidr(unsigned int sel)
+{
+	uint32_t reg;
+
+	__asm__ volatile ("msr CSSELR_EL1, %0\n" :: "r" (sel));
+	__asm__ volatile ("mrs %0, CCSIDR_EL1\n" : "=r" (reg));
+
+	return reg;
+}
+
+void sunxi_soc_fdt_fixup(void *dtb)
+{
+	int node = fdt_path_offset(dtb, "/cpus/cpu@0");
+	uint32_t phandle, ccsidr, cell;
+	int sets, line_size, assoc;
+	int ret;
+
+	if (node < 0) {
+		return;
+	}
+
+	ret = fdt_read_uint32(dtb, node, "next-level-cache", &phandle);
+	if (ret != 0) {
+		return;
+	}
+
+	node = fdt_node_offset_by_phandle(dtb, phandle);
+	if (node < 0) {
+		return;
+	}
+
+	ccsidr = armv8_get_ccsidr(CACHE_L2U);
+	sets = ((ccsidr >> CCSIDR_SETS_SHIFT) & CCSIDR_SETS_MASK) + 1;
+	line_size = 16U << ((ccsidr >> CCSIDR_LSIZE_SHIFT) & CCSIDR_LSIZE_MASK);
+	assoc = ((ccsidr >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK) + 1;
+
+	cell = cpu_to_fdt32(sets);
+	fdt_setprop(dtb, node, "cache-sets", &cell, sizeof(cell));
+
+	cell = cpu_to_fdt32(line_size);
+	fdt_setprop(dtb, node, "cache-line-size", &cell, sizeof(cell));
+
+	cell = cpu_to_fdt32(sets * assoc * line_size);
+	fdt_setprop(dtb, node, "cache-size", &cell, sizeof(cell));
+}
diff --git a/plat/allwinner/sun50i_h616/sunxi_power.c b/plat/allwinner/sun50i_h616/sunxi_power.c
index dd6ebba9..cab7e464 100644
--- a/plat/allwinner/sun50i_h616/sunxi_power.c
+++ b/plat/allwinner/sun50i_h616/sunxi_power.c
@@ -10,97 +10,254 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/allwinner/axp.h>
 #include <drivers/allwinner/sunxi_rsb.h>
+#include <drivers/mentor/mi2cv.h>
 #include <lib/mmio.h>
+#include <libfdt.h>
 
 #include <sunxi_cpucfg.h>
 #include <sunxi_def.h>
 #include <sunxi_mmap.h>
 #include <sunxi_private.h>
 
-#define AXP305_I2C_ADDR	0x36
-#define AXP305_HW_ADDR	0x745
-#define AXP305_RT_ADDR	0x3a
+static uint16_t pmic_bus_addr;
+static uint8_t rsb_rt_addr;
+
+static bool is_using_rsb(void)
+{
+	return rsb_rt_addr != 0;
+}
 
 static enum pmic_type {
 	UNKNOWN,
 	AXP305,
+	AXP313,
+	AXP717,
 } pmic;
 
+static uint8_t get_rsb_rt_address(uint16_t hw_addr)
+{
+	switch (hw_addr) {
+	case 0x3a3: return 0x2d;
+	case 0x745: return 0x3a;
+	}
+
+	return 0;
+}
+
 int axp_read(uint8_t reg)
 {
-	return rsb_read(AXP305_RT_ADDR, reg);
+	uint8_t val;
+	int ret;
+
+	if (is_using_rsb()) {
+		return rsb_read(rsb_rt_addr, reg);
+	}
+
+	ret = i2c_write(pmic_bus_addr, 0, 0, &reg, 1);
+	if (ret == 0) {
+		ret = i2c_read(pmic_bus_addr, 0, 0, &val, 1);
+	}
+	if (ret) {
+		ERROR("PMIC: Cannot read PMIC register %02x\n", reg);
+		return ret;
+	}
+
+	return val;
 }
 
 int axp_write(uint8_t reg, uint8_t val)
 {
-	return rsb_write(AXP305_RT_ADDR, reg, val);
+	int ret;
+
+	if (is_using_rsb()) {
+		return rsb_write(rsb_rt_addr, reg, val);
+	}
+
+	ret = i2c_write(pmic_bus_addr, reg, 1, &val, 1);
+	if (ret) {
+		ERROR("PMIC: Cannot write PMIC register %02x\n", reg);
+	}
+
+	return ret;
 }
 
-static int rsb_init(void)
+static int rsb_init(int rsb_hw_addr)
 {
 	int ret;
 
 	ret = rsb_init_controller();
-	if (ret)
+	if (ret) {
 		return ret;
+	}
 
 	/* Switch to the recommended 3 MHz bus clock. */
 	ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
-	if (ret)
+	if (ret) {
 		return ret;
+	}
 
 	/* Initiate an I2C transaction to switch the PMIC to RSB mode. */
 	ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8);
-	if (ret)
+	if (ret) {
 		return ret;
+	}
 
 	/* Associate the 8-bit runtime address with the 12-bit bus address. */
-	ret = rsb_assign_runtime_address(AXP305_HW_ADDR, AXP305_RT_ADDR);
-	if (ret)
+	ret = rsb_assign_runtime_address(rsb_hw_addr, rsb_rt_addr);
+	if (ret) {
 		return ret;
+	}
 
-	return axp_check_id();
+	return 0;
 }
 
-int sunxi_pmic_setup(uint16_t socid, const void *fdt)
+static int pmic_bus_init(uint16_t socid, uint16_t rsb_hw_addr)
 {
 	int ret;
 
-	INFO("PMIC: Probing AXP305 on RSB\n");
-
-	ret = sunxi_init_platform_r_twi(socid, true);
+	ret = sunxi_init_platform_r_twi(socid, is_using_rsb());
 	if (ret) {
 		INFO("Could not init platform bus: %d\n", ret);
+		pmic = UNKNOWN;
 		return ret;
 	}
 
-	ret = rsb_init();
+	if (is_using_rsb()) {
+		ret = rsb_init(rsb_hw_addr);
+		if (ret) {
+			pmic = UNKNOWN;
+			return ret;
+		}
+	} else {
+		/* initialise mi2cv driver */
+		i2c_init((void *)SUNXI_R_I2C_BASE);
+	}
+
+	return 0;
+}
+
+int sunxi_pmic_setup(uint16_t socid, const void *fdt)
+{
+	int node, parent, ret;
+	uint32_t reg;
+
+	node = fdt_node_offset_by_compatible(fdt, 0, "x-powers,axp806");
+	if (node >= 0) {
+		pmic = AXP305;
+	}
+
+	if (pmic == UNKNOWN) {
+		node = fdt_node_offset_by_compatible(fdt, 0, "x-powers,axp313a");
+		if (node >= 0) {
+			pmic = AXP313;
+		}
+	}
+
+	if (pmic == UNKNOWN) {
+		node = fdt_node_offset_by_compatible(fdt, 0, "x-powers,axp717");
+		if (node >= 0) {
+			pmic = AXP717;
+		}
+	}
+
+	if (pmic == UNKNOWN) {
+		INFO("PMIC: No known PMIC in DT, skipping setup.\n");
+		return -ENODEV;
+	}
+
+	if (fdt_read_uint32(fdt, node, "reg", &reg)) {
+		ERROR("PMIC: PMIC DT node does not contain reg property.\n");
+		return -EINVAL;
+	}
+
+	pmic_bus_addr = reg;
+	parent = fdt_parent_offset(fdt, node);
+	ret = fdt_node_check_compatible(fdt, parent, "allwinner,sun8i-a23-rsb");
+	if (ret == 0) {
+		rsb_rt_addr = get_rsb_rt_address(pmic_bus_addr);
+		if (rsb_rt_addr == 0) {
+			ERROR("PMIC: no mapping for RSB address 0x%x\n",
+			      pmic_bus_addr);
+			return -EINVAL;
+		}
+	}
+
+	INFO("Probing for PMIC on %s:\n", is_using_rsb() ? "RSB" : "I2C");
+
+	ret = pmic_bus_init(socid, pmic_bus_addr);
 	if (ret) {
-		INFO("Could not init RSB: %d\n", ret);
 		return ret;
 	}
 
-	pmic = AXP305;
-	axp_setup_regulators(fdt);
+	ret = axp_read(0x03);
+	switch (ret & 0xcf) {
+	case 0x40:				/* AXP305 */
+		if (pmic == AXP305) {
+			INFO("PMIC: found AXP305, setting up regulators\n");
+			axp_setup_regulators(fdt);
+		} else {
+			pmic = UNKNOWN;
+		}
+		break;
+	case 0x48:				/* AXP1530 */
+	case 0x4b:				/* AXP313A */
+	case 0x4c:				/* AXP313B */
+		if (pmic == AXP313) {
+			INFO("PMIC: found AXP313\n");
+			/* no regulators to set up */
+		} else {
+			pmic = UNKNOWN;
+		}
+		break;
+	case 0xcf:		/* version reg not implemented on AXP717 */
+		if (pmic == AXP717) {
+			INFO("PMIC: found AXP717\n");
+			/* no regulators to set up, U-Boot takes care of this */
+		} else {
+			pmic = UNKNOWN;
+		}
+		break;
+	}
 
-	/* Switch the PMIC back to I2C mode. */
-	ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C);
-	if (ret)
-		return ret;
+	if (is_using_rsb()) {
+		/* Switch the PMIC back to I2C mode. */
+		return rsb_write(rsb_rt_addr, AXP20X_MODE_REG, AXP20X_MODE_I2C);
+	}
+
+	if (pmic == UNKNOWN) {
+		INFO("Incompatible or unknown PMIC found.\n");
+		return -ENODEV;
+	}
 
 	return 0;
 }
 
 void sunxi_power_down(void)
 {
+	int ret;
+
+	if (pmic == UNKNOWN) {
+		return;
+	}
+
+	/* Re-initialise after rich OS might have used it. */
+	ret = pmic_bus_init(SUNXI_SOC_H616, pmic_bus_addr);
+	if (ret) {
+		return;
+	}
+
 	switch (pmic) {
 	case AXP305:
-		/* Re-initialise after rich OS might have used it. */
-		sunxi_init_platform_r_twi(SUNXI_SOC_H616, true);
-		rsb_init();
-		axp_power_off();
+		axp_setbits(0x32, BIT(7));
+		break;
+	case AXP313:
+		axp_setbits(0x1a, BIT(7));
+		break;
+	case AXP717:
+		axp_setbits(0x27, BIT(0));
 		break;
 	default:
 		break;
diff --git a/plat/amd/versal2/aarch64/common.c b/plat/amd/versal2/aarch64/common.c
new file mode 100644
index 00000000..0e46edc9
--- /dev/null
+++ b/plat/amd/versal2/aarch64/common.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <def.h>
+#include <plat_common.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+
+uint32_t platform_id, platform_version;
+
+/*
+ * Table of regions to map using the MMU.
+ * This doesn't include TZRAM as the 'mem_layout' argument passed to
+ * configure_mmu_elx() will give the available subset of that,
+ */
+const mmap_region_t plat_mmap[] = {
+	MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CRF_BASE, CRF_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(IPI_BASE, IPI_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+#if TRANSFER_LIST
+	MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_BASE + FW_HANDOFF_SIZE,
+			MT_MEMORY | MT_RW | MT_NS),
+#endif
+	{ 0 }
+};
+
+const mmap_region_t *plat_get_mmap(void)
+{
+	return plat_mmap;
+}
+
+/* For saving cpu clock for certain platform */
+uint32_t cpu_clock;
+
+const char *board_name_decode(void)
+{
+	const char *platform;
+
+	switch (platform_id) {
+	case SPP:
+		platform = "IPP";
+		break;
+	case EMU:
+		platform = "EMU";
+		break;
+	case SILICON:
+		platform = "Silicon";
+		break;
+	case QEMU:
+		platform = "QEMU";
+		break;
+	default:
+		platform = "Unknown";
+	}
+
+	return platform;
+}
+
+void board_detection(void)
+{
+	uint32_t version_type;
+
+	version_type = mmio_read_32(PMC_TAP_VERSION);
+	platform_id = FIELD_GET(PLATFORM_MASK, version_type);
+	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version_type);
+
+	if (platform_id == QEMU_COSIM) {
+		platform_id = QEMU;
+	}
+
+	/* Make sure that console is setup to see this message */
+	VERBOSE("Platform id: %d version: %d.%d\n", platform_id,
+		platform_version / 10U, platform_version % 10U);
+}
+
+uint32_t get_uart_clk(void)
+{
+	uint32_t uart_clock = 0;
+
+	switch (platform_id) {
+	case SPP:
+	case SPP_MMD:
+		uart_clock = cpu_clock;
+		break;
+	case EMU:
+	case EMU_MMD:
+		uart_clock = 25000000;
+		break;
+	case QEMU:
+		/* Random values now */
+		uart_clock = 25000000;
+		break;
+	case SILICON:
+		uart_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+
+	return uart_clock;
+}
+
+void config_setup(void)
+{
+	uint32_t val;
+	uintptr_t crl_base, iou_scntrs_base, psx_base;
+
+	crl_base = CRL;
+	iou_scntrs_base = IOU_SCNTRS;
+	psx_base = PSX_CRF;
+
+	/* Reset for system timestamp generator in FPX */
+	mmio_write_32(psx_base + PSX_CRF_RST_TIMESTAMP_OFFSET, 0);
+
+	/* Global timer init - Program time stamp reference clk */
+	val = mmio_read_32(crl_base + CRL_TIMESTAMP_REF_CTRL_OFFSET);
+	val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
+	mmio_write_32(crl_base + CRL_TIMESTAMP_REF_CTRL_OFFSET, val);
+
+	/* Clear reset of timestamp reg */
+	mmio_write_32(crl_base + CRL_RST_TIMESTAMP_OFFSET, 0);
+
+	/* Program freq register in System counter and enable system counter. */
+	mmio_write_32(iou_scntrs_base + IOU_SCNTRS_BASE_FREQ_OFFSET,
+		      cpu_clock);
+	mmio_write_32(iou_scntrs_base + IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET,
+		      IOU_SCNTRS_CONTROL_EN);
+
+	generic_delay_timer_init();
+
+	/* Configure IPI data */
+	soc_ipi_config_table_init();
+}
+
+uint32_t plat_get_syscnt_freq2(void)
+{
+	return cpu_clock;
+}
diff --git a/plat/amd/versal2/aarch64/helpers.S b/plat/amd/versal2/aarch64/helpers.S
new file mode 100644
index 00000000..580bb764
--- /dev/null
+++ b/plat/amd/versal2/aarch64/helpers.S
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <drivers/arm/gicv3.h>
+
+#include <platform_def.h>
+
+	.globl	plat_secondary_cold_boot_setup
+	.globl	plat_is_my_cpu_primary
+	.globl	platform_mem_init
+	.globl	plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * This function performs any platform specific actions
+	 * needed for a secondary cpu after a cold reset e.g
+	 * mark the cpu's presence, mechanism to place it in a
+	 * holding pen etc.
+	 * TODO: Should we read the PSYS register to make sure
+	 * that the request has gone through.
+	 * -----------------------------------------------------
+	 */
+func plat_secondary_cold_boot_setup
+	mrs	x0, mpidr_el1
+
+	/*
+	 * There is no sane reason to come out of this wfi. This
+	 * cpu will be powered on and reset by the cpu_on pm api
+	 */
+	dsb	sy
+	bl	plat_panic_handler
+endfunc plat_secondary_cold_boot_setup
+
+func plat_is_my_cpu_primary
+	mov	x9, x30
+	bl	plat_my_core_pos
+	cmp	x0, #PRIMARY_CPU
+	cset	x0, eq
+	ret	x9
+endfunc plat_is_my_cpu_primary
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_core_pos_by_mpidr()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_core_pos_by_mpidr
+endfunc plat_my_core_pos
+
+	/* ---------------------------------------------------------------------
+	 * We don't need to carry out any memory initialization on platform
+	 * The Secure RAM is accessible straight away.
+	 * ---------------------------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c
new file mode 100644
index 00000000..47d4c2ca
--- /dev/null
+++ b/plat/amd/versal2/bl31_setup.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <bl31/bl31.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/dcc.h>
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <lib/cpus/cpu_ops.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
+#include <plat_console.h>
+#include <scmi.h>
+
+#include <def.h>
+#include <plat_fdt.h>
+#include <plat_private.h>
+#include <plat_startup.h>
+#include <plat_xfer_list.h>
+#include <pm_api_sys.h>
+#include <pm_client.h>
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/*
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ */
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	assert(sec_state_is_valid(type));
+
+	if (type == NON_SECURE) {
+		return &bl33_image_ep_info;
+	}
+
+	return &bl32_image_ep_info;
+}
+
+/*
+ * Set the build time defaults,if we can't find any config data.
+ */
+static inline void bl31_set_default_config(void)
+{
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
+#if defined(SPD_opteed)
+	/* NS dtb addr passed to optee_os */
+	bl32_image_ep_info.args.arg3 = XILINX_OF_BOARD_DTB_ADDR;
+#endif
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+					  DISABLE_ALL_EXCEPTIONS);
+}
+
+/*
+ * Perform any BL31 specific platform actions. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
+ * are lost (potentially). This needs to be done before the MMU is initialized
+ * so that the memory layout can be used while creating page tables.
+ */
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	(void)arg0;
+	(void)arg1;
+	(void)arg2;
+	(void)arg3;
+	uint32_t uart_clock;
+	int32_t rc;
+
+	board_detection();
+
+	/* FIXME */
+	switch (platform_id) {
+	case SPP:
+		switch (platform_version) {
+		case SPP_PSXC_MMI_V2_0:
+			cpu_clock = 770000;
+			break;
+		case SPP_PSXC_MMI_V3_0:
+			cpu_clock = 908000;
+			break;
+		default:
+			panic();
+		}
+		break;
+	case SPP_MMD:
+		switch (platform_version) {
+		case SPP_PSXC_ISP_AIE_V2_0:
+		case SPP_PSXC_MMD_AIE_FRZ_EA:
+		case SPP_PSXC_MMD_AIE_V3_0:
+			cpu_clock = 760000;
+			break;
+		default:
+			panic();
+		}
+		break;
+	case EMU:
+	case EMU_MMD:
+		cpu_clock = 112203;
+		break;
+	case QEMU:
+		/* Random values now */
+		cpu_clock = 3333333;
+		break;
+	case SILICON:
+		cpu_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+
+	uart_clock = get_uart_clk();
+
+	setup_console();
+
+	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
+	       platform_version / 10U, platform_version % 10U);
+
+	/* Initialize the platform config for future decision making */
+	config_setup();
+
+	/*
+	 * Do initial security configuration to allow DRAM/device access. On
+	 * Base only DRAM security is programmable (via TrustZone), but
+	 * other platforms might have more programmable security devices
+	 * present.
+	 */
+
+	/* Populate common information for BL32 and BL33 */
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+	rc = transfer_list_populate_ep_info(&bl32_image_ep_info, &bl33_image_ep_info);
+	if (rc == TL_OPS_NON || rc == TL_OPS_CUS) {
+		NOTICE("BL31: TL not found, using default config\n");
+		bl31_set_default_config();
+	}
+
+	long rev_var = cpu_get_rev_var();
+
+	INFO("CPU Revision = 0x%lx\n", rev_var);
+	INFO("cpu_clock = %dHz, uart_clock = %dHz\n", cpu_clock, uart_clock);
+	NOTICE("BL31: Executing from 0x%x\n", BL31_BASE);
+	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
+	NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
+
+}
+
+static versal_intr_info_type_el3_t type_el3_interrupt_table[MAX_INTR_EL3];
+
+int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
+{
+	static uint32_t index;
+	uint32_t i;
+
+	/* Validate 'handler' and 'id' parameters */
+	if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
+		return -EINVAL;
+	}
+
+	/* Check if a handler has already been registered */
+	for (i = 0; i < index; i++) {
+		if (id == type_el3_interrupt_table[i].id) {
+			return -EALREADY;
+		}
+	}
+
+	type_el3_interrupt_table[index].id = id;
+	type_el3_interrupt_table[index].handler = handler;
+
+	index++;
+
+	return 0;
+}
+
+static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
+					  void *handle, void *cookie)
+{
+	(void)id;
+	uint32_t intr_id;
+	uint32_t i;
+	interrupt_type_handler_t handler = NULL;
+
+	intr_id = plat_ic_get_pending_interrupt_id();
+
+	for (i = 0; i < MAX_INTR_EL3; i++) {
+		if (intr_id == type_el3_interrupt_table[i].id) {
+			handler = type_el3_interrupt_table[i].handler;
+		}
+	}
+
+	if (handler != NULL) {
+		(void)handler(intr_id, flags, handle, cookie);
+	}
+
+	return 0;
+}
+
+void bl31_platform_setup(void)
+{
+	prepare_dtb();
+
+	/* Initialize the gic cpu and distributor interfaces */
+	plat_gic_driver_init();
+	plat_gic_init();
+
+	if (platform_id != EMU) {
+		init_scmi_server();
+	}
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	uint64_t flags = 0;
+	int32_t rc;
+
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
+					     rdo_el3_interrupt_handler, flags);
+	if (rc != 0) {
+		panic();
+	}
+
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
+}
+
+/*
+ * Perform the very early platform specific architectural setup here.
+ */
+void bl31_plat_arch_setup(void)
+{
+	const mmap_region_t bl_regions[] = {
+		MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+		MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+				MT_CODE | MT_SECURE),
+		MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
+				MT_RO_DATA | MT_SECURE),
+		MAP_REGION_FLAT(SMT_BUFFER_BASE, 0x1000,
+			MT_DEVICE | MT_RW | MT_NON_CACHEABLE | MT_EXECUTE_NEVER | MT_NS),
+		{0}
+	};
+
+	setup_page_tables(bl_regions, plat_get_mmap());
+	enable_mmu(0);
+}
diff --git a/plat/xilinx/versal_net/versal_net_gicv3.c b/plat/amd/versal2/gicv3.c
similarity index 72%
rename from plat/xilinx/versal_net/versal_net_gicv3.c
rename to plat/amd/versal2/gicv3.c
index 2fdef12e..c7b44e16 100644
--- a/plat/xilinx/versal_net/versal_net_gicv3.c
+++ b/plat/amd/versal2/gicv3.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,36 +11,36 @@
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 
 #include <plat_private.h>
-#include <platform_def.h>
 
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
  * the way the GICv3 driver is initialised and used.
  *****************************************************************************/
-#pragma weak plat_versal_net_gic_driver_init
-#pragma weak plat_versal_net_gic_init
-#pragma weak plat_versal_net_gic_cpuif_enable
-#pragma weak plat_versal_net_gic_cpuif_disable
-#pragma weak plat_versal_net_gic_pcpu_init
-#pragma weak plat_versal_net_gic_redistif_on
-#pragma weak plat_versal_net_gic_redistif_off
+#pragma weak plat_gic_driver_init
+#pragma weak plat_gic_init
+#pragma weak plat_gic_cpuif_enable
+#pragma weak plat_gic_cpuif_disable
+#pragma weak plat_gic_pcpu_init
+#pragma weak plat_gic_redistif_on
+#pragma weak plat_gic_redistif_off
 
 /* The GICv3 driver only needs to be initialized in EL3 */
 static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
-static const interrupt_prop_t versal_net_interrupt_props[] = {
-	PLAT_VERSAL_NET_G1S_IRQ_PROPS(INTR_GROUP1S),
-	PLAT_VERSAL_NET_G0_IRQ_PROPS(INTR_GROUP0)
+static const interrupt_prop_t _interrupt_props[] = {
+	PLAT_G1S_IRQ_PROPS(INTR_GROUP1S),
+	PLAT_G0_IRQ_PROPS(INTR_GROUP0)
 };
 
 /*
  * We save and restore the GICv3 context on system suspend. Allocate the
  * data in the designated EL3 Secure carve-out memory.
  */
-static gicv3_redist_ctx_t rdist_ctx __section(".versal_net_el3_tzc_dram");
-static gicv3_dist_ctx_t dist_ctx __section(".versal_net_el3_tzc_dram");
+static gicv3_redist_ctx_t rdist_ctx __section("._el3_tzc_dram");
+static gicv3_dist_ctx_t dist_ctx __section("._el3_tzc_dram");
 
 /*
  * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
@@ -56,23 +56,23 @@ static gicv3_dist_ctx_t dist_ctx __section(".versal_net_el3_tzc_dram");
  *   - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
  *   - No CPUs implemented in the system use affinity level 3.
  */
-static uint32_t versal_net_gicv3_mpidr_hash(u_register_t mpidr)
+static uint32_t _gicv3_mpidr_hash(u_register_t mpidr)
 {
 	mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
 	return plat_core_pos_by_mpidr(mpidr);
 }
 
-static const gicv3_driver_data_t versal_net_gic_data __unused = {
+static const gicv3_driver_data_t _gic_data __unused = {
 	.gicd_base = PLAT_GICD_BASE_VALUE,
 	.gicr_base = PLAT_GICR_BASE_VALUE,
-	.interrupt_props = versal_net_interrupt_props,
-	.interrupt_props_num = ARRAY_SIZE(versal_net_interrupt_props),
+	.interrupt_props = _interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
 	.rdistif_base_addrs = rdistif_base_addrs,
-	.mpidr_to_core_pos = versal_net_gicv3_mpidr_hash
+	.mpidr_to_core_pos = _gicv3_mpidr_hash
 };
 
-void __init plat_versal_net_gic_driver_init(void)
+void __init plat_gic_driver_init(void)
 {
 	/*
 	 * The GICv3 driver is initialized in EL3 and does not need
@@ -81,14 +81,14 @@ void __init plat_versal_net_gic_driver_init(void)
 	 * not need GIC interface base addresses to be configured.
 	 */
 #if IMAGE_BL31
-	gicv3_driver_init(&versal_net_gic_data);
+	gicv3_driver_init(&_gic_data);
 #endif
 }
 
 /******************************************************************************
- * Versal NET common helper to initialize the GIC. Only invoked by BL31
+ * common helper to initialize the GIC. Only invoked by BL31
  *****************************************************************************/
-void __init plat_versal_net_gic_init(void)
+void __init plat_gic_init(void)
 {
 	gicv3_distif_init();
 	gicv3_rdistif_init(plat_my_core_pos());
@@ -96,48 +96,46 @@ void __init plat_versal_net_gic_init(void)
 }
 
 /******************************************************************************
- * Versal NET common helper to enable the GIC CPU interface
+ * common helper to enable the GIC CPU interface
  *****************************************************************************/
-void plat_versal_net_gic_cpuif_enable(void)
+void plat_gic_cpuif_enable(void)
 {
 	gicv3_cpuif_enable(plat_my_core_pos());
 }
 
 /******************************************************************************
- * Versal NET common helper to disable the GIC CPU interface
+ * common helper to disable the GIC CPU interface
  *****************************************************************************/
-void plat_versal_net_gic_cpuif_disable(void)
+void plat_gic_cpuif_disable(void)
 {
 	gicv3_cpuif_disable(plat_my_core_pos());
 }
 
 /******************************************************************************
- * Versal NET common helper to initialize the per-cpu redistributor interface in
- * GICv3
+ * common helper to initialize the per-cpu redistributor interface in GICv3
  *****************************************************************************/
-void plat_versal_net_gic_pcpu_init(void)
+void plat_gic_pcpu_init(void)
 {
 	gicv3_rdistif_init(plat_my_core_pos());
 }
 
 /******************************************************************************
- * Versal NET common helpers to power GIC redistributor interface
+ * common helpers to power GIC redistributor interface
  *****************************************************************************/
-void plat_versal_net_gic_redistif_on(void)
+void plat_gic_redistif_on(void)
 {
 	gicv3_rdistif_on(plat_my_core_pos());
 }
 
-void plat_versal_net_gic_redistif_off(void)
+void plat_gic_redistif_off(void)
 {
 	gicv3_rdistif_off(plat_my_core_pos());
 }
 
 /******************************************************************************
- * Versal NET common helper to save & restore the GICv3 on resume from system
- * suspend
+ * common helper to save & restore the GICv3 on resume from system suspend
  *****************************************************************************/
-void plat_versal_net_gic_save(void)
+void plat_gic_save(void)
 {
 	/*
 	 * If an ITS is available, save its context before
@@ -165,7 +163,7 @@ void plat_versal_net_gic_save(void)
 	 */
 }
 
-void plat_versal_net_gic_resume(void)
+void plat_gic_resume(void)
 {
 	/* Restore the GIC Distributor context */
 	gicv3_distif_init_restore(&dist_ctx);
diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h
new file mode 100644
index 00000000..f3a79076
--- /dev/null
+++ b/plat/amd/versal2/include/def.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEF_H
+#define DEF_H
+
+#include <plat/arm/common/smccc_def.h>
+#include <plat/common/common_def.h>
+
+#define MAX_INTR_EL3			2
+
+/* List all consoles */
+#define VERSAL2_CONSOLE_ID_none		0
+#define VERSAL2_CONSOLE_ID_pl011	1
+#define VERSAL2_CONSOLE_ID_pl011_0       1
+#define VERSAL2_CONSOLE_ID_pl011_1       2
+#define VERSAL2_CONSOLE_ID_dcc           3
+#define VERSAL2_CONSOLE_ID_dtb           4
+
+#define CONSOLE_IS(con) (VERSAL2_CONSOLE_ID_ ## con == VERSAL2_CONSOLE)
+
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011   1
+#define RT_CONSOLE_ID_pl011_0   1
+#define RT_CONSOLE_ID_pl011_1   2
+#define RT_CONSOLE_ID_dcc       3
+#define RT_CONSOLE_ID_dtb       4
+
+#define RT_CONSOLE_IS(con)      (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
+/* List all platforms */
+#define SILICON		U(0)
+#define SPP			U(1)
+#define EMU			U(2)
+#define QEMU			U(3)
+#define SPP_MMD			U(5)
+#define EMU_MMD			U(6)
+#define QEMU_COSIM		U(7)
+
+/* For platform detection */
+#define PMC_TAP				U(0xF11A0000)
+#define PMC_TAP_VERSION			(PMC_TAP + 0x4U)
+# define PLATFORM_MASK			GENMASK(27U, 24U)
+# define PLATFORM_VERSION_MASK		GENMASK(31U, 28U)
+
+/* Global timer reset */
+#define PSX_CRF			U(0xEC200000)
+#define ACPU0_CLK_CTRL		U(0x10C)
+#define ACPU_CLK_CTRL_CLKACT	BIT(25)
+
+#define RST_APU0_OFFSET		U(0x300)
+#define RST_APU_COLD_RESET	BIT(0)
+#define RST_APU_WARN_RESET	BIT(4)
+#define RST_APU_CLUSTER_COLD_RESET	BIT(8)
+#define RST_APU_CLUSTER_WARM_RESET	BIT(9)
+
+#define PSX_CRF_RST_TIMESTAMP_OFFSET	U(0x33C)
+
+#define APU_PCLI			(0xECB10000ULL)
+#define APU_PCLI_CPU_STEP		(0x30ULL)
+#define APU_PCLI_CLUSTER_CPU_STEP	(4ULL * APU_PCLI_CPU_STEP)
+#define APU_PCLI_CLUSTER_OFFSET		U(0x8000)
+#define APU_PCLI_CLUSTER_STEP		U(0x1000)
+#define PCLI_PREQ_OFFSET		U(0x4)
+#define PREQ_CHANGE_REQUEST		BIT(0)
+#define PCLI_PSTATE_OFFSET		U(0x8)
+#define PCLI_PSTATE_VAL_SET		U(0x48)
+#define PCLI_PSTATE_VAL_CLEAR		U(0x38)
+
+/* Firmware Image Package */
+#define PRIMARY_CPU		U(0)
+
+#define CORE_0_ISR_WAKE_OFFSET			(0x00000020ULL)
+#define APU_PCIL_CORE_X_ISR_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_WAKE_MASK		(0x00000001U)
+#define CORE_0_IEN_WAKE_OFFSET			(0x00000028ULL)
+#define APU_PCIL_CORE_X_IEN_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IEN_WAKE_MASK		(0x00000001U)
+#define CORE_0_IDS_WAKE_OFFSET			(0x0000002CULL)
+#define APU_PCIL_CORE_X_IDS_WAKE_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_WAKE_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IDS_WAKE_MASK		(0x00000001U)
+#define CORE_0_ISR_POWER_OFFSET			(0x00000010ULL)
+#define APU_PCIL_CORE_X_ISR_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_ISR_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_ISR_POWER_MASK		U(0x00000001)
+#define CORE_0_IEN_POWER_OFFSET			(0x00000018ULL)
+#define APU_PCIL_CORE_X_IEN_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IEN_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IEN_POWER_MASK		(0x00000001U)
+#define CORE_0_IDS_POWER_OFFSET			(0x0000001CULL)
+#define APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id)	(APU_PCLI + (CORE_0_IDS_POWER_OFFSET + \
+						 (APU_PCLI_CPU_STEP * (cpu_id))))
+#define APU_PCIL_CORE_X_IDS_POWER_MASK		(0x00000001U)
+#define CORE_PWRDN_EN_BIT_MASK			(0x1U)
+
+/*******************************************************************************
+ * memory map related constants
+ ******************************************************************************/
+/* IPP 1.2/SPP 0.9 mapping */
+#define DEVICE0_BASE		U(0xE8000000) /* psx, crl, iou */
+#define DEVICE0_SIZE		U(0x08000000)
+#define DEVICE1_BASE		U(0xE2000000) /* gic */
+#define DEVICE1_SIZE		U(0x00800000)
+#define DEVICE2_BASE		U(0xF1000000) /* uart, pmc_tap */
+#define DEVICE2_SIZE		U(0x01000000)
+#define CRF_BASE		U(0xFD1A0000)
+#define CRF_SIZE		U(0x00600000)
+#define IPI_BASE		U(0xEB300000)
+#define IPI_SIZE		U(0x00100000)
+
+/* CRL */
+#define CRL					U(0xEB5E0000)
+#define CRL_TIMESTAMP_REF_CTRL_OFFSET	U(0x14C)
+#define CRL_RST_TIMESTAMP_OFFSET		U(0x348)
+
+#define CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT	(1U << 25U)
+
+/* IOU SCNTRS */
+#define IOU_SCNTRS					U(0xEC920000)
+#define IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET	U(0)
+#define IOU_SCNTRS_BASE_FREQ_OFFSET			U(0x20)
+
+#define IOU_SCNTRS_CONTROL_EN	U(1)
+
+#define APU_CLUSTER0		U(0xECC00000)
+#define APU_RVBAR_L_0		U(0x40)
+#define APU_RVBAR_H_0		U(0x44)
+#define APU_CLUSTER_STEP	U(0x100000)
+
+#define SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL	U(0xF1060504)
+#define PMXC_IOU_SLCR_SRAM_CSR	U(0xF106104C)
+#define PMXC_IOU_SLCR_PHY_RESET	U(0xF1061050)
+#define PMXC_IOU_SLCR_TX_RX_CONFIG_RDY	U(0xF1061054)
+#define PMXC_CRP_RST_UFS	U(0xF1260340)
+
+/*******************************************************************************
+ * IRQ constants
+ ******************************************************************************/
+#define IRQ_SEC_PHY_TIMER	U(29)
+
+/*******************************************************************************
+ * UART related constants
+ ******************************************************************************/
+#define UART0_BASE		U(0xF1920000)
+#define UART1_BASE		U(0xF1930000)
+
+#define UART_BAUDRATE	115200
+
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
+#define UART_BASE	    UART0_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(pl011_1)
+#define UART_BASE           UART1_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
+#else
+# error "invalid VERSAL2_CONSOLE"
+#endif
+
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE UART0_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE UART1_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
+#endif /* DEF_H */
diff --git a/plat/amd/versal2/include/plat_ipi.h b/plat/amd/versal2/include/plat_ipi.h
new file mode 100644
index 00000000..503ec1fe
--- /dev/null
+++ b/plat/amd/versal2/include/plat_ipi.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Versal Gen 2 IPI management enums and defines */
+
+#ifndef PLAT_IPI_H
+#define PLAT_IPI_H
+
+#include <stdint.h>
+
+#include <ipi.h>
+
+/*********************************************************************
+ * IPI agent IDs macros
+ ********************************************************************/
+#define IPI_ID_PMC	1U
+#define IPI_ID_APU	2U
+#define IPI_ID_RPU0	3U
+#define IPI_ID_RPU1	4U
+#define IPI_ID_3	5U
+#define IPI_ID_4	6U
+#define IPI_ID_5	7U
+#define IPI_ID_MAX	8U
+
+/*********************************************************************
+ * IPI message buffers
+ ********************************************************************/
+#define IPI_BUFFER_BASEADDR	(0xEB3F0000U)
+
+#define IPI_LOCAL_ID		IPI_ID_APU
+#define IPI_REMOTE_ID		IPI_ID_PMC
+
+#define IPI_BUFFER_LOCAL_BASE	(IPI_BUFFER_BASEADDR + (IPI_LOCAL_ID * 0x200U))
+#define IPI_BUFFER_REMOTE_BASE	(IPI_BUFFER_BASEADDR + (IPI_REMOTE_ID * 0x200U))
+
+#define IPI_BUFFER_TARGET_LOCAL_OFFSET	(IPI_LOCAL_ID * 0x40U)
+#define IPI_BUFFER_TARGET_REMOTE_OFFSET	(IPI_REMOTE_ID * 0x40U)
+
+#define IPI_BUFFER_MAX_WORDS	8
+
+#define IPI_BUFFER_REQ_OFFSET	0x0U
+#define IPI_BUFFER_RESP_OFFSET	0x20U
+
+/*********************************************************************
+ * Platform specific IPI API declarations
+ ********************************************************************/
+
+/* Configure IPI table */
+extern void soc_ipi_config_table_init(void);
+
+/*******************************************************************************
+ * IPI registers and bitfields
+ ******************************************************************************/
+#define IPI0_REG_BASE		(0xEB330000U)
+#define IPI0_TRIG_BIT		(1 << 2)
+#define PMC_IPI_TRIG_BIT	(1 << 1)
+#define IPI1_REG_BASE		(0xEB340000U)
+#define IPI1_TRIG_BIT		(1 << 3)
+#define IPI2_REG_BASE		(0xEB350000U)
+#define IPI2_TRIG_BIT		(1 << 4)
+#define IPI3_REG_BASE		(0xEB360000U)
+#define IPI3_TRIG_BIT		(1 << 5)
+#define IPI4_REG_BASE		(0xEB370000U)
+#define IPI4_TRIG_BIT		(1 << 6)
+#define IPI5_REG_BASE		(0xEB380000U)
+#define IPI5_TRIG_BIT		(1 << 7)
+
+#endif /* PLAT_IPI_H */
diff --git a/plat/amd/versal2/include/plat_macros.S b/plat/amd/versal2/include/plat_macros.S
new file mode 100644
index 00000000..d20f693d
--- /dev/null
+++ b/plat/amd/versal2/include/plat_macros.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/arm/gicv3.h>
+
+#include "../include/platform_def.h"
+
+.section .rodata.gic_reg_name, "aS"
+/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+
+/* Applicable only to GICv3 with SRE enabled */
+icc_regs:
+	.asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
+
+/* Registers common to both GICv2 and GICv3 */
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+	/* ---------------------------------------------
+	 * The below utility macro prints out relevant GIC
+	 * registers whenever an unhandled exception is
+	 * taken in BL31 on platform.
+	 * Expects: GICD base in x16, GICC base in x17
+	 * Clobbers: x0 - x10, sp
+	 * ---------------------------------------------
+	 */
+	.macro _print_gic_regs
+	/* Check for GICv3 system register access */
+	mrs	x7, id_aa64pfr0_el1
+	ubfx	x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
+	cmp	x7, #1
+	b.ne	print_gicv2
+
+	/* Check for SRE enable */
+	mrs	x8, ICC_SRE_EL3
+	tst	x8, #ICC_SRE_SRE_BIT
+	b.eq	print_gicv2
+
+	/* Load the icc reg list to x6 */
+	adr	x6, icc_regs
+	/* Load the icc regs to gp regs used by str_in_crash_buf_print */
+	mrs	x8, ICC_HPPIR0_EL1
+	mrs	x9, ICC_HPPIR1_EL1
+	mrs	x10, ICC_CTLR_EL3
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+	b	print_gic_common
+
+print_gicv2:
+	/* Load the gicc reg list to x6 */
+	adr	x6, gicc_regs
+	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+	ldr	w8, [x17, #GICC_HPPIR]
+	ldr	w9, [x17, #GICC_AHPPIR]
+	ldr	w10, [x17, #GICC_CTLR]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+
+print_gic_common:
+	/* Print the GICD_ISPENDR regs */
+	add	x7, x16, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+gicd_ispendr_loop:
+	sub	x4, x7, x16
+	cmp	x4, #0x280
+	b.eq	exit_print_gic_regs
+	bl	asm_print_hex
+
+	adr	x4, spacer
+	bl	asm_print_str
+
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+
+	adr	x4, newline
+	bl	asm_print_str
+	b	gicd_ispendr_loop
+exit_print_gic_regs:
+	.endm
+
+	/* ---------------------------------------------
+	 * The below required platform porting macro
+	 * prints out relevant GIC and CCI registers
+	 * whenever an unhandled exception is taken in
+	 * BL31.
+	 * Clobbers: x0 - x10, x16, x17, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_crash_print_regs
+	/*
+	 * Empty for now to handle more platforms variant.
+	 * Uncomment it when versions are stable
+	 */
+	/*
+	mov_imm	x17, PLAT_GICD_BASE_VALUE
+	mov_imm	x16, PLAT_GICR_BASE_VALUE
+	_print_gic_regs
+	*/
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/amd/versal2/include/plat_pm_common.h b/plat/amd/versal2/include/plat_pm_common.h
new file mode 100644
index 00000000..5e684720
--- /dev/null
+++ b/plat/amd/versal2/include/plat_pm_common.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Contains platform specific definitions of commonly used macros data types
+ * for PU Power Management. This file should be common for all PU's.
+ */
+
+#ifndef PLAT_PM_COMMON_H
+#define PLAT_PM_COMMON_H
+
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include "pm_defs.h"
+
+#define NON_SECURE_FLAG		1U
+#define SECURE_FLAG		0U
+
+#endif /* PLAT_PM_COMMON_H */
diff --git a/plat/amd/versal2/include/plat_private.h b/plat/amd/versal2/include/plat_private.h
new file mode 100644
index 00000000..5a2e5bd9
--- /dev/null
+++ b/plat/amd/versal2/include/plat_private.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
+
+#include <bl31/interrupt_mgmt.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#define SPP_PSXC_MMI_V2_0	U(6)
+#define SPP_PSXC_MMI_V3_0	U(8)
+
+/* MMD */
+#define SPP_PSXC_ISP_AIE_V2_0	U(3)
+#define SPP_PSXC_MMD_AIE_FRZ_EA	U(4)
+#define SPP_PSXC_MMD_AIE_V3_0	U(5)
+
+typedef struct versal_intr_info_type_el3 {
+	uint32_t id;
+	interrupt_type_handler_t handler;
+} versal_intr_info_type_el3_t;
+
+void config_setup(void);
+uint32_t get_uart_clk(void);
+
+const mmap_region_t *plat_get_mmap(void);
+
+void plat_gic_driver_init(void);
+void plat_gic_init(void);
+void plat_gic_cpuif_enable(void);
+void plat_gic_cpuif_disable(void);
+void plat_gic_pcpu_init(void);
+void plat_gic_save(void);
+void plat_gic_resume(void);
+void plat_gic_redistif_on(void);
+void plat_gic_redistif_off(void);
+
+extern uint32_t cpu_clock, platform_id, platform_version;
+void board_detection(void);
+const char *board_name_decode(void);
+uint64_t smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+		       uint64_t x4, void *cookie, void *handle, uint64_t flags);
+int32_t sip_svc_setup_init(void);
+/*
+ * Register handler to specific GIC entrance
+ * for INTR_TYPE_EL3 type of interrupt
+ */
+int request_intr_type_el3(uint32_t irq, interrupt_type_handler_t fiq_handler);
+
+#endif /* PLAT_PRIVATE_H */
diff --git a/plat/amd/versal2/include/platform_def.h b/plat/amd/versal2/include/platform_def.h
new file mode 100644
index 00000000..42c9b08a
--- /dev/null
+++ b/plat/amd/versal2/include/platform_def.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include "def.h"
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE		U(0x440)
+
+#define PLATFORM_CLUSTER_COUNT		U(4)
+#define PLATFORM_CORE_COUNT_PER_CLUSTER	U(2) /* 2 CPUs per cluster */
+
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * PLATFORM_CORE_COUNT_PER_CLUSTER)
+
+#define PLAT_MAX_PWR_LVL		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at the top of the Trusted SRAM (just below the shared memory, if
+ * present). BL31_BASE is calculated using the current BL31 debug size plus a
+ * little space for growth.
+ */
+#ifndef MEM_BASE
+# define BL31_BASE			U(0xBBF00000)
+# define BL31_LIMIT			U(0xBC000000)
+#else
+# define BL31_BASE			U(MEM_BASE)
+# define BL31_LIMIT			U(MEM_BASE + MEM_SIZE)
+# ifdef MEM_PROGBITS_SIZE
+#  define BL31_PROGBITS_LIMIT		U(MEM_BASE + \
+					  MEM_PROGBITS_SIZE)
+# endif
+#endif
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+#ifndef BL32_MEM_BASE
+# define BL32_BASE			U(0x60000000)
+# define BL32_LIMIT			U(0x80000000)
+#else
+# define BL32_BASE			U(BL32_MEM_BASE)
+# define BL32_LIMIT			U(BL32_MEM_BASE + BL32_MEM_SIZE)
+#endif
+
+/*******************************************************************************
+ * BL33 specific defines.
+ ******************************************************************************/
+#ifndef PRELOADED_BL33_BASE
+# define PLAT_ARM_NS_IMAGE_BASE		U(0x8000000)
+#else
+# define PLAT_ARM_NS_IMAGE_BASE		U(PRELOADED_BL33_BASE)
+#endif
+
+/*******************************************************************************
+ * TSP  specific defines.
+ ******************************************************************************/
+#define TSP_SEC_MEM_BASE		BL32_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE)
+
+/* ID of the secure physical generic timer interrupt used by the TSP */
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+#define TSP_IRQ_SEC_PHY_TIMER		ARM_IRQ_SEC_PHY_TIMER
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_DDR_LOWMEM_MAX		U(0x80000000)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32U)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32U)
+
+#define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
+
+#define PLAT_OCM_BASE			U(0xBBF00000)
+#define PLAT_OCM_LIMIT			U(0xBC000000)
+
+#if TRANSFER_LIST
+/*
+ * FIXME: This address should come from firmware before TF-A
+ * Having this to make sure the transfer list functionality works
+ */
+#define FW_HANDOFF_BASE         U(0x70000000)
+#define FW_HANDOFF_SIZE         U(0x10000)
+#endif
+
+#define IS_TFA_IN_OCM(x)	((x >= PLAT_OCM_BASE) && (x < PLAT_OCM_LIMIT))
+
+#ifndef MAX_MMAP_REGIONS
+#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+#define MAX_MMAP_REGIONS		11
+#else
+#define MAX_MMAP_REGIONS		10
+#endif
+#endif
+
+#ifndef MAX_XLAT_TABLES
+#define MAX_XLAT_TABLES			U(12)
+#endif
+
+#define CACHE_WRITEBACK_SHIFT	U(6)
+#define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
+
+#define PLAT_GICD_BASE_VALUE	U(0xE2000000)
+#define PLAT_GICR_BASE_VALUE	U(0xE2060000)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLAT_IPI_IRQ	89
+#define PLAT_VERSAL_IPI_IRQ	PLAT_IPI_IRQ
+
+#define PLAT_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
+#define PLAT_G0_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE), \
+
+#define IRQ_MAX		200U
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/amd/versal2/include/scmi.h b/plat/amd/versal2/include/scmi.h
new file mode 100644
index 00000000..761535bd
--- /dev/null
+++ b/plat/amd/versal2/include/scmi.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCMI_H
+#define SCMI_H
+
+#include "versal2-scmi.h"
+
+#define SIP_SCMI	(0xC200ffffU)
+#define SMT_BUFFER_BASE	0x7fffe000
+
+void init_scmi_server(void);
+
+size_t plat_scmi_pd_count(unsigned int agent_id);
+const char *plat_scmi_pd_get_name(unsigned int agent_id, unsigned int pd_id);
+unsigned int plat_scmi_pd_statistics(unsigned int agent_id, unsigned long *pd_id);
+unsigned int plat_scmi_pd_get_attributes(unsigned int agent_id, unsigned int pd_id);
+unsigned int plat_scmi_pd_get_state(unsigned int agent_id, unsigned int pd_id);
+int32_t plat_scmi_pd_set_state(unsigned int agent_id, unsigned int flags, unsigned int pd_id,
+				unsigned int state);
+
+#define SCMI_VENDOR	"AMD"
+#define SCMI_PRODUCT	"Versal Gen 2"
+
+#endif /* DEF_H */
diff --git a/plat/amd/versal2/include/versal2-scmi.h b/plat/amd/versal2/include/versal2-scmi.h
new file mode 100644
index 00000000..c08b4b1a
--- /dev/null
+++ b/plat/amd/versal2/include/versal2-scmi.h
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+/*
+ * Macros IDs for AMD Versal Gen 2
+ *
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * Michal Simek <michal.simek@amd.com>
+ */
+
+#ifndef _VERSAL2_SCMI_H
+#define _VERSAL2_SCMI_H
+
+#define CLK_GEM0_0	0
+#define CLK_GEM0_1	1
+#define CLK_GEM0_2	2
+#define CLK_GEM0_3	3
+#define CLK_GEM0_4	4
+#define CLK_GEM1_0	5
+#define CLK_GEM1_1	6
+#define CLK_GEM1_2	7
+#define CLK_GEM1_3	8
+#define CLK_GEM1_4	9
+#define CLK_SERIAL0_0	10
+#define CLK_SERIAL0_1	11
+#define CLK_SERIAL1_0	12
+#define CLK_SERIAL1_1	13
+#define CLK_UFS0_0	14
+#define CLK_UFS0_1	15
+#define CLK_UFS0_2	16
+#define CLK_USB0_0	17
+#define CLK_USB0_1	18
+#define CLK_USB0_2	19
+#define CLK_USB1_0	20
+#define CLK_USB1_1	21
+#define CLK_USB1_2	22
+#define CLK_MMC0_0	23
+#define CLK_MMC0_1	24
+#define CLK_MMC0_2	25
+#define CLK_MMC1_0	26
+#define CLK_MMC1_1	27
+#define CLK_MMC1_2	28
+#define CLK_TTC0_0	29
+#define CLK_TTC1_0	30
+#define CLK_TTC2_0	31
+#define CLK_TTC3_0	32
+#define CLK_TTC4_0	33
+#define CLK_TTC5_0	34
+#define CLK_TTC6_0	35
+#define CLK_TTC7_0	36
+#define CLK_I2C0_0	37
+#define CLK_I2C1_0	38
+#define CLK_I2C2_0	39
+#define CLK_I2C3_0	40
+#define CLK_I2C4_0	41
+#define CLK_I2C5_0	42
+#define CLK_I2C6_0	43
+#define CLK_I2C7_0	44
+#define CLK_OSPI0_0	45
+#define CLK_QSPI0_0	46
+#define CLK_QSPI0_1	47
+#define CLK_WWDT0_0	48
+#define CLK_WWDT1_0	49
+#define CLK_WWDT2_0	50
+#define CLK_WWDT3_0	51
+#define CLK_ADMA0_0	52
+#define CLK_ADMA0_1	53
+#define CLK_ADMA1_0	54
+#define CLK_ADMA1_1	55
+#define CLK_ADMA2_0	56
+#define CLK_ADMA2_1	57
+#define CLK_ADMA3_0	58
+#define CLK_ADMA3_1	59
+#define CLK_ADMA4_0	60
+#define CLK_ADMA4_1	61
+#define CLK_ADMA5_0	62
+#define CLK_ADMA5_1	63
+#define CLK_ADMA6_0	64
+#define CLK_ADMA6_1	65
+#define CLK_ADMA7_0	66
+#define CLK_ADMA7_1	67
+#define CLK_CAN0_0	68
+#define CLK_CAN0_1	69
+#define CLK_CAN1_0	70
+#define CLK_CAN1_1	71
+#define CLK_CAN2_0	72
+#define CLK_CAN2_1	73
+#define CLK_CAN3_0	74
+#define CLK_CAN3_1	75
+#define CLK_PS_GPIO_0	76
+#define CLK_PMC_GPIO_0	77
+#define CLK_SPI0_0	78
+#define CLK_SPI0_1	79
+#define CLK_SPI1_0	80
+#define CLK_SPI1_1	81
+#define CLK_I3C0_0	82
+#define CLK_I3C1_0	83
+#define CLK_I3C2_0	84
+#define CLK_I3C3_0	85
+#define CLK_I3C4_0	86
+#define CLK_I3C5_0	87
+#define CLK_I3C6_0	88
+#define CLK_I3C7_0	89
+
+#define RESET_GEM0_0	0
+#define RESET_GEM1_0	1
+#define RESET_SERIAL0_0	2
+#define RESET_SERIAL1_0	3
+#define RESET_UFS0_0	4
+#define RESET_I2C0_0	5
+#define RESET_I2C1_0	6
+#define RESET_I2C2_0	7
+#define RESET_I2C3_0	8
+#define RESET_I2C4_0	9
+#define RESET_I2C5_0	10
+#define RESET_I2C6_0	11
+#define RESET_I2C7_0	12
+#define RESET_I2C8_0	13
+#define RESET_OSPI0_0	14
+#define RESET_USB0_0	15
+#define RESET_USB0_1	16
+#define RESET_USB0_2	17
+#define RESET_USB1_0	18
+#define RESET_USB1_1	19
+#define RESET_USB1_2	20
+#define RESET_MMC0_0	21
+#define RESET_MMC1_0	22
+#define RESET_SPI0_0	23
+#define RESET_SPI1_0	24
+#define RESET_QSPI0_0	25
+#define RESET_I3C0_0	26
+#define RESET_I3C1_0	27
+#define RESET_I3C2_0	28
+#define RESET_I3C3_0	29
+#define RESET_I3C4_0	30
+#define RESET_I3C5_0	31
+#define RESET_I3C6_0	32
+#define RESET_I3C7_0	33
+#define RESET_I3C8_0	34
+#define RESET_UFSPHY_0  35
+
+#define PD_USB0		0
+#define PD_USB1		1
+
+#endif /* _VERSAL2_SCMI_H */
diff --git a/plat/amd/versal2/plat_psci.c b/plat/amd/versal2/plat_psci.c
new file mode 100644
index 00000000..eab032dd
--- /dev/null
+++ b/plat/amd/versal2/plat_psci.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <plat_arm.h>
+
+#include <plat_private.h>
+#include <pm_defs.h>
+
+#define PM_RET_ERROR_NOFEATURE U(19)
+#define ALWAYSTRUE true
+#define LINEAR_MODE BIT(1)
+
+static uintptr_t _sec_entry;
+
+static void zynqmp_cpu_standby(plat_local_state_t cpu_state)
+{
+	dsb();
+	wfi();
+}
+
+#define MPIDR_MT_BIT	(24)
+
+static int32_t zynqmp_nopmu_pwr_domain_on(u_register_t mpidr)
+{
+	uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr) & ~BIT(MPIDR_MT_BIT);
+	uint32_t cpu = cpu_id % PLATFORM_CORE_COUNT_PER_CLUSTER;
+	uint32_t cluster = cpu_id / PLATFORM_CORE_COUNT_PER_CLUSTER;
+	uintptr_t apu_cluster_base = 0, apu_pcli_base, apu_pcli_cluster = 0;
+	uintptr_t rst_apu_cluster = PSX_CRF + RST_APU0_OFFSET + ((uint64_t)cluster * 0x4U);
+
+	VERBOSE("%s: mpidr: 0x%lx, cpuid: %x, cpu: %x, cluster: %x\n",
+		__func__, mpidr, cpu_id, cpu, cluster);
+
+	if (cpu_id == -1) {
+		return PSCI_E_INTERN_FAIL;
+	}
+
+	if (cluster > 3) {
+		panic();
+	}
+
+	apu_pcli_cluster = APU_PCLI + APU_PCLI_CLUSTER_OFFSET + ((uint64_t)cluster * APU_PCLI_CLUSTER_STEP);
+	apu_cluster_base = APU_CLUSTER0 + ((uint64_t)cluster * APU_CLUSTER_STEP);
+
+	/* Enable clock */
+	mmio_setbits_32(PSX_CRF + ACPU0_CLK_CTRL + ((uint64_t)cluster * 0x4U), ACPU_CLK_CTRL_CLKACT);
+
+	/* Enable cluster states */
+	mmio_setbits_32(apu_pcli_cluster + PCLI_PSTATE_OFFSET, PCLI_PSTATE_VAL_SET);
+	mmio_setbits_32(apu_pcli_cluster + PCLI_PREQ_OFFSET, PREQ_CHANGE_REQUEST);
+
+	/* assert core reset */
+	mmio_setbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
+
+	/* program RVBAR */
+	mmio_write_32(apu_cluster_base + APU_RVBAR_L_0 + (cpu << 3),
+		      (uint32_t)_sec_entry);
+	mmio_write_32(apu_cluster_base + APU_RVBAR_H_0 + (cpu << 3),
+		      _sec_entry >> 32);
+
+	/* de-assert core reset */
+	mmio_clrbits_32(rst_apu_cluster, ((RST_APU_COLD_RESET|RST_APU_WARN_RESET) << cpu));
+
+	/* clear cluster resets */
+	mmio_clrbits_32(rst_apu_cluster, RST_APU_CLUSTER_WARM_RESET);
+	mmio_clrbits_32(rst_apu_cluster, RST_APU_CLUSTER_COLD_RESET);
+
+	apu_pcli_base = APU_PCLI + (APU_PCLI_CPU_STEP * cpu) +
+			(APU_PCLI_CLUSTER_CPU_STEP * cluster);
+
+	mmio_write_32(apu_pcli_base + PCLI_PSTATE_OFFSET, PCLI_PSTATE_VAL_CLEAR);
+	mmio_write_32(apu_pcli_base + PCLI_PREQ_OFFSET, PREQ_CHANGE_REQUEST);
+
+	return PSCI_E_SUCCESS;
+}
+
+static void zynqmp_nopmu_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	plat_gic_cpuif_disable();
+}
+
+static void __dead2 zynqmp_nopmu_system_reset(void)
+{
+	while (ALWAYSTRUE) {
+		wfi();
+	}
+}
+
+static int32_t zynqmp_validate_ns_entrypoint(uint64_t ns_entrypoint)
+{
+	VERBOSE("Validate ns_entry point %lx\n", ns_entrypoint);
+
+	if ((ns_entrypoint) != 0U) {
+		return PSCI_E_SUCCESS;
+	} else {
+		return PSCI_E_INVALID_ADDRESS;
+	}
+}
+
+static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	plat_gic_pcpu_init();
+	plat_gic_cpuif_enable();
+}
+
+static void __dead2 zynqmp_system_off(void)
+{
+	while (ALWAYSTRUE) {
+		wfi();
+	}
+}
+
+static int32_t zynqmp_validate_power_state(uint32_t power_state, psci_power_state_t *req_state)
+{
+	return PSCI_E_SUCCESS;
+}
+
+static const struct plat_psci_ops _nopmc_psci_ops = {
+	.cpu_standby			= zynqmp_cpu_standby,
+	.pwr_domain_on			= zynqmp_nopmu_pwr_domain_on,
+	.pwr_domain_off			= zynqmp_nopmu_pwr_domain_off,
+	.system_reset			= zynqmp_nopmu_system_reset,
+	.validate_ns_entrypoint		= zynqmp_validate_ns_entrypoint,
+	.pwr_domain_on_finish		= zynqmp_pwr_domain_on_finish,
+	.system_off			= zynqmp_system_off,
+	.validate_power_state		= zynqmp_validate_power_state,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int32_t plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			    const struct plat_psci_ops **psci_ops)
+{
+	_sec_entry = sec_entrypoint;
+
+	VERBOSE("Setting up entry point %lx\n", _sec_entry);
+
+	*psci_ops = &_nopmc_psci_ops;
+
+	return 0;
+}
+
+int sip_svc_setup_init(void)
+{
+	return 0;
+}
+
+static int32_t no_pm_ioctl(uint32_t device_id, uint32_t ioctl_id,
+			   uint32_t arg1, uint32_t arg2)
+{
+	int32_t ret = 0;
+	VERBOSE("%s: ioctl_id: %x, arg1: %x\n", __func__, ioctl_id, arg1);
+
+	switch (ioctl_id) {
+	case IOCTL_OSPI_MUX_SELECT:
+		if ((arg1 == 0) || (arg1 == 1)) {
+			mmio_clrsetbits_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, LINEAR_MODE,
+					(arg1 ? LINEAR_MODE : 0));
+		} else {
+			ret = PM_RET_ERROR_ARGS;
+		}
+		break;
+	case IOCTL_UFS_TXRX_CFGRDY_GET:
+		ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_TX_RX_CONFIG_RDY);
+		break;
+	case IOCTL_UFS_SRAM_CSR_SEL:
+		if (arg1 == 1) {
+			ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_SRAM_CSR);
+		} else if (arg1 == 0) {
+			mmio_write_32(PMXC_IOU_SLCR_SRAM_CSR, arg2);
+		}
+		break;
+	case IOCTL_USB_SET_STATE:
+		break;
+	default:
+		ret = PM_RET_ERROR_NOFEATURE;
+		break;
+	}
+
+	return ret;
+}
+
+static uint64_t no_pm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
+			      uint64_t x4, void *cookie, void *handle, uint64_t flags)
+{
+	int32_t ret;
+	uint32_t arg[4], api_id;
+
+	arg[0] = (uint32_t)x1;
+	arg[1] = (uint32_t)(x1 >> 32);
+	arg[2] = (uint32_t)x2;
+	arg[3] = (uint32_t)(x2 >> 32);
+
+	api_id = smc_fid & FUNCID_NUM_MASK;
+	VERBOSE("%s: smc_fid: %x, api_id=0x%x\n", __func__, smc_fid, api_id);
+
+	switch (api_id) {
+	case PM_IOCTL:
+	{
+		ret = no_pm_ioctl(arg[0], arg[1], arg[2], arg[3]);
+		/* Firmware driver expects return code in upper 32 bits and
+		 * status in lower 32 bits.
+		 * status is always SUCCESS(0) for mmio low level register
+		 * r/w calls and return value is the value returned from
+		 * no_pm_ioctl
+		 */
+		SMC_RET1(handle, ((uint64_t)ret << 32));
+	}
+	case PM_GET_CHIPID:
+	{
+		uint32_t idcode, version_type;
+
+		idcode  = mmio_read_32(PMC_TAP);
+		version_type = mmio_read_32(PMC_TAP_VERSION);
+		SMC_RET2(handle, ((uint64_t)idcode << 32), version_type);
+	}
+	default:
+		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+uint64_t smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4,
+		     void *cookie, void *handle, uint64_t flags)
+{
+	return no_pm_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+}
diff --git a/plat/amd/versal2/plat_topology.c b/plat/amd/versal2/plat_topology.c
new file mode 100644
index 00000000..07631398
--- /dev/null
+++ b/plat/amd/versal2/plat_topology.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+
+static const uint8_t plat_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	1,
+	/* Number of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the second cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the third cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+	/* Number of children for the fourth cluster node */
+	PLATFORM_CORE_COUNT_PER_CLUSTER,
+};
+
+const uint8_t *plat_get_power_domain_tree_desc(void)
+{
+	return plat_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	uint32_t cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+
+	cluster_id = MPIDR_AFFLVL2_VAL(mpidr);
+	cpu_id = MPIDR_AFFLVL1_VAL(mpidr);
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -3;
+	}
+
+	/*
+	 * Validate cpu_id by checking whether it represents a CPU in
+	 * one of the two clusters present on the platform.
+	 */
+	if (cpu_id >= PLATFORM_CORE_COUNT_PER_CLUSTER) {
+		return -1;
+	}
+
+	return (cpu_id + (cluster_id * PLATFORM_CORE_COUNT_PER_CLUSTER));
+}
diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk
new file mode 100644
index 00000000..3114976b
--- /dev/null
+++ b/plat/amd/versal2/platform.mk
@@ -0,0 +1,159 @@
+# Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+PLAT_PATH := plat/amd/versal2
+
+override NEED_BL1 := no
+override NEED_BL2 := no
+
+# A78 Erratum for SoC
+ERRATA_A78_AE_1941500 := 1
+ERRATA_A78_AE_1951502 := 1
+ERRATA_A78_AE_2376748 := 1
+ERRATA_A78_AE_2395408 := 1
+ERRATA_ABI_SUPPORT    := 1
+
+# Platform Supports Armv8.2 extensions
+ARM_ARCH_MAJOR := 8
+ARM_ARCH_MINOR := 2
+
+override PROGRAMMABLE_RESET_ADDRESS := 1
+PSCI_EXTENDED_STATE_ID := 1
+SEPARATE_CODE_AND_RODATA := 1
+override RESET_TO_BL31 := 1
+PL011_GENERIC_UART := 1
+IPI_CRC_CHECK := 0
+GIC_ENABLE_V4_EXTN :=  0
+GICV3_SUPPORT_GIC600 := 1
+
+override CTX_INCLUDE_AARCH32_REGS    := 0
+
+# Platform to support Dynamic XLAT Table by default
+override PLAT_XLAT_TABLES_DYNAMIC := 1
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+
+ifdef MEM_BASE
+    $(eval $(call add_define,MEM_BASE))
+
+    ifndef MEM_SIZE
+        $(error "MEM_BASE defined without MEM_SIZE")
+    endif
+    $(eval $(call add_define,MEM_SIZE))
+
+    ifdef MEM_PROGBITS_SIZE
+        $(eval $(call add_define,MEM_PROGBITS_SIZE))
+    endif
+endif
+
+ifdef BL32_MEM_BASE
+    $(eval $(call add_define,BL32_MEM_BASE))
+
+    ifndef BL32_MEM_SIZE
+        $(error "BL32_MEM_BASE defined without BL32_MEM_SIZE")
+    endif
+    $(eval $(call add_define,BL32_MEM_SIZE))
+endif
+
+ifdef IPI_CRC_CHECK
+    $(eval $(call add_define,IPI_CRC_CHECK))
+endif
+
+USE_COHERENT_MEM := 0
+HW_ASSISTED_COHERENCY := 1
+
+VERSAL2_CONSOLE  ?=      pl011
+ifeq (${VERSAL2_CONSOLE}, $(filter ${VERSAL2_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
+	else
+	  $(error "Please define VERSAL2_CONSOLE")
+  endif
+
+$(eval $(call add_define_val,VERSAL2_CONSOLE,VERSAL2_CONSOLE_ID_${VERSAL2_CONSOLE}))
+
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq 	(${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+	$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
+
+ifdef XILINX_OF_BOARD_DTB_ADDR
+$(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
+endif
+
+PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
+				-Iplat/xilinx/common/include/			\
+				-Iplat/xilinx/common/ipi_mailbox_service/	\
+				-I${PLAT_PATH}/include/				\
+				-Iplat/xilinx/versal/pm_service/
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+include lib/libfdt/libfdt.mk
+
+PLAT_BL_COMMON_SOURCES	:=	\
+				drivers/arm/dcc/dcc_console.c			\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				${GICV3_SOURCES}				\
+				drivers/arm/pl011/aarch64/pl011_console.S	\
+				plat/common/aarch64/crash_console_helpers.S	\
+				plat/arm/common/arm_common.c			\
+				plat/common/plat_gicv3.c			\
+				${PLAT_PATH}/aarch64/helpers.S			\
+				${PLAT_PATH}/aarch64/common.c			\
+				${PLAT_PATH}/plat_topology.c                    \
+				${XLAT_TABLES_LIB_SRCS}
+
+BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
+				lib/cpus/aarch64/cortex_a78_ae.S		\
+				lib/cpus/aarch64/cortex_a78.S			\
+				plat/common/plat_psci_common.c			\
+				drivers/scmi-msg/base.c				\
+				drivers/scmi-msg/entry.c			\
+				drivers/scmi-msg/smt.c				\
+				drivers/scmi-msg/clock.c			\
+				drivers/scmi-msg/power_domain.c			\
+				drivers/scmi-msg/reset_domain.c			\
+				${PLAT_PATH}/scmi.c
+
+BL31_SOURCES		+=	${PLAT_PATH}/plat_psci.c
+
+BL31_SOURCES		+=	plat/xilinx/common/plat_fdt.c			\
+				common/fdt_wrappers.c                           \
+				plat/xilinx/common/plat_fdt.c                   \
+				plat/xilinx/common/plat_console.c               \
+				plat/xilinx/common/plat_startup.c		\
+				plat/xilinx/common/ipi.c			\
+				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c	\
+				${PLAT_PATH}/soc_ipi.c				\
+				plat/xilinx/common/versal.c			\
+				${PLAT_PATH}/bl31_setup.c			\
+				common/fdt_fixup.c				\
+				common/fdt_wrappers.c				\
+				${LIBFDT_SRCS}					\
+				${PLAT_PATH}/sip_svc_setup.c			\
+				${PLAT_PATH}/gicv3.c
+
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+# enable the cpu macros for errata abi interface
+CORTEX_A78_AE_H_INC     := 1
+$(eval $(call add_define, CORTEX_A78_AE_H_INC))
+endif
+
+# Enable Handoff protocol using transfer lists
+TRANSFER_LIST                   := 1
+
+include lib/transfer_list/transfer_list.mk
+BL31_SOURCES           +=      plat/xilinx/common/plat_xfer_list.c
diff --git a/plat/amd/versal2/scmi.c b/plat/amd/versal2/scmi.c
new file mode 100644
index 00000000..6375df3b
--- /dev/null
+++ b/plat/amd/versal2/scmi.c
@@ -0,0 +1,671 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
+#include <scmi.h>
+
+#include "plat_private.h"
+
+#define HIGH (1)
+#define LOW (0)
+
+struct scmi_clk {
+	unsigned long clock_id;
+	unsigned long rate;
+	const char *name;
+	bool enabled;
+};
+
+#define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled, _rate) \
+	[_scmi_id] = { \
+		.clock_id = (_id), \
+		.name = (_name), \
+		.enabled = (_init_enabled), \
+		.rate = (_rate), \
+	}
+
+static struct scmi_clk scmi0_clock[] = {
+	CLOCK_CELL(CLK_GEM0_0, CLK_GEM0_0, "gem0_pclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM0_1, CLK_GEM0_1, "gem0_hclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM0_2, CLK_GEM0_2, "gem0_tx_clk", true, 125000000),
+	CLOCK_CELL(CLK_GEM0_3, CLK_GEM0_3, "gem0_rx_clk", true, 100000000),
+	CLOCK_CELL(CLK_GEM0_4, CLK_GEM0_4, "gem0_tsu_clk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_0, CLK_GEM1_0, "gem1_pclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_1, CLK_GEM1_1, "gem1_hclk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_2, CLK_GEM1_2, "gem1_tx_clk", true, 125000000),
+	CLOCK_CELL(CLK_GEM1_3, CLK_GEM1_3, "gem1_rx_clk", true, 100000000),
+	CLOCK_CELL(CLK_GEM1_4, CLK_GEM1_4, "gem1_tsu_clk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL0_0, CLK_SERIAL0_0, "uart0_uartclk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL0_1, CLK_SERIAL0_1, "uart0_apb_pclk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL1_0, CLK_SERIAL1_0, "uart1_uartclk", true, 100000000),
+	CLOCK_CELL(CLK_SERIAL1_1, CLK_SERIAL1_1, "uart1_apb_pclk", true, 100000000),
+	CLOCK_CELL(CLK_UFS0_0, CLK_UFS0_0, "ufs_core_clk", true, 100000000),
+	CLOCK_CELL(CLK_UFS0_1, CLK_UFS0_1, "ufs_phy_clk", true, 26000000),
+	CLOCK_CELL(CLK_UFS0_2, CLK_UFS0_2, "ufs_ref_pclk", true, 26000000),
+	CLOCK_CELL(CLK_USB0_0, CLK_USB0_0, "usb0_bus_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB0_1, CLK_USB0_1, "usb0_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB0_2, CLK_USB0_2, "usb0_dwc_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB1_0, CLK_USB1_0, "usb1_bus_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB1_1, CLK_USB1_1, "usb1_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_USB1_2, CLK_USB1_2, "usb1_dwc_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC0_0, CLK_MMC0_0, "mmc0_xin_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC0_1, CLK_MMC0_1, "mmc0_ahb_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC0_2, CLK_MMC0_2, "mmc0_gate_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC1_0, CLK_MMC1_0, "mmc1_xin_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC1_1, CLK_MMC1_1, "mmc1_ahb_clk", true, 100000000),
+	CLOCK_CELL(CLK_MMC1_2, CLK_MMC1_2, "mmc1_gate_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC0_0, CLK_TTC0_0, "ttc0_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC1_0, CLK_TTC1_0, "ttc1_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC2_0, CLK_TTC2_0, "ttc2_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC3_0, CLK_TTC3_0, "ttc3_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC4_0, CLK_TTC4_0, "ttc4_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC5_0, CLK_TTC5_0, "ttc5_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC6_0, CLK_TTC6_0, "ttc6_clk", true, 100000000),
+	CLOCK_CELL(CLK_TTC7_0, CLK_TTC7_0, "ttc7_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C0_0, CLK_I2C0_0, "i2c0_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C1_0, CLK_I2C1_0, "i2c1_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C2_0, CLK_I2C2_0, "i2c2_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C3_0, CLK_I2C3_0, "i2c3_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C4_0, CLK_I2C4_0, "i2c4_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C5_0, CLK_I2C5_0, "i2c5_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C6_0, CLK_I2C6_0, "i2c6_clk", true, 100000000),
+	CLOCK_CELL(CLK_I2C7_0, CLK_I2C7_0, "i2c7_clk", true, 100000000),
+	CLOCK_CELL(CLK_OSPI0_0, CLK_OSPI0_0, "ospi0_clk", true, 100000000),
+	CLOCK_CELL(CLK_QSPI0_0, CLK_QSPI0_0, "qpsi0_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_QSPI0_1, CLK_QSPI0_1, "qspi0_pclk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT0_0, CLK_WWDT0_0, "wwdt0_clk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT1_0, CLK_WWDT1_0, "wwdt1_clk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT2_0, CLK_WWDT2_0, "wwdt2_clk", true, 100000000),
+	CLOCK_CELL(CLK_WWDT3_0, CLK_WWDT3_0, "wwdt3_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA0_0, CLK_ADMA0_0, "adma0_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA0_1, CLK_ADMA0_1, "adma0_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA1_0, CLK_ADMA1_0, "adma1_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA1_1, CLK_ADMA1_1, "adma1_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA2_0, CLK_ADMA2_0, "adma2_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA2_1, CLK_ADMA2_1, "adma2_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA3_0, CLK_ADMA3_0, "adma3_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA3_1, CLK_ADMA3_1, "adma3_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA4_0, CLK_ADMA4_0, "adma4_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA4_1, CLK_ADMA4_1, "adma4_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA5_0, CLK_ADMA5_0, "adma5_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA5_1, CLK_ADMA5_1, "adma5_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA6_0, CLK_ADMA6_0, "adma6_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA6_1, CLK_ADMA6_1, "adma6_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA7_0, CLK_ADMA7_0, "adma7_main_clk", true, 100000000),
+	CLOCK_CELL(CLK_ADMA7_1, CLK_ADMA7_1, "adma7_apb_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN0_0, CLK_CAN0_0, "can0_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN0_1, CLK_CAN0_1, "can0_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN1_0, CLK_CAN1_0, "can1_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN1_1, CLK_CAN1_1, "can1_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN2_0, CLK_CAN2_0, "can2_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN2_1, CLK_CAN2_1, "can2_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN3_0, CLK_CAN3_0, "can3_can_clk", true, 100000000),
+	CLOCK_CELL(CLK_CAN3_1, CLK_CAN3_1, "can3_axi_clk", true, 100000000),
+	CLOCK_CELL(CLK_PS_GPIO_0, CLK_PS_GPIO_0, "ps_gpio_clk", true, 100000000),
+	CLOCK_CELL(CLK_PMC_GPIO_0, CLK_PMC_GPIO_0, "pmc_gpio_clk", true, 100000000),
+	CLOCK_CELL(CLK_SPI0_0, CLK_SPI0_0, "spi0_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_SPI0_1, CLK_SPI0_1, "spi0_pclk", true, 100000000),
+	CLOCK_CELL(CLK_SPI1_0, CLK_SPI1_0, "spi1_ref_clk", true, 100000000),
+	CLOCK_CELL(CLK_SPI1_1, CLK_SPI1_1, "spi1_pclk", true, 100000000),
+	CLOCK_CELL(CLK_I3C0_0, CLK_I3C0_0, "i3c0_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C1_0, CLK_I3C1_0, "i3c1_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C2_0, CLK_I3C2_0, "i3c2_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C3_0, CLK_I3C3_0, "i3c3_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C4_0, CLK_I3C4_0, "i3c4_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C5_0, CLK_I3C5_0, "i3c5_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C6_0, CLK_I3C6_0, "i3c6_clk", true, 100000000),
+	CLOCK_CELL(CLK_I3C7_0, CLK_I3C7_0, "i3c7_clk", true, 100000000),
+};
+
+/*
+ * struct scmi_reset - Data for the exposed reset controller
+ * @reset_id: Reset identifier in RCC reset driver
+ * @name: Reset string ID exposed to agent
+ */
+struct scmi_reset {
+	unsigned long reset_id;
+	const char *name;
+};
+
+#define RESET_CELL(_scmi_id, _id, _name) \
+	[_scmi_id] = { \
+		.reset_id = (_id), \
+		.name = (_name), \
+	}
+
+static struct scmi_reset scmi0_reset[] = {
+	RESET_CELL(RESET_GEM0_0, RESET_GEM0_0, "gem0"),
+	RESET_CELL(RESET_GEM1_0, RESET_GEM1_0, "gem1"),
+	RESET_CELL(RESET_SERIAL0_0, RESET_SERIAL0_0, "serial0"),
+	RESET_CELL(RESET_SERIAL1_0, RESET_SERIAL1_0, "serial1"),
+	RESET_CELL(RESET_UFS0_0, RESET_UFS0_0, "ufs0"),
+	RESET_CELL(RESET_I2C0_0, RESET_I2C0_0, "i2c0"),
+	RESET_CELL(RESET_I2C1_0, RESET_I2C1_0, "i2c1"),
+	RESET_CELL(RESET_I2C2_0, RESET_I2C2_0, "i2c2"),
+	RESET_CELL(RESET_I2C3_0, RESET_I2C3_0, "i2c3"),
+	RESET_CELL(RESET_I2C4_0, RESET_I2C4_0, "i2c4"),
+	RESET_CELL(RESET_I2C5_0, RESET_I2C5_0, "i2c5"),
+	RESET_CELL(RESET_I2C6_0, RESET_I2C6_0, "i2c6"),
+	RESET_CELL(RESET_I2C7_0, RESET_I2C7_0, "i2c7"),
+	RESET_CELL(RESET_I2C8_0, RESET_I2C8_0, "i2c8"),
+	RESET_CELL(RESET_OSPI0_0, RESET_OSPI0_0, "ospi"),
+	RESET_CELL(RESET_USB0_0, RESET_USB0_0, "usb0_0"),
+	RESET_CELL(RESET_USB0_1, RESET_USB0_1, "usb0_1"),
+	RESET_CELL(RESET_USB0_2, RESET_USB0_2, "usb0_2"),
+	RESET_CELL(RESET_USB1_0, RESET_USB1_0, "usb1_0"),
+	RESET_CELL(RESET_USB1_1, RESET_USB1_1, "usb1_1"),
+	RESET_CELL(RESET_USB1_2, RESET_USB1_2, "usb1_2"),
+	RESET_CELL(RESET_MMC0_0, RESET_MMC0_0, "mmc0"),
+	RESET_CELL(RESET_MMC1_0, RESET_MMC1_0, "mmc1"),
+	RESET_CELL(RESET_SPI0_0, RESET_SPI0_0, "spi0"),
+	RESET_CELL(RESET_SPI1_0, RESET_SPI1_0, "spi1"),
+	RESET_CELL(RESET_QSPI0_0, RESET_QSPI0_0, "qspi"),
+	RESET_CELL(RESET_I3C0_0, RESET_I3C0_0, "i3c0"),
+	RESET_CELL(RESET_I3C1_0, RESET_I3C1_0, "i3c1"),
+	RESET_CELL(RESET_I3C2_0, RESET_I3C2_0, "i3c2"),
+	RESET_CELL(RESET_I3C3_0, RESET_I3C3_0, "i3c3"),
+	RESET_CELL(RESET_I3C4_0, RESET_I3C4_0, "i3c4"),
+	RESET_CELL(RESET_I3C5_0, RESET_I3C5_0, "i3c5"),
+	RESET_CELL(RESET_I3C6_0, RESET_I3C6_0, "i3c6"),
+	RESET_CELL(RESET_I3C7_0, RESET_I3C7_0, "i3c7"),
+	RESET_CELL(RESET_I3C8_0, RESET_I3C8_0, "i3c8"),
+	RESET_CELL(RESET_UFSPHY_0, RESET_UFSPHY_0, "ufsphy0"),
+};
+
+/**
+ * struct scmi_pd - Data for the exposed power domain controller
+ * @pd_id: pd identifier in RCC reset driver
+ * @name: pd string ID exposed to agent
+ * @state: keep state setting
+ */
+struct scmi_pd {
+	unsigned long pd_id;
+	const char *name;
+	unsigned int state;
+};
+
+#define PD_CELL(_scmi_id, _id, _name, _state) \
+	[_scmi_id] = { \
+		.pd_id = _id, \
+		.name = _name, \
+		.state = _state, \
+	}
+
+static struct scmi_pd scmi0_pd[] = {
+	PD_CELL(PD_USB0, PD_USB0, "usb0", 0),
+	PD_CELL(PD_USB1, PD_USB1, "usb1", 0),
+};
+
+struct scmi_resources {
+	struct scmi_clk *clock;
+	size_t clock_count;
+	struct scmi_reset *reset;
+	size_t reset_count;
+	struct scmi_pd *pd;
+	size_t pd_count;
+};
+
+static const struct scmi_resources resources[] = {
+	[0] = {
+		.clock = scmi0_clock,
+		.clock_count = ARRAY_SIZE(scmi0_clock),
+		.reset = scmi0_reset,
+		.reset_count = ARRAY_SIZE(scmi0_reset),
+		.pd = scmi0_pd,
+		.pd_count = ARRAY_SIZE(scmi0_pd),
+	},
+};
+
+static const struct scmi_resources *find_resource(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(resources));
+
+	return &resources[agent_id];
+}
+
+static struct scmi_clk *clk_find(unsigned int agent_id, unsigned int scmi_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t n = 0U;
+	struct scmi_clk *ret = NULL;
+
+	if (resource != NULL) {
+		for (n = 0U; n < resource->clock_count; n++) {
+			if (n == scmi_id) {
+				ret = &resource->clock[n];
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
+size_t plat_scmi_clock_count(unsigned int agent_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t ret;
+
+	if (resource == NULL) {
+		ret = 0U;
+	} else {
+		VERBOSE("SCMI: CLK: %d clocks\n", (unsigned int)resource->clock_count);
+
+		ret = resource->clock_count;
+	}
+	return ret;
+}
+
+const char *plat_scmi_clock_get_name(unsigned int agent_id, unsigned int scmi_id)
+{
+	const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	const char *ret;
+
+	if (clock == NULL) {
+		ret = NULL;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, get_name: %s\n", scmi_id, clock->name);
+
+		ret = clock->name;
+	}
+	return ret;
+};
+
+/* Called by Linux */
+int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
+				    unsigned long *array, size_t *nb_elts,
+				    uint32_t start_idx)
+{
+	const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+
+	if (clock == NULL) {
+		return SCMI_NOT_FOUND;
+	}
+
+	if (start_idx > 0) {
+		return SCMI_OUT_OF_RANGE;
+	}
+
+	if (array == NULL) {
+		*nb_elts = 1U;
+	} else if (*nb_elts == 1U) {
+		*array = clock->rate;
+		VERBOSE("SCMI: CLK: id: %d, clk_name: %s, get_rate %lu\n",
+		     scmi_id, clock->name, *array);
+	} else {
+		return SCMI_GENERIC_ERROR;
+	}
+
+	return SCMI_SUCCESS;
+}
+
+unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, unsigned int scmi_id)
+{
+	const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	unsigned long ret;
+
+	if ((clock == NULL)) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, get_rate: %lu\n", scmi_id, clock->rate);
+		ret = clock->rate;
+	}
+	return ret;
+}
+
+int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id,
+				 unsigned long rate)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	unsigned long ret = UL(SCMI_SUCCESS);
+
+	if ((clock == NULL)) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, set_rate: %lu\n", scmi_id, rate);
+		clock->rate = rate;
+	}
+	return ret;
+}
+
+int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id)
+{
+	const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	int32_t ret;
+
+	if ((clock == NULL)) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		VERBOSE("SCMI: CLK: id: %d, get_state: %d\n", scmi_id, clock->enabled);
+
+		if (clock->enabled) {
+			ret = HIGH;
+		} else {
+			ret = LOW;
+		}
+	}
+	return ret;
+}
+
+int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
+				  bool enable_not_disable)
+{
+	struct scmi_clk *clock = clk_find(agent_id, scmi_id);
+	int32_t ret;
+
+	if (clock == NULL) {
+		ret = SCMI_NOT_FOUND;
+	} else {
+		if (enable_not_disable) {
+			if (!clock->enabled) {
+				VERBOSE("SCMI: clock: %u enable\n", scmi_id);
+				clock->enabled = true;
+			}
+		} else {
+			if (clock->enabled) {
+				VERBOSE("SCMI: clock: %u disable\n", scmi_id);
+				clock->enabled = false;
+			}
+		}
+
+		VERBOSE("SCMI: CLK: id: %d, set_state: %d\n", scmi_id, clock->enabled);
+
+		ret = SCMI_SUCCESS;
+	}
+
+	return ret;
+}
+
+
+/*
+ * Platform SCMI reset domains
+ */
+static struct scmi_reset *find_reset(unsigned int agent_id,
+					 unsigned int scmi_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t n;
+
+	if (resource != NULL) {
+		for (n = 0U; n < resource->reset_count; n++) {
+			if (n == scmi_id) {
+				return &resource->reset[n];
+			}
+		}
+	}
+
+	return NULL;
+}
+
+const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id)
+{
+	const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
+
+	if (reset == NULL) {
+		return NULL;
+	}
+
+	return reset->name;
+}
+
+size_t plat_scmi_rstd_count(unsigned int agent_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+
+	if (resource == NULL) {
+		return 0U;
+	}
+
+	return resource->reset_count;
+}
+
+int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id,
+				uint32_t state)
+{
+	const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
+
+	if (reset == NULL) {
+		return SCMI_NOT_FOUND;
+	}
+
+	/* Supports only reset with context loss */
+	if (state != 0U) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	NOTICE("SCMI reset on ID %lu/%s\n",
+	       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+
+	return SCMI_SUCCESS;
+}
+
+int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id,
+				 bool assert_not_deassert)
+{
+	const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
+
+	if (reset == NULL) {
+		return SCMI_NOT_FOUND;
+	}
+
+	if (assert_not_deassert) {
+		NOTICE("SCMI reset %lu/%s set\n",
+		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+
+		switch (scmi_id) {
+		case RESET_UFS0_0:
+			mmio_write_32(PMXC_CRP_RST_UFS, 1);
+			break;
+		case RESET_UFSPHY_0:
+			mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 1);
+			break;
+		default:
+			break;
+		}
+	} else {
+		NOTICE("SCMI reset %lu/%s release\n",
+		       reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
+
+		switch (scmi_id) {
+		case RESET_UFS0_0:
+			mmio_write_32(PMXC_CRP_RST_UFS, 0);
+			break;
+		case RESET_UFSPHY_0:
+			mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 0);
+			break;
+		default:
+			break;
+		}
+	}
+
+	return SCMI_SUCCESS;
+}
+
+/*
+ * Platform SCMI reset domains
+ */
+static struct scmi_pd *find_pd(unsigned int agent_id, unsigned int pd_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t n;
+
+	if (resource != NULL) {
+		for (n = 0U; n < resource->pd_count; n++) {
+			if (n == pd_id) {
+				return &resource->pd[n];
+			}
+		}
+	}
+
+	return NULL;
+}
+
+size_t plat_scmi_pd_count(unsigned int agent_id)
+{
+	const struct scmi_resources *resource = find_resource(agent_id);
+	size_t ret;
+
+	if (resource == NULL) {
+		ret = 0U;
+	} else {
+		ret = resource->pd_count;
+
+		NOTICE("SCMI: PD: %d\n", (unsigned int)ret);
+	}
+	return ret;
+}
+
+const char *plat_scmi_pd_get_name(unsigned int agent_id, unsigned int pd_id)
+{
+	const struct scmi_pd *pd = find_pd(agent_id, pd_id);
+
+	if (pd == NULL) {
+		return NULL;
+	}
+
+	return pd->name;
+}
+
+unsigned int plat_scmi_pd_statistics(unsigned int agent_id, unsigned long *pd_id)
+{
+	return 0U;
+}
+
+unsigned int plat_scmi_pd_get_attributes(unsigned int agent_id, unsigned int pd_id)
+{
+	return 0U;
+}
+
+unsigned int plat_scmi_pd_get_state(unsigned int agent_id, unsigned int pd_id)
+{
+	const struct scmi_pd *pd = find_pd(agent_id, pd_id);
+
+	if (pd == NULL) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	NOTICE("SCMI: PD: get id: %d, state: %x\n", pd_id, pd->state);
+
+	return pd->state;
+}
+
+int32_t plat_scmi_pd_set_state(unsigned int agent_id, unsigned int flags, unsigned int pd_id,
+			       unsigned int state)
+{
+	struct scmi_pd *pd = find_pd(agent_id, pd_id);
+
+	if (pd == NULL) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	NOTICE("SCMI: PD: set id: %d, orig state: %x, new state: %x,  flags: %x\n",
+	       pd_id, pd->state, state, flags);
+
+	pd->state = state;
+
+	return 0U;
+}
+
+
+/* Currently only one channel is supported. Expectation is that channel 0 is used by NS SW */
+static struct scmi_msg_channel scmi_channel[] = {
+	[0] = {
+		.shm_addr = SMT_BUFFER_BASE,
+		.shm_size = SMT_BUF_SLOT_SIZE,
+	},
+};
+
+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(scmi_channel));
+
+	VERBOSE("%d: SCMI asking for channel\n", agent_id);
+
+	/* Just in case that code is reused */
+	return &scmi_channel[agent_id];
+}
+
+/* Base protocol implementations */
+const char *plat_scmi_vendor_name(void)
+{
+	return SCMI_VENDOR;
+}
+
+const char *plat_scmi_sub_vendor_name(void)
+{
+	return SCMI_PRODUCT;
+}
+
+/* Currently supporting Clocks and Reset Domains */
+static const uint8_t plat_protocol_list[] = {
+	SCMI_PROTOCOL_ID_BASE,
+	SCMI_PROTOCOL_ID_CLOCK,
+	SCMI_PROTOCOL_ID_RESET_DOMAIN,
+	SCMI_PROTOCOL_ID_POWER_DOMAIN,
+	/* SCMI_PROTOCOL_ID_SENSOR, */
+	0U /* Null termination */
+};
+
+size_t plat_scmi_protocol_count(void)
+{
+	const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U;
+
+	VERBOSE("SCMI: Protocol count: %d\n", (int32_t)count);
+
+	return count;
+}
+
+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
+{
+	return plat_protocol_list;
+}
+
+void init_scmi_server(void)
+{
+	size_t i;
+	int32_t ret;
+
+	for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++)
+		scmi_smt_init_agent_channel(&scmi_channel[i]);
+
+	INFO("SCMI: Server initialized\n");
+
+	if (platform_id == QEMU) {
+		/* default setting is for QEMU */
+	} else if (platform_id == SPP) {
+		for (i = 0U; i < ARRAY_SIZE(scmi0_clock); i++) {
+
+			/* Keep i2c on 100MHz to calculate rates properly */
+			if ((i >= CLK_I2C0_0) && (i <= CLK_I2C7_0))
+				continue;
+
+			/* Keep UFS clocks to default values to get the expected rates */
+			if (i >= CLK_UFS0_0 && i <= CLK_UFS0_2)
+				continue;
+
+			/*
+			 * SPP supports multiple versions.
+			 * The cpu_clock value is set to corresponding SPP
+			 * version in early platform setup, resuse the same
+			 * value here.
+			 */
+			ret = plat_scmi_clock_set_rate(0, i, cpu_clock);
+			if (ret < 0) {
+				NOTICE("Failed to set clock rate for SPP scmi_id=%ld\n", i);
+			}
+		}
+	} else {
+		 /* Making MISRA C 2012 15.7 compliant */
+	}
+}
diff --git a/plat/amd/versal2/sip_svc_setup.c b/plat/amd/versal2/sip_svc_setup.c
new file mode 100644
index 00000000..68500306
--- /dev/null
+++ b/plat/amd/versal2/sip_svc_setup.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
+
+#include <errno.h>
+#include <inttypes.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
+#include <scmi.h>
+#include <tools_share/uuid.h>
+
+#include "ipi_mailbox_svc.h"
+#include "plat_private.h"
+#include "pm_svc_main.h"
+
+/* SMC function IDs for SiP Service queries */
+#define SIP_SVC_UID		(0x8200ff01U)
+#define SIP_SVC_VERSION	(0x8200ff03U)
+
+/* SiP Service Calls version numbers */
+#define SIP_SVC_VERSION_MAJOR		(0U)
+#define SIP_SVC_VERSION_MINOR		(1U)
+
+/* These macros are used to identify PM calls from the SMC function ID */
+#define SIP_FID_MASK	GENMASK(23, 16)
+#define XLNX_FID_MASK	GENMASK(23, 12)
+#define PM_FID_VALUE	0u
+#define IPI_FID_VALUE	0x1000u
+#define is_pm_fid(_fid) (((_fid) & XLNX_FID_MASK) == PM_FID_VALUE)
+#define is_ipi_fid(_fid) (((_fid) & XLNX_FID_MASK) == IPI_FID_VALUE)
+
+/* SiP Service UUID */
+DEFINE_SVC_UUID2(_sip_uuid,
+		0x0499eb70, 0x5ed0, 0x11ee, 0xb3, 0x0a,
+		0x87, 0xd1, 0x1d, 0x4f, 0x8a, 0x9b);
+
+/**
+ * sip_svc_setup() - Setup SiP Service
+ *
+ * Return: 0 on success, negative error code on failure.
+ *
+ */
+static int32_t sip_svc_setup(void)
+{
+	return sip_svc_setup_init();
+}
+
+/*
+ * sip_svc_smc_handler() - Top-level SiP Service SMC handler
+ *
+ * Handler for all SiP SMC calls. Handles standard SIP requests
+ * and calls PM SMC handler if the call is for a PM-API function.
+ */
+static uintptr_t sip_svc_smc_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)
+{
+	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
+		smc_fid, x1, x2, x3, x4);
+
+	if ((smc_fid & SIP_FID_MASK) != 0) {
+		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
+	/* Let PM SMC handler deal with PM-related requests */
+	if (is_pm_fid(smc_fid)) {
+		return smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+	}
+
+	/* Let IPI SMC handler deal with IPI-related requests if platform */
+	if (is_ipi_fid(smc_fid)) {
+		return ipi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
+	}
+
+	/* Let PM SMC handler deal with PM-related requests */
+	switch (smc_fid) {
+	case SIP_SVC_UID:
+		SMC_UUID_RET(handle, _sip_uuid);
+
+	case SIP_SVC_VERSION:
+		SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR);
+
+	case SIP_SCMI:
+		if (platform_id != EMU) {
+			scmi_smt_fastcall_smc_entry(0);
+			SMC_RET1(handle, 0);
+		}
+		WARN("SCMI is not working on EMU\n");
+		SMC_RET1(handle, SMC_UNK);
+	default:
+		WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+/* Register PM Service Calls as runtime service */
+DECLARE_RT_SVC(
+		sip_svc,
+		OEN_SIP_START,
+		OEN_SIP_END,
+		SMC_TYPE_FAST,
+		sip_svc_setup,
+		sip_svc_smc_handler);
diff --git a/plat/amd/versal2/soc_ipi.c b/plat/amd/versal2/soc_ipi.c
new file mode 100644
index 00000000..85d1bcdd
--- /dev/null
+++ b/plat/amd/versal2/soc_ipi.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * SoC IPI agent registers access management
+ */
+
+#include <lib/utils_def.h>
+#include <plat_ipi.h>
+
+/* versal2 ipi configuration table */
+static const struct ipi_config ipi_table[IPI_ID_MAX] = {
+	/* A78 IPI */
+	[IPI_ID_APU] = {
+		.ipi_bit_mask = IPI0_TRIG_BIT,
+		.ipi_reg_base = IPI0_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* PMC IPI */
+	[IPI_ID_PMC] = {
+		.ipi_bit_mask = PMC_IPI_TRIG_BIT,
+		.ipi_reg_base = IPI0_REG_BASE,
+		.secure_only = IPI_SECURE_MASK,
+	},
+
+	/* RPU0 IPI */
+	[IPI_ID_RPU0] = {
+		.ipi_bit_mask = IPI1_TRIG_BIT,
+		.ipi_reg_base = IPI1_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* RPU1 IPI */
+	[IPI_ID_RPU1] = {
+		.ipi_bit_mask = IPI2_TRIG_BIT,
+		.ipi_reg_base = IPI2_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI3 IPI */
+	[IPI_ID_3] = {
+		.ipi_bit_mask = IPI3_TRIG_BIT,
+		.ipi_reg_base = IPI3_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI4 IPI */
+	[IPI_ID_4] = {
+		.ipi_bit_mask = IPI4_TRIG_BIT,
+		.ipi_reg_base = IPI4_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI5 IPI */
+	[IPI_ID_5] = {
+		.ipi_bit_mask = IPI5_TRIG_BIT,
+		.ipi_reg_base = IPI5_REG_BASE,
+		.secure_only = 0,
+	},
+};
+
+/**
+ * soc_ipi_config_table_init() - Initialize versal2 IPI configuration data.
+ */
+void soc_ipi_config_table_init(void)
+{
+	ipi_config_table_init(ipi_table, ARRAY_SIZE(ipi_table));
+}
diff --git a/plat/amd/versal2/tsp/tsp-versal2.mk b/plat/amd/versal2/tsp/tsp-versal2.mk
new file mode 100644
index 00000000..422ed173
--- /dev/null
+++ b/plat/amd/versal2/tsp/tsp-versal2.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# TSP source files specific to Versal Gen 2 platform
+
+PLAT_XILINX_COMMON := plat/xilinx/common/
+
+include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
diff --git a/plat/amlogic/axg/platform.mk b/plat/amlogic/axg/platform.mk
index 3560b0cd..aadecab5 100644
--- a/plat/amlogic/axg/platform.mk
+++ b/plat/amlogic/axg/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -41,9 +41,9 @@ BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S			\
 				${GIC_SOURCES}
 
 # Tune compiler for Cortex-A53
-ifeq ($(notdir $(CC)),armclang)
+ifeq ($($(ARCH)-cc-id),arm-clang)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
-else ifneq ($(findstring clang,$(notdir $(CC))),)
+else ifneq ($(filter %-clang,$($(ARCH)-cc-id)),)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
 else
     TF_CFLAGS_aarch64	+=	-mtune=cortex-a53
@@ -85,11 +85,10 @@ all: ${BUILD_PLAT}/bl31.img
 distclean realclean clean: cleanimage
 
 cleanimage:
-	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+	$(q)${MAKE} -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}:
-	${Q}${MAKE} -C ${DOIMAGEPATH}
+	$(q)${MAKE} -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
 	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
-
diff --git a/plat/amlogic/g12a/platform.mk b/plat/amlogic/g12a/platform.mk
index b0c91b06..15658d34 100644
--- a/plat/amlogic/g12a/platform.mk
+++ b/plat/amlogic/g12a/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -41,9 +41,9 @@ BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S			\
 				${GIC_SOURCES}
 
 # Tune compiler for Cortex-A53
-ifeq ($(notdir $(CC)),armclang)
+ifeq ($($(ARCH)-cc-id),arm-clang)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
-else ifneq ($(findstring clang,$(notdir $(CC))),)
+else ifneq ($(filter %-clang,$($(ARCH)-cc-id)),)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
 else
     TF_CFLAGS_aarch64	+=	-mtune=cortex-a53
@@ -81,11 +81,10 @@ all: ${BUILD_PLAT}/bl31.img
 distclean realclean clean: cleanimage
 
 cleanimage:
-	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+	$(q)${MAKE} -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}:
-	${Q}${MAKE} -C ${DOIMAGEPATH}
+	$(q)${MAKE} -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
 	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
-
diff --git a/plat/amlogic/gxbb/platform.mk b/plat/amlogic/gxbb/platform.mk
index 62384d2a..fbebd3e7 100644
--- a/plat/amlogic/gxbb/platform.mk
+++ b/plat/amlogic/gxbb/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -37,9 +37,9 @@ BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S			\
 				${GIC_SOURCES}
 
 # Tune compiler for Cortex-A53
-ifeq ($(notdir $(CC)),armclang)
+ifeq ($($(ARCH)-cc-id),arm-clang)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
-else ifneq ($(findstring clang,$(notdir $(CC))),)
+else ifneq ($(filter %-clang,$($(ARCH)-cc-id)),)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
 else
     TF_CFLAGS_aarch64	+=	-mtune=cortex-a53
diff --git a/plat/amlogic/gxl/platform.mk b/plat/amlogic/gxl/platform.mk
index 641d177b..31063a97 100644
--- a/plat/amlogic/gxl/platform.mk
+++ b/plat/amlogic/gxl/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -41,9 +41,9 @@ BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S			\
 				${GIC_SOURCES}
 
 # Tune compiler for Cortex-A53
-ifeq ($(notdir $(CC)),armclang)
+ifeq ($($(ARCH)-cc-id),arm-clang)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
-else ifneq ($(findstring clang,$(notdir $(CC))),)
+else ifneq ($(filter %-clang,$($(ARCH)-cc-id)),)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
 else
     TF_CFLAGS_aarch64	+=	-mtune=cortex-a53
@@ -81,11 +81,10 @@ all: ${BUILD_PLAT}/bl31.img
 distclean realclean clean: cleanimage
 
 cleanimage:
-	${Q}${MAKE} -C ${DOIMAGEPATH} clean
+	$(q)${MAKE} -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}:
-	${Q}${MAKE} -C ${DOIMAGEPATH}
+	$(q)${MAKE} -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL}
 	${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img
-
diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
index b9ff8bff..5bf6a3f6 100644
--- a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
+++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 
@@ -20,7 +21,7 @@
 
 		hw-config {
 			load-address = <0x0 0x83000000>;
-			max-size = <0x01000000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
 	};
diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h
index 9f3df1ef..b1349117 100644
--- a/plat/arm/board/a5ds/include/platform_def.h
+++ b/plat/arm/board/a5ds/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -208,6 +208,9 @@
  */
 #define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + (PAGE_SIZE * 2))
 
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x01000000)
+
 /*******************************************************************************
  * BL1 specific defines.
  * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of
diff --git a/plat/arm/board/arm_fpga/fpga_def.h b/plat/arm/board/arm_fpga/fpga_def.h
index 2884ea6d..5e3a0a99 100644
--- a/plat/arm/board/arm_fpga/fpga_def.h
+++ b/plat/arm/board/arm_fpga/fpga_def.h
@@ -21,7 +21,7 @@
 
 #define FPGA_MAX_CLUSTER_COUNT			4
 #define FPGA_MAX_CPUS_PER_CLUSTER		8
-#define FPGA_MAX_PE_PER_CPU			4
+#define FPGA_MAX_PE_PER_CPU			2
 
 #define FPGA_PRIMARY_CPU			0x0
 /*******************************************************************************
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index f44b37d4..967bf217 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -41,8 +41,13 @@ ENABLE_FEAT_CSV2_2		:= 2
 ENABLE_FEAT_ECV			:= 2
 ENABLE_FEAT_FGT			:= 2
 ENABLE_FEAT_HCX			:= 2
+ENABLE_FEAT_MTE2		:= 2
+ENABLE_FEAT_TCR2		:= 2
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_TRF_FOR_NS		:= 2
+ENABLE_SME_FOR_NS		:= 2
+ENABLE_SME2_FOR_NS		:= 2
+ENABLE_FEAT_LS64_ACCDATA	:= 2
 
 # Treating this as a memory-constrained port for now
 USE_COHERENT_MEM	:=	0
@@ -77,8 +82,8 @@ else
 				lib/cpus/aarch64/neoverse_n1.S			\
 				lib/cpus/aarch64/neoverse_n2.S			\
 				lib/cpus/aarch64/neoverse_v1.S			\
-				lib/cpus/aarch64/cortex_chaberton.S		\
-				lib/cpus/aarch64/cortex_blackhawk.S
+				lib/cpus/aarch64/cortex_a725.S		\
+				lib/cpus/aarch64/cortex_x925.S
 
 # AArch64/AArch32 cores
 	FPGA_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S	\
@@ -123,12 +128,20 @@ BL31_SOURCES		+=	common/fdt_fixup.c				\
 
 BL31_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 
-$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,bl31))
-$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,bl31))
-$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,bl31))
+$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,bl31,BL31))
+$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,bl31,BL31))
+$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,bl31,BL31))
+
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
+        AXF_LDFLAGS	+=	-Wl,--build-id=none -mno-fix-cortex-a53-843419
+else
+        AXF_LDFLAGS	+=	--build-id=none
+endif
+
+AXF_LDFLAGS += -nostdlib -no-pie
 
 bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/kernel_trampoline.o ${BUILD_PLAT}/build_axf.ld
-	$(ECHO) "  LD      $@"
-	$(Q)$(LD) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -s -n -o ${BUILD_PLAT}/bl31.axf
+	$(s)echo "  LD      $@"
+	$(q)$($(ARCH)-ld) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} ${AXF_LDFLAGS} -s -n -o ${BUILD_PLAT}/bl31.axf
 
 all: bl31.axf
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
new file mode 100644
index 00000000..53cd3b0f
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/fdts/rd1ae_fw_config.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/tbbr/tbbr_img_def.h>
+
+/dts-v1/;
+
+/ {
+	dtb-registry {
+		compatible = "fconf,dyn_cfg-dtb_registry";
+
+		hw-config {
+			load-address = <0x0 0x83000000>;
+			max-size = <0x8000>;
+			id = <HW_CONFIG_ID>;
+		};
+	};
+};
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/include/plat_macros.S b/plat/arm/board/automotive_rd/platform/rd1ae/include/plat_macros.S
new file mode 100644
index 00000000..8efe8acb
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/include/plat_macros.S
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <arm_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ *
+ * There are currently no platform specific regs
+ * to print.
+ * ---------------------------------------------
+ */
+	.macro plat_crash_print_regs
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h b/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
new file mode 100644
index 00000000..44c8ee3c
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/include/platform_def.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+/* These are referenced by arm_def.h #included next, so #define first. */
+#define PLAT_ARM_TRUSTED_SRAM_BASE		UL(0x0)
+
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/common/common_def.h>
+
+#define PLATFORM_CORE_COUNT			U(16)
+#define PLAT_ARM_CLUSTER_COUNT			U(16)
+#define PLAT_MAX_CPUS_PER_CLUSTER		U(1)
+#define PLAT_MAX_PE_PER_CPU			U(1)
+
+#define PLATFORM_STACK_SIZE			UL(0x1000)
+
+/* BL1 is not supported */
+#define PLAT_ARM_TRUSTED_ROM_BASE		UL(0x0)
+#define PLAT_ARM_TRUSTED_ROM_SIZE		UL(0x0)
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE		UL(0x00080000)
+
+/* USE_ROMLIB is not supported */
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE		U(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE		U(0)
+
+/* Defined based on actual binary sizes */
+#define PLAT_ARM_MAX_BL1_RW_SIZE		0x0
+#define PLAT_ARM_MAX_BL2_SIZE			0x20000
+#define PLAT_ARM_MAX_BL31_SIZE			0x70000
+
+#define PLAT_ARM_DRAM2_BASE			ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE			ULL(0x180000000)
+
+#define PLAT_CSS_MHU_BASE			UL(0x2A920000)
+#define PLAT_ARM_NSTIMER_FRAME_ID		U(0)
+
+#define SOC_CSS_SEC_UART_BASE			UL(0x2A410000)
+#define SOC_CSS_NSEC_UART_BASE			UL(0x2A400000)
+#define SOC_CSS_UART_SIZE			UL(0x10000)
+#define SOC_CSS_UART_CLK_IN_HZ			UL(7372800)
+#define PLAT_ARM_BOOT_UART_BASE			SOC_CSS_SEC_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
+#define PLAT_ARM_RUN_UART_BASE			SOC_CSS_SEC_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
+#define PLAT_ARM_CRASH_UART_BASE		SOC_CSS_SEC_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
+
+/* Physical and virtual address space limits for MMU */
+#define PLAT_PHY_ADDR_SPACE_SIZE		(1ULL << 42)
+#define PLAT_VIRT_ADDR_SPACE_SIZE		(1ULL << 42)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE			UL(0x30000000)
+#define PLAT_ARM_GICR_BASE			UL(0x301C0000)
+#define PLAT_ARM_GICC_BASE			UL(0x2C000000)
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)		CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)		ARM_G0_IRQ_PROPS(grp)
+
+/* Virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME		UL(0xC0000000)
+
+/* Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_BASE			UL(0x2A480000)
+#define SBSA_SECURE_WDOG_TIMEOUT		UL(100)
+
+#define V2M_SYS_LED_SS_SHIFT			U(0)
+#define V2M_SYS_LED_EL_SHIFT			U(1)
+#define V2M_SYS_LED_EC_SHIFT			U(3)
+
+#define V2M_SYS_LED_SS_MASK			U(0x01)
+#define V2M_SYS_LED_EL_MASK			U(0x03)
+#define V2M_SYS_LED_EC_MASK			U(0x1f)
+
+#define V2M_SYSREGS_BASE			UL(0x0C010000)
+#define V2M_SYS_LED				U(0x8)
+
+#define PLAT_ARM_SCMI_CHANNEL_COUNT		U(1)
+#define CSS_SYSTEM_PWR_DMN_LVL			ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL				ARM_PWR_LVL1
+
+#define MAX_IO_DEVICES				U(3)
+#define MAX_IO_HANDLES				U(4)
+
+#ifdef IMAGE_BL2
+#define PLAT_ARM_MMAP_ENTRIES			U(5)
+#else
+#define PLAT_ARM_MMAP_ENTRIES			U(6)
+#endif
+#define MAX_XLAT_TABLES				U(6)
+
+#define V2M_FLASH0_BASE				UL(0x08000000)
+#define V2M_FLASH0_SIZE				UL(0x04000000)
+#define V2M_FLASH_BLOCK_SIZE			UL(0x00040000)	/* 256 KB */
+#define PLAT_ARM_FLASH_IMAGE_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_FW_CONFIG_MAX_SIZE			(ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE)
+#define PLAT_FW_CONFIG_BASE			ARM_FW_CONFIG_BASE
+
+/* RD1AE-specific memory mappings */
+#define RD1AE_EXTERNAL_FLASH	MAP_REGION_FLAT(V2M_FLASH0_BASE, \
+						V2M_FLASH0_SIZE, \
+						MT_DEVICE | MT_RO | \
+						MT_SECURE)
+
+#define RD1AE_MAP_NS_DRAM1	MAP_REGION_FLAT(ARM_DRAM1_BASE,	\
+						ARM_DRAM1_SIZE,	\
+						MT_MEMORY | MT_RW | \
+						MT_NS)
+
+#define RD1AE_DEVICE_BASE	(0x20000000)
+#define RD1AE_DEVICE_SIZE	(0x20000000)
+#define RD1AE_MAP_DEVICE	MAP_REGION_FLAT(RD1AE_DEVICE_BASE, \
+						RD1AE_DEVICE_SIZE, \
+						MT_DEVICE | MT_RW | \
+						MT_SECURE)
+
+#define SOC_PLATFORM_PERIPH_BASE	UL(0x0E000000)
+#define SOC_PLATFORM_PERIPH_SIZE	UL(0x02000000)
+#define SOC_PLATFORM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(SOC_PLATFORM_PERIPH_BASE, \
+							SOC_PLATFORM_PERIPH_SIZE, \
+							MT_DEVICE | MT_RW | MT_SECURE)
+
+/* Non-volatile counters */
+#define TRUSTED_NVCTR_BASE_OFFSET	UL(0x00E70000)
+#define TFW_NVCTR_BASE_OFFSET		0x0000
+#define NTFW_CTR_BASE_OFFSET		0x0004
+#define SOC_TRUSTED_NVCTR_BASE		(SOC_PLATFORM_PERIPH_BASE + TRUSTED_NVCTR_BASE_OFFSET)
+#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE + TFW_NVCTR_BASE_OFFSET)
+#define TFW_NVCTR_SIZE			U(4)
+#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + NTFW_CTR_BASE_OFFSET)
+#define NTFW_CTR_SIZE			U(4)
+
+/*******************************************************************************
+ * Memprotect definitions
+ ******************************************************************************/
+/* PSCI memory protect definitions:
+ * This variable is stored in a non-secure flash because some ARM reference
+ * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
+ * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
+ */
+#define PLAT_ARM_MEM_PROT_ADDR	(V2M_FLASH0_BASE + \
+					V2M_FLASH0_SIZE - \
+					V2M_FLASH_BLOCK_SIZE)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/include/rd1ae_helpers.S b/plat/arm/board/automotive_rd/platform/rd1ae/include/rd1ae_helpers.S
new file mode 100644
index 00000000..32260efc
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/include/rd1ae_helpers.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+	.globl	plat_arm_calc_core_pos
+
+	/* ---------------------------------------------------------------------
+	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+	 *
+	 * Function to calculate the core position on rd1ae.
+	 *
+	 * (ClusterId * PLAT_MAX_CPUS_PER_CLUSTER * PLAT_MAX_PE_PER_CPU) +
+	 * (CPUId * PLAT_MAX_PE_PER_CPU) +
+	 * ThreadId
+	 *
+	 * which can be simplified as:
+	 *
+	 * ((ClusterId * PLAT_MAX_CPUS_PER_CLUSTER + CPUId) * PLAT_MAX_PE_PER_CPU)
+	 * + ThreadId
+	 * ---------------------------------------------------------------------
+	 */
+func plat_arm_calc_core_pos
+	mov	x4, x0
+
+	/* Extract individual affinity fields from MPIDR */
+	ubfx    x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx    x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS
+
+	/* Compute linear position */
+	mov     x4, #PLAT_ARM_CLUSTER_COUNT
+	madd    x2, x3, x4, x2
+	mov     x4, #PLAT_MAX_CPUS_PER_CLUSTER
+	madd    x1, x2, x4, x1
+	mov     x4, #PLAT_MAX_PE_PER_CPU
+	madd    x0, x1, x4, x0
+	ret
+endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
new file mode 100644
index 00000000..35cd8a19
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/platform.mk
@@ -0,0 +1,88 @@
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# RD1AE (Kronos) platform.
+$(info Platform ${PLAT} is (kronos) specific.)
+
+RD1AE_BASE		=	plat/arm/board/automotive_rd/platform/rd1ae
+
+PLAT_INCLUDES		+=	-I${RD1AE_BASE}/include/
+
+override ARM_FW_CONFIG_LOAD_ENABLE	:=	1
+override ARM_PLAT_MT			:=	1
+override ARM_RECOM_STATE_ID_ENC		:=	1
+override CSS_LOAD_SCP_IMAGES		:=	0
+override CTX_INCLUDE_AARCH32_REGS	:=	0
+override ENABLE_SVE_FOR_NS		:=	1
+override ENABLE_SVE_FOR_SWD		:=	1
+override NEED_BL1			:=	0
+override NEED_BL2U			:=	0
+override PSCI_EXTENDED_STATE_ID		:=	1
+
+ARM_ARCH_MAJOR				:=	9
+ARM_ARCH_MINOR				:=	2
+CSS_USE_SCMI_SDS_DRIVER			:=	1
+ENABLE_FEAT_AMU				:=	1
+ENABLE_FEAT_ECV				:=	1
+ENABLE_FEAT_FGT				:=	1
+ENABLE_FEAT_MTE2			:=	1
+ENABLE_MPAM_FOR_LOWER_ELS		:=	1
+GIC_ENABLE_V4_EXTN			:=	1
+GICV3_SUPPORT_GIC600			:=	1
+HW_ASSISTED_COHERENCY			:=	1
+PLAT_MHU_VERSION			:=	1
+RESET_TO_BL2				:=	1
+SVE_VECTOR_LEN				:=	128
+USE_COHERENT_MEM			:=	0
+
+RD1AE_CPU_SOURCES	:=	lib/cpus/aarch64/neoverse_v3.S
+
+include drivers/arm/gic/v3/gicv3.mk
+RD1AE_GIC_SOURCES	:=	${GICV3_SOURCES}	\
+				plat/common/plat_gicv3.c	\
+				plat/arm/common/arm_gicv3.c
+
+PLAT_BL_COMMON_SOURCES	+=	${RD1AE_BASE}/rd1ae_plat.c	\
+				${RD1AE_BASE}/include/rd1ae_helpers.S
+
+BL2_SOURCES	+=	${RD1AE_CPU_SOURCES}	\
+			${RD1AE_BASE}/rd1ae_err.c	\
+			${RD1AE_BASE}/rd1ae_bl2_mem_params_desc.c	\
+			lib/utils/mem_region.c	\
+			plat/arm/common/arm_nor_psci_mem_protect.c	\
+			drivers/arm/sbsa/sbsa.c
+
+BL31_SOURCES	+=	${RD1AE_CPU_SOURCES}	\
+			${RD1AE_GIC_SOURCES}	\
+			${RD1AE_BASE}/rd1ae_bl31_setup.c	\
+			${RD1AE_BASE}/rd1ae_topology.c	\
+			drivers/cfi/v2m/v2m_flash.c	\
+			lib/utils/mem_region.c	\
+			plat/arm/common/arm_nor_psci_mem_protect.c
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+BL2_SOURCES	+=	${RD1AE_BASE}/rd1ae_tbb.c
+endif
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES	+=	${RD1AE_BASE}/fdts/${PLAT}_fw_config.dts	\
+			fdts/${PLAT}.dts
+
+FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+HW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config,${HW_CONFIG}))
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+FIP_BL2_ARGS	:=	tb-fw
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
+endif
+
+include plat/arm/common/arm_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
new file mode 100644
index 00000000..30cc90f0
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl2_mem_params_desc.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Following descriptor provides BL image/ep information that gets used
+ * by BL2 to load the images and also subset of this information is
+ * passed to next BL image. The image loading sequence is managed by
+ * populating the images in required loading order. The image execution
+ * sequence is managed by populating the `next_handoff_image_id` with
+ * the next executable image id.
+ ******************************************************************************/
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+	/* Fill BL31 related information */
+	{
+		.image_id = BL31_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+			VERSION_2, entry_point_info_t,
+			SECURE | EXECUTABLE | EP_FIRST_EXE),
+		.ep_info.pc = BL31_BASE,
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+			DISABLE_ALL_EXCEPTIONS),
+#if DEBUG
+		.ep_info.args.arg3 = ARM_BL31_PLAT_PARAM_VAL,
+#endif
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+			VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+		.image_info.image_base = BL31_BASE,
+		.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+	/* Fill HW_CONFIG related information */
+	{
+		.image_id = HW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+			VERSION_2, entry_point_info_t,
+			NON_SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+			VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+	/* Fill BL33 related information */
+	{
+		.image_id = BL33_IMAGE_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+			VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
+		.ep_info.pc = PLAT_ARM_NS_IMAGE_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+			VERSION_2, image_info_t, 0),
+		.image_info.image_base = PLAT_ARM_NS_IMAGE_BASE,
+		.image_info.image_max_size = ARM_DRAM1_BASE + ARM_DRAM1_SIZE
+			- PLAT_ARM_NS_IMAGE_BASE,
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
new file mode 100644
index 00000000..ce7bad75
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_bl31_setup.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+
+static scmi_channel_plat_info_t plat_rd_scmi_info[] = {
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+};
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
+{
+	return &plat_rd_scmi_info[channel_id];
+}
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+	return css_scmi_override_pm_ops(ops);
+}
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_err.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_err.c
new file mode 100644
index 00000000..62544733
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_err.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/sbsa.h>
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rd1ae error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+	console_flush();
+
+	sbsa_wdog_refresh(SBSA_SECURE_WDOG_BASE);
+
+	while (1) {
+		wfi();
+	}
+}
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
new file mode 100644
index 00000000..e917330b
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_plat.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/sbsa.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	RD1AE_MAP_DEVICE,
+	RD1AE_EXTERNAL_FLASH,
+	SOC_PLATFORM_PERIPH_MAP_DEVICE,
+#if IMAGE_BL2
+	RD1AE_MAP_NS_DRAM1,
+#endif
+	{0}
+};
+
+void plat_arm_secure_wdt_start(void)
+{
+	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
+
+/*
+ * For rd1ae we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers
+ */
+void plat_arm_interconnect_init(void)
+{
+}
+
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
+
+/*
+ * TZC programming is currently not done.
+ */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_tbb.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_tbb.c
new file mode 100644
index 00000000..01fbcce8
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_tbb.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	assert(heap_addr != NULL);
+	assert(heap_size != NULL);
+
+	return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *     algorithm       OBJECT IDENTIFIER,
+ *     parameters      ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ *     digestAlgorithm AlgorithmIdentifier,
+ *     digest          OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	return arm_get_rotpk_info(cookie, key_ptr, key_len, flags);
+}
diff --git a/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_topology.c b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_topology.c
new file mode 100644
index 00000000..25331840
--- /dev/null
+++ b/plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_topology.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ *
+ * This descriptor defines the layout of the power domain tree for the RD1AE
+ * platform, which consists of 16 clusters.
+ ******************************************************************************/
+const unsigned char rd1_ae_pd_tree_desc[] = {
+	(PLAT_ARM_CLUSTER_COUNT),
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+	PLAT_MAX_CPUS_PER_CLUSTER,
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return rd1_ae_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)),
+};
+
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+	return PLAT_MAX_CPUS_PER_CLUSTER;
+}
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 655a4d2a..4a2572fc 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -219,6 +219,15 @@ int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
 	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
 		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
 							NON_TRUSTED_NV_CTR_ID);
+#if defined(ARM_COT_cca)
+	} else if (strcmp(oid, CCA_FW_NVCOUNTER_OID) == 0) {
+		/*
+		 * Use Trusted NV counter for platforms that don't support
+		 * the CCA NV Counter.
+		 */
+		nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+							TRUSTED_NV_CTR_ID);
+#endif
 	} else {
 		return 1;
 	}
diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
index a7fadf6a..22ae9d35 100644
--- a/plat/arm/board/common/rotpk/arm_dev_rotpk.S
+++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
@@ -1,17 +1,10 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-/* corstone1000 platform provides custom values for the macros defined in
- * arm_def.h , so only platform_def.h needs to be included
- */
-#if !defined(TARGET_PLATFORM_FVP) && !defined(TARGET_PLATFORM_FPGA)
-#include "plat/arm/common/arm_def.h"
-#else
-#include <platform_def.h>
-#endif
+#include <plat/arm/board/common/rotpk/rotpk_def.h>
 
 	.global arm_rotpk_header
 	.section .rodata.arm_rotpk_hash, "a"
diff --git a/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin b/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
deleted file mode 100644
index b2f3e60a..00000000
--- a/plat/arm/board/common/swd_rotpk/arm_swd_rotpk_rsa_sha256.bin
+++ /dev/null
@@ -1 +0,0 @@
-0¾âÃ’æœÈË“(ì¨0ŠwIӁÕéã¡gk
\ No newline at end of file
diff --git a/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c b/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
index fe521a9f..de6a15a5 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, 2024 ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,9 +34,14 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
 		.image_info.image_base = BL31_BASE,
 		.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
 
+#ifdef CORSTONE1000_WITH_BL32
 		.next_handoff_image_id = BL32_IMAGE_ID,
+#else
+		.next_handoff_image_id = BL33_IMAGE_ID,
+#endif
 	},
 
+#ifdef CORSTONE1000_WITH_BL32
 	/* Fill BL32 related information */
 	{
 		.image_id = BL32_IMAGE_ID,
@@ -65,14 +70,15 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
 		VERSION_2, image_info_t, 0),
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
-
+#endif
 	/* Fill BL33 related information */
 	{
 		.image_id = BL33_IMAGE_ID,
 		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
 			VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE),
 		.ep_info.pc = BL33_BASE,
-
+		.ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+				       DISABLE_ALL_EXCEPTIONS),
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
 			VERSION_2, image_info_t, 0),
 		.image_info.image_base = BL33_BASE,
diff --git a/plat/arm/board/corstone1000/common/corstone1000_helpers.S b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
index cbe27c3b..a4ca9fe9 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_helpers.S
+++ b/plat/arm/board/corstone1000/common/corstone1000_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024 Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,8 +21,34 @@
 	 * --------------------------------------------------------------------
 	 */
 func plat_secondary_cold_boot_setup
+#if defined(CORSTONE1000_FVP_MULTICORE)
+
+	/* Calculate the address of our hold entry */
+	bl	plat_my_core_pos
+	lsl	x0, x0, #CORSTONE1000_SECONDARY_CORE_HOLD_SHIFT
+	mov_imm	x2, CORSTONE1000_SECONDARY_CORE_HOLD_BASE
+
+	/* Set the wait state for the secondary core */
+	mov_imm	x3, CORSTONE1000_SECONDARY_CORE_STATE_WAIT
+	str	x3, [x2, x0]
+	dmb	ish
+
+	/* Poll until the primary core signals to go  */
+poll_mailbox:
+	ldr	x1, [x2, x0]
+	cmp	x1, #CORSTONE1000_SECONDARY_CORE_STATE_WAIT
+	beq	1f
+	mov_imm	x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
+	ldr	x1, [x0]
+	br	x1
+1:
+	wfe
+	b	poll_mailbox
+#else
 cb_panic:
 	b	cb_panic
+#endif
+
 endfunc plat_secondary_cold_boot_setup
 
 	/* ---------------------------------------------------------------------
diff --git a/plat/arm/board/corstone1000/common/corstone1000_plat.c b/plat/arm/board/corstone1000/common/corstone1000_plat.c
index ed3801ca..e388c82f 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_plat.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,7 +23,6 @@
 
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
-	ARM_MAP_NS_SHARED_RAM,
 	ARM_MAP_NS_DRAM1,
 	CORSTONE1000_MAP_DEVICE,
 	CORSTONE1000_EXTERNAL_FLASH,
diff --git a/plat/arm/board/corstone1000/common/corstone1000_pm.c b/plat/arm/board/corstone1000/common/corstone1000_pm.c
index 4b0a791e..bd3faec8 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_pm.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,8 @@
 #include <lib/psci/psci.h>
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
+#include <plat/common/platform.h>
+#include <drivers/arm/gicv2.h>
 /*******************************************************************************
  * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
  * platform layer will take care of registering the handlers with PSCI.
@@ -18,6 +20,15 @@ static void __dead2 corstone1000_system_reset(void)
 	uint32_t volatile * const watchdog_ctrl_reg = (uint32_t *) SECURE_WATCHDOG_ADDR_CTRL_REG;
 	uint32_t volatile * const watchdog_val_reg = (uint32_t *) SECURE_WATCHDOG_ADDR_VAL_REG;
 
+	/*
+	 * Disable GIC CPU interface to prevent pending interrupt
+	 * from waking up the AP from WFI.
+	 */
+	gicv2_cpuif_disable();
+
+	/* Flush and invalidate data cache */
+	dcsw_op_all(DCCISW);
+
 	*(watchdog_val_reg) = SECURE_WATCHDOG_COUNTDOWN_VAL;
 	*watchdog_ctrl_reg = SECURE_WATCHDOG_MASK_ENABLE;
 	while (1) {
@@ -25,9 +36,52 @@ static void __dead2 corstone1000_system_reset(void)
 	}
 }
 
+#if defined(CORSTONE1000_FVP_MULTICORE)
+int corstone1000_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/*
+	 * Check if the non secure entrypoint lies within the non
+	 * secure DRAM.
+	 */
+	if ((entrypoint >= ARM_NS_DRAM1_BASE) && (entrypoint < (ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE))) {
+		return PSCI_E_SUCCESS;
+	}
+	return PSCI_E_INVALID_ADDRESS;
+}
+
+int corstone1000_pwr_domain_on(u_register_t mpidr)
+{
+	int core_index = plat_core_pos_by_mpidr(mpidr);
+	uint64_t *secondary_core_hold_base = (uint64_t *)CORSTONE1000_SECONDARY_CORE_HOLD_BASE;
+
+	/* Validate the core index */
+	if (core_index < 0 || core_index > PLATFORM_CORE_COUNT) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+	secondary_core_hold_base[core_index] = CORSTONE1000_SECONDARY_CORE_STATE_GO;
+	dsbish();
+	sev();
+
+	return PSCI_E_SUCCESS;
+}
+
+void corstone1000_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	(void)target_state;
+	plat_arm_gic_init();
+}
+#endif
+
 plat_psci_ops_t plat_arm_psci_pm_ops = {
+#if defined(CORSTONE1000_FVP_MULTICORE)
+	.pwr_domain_on = corstone1000_pwr_domain_on,
+	.pwr_domain_on_finish = corstone1000_pwr_domain_on_finish,
+	.validate_ns_entrypoint = corstone1000_validate_ns_entrypoint,
+	.system_reset = corstone1000_system_reset,
+#else
+	.validate_ns_entrypoint = NULL,
 	.system_reset = corstone1000_system_reset,
-	.validate_ns_entrypoint = NULL
+#endif
 };
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
diff --git a/plat/arm/board/corstone1000/common/include/platform_def.h b/plat/arm/board/corstone1000/common/include/platform_def.h
index 442d187f..caf3d462 100644
--- a/plat/arm/board/corstone1000/common/include/platform_def.h
+++ b/plat/arm/board/corstone1000/common/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,15 +10,13 @@
 #include <common/tbbr/tbbr_img_def.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/board/common/rotpk/rotpk_def.h>
 #include <plat/arm/board/common/v2m_def.h>
 #include <plat/arm/common/arm_spm_def.h>
 #include <plat/arm/common/smccc_def.h>
 #include <plat/common/common_def.h>
 #include <plat/arm/soc/common/soc_css_def.h>
 
-#define ARM_ROTPK_HEADER_LEN		19
-#define ARM_ROTPK_HASH_LEN		32
-
 /* Special value used to verify platform parameters from BL2 to BL31 */
 #define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
 
@@ -57,42 +55,42 @@
 
 /* Memory related constants */
 
-/* SRAM (CVM) memory layout
+/* Memory mappings of where the BLs in the FIP are copied to
  *
- * <ARM_TRUSTED_SRAM_BASE>
+ * <ARM_TRUSTED_SRAM_BASE> = 0x02000000
  *	partition size: sizeof(meminfo_t) = 16 bytes
  *	content: memory info area used by the next BL
  *
- * <ARM_FW_CONFIG_BASE>
+ * <ARM_FW_CONFIG_BASE> = 0x02000010
  *	partition size: 4080 bytes
  *
- * <ARM_BL2_MEM_DESC_BASE>
+ * <ARM_BL2_MEM_DESC_BASE> = 0x02001000
  *	partition size: 4 KB
  *	content: Area where BL2 copies the images descriptors
  *
- * <ARM_BL_RAM_BASE> = <BL32_BASE>
- *	partition size: 688 KB
+ * <ARM_BL_RAM_BASE> = <BL32_BASE> = 0x02002000
+ *	partition size: 3752 KB
  *	content: BL32 (optee-os)
  *
- * <CORSTONE1000_TOS_FW_CONFIG_BASE> = 0x20ae000
+ * <CORSTONE1000_TOS_FW_CONFIG_BASE> = 0x023AC000
  *	partition size: 8 KB
  *	content: BL32 config (TOS_FW_CONFIG)
  *
- * <BL31_BASE>
+ * <BL31_BASE> = 0x023AE000
  *	partition size: 140 KB
  *	content: BL31
  *
- * <BL2_SIGNATURE_BASE>
+ * <BL2_SIGNATURE_BASE> = 0x023D1000
  *	partition size: 4 KB
  *	content: MCUBOOT data needed to verify TF-A BL2
  *
- * <BL2_BASE>
+ * <BL2_BASE> = 0x023D2000
  *	partition size: 176 KB
  *	content: BL2
  *
- * <ARM_NS_SHARED_RAM_BASE> = <ARM_TRUSTED_SRAM_BASE> + 1 MB
- *	partition size: 512 KB
- *	content: BL33 (u-boot)
+ * <BL33_BASE> = 0x80000000
+ *	partition size: 12 MB
+ *	content: BL33 (U-Boot)
  */
 
 /* DDR memory */
@@ -117,11 +115,8 @@
 /* The remaining Trusted SRAM is used to load the BL images */
 #define TOTAL_SRAM_SIZE		(SZ_4M)  /* 4 MB */
 
-/* Last 512KB of CVM is allocated for shared RAM as an example openAMP */
-#define ARM_NS_SHARED_RAM_SIZE	(512 * SZ_1K)
 
 #define PLAT_ARM_TRUSTED_SRAM_SIZE	(TOTAL_SRAM_SIZE - \
-					 ARM_NS_SHARED_RAM_SIZE - \
 					 ARM_SHARED_RAM_SIZE)
 
 #define PLAT_ARM_MAX_BL2_SIZE	(180 * SZ_1K)  /* 180 KB */
@@ -160,11 +155,6 @@
 
 /* NS memory */
 
-/* The last 512KB of the SRAM is allocated as shared memory */
-#define ARM_NS_SHARED_RAM_BASE	(ARM_TRUSTED_SRAM_BASE + TOTAL_SRAM_SIZE - \
-				 (PLAT_ARM_MAX_BL31_SIZE + \
-				  PLAT_ARM_MAX_BL32_SIZE))
-
 #define BL33_BASE		ARM_DRAM1_BASE
 #define PLAT_ARM_MAX_BL33_SIZE	(12 * SZ_1M)  /* 12 MB*/
 #define BL33_LIMIT		(ARM_DRAM1_BASE + PLAT_ARM_MAX_BL33_SIZE)
@@ -264,9 +254,22 @@
 #define ARM_LOCAL_STATE_OFF	U(2)
 
 #define PLAT_ARM_TRUSTED_MAILBOX_BASE	ARM_TRUSTED_SRAM_BASE
+
+#if defined(CORSTONE1000_FVP_MULTICORE)
+/* The secondary core entrypoint address points to bl31_warm_entrypoint
+ * and the address size is 8 bytes */
+#define CORSTONE1000_SECONDARY_CORE_ENTRYPOINT_ADDRESS_SIZE    UL(0x8)
+
+#define CORSTONE1000_SECONDARY_CORE_HOLD_BASE	(PLAT_ARM_TRUSTED_MAILBOX_BASE + \
+						CORSTONE1000_SECONDARY_CORE_ENTRYPOINT_ADDRESS_SIZE)
+#define CORSTONE1000_SECONDARY_CORE_STATE_WAIT	ULL(0)
+#define CORSTONE1000_SECONDARY_CORE_STATE_GO	ULL(1)
+#define CORSTONE1000_SECONDARY_CORE_HOLD_SHIFT	ULL(3)
+#endif
+
 #define PLAT_ARM_NSTIMER_FRAME_ID	U(1)
 
-#define PLAT_ARM_NS_IMAGE_BASE		(ARM_NS_SHARED_RAM_BASE)
+#define PLAT_ARM_NS_IMAGE_BASE		(BL33_BASE)
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
@@ -295,11 +298,6 @@
 				ARM_SHARED_RAM_SIZE, \
 				MT_MEMORY | MT_RW | MT_SECURE)
 
-#define ARM_MAP_NS_SHARED_RAM	MAP_REGION_FLAT( \
-				ARM_NS_SHARED_RAM_BASE, \
-				ARM_NS_SHARED_RAM_SIZE, \
-				MT_MEMORY | MT_RW | MT_NS)
-
 #define ARM_MAP_NS_DRAM1	MAP_REGION_FLAT( \
 				ARM_NS_DRAM1_BASE, \
 				ARM_NS_DRAM1_SIZE, \
diff --git a/plat/arm/board/corstone1000/platform.mk b/plat/arm/board/corstone1000/platform.mk
index dcd0df84..dfde5aaf 100644
--- a/plat/arm/board/corstone1000/platform.mk
+++ b/plat/arm/board/corstone1000/platform.mk
@@ -1,12 +1,12 @@
 #
-# Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2024 Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 # Making sure the corstone1000 platform type is specified
 ifeq ($(filter ${TARGET_PLATFORM}, fpga fvp),)
-	$(error TARGET_PLATFORM must be fpga or fvp)
+        $(error TARGET_PLATFORM must be fpga or fvp)
 endif
 
 CORSTONE1000_CPU_LIBS	+=lib/cpus/aarch64/cortex_a35.S
@@ -28,9 +28,21 @@ FIP_BL2_ARGS := tb-fw
 
 override NEED_BL2U	:=	no
 override NEED_BL31	:=	yes
-NEED_BL32		:=	yes
+NEED_BL32		?=	yes
 override NEED_BL33	:=	yes
 
+# Add CORSTONE1000_WITH_BL32 as a preprocessor define (-D option)
+ifeq (${NEED_BL32},yes)
+$(eval $(call add_define,CORSTONE1000_WITH_BL32))
+endif
+
+ENABLE_MULTICORE       :=      0
+ifneq ($(filter ${TARGET_PLATFORM}, fvp),)
+ifeq (${ENABLE_MULTICORE},1)
+$(eval $(call add_define,CORSTONE1000_FVP_MULTICORE))
+endif
+endif
+
 # Include GICv2 driver files
 include drivers/arm/gic/v2/gicv2.mk
 
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 8efc2386..46fb44a7 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -6,9 +6,10 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/gicv3.h>
-#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <platform_def.h>
 
 	.globl	plat_secondary_cold_boot_setup
@@ -29,6 +30,21 @@
 	 */
 func plat_secondary_cold_boot_setup
 #ifndef EL3_PAYLOAD_BASE
+
+	/* --------------------------------------------
+	 * Check if core supports powering down, if it
+	 * supports power down then set core power down
+	 * bit before requesting for the cores to be
+	 * powered off from base power controller.
+	 * ---------------------------------------------
+	 */
+	bl	check_cpupwrctrl_el1_is_available
+	cbz	x0, base_power_off
+
+	mrs	x1, CPUPWRCTLR_EL1
+	orr	x1, x1, #CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CPUPWRCTLR_EL1, x1
+
 	/* ---------------------------------------------
 	 * Power down this cpu.
 	 * TODO: Do we need to worry about powering the
@@ -37,6 +53,7 @@ func plat_secondary_cold_boot_setup
 	 * loader zeroes out the zi section.
 	 * ---------------------------------------------
 	 */
+base_power_off:
 	mrs	x0, mpidr_el1
 	mov_imm	x1, PWRC_BASE
 	str	w0, [x1, #PPOFFR_OFF]
diff --git a/plat/arm/board/fvp/aarch64/fvp_lsp_ras_sp.c b/plat/arm/board/fvp/aarch64/fvp_lsp_ras_sp.c
new file mode 100644
index 00000000..5324fec9
--- /dev/null
+++ b/plat/arm/board/fvp/aarch64/fvp_lsp_ras_sp.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <inttypes.h>
+#include <stdint.h>
+
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/extensions/ras.h>
+
+#include <plat/common/platform.h>
+#include <services/el3_spmd_logical_sp.h>
+#include <services/ffa_svc.h>
+#include <services/sdei.h>
+
+
+#define CACTUS_SP_RAS_DELEGATE_CMD 0x72617365
+#define EVENT_NOTIFY_OS_RAS_ERROR U(5000)
+
+/*
+ * Note: Typical RAS error handling flow with Firmware First Handling
+ *
+ * Step 1: Exception resulting from a RAS error in the normal world is routed to
+ *         EL3.
+ * Step 2: This exception is typically signaled as either a synchronous external
+ *         abort or SError or interrupt. TF-A (EL3 firmware) delegates the
+ *         control to platform specific handler built on top of the RAS helper
+ *         utilities.
+ * Step 3: With the help of a Logical Secure Partition, TF-A sends a direct
+ *         message to dedicated S-EL0 (or S-EL1) RAS Partition managed by SPMC.
+ *         TF-A also populates a shared buffer with a data structure containing
+ *         enough information (such as system registers) to identify and triage
+ *         the RAS error.
+ * Step 4: RAS SP generates the Common Platform Error Record (CPER) and shares
+ *         it with normal world firmware and/or OS kernel through a reserved
+ *         buffer memory.
+ * Step 5: RAS SP responds to the direct message with information necessary for
+ *         TF-A to notify the OS kernel.
+ * Step 6: Consequently, TF-A dispatches an SDEI event to notify the OS kernel
+ *         about the CPER records for further logging.
+ */
+
+static int injected_fault_handler(const struct err_record_info *info,
+		int probe_data, const struct err_handler_data *const data)
+{
+	/*
+	 * At the moment, an FF-A compatible SP that supports RAS firmware is
+	 * not available. Hence the sequence below does not exactly follow the
+	 * steps outlined above. Therefore, some steps are essentially spoofed.
+	 * The handling of RAS error is completely done in EL3 firmware.
+	 */
+	uint64_t status, cactus_cmd_ret;
+	int ret, event_num;
+	cpu_context_t *ns_cpu_context;
+
+	/* Get a reference to the non-secure context */
+	ns_cpu_context = cm_get_context(NON_SECURE);
+	assert(ns_cpu_context != NULL);
+
+	/*
+	 * The faulting error record is already selected by the SER probe
+	 * function.
+	 */
+	status = read_erxstatus_el1();
+
+	ERROR("Fault reported by system error record %d on 0x%lx: status=0x%" PRIx64 "\n",
+			probe_data, read_mpidr_el1(), status);
+	ERROR(" exception reason=%u syndrome=0x%" PRIx64 "\n", data->ea_reason,
+			data->flags);
+
+	/* Clear error */
+	write_erxstatus_el1(status);
+
+	/*
+	 * Initiate an EL3 direct message from LSP to Cactus RAS Secure
+	 * Partition (ID 8001). Currently, the payload is being spoofed.
+	 * The direct message response contains the SDEI event ID for the
+	 * associated RAS error.
+	 */
+	(void)plat_spmd_logical_sp_smc_handler(0, 0, 0, CACTUS_SP_RAS_DELEGATE_CMD,
+						EVENT_NOTIFY_OS_RAS_ERROR,
+						NULL, ns_cpu_context, 0);
+
+	cactus_cmd_ret = read_ctx_reg(get_gpregs_ctx(ns_cpu_context), CTX_GPREG_X3);
+	event_num = (int)read_ctx_reg(get_gpregs_ctx(ns_cpu_context), CTX_GPREG_X4);
+
+	if (cactus_cmd_ret != 0) {
+		ERROR("RAS error could not be handled by SP: %lx\n", cactus_cmd_ret);
+		panic();
+	}
+
+	if (event_num != EVENT_NOTIFY_OS_RAS_ERROR) {
+		ERROR("Unexpected event id sent by RAS SP: %d\n", event_num);
+		panic();
+	}
+
+	/* Dispatch the event to the SDEI client */
+	ret = sdei_dispatch_event(event_num);
+	if (ret < 0) {
+		ERROR("Can't dispatch event to SDEI\n");
+		panic();
+	} else {
+		INFO("SDEI event dispatched\n");
+	}
+
+	return 0;
+}
+
+struct ras_interrupt fvp_ras_interrupts[] = {
+};
+
+struct err_record_info fvp_err_records[] = {
+	/* Record for injected fault */
+	ERR_RECORD_SYSREG_V1(0, 2, ras_err_ser_probe_sysreg,
+			injected_fault_handler, NULL),
+};
+
+REGISTER_ERR_RECORD_INFO(fvp_err_records);
+REGISTER_RAS_INTERRUPTS(fvp_ras_interrupts);
diff --git a/plat/arm/board/fvp/fdts/fvp_cactus_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_cactus_sp_manifest.dts
new file mode 100644
index 00000000..de804e05
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_cactus_sp_manifest.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
+ * that will be consumed by EL3 SPMC.
+ *
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,ffa-manifest-1.0";
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	/* Properties */
+	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
+	id = <0x8001>;
+	uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
+	messaging-method = <3>; /* Direct messaging only */
+	exception-level = <2>; /* S-EL1 */
+	execution-state = <0>; /* AARCH64 */
+	execution-ctx-count = <8>;
+	/* Boot protocol */
+	gp-register-num = <0>;
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi b/plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi
new file mode 100644
index 00000000..9c8328bb
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_cot_desc.dtsi
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#if COT_DESC_IN_DTB
+	#if defined(ARM_COT_cca)
+		#include "cca_cot_descriptors.dtsi"
+	#elif defined(ARM_COT_dualroot)
+		#include "dualroot_cot_descriptors.dtsi"
+	#elif defined(ARM_COT_tbbr)
+		#include "tbbr_cot_descriptors.dtsi"
+	#endif
+#endif
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index 4adf5d58..5d587311 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 
@@ -20,7 +21,7 @@
 
 		hw-config {
 			load-address = <0x0 0x07f00000>;
-			max-size = <0x00100000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 			secondary-load-address = <0x0 0x82000000>;
 		};
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_el1_optee_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_el1_optee_manifest.dts
new file mode 100644
index 00000000..36a22a1b
--- /dev/null
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_el1_optee_manifest.dts
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,ffa-core-manifest-1.0";
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	attribute {
+		spmc_id = <0x8000>;
+		maj_ver = <0x1>;
+		min_ver = <0x1>;
+		exec_state = <0x0>;
+		load_address = <0x0 0x6000000>;
+		entrypoint = <0x0 0x6000000>;
+		binary_size = <0x80000>;
+	};
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
index e159248b..bf0e7f38 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,7 @@
 	attribute {
 		spmc_id = <0x8000>;
 		maj_ver = <0x1>;
-		min_ver = <0x1>;
+		min_ver = <0x2>;
 		exec_state = <0x0>;
 		load_address = <0x0 0x6000000>;
 		entrypoint = <0x0 0x6000000>;
@@ -92,10 +92,25 @@
 
 	memory@1 {
 		device_type = "ns-memory";
-		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
-		      <0x0 0x88000000 0x0 0x10000000>;
+		reg = <0x0 0x80000000 0x0 0x7c000000>,
+		      <0x8 0x80000000 0x1 0x80000000>,
+		      <0x00008800 0x80000000 0x0 0x7f000000>;
 	};
 
+	memory@2 {
+		device_type = "device-memory";
+		reg = <0x0 0x1c0b0000 0x0 0x20000>, /* UART 2-3 */
+		      <0x0 0x2bfe0000 0x0 0x20000>, /* SMMUv3TestEngine */
+		      <0x0 0x2a490000 0x0 0x20000>, /* SP805 Trusted Watchdog */
+		      <0x0 0x1c130000 0x0 0x10000>; /* Virtio block device */
+	};
+
+	memory@3 {
+		device_type = "ns-device-memory";
+		reg = <0x0 0x1c090000 0x0 0x20000>; /* UART 0-1 */
+	};
+
+
 #if MEASURED_BOOT
 #include "event_log.dtsi"
 #endif
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
index 041dade7..234ab587 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
@@ -1,8 +1,9 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
 /dts-v1/;
 
 #define	AFF	00
@@ -15,12 +16,12 @@
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
 	#address-cells = <2>;
-	#size-cells = <1>;
+	#size-cells = <2>;
 
 	attribute {
 		spmc_id = <0x8000>;
 		maj_ver = <0x1>;
-		min_ver = <0x1>;
+		min_ver = <0x2>;
 		exec_state = <0x0>;
 		load_address = <0x0 0x6000000>;
 		entrypoint = <0x0 0x6000000>;
@@ -34,7 +35,7 @@
 			debug_name = "op-tee";
 			load_address = <0x6280000>;
 			vcpu_count = <8>;
-			mem_size = <1048576>;
+			mem_size = <0xd80000>;
 		};
 	};
 
@@ -59,6 +60,18 @@
 
 	memory@6000000 {
 		device_type = "memory";
-		reg = <0x0 0x6000000 0x2000000>; /* Trusted DRAM */
+		reg = <0x0 0x6000000 0x0 0x2000000>; /* Trusted DRAM */
+	};
+
+	memory@80000000 {
+		device_type = "ns-memory";
+		reg = <0x0 0x80000000 0x0 0x7c000000>,
+		      <0x8 0x80000000 0x1 0x80000000>,
+		      <0x00008800 0x80000000 0x0 0x7f000000>;
+	};
+
+	memory@0 {
+		device_type = "device-memory";
+		reg = <0x0 0x1c090000 0x0 0x40000>; /* UART */
 	};
 };
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 6ba76db6..f5d7f658 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -103,9 +103,7 @@
 #endif /* ARM_BL2_SP_LIST_DTS */
 	};
 
-#if COT_DESC_IN_DTB
-	#include "cot_descriptors.dtsi"
-#endif
+#include "fvp_cot_desc.dtsi"
 
 #if MEASURED_BOOT
 	#include "event_log.dtsi"
@@ -117,11 +115,18 @@
 
 #include "../fvp_def.h"
 
-&trusted_nv_counter {
+#if defined(ARM_COT_cca)
+/* FVP does not support the CCA NV Counter so use the Trusted one. */
+&cca_nv_ctr {
+	reg = <TFW_NVCTR_BASE>;
+};
+#endif
+
+&trusted_nv_ctr {
 	reg = <TFW_NVCTR_BASE>;
 };
 
-&non_trusted_nv_counter {
+&non_trusted_nv_ctr {
 	reg = <NTFW_CTR_BASE>;
 };
 #endif
diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
index 27f4724c..4611f806 100644
--- a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -15,23 +15,30 @@
 
 	/* Properties */
 	description = "op-tee";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <0xe0786148 0xe311f8e7 0x02005ebc 0x1bc5d5a5>;
 	id = <1>;
 	execution-ctx-count = <8>;
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x6280000>;
+	mem-size = <0xd80000>; 	/* OP-TEE specific extension */
 	entrypoint-offset = <0x4000>;
 	xlat-granule = <0>; /* 4KiB */
 	boot-order = <0>;
 	messaging-method = <0x3>; /* Direct request/response supported. */
-	managed-exit;
+	ns-interrupts-action = <1>; /* NS_ACTION_ME */
 	run-time-model = <1>; /* SP pre-emptible. */
 
 	/* Boot protocol */
 	gp-register-num = <0x0>;
 
+	/* Boot Info */
+	boot-info {
+		compatible = "arm,ffa-manifest-boot-info";
+		ffa_manifest;
+	};
+
 	device-regions {
 		compatible = "arm,ffa-manifest-device-regions";
 
@@ -39,6 +46,7 @@
 			base-address = <0x00000000 0x1c0a0000>;
 			pages-count = <1>;
 			attributes = <0x3>; /* read-write */
+			interrupts = <38 0x900>;
 		};
 	};
 };
diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
index dc95ba1c..f14dbffa 100644
--- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <stdint.h>
 
 #include <drivers/measured_boot/event_log/event_log.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <drivers/measured_boot/metadata.h>
 #include <plat/arm/common/plat_arm.h>
 #include <tools_share/zero_oid.h>
 
@@ -16,49 +16,17 @@ static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE];
 
 /* FVP table with platform specific image IDs, names and PCRs */
 const event_log_metadata_t fvp_event_log_metadata[] = {
-	{ FW_CONFIG_ID, EVLOG_FW_CONFIG_STRING, PCR_0 },
-	{ TB_FW_CONFIG_ID, EVLOG_TB_FW_CONFIG_STRING, PCR_0 },
-	{ BL2_IMAGE_ID, EVLOG_BL2_STRING, PCR_0 },
+	{ FW_CONFIG_ID, MBOOT_FW_CONFIG_STRING, PCR_0 },
+	{ TB_FW_CONFIG_ID, MBOOT_TB_FW_CONFIG_STRING, PCR_0 },
+	{ BL2_IMAGE_ID, MBOOT_BL2_IMAGE_STRING, PCR_0 },
 
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
 
-/* FVP table with platform specific image IDs and metadata. Intentionally not a
- * const struct, some members might set by bootloaders during trusted boot.
- */
-struct rss_mboot_metadata fvp_rss_mboot_metadata[] = {
-	{
-		.id = FW_CONFIG_ID,
-		.slot = U(6),
-		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_FW_CONFIG_STRING,
-		.pk_oid = ZERO_OID,
-		.lock_measurement = true },
-	{
-		.id = TB_FW_CONFIG_ID,
-		.slot = U(7),
-		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING,
-		.pk_oid = ZERO_OID,
-		.lock_measurement = true },
-	{
-		.id = BL2_IMAGE_ID,
-		.slot = U(8),
-		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_BL2_STRING,
-		.pk_oid = ZERO_OID,
-		.lock_measurement = true },
-
-	{
-		.id = RSS_MBOOT_INVALID_ID }
-};
-
 void bl1_plat_mboot_init(void)
 {
 	event_log_init(event_log, event_log + sizeof(event_log));
 	event_log_write_header();
-
-	rss_measured_boot_init(fvp_rss_mboot_metadata);
 }
 
 void bl1_plat_mboot_finish(void)
diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
index 349e064d..8bf7dad6 100644
--- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,7 @@
 
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/measured_boot/event_log/event_log.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <drivers/measured_boot/metadata.h>
 #if defined(ARM_COT_cca)
 #include <tools_share/cca_oid.h>
 #else
@@ -29,27 +29,27 @@ static uint64_t event_log_base;
 
 /* FVP table with platform specific image IDs, names and PCRs */
 const event_log_metadata_t fvp_event_log_metadata[] = {
-	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
-	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
-	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
-	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
-	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
-	{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
-	{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
-	{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
-	{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
-	{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
-	{ RMM_IMAGE_ID, EVLOG_RMM_STRING, PCR_0},
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
+	{ HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
+	{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
+	{ SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
+	{ SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
+	{ TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
+	{ RMM_IMAGE_ID, MBOOT_RMM_IMAGE_STRING, PCR_0},
 
 #if defined(SPD_spmd)
-	{ SP_PKG1_ID, EVLOG_SP1_STRING, PCR_0 },
-	{ SP_PKG2_ID, EVLOG_SP2_STRING, PCR_0 },
-	{ SP_PKG3_ID, EVLOG_SP3_STRING, PCR_0 },
-	{ SP_PKG4_ID, EVLOG_SP4_STRING, PCR_0 },
-	{ SP_PKG5_ID, EVLOG_SP5_STRING, PCR_0 },
-	{ SP_PKG6_ID, EVLOG_SP6_STRING, PCR_0 },
-	{ SP_PKG7_ID, EVLOG_SP7_STRING, PCR_0 },
-	{ SP_PKG8_ID, EVLOG_SP8_STRING, PCR_0 },
+	{ SP_PKG1_ID, MBOOT_SP1_STRING, PCR_0 },
+	{ SP_PKG2_ID, MBOOT_SP2_STRING, PCR_0 },
+	{ SP_PKG3_ID, MBOOT_SP3_STRING, PCR_0 },
+	{ SP_PKG4_ID, MBOOT_SP4_STRING, PCR_0 },
+	{ SP_PKG5_ID, MBOOT_SP5_STRING, PCR_0 },
+	{ SP_PKG6_ID, MBOOT_SP6_STRING, PCR_0 },
+	{ SP_PKG7_ID, MBOOT_SP7_STRING, PCR_0 },
+	{ SP_PKG8_ID, MBOOT_SP8_STRING, PCR_0 },
 #endif
 
 	{ CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 },
@@ -57,44 +57,6 @@ const event_log_metadata_t fvp_event_log_metadata[] = {
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
 
-/* FVP table with platform specific image IDs and metadata. Intentionally not a
- * const struct, some members might set by bootloaders during trusted boot.
- */
-struct rss_mboot_metadata fvp_rss_mboot_metadata[] = {
-	{
-		.id = BL31_IMAGE_ID,
-		.slot = U(9),
-		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_BL31_STRING,
-		.pk_oid = BL31_IMAGE_KEY_OID,
-		.lock_measurement = true },
-	{
-		.id = HW_CONFIG_ID,
-		.slot = U(10),
-		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_HW_CONFIG_STRING,
-		.pk_oid = HW_CONFIG_KEY_OID,
-		.lock_measurement = true },
-	{
-		.id = SOC_FW_CONFIG_ID,
-		.slot = U(11),
-		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING,
-		.pk_oid = SOC_FW_CONFIG_KEY_OID,
-		.lock_measurement = true },
-#if ENABLE_RME
-	{
-		.id = RMM_IMAGE_ID,
-		.slot = U(12),
-		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_RMM_STRING,
-		.pk_oid = RMM_IMAGE_KEY_OID,
-		.lock_measurement = true },
-#endif /* ENABLE_RME */
-	{
-		.id = RSS_MBOOT_INVALID_ID }
-};
-
 void bl2_plat_mboot_init(void)
 {
 	uint8_t *event_log_start;
@@ -126,8 +88,6 @@ void bl2_plat_mboot_init(void)
 				       event_log_max_size);
 
 	event_log_init((uint8_t *)event_log_start, event_log_finish);
-
-	rss_measured_boot_init(fvp_rss_mboot_metadata);
 }
 
 int plat_mboot_measure_critical_data(unsigned int critical_data_id,
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index ebd52664..ebdd80d4 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <common/debug.h>
 #include <common/desc_image_load.h>
 #include <drivers/arm/sp804_delay_timer.h>
+#include <fvp_pas_def.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/transfer_list.h>
@@ -19,10 +20,39 @@
 
 #include "fvp_private.h"
 
-static struct transfer_list_header *ns_tl __unused;
+#if ENABLE_RME
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+	ARM_PAS_KERNEL,
+	ARM_PAS_SECURE,
+	ARM_PAS_REALM,
+	ARM_PAS_EL3_DRAM,
+	ARM_PAS_GPTS,
+	ARM_PAS_KERNEL_1
+};
+
+static const arm_gpt_info_t arm_gpt_info = {
+	.pas_region_base  = pas_regions,
+	.pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions),
+	.l0_base = (uintptr_t)ARM_L0_GPT_BASE,
+	.l1_base = (uintptr_t)ARM_L1_GPT_BASE,
+	.l0_size = (size_t)ARM_L0_GPT_SIZE,
+	.l1_size = (size_t)ARM_L1_GPT_SIZE,
+	.pps = GPCCR_PPS_64GB,
+	.pgs = GPCCR_PGS_4K
+};
+#endif
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
 {
+	struct transfer_list_entry *te __unused;
+
+#if TRANSFER_LIST
+	arg0 = arg3;
+#endif
 	arm_bl2_early_platform_setup((uintptr_t)arg0, (meminfo_t *)arg1);
 
 	/* Initialize the platform config for future decision making */
@@ -33,30 +63,32 @@ void bl2_platform_setup(void)
 {
 	arm_bl2_platform_setup();
 
-#if TRANSFER_LIST
-	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE);
-	assert(ns_tl != NULL);
-#endif
 	/* Initialize System level generic or SP804 timer */
 	fvp_timer_init();
 }
 
+#if ENABLE_RME
+const arm_gpt_info_t *plat_arm_get_gpt_info(void)
+{
+	return &arm_gpt_info;
+}
+#endif /* ENABLE_RME */
+
 /*******************************************************************************
  * This function returns the list of executable images
  ******************************************************************************/
 struct bl_params *plat_get_next_bl_params(void)
 {
 	struct bl_params *arm_bl_params;
-	const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
-	struct transfer_list_entry *te __unused;
 	bl_mem_params_node_t *param_node __unused;
+	const struct dyn_cfg_dtb_info_t *fw_config_info __unused;
+	const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
+	entry_point_info_t *ep __unused;
+	uint32_t next_exe_img_id __unused;
+	uintptr_t fw_config_base __unused;
 
 	arm_bl_params = arm_get_next_bl_params();
 
-#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE
-	const struct dyn_cfg_dtb_info_t *fw_config_info;
-	uintptr_t fw_config_base = 0UL;
-
 #if __aarch64__
 	/* Get BL31 image node */
 	param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
@@ -66,6 +98,15 @@ struct bl_params *plat_get_next_bl_params(void)
 #endif /* __aarch64__ */
 	assert(param_node != NULL);
 
+#if TRANSFER_LIST
+	arm_bl_params->head = &param_node->params_node_mem;
+	arm_bl_params->head->ep_info = &param_node->ep_info;
+	arm_bl_params->head->image_id = param_node->image_id;
+
+	arm_bl2_setup_next_ep_info(param_node);
+#elif !RESET_TO_BL2 && !EL3_PAYLOAD_BASE
+	fw_config_base = 0UL;
+
 	/* Update the next image's ep info with the FW config address */
 	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
 	assert(fw_config_info != NULL);
@@ -79,49 +120,29 @@ struct bl_params *plat_get_next_bl_params(void)
 	param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
 	assert(param_node != NULL);
 
-#if TRANSFER_LIST
-	/* Update BL33's ep info with NS HW config address  */
-	te = transfer_list_find(ns_tl, TL_TAG_FDT);
-	assert(te != NULL);
-
-	param_node->ep_info.args.arg1 = TRANSFER_LIST_SIGNATURE |
-					REGISTER_CONVENTION_VERSION_MASK;
-	param_node->ep_info.args.arg2 = 0;
-	param_node->ep_info.args.arg3 = (uintptr_t)ns_tl;
-	param_node->ep_info.args.arg0 =
-		te ? (uintptr_t)transfer_list_entry_data(te) : 0;
-#else
 	hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 	assert(hw_config_info != NULL);
 
 	param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr;
 #endif /* TRANSFER_LIST */
-#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */
 
 	return arm_bl_params;
 }
 
 int bl2_plat_handle_post_image_load(unsigned int image_id)
 {
-#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE
+#if !RESET_TO_BL2 && !EL3_PAYLOAD_BASE && !TRANSFER_LIST
 	if (image_id == HW_CONFIG_ID) {
-		const struct dyn_cfg_dtb_info_t *hw_config_info;
+		const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
 		struct transfer_list_entry *te __unused;
+		bl_mem_params_node_t *param_node __unused;
 
-		const bl_mem_params_node_t *param_node =
-			get_bl_mem_params_node(image_id);
+		param_node = get_bl_mem_params_node(image_id);
 		assert(param_node != NULL);
 
 		hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
 		assert(hw_config_info != NULL);
 
-#if TRANSFER_LIST
-		/* Update BL33's ep info with NS HW config address  */
-		te = transfer_list_add(ns_tl, TL_TAG_FDT,
-				       param_node->image_info.image_size,
-				       (void *)hw_config_info->config_addr);
-		assert(te != NULL);
-#else
 		memcpy((void *)hw_config_info->secondary_config_addr,
 		       (void *)hw_config_info->config_addr,
 		       (size_t)param_node->image_info.image_size);
@@ -132,9 +153,8 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 		 */
 		flush_dcache_range(hw_config_info->secondary_config_addr,
 				   param_node->image_info.image_size);
-#endif /* TRANSFER_LIST */
 	}
-#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */
+#endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE && !TRANSFER_LIST*/
 
 	return arm_bl2_plat_handle_post_image_load(image_id);
 }
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index e46dbc91..e0875656 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -1,16 +1,19 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
+
+#include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/smmu_v3.h>
 #include <fconf_hw_config_getter.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/mmio.h>
+
 #include <plat/arm/common/arm_config.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
@@ -25,6 +28,9 @@ void __init bl31_early_platform_setup2(u_register_t arg0,
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
+#if TRANSFER_LIST
+	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
+#else
 #if !RESET_TO_BL31 && !RESET_TO_BL2
 	const struct dyn_cfg_dtb_info_t *soc_fw_config_info;
 
@@ -48,8 +54,8 @@ void __init bl31_early_platform_setup2(u_register_t arg0,
 	assert(hw_config_info->secondary_config_addr != 0UL);
 	arg2 = hw_config_info->secondary_config_addr;
 #endif /* !RESET_TO_BL31 && !RESET_TO_BL2 */
-
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+#endif /* TRANSFER_LIST */
 
 	/* Initialize the platform config for future decision making */
 	fvp_config_setup();
@@ -73,10 +79,22 @@ void __init bl31_early_platform_setup2(u_register_t arg0,
 	fvp_timer_init();
 
 	/* On FVP RevC, initialize SMMUv3 */
-	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U)
-		smmuv3_init(PLAT_FVP_SMMUV3_BASE);
+	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) {
+		if (smmuv3_security_init(PLAT_FVP_SMMUV3_BASE) != 0) {
+			/*
+			 * Don't proceed for smmuv3 initialization if the
+			 * security init failed.
+			 */
+			return;
+		}
+		/* SMMUv3 initialization failure is not fatal */
+		if (smmuv3_init(PLAT_FVP_SMMUV3_BASE) != 0) {
+			WARN("Failed initializing SMMU.\n");
+		}
+	}
 }
 
+#if !TRANSFER_LIST
 void __init bl31_plat_arch_setup(void)
 {
 	int rc __unused;
@@ -131,6 +149,7 @@ void __init bl31_plat_arch_setup(void)
 	}
 #endif /* !RESET_TO_BL31 && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1 */
 }
+#endif /* TRANSFER_LIST */
 
 unsigned int plat_get_syscnt_freq2(void)
 {
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index c40a3ced..bdc2cacf 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
+#include <string.h>
 
 #include <common/debug.h>
 #include <drivers/arm/cci.h>
@@ -24,7 +25,6 @@
 #endif
 
 #include <plat/arm/common/arm_config.h>
-#include <plat/arm/common/arm_pas_def.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -34,6 +34,14 @@
 #define FVP_GICV2		1
 #define FVP_GICV3		2
 
+/* Defines for RMM Console*/
+#define FVP_RMM_CONSOLE_BASE		UL(0x1c0c0000)
+#define FVP_RMM_CONSOLE_BAUD		UL(115200)
+#define FVP_RMM_CONSOLE_CLK_IN_HZ	UL(14745600)
+#define FVP_RMM_CONSOLE_NAME		"pl011"
+
+#define FVP_RMM_CONSOLE_COUNT		UL(1)
+
 /*******************************************************************************
  * arm_config holds the characteristics of the differences between the three FVP
  * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot
@@ -73,9 +81,14 @@ arm_config_t arm_config;
 
 #if TRANSFER_LIST
 #ifdef FW_NS_HANDOFF_BASE
-#define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, \
-					  FW_HANDOFF_SIZE,    \
-					  MT_MEMORY | MT_RW | MT_NS)
+#define MAP_FW_NS_HANDOFF                                             \
+	MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, PLAT_ARM_FW_HANDOFF_SIZE, \
+			MT_MEMORY | MT_RW | MT_NS)
+#endif
+#ifdef PLAT_ARM_EL3_FW_HANDOFF_BASE
+#define MAP_EL3_FW_HANDOFF                            \
+	MAP_REGION_FLAT(PLAT_ARM_EL3_FW_HANDOFF_BASE, \
+			PLAT_ARM_FW_HANDOFF_SIZE, MT_MEMORY | MT_RW | EL3_PAS)
 #endif
 #endif
 
@@ -157,7 +170,10 @@ defined(SPD_spmd))
 	ARM_MAP_OPTEE_CORE_MEM,
 	ARM_OPTEE_PAGEABLE_LOAD_MEM,
 #endif
-	{0}
+#ifdef MAP_EL3_FW_HANDOFF
+	MAP_EL3_FW_HANDOFF,
+#endif
+	{ 0 }
 };
 #endif
 #ifdef IMAGE_BL2U
@@ -194,12 +210,20 @@ const mmap_region_t plat_arm_mmap[] = {
 #ifdef MAP_FW_NS_HANDOFF
 	MAP_FW_NS_HANDOFF,
 #endif
-	{0}
+#if defined(MAP_EL3_FW_HANDOFF) && !RESET_TO_BL31
+	MAP_EL3_FW_HANDOFF,
+#endif
+	{ 0 }
 };
 
 #if defined(IMAGE_BL31) && SPM_MM
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
 	V2M_MAP_IOFPGA_EL0, /* for the UART */
+	V2M_MAP_SECURE_SYSTEMREG_EL0, /* for initializing flash */
+#if PSA_FWU_SUPPORT
+	V2M_MAP_FLASH0_RW_EL0, /* for firmware update service in standalone mm */
+#endif
+	V2M_MAP_FLASH1_RW_EL0, /* for secure variable service in standalone mm */
 	MAP_REGION_FLAT(DEVICE0_BASE,
 			DEVICE0_SIZE,
 			MT_DEVICE | MT_RO | MT_SECURE | MT_USER),
@@ -551,10 +575,28 @@ size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
 	return (size_t)RMM_SHARED_SIZE;
 }
 
+/*
+ * Calculate checksum of 64-bit words @buffer with @size length
+ */
+static uint64_t checksum_calc(uint64_t *buffer, size_t size)
+{
+	uint64_t sum = 0UL;
+
+	assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL);
+	assert((size & (sizeof(uint64_t) - 1UL)) == 0UL);
+
+	for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) {
+		sum += buffer[i];
+	}
+
+	return sum;
+}
+
 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 {
-	uint64_t checksum, num_banks;
+	uint64_t checksum, num_banks, num_consoles;
 	struct ns_dram_bank *bank_ptr;
+	struct console_info *console_ptr;
 
 	assert(manifest != NULL);
 
@@ -562,62 +604,110 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
 	num_banks = FCONF_GET_PROPERTY(hw_config, dram_layout, num_banks);
 	assert(num_banks <= ARM_DRAM_NUM_BANKS);
 
+	/* Set number of consoles */
+	num_consoles = FVP_RMM_CONSOLE_COUNT;
+
 	manifest->version = RMMD_MANIFEST_VERSION;
 	manifest->padding = 0U; /* RES0 */
 	manifest->plat_data = (uintptr_t)NULL;
 	manifest->plat_dram.num_banks = num_banks;
+	manifest->plat_console.num_consoles = num_consoles;
 
 	/*
-	 * Array ns_dram_banks[] follows ns_dram_info structure:
+	 * Boot Manifest structure illustration, with two dram banks and
+	 * a single console.
 	 *
-	 * +-----------------------------------+
-	 * |  offset  |   field   |  comment   |
-	 * +----------+-----------+------------+
-	 * |    0     |  version  | 0x00000002 |
-	 * +----------+-----------+------------+
-	 * |    4     |  padding  | 0x00000000 |
-	 * +----------+-----------+------------+
-	 * |    8     | plat_data |    NULL    |
-	 * +----------+-----------+------------+
-	 * |    16    | num_banks |            |
-	 * +----------+-----------+            |
-	 * |    24    |   banks   | plat_dram  |
-	 * +----------+-----------+            |
-	 * |    32    | checksum  |            |
-	 * +----------+-----------+------------+
-	 * |    40    |  base 0   |            |
-	 * +----------+-----------+   bank[0]  |
-	 * |    48    |  size 0   |            |
-	 * +----------+-----------+------------+
-	 * |    56    |  base 1   |            |
-	 * +----------+-----------+   bank[1]  |
-	 * |    64    |  size 1   |            |
-	 * +----------+-----------+------------+
+	 * +----------------------------------------+
+	 * | offset |     field      |    comment   |
+	 * +--------+----------------+--------------+
+	 * |   0    |    version     |  0x00000003  |
+	 * +--------+----------------+--------------+
+	 * |   4    |    padding     |  0x00000000  |
+	 * +--------+----------------+--------------+
+	 * |   8    |   plat_data    |     NULL     |
+	 * +--------+----------------+--------------+
+	 * |   16   |   num_banks    |              |
+	 * +--------+----------------+              |
+	 * |   24   |     banks      |   plat_dram  |
+	 * +--------+----------------+              |
+	 * |   32   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   40   |  num_consoles  |              |
+	 * +--------+----------------+              |
+	 * |   48   |    consoles    | plat_console |
+	 * +--------+----------------+              |
+	 * |   56   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   64   |     base 0     |              |
+	 * +--------+----------------+    bank[0]   |
+	 * |   72   |     size 0     |              |
+	 * +--------+----------------+--------------+
+	 * |   80   |     base 1     |              |
+	 * +--------+----------------+    bank[1]   |
+	 * |   88   |     size 1     |              |
+	 * +--------+----------------+--------------+
+	 * |   96   |     base       |              |
+	 * +--------+----------------+              |
+	 * |   104  |   map_pages    |              |
+	 * +--------+----------------+              |
+	 * |   112  |     name       |              |
+	 * +--------+----------------+  consoles[0] |
+	 * |   120  |   clk_in_hz    |              |
+	 * +--------+----------------+              |
+	 * |   128  |   baud_rate    |              |
+	 * +--------+----------------+              |
+	 * |   136  |     flags      |              |
+	 * +--------+----------------+--------------+
 	 */
+
 	bank_ptr = (struct ns_dram_bank *)
-			((uintptr_t)&manifest->plat_dram.checksum +
-			sizeof(manifest->plat_dram.checksum));
+			(((uintptr_t)manifest) + sizeof(*manifest));
+	console_ptr = (struct console_info *)
+			((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
 
 	manifest->plat_dram.banks = bank_ptr;
+	manifest->plat_console.consoles = console_ptr;
+
+	/* Ensure the manifest is not larger than the shared buffer */
+	assert((sizeof(struct rmm_manifest) +
+		(sizeof(struct console_info) * manifest->plat_console.num_consoles) +
+		(sizeof(struct ns_dram_bank) * manifest->plat_dram.num_banks)) <= ARM_EL3_RMM_SHARED_SIZE);
 
 	/* Calculate checksum of plat_dram structure */
 	checksum = num_banks + (uint64_t)bank_ptr;
 
 	/* Store FVP DRAM banks data in Boot Manifest */
 	for (unsigned long i = 0UL; i < num_banks; i++) {
-		uintptr_t base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base);
-		uint64_t size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size);
-
-		bank_ptr[i].base = base;
-		bank_ptr[i].size = size;
-
-		/* Update checksum */
-		checksum += base + size;
+		bank_ptr[i].base = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].base);
+		bank_ptr[i].size = FCONF_GET_PROPERTY(hw_config, dram_layout, dram_bank[i].size);
 	}
 
+	/* Update checksum */
+	checksum += checksum_calc((uint64_t *)bank_ptr, sizeof(struct ns_dram_bank) * num_banks);
+
 	/* Checksum must be 0 */
 	manifest->plat_dram.checksum = ~checksum + 1UL;
 
+	/* Calculate the checksum of the plat_consoles structure */
+	checksum = num_consoles + (uint64_t)console_ptr;
+
+	/* Zero out the console info struct */
+	(void)memset((void *)console_ptr, '\0', sizeof(struct console_info) * num_consoles);
+
+	console_ptr[0].base = FVP_RMM_CONSOLE_BASE;
+	console_ptr[0].map_pages = 1UL;
+	console_ptr[0].clk_in_hz = FVP_RMM_CONSOLE_CLK_IN_HZ;
+	console_ptr[0].baud_rate = FVP_RMM_CONSOLE_BAUD;
+
+	(void)strlcpy(console_ptr[0].name, FVP_RMM_CONSOLE_NAME, RMM_CONSOLE_MAX_NAME_LEN - 1UL);
+
+	/* Update checksum */
+	checksum += checksum_calc((uint64_t *)console_ptr,
+					sizeof(struct console_info) * num_consoles);
+
+	/* Checksum must be 0 */
+	manifest->plat_console.checksum = ~checksum + 1UL;
+
 	return 0;
 }
 #endif	/* ENABLE_RME */
diff --git a/plat/arm/board/fvp/fvp_common_measured_boot.c b/plat/arm/board/fvp/fvp_common_measured_boot.c
index 0c1d5e70..605f0ff6 100644
--- a/plat/arm/board/fvp/fvp_common_measured_boot.c
+++ b/plat/arm/board/fvp/fvp_common_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,17 +9,14 @@
 
 #include <common/desc_image_load.h>
 #include <drivers/measured_boot/event_log/event_log.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
 extern event_log_metadata_t fvp_event_log_metadata[];
-extern struct rss_mboot_metadata fvp_rss_mboot_metadata[];
 
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 {
 	int err;
-	int rc = 0;
 
 	/* Calculate image hash and record data in Event Log */
 	err = event_log_measure_and_record(image_data->image_base,
@@ -29,26 +26,14 @@ int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 	if (err != 0) {
 		ERROR("%s%s image id %u (%i)\n",
 		      "Failed to ", "record in event log", image_id, err);
-		rc = err;
+		return err;
 	}
 
-	/* Calculate image hash and record data in RSS */
-	err = rss_mboot_measure_and_record(fvp_rss_mboot_metadata,
-					   image_data->image_base,
-					   image_data->image_size,
-					   image_id);
-	if (err != 0) {
-		ERROR("%s%s image id %u (%i)\n",
-		      "Failed to ", "record in RSS", image_id, err);
-		rc = (rc == 0) ? err : -1;
-	}
-
-	return rc;
+	return 0;
 }
 
 int plat_mboot_measure_key(const void *pk_oid, const void *pk_ptr,
 			   size_t pk_len)
 {
-	return rss_mboot_set_signer_id(fvp_rss_mboot_metadata, pk_oid, pk_ptr,
-				       pk_len);
+	return 0;
 }
diff --git a/plat/arm/board/fvp/fvp_cpu_errata.mk b/plat/arm/board/fvp/fvp_cpu_errata.mk
index b8fa4ea8..b26fa803 100644
--- a/plat/arm/board/fvp/fvp_cpu_errata.mk
+++ b/plat/arm/board/fvp/fvp_cpu_errata.mk
@@ -1,63 +1,32 @@
 #
-# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-
-#/*
-# * TODO: below lines of code to be removed
-# * after abi and framework are synchronized
-# */
+# Flags to enable the cpu structures in the Errata ABI file
+# file: services/std_svc/errata_abi/errata_abi_main.c. This is specifically
+# for platforms that need to enable errata based on non-arm interconnect IP.
 
 ifeq (${ERRATA_ABI_SUPPORT}, 1)
-# enable the cpu macros for errata abi interface
-ifeq (${ARCH}, aarch64)
-ifeq (${HW_ASSISTED_COHERENCY}, 0)
-CORTEX_A35_H_INC	:= 1
-CORTEX_A53_H_INC	:= 1
-CORTEX_A57_H_INC	:= 1
-CORTEX_A72_H_INC	:= 1
-CORTEX_A73_H_INC	:= 1
-$(eval $(call add_define, CORTEX_A35_H_INC))
-$(eval $(call add_define, CORTEX_A53_H_INC))
-$(eval $(call add_define, CORTEX_A57_H_INC))
-$(eval $(call add_define, CORTEX_A72_H_INC))
-$(eval $(call add_define, CORTEX_A73_H_INC))
-else
+ifeq (${ERRATA_NON_ARM_INTERCONNECT}, 1)
 ifeq (${CTX_INCLUDE_AARCH32_REGS}, 0)
-CORTEX_A76_H_INC	:= 1
-CORTEX_A77_H_INC	:= 1
+CORTEX_A710_H_INC	:= 1
 CORTEX_A78_H_INC	:= 1
-NEOVERSE_N1_H_INC	:= 1
-NEOVERSE_N2_H_INC	:= 1
-NEOVERSE_V1_H_INC	:= 1
 CORTEX_A78_AE_H_INC	:= 1
-CORTEX_A510_H_INC	:= 1
-CORTEX_A710_H_INC	:= 1
-CORTEX_A715_H_INC 	:= 1
 CORTEX_A78C_H_INC	:= 1
-CORTEX_X2_H_INC		:= 1
-$(eval $(call add_define, CORTEX_A76_H_INC))
-$(eval $(call add_define, CORTEX_A77_H_INC))
+CORTEX_X3_H_INC		:= 1
+CORTEX_X4_H_INC		:= 1
+NEOVERSE_N2_H_INC	:= 1
+NEOVERSE_V1_H_INC	:= 1
+$(eval $(call add_define, CORTEX_A710_H_INC))
 $(eval $(call add_define, CORTEX_A78_H_INC))
-$(eval $(call add_define, NEOVERSE_N1_H_INC))
-$(eval $(call add_define, NEOVERSE_N2_H_INC))
-$(eval $(call add_define, NEOVERSE_V1_H_INC))
 $(eval $(call add_define, CORTEX_A78_AE_H_INC))
-$(eval $(call add_define, CORTEX_A510_H_INC))
-$(eval $(call add_define, CORTEX_A710_H_INC))
-$(eval $(call add_define, CORTEX_A715_H_INC))
 $(eval $(call add_define, CORTEX_A78C_H_INC))
-$(eval $(call add_define, CORTEX_X2_H_INC))
-endif
-CORTEX_A55_H_INC	:= 1
-CORTEX_A75_H_INC	:= 1
-$(eval $(call add_define, CORTEX_A55_H_INC))
-$(eval $(call add_define, CORTEX_A75_H_INC))
+$(eval $(call add_define, CORTEX_X3_H_INC))
+$(eval $(call add_define, CORTEX_X4_H_INC))
+$(eval $(call add_define, NEOVERSE_N2_H_INC))
+$(eval $(call add_define, NEOVERSE_V1_H_INC))
 endif
-else
-CORTEX_A32_H_INC	:= 1
-$(eval $(call add_define, CORTEX_A32_H_INC))
 endif
 endif
diff --git a/plat/arm/board/fvp/fvp_cpu_pwr.c b/plat/arm/board/fvp/fvp_cpu_pwr.c
new file mode 100644
index 00000000..f2771c23
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_cpu_pwr.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if __aarch64__
+
+#include <aem_generic.h>
+#include <arch_helpers.h>
+#include <cortex_a35.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a72.h>
+#include <cortex_a73.h>
+#include <cortex_a78_ae.h>
+#include <drivers/arm/fvp/fvp_cpu_pwr.h>
+#include <lib/utils_def.h>
+#include <neoverse_e1.h>
+
+bool check_cpupwrctrl_el1_is_available(void)
+{
+	/* Poupulate list of CPU midr that doesn't support CPUPWRCTL_EL1 */
+	const unsigned int midr_no_cpupwrctl[] = {
+		BASE_AEM_MIDR,
+		CORTEX_A35_MIDR,
+		CORTEX_A53_MIDR,
+		CORTEX_A57_MIDR,
+		CORTEX_A72_MIDR,
+		CORTEX_A73_MIDR,
+		CORTEX_A78_AE_MIDR,
+		NEOVERSE_E1_MIDR
+	};
+	unsigned int midr = (unsigned int)read_midr();
+
+	for (unsigned int i = 0U; i < ARRAY_SIZE(midr_no_cpupwrctl); i++) {
+		if (midr_no_cpupwrctl[i] == midr) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+#endif /* __arch64__ */
diff --git a/plat/arm/board/fvp/fvp_el3_spmc.c b/plat/arm/board/fvp/fvp_el3_spmc.c
index 6b44f634..c57a2444 100644
--- a/plat/arm/board/fvp/fvp_el3_spmc.c
+++ b/plat/arm/board/fvp/fvp_el3_spmc.c
@@ -7,23 +7,14 @@
 
 #include <platform_def.h>
 
-/*
- * On the FVP platform when using the EL3 SPMC implementation allocate the
- * datastore for tracking shared memory descriptors in the TZC DRAM section
- * to ensure sufficient storage can be allocated.
- * Provide an implementation of the accessor method to allow the datastore
- * details to be retrieved by the SPMC.
- * The SPMC will take care of initializing the memory region.
- */
-
-#define PLAT_SPMC_SHMEM_DATASTORE_SIZE 512 * 1024
+IMPORT_SYM(uintptr_t, __PLAT_SPMC_SHMEM_DATASTORE_START__, DATASTORE_BASE);
 
-__section(".arm_el3_tzc_dram") static uint8_t
+__section(".arm_el3_tzc_dram") __unused static uint8_t
 plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE];
 
 int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
 {
-	*datastore = plat_spmc_shmem_datastore;
+	*datastore = (uint8_t *)DATASTORE_BASE;
 	*size = PLAT_SPMC_SHMEM_DATASTORE_SIZE;
 	return 0;
 }
diff --git a/plat/arm/board/fvp/fvp_el3_token_sign.c b/plat/arm/board/fvp/fvp_el3_token_sign.c
new file mode 100644
index 00000000..282f94af
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_el3_token_sign.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <plat/common/platform.h>
+#include <services/rmm_el3_token_sign.h>
+
+static struct el3_token_sign_request el3_req = { 0 };
+static bool el3_req_valid;
+
+/*
+ * According to https://www.secg.org/sec1-v2.pdf 2.3.3
+ * the size of the ECDSA P384 public key is 97 bytes,
+ * with the first byte being 0x04.
+ */
+static uint8_t sample_attest_pub_key[] = {
+	0x04, 0x76, 0xf9, 0x88, 0x09, 0x1b, 0xe5, 0x85, 0xed, 0x41,
+	0x80, 0x1a, 0xec, 0xfa, 0xb8, 0x58, 0x54, 0x8c, 0x63, 0x05,
+	0x7e, 0x16, 0xb0, 0xe6, 0x76, 0x12, 0x0b, 0xbd, 0x0d, 0x2f,
+	0x9c, 0x29, 0xe0, 0x56, 0xc5, 0xd4, 0x1a, 0x01, 0x30, 0xeb,
+	0x9c, 0x21, 0x51, 0x78, 0x99, 0xdc, 0x23, 0x14, 0x6b, 0x28,
+	0xe1, 0xb0, 0x62, 0xbd, 0x3e, 0xa4, 0xb3, 0x15, 0xfd, 0x21,
+	0x9f, 0x1c, 0xbb, 0x52, 0x8c, 0xb6, 0xe7, 0x4c, 0xa4, 0x9b,
+	0xe1, 0x67, 0x73, 0x73, 0x4f, 0x61, 0xa1, 0xca, 0x61, 0x03,
+	0x1b, 0x2b, 0xbf, 0x3d, 0x91, 0x8f, 0x2f, 0x94, 0xff, 0xc4,
+	0x22, 0x8e, 0x50, 0x91, 0x95, 0x44, 0xae
+};
+
+/*
+ * FVP does not support HES, so provide 0's as keys.
+ */
+int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
+					 unsigned int type)
+{
+	(void)type;
+	if (*len < sizeof(sample_attest_pub_key)) {
+		return E_RMM_INVAL;
+	}
+
+	if (type != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+		ERROR("Invalid ECC curve specified\n");
+		return E_RMM_INVAL;
+	}
+
+	*len = sizeof(sample_attest_pub_key);
+
+	(void)memcpy((void *)buf, sample_attest_pub_key,
+		     sizeof(sample_attest_pub_key));
+
+	return 0;
+}
+
+int plat_rmmd_el3_token_sign_push_req(const struct el3_token_sign_request *req)
+{
+	/*
+	 * TODO: Today this function is called with a lock held on the
+	 * RMM<->EL3 shared buffer. In the future, we may move to a
+	 * different design that may require handling multi-threaded
+	 * calls to this function, for example, if we have a per CPU
+	 * buffer between RMM and EL3.
+	 */
+	if (el3_req_valid) {
+		return E_RMM_AGAIN;
+	}
+
+	el3_req = *req;
+
+	if ((el3_req.hash_alg_id != EL3_TOKEN_SIGN_HASH_ALG_SHA384) ||
+	    (el3_req.sig_alg_id != ATTEST_KEY_CURVE_ECC_SECP384R1)) {
+		return E_RMM_INVAL;
+	}
+
+	el3_req_valid = true;
+
+	return 0;
+}
+
+int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp)
+{
+	if (!el3_req_valid) {
+		return E_RMM_AGAIN;
+	}
+
+	resp->rec_granule = el3_req.rec_granule;
+	resp->req_ticket = el3_req.req_ticket;
+	resp->sig_len = (uint16_t)sizeof(resp->signature_buf);
+	/* TODO: Provide real signature */
+	memset(resp->signature_buf, 0, sizeof(resp->signature_buf));
+
+	el3_req_valid = false;
+
+	return 0;
+}
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
index 5fb3141c..0894bf76 100644
--- a/plat/arm/board/fvp/fvp_plat_attest_token.c
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,110 +10,250 @@
 
 #include <plat/common/platform.h>
 
+/*
+ * This is the CBOR serialization of the CCA platform token described at
+ * https://git.trustedfirmware.org/TF-M/tf-m-tools/+/refs/heads/main/iat-verifier/tests/data/cca_example_platform_token.yaml
+ */
 static const uint8_t sample_platform_token[] = {
-	0xD2, 0x84, 0x44, 0xA1, 0x01, 0x38, 0x22, 0xA0,
-	0x59, 0x02, 0x33, 0xA9, 0x19, 0x01, 0x09, 0x78,
-	0x1C, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
-	0x61, 0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F,
-	0x43, 0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F,
-	0x31, 0x2E, 0x30, 0x2E, 0x30, 0x0A, 0x58, 0x20,
-	0xB5, 0x97, 0x3C, 0xB6, 0x8B, 0xAA, 0x9F, 0xC5,
-	0x55, 0x58, 0x78, 0x6B, 0x7E, 0xC6, 0x7F, 0x69,
-	0xE4, 0x0D, 0xF5, 0xBA, 0x5A, 0xA9, 0x21, 0xCD,
-	0x0C, 0x27, 0xF4, 0x05, 0x87, 0xA0, 0x11, 0xEA,
-	0x19, 0x09, 0x5C, 0x58, 0x20, 0x7F, 0x45, 0x4C,
-	0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3E,
-	0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00,
-	0x58, 0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03,
-	0x02, 0x01, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B,
-	0x0A, 0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13,
-	0x12, 0x11, 0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B,
-	0x1A, 0x19, 0x18, 0x19, 0x09, 0x61, 0x58, 0x21,
-	0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
-	0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
-	0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
-	0x10, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
-	0x18, 0x19, 0x09, 0x5B, 0x19, 0x30, 0x03, 0x19,
-	0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2D, 0x32,
-	0x35, 0x36, 0x19, 0x09, 0x5F, 0x84, 0xA5, 0x01,
-	0x62, 0x42, 0x4C, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x33, 0x2E, 0x34, 0x2E, 0x32, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x06, 0x74, 0x54, 0x46, 0x2D, 0x4D, 0x5F, 0x53,
-	0x48, 0x41, 0x32, 0x35, 0x36, 0x4D, 0x65, 0x6D,
-	0x50, 0x72, 0x65, 0x58, 0x49, 0x50, 0xA4, 0x01,
-	0x62, 0x4D, 0x31, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x63,
-	0x31, 0x2E, 0x32, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0xA4, 0x01,
-	0x62, 0x4D, 0x32, 0x05, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x04, 0x65,
-	0x31, 0x2E, 0x32, 0x2E, 0x33, 0x02, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0xA4, 0x01, 0x62, 0x4D, 0x33, 0x05, 0x58, 0x20,
-	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-	0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
-	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-	0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
-	0x04, 0x61, 0x31, 0x02, 0x58, 0x20, 0x07, 0x06,
-	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
-	0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x17, 0x16,
-	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x1F, 0x1E,
-	0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x19, 0x09,
-	0x60, 0x6C, 0x77, 0x68, 0x61, 0x74, 0x65, 0x76,
-	0x65, 0x72, 0x2E, 0x63, 0x6F, 0x6D, 0x58, 0x60,
-	0xE6, 0xB6, 0x38, 0x4F, 0xAE, 0x3F, 0x6E, 0x67,
-	0xF5, 0xD4, 0x97, 0x4B, 0x3F, 0xFD, 0x0A, 0xFA,
-	0x1D, 0xF0, 0x2F, 0x73, 0xB8, 0xFF, 0x5F, 0x02,
-	0xC0, 0x0F, 0x40, 0xAC, 0xF3, 0xA2, 0x9D, 0xB5,
-	0x31, 0x50, 0x16, 0x4F, 0xFA, 0x34, 0x3D, 0x0E,
-	0xAF, 0xE0, 0xD0, 0xD1, 0x6C, 0xF0, 0x9D, 0xC1,
-	0x01, 0x42, 0xA2, 0x3C, 0xCE, 0xD4, 0x4A, 0x59,
-	0xDC, 0x29, 0x0A, 0x30, 0x93, 0x5F, 0xB4, 0x98,
-	0x61, 0xBA, 0xE3, 0x91, 0x22, 0x95, 0x24, 0xF4,
-	0xAE, 0x47, 0x93, 0xD3, 0x84, 0xA3, 0x76, 0xD0,
-	0xC1, 0x26, 0x96, 0x53, 0xA3, 0x60, 0x3F, 0x6C,
-	0x75, 0x96, 0x90, 0x6A, 0xF9, 0x4E, 0xDA, 0x30
+	0xd2, 0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0,
+	0x59, 0x05, 0x81, 0xa9, 0x19, 0x01, 0x09, 0x78,
+	0x23, 0x74, 0x61, 0x67, 0x3a, 0x61, 0x72, 0x6d,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x32, 0x30, 0x32,
+	0x33, 0x3a, 0x63, 0x63, 0x61, 0x5f, 0x70, 0x6c,
+	0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x23, 0x31,
+	0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x58, 0x20, 0x0d,
+	0x22, 0xe0, 0x8a, 0x98, 0x46, 0x90, 0x58, 0x48,
+	0x63, 0x18, 0x28, 0x34, 0x89, 0xbd, 0xb3, 0x6f,
+	0x09, 0xdb, 0xef, 0xeb, 0x18, 0x64, 0xdf, 0x43,
+	0x3f, 0xa6, 0xe5, 0x4e, 0xa2, 0xd7, 0x11, 0x19,
+	0x09, 0x5c, 0x58, 0x20, 0x7f, 0x45, 0x4c, 0x46,
+	0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3e, 0x00,
+	0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00, 0x58,
+	0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
+	0x01, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a,
+	0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12,
+	0x11, 0x10, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a,
+	0x19, 0x18, 0x19, 0x09, 0x61, 0x44, 0xcf, 0xcf,
+	0xcf, 0xcf, 0x19, 0x09, 0x5b, 0x19, 0x30, 0x03,
+	0x19, 0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0x19, 0x09, 0x60, 0x78, 0x3a,
+	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+	0x76, 0x65, 0x72, 0x61, 0x69, 0x73, 0x6f, 0x6e,
+	0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+	0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b,
+	0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x65, 0x72,
+	0x61, 0x69, 0x73, 0x6f, 0x6e, 0x2f, 0x76, 0x65,
+	0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x19, 0x09, 0x5f, 0x8d, 0xa4, 0x01,
+	0x69, 0x52, 0x53, 0x45, 0x5f, 0x42, 0x4c, 0x31,
+	0x5f, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0x9a, 0x27, 0x1f, 0x2a, 0x91, 0x6b, 0x0b, 0x6e,
+	0xe6, 0xce, 0xcb, 0x24, 0x26, 0xf0, 0xb3, 0x20,
+	0x6e, 0xf0, 0x74, 0x57, 0x8b, 0xe5, 0x5d, 0x9b,
+	0xc9, 0x4f, 0x6f, 0x3f, 0xe3, 0xab, 0x86, 0xaa,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x67, 0x52, 0x53, 0x45, 0x5f,
+	0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x53, 0xc2, 0x34, 0xe5, 0xe8, 0x47, 0x2b,
+	0x6a, 0xc5, 0x1c, 0x1a, 0xe1, 0xca, 0xb3, 0xfe,
+	0x06, 0xfa, 0xd0, 0x53, 0xbe, 0xb8, 0xeb, 0xfd,
+	0x89, 0x77, 0xb0, 0x10, 0x65, 0x5b, 0xfd, 0xd3,
+	0xc3, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x65, 0x52, 0x53, 0x45,
+	0x5f, 0x53, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0x11, 0x21, 0xcf, 0xcc, 0xd5, 0x91, 0x3f, 0x0a,
+	0x63, 0xfe, 0xc4, 0x0a, 0x6f, 0xfd, 0x44, 0xea,
+	0x64, 0xf9, 0xdc, 0x13, 0x5c, 0x66, 0x63, 0x4b,
+	0xa0, 0x01, 0xd1, 0x0b, 0xcf, 0x43, 0x02, 0xa2,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f, 0x42,
+	0x4c, 0x31, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0x15, 0x71, 0xb5, 0xec, 0x78, 0xbd, 0x68, 0x51,
+	0x2b, 0xf7, 0x83, 0x0b, 0xb6, 0xa2, 0xa4, 0x4b,
+	0x20, 0x47, 0xc7, 0xdf, 0x57, 0xbc, 0xe7, 0x9e,
+	0xb8, 0xa1, 0xc0, 0xe5, 0xbe, 0xa0, 0xa5, 0x01,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f, 0x42,
+	0x4c, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0x10, 0x15, 0x9b, 0xaf, 0x26, 0x2b, 0x43, 0xa9,
+	0x2d, 0x95, 0xdb, 0x59, 0xda, 0xe1, 0xf7, 0x2c,
+	0x64, 0x51, 0x27, 0x30, 0x16, 0x61, 0xe0, 0xa3,
+	0xce, 0x4e, 0x38, 0xb2, 0x95, 0xa9, 0x7c, 0x58,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x67, 0x53, 0x43, 0x50, 0x5f,
+	0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x10, 0x12, 0x2e, 0x85, 0x6b, 0x3f, 0xcd,
+	0x49, 0xf0, 0x63, 0x63, 0x63, 0x17, 0x47, 0x61,
+	0x49, 0xcb, 0x73, 0x0a, 0x1a, 0xa1, 0xcf, 0xaa,
+	0xd8, 0x18, 0x55, 0x2b, 0x72, 0xf5, 0x6d, 0x6f,
+	0x68, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43, 0x50,
+	0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0xf1,
+	0x4b, 0x49, 0x87, 0x90, 0x4b, 0xcb, 0x58, 0x14,
+	0xe4, 0x45, 0x9a, 0x05, 0x7e, 0xd4, 0xd2, 0x0f,
+	0x58, 0xa6, 0x33, 0x15, 0x22, 0x88, 0xa7, 0x61,
+	0x21, 0x4d, 0xcd, 0x28, 0x78, 0x0b, 0x56, 0x02,
+	0x58, 0x20, 0xaa, 0x67, 0xa1, 0x69, 0xb0, 0xbb,
+	0xa2, 0x17, 0xaa, 0x0a, 0xa8, 0x8a, 0x65, 0x34,
+	0x69, 0x20, 0xc8, 0x4c, 0x42, 0x44, 0x7c, 0x36,
+	0xba, 0x5f, 0x7e, 0xa6, 0x5f, 0x42, 0x2c, 0x1f,
+	0xe5, 0xd8, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x41, 0x50,
+	0x5f, 0x42, 0x4c, 0x33, 0x31, 0x05, 0x58, 0x20,
+	0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3,
+	0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56,
+	0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3,
+	0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3,
+	0x02, 0x58, 0x20, 0x2e, 0x6d, 0x31, 0xa5, 0x98,
+	0x3a, 0x91, 0x25, 0x1b, 0xfa, 0xe5, 0xae, 0xfa,
+	0x1c, 0x0a, 0x19, 0xd8, 0xba, 0x3c, 0xf6, 0x01,
+	0xd0, 0xe8, 0xa7, 0x06, 0xb4, 0xcf, 0xa9, 0x66,
+	0x1a, 0x6b, 0x8a, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x63, 0x52,
+	0x4d, 0x4d, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0xa1, 0xfb, 0x50, 0xe6, 0xc8, 0x6f, 0xae, 0x16,
+	0x79, 0xef, 0x33, 0x51, 0x29, 0x6f, 0xd6, 0x71,
+	0x34, 0x11, 0xa0, 0x8c, 0xf8, 0xdd, 0x17, 0x90,
+	0xa4, 0xfd, 0x05, 0xfa, 0xe8, 0x68, 0x81, 0x64,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x69, 0x48, 0x57, 0x5f, 0x43,
+	0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58, 0x20,
+	0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3,
+	0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56,
+	0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3,
+	0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3,
+	0x02, 0x58, 0x20, 0x1a, 0x25, 0x24, 0x02, 0x97,
+	0x2f, 0x60, 0x57, 0xfa, 0x53, 0xcc, 0x17, 0x2b,
+	0x52, 0xb9, 0xff, 0xca, 0x69, 0x8e, 0x18, 0x31,
+	0x1f, 0xac, 0xd0, 0xf3, 0xb0, 0x6e, 0xca, 0xae,
+	0xf7, 0x9e, 0x17, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x69, 0x46,
+	0x57, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47,
+	0x05, 0x58, 0x20, 0x53, 0x78, 0x79, 0x63, 0x07,
+	0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2,
+	0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30,
+	0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97,
+	0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20, 0x9a, 0x92,
+	0xad, 0xbc, 0x0c, 0xee, 0x38, 0xef, 0x65, 0x8c,
+	0x71, 0xce, 0x1b, 0x1b, 0xf8, 0xc6, 0x56, 0x68,
+	0xf1, 0x66, 0xbf, 0xb2, 0x13, 0x64, 0x4c, 0x89,
+	0x5c, 0xcb, 0x1a, 0xd0, 0x7a, 0x25, 0x06, 0x67,
+	0x73, 0x68, 0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4,
+	0x01, 0x6c, 0x54, 0x42, 0x5f, 0x46, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x23, 0x89, 0x03, 0x18,
+	0x0c, 0xc1, 0x04, 0xec, 0x2c, 0x5d, 0x8b, 0x3f,
+	0x20, 0xc5, 0xbc, 0x61, 0xb3, 0x89, 0xec, 0x0a,
+	0x96, 0x7d, 0xf8, 0xcc, 0x20, 0x8c, 0xdc, 0x7c,
+	0xd4, 0x54, 0x17, 0x4f, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x6d,
+	0x53, 0x4f, 0x43, 0x5f, 0x46, 0x57, 0x5f, 0x43,
+	0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58, 0x20,
+	0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3,
+	0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56,
+	0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3,
+	0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3,
+	0x02, 0x58, 0x20, 0xe6, 0xc2, 0x1e, 0x8d, 0x26,
+	0x0f, 0xe7, 0x18, 0x82, 0xde, 0xbd, 0xb3, 0x39,
+	0xd2, 0x40, 0x2a, 0x2c, 0xa7, 0x64, 0x85, 0x29,
+	0xbc, 0x23, 0x03, 0xf4, 0x86, 0x49, 0xbc, 0xe0,
+	0x38, 0x00, 0x17, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0x58, 0x60, 0x31, 0xd0,
+	0x4d, 0x52, 0xcc, 0xde, 0x95, 0x2c, 0x1e, 0x32,
+	0xcb, 0xa1, 0x81, 0x88, 0x5a, 0x40, 0xb8, 0xcc,
+	0x38, 0xe0, 0x52, 0x8c, 0x1e, 0x89, 0x58, 0x98,
+	0x07, 0x64, 0x2a, 0xa5, 0xe3, 0xf2, 0xbc, 0x37,
+	0xf9, 0x53, 0x74, 0x50, 0x6b, 0xff, 0x4d, 0x2e,
+	0x4b, 0xe7, 0x06, 0x3c, 0x4d, 0x72, 0x41, 0x92,
+	0x70, 0xc7, 0x22, 0xe8, 0xd4, 0xd9, 0x3e, 0xe8,
+	0xb6, 0xc9, 0xfa, 0xce, 0x3b, 0x43, 0xc9, 0x76,
+	0x1a, 0x49, 0x94, 0x1a, 0xb6, 0xf3, 0x8f, 0xfd,
+	0xff, 0x49, 0x6a, 0xd4, 0x63, 0xb4, 0xcb, 0xfa,
+	0x11, 0xd8, 0x3e, 0x23, 0xe3, 0x1f, 0x7f, 0x62,
+	0x32, 0x9d, 0xe3, 0x0c, 0x1c, 0xc8
 };
+static uint64_t platform_token_offset;
 
 /*
  * Get the hardcoded platform attestation token as FVP does not support
- * RSS.
+ * RSE.
+ *
+ * Note: This implementation caters for retrieval of the platform token
+ * in hunks to facilitate EL3-RMM interface testing. For most platforms,
+ * since the shared buffer size is known, the implementation can be more
+ * optimized.
  */
 int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
-				   uintptr_t hash, size_t hash_size)
+				   uintptr_t hash, size_t hash_size,
+				   size_t *remaining_len)
 {
 	(void)hash;
 	(void)hash_size;
+	size_t platform_token_size = sizeof(sample_platform_token);
+	size_t local_hunk_len;
+	size_t local_remaining_len;
 
-	if (*len < sizeof(sample_platform_token)) {
+	if (hash_size != 0) {
+		platform_token_offset = 0;
+	} else if (platform_token_offset == 0) {
 		return -EINVAL;
 	}
 
-	(void)memcpy((void *)buf, (const void *)sample_platform_token,
-		     sizeof(sample_platform_token));
-	*len = sizeof(sample_platform_token);
+	local_hunk_len = *len;
+	local_remaining_len = platform_token_size - platform_token_offset;
+
+	/*
+	 * If the buffer is enough to fit the remaining bytes of the token,
+	 * return only the remaining bytes of the token.
+	 */
+	if (local_hunk_len >= local_remaining_len) {
+		local_hunk_len = local_remaining_len;
+	}
+	/* Update remaining bytes according to hunk size */
+	local_remaining_len -= local_hunk_len;
+
+	(void)memcpy((void *)buf,
+			(const void *)sample_platform_token
+				+ platform_token_offset,
+			local_hunk_len);
+
+	platform_token_offset += local_hunk_len;
+	*len = local_hunk_len;
+	*remaining_len = local_remaining_len;
 
 	return 0;
 }
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 51dda9ec..80dfd2a9 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -1,17 +1,15 @@
 /*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 
-#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/arm/gicv3.h>
 #include <drivers/arm/fvp/fvp_pwrc.h>
-#include <lib/extensions/spe.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
 #include <plat/arm/common/arm_config.h>
@@ -54,14 +52,6 @@ static void fvp_cluster_pwrdwn_common(void)
 {
 	uint64_t mpidr = read_mpidr_el1();
 
-	/*
-	 * On power down we need to disable statistical profiling extensions
-	 * before exiting coherency.
-	 */
-	if (is_feat_spe_supported()) {
-		spe_disable();
-	}
-
 	/* Disable coherency if this cluster is to be turned off */
 	fvp_interconnect_disable();
 
@@ -333,13 +323,13 @@ static int fvp_node_hw_state(u_register_t target_cpu,
 			     unsigned int power_level)
 {
 	unsigned int psysr;
-	int ret;
+	int ret = 0;
 
 	/*
 	 * The format of 'power_level' is implementation-defined, but 0 must
 	 * mean a CPU. We also allow 1 to denote the cluster
 	 */
-	if ((power_level != ARM_PWR_LVL0) && (power_level != ARM_PWR_LVL1))
+	if ((power_level < ARM_PWR_LVL0) || (power_level > ARM_PWR_LVL1))
 		return PSCI_E_INVALID_PARAMS;
 
 	/*
@@ -353,9 +343,14 @@ static int fvp_node_hw_state(u_register_t target_cpu,
 
 	if (power_level == ARM_PWR_LVL0) {
 		ret = ((psysr & PSYSR_AFF_L0) != 0U) ? HW_ON : HW_OFF;
-	} else {
-		/* power_level == ARM_PWR_LVL1 */
-		ret = ((psysr & PSYSR_AFF_L1) != 0U) ? HW_ON : HW_OFF;
+	} else if (power_level == ARM_PWR_LVL1) {
+	/*
+	 * Use L1 affinity if MPIDR_EL1.MT bit is not set else use L2 affinity.
+	 */
+		if ((read_mpidr_el1() & MPIDR_MT_MASK) == 0U)
+			ret = ((psysr & PSYSR_AFF_L1) != 0U) ? HW_ON : HW_OFF;
+		else
+			ret = ((psysr & PSYSR_AFF_L2) != 0U) ? HW_ON : HW_OFF;
 	}
 
 	return ret;
diff --git a/plat/arm/board/fvp/fvp_realm_attest_key.c b/plat/arm/board/fvp/fvp_realm_attest_key.c
index fe0cde72..150608d6 100644
--- a/plat/arm/board/fvp/fvp_realm_attest_key.c
+++ b/plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -19,7 +19,7 @@ static const uint8_t sample_delegated_key[] = {
 
 /*
  * Get the hardcoded delegated realm attestation key as FVP
- * does not support RSS.
+ * does not support RSE.
  */
 int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
 				       unsigned int type)
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index 971e35b5..1db05023 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,7 +36,7 @@ const unsigned char *plat_get_power_domain_tree_desc(void)
 	 * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and
 	 * RESET_TO_BL2 systems.
 	 */
-#if RESET_TO_SP_MIN || RESET_TO_BL31 || RESET_TO_BL2
+#if RESET_TO_SP_MIN || RESET_TO_BL31 || RESET_TO_BL2 || IMAGE_BL1
 	cluster_count = FVP_CLUSTER_COUNT;
 	cpus_per_cluster = FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU;
 #else
@@ -106,8 +106,10 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
 	if (thread_id >= FVP_MAX_PE_PER_CPU)
 		return -1;
 
+#if !IMAGE_BL1
 	if (fvp_pwrc_read_psysr(mpidr) == PSYSR_INVALID)
 		return -1;
+#endif /* IMAGE_BL1 */
 
 	/*
 	 * Core position calculation for FVP platform depends on the MT bit in
diff --git a/include/plat/arm/common/arm_pas_def.h b/plat/arm/board/fvp/include/fvp_pas_def.h
similarity index 95%
rename from include/plat/arm/common/arm_pas_def.h
rename to plat/arm/board/fvp/include/fvp_pas_def.h
index fba8d2c7..46843872 100644
--- a/include/plat/arm/common/arm_pas_def.h
+++ b/plat/arm/board/fvp/include/fvp_pas_def.h
@@ -1,13 +1,13 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#ifndef ARM_PAS_DEF_H
-#define ARM_PAS_DEF_H
+#ifndef FVP_PAS_DEF_H
+#define FVP_PAS_DEF_H
 
 #include <lib/gpt_rme/gpt_rme.h>
-#include <plat/arm/common/arm_def.h>
+#include <platform_def.h>
 
 /*****************************************************************************
  * PAS regions used to initialize the Granule Protection Table (GPT)
@@ -107,11 +107,11 @@
 							       ARM_EL3_TZC_DRAM1_SIZE, \
 							       GPT_GPI_ROOT)
 
-#define	ARM_PAS_GPTS			GPT_MAP_REGION_GRANULE(ARM_L1_GPT_ADDR_BASE, \
+#define	ARM_PAS_GPTS			GPT_MAP_REGION_GRANULE(ARM_L1_GPT_BASE, \
 							       ARM_L1_GPT_SIZE, \
 							       GPT_GPI_ROOT)
 
 /* GPT Configuration options */
 #define PLATFORM_L0GPTSZ		GPCCR_L0GPTSZ_30BITS
 
-#endif /* ARM_PAS_DEF_H */
+#endif /* FVP_PAS_DEF_H */
diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S
index 7c8bf065..2f999990 100644
--- a/plat/arm/board/fvp/include/plat.ld.S
+++ b/plat/arm/board/fvp/include/plat.ld.S
@@ -1,12 +1,38 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #ifndef PLAT_LD_S
 #define PLAT_LD_S
 
-#include <plat/arm/common/arm_tzc_dram.ld.S>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+MEMORY {
+    EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE
+}
+
+SECTIONS
+{
+	. = ARM_EL3_TZC_DRAM1_BASE;
+	ASSERT(. == ALIGN(PAGE_SIZE),
+	"ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
+	.el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) {
+	__PLAT_SPMC_SHMEM_DATASTORE_START__ = .;
+	*(.arm_spmc_shmem_datastore)
+	__PLAT_SPMC_SHMEM_DATASTORE_END__ = .;
+	__EL3_SEC_DRAM_START__ = .;
+	*(.arm_el3_tzc_dram)
+#if SEPARATE_SIMD_SECTION
+	. = ALIGN(16);
+	*(.simd_context)
+#endif
+	__EL3_SEC_DRAM_UNALIGNED_END__ = .;
+
+	. = ALIGN(PAGE_SIZE);
+	__EL3_SEC_DRAM_END__ = .;
+	} >EL3_SEC_DRAM
+}
 
 #if RECLAIM_INIT_CODE
 #include <plat/arm/common/arm_reclaim_init.ld.S>
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index aad04173..e0c9725c 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -99,6 +99,20 @@
 					FVP_DTB_DRAM_MAP_SIZE,		\
 					MT_MEMORY | MT_RO | MT_NS)
 
+/*
+ * On the FVP platform when using the EL3 SPMC implementation allocate the
+ * datastore for tracking shared memory descriptors in the TZC DRAM section
+ * to ensure sufficient storage can be allocated.
+ * Provide an implementation of the accessor method to allow the datastore
+ * details to be retrieved by the SPMC.
+ * The SPMC will take care of initializing the memory region.
+ */
+
+#define PLAT_SPMC_SHMEM_DATASTORE_SIZE 512 * 1024
+
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x4000)
+
 #if SPMC_AT_EL3
 /*
  * Number of Secure Partitions supported.
@@ -129,8 +143,18 @@
 #define PLAT_ARM_NS_IMAGE_BASE		(ARM_DRAM1_BASE + UL(0x8000000))
 
 #if TRANSFER_LIST
-#define FW_HANDOFF_SIZE			0x4000
-#define FW_NS_HANDOFF_BASE		(PLAT_ARM_NS_IMAGE_BASE - FW_HANDOFF_SIZE)
+#define PLAT_ARM_FW_HANDOFF_SIZE	U(0x5000)
+
+#define FW_NS_HANDOFF_BASE		(PLAT_ARM_NS_IMAGE_BASE - PLAT_ARM_FW_HANDOFF_SIZE)
+#define PLAT_ARM_EL3_FW_HANDOFF_BASE	ARM_BL_RAM_BASE
+#define PLAT_ARM_EL3_FW_HANDOFF_LIMIT	PLAT_ARM_EL3_FW_HANDOFF_BASE + PLAT_ARM_FW_HANDOFF_SIZE
+
+#if RESET_TO_BL31
+#define PLAT_ARM_TRANSFER_LIST_DTB_OFFSET	FW_NS_HANDOFF_BASE + TRANSFER_LIST_DTB_OFFSET
+#endif
+
+#else
+#define PLAT_ARM_FW_HANDOFF_SIZE	U(0)
 #endif
 
 /*
@@ -234,7 +258,13 @@ defined(IMAGE_BL2) && MEASURED_BOOT
 /* When ARM_BL31_IN_DRAM is set, BL2 can use almost all of Trusted SRAM. */
 # define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1F000) - FVP_BL2_ROMLIB_OPTIMIZATION)
 #else
-# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x13000) - FVP_BL2_ROMLIB_OPTIMIZATION)
+/**
+ * Default to just under half of SRAM to ensure there's enough room for really
+ * large BL31 build configurations when using the default SRAM size (256 Kb).
+ */
+#define PLAT_ARM_MAX_BL2_SIZE                                               \
+	(((PLAT_ARM_TRUSTED_SRAM_SIZE / 3) & ~PAGE_SIZE_MASK) - PAGE_SIZE - \
+	 FVP_BL2_ROMLIB_OPTIMIZATION)
 #endif
 
 #if RESET_TO_BL31
@@ -249,9 +279,15 @@ defined(IMAGE_BL2) && MEASURED_BOOT
  * BL2 and BL1-RW.
  * Size of the BL31 PROGBITS increases as the SRAM size increases.
  */
+#if TRANSFER_LIST
+#define PLAT_ARM_MAX_BL31_SIZE                              \
+	(PLAT_ARM_TRUSTED_SRAM_SIZE - ARM_SHARED_RAM_SIZE - \
+	 PLAT_ARM_FW_HANDOFF_SIZE - ARM_L0_GPT_SIZE)
+#else
 #define PLAT_ARM_MAX_BL31_SIZE		(PLAT_ARM_TRUSTED_SRAM_SIZE - \
 					 ARM_SHARED_RAM_SIZE - \
 					 ARM_FW_CONFIGS_SIZE - ARM_L0_GPT_SIZE)
+#endif /* TRANSFER_LIST */
 #endif /* RESET_TO_BL31 */
 
 #ifndef __aarch64__
@@ -265,7 +301,9 @@ defined(IMAGE_BL2) && MEASURED_BOOT
  * calculated using the current SP_MIN PROGBITS debug size plus the sizes of
  * BL2 and BL1-RW
  */
-# define PLAT_ARM_MAX_BL32_SIZE		UL(0x3B000)
+# define PLAT_ARM_MAX_BL32_SIZE		(PLAT_ARM_TRUSTED_SRAM_SIZE - \
+					 ARM_SHARED_RAM_SIZE - \
+					 ARM_FW_CONFIGS_SIZE)
 #endif /* RESET_TO_SP_MIN */
 #endif
 
@@ -416,7 +454,7 @@ defined(IMAGE_BL2) && MEASURED_BOOT
 #define PLAT_SDEI_DP_EVENT_MAX_CNT	ARM_SDEI_DP_EVENT_MAX_CNT
 #define PLAT_SDEI_DS_EVENT_MAX_CNT	ARM_SDEI_DS_EVENT_MAX_CNT
 #else
-  #if PLATFORM_TEST_RAS_FFH
+  #if PLATFORM_TEST_RAS_FFH || PLATFORM_TEST_FFH_LSP_RAS_SP
   #define PLAT_ARM_PRIVATE_SDEI_EVENTS \
 	ARM_SDEI_PRIVATE_EVENTS, \
 	SDEI_EXPLICIT_EVENT(5000, SDEI_MAPF_NORMAL), \
diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i
index dc8032f3..077283e4 100644
--- a/plat/arm/board/fvp/jmptbl.i
+++ b/plat/arm/board/fvp/jmptbl.i
@@ -36,7 +36,6 @@ fdt     fdt_get_alias_namelen
 fdt     fdt_get_name
 fdt     fdt_get_alias
 fdt     fdt_node_offset_by_phandle
-fdt     fdt_subnode_offset
 fdt     fdt_add_subnode
 mbedtls mbedtls_asn1_get_alg
 mbedtls mbedtls_asn1_get_alg_null
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 2fdff348..0156b31f 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,89 +7,80 @@
 include common/fdt_wrappers.mk
 
 # Use the GICv3 driver on the FVP by default
-FVP_USE_GIC_DRIVER	:= FVP_GICV3
+FVP_USE_GIC_DRIVER		:= FVP_GICV3
 
 # Default cluster count for FVP
-FVP_CLUSTER_COUNT	:= 2
+FVP_CLUSTER_COUNT		:= 2
 
 # Default number of CPUs per cluster on FVP
 FVP_MAX_CPUS_PER_CLUSTER	:= 4
 
 # Default number of threads per CPU on FVP
-FVP_MAX_PE_PER_CPU	:= 1
+FVP_MAX_PE_PER_CPU		:= 1
 
 # Disable redistributor frame of inactive/fused CPU cores by marking it as read
 # only; enable redistributor frames of all CPU cores by default.
-FVP_GICR_REGION_PROTECTION		:= 0
+FVP_GICR_REGION_PROTECTION	:= 0
 
-FVP_DT_PREFIX		:= fvp-base-gicv3-psci
+FVP_DT_PREFIX			:= fvp-base-gicv3-psci
 
-# Size (in kilobytes) of the Trusted SRAM region to  utilize when building for
+# Size (in kilobytes) of the Trusted SRAM region to  utilize when building for
 # the FVP platform. This option defaults to 256.
-FVP_TRUSTED_SRAM_SIZE	:= 256
+FVP_TRUSTED_SRAM_SIZE		:= 256
 
 # Macro to enable helpers for running SPM tests. Disabled by default.
 PLAT_TEST_SPM	:= 0
 
-# This is a very trickly TEMPORARY fix. Enabling ALL features exceeds BL31's
-# progbits limit. We need a way to build all useful configurations while waiting
-# on the fvp to increase its SRAM size. The problem is twofild:
-#  1. the cleanup that introduced these enables cleaned up tf-a a little too
-#     well and things that previously (incorrectly) were enabled, no longer are.
-#     A bunch of CI configs build subtly incorrectly and this combo makes it
-#     necessary to forcefully and unconditionally enable them here.
-#  2. the progbits limit is exceeded only when the tsp is involved. However,
-#     there are tsp CI configs that run on very high architecture revisions so
-#     disabling everything isn't an option.
-# The fix is to enable everything, as before. When the tsp is included, though,
-# we need to slim the size down. In that case, disable all optional features,
-# that will not be present in CI when the tsp is.
-# Similarly, DRTM support is only tested on v8.0 models. Disable everything just
-# for it.
-# TODO: make all of this unconditional (or only base the condition on
-# ARM_ARCH_* when the makefile supports it).
-ifneq (${DRTM_SUPPORT}, 1)
-ifneq (${SPD}, tspd)
-	ENABLE_FEAT_AMU			:= 2
-	ENABLE_FEAT_AMUv1p1		:= 2
-	ENABLE_FEAT_HCX			:= 2
-	ENABLE_FEAT_RNG			:= 2
-	ENABLE_FEAT_TWED		:= 2
-	ENABLE_FEAT_GCS			:= 2
+# By default dont build CPUs with no FVP model.
+BUILD_CPUS_WITH_NO_FVP_MODEL	?= 0
+
+ENABLE_FEAT_AMU			:= 2
+ENABLE_FEAT_AMUv1p1		:= 2
+ENABLE_FEAT_HCX			:= 2
+ENABLE_FEAT_RNG			:= 2
+ENABLE_FEAT_TWED		:= 2
+ENABLE_FEAT_GCS			:= 2
+
 ifeq (${ARCH}, aarch64)
-ifneq (${SPD}, spmd)
+
 ifeq (${SPM_MM}, 0)
 ifeq (${CTX_INCLUDE_FPREGS}, 0)
-	ENABLE_SME_FOR_NS		:= 2
-	ENABLE_SME2_FOR_NS		:= 2
-endif
-endif
-endif
+      ENABLE_SME_FOR_NS		:= 2
+      ENABLE_SME2_FOR_NS	:= 2
+else
+      ENABLE_SVE_FOR_NS		:= 0
+      ENABLE_SME_FOR_NS		:= 0
+      ENABLE_SME2_FOR_NS	:= 0
 endif
 endif
 
-# enable unconditionally for all builds
-ifeq (${ARCH}, aarch64)
-    ENABLE_BRBE_FOR_NS		:= 2
-    ENABLE_TRBE_FOR_NS		:= 2
+      ENABLE_BRBE_FOR_NS	:= 2
+      ENABLE_TRBE_FOR_NS	:= 2
+      ENABLE_FEAT_D128		:= 2
 endif
+
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_FEAT_CSV2_2		:= 2
+ENABLE_FEAT_CSV2_3		:= 2
+ENABLE_FEAT_DEBUGV8P9		:= 2
 ENABLE_FEAT_DIT			:= 2
 ENABLE_FEAT_PAN			:= 2
-ENABLE_FEAT_MTE_PERM		:= 2
 ENABLE_FEAT_VHE			:= 2
 CTX_INCLUDE_NEVE_REGS		:= 2
 ENABLE_FEAT_SEL2		:= 2
 ENABLE_TRF_FOR_NS		:= 2
 ENABLE_FEAT_ECV			:= 2
 ENABLE_FEAT_FGT			:= 2
+ENABLE_FEAT_FGT2		:= 2
+ENABLE_FEAT_THE			:= 2
 ENABLE_FEAT_TCR2		:= 2
 ENABLE_FEAT_S2PIE		:= 2
 ENABLE_FEAT_S1PIE		:= 2
 ENABLE_FEAT_S2POE		:= 2
 ENABLE_FEAT_S1POE		:= 2
-endif
+ENABLE_FEAT_SCTLR2		:= 2
+ENABLE_FEAT_MTE2		:= 2
+ENABLE_FEAT_LS64_ACCDATA	:= 2
 
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))
@@ -205,21 +196,31 @@ else
 					lib/cpus/aarch64/cortex_a78_ae.S	\
 					lib/cpus/aarch64/cortex_a78c.S		\
 					lib/cpus/aarch64/cortex_a710.S		\
+					lib/cpus/aarch64/cortex_a715.S		\
+					lib/cpus/aarch64/cortex_a720.S		\
+					lib/cpus/aarch64/cortex_a720_ae.S	\
 					lib/cpus/aarch64/neoverse_n_common.S	\
 					lib/cpus/aarch64/neoverse_n1.S		\
 					lib/cpus/aarch64/neoverse_n2.S		\
 					lib/cpus/aarch64/neoverse_v1.S		\
 					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/cortex_x2.S		\
-					lib/cpus/aarch64/cortex_gelas.S		\
-					lib/cpus/aarch64/nevis.S		\
-					lib/cpus/aarch64/travis.S
+					lib/cpus/aarch64/cortex_x4.S
 	endif
 	# AArch64/AArch32 cores
 	FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S		\
 				lib/cpus/aarch64/cortex_a75.S
 endif
 
+#Build AArch64-only CPUs with no FVP model yet.
+ifeq (${BUILD_CPUS_WITH_NO_FVP_MODEL},1)
+	FVP_CPU_LIBS    +=	lib/cpus/aarch64/neoverse_n3.S		\
+				lib/cpus/aarch64/cortex_gelas.S		\
+				lib/cpus/aarch64/nevis.S		\
+				lib/cpus/aarch64/travis.S		\
+				lib/cpus/aarch64/cortex_arcadia.S
+endif
+
 else
 FVP_CPU_LIBS		+=	lib/cpus/aarch32/cortex_a32.S			\
 				lib/cpus/aarch32/cortex_a57.S			\
@@ -234,8 +235,10 @@ BL1_SOURCES		+=	drivers/arm/smmu/smmu_v3.c			\
 				lib/semihosting/${ARCH}/semihosting_call.S	\
 				plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
 				plat/arm/board/fvp/fvp_bl1_setup.c		\
+				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/board/fvp/fvp_err.c			\
 				plat/arm/board/fvp/fvp_io_storage.c		\
+				plat/arm/board/fvp/fvp_topology.c		\
 				${FVP_CPU_LIBS}					\
 				${FVP_INTERCONNECT_SOURCES}
 
@@ -263,10 +266,12 @@ BL2_SOURCES		+=	plat/arm/common/fconf/fconf_nv_cntr_getter.c
 endif
 
 ifeq (${ENABLE_RME},1)
-BL2_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S
+BL2_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S	\
+				plat/arm/board/fvp/fvp_cpu_pwr.c
 
 BL31_SOURCES		+=	plat/arm/board/fvp/fvp_plat_attest_token.c	\
-				plat/arm/board/fvp/fvp_realm_attest_key.c
+				plat/arm/board/fvp/fvp_realm_attest_key.c	\
+				plat/arm/board/fvp/fvp_el3_token_sign.c
 endif
 
 ifeq (${ENABLE_FEAT_RNG_TRAP},1)
@@ -275,6 +280,7 @@ endif
 
 ifeq (${RESET_TO_BL2},1)
 BL2_SOURCES		+=	plat/arm/board/fvp/${ARCH}/fvp_helpers.S	\
+				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/board/fvp/fvp_bl2_el3_setup.c		\
 				${FVP_CPU_LIBS}					\
 				${FVP_INTERCONNECT_SOURCES}
@@ -301,6 +307,7 @@ BL31_SOURCES		+=	drivers/arm/fvp/fvp_pwrc.c			\
 				plat/arm/board/fvp/fvp_pm.c			\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/aarch64/fvp_helpers.S	\
+				plat/arm/board/fvp/fvp_cpu_pwr.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
 				${FVP_CPU_LIBS}					\
 				${FVP_GIC_SOURCES}				\
@@ -330,7 +337,17 @@ endif
 
 # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
 ifdef UNIX_MK
+FVP_TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 FVP_HW_CONFIG_DTS	:=	fdts/${FVP_DT_PREFIX}.dts
+
+FDT_SOURCES		+=	${FVP_HW_CONFIG_DTS}
+$(eval FVP_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS)))
+
+ifeq (${TRANSFER_LIST}, 1)
+FDT_SOURCES		+=	$(addprefix plat/arm/board/fvp/fdts/,	\
+					${PLAT}_tb_fw_config.dts	\
+				)
+else
 FDT_SOURCES		+=	$(addprefix plat/arm/board/fvp/fdts/,	\
 					${PLAT}_fw_config.dts		\
 					${PLAT}_tb_fw_config.dts	\
@@ -339,7 +356,6 @@ FDT_SOURCES		+=	$(addprefix plat/arm/board/fvp/fdts/,	\
 				)
 
 FVP_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
-FVP_TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
 FVP_SOC_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb
 FVP_NT_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
@@ -351,10 +367,6 @@ FVP_TOS_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tsp_fw_config.dtb
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG}))
 endif
 
-ifeq (${TRANSFER_LIST}, 1)
-include lib/transfer_list/transfer_list.mk
-endif
-
 ifeq (${SPD},spmd)
 
 ifeq ($(ARM_SPMC_MANIFEST_DTS),)
@@ -370,20 +382,30 @@ endif
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_FW_CONFIG},--fw-config,${FVP_FW_CONFIG}))
-# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
 # Add the SOC_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config,${FVP_SOC_FW_CONFIG}))
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
+endif
 
-FDT_SOURCES		+=	${FVP_HW_CONFIG_DTS}
-$(eval FVP_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS)))
-
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config,${FVP_TB_FW_CONFIG}))
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_HW_CONFIG},--hw-config,${FVP_HW_CONFIG}))
 endif
 
+ifeq (${TRANSFER_LIST}, 1)
+include lib/transfer_list/transfer_list.mk
+
+ifeq ($(RESET_TO_BL31), 1)
+HW_CONFIG			:=	${FVP_HW_CONFIG}
+FW_HANDOFF_SIZE			:=	20000
+
+TRANSFER_LIST_DTB_OFFSET	:=	0x20
+$(eval $(call add_define,TRANSFER_LIST_DTB_OFFSET))
+endif
+endif
+
 # Enable dynamic mitigation support by default
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
@@ -398,11 +420,15 @@ endif
 endif
 
 ifeq (${HANDLE_EA_EL3_FIRST_NS},1)
-ifeq (${ENABLE_FEAT_RAS},1)
-BL31_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_ras.c
-else
-BL31_SOURCES		+= 	plat/arm/board/fvp/aarch64/fvp_ea.c
-endif
+    ifeq (${ENABLE_FEAT_RAS},1)
+    	ifeq (${PLATFORM_TEST_FFH_LSP_RAS_SP},1)
+            BL31_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_lsp_ras_sp.c
+	else
+            BL31_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_ras.c
+	endif
+    else
+        BL31_SOURCES		+= 	plat/arm/board/fvp/aarch64/fvp_ea.c
+    endif
 endif
 
 ifneq (${ENABLE_STACK_PROTECTOR},0)
@@ -440,26 +466,6 @@ ifneq (${RESET_TO_BL2}, 0)
     override BL1_SOURCES =
 endif
 
-# RSS is not supported on FVP right now. Thus, we use the mocked version
-# of the provided PSA APIs. They return with success and hard-coded token/key.
-PLAT_RSS_NOT_SUPPORTED	:= 1
-
-# Include Measured Boot makefile before any Crypto library makefile.
-# Crypto library makefile may need default definitions of Measured Boot build
-# flags present in Measured Boot makefile.
-ifeq (${MEASURED_BOOT},1)
-    RSS_MEASURED_BOOT_MK := drivers/measured_boot/rss/rss_measured_boot.mk
-    $(info Including ${RSS_MEASURED_BOOT_MK})
-    include ${RSS_MEASURED_BOOT_MK}
-
-    ifneq (${MBOOT_RSS_HASH_ALG}, sha256)
-        $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
-    endif
-
-    BL1_SOURCES		+=	${MEASURED_BOOT_SOURCES}
-    BL2_SOURCES		+=	${MEASURED_BOOT_SOURCES}
-endif
-
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
 
@@ -471,23 +477,6 @@ BL1_SOURCES		+=	plat/arm/board/fvp/fvp_common_measured_boot.c	\
 BL2_SOURCES		+=	plat/arm/board/fvp/fvp_common_measured_boot.c	\
 				plat/arm/board/fvp/fvp_bl2_measured_boot.c	\
 				lib/psa/measured_boot.c
-
-# Even though RSS is not supported on FVP (see above), we support overriding
-# PLAT_RSS_NOT_SUPPORTED from the command line, just for the purpose of building
-# the code to detect any build regressions. The resulting firmware will not be
-# functional.
-ifneq (${PLAT_RSS_NOT_SUPPORTED},1)
-    $(warning "RSS is not supported on FVP. The firmware will not be functional.")
-    include drivers/arm/rss/rss_comms.mk
-    BL1_SOURCES		+=	${RSS_COMMS_SOURCES}
-    BL2_SOURCES		+=	${RSS_COMMS_SOURCES}
-    BL31_SOURCES	+=	${RSS_COMMS_SOURCES}
-
-    BL1_CFLAGS		+=	-DPLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0
-    BL2_CFLAGS		+=	-DPLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0
-    BL31_CFLAGS		+=	-DPLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0
-endif
-
 endif
 
 ifeq (${DRTM_SUPPORT}, 1)
@@ -538,6 +527,22 @@ ifeq (${PLATFORM_TEST_RAS_FFH}, 1)
     endif
 endif
 
+$(eval $(call add_define,PLATFORM_TEST_FFH_LSP_RAS_SP))
+ifeq (${PLATFORM_TEST_FFH_LSP_RAS_SP}, 1)
+    ifeq (${PLATFORM_TEST_RAS_FFH}, 1)
+         $(error "PLATFORM_TEST_RAS_FFH is incompatible with PLATFORM_TEST_FFH_LSP_RAS_SP")
+    endif
+    ifeq (${ENABLE_SPMD_LP}, 0)
+         $(error "PLATFORM_TEST_FFH_LSP_RAS_SP expects ENABLE_SPMD_LP to be 1")
+    endif
+    ifeq (${ENABLE_FEAT_RAS}, 0)
+         $(error "PLATFORM_TEST_FFH_LSP_RAS_SP expects ENABLE_FEAT_RAS to be 1")
+    endif
+    ifeq (${HANDLE_EA_EL3_FIRST_NS}, 0)
+         $(error "PLATFORM_TEST_FFH_LSP_RAS_SP expects HANDLE_EA_EL3_FIRST_NS to be 1")
+    endif
+endif
+
 ifeq (${ERRATA_ABI_SUPPORT}, 1)
 include plat/arm/board/fvp/fvp_cpu_errata.mk
 endif
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_main.c b/plat/arm/board/fvp_r/fvp_r_bl1_main.c
index 252fc31f..6fe2b5b3 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_main.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,7 @@
 #include <arch_helpers.h>
 #include <bl1/bl1.h>
 #include <common/bl_common.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <drivers/auth/auth_mod.h>
 #include <drivers/console.h>
@@ -91,27 +92,6 @@ void bl1_load_bl33(void)
 	NOTICE("BL1: Booting BL33\n");
 }
 
-/*******************************************************************************
- * Helper utility to calculate the BL2 memory layout taking into consideration
- * the BL1 RW data assuming that it is at the top of the memory layout.
- ******************************************************************************/
-void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
-			meminfo_t *bl2_mem_layout)
-{
-	assert(bl1_mem_layout != NULL);
-	assert(bl2_mem_layout != NULL);
-
-	/*
-	 * Remove BL1 RW data from the scope of memory visible to BL2.
-	 * This is assuming BL1 RW data is at the top of bl1_mem_layout.
-	 */
-	assert(bl1_mem_layout->total_base < BL1_RW_BASE);
-	bl2_mem_layout->total_base = bl1_mem_layout->total_base;
-	bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base;
-
-	flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t));
-}
-
 /*******************************************************************************
  * This function prepares for entry to BL33
  ******************************************************************************/
@@ -182,7 +162,7 @@ void bl1_main(void)
 
 	/* Announce our arrival */
 	NOTICE(FIRMWARE_WELCOME_STR);
-	NOTICE("BL1: %s\n", version_string);
+	NOTICE("BL1: %s\n", build_version_string);
 	NOTICE("BL1: %s\n", build_message);
 
 	INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT);
@@ -265,4 +245,3 @@ void print_debug_loop_message(void)
 	NOTICE("BL1: Please connect the debugger to continue\n");
 }
 #endif
-
diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
index 6a7c0c80..dcf5e046 100644
--- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
+++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -235,7 +235,7 @@ int bl1_plat_handle_post_image_load(unsigned int image_id)
 	 */
 	bl33_secram_layout = (meminfo_t *) bl1_secram_layout->total_base;
 
-	bl1_calc_bl2_mem_layout(bl1_secram_layout, bl33_secram_layout);
+	bl1_plat_calc_bl2_layout(bl1_secram_layout, bl33_secram_layout);
 
 	ep_info->args.arg1 = (uintptr_t)bl33_secram_layout;
 
diff --git a/plat/arm/board/fvp_r/include/platform_def.h b/plat/arm/board/fvp_r/include/platform_def.h
index ea3a258f..1fdec150 100644
--- a/plat/arm/board/fvp_r/include/platform_def.h
+++ b/plat/arm/board/fvp_r/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -75,13 +75,6 @@
 #define PLAT_BL1_RO_LIMIT               (BL1_RO_BASE \
 					+ PLAT_ARM_TRUSTED_ROM_SIZE)
 
-#define PLAT_ARM_SYS_CNTCTL_BASE	UL(0xaa430000)
-#define PLAT_ARM_SYS_CNTREAD_BASE	UL(0xaa800000)
-#define PLAT_ARM_SYS_TIMCTL_BASE	UL(0xaa810000)
-#define PLAT_ARM_SYS_CNT_BASE_S		UL(0xaa820000)
-#define PLAT_ARM_SYS_CNT_BASE_NS	UL(0xaa830000)
-#define PLAT_ARM_SP805_TWDG_BASE	UL(0xaa490000)
-
 /* virtual address used by dynamic mem_protect for chunk_base */
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
 
@@ -90,11 +83,11 @@
 
 #define PLAT_ARM_DRAM2_SIZE		UL(0x80000000)
 
-#define PLAT_HW_CONFIG_DTB_SIZE		ULL(0x8000)
+#define PLAT_ARM_HW_CONFIG_SIZE		ULL(0x8000)
 
 #define ARM_DTB_DRAM_NS			MAP_REGION_FLAT(		\
 					PLAT_HW_CONFIG_DTB_BASE,	\
-					PLAT_HW_CONFIG_DTB_SIZE,	\
+					PLAT_ARM_HW_CONFIG_SIZE,	\
 					MT_MEMORY | MT_RO | MT_NS)
 
 #define V2M_FVP_R_SYSREGS_BASE		UL(0x9c010000)
diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk
index f14ea544..71cb9e2d 100644
--- a/plat/arm/board/fvp_r/platform.mk
+++ b/plat/arm/board/fvp_r/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -25,7 +25,7 @@ FVP_R_INTERCONNECT_SOURCES	:= 	drivers/arm/cci/cci.c
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
 
-PLAT_INCLUDES		:=	-Iplat/arm/board/fvp_r/include
+PLAT_INCLUDES		+=	-Iplat/arm/board/fvp_r/include
 
 FVP_R_BL_COMMON_SOURCES	:=	plat/arm/board/fvp_r/fvp_r_common.c		\
 				plat/arm/board/fvp_r/fvp_r_context_mgmt.c	\
diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
index 6e5691bd..422ef40f 100644
--- a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
+++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 
@@ -20,7 +21,7 @@
 
 		hw-config {
 			load-address = <0x0 0x82000000>;
-			max-size = <0x01000000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
 	};
diff --git a/plat/arm/board/fvp_ve/fvp_ve_def.h b/plat/arm/board/fvp_ve/fvp_ve_def.h
index 98de5f66..cb4b74c2 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_def.h
+++ b/plat/arm/board/fvp_ve/fvp_ve_def.h
@@ -70,15 +70,4 @@
 #define FVP_VE_IRQ_TZ_WDOG			56
 #define FVP_VE_IRQ_SEC_SYS_TIMER		57
 
-#define V2M_FLASH1_BASE			UL(0x0C000000)
-#define V2M_FLASH1_SIZE			UL(0x04000000)
-
-#define V2M_MAP_FLASH1_RW		MAP_REGION_FLAT(V2M_FLASH1_BASE,\
-						V2M_FLASH1_SIZE,	\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#define V2M_MAP_FLASH1_RO		MAP_REGION_FLAT(V2M_FLASH1_BASE,\
-						V2M_FLASH1_SIZE,	\
-						MT_RO_DATA | MT_SECURE)
-
 #endif /* FVP_VE_DEF_H */
diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h
index bd8ef6af..e09ea02e 100644
--- a/plat/arm/board/fvp_ve/include/platform_def.h
+++ b/plat/arm/board/fvp_ve/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -158,6 +158,9 @@
 #define PLAT_PHY_ADDR_SPACE_SIZE			(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE			(1ULL << 32)
 
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x01000000)
+
 /*
  * This macro defines the deepest retention state possible. A higher state
  * id will represent an invalid or a power down state.
diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts
index 2d79ac7a..11e95741 100644
--- a/plat/arm/board/juno/fdts/juno_fw_config.dts
+++ b/plat/arm/board/juno/fdts/juno_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2019-2023, ARM Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 
@@ -20,7 +21,7 @@
 
 		hw-config {
 			load-address = <0x0 0x82000000>;
-			max-size = <0x8000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
 	};
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 5c9a7a3a..777729ef 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,6 +36,9 @@
  * Other platform porting definitions are provided by included headers
  */
 
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x8000)
+
 /*
  * Required ARM standard platform porting definitions
  */
@@ -246,12 +249,14 @@
 /* MHU related constants */
 #define PLAT_CSS_MHU_BASE		UL(0x2b1f0000)
 
+#if CSS_USE_SCMI_SDS_DRIVER
+/* Index of SDS region used in the communication between AP and SCP */
+#define SDS_SCP_AP_REGION_ID			U(0)
+#else
 /*
  * Base address of the first memory region used for communication between AP
  * and SCP. Used by the BOM and SCPI protocols.
- */
-#if !CSS_USE_SCMI_SDS_DRIVER
-/*
+ *
  * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which
  * means the SCP/AP configuration data gets overwritten when the AP initiates
  * communication with the SCP. The configuration data is expected to be a
@@ -261,7 +266,7 @@
 #define PLAT_CSS_SCP_COM_SHARED_MEM_BASE	(ARM_TRUSTED_SRAM_BASE + UL(0x80))
 #define PLAT_CSS_PRIMARY_CPU_SHIFT		8
 #define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH		4
-#endif
+#endif /* CSS_USE_SCMI_SDS_DRIVER */
 
 /*
  * SCP_BL2 uses up whatever remaining space is available as it is loaded before
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index a9d5cc37..2bc948d6 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,13 +32,14 @@ static int is_watchdog_reset(void)
 	int ret;
 	uint32_t scp_reset_synd_flags;
 
-	ret = sds_init();
+	ret = sds_init(SDS_SCP_AP_REGION_ID);
 	if (ret != SDS_OK) {
 		ERROR("SCP SDS initialization failed\n");
 		panic();
 	}
 
-	ret = sds_struct_read(SDS_RESET_SYNDROME_STRUCT_ID,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+					SDS_RESET_SYNDROME_STRUCT_ID,
 					SDS_RESET_SYNDROME_OFFSET,
 					&scp_reset_synd_flags,
 					SDS_RESET_SYNDROME_SIZE,
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index 02614da4..2cd01e41 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -1,14 +1,16 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <drivers/arm/css/sds.h>
 #include <lib/smccc.h>
-#include <platform_def.h>
+#include <lib/utils_def.h>
 #include <services/arm_arch_svc.h>
 
 #include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
 
 /*
  * Table of memory regions for different BL stages to map using the MMU.
@@ -138,3 +140,16 @@ int32_t plat_get_soc_revision(void)
 	return (int32_t)(((sys_id >> V2M_SYS_ID_REV_SHIFT) &
 			  V2M_SYS_ID_REV_MASK) & SOC_ID_REV_MASK);
 }
+
+#if CSS_USE_SCMI_SDS_DRIVER
+static sds_region_desc_t juno_sds_regions[] = {
+	{ .base = PLAT_ARM_SDS_MEM_BASE },
+};
+
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
+{
+	*region_count = ARRAY_SIZE(juno_sds_regions);
+
+	return juno_sds_regions;
+}
+#endif /* CSS_USE_SCMI_SDS_DRIVER */
diff --git a/plat/arm/board/juno/juno_tbbr_cot_bl2.c b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
index 8930dbbd..d001dbe6 100644
--- a/plat/arm/board/juno/juno_tbbr_cot_bl2.c
+++ b/plat/arm/board/juno/juno_tbbr_cot_bl2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -745,6 +745,21 @@ static const auth_img_desc_t npu_fw_image = {
 };
 #endif /* ETHOSN_NPU_TZMP1 */
 
+/* HW Config */
+static const auth_img_desc_t hw_config = {
+	.img_id = HW_CONFIG_ID,
+	.img_type = IMG_RAW,
+	.parent = &trusted_boot_fw_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_HASH,
+			.param.hash = {
+				.data = &raw_data,
+				.hash = &hw_config_hash
+			}
+		}
+	}
+};
 
 static const auth_img_desc_t * const cot_desc[] = {
 	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index a00bf261..8eca0c5e 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -134,7 +134,7 @@ all : bl1_romlib.bin
 endif
 
 bl1_romlib.bin : $(BUILD_PLAT)/bl1.bin romlib.bin
-	@echo "Building combined BL1 and ROMLIB binary for Juno $@"
+	$(s)echo "Building combined BL1 and ROMLIB binary for Juno $@"
 	./lib/romlib/gen_combined_bl1_romlib.sh -o bl1_romlib.bin $(BUILD_PLAT)
 
 # Errata workarounds for Cortex-A53:
diff --git a/plat/arm/board/morello/fdts/morello_fw_config.dts b/plat/arm/board/morello/fdts/morello_fw_config.dts
index a63d7eb1..a93d6c43 100644
--- a/plat/arm/board/morello/fdts/morello_fw_config.dts
+++ b/plat/arm/board/morello/fdts/morello_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 / {
@@ -25,7 +26,7 @@
 
 		hw-config {
 			load-address = <0x0 0xFEFF8000>;
-			max-size = <0x8000>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
 	};
diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h
index 993aa468..7ec89db2 100644
--- a/plat/arm/board/morello/include/platform_def.h
+++ b/plat/arm/board/morello/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -59,6 +59,10 @@
 
 #if CSS_USE_SCMI_SDS_DRIVER
 #define MORELLO_SCMI_PAYLOAD_BASE		ULL(0x45400000)
+/*
+ * Index of SDS region used in the communication with SCP
+ */
+#define SDS_SCP_AP_REGION_ID			U(0)
 #else
 #define PLAT_CSS_SCP_COM_SHARED_MEM_BASE	ULL(0x45400000)
 #endif
@@ -71,6 +75,9 @@
  */
 #define PLAT_ARM_MAX_BL1_RW_SIZE		UL(0xC000)
 
+/* Define memory configuration for device tree files. */
+#define PLAT_ARM_HW_CONFIG_SIZE			U(0x8000)
+
 /*
  * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
  */
diff --git a/plat/arm/board/morello/morello_bl2_setup.c b/plat/arm/board/morello/morello_bl2_setup.c
index 39020e23..38e2e6a2 100644
--- a/plat/arm/board/morello/morello_bl2_setup.c
+++ b/plat/arm/board/morello/morello_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -155,13 +155,14 @@ void bl2_platform_setup(void)
 	int ret;
 	struct morello_plat_info plat_info;
 
-	ret = sds_init();
+	ret = sds_init(SDS_SCP_AP_REGION_ID);
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed. ret:%d\n", ret);
 		panic();
 	}
 
-	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+				MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
 				&plat_info,
 				MORELLO_SDS_PLATFORM_INFO_SIZE,
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
index 8469cd13..63738255 100644
--- a/plat/arm/board/morello/morello_bl31_setup.c
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,13 +43,14 @@ void bl31_platform_setup(void)
 #ifdef TARGET_PLATFORM_SOC
 	int ret;
 
-	ret = sds_init();
+	ret = sds_init(SDS_SCP_AP_REGION_ID);
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed. ret:%d\n", ret);
 		panic();
 	}
 
-	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+				MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
 				&plat_info,
 				MORELLO_SDS_PLATFORM_INFO_SIZE,
diff --git a/plat/arm/board/morello/morello_image_load.c b/plat/arm/board/morello/morello_image_load.c
index 4ea2bb30..b9590319 100644
--- a/plat/arm/board/morello/morello_image_load.c
+++ b/plat/arm/board/morello/morello_image_load.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <common/desc_image_load.h>
 #include <drivers/arm/css/sds.h>
@@ -13,6 +14,7 @@
 #include "morello_def.h"
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 
 /* In client mode, a part of the DDR memory is reserved for Tag bits.
  * Calculate the usable memory size after subtracting the Tag memory.
@@ -141,7 +143,7 @@ static int plat_morello_append_config_node(struct morello_plat_info *plat_info,
 		return -1;
 	}
 
-	err = fdt_setprop_string(fdt, nodeoffset_fw, "tfa-fw-version", version_string);
+	err = fdt_setprop_string(fdt, nodeoffset_fw, "tfa-fw-version", build_version_string);
 	if (err < 0) {
 		WARN("NT_FW_CONFIG: Unable to set tfa-fw-version\n");
 	}
@@ -167,13 +169,14 @@ bl_params_t *plat_get_next_bl_params(void)
 	struct morello_plat_info plat_info;
 	struct morello_firmware_version fw_version;
 
-	ret = sds_init();
+	ret = sds_init(SDS_SCP_AP_REGION_ID);
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed. ret:%d\n", ret);
 		panic();
 	}
 
-	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+				MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
 				&plat_info,
 				MORELLO_SDS_PLATFORM_INFO_SIZE,
@@ -183,7 +186,8 @@ bl_params_t *plat_get_next_bl_params(void)
 		panic();
 	}
 
-	ret = sds_struct_read(MORELLO_SDS_FIRMWARE_VERSION_STRUCT_ID,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+				MORELLO_SDS_FIRMWARE_VERSION_STRUCT_ID,
 				MORELLO_SDS_FIRMWARE_VERSION_OFFSET,
 				&fw_version,
 				MORELLO_SDS_FIRMWARE_VERSION_SIZE,
diff --git a/plat/arm/board/morello/morello_plat.c b/plat/arm/board/morello/morello_plat.c
index 2ca3d08c..61fed642 100644
--- a/plat/arm/board/morello/morello_plat.c
+++ b/plat/arm/board/morello/morello_plat.c
@@ -1,12 +1,14 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 
+#include <drivers/arm/css/sds.h>
 #include <drivers/arm/sbsa.h>
+#include <lib/utils_def.h>
 #include <plat/arm/common/plat_arm.h>
 
 #include "morello_def.h"
@@ -68,3 +70,16 @@ void plat_arm_secure_wdt_stop(void)
 {
 	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
 }
+
+#if CSS_USE_SCMI_SDS_DRIVER
+static sds_region_desc_t morello_sds_regions[] = {
+	{ .base = PLAT_ARM_SDS_MEM_BASE },
+};
+
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
+{
+	*region_count = ARRAY_SIZE(morello_sds_regions);
+
+	return morello_sds_regions;
+}
+#endif /* CSS_USE_SCMI_SDS_DRIVER */
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 74d0c911..eb878edb 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,9 +19,6 @@
 #define PLAT_ARM_RUN_UART_BASE			0x1C090000
 #define PLAT_ARM_RUN_UART_CLK_IN_HZ		24000000
 
-#define PLAT_ARM_SP_MIN_RUN_UART_BASE		0x2A410000
-#define PLAT_ARM_SP_MIN_RUN_UART_CLK_IN_HZ	50000000
-
 #define PLAT_ARM_CRASH_UART_BASE		PLAT_ARM_RUN_UART_BASE
 #define PLAT_ARM_CRASH_UART_CLK_IN_HZ		PLAT_ARM_RUN_UART_CLK_IN_HZ
 
@@ -77,6 +74,10 @@
 
 #if CSS_USE_SCMI_SDS_DRIVER
 #define N1SDP_SCMI_PAYLOAD_BASE			0x45400000
+/*
+ * Index of SDS region used in the communication with SCP
+ */
+#define SDS_SCP_AP_REGION_ID			U(0)
 #else
 #define PLAT_CSS_SCP_COM_SHARED_MEM_BASE	0x45400000
 #endif
diff --git a/plat/arm/board/n1sdp/n1sdp_bl2_setup.c b/plat/arm/board/n1sdp/n1sdp_bl2_setup.c
index 5f8af9f3..5a5b9a5f 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl2_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 
 #include "n1sdp_def.h"
 #include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
 
 struct n1sdp_plat_info {
 	bool multichip_mode;
@@ -60,13 +61,14 @@ void bl2_platform_setup(void)
 	int ret;
 	struct n1sdp_plat_info plat_info;
 
-	ret = sds_init();
+	ret = sds_init(SDS_SCP_AP_REGION_ID);
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed\n");
 		panic();
 	}
 
-	ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+				N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
 				N1SDP_SDS_PLATFORM_INFO_OFFSET,
 				&plat_info,
 				N1SDP_SDS_PLATFORM_INFO_SIZE,
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index 430aab68..27ea7f7d 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -127,13 +127,14 @@ void bl31_platform_setup(void)
 	int ret;
 	struct n1sdp_plat_info plat_info;
 
-	ret = sds_init();
+	ret = sds_init(SDS_SCP_AP_REGION_ID);
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed\n");
 		panic();
 	}
 
-	ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+				N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
 				N1SDP_SDS_PLATFORM_INFO_OFFSET,
 				&plat_info,
 				N1SDP_SDS_PLATFORM_INFO_SIZE,
diff --git a/plat/arm/board/n1sdp/n1sdp_image_load.c b/plat/arm/board/n1sdp/n1sdp_image_load.c
index 6c3528ce..6ae2b262 100644
--- a/plat/arm/board/n1sdp/n1sdp_image_load.c
+++ b/plat/arm/board/n1sdp/n1sdp_image_load.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 
 #include "n1sdp_def.h"
 #include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
 
 /*
  * Platform information structure stored in SDS.
@@ -108,13 +109,14 @@ bl_params_t *plat_get_next_bl_params(void)
 	int ret;
 	struct n1sdp_plat_info plat_info;
 
-	ret = sds_init();
+	ret = sds_init(SDS_SCP_AP_REGION_ID);
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed. ret:%d\n", ret);
 		panic();
 	}
 
-	ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+				N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
 				N1SDP_SDS_PLATFORM_INFO_OFFSET,
 				&plat_info,
 				N1SDP_SDS_PLATFORM_INFO_SIZE,
diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
index 747ff068..42efdeef 100644
--- a/plat/arm/board/n1sdp/n1sdp_plat.c
+++ b/plat/arm/board/n1sdp/n1sdp_plat.c
@@ -1,12 +1,14 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 
+#include <drivers/arm/css/sds.h>
 #include <drivers/arm/sbsa.h>
+#include <lib/utils_def.h>
 #include <plat/arm/common/plat_arm.h>
 
 #include "n1sdp_def.h"
@@ -71,3 +73,16 @@ void plat_arm_secure_wdt_stop(void)
 {
 	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
 }
+
+#if CSS_USE_SCMI_SDS_DRIVER
+static sds_region_desc_t n1sdp_sds_regions[] = {
+	{ .base = PLAT_ARM_SDS_MEM_BASE },
+};
+
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
+{
+	*region_count = ARRAY_SIZE(n1sdp_sds_regions);
+
+	return n1sdp_sds_regions;
+}
+#endif /* CSS_USE_SCMI_SDS_DRIVER */
diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/board/neoverse_rd/common/arch/aarch64/nrd_helper.S
similarity index 84%
rename from plat/arm/css/sgi/aarch64/sgi_helper.S
rename to plat/arm/board/neoverse_rd/common/arch/aarch64/nrd_helper.S
index ced59e8d..8d9c0d71 100644
--- a/plat/arm/css/sgi/aarch64/sgi_helper.S
+++ b/plat/arm/board/neoverse_rd/common/arch/aarch64/nrd_helper.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,15 +21,15 @@
 	 *
 	 * Helper function to calculate the core position.
 	 * (ChipId * PLAT_ARM_CLUSTER_COUNT *
-	 *  CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
-	 * (ClusterId * CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU) +
-	 * (CPUId * CSS_SGI_MAX_PE_PER_CPU) +
+	 *  NRD_MAX_CPUS_PER_CLUSTER * NRD_MAX_PE_PER_CPU) +
+	 * (ClusterId * NRD_MAX_CPUS_PER_CLUSTER * NRD_MAX_PE_PER_CPU) +
+	 * (CPUId * NRD_MAX_PE_PER_CPU) +
 	 * ThreadId
 	 *
 	 * which can be simplified as:
 	 *
 	 * ((((ChipId * PLAT_ARM_CLUSTER_COUNT) + ClusterId) *
-	 *   CSS_SGI_MAX_CPUS_PER_CLUSTER) + CPUId) * CSS_SGI_MAX_PE_PER_CPU +
+	 *   NRD_MAX_CPUS_PER_CLUSTER) + CPUId) * NRD_MAX_PE_PER_CPU +
 	 * ThreadId
 	 * ------------------------------------------------------
 	 */
@@ -38,7 +38,7 @@ func plat_arm_calc_core_pos
 	mov	x4, x0
 
 	/*
-	 * The MT bit in MPIDR is always set for SGI platforms
+	 * The MT bit in MPIDR is always set for Neoverse RD platforms
 	 * and the affinity level 0 corresponds to thread affinity level.
 	 */
 
@@ -51,9 +51,9 @@ func plat_arm_calc_core_pos
 	/* Compute linear position */
 	mov     x4, #PLAT_ARM_CLUSTER_COUNT
 	madd    x2, x3, x4, x2
-	mov     x4, #CSS_SGI_MAX_CPUS_PER_CLUSTER
+	mov     x4, #NRD_MAX_CPUS_PER_CLUSTER
 	madd    x1, x2, x4, x1
-	mov     x4, #CSS_SGI_MAX_PE_PER_CPU
+	mov     x4, #NRD_MAX_PE_PER_CPU
 	madd    x0, x1, x4, x0
 	ret
 endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_def1.h
new file mode 100644
index 00000000..74835f69
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_def1.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the CSS specific memory and interrupt map
+ * definitions for the first generation platforms based on the A75, N1 and V1
+ * CPUs. There are minor differences in the memory map of these platforms and
+ * those differences are not in the scope of this file.
+ */
+
+#ifndef NRD_CSS_DEF1_H
+#define NRD_CSS_DEF1_H
+
+/*******************************************************************************
+ * CSS memory map related defines
+ ******************************************************************************/
+
+/* On-Chip ROM */
+#define NRD_CSS_TRUSTED_ROM_BASE	UL(0x00000000)
+#define NRD_CSS_TRUSTED_ROM_SIZE	UL(0x00080000)	/* 512KB */
+
+/* On-Chip RAM */
+#define	NRD_CSS_TRUSTED_SRAM_SIZE	UL(0x00080000)	/* 512KB */
+#define NRD_CSS_NONTRUSTED_SRAM_BASE	UL(0x06000000)
+#define NRD_CSS_NONTRUSTED_SRAM_SIZE	UL(0x00080000)	/* 512KB */
+
+/* PL011 UART */
+#define NRD_CSS_SEC_UART_BASE		UL(0x2A410000)
+#define NRD_CSS_UART_SIZE		UL(0x10000)
+
+/* CSS peripherals */
+#define NRD_CSS_PERIPH_BASE		UL(0x20000000)
+#define NRD_CSS_PERIPH_SIZE		UL(0x40000000)
+
+/* Secure Watchdog */
+#define NRD_CSS_WDOG_BASE		UL(0x2A480000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_BASE		ULL(0x8080000000)
+#define NRD_CSS_DRAM2_SIZE		ULL(0x180000000)
+
+#endif /* NRD_CSS_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_fw_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_fw_def1.h
new file mode 100644
index 00000000..70a7d49b
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_css_fw_def1.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the CSS firmware specific definitions for
+ * the first generation platforms based on the A75, N1 and V1 CPUs.
+ */
+
+#ifndef NRD1_CSS_FW_DEF1_H
+#define NRD1_CSS_FW_DEF1_H
+
+#include <nrd_css_def1.h>
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define NRD_CSS_BL1_RW_SIZE		UL(64 * 1024)	/* 64KB */
+
+#if TRUSTED_BOARD_BOOT
+# define NRD_CSS_BL2_SIZE		UL(0x28000)
+#else
+# define NRD_CSS_BL2_SIZE		UL(0x14000)
+#endif
+
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
+ * and BL1-RW.
+ */
+#define NRD_CSS_BL31_SIZE		UL(116 * 1024)	/* 116 KB */
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define NRD_CSS_UART_CLK_IN_HZ		UL(7372800)
+
+/*******************************************************************************
+ * Watchdog config
+ ******************************************************************************/
+
+#define NRD_CSS_WDOG_TIMEOUT		UL(100)
+
+/*******************************************************************************
+ * Platform ID
+ ******************************************************************************/
+
+/* Platform ID address */
+#define SSC_VERSION		(SSC_REG_BASE + SSC_VERSION_OFFSET)
+#ifndef __ASSEMBLER__
+/* SSC_VERSION related accessors */
+/* Returns the part number of the platform */
+#define GET_NRD_PART_NUM						\
+			GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
+/* Returns the configuration number of the platform */
+#define GET_NRD_CONFIG_NUM						\
+			GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
+#endif /* __ASSEMBLER__ */
+
+/*******************************************************************************
+ * MMU mappings
+ ******************************************************************************/
+
+#define NRD_CSS_PERIPH_MMAP(n)						\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_CSS_PERIPH_BASE,				\
+			NRD_CSS_PERIPH_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_CSS_SHARED_RAM_MMAP(n)					\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			ARM_SHARED_RAM_BASE,				\
+			ARM_SHARED_RAM_SIZE,				\
+			MT_NON_CACHEABLE | MT_RW | MT_SECURE)
+
+#if SPM_MM
+/*
+ * Stand-alone MM logs would be routed via secure UART. Define page table
+ * entry for secure UART which would be common to all platforms.
+ */
+#define NRD_CSS_SECURE_UART_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_CSS_SEC_UART_BASE,				\
+			NRD_CSS_UART_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+#endif
+
+#endif /* NRD_CSS_FW_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_plat_arm_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_plat_arm_def1.h
new file mode 100644
index 00000000..bca095cd
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_plat_arm_def1.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the platform port definitions for the
+ * first generation platforms based on the A75, N1 and V1 CPUs.
+ */
+
+#ifndef NRD_PLAT_ARM_DEF1_H
+#define NRD_PLAT_ARM_DEF1_H
+
+#ifndef __ASSEMBLER__
+#include <lib/mmio.h>
+#endif /* __ASSEMBLER__ */
+
+#include <lib/utils_def.h>
+#include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
+#include <plat/common/common_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_ros_fw_def1.h>
+
+/*******************************************************************************
+ * Core count
+ ******************************************************************************/
+
+#define PLATFORM_CORE_COUNT	(NRD_CHIP_COUNT *			\
+				PLAT_ARM_CLUSTER_COUNT *		\
+				NRD_MAX_CPUS_PER_CLUSTER *		\
+				NRD_MAX_PE_PER_CPU)
+
+/*******************************************************************************
+ * PA/VA config
+ ******************************************************************************/
+
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#endif
+
+/*******************************************************************************
+ * XLAT definitions
+ ******************************************************************************/
+
+#if defined(IMAGE_BL31)
+# if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
+#  define PLAT_ARM_MMAP_ENTRIES		(10 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(11 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define PLAT_SP_IMAGE_MMAP_REGIONS	U(12)
+#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	U(14)
+# else
+#  define PLAT_ARM_MMAP_ENTRIES		(5 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(6 + ((NRD_CHIP_COUNT - 1) * 3))
+# endif
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES		U(8)
+# define MAX_XLAT_TABLES		U(5)
+#elif defined(IMAGE_BL2)
+# define PLAT_ARM_MMAP_ENTRIES		(11 + (NRD_CHIP_COUNT - 1))
+
+/*
+ * MAX_XLAT_TABLES entries need to be doubled because when the address width
+ * exceeds 40 bits an additional level of translation is required. In case of
+ * multichip platforms peripherals also fall into address space with width
+ * > 40 bits.
+ */
+# define MAX_XLAT_TABLES		(11  + ((NRD_CHIP_COUNT - 1) * 2))
+#elif !USE_ROMLIB
+# define PLAT_ARM_MMAP_ENTRIES		U(11)
+# define MAX_XLAT_TABLES		U(7)
+#else
+# define PLAT_ARM_MMAP_ENTRIES		U(12)
+# define MAX_XLAT_TABLES		U(6)
+#endif
+
+/*******************************************************************************
+ * Stack size
+ ******************************************************************************/
+
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		U(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		U(0x440)
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		U(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		U(0x400)
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE		U(0x400)
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+#  define PLATFORM_STACK_SIZE		U(0x500)
+# else
+#  define PLATFORM_STACK_SIZE		U(0x400)
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE		U(0x440)
+#endif
+
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))
+/*
+ * Secure partition stack follows right after the memory region that is shared
+ * between EL3 and S-EL0.
+ */
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
+#endif /* SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP) */
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	U(0x1000)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	U(0xe000)
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	U(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	U(0)
+#endif
+
+#define PLAT_ARM_MAX_BL1_RW_SIZE	NRD_CSS_BL1_RW_SIZE
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth. Additional 8KiB space is added per chip in
+ * order to accommodate the additional level of translation required for "TZC"
+ * peripheral access which lies in >4TB address space.
+ *
+ */
+#define PLAT_ARM_MAX_BL2_SIZE		(NRD_CSS_BL2_SIZE +		\
+						((NRD_CHIP_COUNT - 1) * 0x2000))
+
+#define PLAT_ARM_MAX_BL31_SIZE		(NRD_CSS_BL31_SIZE +		\
+						PLAT_ARM_MAX_BL2_SIZE +	\
+						PLAT_ARM_MAX_BL1_RW_SIZE)
+
+/*******************************************************************************
+ * ROM, SRAM and DRAM config
+ ******************************************************************************/
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	NRD_CSS_TRUSTED_SRAM_SIZE
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	NRD_CSS_TRUSTED_ROM_BASE
+#define PLAT_ARM_TRUSTED_ROM_SIZE	NRD_CSS_TRUSTED_ROM_SIZE
+
+#define PLAT_ARM_NSRAM_BASE		NRD_CSS_NONTRUSTED_SRAM_BASE
+#define PLAT_ARM_NSRAM_SIZE		NRD_CSS_NONTRUSTED_SRAM_SIZE
+
+#define PLAT_ARM_DRAM2_BASE		NRD_CSS_DRAM2_BASE
+#define PLAT_ARM_DRAM2_SIZE		NRD_CSS_DRAM2_SIZE
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define PLAT_ARM_BOOT_UART_BASE		NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE		NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE	NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+/*******************************************************************************
+ * Timer config
+ ******************************************************************************/
+
+#define PLAT_ARM_NSTIMER_FRAME_ID	(0)
+
+/*******************************************************************************
+ * Power config
+ ******************************************************************************/
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/*******************************************************************************
+ * Flash config
+ ******************************************************************************/
+
+#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
+					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+/* IO storage framework */
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+/*******************************************************************************
+ * SCMI config
+ ******************************************************************************/
+
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	NRD_CHIP_COUNT
+
+/*******************************************************************************
+ * SDS config
+ ******************************************************************************/
+
+/* Index of SDS region used in the communication with SCP */
+#define SDS_SCP_AP_REGION_ID		U(0)
+/* SDS ID for unusable CPU MPID list structure */
+#define SDS_ISOLATED_CPU_LIST_ID	U(128)
+
+/*******************************************************************************
+ * GIC/EHF config
+ ******************************************************************************/
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+#define PLAT_SP_PRI			U(0x10)
+
+/*******************************************************************************
+ * Platform type identification macro
+ ******************************************************************************/
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0f)
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x0)
+#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
+
+#ifndef __ASSEMBLER__
+#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
+		((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)	\
+		>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+#endif /* __ASSEMBLER__ */
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR		NRD_ROS_PLATFORM_BASE +	\
+						UL(0x00fe00e0)
+
+#endif /* NRD_PLAT_ARM_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_def1.h
new file mode 100644
index 00000000..b86ab21d
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_def1.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the RoS specific definitions for the first
+ * generation platforms based on the A75, N1 and V1 CPUs. RoS (Rest Of System)
+ * is used to refer to the part of the reference design platform that excludes
+ * CSS.
+ */
+
+#ifndef NRD_ROS_DEF1_H
+#define NRD_ROS_DEF1_H
+
+/*******************************************************************************
+ * ROS configs
+ ******************************************************************************/
+
+/* RoS Peripherals */
+#define NRD_ROS_PERIPH_BASE		UL(0x60000000)
+#define NRD_ROS_PERIPH_SIZE		UL(0x20000000)
+
+/* System Reg */
+#define NRD_ROS_SYSTEMREG_BASE		UL(0x1C010000)
+#define NRD_ROS_SYSTEMREG_SIZE		UL(0x00010000)
+
+/* NOR Flash 2 */
+#define NRD_ROS_NOR2_FLASH_BASE		UL(0x10000000)
+#define NRD_ROS_NOR2_FLASH_SIZE		UL(0x04000000)
+
+/* RoS Platform */
+#define NRD_ROS_PLATFORM_BASE		UL(0x7F000000)
+#define NRD_ROS_PLATFORM_SIZE		UL(0x20000000)
+
+#endif /* NRD_ROS_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_fw_def1.h b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_fw_def1.h
new file mode 100644
index 00000000..c5210432
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd1/nrd_ros_fw_def1.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the RoS firmware specific definitions for the
+ * first generation platforms based on the A75, N1 and V1 CPUs. RoS (Rest Of
+ * System) is used to refer to the part of the reference design platform that
+ * excludes CSS.
+ */
+
+#ifndef NRD_ROS_FW_DEF1_H
+#define NRD_ROS_FW_DEF1_H
+
+#include <nrd_ros_def1.h>
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_ROS_PERIPH_MMAP(n)						\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_ROS_PERIPH_BASE,				\
+			NRD_ROS_PERIPH_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_SECURE_SYSTEMREG_USER_MMAP				\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_SYSTEMREG_BASE,				\
+			NRD_ROS_SYSTEMREG_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define NRD_ROS_SECURE_NOR2_USER_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_NOR2_FLASH_BASE,			\
+			NRD_ROS_NOR2_FLASH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define NRD_MAP_FLASH0_RO						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RO | MT_SECURE)
+
+/*******************************************************************************
+ * TZ config
+ ******************************************************************************/
+
+/*
+ * Mapping definition of the TrustZone Controller for Arm Neoverse RD platforms
+ * where both the DRAM regions are marked for non-secure access. This applies
+ * to multi-chip platforms.
+ */
+#define NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(n)				\
+	{NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_BASE,		\
+		NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_END,		\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},	\
+	{NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_BASE,		\
+		NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_END,		\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
+
+#endif  /* NRD_ROS_FW_DEF1_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_def2.h
new file mode 100644
index 00000000..6cf57d4e
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_def2.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS specific definitions for the second generation
+ * platforms based on the N2/V2 CPU.
+ */
+
+#ifndef NRD_CSS_DEF2_H
+#define NRD_CSS_DEF2_H
+
+/*******************************************************************************
+ * CSS memory map related defines
+ ******************************************************************************/
+
+/* Boot ROM */
+#define NRD_CSS_SECURE_ROM_BASE			UL(0x00000000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_BASE			ULL(0x8080000000)
+
+/* NS SRAM */
+#define NRD_CSS_NS_SRAM_BASE			UL(0x06000000)
+
+/* PL011 UART */
+#define NRD_CSS_SEC_UART_BASE			UL(0x2A410000)
+#define NRD_CSS_NSEC_UART_BASE			UL(0x2A400000)
+#define NRD_CSS_UART_SIZE			UL(0x10000)
+
+/* General Peripherals */
+#define NRD_CSS_PERIPH_BASE			UL(0x20000000)
+#define NRD_CSS_PERIPH_SIZE			UL(0x20000000)
+
+/* NS RAM Error record */
+#define NRD_CSS_NS_RAM_ERR_REC_BASE		UL(0x2A4C0000)
+
+/*Secure Watchdog */
+#define NRD_CSS_SECURE_WDOG_BASE		UL(0x2A480000)
+
+/* MHU */
+#define NRD_CSS_AP_SCP_S_MHU_BASE		UL(0x2A920000)
+
+/* GIC */
+#define NRD_CSS_GIC_BASE			UL(0x30000000)
+
+#endif /* NRD_CSS_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_fw_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_fw_def2.h
new file mode 100644
index 00000000..481632bf
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_css_fw_def2.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS-firmware specific definitions for the second
+ * generation platforms based on the N2/V2 CPU.
+ */
+
+#ifndef NRD_CSS_FW_DEF2_H
+#define NRD_CSS_FW_DEF2_H
+
+#include <nrd_css_def2.h>
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define NRD_CSS_BL1_RW_SIZE		UL(64 * 1024)	/* 64KB */
+
+#if TRUSTED_BOARD_BOOT
+# define NRD_CSS_BL2_SIZE		UL(0x20000)
+#else
+# define NRD_CSS_BL2_SIZE		UL(0x14000)
+#endif
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
+ * and BL1-RW. NRD_BL31_SIZE - is tuned with respect to the actual BL31
+ * PROGBITS size which is around 64-68KB at the time this change is being made.
+ * A buffer of ~35KB is added to account for future expansion of the image,
+ * making it a total of 100KB.
+ */
+#define NRD_CSS_BL31_SIZE		UL(116 * 1024)	/* 116 KB */
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define NRD_CSS_UART_CLK_IN_HZ		UL(7372800)
+
+/*******************************************************************************
+ * Watchdog config
+ ******************************************************************************/
+
+#define NRD_CSS_SECURE_WDOG_TIMEOUT	UL(100)
+
+/*******************************************************************************
+ * RAS config
+ ******************************************************************************/
+
+#define NRD_CSS_NS_RAM_ECC_CE_INT		U(87)
+#define NRD_CSS_NS_RAM_ECC_UE_INT		U(88)
+
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))			\
+	&& ENABLE_FEAT_RAS && FFH_SUPPORT
+/*
+ * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
+ * memory shared between EL3 and S-EL0.
+ */
+#define NRD_CSS_SP_CPER_BUF_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
+#define NRD_CSS_SP_CPER_BUF_SIZE	UL(0x10000)
+#endif /* SPM_MM && ENABLE_FEAT_RAS && FFH_SUPPORT */
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_CSS_SHARED_RAM_MMAP(n)					\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			ARM_SHARED_RAM_BASE,				\
+			ARM_SHARED_RAM_SIZE,				\
+			MT_NON_CACHEABLE | MT_RW | MT_SECURE)
+
+#define NRD_CSS_PERIPH_MMAP(n)						\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_CSS_PERIPH_BASE,				\
+			NRD_CSS_PERIPH_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) &&			\
+ENABLE_FEAT_RAS && FFH_SUPPORT
+/*
+ * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
+ * memory shared between EL3 and S-EL0.
+ */
+#define NRD_CSS_SP_CPER_BUF_MMAP					\
+		MAP_REGION2(						\
+			NRD_CSS_SP_CPER_BUF_BASE,			\
+			NRD_CSS_SP_CPER_BUF_BASE,			\
+			NRD_CSS_SP_CPER_BUF_SIZE,			\
+			MT_RW_DATA | MT_NS | MT_USER,			\
+			PAGE_SIZE)
+#endif
+
+#if SPM_MM
+#define NRD_CSS_SECURE_UART_USER_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_CSS_SEC_UART_BASE,				\
+			NRD_CSS_UART_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+#endif
+
+#endif /* NRD_CSS_FW_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_plat_arm_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_plat_arm_def2.h
new file mode 100644
index 00000000..3ee413f6
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_plat_arm_def2.h
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the trusted firmware required platform port
+ * definitions for the second generation platforms based on the N2/V2 CPUs. The
+ * common platform support for Arm platforms expect platforms to define certain
+ * definitions and those definitions are referred to as the platform port
+ * definitions.
+ */
+
+#ifndef NRD_PLAT_ARM_DEF2_H
+#define NRD_PLAT_ARM_DEF2_H
+
+#ifndef __ASSEMBLER__
+#include <lib/mmio.h>
+#endif /* __ASSEMBLER__ */
+
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <nrd_css_fw_def2.h>
+#include <nrd_ros_fw_def2.h>
+
+/*******************************************************************************
+ * Core count
+ ******************************************************************************/
+
+#define PLATFORM_CORE_COUNT		(NRD_CHIP_COUNT *		\
+					PLAT_ARM_CLUSTER_COUNT *	\
+					NRD_MAX_CPUS_PER_CLUSTER *	\
+					NRD_MAX_PE_PER_CPU)
+
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_CLUSTER_COUNT		U(8)
+#elif (NRD_PLATFORM_VARIANT == 2)
+#define PLAT_ARM_CLUSTER_COUNT		U(4)
+#else
+#define PLAT_ARM_CLUSTER_COUNT		U(16)
+#endif
+
+/*******************************************************************************
+ * PA/VA config
+ ******************************************************************************/
+
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#endif
+
+/*******************************************************************************
+ * XLAT definitions
+ ******************************************************************************/
+
+#if defined(IMAGE_BL31)
+# if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
+#  define PLAT_ARM_MMAP_ENTRIES		(10  + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(8  + ((NRD_CHIP_COUNT - 1) * 3))
+#  define PLAT_SP_IMAGE_MMAP_REGIONS	U(12)
+#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	U(14)
+# else
+#  define PLAT_ARM_MMAP_ENTRIES		(5 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(6 + ((NRD_CHIP_COUNT - 1) * 3))
+# endif
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES		U(8)
+# define MAX_XLAT_TABLES		U(5)
+#elif defined(IMAGE_BL2)
+# define PLAT_ARM_MMAP_ENTRIES		(11 + (NRD_CHIP_COUNT - 1))
+
+/*
+ * MAX_XLAT_TABLES entries need to be doubled because when the address width
+ * exceeds 40 bits an additional level of translation is required. In case of
+ * multichip platforms peripherals also fall into address space with width
+ * > 40 bits
+ *
+ */
+# define MAX_XLAT_TABLES		(7  + ((NRD_CHIP_COUNT - 1) * 2))
+#elif !USE_ROMLIB
+# define PLAT_ARM_MMAP_ENTRIES		U(11)
+# define MAX_XLAT_TABLES		U(7)
+#else
+# define PLAT_ARM_MMAP_ENTRIES		U(12)
+# define MAX_XLAT_TABLES		U(6)
+#endif
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0x1000)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0xe000)
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0)
+#endif
+
+#define PLAT_ARM_MAX_BL1_RW_SIZE	NRD_CSS_BL1_RW_SIZE
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth. Additional 8KiB space is added per chip in
+ * order to accommodate the additional level of translation required for "TZC"
+ * peripheral access which lies in >4TB address space.
+ *
+ */
+#define PLAT_ARM_MAX_BL2_SIZE		(NRD_CSS_BL2_SIZE +		\
+						((NRD_CHIP_COUNT - 1) * 0x2000))
+
+#define PLAT_ARM_MAX_BL31_SIZE		(NRD_CSS_BL31_SIZE +		\
+						PLAT_ARM_MAX_BL2_SIZE +	\
+						PLAT_ARM_MAX_BL1_RW_SIZE)
+
+/*******************************************************************************
+ * Stack sizes
+ ******************************************************************************/
+
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x440)
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE		UL(0x400)
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+#  define PLATFORM_STACK_SIZE		UL(0x500)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE		UL(0x440)
+#endif
+
+#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) &&			\
+ENABLE_FEAT_RAS && FFH_SUPPORT
+/*
+ * Secure partition stack follows right after the memory space reserved for
+ * CPER buffer memory.
+ */
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +   \
+					 PLAT_SP_IMAGE_NS_BUF_SIZE +   \
+					 NRD_CSS_SP_CPER_BUF_SIZE)
+#elif (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))
+/*
+ * Secure partition stack follows right after the memory region that is shared
+ * between EL3 and S-EL0.
+ */
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
+#endif /* SPM_MM && ENABLE_FEAT_RAS && FFH_SUPPORT */
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define PLAT_ARM_BOOT_UART_BASE		NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE		NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE	NRD_CSS_SEC_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+/*******************************************************************************
+ * SCMI config
+ ******************************************************************************/
+
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	NRD_CHIP_COUNT
+
+/*******************************************************************************
+ * ROM, SRAM and DRAM config
+ ******************************************************************************/
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	NRD_CSS_SECURE_ROM_BASE
+#define PLAT_ARM_TRUSTED_ROM_SIZE	NRD_CSS_SECURE_ROM_SIZE
+
+#define PLAT_ARM_DRAM2_BASE		NRD_CSS_DRAM2_BASE
+#define PLAT_ARM_DRAM2_SIZE		NRD_CSS_DRAM2_SIZE
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	NRD_CSS_SECURE_SRAM_SIZE
+
+#define PLAT_ARM_NSTIMER_FRAME_ID	0
+
+#define PLAT_ARM_NSRAM_BASE		NRD_CSS_NS_SRAM_BASE
+#define PLAT_ARM_NSRAM_SIZE		NRD_CSS_NS_SRAM_SIZE
+/*
+ * Required platform porting definitions common to all ARM CSS SoCs
+ */
+/* 2MB used for SCP DDR retraining */
+#define PLAT_ARM_SCP_TZC_DRAM1_SIZE	UL(0x00200000)
+
+/*******************************************************************************
+ * GIC/EHF config
+ ******************************************************************************/
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		NRD_CSS_GIC_BASE
+
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x00100000)
+#elif (NRD_PLATFORM_VARIANT == 3)
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x00300000)
+#else
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x001C0000)
+#endif
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
+#define PLAT_SP_PRI			PLAT_RAS_PRI
+#else
+#define PLAT_SP_PRI			(0x10)
+#endif
+
+/* Interrupt priority level for shutdown/reboot */
+#define PLAT_REBOOT_PRI		GIC_HIGHEST_SEC_PRIORITY
+#define PLAT_EHF_DESC		EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_REBOOT_PRI)
+
+/*******************************************************************************
+ * Secure world config
+ ******************************************************************************/
+
+#define SECURE_PARTITION_COUNT		1
+#define NS_PARTITION_COUNT		1
+#define MAX_EL3_LP_DESCS_COUNT		1
+
+/*******************************************************************************
+ * MHU config
+ ******************************************************************************/
+
+#define PLAT_CSS_MHU_BASE		NRD_CSS_AP_SCP_S_MHU_BASE
+#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
+
+/*******************************************************************************
+ * Power config
+ ******************************************************************************/
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/*******************************************************************************
+ * TZ config
+ ******************************************************************************/
+
+#define PLAT_ARM_TZC_BASE		NRD_ROS_MEMCNTRL_BASE + UL(0x00720000)
+#define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+/*******************************************************************************
+ * SDS config
+ ******************************************************************************/
+
+/* SDS ID for unusable CPU MPID list structure */
+#define SDS_ISOLATED_CPU_LIST_ID	U(128)
+
+/* Index of SDS region used in the communication with SCP */
+#define SDS_SCP_AP_REGION_ID		U(0)
+
+/*******************************************************************************
+ * Flash config
+ ******************************************************************************/
+
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+#define V2M_SYS_LED			U(0x8)
+
+#define V2M_SYS_LED_SS_SHIFT		U(0)
+#define V2M_SYS_LED_EL_SHIFT		U(1)
+#define V2M_SYS_LED_EC_SHIFT		U(3)
+
+#define V2M_SYS_LED_SS_MASK		U(0x01)
+#define V2M_SYS_LED_EL_MASK		U(0x03)
+#define V2M_SYS_LED_EC_MASK		U(0x1f)
+
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
+
+#define V2M_SYSREGS_BASE		NRD_ROS_SYSTEM_PERIPH_BASE +	\
+						UL(0x00010000)
+#define V2M_FLASH0_BASE			NRD_ROS_SMC0_BASE
+#define V2M_FLASH0_SIZE			NRD_ROS_SMC0_SIZE
+#define V2M_FLASH_BLOCK_SIZE		UL(0x00040000)	/* 256 KB */
+
+#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE +	\
+					V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/*******************************************************************************
+ * Platform type identification macro
+ ******************************************************************************/
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0F)
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK	U(0xF00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT	U(0x08)
+#define BOARD_CSS_PLAT_TYPE_RTL			U(0x00)
+#define BOARD_CSS_PLAT_TYPE_FPGA		U(0x01)
+#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
+#define BOARD_CSS_PLAT_TYPE_FVP			U(0x03)
+
+#ifndef __ASSEMBLER__
+#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
+	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
+	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+#endif /* __ASSEMBLER__ */
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR	NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00FE00E0)
+
+/*******************************************************************************
+ * ROS peripheral config
+ ******************************************************************************/
+
+/* Non-volatile counters */
+#define SOC_TRUSTED_NVCTR_BASE		NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00E70000)
+#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE	+ 0x0000)
+#define TFW_NVCTR_SIZE			U(4)
+#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE			U(4)
+
+/*******************************************************************************
+ * MMU config
+ ******************************************************************************/
+
+#define V2M_MAP_FLASH0_RW						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define V2M_MAP_FLASH0_RO						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_RO_DATA | MT_SECURE)
+
+#endif /* NRD_PLAT_ARM_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_def2.h
new file mode 100644
index 00000000..3558cfc6
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_def2.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the RoS specific definitions for the second generation
+ * platforms based on the N2/V2 CPU.
+ */
+
+#ifndef NRD_ROS_DEF2_H
+#define NRD_ROS_DEF2_H
+
+/*******************************************************************************
+ * SoC memory map related defines
+ ******************************************************************************/
+
+/* System Reg */
+#define NRD_ROS_SYSTEMREG_BASE			UL(0x0C010000)
+#define NRD_ROS_SYSTEMREG_SIZE			UL(0x00010000)
+
+/* NOR flash 2 */
+#define NRD_ROS_NOR2_FLASH_BASE			ULL(0x001054000000)
+#define NRD_ROS_NOR2_FLASH_SIZE			UL(0x000004000000)
+
+/* Memory controller */
+#define NRD_ROS_MEMCNTRL_BASE			UL(0x10000000)
+#define NRD_ROS_MEMCNTRL_SIZE			UL(0x10000000)
+
+/* System peripherals */
+#define NRD_ROS_SYSTEM_PERIPH_BASE		UL(0x0C000000)
+#define NRD_ROS_SYSTEM_PERIPH_SIZE		UL(0x02000000)
+
+/* Platform peripherals */
+#define NRD_ROS_PLATFORM_PERIPH_BASE		UL(0x0E000000)
+#define NRD_ROS_PLATFORM_PERIPH_SIZE		UL(0x02000000)
+
+/* SMC0 */
+#define NRD_ROS_SMC0_BASE			UL(0x08000000)
+#define NRD_ROS_SMC0_SIZE			UL(0x04000000)
+
+#endif /* NRD_ROS_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_fw_def2.h b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_fw_def2.h
new file mode 100644
index 00000000..60916729
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd2/nrd_ros_fw_def2.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the RoS firmware specific definitions for the
+ * second generation platforms based on the N2/V2 CPUs. RoS (Rest Of System) is
+ * used to refer to the part of the reference design platform that excludes CSS.
+ */
+
+#ifndef NRD_ROS_FW_DEF2_H
+#define NRD_ROS_FW_DEF2_H
+
+#include <nrd_ros_def2.h>
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_ROS_PLATFORM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_PLATFORM_PERIPH_BASE,			\
+			NRD_ROS_PLATFORM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#if SPM_MM
+
+#define NRD_ROS_PLATFORM_PERIPH_USER_MMAP				\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_PLATFORM_PERIPH_BASE,			\
+			NRD_ROS_PLATFORM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+#endif
+
+#define NRD_ROS_SYSTEM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_SYSTEM_PERIPH_BASE,			\
+			NRD_ROS_SYSTEM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_MEMCNTRL_MMAP(n)					\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_ROS_MEMCNTRL_BASE,				\
+			NRD_ROS_MEMCNTRL_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_SECURE_SYSTEMREG_USER_MMAP				\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_SYSTEMREG_BASE,				\
+			NRD_ROS_SYSTEMREG_SIZE,				\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#define NRD_ROS_SECURE_NOR2_USER_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_NOR2_FLASH_BASE,			\
+			NRD_ROS_NOR2_FLASH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+
+#define NRD_ROS_FLASH0_RO_MMAP						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RO | MT_SECURE)
+
+/*******************************************************************************
+ * TZ config
+ ******************************************************************************/
+
+/*
+ * Mapping definition of the TrustZone Controller for Arm Neoverse RD platforms
+ * where both the DRAM regions are marked for non-secure access. This applies
+ * to multi-chip platforms.
+ */
+#define NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(n)				\
+	{NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_BASE,		\
+		NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_END,		\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},	\
+	{NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_BASE,		\
+		NRD_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_END,		\
+		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
+
+#endif /* NRD_ROS_FW_DEF2_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h
new file mode 100644
index 00000000..bd2e682a
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_def3.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS specific definitions for the third generation of
+ * platforms.
+ */
+
+#ifndef NRD_CSS_DEF3_H
+#define NRD_CSS_DEF3_H
+
+/*******************************************************************************
+ * CSS memory map related defines
+ ******************************************************************************/
+
+/* Shared RAM */
+#define NRD_CSS_SHARED_SRAM_BASE		UL(0x00000000)
+
+/* General Peripherals */
+#define NRD_CSS_PERIPH_BASE			UL(0x20000000)
+#define NRD_CSS_PERIPH_SIZE			UL(0x20000000)
+
+/* System NCI */
+#define NRD_CSS_SYSTEM_NCI_BASE			UL(0x20000000)
+#define NRD_CSS_SYSTEM_NCI_SIZE			UL(0x04000000)
+
+/* Debug NIC */
+#define NRD_CSS_DEBUG_NIC_BASE			UL(0x28000000)
+#define NRD_CSS_DEBUG_NIC_SIZE			UL(0x01000000)
+
+/* NS UART */
+#define NRD_CSS_NS_UART_BASE			UL(0x2A400000)
+#define NRD_CSS_NS_UART_SIZE			UL(0x00010000)
+
+/* Secure UART */
+#define NRD_CSS_SECURE_UART_BASE		UL(0x2A410000)
+#define NRD_CSS_SECURE_UART_SIZE		UL(0x00010000)
+
+/* Realm UART */
+#define NRD_CSS_REALM_UART_BASE			UL(0x2A420000)
+#define NRD_CSS_REALM_UART_SIZE			UL(0x00010000)
+
+/* Generic Refclk */
+#define NRD_CSS_GENERIC_REFCLK_BASE		UL(0x2A430000)
+#define NRD_CSS_GENERIC_REFCLK_SIZE		UL(0x00010000)
+
+/* NS Watchdog */
+#define NRD_CSS_AP_NS_WDOG_BASE			UL(0x2A440000)
+#define NRD_CSS_AP_NS_WDOG_SIZE			UL(0x00020000)
+
+/* Root Watchdog */
+#define NRD_CSS_AP_ROOT_WDOG_BASE		UL(0x2A460000)
+#define NRD_CSS_AP_ROOT_WDOG_SIZE		UL(0x00020000)
+
+/* Secure Watchdog */
+#define NRD_CSS_AP_SECURE_WDOG_BASE		UL(0x2A480000)
+#define NRD_CSS_AP_SECURE_WDOG_SIZE		UL(0x00020000)
+
+/* SID */
+#define NRD_CSS_SID_BASE			UL(0x2A4A0000)
+#define NRD_CSS_SID_SIZE			UL(0x00010000)
+
+/* SRAM Secure Error Record Block - AP */
+#define NRD_CSS_SECURE_SRAM_ERB_AP_BASE		UL(0x2A4B0000)
+#define NRD_CSS_SECURE_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM NS Error Record Block - AP */
+#define NRD_CSS_NS_SRAM_ERB_AP_BASE		UL(0x2A4C0000)
+#define NRD_CSS_NS_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - AP */
+#define NRD_CSS_ROOT_SRAM_ERB_AP_BASE		UL(0x2A4D0000)
+#define NRD_CSS_ROOT_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - AP */
+#define NRD_CSS_REALM_SRAM_ERB_AP_BASE		UL(0x2A4E0000)
+#define NRD_CSS_REALM_SRAM_ERB_AP_SIZE		UL(0x00010000)
+
+/* SRAM Secure Error Record Block - SCP */
+#define NRD_CSS_SECURE_SRAM_ERB_SCP_BASE	UL(0x2A4F0000)
+#define NRD_CSS_SECURE_SRAM_ERB_SCP_SIZE	UL(0x00010000)
+
+/* SRAM NS Error Record Block - SCP */
+#define NRD_CSS_NS_SRAM_ERB_SCP_BASE		UL(0x2A500000)
+#define NRD_CSS_NS_SRAM_ERB_SCP_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - SCP */
+#define NRD_CSS_ROOT_SRAM_ERB_SCP_BASE		UL(0x2A510000)
+#define NRD_CSS_ROOT_SRAM_ERB_SCP_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - SCP */
+#define NRD_CSS_REALM_SRAM_ERB_SCP_BASE		UL(0x2A520000)
+#define NRD_CSS_REALM_SRAM_ERB_SCP_SIZE		UL(0x00010000)
+
+/* SRAM Secure Error Record Block - MCP */
+#define NRD_CSS_SECURE_SRAM_ERB_MCP_BASE	UL(0x2A530000)
+#define NRD_CSS_SECURE_SRAM_ERB_MCP_SIZE	UL(0x00010000)
+
+/* SRAM NS Error Record Block - MCP */
+#define NRD_CSS_NS_SRAM_ERB_MCP_BASE		UL(0x2A540000)
+#define NRD_CSS_NS_SRAM_ERB_MCP_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - MCP */
+#define NRD_CSS_ROOT_SRAM_ERB_MCP_BASE		UL(0x2A550000)
+#define NRD_CSS_ROOT_SRAM_ERB_MCP_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - MCP */
+#define NRD_CSS_REALM_SRAM_ERB_MCP_BASE		UL(0x2A560000)
+#define NRD_CSS_REALM_SRAM_ERB_MCP_SIZE		UL(0x00010000)
+
+/* SRAM Secure Error Record Block - RSE */
+#define NRD_CSS_SECURE_SRAM_ERB_RSE_BASE	UL(0x2A570000)
+#define NRD_CSS_SECURE_SRAM_ERB_RSE_SIZE	UL(0x00010000)
+
+/* SRAM NS Error Record Block - RSE */
+#define NRD_CSS_NS_SRAM_ERB_RSE_BASE		UL(0x2A580000)
+#define NRD_CSS_NS_SRAM_ERB_RSE_SIZE		UL(0x00010000)
+
+/* SRAM Root Error Record Block - RSE */
+#define NRD_CSS_ROOT_SRAM_ERB_RSE_BASE		UL(0x2A590000)
+#define NRD_CSS_ROOT_SRAM_ERB_RSE_SIZE		UL(0x00010000)
+
+/* SRAM Realm Error Record Block - RSE */
+#define NRD_CSS_REALM_SRAM_ERB_RSE_BASE		UL(0x2A5A0000)
+#define NRD_CSS_REALM_SRAM_ERB_RSE_SIZE		UL(0x00010000)
+
+/* RSE SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_BASE	UL(0x2A5B0000)
+#define NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* RSE SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_RSE_NS_SRAM_ERB_RSM_BASE	UL(0x2A5C0000)
+#define NRD_CSS_RSE_NS_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* SCP SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_BASE	UL(0x2A5D0000)
+#define NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* SCP SRAM NS Error Record Block - RSM */
+#define NRD_CSS_SCP_NS_SRAM_ERB_RSM_BASE	UL(0x2A5E0000)
+#define NRD_CSS_SCP_NS_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* MCP SRAM Secure Error Record Block - RSM */
+#define NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_BASE	UL(0x2A5F0000)
+#define NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* MCP SRAM NS Error Record Block - RSM */
+#define NRD_CSS_MCP_NS_SRAM_ERB_RSM_BASE	UL(0x2A600000)
+#define NRD_CSS_MCP_NS_SRAM_ERB_RSM_SIZE	UL(0x00010000)
+
+/* CNTCTL Refclk Readframe */
+#define NRD_CSS_CNTCTL_REFCLK_READFRAME_BASE	UL(0x2A800000)
+#define NRD_CSS_CNTCTL_REFCLK_READFRAME_SIZE	UL(0x00020000)
+
+/* CNTCTL base */
+#define NRD_CSS_SYS_TIMCTL_BASE			UL(0x2A810000)
+
+/* Secure Timer */
+#define NRD_CSS_SECURE_TIMER_CTL_BASE		UL(0x2A820000)
+#define NRD_CSS_SECURE_TIMER_CTL_SIZE		UL(0x00010000)
+
+/* NS Timer */
+#define NRD_CSS_NS_TIMER_CTL_BASE		UL(0x2A830000)
+#define NRD_CSS_NS_TIMER_CTL_SIZE		UL(0x00010000)
+
+/* AP - SCP NS MHU */
+#define NRD_CSS_AP_SCP_NS_MHU_BASE		UL(0x2A900000)
+#define NRD_CSS_AP_SCP_NS_MHU_SIZE		UL(0x00020000)
+
+/* AP - SCP Secure MHU */
+#define NRD_CSS_AP_SCP_SECURE_MHU_BASE		UL(0x2A920000)
+#define NRD_CSS_AP_SCP_SECURE_MHU_SIZE		UL(0x00020000)
+
+/* AP - SCP Root MHU */
+#define NRD_CSS_AP_SCP_ROOT_MHU_BASE		UL(0x2A940000)
+#define NRD_CSS_AP_SCP_ROOT_MHU_SIZE		UL(0x00020000)
+
+/* AP - MCP NS MHU */
+#define NRD_CSS_AP_MCP_NS_MHU_BASE		UL(0x2AA00000)
+#define NRD_CSS_AP_MCP_NS_MHU_SIZE		UL(0x00020000)
+
+/* AP - MCP Secure MHU */
+#define NRD_CSS_AP_MCP_SECURE_MHU_BASE		UL(0x2AA20000)
+#define NRD_CSS_AP_MCP_SECURE_MHU_SIZE		UL(0x00020000)
+
+/* AP - MCP Root MHU */
+#define NRD_CSS_AP_MCP_ROOT_MHU_BASE		UL(0x2AA40000)
+#define NRD_CSS_AP_MCP_ROOT_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE NS MHU */
+#define NRD_CSS_AP_RSE_NS_MHU_BASE		UL(0x2AB00000)
+#define NRD_CSS_AP_RSE_NS_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE Secure MHU */
+#define NRD_CSS_AP_RSE_SECURE_MHU_BASE		UL(0x2AB20000)
+#define NRD_CSS_AP_RSE_SECURE_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE Root MHU */
+#define NRD_CSS_AP_RSE_ROOT_MHU_BASE		UL(0x2AB40000)
+#define NRD_CSS_AP_RSE_ROOT_MHU_SIZE		UL(0x00020000)
+
+/* AP - RSE Realm MHU */
+#define NRD_CSS_AP_RSE_REALM_MHU_BASE		UL(0x2AB60000)
+#define NRD_CSS_AP_RSE_REALM_MHU_SIZE		UL(0x00020000)
+
+/* SCP - MCP - RSE Cross chip MHU */
+#define NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_BASE	UL(0x2AC00000)
+#define NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_SIZE	UL(0x00120000)
+
+/* Synchronization Master Tupdate */
+#define NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_BASE	UL(0x2B100000)
+#define NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_SIZE	UL(0x00030000)
+
+/* AP - RSE NS MHU */
+#define NRD_CSS_STM_SYSTEM_ITS_BASE		UL(0x2CF00000)
+#define NRD_CSS_STM_SYSTEM_ITS_SIZE		UL(0x02100000)
+
+/* SCP - MCP - RSE Shared SRAM */
+#define NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_BASE	UL(0x2F000000)
+#define NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_SIZE	UL(0x00400000)
+
+/* GIC base */
+#define NRD_CSS_GIC_BASE			UL(0x30000000)
+#define NRD_CSS_GIC_SIZE			UL(0x08000000)
+
+/* CMN */
+#define NRD_CSS_CMN_BASE			ULL(0x100000000)
+#define NRD_CSS_CMN_SIZE			UL(0x40000000)
+
+/* LCP Peripherals */
+#define NRD_CSS_LCP_PERIPHERAL_BASE		ULL(0x200000000)
+#define NRD_CSS_LCP_PERIPHERAL_SIZE		UL(0x40000000)
+
+/* DDR IO */
+#define NRD_CSS_DDR_IO_BASE			ULL(0x240000000)
+#define NRD_CSS_DDR_IO_SIZE			UL(0x40000000)
+
+/* SMMU & NCI IO */
+#define NRD_CSS_SMMU_NCI_IO_BASE		ULL(0x280000000)
+#define NRD_CSS_SMMU_NCI_IO_SIZE		UL(0x60000000)
+
+/* GPC SMMU */
+#define NRD_CSS_GPC_SMMUV3_BASE			UL(0x300000000)
+#define NRD_CSS_GPC_SMMUV3_SIZE			UL(0x8000000)
+
+/* DRAM1 */
+#define NRD_CSS_DRAM1_BASE			UL(0x80000000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_BASE			ULL(0x8080000000)
+
+/*******************************************************************************
+ * MHUv3 related definitions
+ ******************************************************************************/
+
+#define MHU_V3_MBX_FRAME_OFFSET			UL(0x10000)
+
+/* MHUv3 Postbox and Mailbox register frame base */
+#define AP_RSE_ROOT_MHU_V3_PBX		NRD_CSS_AP_RSE_ROOT_MHU_BASE
+#define AP_RSE_ROOT_MHU_V3_MBX		NRD_CSS_AP_RSE_ROOT_MHU_BASE + \
+						MHU_V3_MBX_FRAME_OFFSET
+
+#define AP_RSE_SECURE_MHU_V3_PBX	NRD_CSS_AP_RSE_SECURE_MHU_BASE
+#define AP_RSE_SECURE_MHU_V3_MBX	NRD_CSS_AP_RSE_SECURE_MHU_BASE + \
+						MHU_V3_MBX_FRAME_OFFSET
+
+#endif /* NRD_CSS_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h
new file mode 100644
index 00000000..3fbc125c
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_css_fw_def3.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the CSS-firmware specific definitions for the third
+ * generation of platforms.
+ */
+
+#ifndef NRD_CSS_FW_DEF3_H
+#define NRD_CSS_FW_DEF3_H
+
+#include <nrd_css_def3.h>
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define NRD_CSS_BL1_RW_SIZE		UL(64 * 1024)	/* 64KB */
+
+#define NRD_CSS_BL1_RO_BASE		NRD_CSS_SHARED_SRAM_BASE
+#define NRD_CSS_BL1_RO_SIZE		UL(0x00019000)
+
+# define NRD_CSS_BL2_SIZE		UL(0x30000)
+
+/*
+ * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
+ * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
+ * and BL1-RW. NRD_BL31_SIZE - is tuned with respect to the actual BL31
+ * PROGBITS size which is around 64-68KB at the time this change is being made.
+ * A buffer of ~35KB is added to account for future expansion of the image,
+ * making it a total of 100KB.
+ */
+#define NRD_CSS_BL31_SIZE		UL(116 * 1024)	/* 116 KB */
+
+#define NRD_CSS_DRAM1_CARVEOUT_SIZE	UL(0x0C000000)	/* 117MB */
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define NRD_CSS_UART_CLK_IN_HZ		UL(7372800)
+
+/*******************************************************************************
+ * Watchdog config
+ ******************************************************************************/
+
+#define NRD_CSS_AP_SECURE_WDOG_TIMEOUT	UL(100)
+
+/*******************************************************************************
+ * RMM Console Config
+ ******************************************************************************/
+
+#define NRD_CSS_RMM_CONSOLE_BASE		NRD_CSS_REALM_UART_BASE
+#define NRD_CSS_RMM_CONSOLE_BAUD		ARM_CONSOLE_BAUDRATE
+#define NRD_CSS_RMM_CONSOLE_CLK_IN_HZ		UL(14745600)
+#define NRD_CSS_RMM_CONSOLE_NAME		"pl011"
+#define NRD_CSS_RMM_CONSOLE_COUNT		UL(1)
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_CSS_PERIPH_MMAP(n)						\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			NRD_CSS_PERIPH_BASE,				\
+			NRD_CSS_PERIPH_SIZE,				\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define NRD_CSS_SHARED_RAM_MMAP(n)					\
+		MAP_REGION_FLAT(					\
+			NRD_REMOTE_CHIP_MEM_OFFSET(n) +			\
+			ARM_SHARED_RAM_BASE,				\
+			ARM_SHARED_RAM_SIZE,				\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#define NRD_CSS_GPC_SMMU_SMMUV3_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_CSS_GPC_SMMUV3_BASE,			\
+			NRD_CSS_GPC_SMMUV3_SIZE,			\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define NRD_CSS_BL1_RW_MMAP						\
+		MAP_REGION_FLAT(					\
+			BL1_RW_BASE,					\
+			BL1_RW_LIMIT - BL1_RW_BASE,			\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#define NRD_CSS_NS_DRAM1_MMAP						\
+		MAP_REGION_FLAT(					\
+			ARM_NS_DRAM1_BASE,				\
+			ARM_NS_DRAM1_SIZE,				\
+			MT_MEMORY | MT_RW | MT_NS)
+
+#define NRD_CSS_GPT_L1_DRAM_MMAP					\
+		MAP_REGION_FLAT(					\
+			ARM_L1_GPT_BASE,				\
+			ARM_L1_GPT_SIZE,				\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#define NRD_CSS_EL3_RMM_SHARED_MEM_MMAP					\
+		MAP_REGION_FLAT(					\
+			ARM_EL3_RMM_SHARED_BASE,			\
+			ARM_EL3_RMM_SHARED_SIZE,			\
+			MT_MEMORY | MT_RW | MT_REALM)
+
+#define NRD_CSS_RMM_REGION_MMAP						\
+		MAP_REGION_FLAT(					\
+			ARM_REALM_BASE,					\
+			ARM_REALM_SIZE,					\
+			MT_MEMORY | MT_RW | MT_REALM)
+
+#if RESET_TO_BL31
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+
+/* Define the DTB image base and size */
+#define NRD_CSS_BL31_PRELOAD_DTB_BASE	UL(0xF3000000)
+#define NRD_CSS_BL31_PRELOAD_DTB_SIZE	UL(0x1000)
+#define NRD_CSS_MAP_BL31_DTB		MAP_REGION_FLAT(		\
+					NRD_CSS_BL31_PRELOAD_DTB_BASE,	\
+					NRD_CSS_BL31_PRELOAD_DTB_SIZE,	\
+					MT_RW_DATA | MT_NS)
+#endif /* RESET_TO_BL31 */
+
+#endif /* NRD_CSS_FW_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h
new file mode 100644
index 00000000..f9a62ae3
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_pas_def3.h
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NRD_PAS_DEF3_H
+#define NRD_PAS_DEF3_H
+
+#ifndef __ASSEMBLER__
+#include <stddef.h>
+#include <lib/gpt_rme/gpt_rme.h>
+#endif
+
+#include <nrd_css_def3.h>
+
+/*****************************************************************************
+ * PAS regions used to initialize the Granule Protection Table (GPT)
+ ****************************************************************************/
+
+/*
+ * =====================================================================
+ * Base Addr        |Size    |L? GPT |PAS    |Content                  |
+ * =====================================================================
+ * 0x00000000       |256MB   |L0 GPT |ANY    |SHARED RAM               |
+ * 0x0FFFFFFF       |        |       |       |AP EXPANSION             |
+ * ---------------------------------------------------------------------
+ * 0x20000000       |64MB    |L1 GPT |ROOT   |SYSTEM NCI               |
+ * 0x23FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x28000000       |16MB    |L1 GPT |SECURE |DEBUG NIC                |
+ * 0x28FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A400000       |64KB    |L1 GPT |NS     |NS UART                  |
+ * 0x2A40FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A410000       |64KB    |L1 GPT |SECURE |SECURE UART              |
+ * 0x2A41FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A420000       |64KB    |L1 GPT |REALM  |REALM UART               |
+ * 0x2A42FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A430000       |64KB    |L1 GPT |SECURE |GENERIC REFCLK           |
+ * 0x2A43FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A440000       |128KB   |L1 GPT |NS     |AP NS WDOG               |
+ * 0x2A45FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A460000       |128KB   |L1 GPT |ROOT   |AP ROOT WDOG             |
+ * 0x2A47FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A480000       |128KB   |L1 GPT |SECURE |AP SECURE WDOG           |
+ * 0x2A49FFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A4A0000       |64KB    |L1 GPT |NS     |SID                      |
+ * 0x2A4AFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2A4B0000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A4BFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4C0000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A4CFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4D0000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A4DFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4E0000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A4EFFFF       |        |       |       |RECORD BLOCK - AP        |
+ * ---------------------------------------------------------------------
+ * 0x2A4F0000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A4FFFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A500000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A50FFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A510000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A51FFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A520000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A52FFFF       |        |       |       |RECORD BLOCK - SCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A530000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A53FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A540000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A54FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A550000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A55FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A560000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A56FFFF       |        |       |       |RECORD BLOCK - MCP       |
+ * ---------------------------------------------------------------------
+ * 0x2A570000       |64KB    |L1 GPT |SECURE |SECURE SRAM ERROR        |
+ * 0x2A57FFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A580000       |64KB    |L1 GPT |NS     |NS SRAM ERROR            |
+ * 0x2A58FFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A590000       |64KB    |L1 GPT |ROOT   |ROOT SRAM ERROR          |
+ * 0x2A59FFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A5A0000       |64KB    |L1 GPT |REALM  |REALM SRAM ERROR         |
+ * 0x2A5AFFFF       |        |       |       |RECORD BLOCK - RSE       |
+ * ---------------------------------------------------------------------
+ * 0x2A5B0000       |64KB    |L1 GPT |SECURE |RSE SECURE SRAM ERROR    |
+ * 0x2A5BFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5C0000       |64KB    |L1 GPT |NS     |RSE NS SRAM ERROR        |
+ * 0x2A5CFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5D0000       |64KB    |L1 GPT |SECURE |SCP SECURE SRAM ERROR    |
+ * 0x2A5DFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5E0000       |64KB    |L1 GPT |NS     |SCP NS SRAM ERROR        |
+ * 0x2A5EFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A5F0000       |64KB    |L1 GPT |SECURE |MCP SECURE SRAM ERROR    |
+ * 0x2A5FFFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A600000       |64KB    |L1 GPT |NS     |MCP NS SRAM ERROR        |
+ * 0x2A60FFFF       |        |       |       |RECORD BLOCK - RSM       |
+ * ---------------------------------------------------------------------
+ * 0x2A800000       |128KB   |L1 GPT |NS     |CNTCTL REFCLK            |
+ * 0x2A81FFFF       |        |       |       |READ FRAME               |
+ * ---------------------------------------------------------------------
+ * 0x2A820000       |64KB    |L1 GPT |SECURE |SECURE TIMER CTL         |
+ * 0x2A82FFFF       |        |       |       |BASE FRAME               |
+ * ---------------------------------------------------------------------
+ * 0x2A830000       |64KB    |L1 GPT |NS     |NS TIMER CTL             |
+ * 0x2A83FFFF       |        |       |       |BASE FRAME               |
+ * ---------------------------------------------------------------------
+ * 0x2A900000       |128KB   |L1 GPT |NS     |AP-SCP NS                |
+ * 0x2A91FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2A920000       |128KB   |L1 GPT |SECURE |AP-SCP SECURE            |
+ * 0x2A93FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2A940000       |128KB   |L1 GPT |ROOT   |AP-SCP ROOT              |
+ * 0x2A95FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AA00000       |128KB   |L1 GPT |NS     |AP-MCP NS                |
+ * 0x2AA1FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AA20000       |128KB   |L1 GPT |SECURE |AP-MCP SECURE            |
+ * 0x2AA3FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AA40000       |128KB   |L1 GPT |ROOT   |AP-MCP ROOT              |
+ * 0x2AA5FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB00000       |128KB   |L1 GPT |NS     |AP-MCP NS                |
+ * 0x2AB1FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB20000       |128KB   |L1 GPT |SECURE |AP-RSE SECURE            |
+ * 0x2AB3FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB40000       |128KB   |L1 GPT |ROOT   |AP-RSE ROOT              |
+ * 0x2AB5FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AB60000       |128KB   |L1 GPT |REALM  |AP-RSE REALM             |
+ * 0x2AB7FFFF       |        |       |       |MHU                      |
+ * ---------------------------------------------------------------------
+ * 0x2AC00000       |1152KB  |L1 GPT |ROOT   |SCP MCP RSE              |
+ * 0x2ACEFFFF       |        |       |       |CROSS CHIP MHU           |
+ * ---------------------------------------------------------------------
+ * 0x2B100000       |192KB   |L1 GPT |SECURE |SYNCNT                   |
+ * 0x2B12FFFF       |        |       |       |MSTUPDTVAL_ADDR          |
+ * ---------------------------------------------------------------------
+ * 0x2CF00000       |~33MB   |L1 GPT |NS     |STM SYSTEM ITS           |
+ * 0x2EFFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x2F000000       |4MB     |L1 GPT |ANY    |SHARED SRAM              |
+ * 0x2F3FFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x30000000       |128MB   |L1 GPT |ANY    |GIC CLAYTON              |
+ * 0x37FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x80000000       |2GB -   |L1 GPT |NS     |NS DRAM                  |
+ * 0xFFFE2BFF       |117MB   |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x80000000       |26MB    |L1 GPT |REALM  |RMM                      |
+ * 0x37FFFFFF       |        |       |       |TF-A SHARED              |
+ * ---------------------------------------------------------------------
+ * 0x80000000       |2MB     |L1 GPT |ROOT   |L1GPT                    |
+ * 0x37FFFFFF       |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x100080000000   |2GB     |L1 GPT |NS     |DRAM 1 CHIP 3            |
+ * 0x1000FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x200080000000   |2GB     |L1 GPT |NS     |DRAM 1 CHIP 2            |
+ * 0x2000FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x300080000000   |2GB     |L1 GPT |NS     |DRAM 1 CHIP 1            |
+ * 0x3000FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x100000000      |1GB     |L1 GPT |ANY    |CMN                      |
+ * 0x13FFFFFFF      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x200000000      |1GB     |L1 GPT |ANY    |LCP PERIPHERALS          |
+ * 0x23FFFFFFF      |        |       |       |DDR                      |
+ * ---------------------------------------------------------------------
+ * 0x240000000      |1GB     |L1 GPT |ANY    |DDR IO                   |
+ * 0x27FFFFFFF      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x280000000      |1.5GB   |L1 GPT |ANY    |SMMU & NCI IO            |
+ * 0x2DFFFFFFF      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x300000000      |128MB   |L1 GPT |ROOT   |GPC SMMU                 |
+ * 0x308000000      |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x8080000000     |6GB     |L1 GPT |ANY    |DRAM 2 CHIP 0            |
+ * 0x81FFFFFFFF     |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x108080000000   |6GB     |L1 GPT |NS     |DRAM 2 CHIP 1            |
+ * 0x1081FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x208080000000   |6GB     |L1 GPT |NS     |DRAM 2 CHIP 2            |
+ * 0x2081FFFFFFFF   |        |       |       |                         |
+ * ---------------------------------------------------------------------
+ * 0x308080000000   |6GB     |L1 GPT |NS     |DRAM 2 CHIP 3            |
+ * 0x3081FFFFFFFF   |        |       |       |                         |
+ * =====================================================================
+ */
+
+/*******************************************************************************
+ * Multichip config
+ ******************************************************************************/
+
+#define NRD_MC_BASE(base, n)		(NRD_REMOTE_CHIP_MEM_OFFSET(n) + base)
+
+/*******************************************************************************
+ * PAS mappings
+ ******************************************************************************/
+
+#define NRD_PAS_SHARED_SRAM						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SHARED_SRAM_BASE,			\
+			NRD_CSS_SHARED_SRAM_SIZE,			\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_SYSTEM_NCI						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SYSTEM_NCI_BASE,			\
+			NRD_CSS_SYSTEM_NCI_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_DEBUG_NIC						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_DEBUG_NIC_BASE,				\
+			NRD_CSS_DEBUG_NIC_SIZE,				\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_UART							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_UART_BASE,				\
+			NRD_CSS_NS_UART_SIZE,				\
+			GPT_GPI_NS)
+
+#define NRD_PAS_REALM_UART						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_UART_BASE,			\
+			NRD_CSS_REALM_UART_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_AP_NS_WDOG						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_NS_WDOG_BASE,			\
+			NRD_CSS_AP_NS_WDOG_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_ROOT_WDOG						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_ROOT_WDOG_BASE,			\
+			NRD_CSS_AP_ROOT_WDOG_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_SECURE_WDOG						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_SECURE_WDOG_BASE,			\
+			NRD_CSS_AP_SECURE_WDOG_SIZE,			\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_SECURE_SRAM_ERB_AP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_AP_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_AP_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_AP						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_AP_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_AP_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_AP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_AP_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_AP_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_AP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_AP_BASE,			\
+			NRD_CSS_REALM_SRAM_ERB_AP_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SECURE_SRAM_ERB_SCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_SCP_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_SCP_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_SCP						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_SCP_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_SCP_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_SCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_SCP_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_SCP_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_SCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_SCP_BASE,		\
+			NRD_CSS_REALM_SRAM_ERB_SCP_SIZE,		\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SECURE_SRAM_ERB_MCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_MCP_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_MCP_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_MCP						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_MCP_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_MCP_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_MCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_MCP_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_MCP_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_MCP					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_MCP_BASE,		\
+			NRD_CSS_REALM_SRAM_ERB_MCP_SIZE,		\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SECURE_SRAM_ERB_RSE					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SECURE_SRAM_ERB_RSE_BASE,		\
+			NRD_CSS_SECURE_SRAM_ERB_RSE_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_NS_SRAM_ERB_RSE						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_NS_SRAM_ERB_RSE_BASE,			\
+			NRD_CSS_NS_SRAM_ERB_RSE_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_ROOT_SRAM_ERB_RSE					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_ROOT_SRAM_ERB_RSE_BASE,			\
+			NRD_CSS_ROOT_SRAM_ERB_RSE_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_REALM_SRAM_ERB_RSE					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_REALM_SRAM_ERB_RSE_BASE,		\
+			NRD_CSS_REALM_SRAM_ERB_RSE_SIZE,		\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_RSE_SECURE_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_RSE_SECURE_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_RSE_NS_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_RSE_NS_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_RSE_NS_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_NS)
+
+#define NRD_PAS_SCP_SECURE_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_SCP_SECURE_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_SCP_NS_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_NS_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_SCP_NS_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_NS)
+
+#define NRD_PAS_MCP_SECURE_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_MCP_SECURE_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define	NRD_PAS_MCP_NS_SRAM_ERB_RSM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_MCP_NS_SRAM_ERB_RSM_BASE,		\
+			NRD_CSS_MCP_NS_SRAM_ERB_RSM_SIZE,		\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_SCP_ROOT_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_SCP_ROOT_MHU_BASE,			\
+			NRD_CSS_AP_SCP_ROOT_MHU_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_MCP_NS_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_MCP_NS_MHU_BASE,			\
+			NRD_CSS_AP_MCP_NS_MHU_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_MCP_SECURE_MHU					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_MCP_SECURE_MHU_BASE,			\
+			NRD_CSS_AP_MCP_SECURE_MHU_SIZE,			\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_AP_MCP_ROOT_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_MCP_ROOT_MHU_BASE,			\
+			NRD_CSS_AP_MCP_ROOT_MHU_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_RSE_NS_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_NS_MHU_BASE,			\
+			NRD_CSS_AP_RSE_NS_MHU_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_AP_RSE_SECURE_MHU					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_SECURE_MHU_BASE,			\
+			NRD_CSS_AP_RSE_SECURE_MHU_SIZE,			\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_AP_RSE_ROOT_MHU						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_ROOT_MHU_BASE,			\
+			NRD_CSS_AP_RSE_ROOT_MHU_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_AP_RSE_REALM_MHU					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_AP_RSE_REALM_MHU_BASE,			\
+			NRD_CSS_AP_RSE_REALM_MHU_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_SCP_MCP_RSE_CROSS_CHIP_MHU				\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_BASE,	\
+			NRD_CSS_SCP_MCP_RSE_CROSS_CHIP_MHU_SIZE,	\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_SYNCNT_MSTUPDTVAL_ADDR					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_BASE,		\
+			NRD_CSS_SYNCNT_MSTUPDTVAL_ADDR_SIZE,		\
+			GPT_GPI_SECURE)
+
+#define NRD_PAS_STM_SYSTEM_ITS						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_STM_SYSTEM_ITS_BASE,			\
+			NRD_CSS_STM_SYSTEM_ITS_SIZE,			\
+			GPT_GPI_NS)
+
+#define NRD_PAS_SCP_MCP_RSE_SHARED_SRAM					\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_BASE,		\
+			NRD_CSS_SCP_MCP_RSE_SHARED_SRAM_SIZE,		\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_GIC							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_GIC_BASE,				\
+			NRD_CSS_GIC_SIZE,				\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_NS_DRAM							\
+		GPT_MAP_REGION_GRANULE(					\
+			ARM_NS_DRAM1_BASE,				\
+			ARM_NS_DRAM1_SIZE,				\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM1_CHIP1						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM1_BASE, 1),		\
+			ARM_DRAM1_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM1_CHIP2						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM1_BASE, 2),		\
+			ARM_DRAM1_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM1_CHIP3						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM1_BASE, 3),		\
+			ARM_DRAM1_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_RMM							\
+		GPT_MAP_REGION_GRANULE(					\
+			ARM_REALM_BASE,					\
+			ARM_REALM_SIZE +				\
+			ARM_EL3_RMM_SHARED_SIZE,			\
+			GPT_GPI_REALM)
+
+#define NRD_PAS_L1GPT							\
+		GPT_MAP_REGION_GRANULE(					\
+			ARM_L1_GPT_BASE,				\
+			ARM_L1_GPT_SIZE,				\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_CMN							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_CMN_BASE,				\
+			NRD_CSS_CMN_SIZE,				\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_LCP_PERIPHERAL						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_LCP_PERIPHERAL_BASE,			\
+			NRD_CSS_LCP_PERIPHERAL_SIZE,			\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_DDR_IO							\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_DDR_IO_BASE,				\
+			NRD_CSS_DDR_IO_SIZE,				\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_SMMU_NCI_IO						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_SMMU_NCI_IO_BASE,			\
+			NRD_CSS_SMMU_NCI_IO_SIZE,			\
+			GPT_GPI_ANY)
+
+#define NRD_PAS_GPC_SMMUV3						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_CSS_GPC_SMMUV3_BASE,			\
+			NRD_CSS_GPC_SMMUV3_SIZE,			\
+			GPT_GPI_ROOT)
+
+#define NRD_PAS_DRAM2_CHIP0						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 0),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM2_CHIP1						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 1),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM2_CHIP2						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 2),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#define NRD_PAS_DRAM2_CHIP3						\
+		GPT_MAP_REGION_GRANULE(					\
+			NRD_MC_BASE(NRD_CSS_DRAM2_BASE, 3),		\
+			ARM_DRAM2_SIZE,					\
+			GPT_GPI_NS)
+
+#endif /* NRD_PAS_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h
new file mode 100644
index 00000000..8d6d1cb3
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h
@@ -0,0 +1,784 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the platform port definitions for the
+ * third generation of platforms.
+ */
+
+#ifndef NRD_PLAT_ARM_DEF3_H
+#define NRD_PLAT_ARM_DEF3_H
+
+#include <common/tbbr/tbbr_img_def.h>
+
+#ifndef __ASSEMBLER__
+#include <lib/mmio.h>
+#endif /* __ASSEMBLER__ */
+
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/common/common_def.h>
+#include <nrd_css_fw_def3.h>
+#include <nrd_ros_fw_def3.h>
+
+/*******************************************************************************
+ * Core count
+ ******************************************************************************/
+
+#define PLATFORM_CORE_COUNT		(NRD_CHIP_COUNT *		\
+					PLAT_ARM_CLUSTER_COUNT *	\
+					NRD_MAX_CPUS_PER_CLUSTER *	\
+					NRD_MAX_PE_PER_CPU)
+
+/*******************************************************************************
+ * PA/VA config
+ ******************************************************************************/
+
+#ifdef __aarch64__
+#define PLAT_PHY_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	NRD_REMOTE_CHIP_MEM_OFFSET( \
+						NRD_CHIP_COUNT)
+#else
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#endif
+
+/*******************************************************************************
+ * XLAT definitions
+ ******************************************************************************/
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage. In addition to that, on
+ * multi-chip platforms, address regions on each of the remote chips are
+ * also mapped. In BL31, for instance, three address regions on the remote
+ * chips are accessed - secure ram, css device and soc device regions.
+ */
+#if defined(IMAGE_BL31)
+#  define PLAT_ARM_MMAP_ENTRIES		(10 + ((NRD_CHIP_COUNT - 1) * 3))
+#  define MAX_XLAT_TABLES		(10 + ((NRD_CHIP_COUNT - 1) * 3))
+#elif defined(IMAGE_BL32)
+# define PLAT_ARM_MMAP_ENTRIES		U(8)
+# define MAX_XLAT_TABLES		U(5)
+#elif defined(IMAGE_BL2)
+# define PLAT_ARM_MMAP_ENTRIES		(16 + (NRD_CHIP_COUNT - 1))
+# define MAX_XLAT_TABLES		(11  + ((NRD_CHIP_COUNT - 1) * 2))
+#else
+# define PLAT_ARM_MMAP_ENTRIES		U(7)
+# define MAX_XLAT_TABLES		U(7)
+#endif
+
+/*******************************************************************************
+ * BL sizes
+ ******************************************************************************/
+
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0)
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0)
+
+#define PLAT_ARM_MAX_BL1_RW_SIZE	NRD_CSS_BL1_RW_SIZE
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth. Additional 8KiB space is added per chip in
+ * order to accommodate the additional level of translation required for "TZC"
+ * peripheral access which lies in >4TB address space.
+ *
+ */
+#define PLAT_ARM_MAX_BL2_SIZE		(NRD_CSS_BL2_SIZE +		\
+						((NRD_CHIP_COUNT - 1) * 0x2000))
+
+#define PLAT_ARM_MAX_BL31_SIZE		(NRD_CSS_BL31_SIZE +		\
+						PLAT_ARM_MAX_BL2_SIZE +	\
+						PLAT_ARM_MAX_BL1_RW_SIZE)
+
+/*******************************************************************************
+ * BL31 plat param
+ ******************************************************************************/
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
+
+/*******************************************************************************
+ * Stack sizes
+ ******************************************************************************/
+
+#if defined(IMAGE_BL1)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x440)
+# endif
+#elif defined(IMAGE_BL2)
+# if TRUSTED_BOARD_BOOT
+#  define PLATFORM_STACK_SIZE		UL(0x1000)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL2U)
+# define PLATFORM_STACK_SIZE		UL(0x400)
+#elif defined(IMAGE_BL31)
+# if SPM_MM
+#  define PLATFORM_STACK_SIZE		UL(0x500)
+# else
+#  define PLATFORM_STACK_SIZE		UL(0x400)
+# endif
+#elif defined(IMAGE_BL32)
+# define PLATFORM_STACK_SIZE		UL(0x440)
+#endif
+
+/*******************************************************************************
+ * Console config
+ ******************************************************************************/
+
+#define ARM_CONSOLE_BAUDRATE		(115200)
+
+/* UART related constants */
+#define PLAT_ARM_BOOT_UART_BASE		NRD_CSS_SECURE_UART_BASE
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_RUN_UART_BASE		NRD_CSS_SECURE_UART_BASE
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+#define PLAT_ARM_CRASH_UART_BASE	NRD_CSS_SECURE_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ	NRD_CSS_UART_CLK_IN_HZ
+
+/*******************************************************************************
+ * System counter and timer config
+ ******************************************************************************/
+
+#define ARM_SYS_CNTCTL_BASE		NRD_CSS_GENERIC_REFCLK_BASE
+#define ARM_SYS_CNTREAD_BASE		NRD_CSS_CNTCTL_REFCLK_READFRAME_BASE
+#define ARM_SYS_TIMCTL_BASE		NRD_CSS_SYS_TIMCTL_BASE
+#define ARM_SYS_CNT_BASE_S		NRD_CSS_SECURE_TIMER_CTL_BASE
+#define ARM_SYS_CNT_BASE_NS		NRD_CSS_NS_TIMER_CTL_BASE
+
+/*******************************************************************************
+ * SRAM and DRAM config for FW
+ ******************************************************************************/
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	NRD_CSS_SECURE_ROM_BASE
+#define PLAT_ARM_TRUSTED_ROM_SIZE	NRD_CSS_SECURE_ROM_SIZE
+
+#define PLAT_ARM_DRAM2_BASE		NRD_CSS_DRAM2_BASE
+#define PLAT_ARM_DRAM2_SIZE		NRD_CSS_DRAM2_SIZE
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE	NRD_CSS_SECURE_SRAM_SIZE
+
+#define PLAT_ARM_NSTIMER_FRAME_ID	(0)
+
+#define PLAT_ARM_NSRAM_BASE		NRD_CSS_NS_SRAM_BASE
+#define PLAT_ARM_NSRAM_SIZE		NRD_CSS_NS_SRAM_SIZE
+
+/*******************************************************************************
+ * Power config
+ ******************************************************************************/
+
+/*
+ * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The
+ * power levels have a 1:1 mapping with the MPIDR affinity levels.
+ */
+#define ARM_PWR_LVL0			MPIDR_AFFLVL0
+#define ARM_PWR_LVL1			MPIDR_AFFLVL1
+#define ARM_PWR_LVL2			MPIDR_AFFLVL2
+#define ARM_PWR_LVL3			MPIDR_AFFLVL3
+
+/* Local power state for power domains in Run state. */
+#define ARM_LOCAL_STATE_RUN		U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define ARM_LOCAL_STATE_RET		U(1)
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains
+ */
+#define ARM_LOCAL_STATE_OFF		U(2)
+/*
+ * 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		ARM_LOCAL_STATE_RET
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE		ARM_LOCAL_STATE_OFF
+
+#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
+
+/*******************************************************************************
+ * MHU config
+ ******************************************************************************/
+
+#define PLAT_CSS_MHU_BASE		NRD_CSS_AP_SCP_SECURE_MHU_BASE
+#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
+
+/*******************************************************************************
+ * Cache config
+ ******************************************************************************/
+
+#define ARM_CACHE_WRITEBACK_SHIFT	U(6)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_GRANULE		(U(1) << ARM_CACHE_WRITEBACK_SHIFT)
+
+/*******************************************************************************
+ * SCMI config
+ ******************************************************************************/
+
+/* Number of SCMI channels on the platform */
+#define PLAT_ARM_SCMI_CHANNEL_COUNT	NRD_CHIP_COUNT
+
+/*******************************************************************************
+ * GIC/EHF config
+ ******************************************************************************/
+
+/* CPU Fault Handling Interrupt(FHI) PPI interrupt ID */
+#define PLAT_CORE_FAULT_IRQ		U(17)
+
+/* ARM platforms use 3 upper bits of secure interrupt priority */
+#define PLAT_PRI_BITS			U(3)
+
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
+#define PLAT_RAS_PRI			U(0x10)
+#endif
+
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
+#define PLAT_SP_PRI			PLAT_RAS_PRI
+#else
+#define PLAT_SP_PRI			U(0x10)
+#endif
+
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+
+#define ARM_IRQ_SEC_SGI_0		U(8)
+#define ARM_IRQ_SEC_SGI_1		U(9)
+#define ARM_IRQ_SEC_SGI_2		U(10)
+#define ARM_IRQ_SEC_SGI_3		U(11)
+#define ARM_IRQ_SEC_SGI_4		U(12)
+#define ARM_IRQ_SEC_SGI_5		U(13)
+#define ARM_IRQ_SEC_SGI_6		U(14)
+#define ARM_IRQ_SEC_SGI_7		U(15)
+
+#define ARM_G0_IRQ_PROPS(grp)						\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI,		\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define ARM_G1S_IRQ_PROPS(grp)						\
+	INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_LEVEL),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE)
+
+#define ARM_G0_IRQ_PROPS(grp)						\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI,		\
+			(grp), GIC_INTR_CFG_EDGE),			\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+			(grp), GIC_INTR_CFG_EDGE)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+
+#define PLAT_ARM_GICD_BASE		NRD_CSS_GIC_BASE
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x00100000)
+#else
+#define PLAT_ARM_GICR_BASE		NRD_CSS_GIC_BASE + UL(0x001C0000)
+#endif
+
+/*******************************************************************************
+ * SDEI config
+ ******************************************************************************/
+
+#define PLAT_SDEI_CRITICAL_PRI		U(0x60)
+#define PLAT_SDEI_NORMAL_PRI		U(0x70)
+
+/* SGI used for SDEI signalling */
+#define ARM_SDEI_SGI			ARM_IRQ_SEC_SGI_0
+
+#if SDEI_IN_FCONF
+/* ARM SDEI dynamic private event max count */
+#define ARM_SDEI_DP_EVENT_MAX_CNT	U(3)
+
+/* ARM SDEI dynamic shared event max count */
+#define ARM_SDEI_DS_EVENT_MAX_CNT	U(3)
+#else
+/* ARM SDEI dynamic private event numbers */
+#define ARM_SDEI_DP_EVENT_0		UL(1000)
+#define ARM_SDEI_DP_EVENT_1		UL(1001)
+#define ARM_SDEI_DP_EVENT_2		UL(1002)
+
+/* ARM SDEI dynamic shared event numbers */
+#define ARM_SDEI_DS_EVENT_0		UL(2000)
+#define ARM_SDEI_DS_EVENT_1		UL(2001)
+#define ARM_SDEI_DS_EVENT_2		UL(2002)
+
+#define ARM_SDEI_PRIVATE_EVENTS						\
+	SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI),				\
+	SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_0,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),				\
+	SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_1,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),				\
+	SDEI_PRIVATE_EVENT(ARM_SDEI_DP_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+
+#define ARM_SDEI_SHARED_EVENTS						\
+	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_0,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),				\
+	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_1,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),				\
+	SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_2,				\
+	SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+#endif /* SDEI_IN_FCONF */
+
+/*******************************************************************************
+ * SDS config
+ ******************************************************************************/
+
+/* SDS ID for unusable CPU MPID list structure */
+#define SDS_ISOLATED_CPU_LIST_ID	U(128)
+
+/* Index of SDS region used in the communication with SCP */
+#define SDS_SCP_AP_REGION_ID		U(0)
+
+/*******************************************************************************
+ * SMMUv3 Config
+ ******************************************************************************/
+
+/* SMMUv3 root offset register */
+#define PLAT_ARM_SMMUV3_ROOT_REG_OFFSET	UL(0xA0000)
+
+/*******************************************************************************
+ * Platform type identification macro
+ ******************************************************************************/
+
+/* Platform ID related accessors */
+#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0F)
+#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK	U(0xF00)
+#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT	U(0x08)
+#define BOARD_CSS_PLAT_TYPE_RTL			U(0x00)
+#define BOARD_CSS_PLAT_TYPE_FPGA		U(0x01)
+#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
+#define BOARD_CSS_PLAT_TYPE_FVP			U(0x03)
+
+#ifndef __ASSEMBLER__
+#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
+	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
+	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
+#endif /* __ASSEMBLER__ */
+
+/* Platform ID address */
+#define BOARD_CSS_PLAT_ID_REG_ADDR	NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00FE00E0)
+
+/*******************************************************************************
+ * Flash config
+ ******************************************************************************/
+
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+#define V2M_SYS_LED			U(0x8)
+
+#define V2M_SYS_LED_SS_SHIFT		U(0)
+#define V2M_SYS_LED_EL_SHIFT		U(1)
+#define V2M_SYS_LED_EC_SHIFT		U(3)
+
+#define V2M_SYS_LED_SS_MASK		U(0x01)
+#define V2M_SYS_LED_EL_MASK		U(0x03)
+#define V2M_SYS_LED_EC_MASK		U(0x1f)
+
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
+
+#define V2M_SYSREGS_BASE		NRD_ROS_SYSTEM_PERIPH_BASE +	\
+						UL(0x00010000)
+#define V2M_FLASH0_BASE			NRD_ROS_SMC0_BASE
+#define V2M_FLASH0_SIZE			NRD_ROS_SMC0_SIZE
+#define V2M_FLASH_BLOCK_SIZE		UL(0x00040000)	/* 256 KB */
+
+#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
+#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE +	\
+					V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
+#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+
+/*******************************************************************************
+ * ROS peripheral config
+ ******************************************************************************/
+
+/* Non-volatile counters */
+#define SOC_TRUSTED_NVCTR_BASE		NRD_ROS_PLATFORM_PERIPH_BASE +	\
+						UL(0x00E70000)
+#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE	+ 0x0000)
+#define TFW_NVCTR_SIZE			U(4)
+#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0004)
+#define NTFW_CTR_SIZE			U(4)
+
+/*******************************************************************************
+ * SRAM layout
+ ******************************************************************************/
+
+/* if !RESET_TO_BL31
+ *              Trusted SRAM
+ * 0x00100000 +--------------+
+ *            |    L0 GPT    |
+ * 0x000E0000 +--------------+  loaded by BL2  +----------------+
+ *            |   BL1 (rw)   |  <<<<<<<<<<<<<  |                |
+ *            |--------------|  <<<<<<<<<<<<<  |  BL31 NOBITS   |
+ *            |     BL2      |  <<<<<<<<<<<<<  |                |
+ *            |--------------|  <<<<<<<<<<<<<  |----------------|
+ *            |              |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
+ *            |              |                 +----------------+
+ *            +--------------+
+ *            |    CONFIG    |
+ * 0x0001A000 +--------------+
+ *            |    Shared    |
+ * 0x00019000 +--------------+
+ *            |   BL1 (ro)   |
+ * 0x00000000 +--------------+
+ *
+ * else
+ *
+ *              Trusted SRAM
+ * 0x00100000 +--------------+
+ *            |    L0 GPT    |
+ * 0x000E0000 +--------------
+ *            |              |  side-loaded    +----------------+
+ *            |              |  <<<<<<<<<<<<<  |                |
+ *            |              |  <<<<<<<<<<<<<  |  BL31 NOBITS   |
+ *            |              |  <<<<<<<<<<<<<  |                |
+ *            |              |  <<<<<<<<<<<<<  |----------------|
+ *            |              |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
+ * 0x00063000 |              |                 +----------------+
+ * 0x0001A000 +--------------+
+ *            |    Shared    |
+ * 0x00019000 +--------------+
+ *            |   BL1 (ro)   |
+ * 0x00000000 +--------------+
+ * endif
+ */
+
+/*******************************************************************************
+ * BL1 RO specifics
+ ******************************************************************************/
+
+/*
+ * SRAM region to store BL1 code and RO. This has been carved out at the bottom
+ * of SRAM
+ */
+
+#define BL1_RO_BASE			NRD_CSS_BL1_RO_BASE
+#define BL1_RO_LIMIT			(NRD_CSS_BL1_RO_BASE		\
+					 + NRD_CSS_BL1_RO_SIZE)
+
+/*******************************************************************************
+ * L0 GPT specifics
+ ******************************************************************************/
+
+/*
+ * L0 GPT has to be aligned to its size. In order to avoid holes due to
+ * alignment, place L0 GPT at the top of SRAM.
+ */
+#define ARM_L0_GPT_SIZE			UL(0x00020000) /* 128KB */
+#define ARM_L0_GPT_BASE			NRD_CSS_SHARED_SRAM_SIZE -	\
+					ARM_L0_GPT_SIZE
+
+#define ARM_L0_GPT_LIMIT		(ARM_L0_GPT_BASE + ARM_L0_GPT_SIZE)
+
+/*******************************************************************************
+ * Arm shared RAM specifics
+ ******************************************************************************/
+
+#define ARM_SHARED_RAM_BASE		(NRD_CSS_BL1_RO_BASE +		\
+					 NRD_CSS_BL1_RO_SIZE)
+#define ARM_SHARED_RAM_SIZE		UL(0x00001000)	/* 4 KB */
+
+/*******************************************************************************
+ * Arm BL RAM specifics
+ ******************************************************************************/
+
+/*Rest of SRAM till L0 GPT base */
+#define ARM_BL_RAM_BASE			(ARM_SHARED_RAM_BASE +		\
+					 ARM_SHARED_RAM_SIZE)
+#define ARM_BL_RAM_SIZE			(ARM_L0_GPT_BASE -		\
+					 ARM_BL_RAM_BASE)
+
+/*******************************************************************************
+ * FW_CONFIG specifics
+ ******************************************************************************/
+
+/*
+ * To enable FW_CONFIG to be loaded by BL1, define the corresponding base
+ * and limit. Leave enough space of BL2 meminfo.
+ */
+#define ARM_FW_CONFIG_BASE		(ARM_BL_RAM_BASE + sizeof(meminfo_t))
+#define ARM_FW_CONFIG_LIMIT		((ARM_BL_RAM_BASE + PAGE_SIZE) \
+					+ (PAGE_SIZE / 2U))
+
+/*
+ * Boot parameters passed from BL2 to BL31/BL32 are stored here
+ */
+#define ARM_BL2_MEM_DESC_BASE		(ARM_FW_CONFIG_LIMIT)
+#define ARM_BL2_MEM_DESC_LIMIT		(ARM_BL2_MEM_DESC_BASE		\
+					+ (PAGE_SIZE / 2U))
+
+/*
+ * Define limit of firmware configuration memory:
+ * ARM_FW_CONFIG + ARM_BL2_MEM_DESC memory
+ */
+#define ARM_FW_CONFIGS_SIZE		(PAGE_SIZE * 2)
+#if RESET_TO_BL31
+#define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE)
+#else
+#define ARM_FW_CONFIGS_LIMIT		(ARM_BL_RAM_BASE + ARM_FW_CONFIGS_SIZE)
+#endif
+
+/*******************************************************************************
+ * BL1 RW specifics
+ ******************************************************************************/
+
+#define BL1_RW_BASE			(ARM_BL_RAM_BASE +		\
+					 ARM_BL_RAM_SIZE -		\
+					 PLAT_ARM_MAX_BL1_RW_SIZE)
+#define BL1_RW_LIMIT			(ARM_BL_RAM_BASE +		\
+					 ARM_BL_RAM_SIZE)
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+
+/* Put BL2 just below BL1. */
+#define BL2_BASE			(BL1_RW_BASE - PLAT_ARM_MAX_BL2_SIZE)
+#define BL2_LIMIT			BL1_RW_BASE
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+
+/* Keep BL31 below BL2 in the Trusted SRAM.*/
+#if RESET_TO_BL31
+#define BL31_BASE			(0x63000)
+#else
+#define BL31_BASE			((ARM_BL_RAM_BASE +		\
+					  ARM_BL_RAM_SIZE) -		\
+					  PLAT_ARM_MAX_BL31_SIZE)
+#endif
+#define BL31_PROGBITS_LIMIT		BL2_BASE
+#define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+
+/*
+ * The max number of regions like RO(code), coherent and data required by
+ * different BL stages which need to be mapped in the MMU.
+ */
+#define ARM_BL_REGIONS			7
+
+#define MAX_MMAP_REGIONS		(PLAT_ARM_MMAP_ENTRIES +	\
+					 ARM_BL_REGIONS)
+
+/*******************************************************************************
+ * DRAM layout
+ ******************************************************************************/
+
+/*
+ * The top 100MB of DRAM1 is configured as follows:
+ *   - L1 GPT DRAM: Reserved for L1 GPT if RME is enabled
+ *   - TF-A <-> RMM SHARED: Area shared for communication between TF-A and RMM
+ *   - REALM DRAM: Reserved for Realm world if RME is enabled
+ *
+ *                    DRAM layout
+ *               +------------------+
+ *               |   REALM (RMM)    |
+ *               |   (32MB - 4KB)   |
+ *               +------------------+
+ *               |                  |
+ *               |   TF-A <-> RMM   |
+ *               |   SHARED (4KB)   |
+ *               +------------------+
+ *               |       L1 GPT     |
+ *               |                  |
+ *     DRAM1 End +------------------+
+ */
+
+/* Number of DRAM banks */
+#if (NRD_PLATFORM_VARIANT == 2)
+#define ARM_DRAM_NUM_BANKS		U(8)
+#else
+#define ARM_DRAM_NUM_BANKS		U(2)
+#endif
+
+/*******************************************************************************
+ * DRAM bank1 specific defines.
+ ******************************************************************************/
+
+/* Bank-1 DRAM */
+#define ARM_DRAM1_BASE			UL(0x80000000)
+#define ARM_DRAM1_SIZE			UL(0x80000000)
+#define ARM_DRAM1_END			(ARM_DRAM1_BASE +		\
+					 ARM_DRAM1_SIZE - 1U)
+
+/*******************************************************************************
+ * DRAM bank2 specific defines.
+ ******************************************************************************/
+
+/* Bank-2 DRAM */
+#define ARM_DRAM2_BASE			PLAT_ARM_DRAM2_BASE
+#define ARM_DRAM2_SIZE			PLAT_ARM_DRAM2_SIZE
+#define ARM_DRAM2_END			(ARM_DRAM2_BASE +		\
+					 ARM_DRAM2_SIZE - 1U)
+
+/*******************************************************************************
+ * L1GPT specific defines.
+ ******************************************************************************/
+
+/* 2MB per L1 entry, PPS - 48 bits, PGS - 4KB, L0GPTSZ - 16GB */
+#define ARM_L1_GPT_SIZE			(UL(40 * 1024 * 1024) +		\
+					((NRD_CHIP_COUNT - 1) *		\
+					(4 * 1024 * 1024)))
+
+#define ARM_L1_GPT_BASE			(ARM_DRAM1_BASE +		\
+					 ARM_DRAM1_SIZE -		\
+					 ARM_L1_GPT_SIZE)
+#define ARM_L1_GPT_END			(ARM_L1_GPT_BASE +		\
+					 ARM_L1_GPT_SIZE - 1U)
+
+/*******************************************************************************
+ * "RMM TF-A shared region" specific defines.
+ ******************************************************************************/
+
+/* PLAT_ARM_EL3_RMM_SHARED_SIZE */
+#define ARM_EL3_RMM_SHARED_SIZE		(PAGE_SIZE)    /* 4KB */
+
+#define ARM_EL3_RMM_SHARED_BASE		(ARM_L1_GPT_BASE -		\
+					 ARM_EL3_RMM_SHARED_SIZE)
+
+#define ARM_EL3_RMM_SHARED_END		(ARM_EL3_RMM_SHARED_BASE +	\
+					 ARM_EL3_RMM_SHARED_SIZE - 1U)
+
+/*******************************************************************************
+ * RMM specific defines.
+ ******************************************************************************/
+
+/* ARM_REALM_SIZE */
+#define ARM_REALM_SIZE			(UL(0x02600000) -		\
+					 ARM_EL3_RMM_SHARED_SIZE)
+#define ARM_REALM_BASE			(ARM_EL3_RMM_SHARED_BASE -	\
+					 ARM_REALM_SIZE)
+
+#define ARM_REALM_END			(ARM_REALM_BASE + ARM_REALM_SIZE - 1U)
+
+#define RMM_BASE			(ARM_REALM_BASE)
+#define RMM_LIMIT			(RMM_BASE + ARM_REALM_SIZE)
+#define RMM_SHARED_BASE			(ARM_EL3_RMM_SHARED_BASE)
+#define RMM_SHARED_SIZE			(ARM_EL3_RMM_SHARED_SIZE)
+
+/*******************************************************************************
+ * NRD_CSS_CARVEOUT_RESERVED region specific defines.
+ ******************************************************************************/
+
+#define NRD_CSS_CARVEOUT_RESERVED_BASE	(ARM_DRAM1_BASE +		\
+					 ARM_DRAM1_SIZE -		\
+					 NRD_CSS_DRAM1_CARVEOUT_SIZE)
+#define NRD_CSS_CARVEOUT_RESERVED_SIZE	(NRD_CSS_DRAM1_CARVEOUT_SIZE -	\
+					(ARM_EL3_RMM_SHARED_SIZE +	\
+					 ARM_REALM_SIZE +		\
+					 ARM_L1_GPT_SIZE))
+
+#define NRD_CSS_CARVEOUT_RESERVED_END	(NRD_CSS_CARVEOUT_RESERVED_BASE +\
+					 NRD_CSS_CARVEOUT_RESERVED_SIZE - 1U)
+
+/*******************************************************************************
+ * NS RAM specific defines specific defines.
+ ******************************************************************************/
+
+#define ARM_NS_DRAM1_BASE		ARM_DRAM1_BASE
+#define ARM_NS_DRAM1_SIZE		(ARM_DRAM1_SIZE -		\
+					 NRD_CSS_DRAM1_CARVEOUT_SIZE)
+
+#define ARM_NS_DRAM1_END		(ARM_NS_DRAM1_BASE +		\
+					 ARM_NS_DRAM1_SIZE - 1U)
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define V2M_MAP_FLASH0_RW						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define V2M_MAP_FLASH0_RO						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_RO_DATA | EL3_PAS)
+
+#define ARM_MAP_L0_GPT_REGION						\
+		MAP_REGION_FLAT(					\
+			ARM_L0_GPT_BASE,				\
+			ARM_L0_GPT_SIZE,				\
+			MT_MEMORY | MT_RW | MT_ROOT)
+
+#define ARM_MAP_BL_CONFIG_REGION					\
+		MAP_REGION_FLAT(					\
+			ARM_BL_RAM_BASE,				\
+			(ARM_FW_CONFIGS_LIMIT - ARM_BL_RAM_BASE),	\
+			MT_MEMORY | MT_RW | EL3_PAS)
+
+#if SEPARATE_CODE_AND_RODATA
+#define ARM_MAP_BL_RO							\
+		MAP_REGION_FLAT(					\
+			BL_CODE_BASE,					\
+			(BL_CODE_END - BL_CODE_BASE),			\
+			MT_CODE | EL3_PAS),				\
+		MAP_REGION_FLAT(					\
+			BL_RO_DATA_BASE,				\
+			(BL_RO_DATA_END - BL_RO_DATA_BASE),		\
+			MT_RO_DATA | EL3_PAS)
+#else
+#define ARM_MAP_BL_RO							\
+		MAP_REGION_FLAT(					\
+			BL_CODE_BASE,					\
+			(BL_CODE_END - BL_CODE_BASE),			\
+			MT_CODE | EL3_PAS)
+#endif
+
+#if USE_COHERENT_MEM
+#define ARM_MAP_BL_COHERENT_RAM						\
+		MAP_REGION_FLAT(					\
+			BL_COHERENT_RAM_BASE,				\
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,	\
+			MT_DEVICE | MT_RW | EL3_PAS)
+#endif
+
+#define ARM_MAP_DRAM2							\
+		MAP_REGION_FLAT(					\
+			ARM_DRAM2_BASE,					\
+			ARM_DRAM2_SIZE,					\
+			MT_MEMORY | MT_RW | MT_NS)
+
+#endif /* NRD_PLAT_ARM_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h
new file mode 100644
index 00000000..c9876217
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_def3.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file contains the RoS specific definitions for the third generation of
+ * platforms.
+ */
+
+#ifndef NRD_ROS_DEF3_H
+#define NRD_ROS_DEF3_H
+
+/*******************************************************************************
+ * RoS memory map related defines
+ ******************************************************************************/
+
+/* System peripherals */
+#define NRD_ROS_SYSTEM_PERIPH_BASE		UL(0x0C000000)
+#define NRD_ROS_SYSTEM_PERIPH_SIZE		UL(0x02000000)
+
+/* Platform peripherals */
+#define NRD_ROS_PLATFORM_PERIPH_BASE		UL(0x0E000000)
+#define NRD_ROS_PLATFORM_PERIPH_SIZE		UL(0x02000000)
+
+/* SMC0 */
+#define NRD_ROS_SMC0_BASE			UL(0x08000000)
+#define NRD_ROS_SMC0_SIZE			UL(0x04000000)
+
+#endif /* NRD_ROS_DEF3_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h
new file mode 100644
index 00000000..c0fde85d
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_ros_fw_def3.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is limited to include the RoS firmware specific definitions for the
+ * third generation of platforms. RoS (Rest Of System) is used to refer to the
+ * part of the reference design platform that excludes CSS.
+ */
+
+#ifndef NRD_ROS_FW_DEF3_H
+#define NRD_ROS_FW_DEF3_H
+
+#include <nrd_ros_def3.h>
+
+/*******************************************************************************
+ * MMU mapping
+ ******************************************************************************/
+
+#define NRD_ROS_PLATFORM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_PLATFORM_PERIPH_BASE,			\
+			NRD_ROS_PLATFORM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_SYSTEM_PERIPH_MMAP					\
+		MAP_REGION_FLAT(					\
+			NRD_ROS_SYSTEM_PERIPH_BASE,			\
+			NRD_ROS_SYSTEM_PERIPH_SIZE,			\
+			MT_DEVICE | MT_RW | MT_SECURE)
+
+#define NRD_ROS_V2M_MEM_PROTECT_MMAP					\
+		MAP_REGION_FLAT(					\
+			PLAT_ARM_MEM_PROT_ADDR,				\
+			V2M_FLASH_BLOCK_SIZE,				\
+			MT_DEVICE | MT_RW | EL3_PAS)
+
+#define NRD_ROS_FLASH0_RO_MMAP						\
+		MAP_REGION_FLAT(					\
+			V2M_FLASH0_BASE,				\
+			V2M_FLASH0_SIZE,				\
+			MT_DEVICE | MT_RO | MT_SECURE)
+
+#endif /* NRD_ROS_FW_DEF3_H */
diff --git a/plat/arm/css/sgi/include/sgi_dmc620_tzc_regions.h b/plat/arm/board/neoverse_rd/common/include/nrd_dmc620_tzc_regions.h
similarity index 72%
rename from plat/arm/css/sgi/include/sgi_dmc620_tzc_regions.h
rename to plat/arm/board/neoverse_rd/common/include/nrd_dmc620_tzc_regions.h
index e9391631..c63d7505 100644
--- a/plat/arm/css/sgi/include/sgi_dmc620_tzc_regions.h
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_dmc620_tzc_regions.h
@@ -1,16 +1,16 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef SGI_DMC620_TZC_REGIONS_H
-#define SGI_DMC620_TZC_REGIONS_H
+#ifndef NRD_DMC620_TZC_REGIONS_H
+#define NRD_DMC620_TZC_REGIONS_H
 
 #include <drivers/arm/tzc_dmc620.h>
 
 #if SPM_MM
-#define CSS_SGI_DMC620_TZC_REGIONS_DEF				\
+#define NRD_DMC620_TZC_REGIONS_DEF				\
 	{							\
 		.region_base = ARM_AP_TZC_DRAM1_BASE,		\
 		.region_top = PLAT_SP_IMAGE_NS_BUF_BASE - 1,	\
@@ -25,7 +25,7 @@
 		.sec_attr = TZC_DMC620_REGION_S_RDWR		\
 	}
 #else
-#define CSS_SGI_DMC620_TZC_REGIONS_DEF				\
+#define NRD_DMC620_TZC_REGIONS_DEF				\
 	{							\
 		.region_base = ARM_AP_TZC_DRAM1_BASE,		\
 		.region_top = ARM_AP_TZC_DRAM1_END,		\
@@ -33,4 +33,4 @@
 	}
 #endif /* SPM_MM */
 
-#endif /* SGI_DMC620_TZC_REGIONS_H */
+#endif /* NRD_DMC620_TZC_REGIONS_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd_plat.h b/plat/arm/board/neoverse_rd/common/include/nrd_plat.h
new file mode 100644
index 00000000..775f233a
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_plat.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NRD_PLAT_H
+#define NRD_PLAT_H
+
+/* BL31 platform setup common to all Neoverse RD platforms */
+void nrd_bl31_common_platform_setup(void);
+
+#endif /* NRD_PLAT_H */
diff --git a/plat/arm/css/sgi/include/sgi_ras.h b/plat/arm/board/neoverse_rd/common/include/nrd_ras.h
similarity index 66%
rename from plat/arm/css/sgi/include/sgi_ras.h
rename to plat/arm/board/neoverse_rd/common/include/nrd_ras.h
index d311807e..768689c0 100644
--- a/plat/arm/css/sgi/include/sgi_ras.h
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_ras.h
@@ -1,22 +1,22 @@
 /*
- * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef SGI_RAS_H
-#define SGI_RAS_H
+#ifndef NRD_RAS_H
+#define NRD_RAS_H
 
 #include <lib/extensions/ras.h>
 #include <plat/common/platform.h>
 
 /*
  * Interrupt type supported.
- * - SGI_RAS_INTR_TYPE_SPI: Denotes a SPI interrupt
- * - SGI_RAS_INTR_TYPE_PPI: Denotes a PPI interrupt
+ * - NRD_RAS_INTR_TYPE_SPI: Denotes a SPI interrupt
+ * - NRD_RAS_INTR_TYPE_PPI: Denotes a PPI interrupt
  */
-#define SGI_RAS_INTR_TYPE_SPI 0
-#define SGI_RAS_INTR_TYPE_PPI 1
+#define NRD_RAS_INTR_TYPE_SPI 0
+#define NRD_RAS_INTR_TYPE_PPI 1
 
 /*
  * MM Communicate information structure. Required to generate MM Communicate
@@ -29,15 +29,15 @@ typedef struct mm_communicate_header {
 } mm_communicate_header_t;
 
 /* RAS error info data structure. */
-struct sgi_ras_ev_map {
+struct nrd_ras_ev_map {
 	int sdei_ev_num;	/* SDEI Event number */
 	int intr;		/* Physical intr number */
 	int intr_type;          /* Interrupt Type (SPI or PPI)*/
 };
 
 /* RAS config data structure. Must be defined by each platform. */
-struct plat_sgi_ras_config {
-	struct sgi_ras_ev_map *ev_map;
+struct plat_nrd_ras_config {
+	struct nrd_ras_ev_map *ev_map;
 	int ev_map_size;
 };
 
@@ -45,7 +45,7 @@ struct plat_sgi_ras_config {
  * Find event map for a given interrupt number. On success, returns pointer
  * to the event map. On error, returns NULL.
  */
-struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num);
+struct nrd_ras_ev_map *nrd_find_ras_event_map_by_intr(uint32_t intr_num);
 
 /*
  * Initialization function for the framework.
@@ -53,16 +53,16 @@ struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num);
  * Registers RAS config provided by the platform and then configures and
  * enables interrupt for each registered error. On success, return 0.
  */
-int sgi_ras_platform_setup(struct plat_sgi_ras_config *config);
+int nrd_ras_platform_setup(struct plat_nrd_ras_config *config);
 
 /* Base element RAM RAS interrupt handler function. */
-int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
+int nrd_ras_sram_intr_handler(const struct err_record_info *err_rec,
 				int probe_data,
 				const struct err_handler_data *const data);
 
 /* CPU RAS interrupt handler */
-int sgi_ras_cpu_intr_handler(const struct err_record_info *err_rec,
+int nrd_ras_cpu_intr_handler(const struct err_record_info *err_rec,
 				int probe_data,
 				const struct err_handler_data *const data);
 
-#endif /* SGI_RAS_H */
+#endif /* NRD_RAS_H */
diff --git a/plat/arm/board/neoverse_rd/common/include/nrd_sdei.h b/plat/arm/board/neoverse_rd/common/include/nrd_sdei.h
new file mode 100644
index 00000000..f1b60154
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_sdei.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NRD_SDEI_H
+#define NRD_SDEI_H
+
+#if SDEI_SUPPORT
+
+/* ARM SDEI dynamic shared event numbers */
+#define NRD_SDEI_DS_EVENT_0		U(804)
+#define NRD_SDEI_DS_EVENT_1		U(805)
+
+#define PLAT_ARM_PRIVATE_SDEI_EVENTS					      \
+		SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI),			      \
+		SDEI_EXPLICIT_EVENT(NRD_SDEI_DS_EVENT_0, SDEI_MAPF_CRITICAL), \
+		SDEI_EXPLICIT_EVENT(NRD_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL),
+
+#define PLAT_ARM_SHARED_SDEI_EVENTS
+
+#endif /* SDEI_SUPPORT */
+
+#endif /* NRD_SDEI_H */
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/board/neoverse_rd/common/include/nrd_variant.h
similarity index 60%
rename from plat/arm/css/sgi/include/sgi_variant.h
rename to plat/arm/board/neoverse_rd/common/include/nrd_variant.h
index 8f9529aa..86d82e27 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/board/neoverse_rd/common/include/nrd_variant.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef SGI_VARIANT_H
-#define SGI_VARIANT_H
+#ifndef NRD_VARIANT_H
+#define NRD_VARIANT_H
 
 /* SSC_VERSION values for SGI575 */
 #define SGI575_SSC_VER_PART_NUM			0x0783
@@ -28,23 +28,31 @@
 #define RD_V2_SID_VER_PART_NUM			0x07F2
 #define RD_V2_CONFIG_ID				0x1
 
-/* Structure containing SGI platform variant information */
-typedef struct sgi_platform_info {
+/* SID Version values for RD-V3 */
+#define RD_V3_SID_VER_PART_NUM		0x07EE
+#define RD_V3_CONFIG_ID			0x0
+
+/* SID Version values for RD-V3 variants */
+#define RD_V3_CFG1_SID_VER_PART_NUM	0x07F9
+#define RD_V3_CFG2_SID_VER_PART_NUM	0x07EE
+
+/* Structure containing Neoverse RD platform variant information */
+typedef struct nrd_platform_info {
 	unsigned int platform_id;	/* Part Number of the platform */
 	unsigned int config_id;		/* Config Id of the platform */
 	unsigned int chip_id;		/* Chip Id or Node number */
 	unsigned int multi_chip_mode;	/* Multi-chip mode availability */
-} sgi_platform_info_t;
+} nrd_platform_info_t;
 
-extern sgi_platform_info_t sgi_plat_info;
+extern nrd_platform_info_t nrd_plat_info;
 
 /* returns the part number of the platform*/
-unsigned int plat_arm_sgi_get_platform_id(void);
+unsigned int plat_arm_nrd_get_platform_id(void);
 
 /* returns the configuration id of the platform */
-unsigned int plat_arm_sgi_get_config_id(void);
+unsigned int plat_arm_nrd_get_config_id(void);
 
 /* returns true if operating in multi-chip configuration */
-unsigned int plat_arm_sgi_get_multi_chip_mode(void);
+unsigned int plat_arm_nrd_get_multi_chip_mode(void);
 
-#endif /* SGI_VARIANT_H */
+#endif /* NRD_VARIANT_H */
diff --git a/plat/arm/css/sgi/include/plat_macros.S b/plat/arm/board/neoverse_rd/common/include/plat_macros.S
similarity index 86%
rename from plat/arm/css/sgi/include/plat_macros.S
rename to plat/arm/board/neoverse_rd/common/include/plat_macros.S
index 521bcc32..df7cfb63 100644
--- a/plat/arm/css/sgi/include/plat_macros.S
+++ b/plat/arm/board/neoverse_rd/common/include/plat_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/board/neoverse_rd/common/nrd-common.mk
similarity index 61%
rename from plat/arm/css/sgi/sgi-common.mk
rename to plat/arm/board/neoverse_rd/common/nrd-common.mk
index 2cd70342..a09f369c 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/board/neoverse_rd/common/nrd-common.mk
@@ -1,12 +1,12 @@
 #
-# Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 CSS_USE_SCMI_SDS_DRIVER		:=	1
 
-CSS_ENT_BASE			:=	plat/arm/css/sgi
+NRD_COMMON_BASE			:=	plat/arm/board/neoverse_rd/common
 
 ENABLE_FEAT_RAS			:=	1
 
@@ -16,18 +16,18 @@ EL3_EXCEPTION_HANDLING		:=	0
 
 HANDLE_EA_EL3_FIRST_NS		:=	0
 
-CSS_SGI_CHIP_COUNT		:=	1
+NRD_CHIP_COUNT		:=	1
 
-CSS_SGI_PLATFORM_VARIANT	:=	0
+NRD_PLATFORM_VARIANT	:=	0
 
 # Do not enable SVE
 ENABLE_SVE_FOR_NS		:=	0
 
 CTX_INCLUDE_FPREGS		:=	1
 
-INTERCONNECT_SOURCES	:=	${CSS_ENT_BASE}/sgi_interconnect.c
+INTERCONNECT_SOURCES	:=	${NRD_COMMON_BASE}/nrd_interconnect.c
 
-PLAT_INCLUDES		+=	-I${CSS_ENT_BASE}/include
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include
 
 # GIC-600 configuration
 GICV3_SUPPORT_GIC600	:=	1
@@ -39,29 +39,24 @@ ENT_GIC_SOURCES		:=	${GICV3_SOURCES}		\
 				plat/common/plat_gicv3.c	\
 				plat/arm/common/arm_gicv3.c
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/aarch64/sgi_helper.S
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/arch/aarch64/nrd_helper.S
 
 BL1_SOURCES		+=	${INTERCONNECT_SOURCES}			\
+				${NRD_COMMON_BASE}/nrd_bl1_setup.c	\
 				drivers/arm/sbsa/sbsa.c
 
-BL2_SOURCES		+=	${CSS_ENT_BASE}/sgi_image_load.c	\
+BL2_SOURCES		+=	${NRD_COMMON_BASE}/nrd_image_load.c	\
 				drivers/arm/css/sds/sds.c
 
 BL31_SOURCES		+=	${INTERCONNECT_SOURCES}			\
 				${ENT_GIC_SOURCES}			\
-				${CSS_ENT_BASE}/sgi_bl31_setup.c	\
-				${CSS_ENT_BASE}/sgi_topology.c
+				${NRD_COMMON_BASE}/nrd_bl31_setup.c	\
+				${NRD_COMMON_BASE}/nrd_topology.c	\
+				drivers/delay_timer/generic_delay_timer.c
 
-ifneq (${RESET_TO_BL31},0)
-  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
-  Please set RESET_TO_BL31 to 0.")
-endif
+$(eval $(call add_define,NRD_CHIP_COUNT))
 
-$(eval $(call add_define,SGI_PLAT))
-
-$(eval $(call add_define,CSS_SGI_CHIP_COUNT))
-
-$(eval $(call add_define,CSS_SGI_PLATFORM_VARIANT))
+$(eval $(call add_define,NRD_PLATFORM_VARIANT))
 
 override CSS_LOAD_SCP_IMAGES	:=	0
 override NEED_BL2U		:=	no
@@ -78,5 +73,4 @@ USE_COHERENT_MEM	:=	0
 
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
-include plat/arm/soc/common/soc_css.mk
 include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/neoverse_rd/common/nrd_bl1_setup.c b/plat/arm/board/neoverse_rd/common/nrd_bl1_setup.c
new file mode 100644
index 00000000..a0f656f4
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/nrd_bl1_setup.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/soc/common/soc_css.h>
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+
+void soc_css_init_nic400(void)
+{
+}
+
+void soc_css_init_pcie(void)
+{
+}
diff --git a/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
new file mode 100644
index 00000000..bce88347
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/nrd_bl31_setup.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <libfdt.h>
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <drivers/generic_delay_timer.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+#include <plat/common/platform.h>
+
+#include <nrd_ras.h>
+#include <nrd_variant.h>
+
+nrd_platform_info_t nrd_plat_info;
+
+static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+};
+
+static scmi_channel_plat_info_t plat_rd_scmi_info[] = {
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#if (NRD_CHIP_COUNT > 1)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(1),
+		.db_reg_addr = PLAT_CSS_MHU_BASE
+			+ NRD_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 2)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(2),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 3)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(3),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+			NRD_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhuv2_ring_doorbell,
+	},
+	#endif
+};
+
+static scmi_channel_plat_info_t plat3_rd_scmi_info[] = {
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#if (NRD_CHIP_COUNT > 1)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(1),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(1) +
+					MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 2)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(2),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(2) +
+					MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#endif
+	#if (NRD_CHIP_COUNT > 3)
+	{
+		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(3),
+		.db_reg_addr = PLAT_CSS_MHU_BASE +
+					NRD_REMOTE_CHIP_MEM_OFFSET(3) +
+					MHU_V3_SENDER_REG_SET(0),
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+	},
+	#endif
+};
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
+{
+	if (nrd_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_N2_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_V2_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_N2_CFG3_SID_VER_PART_NUM) {
+		if (channel_id >= ARRAY_SIZE(plat_rd_scmi_info)) {
+			panic();
+		}
+		return &plat_rd_scmi_info[channel_id];
+	} else if (nrd_plat_info.platform_id == RD_V3_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_V3_CFG1_SID_VER_PART_NUM ||
+		nrd_plat_info.platform_id == RD_V3_CFG2_SID_VER_PART_NUM) {
+		if (channel_id >= ARRAY_SIZE(plat3_rd_scmi_info)) {
+			panic();
+		}
+		return &plat3_rd_scmi_info[channel_id];
+	} else if (nrd_plat_info.platform_id == SGI575_SSC_VER_PART_NUM) {
+		return &sgi575_scmi_plat_info;
+	} else {
+		panic();
+	}
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	nrd_plat_info.platform_id = plat_arm_nrd_get_platform_id();
+	nrd_plat_info.config_id = plat_arm_nrd_get_config_id();
+	nrd_plat_info.multi_chip_mode = plat_arm_nrd_get_multi_chip_mode();
+
+	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+}
+
+/*******************************************************************************
+ * This function inserts platform information via device tree nodes as,
+ * system-id {
+ *    platform-id = <0>;
+ *    config-id = <0>;
+ * }
+ ******************************************************************************/
+#if RESET_TO_BL31
+static int append_config_node(uintptr_t fdt_base_addr, uintptr_t fdt_base_size)
+{
+	void *fdt;
+	int nodeoffset, err;
+	unsigned int platid = 0, platcfg = 0;
+
+	if (fdt_base_addr == 0) {
+		ERROR("NT_FW CONFIG base address is NULL\n");
+		return -1;
+	}
+
+	fdt = (void *)fdt_base_addr;
+
+	/* Check the validity of the fdt */
+	if (fdt_check_header(fdt) != 0) {
+		ERROR("Invalid NT_FW_CONFIG DTB passed\n");
+		return -1;
+	}
+
+	nodeoffset = fdt_subnode_offset(fdt, 0, "system-id");
+	if (nodeoffset < 0) {
+		ERROR("Failed to get system-id node offset\n");
+		return -1;
+	}
+
+	platid = plat_arm_nrd_get_platform_id();
+	err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid);
+	if (err < 0) {
+		ERROR("Failed to set platform-id\n");
+		return -1;
+	}
+
+	platcfg = plat_arm_nrd_get_config_id();
+	err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg);
+	if (err < 0) {
+		ERROR("Failed to set config-id\n");
+		return -1;
+	}
+
+	platcfg = plat_arm_nrd_get_multi_chip_mode();
+	err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
+	if (err < 0) {
+		ERROR("Failed to set multi-chip-mode\n");
+		return -1;
+	}
+
+	flush_dcache_range((uintptr_t)fdt, fdt_base_size);
+	return 0;
+}
+#endif
+
+void nrd_bl31_common_platform_setup(void)
+{
+	generic_delay_timer_init();
+
+	arm_bl31_platform_setup();
+
+	/* Configure the warm reboot SGI for primary core */
+	css_setup_cpu_pwr_down_intr();
+
+#if CSS_SYSTEM_GRACEFUL_RESET
+	/* Register priority level handlers for reboot */
+	ehf_register_priority_handler(PLAT_REBOOT_PRI,
+			css_reboot_interrupt_handler);
+#endif
+
+#if RESET_TO_BL31
+	int ret = append_config_node(NRD_CSS_BL31_PRELOAD_DTB_BASE,
+			NRD_CSS_BL31_PRELOAD_DTB_SIZE);
+
+	if (ret != 0) {
+		panic();
+	}
+#endif
+}
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+	/*
+	 * For RD-E1-Edge, only CPU power ON/OFF, PSCI platform callbacks are
+	 * supported.
+	 */
+	if (((nrd_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
+	    (nrd_plat_info.config_id == RD_E1_EDGE_CONFIG_ID))) {
+		ops->cpu_standby = NULL;
+		ops->system_off = NULL;
+		ops->system_reset = NULL;
+		ops->get_sys_suspend_power_state = NULL;
+		ops->pwr_domain_suspend = NULL;
+		ops->pwr_domain_suspend_finish = NULL;
+	}
+
+	return css_scmi_override_pm_ops(ops);
+}
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/board/neoverse_rd/common/nrd_image_load.c
similarity index 84%
rename from plat/arm/css/sgi/sgi_image_load.c
rename to plat/arm/board/neoverse_rd/common/nrd_image_load.c
index ac4bfd29..15d90beb 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_image_load.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,10 +12,9 @@
 #include <drivers/arm/css/sds.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-
 #include <platform_def.h>
-#include <sgi_base_platform_def.h>
-#include <sgi_variant.h>
+
+#include <nrd_variant.h>
 
 /*
  * Information about the isolated CPUs obtained from SDS.
@@ -26,17 +25,18 @@ struct isolated_cpu_mpid_list {
 };
 
 /* Function to read isolated CPU MPID list from SDS. */
-void plat_arm_sgi_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
+void plat_arm_nrd_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
 {
 	int ret;
 
-	ret = sds_init();
+	ret = sds_init(SDS_SCP_AP_REGION_ID);
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed, error: %d\n", ret);
 		panic();
 	}
 
-	ret = sds_struct_read(SDS_ISOLATED_CPU_LIST_ID, 0, &list->num_entries,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+			SDS_ISOLATED_CPU_LIST_ID, 0, &list->num_entries,
 			sizeof(list->num_entries), SDS_ACCESS_MODE_CACHED);
 	if (ret != SDS_OK) {
 		INFO("SDS CPU num elements read failed, error: %d\n", ret);
@@ -54,7 +54,8 @@ void plat_arm_sgi_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
 		return;
 	}
 
-	ret = sds_struct_read(SDS_ISOLATED_CPU_LIST_ID,
+	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
+			SDS_ISOLATED_CPU_LIST_ID,
 			sizeof(list->num_entries),
 			&list->mpid_list,
 			sizeof(list->mpid_list[0]) * list->num_entries,
@@ -73,7 +74,7 @@ void plat_arm_sgi_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
  *    isolated-cpu-list = <0>
  * }
  ******************************************************************************/
-static int plat_sgi_append_config_node(void)
+static int plat_nrd_append_config_node(void)
 {
 	bl_mem_params_node_t *mem_params;
 	void *fdt;
@@ -101,28 +102,28 @@ static int plat_sgi_append_config_node(void)
 		return -1;
 	}
 
-	platid = plat_arm_sgi_get_platform_id();
+	platid = plat_arm_nrd_get_platform_id();
 	err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid);
 	if (err < 0) {
 		ERROR("Failed to set platform-id\n");
 		return -1;
 	}
 
-	platcfg = plat_arm_sgi_get_config_id();
+	platcfg = plat_arm_nrd_get_config_id();
 	err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg);
 	if (err < 0) {
 		ERROR("Failed to set config-id\n");
 		return -1;
 	}
 
-	platcfg = plat_arm_sgi_get_multi_chip_mode();
+	platcfg = plat_arm_nrd_get_multi_chip_mode();
 	err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
 	if (err < 0) {
 		ERROR("Failed to set multi-chip-mode\n");
 		return -1;
 	}
 
-	plat_arm_sgi_get_isolated_cpu_list(&cpu_mpid_list);
+	plat_arm_nrd_get_isolated_cpu_list(&cpu_mpid_list);
 	if (cpu_mpid_list.num_entries > 0) {
 		err = fdt_setprop(fdt, nodeoffset, "isolated-cpu-list",
 				&cpu_mpid_list,
@@ -146,10 +147,9 @@ bl_params_t *plat_get_next_bl_params(void)
 {
 	int ret;
 
-	ret = plat_sgi_append_config_node();
+	ret = plat_nrd_append_config_node();
 	if (ret != 0)
 		panic();
 
 	return arm_get_next_bl_params();
 }
-
diff --git a/plat/arm/css/sgi/sgi_interconnect.c b/plat/arm/board/neoverse_rd/common/nrd_interconnect.c
similarity index 94%
rename from plat/arm/css/sgi/sgi_interconnect.c
rename to plat/arm/board/neoverse_rd/common/nrd_interconnect.c
index e9cd8125..4f9cc851 100644
--- a/plat/arm/css/sgi/sgi_interconnect.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_interconnect.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/board/neoverse_rd/common/nrd_plat1.c
similarity index 79%
rename from plat/arm/css/sgi/sgi_plat.c
rename to plat/arm/board/neoverse_rd/common/nrd_plat1.c
index 01b426e8..32444f4f 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_plat1.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,18 +11,16 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/ccn.h>
+#include <drivers/arm/css/sds.h>
+#include <lib/utils_def.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <drivers/arm/sbsa.h>
-#include <sgi_base_platform_def.h>
 
 #if SPM_MM
 #include <services/spm_mm_partition.h>
 #endif
 
-#define SGI_MAP_FLASH0_RO	MAP_REGION_FLAT(V2M_FLASH0_BASE,\
-						V2M_FLASH0_SIZE,	\
-						MT_DEVICE | MT_RO | MT_SECURE)
 /*
  * Table of regions for different BL stages to map using the MMU.
  * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
@@ -33,30 +31,30 @@
 #if IMAGE_BL1
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
-	SGI_MAP_FLASH0_RO,
-	CSS_SGI_MAP_DEVICE,
-	SOC_CSS_MAP_DEVICE,
+	NRD_MAP_FLASH0_RO,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PERIPH_MMAP(0),
 	{0}
 };
 #endif
 #if IMAGE_BL2
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
-	SGI_MAP_FLASH0_RO,
+	NRD_MAP_FLASH0_RO,
 #ifdef PLAT_ARM_MEM_PROT_ADDR
 	ARM_V2M_MAP_MEM_PROTECT,
 #endif
-	CSS_SGI_MAP_DEVICE,
-	SOC_CSS_MAP_DEVICE,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PERIPH_MMAP(0),
 	ARM_MAP_NS_DRAM1,
-#if CSS_SGI_CHIP_COUNT > 1
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
+#if NRD_CHIP_COUNT > 1
+	NRD_CSS_PERIPH_MMAP(1),
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2),
+#if NRD_CHIP_COUNT > 2
+	NRD_CSS_PERIPH_MMAP(2),
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3),
+#if NRD_CHIP_COUNT > 3
+	NRD_CSS_PERIPH_MMAP(3),
 #endif
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
@@ -74,11 +72,11 @@ const mmap_region_t plat_arm_mmap[] = {
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
 	V2M_MAP_IOFPGA,
-	CSS_SGI_MAP_DEVICE,
+	NRD_CSS_PERIPH_MMAP(0),
 #ifdef PLAT_ARM_MEM_PROT_ADDR
 	ARM_V2M_MAP_MEM_PROTECT,
 #endif
-	SOC_CSS_MAP_DEVICE,
+	NRD_ROS_PERIPH_MMAP(0),
 #if SPM_MM
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
@@ -87,15 +85,11 @@ const mmap_region_t plat_arm_mmap[] = {
 
 #if SPM_MM && defined(IMAGE_BL31)
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
-	PLAT_ARM_SECURE_MAP_SYSTEMREG,
-	PLAT_ARM_SECURE_MAP_NOR2,
-	SOC_PLATFORM_SECURE_UART,
-	PLAT_ARM_SECURE_MAP_DEVICE,
+	NRD_ROS_SECURE_SYSTEMREG_USER_MMAP,
+	NRD_ROS_SECURE_NOR2_USER_MMAP,
+	NRD_CSS_SECURE_UART_MMAP,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
-#if ENABLE_FEAT_RAS && FFH_SUPPORT
-	CSS_SGI_SP_CPER_BUF_MMAP,
-#endif
 	ARM_SP_IMAGE_RW_MMAP,
 	ARM_SPM_BUF_EL0_MMAP,
 	{0}
@@ -167,10 +161,21 @@ int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
 
 void plat_arm_secure_wdt_start(void)
 {
-	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+	sbsa_wdog_start(NRD_CSS_WDOG_BASE, NRD_CSS_WDOG_TIMEOUT);
 }
 
 void plat_arm_secure_wdt_stop(void)
 {
-	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+	sbsa_wdog_stop(NRD_CSS_WDOG_BASE);
+}
+
+static sds_region_desc_t nrd_sds_regions[] = {
+	{ .base = PLAT_ARM_SDS_MEM_BASE },
+};
+
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
+{
+	*region_count = ARRAY_SIZE(nrd_sds_regions);
+
+	return nrd_sds_regions;
 }
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/board/neoverse_rd/common/nrd_plat2.c
similarity index 73%
rename from plat/arm/css/sgi/sgi_plat_v2.c
rename to plat/arm/board/neoverse_rd/common/nrd_plat2.c
index 624fed34..4a7b0214 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_plat2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,9 +8,11 @@
 
 #include <platform_def.h>
 
+#include <lib/utils_def.h>
+#include <drivers/arm/css/sds.h>
+#include <drivers/arm/sbsa.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <drivers/arm/sbsa.h>
 
 #if SPM_MM
 #include <services/spm_mm_partition.h>
@@ -21,35 +23,35 @@
  */
 #if IMAGE_BL1
 const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
-	SGI_MAP_FLASH0_RO,
-	CSS_SGI_MAP_DEVICE,
-	SOC_PLATFORM_PERIPH_MAP_DEVICE,
-	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
 	{0}
 };
 #endif
 
 #if IMAGE_BL2
 const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
-	SGI_MAP_FLASH0_RO,
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
 #ifdef PLAT_ARM_MEM_PROT_ADDR
 	ARM_V2M_MAP_MEM_PROTECT,
 #endif
-	CSS_SGI_MAP_DEVICE,
-	SOC_MEMCNTRL_MAP_DEVICE,
-	SOC_PLATFORM_PERIPH_MAP_DEVICE,
-	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_MEMCNTRL_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
 	ARM_MAP_NS_DRAM1,
-#if CSS_SGI_CHIP_COUNT > 1
-	SOC_MEMCNTRL_MAP_DEVICE_REMOTE_CHIP(1),
+#if NRD_CHIP_COUNT > 1
+	NRD_ROS_MEMCNTRL_MMAP(1),
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
-	SOC_MEMCNTRL_MAP_DEVICE_REMOTE_CHIP(2),
+#if NRD_CHIP_COUNT > 2
+	NRD_ROS_MEMCNTRL_MMAP(2),
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
-	SOC_MEMCNTRL_MAP_DEVICE_REMOTE_CHIP(3),
+#if NRD_CHIP_COUNT > 3
+	NRD_ROS_MEMCNTRL_MMAP(3),
 #endif
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
@@ -66,13 +68,13 @@ const mmap_region_t plat_arm_mmap[] = {
 
 #if IMAGE_BL31
 const mmap_region_t plat_arm_mmap[] = {
-	ARM_MAP_SHARED_RAM,
+	NRD_CSS_SHARED_RAM_MMAP(0),
 #ifdef PLAT_ARM_MEM_PROT_ADDR
 	ARM_V2M_MAP_MEM_PROTECT,
 #endif
-	CSS_SGI_MAP_DEVICE,
-	SOC_PLATFORM_PERIPH_MAP_DEVICE,
-	SOC_SYSTEM_PERIPH_MAP_DEVICE,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
 #if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
@@ -81,14 +83,14 @@ const mmap_region_t plat_arm_mmap[] = {
 
 #if SPM_MM && defined(IMAGE_BL31)
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
-	PLAT_ARM_SECURE_MAP_SYSTEMREG,
-	PLAT_ARM_SECURE_MAP_NOR2,
-	SOC_PLATFORM_SECURE_UART,
-	SOC_PLATFORM_PERIPH_MAP_DEVICE_USER,
+	NRD_ROS_SECURE_SYSTEMREG_USER_MMAP,
+	NRD_ROS_SECURE_NOR2_USER_MMAP,
+	NRD_CSS_SECURE_UART_USER_MMAP,
+	NRD_ROS_PLATFORM_PERIPH_USER_MMAP,
 	ARM_SP_IMAGE_MMAP,
 	ARM_SP_IMAGE_NS_BUF_MMAP,
 #if ENABLE_FEAT_RAS && FFH_SUPPORT
-	CSS_SGI_SP_CPER_BUF_MMAP,
+	NRD_CSS_SP_CPER_BUF_MMAP,
 #endif
 	ARM_SP_IMAGE_RW_MMAP,
 	ARM_SPM_BUF_EL0_MMAP,
@@ -169,10 +171,21 @@ int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
 
 void plat_arm_secure_wdt_start(void)
 {
-	sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+	sbsa_wdog_start(NRD_CSS_SECURE_WDOG_BASE, NRD_CSS_SECURE_WDOG_TIMEOUT);
 }
 
 void plat_arm_secure_wdt_stop(void)
 {
-	sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+	sbsa_wdog_stop(NRD_CSS_SECURE_WDOG_BASE);
+}
+
+static sds_region_desc_t nrd_sds_regions[] = {
+	{ .base = PLAT_ARM_SDS_MEM_BASE },
+};
+
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
+{
+	*region_count = ARRAY_SIZE(nrd_sds_regions);
+
+	return nrd_sds_regions;
 }
diff --git a/plat/arm/board/neoverse_rd/common/nrd_plat3.c b/plat/arm/board/neoverse_rd/common/nrd_plat3.c
new file mode 100644
index 00000000..00f346ec
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/common/nrd_plat3.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <drivers/arm/css/sds.h>
+#include <drivers/arm/sbsa.h>
+#include <lib/utils_def.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
+	{0}
+};
+#endif /* IMAGE_BL3 */
+
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(0),
+	NRD_ROS_FLASH0_RO_MMAP,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+	NRD_ROS_V2M_MEM_PROTECT_MMAP,
+#endif
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
+	NRD_CSS_NS_DRAM1_MMAP,
+#if TRUSTED_BOARD_BOOT && !RESET_TO_BL2
+	NRD_CSS_BL1_RW_MMAP,
+#endif
+	NRD_CSS_GPT_L1_DRAM_MMAP,
+	NRD_CSS_RMM_REGION_MMAP,
+	{0}
+};
+#endif /* IMAGE_BL2 */
+
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+	NRD_CSS_SHARED_RAM_MMAP(0),
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+	NRD_ROS_V2M_MEM_PROTECT_MMAP,
+#endif
+	NRD_CSS_PERIPH_MMAP(0),
+	NRD_ROS_PLATFORM_PERIPH_MMAP,
+	NRD_ROS_SYSTEM_PERIPH_MMAP,
+	NRD_CSS_GPT_L1_DRAM_MMAP,
+	NRD_CSS_EL3_RMM_SHARED_MEM_MMAP,
+	NRD_CSS_GPC_SMMU_SMMUV3_MMAP,
+#if RESET_TO_BL31
+	NRD_CSS_MAP_BL31_DTB,
+#endif
+	{0}
+};
+#endif /* IMAGE_BL31 */
+
+ARM_CASSERT_MMAP
+
+#if TRUSTED_BOARD_BOOT
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+	assert(heap_addr != NULL);
+	assert(heap_size != NULL);
+
+	return arm_get_mbedtls_heap(heap_addr, heap_size);
+}
+#endif
+
+void plat_arm_secure_wdt_start(void)
+{
+	sbsa_wdog_start(NRD_CSS_AP_SECURE_WDOG_BASE,
+			NRD_CSS_AP_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+	sbsa_wdog_stop(NRD_CSS_AP_SECURE_WDOG_BASE);
+}
+
+static sds_region_desc_t nrd_sds_regions[] = {
+	{ .base = PLAT_ARM_SDS_MEM_BASE },
+};
+
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
+{
+	*region_count = ARRAY_SIZE(nrd_sds_regions);
+
+	return nrd_sds_regions;
+}
diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/board/neoverse_rd/common/nrd_topology.c
similarity index 78%
rename from plat/arm/css/sgi/sgi_topology.c
rename to plat/arm/board/neoverse_rd/common/nrd_topology.c
index 1c3b5bfc..ff04b2b2 100644
--- a/plat/arm/css/sgi/sgi_topology.c
+++ b/plat/arm/board/neoverse_rd/common/nrd_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <plat/arm/common/plat_arm.h>
 
 /*
- * Common topology related methods for SGI and RD based platforms
+ * Common topology related methods for Neoverse RD platforms
  */
 /*******************************************************************************
  * This function returns the core count within the cluster corresponding to
@@ -15,7 +15,7 @@
  ******************************************************************************/
 unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
 {
-	return CSS_SGI_MAX_CPUS_PER_CLUSTER;
+	return NRD_MAX_CPUS_PER_CLUSTER;
 }
 
 #if ARM_PLAT_MT
@@ -24,6 +24,6 @@ unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
  *****************************************************************************/
 unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr)
 {
-	return CSS_SGI_MAX_PE_PER_CPU;
+	return NRD_MAX_PE_PER_CPU;
 }
 #endif
diff --git a/plat/arm/css/sgi/ras/sgi_ras_common.c b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_common.c
similarity index 65%
rename from plat/arm/css/sgi/ras/sgi_ras_common.c
rename to plat/arm/board/neoverse_rd/common/ras/nrd_ras_common.c
index 9789670d..24f4506a 100644
--- a/plat/arm/css/sgi/ras/sgi_ras_common.c
+++ b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,27 +11,27 @@
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
-#include <sgi_ras.h>
+#include <nrd_ras.h>
 
-static struct plat_sgi_ras_config *sgi_ras_config;
+static struct plat_nrd_ras_config *nrd_ras_config;
 
 /*
  * Find event map for a given interrupt number. On success, returns pointer to
  * the event map. On error, returns NULL.
  */
-struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num)
+struct nrd_ras_ev_map *nrd_find_ras_event_map_by_intr(uint32_t intr_num)
 {
-	struct sgi_ras_ev_map *map;
+	struct nrd_ras_ev_map *map;
 	int size;
 	int i;
 
-	if (sgi_ras_config == NULL) {
+	if (nrd_ras_config == NULL) {
 		ERROR("RAS config is NULL\n");
 		return NULL;
 	}
 
-	map = sgi_ras_config->ev_map;
-	size = sgi_ras_config->ev_map_size;
+	map = nrd_ras_config->ev_map;
+	size = nrd_ras_config->ev_map_size;
 
 	for (i = 0; i < size; i++) {
 		if (map->intr == intr_num)
@@ -47,14 +47,14 @@ struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num)
  * Programs GIC registers and configures interrupt ID's as Group0 EL3
  * interrupts. Current support is to register PPI and SPI interrupts.
  */
-static void sgi_ras_intr_configure(int intr, int intr_type)
+static void nrd_ras_intr_configure(int intr, int intr_type)
 {
 	plat_ic_set_interrupt_type(intr, INTR_TYPE_EL3);
 	plat_ic_set_interrupt_priority(intr, PLAT_RAS_PRI);
 	plat_ic_clear_interrupt_pending(intr);
 
 	/* Routing mode option available only for SPI interrupts */
-	if (intr_type == SGI_RAS_INTR_TYPE_SPI) {
+	if (intr_type == NRD_RAS_INTR_TYPE_SPI) {
 		plat_ic_set_spi_routing(intr, INTR_ROUTING_MODE_ANY,
 					(u_register_t)read_mpidr_el1());
 	}
@@ -67,15 +67,15 @@ static void sgi_ras_intr_configure(int intr, int intr_type)
  * Registers RAS config provided by the platform and then configures and
  * enables interrupt for each registered error. On success, return 0.
  */
-int sgi_ras_platform_setup(struct plat_sgi_ras_config *config)
+int nrd_ras_platform_setup(struct plat_nrd_ras_config *config)
 {
-	struct sgi_ras_ev_map *map;
+	struct nrd_ras_ev_map *map;
 	int size;
 	int i;
 
 	/* Check if parameter is valid. */
 	if (config == NULL) {
-		ERROR("SGI: Failed to register RAS config\n");
+		ERROR("NRD: Failed to register RAS config\n");
 		return -1;
 	}
 
@@ -83,17 +83,17 @@ int sgi_ras_platform_setup(struct plat_sgi_ras_config *config)
 	 * Maintain a reference to the platform RAS config data for later
 	 * use.
 	 */
-	sgi_ras_config = config;
+	nrd_ras_config = config;
 
-	map = sgi_ras_config->ev_map;
-	size = sgi_ras_config->ev_map_size;
+	map = nrd_ras_config->ev_map;
+	size = nrd_ras_config->ev_map_size;
 
 	for (i = 0; i < size; i++) {
-		sgi_ras_intr_configure(map->intr, map->intr_type);
+		nrd_ras_intr_configure(map->intr, map->intr_type);
 		map++;
 	}
 
-	INFO("SGI: Platform RAS setup successful\n");
+	INFO("NRD: Platform RAS setup successful\n");
 
 	return 0;
 }
diff --git a/plat/arm/css/sgi/ras/sgi_ras_cpu.c b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
similarity index 57%
rename from plat/arm/css/sgi/ras/sgi_ras_cpu.c
rename to plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
index 5e77dbb8..dcee92c8 100644
--- a/plat/arm/css/sgi/ras/sgi_ras_cpu.c
+++ b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_cpu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +14,7 @@
 #include <services/sdei.h>
 #include <services/spm_mm_svc.h>
 
-#include <sgi_ras.h>
+#include <nrd_ras.h>
 
 #define CPU_CONTEXT_REG_GPR_ARR_SIZE 32
 #define CPU_CONTEXT_REG_EL1_ARR_SIZE 17
@@ -62,72 +62,70 @@ static void populate_cpu_err_data(cpu_err_info *cpu_info,
 	cpu_info->SecurityState = security_state;
 
 	/* populate CPU EL1 context information. */
-	cpu_info->ErrCtxEl1Reg[0]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_ELR_EL1);
-	cpu_info->ErrCtxEl1Reg[1]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_ESR_EL1);
-	cpu_info->ErrCtxEl1Reg[2]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_FAR_EL1);
+	cpu_info->ErrCtxEl1Reg[0]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  elr_el1);
+	cpu_info->ErrCtxEl1Reg[1]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  esr_el1);
+	cpu_info->ErrCtxEl1Reg[2]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  far_el1);
 	cpu_info->ErrCtxEl1Reg[3]  = read_isr_el1();
-	cpu_info->ErrCtxEl1Reg[4]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_MAIR_EL1);
+	cpu_info->ErrCtxEl1Reg[4]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  mair_el1);
 	cpu_info->ErrCtxEl1Reg[5]  = read_midr_el1();
 	cpu_info->ErrCtxEl1Reg[6]  = read_mpidr_el1();
-	cpu_info->ErrCtxEl1Reg[7]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_SCTLR_EL1);
+	cpu_info->ErrCtxEl1Reg[7] = read_ctx_sctlr_el1_reg_errata(ctx);
 	cpu_info->ErrCtxEl1Reg[8]  = read_ctx_reg(get_gpregs_ctx(ctx),
 						  CTX_GPREG_SP_EL0);
-	cpu_info->ErrCtxEl1Reg[9]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_SP_EL1);
-	cpu_info->ErrCtxEl1Reg[10] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_SPSR_EL1);
-	cpu_info->ErrCtxEl1Reg[11] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TCR_EL1);
-	cpu_info->ErrCtxEl1Reg[12] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TPIDR_EL0);
-	cpu_info->ErrCtxEl1Reg[13] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TPIDR_EL1);
-	cpu_info->ErrCtxEl1Reg[14] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TPIDRRO_EL0);
-	cpu_info->ErrCtxEl1Reg[15] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TTBR0_EL1);
-	cpu_info->ErrCtxEl1Reg[16] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
-						  CTX_TTBR1_EL1);
-
-#if CTX_INCLUDE_EL2_REGS
-	cpu_info->ErrCtxEl2Reg[0]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_ELR_EL2);
-	cpu_info->ErrCtxEl2Reg[1]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_ESR_EL2);
-	cpu_info->ErrCtxEl2Reg[2]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_FAR_EL2);
-	cpu_info->ErrCtxEl2Reg[3]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_HACR_EL2);
-	cpu_info->ErrCtxEl2Reg[4]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_HCR_EL2);
-	cpu_info->ErrCtxEl2Reg[5]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_HPFAR_EL2);
-	cpu_info->ErrCtxEl2Reg[6]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_MAIR_EL2);
-	cpu_info->ErrCtxEl2Reg[7]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_SCTLR_EL2);
-	cpu_info->ErrCtxEl2Reg[8]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_SP_EL2);
-	cpu_info->ErrCtxEl2Reg[9]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_SPSR_EL2);
-	cpu_info->ErrCtxEl2Reg[10]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_TCR_EL2);
-	cpu_info->ErrCtxEl2Reg[11]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_TPIDR_EL2);
-	cpu_info->ErrCtxEl2Reg[12]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_TTBR0_EL2);
-	cpu_info->ErrCtxEl2Reg[13]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_VTCR_EL2);
-	cpu_info->ErrCtxEl2Reg[14]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_VTTBR_EL2);
-	cpu_info->ErrCtxEl2Reg[15]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
-						   CTX_ESR_EL2);
-#endif
+	cpu_info->ErrCtxEl1Reg[9]  = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  sp_el1);
+	cpu_info->ErrCtxEl1Reg[10] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  spsr_el1);
+	cpu_info->ErrCtxEl1Reg[11] = read_ctx_tcr_el1_reg_errata(ctx);
+	cpu_info->ErrCtxEl1Reg[12] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  tpidr_el0);
+	cpu_info->ErrCtxEl1Reg[13] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  tpidr_el1);
+	cpu_info->ErrCtxEl1Reg[14] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  tpidrro_el0);
+	cpu_info->ErrCtxEl1Reg[15] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  ttbr0_el1);
+	cpu_info->ErrCtxEl1Reg[16] = read_el1_ctx_common(get_el1_sysregs_ctx(ctx),
+						  ttbr1_el1);
+
+#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
+	cpu_info->ErrCtxEl2Reg[0]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						elr_el2);
+	cpu_info->ErrCtxEl2Reg[1]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						esr_el2);
+	cpu_info->ErrCtxEl2Reg[2]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						far_el2);
+	cpu_info->ErrCtxEl2Reg[3]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						hacr_el2);
+	cpu_info->ErrCtxEl2Reg[4]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						hcr_el2);
+	cpu_info->ErrCtxEl2Reg[5]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						hpfar_el2);
+	cpu_info->ErrCtxEl2Reg[6]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						mair_el2);
+	cpu_info->ErrCtxEl2Reg[7]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						sctlr_el2);
+	cpu_info->ErrCtxEl2Reg[8]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						sp_el2);
+	cpu_info->ErrCtxEl2Reg[9]   = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						spsr_el2);
+	cpu_info->ErrCtxEl2Reg[10]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						tcr_el2);
+	cpu_info->ErrCtxEl2Reg[11]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						tpidr_el2);
+	cpu_info->ErrCtxEl2Reg[12]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						ttbr0_el2);
+	cpu_info->ErrCtxEl2Reg[13]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						vtcr_el2);
+	cpu_info->ErrCtxEl2Reg[14]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						vttbr_el2);
+	cpu_info->ErrCtxEl2Reg[15]  = read_el2_ctx_common(get_el2_sysregs_ctx(ctx),
+						esr_el2);
+#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 
 	cpu_info->ErrCtxEl3Reg[0]   = read_ctx_reg(get_el3state_ctx(ctx),
 						   CTX_ELR_EL3);
@@ -143,11 +141,11 @@ static void populate_cpu_err_data(cpu_err_info *cpu_info,
 }
 
 /* CPU RAS interrupt handler */
-int sgi_ras_cpu_intr_handler(const struct err_record_info *err_rec,
+int nrd_ras_cpu_intr_handler(const struct err_record_info *err_rec,
 				int probe_data,
 				const struct err_handler_data *const data)
 {
-	struct sgi_ras_ev_map *ras_map;
+	struct nrd_ras_ev_map *ras_map;
 	mm_communicate_header_t *header;
 	cpu_err_info cpu_info = {0};
 	uint64_t clear_status;
@@ -186,9 +184,9 @@ int sgi_ras_cpu_intr_handler(const struct err_record_info *err_rec,
 	 * Find if this is a RAS interrupt. There must be an event against
 	 * this interrupt
 	 */
-	ras_map = sgi_find_ras_event_map_by_intr(intr);
+	ras_map = nrd_find_ras_event_map_by_intr(intr);
 	if (ras_map == NULL) {
-		ERROR("SGI: RAS error info for interrupt id: %d not found\n",
+		ERROR("NRD: RAS error info for interrupt id: %d not found\n",
 			intr);
 		return -1;
 	}
diff --git a/plat/arm/css/sgi/ras/sgi_ras_sram.c b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_sram.c
similarity index 81%
rename from plat/arm/css/sgi/ras/sgi_ras_sram.c
rename to plat/arm/board/neoverse_rd/common/ras/nrd_ras_sram.c
index b1007003..96aa8643 100644
--- a/plat/arm/css/sgi/ras/sgi_ras_sram.c
+++ b/plat/arm/board/neoverse_rd/common/ras/nrd_ras_sram.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
 #include <services/spm_mm_svc.h>
 
 #include <platform_def.h>
-#include <sgi_ras.h>
+#include <nrd_ras.h>
 
 /* Base Element RAM Error Record offsets. */
 #define ERRSTATUS	U(0)
@@ -22,11 +22,11 @@
  * Base Element RAM error information data structure communicated as part of MM
  * Communication data payload.
  */
-typedef struct sgi_sram_err_info {
+typedef struct nrd_sram_err_info {
 	uint32_t err_status;
 	uint32_t err_code;
 	uint32_t err_addr;
-} sgi_sram_err_info_t;
+} nrd_sram_err_info_t;
 
 /*
  * MM Communicate message header GUID to indicate the payload is intended for
@@ -38,13 +38,13 @@ struct efi_guid sram_ecc_event_guid = {
 };
 
 /* Base element RAM RAS error interrupt handler */
-int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
+int nrd_ras_sram_intr_handler(const struct err_record_info *err_rec,
 				int probe_data,
 				const struct err_handler_data *const data)
 {
-	struct sgi_ras_ev_map *ras_map;
+	struct nrd_ras_ev_map *ras_map;
 	mm_communicate_header_t *header;
-	sgi_sram_err_info_t sram_info;
+	nrd_sram_err_info_t sram_info;
 	uintptr_t base_addr;
 	uint32_t clear_status, intr;
 	int ret;
@@ -52,12 +52,13 @@ int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
 	cm_el1_sysregs_context_save(NON_SECURE);
 	intr = data->interrupt;
 
-	INFO("SGI: Base element RAM interrupt [%d] handler\n", intr);
+	INFO("NRD: Base element RAM interrupt [%d] handler\n", intr);
 
 	/* Determine error record base address to read. */
 	base_addr = 0;
-	if (intr == NS_RAM_ECC_CE_INT || intr == NS_RAM_ECC_UE_INT) {
-		base_addr = SOC_NS_RAM_ERR_REC_BASE;
+	if (intr == NRD_CSS_NS_RAM_ECC_CE_INT ||
+		intr == NRD_CSS_NS_RAM_ECC_UE_INT) {
+		base_addr = NRD_CSS_NS_RAM_ERR_REC_BASE;
 	}
 	sram_info.err_status = mmio_read_32(base_addr + ERRSTATUS);
 	sram_info.err_code = mmio_read_32(base_addr + ERRCODE);
@@ -87,9 +88,9 @@ int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
 	 * Find if this is a RAS interrupt. There must be an event against
 	 * this interrupt
 	 */
-	ras_map = sgi_find_ras_event_map_by_intr(intr);
+	ras_map = nrd_find_ras_event_map_by_intr(intr);
 	if (ras_map == NULL) {
-		ERROR("SGI: RAS error info for interrupt id: %d not found\n",
+		ERROR("NRD: RAS error info for interrupt id: %d not found\n",
 			intr);
 		return -1;
 	}
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_fw_config.dts
similarity index 86%
rename from plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_fw_config.dts
index d3b7fba4..085a42a5 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
similarity index 86%
rename from plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
index 68366c5c..3cef0d15 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
similarity index 89%
rename from plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
index 257ef4a3..78cd5a82 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/fdts/rdn1edge_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/rdn1edge/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdn1edge/include/platform_def.h
new file mode 100644
index 00000000..5357c31e
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/include/platform_def.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_plat_arm_def1.h>
+#include <nrd_ros_fw_def1.h>
+#include <nrd_sdei.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
+
+#define PLAT_ARM_CLUSTER_COUNT		U(2)
+#define NRD_MAX_CPUS_PER_CLUSTER	U(4)
+#define NRD_MAX_PE_PER_CPU		U(1)
+
+#define PLAT_CSS_MHU_BASE		UL(0x45400000)
+
+/* Base address of DMC-620 instances */
+#define RDN1EDGE_DMC620_BASE0		UL(0x4e000000)
+#define RDN1EDGE_DMC620_BASE1		UL(0x4e100000)
+
+/* Virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
+
+/* Maximum number of address bits used per chip */
+#define NRD_ADDR_BITS_PER_CHIP	U(42)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
+
+/* GIC SPI range for multichip */
+#define NRD_CHIP0_SPI_MIN		U(32)
+#define NRD_CHIP0_SPI_MAX		U(991)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/neoverse_rd/platform/rdn1edge/platform.mk
similarity index 65%
rename from plat/arm/board/rdn1edge/platform.mk
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/platform.mk
index 95753aaf..4892804f 100644
--- a/plat/arm/board/rdn1edge/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/platform.mk
@@ -1,25 +1,24 @@
 #
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-$(warning Platform ${PLAT} is deprecated. Some of the features might not work as expected)
-
 # GIC-600 configuration
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
 
-include plat/arm/css/sgi/sgi-common.mk
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-RDN1EDGE_BASE		=	plat/arm/board/rdn1edge
+RDN1EDGE_BASE		=	plat/arm/board/neoverse_rd/platform/rdn1edge
 
-PLAT_INCLUDES		+=	-I${RDN1EDGE_BASE}/include/
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd1/	\
+				-I${RDN1EDGE_BASE}/include/
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n1.S
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n1.S
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat1.c
 
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDN1EDGE_BASE}/rdn1edge_err.c
 
 BL2_SOURCES		+=	${RDN1EDGE_BASE}/rdn1edge_plat.c	\
@@ -29,7 +28,7 @@ BL2_SOURCES		+=	${RDN1EDGE_BASE}/rdn1edge_plat.c	\
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDN1EDGE_BASE}/rdn1edge_plat.c	\
 				${RDN1EDGE_BASE}/rdn1edge_topology.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -62,14 +61,23 @@ NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 $(eval $(call CREATE_SEQ,SEQ,2))
-ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
+ifneq ($(NRD_CHIP_COUNT),$(filter $(NRD_CHIP_COUNT),$(SEQ)))
  $(error  "Chip count for RDN1Edge platform should be one of $(SEQ), currently \
-   set to ${CSS_SGI_CHIP_COUNT}.")
+   set to ${NRD_CHIP_COUNT}.")
+endif
+
+ifneq ($(NRD_PLATFORM_VARIANT),0)
+ $(error "NRD_PLATFORM_VARIANT for RD-N1-Edge should always be 0, \
+     currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-N1-Edge should always be 0, \
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
 endif
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
+override SPMD_SPM_AT_SEL2		:= 0
+
+# Enable the flag since RD-N1-EDGE has a system level cache
+NEOVERSE_Nx_EXTERNAL_LLC		:=	1
diff --git a/plat/arm/board/rdn1edge/rdn1edge_err.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_err.c
similarity index 71%
rename from plat/arm/board/rdn1edge/rdn1edge_err.c
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_err.c
index 46d318c7..273e1f45 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn1edge/rdn1edge_plat.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c
similarity index 70%
rename from plat/arm/board/rdn1edge/rdn1edge_plat.c
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c
index 6da8bcd6..ccabe229 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_plat.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,26 +8,28 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <sgi_soc_platform_def.h>
-#include <sgi_plat.h>
+
+#include <nrd_plat.h>
 
 #if defined(IMAGE_BL31)
 static const mmap_region_t rdn1edge_dynamic_mmap[] = {
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
-	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1)
+	NRD_CSS_SHARED_RAM_MMAP(1),
+	NRD_CSS_PERIPH_MMAP(1),
+	NRD_ROS_PERIPH_MMAP(1)
 };
 
 static struct gic600_multichip_data rdn1e1_multichip_data __init = {
 	.rt_owner_base = PLAT_ARM_GICD_BASE,
 	.rt_owner = 0,
-	.chip_count = CSS_SGI_CHIP_COUNT,
+	.chip_count = NRD_CHIP_COUNT,
 	.chip_addrs = {
 		PLAT_ARM_GICD_BASE >> 16,
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
 	},
 	.spi_ids = {
-		{PLAT_ARM_GICD_BASE, 32, 255},
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP0_SPI_MIN,
+		NRD_CHIP0_SPI_MAX},
 		{0, 0, 0}
 	}
 };
@@ -35,23 +37,23 @@ static struct gic600_multichip_data rdn1e1_multichip_data __init = {
 static uintptr_t rdn1e1_multichip_gicr_frames[] = {
 	PLAT_ARM_GICR_BASE,				/* Chip 0's GICR Base */
 	PLAT_ARM_GICR_BASE +
-		CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),	/* Chip 1's GICR BASE */
+		NRD_REMOTE_CHIP_MEM_OFFSET(1),		/* Chip 1's GICR BASE */
 	UL(0)						/* Zero Termination */
 };
 #endif /* IMAGE_BL31 */
 
-unsigned int plat_arm_sgi_get_platform_id(void)
+unsigned int plat_arm_nrd_get_platform_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
 				& SID_SYSTEM_ID_PART_NUM_MASK;
 }
 
-unsigned int plat_arm_sgi_get_config_id(void)
+unsigned int plat_arm_nrd_get_config_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
 }
 
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
 {
 	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
 			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
@@ -68,12 +70,12 @@ void bl31_platform_setup(void)
 	unsigned int i;
 	int ret;
 
-	if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) {
+	if (plat_arm_nrd_get_multi_chip_mode() == 0 && NRD_CHIP_COUNT > 1) {
 		ERROR("Chip Count is set to %d but multi-chip mode not enabled\n",
-				CSS_SGI_CHIP_COUNT);
+				NRD_CHIP_COUNT);
 		panic();
-	} else if (plat_arm_sgi_get_multi_chip_mode() == 1 &&
-			CSS_SGI_CHIP_COUNT > 1) {
+	} else if (plat_arm_nrd_get_multi_chip_mode() == 1 &&
+			NRD_CHIP_COUNT > 1) {
 		INFO("Enabling support for multi-chip in RD-N1-Edge\n");
 
 		for (i = 0; i < ARRAY_SIZE(rdn1edge_dynamic_mmap); i++) {
@@ -93,6 +95,6 @@ void bl31_platform_setup(void)
 		gic600_multichip_init(&rdn1e1_multichip_data);
 	}
 
-	sgi_bl31_common_platform_setup();
+	nrd_bl31_common_platform_setup();
 }
 #endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdn1edge/rdn1edge_security.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_security.c
similarity index 85%
rename from plat/arm/board/rdn1edge/rdn1edge_security.c
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_security.c
index 49435329..f3f6238f 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_security.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
-#include <sgi_dmc620_tzc_regions.h>
+#include <nrd_dmc620_tzc_regions.h>
 
 uintptr_t rdn1edge_dmc_base[] = {
 	RDN1EDGE_DMC620_BASE0,
@@ -20,7 +20,7 @@ static const tzc_dmc620_driver_data_t rdn1edge_plat_driver_data = {
 };
 
 static const tzc_dmc620_acc_addr_data_t rdn1edge_acc_addr_data[] = {
-	CSS_SGI_DMC620_TZC_REGIONS_DEF
+	NRD_DMC620_TZC_REGIONS_DEF
 };
 
 static const tzc_dmc620_config_data_t rdn1edge_plat_config_data = {
diff --git a/plat/arm/board/rdn1edge/rdn1edge_topology.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_topology.c
similarity index 86%
rename from plat/arm/board/rdn1edge/rdn1edge_topology.c
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_topology.c
index 5bbea699..133eb166 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,12 +11,12 @@
  * The power domain tree descriptor.
  ******************************************************************************/
 static const unsigned char rdn1edge_pd_tree_desc[] = {
-	(PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT),
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-#if (CSS_SGI_CHIP_COUNT > 1)
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER
+	(PLAT_ARM_CLUSTER_COUNT) * (NRD_CHIP_COUNT),
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#if (NRD_CHIP_COUNT > 1)
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER
 #endif
 };
 
@@ -41,7 +41,7 @@ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
-#if (CSS_SGI_CHIP_COUNT > 1)
+#if (NRD_CHIP_COUNT > 1)
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_trusted_boot.c
similarity index 88%
rename from plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_trusted_boot.c
index 4592b8fb..84622d00 100644
--- a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn1edge/rdn1edge_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_fw_config.dts
similarity index 64%
rename from plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_fw_config.dts
index 69fb0d49..f857f72a 100644
--- a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,14 @@
 			id = <TB_FW_CONFIG_ID>;
 		};
 
+#if SPMC_AT_EL3
+		tos_fw-config {
+			load-address = <0x0 0x04001500>;
+			max-size = <0x1000>;
+			id = <TOS_FW_CONFIG_ID>;
+		};
+
+#endif
 		nt_fw-config {
 			load-address = <0x0 0xFEF00000>;
 			max-size = <0x0100000>;
diff --git a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_nt_fw_config.dts
similarity index 90%
rename from plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_nt_fw_config.dts
index dd70141d..8e585656 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 - 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_stmm_sel0_manifest.dts b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_stmm_sel0_manifest.dts
new file mode 100644
index 00000000..dbdc7e59
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_stmm_sel0_manifest.dts
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+#include <platform_def.h>
+
+/ {
+#define MODE_SEL0		(0x1)
+
+#define SECURE_RO		0x1
+#define SECURE_RW		0x3
+#define SECURE_EXECUTE_RO 	0x5
+#define SECURE_EXECUTE_RW 	0x7
+#define NON_SECURE_RO 		0x9
+#define NON_SECURE_RW 		0xB
+#define NON_SECURE_EXECUTE_RO 	0xD
+#define NON_SECURE_EXECUTE_RW 	0xF
+	/*
+	 * FF-A compatible Secure Partition Manager parses the
+	 * manifest file and fetch the following booting arguments to
+	 * pass on to the StandAloneMM(StMM) Secure Partition.
+	 */
+	compatible = "arm,ffa-manifest-1.0";
+
+	description = "RDN2 StMM";
+	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
+	uuid = <0x378daedc 0xf06b4446 0x831440ab 0x933c87a3>;
+	id = <0x8001>;
+	execution-ctx-count = <1>;
+	exception-level = <MODE_SEL0>; /* S-EL0 */
+	execution-state = <0>; /* AArch64 */
+	load-address = <0x0 0xFF200000>;
+	image-size = <0x0 0x280000>;
+	xlat-granule = <0>; /* 4KiB */
+	boot-order = <0>;
+	messaging-method = <0x3>; /* Direct request/response supported. */
+	power-management-messages = <0>;
+	gp-register-num = <0>;
+
+	device-regions {
+		compatible = "arm,ffa-manifest-device-regions";
+
+		/*
+		 * System registers region for access from S-EL0.
+		 * Similar to PLAT_ARM_SECURE_MAP_SYSTEMREG.
+		 */
+		sys-regs {
+			base-address = <0x0 0x0C010000>;
+			pages-count = <0x10>;
+			attributes = <SECURE_RW>;
+		};
+
+		rtc {
+			base-address = <0x0 0x0C170000>;
+			pages-count = <0x1>;
+			attributes = <SECURE_RW>;
+		};
+
+		/*
+		 * ARM CSS SoC Expansion Peripherals.
+		 */
+		soc_components {
+			base-address = <0x0 0x0E000000>;
+			pages-count = <0x2000>;
+			attributes = <SECURE_RW>;
+		};
+
+		cluster_utility {
+			base-address = <0x0 0x20000000>;
+			pages-count = <0x20000>;
+			attributes = <SECURE_RW>;
+		};
+
+		secure_uart {
+			base-address = <0x0 0x2A410000>;
+			pages-count = <0x10>;
+			attributes = <SECURE_RW>;
+		};
+
+		/*
+		 * Used for Secure booting.
+		 */
+		nor_flash2 {
+			base-address = <0x10 0x54000000>;
+			pages-count = <0x4000>;
+			attributes = <SECURE_RW>;
+		};
+	};
+
+	memory-regions {
+		compatible = "arm,ffa-manifest-memory-regions";
+
+		/*
+		 * SPM Payload memory. Mapped as code region for S-EL0
+		 * Similar to ARM_SP_IMAGE_MMAP macro used for defining base of
+		 * the SP image.
+		 */
+		stmm_region {
+			base-address = <0x0 0xff200000>;
+			pages-count = <0x300>;
+			/* StMM will remap the regions during runtime. */
+			attributes = <SECURE_EXECUTE_RO>;
+		};
+
+		/*
+		 * Memory shared between EL3 SPMC and S-EL0.
+		 */
+		rx-tx-buffers {
+			description = "shared-buff";
+			base-address = <0x0 0xff500000>;
+			pages-count = <0x100>;
+			attributes = <SECURE_RW>;
+		};
+
+		/*
+		 * Memory shared between Normal world and S-EL0.
+		 */
+		ns_comm_buffer {
+			/*
+			 * Description is needed for StMM to identify
+			 * ns-communication buffer.
+			 */
+			description = "ns-comm";
+			base-address = <0x0 0xff600000>;
+			pages-count = <0x30>;
+			attributes = <NON_SECURE_RW>;
+		};
+
+		/*
+		 * Heap used by SP to allocate memory for DMA.
+		 */
+		heap {
+			/*
+			 * Description is needed for StMM to identify
+			 * heap buffer.
+			 */
+			description = "heap";
+			base-address = <0x0 0xFF630000>;
+			pages-count = <0x5D0>;
+			attributes = <SECURE_RW>;
+		};
+	};
+};
diff --git a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_tb_fw_config.dts
similarity index 89%
rename from plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_tb_fw_config.dts
index 49eda273..c370623b 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/fdts/rdn2_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/rdn2/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdn2/include/platform_def.h
new file mode 100644
index 00000000..f6f2b862
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/include/platform_def.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+
+#include <nrd_css_fw_def2.h>
+#include <nrd_plat_arm_def2.h>
+#include <nrd_ros_fw_def2.h>
+#include <nrd_sdei.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)					\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
+
+#define NRD_MAX_CPUS_PER_CLUSTER	U(1)
+#define NRD_MAX_PE_PER_CPU		U(1)
+
+/* Boot ROM */
+#define NRD_CSS_SECURE_ROM_SIZE		UL(0x00080000) /* 512KB */
+
+/* Secure SRAM */
+#define NRD_CSS_SECURE_SRAM_SIZE	UL(0x00080000) /* 512KB */
+
+/* NS SRAM */
+#define NRD_CSS_NS_SRAM_SIZE		UL(0x00080000) /* 512KB */
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_SIZE		ULL(0x180000000) /* 6GB */
+
+#define TZC400_OFFSET			UL(0x1000000)
+
+#if (NRD_PLATFORM_VARIANT == 1)
+#define TZC400_COUNT			U(2)
+#elif (NRD_PLATFORM_VARIANT == 2)
+#define TZC400_COUNT			U(4)
+#else
+#define TZC400_COUNT			U(8)
+#endif
+
+#define TZC400_BASE(n)			(PLAT_ARM_TZC_BASE + \
+						(n * TZC400_OFFSET))
+
+#define TZC_NSAID_ALL_AP		U(0)
+#define TZC_NSAID_PCI			U(1)
+#define TZC_NSAID_HDLCD0		U(2)
+#define TZC_NSAID_DMA			U(5)
+#define TZC_NSAID_DMA2			U(8)
+#define TZC_NSAID_CLCD			U(7)
+#define TZC_NSAID_AP			U(9)
+#define TZC_NSAID_VIRTIO		U(15)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS	\
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI))    | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA))    | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA2))   | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP))     | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD))   | \
+		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
+
+/*
+ * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
+ */
+#if (NRD_PLATFORM_VARIANT == 2)
+#define NRD_ADDR_BITS_PER_CHIP	U(46)	/* 64TB */
+#else
+#define NRD_ADDR_BITS_PER_CHIP	U(42)	/* 4TB */
+#endif
+
+/* GIC SPI range for multichip */
+#define NRD_CHIP0_SPI_MIN		U(32)
+#define NRD_CHIP0_SPI_MAX		U(511)
+#if NRD_CHIP_COUNT > 1
+#define NRD_CHIP1_SPI_MIN		U(512)
+#define NRD_CHIP1_SPI_MAX		U(991)
+#endif
+#if NRD_CHIP_COUNT > 2
+#define NRD_CHIP2_SPI_MIN		U(4096)
+#define NRD_CHIP2_SPI_MAX		U(4575)
+#endif
+#if NRD_CHIP_COUNT > 3
+#define NRD_CHIP3_SPI_MIN		U(4576)
+#define NRD_CHIP3_SPI_MAX		U(5055)
+#endif
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdn2/include/rdn2_ras.h b/plat/arm/board/neoverse_rd/platform/rdn2/include/rdn2_ras.h
new file mode 100644
index 00000000..c8a6f2d7
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/include/rdn2_ras.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDN2_RAS_H
+#define RDN2_RAS_H
+
+#include <nrd_ras.h>
+
+extern struct plat_nrd_ras_config ras_config;
+
+#endif /* RDN2_RAS_H */
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
similarity index 50%
rename from plat/arm/board/rdn2/platform.mk
rename to plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
index ef8f3d47..c2dfba6e 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/platform.mk
@@ -1,19 +1,19 @@
-# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 RD_N2_VARIANTS	:= 0 1 2 3
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),\
-	$(filter $(CSS_SGI_PLATFORM_VARIANT),$(RD_N2_VARIANTS)))
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-N2 should be 0, 1, 2 or 3, currently \
-	set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq ($(NRD_PLATFORM_VARIANT),\
+	$(filter $(NRD_PLATFORM_VARIANT),$(RD_N2_VARIANTS)))
+ $(error "NRD_PLATFORM_VARIANT for RD-N2 should be 0, 1, 2 or 3, currently \
+	set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
 $(eval $(call CREATE_SEQ,SEQ,4))
-ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
+ifneq ($(NRD_CHIP_COUNT),$(filter $(NRD_CHIP_COUNT),$(SEQ)))
  $(error  "Chip count for RD-N2-MC should be either $(SEQ) \
- currently it is set to ${CSS_SGI_CHIP_COUNT}.")
+ currently it is set to ${NRD_CHIP_COUNT}.")
 endif
 
 # RD-N2 platform uses GIC-700 which is based on GICv4.1
@@ -21,25 +21,26 @@ GIC_ENABLE_V4_EXTN	:=	1
 GIC_EXT_INTID		:=	1
 
 #Enable GIC Multichip Extension only for Multichip Platforms
-ifeq (${CSS_SGI_PLATFORM_VARIANT}, 2)
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
 endif
 
 override CSS_SYSTEM_GRACEFUL_RESET	:= 1
 override EL3_EXCEPTION_HANDLING		:= 1
 
-include plat/arm/css/sgi/sgi-common.mk
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-RDN2_BASE		=	plat/arm/board/rdn2
+RDN2_BASE		=	plat/arm/board/neoverse_rd/platform/rdn2
 
-PLAT_INCLUDES		+=	-I${RDN2_BASE}/include/
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd2/	\
+				-I${RDN2_BASE}/include/
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n2.S \
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_n2.S \
 				lib/cpus/aarch64/neoverse_v2.S
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat_v2.c
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat2.c
 
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDN2_BASE}/rdn2_err.c
 
 BL2_SOURCES		+=	${RDN2_BASE}/rdn2_plat.c		\
@@ -50,7 +51,7 @@ BL2_SOURCES		+=	${RDN2_BASE}/rdn2_plat.c		\
 				plat/arm/common/arm_tzc400.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDN2_BASE}/rdn2_plat.c		\
 				${RDN2_BASE}/rdn2_topology.c		\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -62,7 +63,7 @@ BL1_SOURCES		+=	${RDN2_BASE}/rdn2_trusted_boot.c
 BL2_SOURCES		+=	${RDN2_BASE}/rdn2_trusted_boot.c
 endif
 
-ifeq (${CSS_SGI_PLATFORM_VARIANT}, 2)
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
 BL31_SOURCES	+=	drivers/arm/gic/v3/gic600_multichip.c
 
 # Enable dynamic addition of MMAP regions in BL31
@@ -71,9 +72,9 @@ endif
 
 ifeq (${ENABLE_FEAT_RAS}-${HANDLE_EA_EL3_FIRST_NS},1-1)
 BL31_SOURCES		+=	${RDN2_BASE}/rdn2_ras.c			\
-				${CSS_ENT_BASE}/ras/sgi_ras_common.c	\
-				${CSS_ENT_BASE}/ras/sgi_ras_sram.c	\
-				${CSS_ENT_BASE}/ras/sgi_ras_cpu.c
+				${NRD_COMMON_BASE}/ras/nrd_ras_common.c	\
+				${NRD_COMMON_BASE}/ras/nrd_ras_sram.c	\
+				${NRD_COMMON_BASE}/ras/nrd_ras_cpu.c
 endif
 
 # Add the FDT_SOURCES and options for Dynamic Config
@@ -93,5 +94,46 @@ NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
 
+ifeq (${SPMC_AT_EL3}, 1)
+STMM_CONFIG_DTS		:=	${RDN2_BASE}/fdts/${PLAT}_stmm_sel0_manifest.dts
+FDT_SOURCES		+=	${STMM_CONFIG_DTS}
+TOS_FW_CONFIG		:=	${BUILD_PLAT}/fdts/$(notdir $(basename ${STMM_CONFIG_DTS})).dtb
+
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TOS_FW_CONFIG},--tos-fw-config,${TOS_FW_CONFIG}))
+endif
+
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
 override CTX_INCLUDE_AARCH32_REGS	:= 0
-override ENABLE_FEAT_AMU		:= 1
+override ENABLE_FEAT_AMU		:= 2
+override ENABLE_FEAT_MTE2       	:= 2
+override SPMD_SPM_AT_SEL2		:= 0
+
+# Enable the flag since RD-N2 has a system level cache
+NEOVERSE_Nx_EXTERNAL_LLC		:=	1
+
+# Enable N2 CPU errata workarounds
+ERRATA_N2_2002655	:=	1
+ERRATA_N2_2009478	:=	1
+ERRATA_N2_2067956	:=	1
+ERRATA_N2_2025414	:=	1
+ERRATA_N2_2189731	:=	1
+ERRATA_N2_2138956	:=	1
+ERRATA_N2_2138953	:=	1
+ERRATA_N2_2242415	:=	1
+ERRATA_N2_2138958	:=	1
+ERRATA_N2_2242400	:=	1
+ERRATA_N2_2280757	:=	1
+ERRATA_N2_2326639	:=	1
+ERRATA_N2_2340933	:=	1
+ERRATA_N2_2346952	:=	1
+ERRATA_N2_2376738	:=	1
+ERRATA_N2_2388450	:=	1
+ERRATA_N2_2743014	:=	1
+ERRATA_N2_2743089	:=	1
+ERRATA_N2_2728475	:=	1
+ERRATA_N2_2779511	:=	1
diff --git a/plat/arm/board/rdn2/rdn2_err.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_err.c
similarity index 71%
rename from plat/arm/board/rdn2/rdn2_err.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_err.c
index 802ac21f..d7126454 100644
--- a/plat/arm/board/rdn2/rdn2_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c
similarity index 60%
rename from plat/arm/board/rdn2/rdn2_plat.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c
index 2a6c658b..b1046d69 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,93 +9,101 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <services/el3_spmc_ffa_memory.h>
+
+#include <nrd_plat.h>
 #include <rdn2_ras.h>
-#include <sgi_soc_platform_def_v2.h>
-#include <sgi_plat.h>
 
 #if defined(IMAGE_BL31)
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 static const mmap_region_t rdn2mc_dynamic_mmap[] = {
-#if CSS_SGI_CHIP_COUNT > 1
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
+#if NRD_CHIP_COUNT > 1
+	NRD_CSS_SHARED_RAM_MMAP(1),
+	NRD_CSS_PERIPH_MMAP(1),
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(2),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2),
+#if NRD_CHIP_COUNT > 2
+	NRD_CSS_SHARED_RAM_MMAP(2),
+	NRD_CSS_PERIPH_MMAP(2),
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(3),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3),
+#if NRD_CHIP_COUNT > 3
+	NRD_CSS_SHARED_RAM_MMAP(3),
+	NRD_CSS_PERIPH_MMAP(3),
 #endif
 };
 #endif
 
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 static struct gic600_multichip_data rdn2mc_multichip_data __init = {
 	.rt_owner_base = PLAT_ARM_GICD_BASE,
 	.rt_owner = 0,
-	.chip_count = CSS_SGI_CHIP_COUNT,
+	.chip_count = NRD_CHIP_COUNT,
 	.chip_addrs = {
 		PLAT_ARM_GICD_BASE >> 16,
-#if CSS_SGI_CHIP_COUNT > 1
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
+#if NRD_CHIP_COUNT > 1
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
+#if NRD_CHIP_COUNT > 2
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
+#if NRD_CHIP_COUNT > 3
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
 #endif
 	},
 	.spi_ids = {
-		{PLAT_ARM_GICD_BASE, 32, 511},
-	#if CSS_SGI_CHIP_COUNT > 1
-		{PLAT_ARM_GICD_BASE, 512, 991},
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP0_SPI_MIN,
+		NRD_CHIP0_SPI_MAX},
+	#if NRD_CHIP_COUNT > 1
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP1_SPI_MIN,
+		NRD_CHIP1_SPI_MAX},
 	#endif
-	#if CSS_SGI_CHIP_COUNT > 2
-		{PLAT_ARM_GICD_BASE, 4096, 4575},
+	#if NRD_CHIP_COUNT > 2
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP2_SPI_MIN,
+		NRD_CHIP2_SPI_MAX},
 	#endif
-	#if CSS_SGI_CHIP_COUNT > 3
-		{PLAT_ARM_GICD_BASE, 4576, 5055},
+	#if NRD_CHIP_COUNT > 3
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP3_SPI_MIN,
+		NRD_CHIP3_SPI_MAX},
 	#endif
 	}
 };
 #endif
 
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 static uintptr_t rdn2mc_multichip_gicr_frames[] = {
 	/* Chip 0's GICR Base */
 	PLAT_ARM_GICR_BASE,
-#if CSS_SGI_CHIP_COUNT > 1
+#if NRD_CHIP_COUNT > 1
 	/* Chip 1's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
 #endif
-#if CSS_SGI_CHIP_COUNT > 2
+#if NRD_CHIP_COUNT > 2
 	/* Chip 2's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
+#if NRD_CHIP_COUNT > 3
 	/* Chip 3's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
 #endif
 	UL(0)	/* Zero Termination */
 };
 #endif
 #endif /* IMAGE_BL31 */
 
-unsigned int plat_arm_sgi_get_platform_id(void)
+unsigned int plat_arm_nrd_get_platform_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
 			    & SID_SYSTEM_ID_PART_NUM_MASK;
 }
 
-unsigned int plat_arm_sgi_get_config_id(void)
+unsigned int plat_arm_nrd_get_config_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
 }
 
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
 {
 	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
 			     SID_MULTI_CHIP_MODE_MASK) >>
@@ -105,13 +113,13 @@ unsigned int plat_arm_sgi_get_multi_chip_mode(void)
 #if defined(IMAGE_BL31)
 void bl31_platform_setup(void)
 {
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 	int ret;
 	unsigned int i;
 
-	if (plat_arm_sgi_get_multi_chip_mode() == 0) {
-		ERROR("Chip Count is set to %u but multi-chip mode is not "
-			"enabled\n", CSS_SGI_CHIP_COUNT);
+	if (plat_arm_nrd_get_multi_chip_mode() == 0) {
+		ERROR("Chip Count is %u but multi-chip mode is not enabled\n",
+			NRD_CHIP_COUNT);
 		panic();
 	} else {
 		INFO("Enabling multi-chip support for RD-N2 variant\n");
@@ -135,10 +143,10 @@ void bl31_platform_setup(void)
 	}
 #endif
 
-	sgi_bl31_common_platform_setup();
+	nrd_bl31_common_platform_setup();
 
 #if ENABLE_FEAT_RAS && FFH_SUPPORT
-	sgi_ras_platform_setup(&ras_config);
+	nrd_ras_platform_setup(&ras_config);
 #endif
 }
 #endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdn2/rdn2_ras.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_ras.c
similarity index 60%
rename from plat/arm/board/rdn2/rdn2_ras.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_ras.c
index 3aed58e9..e3287644 100644
--- a/plat/arm/board/rdn2/rdn2_ras.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_ras.c
@@ -1,30 +1,31 @@
 /*
- * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <platform_def.h>
-#include <sgi_ras.h>
-#include <sgi_sdei.h>
 
-struct sgi_ras_ev_map plat_ras_map[] = {
+#include <nrd_ras.h>
+#include <nrd_sdei.h>
+
+struct nrd_ras_ev_map plat_ras_map[] = {
 	/* Non Secure base RAM ECC CE interrupt */
-	{SGI_SDEI_DS_EVENT_0, NS_RAM_ECC_CE_INT, SGI_RAS_INTR_TYPE_SPI},
+	{NRD_SDEI_DS_EVENT_0, NRD_CSS_NS_RAM_ECC_CE_INT, NRD_RAS_INTR_TYPE_SPI},
 
 	/* Non Secure base RAM ECC UE interrupt */
-	{SGI_SDEI_DS_EVENT_0, NS_RAM_ECC_UE_INT, SGI_RAS_INTR_TYPE_SPI},
+	{NRD_SDEI_DS_EVENT_0, NRD_CSS_NS_RAM_ECC_UE_INT, NRD_RAS_INTR_TYPE_SPI},
 
 	/* CPU 1-bit ECC CE error interrupt */
-	{SGI_SDEI_DS_EVENT_1, PLAT_CORE_FAULT_IRQ, SGI_RAS_INTR_TYPE_PPI}
+	{NRD_SDEI_DS_EVENT_1, PLAT_CORE_FAULT_IRQ, NRD_RAS_INTR_TYPE_PPI}
 };
 
 /* RAS error record list definition, used by the common RAS framework. */
 struct err_record_info plat_err_records[] = {
 	/* Base element RAM Non-secure error record. */
-	ERR_RECORD_MEMMAP_V1(SOC_NS_RAM_ERR_REC_BASE, 4, NULL,
-				&sgi_ras_sram_intr_handler, 0),
-	ERR_RECORD_SYSREG_V1(0, 1, NULL, &sgi_ras_cpu_intr_handler, 0),
+	ERR_RECORD_MEMMAP_V1(NRD_CSS_NS_RAM_ERR_REC_BASE, 4, NULL,
+				&nrd_ras_sram_intr_handler, 0),
+	ERR_RECORD_SYSREG_V1(0, 1, NULL, &nrd_ras_cpu_intr_handler, 0),
 };
 
 /* RAS error interrupt list definition, used by the common RAS framework. */
@@ -33,10 +34,10 @@ struct ras_interrupt plat_ras_interrupts[] = {
 		.intr_number = PLAT_CORE_FAULT_IRQ,
 		.err_record = &plat_err_records[1],
 	}, {
-		.intr_number = NS_RAM_ECC_CE_INT,
+		.intr_number = NRD_CSS_NS_RAM_ECC_CE_INT,
 		.err_record = &plat_err_records[0],
 	}, {
-		.intr_number = NS_RAM_ECC_UE_INT,
+		.intr_number = NRD_CSS_NS_RAM_ECC_UE_INT,
 		.err_record = &plat_err_records[0],
 	},
 };
@@ -47,7 +48,7 @@ REGISTER_ERR_RECORD_INFO(plat_err_records);
 REGISTER_RAS_INTERRUPTS(plat_ras_interrupts);
 
 /* Platform RAS handling config data definition */
-struct plat_sgi_ras_config ras_config = {
+struct plat_nrd_ras_config ras_config = {
 	plat_ras_map,
 	ARRAY_SIZE(plat_ras_map)
 };
diff --git a/plat/arm/board/rdn2/rdn2_security.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_security.c
similarity index 55%
rename from plat/arm/board/rdn2/rdn2_security.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_security.c
index 7cd4a1c8..7319d1a4 100644
--- a/plat/arm/board/rdn2/rdn2_security.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,9 +8,9 @@
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
-#define RDN2_TZC_CPER_REGION					\
-	{CSS_SGI_SP_CPER_BUF_BASE, (CSS_SGI_SP_CPER_BUF_BASE +	\
-	CSS_SGI_SP_CPER_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
+#define RDN2_TZC_CPER_REGION				\
+	{NRD_CSS_SP_CPER_BUF_BASE, (NRD_CSS_SP_CPER_BUF_BASE +	\
+	NRD_CSS_SP_CPER_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
 	PLAT_ARM_TZC_NS_DEV_ACCESS}
 
 static const arm_tzc_regions_info_t tzc_regions[] = {
@@ -21,29 +21,29 @@ static const arm_tzc_regions_info_t tzc_regions[] = {
 	{}
 };
 
-#if (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1)
-static const arm_tzc_regions_info_t tzc_regions_mc[][CSS_SGI_CHIP_COUNT - 1] = {
+#if (NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 1)
+static const arm_tzc_regions_info_t tzc_regions_mc[][NRD_CHIP_COUNT - 1] = {
 	{
 		/* TZC memory regions for second chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(1),
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(1),
 		{}
 	},
-#if CSS_SGI_CHIP_COUNT > 2
+#if NRD_CHIP_COUNT > 2
 	{
 		/* TZC memory regions for third chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(2),
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(2),
 		{}
 	},
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
+#if NRD_CHIP_COUNT > 3
 	{
 		/* TZC memory regions for fourth chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(3),
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(3),
 		{}
 	},
 #endif
 };
-#endif /* CSS_SGI_PLATFORM_VARIANT && CSS_SGI_CHIP_COUNT */
+#endif /* NRD_PLATFORM_VARIANT && NRD_CHIP_COUNT */
 
 /* Initialize the secure environment */
 void plat_arm_security_setup(void)
@@ -56,14 +56,14 @@ void plat_arm_security_setup(void)
 		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
 	}
 
-#if (CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1)
+#if (NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 1)
 	unsigned int j;
 
-	for (i = 1; i < CSS_SGI_CHIP_COUNT; i++) {
+	for (i = 1; i < NRD_CHIP_COUNT; i++) {
 		INFO("Configuring TrustZone Controller for Chip %u\n", i);
 
 		for (j = 0; j < TZC400_COUNT; j++) {
-			arm_tzc400_setup(CSS_SGI_REMOTE_CHIP_MEM_OFFSET(i)
+			arm_tzc400_setup(NRD_REMOTE_CHIP_MEM_OFFSET(i)
 				+ TZC400_BASE(j), tzc_regions_mc[i-1]);
 		}
 	}
diff --git a/plat/arm/board/rdn2/rdn2_topology.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_topology.c
similarity index 77%
rename from plat/arm/board/rdn2/rdn2_topology.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_topology.c
index 24acc4d8..b8b6b7ad 100644
--- a/plat/arm/board/rdn2/rdn2_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,31 +11,31 @@
  * The power domain tree descriptor.
  ******************************************************************************/
 const unsigned char rd_n2_pd_tree_desc[] = {
-	(PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT),
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(PLAT_ARM_CLUSTER_COUNT) * (NRD_CHIP_COUNT),
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #if (PLAT_ARM_CLUSTER_COUNT > 4 || \
-	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 1))
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 1))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
 #if (PLAT_ARM_CLUSTER_COUNT > 8 || \
-	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 2))
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 2))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
 #if (PLAT_ARM_CLUSTER_COUNT > 8 || \
-	(CSS_SGI_PLATFORM_VARIANT == 2 && CSS_SGI_CHIP_COUNT > 3))
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 3))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
 };
 
@@ -51,25 +51,25 @@ const unsigned char *plat_get_power_domain_tree_desc(void)
  * The array mapping platform core position (implemented by plat_my_core_pos())
  * to the SCMI power domain ID implemented by SCP.
  ******************************************************************************/
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
+#if (NRD_PLATFORM_VARIANT == 2)
 const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
-#if (CSS_SGI_CHIP_COUNT > 1)
+#if (NRD_CHIP_COUNT > 1)
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 2)
+#if (NRD_CHIP_COUNT > 2)
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
+#if (NRD_CHIP_COUNT > 3)
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)),
diff --git a/plat/arm/board/rdn2/rdn2_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_trusted_boot.c
similarity index 88%
rename from plat/arm/board/rdn2/rdn2_trusted_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdn2/rdn2_trusted_boot.c
index 4592b8fb..84622d00 100644
--- a/plat/arm/board/rdn2/rdn2_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdn2/rdn2_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_fw_config.dts
similarity index 83%
rename from plat/arm/board/rdv1/fdts/rdv1_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_fw_config.dts
index 9c9cefe8..d4434437 100644
--- a/plat/arm/board/rdv1/fdts/rdv1_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_nt_fw_config.dts
similarity index 83%
rename from plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_nt_fw_config.dts
index 62ba2c3f..fb088854 100644
--- a/plat/arm/board/rdv1/fdts/rdv1_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_tb_fw_config.dts
similarity index 89%
rename from plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_tb_fw_config.dts
index 49eda273..c370623b 100644
--- a/plat/arm/board/rdv1/fdts/rdv1_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/fdts/rdv1_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdv1/include/platform_def.h
similarity index 64%
rename from plat/arm/board/rdv1/include/platform_def.h
rename to plat/arm/board/neoverse_rd/platform/rdv1/include/platform_def.h
index 620fa3e2..cd401174 100644
--- a/plat/arm/board/rdv1/include/platform_def.h
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,19 +8,21 @@
 #define PLATFORM_DEF_H
 
 #include <lib/utils_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_plat_arm_def1.h>
+#include <nrd_ros_fw_def1.h>
 
-#include <sgi_soc_platform_def.h>
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
 
 #define PLAT_ARM_CLUSTER_COUNT		U(16)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
+#define NRD_MAX_CPUS_PER_CLUSTER	U(1)
+#define NRD_MAX_PE_PER_CPU		U(1)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45400000)
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
 /* TZC Related Constants */
 #define PLAT_ARM_TZC_BASE		UL(0x21830000)
 #define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
@@ -47,22 +49,10 @@
 		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
 
 /* Maximum number of address bits used per chip */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(42)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
+#define NRD_ADDR_BITS_PER_CHIP	U(42)
 
 /* GIC related constants */
 #define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
 #define PLAT_ARM_GICR_BASE		UL(0x30140000)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdv1/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv1/platform.mk
similarity index 64%
rename from plat/arm/board/rdv1/platform.mk
rename to plat/arm/board/neoverse_rd/platform/rdv1/platform.mk
index a5fba671..db8efbbe 100644
--- a/plat/arm/board/rdv1/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -6,17 +6,18 @@
 # RD-V1 platform uses GIC-700 which is based on GICv4.1
 GIC_ENABLE_V4_EXTN	:=	1
 
-include plat/arm/css/sgi/sgi-common.mk
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-RDV1_BASE		=	plat/arm/board/rdv1
+RDV1_BASE		=	plat/arm/board/neoverse_rd/platform/rdv1
 
-PLAT_INCLUDES		+=	-I${RDV1_BASE}/include/
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd1/	\
+				-I${RDV1_BASE}/include/
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat1.c
 
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDV1_BASE}/rdv1_err.c
 
 BL2_SOURCES		+=	${RDV1_BASE}/rdv1_plat.c	\
@@ -27,7 +28,7 @@ BL2_SOURCES		+=	${RDV1_BASE}/rdv1_plat.c	\
 				plat/arm/common/arm_tzc400.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDV1_BASE}/rdv1_plat.c	\
 				${RDV1_BASE}/rdv1_topology.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -57,9 +58,18 @@ NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
-override ENABLE_FEAT_AMU		:= 1
+override ENABLE_FEAT_AMU		:= 2
+override SPMD_SPM_AT_SEL2		:= 0
 
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-V1 should always be 0, \
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq ($(NRD_PLATFORM_VARIANT),0)
+ $(error "NRD_PLATFORM_VARIANT for RD-V1 should always be 0, \
+     currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
+
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
+# Enable the flag since RD-V1 has a system level cache
+NEOVERSE_Nx_EXTERNAL_LLC		:=	1
diff --git a/plat/arm/board/rdv1/rdv1_err.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_err.c
similarity index 71%
rename from plat/arm/board/rdv1/rdv1_err.c
rename to plat/arm/board/neoverse_rd/platform/rdv1/rdv1_err.c
index 68f9a3ef..d75f525c 100644
--- a/plat/arm/board/rdv1/rdv1_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1/rdv1_plat.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_plat.c
similarity index 59%
rename from plat/arm/board/rdv1/rdv1_plat.c
rename to plat/arm/board/neoverse_rd/platform/rdv1/rdv1_plat.c
index ab5251e5..7cdc19a9 100644
--- a/plat/arm/board/rdv1/rdv1_plat.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_plat.c
@@ -1,24 +1,25 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <plat/common/platform.h>
-#include <sgi_plat.h>
 
-unsigned int plat_arm_sgi_get_platform_id(void)
+#include <nrd_plat.h>
+
+unsigned int plat_arm_nrd_get_platform_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
 				& SID_SYSTEM_ID_PART_NUM_MASK;
 }
 
-unsigned int plat_arm_sgi_get_config_id(void)
+unsigned int plat_arm_nrd_get_config_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
 }
 
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
 {
 	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
 			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
@@ -26,5 +27,5 @@ unsigned int plat_arm_sgi_get_multi_chip_mode(void)
 
 void bl31_platform_setup(void)
 {
-	sgi_bl31_common_platform_setup();
+	nrd_bl31_common_platform_setup();
 }
diff --git a/plat/arm/board/rdv1/rdv1_security.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_security.c
similarity index 82%
rename from plat/arm/board/rdv1/rdv1_security.c
rename to plat/arm/board/neoverse_rd/platform/rdv1/rdv1_security.c
index 1247db86..a936a71b 100644
--- a/plat/arm/board/rdv1/rdv1_security.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1/rdv1_topology.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_topology.c
similarity index 77%
rename from plat/arm/board/rdv1/rdv1_topology.c
rename to plat/arm/board/neoverse_rd/platform/rdv1/rdv1_topology.c
index ab64fd8d..20e4266b 100644
--- a/plat/arm/board/rdv1/rdv1_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,22 +12,22 @@
  ******************************************************************************/
 const unsigned char rd_v1_pd_tree_desc[] = {
 	PLAT_ARM_CLUSTER_COUNT,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER
 };
 
 /*******************************************************************************
diff --git a/plat/arm/board/rdv1/rdv1_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_trusted_boot.c
similarity index 88%
rename from plat/arm/board/rdv1/rdv1_trusted_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdv1/rdv1_trusted_boot.c
index 4592b8fb..84622d00 100644
--- a/plat/arm/board/rdv1/rdv1_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1/rdv1_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_fw_config.dts
similarity index 83%
rename from plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_fw_config.dts
index 9c9cefe8..d4434437 100644
--- a/plat/arm/board/rdv1mc/fdts/rdv1mc_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
similarity index 83%
rename from plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
index 71c7db3c..78fa31e1 100644
--- a/plat/arm/board/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
similarity index 89%
rename from plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
index 49eda273..c370623b 100644
--- a/plat/arm/board/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/fdts/rdv1mc_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1mc/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdv1mc/include/platform_def.h
similarity index 69%
rename from plat/arm/board/rdv1mc/include/platform_def.h
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/include/platform_def.h
index 36709048..b4c5c0a2 100644
--- a/plat/arm/board/rdv1mc/include/platform_def.h
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,18 +8,21 @@
 #define PLATFORM_DEF_H
 
 #include <lib/utils_def.h>
-#include <sgi_soc_platform_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_plat_arm_def1.h>
+#include <nrd_ros_fw_def1.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
 
 #define PLAT_ARM_CLUSTER_COUNT		U(4)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
+#define NRD_MAX_CPUS_PER_CLUSTER	U(1)
+#define NRD_MAX_PE_PER_CPU		U(1)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45400000)
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
 /* TZC Related Constants */
 #define PLAT_ARM_TZC_BASE		UL(0x21830000)
 #define TZC400_BASE(n)			(PLAT_ARM_TZC_BASE + \
@@ -47,17 +50,14 @@
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
 
 /* Remote chip address offset (4TB per chip) */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(42)
-
-/* Physical and virtual address space limits for MMU in AARCH64 mode */
-#define PLAT_PHY_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
+#define NRD_ADDR_BITS_PER_CHIP	U(42)
 
 /* GIC related constants */
 #define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
 #define PLAT_ARM_GICR_BASE		UL(0x30140000)
 
+/* GIC SPI range for multichip */
+#define NRD_CHIP0_SPI_MIN		U(32)
+#define NRD_CHIP0_SPI_MAX		U(991)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdv1mc/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk
similarity index 65%
rename from plat/arm/board/rdv1mc/platform.mk
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk
index 92f7c101..6d518d5c 100644
--- a/plat/arm/board/rdv1mc/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,17 +7,18 @@
 GIC_ENABLE_V4_EXTN		:=	1
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
 
-include plat/arm/css/sgi/sgi-common.mk
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-RDV1MC_BASE	=	plat/arm/board/rdv1mc
+RDV1MC_BASE	=	plat/arm/board/neoverse_rd/platform/rdv1mc
 
-PLAT_INCLUDES		+=	-I${RDV1MC_BASE}/include/
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd1/	\
+				-I${RDV1MC_BASE}/include/
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_v1.S
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat1.c
 
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDV1MC_BASE}/rdv1mc_err.c
 
 BL2_SOURCES		+=	${RDV1MC_BASE}/rdv1mc_plat.c	\
@@ -28,7 +29,7 @@ BL2_SOURCES		+=	${RDV1MC_BASE}/rdv1mc_plat.c	\
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${RDV1MC_BASE}/rdv1mc_plat.c	\
 				${RDV1MC_BASE}/rdv1mc_topology.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -56,9 +57,9 @@ $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
 
 $(eval $(call CREATE_SEQ,SEQ,4))
-ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),$(SEQ)))
+ifneq ($(NRD_CHIP_COUNT),$(filter $(NRD_CHIP_COUNT),$(SEQ)))
  $(error  "Chip count for RD-V1-MC should be either $(SEQ) \
- currently it is set to ${CSS_SGI_CHIP_COUNT}.")
+ currently it is set to ${NRD_CHIP_COUNT}.")
 endif
 
 FDT_SOURCES		+=	${RDV1MC_BASE}/fdts/${PLAT}_nt_fw_config.dts
@@ -68,9 +69,18 @@ NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
-override ENABLE_FEAT_AMU		:= 1
+override ENABLE_FEAT_AMU		:= 2
+override SPMD_SPM_AT_SEL2		:= 0
 
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-V1-MC should always be 0, \
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq ($(NRD_PLATFORM_VARIANT),0)
+ $(error "NRD_PLATFORM_VARIANT for RD-V1-MC should always be 0, \
+     currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
+
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
+endif
+
+# Enable the flag since RD-V1-MC has a system level cache
+NEOVERSE_Nx_EXTERNAL_LLC		:=	1
diff --git a/plat/arm/board/rdv1mc/rdv1mc_err.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_err.c
similarity index 71%
rename from plat/arm/board/rdv1mc/rdv1mc_err.c
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_err.c
index 755a5034..b855edd7 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_err.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdv1mc/rdv1mc_plat.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c
similarity index 54%
rename from plat/arm/board/rdv1mc/rdv1mc_plat.c
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c
index e4469dcc..5713cb9a 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_plat.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,47 +8,49 @@
 #include <drivers/arm/gic600_multichip.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <sgi_soc_platform_def.h>
-#include <sgi_plat.h>
+
+#include <nrd_plat.h>
 
 #if defined(IMAGE_BL31)
 static const mmap_region_t rdv1mc_dynamic_mmap[] = {
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
-	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1),
-#if (CSS_SGI_CHIP_COUNT > 2)
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(2),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(2),
-	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(2),
+	NRD_CSS_SHARED_RAM_MMAP(1),
+	NRD_CSS_PERIPH_MMAP(1),
+	NRD_ROS_PERIPH_MMAP(1),
+#if (NRD_CHIP_COUNT > 2)
+	NRD_CSS_SHARED_RAM_MMAP(2),
+	NRD_CSS_PERIPH_MMAP(2),
+	NRD_ROS_PERIPH_MMAP(2),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
-	ARM_MAP_SHARED_RAM_REMOTE_CHIP(3),
-	CSS_SGI_MAP_DEVICE_REMOTE_CHIP(3),
-	SOC_CSS_MAP_DEVICE_REMOTE_CHIP(3)
+#if (NRD_CHIP_COUNT > 3)
+	NRD_CSS_SHARED_RAM_MMAP(3),
+	NRD_CSS_PERIPH_MMAP(3),
+	NRD_ROS_PERIPH_MMAP(3)
 #endif
 };
 
 static struct gic600_multichip_data rdv1mc_multichip_data __init = {
 	.rt_owner_base = PLAT_ARM_GICD_BASE,
 	.rt_owner = 0,
-	.chip_count = CSS_SGI_CHIP_COUNT,
+	.chip_count = NRD_CHIP_COUNT,
 	.chip_addrs = {
 		PLAT_ARM_GICD_BASE >> 16,
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
-#if (CSS_SGI_CHIP_COUNT > 2)
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
+#if (NRD_CHIP_COUNT > 2)
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
-		(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
+#if (NRD_CHIP_COUNT > 3)
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
 #endif
 	},
 	.spi_ids = {
-		{PLAT_ARM_GICD_BASE, 32, 255},
+		{PLAT_ARM_GICD_BASE,
+		NRD_CHIP0_SPI_MIN,
+		NRD_CHIP0_SPI_MAX},
 		{0, 0, 0},
-#if (CSS_SGI_CHIP_COUNT > 2)
+#if (NRD_CHIP_COUNT > 2)
 		{0, 0, 0},
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
+#if (NRD_CHIP_COUNT > 3)
 		{0, 0, 0},
 #endif
 	}
@@ -58,31 +60,31 @@ static uintptr_t rdv1mc_multichip_gicr_frames[] = {
 	/* Chip 0's GICR Base */
 	PLAT_ARM_GICR_BASE,
 	/* Chip 1's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
-#if (CSS_SGI_CHIP_COUNT > 2)
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
+#if (NRD_CHIP_COUNT > 2)
 	/* Chip 2's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
+#if (NRD_CHIP_COUNT > 3)
 	/* Chip 3's GICR BASE */
-	PLAT_ARM_GICR_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
 #endif
 	UL(0)	/* Zero Termination */
 };
 #endif /* IMAGE_BL31 */
 
-unsigned int plat_arm_sgi_get_platform_id(void)
+unsigned int plat_arm_nrd_get_platform_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
 				& SID_SYSTEM_ID_PART_NUM_MASK;
 }
 
-unsigned int plat_arm_sgi_get_config_id(void)
+unsigned int plat_arm_nrd_get_config_id(void)
 {
 	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
 }
 
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
 {
 	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
 			SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
@@ -99,13 +101,13 @@ void bl31_platform_setup(void)
 	int ret;
 	unsigned int i;
 
-	if ((plat_arm_sgi_get_multi_chip_mode() == 0) &&
-			(CSS_SGI_CHIP_COUNT > 1)) {
-		ERROR("Chip Count is set to %u but multi-chip mode is not "
-			"enabled\n", CSS_SGI_CHIP_COUNT);
+	if ((plat_arm_nrd_get_multi_chip_mode() == 0) &&
+			(NRD_CHIP_COUNT > 1)) {
+		ERROR("Chip Count is %u but multi-chip mode is not enabled\n",
+			NRD_CHIP_COUNT);
 		panic();
-	} else if ((plat_arm_sgi_get_multi_chip_mode() == 1) &&
-			(CSS_SGI_CHIP_COUNT > 1)) {
+	} else if ((plat_arm_nrd_get_multi_chip_mode() == 1) &&
+			(NRD_CHIP_COUNT > 1)) {
 		INFO("Enabling support for multi-chip in RD-V1-MC\n");
 
 		for (i = 0; i < ARRAY_SIZE(rdv1mc_dynamic_mmap); i++) {
@@ -126,6 +128,6 @@ void bl31_platform_setup(void)
 		gic600_multichip_init(&rdv1mc_multichip_data);
 	}
 
-	sgi_bl31_common_platform_setup();
+	nrd_bl31_common_platform_setup();
 }
 #endif /* IMAGE_BL31 */
diff --git a/plat/arm/board/rdv1mc/rdv1mc_security.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_security.c
similarity index 63%
rename from plat/arm/board/rdv1mc/rdv1mc_security.c
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_security.c
index adc0bf81..1e59831b 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_security.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,29 +14,29 @@ static const arm_tzc_regions_info_t tzc_regions[] = {
 	{}
 };
 
-#if CSS_SGI_CHIP_COUNT > 1
-static const arm_tzc_regions_info_t tzc_regions_mc[][CSS_SGI_CHIP_COUNT - 1] = {
+#if NRD_CHIP_COUNT > 1
+static const arm_tzc_regions_info_t tzc_regions_mc[][NRD_CHIP_COUNT - 1] = {
 	{
 		/* TZC memory regions for second chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(1),
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(1),
 		{}
 	},
-#if CSS_SGI_CHIP_COUNT > 2
+#if NRD_CHIP_COUNT > 2
 	{
 		/* TZC memory regions for third chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(2),
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(2),
 		{}
 	},
 #endif
-#if CSS_SGI_CHIP_COUNT > 3
+#if NRD_CHIP_COUNT > 3
 	{
 		/* TZC memory regions for fourth chip */
-		SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(3),
+		NRD_ROS_TZC_NS_REMOTE_REGIONS_DEF(3),
 		{}
 	},
 #endif
 };
-#endif /* CSS_SGI_CHIP_COUNT */
+#endif /* NRD_CHIP_COUNT */
 
 /* Initialize the secure environment */
 void plat_arm_security_setup(void)
@@ -49,14 +49,14 @@ void plat_arm_security_setup(void)
 		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
 	}
 
-#if CSS_SGI_CHIP_COUNT > 1
+#if NRD_CHIP_COUNT > 1
 	unsigned int j;
 
-	for (i = 1; i < CSS_SGI_CHIP_COUNT; i++) {
+	for (i = 1; i < NRD_CHIP_COUNT; i++) {
 		INFO("Configuring TrustZone Controller for Chip %u\n", i);
 
 		for (j = 0; j < TZC400_COUNT; j++) {
-			arm_tzc400_setup(CSS_SGI_REMOTE_CHIP_MEM_OFFSET(i)
+			arm_tzc400_setup(NRD_REMOTE_CHIP_MEM_OFFSET(i)
 				+ TZC400_BASE(j), tzc_regions_mc[i-1]);
 		}
 	}
diff --git a/plat/arm/board/rdv1mc/rdv1mc_topology.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_topology.c
similarity index 70%
rename from plat/arm/board/rdv1mc/rdv1mc_topology.c
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_topology.c
index 4486e5cf..52514ca3 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,34 +7,35 @@
 #include <common/debug.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/arm/css/common/css_pm.h>
-#include <sgi_variant.h>
+
+#include <nrd_variant.h>
 
 /******************************************************************************
  * The power domain tree descriptor.
  ******************************************************************************/
 const unsigned char rd_v1_mc_pd_tree_desc_multi_chip[] = {
-	((PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT)),
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-#if (CSS_SGI_CHIP_COUNT > 1)
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+	((PLAT_ARM_CLUSTER_COUNT) * (NRD_CHIP_COUNT)),
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#if (NRD_CHIP_COUNT > 1)
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
-#if (CSS_SGI_CHIP_COUNT > 2)
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
+#if (NRD_CHIP_COUNT > 2)
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER
+#if (NRD_CHIP_COUNT > 3)
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER
 #endif
 };
 
@@ -43,7 +44,7 @@ const unsigned char rd_v1_mc_pd_tree_desc_multi_chip[] = {
  ******************************************************************************/
 const unsigned char *plat_get_power_domain_tree_desc(void)
 {
-	if (plat_arm_sgi_get_multi_chip_mode() == 1)
+	if (plat_arm_nrd_get_multi_chip_mode() == 1)
 		return rd_v1_mc_pd_tree_desc_multi_chip;
 	panic();
 }
@@ -57,19 +58,19 @@ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
-#if (CSS_SGI_CHIP_COUNT > 1)
+#if (NRD_CHIP_COUNT > 1)
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 2)
+#if (NRD_CHIP_COUNT > 2)
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)),
 	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)),
 #endif
-#if (CSS_SGI_CHIP_COUNT > 3)
+#if (NRD_CHIP_COUNT > 3)
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)),
 	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)),
diff --git a/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_trusted_boot.c
similarity index 88%
rename from plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_trusted_boot.c
index 4592b8fb..84622d00 100644
--- a/plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv1mc/rdv1mc_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_fw_config.dts
similarity index 71%
rename from plat/arm/board/rdn2/fdts/rdn2_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_fw_config.dts
index 9c9cefe8..62ba0fad 100644
--- a/plat/arm/board/rdn2/fdts/rdn2_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,13 +13,13 @@
 		compatible = "fconf,dyn_cfg-dtb_registry";
 
 		tb_fw-config {
-			load-address = <0x0 0x4001300>;
+			load-address = <0x0 0x01f300>;
 			max-size = <0x200>;
 			id = <TB_FW_CONFIG_ID>;
 		};
 
 		nt_fw-config {
-			load-address = <0x0 0xFEF00000>;
+			load-address = <0x0 0xF3000000>;
 			max-size = <0x0100000>;
 			id = <NT_FW_CONFIG_ID>;
 		};
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts
similarity index 78%
rename from plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts
index 0af821e1..941d4a03 100644
--- a/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 /dts-v1/;
 / {
 	/* compatible string */
-	compatible = "arm,rd-e1edge";
+	compatible = "arm,rd-v3";
 
 	/*
 	 * Place holder for system-id node with default values. The
@@ -19,5 +19,4 @@
 		config-id = <0x0>;
 		multi-chip-mode = <0x0>;
 	};
-
 };
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_tb_fw_config.dts
similarity index 90%
rename from plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_tb_fw_config.dts
index dba91e53..a4c7c728 100644
--- a/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/fdts/rdv3_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h
new file mode 100644
index 00000000..b55dbe80
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat/arm/css/common/css_def.h>
+#include <nrd_css_fw_def3.h>
+#include <nrd_pas_def3.h>
+#include <nrd_plat_arm_def3.h>
+#include <nrd_ros_fw_def3.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
+
+/* PE-Cluster count */
+#if (NRD_PLATFORM_VARIANT == 1)
+#define PLAT_ARM_CLUSTER_COUNT		U(8)
+#elif (NRD_PLATFORM_VARIANT == 2)
+#define PLAT_ARM_CLUSTER_COUNT		U(4)
+#else
+#define PLAT_ARM_CLUSTER_COUNT		U(16)
+#endif
+#define NRD_MAX_CPUS_PER_CLUSTER	U(1)
+#define NRD_MAX_PE_PER_CPU		U(1)
+
+/* Shared RAM*/
+#define NRD_CSS_SHARED_SRAM_SIZE	UL(0x000100000)
+
+/* DRAM1 */
+#define NRD_CSS_DRAM1_SIZE		ULL(0x80000000)
+
+/* DRAM2 */
+#define NRD_CSS_DRAM2_SIZE		ULL(0x180000000)
+
+/* Address bits */
+#define NRD_ADDR_BITS_PER_CHIP		U(36)  /* 64GB */
+
+/*
+ * In the current implementation, the RoT Service request that requires the
+ * biggest message buffer is the RSE_DELEGATED_ATTEST_GET_PLATFORM_TOKEN. The
+ * maximum required buffer size is calculated based on the platform-specific
+ * needs of this request.
+ */
+#define PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE	UL(0x1000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h
new file mode 100644
index 00000000..fa64963b
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_mhuv3.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDV3_MHUV3_H
+#define RDV3_MHUV3_H
+
+void mhu_v3_get_secure_device_base(uintptr_t *base, bool sender);
+
+#endif /* RDV3_MHUV3_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h
new file mode 100644
index 00000000..cb8e786b
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/include/rdv3_rse_comms.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RDV3_RSE_COMMS_H
+#define RDV3_RSE_COMMS_H
+
+int plat_rse_comms_init(void);
+
+#endif /* RDV3_RSE_COMMS_H */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
new file mode 100644
index 00000000..f37d9038
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/platform.mk
@@ -0,0 +1,156 @@
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RD_V3_VARIANTS := 0 1 2
+ifneq ($(NRD_PLATFORM_VARIANT),						\
+	$(filter $(NRD_PLATFORM_VARIANT),$(RD_V3_VARIANTS)))
+	$(error "NRD_PLATFORM_VARIANT for RD-V3 should be 0, 1, or 2,"
+	"currently set to ${NRD_PLATFORM_VARIANT}.")
+endif
+
+$(eval $(call CREATE_SEQ,SEQ,4))
+ifneq ($(NRD_CHIP_COUNT),$(filter $(NRD_CHIP_COUNT),$(SEQ)))
+	$(error  "Chip count for RD-V3-MC should be either $(SEQ) \
+	currently it is set to ${NRD_CHIP_COUNT}.")
+endif
+
+# Build options
+# Major and Minor versions
+override ARM_ARCH_MAJOR			:= 8
+override ARM_ARCH_MINOR			:= 7
+
+# Misc options
+override CTX_INCLUDE_AARCH32_REGS	:= 0
+
+ifeq (${PLAT_RESET_TO_BL31}, 1)
+# Support for BL31 boot flow
+override RESET_TO_BL31			:= 1
+
+# arm_common.mk sets ENABLE_PIE=1, but Makefile blocks PIE for RME
+override ENABLE_PIE			:= 0
+
+# Non Trusted Firmware parameters
+override ARM_PRELOADED_DTB_BASE		:= 0xF3000000
+override ARM_LINUX_KERNEL_AS_BL33	:= 1
+override PRELOADED_BL33_BASE		:= 0xE0000000
+
+# These are internal build flags but as of now RESET_TO_BL31 won't work without defining them
+override NEED_BL1			:= no
+override NEED_BL2			:= no
+override NEED_BL32			:= no
+endif
+
+# RD-V3 platform uses GIC-700 which is based on GICv4.1
+GIC_ENABLE_V4_EXTN			:= 1
+
+# Enable GIC multichip extension only for multichip platforms
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
+GICV3_IMPL_GIC600_MULTICHIP	:= 1
+endif
+
+# RD-V3 uses MHUv3
+PLAT_MHU_VERSION := 3
+
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
+include drivers/arm/rse/rse_comms.mk
+include drivers/auth/mbedtls/mbedtls_common.mk
+ifeq (${MEASURED_BOOT},1)
+include drivers/measured_boot/rse/rse_measured_boot.mk
+endif
+
+RDV3_BASE	=	plat/arm/board/neoverse_rd/platform/rdv3
+
+PLAT_INCLUDES	+=	-I${NRD_COMMON_BASE}/include/nrd3/		\
+			-I${RDV3_BASE}/include/			\
+			-Iinclude/lib/psa
+
+NRD_CPU_SOURCES	:=	lib/cpus/aarch64/neoverse_v3.S
+
+# Source files for RD-V3 variants
+PLAT_BL_COMMON_SOURCES							\
+		+=	${NRD_COMMON_BASE}/nrd_plat3.c			\
+			${RDV3_BASE}/rdv3_common.c
+
+PLAT_MEASURED_BOOT_SOURCES						\
+		:=	${MEASURED_BOOT_SOURCES} 			\
+			${RSE_COMMS_SOURCES}				\
+			${RDV3_BASE}/rdv3_common_measured_boot.c \
+			lib/psa/measured_boot.c
+
+BL1_SOURCES	+=	${NRD_CPU_SOURCES}				\
+			${RDV3_BASE}/rdv3_err.c		\
+			${RDV3_BASE}/rdv3_mhuv3.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL1_SOURCES	+=	${RDV3_BASE}/rdv3_trusted_boot.c
+endif
+ifeq (${MEASURED_BOOT},1)
+BL1_SOURCES	+=	${PLAT_MEASURED_BOOT_SOURCES}			\
+			${RDV3_BASE}/rdv3_bl1_measured_boot.c
+endif
+
+BL2_SOURCES	+=	${RDV3_BASE}/rdv3_bl2_setup.c		\
+			${RDV3_BASE}/rdv3_err.c		\
+			${RDV3_BASE}/rdv3_mhuv3.c		\
+			${RDV3_BASE}/rdv3_security.c		\
+			lib/utils/mem_region.c				\
+			plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+BL2_SOURCES	+=	${RDV3_BASE}/rdv3_trusted_boot.c
+endif
+ifeq (${MEASURED_BOOT},1)
+BL2_SOURCES	+=	${PLAT_MEASURED_BOOT_SOURCES}			\
+			${RDV3_BASE}/rdv3_bl2_measured_boot.c
+endif
+
+ifeq (${PLAT_RESET_TO_BL31}, 1)
+BL31_SOURCES	+=	${RDV3_BASE}/rdv3_security.c
+endif
+
+BL31_SOURCES	+=	${NRD_CPU_SOURCES}				\
+			${MBEDTLS_SOURCES}				\
+			${RSE_COMMS_SOURCES}				\
+			${RDV3_BASE}/rdv3_bl31_setup.c	\
+			${RDV3_BASE}/rdv3_mhuv3.c		\
+			${RDV3_BASE}/rdv3_topology.c		\
+			${RDV3_BASE}/rdv3_plat_attest_token.c	\
+			${RDV3_BASE}/rdv3_realm_attest_key.c	\
+			drivers/arm/smmu/smmu_v3.c			\
+			drivers/cfi/v2m/v2m_flash.c			\
+			lib/psa/cca_attestation.c			\
+			lib/psa/delegated_attestation.c			\
+			lib/utils/mem_region.c				\
+			plat/arm/common/arm_dyn_cfg.c			\
+			plat/arm/common/arm_nor_psci_mem_protect.c
+ifeq (${NRD_PLATFORM_VARIANT}, 2)
+BL31_SOURCES	+=	drivers/arm/gic/v3/gic600_multichip.c
+endif
+
+# XLAT options for RD-V3 variants
+BL31_CFLAGS	+=      -DPLAT_XLAT_TABLES_DYNAMIC
+BL2_CFLAGS	+=      -DPLAT_XLAT_TABLES_DYNAMIC
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES	+=	${RDV3_BASE}/fdts/${PLAT}_fw_config.dts	\
+			${RDV3_BASE}/fdts/${PLAT}_tb_fw_config.dts \
+			${RDV3_BASE}/fdts/${PLAT}_nt_fw_config.dts
+
+FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
+TB_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+NT_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
+
+# Features for RD-V3 variants
+override ENABLE_FEAT_MPAM	:= 2
+override ENABLE_FEAT_AMU	:= 2
+override ENABLE_SVE_FOR_SWD	:= 1
+override ENABLE_SVE_FOR_NS	:= 2
+override ENABLE_FEAT_MTE2	:= 2
+override CTX_INCLUDE_SVE_REGS	:= 1
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c
new file mode 100644
index 00000000..4db9a111
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl1_measured_boot.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+#include <nrd_plat.h>
+#include <rdv3_rse_comms.h>
+
+/*
+ * Platform specific table with image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rse_mboot_metadata rdv3_rse_mboot_metadata[] = {
+	{
+		.id = FW_CONFIG_ID,
+		.slot = U(8),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_FW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = TB_FW_CONFIG_ID,
+		.slot = U(9),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_TB_FW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = BL2_IMAGE_ID,
+		.slot = U(10),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL2_IMAGE_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = RSE_MBOOT_INVALID_ID
+	}
+};
+
+void bl1_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)plat_rse_comms_init();
+
+	rse_measured_boot_init(rdv3_rse_mboot_metadata);
+}
+
+void bl1_plat_mboot_finish(void)
+{
+	/* Nothing to do. */
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c
new file mode 100644
index 00000000..1b94427a
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_measured_boot.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
+#include <lib/psa/measured_boot.h>
+#include <plat/common/common_def.h>
+#include <platform_def.h>
+
+#include <nrd_plat.h>
+#include <rdv3_rse_comms.h>
+
+/*
+ * Platform specific table with image IDs and metadata. Intentionally not a
+ * const struct, some members might set by bootloaders during trusted boot.
+ */
+struct rse_mboot_metadata rdv3_rse_mboot_metadata[] = {
+	{
+		.id = BL31_IMAGE_ID,
+		.slot = U(11),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL31_IMAGE_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = HW_CONFIG_ID,
+		.slot = U(12),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_HW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+	{
+		.id = SOC_FW_CONFIG_ID,
+		.slot = U(13),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
+		.lock_measurement = false
+	},
+#if ENABLE_RME
+	{
+		.id = RMM_IMAGE_ID,
+		.slot = U(14),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_RMM_IMAGE_STRING,
+		.lock_measurement = false
+	},
+#endif /* ENABLE_RME */
+	{
+		.id = RSE_MBOOT_INVALID_ID
+	}
+};
+
+void bl2_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)plat_rse_comms_init();
+
+	rse_measured_boot_init(rdv3_rse_mboot_metadata);
+}
+
+void bl2_plat_mboot_finish(void)
+{
+	/* Nothing to do. */
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_setup.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_setup.c
new file mode 100644
index 00000000..8dac8d3a
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl2_setup.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/gpt_rme/gpt_rme.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <nrd_plat.h>
+
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+	NRD_PAS_SHARED_SRAM,
+	NRD_PAS_SYSTEM_NCI,
+	NRD_PAS_DEBUG_NIC,
+	NRD_PAS_NS_UART,
+	NRD_PAS_REALM_UART,
+	NRD_PAS_AP_NS_WDOG,
+	NRD_PAS_AP_ROOT_WDOG,
+	NRD_PAS_AP_SECURE_WDOG,
+	NRD_PAS_SECURE_SRAM_ERB_AP,
+	NRD_PAS_NS_SRAM_ERB_AP,
+	NRD_PAS_ROOT_SRAM_ERB_AP,
+	NRD_PAS_REALM_SRAM_ERB_AP,
+	NRD_PAS_SECURE_SRAM_ERB_SCP,
+	NRD_PAS_NS_SRAM_ERB_SCP,
+	NRD_PAS_ROOT_SRAM_ERB_SCP,
+	NRD_PAS_REALM_SRAM_ERB_SCP,
+	NRD_PAS_SECURE_SRAM_ERB_MCP,
+	NRD_PAS_NS_SRAM_ERB_MCP,
+	NRD_PAS_ROOT_SRAM_ERB_MCP,
+	NRD_PAS_REALM_SRAM_ERB_MCP,
+	NRD_PAS_SECURE_SRAM_ERB_RSE,
+	NRD_PAS_NS_SRAM_ERB_RSE,
+	NRD_PAS_ROOT_SRAM_ERB_RSE,
+	NRD_PAS_REALM_SRAM_ERB_RSE,
+	NRD_PAS_RSE_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_RSE_NS_SRAM_ERB_RSM,
+	NRD_PAS_SCP_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_SCP_NS_SRAM_ERB_RSM,
+	NRD_PAS_MCP_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_MCP_NS_SRAM_ERB_RSM,
+	NRD_PAS_AP_SCP_ROOT_MHU,
+	NRD_PAS_AP_MCP_NS_MHU,
+	NRD_PAS_AP_MCP_SECURE_MHU,
+	NRD_PAS_AP_MCP_ROOT_MHU,
+	NRD_PAS_AP_RSE_NS_MHU,
+	NRD_PAS_AP_RSE_SECURE_MHU,
+	NRD_PAS_AP_RSE_ROOT_MHU,
+	NRD_PAS_AP_RSE_REALM_MHU,
+	NRD_PAS_SCP_MCP_RSE_CROSS_CHIP_MHU,
+	NRD_PAS_SYNCNT_MSTUPDTVAL_ADDR,
+	NRD_PAS_STM_SYSTEM_ITS,
+	NRD_PAS_SCP_MCP_RSE_SHARED_SRAM,
+	NRD_PAS_GIC,
+	NRD_PAS_NS_DRAM,
+	NRD_PAS_RMM,
+	NRD_PAS_L1GPT,
+	NRD_PAS_CMN,
+	NRD_PAS_LCP_PERIPHERAL,
+	NRD_PAS_DDR_IO,
+	NRD_PAS_SMMU_NCI_IO,
+	NRD_PAS_DRAM2_CHIP0,
+#if NRD_CHIP_COUNT > 1
+	NRD_PAS_DRAM1_CHIP1,
+	NRD_PAS_DRAM2_CHIP1,
+#endif
+#if NRD_CHIP_COUNT > 2
+	NRD_PAS_DRAM1_CHIP2,
+	NRD_PAS_DRAM2_CHIP2,
+#endif
+#if NRD_CHIP_COUNT > 3
+	NRD_PAS_DRAM1_CHIP3,
+	NRD_PAS_DRAM2_CHIP3
+#endif
+};
+
+static const arm_gpt_info_t arm_gpt_info = {
+	.pas_region_base  = pas_regions,
+	.pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions),
+	.l0_base = (uintptr_t)ARM_L0_GPT_BASE,
+	.l1_base = (uintptr_t)ARM_L1_GPT_BASE,
+	.l0_size = (size_t)ARM_L0_GPT_SIZE,
+	.l1_size = (size_t)ARM_L1_GPT_SIZE,
+	.pps = GPCCR_PPS_256TB,
+	.pgs = GPCCR_PGS_4K
+};
+
+const arm_gpt_info_t *plat_arm_get_gpt_info(void)
+{
+	return &arm_gpt_info;
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c
new file mode 100644
index 00000000..a5d687e8
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_bl31_setup.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/arm/smmu_v3.h>
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <nrd_plat.h>
+#include <nrd_variant.h>
+#include <rdv3_rse_comms.h>
+
+#if (NRD_PLATFORM_VARIANT == 2)
+static const mmap_region_t rdv3mc_dynamic_mmap[] = {
+#if NRD_CHIP_COUNT > 1
+	NRD_CSS_SHARED_RAM_MMAP(1),
+	NRD_CSS_PERIPH_MMAP(1),
+#endif
+#if NRD_CHIP_COUNT > 2
+	NRD_CSS_SHARED_RAM_MMAP(2),
+	NRD_CSS_PERIPH_MMAP(2),
+#endif
+#if NRD_CHIP_COUNT > 3
+	NRD_CSS_SHARED_RAM_MMAP(3),
+	NRD_CSS_PERIPH_MMAP(3),
+#endif
+};
+
+static struct gic600_multichip_data rdv3mc_multichip_data __init = {
+	.rt_owner_base = PLAT_ARM_GICD_BASE,
+	.rt_owner = 0,
+	.chip_count = NRD_CHIP_COUNT,
+	.chip_addrs = {
+		PLAT_ARM_GICD_BASE >> 16,
+#if NRD_CHIP_COUNT > 1
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1)) >> 16,
+#endif
+#if NRD_CHIP_COUNT > 2
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2)) >> 16,
+#endif
+#if NRD_CHIP_COUNT > 3
+		(PLAT_ARM_GICD_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3)) >> 16,
+#endif
+	},
+	.spi_ids = {
+		{PLAT_ARM_GICD_BASE, 32, 511},
+#if NRD_CHIP_COUNT > 1
+		{PLAT_ARM_GICD_BASE, 512, 991},
+#endif
+#if NRD_CHIP_COUNT > 2
+		{PLAT_ARM_GICD_BASE, 4096, 4575},
+#endif
+#if NRD_CHIP_COUNT > 3
+		{PLAT_ARM_GICD_BASE, 4576, 5055},
+#endif
+	}
+};
+
+static uintptr_t rdv3mc_multichip_gicr_frames[] = {
+	/* Chip 0's GICR Base */
+	PLAT_ARM_GICR_BASE,
+#if NRD_CHIP_COUNT > 1
+	/* Chip 1's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(1),
+#endif
+#if NRD_CHIP_COUNT > 2
+	/* Chip 2's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(2),
+#endif
+#if NRD_CHIP_COUNT > 3
+	/* Chip 3's GICR BASE */
+	PLAT_ARM_GICR_BASE + NRD_REMOTE_CHIP_MEM_OFFSET(3),
+#endif
+	UL(0)	/* Zero Termination */
+};
+#endif /* NRD_PLATFORM_VARIANT == 2 */
+
+void bl31_platform_setup(void)
+{
+	/*
+	 * Perform SMMUv3 GPT configuration for the GPC SMMU present in system
+	 * control block on RD-V3 platforms. This SMMUv3 initialization is
+	 * not fatal.
+	 *
+	 * Don't perform smmuv3_security_init() for this instance of SMMUv3 as
+	 * the global aborts need not be configured to allow the components in
+	 * system control block send transations downstream to SMMUv3.
+	 */
+	if (smmuv3_init(NRD_CSS_GPC_SMMUV3_BASE) != 0) {
+		WARN("Failed initializing System SMMU.\n");
+	}
+
+#if (NRD_PLATFORM_VARIANT == 2)
+	int ret;
+	unsigned int i;
+
+	if (plat_arm_nrd_get_multi_chip_mode() == 0) {
+		ERROR("Chip Count is %u but multi-chip mode is not enabled\n",
+		       NRD_CHIP_COUNT);
+		panic();
+	} else {
+		INFO("Enabling multi-chip support for RD-V3 variant\n");
+
+		for (i = 0; i < ARRAY_SIZE(rdv3mc_dynamic_mmap); i++) {
+			ret = mmap_add_dynamic_region(
+					rdv3mc_dynamic_mmap[i].base_pa,
+					rdv3mc_dynamic_mmap[i].base_va,
+					rdv3mc_dynamic_mmap[i].size,
+					rdv3mc_dynamic_mmap[i].attr);
+			if (ret != 0) {
+				ERROR("Failed to add entry i: %d (ret=%d)\n",
+				       i, ret);
+				panic();
+			}
+		}
+
+		plat_arm_override_gicr_frames(
+			rdv3mc_multichip_gicr_frames);
+		gic600_multichip_init(&rdv3mc_multichip_data);
+	}
+#endif /* NRD_PLATFORM_VARIANT == 2 */
+	nrd_bl31_common_platform_setup();
+
+	if (plat_rse_comms_init() != 0) {
+		WARN("Failed initializing AP-RSE comms.\n");
+	}
+}
+
+#if RESET_TO_BL31
+/*
+ * The GPT library might modify the gpt regions structure to optimize
+ * the layout, so the array cannot be constant.
+ */
+static pas_region_t pas_regions[] = {
+	NRD_PAS_SHARED_SRAM,
+	NRD_PAS_SYSTEM_NCI,
+	NRD_PAS_DEBUG_NIC,
+	NRD_PAS_NS_UART,
+	NRD_PAS_REALM_UART,
+	NRD_PAS_AP_NS_WDOG,
+	NRD_PAS_AP_ROOT_WDOG,
+	NRD_PAS_AP_SECURE_WDOG,
+	NRD_PAS_SECURE_SRAM_ERB_AP,
+	NRD_PAS_NS_SRAM_ERB_AP,
+	NRD_PAS_ROOT_SRAM_ERB_AP,
+	NRD_PAS_REALM_SRAM_ERB_AP,
+	NRD_PAS_SECURE_SRAM_ERB_SCP,
+	NRD_PAS_NS_SRAM_ERB_SCP,
+	NRD_PAS_ROOT_SRAM_ERB_SCP,
+	NRD_PAS_REALM_SRAM_ERB_SCP,
+	NRD_PAS_SECURE_SRAM_ERB_MCP,
+	NRD_PAS_NS_SRAM_ERB_MCP,
+	NRD_PAS_ROOT_SRAM_ERB_MCP,
+	NRD_PAS_REALM_SRAM_ERB_MCP,
+	NRD_PAS_SECURE_SRAM_ERB_RSE,
+	NRD_PAS_NS_SRAM_ERB_RSE,
+	NRD_PAS_ROOT_SRAM_ERB_RSE,
+	NRD_PAS_REALM_SRAM_ERB_RSE,
+	NRD_PAS_RSE_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_RSE_NS_SRAM_ERB_RSM,
+	NRD_PAS_SCP_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_SCP_NS_SRAM_ERB_RSM,
+	NRD_PAS_MCP_SECURE_SRAM_ERB_RSM,
+	NRD_PAS_MCP_NS_SRAM_ERB_RSM,
+	NRD_PAS_AP_SCP_ROOT_MHU,
+	NRD_PAS_AP_MCP_NS_MHU,
+	NRD_PAS_AP_MCP_SECURE_MHU,
+	NRD_PAS_AP_MCP_ROOT_MHU,
+	NRD_PAS_AP_RSE_NS_MHU,
+	NRD_PAS_AP_RSE_SECURE_MHU,
+	NRD_PAS_AP_RSE_ROOT_MHU,
+	NRD_PAS_AP_RSE_REALM_MHU,
+	NRD_PAS_SCP_MCP_RSE_CROSS_CHIP_MHU,
+	NRD_PAS_SYNCNT_MSTUPDTVAL_ADDR,
+	NRD_PAS_STM_SYSTEM_ITS,
+	NRD_PAS_SCP_MCP_RSE_SHARED_SRAM,
+	NRD_PAS_GIC,
+	NRD_PAS_NS_DRAM,
+	NRD_PAS_RMM,
+	NRD_PAS_L1GPT,
+	NRD_PAS_CMN,
+	NRD_PAS_LCP_PERIPHERAL,
+	NRD_PAS_DDR_IO,
+	NRD_PAS_SMMU_NCI_IO,
+	NRD_PAS_DRAM2_CHIP0,
+#if NRD_CHIP_COUNT > 1
+	NRD_PAS_DRAM1_CHIP1,
+	NRD_PAS_DRAM2_CHIP1,
+#endif
+#if NRD_CHIP_COUNT > 2
+	NRD_PAS_DRAM1_CHIP2,
+	NRD_PAS_DRAM2_CHIP2,
+#endif
+#if NRD_CHIP_COUNT > 3
+	NRD_PAS_DRAM1_CHIP3,
+	NRD_PAS_DRAM2_CHIP3
+#endif
+};
+
+static const arm_gpt_info_t arm_gpt_info = {
+	.pas_region_base  = pas_regions,
+	.pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions),
+	.l0_base = (uintptr_t)ARM_L0_GPT_BASE,
+	.l1_base = (uintptr_t)ARM_L1_GPT_BASE,
+	.l0_size = (size_t)ARM_L0_GPT_SIZE,
+	.l1_size = (size_t)ARM_L1_GPT_SIZE,
+	.pps = GPCCR_PPS_256TB,
+	.pgs = GPCCR_PGS_4K
+};
+
+const arm_gpt_info_t *plat_arm_get_gpt_info(void)
+{
+	return &arm_gpt_info;
+}
+
+#endif /* RESET_TO_BL31 */
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
new file mode 100644
index 00000000..10fe666b
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <drivers/arm/rse_comms.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <nrd_plat.h>
+#include <rdv3_mhuv3.h>
+#include <rdv3_rse_comms.h>
+
+unsigned int plat_arm_nrd_get_platform_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET) &
+	       SID_SYSTEM_ID_PART_NUM_MASK;
+}
+
+unsigned int plat_arm_nrd_get_config_id(void)
+{
+	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
+}
+
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
+{
+	return (mmio_read_32(SID_REG_BASE + SID_NODE_ID_OFFSET) &
+		SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
+}
+
+/*
+ * Get a pointer to the RMM-EL3 shared buffer and return it
+ * through the pointer passed as parameter.
+ *
+ * This function returns the size of the shared buffer.
+ */
+size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
+{
+	*shared = (uintptr_t)RMM_SHARED_BASE;
+
+	return (size_t)RMM_SHARED_SIZE;
+}
+
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
+{
+	uint64_t checksum, num_banks, num_consoles;
+	struct ns_dram_bank *bank_ptr;
+	struct console_info *console_ptr;
+
+	assert(manifest != NULL);
+
+	/* DRAM Bank-1 and Bank-2 */
+	num_banks = 2;
+	assert(num_banks <= ARM_DRAM_NUM_BANKS);
+
+	/* Set number of consoles */
+	num_consoles = NRD_CSS_RMM_CONSOLE_COUNT;
+
+	manifest->version = RMMD_MANIFEST_VERSION;
+	manifest->padding = 0U; /* RES0 */
+	manifest->plat_data = (uintptr_t)NULL;
+	manifest->plat_dram.num_banks = num_banks;
+	manifest->plat_console.num_consoles = num_consoles;
+
+	/*
+	 * Boot Manifest structure illustration, with two dram banks and
+	 * a single console.
+	 *
+	 * +----------------------------------------+
+	 * | offset |     field      |    comment   |
+	 * +--------+----------------+--------------+
+	 * |   0    |    version     |  0x00000003  |
+	 * +--------+----------------+--------------+
+	 * |   4    |    padding     |  0x00000000  |
+	 * +--------+----------------+--------------+
+	 * |   8    |   plat_data    |     NULL     |
+	 * +--------+----------------+--------------+
+	 * |   16   |   num_banks    |              |
+	 * +--------+----------------+              |
+	 * |   24   |     banks      |   plat_dram  |
+	 * +--------+----------------+              |
+	 * |   32   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   40   |  num_consoles  |              |
+	 * +--------+----------------+              |
+	 * |   48   |    consoles    | plat_console |
+	 * +--------+----------------+              |
+	 * |   56   |    checksum    |              |
+	 * +--------+----------------+--------------+
+	 * |   64   |     base 0     |              |
+	 * +--------+----------------+    bank[0]   |
+	 * |   72   |     size 0     |              |
+	 * +--------+----------------+--------------+
+	 * |   80   |     base 1     |              |
+	 * +--------+----------------+    bank[1]   |
+	 * |   88   |     size 1     |              |
+	 * +--------+----------------+--------------+
+	 * |   96   |     base       |              |
+	 * +--------+----------------+              |
+	 * |   104  |   map_pages    |              |
+	 * +--------+----------------+              |
+	 * |   112  |     name       |              |
+	 * +--------+----------------+  consoles[0] |
+	 * |   120  |   clk_in_hz    |              |
+	 * +--------+----------------+              |
+	 * |   128  |   baud_rate    |              |
+	 * +--------+----------------+              |
+	 * |   136  |     flags      |              |
+	 * +--------+----------------+--------------+
+	 */
+
+	bank_ptr = (struct ns_dram_bank *)
+			(((uintptr_t)manifest) + sizeof(*manifest));
+	console_ptr = (struct console_info *)
+			((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
+
+	manifest->plat_dram.banks = bank_ptr;
+	manifest->plat_console.consoles = console_ptr;
+
+	/* Ensure the manifest is not larger than the shared buffer */
+	assert((sizeof(struct rmm_manifest) +
+		(sizeof(struct console_info) *
+		manifest->plat_console.num_consoles) +
+		(sizeof(struct ns_dram_bank) * manifest->plat_dram.num_banks))
+		<= ARM_EL3_RMM_SHARED_SIZE);
+
+	/* Calculate checksum of plat_dram structure */
+	checksum = num_banks + (uint64_t)bank_ptr;
+
+	/* Store FVP DRAM banks data in Boot Manifest */
+	bank_ptr[0].base = ARM_NS_DRAM1_BASE;
+	bank_ptr[0].size = ARM_NS_DRAM1_SIZE;
+
+	bank_ptr[1].base = ARM_DRAM2_BASE;
+	bank_ptr[1].size = ARM_DRAM2_SIZE;
+
+	/* Update checksum */
+	checksum += bank_ptr[0].base + bank_ptr[0].size + bank_ptr[1].base +
+		bank_ptr[1].size;
+
+	/* Checksum must be 0 */
+	manifest->plat_dram.checksum = ~checksum + 1UL;
+
+	/* Calculate the checksum of the plat_consoles structure */
+	checksum = num_consoles + (uint64_t)console_ptr;
+
+	/* Zero out the console info struct */
+	memset((void *)console_ptr, '\0',
+		sizeof(struct console_info) * num_consoles);
+
+	console_ptr[0].map_pages = 1;
+	console_ptr[0].base = NRD_CSS_RMM_CONSOLE_BASE;
+	console_ptr[0].clk_in_hz = NRD_CSS_RMM_CONSOLE_CLK_IN_HZ;
+	console_ptr[0].baud_rate = NRD_CSS_RMM_CONSOLE_BAUD;
+
+	strlcpy(console_ptr[0].name, NRD_CSS_RMM_CONSOLE_NAME,
+		sizeof(console_ptr[0].name));
+
+	/* Update checksum */
+	checksum += console_ptr[0].base + console_ptr[0].map_pages +
+		console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
+
+	/* Checksum must be 0 */
+	manifest->plat_console.checksum = ~checksum + 1UL;
+
+	return 0;
+}
+
+int plat_rse_comms_init(void)
+{
+	uintptr_t snd_base, rcv_base;
+
+	/* Get sender and receiver frames for AP-RSE communication */
+	mhu_v3_get_secure_device_base(&snd_base, true);
+	mhu_v3_get_secure_device_base(&rcv_base, false);
+
+	VERBOSE("Initializing the rse_comms now\n");
+	/* Initialize the communication channel between AP and RSE */
+	return rse_comms_init(snd_base, rcv_base);
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c
new file mode 100644
index 00000000..f5160ceb
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common_measured_boot.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
+
+extern struct rse_mboot_metadata rdv3_rse_mboot_metadata[];
+
+struct rse_mboot_metadata *plat_rse_mboot_get_metadata(void)
+{
+	return rdv3_rse_mboot_metadata;
+}
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	int err;
+
+	/* Calculate image hash and record data in RSE */
+	err = rse_mboot_measure_and_record(rdv3_rse_mboot_metadata,
+					   image_data->image_base,
+					   image_data->image_size,
+					   image_id);
+	if (err != 0) {
+		ERROR("Measure and record failed for image id %u, err (%i)\n",
+		      image_id, err);
+	}
+
+	return err;
+}
+
+int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
+{
+	return rse_mboot_set_signer_id(rdv3_rse_mboot_metadata, pk_oid,
+				       pk_ptr, pk_len);
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c
new file mode 100644
index 00000000..270febf8
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_err.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*
+ * rdv3 error handler
+ */
+void __dead2 plat_arm_error_handler(int err)
+{
+	while (1) {
+		wfi();
+	}
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c
new file mode 100644
index 00000000..738f753d
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+
+#include <nrd_css_def3.h>
+#include <nrd_plat.h>
+#include <rdv3_mhuv3.h>
+
+void mhu_v3_get_secure_device_base(uintptr_t *base, bool sender)
+{
+	if (sender) {
+		*base = AP_RSE_ROOT_MHU_V3_PBX;
+	} else {
+		*base = AP_RSE_ROOT_MHU_V3_MBX;
+	}
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c
new file mode 100644
index 00000000..55846624
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_plat_attest_token.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <cca_attestation.h>
+#include <common/debug.h>
+#include <plat/common/common_def.h>
+#include <psa/error.h>
+
+int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
+				   uintptr_t hash, size_t hash_size,
+				   size_t *remaining_len)
+{
+	psa_status_t ret;
+
+	assert(*len == SZ_4K);
+
+	ret = cca_attestation_get_plat_token(buf, len, hash, hash_size);
+	if (ret != PSA_SUCCESS) {
+		ERROR("Unable to fetch CCA attestation token\n");
+		return -1;
+	}
+
+	assert(*len <= SZ_4K);
+
+	*remaining_len = 0;
+
+	return 0;
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_realm_attest_key.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_realm_attest_key.c
new file mode 100644
index 00000000..224c20b9
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_realm_attest_key.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdint.h>
+
+#include <cca_attestation.h>
+#include <common/debug.h>
+#include <psa/error.h>
+
+int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
+				       unsigned int type)
+{
+	psa_status_t ret;
+
+	ret = cca_attestation_get_realm_key(buf, len, type);
+	if (ret != PSA_SUCCESS) {
+		ERROR("Unable to fetch CCA attestation key\n");
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_security.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_security.c
new file mode 100644
index 00000000..a12d3e22
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_security.c
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Placeholder function to resolve build dependency */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c
new file mode 100644
index 00000000..6eb5002a
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_topology.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+
+/******************************************************************************
+ * The power domain tree descriptor.
+ ******************************************************************************/
+const unsigned char rd_v3_pd_tree_desc[] = {
+	(PLAT_ARM_CLUSTER_COUNT) * (NRD_CHIP_COUNT),
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#if (PLAT_ARM_CLUSTER_COUNT > 4 || \
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 1))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#endif
+#if (PLAT_ARM_CLUSTER_COUNT > 8 || \
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 2))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#endif
+#if (PLAT_ARM_CLUSTER_COUNT > 12 || \
+	(NRD_PLATFORM_VARIANT == 2 && NRD_CHIP_COUNT > 3))
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER,
+#endif
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return rd_v3_pd_tree_desc;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+#if (NRD_PLATFORM_VARIANT == 2)
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+#if (NRD_CHIP_COUNT > 1)
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
+#endif
+#if (NRD_CHIP_COUNT > 2)
+	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x2) | SET_SCMI_DOMAIN_ID(0x3)),
+#endif
+#if (NRD_CHIP_COUNT > 3)
+	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x3) | SET_SCMI_DOMAIN_ID(0x3)),
+#endif
+};
+#else
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+#if (NRD_PLATFORM_VARIANT == 0)
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xE)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xF)),
+#endif
+};
+#endif
diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_trusted_boot.c
similarity index 89%
rename from plat/arm/board/rde1edge/rde1edge_trusted_boot.c
rename to plat/arm/board/neoverse_rd/platform/rdv3/rdv3_trusted_boot.c
index 4592b8fb..6aec208d 100644
--- a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_fw_config.dts
similarity index 86%
rename from plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_fw_config.dts
index 84fc1ad5..fe62b6d1 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_nt_fw_config.dts
similarity index 86%
rename from plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_nt_fw_config.dts
index 260247a0..05734883 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_nt_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_tb_fw_config.dts
similarity index 89%
rename from plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
rename to plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_tb_fw_config.dts
index 49eda273..c370623b 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/fdts/sgi575_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/neoverse_rd/platform/sgi575/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/sgi575/include/platform_def.h
new file mode 100644
index 00000000..07970175
--- /dev/null
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/include/platform_def.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+#include <nrd_css_fw_def1.h>
+#include <nrd_plat_arm_def1.h>
+#include <nrd_ros_fw_def1.h>
+#include <nrd_sdei.h>
+
+/* Remote chip address offset */
+#define NRD_REMOTE_CHIP_MEM_OFFSET(n)	\
+		((ULL(1) << NRD_ADDR_BITS_PER_CHIP) * (n))
+
+#define PLAT_ARM_CLUSTER_COUNT		U(2)
+#define NRD_MAX_CPUS_PER_CLUSTER	U(4)
+#define NRD_MAX_PE_PER_CPU		U(1)
+
+#define PLAT_CSS_MHU_BASE		UL(0x45000000)
+
+/* Base address of DMC-620 instances */
+#define SGI575_DMC620_BASE0		UL(0x4e000000)
+#define SGI575_DMC620_BASE1		UL(0x4e100000)
+
+/* Maximum number of address bits used per chip */
+#define NRD_ADDR_BITS_PER_CHIP	U(36)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		UL(0x30000000)
+#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/neoverse_rd/platform/sgi575/platform.mk
similarity index 65%
rename from plat/arm/board/sgi575/platform.mk
rename to plat/arm/board/neoverse_rd/platform/sgi575/platform.mk
index 2f2bf73b..1f401070 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/platform.mk
@@ -1,22 +1,21 @@
 #
-# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-$(warning Platform ${PLAT} is deprecated. Some of the features might not work as expected)
+include plat/arm/board/neoverse_rd/common/nrd-common.mk
 
-include plat/arm/css/sgi/sgi-common.mk
+SGI575_BASE		=	plat/arm/board/neoverse_rd/platform/sgi575
 
-SGI575_BASE		=	plat/arm/board/sgi575
+PLAT_INCLUDES		+=	-I${NRD_COMMON_BASE}/include/nrd1/	\
+				-I${SGI575_BASE}/include/
 
-PLAT_INCLUDES		+=	-I${SGI575_BASE}/include/
+NRD_CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a75.S
 
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a75.S
+PLAT_BL_COMMON_SOURCES	+=	${NRD_COMMON_BASE}/nrd_plat1.c
 
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
-
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL1_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${SGI575_BASE}/sgi575_err.c
 
 BL2_SOURCES		+=	${SGI575_BASE}/sgi575_plat.c		\
@@ -26,7 +25,7 @@ BL2_SOURCES		+=	${SGI575_BASE}/sgi575_plat.c		\
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
+BL31_SOURCES		+=	${NRD_CPU_SOURCES}			\
 				${SGI575_BASE}/sgi575_plat.c		\
 				${SGI575_BASE}/sgi575_topology.c	\
 				drivers/cfi/v2m/v2m_flash.c		\
@@ -56,12 +55,19 @@ NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 # Add the NT_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
 
-ifneq ($(CSS_SGI_CHIP_COUNT),1)
+ifneq ($(NRD_CHIP_COUNT),1)
  $(error  "Chip count for SGI575 should be 1, currently set to \
-   ${CSS_SGI_CHIP_COUNT}.")
+   ${NRD_CHIP_COUNT}.")
+endif
+
+ifneq ($(NRD_PLATFORM_VARIANT),0)
+ $(error "NRD_PLATFORM_VARIANT for SGI575 should always be 0,\
+     currently set to ${NRD_PLATFORM_VARIANT}.")
 endif
 
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for SGI575 should always be 0,\
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
+ifneq (${RESET_TO_BL31},0)
+  $(error "Using BL31 as the reset vector is not supported on ${PLAT} platform. \
+  Please set RESET_TO_BL31 to 0.")
 endif
+
+override SPMD_SPM_AT_SEL2		:= 0
diff --git a/plat/arm/board/sgi575/sgi575_err.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_err.c
similarity index 71%
rename from plat/arm/board/sgi575/sgi575_err.c
rename to plat/arm/board/neoverse_rd/platform/sgi575/sgi575_err.c
index 21bfcb73..7e656abb 100644
--- a/plat/arm/board/sgi575/sgi575_err.c
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_err.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/sgi575/sgi575_plat.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_plat.c
similarity index 52%
rename from plat/arm/board/sgi575/sgi575_plat.c
rename to plat/arm/board/neoverse_rd/platform/sgi575/sgi575_plat.c
index dc294e6a..8b746160 100644
--- a/plat/arm/board/sgi575/sgi575_plat.c
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_plat.c
@@ -1,30 +1,31 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <plat/common/platform.h>
-#include <sgi_plat.h>
-#include <sgi_variant.h>
 
-unsigned int plat_arm_sgi_get_platform_id(void)
+#include <nrd_plat.h>
+#include <nrd_variant.h>
+
+unsigned int plat_arm_nrd_get_platform_id(void)
 {
 	return mmio_read_32(SSC_VERSION) & SSC_VERSION_PART_NUM_MASK;
 }
 
-unsigned int plat_arm_sgi_get_config_id(void)
+unsigned int plat_arm_nrd_get_config_id(void)
 {
 	return (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT)
 			& SSC_VERSION_CONFIG_MASK;
 }
 
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
+unsigned int plat_arm_nrd_get_multi_chip_mode(void)
 {
 	return 0;
 }
 
 void bl31_platform_setup(void)
 {
-	sgi_bl31_common_platform_setup();
+	nrd_bl31_common_platform_setup();
 }
diff --git a/plat/arm/board/sgi575/sgi575_security.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_security.c
similarity index 85%
rename from plat/arm/board/sgi575/sgi575_security.c
rename to plat/arm/board/neoverse_rd/platform/sgi575/sgi575_security.c
index 17d07d1a..8b8a3828 100644
--- a/plat/arm/board/sgi575/sgi575_security.c
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
-#include <sgi_dmc620_tzc_regions.h>
+#include <nrd_dmc620_tzc_regions.h>
 
 uintptr_t sgi575_dmc_base[] = {
 	SGI575_DMC620_BASE0,
@@ -20,7 +20,7 @@ static const tzc_dmc620_driver_data_t sgi575_plat_driver_data = {
 };
 
 static const tzc_dmc620_acc_addr_data_t sgi575_acc_addr_data[] = {
-	CSS_SGI_DMC620_TZC_REGIONS_DEF
+	NRD_DMC620_TZC_REGIONS_DEF
 };
 
 static const tzc_dmc620_config_data_t sgi575_plat_config_data = {
diff --git a/plat/arm/board/sgi575/sgi575_topology.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_topology.c
similarity index 89%
rename from plat/arm/board/sgi575/sgi575_topology.c
rename to plat/arm/board/neoverse_rd/platform/sgi575/sgi575_topology.c
index f7c38567..15ffc650 100644
--- a/plat/arm/board/sgi575/sgi575_topology.c
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,8 +11,8 @@
  ******************************************************************************/
 static const unsigned char sgi575_pd_tree_desc[] = {
 	PLAT_ARM_CLUSTER_COUNT,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER
+	NRD_MAX_CPUS_PER_CLUSTER,
+	NRD_MAX_CPUS_PER_CLUSTER
 };
 
 /*******************************************************************************
diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_trusted_boot.c
similarity index 88%
rename from plat/arm/board/sgi575/sgi575_trusted_boot.c
rename to plat/arm/board/neoverse_rd/platform/sgi575/sgi575_trusted_boot.c
index 4592b8fb..84622d00 100644
--- a/plat/arm/board/sgi575/sgi575_trusted_boot.c
+++ b/plat/arm/board/neoverse_rd/platform/sgi575/sgi575_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
deleted file mode 100644
index 69bfd7bc..00000000
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-
-#include <sgi_sdei.h>
-#include <sgi_soc_platform_def.h>
-
-#define PLAT_ARM_CLUSTER_COUNT		U(2)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(8)
-#define CSS_SGI_MAX_PE_PER_CPU		U(2)
-
-#define PLAT_CSS_MHU_BASE		UL(0x45400000)
-
-/* Base address of DMC-620 instances */
-#define RDE1EDGE_DMC620_BASE0		UL(0x4e000000)
-#define RDE1EDGE_DMC620_BASE1		UL(0x4e100000)
-
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL2
-
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL3
-
-/* Maximum number of address bits used per chip */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(36)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
-#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk
deleted file mode 100644
index 4a9a467b..00000000
--- a/plat/arm/board/rde1edge/platform.mk
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-$(warning Platform ${PLAT} is deprecated. \
-  Some of the features might not work as expected)
-
-include plat/arm/css/sgi/sgi-common.mk
-
-RDE1EDGE_BASE		=	plat/arm/board/rde1edge
-
-PLAT_INCLUDES		+=	-I${RDE1EDGE_BASE}/include/
-
-SGI_CPU_SOURCES		:=	lib/cpus/aarch64/neoverse_e1.S
-
-PLAT_BL_COMMON_SOURCES	+=	${CSS_ENT_BASE}/sgi_plat.c
-
-BL1_SOURCES		+=	${SGI_CPU_SOURCES}			\
-				${RDE1EDGE_BASE}/rde1edge_err.c
-
-BL2_SOURCES		+=	${RDE1EDGE_BASE}/rde1edge_plat.c	\
-				${RDE1EDGE_BASE}/rde1edge_security.c	\
-				${RDE1EDGE_BASE}/rde1edge_err.c		\
-				drivers/arm/tzc/tzc_dmc620.c		\
-				lib/utils/mem_region.c			\
-				plat/arm/common/arm_nor_psci_mem_protect.c
-
-BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
-				${RDE1EDGE_BASE}/rde1edge_plat.c	\
-				${RDE1EDGE_BASE}/rde1edge_topology.c	\
-				drivers/cfi/v2m/v2m_flash.c		\
-				lib/utils/mem_region.c			\
-				plat/arm/common/arm_nor_psci_mem_protect.c
-
-ifeq (${TRUSTED_BOARD_BOOT}, 1)
-BL1_SOURCES		+=	${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
-BL2_SOURCES		+=	${RDE1EDGE_BASE}/rde1edge_trusted_boot.c
-endif
-
-# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES		+=	${RDE1EDGE_BASE}/fdts/${PLAT}_fw_config.dts	\
-				${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
-FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
-TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
-
-# Add the FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
-# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
-
-FDT_SOURCES		+=	${RDE1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts
-NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
-
-# Add the NT_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config,${NT_FW_CONFIG}))
-
-ifneq ($(CSS_SGI_CHIP_COUNT),1)
- $(error  "Chip count for RDE1Edge should be 1, currently set to \
-   ${CSS_SGI_CHIP_COUNT}.")
-endif
-
-ifneq ($(CSS_SGI_PLATFORM_VARIANT),0)
- $(error "CSS_SGI_PLATFORM_VARIANT for RD-E1-Edge should always be 0, \
-     currently set to ${CSS_SGI_PLATFORM_VARIANT}.")
-endif
-
-override CTX_INCLUDE_AARCH32_REGS	:= 0
diff --git a/plat/arm/board/rde1edge/rde1edge_err.c b/plat/arm/board/rde1edge/rde1edge_err.c
deleted file mode 100644
index c72c18ce..00000000
--- a/plat/arm/board/rde1edge/rde1edge_err.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/*
- * rde1edge error handler
- */
-void __dead2 plat_arm_error_handler(int err)
-{
-	while (true) {
-		wfi();
-	}
-}
diff --git a/plat/arm/board/rde1edge/rde1edge_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c
deleted file mode 100644
index 44d818ae..00000000
--- a/plat/arm/board/rde1edge/rde1edge_plat.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/common/platform.h>
-#include <sgi_plat.h>
-
-unsigned int plat_arm_sgi_get_platform_id(void)
-{
-	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
-				& SID_SYSTEM_ID_PART_NUM_MASK;
-}
-
-unsigned int plat_arm_sgi_get_config_id(void)
-{
-	return mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
-}
-
-unsigned int plat_arm_sgi_get_multi_chip_mode(void)
-{
-	return 0;
-}
-
-void bl31_platform_setup(void)
-{
-	sgi_bl31_common_platform_setup();
-}
diff --git a/plat/arm/board/rde1edge/rde1edge_security.c b/plat/arm/board/rde1edge/rde1edge_security.c
deleted file mode 100644
index 35f81d19..00000000
--- a/plat/arm/board/rde1edge/rde1edge_security.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2019-2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <sgi_dmc620_tzc_regions.h>
-
-uintptr_t rde1edge_dmc_base[] = {
-	RDE1EDGE_DMC620_BASE0,
-	RDE1EDGE_DMC620_BASE1
-};
-
-static const tzc_dmc620_driver_data_t rde1edge_plat_driver_data = {
-	.dmc_base = rde1edge_dmc_base,
-	.dmc_count = ARRAY_SIZE(rde1edge_dmc_base)
-};
-
-static const tzc_dmc620_acc_addr_data_t rde1edge_acc_addr_data[] = {
-	CSS_SGI_DMC620_TZC_REGIONS_DEF
-};
-
-static const tzc_dmc620_config_data_t rde1edge_plat_config_data = {
-	.plat_drv_data = &rde1edge_plat_driver_data,
-	.plat_acc_addr_data = rde1edge_acc_addr_data,
-	.acc_addr_count = ARRAY_SIZE(rde1edge_acc_addr_data)
-};
-
-/* Initialize the secure environment */
-void plat_arm_security_setup(void)
-{
-	arm_tzc_dmc620_setup(&rde1edge_plat_config_data);
-}
diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c
deleted file mode 100644
index 91cc37e1..00000000
--- a/plat/arm/board/rde1edge/rde1edge_topology.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <plat/arm/common/plat_arm.h>
-
-/******************************************************************************
- * The power domain tree descriptor. RD-E1-Edge platform consists of two
- * clusters with eight CPUs in each cluster. The CPUs are multi-threaded with
- * two threads per CPU.
- ******************************************************************************/
-static const unsigned char rde1edge_pd_tree_desc[] = {
-	CSS_SGI_CHIP_COUNT,
-	PLAT_ARM_CLUSTER_COUNT,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU,
-	CSS_SGI_MAX_CPUS_PER_CLUSTER * CSS_SGI_MAX_PE_PER_CPU
-};
-
-/******************************************************************************
- * This function returns the topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
-	return rde1edge_pd_tree_desc;
-}
-
-/*******************************************************************************
- * The array mapping platform core position (implemented by plat_my_core_pos())
- * to the SCMI power domain ID implemented by SCP.
- ******************************************************************************/
-const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
-	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
-};
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
deleted file mode 100644
index de019027..00000000
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-
-#include <sgi_sdei.h>
-#include <sgi_soc_platform_def.h>
-
-#define PLAT_ARM_CLUSTER_COUNT		U(2)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(4)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
-
-#define PLAT_CSS_MHU_BASE		UL(0x45400000)
-
-/* Base address of DMC-620 instances */
-#define RDN1EDGE_DMC620_BASE0		UL(0x4e000000)
-#define RDN1EDGE_DMC620_BASE1		UL(0x4e100000)
-
-/* System power domain level */
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
-/* Virtual address used by dynamic mem_protect for chunk_base */
-#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
-
-/* Maximum number of address bits used per chip */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(42)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
-#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
deleted file mode 100644
index 2391b725..00000000
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-#include <sgi_sdei.h>
-#include <sgi_soc_platform_def_v2.h>
-
-#if (CSS_SGI_PLATFORM_VARIANT == 1)
-#define PLAT_ARM_CLUSTER_COUNT		U(8)
-#elif (CSS_SGI_PLATFORM_VARIANT == 2)
-#define PLAT_ARM_CLUSTER_COUNT		U(4)
-#else
-#define PLAT_ARM_CLUSTER_COUNT		U(16)
-#endif
-
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(1)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
-
-#define PLAT_CSS_MHU_BASE		UL(0x2A920000)
-#define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
-
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
-/* TZC Related Constants */
-#define PLAT_ARM_TZC_BASE		UL(0x10720000)
-#define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
-
-#define TZC400_OFFSET			UL(0x1000000)
-
-#if (CSS_SGI_PLATFORM_VARIANT == 1)
-#define TZC400_COUNT			U(2)
-#elif (CSS_SGI_PLATFORM_VARIANT == 2)
-#define TZC400_COUNT			U(4)
-#else
-#define TZC400_COUNT			U(8)
-#endif
-
-#define TZC400_BASE(n)			(PLAT_ARM_TZC_BASE + \
-						(n * TZC400_OFFSET))
-
-#define TZC_NSAID_ALL_AP		U(0)
-#define TZC_NSAID_PCI			U(1)
-#define TZC_NSAID_HDLCD0		U(2)
-#define TZC_NSAID_DMA			U(5)
-#define TZC_NSAID_DMA2			U(8)
-#define TZC_NSAID_CLCD			U(7)
-#define TZC_NSAID_AP			U(9)
-#define TZC_NSAID_VIRTIO		U(15)
-
-#define PLAT_ARM_TZC_NS_DEV_ACCESS	\
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI))    | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA))    | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_DMA2))   | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP))     | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD))   | \
-		(TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO))
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#if (CSS_SGI_PLATFORM_VARIANT == 2)
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(46)	/* 64TB */
-#else
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(42)	/* 4TB */
-#endif
-
-#define PLAT_PHY_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	CSS_SGI_REMOTE_CHIP_MEM_OFFSET( \
-						CSS_SGI_CHIP_COUNT)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
-
-/* Virtual address used by dynamic mem_protect for chunk_base */
-#define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xC0000000)
-
-#if (CSS_SGI_PLATFORM_VARIANT == 1)
-#define PLAT_ARM_GICR_BASE		UL(0x30100000)
-#elif (CSS_SGI_PLATFORM_VARIANT == 3)
-#define PLAT_ARM_GICR_BASE		UL(0x30300000)
-#else
-#define PLAT_ARM_GICR_BASE		UL(0x301C0000)
-#endif
-
-/* Interrupt priority level for shutdown/reboot */
-#define PLAT_REBOOT_PRI		GIC_HIGHEST_SEC_PRIORITY
-#define PLAT_EHF_DESC		EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_REBOOT_PRI)
-
-/*
- * Number of Secure Partitions supported.
- * SPMC at EL3, uses this count to configure the maximum number of supported
- * secure partitions.
- */
-#define SECURE_PARTITION_COUNT          1
-
-/*
- * Number of NWd Partitions supported.
- * SPMC at EL3, uses this count to configure the maximum number of supported
- * nwld partitions.
- */
-#define NS_PARTITION_COUNT              1
-
-/*
- * Number of Logical Partitions supported.
- * SPMC at EL3, uses this count to configure the maximum number of supported
- * logical partitions.
- */
-#define MAX_EL3_LP_DESCS_COUNT		1
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/rdn2/include/rdn2_ras.h b/plat/arm/board/rdn2/include/rdn2_ras.h
deleted file mode 100644
index 1d9af609..00000000
--- a/plat/arm/board/rdn2/include/rdn2_ras.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef RDN2_RAS_H
-#define RDN2_RAS_H
-
-#include <sgi_ras.h>
-
-extern struct plat_sgi_ras_config ras_config;
-
-#endif /* RDN2_RAS_H */
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
deleted file mode 100644
index 82a38c54..00000000
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-
-#include <sgi_sdei.h>
-#include <sgi_soc_platform_def.h>
-
-#define PLAT_ARM_CLUSTER_COUNT		U(2)
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(4)
-#define CSS_SGI_MAX_PE_PER_CPU		U(1)
-
-#define PLAT_CSS_MHU_BASE		UL(0x45000000)
-
-/* Base address of DMC-620 instances */
-#define SGI575_DMC620_BASE0		UL(0x4e000000)
-#define SGI575_DMC620_BASE1		UL(0x4e100000)
-
-/* System power domain level */
-#define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
-
-#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
-
-/* Maximum number of address bits used per chip */
-#define CSS_SGI_ADDR_BITS_PER_CHIP	U(36)
-
-/*
- * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
- */
-#ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << CSS_SGI_ADDR_BITS_PER_CHIP)
-#else
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#endif
-
-/* GIC related constants */
-#define PLAT_ARM_GICD_BASE		UL(0x30000000)
-#define PLAT_ARM_GICC_BASE		UL(0x2C000000)
-#define PLAT_ARM_GICR_BASE		UL(0x300C0000)
-
-#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc/fdts/dice_prot_env.dtsi b/plat/arm/board/tc/fdts/dice_prot_env.dtsi
new file mode 100644
index 00000000..118f995d
--- /dev/null
+++ b/plat/arm/board/tc/fdts/dice_prot_env.dtsi
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* DICE Protection Environment Client Config */
+dice_protection_environment: context_handle {
+	compatible = "arm,dpe_ctx_handle";
+	dpe_ctx_handle = <0x0>;
+};
diff --git a/plat/arm/board/tc/fdts/tc_fw_config.dts b/plat/arm/board/tc/fdts/tc_fw_config.dts
index a84c7f85..de446eab 100644
--- a/plat/arm/board/tc/fdts/tc_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_fw_config.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <platform_def.h>
 
 /dts-v1/;
 
@@ -25,9 +26,14 @@
 		};
 
 		hw-config {
-			load-address = <0x0 0x83000000>;
-			max-size = <0x8000>;
+			load-address = <0x0 PLAT_HW_CONFIG_DTB_BASE>;
+			max-size = <PLAT_ARM_HW_CONFIG_SIZE>;
 			id = <HW_CONFIG_ID>;
 		};
+		nt_fw-config {
+			load-address = <0x0 (PLAT_HW_CONFIG_DTB_BASE + PLAT_ARM_HW_CONFIG_SIZE)>;
+			max-size = <0x1000>;
+			id = <NT_FW_CONFIG_ID>;
+		};
 	};
 };
diff --git a/plat/arm/board/tc/fdts/tc_nt_fw_config.dts b/plat/arm/board/tc/fdts/tc_nt_fw_config.dts
new file mode 100644
index 00000000..bb3086dd
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_nt_fw_config.dts
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+#if DICE_PROTECTION_ENVIRONMENT
+	#include "dice_prot_env.dtsi"
+#endif
+};
diff --git a/plat/arm/board/tc/fdts/tc_spmc_common_sp_manifest.dtsi b/plat/arm/board/tc/fdts/tc_spmc_common_sp_manifest.dtsi
new file mode 100644
index 00000000..06c29371
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_spmc_common_sp_manifest.dtsi
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Secure world memory map. For a full view of the DRAM map, see platform_def.h
+ *
+ *  0xf900_c000  ------------------
+ *               |       ...      |
+ *  0xf901_c000  ------------------
+ *               |     (63MB)     |  Trusty (=/=> OP-TEE)
+ *  0xfcf1_c000  ------------------
+ *               |       ...      |
+ *  0xfd00_0000  ------------------
+ *               |     (512K)     |  Hafnium
+ *  0xfd08_0000  ------------------
+ *               |       ...      |  Hafnium stack
+ *  0xfd28_0000  ------------------
+ *               |     (11MB)     |  OP-TEE (=/=> Trusty)
+ *  0xfdd8_0000  ------------------
+ *               |       ...      |
+ *  0xfde0_0000  ------------------
+ *               |     (2MB)      |  Firmware Upgrade
+ *  0xfec0_0000  ------------------
+ *               |     (2MB)      |  Crypto
+ *  0xfee0_0000	 ------------------
+ *               |     (2MB)      |  Internal Truested Storage
+ *  0xff00_0000  ------------------
+ */
+&hafnium {
+	vm1 {
+		is_ffa_partition;
+		vcpu_count = <8>;
+		/* partition information filled in separately */
+	};
+#ifdef TS_SP_FW_CONFIG
+	vm2 {
+		is_ffa_partition;
+		debug_name = "internal-trusted-storage";
+		load_address = <0xfee00000>;
+		vcpu_count = <1>;
+		mem_size = <0x200000>; /* 2MB TZC DRAM */
+	};
+	vm3 {
+		is_ffa_partition;
+		debug_name = "crypto";
+		load_address = <0xfec00000>;
+		vcpu_count = <1>;
+		mem_size = <0x200000>; /* 2MB TZC DRAM */
+	};
+	vm4 {
+		is_ffa_partition;
+		debug_name = "firmware-update";
+		load_address = <0xfde00000>;
+		vcpu_count = <1>;
+		mem_size = <0xe00000>; /* 14MB TZC DRAM */
+	};
+#endif
+};
diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
similarity index 65%
rename from plat/arm/board/tc/fdts/tc_spmc_manifest.dts
rename to plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
index b64e0762..737997d4 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts
+++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dtsi
@@ -1,9 +1,9 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-/dts-v1/;
+#include <platform_def.h>
 
 / {
 	compatible = "arm,ffa-core-manifest-1.0";
@@ -13,43 +13,16 @@
 	attribute {
 		spmc_id = <0x8000>;
 		maj_ver = <0x1>;
-		min_ver = <0x1>;
+		min_ver = <0x2>;
 		exec_state = <0x0>;
 		load_address = <0x0 0xfd000000>;
 		entrypoint = <0x0 0xfd000000>;
 		binary_size = <0x80000>;
 	};
 
-	hypervisor {
+	hafnium:hypervisor {
 		compatible = "hafnium,hafnium";
-		vm1 {
-			is_ffa_partition;
-			debug_name = "cactus-primary";
-			load_address = <0xfe000000>;
-			vcpu_count = <8>;
-			mem_size = <1048576>;
-		};
-		vm2 {
-			is_ffa_partition;
-			debug_name = "cactus-secondary";
-			load_address = <0xfe100000>;
-			vcpu_count = <8>;
-			mem_size = <1048576>;
-		};
-		vm3 {
-			is_ffa_partition;
-			debug_name = "cactus-tertiary";
-			load_address = <0xfe200000>;
-			vcpu_count = <1>;
-			mem_size = <1048576>;
-		};
-		vm4 {
-			is_ffa_partition;
-			debug_name = "ivy";
-			load_address = <0xfe600000>;
-			vcpu_count = <1>;
-			mem_size = <1048576>;
-		};
+		/* filled in in top level .dts */
 	};
 
 	cpus {
@@ -117,16 +90,34 @@
 		};
 	};
 
+	/* the full secure world range */
 	memory@0 {
 		device_type = "memory";
-		reg = <0x0 0xfd000000 0x0 0x2000000>,
-		      <0x0 0x7000000 0x0 0x1000000>,
+		reg = <0x0 TC_TZC_DRAM1_BASE 0x0 TC_TZC_DRAM1_SIZE>,
 		      <0x0 0xff000000 0x0 0x1000000>;
 	};
 
 	memory@1 {
 		device_type = "ns-memory";
-		reg = <0x00008800 0x80000000 0x0 0x7f000000>,
-		      <0x0 0x88000000 0x1 0x00000000>;
+		reg = <0x0 TC_NS_DRAM1_BASE 0x0 TC_NS_DRAM1_SIZE>,
+		      <HI(PLAT_ARM_DRAM2_BASE) LO(PLAT_ARM_DRAM2_BASE)
+		       HI(TC_NS_DRAM2_SIZE) LO(TC_NS_DRAM2_SIZE)>;
+	};
+
+	memory@2 {
+		device_type = "device-memory";
+		reg = <0x0 0x25000000 0x0 0x10000>; /* For cactus tertiary dummy device. */
+	};
+
+	s_uart {
+		device_type = "device-memory";
+		reg = <0x0 PLAT_ARM_BOOT_UART_BASE 0x0 0x01000>;
+	};
+
+#ifdef TS_SP_FW_CONFIG
+	ns_flash {
+		device_type = "ns-device-memory";
+		reg = <0x0 V2M_FLASH0_BASE 0x0 V2M_FLASH0_SIZE>;
 	};
+#endif
 };
diff --git a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
index 382f0e1b..840b80ff 100644
--- a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
+++ b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts
@@ -1,129 +1,17 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /dts-v1/;
 
-/ {
-	compatible = "arm,ffa-core-manifest-1.0";
-	#address-cells = <2>;
-	#size-cells = <2>;
+#include <tc_spmc_manifest.dtsi>
+#include <tc_spmc_common_sp_manifest.dtsi>
 
-	attribute {
-		spmc_id = <0x8000>;
-		maj_ver = <0x1>;
-		min_ver = <0x1>;
-		exec_state = <0x0>;
-		load_address = <0x0 0xfd000000>;
-		entrypoint = <0x0 0xfd000000>;
-		binary_size = <0x80000>;
-	};
-
-	hypervisor {
-		compatible = "hafnium,hafnium";
-		vm1 {
-			is_ffa_partition;
-			debug_name = "op-tee";
-			load_address = <0xfd280000>;
-			vcpu_count = <8>;
-#ifdef TS_SP_FW_CONFIG
-			mem_size = <26738688>; /* 25MB TZC DRAM */
-#else
-			mem_size = <30928896>; /* 29MB TZC DRAM */
-#endif
-		};
-#ifdef TS_SP_FW_CONFIG
-		vm2 {
-			is_ffa_partition;
-			debug_name = "internal-trusted-storage";
-			load_address = <0xfee00000>;
-			vcpu_count = <1>;
-			mem_size = <2097152>; /* 2MB TZC DRAM */
-		};
-		vm3 {
-			is_ffa_partition;
-			debug_name = "crypto";
-			load_address = <0xfec00000>;
-			vcpu_count = <1>;
-			mem_size = <2097152>; /* 2MB TZC DRAM */
-		};
-#endif
-	};
-
-	cpus {
-		#address-cells = <0x2>;
-		#size-cells = <0x0>;
-
-		CPU0:cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x0>;
-			enable-method = "psci";
-		};
-
-		/*
-		 * SPMC (Hafnium) requires secondary cpu nodes are declared in
-		 * descending order
-		 */
-		CPU7:cpu@700 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x700>;
-			enable-method = "psci";
-		};
-
-		CPU6:cpu@600 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x600>;
-			enable-method = "psci";
-		};
-
-		CPU5:cpu@500 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x500>;
-			enable-method = "psci";
-		};
-
-		CPU4:cpu@400 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x400>;
-			enable-method = "psci";
-		};
-
-		CPU3:cpu@300 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x300>;
-			enable-method = "psci";
-		};
-
-		CPU2:cpu@200 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x200>;
-			enable-method = "psci";
-		};
-
-		CPU1:cpu@100 {
-			device_type = "cpu";
-			compatible = "arm,armv8";
-			reg = <0x0 0x100>;
-			enable-method = "psci";
-		};
-	};
-
-	memory@0 {
-		device_type = "memory";
-		reg = <0x0 0xfd000000 0x0 0x2000000>;
-	};
-
-	memory@1 {
-		device_type = "ns-memory";
-		reg = <0x0 0x80000000 0x0 0x79000000>,
-		      <0x80 0x80000000 0x1 0x80000000>;
+&hafnium {
+	vm1 {
+		debug_name = "op-tee";
+		load_address = <0xfd280000>;
+		mem_size = <0xb00000>; /* 11MB TZC DRAM */
 	};
 };
diff --git a/plat/arm/board/tc/fdts/tc_spmc_test_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_test_manifest.dts
new file mode 100644
index 00000000..2e35f82c
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_spmc_test_manifest.dts
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+#include <tc_spmc_manifest.dtsi>
+
+/ {
+	hypervisor {
+		vm1 {
+			is_ffa_partition;
+			debug_name = "cactus-primary";
+			load_address = <0xfe000000>;
+			vcpu_count = <8>;
+			mem_size = <1048576>;
+		};
+		vm2 {
+			is_ffa_partition;
+			debug_name = "cactus-secondary";
+			load_address = <0xfe100000>;
+			vcpu_count = <8>;
+			mem_size = <1048576>;
+		};
+		vm3 {
+			is_ffa_partition;
+			debug_name = "cactus-tertiary";
+			load_address = <0xfe200000>;
+			vcpu_count = <1>;
+			mem_size = <1048576>;
+		};
+		vm4 {
+			is_ffa_partition;
+			debug_name = "ivy";
+			load_address = <0xfe600000>;
+			vcpu_count = <1>;
+			mem_size = <1048576>;
+		};
+	};
+};
diff --git a/plat/arm/board/tc/fdts/tc_spmc_trusty_sp_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_trusty_sp_manifest.dts
new file mode 100644
index 00000000..8233eda4
--- /dev/null
+++ b/plat/arm/board/tc/fdts/tc_spmc_trusty_sp_manifest.dts
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/dts-v1/;
+
+#include <tc_spmc_manifest.dtsi>
+#include <tc_spmc_common_sp_manifest.dtsi>
+
+&hafnium {
+	vm1 {
+		debug_name = "trusty";
+		load_address = <0xf901c000>;
+		mem_size = <0x3f00000>; /* 64MB TZC DRAM - 1MB align */
+	};
+};
diff --git a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
index 4c6ccef2..cb741a35 100644
--- a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
+++ b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,12 +41,21 @@
 		       uuid = "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0";
 		       load-address = <0xfec00000>;
 		};
+		firmware-update {
+		       uuid = "6823a838-1b06-470e-9774-0cce8bfb53fd";
+		       load-address = <0xfde00000>;
+		};
 #endif
 #if OPTEE_SP_FW_CONFIG
 		op-tee {
 		       uuid = "486178e0-e7f8-11e3-bc5e-0002a5d5c51b";
 		       load-address = <0xfd280000>;
 		};
+#elif TRUSTY_SP_FW_CONFIG
+		trusty {
+		       uuid = "40ee25f0-a2bc-304c-8c4c-a173c57d8af1";
+		       load-address = <0xf901c000>;
+		};
 #else
 		cactus-primary {
 			uuid = "b4b5671e-4a90-4fe1-b81f-fb13dae1dacb";
@@ -73,4 +82,7 @@
 #endif
 #endif /* ARM_BL2_SP_LIST_DTS */
 	};
+#if DICE_PROTECTION_ENVIRONMENT
+	#include "dice_prot_env.dtsi"
+#endif
 };
diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h
index 59fff6e2..86fce0e3 100644
--- a/plat/arm/board/tc/include/platform_def.h
+++ b/plat/arm/board/tc/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,18 +7,31 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
+#include <cortex_a520.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 #include <plat/arm/board/common/board_css_def.h>
 #include <plat/arm/board/common/v2m_def.h>
+
+/*
+ * arm_def.h depends on the platform system counter macros, so must define the
+ * platform macros before including arm_def.h.
+ */
+#if TARGET_PLATFORM == 4
+#ifdef ARM_SYS_CNTCTL_BASE
+#error "error: ARM_SYS_CNTCTL_BASE is defined prior to the PLAT_ARM_SYS_CNTCTL_BASE definition"
+#endif
+#define PLAT_ARM_SYS_CNTCTL_BASE	UL(0x47000000)
+#define PLAT_ARM_SYS_CNTREAD_BASE	UL(0x47010000)
+#endif
+
 #include <plat/arm/common/arm_def.h>
+
 #include <plat/arm/common/arm_spm_def.h>
 #include <plat/arm/css/common/css_def.h>
 #include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#define PLATFORM_CORE_COUNT		8
-
 #define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00080000	/* 512 KB */
 
 /*
@@ -30,6 +43,17 @@
  *   - Region to load secure partitions
  *
  *
+ *  0x8000_0000  ------------------   TC_NS_DRAM1_BASE
+ *               |       DTB      |
+ *               |      (32K)     |
+ *  0x8000_8000  ------------------
+ *               | NT_FW_CONFIG   |
+ *               |      (4KB)     |
+ *  0x8000_9000  ------------------
+ *               |       ...      |
+ *  0xf8e0_0000  ------------------   TC_NS_OPTEE_BASE
+ *               |  OP-TEE shmem  |
+ *               |      (2MB)     |
  *  0xF900_0000  ------------------   TC_TZC_DRAM1_BASE
  *               |                |
  *               |      SPMC      |
@@ -46,7 +70,7 @@
  */
 #define TC_TZC_DRAM1_BASE		(ARM_AP_TZC_DRAM1_BASE -	\
 					 TC_TZC_DRAM1_SIZE)
-#define TC_TZC_DRAM1_SIZE		96 * SZ_1M	/* 96 MB */
+#define TC_TZC_DRAM1_SIZE		(96 * SZ_1M)	/* 96 MB */
 #define TC_TZC_DRAM1_END		(TC_TZC_DRAM1_BASE +		\
 					 TC_TZC_DRAM1_SIZE - 1)
 
@@ -54,8 +78,10 @@
 #define TC_NS_DRAM1_SIZE		(ARM_DRAM1_SIZE -		\
 					 ARM_TZC_DRAM1_SIZE -		\
 					 TC_TZC_DRAM1_SIZE)
-#define TC_NS_DRAM1_END		(TC_NS_DRAM1_BASE +		\
-					 TC_NS_DRAM1_SIZE - 1)
+#define TC_NS_DRAM1_END			(TC_NS_DRAM1_BASE + TC_NS_DRAM1_SIZE - 1)
+
+#define TC_NS_OPTEE_SIZE		(2 * SZ_1M)
+#define TC_NS_OPTEE_BASE		(TC_NS_DRAM1_BASE + TC_NS_DRAM1_SIZE - TC_NS_OPTEE_SIZE)
 
 /*
  * Mappings for TC DRAM1 (non-secure) and TC TZC DRAM1 (secure)
@@ -71,12 +97,12 @@
 						TC_TZC_DRAM1_SIZE,	\
 						MT_MEMORY | MT_RW | MT_SECURE)
 
-#define PLAT_HW_CONFIG_DTB_BASE	ULL(0x83000000)
-#define PLAT_HW_CONFIG_DTB_SIZE	ULL(0x8000)
+#define PLAT_HW_CONFIG_DTB_BASE	TC_NS_DRAM1_BASE
+#define PLAT_ARM_HW_CONFIG_SIZE	ULL(0x8000)
 
 #define PLAT_DTB_DRAM_NS MAP_REGION_FLAT(	\
 					PLAT_HW_CONFIG_DTB_BASE,	\
-					PLAT_HW_CONFIG_DTB_SIZE,	\
+					PLAT_ARM_HW_CONFIG_SIZE,	\
 					MT_MEMORY | MT_RO | MT_NS)
 /*
  * Max size of SPMC is 2MB for tc. With SPMD enabled this value corresponds to
@@ -137,7 +163,7 @@
  * little space for growth. Current size is considering that TRUSTED_BOARD_BOOT
  * and MEASURED_BOOT is enabled.
  */
-# define PLAT_ARM_MAX_BL2_SIZE		0x26000
+# define PLAT_ARM_MAX_BL2_SIZE		0x29000
 
 
 /*
@@ -152,24 +178,16 @@
  * Size of cacheable stacks
  */
 #if defined(IMAGE_BL1)
-# if TRUSTED_BOARD_BOOT
 #  define PLATFORM_STACK_SIZE		0x1000
-# else
-#  define PLATFORM_STACK_SIZE		0x440
-# endif
 #elif defined(IMAGE_BL2)
-# if TRUSTED_BOARD_BOOT
 #  define PLATFORM_STACK_SIZE		0x1000
-# else
-#  define PLATFORM_STACK_SIZE		0x400
-# endif
 #elif defined(IMAGE_BL2U)
 # define PLATFORM_STACK_SIZE		0x400
 #elif defined(IMAGE_BL31)
 # if SPM_MM
 #  define PLATFORM_STACK_SIZE		0x500
 # else
-#  define PLATFORM_STACK_SIZE		0xa00
+#  define PLATFORM_STACK_SIZE		0xb00
 # endif
 #elif defined(IMAGE_BL32)
 # define PLATFORM_STACK_SIZE		0x440
@@ -177,15 +195,22 @@
 
 /*
  * In the current implementation the RoT Service request that requires the
- * biggest message buffer is the RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN. The
+ * biggest message buffer is the RSE_DELEGATED_ATTEST_GET_PLATFORM_TOKEN. The
  * maximum required buffer size is calculated based on the platform-specific
  * needs of this request.
  */
-#define PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE	0x500
+#define PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE	0x500
 
 #define TC_DEVICE_BASE			0x21000000
 #define TC_DEVICE_SIZE			0x5f000000
 
+#if defined(TARGET_FLAVOUR_FPGA)
+#undef V2M_FLASH0_BASE
+#undef V2M_FLASH0_SIZE
+#define V2M_FLASH0_BASE			UL(0x0C000000)
+#define V2M_FLASH0_SIZE			UL(0x02000000)
+#endif
+
 // TC_MAP_DEVICE covers different peripherals
 // available to the platform
 #define TC_MAP_DEVICE	MAP_REGION_FLAT(		\
@@ -197,8 +222,11 @@
 #define TC_FLASH0_RO	MAP_REGION_FLAT(V2M_FLASH0_BASE,\
 						V2M_FLASH0_SIZE,	\
 						MT_DEVICE | MT_RO | MT_SECURE)
-
-#define PLAT_ARM_NSTIMER_FRAME_ID	0
+#if TARGET_PLATFORM == 2
+#define PLAT_ARM_NSTIMER_FRAME_ID	U(0)
+#else
+#define PLAT_ARM_NSTIMER_FRAME_ID	U(1)
+#endif
 
 #define PLAT_ARM_TRUSTED_ROM_BASE	0x0
 
@@ -206,12 +234,24 @@
 #define PLAT_ARM_TRUSTED_ROM_SIZE	(0x00080000 - PLAT_ARM_TRUSTED_ROM_BASE)
 
 #define PLAT_ARM_NSRAM_BASE		0x06000000
+#if TARGET_FLAVOUR_FVP
 #define PLAT_ARM_NSRAM_SIZE		0x00080000	/* 512KB */
+#else /* TARGET_FLAVOUR_FPGA */
+#define PLAT_ARM_NSRAM_SIZE		0x00008000	/* 64KB */
+#endif /* TARGET_FLAVOUR_FPGA */
 
+#if TARGET_PLATFORM <= 2
 #define PLAT_ARM_DRAM2_BASE		ULL(0x8080000000)
+#elif TARGET_PLATFORM >= 3
+#define PLAT_ARM_DRAM2_BASE		ULL(0x880000000)
+#endif /* TARGET_PLATFORM >= 3 */
 #define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
 #define PLAT_ARM_DRAM2_END		(PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL)
 
+#define TC_NS_MTE_SIZE			(256 * SZ_1M)
+/* the SCP puts the carveout at the end of DRAM2 */
+#define TC_NS_DRAM2_SIZE		(PLAT_ARM_DRAM2_SIZE - TC_NS_MTE_SIZE)
+
 #define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_INT_PROPS(grp)
 #define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp),	\
 					INTR_PROP_DESC(SBSA_SECURE_WDOG_INTID,	\
@@ -221,6 +261,8 @@
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
 					 PLAT_SP_IMAGE_NS_BUF_SIZE)
 
+#define PLAT_ARM_SP_MAX_SIZE		U(0x2000000)
+
 /*******************************************************************************
  * Memprotect definitions
  ******************************************************************************/
@@ -240,17 +282,46 @@
 
 #define PLAT_ARM_SCMI_CHANNEL_COUNT	1
 
+/* Index of SDS region used in the communication with SCP */
+#define SDS_SCP_AP_REGION_ID		U(0)
+/* Index of SDS region used in the communication with RSE */
+#define SDS_RSE_AP_REGION_ID		U(1)
+/*
+ * Memory region for RSE's shared data storage (SDS)
+ * It is placed right after the SCMI payload area.
+ */
+#define PLAT_ARM_RSE_AP_SDS_MEM_BASE	(CSS_SCMI_PAYLOAD_BASE + \
+					 CSS_SCMI_PAYLOAD_SIZE_MAX)
+
 #define PLAT_ARM_CLUSTER_COUNT		U(1)
+#if TARGET_FLAVOUR_FPGA && TARGET_PLATFORM == 2
+#define PLAT_MAX_CPUS_PER_CLUSTER	U(14)
+#else /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM == 2 */
 #define PLAT_MAX_CPUS_PER_CLUSTER	U(8)
+#endif /* TARGET_FLAVOUR_FPGA && TARGET_PLATFORM == 2 */
 #define PLAT_MAX_PE_PER_CPU		U(1)
 
+#define PLATFORM_CORE_COUNT		(PLAT_MAX_CPUS_PER_CLUSTER * PLAT_ARM_CLUSTER_COUNT)
+
 /* Message Handling Unit (MHU) base addresses */
-#define PLAT_CSS_MHU_BASE		UL(0x45400000)
+#if TARGET_PLATFORM <= 2
+	#define PLAT_CSS_MHU_BASE		UL(0x45400000)
+#elif TARGET_PLATFORM >= 3
+	#define PLAT_CSS_MHU_BASE		UL(0x46000000)
+#endif /* TARGET_PLATFORM >= 3 */
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
 
-/* TC2: AP<->RSS MHUs */
-#define PLAT_RSS_AP_SND_MHU_BASE	UL(0x2A840000)
-#define PLAT_RSS_AP_RCV_MHU_BASE	UL(0x2A850000)
+/* AP<->RSS MHUs */
+#if TARGET_PLATFORM <= 2
+#define PLAT_RSE_AP_SND_MHU_BASE	UL(0x2A840000)
+#define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x2A850000)
+#elif TARGET_PLATFORM == 3
+#define PLAT_RSE_AP_SND_MHU_BASE	UL(0x49000000)
+#define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x49100000)
+#elif TARGET_PLATFORM == 4
+#define PLAT_RSE_AP_SND_MHU_BASE	UL(0x49000000)
+#define PLAT_RSE_AP_RCV_MHU_BASE	UL(0x49010000)
+#endif
 
 #define CSS_SYSTEM_PWR_DMN_LVL		ARM_PWR_LVL2
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL1
@@ -278,6 +349,7 @@
  */
 #define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x20000
 
+#if TARGET_PLATFORM <= 2
 /* TZC Related Constants */
 #define PLAT_ARM_TZC_BASE		UL(0x25000000)
 #define PLAT_ARM_TZC_FILTERS		TZC_400_REGION_ATTR_FILTER_BIT(0)
@@ -305,6 +377,7 @@
 		PLAT_ARM_TZC_NS_DEV_ACCESS},	\
 	{PLAT_ARM_DRAM2_BASE, PLAT_ARM_DRAM2_END,	\
 		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
+#endif
 
 /* virtual address used by dynamic mem_protect for chunk_base */
 #define PLAT_ARM_MEM_PROTEC_VA_FRAME	UL(0xc0000000)
@@ -322,4 +395,88 @@
 #define PLAT_ARM_FIP_OFFSET_IN_GPT		0x6000
 #endif /* ARM_GPT_SUPPORT */
 
+/* UART related constants */
+
+#define TC_UART0			0x2a400000
+#define TC_UART1			0x2a410000
+
+/*
+ * TODO: if any more undefs are needed, it's better to consider dropping the
+ * board_css_def.h include above
+ */
+#undef PLAT_ARM_BOOT_UART_BASE
+#undef PLAT_ARM_RUN_UART_BASE
+
+#undef PLAT_ARM_CRASH_UART_BASE
+#undef PLAT_ARM_BOOT_UART_CLK_IN_HZ
+#undef PLAT_ARM_RUN_UART_CLK_IN_HZ
+
+#if TARGET_FLAVOUR_FVP
+#define PLAT_ARM_BOOT_UART_BASE		TC_UART1
+#define TC_UARTCLK			7372800
+#else /* TARGET_FLAVOUR_FPGA */
+#define PLAT_ARM_BOOT_UART_BASE		TC_UART0
+#if TARGET_PLATFORM <= 2
+#define TC_UARTCLK			5000000
+#elif TARGET_PLATFORM >= 3
+#define TC_UARTCLK			3750000
+#endif /* TARGET_PLATFORM >= 3 */
+#undef  ARM_CONSOLE_BAUDRATE
+#define ARM_CONSOLE_BAUDRATE		38400
+#endif /* TARGET_FLAVOUR_FPGA */
+
+#define PLAT_ARM_RUN_UART_BASE		TC_UART0
+#define PLAT_ARM_CRASH_UART_BASE	PLAT_ARM_RUN_UART_BASE
+
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	TC_UARTCLK
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ	TC_UARTCLK
+
+#if TARGET_PLATFORM == 3
+#define NCI_BASE_ADDR			UL(0x4F000000)
+#ifdef TARGET_FLAVOUR_FPGA
+#define MCN_ADDRESS_SPACE_SIZE		0x00120000
+#else
+#define MCN_ADDRESS_SPACE_SIZE		0x00130000
+#endif	/* TARGET_FLAVOUR_FPGA */
+#define MCN_OFFSET_IN_NCI		0x00C90000
+#define MCN_BASE_ADDR			(NCI_BASE_ADDR + MCN_OFFSET_IN_NCI)
+#define MCN_PMU_OFFSET			0x000C4000
+#define MCN_MICROARCH_OFFSET		0x000E4000
+#define MCN_MICROARCH_BASE_ADDR		(MCN_BASE_ADDR + MCN_MICROARCH_OFFSET)
+#define MCN_SCR_OFFSET			0x4
+#define MCN_SCR_PMU_BIT			10
+#define MCN_INSTANCES			4
+#define MCN_PMU_ADDR(n)			(MCN_BASE_ADDR + \
+					 (n * MCN_ADDRESS_SPACE_SIZE) + \
+					 MCN_PMU_OFFSET)
+#define MCN_MPAM_NS_OFFSET		0x000D0000
+#define MCN_MPAM_NS_BASE_ADDR		(MCN_BASE_ADDR + MCN_MPAM_NS_OFFSET)
+#define MCN_MPAM_S_OFFSET		0x000D4000
+#define MCN_MPAM_S_BASE_ADDR		(MCN_BASE_ADDR + MCN_MPAM_S_OFFSET)
+#define MPAM_SLCCFG_CTL_OFFSET		0x00003018
+#define SLC_RDALLOCMODE_SHIFT		8
+#define SLC_RDALLOCMODE_MASK		(3 << SLC_RDALLOCMODE_SHIFT)
+#define SLC_WRALLOCMODE_SHIFT		12
+#define SLC_WRALLOCMODE_MASK		(3 << SLC_WRALLOCMODE_SHIFT)
+
+#define SLC_DONT_ALLOC			0
+#define SLC_ALWAYS_ALLOC		1
+#define SLC_ALLOC_BUS_SIGNAL_ATTR	2
+
+#define MCN_CONFIG_OFFSET		0x204
+#define MCN_CONFIG_ADDR			(MCN_BASE_ADDR + MCN_CONFIG_OFFSET)
+#define MCN_CONFIG_SLC_PRESENT_BIT	3
+
+/*
+ * TC3 CPUs have the same definitions for:
+ *   CORTEX_{A520|A725|X925}_CPUECTLR_EL1
+ *   CORTEX_{A520|A725|X925}_CPUECTLR_EL1_EXTLLC_BIT
+ * Define the common macros for easier using.
+ */
+#define CPUECTLR_EL1			CORTEX_A520_CPUECTLR_EL1
+#define CPUECTLR_EL1_EXTLLC_BIT		CORTEX_A520_CPUECTLR_EL1_EXTLLC_BIT
+#endif /* TARGET_PLATFORM == 3 */
+
+#define CPUACTLR_CLUSTERPMUEN		(ULL(1) << 12)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc/include/tc_helpers.S b/plat/arm/board/tc/include/tc_helpers.S
index 5f548566..9adf09af 100644
--- a/plat/arm/board/tc/include/tc_helpers.S
+++ b/plat/arm/board/tc/include/tc_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,9 @@
 #include <platform_def.h>
 #include <cpu_macros.S>
 
+#define TC_HANDLER(rev)         plat_reset_handler_tc##rev
+#define PLAT_RESET_HANDLER(rev) TC_HANDLER(rev)
+
 	.globl	plat_arm_calc_core_pos
 	.globl	plat_reset_handler
 
@@ -49,13 +52,46 @@ func plat_arm_calc_core_pos
 	ret
 endfunc plat_arm_calc_core_pos
 
+func mark_extllc_presence
+#ifdef MCN_CONFIG_ADDR
+	mov_imm x0, (MCN_CONFIG_ADDR)
+	ldr	w1, [x0]
+	ubfx	x1, x1, #MCN_CONFIG_SLC_PRESENT_BIT, #1
+	sysreg_bitfield_insert_from_gpr CPUECTLR_EL1, x1, \
+					CPUECTLR_EL1_EXTLLC_BIT, 1
+#endif
+	ret
+endfunc mark_extllc_presence
+
+func enable_dsu_pmu_el1_access
+	sysreg_bit_set actlr_el2, CPUACTLR_CLUSTERPMUEN
+	sysreg_bit_set actlr_el3, CPUACTLR_CLUSTERPMUEN
+	ret
+endfunc enable_dsu_pmu_el1_access
+
+func TC_HANDLER(2)
+	ret
+endfunc TC_HANDLER(2)
+
+func TC_HANDLER(3)
+	mov	x9, lr
+	bl	mark_extllc_presence
+	bl	enable_dsu_pmu_el1_access
+	mov	lr, x9
+	ret
+endfunc TC_HANDLER(3)
+
+func TC_HANDLER(4)
+	ret
+endfunc TC_HANDLER(4)
+
 	/* -----------------------------------------------------
 	 * void plat_reset_handler(void);
-	 *
-	 * Determine the CPU MIDR and disable power down bit for
-	 * that CPU.
 	 * -----------------------------------------------------
 	 */
 func plat_reset_handler
+	mov	x8, lr
+	bl	PLAT_RESET_HANDLER(TARGET_PLATFORM)
+	mov	lr, x8
 	ret
 endfunc plat_reset_handler
diff --git a/plat/arm/board/tc/include/tc_plat.h b/plat/arm/board/tc/include/tc_plat.h
index a6b2b0df..6ba4694f 100644
--- a/plat/arm/board/tc/include/tc_plat.h
+++ b/plat/arm/board/tc/include/tc_plat.h
@@ -8,7 +8,7 @@
 #define TC_PLAT_H
 
 #ifdef PLATFORM_TEST_ROTPK
-#include <rss_crypto_defs.h>
+#include <rse_crypto_defs.h>
 #endif
 
 void tc_bl31_common_platform_setup(void);
@@ -23,7 +23,7 @@ int nv_counter_test(void);
 
 #ifdef PLATFORM_TEST_ROTPK
 struct key_id_info {
-	enum rss_key_id_builtin_t key_id;
+	enum rse_key_id_builtin_t key_id;
 	const char *key_id_name;
 };
 
diff --git a/plat/arm/board/tc/nv_counter_test.c b/plat/arm/board/tc/nv_counter_test.c
index 179ec4b0..90255693 100644
--- a/plat/arm/board/tc/nv_counter_test.c
+++ b/plat/arm/board/tc/nv_counter_test.c
@@ -7,9 +7,9 @@
 #include <stdint.h>
 #include <stdio.h>
 
-#include <drivers/arm/rss_comms.h>
+#include <drivers/arm/rse_comms.h>
 #include <plat/common/platform.h>
-#include "rss_platform_api.h"
+#include "rse_platform_api.h"
 
 #include <platform_def.h>
 
@@ -20,30 +20,30 @@ int nv_counter_test(void)
 	uint32_t new_val;
 	uint32_t id;
 
-	status = rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+	status = rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE);
 	if (status != PSA_SUCCESS) {
-		printf("Failed to initialize RSS communication channel - psa_status = %d\n", status);
+		printf("Failed to initialize RSE communication channel - psa_status = %d\n", status);
 		return -1;
 	}
 
 	for (id = 0; id < 3; id++) {
-		status = rss_platform_nv_counter_read(id, sizeof(old_val), (uint8_t *)&old_val);
+		status = rse_platform_nv_counter_read(id, sizeof(old_val), (uint8_t *)&old_val);
 		if (status != PSA_SUCCESS) {
-			printf("Failed during first id=(%d) rss_platform_nv_counter_read - psa_status = %d\n",
+			printf("Failed during first id=(%d) rse_platform_nv_counter_read - psa_status = %d\n",
 				       id, status);
 			return -1;
 		}
 
-		status = rss_platform_nv_counter_increment(id);
+		status = rse_platform_nv_counter_increment(id);
 		if (status != PSA_SUCCESS) {
-			printf("Failed during id=(%d) rss_platform_nv_counter_increment - psa_status = %d\n",
+			printf("Failed during id=(%d) rse_platform_nv_counter_increment - psa_status = %d\n",
 					id, status);
 			return -1;
 		}
 
-		status = rss_platform_nv_counter_read(id, sizeof(new_val), (uint8_t *)&new_val);
+		status = rse_platform_nv_counter_read(id, sizeof(new_val), (uint8_t *)&new_val);
 		if (status != PSA_SUCCESS) {
-			printf("Failed during second id=(%d) rss_platform_nv_counter_read - psa_status = %d\n",
+			printf("Failed during second id=(%d) rse_platform_nv_counter_read - psa_status = %d\n",
 					id, status);
 			return -1;
 		}
diff --git a/plat/arm/board/tc/plat_def_fip_uuid.h b/plat/arm/board/tc/plat_def_fip_uuid.h
index 631f7c95..46a455cd 100644
--- a/plat/arm/board/tc/plat_def_fip_uuid.h
+++ b/plat/arm/board/tc/plat_def_fip_uuid.h
@@ -10,28 +10,28 @@
 
 #include "uuid.h"
 
-#define UUID_RSS_FIRMWARE_BL1_2 \
+#define UUID_RSE_FIRMWARE_BL1_2 \
 	{{0x0a, 0xa5, 0xb1, 0xbe}, {0xe7, 0x84}, {0x41, 0xc5}, 0x81, 0xb8, {0x4a, 0x41, 0xcb, 0x4a, 0xd2, 0xdf}}
 
-#define UUID_RSS_FIRMWARE_BL2 \
+#define UUID_RSE_FIRMWARE_BL2 \
 	{{0xa3, 0xb3, 0xb3, 0x0d}, {0xeb, 0xc9}, {0x40, 0x48}, 0xb4, 0x80, {0x15, 0x53, 0x61, 0xc1, 0x70, 0x48}}
 
-#define UUID_RSS_FIRMWARE_SCP_BL1 \
+#define UUID_RSE_FIRMWARE_SCP_BL1 \
 	{{0xbf, 0xd5, 0x09, 0x8d}, {0xa7, 0x07}, {0x4f, 0x15}, 0x89, 0x1c, {0x37, 0x22, 0x10, 0xcb, 0x51, 0xe2}}
 
-#define UUID_RSS_FIRMWARE_AP_BL1 \
+#define UUID_RSE_FIRMWARE_AP_BL1 \
 	{{0x12, 0x4c, 0x50, 0xe0}, {0xf2, 0xda}, {0x45, 0xe9}, 0x85, 0xc8, {0xda, 0xd9, 0x60, 0x9b, 0x7a, 0x11}}
 
-#define UUID_RSS_FIRMWARE_NS \
+#define UUID_RSE_FIRMWARE_NS \
 	{{0x8d, 0x95, 0x9f, 0x72}, {0xb8, 0xb1}, {0x42, 0x11}, 0x9a, 0xe6, {0x4b, 0x80, 0x97, 0x47, 0x5a, 0xd9}}
 
-#define UUID_RSS_FIRMWARE_S \
+#define UUID_RSE_FIRMWARE_S \
 	{{0x22, 0xea, 0x33, 0x85}, {0xf8, 0x6e}, {0x47, 0x93}, 0x96, 0x8a, {0x2f, 0xe3, 0xdd, 0x50, 0x33, 0xcc}}
 
-#define UUID_RSS_SIC_TABLES_NS \
+#define UUID_RSE_SIC_TABLES_NS \
 	{{0xd9, 0x10, 0x00, 0x72}, {0x6a, 0x28}, {0x4b, 0xec}, 0xb0, 0xd6, {0x8c, 0xed, 0xc4, 0x15, 0x7c, 0xe0}}
 
-#define UUID_RSS_SIC_TABLES_S \
+#define UUID_RSE_SIC_TABLES_S \
 	{{0xc7, 0x38, 0xd0, 0xde}, {0x8c, 0x26}, {0x48, 0x51}, 0x93, 0x36, {0xf3, 0xdb, 0xe2, 0x96, 0x65, 0x18}}
 
 #endif /* __PLAT_DEF_FIP_UUID__ */
diff --git a/plat/arm/board/tc/plat_tc_mbedtls_config.h b/plat/arm/board/tc/plat_tc_mbedtls_config.h
index f0aa60b5..4fd8b6be 100644
--- a/plat/arm/board/tc/plat_tc_mbedtls_config.h
+++ b/plat/arm/board/tc/plat_tc_mbedtls_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Ltd. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Ltd. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,15 +19,26 @@
 #undef TF_MBEDTLS_HEAP_SIZE
 #define TF_MBEDTLS_HEAP_SIZE	PLATFORM_TEST_MIN_MBEDTLS_HEAP_SIZE
 #endif
-#endif
+#endif /* TF_MBEDTLS_HEAP_SIZE */
+
+/**
+ * On Arm TC platforms, the ROTPK is always hashed using the SHA-256
+ * algorithm.
+ * TODO: Update to hash the ROTPK with the selected HASH_ALG to avoid
+ * the need for explicitly enabling the SHA-256 configuration in mbedTLS.
+ */
+#define MBEDTLS_SHA256_C
+
+/*
+ * Use an implementation of SHA-256 with a smaller memory footprint
+ * but reduced speed.
+ */
+#define MBEDTLS_SHA256_SMALLER
 
 #define MBEDTLS_PSA_CRYPTO_C
-#define MBEDTLS_HMAC_DRBG_C
-#define MBEDTLS_ENTROPY_C
-#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
-#define MBEDTLS_NO_PLATFORM_ENTROPY
-#define MBEDTLS_TEST_NULL_ENTROPY
+#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
 #define MBEDTLS_ECP_C
 #define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define MBEDTLS_ECP_NO_INTERNAL_RNG
 
 #endif /* PLAT_TC_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 6874cfa5..9cd3011e 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -1,61 +1,101 @@
-# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 include common/fdt_wrappers.mk
 
-ifeq ($(TARGET_PLATFORM), 0)
-	$(error Platform ${PLAT}$(TARGET_PLATFORM) is deprecated.)
-endif
-
-ifeq ($(TARGET_PLATFORM), 1)
-        $(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
-          Some of the features might not work as expected)
-endif
+TARGET_FLAVOUR			:=	fvp
+# DPU with SCMI may not necessarily work, so allow its independence
+TC_DPU_USE_SCMI_CLK		:=	1
+# SCMI power domain control enable
+TC_SCMI_PD_CTRL_EN		:=	1
+
+# System setup
+CSS_USE_SCMI_SDS_DRIVER		:=	1
+HW_ASSISTED_COHERENCY		:=	1
+USE_COHERENT_MEM		:=	0
+GIC_ENABLE_V4_EXTN		:=      1
+GICV3_SUPPORT_GIC600		:=	1
+override NEED_BL2U		:=	no
+override ARM_PLAT_MT		:=	1
+
+# CPU setup
+ARM_ARCH_MINOR			:=	7
+BRANCH_PROTECTION		:=	1
+ENABLE_FEAT_MPAM		:=	1 # default is 2, optimise
+ENABLE_SVE_FOR_NS		:=	2 # to show we use it
+ENABLE_SVE_FOR_SWD		:=	1
+ENABLE_SME_FOR_NS		:=	2
+ENABLE_SME2_FOR_NS		:=	2
+ENABLE_SME_FOR_SWD		:=	1
+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
+
+CTX_INCLUDE_AARCH32_REGS	:=	0
 
-ifeq ($(shell expr $(TARGET_PLATFORM) \<= 2), 0)
-        $(error TARGET_PLATFORM must be less than or equal to 2)
+ifeq (${SPD},spmd)
+	SPMD_SPM_AT_SEL2	:=	1
+	CTX_INCLUDE_PAUTH_REGS	:=	1
 endif
 
-$(eval $(call add_define,TARGET_PLATFORM))
-
-CSS_LOAD_SCP_IMAGES	:=	1
-
-CSS_USE_SCMI_SDS_DRIVER	:=	1
-
-ENABLE_FEAT_RAS		:=	1
-
-SDEI_SUPPORT		:=	0
+# TC RESOLUTION - LIST OF VALID OPTIONS (this impacts only FVP)
+TC_RESOLUTION_OPTIONS		:= 	640x480p60 \
+					1920x1080p60
+# Set default to the 640x480p60 resolution mode
+TC_RESOLUTION ?= $(firstword $(TC_RESOLUTION_OPTIONS))
 
-EL3_EXCEPTION_HANDLING	:=	0
-
-HANDLE_EA_EL3_FIRST_NS	:=	0
+# Check resolution option for FVP
+ifneq ($(filter ${TARGET_FLAVOUR}, fvp),)
+ifeq ($(filter ${TC_RESOLUTION}, ${TC_RESOLUTION_OPTIONS}),)
+        $(error TC_RESOLUTION is ${TC_RESOLUTION}, it must be: ${TC_RESOLUTION_OPTIONS})
+endif
+endif
 
-# System coherency is managed in hardware
-HW_ASSISTED_COHERENCY	:=	1
+ifneq ($(shell expr $(TARGET_PLATFORM) \<= 1), 0)
+        $(error Platform ${PLAT}$(TARGET_PLATFORM) is no longer available.)
+endif
 
-# When building for systems with hardware-assisted coherency, there's no need to
-# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
-USE_COHERENT_MEM	:=	0
+ifneq ($(shell expr $(TARGET_PLATFORM) = 2), 0)
+        $(warning Platform ${PLAT}$(TARGET_PLATFORM) is deprecated. \
+          Some of the features might not work as expected)
+endif
 
-GIC_ENABLE_V4_EXTN	:=      1
+ifeq ($(shell expr $(TARGET_PLATFORM) \<= 4), 0)
+        $(error TARGET_PLATFORM must be less than or equal to 4)
+endif
 
-# GIC-600 configuration
-GICV3_SUPPORT_GIC600	:=	1
+ifeq ($(filter ${TARGET_FLAVOUR}, fvp fpga),)
+        $(error TARGET_FLAVOUR must be fvp or fpga)
+endif
 
-# Enable SVE
-ENABLE_SVE_FOR_NS	:=	2
-ENABLE_SVE_FOR_SWD	:=	1
+$(eval $(call add_defines, \
+	TARGET_PLATFORM \
+	TARGET_FLAVOUR_$(call uppercase,${TARGET_FLAVOUR}) \
+	TC_RESOLUTION_$(call uppercase,${TC_RESOLUTION}) \
+	TC_DPU_USE_SCMI_CLK \
+	TC_SCMI_PD_CTRL_EN \
+))
 
-# enable trace buffer control registers access to NS by default
-ENABLE_TRBE_FOR_NS              := 1
+CSS_LOAD_SCP_IMAGES	:=	1
 
-# enable trace system registers access to NS by default
-ENABLE_SYS_REG_TRACE_FOR_NS     := 1
+# Save DSU PMU registers on cluster off and restore them on cluster on
+PRESERVE_DSU_PMU_REGS		:= 1
 
-# enable trace filter control registers access to NS by default
-ENABLE_TRF_FOR_NS               := 1
+# Specify MHU type based on platform
+ifneq ($(filter ${TARGET_PLATFORM}, 2),)
+	PLAT_MHU_VERSION	:= 2
+else
+	PLAT_MHU_VERSION	:= 3
+endif
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
@@ -64,13 +104,10 @@ ENT_GIC_SOURCES		:=	${GICV3_SOURCES}		\
 				plat/common/plat_gicv3.c	\
 				plat/arm/common/arm_gicv3.c
 
-override NEED_BL2U	:=	no
-
-override ARM_PLAT_MT	:=	1
-
 TC_BASE	=	plat/arm/board/tc
 
-PLAT_INCLUDES		+=	-I${TC_BASE}/include/
+PLAT_INCLUDES		+=	-I${TC_BASE}/include/ \
+				-I${TC_BASE}/fdts/
 
 # CPU libraries for TARGET_PLATFORM=1
 ifeq (${TARGET_PLATFORM}, 1)
@@ -81,12 +118,32 @@ endif
 
 # CPU libraries for TARGET_PLATFORM=2
 ifeq (${TARGET_PLATFORM}, 2)
+ERRATA_A520_2938996	:=	1
+ERRATA_X4_2726228	:=	1
+
 TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a520.S \
 			lib/cpus/aarch64/cortex_a720.S \
 			lib/cpus/aarch64/cortex_x4.S
 endif
 
-INTERCONNECT_SOURCES	:=	${TC_BASE}/tc_interconnect.c
+# CPU libraries for TARGET_PLATFORM=3
+ifeq (${TARGET_PLATFORM}, 3)
+ERRATA_A520_2938996	:=	1
+
+TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_a520.S \
+			lib/cpus/aarch64/cortex_a725.S \
+			lib/cpus/aarch64/cortex_x925.S
+endif
+
+# CPU libraries for TARGET_PLATFORM=4
+ifeq (${TARGET_PLATFORM}, 4)
+TC_CPU_SOURCES	+=	lib/cpus/aarch64/cortex_gelas.S \
+			lib/cpus/aarch64/nevis.S \
+			lib/cpus/aarch64/travis.S
+endif
+
+INTERCONNECT_SOURCES	:=	${TC_BASE}/tc_interconnect.c \
+				plat/arm/common/arm_ni.c
 
 PLAT_BL_COMMON_SOURCES	+=	${TC_BASE}/tc_plat.c	\
 				${TC_BASE}/include/tc_helpers.S
@@ -94,6 +151,7 @@ PLAT_BL_COMMON_SOURCES	+=	${TC_BASE}/tc_plat.c	\
 BL1_SOURCES		+=	${INTERCONNECT_SOURCES}	\
 				${TC_CPU_SOURCES}	\
 				${TC_BASE}/tc_trusted_boot.c	\
+				${TC_BASE}/tc_bl1_setup.c \
 				${TC_BASE}/tc_err.c	\
 				drivers/arm/sbsa/sbsa.c
 
@@ -103,9 +161,12 @@ BL2_SOURCES		+=	${TC_BASE}/tc_security.c	\
 				${TC_BASE}/tc_bl2_setup.c		\
 				lib/utils/mem_region.c			\
 				drivers/arm/tzc/tzc400.c		\
-				plat/arm/common/arm_tzc400.c		\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
+ifeq ($(shell test $(TARGET_PLATFORM) -le 2; echo $$?),0)
+BL2_SOURCES		+=	plat/arm/common/arm_tzc400.c
+endif
+
 BL31_SOURCES		+=	${INTERCONNECT_SOURCES}	\
 				${TC_CPU_SOURCES}	\
 				${ENT_GIC_SOURCES}			\
@@ -113,6 +174,7 @@ BL31_SOURCES		+=	${INTERCONNECT_SOURCES}	\
 				${TC_BASE}/tc_topology.c	\
 				lib/fconf/fconf.c			\
 				lib/fconf/fconf_dyn_cfg_getter.c	\
+				drivers/arm/css/dsu/dsu.c			\
 				drivers/cfi/v2m/v2m_flash.c		\
 				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
@@ -122,18 +184,22 @@ BL31_SOURCES		+=	${FDT_WRAPPERS_SOURCES}
 
 # Add the FDT_SOURCES and options for Dynamic Config
 FDT_SOURCES		+=	${TC_BASE}/fdts/${PLAT}_fw_config.dts	\
-				${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts
+				${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts \
+				${TC_BASE}/fdts/${PLAT}_nt_fw_config.dts
 FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
 TB_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FVP_NT_FW_CONFIG	:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
 # Add the FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
 
 ifeq (${SPD},spmd)
 ifeq ($(ARM_SPMC_MANIFEST_DTS),)
-ARM_SPMC_MANIFEST_DTS	:=	${TC_BASE}/fdts/${PLAT}_spmc_manifest.dts
+ARM_SPMC_MANIFEST_DTS	:=	${TC_BASE}/fdts/${PLAT}_spmc_test_manifest.dts
 endif
 
 FDT_SOURCES		+=	${ARM_SPMC_MANIFEST_DTS}
@@ -144,7 +210,7 @@ $(eval $(call TOOL_ADD_PAYLOAD,${TC_TOS_FW_CONFIG},--tos-fw-config,${TC_TOS_FW_C
 endif
 
 #Device tree
-TC_HW_CONFIG_DTS	:=	fdts/tc.dts
+TC_HW_CONFIG_DTS	:=	fdts/${PLAT}${TARGET_PLATFORM}.dts
 TC_HW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}.dtb
 FDT_SOURCES		+=	${TC_HW_CONFIG_DTS}
 $(eval TC_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(TC_HW_CONFIG_DTS)))
@@ -152,43 +218,59 @@ $(eval TC_HW_CONFIG	:=	${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(TC_HW_CONFIG_DTS))
 # Add the HW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TC_HW_CONFIG},--hw-config,${TC_HW_CONFIG}))
 
-override CTX_INCLUDE_AARCH32_REGS	:= 0
-
-override CTX_INCLUDE_PAUTH_REGS	:= 1
-
-override ENABLE_SPE_FOR_NS	:= 0
-
-override ENABLE_FEAT_AMU := 1
-override ENABLE_AMU_AUXILIARY_COUNTERS := 1
-override ENABLE_AMU_FCONF := 1
-
-override ENABLE_MPMM := 1
-override ENABLE_MPMM_FCONF := 1
-
 # Include Measured Boot makefile before any Crypto library makefile.
 # Crypto library makefile may need default definitions of Measured Boot build
 # flags present in Measured Boot makefile.
+$(info Including rse_comms.mk)
 ifeq (${MEASURED_BOOT},1)
-    MEASURED_BOOT_MK := drivers/measured_boot/rss/rss_measured_boot.mk
-    $(info Including ${MEASURED_BOOT_MK})
-    include ${MEASURED_BOOT_MK}
-    $(info Including rss_comms.mk)
-    include drivers/arm/rss/rss_comms.mk
-
-    BL1_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
+        $(info Including rse_comms.mk)
+        include drivers/arm/rse/rse_comms.mk
+
+	BL1_SOURCES	+=	${RSE_COMMS_SOURCES}
+	BL2_SOURCES	+=	${RSE_COMMS_SOURCES}
+	PLAT_INCLUDES	+=	-Iinclude/lib/psa
+
+    ifeq (${DICE_PROTECTION_ENVIRONMENT},1)
+        $(info Including qcbor.mk)
+        include drivers/measured_boot/rse/qcbor.mk
+        $(info Including dice_prot_env.mk)
+        include drivers/measured_boot/rse/dice_prot_env.mk
+
+	BL1_SOURCES	+=	${QCBOR_SOURCES} \
+				${DPE_SOURCES} \
+				plat/arm/board/tc/tc_common_dpe.c \
+				plat/arm/board/tc/tc_bl1_dpe.c \
+				lib/psa/dice_protection_environment.c \
+				drivers/arm/css/sds/sds.c \
+				drivers/delay_timer/delay_timer.c \
+				drivers/delay_timer/generic_delay_timer.c
+
+	BL2_SOURCES	+=	${QCBOR_SOURCES} \
+				${DPE_SOURCES} \
+				plat/arm/board/tc/tc_common_dpe.c \
+				plat/arm/board/tc/tc_bl2_dpe.c \
+				lib/psa/dice_protection_environment.c
+
+	PLAT_INCLUDES	+=	-I${QCBOR_INCLUDES} \
+				-Iinclude/lib/dice
+    else
+        $(info Including rse_measured_boot.mk)
+        include drivers/measured_boot/rse/rse_measured_boot.mk
+
+	BL1_SOURCES	+=	${MEASURED_BOOT_SOURCES} \
 				plat/arm/board/tc/tc_common_measured_boot.c \
 				plat/arm/board/tc/tc_bl1_measured_boot.c \
-				lib/psa/measured_boot.c			 \
-				${RSS_COMMS_SOURCES}
+				lib/psa/measured_boot.c
 
-    BL2_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
+	BL2_SOURCES		+=	${MEASURED_BOOT_SOURCES} \
 				plat/arm/board/tc/tc_common_measured_boot.c \
 				plat/arm/board/tc/tc_bl2_measured_boot.c \
-				lib/psa/measured_boot.c			 \
-				${RSS_COMMS_SOURCES}
-
-PLAT_INCLUDES		+=	-Iinclude/lib/psa
+				lib/psa/measured_boot.c
+    endif
+endif
 
+ifeq (${TRNG_SUPPORT},1)
+	BL31_SOURCES	+=	plat/arm/board/tc/tc_trng.c
 endif
 
 ifneq (${PLATFORM_TEST},)
@@ -202,5 +284,4 @@ endif
 
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
-include plat/arm/soc/common/soc_css.mk
 include plat/arm/board/common/board_common.mk
diff --git a/plat/arm/board/tc/platform_test.mk b/plat/arm/board/tc/platform_test.mk
index 2fd5ea0e..2ce66485 100644
--- a/plat/arm/board/tc/platform_test.mk
+++ b/plat/arm/board/tc/platform_test.mk
@@ -1,47 +1,47 @@
-# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2022-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 $(eval $(call add_define,PLATFORM_TESTS))
 
-ifeq (${PLATFORM_TEST},rss-nv-counters)
-    include drivers/arm/rss/rss_comms.mk
+ifeq (${PLATFORM_TEST},rse-nv-counters)
+    include drivers/arm/rse/rse_comms.mk
 
     # Test code.
     BL31_SOURCES	+=	plat/arm/board/tc/nv_counter_test.c
 
     # Code under testing.
-    BL31_SOURCES	+=	lib/psa/rss_platform.c \
-				drivers/arm/rss/rss_comms.c \
-				${RSS_COMMS_SOURCES}
+    BL31_SOURCES	+=	lib/psa/rse_platform.c \
+				${RSE_COMMS_SOURCES}
 
     PLAT_INCLUDES	+=	-Iinclude/lib/psa
 
     $(eval $(call add_define,PLATFORM_TEST_NV_COUNTERS))
-else ifeq (${PLATFORM_TEST},rss-rotpk)
-    include drivers/arm/rss/rss_comms.mk
+else ifeq (${PLATFORM_TEST},rse-rotpk)
+    include drivers/arm/rse/rse_comms.mk
 
     # Test code.
     BL31_SOURCES	+=	plat/arm/board/tc/rotpk_test.c
 
     # Code under testing.
-    BL31_SOURCES	+=	lib/psa/rss_platform.c \
-				drivers/arm/rss/rss_comms.c \
-				${RSS_COMMS_SOURCES}
+    BL31_SOURCES	+=	lib/psa/rse_platform.c \
+				${RSE_COMMS_SOURCES}
 
     PLAT_INCLUDES	+=	-Iinclude/lib/psa
 
     $(eval $(call add_define,PLATFORM_TEST_ROTPK))
 else ifeq (${PLATFORM_TEST},tfm-testsuite)
+    include drivers/arm/rse/rse_comms.mk
+    include drivers/measured_boot/rse/qcbor.mk
 
     # The variables need to be set to compile the platform test:
     ifeq (${TF_M_TESTS_PATH},)
-        # Example: ../rss/tf-m-tests
+        # Example: ../rse/tf-m-tests
         $(error Error: TF_M_TESTS_PATH not set)
     endif
     ifeq (${TF_M_EXTRAS_PATH},)
-        # Example: ../rss/tf-m-extras
+        # Example: ../rse/tf-m-extras
         $(error Error: TF_M_EXTRAS_PATH not set)
     endif
     ifeq (${MEASUREMENT_VALUE_SIZE},)
@@ -56,43 +56,47 @@ else ifeq (${PLATFORM_TEST},tfm-testsuite)
 
     MBEDTLS_CONFIG_FILE		=	"<plat_tc_mbedtls_config.h>"
 
-    LIBMBEDTLS_SRCS		+= 	$(addprefix ${MBEDTLS_DIR}/library/,	\
+    LIBMBEDTLS_SRCS		+=	$(addprefix ${MBEDTLS_DIR}/library/,	\
 					entropy.c				\
 					entropy_poll.c				\
 					hmac_drbg.c				\
 					psa_crypto.c				\
 					psa_crypto_client.c			\
-					psa_crypto_driver_wrappers.c		\
+					psa_crypto_driver_wrappers_no_static.c	\
 					psa_crypto_hash.c			\
 					psa_crypto_rsa.c			\
 					psa_crypto_ecp.c			\
 					psa_crypto_slot_management.c		\
+					psa_util.c				\
 					)
 
-    BL31_SOURCES	+=	${RSS_COMMS_SOURCES} 				\
-				plat/arm/common/arm_dyn_cfg.c 			\
-				${TC_BASE}/rss_ap_tests.c 			\
-				${TC_BASE}/rss_ap_testsuites.c 			\
-				${TC_BASE}/rss_ap_test_stubs.c			\
-				$(TF_M_TESTS_PATH)/test/framework/test_framework.c \
+    BL31_SOURCES	+=	${RSE_COMMS_SOURCES}				\
+				plat/arm/common/arm_dyn_cfg.c			\
+				${TC_BASE}/rse_ap_tests.c			\
+				${TC_BASE}/rse_ap_testsuites.c			\
+				${TC_BASE}/rse_ap_test_stubs.c			\
+				$(TF_M_TESTS_PATH)/tests_reg/test/framework/test_framework.c \
 				$(MEASURED_BOOT_TESTS_PATH)/measured_boot_common.c \
 				$(MEASURED_BOOT_TESTS_PATH)/measured_boot_tests_common.c \
 				$(DELEGATED_ATTEST_TESTS_PATH)/delegated_attest_test.c \
-				drivers/auth/mbedtls/mbedtls_common.c 		\
-				lib/psa/measured_boot.c 			\
-				lib/psa/delegated_attestation.c
+				drivers/auth/mbedtls/mbedtls_common.c		\
+				lib/psa/measured_boot.c				\
+				lib/psa/delegated_attestation.c			\
+				${QCBOR_SOURCES}
 
     PLAT_INCLUDES	+=	-I$(TF_M_EXTRAS_PATH)/partitions/measured_boot/interface/include \
 				-I$(TF_M_EXTRAS_PATH)/partitions/delegated_attestation/interface/include \
-				-I$(TF_M_TESTS_PATH)/test/framework 		\
-				-I$(TF_M_TESTS_PATH)/log 			\
-				-I$(TF_M_TESTS_PATH)/test/secure_fw/suites/extra \
-				-I$(MEASURED_BOOT_TESTS_PATH)/non_secure 	\
-				-I$(DELEGATED_ATTEST_TESTS_PATH) 		\
-				-I$(DELEGATED_ATTEST_TESTS_PATH)/non_secure \
-				-Iplat/arm/board/tc 				\
-				-Iinclude/drivers/auth/mbedtls 			\
-				-Iinclude/drivers/arm
+				-I$(TF_M_TESTS_PATH)/tests_reg/test/framework	\
+				-I$(TF_M_TESTS_PATH)/tests_reg/test/secure_fw/suites/extra \
+				-I$(TF_M_TESTS_PATH)/lib/log			\
+				-I$(MEASURED_BOOT_TESTS_PATH)/non_secure	\
+				-I$(DELEGATED_ATTEST_TESTS_PATH)		\
+				-I$(DELEGATED_ATTEST_TESTS_PATH)/non_secure	\
+				-Iplat/arm/board/tc				\
+				-Iinclude/drivers/auth/mbedtls			\
+				-Iinclude/drivers/arm				\
+				-Iinclude/lib/psa				\
+				-I${QCBOR_INCLUDES}
 
     # Some of the PSA functions are declared in multiple header files, that
     # triggers this warning.
diff --git a/plat/arm/board/tc/rotpk_test.c b/plat/arm/board/tc/rotpk_test.c
index ed56c31b..2178f697 100644
--- a/plat/arm/board/tc/rotpk_test.c
+++ b/plat/arm/board/tc/rotpk_test.c
@@ -7,9 +7,9 @@
 #include <stdint.h>
 #include <stdio.h>
 
-#include <drivers/arm/rss_comms.h>
+#include <drivers/arm/rse_comms.h>
 #include <plat/common/platform.h>
-#include <rss_platform_api.h>
+#include <rse_platform_api.h>
 #include <tc_plat.h>
 
 static void print_hex(const char *key_id_name, size_t key_size, const uint8_t *key_buf)
@@ -28,19 +28,19 @@ int rotpk_test(void)
 	size_t key_size;
 
 	struct key_id_info key_ids[3] = {
-	       {.key_id = RSS_BUILTIN_KEY_ID_HOST_S_ROTPK,  .key_id_name = "Secure-ROTPK"},
-	       {.key_id = RSS_BUILTIN_KEY_ID_HOST_NS_ROTPK,  .key_id_name = "NS-ROTPK"},
-	       {.key_id = RSS_BUILTIN_KEY_ID_HOST_CCA_ROTPK,  .key_id_name = "CCA-ROTPK"}
+	       {.key_id = RSE_BUILTIN_KEY_ID_HOST_S_ROTPK,  .key_id_name = "Secure-ROTPK"},
+	       {.key_id = RSE_BUILTIN_KEY_ID_HOST_NS_ROTPK,  .key_id_name = "NS-ROTPK"},
+	       {.key_id = RSE_BUILTIN_KEY_ID_HOST_CCA_ROTPK,  .key_id_name = "CCA-ROTPK"}
 	};
 
-	status = rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+	status = rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE);
 	if (status != PSA_SUCCESS) {
-		printf("Failed to initialize RSS communication channel - psa_status = %d\n", status);
+		printf("Failed to initialize RSE communication channel - psa_status = %d\n", status);
 		return -1;
 	}
 
 	for (int i = 0; i < ARRAY_SIZE(key_ids); i++) {
-		status = rss_platform_key_read(key_ids[i].key_id, key_buf,
+		status = rse_platform_key_read(key_ids[i].key_id, key_buf,
 			       sizeof(key_buf), &key_size);
 		if (status != PSA_SUCCESS) {
 			printf("Failed to retrieve %s - psa_status = %d\n", key_ids[i].key_id_name, status);
diff --git a/plat/arm/board/tc/rss_ap_test_stubs.c b/plat/arm/board/tc/rse_ap_test_stubs.c
similarity index 92%
rename from plat/arm/board/tc/rss_ap_test_stubs.c
rename to plat/arm/board/tc/rse_ap_test_stubs.c
index aa97476f..cf791814 100644
--- a/plat/arm/board/tc/rss_ap_test_stubs.c
+++ b/plat/arm/board/tc/rse_ap_test_stubs.c
@@ -26,7 +26,7 @@ tfm_measured_boot_extend_measurement(uint8_t index,
 				     size_t measurement_value_size,
 				     bool lock_measurement)
 {
-	return rss_measured_boot_extend_measurement(index,
+	return rse_measured_boot_extend_measurement(index,
 						    signer_id,
 						    signer_id_size,
 						    version,
@@ -56,7 +56,7 @@ tfm_measured_boot_read_measurement(uint8_t index,
 				   size_t *measurement_value_len,
 				   bool *is_locked)
 {
-	return rss_measured_boot_read_measurement(index,
+	return rse_measured_boot_read_measurement(index,
 						  signer_id,
 						  signer_id_size,
 						  signer_id_len,
@@ -80,7 +80,7 @@ tfm_delegated_attest_get_token(const uint8_t *dak_pub_hash,
 			       size_t         token_buf_size,
 			       size_t        *token_size)
 {
-	return rss_delegated_attest_get_token(dak_pub_hash,
+	return rse_delegated_attest_get_token(dak_pub_hash,
 					      dak_pub_hash_size,
 					      token_buf,
 					      token_buf_size,
@@ -95,7 +95,7 @@ tfm_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
 				       size_t   *key_size,
 				       uint32_t  hash_algo)
 {
-	return rss_delegated_attest_get_delegated_key(ecc_curve,
+	return rse_delegated_attest_get_delegated_key(ecc_curve,
 						      key_bits,
 						      key_buf,
 						      key_buf_size,
diff --git a/plat/arm/board/tc/rss_ap_tests.c b/plat/arm/board/tc/rse_ap_tests.c
similarity index 94%
rename from plat/arm/board/tc/rss_ap_tests.c
rename to plat/arm/board/tc/rse_ap_tests.c
index ea90ac33..3ca628a6 100644
--- a/plat/arm/board/tc/rss_ap_tests.c
+++ b/plat/arm/board/tc/rse_ap_tests.c
@@ -10,9 +10,9 @@
 #include <mbedtls_common.h>
 #include <plat/common/platform.h>
 #include <psa/crypto.h>
-#include <rss_comms.h>
+#include <rse_comms.h>
 
-#include "rss_ap_testsuites.h"
+#include "rse_ap_testsuites.h"
 
 static struct test_suite_t test_suites[] = {
 	{.freg = register_testsuite_delegated_attest},
@@ -32,7 +32,7 @@ static int run_tests(void)
 	size_t i;
 
 	/* Initialize test environment. */
-	rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE, PLAT_RSS_AP_RCV_MHU_BASE);
+	rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE, PLAT_RSE_AP_RCV_MHU_BASE);
 	mbedtls_init();
 	status = psa_crypto_init();
 	if (status != PSA_SUCCESS) {
diff --git a/plat/arm/board/tc/rss_ap_testsuites.c b/plat/arm/board/tc/rse_ap_testsuites.c
similarity index 93%
rename from plat/arm/board/tc/rss_ap_testsuites.c
rename to plat/arm/board/tc/rse_ap_testsuites.c
index aa47d4c2..5f4dc165 100644
--- a/plat/arm/board/tc/rss_ap_testsuites.c
+++ b/plat/arm/board/tc/rse_ap_testsuites.c
@@ -11,7 +11,7 @@
  * necessary because both files define the function `extra_tests_init`, so a
  * linker error occurs when both are linked to BL31. This file defines a macro
  * that renames the colliding function names to something unique.
- * `plat/arm/board/tc/rss_ap_tests.c` can call the test init functions with
+ * `plat/arm/board/tc/rse_ap_tests.c` can call the test init functions with
  * their new name.
  */
 
diff --git a/plat/arm/board/tc/rss_ap_testsuites.h b/plat/arm/board/tc/rse_ap_testsuites.h
similarity index 76%
rename from plat/arm/board/tc/rss_ap_testsuites.h
rename to plat/arm/board/tc/rse_ap_testsuites.h
index 58502ab6..9bb42f58 100644
--- a/plat/arm/board/tc/rss_ap_testsuites.h
+++ b/plat/arm/board/tc/rse_ap_testsuites.h
@@ -5,12 +5,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef RSS_AP_TESTSUITES_H
-#define RSS_AP_TESTSUITES_H
+#ifndef RSE_AP_TESTSUITES_H
+#define RSE_AP_TESTSUITES_H
 
 #include <test_framework.h>
 
 void register_testsuite_measured_boot(struct test_suite_t *p_test_suite);
 void register_testsuite_delegated_attest(struct test_suite_t *p_test_suite);
 
-#endif /* RSS_AP_TESTSUITES_H */
+#endif /* RSE_AP_TESTSUITES_H */
diff --git a/plat/arm/board/tc/tc_bl1_dpe.c b/plat/arm/board/tc/tc_bl1_dpe.c
new file mode 100644
index 00000000..de5702a7
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl1_dpe.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/arm/css/sds.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/delay_timer.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rse/dice_prot_env.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tools_share/zero_oid.h>
+
+#include "tc_dpe.h"
+
+struct dpe_metadata tc_dpe_metadata[] = {
+	{
+		.id = FW_CONFIG_ID,
+		.cert_id = DPE_AP_FW_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = ZERO_OID },
+	{
+		.id = TB_FW_CONFIG_ID,
+		.cert_id = DPE_AP_FW_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_TB_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = ZERO_OID },
+	{
+		.id = BL2_IMAGE_ID,
+		.cert_id = DPE_AP_FW_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL2_IMAGE_STRING,
+		.allow_new_context_to_derive = true,
+		.retain_parent_context = true, /* To handle restart */
+		.target_locality = LOCALITY_AP_S,
+		.create_certificate = false,
+		.pk_oid = ZERO_OID },
+	{
+		.id = DPE_INVALID_ID }
+};
+
+/* Effective timeout of 10000 ms */
+#define RSE_DPE_BOOT_10US_RETRIES		1000000
+#define TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID	0x0000000A
+
+/* Context handle is meant to be used by BL2. Sharing it via TB_FW_CONFIG */
+static int new_ctx_handle;
+/* Save a valid parent context handle to be able to send commands to DPE service
+ * in case of an AP cold restart.
+ */
+static int new_parent_ctx_handle;
+
+void plat_dpe_share_context_handle(int *ctx_handle, int *parent_ctx_handle)
+{
+	new_ctx_handle = *ctx_handle;
+	new_parent_ctx_handle = *parent_ctx_handle;
+}
+
+void plat_dpe_get_context_handle(int *ctx_handle)
+{
+	int retry = RSE_DPE_BOOT_10US_RETRIES;
+	int ret;
+
+	/* Initialize System level generic or SP804 timer */
+	generic_delay_timer_init();
+
+	/* Check the initialization of the Shared Data Storage area between RSE
+	 * and AP. Since AP_BL1 is executed first then a bit later the RSE
+	 * runtime, which initialize this area, therefore AP needs to check it
+	 * in a loop until it gets written by RSE Secure Runtime.
+	 */
+	VERBOSE("Waiting for DPE service initialization in RSE Secure Runtime\n");
+	while (retry > 0) {
+		ret = sds_init(SDS_RSE_AP_REGION_ID);
+		if (ret != SDS_OK) {
+			udelay(10);
+			retry--;
+		} else {
+			break;
+		}
+	}
+
+	if (retry == 0) {
+		ERROR("DPE init timeout\n");
+		plat_panic_handler();
+	} else {
+		VERBOSE("DPE init succeeded in %dms.\n",
+			(RSE_DPE_BOOT_10US_RETRIES - retry) / 100);
+	}
+
+	/* TODO: call this in a loop to avoid reading unfinished data */
+	ret = sds_struct_read(SDS_RSE_AP_REGION_ID,
+			      TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID,
+			      0,
+			      ctx_handle,
+			      sizeof(*ctx_handle),
+			      SDS_ACCESS_MODE_NON_CACHED);
+	if (ret != SDS_OK) {
+		ERROR("Unable to get DPE context handle from SDS area\n");
+		plat_panic_handler();
+	}
+
+	VERBOSE("Received DPE context handle: 0x%x\n", *ctx_handle);
+}
+
+void bl1_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE,
+			     PLAT_RSE_AP_RCV_MHU_BASE);
+
+	dpe_init(tc_dpe_metadata);
+}
+
+void bl1_plat_mboot_finish(void)
+{
+	int rc;
+
+	VERBOSE("Share DPE context handle with BL2: 0x%x\n", new_ctx_handle);
+	rc = arm_set_tb_fw_info(&new_ctx_handle);
+	if (rc != 0) {
+		ERROR("Unable to set DPE context handle in TB_FW_CONFIG\n");
+		/*
+		 * It is a fatal error because on TC platform, BL2 software
+		 * assumes that a valid DPE context_handle is passed through
+		 * the DTB object by BL1.
+		 */
+		plat_panic_handler();
+	}
+
+	VERBOSE("Save parent context handle: 0x%x\n", new_parent_ctx_handle);
+	rc = sds_struct_write(SDS_RSE_AP_REGION_ID,
+			      TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID,
+			      0,
+			      &new_parent_ctx_handle,
+			      sizeof(new_parent_ctx_handle),
+			      SDS_ACCESS_MODE_NON_CACHED);
+	if (rc != SDS_OK) {
+		ERROR("Unable to save DPE parent context handle to SDS area\n");
+		plat_panic_handler();
+	}
+}
diff --git a/plat/arm/board/tc/tc_bl1_measured_boot.c b/plat/arm/board/tc/tc_bl1_measured_boot.c
index 6821a6ab..28a1e316 100644
--- a/plat/arm/board/tc/tc_bl1_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl1_measured_boot.c
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdint.h>
 
-#include <drivers/arm/rss_comms.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
-#include <lib/psa/measured_boot.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
 #include <tools_share/zero_oid.h>
 
 #include <plat/arm/common/plat_arm.h>
@@ -17,40 +17,40 @@
 /* Table with platform specific image IDs and metadata. Intentionally not a
  * const struct, some members might set by bootloaders during trusted boot.
  */
-struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
+struct rse_mboot_metadata tc_rse_mboot_metadata[] = {
 	{
 		.id = FW_CONFIG_ID,
 		.slot = U(6),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_FW_CONFIG_STRING,
+		.sw_type = MBOOT_FW_CONFIG_STRING,
 		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 	{
 		.id = TB_FW_CONFIG_ID,
 		.slot = U(7),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING,
+		.sw_type = MBOOT_TB_FW_CONFIG_STRING,
 		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 	{
 		.id = BL2_IMAGE_ID,
 		.slot = U(8),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_BL2_STRING,
+		.sw_type = MBOOT_BL2_IMAGE_STRING,
 		.pk_oid = ZERO_OID,
 		.lock_measurement = true },
 
 	{
-		.id = RSS_MBOOT_INVALID_ID }
+		.id = RSE_MBOOT_INVALID_ID }
 };
 
 void bl1_plat_mboot_init(void)
 {
-	/* Initialize the communication channel between AP and RSS */
-	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
-			     PLAT_RSS_AP_RCV_MHU_BASE);
+	/* Initialize the communication channel between AP and RSE */
+	(void)rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE,
+			     PLAT_RSE_AP_RCV_MHU_BASE);
 
-	rss_measured_boot_init(tc_rss_mboot_metadata);
+	rse_measured_boot_init(tc_rse_mboot_metadata);
 }
 
 void bl1_plat_mboot_finish(void)
diff --git a/plat/arm/board/tc/tc_bl1_setup.c b/plat/arm/board/tc/tc_bl1_setup.c
new file mode 100644
index 00000000..aedc94f9
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl1_setup.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+
+void soc_css_init_nic400(void)
+{
+}
+
+void soc_css_init_pcie(void)
+{
+}
diff --git a/plat/arm/board/tc/tc_bl2_dpe.c b/plat/arm/board/tc/tc_bl2_dpe.c
new file mode 100644
index 00000000..c56612b4
--- /dev/null
+++ b/plat/arm/board/tc/tc_bl2_dpe.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rse/dice_prot_env.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tools_share/tbbr_oid.h>
+
+#include "tc_dpe.h"
+
+/*
+ * The content and the values of this array depends on:
+ * - build config: Which components are loaded: SPMD, TOS, SPx, etc ?
+ * - boot order: the last element in a layer should be treated differently.
+ */
+
+/*
+ * TODO:
+ *     - The content of the array must be tailored according to the build
+ *       config (TOS, SPMD, etc). All loaded components (executables and
+ *       config blobs) must be present in this array.
+ *     - Current content is according to the Trusty build config.
+ */
+struct dpe_metadata tc_dpe_metadata[] = {
+	{
+		.id = BL31_IMAGE_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL31_IMAGE_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = BL31_IMAGE_KEY_OID },
+	{
+		.id = BL32_IMAGE_ID,
+		.cert_id =  DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL32_IMAGE_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = BL32_IMAGE_KEY_OID },
+	{
+		.id = BL33_IMAGE_ID,
+		.cert_id = DPE_HYPERVISOR_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_BL33_IMAGE_STRING,
+		.allow_new_context_to_derive = true,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_AP_NS,
+		.pk_oid = BL33_IMAGE_KEY_OID },
+
+	{
+		.id = HW_CONFIG_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_HW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = HW_CONFIG_KEY_OID },
+	{
+		.id = NT_FW_CONFIG_ID,
+		.cert_id = DPE_HYPERVISOR_CERT_ID,
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_NT_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NT_FW_CONFIG_KEY_OID },
+	{
+		.id = SCP_BL2_IMAGE_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SCP_BL2_IMAGE_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = SCP_BL2_IMAGE_KEY_OID },
+	{
+		.id = SOC_FW_CONFIG_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = SOC_FW_CONFIG_KEY_OID },
+	{
+		.id = TOS_FW_CONFIG_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_TOS_FW_CONFIG_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = TOS_FW_CONFIG_KEY_OID },
+#if defined(SPD_spmd)
+	{
+		.id = SP_PKG1_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP1_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = true, /* With Trusty only one SP is loaded */
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG2_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP2_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG3_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP3_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG4_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP4_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG5_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP5_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG6_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP6_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG7_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP7_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+	{
+		.id = SP_PKG8_ID,
+		.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SP8_STRING,
+		.allow_new_context_to_derive = false,
+		.retain_parent_context = true,
+		.create_certificate = false,
+		.target_locality = LOCALITY_NONE, /* won't derive don't care */
+		.pk_oid = NULL },
+
+#endif
+	{
+		.id = DPE_INVALID_ID }
+};
+
+/* Context handle is meant to be used by BL33. Sharing it via NT_FW_CONFIG */
+static int new_ctx_handle;
+
+void plat_dpe_share_context_handle(int *ctx_handle, int *parent_ctx_handle)
+{
+	new_ctx_handle = *ctx_handle;
+
+	/* Irrelevant in BL2 because cold restart resumes CPU in BL1 */
+	(void)parent_ctx_handle;
+}
+
+void plat_dpe_get_context_handle(int *ctx_handle)
+{
+	int rc;
+
+	rc = arm_get_tb_fw_info(ctx_handle);
+	if (rc != 0) {
+		ERROR("Unable to get DPE context handle from TB_FW_CONFIG\n");
+		/*
+		 * It is a fatal error because on FVP platform, BL2 software
+		 * assumes that a valid DPE context_handle is passed through
+		 * the DTB object by BL1.
+		 */
+		plat_panic_handler();
+	}
+
+	VERBOSE("Received DPE context handle: 0x%x\n", *ctx_handle);
+}
+
+void bl2_plat_mboot_init(void)
+{
+	/* Initialize the communication channel between AP and RSE */
+	(void)rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE,
+			     PLAT_RSE_AP_RCV_MHU_BASE);
+
+	dpe_init(tc_dpe_metadata);
+}
+
+void bl2_plat_mboot_finish(void)
+{
+	int rc;
+
+	VERBOSE("Share DPE context handle with BL33: 0x%x\n", new_ctx_handle);
+	rc = arm_set_nt_fw_info(&new_ctx_handle);
+	if (rc != 0) {
+		ERROR("Unable to set DPE context handle in NT_FW_CONFIG\n");
+		/*
+		 * It is a fatal error because on TC platform, BL33 software
+		 * assumes that a valid DPE context_handle is passed through
+		 * the DTB object by BL2.
+		 */
+		plat_panic_handler();
+	}
+}
diff --git a/plat/arm/board/tc/tc_bl2_measured_boot.c b/plat/arm/board/tc/tc_bl2_measured_boot.c
index 4b791708..3957c906 100644
--- a/plat/arm/board/tc/tc_bl2_measured_boot.c
+++ b/plat/arm/board/tc/tc_bl2_measured_boot.c
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdint.h>
 
-#include <drivers/arm/rss_comms.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
-#include <lib/psa/measured_boot.h>
+#include <drivers/arm/rse_comms.h>
+#include <drivers/measured_boot/metadata.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
 #include <tools_share/tbbr_oid.h>
 
 #include <plat/common/common_def.h>
@@ -17,39 +17,46 @@
 /* TC specific table with image IDs and metadata. Intentionally not a
  * const struct, some members might set by bootloaders during trusted boot.
  */
-struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
+struct rse_mboot_metadata tc_rse_mboot_metadata[] = {
 	{
 		.id = BL31_IMAGE_ID,
 		.slot = U(9),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_BL31_STRING,
+		.sw_type = MBOOT_BL31_IMAGE_STRING,
 		.pk_oid = BL31_IMAGE_KEY_OID,
 		.lock_measurement = true },
 	{
 		.id = HW_CONFIG_ID,
 		.slot = U(10),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_HW_CONFIG_STRING,
+		.sw_type = MBOOT_HW_CONFIG_STRING,
 		.pk_oid = HW_CONFIG_KEY_OID,
 		.lock_measurement = true },
 	{
 		.id = SOC_FW_CONFIG_ID,
 		.slot = U(11),
 		.signer_id_size = SIGNER_ID_MIN_SIZE,
-		.sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING,
+		.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
 		.pk_oid = SOC_FW_CONFIG_KEY_OID,
 		.lock_measurement = true },
 	{
-		.id = RSS_MBOOT_INVALID_ID }
+		.id = SCP_BL2_IMAGE_ID,
+		.slot = U(12),
+		.signer_id_size = SIGNER_ID_MIN_SIZE,
+		.sw_type = MBOOT_SCP_BL2_IMAGE_STRING,
+		.pk_oid = SCP_BL2_IMAGE_KEY_OID,
+		.lock_measurement = true },
+	{
+		.id = RSE_MBOOT_INVALID_ID }
 };
 
 void bl2_plat_mboot_init(void)
 {
-	/* Initialize the communication channel between AP and RSS */
-	(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
-			     PLAT_RSS_AP_RCV_MHU_BASE);
+	/* Initialize the communication channel between AP and RSE */
+	(void)rse_comms_init(PLAT_RSE_AP_SND_MHU_BASE,
+			     PLAT_RSE_AP_RCV_MHU_BASE);
 
-	rss_measured_boot_init(tc_rss_mboot_metadata);
+	rse_measured_boot_init(tc_rse_mboot_metadata);
 }
 
 void bl2_plat_mboot_finish(void)
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index ff7809d2..801872aa 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <libfdt.h>
 #include <tc_plat.h>
 
+#include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/css/css_mhu_doorbell.h>
@@ -19,25 +20,106 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-static scmi_channel_plat_info_t tc_scmi_plat_info[] = {
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
-		.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
+#ifdef PLATFORM_TEST_TFM_TESTSUITE
+#include <psa/crypto_platform.h>
+#include <psa/crypto_types.h>
+#include <psa/crypto_values.h>
+#endif /* PLATFORM_TEST_TFM_TESTSUITE */
+
+#ifdef PLATFORM_TEST_TFM_TESTSUITE
+/*
+ * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+ * mbedTLS config option) so we need to provide an implementation of
+ * mbedtls_psa_external_get_random(). Provide a fake one, since we do not
+ * actually use any of external RNG and this function is only needed during
+ * the execution of TF-M testsuite during exporting the public part of the
+ * delegated attestation key.
+ */
+psa_status_t mbedtls_psa_external_get_random(
+			mbedtls_psa_external_random_context_t *context,
+			uint8_t *output, size_t output_size,
+			size_t *output_length)
+{
+	for (size_t i = 0U; i < output_size; i++) {
+		output[i] = (uint8_t)(read_cntpct_el0() & 0xFFU);
 	}
+
+	*output_length = output_size;
+
+	return PSA_SUCCESS;
+}
+#endif /* PLATFORM_TEST_TFM_TESTSUITE */
+
+#if TARGET_PLATFORM <= 2
+static scmi_channel_plat_info_t tc_scmi_plat_info = {
+	.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+	.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+	.db_preserve_mask = 0xfffffffe,
+	.db_modify_mask = 0x1,
+	.ring_doorbell = &mhuv2_ring_doorbell,
+};
+#elif TARGET_PLATFORM >= 3
+static scmi_channel_plat_info_t tc_scmi_plat_info = {
+	.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+	.db_reg_addr = PLAT_CSS_MHU_BASE + MHU_V3_SENDER_REG_SET(0),
+	.db_preserve_mask = 0xfffffffe,
+	.db_modify_mask = 0x1,
+	.ring_doorbell = &mhu_ring_doorbell,
 };
+#endif
+
+#if TARGET_PLATFORM == 3
+static void enable_ns_mcn_pmu(void)
+{
+	/*
+	 * Enable non-secure access to MCN PMU registers
+	 */
+	for (int i = 0; i < MCN_INSTANCES; i++) {
+		uintptr_t mcn_scr = MCN_MICROARCH_BASE_ADDR + MCN_SCR_OFFSET +
+			(i * MCN_ADDRESS_SPACE_SIZE);
+		mmio_setbits_32(mcn_scr, 1 << MCN_SCR_PMU_BIT);
+	}
+}
+
+static void set_mcn_slc_alloc_mode(void)
+{
+	/*
+	 * SLC WRALLOCMODE and RDALLOCMODE are configured by default to
+	 * 0b01 (always alloc), configure both to 0b10 (use bus signal
+	 * attribute from interface).
+	 */
+	for (int i = 0; i < MCN_INSTANCES; i++) {
+		uintptr_t slccfg_ctl_ns = MCN_MPAM_NS_BASE_ADDR +
+			(i * MCN_ADDRESS_SPACE_SIZE) + MPAM_SLCCFG_CTL_OFFSET;
+		uintptr_t slccfg_ctl_s = MCN_MPAM_S_BASE_ADDR +
+			(i * MCN_ADDRESS_SPACE_SIZE) + MPAM_SLCCFG_CTL_OFFSET;
+
+		mmio_clrsetbits_32(slccfg_ctl_ns,
+				   (SLC_RDALLOCMODE_MASK | SLC_WRALLOCMODE_MASK),
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_RDALLOCMODE_SHIFT) |
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_WRALLOCMODE_SHIFT));
+		mmio_clrsetbits_32(slccfg_ctl_s,
+				   (SLC_RDALLOCMODE_MASK | SLC_WRALLOCMODE_MASK),
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_RDALLOCMODE_SHIFT) |
+				   (SLC_ALLOC_BUS_SIGNAL_ATTR << SLC_WRALLOCMODE_SHIFT));
+	}
+}
+#endif
 
 void bl31_platform_setup(void)
 {
 	tc_bl31_common_platform_setup();
+#if TARGET_PLATFORM == 3
+	enable_ns_mcn_pmu();
+	set_mcn_slc_alloc_mode();
+	plat_arm_ni_setup(NCI_BASE_ADDR);
+#endif
 }
 
-scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
+scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id __unused)
 {
 
-	return &tc_scmi_plat_info[channel_id];
+	return &tc_scmi_plat_info;
 
 }
 
@@ -104,10 +186,10 @@ void __init bl31_plat_arch_setup(void)
 #if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
 void tc_bl31_plat_runtime_setup(void)
 {
-	arm_bl31_plat_runtime_setup();
-
 	/* Start secure watchdog timer. */
 	plat_arm_secure_wdt_start();
+
+	arm_bl31_plat_runtime_setup();
 }
 
 void bl31_plat_runtime_setup(void)
diff --git a/plat/arm/board/tc/tc_common_dpe.c b/plat/arm/board/tc/tc_common_dpe.c
new file mode 100644
index 00000000..72ac6730
--- /dev/null
+++ b/plat/arm/board/tc/tc_common_dpe.c
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/desc_image_load.h>
+#include <drivers/measured_boot/rse/dice_prot_env.h>
+
+extern struct dpe_metadata tc_dpe_metadata[];
+
+int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
+{
+	int err;
+
+	/* Calculate image hash and record it in the DPE service in RSE. */
+	err = dpe_measure_and_record(tc_dpe_metadata,
+				     image_data->image_base,
+				     image_data->image_size,
+				     image_id);
+	if (err != 0) {
+		ERROR("%s%s image id %u (%i)\n",
+		      "Failed to ", "record in DPE", image_id, err);
+	}
+
+	return err;
+}
+
+int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
+{
+	return dpe_set_signer_id(tc_dpe_metadata, pk_oid, pk_ptr, pk_len);
+}
diff --git a/plat/arm/board/tc/tc_common_measured_boot.c b/plat/arm/board/tc/tc_common_measured_boot.c
index 925a4114..6b8d41ac 100644
--- a/plat/arm/board/tc/tc_common_measured_boot.c
+++ b/plat/arm/board/tc/tc_common_measured_boot.c
@@ -8,22 +8,22 @@
 #include <stdint.h>
 
 #include <common/desc_image_load.h>
-#include <drivers/measured_boot/rss/rss_measured_boot.h>
+#include <drivers/measured_boot/rse/rse_measured_boot.h>
 
-extern struct rss_mboot_metadata tc_rss_mboot_metadata[];
+extern struct rse_mboot_metadata tc_rse_mboot_metadata[];
 
 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 {
 	int err;
 
-	/* Calculate image hash and record data in RSS */
-	err = rss_mboot_measure_and_record(tc_rss_mboot_metadata,
+	/* Calculate image hash and record data in RSE */
+	err = rse_mboot_measure_and_record(tc_rse_mboot_metadata,
 					   image_data->image_base,
 					   image_data->image_size,
 					   image_id);
 	if (err != 0) {
 		ERROR("%s%s image id %u (%i)\n",
-		      "Failed to ", "record in RSS", image_id, err);
+		      "Failed to ", "record in RSE", image_id, err);
 	}
 
 	return err;
@@ -31,6 +31,6 @@ int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
 
 int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
 {
-	return rss_mboot_set_signer_id(tc_rss_mboot_metadata, pk_oid, pk_ptr,
+	return rse_mboot_set_signer_id(tc_rse_mboot_metadata, pk_oid, pk_ptr,
 				       pk_len);
 }
diff --git a/plat/arm/board/tc/tc_dpe.h b/plat/arm/board/tc/tc_dpe.h
new file mode 100644
index 00000000..3e1af5a8
--- /dev/null
+++ b/plat/arm/board/tc/tc_dpe.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TC_DPE_H
+#define TC_DPE_H
+
+/*
+ * The certificate structure on the TC platform:
+ *   - The arrows indicate the parent/child relationships (who loads who).
+ *   - The boxes indicate the certificates.
+ *
+ *                                                                  AP FW Cert.
+ *                                                      +--------------------------------+
+ *                                                      |                                |
+ *                             Plat Cert.               |                +->SPx          |           Hyper Cert.
+ *                     +--------------------------+     |                +->SP1          |     +--------------------+
+ *     RoT Cert.       |                          |     |                +->TOS_FW_CONF  |     |                    |
+ *  +------------+     |      +->SCP_BL1    +-----+-----+-->FW_CONF      +->AP_BL32      |     |     +->PVMFW       |
+ *  |            |     |      |             |     |     |                |               |     |     |              |
+ *  | RSE_BL1_2--+-----+-->RSE_BL2------->AP_BL1--+-----+------------->AP_BL2------------+-----+-->AP_BL33          |
+ *  |            |     |      |             |     |     |                |               |     |     |              |
+ *  +------------+     |      +->RSE_S      +-----+-----+-->TB_FW_CONF   +->AP_BL31      |     |     +->HYPERVISOR  |
+ *                     |      +->RSE_NS           |     |                +->SCP_BL2      |     |                    |
+ *                     |                          |     |                +->HW_CONF      |     |                    |
+ *                     +--------------------------+     |                +---------------+-----+-->NT_FW_CONF       |
+ *                                                      |                                |     |                    |
+ *                                                      +--------------------------------+     +--------------------+
+ */
+
+#define DPE_AP_FW_CERT_ID		0x300 /* Includes: FW_CONF - SP1 */
+#define DPE_HYPERVISOR_CERT_ID		0x400 /* Includes: AP_BL33 - PVMFW */
+
+/* Common definition */
+#define DPE_CERT_ID_SAME_AS_PARENT	0xFFFFFFFF
+
+/*
+ * Target Locality:
+ *    The goal is to specify that a certain component is expected to run and
+ *    thereby send DPE commands from a given security domain. RSE is capable of
+ *    of distinguishing the client's locality based on the MHU channel used for
+ *    communication.
+ *    Defines here must match with RSE side:
+ */
+#define LOCALITY_NONE		-1
+/* #define LOCALITY_RSE_S	0 */  /* Not applicable on AP side */
+/* #define LOCALITY_RSE_NS	1 */  /* Not applicable on AP side */
+#define LOCALITY_AP_S		 2
+#define LOCALITY_AP_NS		 3
+
+#endif /* TC_DPE_H */
diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c
index 766bfb57..fed14f7d 100644
--- a/plat/arm/board/tc/tc_plat.c
+++ b/plat/arm/board/tc/tc_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,8 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/ccn.h>
+#include <drivers/arm/css/sds.h>
+#include <lib/utils_def.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <drivers/arm/sbsa.h>
@@ -28,6 +30,7 @@
 #if IMAGE_BL1
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
+	TC_MAP_NS_DRAM1,
 	TC_FLASH0_RO,
 	TC_MAP_DEVICE,
 	{0}
@@ -159,3 +162,15 @@ void plat_arm_secure_wdt_refresh(void)
 {
 	sbsa_wdog_refresh(SBSA_SECURE_WDOG_REFRESH_BASE);
 }
+
+static sds_region_desc_t tc_sds_regions[] = {
+	{ .base = PLAT_ARM_SDS_MEM_BASE },
+	{ .base = PLAT_ARM_RSE_AP_SDS_MEM_BASE },
+};
+
+sds_region_desc_t *plat_sds_get_regions(unsigned int *region_count)
+{
+	*region_count = ARRAY_SIZE(tc_sds_regions);
+
+	return tc_sds_regions;
+}
diff --git a/plat/arm/board/tc/tc_security.c b/plat/arm/board/tc/tc_security.c
index 6a345010..7c7a1a13 100644
--- a/plat/arm/board/tc/tc_security.c
+++ b/plat/arm/board/tc/tc_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,17 +7,21 @@
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
 
+#if (TARGET_PLATFORM <= 2)
 static const arm_tzc_regions_info_t tzc_regions[] = {
 	TC_TZC_REGIONS_DEF,
 	{}
 };
+#endif
 
 /* Initialize the secure environment */
 void plat_arm_security_setup(void)
 {
+#if (TARGET_PLATFORM <= 2)
 	unsigned int i;
 
 	for (i = 0U; i < TZC400_COUNT; i++) {
 		arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
 	}
+#endif
 }
diff --git a/plat/arm/board/tc/tc_topology.c b/plat/arm/board/tc/tc_topology.c
index 9e18da6d..76318738 100644
--- a/plat/arm/board/tc/tc_topology.c
+++ b/plat/arm/board/tc/tc_topology.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <plat/arm/common/plat_arm.h>
 #include <plat/arm/css/common/css_pm.h>
+#include <platform_def.h>
 
 /******************************************************************************
  * The power domain tree descriptor.
@@ -36,6 +37,14 @@ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
 	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
+#if PLATFORM_CORE_COUNT == 14
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x8)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x9)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xA)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xB)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xC)),
+	(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0xD)),
+#endif /* PLATFORM_CORE_COUNT == 14 */
 };
 
 /*******************************************************************************
@@ -56,3 +65,11 @@ unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr)
 	return PLAT_MAX_PE_PER_CPU;
 }
 #endif
+
+/******************************************************************************
+ * Return the cluster ID of current CPU
+ *****************************************************************************/
+unsigned int plat_cluster_id_by_mpidr(u_register_t mpidr)
+{
+	return MPIDR_AFFLVL2_VAL(mpidr);
+}
diff --git a/plat/arm/board/tc/tc_trng.c b/plat/arm/board/tc/tc_trng.c
new file mode 100644
index 00000000..e5ec48a1
--- /dev/null
+++ b/plat/arm/board/tc/tc_trng.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_acle.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <services/trng_svc.h>
+#include <smccc_helpers.h>
+
+DEFINE_SVC_UUID2(_plat_trng_uuid,
+	0x23523c58, 0x7448, 0x4083, 0x9d, 0x16,
+	0xe3, 0xfa, 0xb9, 0xf1, 0x73, 0xbc
+);
+uuid_t plat_trng_uuid;
+
+/* Dummy implementation */
+bool plat_get_entropy(uint64_t *out)
+{
+	*out = 0xABBAEDDAACDCDEAD;
+
+	return true;
+}
+
+void plat_entropy_setup(void)
+{
+	uint64_t dummy;
+
+	plat_trng_uuid = _plat_trng_uuid;
+
+	/* Initialise the entropy source and trigger RNG generation */
+	plat_get_entropy(&dummy);
+}
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index feff6913..f043f59d 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,9 @@
 #include <common/debug.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
+#if TRANSFER_LIST
+#include <lib/transfer_list.h>
+#endif
 #include <lib/utils.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/arm/common/plat_arm.h>
@@ -61,6 +64,10 @@ static meminfo_t bl1_tzram_layout;
 /* Boolean variable to hold condition whether firmware update needed or not */
 static bool is_fwu_needed;
 
+#if TRANSFER_LIST
+static struct transfer_list_header *secure_tl;
+#endif
+
 struct meminfo *bl1_plat_sec_mem_layout(void)
 {
 	return &bl1_tzram_layout;
@@ -144,9 +151,13 @@ void bl1_plat_arch_setup(void)
  */
 void arm_bl1_platform_setup(void)
 {
-	const struct dyn_cfg_dtb_info_t *fw_config_info;
+	const struct dyn_cfg_dtb_info_t *config_info __unused;
+	uint32_t fw_config_max_size __unused;
+	image_info_t config_image_info __unused;
+	struct transfer_list_entry *te __unused;
+
 	image_desc_t *desc;
-	uint32_t fw_config_max_size;
+
 	int err = -1;
 
 	/* Initialise the IO layer and register platform IO devices */
@@ -159,6 +170,37 @@ void arm_bl1_platform_setup(void)
 		return;
 	}
 
+#if TRANSFER_LIST
+	secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
+				       PLAT_ARM_FW_HANDOFF_SIZE);
+
+	if (secure_tl == NULL) {
+		ERROR("Secure transfer list initialisation failed!\n");
+		panic();
+	}
+
+	te = transfer_list_add(secure_tl, TL_TAG_TB_FW_CONFIG,
+			       ARM_TB_FW_CONFIG_MAX_SIZE, NULL);
+	assert(te != NULL);
+
+	/*
+	 * Set the load address of TB_FW_CONFIG in the data section of the TE just
+	 * allocated in the secure transfer list.
+	 */
+	SET_PARAM_HEAD(&config_image_info, PARAM_IMAGE_BINARY, VERSION_2, 0);
+	config_image_info.image_base = (uintptr_t)transfer_list_entry_data(te);
+	config_image_info.image_max_size = te->data_size;
+
+	VERBOSE("FCONF: Loading config with image ID: %u\n", TB_FW_CONFIG_ID);
+	err = load_auth_image(TB_FW_CONFIG_ID, &config_image_info);
+	if (err != 0) {
+		VERBOSE("Failed to load config %u\n", TB_FW_CONFIG_ID);
+		plat_error_handler(err);
+	}
+
+	transfer_list_update_checksum(secure_tl);
+	fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te));
+#else
 	/* Set global DTB info for fixed fw_config information */
 	fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
 	set_config_info(ARM_FW_CONFIG_BASE, ~0UL, fw_config_max_size, FW_CONFIG_ID);
@@ -174,13 +216,14 @@ void arm_bl1_platform_setup(void)
 	 * FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing
 	 * is successful then load TB_FW_CONFIG device tree.
 	 */
-	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
-	if (fw_config_info != NULL) {
-		err = fconf_populate_dtb_registry(fw_config_info->config_addr);
+	config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+	if (config_info != NULL) {
+		err = fconf_populate_dtb_registry(config_info->config_addr);
 		if (err < 0) {
 			ERROR("Parsing of FW_CONFIG failed %d\n", err);
 			plat_error_handler(err);
 		}
+
 		/* load TB_FW_CONFIG */
 		err = fconf_load_config(TB_FW_CONFIG_ID);
 		if (err < 0) {
@@ -191,11 +234,17 @@ void arm_bl1_platform_setup(void)
 		ERROR("Invalid FW_CONFIG address\n");
 		plat_error_handler(err);
 	}
+#endif /* TRANSFER_LIST */
 
-	/* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
 	desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+
+#if TRANSFER_LIST
+	transfer_list_set_handoff_args(secure_tl, &desc->ep_info);
+#else
+	/* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
 	assert(desc != NULL);
-	desc->ep_info.args.arg0 = fw_config_info->config_addr;
+	desc->ep_info.args.arg0 = config_info->config_addr;
+#endif /* TRANSFER_LIST */
 
 #if CRYPTO_SUPPORT
 	/* Share the Mbed TLS heap info with other images */
@@ -250,3 +299,32 @@ unsigned int bl1_plat_get_next_image_id(void)
 {
 	return  is_fwu_needed ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID;
 }
+
+// Use the default implementation of this function when Firmware Handoff is
+// disabled to avoid duplicating its logic.
+#if TRANSFER_LIST
+int bl1_plat_handle_post_image_load(unsigned int image_id)
+{
+	image_desc_t *image_desc __unused;
+
+	assert(image_id == BL2_IMAGE_ID);
+	struct transfer_list_entry *te;
+
+	/* Convey this information to BL2 via its TL. */
+	te = transfer_list_add(secure_tl, TL_TAG_SRAM_LAYOUT64,
+			       sizeof(meminfo_t), NULL);
+	assert(te != NULL);
+
+	bl1_plat_calc_bl2_layout(&bl1_tzram_layout,
+				 (meminfo_t *)transfer_list_entry_data(te));
+
+	transfer_list_update_checksum(secure_tl);
+
+	/**
+	 * Before exiting make sure the contents of the TL are flushed in case there's no
+	 * support for hardware cache coherency.
+	 */
+	flush_dcache_range((uintptr_t)secure_tl, secure_tl->size);
+	return 0;
+}
+#endif /* TRANSFER_LIST*/
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index 01e0db0b..869830d4 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,8 @@
 
 #include <drivers/generic_delay_timer.h>
 #include <drivers/partition/partition.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
@@ -64,6 +66,43 @@ void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
 	generic_delay_timer_init();
 }
 
+#if ARM_FW_CONFIG_LOAD_ENABLE
+/*************************************************************************************
+ * FW CONFIG load function for BL2 when RESET_TO_BL2=1 && ARM_FW_CONFIG_LOAD_ENABLE=1
+ *************************************************************************************/
+void arm_bl2_el3_plat_config_load(void)
+{
+	int ret;
+	const struct dyn_cfg_dtb_info_t *fw_config_info;
+
+	/* Set global DTB info for fixed fw_config information */
+	set_config_info(PLAT_FW_CONFIG_BASE, ~0UL, PLAT_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID);
+
+	/* Fill the device tree information struct with the info from the config dtb */
+	ret = fconf_load_config(FW_CONFIG_ID);
+	if (ret < 0) {
+		ERROR("Loading of FW_CONFIG failed %d\n", ret);
+		plat_error_handler(ret);
+	}
+
+	/*
+	 * FW_CONFIG loaded successfully. Check the FW_CONFIG device tree parsing
+	 * is successful.
+	 */
+	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
+	if (fw_config_info == NULL) {
+		ret = -1;
+		ERROR("Invalid FW_CONFIG address\n");
+		plat_error_handler(ret);
+	}
+	ret = fconf_populate_dtb_registry(fw_config_info->config_addr);
+	if (ret < 0) {
+		ERROR("Parsing of FW_CONFIG failed %d\n", ret);
+		plat_error_handler(ret);
+	}
+}
+#endif /* ARM_FW_CONFIG_LOAD_ENABLE */
+
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
  * moment this is only initializes the mmu in a quick and dirty way.
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 3e8109e6..90ee70cc 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,13 +19,13 @@
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
 #include <lib/gpt_rme/gpt_rme.h>
+#if TRANSFER_LIST
+#include <lib/transfer_list.h>
+#endif
 #ifdef SPD_opteed
 #include <lib/optee_utils.h>
 #endif
 #include <lib/utils.h>
-#if ENABLE_RME
-#include <plat/arm/common/arm_pas_def.h>
-#endif
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
@@ -33,13 +33,18 @@
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
 
 /* Base address of fw_config received from BL1 */
-static uintptr_t config_base;
+static uintptr_t config_base __unused;
 
 /*
  * Check that BL2_BASE is above ARM_FW_CONFIG_LIMIT. This reserved page is
  * for `meminfo_t` data structure and fw_configs passed from BL1.
  */
+#if TRANSFER_LIST
+CASSERT(BL2_BASE >= PLAT_ARM_EL3_FW_HANDOFF_BASE + PLAT_ARM_FW_HANDOFF_SIZE,
+	assert_bl2_base_overflows);
+#elif !RESET_TO_BL2
 CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
+#endif /* TRANSFER_LIST */
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak bl2_early_platform_setup2
@@ -61,6 +66,9 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
 
 #pragma weak arm_bl2_plat_handle_post_image_load
 
+static struct transfer_list_header *secure_tl __unused;
+static struct transfer_list_header *ns_tl __unused;
+
 /*******************************************************************************
  * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
  * in x0. This memory layout is sitting at the base of the free trusted SRAM.
@@ -69,16 +77,28 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
 void arm_bl2_early_platform_setup(uintptr_t fw_config,
 				  struct meminfo *mem_layout)
 {
+	struct transfer_list_entry *te __unused;
 	int __maybe_unused ret;
 
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
-	/* Setup the BL2 memory layout */
-	bl2_tzram_layout = *mem_layout;
+#if TRANSFER_LIST
+	// TODO: modify the prototype of this function fw_config != bl2_tl
+	secure_tl = (struct transfer_list_header *)fw_config;
 
+	te = transfer_list_find(secure_tl, TL_TAG_SRAM_LAYOUT64);
+	assert(te != NULL);
+
+	bl2_tzram_layout = *(meminfo_t *)transfer_list_entry_data(te);
+	transfer_list_rem(secure_tl, te);
+#else
 	config_base = fw_config;
 
+	/* Setup the BL2 memory layout */
+	bl2_tzram_layout = *mem_layout;
+#endif
+
 	/* Initialise the IO layer and register platform IO devices */
 	plat_arm_io_setup();
 
@@ -106,7 +126,25 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_
  */
 void bl2_plat_preload_setup(void)
 {
+#if TRANSFER_LIST
+/* Assume the secure TL hasn't been initialised if BL2 is running at EL3. */
+#if RESET_TO_BL2
+	secure_tl = transfer_list_init((void *)PLAT_ARM_EL3_FW_HANDOFF_BASE,
+				       PLAT_ARM_FW_HANDOFF_SIZE);
+
+	if (secure_tl == NULL) {
+		ERROR("Secure transfer list initialisation failed!\n");
+		panic();
+	}
+#endif
+
+	arm_transfer_list_dyn_cfg_init(secure_tl);
+#else
+#if ARM_FW_CONFIG_LOAD_ENABLE
+	arm_bl2_el3_plat_config_load();
+#endif /* ARM_FW_CONFIG_LOAD_ENABLE */
 	arm_bl2_dyn_cfg_init();
+#endif
 
 #if ARM_GPT_SUPPORT && !PSA_FWU_SUPPORT
 	/* Always use the FIP from bank 0 */
@@ -134,48 +172,6 @@ void bl2_platform_setup(void)
 	arm_bl2_platform_setup();
 }
 
-#if ENABLE_RME
-static void arm_bl2_plat_gpt_setup(void)
-{
-	/*
-	 * The GPT library might modify the gpt regions structure to optimize
-	 * the layout, so the array cannot be constant.
-	 */
-	pas_region_t pas_regions[] = {
-		ARM_PAS_KERNEL,
-		ARM_PAS_SECURE,
-		ARM_PAS_REALM,
-		ARM_PAS_EL3_DRAM,
-		ARM_PAS_GPTS,
-		ARM_PAS_KERNEL_1
-	};
-
-	/* Initialize entire protected space to GPT_GPI_ANY. */
-	if (gpt_init_l0_tables(GPCCR_PPS_64GB, ARM_L0_GPT_ADDR_BASE,
-		ARM_L0_GPT_SIZE) < 0) {
-		ERROR("gpt_init_l0_tables() failed!\n");
-		panic();
-	}
-
-	/* Carve out defined PAS ranges. */
-	if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
-				   ARM_L1_GPT_ADDR_BASE,
-				   ARM_L1_GPT_SIZE,
-				   pas_regions,
-				   (unsigned int)(sizeof(pas_regions) /
-				   sizeof(pas_region_t))) < 0) {
-		ERROR("gpt_init_pas_l1_tables() failed!\n");
-		panic();
-	}
-
-	INFO("Enabling Granule Protection Checks\n");
-	if (gpt_enable() < 0) {
-		ERROR("gpt_enable() failed!\n");
-		panic();
-	}
-}
-#endif /* ENABLE_RME */
-
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here.
  * When RME is enabled the secure environment is initialised before
@@ -196,11 +192,13 @@ void arm_bl2_plat_arch_setup(void)
 		ARM_MAP_ROMLIB_CODE,
 		ARM_MAP_ROMLIB_DATA,
 #endif
+#if !TRANSFER_LIST
 		ARM_MAP_BL_CONFIG_REGION,
+#endif /* TRANSFER_LIST */
 #if ENABLE_RME
 		ARM_MAP_L0_GPT_REGION,
 #endif
-		{0}
+		{ 0 }
 	};
 
 #if ENABLE_RME
@@ -212,11 +210,11 @@ void arm_bl2_plat_arch_setup(void)
 #ifdef __aarch64__
 #if ENABLE_RME
 	/* BL2 runs in EL3 when RME enabled. */
-	assert(get_armv9_2_feat_rme_support() != 0U);
+	assert(is_feat_rme_present());
 	enable_mmu_el3(0);
 
 	/* Initialise and enable granule protection after MMU. */
-	arm_bl2_plat_gpt_setup();
+	arm_gpt_setup();
 #else
 	enable_mmu_el1(0);
 #endif
@@ -229,10 +227,17 @@ void arm_bl2_plat_arch_setup(void)
 
 void bl2_plat_arch_setup(void)
 {
-	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
-
+	const struct dyn_cfg_dtb_info_t *tb_fw_config_info __unused;
+	struct transfer_list_entry *te __unused;
 	arm_bl2_plat_arch_setup();
 
+#if TRANSFER_LIST
+	te = transfer_list_find(secure_tl, TL_TAG_TB_FW_CONFIG);
+	assert(te != NULL);
+
+	fconf_populate("TB_FW", (uintptr_t)transfer_list_entry_data(te));
+	transfer_list_rem(secure_tl, te);
+#else
 	/* Fill the properties struct with the info from the config dtb */
 	fconf_populate("FW_CONFIG", config_base);
 
@@ -241,6 +246,7 @@ void bl2_plat_arch_setup(void)
 	assert(tb_fw_config_info != NULL);
 
 	fconf_populate("TB_FW", tb_fw_config_info->config_addr);
+#endif
 }
 
 int arm_bl2_handle_post_image_load(unsigned int image_id)
@@ -310,5 +316,23 @@ int arm_bl2_plat_handle_post_image_load(unsigned int image_id)
 		return 0;
 	}
 #endif
+
+#if TRANSFER_LIST
+	if (image_id == HW_CONFIG_ID) {
+		/* Refresh the now stale checksum following loading of HW_CONFIG into the TL. */
+		transfer_list_update_checksum(secure_tl);
+	}
+#endif /* TRANSFER_LIST */
+
 	return arm_bl2_handle_post_image_load(image_id);
 }
+
+void arm_bl2_setup_next_ep_info(bl_mem_params_node_t *next_param_node)
+{
+	entry_point_info_t *ep __unused;
+	ep = transfer_list_set_handoff_args(secure_tl,
+					    &next_param_node->ep_info);
+	assert(ep != NULL);
+
+	arm_transfer_list_populate_ep_info(next_param_node, secure_tl);
+}
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 8e90615b..0a8dd372 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,19 +7,27 @@
 #include <assert.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/console.h>
 #include <lib/debugfs.h>
 #include <lib/extensions/ras.h>
+#include <lib/fconf/fconf.h>
 #include <lib/gpt_rme/gpt_rme.h>
 #include <lib/mmio.h>
+#if TRANSFER_LIST
+#include <lib/transfer_list.h>
+#endif
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
+static struct transfer_list_header *secure_tl __unused;
+static struct transfer_list_header *ns_tl __unused;
+
 /*
  * Placeholder variables for copying the arguments that have been passed to
  * BL31 from BL2.
@@ -35,8 +43,12 @@ static entry_point_info_t rmm_image_ep_info;
  * Check that BL31_BASE is above ARM_FW_CONFIG_LIMIT. The reserved page
  * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
  */
+#if TRANSFER_LIST
+CASSERT(BL31_BASE >= PLAT_ARM_EL3_FW_HANDOFF_LIMIT, assert_bl31_base_overflows);
+#else
 CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
-#endif
+#endif /* TRANSFER_LIST */
+#endif /* RESET_TO_BL31 */
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak bl31_early_platform_setup2
@@ -86,7 +98,12 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
 
 	assert(sec_state_is_valid(type));
 	if (type == NON_SECURE) {
+#if TRANSFER_LIST && !RESET_TO_BL31
+		next_image_info = transfer_list_set_handoff_args(
+			ns_tl, &bl33_image_ep_info);
+#else
 		next_image_info = &bl33_image_ep_info;
+#endif
 	}
 #if ENABLE_RME
 	else if (type == REALM) {
@@ -115,6 +132,62 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
  * while creating page tables. BL2 has flushed this information to memory, so
  * we are guaranteed to pick up good data.
  ******************************************************************************/
+#if TRANSFER_LIST
+void __init arm_bl31_early_platform_setup(u_register_t arg0, u_register_t arg1,
+					  u_register_t arg2, u_register_t arg3)
+{
+#if RESET_TO_BL31
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+
+	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+	bl33_image_ep_info.args.arg0 = PLAT_ARM_TRANSFER_LIST_DTB_OFFSET;
+	bl33_image_ep_info.args.arg1 =
+		TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
+	bl33_image_ep_info.args.arg3 = FW_NS_HANDOFF_BASE;
+#else
+	struct transfer_list_entry *te = NULL;
+	struct entry_point_info *ep;
+
+	secure_tl = (struct transfer_list_header *)arg3;
+
+	/*
+	 * Populate the global entry point structures used to execute subsequent
+	 * images.
+	 */
+	while ((te = transfer_list_next(secure_tl, te)) != NULL) {
+		ep = transfer_list_entry_data(te);
+
+		if (te->tag_id == TL_TAG_EXEC_EP_INFO64) {
+			switch (GET_SECURITY_STATE(ep->h.attr)) {
+			case NON_SECURE:
+				bl33_image_ep_info = *ep;
+				break;
+#if ENABLE_RME
+			case REALM:
+				rmm_image_ep_info = *ep;
+				break;
+#endif
+			case SECURE:
+				bl32_image_ep_info = *ep;
+				break;
+			default:
+				ERROR("Unrecognized Image Security State %lu\n",
+				      GET_SECURITY_STATE(ep->h.attr));
+				panic();
+			}
+		}
+	}
+#endif /* RESET_TO_BL31 */
+}
+#else
 void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_config,
 				uintptr_t hw_config, void *plat_params_from_bl2)
 {
@@ -258,11 +331,16 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
 	bl33_image_ep_info.args.arg3 = 0U;
 # endif
 }
+#endif
 
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		u_register_t arg2, u_register_t arg3)
 {
+#if TRANSFER_LIST
+	arm_bl31_early_platform_setup(arg0, arg1, arg2, arg3);
+#else
 	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+#endif
 
 	/*
 	 * Initialize Interconnect for this cluster during cold boot.
@@ -286,6 +364,36 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
  ******************************************************************************/
 void arm_bl31_platform_setup(void)
 {
+	struct transfer_list_entry *te __unused;
+
+#if TRANSFER_LIST && !RESET_TO_BL31
+	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE,
+				   PLAT_ARM_FW_HANDOFF_SIZE);
+
+	if (ns_tl == NULL) {
+		ERROR("Non-secure transfer list initialisation failed!");
+		panic();
+	}
+
+	te = transfer_list_find(secure_tl, TL_TAG_FDT);
+	assert(te != NULL);
+
+	/*
+	 * A pre-existing assumption is that FCONF is unsupported w/ RESET_TO_BL2 and
+	 * RESET_TO_BL31. In the case of RESET_TO_BL31 this makes sense because there
+	 * isn't a prior stage to load the device tree, but the reasoning for RESET_TO_BL2 is
+	 * less clear. For the moment hardware properties that would normally be
+	 * derived from the DT are statically defined.
+	 */
+#if !RESET_TO_BL2
+	fconf_populate("HW_CONFIG", (uintptr_t)transfer_list_entry_data(te));
+#endif
+
+	te = transfer_list_add(ns_tl, TL_TAG_FDT, te->data_size,
+			       transfer_list_entry_data(te));
+	assert(te != NULL);
+#endif /* TRANSFER_LIST */
+
 	/* Initialize the GIC driver, cpu and distributor interfaces */
 	plat_arm_gic_driver_init();
 	plat_arm_gic_init();
@@ -325,15 +433,22 @@ void arm_bl31_platform_setup(void)
 /*******************************************************************************
  * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM
  * standard platforms
- * Perform BL31 platform setup
  ******************************************************************************/
 void arm_bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
-
+	struct transfer_list_entry *te __unused;
 	/* Initialize the runtime console */
 	arm_console_runtime_init();
 
+#if TRANSFER_LIST && !RESET_TO_BL31
+	/*
+	 * We assume BL31 has added all TE's required by BL33 at this stage, ensure
+	 * that data is visible to all observers by performing a flush operation, so
+	 * they can access the updated data even if caching is not enabled.
+	 */
+	flush_dcache_range((uintptr_t)ns_tl, ns_tl->size);
+#endif /* TRANSFER_LIST && !(RESET_TO_BL2 || RESET_TO_BL31) */
+
 #if RECLAIM_INIT_CODE
 	arm_free_init_memory();
 #endif
@@ -431,6 +546,13 @@ void __init arm_bl31_plat_arch_setup(void)
 	enable_mmu_el3(0);
 
 #if ENABLE_RME
+#if RESET_TO_BL31
+	/*  initialize GPT only when RME is enabled. */
+	assert(is_feat_rme_present());
+
+	/* Initialise and enable granule protection after MMU. */
+	arm_gpt_setup();
+#endif /* RESET_TO_BL31 */
 	/*
 	 * Initialise Granule Protection library and enable GPC for the primary
 	 * processor. The tables have already been initialized by a previous BL
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index fc681149..2d4165c4 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,8 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/romlib.h>
+#include <common/par.h>
+#include <lib/extensions/sysreg128.h>
 #include <lib/mmio.h>
 #include <lib/smccc.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
@@ -196,7 +198,8 @@ unsigned int plat_get_syscnt_freq2(void)
  */
 int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
 {
-	uint64_t par, pa;
+	uint64_t pa;
+	sysreg_t par;
 	u_register_t scr_el3;
 
 	/* Doing Non-secure address translation requires SCR_EL3.NS set */
@@ -230,7 +233,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
 		return -1;
 
 	/* Extract Physical Address from PAR */
-	pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT));
+	pa = get_par_el1_pa(par);
 
 	/* Perform NS entry point validation on the physical address */
 	return arm_validate_ns_entrypoint(pa);
@@ -241,3 +244,43 @@ const mmap_region_t *plat_get_addr_mmap(void)
 {
 	return plat_arm_mmap;
 }
+
+#if ENABLE_RME
+void arm_gpt_setup(void)
+{
+	/*
+	 * It is to be noted that any Arm platform that reuses arm_gpt_setup
+	 * must implement plat_arm_get_gpt_info within its platform code
+	 */
+	const arm_gpt_info_t *arm_gpt_info =
+		plat_arm_get_gpt_info();
+
+	if (arm_gpt_info == NULL) {
+		ERROR("arm_gpt_info not initialized!!\n");
+		panic();
+	}
+
+	/* Initialize entire protected space to GPT_GPI_ANY. */
+	if (gpt_init_l0_tables(arm_gpt_info->pps, arm_gpt_info->l0_base,
+		arm_gpt_info->l0_size) < 0) {
+		ERROR("gpt_init_l0_tables() failed!\n");
+		panic();
+	}
+
+	/* Carve out defined PAS ranges. */
+	if (gpt_init_pas_l1_tables(arm_gpt_info->pgs,
+				   arm_gpt_info->l1_base,
+				   arm_gpt_info->l1_size,
+				   arm_gpt_info->pas_region_base,
+				   arm_gpt_info->pas_region_count) < 0) {
+		ERROR("gpt_init_pas_l1_tables() failed!\n");
+		panic();
+	}
+
+	INFO("Enabling Granule Protection Checks\n");
+	if (gpt_enable() < 0) {
+		ERROR("gpt_enable() failed!\n");
+		panic();
+	}
+}
+#endif /* ENABLE_RME */
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index ae0d85da..2fd993c4 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -26,7 +26,7 @@ ifeq (${ARCH}, aarch64)
   else ifeq (${ARM_TSP_RAM_LOCATION}, dram)
     ARM_TSP_RAM_LOCATION_ID = ARM_DRAM_ID
   else
-    $(error "Unsupported ARM_TSP_RAM_LOCATION value")
+    $(error Unsupported ARM_TSP_RAM_LOCATION value)
   endif
 
   # Process flags
@@ -83,7 +83,7 @@ $(eval $(call add_define,ARM_BL31_IN_DRAM))
 # memory. This means we must not run BL31 from TZC-protected DRAM.
 ifeq (${ARM_BL31_IN_DRAM},1)
   ifeq (${ENABLE_RME},1)
-    $(error "BL31 must not run from DRAM on RME-systems. Please set ARM_BL31_IN_DRAM to 0")
+    $(error BL31 must not run from DRAM on RME-systems. Please set ARM_BL31_IN_DRAM to 0)
   endif
 endif
 
@@ -105,25 +105,20 @@ $(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 ifeq (${ARM_LINUX_KERNEL_AS_BL33},1)
   ifneq (${ARCH},aarch64)
     ifneq (${RESET_TO_SP_MIN},1)
-      $(error "ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_SP_MIN=1.")
+      $(error ARM_LINUX_KERNEL_AS_BL33 is only available if RESET_TO_SP_MIN=1.)
     endif
   endif
   ifndef PRELOADED_BL33_BASE
-    $(error "PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
+    $(error PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.)
   endif
   ifeq (${RESET_TO_BL31},1)
     ifndef ARM_PRELOADED_DTB_BASE
-      $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is
-       used with RESET_TO_BL31.")
+      $(error ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used with RESET_TO_BL31.)
     endif
     $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
   endif
 endif
 
-# Use an implementation of SHA-256 with a smaller memory footprint but reduced
-# speed.
-$(eval $(call add_define,MBEDTLS_SHA256_SMALLER))
-
 # Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
 # in the FIP if the platform requires.
 ifneq ($(BL32_EXTRA1),)
@@ -169,6 +164,25 @@ ifneq ($(filter 1,${RESET_TO_BL31} ${RESET_TO_SP_MIN}),)
 	ENABLE_PIE			:=	1
 endif
 
+# On Arm platform, disable ARM_FW_CONFIG_LOAD_ENABLE by default.
+ARM_FW_CONFIG_LOAD_ENABLE		:= 0
+$(eval $(call assert_boolean,ARM_FW_CONFIG_LOAD_ENABLE))
+$(eval $(call add_define,ARM_FW_CONFIG_LOAD_ENABLE))
+
+# In order to enable ARM_FW_CONFIG_LOAD_ENABLE for the Arm platform, the
+# platform should be reset to BL2 (RESET_TO_BL2=1), and FW_CONFIG must be
+# specified.
+ifeq (${ARM_FW_CONFIG_LOAD_ENABLE},1)
+    ifneq (${RESET_TO_BL2},1)
+        $(error RESET_TO_BL2 must be enabled when ARM_FW_CONFIG_LOAD_ENABLE \
+            is enabled)
+    endif
+    ifeq (${FW_CONFIG},)
+        $(error FW_CONFIG must be specified when ARM_FW_CONFIG_LOAD_ENABLE \
+            is enabled)
+    endif
+endif
+
 # Disable GPT parser support, use FIP image by default
 ARM_GPT_SUPPORT			:=	0
 $(eval $(call assert_boolean,ARM_GPT_SUPPORT))
@@ -280,7 +294,7 @@ endif
 ifeq (${JUNO_AARCH32_EL3_RUNTIME},1)
 BL2_SOURCES		+=	plat/arm/common/aarch32/arm_bl2_mem_params_desc.c
 else
-ifneq (${PLAT}, corstone1000)
+ifeq ($(filter $(PLAT), corstone1000 rd1ae),)
 BL2_SOURCES		+=	plat/arm/common/${ARCH}/arm_bl2_mem_params_desc.c
 endif
 endif
@@ -299,6 +313,10 @@ BL31_SOURCES		+=	plat/arm/common/arm_bl31_setup.c		\
 				plat/arm/common/arm_topology.c			\
 				plat/common/plat_psci_common.c
 
+ifeq (${TRANSFER_LIST}, 1)
+	TRANSFER_LIST_SOURCES += plat/arm/common/arm_transfer_list.c
+endif
+
 ifneq ($(filter 1,${ENABLE_PMF} ${ETHOSN_NPU_DRIVER}),)
 ARM_SVC_HANDLER_SRCS :=
 
@@ -361,6 +379,17 @@ ifeq (${DRTM_SUPPORT},1)
 BL31_SOURCES            +=	plat/arm/common/arm_err.c
 endif
 
+ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT} ${DRTM_SUPPORT}),)
+    PLAT_INCLUDES		+=	-Iplat/arm/common	\
+					-Iinclude/drivers/auth/mbedtls
+    # Specify mbed TLS configuration file
+    ifeq (${PSA_CRYPTO},1)
+      MBEDTLS_CONFIG_FILE	?=	"<plat_arm_psa_mbedtls_config.h>"
+    else
+      MBEDTLS_CONFIG_FILE	?=	"<plat_arm_mbedtls_config.h>"
+    endif
+endif
+
 ifneq (${TRUSTED_BOARD_BOOT},0)
 
     # Include common TBB sources
@@ -374,20 +403,37 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
         ifneq (${COT_DESC_IN_DTB},0)
             BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
         else
-            BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_common.c
 	    # Juno has its own TBBR CoT file for BL2
-            ifneq (${PLAT},juno)
-                BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_bl2.c
+            ifeq (${PLAT},juno)
+                BL2_SOURCES	+=	drivers/auth/tbbr/tbbr_cot_common.c
             endif
         endif
     else ifeq (${COT},dualroot)
-        AUTH_SOURCES	+=	drivers/auth/dualroot/cot.c
+        BL1_SOURCES	+=	drivers/auth/dualroot/bl1_cot.c
+        ifneq (${COT_DESC_IN_DTB},0)
+            BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
+        endif
     else ifeq (${COT},cca)
-        AUTH_SOURCES	+=	drivers/auth/cca/cot.c
+        BL1_SOURCES	+=	drivers/auth/cca/bl1_cot.c
+        ifneq (${COT_DESC_IN_DTB},0)
+            BL2_SOURCES	+=	lib/fconf/fconf_cot_getter.c
+        endif
     else
         $(error Unknown chain of trust ${COT})
     endif
 
+    ifeq (${COT_DESC_IN_DTB},0)
+      ifeq (${COT},dualroot)
+        COTDTPATH := fdts/dualroot_cot_descriptors.dtsi
+      else ifeq (${COT},cca)
+        COTDTPATH := fdts/cca_cot_descriptors.dtsi
+      else ifeq (${COT},tbbr)
+        ifneq (${PLAT},juno)
+          COTDTPATH := fdts/tbbr_cot_descriptors.dtsi
+        endif
+      endif
+    endif
+
     BL1_SOURCES		+=	${AUTH_SOURCES}					\
 				bl1/tbbr/tbbr_img_desc.c			\
 				plat/arm/common/arm_bl1_fwu.c			\
@@ -412,10 +458,6 @@ ifneq ($(filter 1,${MEASURED_BOOT} ${DRTM_SUPPORT}),)
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
 
-    ifneq (${MBOOT_EL_HASH_ALG}, sha256)
-        $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
-    endif
-
     ifeq (${MEASURED_BOOT},1)
          BL1_SOURCES		+= 	${EVENT_LOG_SOURCES}
          BL2_SOURCES		+= 	${EVENT_LOG_SOURCES}
@@ -442,6 +484,27 @@ endif
 
 ifeq (${RECLAIM_INIT_CODE}, 1)
     ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
-        $(error "To reclaim init code xlat tables v2 must be used")
+        $(error To reclaim init code xlat tables v2 must be used)
     endif
 endif
+
+ifneq ($(COTDTPATH),)
+        cot-dt-defines = IMAGE_BL2 $(BL2_DEFINES) $(PLAT_BL_COMMON_DEFINES)
+        cot-dt-include-dirs = $(BL2_INCLUDE_DIRS) $(PLAT_BL_COMMON_INCLUDE_DIRS)
+
+        cot-dt-cpp-flags  = $(cot-dt-defines:%=-D%)
+        cot-dt-cpp-flags += $(cot-dt-include-dirs:%=-I%)
+
+        cot-dt-cpp-flags += $(BL2_CPPFLAGS) $(PLAT_BL_COMMON_CPPFLAGS)
+        cot-dt-cpp-flags += $(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH))
+        cot-dt-cpp-flags += -c -x assembler-with-cpp -E -P -o $@ $<
+
+        $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.dts): $(COTDTPATH) | $$(@D)/
+		$(q)$($(ARCH)-cpp) $(cot-dt-cpp-flags)
+
+        $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.c): $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.dts) | $$(@D)/
+		$(if $(host-poetry),$(q)poetry -q install)
+		$(q)$(if $(host-poetry),poetry run )cot-dt2c convert-to-c $< $@
+
+        BL2_SOURCES += $(BUILD_PLAT)/$(COTDTPATH:.dtsi=.c)
+endif
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 99e28098..18ab5be8 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -120,6 +120,7 @@ void arm_bl1_set_mbedtls_heap(void)
 }
 #endif /* CRYPTO_SUPPORT */
 
+#if IMAGE_BL2
 /*
  * BL2 utility function to initialize dynamic configuration specified by
  * FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if
@@ -229,3 +230,4 @@ void arm_bl2_dyn_cfg_init(void)
 		panic();
 	}
 }
+#endif /* IMAGE_BL2 */
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 5dc11151..d13be993 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -124,6 +124,150 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
 }
 
 #if MEASURED_BOOT
+#if DICE_PROTECTION_ENVIRONMENT
+
+#include <common/desc_image_load.h>
+
+#define DTB_PROP_DPE_CTX_HANDLE		"dpe_ctx_handle"
+
+static int arm_set_dpe_context_handle(uintptr_t config_base,
+				      int *ctx_handle)
+{
+	/* As libfdt uses void *, we can't avoid this cast */
+	void *dtb = (void *)config_base;
+	const char *compatible = "arm,dpe_ctx_handle";
+	int err, node;
+
+	/*
+	 * Verify that the DTB is valid, before attempting to write to it,
+	 * and get the DTB root node.
+	 */
+
+	/* Check if the pointer to DT is correct */
+	err = fdt_check_header(dtb);
+	if (err < 0) {
+		WARN("Invalid DTB file passed\n");
+		return err;
+	}
+
+	/* Assert the node offset point to compatible property */
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
+	if (node < 0) {
+		WARN("The compatible property '%s' not%s", compatible,
+			" found in the config\n");
+		return node;
+	}
+
+	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
+
+	err = fdtw_write_inplace_cells(dtb, node,
+		DTB_PROP_DPE_CTX_HANDLE, 1, ctx_handle);
+	if (err < 0) {
+		ERROR("%sDTB property '%s'\n",
+			"Unable to write ", DTB_PROP_DPE_CTX_HANDLE);
+	} else {
+		/*
+		 * Ensure that the info written to the DTB is visible
+		 * to other images.
+		 */
+		flush_dcache_range(config_base, fdt_totalsize(dtb));
+	}
+
+	return err;
+}
+
+/*
+ * This function writes the DPE context handle value to the NT_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+int arm_set_nt_fw_info(int *ctx_handle)
+{
+	uintptr_t config_base;
+	const bl_mem_params_node_t *cfg_mem_params;
+
+	/* Get the config load address and size from NT_FW_CONFIG */
+	cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
+	assert(cfg_mem_params != NULL);
+
+	config_base = cfg_mem_params->image_info.image_base;
+
+	/* Write the context handle value in the DTB */
+	return arm_set_dpe_context_handle(config_base, ctx_handle);
+}
+
+/*
+ * This function writes the DPE context handle value to the TB_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL1.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+int arm_set_tb_fw_info(int *ctx_handle)
+{
+	/*
+	 * Read tb_fw_config device tree for Event Log properties
+	 * and write the Event Log address and its size in the DTB
+	 */
+	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
+	uintptr_t tb_fw_cfg_dtb;
+
+	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+	assert(tb_fw_config_info != NULL);
+
+	tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
+
+	/* Write the context handle value in the DTB */
+	return arm_set_dpe_context_handle(tb_fw_cfg_dtb, ctx_handle);
+}
+
+/*
+ * This function reads the initial DPE context handle from TB_FW_CONFIG DTB.
+ *
+ * This function is supposed to be called only by BL2.
+ *
+ * Returns:
+ *	0 = success
+ *    < 0 = error
+ */
+
+int arm_get_tb_fw_info(int *ctx_handle)
+{
+	/* As libfdt uses void *, we can't avoid this cast */
+	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
+	int node, rc;
+
+	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
+	assert(tb_fw_config_info != NULL);
+
+	void *dtb = (void *)tb_fw_config_info->config_addr;
+	const char *compatible = "arm,dpe_ctx_handle";
+
+	/* Assert the node offset point to compatible property */
+	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
+	if (node < 0) {
+		WARN("The compatible property '%s'%s", compatible,
+		     " not specified in TB_FW config.\n");
+		return node;
+	}
+
+	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
+
+	rc = fdt_read_uint32(dtb, node, DTB_PROP_DPE_CTX_HANDLE, (uint32_t *)ctx_handle);
+	if (rc != 0) {
+		ERROR("%s%s", DTB_PROP_DPE_CTX_HANDLE,
+		      " not specified in TB_FW config.\n");
+	}
+
+	return rc;
+}
+#else
 /*
  * Write the Event Log address and its size in the DTB.
  *
@@ -393,4 +537,5 @@ int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
 
 	return rc;
 }
+#endif /* DICE_PROTECTION_ENVIRONMENT */
 #endif /* MEASURED_BOOT */
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index c411c6cb..25252666 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,7 +17,10 @@
 #pragma weak plat_get_bl_image_load_info
 #pragma weak plat_get_next_bl_params
 
-static bl_params_t *next_bl_params_cpy_ptr;
+#if TRANSFER_LIST
+static bl_params_t next_bl_params_cpy;
+#endif
+bl_params_t *next_bl_params_cpy_ptr;
 
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
@@ -96,9 +99,15 @@ struct bl_load_info *plat_get_bl_image_load_info(void)
  ******************************************************************************/
 struct bl_params *arm_get_next_bl_params(void)
 {
-	bl_mem_params_node_t *bl2_mem_params_descs_cpy
-			= (bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE;
-	const bl_params_t *next_bl_params;
+	bl_mem_params_node_t *bl2_mem_params_descs_cpy __unused;
+	const bl_params_t *next_bl_params __unused;
+
+#if TRANSFER_LIST
+	next_bl_params_cpy_ptr = &next_bl_params_cpy;
+	SET_PARAM_HEAD(next_bl_params_cpy_ptr, PARAM_BL_PARAMS, VERSION_2, 0U);
+#else
+	bl2_mem_params_descs_cpy =
+		(bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE;
 
 	next_bl_params_cpy_ptr =
 		(bl_params_t *)(ARM_BL2_MEM_DESC_BASE +
@@ -127,6 +136,7 @@ struct bl_params *arm_get_next_bl_params(void)
 						(sizeof(bl_params_t)));
 
 	populate_next_bl_params_config(next_bl_params_cpy_ptr);
+#endif /* TRANSFER_LIST */
 
 	return next_bl_params_cpy_ptr;
 }
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index 19ee1b0b..5a3d27ab 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -124,6 +124,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
 	const struct plat_io_policy *policy;
 
 	policy = FCONF_GET_PROPERTY(arm, io_policies, image_id);
+	assert(policy->check != NULL);
 	result = policy->check(policy->image_spec);
 	if (result == 0) {
 		*image_spec = policy->image_spec;
diff --git a/plat/arm/common/arm_ni.c b/plat/arm/common/arm_ni.c
new file mode 100644
index 00000000..b3ad8b38
--- /dev/null
+++ b/plat/arm/common/arm_ni.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+#define NI_CHILD_NODE_COUNT			4
+#define NI_CHILD_POINTERS_START			8
+
+#define NI_PMU_SECURE_CTRL			0x100
+#define NI_PMU_SECURE_EVENT_OBSERVATION		0x108
+#define NI_PMU_DEBUG_ENABLE			0x110
+#define NI_COMP_NUM_SUBFEATURES			0x100
+#define NI_COMP_SUBFEATURE_TYPE_START		0x108
+#define NI_COMP_SUBFEATURE_SECURE_CTRL_START	0x308
+
+#define SECURE_OVERRIDE_DEFAULT			BIT(0)
+#define SECURE_EVENT_ENABLE			BIT(2)
+#define NA_EVENT_ENABLE				BIT(3)
+#define PMU_ENABLE				BIT(0)
+
+#define NI_NODE_MASK				0x0000ffff
+#define NI_NODE_TYPE(node_info)			(node_info & NI_NODE_MASK)
+#define NI_CHILD_POINTER(i)			(NI_CHILD_POINTERS_START + (i * 4))
+#define NI_COMP_SUBFEATURE_TYPE(i)		(NI_COMP_SUBFEATURE_TYPE_START + (i * 8))
+#define NI_COMP_SUBFEATURE_SECURE_CTRL(i)	(NI_COMP_SUBFEATURE_SECURE_CTRL_START + (i * 8))
+
+#define NI_PERIPHERAL_ID0			0xfe0
+#define NI_PIDR0_PART_MASK			0xff
+#define NI_PERIPHERAL_ID1			0xfe4
+#define NI_PIDR1_PART_MASK			0xf
+#define NI_PIDR1_PART_SHIFT			8
+
+enum ni_part {
+	NI_700 = 0x43b,
+	NI_710AE = 0x43d,
+	NI_TOWER = 0x43f,
+};
+
+enum ni_node_type {
+	NI_INVALID_NODE = 0,
+	NI_VOLTAGE_DOMAIN  = 1,
+	NI_POWER_DOMAIN = 2,
+	NI_CLOCK_DOMAIN = 3,
+	NI_ASNI = 4,
+	NI_AMNI = 5,
+	NI_PMU = 6,
+	NI_HSNI = 7,
+	NI_HMNI = 8,
+	NI_PMNI = 9,
+	NI_CMNI = 14,
+	NI_CFGNI = 15
+};
+
+enum ni_subfeature_type {
+	NI_SUBFEATURE_APU = 0,
+	NI_SUBFEATURE_ADDR_MAP = 1,
+	NI_SUBFEATURE_FCU = 2,
+	NI_SUBFEATURE_IDM = 3
+};
+
+static void ni_enable_pmu(uintptr_t pmu_addr)
+{
+	mmio_setbits_32(pmu_addr + NI_PMU_DEBUG_ENABLE, PMU_ENABLE);
+}
+
+static void ni_enable_fcu_ns_access(uintptr_t comp_addr)
+{
+	uint32_t subfeature_type;
+	uint32_t subfeature_count;
+	uint32_t subfeature_secure_ctrl;
+
+	subfeature_count = mmio_read_32(comp_addr + NI_COMP_NUM_SUBFEATURES);
+	for (uint32_t i = 0U; i < subfeature_count; i++) {
+		subfeature_type =
+			NI_NODE_TYPE(mmio_read_32(comp_addr + NI_COMP_SUBFEATURE_TYPE(i)));
+		if (subfeature_type == NI_SUBFEATURE_FCU) {
+			subfeature_secure_ctrl = comp_addr + NI_COMP_SUBFEATURE_SECURE_CTRL(i);
+			mmio_setbits_32(subfeature_secure_ctrl, SECURE_OVERRIDE_DEFAULT);
+		}
+	}
+}
+
+static void ni_enable_pmu_ns_access(uintptr_t comp_addr)
+{
+	mmio_setbits_32(comp_addr + NI_PMU_SECURE_CTRL, SECURE_OVERRIDE_DEFAULT);
+	mmio_setbits_32(comp_addr + NI_PMU_SECURE_EVENT_OBSERVATION,
+			SECURE_EVENT_ENABLE | NA_EVENT_ENABLE);
+}
+
+static void ni_setup_component(uintptr_t comp_addr)
+{
+	uint32_t node_info;
+
+	node_info = mmio_read_32(comp_addr);
+
+	switch (NI_NODE_TYPE(node_info)) {
+	case NI_ASNI:
+	case NI_AMNI:
+	case NI_HSNI:
+	case NI_HMNI:
+	case NI_PMNI:
+		ni_enable_fcu_ns_access(comp_addr);
+		break;
+	case NI_PMU:
+		ni_enable_pmu_ns_access(comp_addr);
+		ni_enable_pmu(comp_addr);
+		break;
+	default:
+		return;
+	}
+}
+
+int plat_arm_ni_setup(uintptr_t global_cfg)
+{
+	uintptr_t vd_addr;
+	uintptr_t pd_addr;
+	uintptr_t cd_addr;
+	uintptr_t comp_addr;
+	uint32_t vd_count;
+	uint32_t pd_count;
+	uint32_t cd_count;
+	uint32_t comp_count;
+	uint32_t part;
+	uint32_t reg;
+
+	reg = mmio_read_32(global_cfg + NI_PERIPHERAL_ID0);
+	part = reg & NI_PIDR0_PART_MASK;
+	reg = mmio_read_32(global_cfg + NI_PERIPHERAL_ID1);
+	part |= ((reg & NI_PIDR1_PART_MASK) << NI_PIDR1_PART_SHIFT);
+
+	if (part != NI_TOWER) {
+		ERROR("0x%x is not supported\n", part);
+		return -EINVAL;
+	}
+
+	vd_count = mmio_read_32(global_cfg + NI_CHILD_NODE_COUNT);
+
+	for (uint32_t i = 0U; i < vd_count; i++) {
+		vd_addr = global_cfg + mmio_read_32(global_cfg + NI_CHILD_POINTER(i));
+		pd_count = mmio_read_32(vd_addr + NI_CHILD_NODE_COUNT);
+
+		for (uint32_t j = 0U; j < pd_count; j++) {
+			pd_addr = global_cfg + mmio_read_32(vd_addr + NI_CHILD_POINTER(j));
+			cd_count = mmio_read_32(pd_addr + NI_CHILD_NODE_COUNT);
+
+			for (uint32_t k = 0U; k < cd_count; k++) {
+				cd_addr = global_cfg + mmio_read_32(pd_addr + NI_CHILD_POINTER(k));
+				comp_count = mmio_read_32(cd_addr + NI_CHILD_NODE_COUNT);
+
+				for (uint32_t l = 0U; l < comp_count; l++) {
+					comp_addr = global_cfg +
+						mmio_read_32(cd_addr + NI_CHILD_POINTER(l));
+					ni_setup_component(comp_addr);
+				}
+			}
+		}
+	}
+
+	return 0;
+}
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 055ab361..498dedf3 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -79,12 +79,8 @@ int arm_validate_power_state(unsigned int power_state,
 	 *  search if the number of entries justify the additional complexity.
 	 */
 	for (i = 0; !!arm_pm_idle_states[i]; i++) {
-#if PSCI_OS_INIT_MODE
 		if ((power_state & ~ARM_LAST_AT_PLVL_MASK) ==
 					arm_pm_idle_states[i])
-#else
-		if (power_state == arm_pm_idle_states[i])
-#endif /* __PSCI_OS_INIT_MODE__ */
 			break;
 	}
 
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index 09226f4b..18e9381a 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,9 +22,11 @@ DEFINE_SVC_UUID2(arm_sip_svc_uid,
 
 static int arm_sip_setup(void)
 {
+#if ENABLE_PMF
 	if (pmf_setup() != 0) {
 		return 1;
 	}
+#endif /* ENABLE_PMF */
 
 #if USE_DEBUGFS
 
@@ -60,12 +62,13 @@ static uintptr_t arm_sip_handler(unsigned int smc_fid,
 	int call_count = 0;
 
 #if ENABLE_PMF
-
 	/*
 	 * Dispatch PMF calls to PMF SMC handler and return its return
 	 * value
 	 */
-	if (is_pmf_fid(smc_fid)) {
+	if (is_pmf_fid_deprecated(smc_fid)) {
+		NOTICE("PMF Interface usage from arm-sip range is deprecated. \
+			Please migrate smc call to Vendor-specific el3 range.\n");
 		return pmf_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
 				handle, flags);
 	}
@@ -73,8 +76,9 @@ static uintptr_t arm_sip_handler(unsigned int smc_fid,
 #endif /* ENABLE_PMF */
 
 #if USE_DEBUGFS
-
-	if (is_debugfs_fid(smc_fid)) {
+	if (is_debugfs_fid_deprecated(smc_fid)) {
+		NOTICE("Debugfs Interface usage from arm-sip range is deprecated. \
+			Please migrate smc call to vendor-specific el3 range.\n");
 		return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
 					   handle, flags);
 	}
diff --git a/plat/arm/common/arm_transfer_list.c b/plat/arm/common/arm_transfer_list.c
new file mode 100644
index 00000000..59fb0398
--- /dev/null
+++ b/plat/arm/common/arm_transfer_list.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *secure_tl)
+{
+	struct transfer_list_entry *te;
+	bl_mem_params_node_t *next_param_node =
+		get_bl_mem_params_node(HW_CONFIG_ID);
+	assert(next_param_node != NULL);
+
+	/*
+	 * The HW_CONFIG needs to be authenticated via the normal loading
+	 * mechanism. Pre-allocate a TE for the configuration and update the
+	 * load information so the configuration is loaded directly into the TE.
+	 */
+	te = transfer_list_add(secure_tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE,
+			       NULL);
+	assert(te != NULL);
+
+	next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+	next_param_node->image_info.image_max_size = PLAT_ARM_HW_CONFIG_SIZE;
+	next_param_node->image_info.image_base =
+		(uintptr_t)transfer_list_entry_data(te);
+}
+
+void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,
+					struct transfer_list_header *secure_tl)
+{
+	uint32_t next_exe_img_id;
+	entry_point_info_t *ep;
+	struct transfer_list_entry *te;
+
+	assert(next_param_node != NULL);
+
+	while ((next_exe_img_id = next_param_node->next_handoff_image_id) !=
+	       INVALID_IMAGE_ID) {
+		next_param_node =
+			&bl_mem_params_desc_ptr[get_bl_params_node_index(
+				next_exe_img_id)];
+		assert(next_param_node != NULL);
+
+		te = transfer_list_add(secure_tl, TL_TAG_EXEC_EP_INFO64,
+				       sizeof(entry_point_info_t),
+				       &next_param_node->ep_info);
+		assert(te != NULL);
+
+		ep = transfer_list_entry_data(te);
+
+		if ((next_exe_img_id == BL32_IMAGE_ID) && SPMC_AT_EL3) {
+			/*
+			 * Populate the BL32 image base, size and max limit in
+			 * the entry point information, since there is no
+			 * platform function to retrieve them in generic
+			 * code. We choose arg2, arg3 and arg4 since the generic
+			 * code uses arg1 for stashing the SP manifest size. The
+			 * SPMC setup uses these arguments to update SP manifest
+			 * with actual SP's base address and it size.
+			 */
+			ep->args.arg2 = next_param_node->image_info.image_base;
+			ep->args.arg3 = next_param_node->image_info.image_size;
+			ep->args.arg4 =
+				next_param_node->image_info.image_base +
+				next_param_node->image_info.image_max_size;
+		}
+
+		next_exe_img_id = next_param_node->next_handoff_image_id;
+	}
+
+	flush_dcache_range((uintptr_t)secure_tl, secure_tl->size);
+}
diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c
index 18c83c79..8655156c 100644
--- a/plat/arm/common/fconf/arm_fconf_sp.c
+++ b/plat/arm/common/fconf/arm_fconf_sp.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
+#include <string.h>
 
 #include <common/debug.h>
 #include <common/desc_image_load.h>
@@ -27,7 +28,7 @@ struct arm_sp_t arm_sp;
 int fconf_populate_arm_sp(uintptr_t config)
 {
 	int sp_node, node, err;
-	union uuid_helper_t uuid_helper;
+	struct uuid uuid;
 	unsigned int index = 0;
 	uint32_t val32;
 	const unsigned int sip_start = SP_PKG1_ID;
@@ -68,13 +69,14 @@ int fconf_populate_arm_sp(uintptr_t config)
 
 		/* Read UUID */
 		err = fdtw_read_uuid(dtb, sp_node, "uuid", 16,
-				     (uint8_t *)&uuid_helper);
+				     (uint8_t *)&uuid);
 		if (err < 0) {
 			ERROR("FCONF: cannot read SP uuid\n");
 			return -1;
 		}
 
-		arm_sp.uuids[index] = uuid_helper;
+		memcpy_s(&arm_sp.uuids[index].uuid_struct, sizeof(struct uuid),
+			 &uuid, sizeof(struct uuid));
 
 		/* Read Load address */
 		err = fdt_read_uint32(dtb, sp_node, "load-address", &val32);
@@ -88,16 +90,16 @@ int fconf_populate_arm_sp(uintptr_t config)
 			" %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
 			" load_addr=%lx\n",
 			__func__,
-			uuid_helper.uuid_struct.time_low[0], uuid_helper.uuid_struct.time_low[1],
-			uuid_helper.uuid_struct.time_low[2], uuid_helper.uuid_struct.time_low[3],
-			uuid_helper.uuid_struct.time_mid[0], uuid_helper.uuid_struct.time_mid[1],
-			uuid_helper.uuid_struct.time_hi_and_version[0],
-			uuid_helper.uuid_struct.time_hi_and_version[1],
-			uuid_helper.uuid_struct.clock_seq_hi_and_reserved,
-			uuid_helper.uuid_struct.clock_seq_low,
-			uuid_helper.uuid_struct.node[0], uuid_helper.uuid_struct.node[1],
-			uuid_helper.uuid_struct.node[2], uuid_helper.uuid_struct.node[3],
-			uuid_helper.uuid_struct.node[4], uuid_helper.uuid_struct.node[5],
+			uuid.time_low[0], uuid.time_low[1],
+			uuid.time_low[2], uuid.time_low[3],
+			uuid.time_mid[0], uuid.time_mid[1],
+			uuid.time_hi_and_version[0],
+			uuid.time_hi_and_version[1],
+			uuid.clock_seq_hi_and_reserved,
+			uuid.clock_seq_low,
+			uuid.node[0], uuid.node[1],
+			uuid.node[2], uuid.node[3],
+			uuid.node[4], uuid.node[5],
 			arm_sp.load_addr[index]);
 
 		/* Read owner field only for dualroot CoT */
diff --git a/plat/arm/common/plat_arm_mbedtls_config.h b/plat/arm/common/plat_arm_mbedtls_config.h
new file mode 100644
index 00000000..a5d0ec40
--- /dev/null
+++ b/plat/arm/common/plat_arm_mbedtls_config.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_ARM_MBEDTLS_CONFIG_H
+#define PLAT_ARM_MBEDTLS_CONFIG_H
+
+#include <mbedtls_config-3.h>
+
+/**
+ * On Arm platforms, the ROTPK is always hashed using the SHA-256
+ * algorithm.
+ * TODO: Update to hash the ROTPK with the selected HASH_ALG to avoid
+ * the need for explicitly enabling the SHA-256 configuration in mbedTLS.
+ */
+#define MBEDTLS_SHA256_C
+
+/*
+ * Use an implementation of SHA-256 with a smaller memory footprint
+ * but reduced speed.
+ */
+#define MBEDTLS_SHA256_SMALLER
+
+#endif /* PLAT_ARM_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/common/plat_arm_psa_mbedtls_config.h b/plat/arm/common/plat_arm_psa_mbedtls_config.h
new file mode 100644
index 00000000..fd434c98
--- /dev/null
+++ b/plat/arm/common/plat_arm_psa_mbedtls_config.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, Arm Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_ARM_PSA_MBEDTLS_CONFIG_H
+#define PLAT_ARM_PSA_MBEDTLS_CONFIG_H
+
+#include "plat_arm_mbedtls_config.h"
+
+#define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
+
+/*
+ * Using PSA crypto API requires an RNG right now. If we don't define the macro
+ * below then we get build errors.
+ *
+ * This is a functionality gap in mbedTLS. The technical limitation is that
+ * psa_crypto_init() is all-or-nothing, and fixing that would require separate
+ * initialization of the keystore, the RNG, etc.
+ *
+ * By defining MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG, we pretend using an external
+ * RNG. As a result, the PSA crypto init code does nothing when it comes to
+ * initializing the RNG, as we are supposed to take care of that ourselves.
+ */
+#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+
+#endif /* PLAT_ARM_PSA_MBEDTLS_CONFIG_H */
diff --git a/plat/arm/common/plat_arm_sip_svc.c b/plat/arm/common/plat_arm_sip_svc.c
index b1dab165..d6341e2c 100644
--- a/plat/arm/common/plat_arm_sip_svc.c
+++ b/plat/arm/common/plat_arm_sip_svc.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdint.h>
+#include <errno.h>
 
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -12,10 +13,73 @@
 #include <plat/arm/common/arm_sip_svc.h>
 #include <plat/common/platform.h>
 
+#if ENABLE_RME && SPMD_SPM_AT_SEL2
+#include <lib/gpt_rme/gpt_rme.h>
+#endif
+
 #if ENABLE_SPMD_LP
 #include <services/el3_spmd_logical_sp.h>
 #endif
 
+#if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
+static uint64_t plat_protect_memory(bool protect,
+				    bool secure_origin,
+				    const uint64_t base,
+				    const size_t size,
+				    void *handle)
+{
+	uint64_t ret = SMC_INVALID_PARAM;
+	uint64_t last_updated = 0;
+
+	if (!secure_origin) {
+		SMC_RET1(handle, SMC_UNK);
+		/* Shall not be reached. */
+	}
+
+	if ((base % PAGE_SIZE_4KB) != 0U &&
+	    (size % PAGE_SIZE_4KB) != 0U) {
+		VERBOSE("Base address must be aligned to 4k.\n");
+		SMC_RET1(handle, SMC_INVALID_PARAM);
+		/* Shall not be reached. */
+	}
+
+	if ((ULONG_MAX - base) < size) {
+		VERBOSE("Base + Size results in overflow.\n");
+		SMC_RET1(handle, SMC_INVALID_PARAM);
+		/* Shall not be reached. */
+	}
+
+	for (uint64_t it = base; it < (base + size); it += PAGE_SIZE_4KB) {
+		/*
+		 * If protect is true, add memory to secure PAS.
+		 * Else unprotect it, making part of non-secure PAS.
+		 */
+		ret = protect
+			? gpt_delegate_pas(it, PAGE_SIZE_4KB,
+					   SMC_FROM_SECURE)
+			: gpt_undelegate_pas(it, PAGE_SIZE_4KB,
+					     SMC_FROM_SECURE);
+
+		switch (ret) {
+		case 0:
+			last_updated = it;
+			break;
+		case -EINVAL:
+			SMC_RET2(handle, SMC_INVALID_PARAM, last_updated);
+			break; /* Shall not be reached. */
+		case -EPERM:
+			SMC_RET2(handle, SMC_DENIED, last_updated);
+			break; /* Shall not be reached. */
+		default:
+			ERROR("Unexpected return\n");
+			panic();
+		}
+	}
+
+	SMC_RET1(handle, SMC_OK);
+}
+#endif /* ENABLE_RME  && SPMD_SPM_AT_SEL2 */
+
 uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
 				u_register_t x1,
 				u_register_t x2,
@@ -25,13 +89,14 @@ uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
 				void *handle,
 				u_register_t flags)
 {
-#if PLAT_TEST_SPM
 	bool secure_origin;
 
 	/* Determine which security state this SMC originated from */
 	secure_origin = is_caller_secure(flags);
+	(void) secure_origin;
 
 	switch (smc_fid) {
+#if PLAT_TEST_SPM
 	case ARM_SIP_SET_INTERRUPT_PENDING:
 		if (!secure_origin) {
 			SMC_RET1(handle, SMC_UNK);
@@ -42,10 +107,19 @@ uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
 
 		SMC_RET1(handle, SMC_OK);
 		break; /* Not reached */
-	default:
+#endif
+
+#if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
+	case PLAT_PROTECT_MEM_SMC64:
+		VERBOSE("Sip Call - Protect memory\n");
+		return plat_protect_memory(true, secure_origin, x1, x2, handle);
+		break;
+	case PLAT_UNPROTECT_MEM_SMC64:
+		VERBOSE("Sip Call - Unprotect memory\n");
+		return plat_protect_memory(false, secure_origin, x1, x2, handle);
 		break;
-	}
 #endif
+	}
 
 #if ENABLE_SPMD_LP
 	return plat_spmd_logical_sp_smc_handler(smc_fid, x1, x2, x3, x4,
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index f15c1379..4cd514bf 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,10 +68,6 @@ void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config,
 	arm_console_boot_init();
 
 #if RESET_TO_SP_MIN
-	/* There are no parameters from BL2 if SP_MIN is a reset vector */
-	assert(from_bl2 == NULL);
-	assert(plat_params_from_bl2 == NULL);
-
 	/* Populate entry point information for BL33 */
 	SET_PARAM_HEAD(&bl33_image_ep_info,
 				PARAM_EP,
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index bb64e734..db4a1691 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -12,6 +12,7 @@
 #include <bl31/interrupt_mgmt.h>
 #include <common/debug.h>
 #include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/dsu.h>
 #include <lib/cassert.h>
 #include <plat/arm/common/plat_arm.h>
 
@@ -82,8 +83,12 @@ static void css_pwr_domain_on_finisher_common(
 	 * Perform the common cluster specific operations i.e enable coherency
 	 * if this cluster was off.
 	 */
-	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
+#if PRESERVE_DSU_PMU_REGS
+		cluster_on_dsu_pmu_context_restore();
+#endif
 		plat_arm_interconnect_enter_coherency();
+	}
 }
 
 /*******************************************************************************
@@ -131,8 +136,12 @@ static void css_power_down_common(const psci_power_state_t *target_state)
 	plat_arm_gic_cpuif_disable();
 
 	/* Cluster is to be turned off, so disable coherency */
-	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+	if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) {
+#if PRESERVE_DSU_PMU_REGS
+		cluster_off_dsu_pmu_context_save();
+#endif
 		plat_arm_interconnect_exit_coherency();
+	}
 }
 
 /*******************************************************************************
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
deleted file mode 100644
index 610f1fcb..00000000
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_BASE_PLATFORM_DEF_H
-#define SGI_BASE_PLATFORM_DEF_H
-
-#include <lib/utils_def.h>
-#include <lib/xlat_tables/xlat_tables_defs.h>
-#include <plat/arm/common/arm_def.h>
-#include <plat/arm/common/arm_spm_def.h>
-#include <plat/arm/css/common/css_def.h>
-#include <plat/common/common_def.h>
-
-#define PLATFORM_CORE_COUNT		(CSS_SGI_CHIP_COUNT *		\
-					PLAT_ARM_CLUSTER_COUNT *	\
-					CSS_SGI_MAX_CPUS_PER_CLUSTER *	\
-					CSS_SGI_MAX_PE_PER_CPU)
-
-#define PLAT_ARM_TRUSTED_SRAM_SIZE	0x00080000	/* 512 KB */
-
-/* Remote chip address offset */
-#define CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n)	\
-		((ULL(1) << CSS_SGI_ADDR_BITS_PER_CHIP) * (n))
-
-/*
- * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
- * plat_arm_mmap array defined for each BL stage. In addition to that, on
- * multi-chip platforms, address regions on each of the remote chips are
- * also mapped. In BL31, for instance, three address regions on the remote
- * chips are accessed - secure ram, css device and soc device regions.
- */
-#if defined(IMAGE_BL31)
-# if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
-#  define PLAT_ARM_MMAP_ENTRIES		(10  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-#  define MAX_XLAT_TABLES		(8  + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-#  define PLAT_SP_IMAGE_MMAP_REGIONS	12
-#  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	14
-# else
-#  define PLAT_ARM_MMAP_ENTRIES		(5 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-#  define MAX_XLAT_TABLES		(6 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-# endif
-#elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES		8
-# define MAX_XLAT_TABLES		5
-#elif defined(IMAGE_BL2)
-# define PLAT_ARM_MMAP_ENTRIES		(11 + (CSS_SGI_CHIP_COUNT - 1))
-
-/*
- * MAX_XLAT_TABLES entries need to be doubled because when the address width
- * exceeds 40 bits an additional level of translation is required. In case of
- * multichip platforms peripherals also fall into address space with width
- * > 40 bits
- *
- */
-# define MAX_XLAT_TABLES		(7  + ((CSS_SGI_CHIP_COUNT - 1) * 2))
-#elif !USE_ROMLIB
-# define PLAT_ARM_MMAP_ENTRIES		11
-# define MAX_XLAT_TABLES		7
-#else
-# define PLAT_ARM_MMAP_ENTRIES		12
-# define MAX_XLAT_TABLES		6
-#endif
-
-/*
- * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
- * plus a little space for growth.
- */
-#define PLAT_ARM_MAX_BL1_RW_SIZE	(64 * 1024)	/* 64 KB */
-
-/*
- * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
- */
-
-#if USE_ROMLIB
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	0x1000
-#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	0xe000
-#else
-#define PLAT_ARM_MAX_ROMLIB_RW_SIZE	0
-#define PLAT_ARM_MAX_ROMLIB_RO_SIZE	0
-#endif
-
-/*
- * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
- * little space for growth. Additional 8KiB space is added per chip in
- * order to accommodate the additional level of translation required for "TZC"
- * peripheral access which lies in >4TB address space.
- *
- */
-#if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE		(0x20000 + ((CSS_SGI_CHIP_COUNT - 1) * \
-							0x2000))
-#else
-# define PLAT_ARM_MAX_BL2_SIZE		(0x14000 + ((CSS_SGI_CHIP_COUNT - 1) * \
-							0x2000))
-#endif
-
-/*
- * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
- * calculated using the current BL31 PROGBITS debug size plus the sizes of BL2
- * and BL1-RW. CSS_SGI_BL31_SIZE - is tuned with respect to the actual BL31
- * PROGBITS size which is around 64-68KB at the time this change is being made.
- * A buffer of ~35KB is added to account for future expansion of the image,
- * making it a total of 100KB.
- */
-#define CSS_SGI_BL31_SIZE		(100 * 1024)	/* 100 KB */
-#define PLAT_ARM_MAX_BL31_SIZE		(CSS_SGI_BL31_SIZE +		\
-						PLAT_ARM_MAX_BL2_SIZE +	\
-						PLAT_ARM_MAX_BL1_RW_SIZE)
-
-/*
- * Size of cacheable stacks
- */
-#if defined(IMAGE_BL1)
-# if TRUSTED_BOARD_BOOT
-#  define PLATFORM_STACK_SIZE 0x1000
-# else
-#  define PLATFORM_STACK_SIZE 0x440
-# endif
-#elif defined(IMAGE_BL2)
-# if TRUSTED_BOARD_BOOT
-#  define PLATFORM_STACK_SIZE 0x1000
-# else
-#  define PLATFORM_STACK_SIZE 0x400
-# endif
-#elif defined(IMAGE_BL2U)
-# define PLATFORM_STACK_SIZE 0x400
-#elif defined(IMAGE_BL31)
-# if SPM_MM
-#  define PLATFORM_STACK_SIZE 0x500
-# else
-#  define PLATFORM_STACK_SIZE 0x400
-# endif
-#elif defined(IMAGE_BL32)
-# define PLATFORM_STACK_SIZE 0x440
-#endif
-
-/* PL011 UART related constants */
-#define SOC_CSS_SEC_UART_BASE			UL(0x2A410000)
-#define SOC_CSS_NSEC_UART_BASE			UL(0x2A400000)
-#define SOC_CSS_UART_SIZE			UL(0x10000)
-#define SOC_CSS_UART_CLK_IN_HZ			UL(7372800)
-
-/* UART related constants */
-#define PLAT_ARM_BOOT_UART_BASE			SOC_CSS_SEC_UART_BASE
-#define PLAT_ARM_BOOT_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
-
-#define PLAT_ARM_RUN_UART_BASE			SOC_CSS_SEC_UART_BASE
-#define PLAT_ARM_RUN_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
-
-#define PLAT_ARM_CRASH_UART_BASE		SOC_CSS_SEC_UART_BASE
-#define PLAT_ARM_CRASH_UART_CLK_IN_HZ		SOC_CSS_UART_CLK_IN_HZ
-
-#define PLAT_ARM_NSTIMER_FRAME_ID	0
-
-#define PLAT_ARM_TRUSTED_ROM_BASE	0x0
-#define PLAT_ARM_TRUSTED_ROM_SIZE	0x00080000	/* 512KB */
-
-#define PLAT_ARM_NSRAM_BASE		0x06000000
-#define PLAT_ARM_NSRAM_SIZE		0x00080000	/* 512KB */
-
-#define PLAT_ARM_DRAM2_BASE		ULL(0x8080000000)
-#define PLAT_ARM_DRAM2_SIZE		ULL(0x180000000)
-
-#define PLAT_ARM_G1S_IRQ_PROPS(grp)	CSS_G1S_IRQ_PROPS(grp)
-#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
-
-#define CSS_SGI_DEVICE_BASE	(0x20000000)
-#define CSS_SGI_DEVICE_SIZE	(0x20000000)
-#define CSS_SGI_MAP_DEVICE	MAP_REGION_FLAT(		\
-					CSS_SGI_DEVICE_BASE,	\
-					CSS_SGI_DEVICE_SIZE,	\
-					MT_DEVICE | MT_RW | MT_SECURE)
-
-#define ARM_MAP_SHARED_RAM_REMOTE_CHIP(n)					\
-			MAP_REGION_FLAT(					\
-				CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) +		\
-				ARM_SHARED_RAM_BASE,				\
-				ARM_SHARED_RAM_SIZE,				\
-				MT_NON_CACHEABLE | MT_RW | MT_SECURE		\
-			)
-
-#define CSS_SGI_MAP_DEVICE_REMOTE_CHIP(n)					\
-			MAP_REGION_FLAT(					\
-				CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) +		\
-				CSS_SGI_DEVICE_BASE,				\
-				CSS_SGI_DEVICE_SIZE,				\
-				MT_DEVICE | MT_RW | MT_SECURE			\
-			)
-
-#define SOC_CSS_MAP_DEVICE_REMOTE_CHIP(n)					\
-			MAP_REGION_FLAT(					\
-				CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) +		\
-				SOC_CSS_DEVICE_BASE,				\
-				SOC_CSS_DEVICE_SIZE,				\
-				MT_DEVICE | MT_RW | MT_SECURE			\
-			)
-
-/* Map the secure region for access from S-EL0 */
-#define PLAT_ARM_SECURE_MAP_DEVICE	MAP_REGION_FLAT(	\
-					SOC_CSS_DEVICE_BASE,	\
-					SOC_CSS_DEVICE_SIZE,	\
-					MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
-
-#if ENABLE_FEAT_RAS && FFH_SUPPORT
-#define PLAT_SP_PRI				PLAT_RAS_PRI
-#else
-#define PLAT_SP_PRI				0x10
-#endif
-
-#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) && ENABLE_FEAT_RAS && FFH_SUPPORT
-/*
- * CPER buffer memory of 128KB is reserved and it is placed adjacent to the
- * memory shared between EL3 and S-EL0.
- */
-#define CSS_SGI_SP_CPER_BUF_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE + \
-					 PLAT_SP_IMAGE_NS_BUF_SIZE)
-#define CSS_SGI_SP_CPER_BUF_SIZE	ULL(0x20000)
-#define CSS_SGI_SP_CPER_BUF_MMAP	MAP_REGION2(			       \
-						CSS_SGI_SP_CPER_BUF_BASE,      \
-						CSS_SGI_SP_CPER_BUF_BASE,      \
-						CSS_SGI_SP_CPER_BUF_SIZE,      \
-						MT_RW_DATA | MT_NS | MT_USER,  \
-						PAGE_SIZE)
-
-/*
- * Secure partition stack follows right after the memory space reserved for
- * CPER buffer memory.
- */
-#define PLAT_ARM_SP_IMAGE_STACK_BASE		(PLAT_SP_IMAGE_NS_BUF_BASE +   \
-						 PLAT_SP_IMAGE_NS_BUF_SIZE +   \
-						 CSS_SGI_SP_CPER_BUF_SIZE)
-#elif (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP))
-/*
- * Secure partition stack follows right after the memory region that is shared
- * between EL3 and S-EL0.
- */
-#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
-					 PLAT_SP_IMAGE_NS_BUF_SIZE)
-#endif /* SPM_MM && ENABLE_FEAT_RAS && FFH_SUPPORT */
-
-/* Platform ID address */
-#define SSC_VERSION                     (SSC_REG_BASE + SSC_VERSION_OFFSET)
-#ifndef __ASSEMBLER__
-/* SSC_VERSION related accessors */
-/* Returns the part number of the platform */
-#define GET_SGI_PART_NUM                                       \
-		GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
-/* Returns the configuration number of the platform */
-#define GET_SGI_CONFIG_NUM                                     \
-		GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
-#endif /* __ASSEMBLER__ */
-
-/*******************************************************************************
- * Memprotect definitions
- ******************************************************************************/
-/* PSCI memory protect definitions:
- * This variable is stored in a non-secure flash because some ARM reference
- * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
- * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
- */
-#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
-					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-/*Secure Watchdog Constants */
-#define SBSA_SECURE_WDOG_BASE		UL(0x2A480000)
-#define SBSA_SECURE_WDOG_TIMEOUT	UL(100)
-
-/* Number of SCMI channels on the platform */
-#define PLAT_ARM_SCMI_CHANNEL_COUNT	CSS_SGI_CHIP_COUNT
-
-/*
- * Mapping definition of the TrustZone Controller for ARM SGI/RD platforms
- * where both the DRAM regions are marked for non-secure access. This applies
- * to multi-chip platforms.
- */
-#define SGI_PLAT_TZC_NS_REMOTE_REGIONS_DEF(n)				\
-	{CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_BASE,		\
-		CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM1_END,	\
-		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS},	\
-	{CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_BASE,		\
-		CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + ARM_DRAM2_END,	\
-		ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS}
-
-#if SPM_MM
-
-/*
- * Stand-alone MM logs would be routed via secure UART. Define page table
- * entry for secure UART which would be common to all platforms.
- */
-#define SOC_PLATFORM_SECURE_UART	MAP_REGION_FLAT(		\
-					SOC_CSS_SEC_UART_BASE,		\
-					SOC_CSS_UART_SIZE,		\
-					MT_DEVICE | MT_RW | 		\
-					MT_SECURE | MT_USER)
-
-#endif
-
-/* SDS ID for unusable CPU MPID list structure */
-#define SDS_ISOLATED_CPU_LIST_ID		U(128)
-
-#endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_plat.h b/plat/arm/css/sgi/include/sgi_plat.h
deleted file mode 100644
index a5fbded3..00000000
--- a/plat/arm/css/sgi/include/sgi_plat.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_PLAT_H
-#define SGI_PLAT_H
-
-/* BL31 platform setup common to all SGI based platforms */
-void sgi_bl31_common_platform_setup(void);
-
-#endif /* SGI_PLAT_H */
diff --git a/plat/arm/css/sgi/include/sgi_sdei.h b/plat/arm/css/sgi/include/sgi_sdei.h
deleted file mode 100644
index f380122b..00000000
--- a/plat/arm/css/sgi/include/sgi_sdei.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SDEI_H
-#define SGI_SDEI_H
-
-#if SDEI_SUPPORT
-
-/* ARM SDEI dynamic shared event numbers */
-#define SGI_SDEI_DS_EVENT_0		U(804)
-#define SGI_SDEI_DS_EVENT_1		U(805)
-
-#define PLAT_ARM_PRIVATE_SDEI_EVENTS					      \
-		SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI),			      \
-		SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_0, SDEI_MAPF_CRITICAL), \
-		SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL),
-
-#define PLAT_ARM_SHARED_SDEI_EVENTS
-
-#endif /* SDEI_SUPPORT */
-
-#endif /* SGI_SDEI_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def.h b/plat/arm/css/sgi/include/sgi_soc_css_def.h
deleted file mode 100644
index f78b45a2..00000000
--- a/plat/arm/css/sgi/include/sgi_soc_css_def.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SOC_CSS_DEF_H
-#define SGI_SOC_CSS_DEF_H
-
-#include <lib/utils_def.h>
-#include <plat/arm/board/common/v2m_def.h>
-#include <plat/arm/soc/common/soc_css_def.h>
-#include <plat/common/common_def.h>
-
-/*
- * Definitions common to all ARM CSSv1-based development platforms
- */
-
-/* Platform ID address */
-#define BOARD_CSS_PLAT_ID_REG_ADDR		UL(0x7ffe00e0)
-
-/* Platform ID related accessors */
-#define BOARD_CSS_PLAT_ID_REG_ID_MASK		0x0f
-#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		0x0
-#define BOARD_CSS_PLAT_TYPE_EMULATOR		0x02
-
-#ifndef __ASSEMBLER__
-
-#include <lib/mmio.h>
-
-#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
-	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
-	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
-
-#endif /* __ASSEMBLER__ */
-
-#define MAX_IO_DEVICES			3
-#define MAX_IO_HANDLES			4
-
-/* Reserve the last block of flash for PSCI MEM PROTECT flag */
-#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
-#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
-#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-#endif /* SGI_SOC_CSS_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
deleted file mode 100644
index d659ae51..00000000
--- a/plat/arm/css/sgi/include/sgi_soc_css_def_v2.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SOC_CSS_DEF_V2_H
-#define SGI_SOC_CSS_DEF_V2_H
-
-#include <lib/utils_def.h>
-#include <plat/common/common_def.h>
-
-/*
- * Definitions common to all ARM CSS SoCs
- */
-
-/* Following covers ARM CSS SoC Peripherals */
-
-#define SOC_SYSTEM_PERIPH_BASE		UL(0x0C000000)
-#define SOC_SYSTEM_PERIPH_SIZE		UL(0x02000000)
-
-#define SOC_PLATFORM_PERIPH_BASE	UL(0x0E000000)
-#define SOC_PLATFORM_PERIPH_SIZE	UL(0x02000000)
-
-#define SOC_CSS_PCIE_CONTROL_BASE	UL(0x0ef20000)
-
-/* Memory controller */
-#define SOC_MEMCNTRL_BASE		UL(0x10000000)
-#define SOC_MEMCNTRL_SIZE		UL(0x10000000)
-
-/* SoC NIC-400 Global Programmers View (GPV) */
-#define SOC_CSS_NIC400_BASE		UL(0x0ED00000)
-
-#define SOC_CSS_NIC400_USB_EHCI		U(0)
-#define SOC_CSS_NIC400_TLX_MASTER	U(1)
-#define SOC_CSS_NIC400_USB_OHCI		U(2)
-#define SOC_CSS_NIC400_PL354_SMC	U(3)
-/*
- * The apb4_bridge controls access to:
- *   - the PCIe configuration registers
- *   - the MMU units for USB, HDLCD and DMA
- */
-#define SOC_CSS_NIC400_APB4_BRIDGE	U(4)
-
-/* Non-volatile counters */
-#define SOC_TRUSTED_NVCTR_BASE		UL(0x0EE70000)
-#define TFW_NVCTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0000)
-#define TFW_NVCTR_SIZE			U(4)
-#define NTFW_CTR_BASE			(SOC_TRUSTED_NVCTR_BASE + 0x0004)
-#define NTFW_CTR_SIZE			U(4)
-
-/* Keys */
-#define SOC_KEYS_BASE			UL(0x0EE80000)
-#define TZ_PUB_KEY_HASH_BASE		(SOC_KEYS_BASE + 0x0000)
-#define TZ_PUB_KEY_HASH_SIZE		U(32)
-#define HU_KEY_BASE			(SOC_KEYS_BASE + 0x0020)
-#define HU_KEY_SIZE			U(16)
-#define END_KEY_BASE			(SOC_KEYS_BASE + 0x0044)
-#define END_KEY_SIZE			U(32)
-
-/* Base Element RAM error definitions */
-#define SOC_NS_RAM_ERR_REC_BASE		UL(0x2A4C0000)
-#define NS_RAM_ECC_CE_INT		U(87)
-#define NS_RAM_ECC_UE_INT		U(88)
-
-#define SOC_PLATFORM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(			\
-						SOC_PLATFORM_PERIPH_BASE, 	\
-						SOC_PLATFORM_PERIPH_SIZE, 	\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#if SPM_MM
-/*
- * Memory map definition for the platform peripheral memory region that is
- * accessible from S-EL0 (with secure user mode access).
- */
-#define SOC_PLATFORM_PERIPH_MAP_DEVICE_USER				       \
-		MAP_REGION_FLAT(					       \
-			SOC_PLATFORM_PERIPH_BASE,			       \
-			SOC_PLATFORM_PERIPH_SIZE,			       \
-			MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
-#endif
-
-#define SOC_SYSTEM_PERIPH_MAP_DEVICE	MAP_REGION_FLAT(			\
-						SOC_SYSTEM_PERIPH_BASE,		\
-						SOC_SYSTEM_PERIPH_SIZE,		\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#define SOC_MEMCNTRL_MAP_DEVICE		MAP_REGION_FLAT(			\
-						SOC_MEMCNTRL_BASE,		\
-						SOC_MEMCNTRL_SIZE,		\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#define SOC_MEMCNTRL_MAP_DEVICE_REMOTE_CHIP(n)					\
-		MAP_REGION_FLAT(						\
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(n) + SOC_MEMCNTRL_BASE,	\
-			SOC_MEMCNTRL_SIZE,					\
-			MT_DEVICE | MT_RW | MT_SECURE)
-
-/*
- * The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs.
- */
-#define SOC_CSS_NIC400_BOOTSEC_BRIDGE		U(5)
-#define SOC_CSS_NIC400_BOOTSEC_BRIDGE_UART1	UL(1 << 12)
-
-/*
- * Required platform porting definitions common to all ARM CSS SoCs
- */
-/* 2MB used for SCP DDR retraining */
-#define PLAT_ARM_SCP_TZC_DRAM1_SIZE	UL(0x00200000)
-
-/* V2M motherboard system registers & offsets */
-#define V2M_SYSREGS_BASE		UL(0x0C010000)
-#define V2M_SYS_LED			U(0x8)
-
-/*
- * V2M sysled bit definitions. The values written to this
- * register are defined in arch.h & runtime_svc.h. Only
- * used by the primary cpu to diagnose any cold boot issues.
- *
- * SYS_LED[0]   - Security state (S=0/NS=1)
- * SYS_LED[2:1] - Exception Level (EL3-EL0)
- * SYS_LED[7:3] - Exception Class (Sync/Async & origin)
- *
- */
-#define V2M_SYS_LED_SS_SHIFT		U(0)
-#define V2M_SYS_LED_EL_SHIFT		U(1)
-#define V2M_SYS_LED_EC_SHIFT		U(3)
-
-#define V2M_SYS_LED_SS_MASK		U(0x01)
-#define V2M_SYS_LED_EL_MASK		U(0x03)
-#define V2M_SYS_LED_EC_MASK		U(0x1f)
-
-/* NOR Flash */
-#define V2M_FLASH0_BASE			UL(0x08000000)
-#define V2M_FLASH0_SIZE			UL(0x04000000)
-#define V2M_FLASH_BLOCK_SIZE		UL(0x00040000)	/* 256 KB */
-
-/*
- * The flash can be mapped either as read-only or read-write.
- *
- * If it is read-write then it should also be mapped as device memory because
- * NOR flash programming involves sending a fixed, ordered sequence of commands.
- *
- * If it is read-only then it should also be mapped as:
- * - Normal memory, because reading from NOR flash is transparent, it is like
- *   reading from RAM.
- * - Non-executable by default. If some parts of the flash need to be executable
- *   then platform code is responsible for re-mapping the appropriate portion
- *   of it as executable.
- */
-#define V2M_MAP_FLASH0_RW		MAP_REGION_FLAT(V2M_FLASH0_BASE,\
-						V2M_FLASH0_SIZE,	\
-						MT_DEVICE | MT_RW | MT_SECURE)
-
-#define V2M_MAP_FLASH0_RO		MAP_REGION_FLAT(V2M_FLASH0_BASE,\
-						V2M_FLASH0_SIZE,	\
-						MT_RO_DATA | MT_SECURE)
-
-#define SGI_MAP_FLASH0_RO		MAP_REGION_FLAT(V2M_FLASH0_BASE,\
-						V2M_FLASH0_SIZE,	\
-						MT_DEVICE | MT_RO | MT_SECURE)
-
-/* Platform ID address */
-#define BOARD_CSS_PLAT_ID_REG_ADDR		UL(0x0EFE00E0)
-
-/* Platform ID related accessors */
-#define BOARD_CSS_PLAT_ID_REG_ID_MASK		U(0x0F)
-#define BOARD_CSS_PLAT_ID_REG_ID_SHIFT		U(0x00)
-#define BOARD_CSS_PLAT_ID_REG_VERSION_MASK	U(0xF00)
-#define BOARD_CSS_PLAT_ID_REG_VERSION_SHIFT	U(0x08)
-#define BOARD_CSS_PLAT_TYPE_RTL			U(0x00)
-#define BOARD_CSS_PLAT_TYPE_FPGA		U(0x01)
-#define BOARD_CSS_PLAT_TYPE_EMULATOR		U(0x02)
-#define BOARD_CSS_PLAT_TYPE_FVP			U(0x03)
-
-#ifndef __ASSEMBLER__
-
-#include <lib/mmio.h>
-
-#define BOARD_CSS_GET_PLAT_TYPE(addr)					\
-	((mmio_read_32(addr) & BOARD_CSS_PLAT_ID_REG_ID_MASK)		\
-	>> BOARD_CSS_PLAT_ID_REG_ID_SHIFT)
-
-#endif /* __ASSEMBLER__ */
-
-
-#define MAX_IO_DEVICES			U(3)
-#define MAX_IO_HANDLES			U(4)
-
-/* Reserve the last block of flash for PSCI MEM PROTECT flag */
-#define PLAT_ARM_FLASH_IMAGE_BASE	V2M_FLASH0_BASE
-#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE	(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-#if ARM_GPT_SUPPORT
-/*
- * Offset of the FIP in the GPT image. BL1 component uses this option
- * as it does not load the partition table to get the FIP base
- * address. At sector 34 by default (i.e. after reserved sectors 0-33)
- * Offset = 34 * 512(sector size) = 17408 i.e. 0x4400
- */
-#define PLAT_ARM_FIP_OFFSET_IN_GPT		0x4400
-#endif /* ARM_GPT_SUPPORT */
-
-#define PLAT_ARM_NVM_BASE		V2M_FLASH0_BASE
-#define PLAT_ARM_NVM_SIZE		(V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-
-#endif /* SGI_SOC_CSS_DEF_V2_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def.h b/plat/arm/css/sgi/include/sgi_soc_platform_def.h
deleted file mode 100644
index 3b8d9c66..00000000
--- a/plat/arm/css/sgi/include/sgi_soc_platform_def.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SOC_PLATFORM_DEF_H
-#define SGI_SOC_PLATFORM_DEF_H
-
-#include <plat/arm/board/common/v2m_def.h>
-#include <plat/arm/soc/common/soc_css_def.h>
-#include <sgi_base_platform_def.h>
-#include <sgi_soc_css_def.h>
-
-/* Map the System registers to access from S-EL0 */
-#define CSS_SYSTEMREG_DEVICE_BASE	(0x1C010000)
-#define CSS_SYSTEMREG_DEVICE_SIZE	(0x00010000)
-#define PLAT_ARM_SECURE_MAP_SYSTEMREG	MAP_REGION_FLAT(		    \
-						CSS_SYSTEMREG_DEVICE_BASE,  \
-						CSS_SYSTEMREG_DEVICE_SIZE,  \
-						(MT_DEVICE | MT_RW |	    \
-						 MT_SECURE | MT_USER))
-
-/* Map the NOR2 Flash to access from S-EL0 */
-#define CSS_NOR2_FLASH_DEVICE_BASE	(0x10000000)
-#define CSS_NOR2_FLASH_DEVICE_SIZE	(0x04000000)
-#define PLAT_ARM_SECURE_MAP_NOR2	MAP_REGION_FLAT(                    \
-						CSS_NOR2_FLASH_DEVICE_BASE, \
-						CSS_NOR2_FLASH_DEVICE_SIZE, \
-						(MT_DEVICE | MT_RW |	    \
-						 MT_SECURE | MT_USER))
-
-#endif /* SGI_SOC_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h b/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
deleted file mode 100644
index 20dd6825..00000000
--- a/plat/arm/css/sgi/include/sgi_soc_platform_def_v2.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SGI_SOC_PLATFORM_DEF_V2_H
-#define SGI_SOC_PLATFORM_DEF_V2_H
-
-#include <sgi_base_platform_def.h>
-#include <sgi_soc_css_def_v2.h>
-
-/* Map the System registers to access from S-EL0 */
-#define CSS_SYSTEMREG_DEVICE_BASE	(0x0C010000)
-#define CSS_SYSTEMREG_DEVICE_SIZE	(0x00010000)
-#define PLAT_ARM_SECURE_MAP_SYSTEMREG	MAP_REGION_FLAT(                    \
-						CSS_SYSTEMREG_DEVICE_BASE,  \
-						CSS_SYSTEMREG_DEVICE_SIZE,  \
-						(MT_DEVICE | MT_RW |	    \
-						 MT_SECURE | MT_USER))
-
-/* Map the NOR2 Flash to access from S-EL0 */
-#define CSS_NOR2_FLASH_DEVICE_BASE	(0x001054000000)
-#define CSS_NOR2_FLASH_DEVICE_SIZE	(0x000004000000)
-#define PLAT_ARM_SECURE_MAP_NOR2	MAP_REGION_FLAT(                    \
-						CSS_NOR2_FLASH_DEVICE_BASE, \
-						CSS_NOR2_FLASH_DEVICE_SIZE, \
-						(MT_DEVICE | MT_RW |	    \
-						 MT_SECURE | MT_USER))
-
-#endif /* SGI_SOC_PLATFORM_DEF_V2_H */
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
deleted file mode 100644
index 7aa7b34a..00000000
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <libfdt.h>
-
-#include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/arm/css/css_mhu_doorbell.h>
-#include <drivers/arm/css/scmi.h>
-#include <plat/arm/common/plat_arm.h>
-
-#include <plat/common/platform.h>
-
-#include <plat/arm/css/common/css_pm.h>
-
-#include <sgi_ras.h>
-#include <sgi_variant.h>
-
-sgi_platform_info_t sgi_plat_info;
-
-static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
-		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhu_ring_doorbell,
-};
-
-static scmi_channel_plat_info_t plat_rd_scmi_info[] = {
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
-		.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	},
-	#if (CSS_SGI_CHIP_COUNT > 1)
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
-		.db_reg_addr = PLAT_CSS_MHU_BASE
-			+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	},
-	#endif
-	#if (CSS_SGI_CHIP_COUNT > 2)
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
-		.db_reg_addr = PLAT_CSS_MHU_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	},
-	#endif
-	#if (CSS_SGI_CHIP_COUNT > 3)
-	{
-		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
-		.db_reg_addr = PLAT_CSS_MHU_BASE +
-			CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0),
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhuv2_ring_doorbell,
-	},
-	#endif
-};
-
-scmi_channel_plat_info_t *plat_css_get_scmi_info(unsigned int channel_id)
-{
-	if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_V2_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_N2_CFG1_SID_VER_PART_NUM ||
-		sgi_plat_info.platform_id == RD_N2_CFG3_SID_VER_PART_NUM) {
-		if (channel_id >= ARRAY_SIZE(plat_rd_scmi_info))
-			panic();
-		return &plat_rd_scmi_info[channel_id];
-	}
-	else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM)
-		return &sgi575_scmi_plat_info;
-	else
-		panic();
-}
-
-void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
-				u_register_t arg2, u_register_t arg3)
-{
-	sgi_plat_info.platform_id = plat_arm_sgi_get_platform_id();
-	sgi_plat_info.config_id = plat_arm_sgi_get_config_id();
-	sgi_plat_info.multi_chip_mode = plat_arm_sgi_get_multi_chip_mode();
-
-	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
-}
-
-void sgi_bl31_common_platform_setup(void)
-{
-	arm_bl31_platform_setup();
-
-	/* Configure the warm reboot SGI for primary core */
-	css_setup_cpu_pwr_down_intr();
-
-#if CSS_SYSTEM_GRACEFUL_RESET
-	/* Register priority level handlers for reboot */
-	ehf_register_priority_handler(PLAT_REBOOT_PRI,
-			css_reboot_interrupt_handler);
-#endif
-}
-
-const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
-{
-	/*
-	 * For RD-E1-Edge, only CPU power ON/OFF, PSCI platform callbacks are
-	 * supported.
-	 */
-	if (((sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) &&
-	    (sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID))) {
-		ops->cpu_standby = NULL;
-		ops->system_off = NULL;
-		ops->system_reset = NULL;
-		ops->get_sys_suspend_power_state = NULL;
-		ops->pwr_domain_suspend = NULL;
-		ops->pwr_domain_suspend_finish = NULL;
-	}
-
-	return css_scmi_override_pm_ops(ops);
-}
diff --git a/plat/aspeed/ast2700/include/platform_def.h b/plat/aspeed/ast2700/include/platform_def.h
index 8be26c37..e6681152 100644
--- a/plat/aspeed/ast2700/include/platform_def.h
+++ b/plat/aspeed/ast2700/include/platform_def.h
@@ -21,9 +21,6 @@
 #define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
 					 PLATFORM_CORE_COUNT_PER_CLUSTER)
 
-/* arch timer */
-#define PLAT_SYSCNT_CLKIN_HZ		U(1600000000)
-
 /* power domain */
 #define PLAT_MAX_PWR_LVL		U(1)
 #define PLAT_NUM_PWR_DOMAINS		U(5)
@@ -55,4 +52,12 @@
 #define CONSOLE_UART_CLKIN_HZ		U(1846153)
 #define CONSOLE_UART_BAUDRATE		U(115200)
 
+/* CLK information */
+#define CLKIN_25M			UL(25000000)
+
+#define PLAT_CLK_GATE_NUM		U(29)
+#define PLAT_CLK_HPLL			(PLAT_CLK_GATE_NUM + 5)
+#define PLAT_CLK_DPLL			(PLAT_CLK_GATE_NUM + 6)
+#define PLAT_CLK_MPLL			(PLAT_CLK_GATE_NUM + 7)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/aspeed/ast2700/include/platform_reg.h b/plat/aspeed/ast2700/include/platform_reg.h
index 7f268654..3c164a4c 100644
--- a/plat/aspeed/ast2700/include/platform_reg.h
+++ b/plat/aspeed/ast2700/include/platform_reg.h
@@ -19,6 +19,10 @@
 
 /* CPU-die SCU */
 #define SCU_CPU_BASE	U(0x12c02000)
+#define SCU_CPU_HW_STRAP1	(SCU_CPU_BASE + 0x010)
+#define SCU_CPU_HPLL	(SCU_CPU_BASE + 0x300)
+#define SCU_CPU_DPLL	(SCU_CPU_BASE + 0x308)
+#define SCU_CPU_MPLL	(SCU_CPU_BASE + 0x310)
 #define SCU_CPU_SMP_EP0	(SCU_CPU_BASE + 0x780)
 #define SCU_CPU_SMP_EP1	(SCU_CPU_BASE + 0x788)
 #define SCU_CPU_SMP_EP2	(SCU_CPU_BASE + 0x790)
diff --git a/plat/aspeed/ast2700/plat_bl31_setup.c b/plat/aspeed/ast2700/plat_bl31_setup.c
index 92a48ff8..087b4795 100644
--- a/plat/aspeed/ast2700/plat_bl31_setup.c
+++ b/plat/aspeed/ast2700/plat_bl31_setup.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
 #include <arch.h>
 #include <common/debug.h>
 #include <common/desc_image_load.h>
@@ -112,3 +113,90 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
 
 	return ep_info;
 }
+
+/*
+ * Clock divider/multiplier configuration struct.
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ *
+ */
+union plat_pll_reg {
+	uint32_t w;
+	struct {
+		uint16_t m : 13;		/* bit[12:0]	*/
+		uint8_t n : 6;			/* bit[18:13]	*/
+		uint8_t p : 4;			/* bit[22:19]	*/
+		uint8_t off : 1;		/* bit[23]	*/
+		uint8_t bypass : 1;		/* bit[24]	*/
+		uint8_t reset : 1;		/* bit[25]	*/
+		uint8_t reserved : 6;		/* bit[31:26]	*/
+	} b;
+};
+
+static uint32_t plat_get_pll_rate(int pll_idx)
+{
+	union plat_pll_reg pll_reg;
+	uint32_t mul = 1, div = 1;
+	uint32_t rate = 0;
+
+	switch (pll_idx) {
+	case PLAT_CLK_HPLL:
+		pll_reg.w = mmio_read_32(SCU_CPU_HPLL);
+		break;
+	case PLAT_CLK_DPLL:
+		pll_reg.w = mmio_read_32(SCU_CPU_DPLL);
+		break;
+	case PLAT_CLK_MPLL:
+		pll_reg.w = mmio_read_32(SCU_CPU_MPLL);
+		break;
+	default:
+		ERROR("%s: invalid PSP clock source (%d)\n", __func__, pll_idx);
+		return -EINVAL;
+	}
+
+	if (pll_idx == PLAT_CLK_HPLL && ((mmio_read_32(SCU_CPU_HW_STRAP1) & GENMASK(3, 2)) != 0U)) {
+		switch ((mmio_read_32(SCU_CPU_HW_STRAP1) & GENMASK(3, 2)) >> 2) {
+		case 1U:
+			rate = 1900000000;
+			break;
+		case 2U:
+			rate = 1800000000;
+			break;
+		case 3U:
+			rate = 1700000000;
+			break;
+		default:
+			rate = 2000000000;
+			break;
+		}
+	} else {
+		if (pll_reg.b.bypass == 0U) {
+			if (pll_idx == PLAT_CLK_MPLL) {
+				/* F = 25Mhz * [M / (n + 1)] / (p + 1) */
+				mul = (pll_reg.b.m) / ((pll_reg.b.n + 1));
+				div = (pll_reg.b.p + 1);
+			} else {
+				/* F = 25Mhz * [(M + 2) / 2 * (n + 1)] / (p + 1) */
+				mul = (pll_reg.b.m + 1) / ((pll_reg.b.n + 1) * 2);
+				div = (pll_reg.b.p + 1);
+			}
+		}
+
+		rate = ((CLKIN_25M * mul) / div);
+	}
+
+	return rate;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	if (mmio_read_32(SCU_CPU_HW_STRAP1) & BIT(4)) {
+		return plat_get_pll_rate(PLAT_CLK_HPLL);
+	} else {
+		return plat_get_pll_rate(PLAT_CLK_MPLL);
+	}
+}
diff --git a/plat/aspeed/ast2700/plat_helpers.S b/plat/aspeed/ast2700/plat_helpers.S
index c6d987e6..e4a283c0 100644
--- a/plat/aspeed/ast2700/plat_helpers.S
+++ b/plat/aspeed/ast2700/plat_helpers.S
@@ -59,12 +59,6 @@ poll_smp_mbox_go:
 	br	x0
 endfunc plat_secondary_cold_boot_setup
 
-/* unsigned int plat_get_syscnt_freq2(void); */
-func plat_get_syscnt_freq2
-	mov_imm	w0, PLAT_SYSCNT_CLKIN_HZ
-	ret
-endfunc plat_get_syscnt_freq2
-
 /* int plat_crash_console_init(void); */
 func plat_crash_console_init
 	mov_imm	x0, CONSOLE_UART_BASE
diff --git a/plat/brcm/common/brcm_bl31_setup.c b/plat/brcm/common/brcm_bl31_setup.c
index d3fa83da..6eef1d4c 100644
--- a/plat/brcm/common/brcm_bl31_setup.c
+++ b/plat/brcm/common/brcm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -235,8 +235,6 @@ void brcm_bl31_platform_setup(void)
  ******************************************************************************/
 void brcm_bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
-
 	/* Initialize the runtime console */
 	bcm_console_runtime_init();
 }
diff --git a/plat/common/aarch32/plat_common.c b/plat/common/aarch32/plat_common.c
index 2c1a8fa0..89791712 100644
--- a/plat/common/aarch32/plat_common.c
+++ b/plat/common/aarch32/plat_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,14 @@
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <plat/common/platform.h>
 
+/* Pointer and function to register platform function to load alernate images */
+const struct plat_try_images_ops *plat_try_img_ops;
+
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
+{
+	plat_try_img_ops = plat_try_ops;
+}
+
 /*
  * The following platform setup functions are weakly defined. They
  * provide typical implementations that may be re-used by multiple
@@ -14,7 +22,6 @@
  */
 #pragma weak bl32_plat_enable_mmu
 
-
 void bl32_plat_enable_mmu(uint32_t flags)
 {
 	enable_mmu_svc_mon(flags);
diff --git a/plat/common/aarch64/crash_console_helpers.S b/plat/common/aarch64/crash_console_helpers.S
index 75b42089..1a500919 100644
--- a/plat/common/aarch64/crash_console_helpers.S
+++ b/plat/common/aarch64/crash_console_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -100,7 +100,7 @@ endfunc plat_crash_console_init
 	 * int plat_crash_console_putc(char c)
 	 * Prints the character on all consoles registered with the console
 	 * framework that have CONSOLE_FLAG_CRASH set. Note that this is only
-	 * helpful for crashes that occur after the platform intialization code
+	 * helpful for crashes that occur after the platform initialization code
 	 * has registered a console. Platforms using this implementation need to
 	 * ensure that all console drivers they use that have the CRASH flag set
 	 * support this (i.e. are written in assembly and comply to the register
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index ab99b158..7a228b97 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,14 @@
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <plat/common/platform.h>
 
+/* Pointer and function to register platform function to load alernate images */
+const struct plat_try_images_ops *plat_try_img_ops;
+
+void plat_setup_try_img_ops(const struct plat_try_images_ops *plat_try_ops)
+{
+	plat_try_img_ops = plat_try_ops;
+}
+
 /*
  * The following platform setup functions are weakly defined. They
  * provide typical implementations that may be re-used by multiple
@@ -35,7 +43,6 @@
 
 void bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
@@ -71,12 +78,19 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
 
 const char *get_el_str(unsigned int el)
 {
-	if (el == MODE_EL3) {
+	switch (el) {
+	case MODE_EL3:
 		return "EL3";
-	} else if (el == MODE_EL2) {
+	case MODE_EL2:
 		return "EL2";
+	case MODE_EL1:
+		return "EL1";
+	case MODE_EL0:
+		return "EL0";
+	default:
+		assert(false);
+		return NULL;
 	}
-	return "EL1";
 }
 
 #if FFH_SUPPORT
diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c
index bcf9f895..ff0e0828 100644
--- a/plat/common/plat_bl1_common.c
+++ b/plat/common/plat_bl1_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,10 +80,8 @@ int bl1_plat_mem_check(uintptr_t mem_base, unsigned int mem_size,
  */
 int bl1_plat_handle_post_image_load(unsigned int image_id)
 {
-	meminfo_t *bl2_secram_layout;
-	meminfo_t *bl1_secram_layout;
+	meminfo_t *bl1_tzram_layout;
 	image_desc_t *image_desc;
-	entry_point_info_t *ep_info;
 
 	if (image_id != BL2_IMAGE_ID)
 		return 0;
@@ -92,26 +90,41 @@ int bl1_plat_handle_post_image_load(unsigned int image_id)
 	image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
 	assert(image_desc != NULL);
 
-	/* Get the entry point info */
-	ep_info = &image_desc->ep_info;
-
 	/* Find out how much free trusted ram remains after BL1 load */
-	bl1_secram_layout = bl1_plat_sec_mem_layout();
+	bl1_tzram_layout = bl1_plat_sec_mem_layout();
 
 	/*
-	 * Create a new layout of memory for BL2 as seen by BL1 i.e.
-	 * tell it the amount of total and free memory available.
-	 * This layout is created at the first free address visible
-	 * to BL2. BL2 will read the memory layout before using its
-	 * memory for other purposes.
+	 * Convey this information to BL2 by storing the layout at the first free
+	 * address visible to BL2.
 	 */
-	bl2_secram_layout = (meminfo_t *) bl1_secram_layout->total_base;
-
-	bl1_calc_bl2_mem_layout(bl1_secram_layout, bl2_secram_layout);
+	bl1_plat_calc_bl2_layout(bl1_tzram_layout,
+				 (meminfo_t *)bl1_tzram_layout->total_base);
 
-	ep_info->args.arg1 = (uintptr_t)bl2_secram_layout;
+	image_desc->ep_info.args.arg1 = (uintptr_t)bl1_tzram_layout->total_base;
 
 	VERBOSE("BL1: BL2 memory layout address = %p\n",
-		(void *) bl2_secram_layout);
+		(void *)image_desc->ep_info.args.arg1);
+
 	return 0;
 }
+
+/*******************************************************************************
+ * Helper utility to calculate the BL2 memory layout taking into consideration
+ * the BL1 RW data assuming that it is at the top of the memory layout.
+ ******************************************************************************/
+void bl1_plat_calc_bl2_layout(const meminfo_t *bl1_mem_layout,
+			      meminfo_t *bl2_mem_layout)
+{
+	assert(bl1_mem_layout != NULL);
+	assert(bl2_mem_layout != NULL);
+
+	/*
+	 * Remove BL1 RW data from the scope of memory visible to BL2.
+	 * This is assuming BL1 RW data is at the top of bl1_mem_layout.
+	 */
+	assert(BL1_RW_BASE > bl1_mem_layout->total_base);
+	bl2_mem_layout->total_base = bl1_mem_layout->total_base;
+	bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base;
+
+	flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t));
+}
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index 89b77ba6..a603f2b1 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,6 @@
 #pragma weak bl2_plat_preload_setup
 #pragma weak bl2_plat_handle_pre_image_load
 #pragma weak bl2_plat_handle_post_image_load
-#pragma weak plat_try_next_boot_source
 #pragma weak plat_get_enc_key_info
 #pragma weak plat_is_smccc_feature_available
 #pragma weak plat_get_soc_version
@@ -69,11 +68,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 	return 0;
 }
 
-int plat_try_next_boot_source(void)
-{
-	return 0;
-}
-
 /*
  * Weak implementation to provide dummy decryption key only for test purposes,
  * platforms must override this API for any real world firmware encryption
diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c
index baa70e0b..d0c7a31e 100644
--- a/plat/common/plat_gicv3.c
+++ b/plat/common/plat_gicv3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -344,6 +344,11 @@ unsigned int plat_ic_set_priority_mask(unsigned int mask)
 	return gicv3_set_pmr(mask);
 }
 
+unsigned int plat_ic_deactivate_priority(unsigned int mask)
+{
+	return gicv3_deactivate_priority(mask);
+}
+
 unsigned int plat_ic_get_interrupt_id(unsigned int raw)
 {
 	unsigned int id = raw & INT_ID_MASK;
diff --git a/plat/hisilicon/hikey/hikey_bl31_setup.c b/plat/hisilicon/hikey/hikey_bl31_setup.c
index 7d008e74..55b425c4 100644
--- a/plat/hisilicon/hikey/hikey_bl31_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -149,7 +149,3 @@ void bl31_platform_setup(void)
 	hisi_ipc_init();
 	hisi_pwrc_setup();
 }
-
-void bl31_plat_runtime_setup(void)
-{
-}
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index 807a9159..b67d3ff9 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -152,13 +152,13 @@ $(BUILD_PLAT)/bl1/hikey_rotpk.o: $(ROTPK_HASH)
 $(BUILD_PLAT)/bl2/hikey_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
-$(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+$(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-$(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
diff --git a/plat/hisilicon/hikey960/hikey960_bl31_setup.c b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
index 159eee9e..6e80347a 100644
--- a/plat/hisilicon/hikey960/hikey960_bl31_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index fd11a4da..c278d8ed 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -145,13 +145,13 @@ $(BUILD_PLAT)/bl1/hikey960_rotpk.o: $(ROTPK_HASH)
 $(BUILD_PLAT)/bl2/hikey960_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
-$(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+$(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-$(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c
index fe60ddcb..5f4a18a4 100644
--- a/plat/hisilicon/poplar/bl31_plat_setup.c
+++ b/plat/hisilicon/poplar/bl31_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -118,11 +118,6 @@ void bl31_platform_setup(void)
 	hisi_tzpc_sec_init();
 }
 
-void bl31_plat_runtime_setup(void)
-{
-	/* do nothing */
-}
-
 void bl31_plat_arch_setup(void)
 {
 	plat_configure_mmu_el3(BL31_BASE,
diff --git a/plat/hisilicon/poplar/include/hi3798cv200.h b/plat/hisilicon/poplar/include/hi3798cv200.h
index e31f4b3e..802dec53 100644
--- a/plat/hisilicon/poplar/include/hi3798cv200.h
+++ b/plat/hisilicon/poplar/include/hi3798cv200.h
@@ -38,7 +38,11 @@
 
 /* SCTL */
 #define REG_BASE_SCTL			(0xF8000000)
+#define REG_SC_SYSRES			(0x0004)
 #define REG_SC_GEN12			(0x00B0)
+#define REG_SC_LOCKEN			(0x020C)
+
+#define SC_UNLOCK_MAGIC			(0x4F50454E)
 
 /* CRG */
 #define REG_BASE_CRG			(0xF8A22000)
diff --git a/plat/hisilicon/poplar/plat_pm.c b/plat/hisilicon/poplar/plat_pm.c
index 67ebca1c..77fc5327 100644
--- a/plat/hisilicon/poplar/plat_pm.c
+++ b/plat/hisilicon/poplar/plat_pm.c
@@ -92,14 +92,18 @@ static void poplar_pwr_domain_suspend_finish(
 static void __dead2 poplar_system_off(void)
 {
 	ERROR("Poplar System Off: operation not handled.\n");
+	/* Turn off watchdog0 before panic() */
+	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0xc00), 0x1ACCE551);
+	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x8),   0x00000000);
 	panic();
 }
 
 static void __dead2 poplar_system_reset(void)
 {
-	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0xc00), 0x1ACCE551);
-	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x0),   0x00000100);
-	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x8),   0x00000003);
+	/* Unlock Sysctrl critical registers */
+	mmio_write_32((uintptr_t)(REG_BASE_SCTL + REG_SC_LOCKEN), SC_UNLOCK_MAGIC);
+	/* Assert system reset */
+	mmio_write_32((uintptr_t)(REG_BASE_SCTL + REG_SC_SYSRES), 0xfee1dead);
 
 	wfi();
 	ERROR("Poplar System Reset: operation not handled.\n");
diff --git a/plat/imx/common/imx8_helpers.S b/plat/imx/common/imx8_helpers.S
index 19293bfe..eb938336 100644
--- a/plat/imx/common/imx8_helpers.S
+++ b/plat/imx/common/imx8_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -86,6 +86,51 @@ func plat_calc_core_pos
 	ret
 endfunc plat_calc_core_pos
 
+	/* ----------------------------------------------
+	 * function to handle platform specific reset.
+	 * ----------------------------------------------
+	 */
+func plat_reset_handler
+#if defined(PLAT_imx8ulp)
+	/* enable the 512KB cache by default */
+	mov	x0, #IMX_SIM1_BASE
+	/*
+	 * if the RVBADDR is ROM entry, that means we did
+	 * NOT switch the L2 cache to 512KB. default is 256K config,
+	 * so skip
+	 */
+	ldr	w1, [x0, #0x5c]
+	cmp	w1, #0x1000
+	b.eq	1f
+	add	x0, x0, #0x30
+	ldr	w1, [x0]
+	/* if already 512KB config, skip */
+	tbnz	w1, #4, 1f
+	ldr	w1, [x0]
+	orr	w1, w1, #0x10
+	str	w1, [x0]
+	orr	w1, w1, #0x10000
+	str	w1, [x0]
+	b	.
+1:	mrs	x0, CORTEX_A35_CPUECTLR_EL1
+	orr     x0, x0, #(0x1 << 0)
+	orr     x0, x0, #(0x1 << 3)
+	msr	CORTEX_A35_CPUECTLR_EL1, x0
+
+	mrs	x0, CORTEX_A35_L2ECTLR_EL1
+	orr     x0, x0, #(0x1 << 0)
+	msr	CORTEX_A35_L2ECTLR_EL1, x0
+	isb
+#endif
+	/* enable EL2 cpuectlr RW access */
+	mov	x0, #0x73
+	msr	actlr_el3, x0
+	msr	actlr_el2, x0
+	isb
+
+	ret
+endfunc plat_reset_handler
+
 	/* ---------------------------------------------
 	 * function to get the entrypoint.
 	 * ---------------------------------------------
diff --git a/plat/imx/common/imx_bl31_common.c b/plat/imx/common/imx_bl31_common.c
new file mode 100644
index 00000000..f6d7e248
--- /dev/null
+++ b/plat/imx/common/imx_bl31_common.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2023-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <imx_plat_common.h>
+
+uint32_t plat_get_spsr_for_bl33_entry(void)
+{
+	unsigned long el_status;
+	unsigned long mode;
+	uint32_t spsr;
+
+	/* figure out what mode we enter the non-secure world */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
diff --git a/plat/imx/common/imx_common.c b/plat/imx/common/imx_common.c
new file mode 100644
index 00000000..01f354ac
--- /dev/null
+++ b/plat/imx/common/imx_common.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2024, Pengutronix, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <errno.h>
+#include <stdint.h>
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+
+#include <plat_common.h>
+
+/*
+ * This function checks if @arg0 can safely be accessed as a pointer
+ * and if it does, it fills in @bl32_info and @bl33_info with data
+ * found in @arg0.
+ *
+ * Returns 0 when @arg0 can be used as entry point info and a negative
+ * error code otherwise.
+ */
+int imx_bl31_params_parse(uintptr_t arg0, uintptr_t ocram_base,
+			  uintptr_t ocram_size,
+			  entry_point_info_t *bl32_info,
+			  entry_point_info_t *bl33_info)
+{
+	bl_params_t *v2 = (void *)(uintptr_t)arg0;
+
+	if (arg0 & 0x3) {
+		return -EINVAL;
+	}
+
+	if (arg0 < ocram_base || arg0 >= ocram_base + ocram_size) {
+		return -EINVAL;
+	}
+
+	if (v2->h.version != PARAM_VERSION_2) {
+		return -EINVAL;
+	}
+
+	if (v2->h.type != PARAM_BL_PARAMS) {
+		return -EINVAL;
+	}
+
+	bl31_params_parse_helper(arg0, bl32_info, bl33_info);
+
+	return 0;
+}
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index ec8631a4..49fdacf0 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -9,14 +9,24 @@
 #include <stdint.h>
 #include <services/std_svc.h>
 #include <string.h>
-#include <platform_def.h>
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <platform_def.h>
 #include <imx_sip_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/mmio.h>
 #include <sci/sci.h>
 
+#if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+/*
+ * Defined in
+ * table 11. ROM event log buffer address location
+ * AN12853 "i.MX ROMs Log Events"
+ */
+#define ROM_LOG_BUFFER_ADDR	0x9E0
+#endif
+
 #if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
 
 #ifdef PLAT_imx8qm
@@ -177,12 +187,82 @@ int imx_src_handler(uint32_t smc_fid,
 }
 #endif /* defined(PLAT_imx8mm) || defined(PLAT_imx8mq) */
 
+#if defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+static bool is_secondary_boot(void)
+{
+	uint32_t *rom_log_addr = (uint32_t *)ROM_LOG_BUFFER_ADDR;
+	bool is_secondary = false;
+	uint32_t *rom_log;
+	uint8_t event_id;
+
+	/* If the ROM event log pointer is not valid. */
+	if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xB00000 ||
+	    *rom_log_addr & 0x3) {
+		return false;
+	}
+
+	/* Parse the ROM event ID version 2 log */
+	rom_log = (uint32_t *)(uintptr_t)(*rom_log_addr);
+	for (size_t i = 0; i < 128; i++) {
+		event_id = rom_log[i] >> 24;
+		switch (event_id) {
+		case 0x00: /* End of list */
+			return is_secondary;
+		/* Log entries with 1 parameter, skip 1 */
+		case 0x80: /* Perform the device initialization */
+		case 0x81: /* The boot device initialization completes */
+		case 0x82: /* Execute boot device driver pre-config */
+		case 0x8F: /* The boot device initialization fails */
+		case 0x90: /* Start to read data from boot device */
+		case 0x91: /* Reading data from boot device completes */
+		case 0x9F: /* Reading data from boot device fails */
+			i += 1;
+			continue;
+		/* Log entries with 2 parameters, skip 2 */
+		case 0xA0: /* Image authentication result */
+		case 0xC0: /* Jump to the boot image soon */
+			i += 2;
+			continue;
+		/* Booted the primary boot image */
+		case 0x50:
+			is_secondary = false;
+			continue;
+		/* Booted the secondary boot image */
+		case 0x51:
+			is_secondary = true;
+			continue;
+		}
+	}
+
+	return is_secondary;
+}
+
+int imx_src_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    void *handle)
+{
+	switch (x1) {
+	case IMX_SIP_SRC_SET_SECONDARY_BOOT:
+		/* we do support that on these SoCs */
+		break;
+	case IMX_SIP_SRC_IS_SECONDARY_BOOT:
+		return is_secondary_boot();
+	default:
+		return SMC_UNK;
+	};
+
+	return 0;
+}
+#endif /* defined(PLAT_imx8mn) || defined(PLAT_imx8mp) */
+
 static uint64_t imx_get_commit_hash(u_register_t x2,
 		    u_register_t x3,
 		    u_register_t x4)
 {
 	/* Parse the version_string */
-	char *parse = (char *)version_string;
+	char *parse = (char *)build_version_string;
 	uint64_t hash = 0;
 
 	do {
@@ -253,3 +333,16 @@ int imx_kernel_entry_handler(uint32_t smc_fid,
 
 	return 0;
 }
+
+#if defined(PLAT_imx8ulp)
+int imx_hifi_xrdc(uint32_t smc_fid)
+{
+	mmio_setbits_32(IMX_SIM2_BASE + 0x8, BIT_32(19) | BIT_32(17) | BIT_32(18));
+	mmio_clrbits_32(IMX_SIM2_BASE + 0x8, BIT_32(16));
+
+	extern int xrdc_apply_hifi_config(void);
+	xrdc_apply_hifi_config();
+
+	return 0;
+}
+#endif
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 6d6633cf..75b709ad 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -1,14 +1,17 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stdint.h>
+
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
 #include <lib/pmf/pmf.h>
 #include <tools_share/uuid.h>
+
 #include <imx_sip_svc.h>
 
 static int32_t imx_sip_setup(void)
@@ -29,6 +32,17 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid,
 	case IMX_SIP_AARCH32:
 		SMC_RET1(handle, imx_kernel_entry_handler(smc_fid, x1, x2, x3, x4));
 		break;
+#if defined(PLAT_imx8ulp)
+	case IMX_SIP_SCMI:
+		scmi_smt_fastcall_smc_entry(0);
+		SMC_RET1(handle, 0);
+		break;
+	case IMX_SIP_HIFI_XRDC:
+		SMC_RET1(handle, imx_hifi_xrdc(smc_fid));
+		break;
+	case IMX_SIP_DDR_DVFS:
+		return dram_dvfs_handler(smc_fid, handle, x1, x2, x3);
+#endif
 #if defined(PLAT_imx8mq)
 	case IMX_SIP_GET_SOC_INFO:
 		SMC_RET1(handle, imx_soc_info_handler(smc_fid, x1, x2, x3));
@@ -60,12 +74,14 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid,
 	case IMX_SIP_MISC_SET_TEMP:
 		SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
 #endif
-#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq) || defined(PLAT_imx8mn) || \
+	defined(PLAT_imx8mp)
 	case IMX_SIP_SRC:
 		SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
 		break;
 #endif
-#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp) || \
+	defined(PLAT_imx8mq)
 	case IMX_SIP_HAB:
 		SMC_RET1(handle, imx_hab_handler(smc_fid, x1, x2, x3, x4));
 		break;
diff --git a/plat/imx/common/include/imx_plat_common.h b/plat/imx/common/include/imx_plat_common.h
new file mode 100644
index 00000000..8ec9481d
--- /dev/null
+++ b/plat/imx/common/include/imx_plat_common.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2023-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX_PLAT_COMMON_H
+#define IMX_PLAT_COMMON_H
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+
+uint32_t plat_get_spsr_for_bl33_entry(void);
+
+#endif /*IMX_PLAT_COMMON_H */
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 0e91c717..404a8295 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,13 +52,26 @@
 int imx_kernel_entry_handler(uint32_t smc_fid, u_register_t x1,
 			     u_register_t x2, u_register_t x3,
 			     u_register_t x4);
+
+#define IMX_SIP_SCMI			0xC20000FE
+
+#define IMX_SIP_HIFI_XRDC		0xC200000E
+
 #if defined(PLAT_imx8mq)
 int imx_soc_info_handler(uint32_t smc_fid, u_register_t x1,
 			 u_register_t x2, u_register_t x3);
 int imx_gpc_handler(uint32_t smc_fid, u_register_t x1,
 		    u_register_t x2, u_register_t x3);
+#if IMX_DRAM_RETENTION
 int dram_dvfs_handler(uint32_t smc_fid, void *handle,
 	u_register_t x1, u_register_t x2, u_register_t x3);
+#else
+static inline int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+		u_register_t x1, u_register_t x2, u_register_t x3)
+{
+	SMC_RET1(handle, SMC_UNK);
+}
+#endif
 #endif
 #if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
 int dram_dvfs_handler(uint32_t smc_fid, void *handle,
@@ -68,7 +81,9 @@ int imx_gpc_handler(uint32_t smc_fid, u_register_t x1,
 		    u_register_t x2, u_register_t x3);
 #endif
 
-#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq) || defined(PLAT_imx8mn) || \
+	defined(PLAT_imx8mp)
+
 int imx_src_handler(uint32_t smc_fid, u_register_t x1,
 		    u_register_t x2, u_register_t x3, void *handle);
 #endif
@@ -94,5 +109,12 @@ int imx_misc_set_temp_handler(uint32_t smc_fid, u_register_t x1,
 uint64_t imx_buildinfo_handler(uint32_t smc_fid, u_register_t x1,
 			       u_register_t x2, u_register_t x3,
 			       u_register_t x4);
+int scmi_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, u_register_t x3);
+int imx_hifi_xrdc(uint32_t smc_fid);
+
+#if defined(PLAT_imx8ulp)
+int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+	u_register_t x1, u_register_t x2, u_register_t x3);
+#endif
 
 #endif /* __IMX_SIP_SVC_H__ */
diff --git a/plat/imx/common/include/plat_common.h b/plat/imx/common/include/plat_common.h
new file mode 100644
index 00000000..6f412225
--- /dev/null
+++ b/plat/imx/common/include/plat_common.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2024, Pengutronix, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PLAT_COMMON_H
+#define PLAT_COMMON_H
+
+#include <stdint.h>
+#include <common/bl_common.h>
+
+int imx_bl31_params_parse(uintptr_t arg0, uintptr_t ocram_base,
+			  uintptr_t ocram_size,
+			  entry_point_info_t *bl32_info,
+			  entry_point_info_t *bl33_info);
+
+#endif /* PLAT_COMMON_H */
diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk
index 156c55dd..a7e8fe81 100644
--- a/plat/imx/imx7/common/imx7.mk
+++ b/plat/imx/imx7/common/imx7.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -71,21 +71,20 @@ ROT_KEY             = $(BUILD_PLAT)/rot_key.pem
 ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
 
 $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
-$(eval $(call MAKE_LIB_DIRS))
 
 $(BUILD_PLAT)/bl2/imx7_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
 
-$(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+$(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
-$(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
diff --git a/plat/imx/imx8m/ddr/clock.c b/plat/imx/imx8m/ddr/clock.c
index 31f2f560..21a1b684 100644
--- a/plat/imx/imx8m/ddr/clock.c
+++ b/plat/imx/imx8m/ddr/clock.c
@@ -91,12 +91,16 @@ void dram_pll_init(unsigned int drate)
 	case 4000:
 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (250 << 12) | (3 << 4) | 1);
 		break;
+	case 3734:
 	case 3733:
 	case 3732:
 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (311 << 12) | (4 << 4) | 1);
 		break;
+	case 3600:
+		mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (8 << 4) | 0);
+		break;
 	case 3200:
-		mmio_write_32(DRAM_PLL_CTRL + 0x4, (200 << 12) | (3 << 4) | 1);
+		mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (9 << 4) | 0);
 		break;
 	case 2400:
 		mmio_write_32(DRAM_PLL_CTRL + 0x4, (300 << 12) | (3 << 4) | 2);
diff --git a/plat/imx/imx8m/imx8m_ccm.c b/plat/imx/imx8m/imx8m_ccm.c
index 10a00c99..6b14446d 100644
--- a/plat/imx/imx8m/imx8m_ccm.c
+++ b/plat/imx/imx8m/imx8m_ccm.c
@@ -17,16 +17,16 @@ static struct imx_uart {
 } imx8m_uart_info[] = {
 	{	/* UART 1 */
 		.ccm_reg = 0x4490,
-		.uart_base = 0x30860000,
+		.uart_base = IMX_UART1_BASE,
 	}, {	/* UART 2 */
 		.ccm_reg = 0x44a0,
-		.uart_base = 0x30890000,
+		.uart_base = IMX_UART2_BASE,
 	}, {	/* UART 3 */
 		.ccm_reg = 0x44b0,
-		.uart_base = 0x30880000,
+		.uart_base = IMX_UART3_BASE,
 	}, {	/* UART 4 */
 		.ccm_reg = 0x44c0,
-		.uart_base = 0x30a60000,
+		.uart_base = IMX_UART4_BASE,
 	}
 };
 
diff --git a/plat/imx/imx8m/imx8m_measured_boot.c b/plat/imx/imx8m/imx8m_measured_boot.c
index bfcd6ceb..159be00a 100644
--- a/plat/imx/imx8m/imx8m_measured_boot.c
+++ b/plat/imx/imx8m/imx8m_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2022, Linaro.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -9,6 +9,7 @@
 
 #include "./include/imx8m_measured_boot.h"
 #include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
 #include <plat/arm/common/plat_arm.h>
 
 /* Event Log data */
@@ -16,11 +17,11 @@ static uint8_t event_log[PLAT_IMX_EVENT_LOG_MAX_SIZE];
 
 /* FVP table with platform specific image IDs, names and PCRs */
 static const event_log_metadata_t imx8m_event_log_metadata[] = {
-	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
-	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
-	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
-	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
-	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
 
diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
index dc9dd594..03edc6e4 100644
--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c
@@ -30,6 +30,7 @@
 #include <imx8m_ccm.h>
 #include <imx8m_csu.h>
 #include <imx8m_snvs.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -61,7 +62,7 @@ static const struct aipstz_cfg aipstz[] = {
 	{0},
 };
 
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
 	/* Master domain assignment */
 	RDC_MDAn(RDC_MDA_M4, DID1),
 
@@ -77,11 +78,31 @@ static const struct imx_rdc_cfg rdc[] = {
 
 static const struct imx_csu_cfg csu_cfg[] = {
 	/* peripherals csl setting */
-	CSU_CSLx(0x1, CSU_SEC_LEVEL_0, UNLOCKED),
+	CSU_CSLx(CSU_CSL_RDC, CSU_SEC_LEVEL_3, LOCKED),
+	CSU_CSLx(CSU_CSL_TZASC, CSU_SEC_LEVEL_5, LOCKED),
+	CSU_CSLx(CSU_CSL_CSU, CSU_SEC_LEVEL_5, LOCKED),
 
 	/* master HP0~1 */
 
 	/* SA setting */
+	CSU_SA(CSU_SA_M4, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_PCIE_CTRL1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USB1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USB2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_VPU, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_GPU, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_APBHDMA, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ENET, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC3, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_HUGO, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_DAP, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA3, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_LCDIF, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_CSI, NON_SEC_ACCESS, LOCKED),
 
 	/* HP control setting */
 
@@ -134,7 +155,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 {
 	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
-	int i;
+	int i, ret;
 
 	/* Enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -143,14 +164,14 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 
 	imx_aipstz_init(aipstz);
 
-	imx_rdc_init(rdc);
-
-	imx_csu_init(csu_cfg);
-
 	if (console_base == 0U) {
 		console_base = imx8m_uart_get_base();
 	}
 
+	imx_rdc_init(rdc, console_base);
+
+	imx_csu_init(csu_cfg);
+
 	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
@@ -187,6 +208,13 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 #endif
 #endif
+	ret = imx_bl31_params_parse(arg0, IMX_NS_OCRAM_SIZE, IMX_NS_OCRAM_BASE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
+	if (ret != 0) {
+		ret = imx_bl31_params_parse(arg0, IMX_TCM_BASE, IMX_TCM_SIZE,
+					    &bl32_image_ep_info,
+					    &bl33_image_ep_info);
+	}
 
 #if !defined(SPD_opteed) && !defined(SPD_trusty)
 	enable_snvs_privileged_access();
diff --git a/plat/imx/imx8m/imx8mm/include/imx_sec_def.h b/plat/imx/imx8m/imx8mm/include/imx_sec_def.h
index 62159837..d53c922d 100644
--- a/plat/imx/imx8m/imx8mm/include/imx_sec_def.h
+++ b/plat/imx/imx8m/imx8mm/include/imx_sec_def.h
@@ -213,4 +213,26 @@ enum csu_csl_idx {
 	CSU_CSL_CAAM = 114,
 };
 
+enum csu_sa_idx {
+	CSU_SA_M4 = 1,
+	CSU_SA_SDMA1 = 2,
+	CSU_SA_PCIE_CTRL1 = 3,
+	CSU_SA_USB1 = 4,
+	CSU_SA_USB2 = 5,
+	CSU_SA_VPU = 6,
+	CSU_SA_GPU = 7,
+	CSU_SA_APBHDMA = 8,
+	CSU_SA_ENET = 9,
+	CSU_SA_USDHC1 = 10,
+	CSU_SA_USDHC2 = 11,
+	CSU_SA_USDHC3 = 12,
+	CSU_SA_HUGO = 13,
+	CSU_SA_DAP = 14,
+	CSU_SA_SDMA2 = 15,
+	CSU_SA_CAAM = 16,
+	CSU_SA_SDMA3 = 17,
+	CSU_SA_LCDIF = 18,
+	CSU_SA_CSI = 19,
+};
+
 #endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index 65749f34..e6ad8fec 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -60,7 +60,9 @@
 #define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
 
 /* non-secure uboot base */
+#ifndef PLAT_NS_IMAGE_OFFSET
 #define PLAT_NS_IMAGE_OFFSET		U(0x40200000)
+#endif
 #define PLAT_NS_IMAGE_SIZE		U(0x00200000)
 
 #define BL32_FDT_OVERLAY_ADDR		(PLAT_NS_IMAGE_OFFSET + 0x3000000)
@@ -83,6 +85,11 @@
 #define PLAT_CRASH_UART_CLK_IN_HZ	24000000
 #define IMX_CONSOLE_BAUDRATE		115200
 
+#define IMX_UART1_BASE			U(0x30860000)
+#define IMX_UART2_BASE			U(0x30890000)
+#define IMX_UART3_BASE			U(0x30880000)
+#define IMX_UART4_BASE			U(0x30a60000)
+
 #define IMX_AIPSTZ1			U(0x301f0000)
 #define IMX_AIPSTZ2			U(0x305f0000)
 #define IMX_AIPSTZ3			U(0x309f0000)
@@ -116,6 +123,8 @@
 #define IMX_ROM_SIZE			U(0x40000)
 #define IMX_NS_OCRAM_BASE		U(0x900000)
 #define IMX_NS_OCRAM_SIZE		U(0x20000)
+#define IMX_TCM_BASE			U(0x7E0000)
+#define IMX_TCM_SIZE			U(0x40000)
 #define IMX_CAAM_RAM_BASE		U(0x100000)
 #define IMX_CAAM_RAM_SIZE		U(0x10000)
 #define IMX_DRAM_BASE			U(0x40000000)
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index 97f4f248..e54256c1 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -30,7 +30,8 @@ IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
@@ -46,13 +47,13 @@ BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
 				plat/imx/common/imx8_topology.c			\
 				plat/imx/common/imx_sip_handler.c		\
 				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/imx_uart_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${XLAT_TABLES_LIB_SRCS}				\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}
 
 ifeq (${NEED_BL2},yes)
@@ -126,21 +127,20 @@ ROT_KEY             = $(BUILD_PLAT)/rot_key.pem
 ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
 
 $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
-$(eval $(call MAKE_LIB_DIRS))
 
 $(BUILD_PLAT)/bl2/imx8mm_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
 
-$(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+$(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
-$(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
@@ -153,6 +153,18 @@ ERRATA_A53_835769	:=	1
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
+ifneq (${PRELOADED_BL33_BASE},)
+$(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
+endif
+
 BL32_BASE		?=	0xbe000000
 $(eval $(call add_define,BL32_BASE))
 
@@ -176,10 +188,6 @@ ifeq (${MEASURED_BOOT},1)
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
 
-ifneq (${MBOOT_EL_HASH_ALG}, sha256)
-    $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
-endif
-
 BL2_SOURCES		+=	plat/imx/imx8m/imx8m_measured_boot.c	\
 				plat/imx/imx8m/imx8m_dyn_cfg_helpers.c	\
 				${EVENT_LOG_SOURCES}
diff --git a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
index f9e430bf..42d173e7 100644
--- a/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mn/imx8mn_bl31_setup.c
@@ -29,6 +29,7 @@
 #include <imx8m_csu.h>
 #include <imx8m_snvs.h>
 #include <platform_def.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -47,7 +48,7 @@ static const struct aipstz_cfg aipstz[] = {
 	{0},
 };
 
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
 	/* Master domain assignment */
 	RDC_MDAn(RDC_MDA_M7, DID1),
 
@@ -126,7 +127,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
 	unsigned int val;
-	int i;
+	int i, ret;
 
 	/* Enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -135,7 +136,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 
 	imx_aipstz_init(aipstz);
 
-	imx_rdc_init(rdc);
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	imx_rdc_init(rdc, console_base);
 
 	imx_csu_init(csu_cfg);
 
@@ -151,10 +156,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	if (console_base == 0U) {
-		console_base = imx8m_uart_get_base();
-	}
-
 	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
@@ -192,6 +193,13 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 #endif
 #endif
 
+	ret = imx_bl31_params_parse(arg0, IMX_NS_OCRAM_SIZE, IMX_NS_OCRAM_BASE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
+	if (ret != 0) {
+		imx_bl31_params_parse(arg0, IMX_TCM_BASE, IMX_TCM_SIZE,
+				      &bl32_image_ep_info, &bl33_image_ep_info);
+	}
+
 #if !defined(SPD_opteed) && !defined(SPD_trusty)
 	enable_snvs_privileged_access();
 #endif
diff --git a/plat/imx/imx8m/imx8mn/include/imx_sec_def.h b/plat/imx/imx8m/imx8mn/include/imx_sec_def.h
index 0ef14a90..83c5fa95 100644
--- a/plat/imx/imx8m/imx8mn/include/imx_sec_def.h
+++ b/plat/imx/imx8m/imx8mn/include/imx_sec_def.h
@@ -207,4 +207,23 @@ enum csu_csl_idx {
 	CSU_CSL_OCRAM_S = 119,
 };
 
+enum csu_sa_idx {
+	CSU_SA_M7 = 1,
+	CSU_SA_SDMA1 = 2,
+	CSU_SA_USB1 = 4,
+	CSU_SA_GPU = 7,
+	CSU_SA_APBHDMA = 8,
+	CSU_SA_ENET1 = 9,
+	CSU_SA_USDHC1 = 10,
+	CSU_SA_USDHC2 = 11,
+	CSU_SA_USDHC3 = 12,
+	CSU_SA_HUGO = 13,
+	CSU_SA_DAP = 14,
+	CSU_SA_SDMA2 = 15,
+	CSU_SA_CAAM = 16,
+	CSU_SA_SDMA3 = 17,
+	CSU_SA_LCDIF = 18,
+	CSU_SA_ISI = 19,
+};
+
 #endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mn/include/platform_def.h b/plat/imx/imx8m/imx8mn/include/platform_def.h
index d5176dd1..b76bdbfd 100644
--- a/plat/imx/imx8m/imx8mn/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mn/include/platform_def.h
@@ -45,7 +45,9 @@
 #define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
 
 /* non-secure uboot base */
+#ifndef PLAT_NS_IMAGE_OFFSET
 #define PLAT_NS_IMAGE_OFFSET		U(0x40200000)
+#endif
 
 #define BL32_FDT_OVERLAY_ADDR		(PLAT_NS_IMAGE_OFFSET + 0x3000000)
 
@@ -66,6 +68,11 @@
 #define PLAT_CRASH_UART_CLK_IN_HZ	24000000
 #define IMX_CONSOLE_BAUDRATE		115200
 
+#define IMX_UART1_BASE			U(0x30860000)
+#define IMX_UART2_BASE			U(0x30890000)
+#define IMX_UART3_BASE			U(0x30880000)
+#define IMX_UART4_BASE			U(0x30a60000)
+
 #define IMX_AIPSTZ1			U(0x301f0000)
 #define IMX_AIPSTZ2			U(0x305f0000)
 #define IMX_AIPSTZ3			U(0x309f0000)
@@ -138,6 +145,8 @@
 #define OCRAM_S_SIZE			U(0x8000)
 #define OCRAM_S_LIMIT			(OCRAM_S_BASE + OCRAM_S_SIZE)
 #define SAVED_DRAM_TIMING_BASE		OCRAM_S_BASE
+#define IMX_TCM_BASE			U(0x7E0000)
+#define IMX_TCM_SIZE			U(0x40000)
 
 #define COUNTER_FREQUENCY		8000000 /* 8MHz */
 
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index e0826e29..6a9d22e1 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -25,7 +25,8 @@ IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
@@ -41,12 +42,12 @@ BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
 				plat/imx/common/imx8_topology.c			\
 				plat/imx/common/imx_sip_handler.c		\
 				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/imx_uart_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}				\
 				${XLAT_TABLES_LIB_SRCS}
 
@@ -59,6 +60,18 @@ ERRATA_A53_835769	:=	1
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
+ifneq (${PRELOADED_BL33_BASE},)
+$(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
+endif
+
 BL32_BASE		?=	0xbe000000
 $(eval $(call add_define,BL32_BASE))
 
diff --git a/plat/imx/imx8m/imx8mp/gpc.c b/plat/imx/imx8m/imx8mp/gpc.c
index 956b5081..a95eb365 100644
--- a/plat/imx/imx8m/imx8mp/gpc.c
+++ b/plat/imx/imx8m/imx8mp/gpc.c
@@ -374,12 +374,20 @@ void imx_gpc_init(void)
 	mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG1PHY_SCR, 0x1);
 	mmio_clrbits_32(IMX_SRC_BASE + SRC_OTG2PHY_SCR, 0x1);
 
-	/* enable all the power domain by default */
+	/* enable all clocks by default */
 	for (i = 0; i < 101; i++) {
 		mmio_write_32(IMX_CCM_BASE + CCGR(i), 0x3);
 	}
 
-	for (i = 0; i < 20; i++) {
-		imx_gpc_pm_domain_enable(i, true);
-	}
+	/* Depending on SKU, we may be lacking e.g. a VPU and shouldn't
+	 * access that domain here, because that would lockup the SoC.
+	 * Other i.MX8M variants don't initialize any power domains, but
+	 * for 8MP we have been enabling the USB power domains since the
+	 * beginning and stopping to do this now may render systems
+	 * unrecoverable. So we'll keep initializing just the USB power
+	 * domains instead of all of them like before.
+	 */
+	imx_gpc_pm_domain_enable(HSIOMIX, true);
+	imx_gpc_pm_domain_enable(USB1_PHY, true);
+	imx_gpc_pm_domain_enable(USB2_PHY, true);
 }
diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
index 43fa0646..141c94bb 100644
--- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c
@@ -29,6 +29,7 @@
 #include <imx8m_csu.h>
 #include <imx8m_snvs.h>
 #include <platform_def.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -48,7 +49,7 @@ static const struct aipstz_cfg aipstz[] = {
 	{0},
 };
 
-static const struct imx_rdc_cfg rdc[] = {
+static struct imx_rdc_cfg rdc[] = {
 	/* Master domain assignment */
 	RDC_MDAn(RDC_MDA_M7, DID1),
 
@@ -63,12 +64,45 @@ static const struct imx_rdc_cfg rdc[] = {
 
 static const struct imx_csu_cfg csu_cfg[] = {
 	/* peripherals csl setting */
-	CSU_CSLx(CSU_CSL_OCRAM, CSU_SEC_LEVEL_2, UNLOCKED),
-	CSU_CSLx(CSU_CSL_OCRAM_S, CSU_SEC_LEVEL_2, UNLOCKED),
+	CSU_CSLx(CSU_CSL_OCRAM, CSU_SEC_LEVEL_2, LOCKED),
+	CSU_CSLx(CSU_CSL_OCRAM_S, CSU_SEC_LEVEL_2, LOCKED),
+	CSU_CSLx(CSU_CSL_RDC, CSU_SEC_LEVEL_3, LOCKED),
+	CSU_CSLx(CSU_CSL_TZASC, CSU_SEC_LEVEL_5, LOCKED),
+	CSU_CSLx(CSU_CSL_CSU, CSU_SEC_LEVEL_5, LOCKED),
 
 	/* master HP0~1 */
 
 	/* SA setting */
+	CSU_SA(CSU_SA_M7, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_PCIE_CTRL1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USB1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USB2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_APB_HDMA, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ENET1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_USDHC3, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_HUGO, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_DAP, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_SDMA3, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_LCDIF1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ISI, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_NPU, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_LCDIF2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_HDMI_TX, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ENET2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_GPU3D, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_GPU2D, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_VPU_G1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_VPU_G2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_VPU_VC8000E, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_AUDIO_EDMA, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ISP1, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_ISP2, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_DEWARP, NON_SEC_ACCESS, LOCKED),
+	CSU_SA(CSU_SA_GIC500, NON_SEC_ACCESS, LOCKED),
 
 	/* HP control setting */
 
@@ -123,6 +157,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	static console_t console;
 	unsigned int val;
 	unsigned int i;
+	int ret;
 
 	/* Enable CSU NS access permission */
 	for (i = 0; i < 64; i++) {
@@ -131,7 +166,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 
 	imx_aipstz_init(aipstz);
 
-	imx_rdc_init(rdc);
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	imx_rdc_init(rdc, console_base);
 
 	imx_csu_init(csu_cfg);
 
@@ -140,10 +179,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x2c);
 	mmio_write_32(IMX_IOMUX_GPR_BASE + 0x2c, val | 0x3DFF0000);
 
-	if (console_base == 0U) {
-		console_base = imx8m_uart_get_base();
-	}
-
 	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
@@ -180,6 +215,13 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 #endif
 #endif
+	ret = imx_bl31_params_parse(arg0, IMX_NS_OCRAM_SIZE, IMX_NS_OCRAM_BASE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
+	if (ret != 0) {
+		ret = imx_bl31_params_parse(arg0, IMX_TCM_BASE, IMX_TCM_SIZE,
+					    &bl32_image_ep_info,
+					    &bl33_image_ep_info);
+	}
 
 #if !defined(SPD_opteed) && !defined(SPD_trusty)
 	enable_snvs_privileged_access();
diff --git a/plat/imx/imx8m/imx8mp/include/imx_sec_def.h b/plat/imx/imx8m/imx8mp/include/imx_sec_def.h
index ba248b59..1ba30339 100644
--- a/plat/imx/imx8m/imx8mp/include/imx_sec_def.h
+++ b/plat/imx/imx8m/imx8mp/include/imx_sec_def.h
@@ -269,6 +269,41 @@ enum csu_csl_idx {
 	CSU_CSL_OCRAM_A = 113,
 	CSU_CSL_OCRAM = 118,
 	CSU_CSL_OCRAM_S = 119,
+	CSU_CSL_VPU = 120,
+};
+
+enum csu_sa_idx {
+	CSU_SA_M7 = 1,
+	CSU_SA_SDMA1 = 2,
+	CSU_SA_PCIE_CTRL1 = 3,
+	CSU_SA_USB1 = 4,
+	CSU_SA_USB2 = 6,
+	CSU_SA_APB_HDMA = 8,
+	CSU_SA_ENET1 = 9,
+	CSU_SA_USDHC1 = 10,
+	CSU_SA_USDHC2 = 11,
+	CSU_SA_USDHC3 = 12,
+	CSU_SA_HUGO = 13,
+	CSU_SA_DAP = 14,
+	CSU_SA_SDMA2 = 15,
+	CSU_SA_CAAM = 16,
+	CSU_SA_SDMA3 = 17,
+	CSU_SA_LCDIF1 = 18,
+	CSU_SA_ISI = 19,
+	CSU_SA_NPU = 20,
+	CSU_SA_LCDIF2 = 21,
+	CSU_SA_HDMI_TX = 22,
+	CSU_SA_ENET2 = 23,
+	CSU_SA_GPU3D = 24,
+	CSU_SA_GPU2D = 25,
+	CSU_SA_VPU_G1 = 26,
+	CSU_SA_VPU_G2 = 27,
+	CSU_SA_VPU_VC8000E = 28,
+	CSU_SA_AUDIO_EDMA = 29,
+	CSU_SA_ISP1 = 30,
+	CSU_SA_ISP2 = 31,
+	CSU_SA_DEWARP = 32,
+	CSU_SA_GIC500 = 33,
 };
 
 #endif /* IMX_SEC_DEF_H */
diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h
index 12812705..78f3d5b8 100644
--- a/plat/imx/imx8m/imx8mp/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mp/include/platform_def.h
@@ -62,7 +62,9 @@
 #define PLAT_SDEI_SGI_PRIVATE		U(9)
 
 /* non-secure uboot base */
+#ifndef PLAT_NS_IMAGE_OFFSET
 #define PLAT_NS_IMAGE_OFFSET		U(0x40200000)
+#endif
 #define PLAT_NS_IMAGE_SIZE		U(0x00200000)
 
 #define BL32_FDT_OVERLAY_ADDR		(PLAT_NS_IMAGE_OFFSET + 0x3000000)
@@ -84,6 +86,11 @@
 #define PLAT_CRASH_UART_CLK_IN_HZ	24000000
 #define IMX_CONSOLE_BAUDRATE		115200
 
+#define IMX_UART1_BASE			U(0x30860000)
+#define IMX_UART2_BASE			U(0x30890000)
+#define IMX_UART3_BASE			U(0x30880000)
+#define IMX_UART4_BASE			U(0x30a60000)
+
 #define IMX_AIPSTZ1			U(0x301f0000)
 #define IMX_AIPSTZ2			U(0x305f0000)
 #define IMX_AIPSTZ3			U(0x309f0000)
@@ -170,6 +177,9 @@
 
 #define MAX_CSU_NUM			U(64)
 
+#define IMX_TCM_BASE			U(0x7E0000)
+#define IMX_TCM_SIZE			U(0x40000)
+
 #define OCRAM_S_BASE			U(0x00180000)
 #define OCRAM_S_SIZE			U(0x8000)
 #define OCRAM_S_LIMIT			(OCRAM_S_BASE + OCRAM_S_SIZE)
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index ce690719..98b99d11 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -26,7 +26,8 @@ IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_hab.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
@@ -42,12 +43,12 @@ BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
 				plat/imx/common/imx8_topology.c			\
 				plat/imx/common/imx_sip_handler.c		\
 				plat/imx/common/imx_sip_svc.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/imx_uart_console.S		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				drivers/arm/tzc/tzc380.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}				\
 				${XLAT_TABLES_LIB_SRCS}
 
@@ -123,21 +124,20 @@ ROT_KEY             = $(BUILD_PLAT)/rot_key.pem
 ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
 
 $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
-$(eval $(call MAKE_LIB_DIRS))
 
 $(BUILD_PLAT)/bl2/imx8mp_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
 
-$(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+$(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
-$(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
@@ -150,6 +150,18 @@ ERRATA_A53_835769	:=	1
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
+ifneq (${PRELOADED_BL33_BASE},)
+$(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
+endif
+
 BL32_BASE		?=	0x56000000
 $(eval $(call add_define,BL32_BASE))
 
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index 7065a658..70c2def7 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
@@ -26,6 +26,7 @@
 #include <imx_aipstz.h>
 #include <imx_uart.h>
 #include <imx8m_caam.h>
+#include <imx8m_ccm.h>
 #include <plat_imx8.h>
 
 #define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
@@ -145,6 +146,7 @@ static void bl31_tz380_setup(void)
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
+	unsigned int console_base = IMX_BOOT_UART_BASE;
 	static console_t console;
 	int i;
 	/* enable CSU NS access permission */
@@ -154,7 +156,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 
 	imx_aipstz_init(aipstz);
 
-	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+	if (console_base == 0U) {
+		console_base = imx8m_uart_get_base();
+	}
+
+	console_imx_uart_register(console_base, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 	/* This console is only used for boot stage */
 	console_set_scope(&console, CONSOLE_FLAG_BOOT);
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index 2526a02d..61c0e8e4 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -38,7 +38,9 @@
 #define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
 
 /* non-secure uboot base */
+#ifndef PLAT_NS_IMAGE_OFFSET
 #define PLAT_NS_IMAGE_OFFSET		U(0x40200000)
+#endif
 #define BL32_FDT_OVERLAY_ADDR		(PLAT_NS_IMAGE_OFFSET + 0x3000000)
 
 /* GICv3 base address */
@@ -63,6 +65,11 @@
 #define PLAT_CRASH_UART_CLK_IN_HZ	25000000
 #define IMX_CONSOLE_BAUDRATE		115200
 
+#define IMX_UART1_BASE			U(0x30860000)
+#define IMX_UART2_BASE			U(0x30890000)
+#define IMX_UART3_BASE			U(0x30880000)
+#define IMX_UART4_BASE			U(0x30a60000)
+
 #define IMX_AIPS_BASE			U(0x30200000)
 #define IMX_AIPS_SIZE			U(0xC00000)
 #define IMX_AIPS1_BASE			U(0x30200000)
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index b1c189fa..73179dd0 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -31,6 +31,7 @@ BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
 				plat/imx/imx8m/gpc_common.c			\
 				plat/imx/imx8m/imx_aipstz.c			\
 				plat/imx/imx8m/imx8m_caam.c			\
+				plat/imx/imx8m/imx8m_ccm.c			\
 				plat/imx/imx8m/imx8m_psci_common.c		\
 				plat/imx/imx8m/imx8mq/gpc.c			\
 				plat/imx/common/imx8_topology.c			\
@@ -42,7 +43,6 @@ BL31_SOURCES		+=	plat/imx/common/imx8_helpers.S			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${XLAT_TABLES_LIB_SRCS}				\
-				${IMX_DRAM_SOURCES}				\
 				${IMX_GIC_SOURCES}
 
 ENABLE_PIE		:=	1
@@ -55,6 +55,18 @@ ERRATA_A53_835769	:=	1
 ERRATA_A53_843419	:=	1
 ERRATA_A53_855873	:=	1
 
+IMX_DRAM_RETENTION	?=	0
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES		+=	${IMX_DRAM_SOURCES}
+endif
+
+ifneq (${PRELOADED_BL33_BASE},)
+$(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
+endif
+
 BL32_BASE		?=	0xfe000000
 $(eval $(call add_define,BL32_BASE))
 
@@ -62,6 +74,9 @@ BL32_SIZE		?=	0x2000000
 $(eval $(call add_define,BL32_SIZE))
 
 IMX_BOOT_UART_BASE	?=	0x30860000
+ifeq (${IMX_BOOT_UART_BASE},auto)
+    override IMX_BOOT_UART_BASE	:=	0
+endif
 $(eval $(call add_define,IMX_BOOT_UART_BASE))
 
 ifeq (${SPD},trusty)
diff --git a/plat/imx/imx8m/imx_rdc.c b/plat/imx/imx8m/imx_rdc.c
index 85de1911..de159565 100644
--- a/plat/imx/imx8m/imx_rdc.c
+++ b/plat/imx/imx8m/imx_rdc.c
@@ -4,13 +4,78 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <errno.h>
+
 #include <lib/mmio.h>
 
 #include <imx_rdc.h>
 
-void imx_rdc_init(const struct imx_rdc_cfg *rdc_cfg)
+struct imx_uart {
+	int index;
+	unsigned int uart_base;
+};
+
+static const struct imx_uart imx8m_uart_info[] = {
+	{	/* UART 1 */
+		.index = RDC_PDAP_UART1,
+		.uart_base = IMX_UART1_BASE,
+	}, {	/* UART 2 */
+		.index = RDC_PDAP_UART2,
+		.uart_base = IMX_UART2_BASE,
+	}, {	/* UART 3 */
+		.index = RDC_PDAP_UART3,
+		.uart_base = IMX_UART3_BASE,
+	}, {	/* UART 4 */
+		.index = RDC_PDAP_UART4,
+		.uart_base = IMX_UART4_BASE,
+	}
+};
+
+static int imx_rdc_uart_get_pdap_index(unsigned int uart_base)
+{
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(imx8m_uart_info); i++) {
+		if (imx8m_uart_info[i].uart_base == uart_base) {
+			return imx8m_uart_info[i].index;
+		}
+	}
+
+	return -ENODEV;
+}
+
+static void imx_rdc_console_access_enable(struct imx_rdc_cfg *rdc_cfg,
+				   unsigned int console_base)
+{
+	struct imx_rdc_cfg *rdc;
+	int console_pdap_index;
+
+	console_pdap_index = imx_rdc_uart_get_pdap_index(console_base);
+	if (console_pdap_index < 0) {
+		return;
+	}
+
+	for (rdc = rdc_cfg; rdc->type != RDC_INVALID; rdc++) {
+		if (rdc->type != RDC_PDAP || rdc->index != console_pdap_index) {
+			continue;
+		}
+
+		if (rdc->index == console_pdap_index &&
+		    rdc->setting.rdc_pdap == (D0R | D0W)) {
+			return;
+		}
+
+		if (rdc->index == console_pdap_index) {
+			rdc->setting.rdc_pdap = D0R | D0W;
+		}
+	}
+}
+
+void imx_rdc_init(struct imx_rdc_cfg *rdc_cfg, unsigned int console_base)
 {
-	const struct imx_rdc_cfg *rdc = rdc_cfg;
+	struct imx_rdc_cfg *rdc = rdc_cfg;
+
+	imx_rdc_console_access_enable(rdc, console_base);
 
 	while (rdc->type != RDC_INVALID) {
 		switch (rdc->type) {
diff --git a/plat/imx/imx8m/include/dram.h b/plat/imx/imx8m/include/dram.h
index 719c3906..1cf0666e 100644
--- a/plat/imx/imx8m/include/dram.h
+++ b/plat/imx/imx8m/include/dram.h
@@ -70,13 +70,19 @@ struct dram_info {
 
 extern struct dram_info dram_info;
 
-void dram_info_init(unsigned long dram_timing_base);
 void dram_umctl2_init(struct dram_timing_info *timing);
 void dram_phy_init(struct dram_timing_info *timing);
 
 /* dram retention */
+#if IMX_DRAM_RETENTION
+void dram_info_init(unsigned long dram_timing_base);
 void dram_enter_retention(void);
 void dram_exit_retention(void);
+#else
+static inline void dram_info_init(unsigned long dram_timing_base) {}
+static inline void dram_enter_retention(void) {}
+static inline void dram_exit_retention(void) {}
+#endif
 
 void dram_clock_switch(unsigned int target_drate, bool bypass_mode);
 
diff --git a/plat/imx/imx8m/include/imx8m_csu.h b/plat/imx/imx8m/include/imx8m_csu.h
index dc634ed9..3851e913 100644
--- a/plat/imx/imx8m/include/imx8m_csu.h
+++ b/plat/imx/imx8m/include/imx8m_csu.h
@@ -20,6 +20,9 @@
 #define CSU_SEC_LEVEL_6		0x03
 #define CSU_SEC_LEVEL_7		0x0
 
+#define SEC_ACCESS		0x0
+#define NON_SEC_ACCESS		0x1
+
 #define LOCKED			0x1
 #define UNLOCKED		0x0
 
@@ -27,11 +30,11 @@
 #define CSLx_LOCK(x)		((0x1 << (((x) % 2) * 16 + 8)))
 #define CSLx_CFG(x, n)		((x) << (((n) % 2) * 16))
 
-#define CSU_HP_REG(x)		(IMX_CSU_BASE + ((x) / 16) * 4 + 0x200)
+#define CSU_HP_REG(x)		(IMX_CSU_BASE + (((x) / 16) * 4) + 0x200)
 #define CSU_HP_LOCK(x)		((0x1 << (((x) % 16) * 2 + 1)))
 #define CSU_HP_CFG(x, n)	((x) << (((n) % 16) * 2))
 
-#define CSU_SA_REG(x)		(IMX_CSU_BASE + 0x218)
+#define CSU_SA_REG(x)		(IMX_CSU_BASE + (((x) / 16) * 4) + 0x218)
 #define CSU_SA_LOCK(x)		((0x1 << (((x) % 16) * 2 + 1)))
 #define CSU_SA_CFG(x, n)	((x) << (((n) % 16) * 2))
 
diff --git a/plat/imx/imx8m/include/imx_rdc.h b/plat/imx/imx8m/include/imx_rdc.h
index a6e10a7b..fbdcbf29 100644
--- a/plat/imx/imx8m/include/imx_rdc.h
+++ b/plat/imx/imx8m/include/imx_rdc.h
@@ -67,7 +67,7 @@ struct imx_rdc_cfg {
 	  .setting.rdc_mem_region[2] = (mrc),	\
 	}
 
-void imx_rdc_init(const struct imx_rdc_cfg *cfg);
+void imx_rdc_init(struct imx_rdc_cfg *cfg, unsigned int console_base);
 
 #endif /* IMX_RDC_H */
 
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index bd7896a9..4c637402 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -408,8 +408,3 @@ unsigned int plat_get_syscnt_freq2(void)
 {
 	return COUNTER_FREQUENCY;
 }
-
-void bl31_plat_runtime_setup(void)
-{
-	return;
-}
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index 13e80fb3..08bf8f39 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -386,8 +386,3 @@ unsigned int plat_get_syscnt_freq2(void)
 {
 	return COUNTER_FREQUENCY;
 }
-
-void bl31_plat_runtime_setup(void)
-{
-	return;
-}
diff --git a/plat/imx/imx8ulp/apd_context.c b/plat/imx/imx8ulp/apd_context.c
new file mode 100644
index 00000000..54b87958
--- /dev/null
+++ b/plat/imx/imx8ulp/apd_context.c
@@ -0,0 +1,657 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <plat_imx8.h>
+#include <xrdc.h>
+
+#define PCC_PR	BIT(31)
+#define PFD_VALID_MASK	U(0x40404040)
+
+#define S400_MU_BASE	U(0x27020000)
+#define S400_MU_RSR	(S400_MU_BASE + 0x12c)
+#define S400_MU_TRx(i)	(S400_MU_BASE + 0x200 + (i) * 4)
+#define S400_MU_RRx(i)	(S400_MU_BASE + 0x280 + (i) * 4)
+
+/*
+ * need to re-init the PLL, CGC1, PCC, CMC, XRDC, SIM, GPIO etc.
+ * init the PLL &PFD first, then switch the CA35 clock to PLL for
+ * performance consideration, restore other bus fabric clock.
+ */
+
+extern void imx8ulp_caam_init(void);
+extern void upower_wait_resp(void);
+extern void dram_enter_retention(void);
+extern void dram_exit_retention(void);
+
+struct plat_gic_ctx imx_gicv3_ctx;
+static uint32_t cmc1_pmprot;
+static uint32_t cmc1_srie;
+
+/* TPM5: global timer */
+static uint32_t tpm5[3];
+
+static uint32_t wdog3[2];
+
+/* CGC1 PLL2 */
+uint32_t pll2[][2] = {
+	{0x292c0510, 0x0}, {0x292c0518, 0x0}, {0x292c051c, 0x0},
+	{0x292c0520, 0x0}, {0x292c0500, 0x0},
+};
+
+/* CGC1 PLL3 */
+uint32_t pll3[][2] = {
+	{0x292c0604, 0x0}, {0x292c0608, 0x0}, {0x292c060c, 0x0},
+	{0x292c0610, 0x0}, {0x292c0618, 0x0}, {0x292c061c, 0x0},
+	{0x292c0620, 0x0}, {0x292c0624, 0x0}, {0x292c0600, 0x0},
+	{0x292c0614, 0x0},
+};
+
+/* CGC1 others */
+uint32_t cgc1[][2] = {
+	{0x292c0014, 0x0}, {0x292c0034, 0x0}, {0x292c0038, 0x0},
+	{0x292c0108, 0x0}, {0x292c0208, 0x0}, {0x292c0700, 0x0},
+	{0x292c0810, 0x0}, {0x292c0900, 0x0}, {0x292c0904, 0x0},
+	{0x292c0908, 0x0}, {0x292c090c, 0x0}, {0x292c0a00, 0x0},
+};
+
+static uint32_t pcc3[61];
+static uint32_t pcc4[32];
+
+static uint32_t pcc5_0[33];
+static uint32_t pcc5_1[][2] = {
+	{0x2da70084, 0x0}, {0x2da70088, 0x0}, {0x2da7008c, 0x0},
+	{0x2da700a0, 0x0}, {0x2da700a4, 0x0}, {0x2da700a8, 0x0},
+	{0x2da700ac, 0x0}, {0x2da700b0, 0x0}, {0x2da700b4, 0x0},
+	{0x2da700bc, 0x0}, {0x2da700c0, 0x0}, {0x2da700c8, 0x0},
+	{0x2da700cc, 0x0}, {0x2da700d0, 0x0}, {0x2da700f0, 0x0},
+	{0x2da700f4, 0x0}, {0x2da700f8, 0x0}, {0x2da70108, 0x0},
+	{0x2da7010c, 0x0}, {0x2da70110, 0x0}, {0x2da70114, 0x0},
+};
+
+static uint32_t cgc2[][2] = {
+	{0x2da60014, 0x0}, {0x2da60020, 0x0}, {0x2da6003c, 0x0},
+	{0x2da60040, 0x0}, {0x2da60108, 0x0}, {0x2da60208, 0x0},
+	{0x2da60900, 0x0}, {0x2da60904, 0x0}, {0x2da60908, 0x0},
+	{0x2da60910, 0x0}, {0x2da60a00, 0x0},
+};
+
+static uint32_t pll4[][2] = {
+	{0x2da60604, 0x0}, {0x2da60608, 0x0}, {0x2da6060c, 0x0},
+	{0x2da60610, 0x0}, {0x2da60618, 0x0}, {0x2da6061c, 0x0},
+	{0x2da60620, 0x0}, {0x2da60624, 0x0}, {0x2da60600, 0x0},
+	{0x2da60614, 0x0},
+};
+
+static uint32_t lpav_sim[][2] = {
+	{0x2da50000, 0x0}, {0x2da50004, 0x0}, {0x2da50008, 0x0},
+	{0x2da5001c, 0x0}, {0x2da50020, 0x0}, {0x2da50024, 0x0},
+	{0x2da50034, 0x0},
+};
+
+#define APD_GPIO_CTRL_NUM		2
+#define LPAV_GPIO_CTRL_NUM		1
+#define GPIO_CTRL_REG_NUM		8
+#define GPIO_PIN_MAX_NUM	32
+#define GPIO_CTX(addr, num)	\
+	{.base = (addr), .pin_num = (num), }
+
+struct gpio_ctx {
+	/* gpio base */
+	uintptr_t base;
+	/* port control */
+	uint32_t port_ctrl[GPIO_CTRL_REG_NUM];
+	/* GPIO ICR, Max 32 */
+	uint32_t pin_num;
+	uint32_t gpio_icr[GPIO_PIN_MAX_NUM];
+};
+
+static uint32_t gpio_ctrl_offset[GPIO_CTRL_REG_NUM] = {
+	 0xc, 0x10, 0x14, 0x18, 0x1c, 0x40, 0x54, 0x58
+};
+static struct gpio_ctx apd_gpio_ctx[APD_GPIO_CTRL_NUM] = {
+	GPIO_CTX(IMX_GPIOE_BASE, 24),
+	GPIO_CTX(IMX_GPIOF_BASE, 32),
+};
+
+static struct gpio_ctx lpav_gpio_ctx = GPIO_CTX(IMX_GPIOD_BASE, 24);
+/* iomuxc setting */
+#define IOMUXC_SECTION_NUM	8
+struct iomuxc_section {
+	uint32_t offset;
+	uint32_t reg_num;
+};
+
+struct iomuxc_section iomuxc_sections[IOMUXC_SECTION_NUM] = {
+	{.offset = IOMUXC_PTD_PCR_BASE, .reg_num = 24},
+	{.offset = IOMUXC_PTE_PCR_BASE, .reg_num = 24},
+	{.offset = IOMUXC_PTF_PCR_BASE, .reg_num = 32},
+	{.offset = IOMUXC_PSMI_BASE0, .reg_num = 10},
+	{.offset = IOMUXC_PSMI_BASE1, .reg_num = 61},
+	{.offset = IOMUXC_PSMI_BASE2, .reg_num = 12},
+	{.offset = IOMUXC_PSMI_BASE3, .reg_num = 20},
+	{.offset = IOMUXC_PSMI_BASE4, .reg_num = 75},
+};
+static uint32_t iomuxc_ctx[258];
+
+#define PORTS_NUM		3U
+void apd_io_pad_off(void)
+{
+	unsigned int i, j;
+
+	/* off the PTD/E/F, need to be customized based on actual user case */
+	for (i = 0; i < PORTS_NUM; i++) {
+		for (j = 0; j < iomuxc_sections[i].reg_num; j++) {
+			mmio_write_32(iomuxc_sections[i].offset + j * 4, 0);
+		}
+	}
+
+	/* disable the PTD compensation */
+	mmio_write_32(IMX_SIM1_BASE + 0x48, 0x800);
+}
+
+void iomuxc_save(void)
+{
+	unsigned int i, j;
+	unsigned int index = 0U;
+
+	for (i = 0U; i < IOMUXC_SECTION_NUM; i++) {
+		for (j = 0U; j < iomuxc_sections[i].reg_num; j++) {
+			iomuxc_ctx[index++] = mmio_read_32(iomuxc_sections[i].offset + j * 4);
+		}
+	}
+
+	apd_io_pad_off();
+}
+
+void iomuxc_restore(void)
+{
+	unsigned int i, j;
+	unsigned int index = 0U;
+
+	for (i = 0U; i < IOMUXC_SECTION_NUM; i++) {
+		for (j = 0U; j < iomuxc_sections[i].reg_num; j++) {
+			mmio_write_32(iomuxc_sections[i].offset + j * 4, iomuxc_ctx[index++]);
+		}
+	}
+}
+
+void gpio_save(struct gpio_ctx *ctx, int port_num)
+{
+	unsigned int i, j;
+
+	for (i = 0U; i < port_num; i++) {
+		/* save the port control setting */
+		for (j = 0U; j < GPIO_CTRL_REG_NUM; j++) {
+			if (j < 4U) {
+				ctx->port_ctrl[j] = mmio_read_32(ctx->base + gpio_ctrl_offset[j]);
+				/*
+				 * clear the permission setting to read the GPIO
+				 * non-secure world setting.
+				 */
+				mmio_write_32(ctx->base + gpio_ctrl_offset[j], 0x0);
+			} else {
+				ctx->port_ctrl[j] = mmio_read_32(ctx->base + gpio_ctrl_offset[j]);
+			}
+		}
+		/* save the gpio icr setting */
+		for (j = 0U; j < ctx->pin_num; j++) {
+			ctx->gpio_icr[j] = mmio_read_32(ctx->base + 0x80 + j * 4);
+		}
+
+		ctx++;
+	}
+}
+
+void gpio_restore(struct gpio_ctx *ctx, int port_num)
+{
+	unsigned int i, j;
+
+	for (i = 0U; i < port_num; i++) {
+		for (j = 0U; j < ctx->pin_num; j++)
+			mmio_write_32(ctx->base + 0x80 + j * 4, ctx->gpio_icr[j]);
+
+		for (j = 4U; j < GPIO_CTRL_REG_NUM; j++) {
+			mmio_write_32(ctx->base + gpio_ctrl_offset[j], ctx->port_ctrl[j]);
+		}
+
+		/* permission config retore last */
+		for (j = 0U; j < 4; j++) {
+			mmio_write_32(ctx->base + gpio_ctrl_offset[j], ctx->port_ctrl[j]);
+		}
+
+		ctx++;
+	}
+}
+
+void cgc1_save(void)
+{
+	unsigned int i;
+
+	/* PLL2 */
+	for (i = 0U; i < ARRAY_SIZE(pll2); i++) {
+		pll2[i][1] = mmio_read_32(pll2[i][0]);
+	}
+
+	/* PLL3 */
+	for (i = 0U; i < ARRAY_SIZE(pll3); i++) {
+		pll3[i][1] = mmio_read_32(pll3[i][0]);
+	}
+
+	/* CGC1 others */
+	for (i = 0U; i < ARRAY_SIZE(cgc1); i++) {
+		cgc1[i][1] = mmio_read_32(cgc1[i][0]);
+	}
+}
+
+void cgc1_restore(void)
+{
+	unsigned int i;
+
+	/* PLL2 */
+	for (i = 0U; i < ARRAY_SIZE(pll2); i++) {
+		mmio_write_32(pll2[i][0], pll2[i][1]);
+	}
+	/* wait for PLL2 lock */
+	while (!(mmio_read_32(pll2[4][0]) & BIT(24))) {
+		;
+	}
+
+	/* PLL3 */
+	for (i = 0U; i < 9U; i++) {
+		mmio_write_32(pll3[i][0], pll3[i][1]);
+	}
+
+	/* wait for PLL3 lock */
+	while (!(mmio_read_32(pll3[4][0]) & BIT(24))) {
+		;
+	}
+
+	/* restore the PFDs */
+	mmio_write_32(pll3[9][0], pll3[9][1] & ~(BIT(31) | BIT(23) | BIT(15) | BIT(7)));
+	mmio_write_32(pll3[9][0], pll3[9][1]);
+
+	/* wait for the PFD is stable, only need to check the enabled PFDs */
+	while (!(mmio_read_32(pll3[9][0]) & PFD_VALID_MASK)) {
+		;
+	}
+
+	/* CGC1 others */
+	for (i = 0U; i < ARRAY_SIZE(cgc1); i++) {
+		mmio_write_32(cgc1[i][0], cgc1[i][1]);
+	}
+}
+
+void tpm5_save(void)
+{
+	tpm5[0] = mmio_read_32(IMX_TPM5_BASE + 0x10);
+	tpm5[1] = mmio_read_32(IMX_TPM5_BASE + 0x18);
+	tpm5[2] = mmio_read_32(IMX_TPM5_BASE + 0x20);
+}
+
+void tpm5_restore(void)
+{
+	mmio_write_32(IMX_TPM5_BASE + 0x10, tpm5[0]);
+	mmio_write_32(IMX_TPM5_BASE + 0x18, tpm5[1]);
+	mmio_write_32(IMX_TPM5_BASE + 0x20, tpm5[2]);
+}
+
+void wdog3_save(void)
+{
+	/* enable wdog3 clock */
+	mmio_write_32(IMX_PCC3_BASE + 0xa8, 0xd2800000);
+
+	/* save the CS & TOVAL regiter */
+	wdog3[0] = mmio_read_32(IMX_WDOG3_BASE);
+	wdog3[1] = mmio_read_32(IMX_WDOG3_BASE + 0x8);
+}
+
+void wdog3_restore(void)
+{
+	/* enable wdog3 clock */
+	mmio_write_32(IMX_PCC3_BASE + 0xa8, 0xd2800000);
+
+	/* reconfig the CS */
+	mmio_write_32(IMX_WDOG3_BASE, wdog3[0]);
+	/* set the tiemout value */
+	mmio_write_32(IMX_WDOG3_BASE + 0x8, wdog3[1]);
+
+	/* wait for the lock status */
+	while ((mmio_read_32(IMX_WDOG3_BASE) & BIT(11))) {
+		;
+	}
+
+	/* wait for the config done */
+	while (!(mmio_read_32(IMX_WDOG3_BASE) & BIT(10))) {
+		;
+	}
+}
+
+static uint32_t lpuart_regs[4];
+#define LPUART_BAUD     0x10
+#define LPUART_CTRL     0x18
+#define LPUART_FIFO     0x28
+#define LPUART_WATER    0x2c
+
+void lpuart_save(void)
+{
+	lpuart_regs[0] = mmio_read_32(IMX_LPUART5_BASE + LPUART_BAUD);
+	lpuart_regs[1] = mmio_read_32(IMX_LPUART5_BASE + LPUART_FIFO);
+	lpuart_regs[2] = mmio_read_32(IMX_LPUART5_BASE + LPUART_WATER);
+	lpuart_regs[3] = mmio_read_32(IMX_LPUART5_BASE + LPUART_CTRL);
+}
+
+void lpuart_restore(void)
+{
+	mmio_write_32(IMX_LPUART5_BASE + LPUART_BAUD, lpuart_regs[0]);
+	mmio_write_32(IMX_LPUART5_BASE + LPUART_FIFO, lpuart_regs[1]);
+	mmio_write_32(IMX_LPUART5_BASE + LPUART_WATER, lpuart_regs[2]);
+	mmio_write_32(IMX_LPUART5_BASE + LPUART_CTRL, lpuart_regs[3]);
+}
+
+bool is_lpav_owned_by_apd(void)
+{
+	return (mmio_read_32(0x2802b044) & BIT(7)) ? true : false;
+}
+
+void lpav_ctx_save(void)
+{
+	unsigned int i;
+	uint32_t val;
+
+	/* CGC2 save */
+	for (i = 0U; i < ARRAY_SIZE(cgc2); i++) {
+		cgc2[i][1] = mmio_read_32(cgc2[i][0]);
+	}
+
+	/* PLL4 */
+	for (i = 0U; i < ARRAY_SIZE(pll4); i++) {
+		pll4[i][1] = mmio_read_32(pll4[i][0]);
+	}
+
+	/* PCC5 save */
+	for (i = 0U; i < ARRAY_SIZE(pcc5_0); i++) {
+		val = mmio_read_32(IMX_PCC5_BASE + i * 4);
+		if (val & PCC_PR) {
+			pcc5_0[i] = val;
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(pcc5_1); i++) {
+		val = mmio_read_32(pcc5_1[i][0]);
+		if (val & PCC_PR) {
+			pcc5_1[i][1] = val;
+		}
+	}
+
+	/* LPAV SIM save */
+	for (i = 0U; i < ARRAY_SIZE(lpav_sim); i++) {
+		lpav_sim[i][1] = mmio_read_32(lpav_sim[i][0]);
+	}
+
+	/* Save GPIO port D */
+	gpio_save(&lpav_gpio_ctx, LPAV_GPIO_CTRL_NUM);
+
+	/* put DDR into retention */
+	dram_enter_retention();
+}
+
+void lpav_ctx_restore(void)
+{
+	unsigned int i;
+
+	/* PLL4 */
+	for (i = 0U; i < 9U; i++) {
+		mmio_write_32(pll4[i][0], pll4[i][1]);
+	}
+
+	/* wait for PLL4 lock */
+	while (!(mmio_read_32(pll4[8][0]) & BIT(24))) {
+		;
+	}
+
+	/* restore the PLL4 PFDs */
+	mmio_write_32(pll4[9][0], pll4[9][1] & ~(BIT(31) | BIT(23) | BIT(15) | BIT(7)));
+	mmio_write_32(pll4[9][0], pll4[9][1]);
+
+	/* wait for the PFD is stable */
+	while (!(mmio_read_32(pll4[9][0]) & PFD_VALID_MASK)) {
+		;
+	}
+
+	/* CGC2 restore */
+	for (i = 0U; i < ARRAY_SIZE(cgc2); i++) {
+		mmio_write_32(cgc2[i][0], cgc2[i][1]);
+	}
+
+	/* PCC5 restore */
+	for (i = 0U; i < ARRAY_SIZE(pcc5_0); i++) {
+		if (pcc5_0[i] & PCC_PR) {
+			mmio_write_32(IMX_PCC5_BASE + i * 4, pcc5_0[i]);
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(pcc5_1); i++) {
+		if (pcc5_1[i][1] & PCC_PR) {
+			mmio_write_32(pcc5_1[i][0], pcc5_1[i][1]);
+		}
+	}
+
+	/* LPAV_SIM */
+	for (i = 0U; i < ARRAY_SIZE(lpav_sim); i++) {
+		mmio_write_32(lpav_sim[i][0], lpav_sim[i][1]);
+	}
+
+	gpio_restore(&lpav_gpio_ctx, LPAV_GPIO_CTRL_NUM);
+	/* DDR retention exit */
+	dram_exit_retention();
+}
+
+void imx_apd_ctx_save(unsigned int proc_num)
+{
+	unsigned int i;
+	uint32_t val;
+
+	/* enable LPUART5's clock by default */
+	mmio_setbits_32(IMX_PCC3_BASE + 0xe8, BIT(30));
+
+	/* save the gic config */
+	plat_gic_save(proc_num, &imx_gicv3_ctx);
+
+	cmc1_pmprot = mmio_read_32(IMX_CMC1_BASE + 0x18);
+	cmc1_srie = mmio_read_32(IMX_CMC1_BASE + 0x8c);
+
+	/* save the PCC3 */
+	for (i = 0U; i < ARRAY_SIZE(pcc3); i++) {
+		/* save the pcc if it is exist */
+		val = mmio_read_32(IMX_PCC3_BASE + i * 4);
+		if (val & PCC_PR) {
+			pcc3[i] = val;
+		}
+	}
+
+	/* save the PCC4 */
+	for (i = 0U; i < ARRAY_SIZE(pcc4); i++) {
+		/* save the pcc if it is exist */
+		val = mmio_read_32(IMX_PCC4_BASE + i * 4);
+		if (val & PCC_PR) {
+			pcc4[i] = val;
+		}
+	}
+
+	/* save the CGC1 */
+	cgc1_save();
+
+	wdog3_save();
+
+	gpio_save(apd_gpio_ctx, APD_GPIO_CTRL_NUM);
+
+	iomuxc_save();
+
+	tpm5_save();
+
+	lpuart_save();
+
+	/*
+	 * save the lpav ctx & put the ddr into retention
+	 * if lpav master is assigned to APD domain.
+	 */
+	if (is_lpav_owned_by_apd()) {
+		lpav_ctx_save();
+	}
+}
+
+void xrdc_reinit(void)
+{
+	xrdc_apply_apd_config();
+	xrdc_apply_lpav_config();
+
+	xrdc_enable();
+}
+
+void s400_release_caam(void)
+{
+	uint32_t msg, resp;
+
+	mmio_write_32(S400_MU_TRx(0), 0x17d70206);
+	mmio_write_32(S400_MU_TRx(1), 0x7);
+
+	do {
+		resp = mmio_read_32(S400_MU_RSR);
+	} while ((resp & 0x3) != 0x3);
+
+	msg = mmio_read_32(S400_MU_RRx(0));
+	resp = mmio_read_32(S400_MU_RRx(1));
+
+	VERBOSE("resp %x; %x", msg, resp);
+}
+
+void imx_apd_ctx_restore(unsigned int proc_num)
+{
+	unsigned int i;
+
+	/* restore the CCG1 */
+	cgc1_restore();
+
+	for (i = 0U; i < ARRAY_SIZE(pcc3); i++) {
+		/* save the pcc if it is exist */
+		if (pcc3[i] & PCC_PR) {
+			mmio_write_32(IMX_PCC3_BASE + i * 4, pcc3[i]);
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(pcc4); i++) {
+		if (pcc4[i] & PCC_PR) {
+			mmio_write_32(IMX_PCC4_BASE + i * 4, pcc4[i]);
+		}
+	}
+
+	wdog3_restore();
+
+	iomuxc_restore();
+
+	tpm5_restore();
+
+	xrdc_reinit();
+
+	/* Restore GPIO after xrdc_reinit, otherwise MSCs are invalid */
+	gpio_restore(apd_gpio_ctx, APD_GPIO_CTRL_NUM);
+
+	/* restore the gic config */
+	plat_gic_restore(proc_num, &imx_gicv3_ctx);
+
+	mmio_write_32(IMX_CMC1_BASE + 0x18, cmc1_pmprot);
+	mmio_write_32(IMX_CMC1_BASE + 0x8c, cmc1_srie);
+
+	/* enable LPUART5's clock by default */
+	mmio_setbits_32(IMX_PCC3_BASE + 0xe8, BIT(30));
+
+	/* restore the console lpuart */
+	lpuart_restore();
+
+	/* FIXME: make uart work for ATF */
+	mmio_write_32(IMX_LPUART_BASE + 0x18, 0xc0000);
+
+	/* Allow M core to reset A core */
+	mmio_clrbits_32(IMX_MU0B_BASE + 0x10, BIT(2));
+	/*
+	 * Ask S400 to release caam to APD as it is owned by s400
+	 */
+	s400_release_caam();
+
+	/* re-init the caam */
+	imx8ulp_caam_init();
+
+	/*
+	 * ack the upower, seems a necessary steps, otherwise the upower can
+	 * not response to the new API service call. put this just before the
+	 * ddr retention exit because that the dram retention exit flow need to
+	 * communicate with upower.
+	 */
+	upower_wait_resp();
+
+	/*
+	 * restore the lpav ctx & make ddr out of retention
+	 * if lpav master is assigned to APD domain.
+	 */
+	if (is_lpav_owned_by_apd()) {
+		lpav_ctx_restore();
+	}
+}
+
+#define DGO_CTRL1	U(0xc)
+#define USB_WAKEUP	U(0x44)
+#define USB1_PHY_DPD_WAKEUP_EN	BIT_32(5)
+#define USB0_PHY_DPD_WAKEUP_EN	BIT_32(4)
+#define USB1_PHY_WAKEUP_ISO_DISABLE	BIT_32(1)
+#define USB0_PHY_WAKEUP_ISO_DISABLE	BIT_32(0)
+
+void usb_wakeup_enable(bool enable)
+{
+	if (enable) {
+		mmio_setbits_32(IMX_SIM1_BASE + USB_WAKEUP,
+				USB1_PHY_WAKEUP_ISO_DISABLE | USB0_PHY_WAKEUP_ISO_DISABLE);
+		mmio_setbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		while (!(mmio_read_32(IMX_SIM1_BASE + DGO_CTRL1) & BIT(1))) {
+			;
+		}
+
+		mmio_clrbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(1));
+
+		/* Need to delay for a while to make sure the wakeup logic can work */
+		udelay(500);
+
+		mmio_setbits_32(IMX_SIM1_BASE + USB_WAKEUP,
+				USB1_PHY_DPD_WAKEUP_EN | USB0_PHY_DPD_WAKEUP_EN);
+		mmio_setbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		while (!(mmio_read_32(IMX_SIM1_BASE + DGO_CTRL1) & BIT(1))) {
+			;
+		}
+
+		mmio_clrbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(1));
+	} else {
+		/*
+		 * USBx_PHY_DPD_WAKEUP_EN should be cleared before USB0_PHY_WAKEUP_ISO_DISABLE
+		 * to provide the correct the wake-up functionality.
+		 */
+		mmio_write_32(IMX_SIM1_BASE + USB_WAKEUP, USB1_PHY_WAKEUP_ISO_DISABLE |
+			USB0_PHY_WAKEUP_ISO_DISABLE);
+		mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		while (!(mmio_read_32(IMX_SIM1_BASE + DGO_CTRL1) & BIT(1))) {
+			;
+		}
+
+		mmio_clrbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
+		mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(1));
+	}
+}
diff --git a/plat/imx/imx8ulp/dram.c b/plat/imx/imx8ulp/dram.c
new file mode 100644
index 00000000..00a52208
--- /dev/null
+++ b/plat/imx/imx8ulp/dram.c
@@ -0,0 +1,798 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <bl31/interrupt_mgmt.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+#include <dram.h>
+#include <upower_api.h>
+
+#define PHY_FREQ_SEL_INDEX(x)		((x) << 16)
+#define PHY_FREQ_MULTICAST_EN(x)	((x) << 8)
+#define DENALI_PHY_1537			U(0x5804)
+
+#define IMX_DDRC_BASE			U(0x2E060000)
+#define SAVED_DRAM_DATA_BASE		U(0x20055000)
+#define DENALI_CTL_143			U(0x23C)
+#define DENALI_CTL_144			U(0x240)
+#define DENALI_CTL_146			U(0x248)
+#define LP_STATE_CS_IDLE		U(0x404000)
+#define LP_STATE_CS_PD_CG		U(0x4F4F00)
+#define LPI_WAKEUP_EN_SHIFT		U(8)
+#define IMX_LPAV_SIM_BASE		0x2DA50000
+#define LPDDR_CTRL			0x14
+#define LPDDR_AUTO_LP_MODE_DISABLE	BIT(24)
+#define SOC_LP_CMD_SHIFT		U(15)
+#define LPDDR_CTRL2			0x18
+#define LPDDR_EN_CLKGATE		(0x1<<17)
+#define LPDDR_MAX_CLKDIV_EN		(0x1 << 16)
+#define LP_AUTO_ENTRY_EN		0x4
+#define LP_AUTO_EXIT_EN			0xF
+
+#define DENALI_CTL_00			U(0x0)
+#define DENALI_CTL_23			U(0x5c)
+#define DFIBUS_FREQ_INIT_SHIFT		U(24)
+#define TSREF2PHYMSTR_SHIFT		U(8)
+#define TSREF2PHYMSTR_MASK		GENMASK(13, 8)
+
+#define DENALI_CTL_24			U(0x60)
+#define DENALI_CTL_25			U(0x64)
+
+#define DENALI_CTL_93			U(0x174)
+#define PWRUP_SREFRESH_EXIT		BIT(0)
+
+#define DENALI_CTL_127				U(0x1fc)
+#define PHYMSTR_TRAIN_AFTER_INIT_COMPLETE	BIT(16)
+
+#define DENALI_CTL_147			U(0x24c)
+#define DENALI_CTL_153			U(0x264)
+#define PCPCS_PD_EN			BIT(8)
+
+#define DENALI_CTL_249			U(0x3E4)
+#define DENALI_CTL_266			U(0x428)
+
+#define DENALI_PHY_1547			U(0x582c)
+#define PHY_LP4_BOOT_DISABLE		BIT(8)
+
+#define DENALI_PHY_1559			U(0x585c)
+#define DENALI_PHY_1590			U(0x58D8)
+
+#define DENALI_PI_00			U(0x2000)
+#define DENALI_PI_04			U(0x2010)
+#define DENALI_PI_52			U(0x20D0)
+#define DENALI_PI_26			U(0x2068)
+#define DENALI_PI_33			U(0x2084)
+#define DENALI_PI_65			U(0x2104)
+#define DENALI_PI_77			U(0x2134)
+#define DENALI_PI_134			U(0x2218)
+#define DENALI_PI_131			U(0x220C)
+#define DENALI_PI_132			U(0x2210)
+#define DENALI_PI_134			U(0x2218)
+#define DENALI_PI_137			U(0x2224)
+#define DENALI_PI_174			U(0x22B8)
+#define DENALI_PI_175			U(0x22BC)
+#define DENALI_PI_181			U(0x22D4)
+#define DENALI_PI_182			U(0x22D8)
+#define DENALI_PI_191			U(0x22FC)
+#define DENALI_PI_192			U(0x2300)
+#define DENALI_PI_212			U(0x2350)
+#define DENALI_PI_214			U(0x2358)
+#define DENALI_PI_217			U(0x2364)
+
+#define LPDDR3_TYPE	U(0x7)
+#define LPDDR4_TYPE	U(0xB)
+
+extern void upower_wait_resp(void);
+
+struct dram_cfg_param {
+	uint32_t reg;
+	uint32_t val;
+};
+
+struct dram_timing_info {
+	/* ddr controller config */
+	struct dram_cfg_param *ctl_cfg;
+	unsigned int ctl_cfg_num;
+	/* pi config */
+	struct dram_cfg_param *pi_cfg;
+	unsigned int pi_cfg_num;
+	/* phy freq1 config */
+	struct dram_cfg_param *phy_f1_cfg;
+	unsigned int phy_f1_cfg_num;
+	/* phy freq2 config */
+	struct dram_cfg_param *phy_f2_cfg;
+	unsigned int phy_f2_cfg_num;
+	/* automatic low power config */
+	struct dram_cfg_param *auto_lp_cfg;
+	unsigned int auto_lp_cfg_num;
+	/* initialized drate table */
+	unsigned int fsp_table[3];
+};
+
+#define CTL_NUM		U(680)
+#define PI_NUM		U(298)
+#define PHY_NUM		U(1654)
+#define PHY_DIFF_NUM	U(49)
+#define AUTO_LP_NUM	U(3)
+struct dram_cfg {
+	uint32_t ctl_cfg[CTL_NUM];
+	uint32_t pi_cfg[PI_NUM];
+	uint32_t phy_full[PHY_NUM];
+	uint32_t phy_diff[PHY_DIFF_NUM];
+	uint32_t auto_lp_cfg[AUTO_LP_NUM];
+};
+
+struct dram_timing_info *info;
+struct dram_cfg *dram_timing_cfg;
+
+/* mark if dram cfg is already saved */
+static bool dram_cfg_saved;
+static bool dram_auto_lp_true;
+static uint32_t dram_class, dram_ctl_143;
+
+/* PHY register index for frequency diff */
+uint32_t freq_specific_reg_array[PHY_DIFF_NUM] = {
+90, 92, 93, 96, 97, 100, 101, 102, 103, 104, 114,
+346, 348, 349, 352, 353, 356, 357, 358, 359, 360,
+370, 602, 604, 605, 608, 609, 612, 613, 614, 615,
+616, 626, 858, 860, 861, 864, 865, 868, 869, 870,
+871, 872, 882, 1063, 1319, 1566, 1624, 1625
+};
+
+/* lock used for DDR DVFS */
+spinlock_t dfs_lock;
+static volatile uint32_t core_count;
+static volatile bool in_progress;
+static volatile bool sys_dvfs;
+static int num_fsp;
+
+static void ddr_init(void)
+{
+	unsigned int i;
+
+	/* restore the ddr ctl config */
+	for (i = 0U; i < CTL_NUM; i++) {
+		mmio_write_32(IMX_DDRC_BASE + i * 4, dram_timing_cfg->ctl_cfg[i]);
+	}
+
+	/* load the PI registers */
+	for (i = 0U; i < PI_NUM; i++) {
+		mmio_write_32(IMX_DDRC_BASE + 0x2000 + i * 4, dram_timing_cfg->pi_cfg[i]);
+	}
+
+
+	 /* restore all PHY registers for all the fsp. */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x100);
+	/* restore all the phy configs */
+	for (i = 0U; i < PHY_NUM; i++) {
+		/* skip the reserved registers space */
+		if (i >= 121U && i <= 255U) {
+			continue;
+		}
+		if (i >= 377U && i <= 511U) {
+			continue;
+		}
+		if (i >= 633U && i <= 767U) {
+			continue;
+		}
+		if (i >= 889U && i <= 1023U) {
+			continue;
+		}
+		if (i >= 1065U && i <= 1279U) {
+			continue;
+		}
+		if (i >= 1321U && i <= 1535U) {
+			continue;
+		}
+		mmio_write_32(IMX_DDRC_BASE + 0x4000 + i * 4, dram_timing_cfg->phy_full[i]);
+	}
+
+	if (dram_class == LPDDR4_TYPE) {
+		/* restore only the diff. */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x0);
+		for (i = 0U; i < PHY_DIFF_NUM; i++) {
+			mmio_write_32(IMX_DDRC_BASE + 0x4000 + freq_specific_reg_array[i] * 4,
+				      dram_timing_cfg->phy_diff[i]);
+		}
+	}
+
+	/* Re-enable MULTICAST mode */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, PHY_FREQ_MULTICAST_EN(1));
+}
+
+void dram_lp_auto_disable(void)
+{
+	uint32_t lp_auto_en;
+
+	dram_timing_cfg = (struct dram_cfg *)(SAVED_DRAM_DATA_BASE +
+					      sizeof(struct dram_timing_info));
+	lp_auto_en = (mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) & (LP_AUTO_ENTRY_EN << 24));
+	/* Save initial config */
+	dram_ctl_143 = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_143);
+
+	if (lp_auto_en && !dram_auto_lp_true) {
+		/* 0.a Save DDRC auto low-power mode parameter */
+		dram_timing_cfg->auto_lp_cfg[0] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
+		dram_timing_cfg->auto_lp_cfg[1] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_147);
+		dram_timing_cfg->auto_lp_cfg[2] = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146);
+		/* Set LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2 to Maximum */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_143, 0xF << 24);
+		/* 0.b Disable DDRC auto low-power mode interface */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_CTL_146, LP_AUTO_ENTRY_EN << 24);
+		/* 0.c Read any location to get DRAM out of Self-refresh */
+		mmio_read_32(DEVICE2_BASE);
+		/* 0.d Confirm DRAM is out of Self-refresh */
+		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) &
+			LP_STATE_CS_PD_CG) != LP_STATE_CS_IDLE) {
+			;
+		}
+		/* 0.e Disable DDRC auto low-power exit */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_CTL_147, LP_AUTO_EXIT_EN);
+		/* dram low power mode flag */
+		dram_auto_lp_true = true;
+	}
+}
+
+void dram_lp_auto_enable(void)
+{
+	/* Switch back to Auto Low-power mode */
+	if (dram_auto_lp_true) {
+		/* 12.a Confirm DRAM is out of Self-refresh */
+		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_146) &
+			LP_STATE_CS_PD_CG) != LP_STATE_CS_IDLE) {
+			;
+		}
+		/* 12.b Enable DDRC auto low-power exit */
+		/*
+		 * 12.c TBC! : Set DENALI_CTL_144 [LPI_CTRL_REQ_EN[24]] and
+		 * [DFI_LP_VERSION[16]] back to default settings = 1b'1.
+		 */
+		/*
+		 * 12.d Reconfigure DENALI_CTL_144 [LPI_WAKEUP_EN[5:0]] bit
+		 * LPI_WAKEUP_EN[3] = 1b'1.
+		 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, dram_timing_cfg->auto_lp_cfg[0]);
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_147, dram_timing_cfg->auto_lp_cfg[1]);
+		/* 12.e Re-enable DDRC auto low-power mode interface */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_146, dram_timing_cfg->auto_lp_cfg[2]);
+		/* restore ctl config */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_143, dram_ctl_143);
+		/* dram low power mode flag */
+		dram_auto_lp_true = false;
+	}
+}
+
+void dram_enter_self_refresh(void)
+{
+	/* disable auto low power interface */
+	dram_lp_auto_disable();
+	/* 1. config the PCC_LPDDR4[SSADO] to 2b'11 for ACK domain 0/1's STOP */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, 0x2 << 22);
+	/* 1.a Clock gate PCC_LPDDR4[CGC] and no software reset PCC_LPDDR4[SWRST] */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, (BIT(30) | BIT(28)));
+
+	/*
+	 * 2. Make sure the DENALI_CTL_144[LPI_WAKEUP_EN[5:0]] has the bit
+	 * LPI_WAKEUP_EN[3] = 1b'1. This enables the option 'self-refresh
+	 * long with mem and ctlr clk gating or self-refresh power-down long
+	 * with mem and ctlr clk gating'
+	 */
+	mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(3) << LPI_WAKEUP_EN_SHIFT);
+	/* TODO: Needed ? 2.a DENALI_CTL_144[LPI_TIMER_WAKEUP_F2] */
+	//mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(0));
+
+	/*
+	 * 3a. Config SIM_LPAV LPDDR_CTRL[LPDDR_AUTO_LP_MODE_DISABLE] to 1b'0(enable
+	 * the logic to automatic handles low power entry/exit. This is the recommended
+	 * option over handling through software.
+	 * 3b. Config the SIM_LPAV LPDDR_CTRL[SOC_LP_CMD] to 6b'101001(encoding for
+	 * self_refresh with both DDR controller and DRAM clock gate. THis is mandatory
+	 * since LPPDR logic will be power gated).
+	 */
+	mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL, LPDDR_AUTO_LP_MODE_DISABLE);
+	mmio_clrsetbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL,
+			   0x3f << SOC_LP_CMD_SHIFT, 0x29 << SOC_LP_CMD_SHIFT);
+	/* 3.c clock gate ddr controller */
+	mmio_setbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL2, LPDDR_EN_CLKGATE);
+	/* 3.d lpddr max clk div en */
+	mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL2, LPDDR_MAX_CLKDIV_EN);
+}
+
+void dram_exit_self_refresh(void)
+{
+	dram_lp_auto_enable();
+}
+
+void dram_enter_retention(void)
+{
+	unsigned int i;
+
+	dram_lp_auto_disable();
+
+	/* 1. config the PCC_LPDDR4[SSADO] to 2b'11 for ACK domain 0/1's STOP */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, 0x2 << 22);
+
+	/*
+	 * 2. Make sure the DENALI_CTL_144[LPI_WAKEUP_EN[5:0]] has the bit
+	 * LPI_WAKEUP_EN[3] = 1b'1. This enables the option 'self-refresh
+	 * long with mem and ctlr clk gating or self-refresh  power-down
+	 * long with mem and ctlr clk gating'
+	 */
+	mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, BIT(3) << LPI_WAKEUP_EN_SHIFT);
+
+	/*
+	 * 3a. Config SIM_LPAV LPDDR_CTRL[LPDDR_AUTO_LP_MODE_DISABLE] to 1b'0(enable
+	 * the logic to automatic handles low power entry/exit. This is the recommended
+	 * option over handling through software.
+	 * 3b. Config the SIM_LPAV LPDDR_CTRL[SOC_LP_CMD] to 6b'101001(encoding for
+	 * self_refresh with both DDR controller and DRAM clock gate. THis is mandatory
+	 * since LPPDR logic will be power gated).
+	 */
+	mmio_clrbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL, LPDDR_AUTO_LP_MODE_DISABLE);
+	mmio_clrsetbits_32(IMX_LPAV_SIM_BASE + LPDDR_CTRL,
+			   0x3f << SOC_LP_CMD_SHIFT, 0x29 << SOC_LP_CMD_SHIFT);
+
+	/* Save DDR Controller & PHY config.
+	 * Set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=1. Read and store all
+	 * the PHY registers for F2 into phy_f1_cfg, then read/store the diff between
+	 * F1 & F2 into phy_f2_cfg.
+	 */
+	if (!dram_cfg_saved) {
+		info = (struct dram_timing_info *)SAVED_DRAM_DATA_BASE;
+		dram_timing_cfg = (struct dram_cfg *)(SAVED_DRAM_DATA_BASE +
+					sizeof(struct dram_timing_info));
+
+		/* get the dram type */
+		dram_class = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_00);
+		dram_class = (dram_class >> 8) & 0xf;
+
+		/* save the ctl registers */
+		for (i = 0U; i < CTL_NUM; i++) {
+			dram_timing_cfg->ctl_cfg[i] = mmio_read_32(IMX_DDRC_BASE + i * 4);
+		}
+		dram_timing_cfg->ctl_cfg[0] = dram_timing_cfg->ctl_cfg[0] & 0xFFFFFFFE;
+
+		/* save the PI registers */
+		for (i = 0U; i < PI_NUM; i++) {
+			dram_timing_cfg->pi_cfg[i] = mmio_read_32(IMX_DDRC_BASE + 0x2000 + i * 4);
+		}
+		dram_timing_cfg->pi_cfg[0] = dram_timing_cfg->pi_cfg[0] & 0xFFFFFFFE;
+
+		/*
+		 * Read and store all PHY registers. full array is a full
+		 * copy for all the setpoint
+		 */
+		if (dram_class == LPDDR4_TYPE) {
+			mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x10000);
+			for (i = 0U; i < PHY_NUM; i++) {
+				/* Make sure MULTICASE is enabled */
+				if (i == 1537U) {
+					dram_timing_cfg->phy_full[i] = 0x100;
+				} else {
+					dram_timing_cfg->phy_full[i] = mmio_read_32(IMX_DDRC_BASE + 0x4000 + i * 4);
+				}
+			}
+
+			/*
+			 * set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=0.
+			 * Read and store only the diff.
+			 */
+			mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1537, 0x0);
+			/* save only the frequency based diff config to save memory */
+			for (i = 0U; i < PHY_DIFF_NUM; i++) {
+				dram_timing_cfg->phy_diff[i] = mmio_read_32(IMX_DDRC_BASE + 0x4000 +
+									    freq_specific_reg_array[i] * 4);
+			}
+		} else {
+			/* LPDDR3, only f1 need to save */
+			for (i = 0U; i < info->phy_f1_cfg_num; i++) {
+				info->phy_f1_cfg[i].val = mmio_read_32(info->phy_f1_cfg[i].reg);
+			}
+		}
+
+		dram_cfg_saved = true;
+	}
+}
+
+void dram_exit_retention(void)
+{
+	uint32_t val;
+
+	/* 1. Config the LPAV PLL4 and DDR clock for the desired LPDDR operating frequency. */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
+
+	/* 2. Write PCC5.PCC_LPDDR4[SWRST] to 1b'1 to release LPDDR from reset. */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(28));
+
+	/* 3. Reload the LPDDR CTL/PI/PHY register */
+	ddr_init();
+
+	if (dram_class == LPDDR4_TYPE) {
+		/* 4a. FIXME Set PHY_SET_DFI_INPUT_N parameters to 4'h1. LPDDR4 only */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1559, 0x01010101);
+
+		/*
+		 * 4b. CTL PWRUP_SREFRESH_EXIT=1'b0 for disabling self refresh exit
+		 * from controller.
+		 */
+		/*
+		 * 4c. PI_PWRUP_SELF_REF_EXIT=1, PI_MC_PWRUP_SELF_REF_EXIT=0 for enabling
+		 * self refresh exit from PI
+		 */
+		/* 4c. PI_INT_LVL_EN=0 to skip Initialization trainings. */
+		/*
+		 * 4d. PI_WRLVL_EN_F0/1/2= PI_CALVL_EN_F0/1/2= PI_RDLVL_EN_F0/1/2=
+		 * PI_RDLVL_GATE_EN_F0/1/2= PI_WDQLVL_EN_F0/1/2=0x2.
+		 * Enable non initialization trainings.
+		 */
+		/* 4e. PI_PWRUP_SREFRESH_EXIT_CS=0xF */
+		/* 4f. PI_DLL_RESET=0x1 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_137, 0x1);
+		/* PI_PWRUP_SELF_REF_EXIT = 1 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_132, 0x01000000);
+		/* PI_MC_PWRUP_SELF_REF_EXIT = 0 */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_132, BIT(16));
+		/* PI_INT_LVL_EN = 0 */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_04, BIT(0));
+		/* PI_WRLVL_EN_F0 = 3, PI_WRLVL_EN_F1 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_174, 0x03030000);
+		/* PI_WRLVL_EN_F2 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_175, 0x03);
+		/* PI_CALVL_EN_F0 = 3, PI_CALVL_EN_F1 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_191, 0x03030000);
+		/* PI_CALVL_EN_F2 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_192, 0x03);
+		/* PI_WDQLVL_EN_F0 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_212, 0x300);
+		/* PI_WDQLVL_EN_F1 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_214, 0x03000000);
+		/* PI_WDQLVL_EN_F2 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_217, 0x300);
+		/* PI_EDLVL_EN_F0 = 3, PI_EDLVL_GATE_EN_F0 = 3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_181, 0x03030000);
+		/*
+		 * PI_RDLVL_EN_F1 = 3, PI_RDLVL_GATE_EN_F1 = 3,
+		 * PI_RDLVL_EN_F2 = 3, PI_RDLVL_GATE_EN_F2 = 3
+		 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_182, 0x03030303);
+		/* PI_PWRUP_SREFRESH_EXIT_CS = 0xF */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_134, 0x000F0000);
+	} else {
+		/* PI_DLL_RESET=1 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_137, 0x1);
+		/* PI_PWRUP_SELF_REF_EXIT=1 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_132, 0x01000000);
+		/* PI_MC_PWRUP_SELF_REF_EXIT=0 */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_132, BIT(16));
+		/* PI_INT_LVL_EN=0 */
+		mmio_clrbits_32(IMX_DDRC_BASE + DENALI_PI_04, BIT(0));
+		/* PI_WRLVL_EN_F0=3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_174, 0x00030000);
+		/* PI_CALVL_EN_F0=3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_191, 0x00030000);
+		/* PI_RDLVL_EN_F0=3,PI_RDLVL_GATE_EN_F0=3 */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_181, 0x03030000);
+		/* PI_PWRUP_SREFRESH_EXIT_CS=0xF */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_134, 0x000F0000);
+	}
+
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, 0x00002D00);
+
+	/* Force in-order AXI read data */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, 0x1);
+
+	/*
+	 * Disable special R/W group switches so that R/W group placement
+	 * is always at END of R/W group.
+	 */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_249, 0x0);
+
+	/* Reduce time for IO pad calibration */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_PHY_1590, 0x01000000);
+
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_25, 0x00020100);
+
+	/* PD disable */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_153, 0x04040000);
+	/*
+	 * 5. Disable automatic LP entry and PCPCS modes LP_AUTO_ENTRY_EN
+	 * to 1b'0, PCPCS_PD_EN to 1b'0
+	 */
+
+	upwr_xcp_set_ddr_retention(APD_DOMAIN, 0, NULL);
+	upower_wait_resp();
+
+	if (dram_class == LPDDR4_TYPE) {
+		/* 7. Write PI START parameter to 1'b1 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_PI_00, 0x00000b01);
+
+		/* 8. Write CTL START parameter to 1'b1 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_00, 0x00000b01);
+	} else {
+		/* 7. Write PI START parameter to 1'b1 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_PI_00, 0x00000701);
+
+		/* 8. Write CTL START parameter to 1'b1 */
+		mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_00, 0x00000701);
+	}
+
+	/* 9. DENALI_CTL_266:  Wait for INT_STATUS_INIT=0x2 */
+	do {
+		val = (mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_266) >> 8) & 0xFF;
+	} while (val != 0x2);
+
+	/*
+	 * 10. Run SW trainings by setting PI_CALVL_REQ,PI_WRLVL_REQ,PI_RDLVL_GATE_REQ,
+	 * PI_RDLVL_REQ,PI_WDQLVL_REQ(NA for LPDDR3) in same order.
+	 */
+	if (dram_class == LPDDR4_TYPE) {
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_52, 0x10000); /* CALVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_26, 0x100); /* WRLVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_65, 0x10000); /* WDQLVL */
+
+		/* 11. Wait for trainings to get complete by polling PI_INT_STATUS */
+		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_PI_77) & 0x07E00000) != 0x07E00000) {
+			;
+		}
+	} else {
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_52, 0x10000); /* CALVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_26, 0x100); /* WRLVL */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
+		mmio_setbits_32(IMX_DDRC_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
+		while ((mmio_read_32(IMX_DDRC_BASE + DENALI_PI_77) & 0x05E00000) != 0x05E00000) {
+			;
+		}
+	}
+
+	dram_lp_auto_enable();
+}
+
+#define LPDDR_DONE       (0x1<<4)
+#define SOC_FREQ_CHG_ACK (0x1<<6)
+#define SOC_FREQ_CHG_REQ (0x1<<7)
+#define LPI_WAKEUP_EN    (0x4<<8)
+#define SOC_FREQ_REQ     (0x1<<11)
+
+static void set_cgc2_ddrclk(uint8_t src, uint8_t div)
+{
+
+	/* Wait until the reg is unlocked for writing */
+	while (mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(31))
+		;
+
+	mmio_write_32(IMX_CGC2_BASE + 0x40, (src << 28) | (div << 21));
+	/* Wait for the clock switching done */
+	while (!(mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(27)))
+		;
+}
+static void set_ddr_clk(uint32_t ddr_freq)
+{
+	/* Disable DDR clock */
+	mmio_clrbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
+	switch (ddr_freq) {
+	/* boot frequency ? */
+	case 48:
+		set_cgc2_ddrclk(2, 0);
+		break;
+	/* default bypass frequency for fsp 1 */
+	case 192:
+		set_cgc2_ddrclk(0, 1);
+		break;
+	case 384:
+		set_cgc2_ddrclk(0, 0);
+		break;
+	case 264:
+		set_cgc2_ddrclk(4, 3);
+		break;
+	case 528:
+		set_cgc2_ddrclk(4, 1);
+		break;
+	default:
+		break;
+	}
+	/* Enable DDR clock */
+	mmio_setbits_32(IMX_PCC5_BASE + 0x108, BIT(30));
+
+	/* Wait until the reg is unlocked for writing */
+	while (mmio_read_32(IMX_CGC2_BASE + 0x40) & BIT(31)) {
+		;
+	}
+}
+
+#define AVD_SIM_LPDDR_CTRL	(IMX_LPAV_SIM_BASE + 0x14)
+#define AVD_SIM_LPDDR_CTRL2	(IMX_LPAV_SIM_BASE + 0x18)
+#define MAX_FSP_NUM	U(3)
+#define DDR_DFS_GET_FSP_COUNT	0x10
+#define DDR_BYPASS_DRATE	U(400)
+
+extern int upower_pmic_i2c_write(uint32_t reg_addr, uint32_t reg_val);
+
+/* Normally, we only switch frequency between 1(bypass) and 2(highest) */
+int lpddr4_dfs(uint32_t freq_index)
+{
+	uint32_t lpddr_ctrl, lpddr_ctrl2;
+	uint32_t ddr_ctl_144;
+
+	/*
+	 * Valid index: 0 to 2
+	 * index 0: boot frequency
+	 * index 1: bypass frequency
+	 * index 2: highest frequency
+	 */
+	if (freq_index > 2U) {
+		return -1;
+	}
+
+	/*
+	 * increase the voltage to 1.1V firstly before increase frequency
+	 * and APD enter OD mode
+	 */
+	if (freq_index == 2U && sys_dvfs) {
+		upower_pmic_i2c_write(0x22, 0x28);
+	}
+
+	/* Enable LPI_WAKEUP_EN */
+	ddr_ctl_144 = mmio_read_32(IMX_DDRC_BASE + DENALI_CTL_144);
+	mmio_setbits_32(IMX_DDRC_BASE + DENALI_CTL_144, LPI_WAKEUP_EN);
+
+	/* put DRAM into long self-refresh & clock gating */
+	lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL);
+	lpddr_ctrl = (lpddr_ctrl & ~((0x3f << 15) | (0x3 << 9))) | (0x28 << 15) | (freq_index << 9);
+	mmio_write_32(AVD_SIM_LPDDR_CTRL, lpddr_ctrl);
+
+	/* Gating the clock */
+	lpddr_ctrl2 = mmio_read_32(AVD_SIM_LPDDR_CTRL2);
+	mmio_setbits_32(AVD_SIM_LPDDR_CTRL2, LPDDR_EN_CLKGATE);
+
+	/* Request frequency change */
+	mmio_setbits_32(AVD_SIM_LPDDR_CTRL, SOC_FREQ_REQ);
+
+	do {
+		lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL);
+		if (lpddr_ctrl & SOC_FREQ_CHG_REQ) {
+			/* Bypass mode */
+			if (info->fsp_table[freq_index] < DDR_BYPASS_DRATE) {
+				/* Change to PLL bypass mode */
+				mmio_write_32(IMX_LPAV_SIM_BASE, 0x1);
+				/* change the ddr clock source & frequency */
+				set_ddr_clk(info->fsp_table[freq_index]);
+			} else {
+				/* Change to PLL unbypass mode */
+				mmio_write_32(IMX_LPAV_SIM_BASE, 0x0);
+				/* change the ddr clock source & frequency */
+				set_ddr_clk(info->fsp_table[freq_index] >> 1);
+			}
+
+			mmio_clrsetbits_32(AVD_SIM_LPDDR_CTRL, SOC_FREQ_CHG_REQ, SOC_FREQ_CHG_ACK);
+			continue;
+		}
+	} while ((lpddr_ctrl & LPDDR_DONE) != 0); /* several try? */
+
+	/* restore the original setting */
+	mmio_write_32(IMX_DDRC_BASE + DENALI_CTL_144, ddr_ctl_144);
+	mmio_write_32(AVD_SIM_LPDDR_CTRL2, lpddr_ctrl2);
+
+	/* Check the DFS result */
+	lpddr_ctrl = mmio_read_32(AVD_SIM_LPDDR_CTRL) & 0xF;
+	if (lpddr_ctrl != 0U) {
+		/* Must be something wrong, return failure */
+		return -1;
+	}
+
+	/* decrease the BUCK3 voltage after frequency changed to lower
+	 * and APD in ND_MODE
+	 */
+	if (freq_index == 1U && sys_dvfs) {
+		upower_pmic_i2c_write(0x22, 0x20);
+	}
+
+	/* DFS done successfully */
+	return 0;
+}
+
+/* for the non-primary core, waiting for DFS done */
+static uint64_t waiting_dvfs(uint32_t id, uint32_t flags,
+		void *handle, void *cookie)
+{
+	uint32_t irq;
+
+	irq = plat_ic_acknowledge_interrupt();
+	if (irq < 1022U) {
+		plat_ic_end_of_interrupt(irq);
+	}
+
+	/* set the WFE done status */
+	spin_lock(&dfs_lock);
+	core_count++;
+	dsb();
+	spin_unlock(&dfs_lock);
+
+	while (in_progress) {
+		wfe();
+	}
+
+	return 0;
+}
+
+int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+		u_register_t x1, u_register_t x2, u_register_t x3)
+{
+	unsigned int fsp_index = x1;
+	uint32_t online_cpus = x2 - 1;
+	uint64_t mpidr = read_mpidr_el1();
+	unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+	/* Get the number of FSPs */
+	if (x1 == DDR_DFS_GET_FSP_COUNT) {
+		SMC_RET2(handle, num_fsp, info->fsp_table[1]);
+	}
+
+	/* start lpddr frequency scaling */
+	in_progress = true;
+	sys_dvfs = x3 ? true : false;
+	dsb();
+
+	/* notify other core wait for scaling done */
+	for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++)
+		/* Skip raise SGI for current CPU */
+		if (i != cpu_id) {
+			plat_ic_raise_el3_sgi(0x8, i);
+		}
+
+	/* Make sure all the cpu in WFE */
+	while (online_cpus != core_count) {
+		;
+	}
+
+	/* Flush the L1/L2 cache */
+	dcsw_op_all(DCCSW);
+
+	lpddr4_dfs(fsp_index);
+
+	in_progress = false;
+	core_count = 0;
+	dsb();
+	sev();
+	isb();
+
+	SMC_RET1(handle, 0);
+}
+
+void dram_init(void)
+{
+	uint32_t flags = 0;
+	uint32_t rc;
+	unsigned int i;
+
+	/* Register the EL3 handler for DDR DVFS */
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_EL3, waiting_dvfs, flags);
+	if (rc) {
+		panic();
+	}
+
+	info = (struct dram_timing_info *)SAVED_DRAM_DATA_BASE;
+
+	/* Get the num of the supported Fsp */
+	for (i = 0; i < MAX_FSP_NUM; i++) {
+		if (!info->fsp_table[i]) {
+			break;
+		}
+	}
+
+	num_fsp = (i > MAX_FSP_NUM) ? MAX_FSP_NUM : i;
+}
diff --git a/plat/imx/imx8ulp/imx8ulp_bl31_setup.c b/plat/imx/imx8ulp/imx8ulp_bl31_setup.c
new file mode 100644
index 00000000..696f4b65
--- /dev/null
+++ b/plat/imx/imx8ulp/imx8ulp_bl31_setup.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <dram.h>
+#include <imx8_lpuart.h>
+#include <imx8ulp_caam.h>
+#include <imx_plat_common.h>
+#include <plat_imx8.h>
+#include <upower_api.h>
+#include <xrdc.h>
+
+#define MAP_BL31_TOTAL										   \
+	MAP_REGION_FLAT(BL31_BASE, BL31_LIMIT - BL31_BASE, MT_MEMORY | MT_RW | MT_SECURE)
+#define MAP_BL31_RO										   \
+	MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_MEMORY | MT_RO | MT_SECURE)
+#define MAP_BL32_TOTAL MAP_REGION_FLAT(BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW)
+#define MAP_COHERENT_MEM									\
+	MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE),	\
+			 MT_DEVICE | MT_RW | MT_SECURE)
+
+#define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
+
+static const mmap_region_t imx_mmap[] = {
+	DEVICE0_MAP, DEVICE1_MAP, DEVICE2_MAP,
+	ELE_MAP, SEC_SIM_MAP, SRAM0_MAP,
+	{0}
+};
+
+extern uint32_t upower_init(void);
+extern void imx8ulp_init_scmi_server(void);
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	static console_t console;
+
+	/* config the TPM5 clock */
+	mmio_write_32(IMX_PCC3_BASE + 0xd0, 0x92000000);
+	mmio_write_32(IMX_PCC3_BASE + 0xd0, 0xd2000000);
+
+	/* enable the GPIO D,E,F non-secure access by default */
+	mmio_write_32(IMX_PCC4_BASE + 0x78, 0xc0000000);
+	mmio_write_32(IMX_PCC4_BASE + 0x7c, 0xc0000000);
+	mmio_write_32(IMX_PCC5_BASE + 0x114, 0xc0000000);
+
+	mmio_write_32(IMX_GPIOE_BASE + 0x10, 0xffffffff);
+	mmio_write_32(IMX_GPIOE_BASE + 0x14, 0x3);
+	mmio_write_32(IMX_GPIOE_BASE + 0x18, 0xffffffff);
+	mmio_write_32(IMX_GPIOE_BASE + 0x1c, 0x3);
+
+	mmio_write_32(IMX_GPIOF_BASE + 0x10, 0xffffffff);
+	mmio_write_32(IMX_GPIOF_BASE + 0x14, 0x3);
+	mmio_write_32(IMX_GPIOF_BASE + 0x18, 0xffffffff);
+	mmio_write_32(IMX_GPIOF_BASE + 0x1c, 0x3);
+
+	mmio_write_32(IMX_GPIOD_BASE + 0x10, 0xffffffff);
+	mmio_write_32(IMX_GPIOD_BASE + 0x14, 0x3);
+	mmio_write_32(IMX_GPIOD_BASE + 0x18, 0xffffffff);
+	mmio_write_32(IMX_GPIOD_BASE + 0x1c, 0x3);
+
+	console_lpuart_register(IMX_LPUART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+		     IMX_CONSOLE_BAUDRATE, &console);
+
+	/* This console is only used for boot stage */
+	console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+
+	bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
+	bl33_image_ep_info.spsr = plat_get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#if defined(SPD_opteed) || defined(SPD_trusty)
+	/* Populate entry point information for BL32 */
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = 0;
+
+	/* Pass TEE base and size to bl33 */
+	bl33_image_ep_info.args.arg1 = BL32_BASE;
+	bl33_image_ep_info.args.arg2 = BL32_SIZE;
+
+#ifdef SPD_trusty
+	bl32_image_ep_info.args.arg0 = BL32_SIZE;
+	bl32_image_ep_info.args.arg1 = BL32_BASE;
+#else
+	/* Make sure memory is clean */
+	mmio_write_32(BL32_FDT_OVERLAY_ADDR, 0);
+	bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
+#endif
+#endif
+}
+
+void bl31_plat_arch_setup(void)
+{
+	const mmap_region_t bl_regions[] = {
+		MAP_BL31_TOTAL,
+		MAP_BL31_RO,
+#if USE_COHERENT_MEM
+		MAP_COHERENT_MEM,
+#endif
+#if defined(SPD_opteed) || defined(SPD_trusty)
+		MAP_BL32_TOTAL,
+#endif
+		{0},
+	};
+
+	setup_page_tables(bl_regions, imx_mmap);
+	enable_mmu_el3(0);
+
+	/* TODO: Hack, refine this piece, scmi channel free */
+	mmio_write_32(SRAM0_BASE + 0x4, 1);
+
+	/* Allow M core to reset A core */
+	mmio_clrbits_32(IMX_MU0B_BASE + 0x10, BIT(2));
+}
+
+void bl31_platform_setup(void)
+{
+	/* select the arch timer source */
+	mmio_setbits_32(IMX_SIM1_BASE + 0x30, 0x8000000);
+
+	generic_delay_timer_init();
+
+	plat_gic_driver_init();
+	plat_gic_init();
+
+	imx8ulp_init_scmi_server();
+	upower_init();
+
+	xrdc_apply_apd_config();
+	xrdc_apply_lpav_config();
+	xrdc_enable();
+
+	imx8ulp_caam_init();
+
+	dram_init();
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+	if (type == NON_SECURE) {
+		return &bl33_image_ep_info;
+	} else {
+		return &bl32_image_ep_info;
+	}
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return COUNTER_FREQUENCY;
+}
+
+void bl31_plat_runtime_setup(void)
+{
+}
+
+#ifdef SPD_trusty
+void plat_trusty_set_boot_args(aapcs64_params_t *args)
+{
+	args->arg0 = BL32_SIZE;
+	args->arg1 = BL32_BASE;
+	args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+}
+#endif
diff --git a/plat/imx/imx8ulp/imx8ulp_caam.c b/plat/imx/imx8ulp/imx8ulp_caam.c
new file mode 100644
index 00000000..d150fe2c
--- /dev/null
+++ b/plat/imx/imx8ulp/imx8ulp_caam.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2021-2024 NXP.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+
+#include <imx8ulp_caam.h>
+
+void imx8ulp_caam_init(void)
+{
+	/* config CAAM JRaMID set MID to Cortex A */
+	mmio_write_32(CAAM_JR0MID, CAAM_NS_MID);
+	mmio_write_32(CAAM_JR1MID, CAAM_NS_MID);
+	mmio_write_32(CAAM_JR2MID, CAAM_NS_MID);
+	mmio_write_32(CAAM_JR3MID, CAAM_NS_MID);
+}
diff --git a/plat/imx/imx8ulp/imx8ulp_psci.c b/plat/imx/imx8ulp/imx8ulp_psci.c
new file mode 100644
index 00000000..628aceab
--- /dev/null
+++ b/plat/imx/imx8ulp/imx8ulp_psci.c
@@ -0,0 +1,555 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+
+#include <plat_imx8.h>
+#include <upower_api.h>
+
+extern void cgc1_save(void);
+extern void cgc1_restore(void);
+extern void imx_apd_ctx_save(unsigned int cpu);
+extern void imx_apd_ctx_restore(unsigned int cpu);
+extern void usb_wakeup_enable(bool enable);
+extern void upower_wait_resp(void);
+extern bool is_lpav_owned_by_apd(void);
+extern void apd_io_pad_off(void);
+extern int upower_pmic_i2c_read(uint32_t reg_addr, uint32_t *reg_val);
+extern void imx8ulp_init_scmi_server(void);
+
+static uintptr_t secure_entrypoint;
+
+#define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0])
+#define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1])
+#define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
+
+#define RVBARADDRx(c)		(IMX_SIM1_BASE + 0x5c + 0x4 * (c))
+#define WKPUx(c)		(IMX_SIM1_BASE + 0x3c + 0x4 * (c))
+#define AD_COREx_LPMODE(c)	(IMX_CMC1_BASE + 0x50 + 0x4 * (c))
+
+#define PMIC_CFG(v, m, msk)		\
+	{				\
+		.volt = (v),		\
+		.mode = (m),		\
+		.mode_msk = (msk),	\
+	}
+
+#define PAD_CFG(c, r, t)		\
+	{				\
+		.pad_close = (c),	\
+		.pad_reset = (r),	\
+		.pad_tqsleep = (t)	\
+	}
+
+#define BIAS_CFG(m, n, p, mbias)	\
+	{				\
+		.dombias_cfg = {	\
+			.mode = (m),	\
+			.rbbn = (n),	\
+			.rbbp = (p),	\
+		},			\
+		.membias_cfg = {mbias},	\
+	}
+
+#define SWT_BOARD(swt_on, msk)	\
+	{			\
+		.on = (swt_on),	\
+		.mask = (msk),	\
+	}
+
+#define SWT_MEM(a, p, m)	\
+	{			\
+		.array = (a),	\
+		.perif = (p),	\
+		.mask = (m),	\
+	}
+
+static int imx_pwr_set_cpu_entry(unsigned int cpu, unsigned int entry)
+{
+	mmio_write_32(RVBARADDRx(cpu), entry);
+
+	/* set update bit */
+	mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(24 + cpu));
+	/* wait for ack */
+	while (!(mmio_read_32(IMX_SIM1_BASE + 0x8) & BIT_32(26 + cpu))) {
+	}
+
+	/* clear update bit */
+	mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) & ~BIT_32(24 + cpu));
+	/* clear ack bit */
+	mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(26 + cpu));
+
+	return 0;
+}
+
+static volatile uint32_t cgc1_nicclk;
+int imx_pwr_domain_on(u_register_t mpidr)
+{
+	unsigned int cpu = MPIDR_AFFLVL0_VAL(mpidr);
+
+	imx_pwr_set_cpu_entry(cpu, secure_entrypoint);
+
+	/* slow down the APD NIC bus clock */
+	cgc1_nicclk = mmio_read_32(IMX_CGC1_BASE + 0x34);
+	mmio_clrbits_32(IMX_CGC1_BASE + 0x34, GENMASK_32(29, 28));
+
+	mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f);
+	mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0);
+
+	/* enable wku wakeup for idle */
+	mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0xffffffff);
+
+	return PSCI_E_SUCCESS;
+}
+
+void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
+	plat_gic_pcpu_init();
+	plat_gic_cpuif_enable();
+
+	/* set APD NIC back to orignally setting */
+	mmio_write_32(IMX_CGC1_BASE + 0x34, cgc1_nicclk);
+}
+
+int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
+{
+	return PSCI_E_SUCCESS;
+}
+
+void imx_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
+
+	plat_gic_cpuif_disable();
+
+	/* disable wakeup */
+	mmio_write_32(WKPUx(cpu), 0);
+
+	/* set core power mode to PD */
+	mmio_write_32(AD_COREx_LPMODE(cpu), 0x3);
+}
+
+/* APD power mode config */
+ps_apd_pwr_mode_cfgs_t apd_pwr_mode_cfgs = {
+	[DPD_PWR_MODE] = {
+		.swt_board_offs = 0x180,
+		.swt_mem_offs = 0x188,
+		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
+		.pad_cfg = PAD_CFG(0x0, 0xc, 0x01e80a02),
+		.bias_cfg = BIAS_CFG(0x0, 0x2, 0x2, 0x0),
+	},
+
+	/* PD */
+	[PD_PWR_MODE] = {
+		.swt_board_offs = 0x170,
+		.swt_mem_offs = 0x178,
+		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
+		.pad_cfg = PAD_CFG(0x0, 0xc, 0x01e80a00),
+		.bias_cfg = BIAS_CFG(0x0, 0x2, 0x2, 0x0),
+	},
+
+	[ADMA_PWR_MODE] = {
+		.swt_board_offs = 0x120,
+		.swt_mem_offs = 0x128,
+		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
+		.pad_cfg = PAD_CFG(0x0, 0x0, 0x0deb7a00),
+		.bias_cfg = BIAS_CFG(0x2, 0x2, 0x2, 0x0),
+	},
+
+	[ACT_PWR_MODE] = {
+		.swt_board_offs = 0x110,
+		.swt_mem_offs = 0x118,
+		.pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2),
+		.pad_cfg = PAD_CFG(0x0, 0x0, 0x0deb7a00),
+		.bias_cfg = BIAS_CFG(0x2, 0x2, 0x2, 0x0),
+	},
+};
+
+/* APD power switch config */
+ps_apd_swt_cfgs_t apd_swt_cfgs = {
+	[DPD_PWR_MODE] = {
+		.swt_board[0] = SWT_BOARD(0x0, 0x1fffc),
+		.swt_mem[0] = SWT_MEM(0x0, 0x0, 0x1ffff),
+		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0),
+	},
+
+	[PD_PWR_MODE] = {
+		.swt_board[0] = SWT_BOARD(0x0, 0x00001fffc),
+		.swt_mem[0] = SWT_MEM(0x00010c00, 0x0, 0x1ffff),
+		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003f0000, 0x0),
+	},
+
+	[ADMA_PWR_MODE] = {
+		.swt_board[0] = SWT_BOARD(0x15f74, 0x15f74),
+		.swt_mem[0] = SWT_MEM(0x0001fffd, 0x0001fffd, 0x1ffff),
+		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0),
+	},
+
+	[ACT_PWR_MODE] = {
+		.swt_board[0] = SWT_BOARD(0x15f74, 0x15f74),
+		.swt_mem[0] = SWT_MEM(0x0001fffd, 0x0001fffd, 0x1ffff),
+		.swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0),
+	},
+};
+
+/* PMIC config for power down, LDO1 should be OFF */
+ps_apd_pmic_reg_data_cfgs_t pd_pmic_reg_cfgs = {
+	[0] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = PD_PWR_MODE,
+		.i2c_addr = 0x30,
+		.i2c_data = 0x9c,
+	},
+	[1] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = PD_PWR_MODE,
+		.i2c_addr = 0x22,
+		.i2c_data = 0xb,
+	},
+	[2] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = ACT_PWR_MODE,
+		.i2c_addr = 0x30,
+		.i2c_data = 0x9d,
+	},
+	[3] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = ACT_PWR_MODE,
+		.i2c_addr = 0x22,
+		.i2c_data = 0x28,
+	},
+};
+
+/* PMIC config for deep power down, BUCK3 should be OFF */
+ps_apd_pmic_reg_data_cfgs_t dpd_pmic_reg_cfgs = {
+	[0] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = DPD_PWR_MODE,
+		.i2c_addr = 0x21,
+		.i2c_data = 0x78,
+	},
+	[1] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = DPD_PWR_MODE,
+		.i2c_addr = 0x30,
+		.i2c_data = 0x9c,
+	},
+	[2] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = ACT_PWR_MODE,
+		.i2c_addr = 0x21,
+		.i2c_data = 0x79,
+	},
+	[3] = {
+		.tag = PMIC_REG_VALID_TAG,
+		.power_mode = ACT_PWR_MODE,
+		.i2c_addr = 0x30,
+		.i2c_data = 0x9d,
+	},
+};
+
+struct ps_pwr_mode_cfg_t *pwr_sys_cfg = (struct ps_pwr_mode_cfg_t *)UPWR_DRAM_SHARED_BASE_ADDR;
+
+void imx_set_pwr_mode_cfg(abs_pwr_mode_t mode)
+{
+	uint32_t volt;
+
+	if (mode >= NUM_PWR_MODES) {
+		return;
+	}
+
+	/* apd power mode config */
+	memcpy(&pwr_sys_cfg->ps_apd_pwr_mode_cfg[mode], &apd_pwr_mode_cfgs[mode],
+		 sizeof(struct ps_apd_pwr_mode_cfg_t));
+
+	/* apd power switch config */
+	memcpy(&pwr_sys_cfg->ps_apd_swt_cfg[mode], &apd_swt_cfgs[mode], sizeof(swt_config_t));
+
+	/*
+	 * BUCK3 & LDO1 can only be shutdown when LPAV is owned by APD side
+	 * otherwise RTD side is responsible to control them in low power mode.
+	 */
+	if (is_lpav_owned_by_apd()) {
+		/* power off the BUCK3 in DPD mode */
+		if (mode == DPD_PWR_MODE) {
+			memcpy(&pwr_sys_cfg->ps_apd_pmic_reg_data_cfg, &dpd_pmic_reg_cfgs,
+				 sizeof(ps_apd_pmic_reg_data_cfgs_t));
+		/* LDO1 should be power off in PD mode */
+		} else if (mode == PD_PWR_MODE) {
+			/* overwrite the buck3 voltage setting in active mode */
+			upower_pmic_i2c_read(0x22, &volt);
+			pd_pmic_reg_cfgs[3].i2c_data = volt;
+			memcpy(&pwr_sys_cfg->ps_apd_pmic_reg_data_cfg, &pd_pmic_reg_cfgs,
+				 sizeof(ps_apd_pmic_reg_data_cfgs_t));
+		}
+	}
+}
+
+void imx_domain_suspend(const psci_power_state_t *target_state)
+{
+	unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
+
+	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+		plat_gic_cpuif_disable();
+		imx_pwr_set_cpu_entry(cpu, secure_entrypoint);
+		/* core put into power down */
+		mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x3);
+		/* FIXME config wakeup interrupt in WKPU */
+		mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x7fffffe3);
+	} else {
+		/* for core standby/retention mode */
+		mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x1);
+		mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x7fffffe3);
+		dsb();
+		write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
+		isb();
+	}
+
+	if (is_local_state_retn(CLUSTER_PWR_STATE(target_state))) {
+		/*
+		 * just for sleep mode for now, need to update to
+		 * support more modes, same for suspend finish call back.
+		 */
+		mmio_write_32(IMX_CMC1_BASE + 0x10, 0x1);
+		mmio_write_32(IMX_CMC1_BASE + 0x20, 0x1);
+
+	} else if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+		/*
+		 * for cluster off state, put cluster into power down mode,
+		 * config the cluster clock to be off.
+		 */
+		mmio_write_32(IMX_CMC1_BASE + 0x10, 0x7);
+		mmio_write_32(IMX_CMC1_BASE + 0x20, 0xf);
+	}
+
+	if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
+		/*
+		 * low power mode config info used by upower
+		 * to do low power mode transition.
+		 */
+		imx_set_pwr_mode_cfg(ADMA_PWR_MODE);
+		imx_set_pwr_mode_cfg(ACT_PWR_MODE);
+		imx_set_pwr_mode_cfg(PD_PWR_MODE);
+
+		/* clear the upower wakeup */
+		upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL);
+		upower_wait_resp();
+
+		/* enable the USB wakeup */
+		usb_wakeup_enable(true);
+
+		/* config the WUU to enabled the wakeup source */
+		mmio_write_32(IMX_PCC3_BASE + 0x98, 0xc0800000);
+
+		/* !!! clear all the pad wakeup pending event */
+		mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff);
+
+		/* enable upower usb phy wakeup by default */
+		mmio_setbits_32(IMX_WUU1_BASE + 0x18, BIT(4) | BIT(1) | BIT(0));
+
+		/* enabled all pad wakeup by default */
+		mmio_write_32(IMX_WUU1_BASE + 0x8, 0xffffffff);
+
+		/* save the AD domain context before entering PD mode */
+		imx_apd_ctx_save(cpu);
+	}
+}
+
+#define DRAM_LPM_STATUS		U(0x2802b004)
+void imx_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+	unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1());
+
+	if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
+		/* restore the ap domain context */
+		imx_apd_ctx_restore(cpu);
+
+		/* clear the upower wakeup */
+		upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL);
+		upower_wait_resp();
+
+		/* disable all pad wakeup */
+		mmio_write_32(IMX_WUU1_BASE + 0x8, 0x0);
+
+		/* clear all the pad wakeup pending event */
+		mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff);
+
+		/*
+		 * disable the usb wakeup after resume to make sure the pending
+		 * usb wakeup in WUU can be cleared successfully, otherwise,
+		 * APD will resume failed in next PD mode.
+		 */
+		usb_wakeup_enable(false);
+
+		/* re-init the SCMI channel */
+		imx8ulp_init_scmi_server();
+	}
+
+	/*
+	 * wait for DDR is ready when DDR is under the RTD
+	 * side control for power saving
+	 */
+	while (mmio_read_32(DRAM_LPM_STATUS) != 0) {
+		;
+	}
+
+	/*
+	 * when resume from low power mode, need to delay for a while
+	 * before access the CMC register.
+	 */
+	udelay(5);
+
+	/* clear cluster's LPM setting. */
+	mmio_write_32(IMX_CMC1_BASE + 0x20, 0x0);
+	mmio_write_32(IMX_CMC1_BASE + 0x10, 0x0);
+
+	/* clear core's LPM setting */
+	mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x0);
+	mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x0);
+
+	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+		imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
+		plat_gic_cpuif_enable();
+	} else {
+		dsb();
+		write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT));
+		isb();
+	}
+}
+
+void __dead2 imx8ulp_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
+{
+	while (1) {
+		wfi();
+	}
+}
+
+void __dead2 imx8ulp_system_reset(void)
+{
+	imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY);
+
+	/* Write invalid command to WDOG CNT to trigger reset */
+	mmio_write_32(IMX_WDOG3_BASE + 0x4, 0x12345678);
+
+	while (true) {
+		wfi();
+	}
+}
+
+int imx_validate_power_state(unsigned int power_state,
+			 psci_power_state_t *req_state)
+{
+	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+	int pwr_type = psci_get_pstate_type(power_state);
+
+	if (pwr_lvl > PLAT_MAX_PWR_LVL) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	if (pwr_type == PSTATE_TYPE_STANDBY) {
+		CORE_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
+		CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE;
+	}
+
+	/* No power down state support */
+	if (pwr_type == PSTATE_TYPE_POWERDOWN) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+void imx_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	unsigned int i;
+
+	for (i = IMX_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++) {
+		req_state->pwr_domain_state[i] = PLAT_POWER_DOWN_OFF_STATE;
+	}
+}
+
+void __dead2 imx_system_off(void)
+{
+	unsigned int i;
+
+	/* config the all the core into OFF mode and IRQ masked. */
+	for (i = 0U; i < PLATFORM_CORE_COUNT; i++) {
+		/* disable wakeup from wkpu */
+		mmio_write_32(WKPUx(i), 0x0);
+
+		/* reset the core reset entry to 0x1000 */
+		imx_pwr_set_cpu_entry(i, 0x1000);
+
+		/* config the core power mode to off */
+		mmio_write_32(AD_COREx_LPMODE(i), 0x3);
+	}
+
+	plat_gic_cpuif_disable();
+
+	/* power off all the pad */
+	apd_io_pad_off();
+
+	/* Config the power mode info for entering DPD mode and ACT mode */
+	imx_set_pwr_mode_cfg(ADMA_PWR_MODE);
+	imx_set_pwr_mode_cfg(ACT_PWR_MODE);
+	imx_set_pwr_mode_cfg(DPD_PWR_MODE);
+
+	/* Set the APD domain into DPD mode */
+	mmio_write_32(IMX_CMC1_BASE + 0x10, 0x7);
+	mmio_write_32(IMX_CMC1_BASE + 0x20, 0x1f);
+
+	/* make sure no pending upower wakeup */
+	upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL);
+	upower_wait_resp();
+
+	/* enable the upower wakeup from wuu, act as APD boot up method  */
+	mmio_write_32(IMX_PCC3_BASE + 0x98, 0xc0800000);
+	mmio_setbits_32(IMX_WUU1_BASE + 0x18, BIT(4));
+
+	/* make sure no pad wakeup event is pending */
+	mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff);
+
+	wfi();
+
+	ERROR("power off failed.\n");
+	panic();
+}
+
+static const plat_psci_ops_t imx_plat_psci_ops = {
+	.pwr_domain_on = imx_pwr_domain_on,
+	.pwr_domain_on_finish = imx_pwr_domain_on_finish,
+	.validate_ns_entrypoint = imx_validate_ns_entrypoint,
+	.system_off = imx_system_off,
+	.system_reset = imx8ulp_system_reset,
+	.pwr_domain_off = imx_pwr_domain_off,
+	.pwr_domain_suspend = imx_domain_suspend,
+	.pwr_domain_suspend_finish = imx_domain_suspend_finish,
+	.get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
+	.validate_power_state = imx_validate_power_state,
+	.pwr_domain_pwr_down_wfi = imx8ulp_pwr_domain_pwr_down_wfi,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	secure_entrypoint = sec_entrypoint;
+	imx_pwr_set_cpu_entry(0, sec_entrypoint);
+	*psci_ops = &imx_plat_psci_ops;
+
+	mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f);
+	mmio_write_32(IMX_SIM1_BASE + 0x3c, 0xffffffff);
+
+	return 0;
+}
diff --git a/plat/imx/imx8ulp/include/dram.h b/plat/imx/imx8ulp/include/dram.h
new file mode 100644
index 00000000..9ed8969a
--- /dev/null
+++ b/plat/imx/imx8ulp/include/dram.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRAM_H
+#define DRAM_H
+
+void dram_init(void);
+
+#endif /* DRAM_H */
+
diff --git a/plat/imx/imx8ulp/include/imx8ulp_caam.h b/plat/imx/imx8ulp/include/imx8ulp_caam.h
new file mode 100644
index 00000000..1b93d7dd
--- /dev/null
+++ b/plat/imx/imx8ulp/include/imx8ulp_caam.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2021-2024 NXP.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8ULP_CAAM_H
+#define IMX8ULP_CAAM_H
+
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+
+#define CAAM_JR0MID		(IMX_CAAM_BASE + 0x10)
+#define CAAM_JR1MID		(IMX_CAAM_BASE + 0x18)
+#define CAAM_JR2MID		(IMX_CAAM_BASE + 0x20)
+#define CAAM_JR3MID		(IMX_CAAM_BASE + 0x28)
+#define CAAM_NS_MID		(0x7)
+
+#define JR0_BASE		(IMX_CAAM_BASE + 0x1000)
+
+void imx8ulp_caam_init(void);
+
+#endif /* IMX8ULP_CAAM_H */
diff --git a/plat/imx/imx8ulp/include/platform_def.h b/plat/imx/imx8ulp/include/platform_def.h
new file mode 100644
index 00000000..20c5851b
--- /dev/null
+++ b/plat/imx/imx8ulp/include/platform_def.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <lib/utils_def.h>
+
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+#define PLATFORM_STACK_SIZE		0x400
+#define CACHE_WRITEBACK_GRANULE		64
+
+#define PLAT_PRIMARY_CPU		0x0
+#define PLATFORM_MAX_CPU_PER_CLUSTER	2
+#define PLATFORM_CLUSTER_COUNT		1
+#define PLATFORM_CORE_COUNT		2
+#define PLATFORM_CLUSTER0_CORE_COUNT	2
+#define PLATFORM_CLUSTER1_CORE_COUNT	0
+
+#define IMX_PWR_LVL0			MPIDR_AFFLVL0
+#define IMX_PWR_LVL1			MPIDR_AFFLVL1
+#define IMX_PWR_LVL2			MPIDR_AFFLVL2
+
+#define PWR_DOMAIN_AT_MAX_LVL		U(1)
+#define PLAT_MAX_PWR_LVL		U(2)
+
+#define PLAT_SLEEP_RET_STATE		U(1)
+#define PLAT_DEEP_SLEEP_RET_STATE	U(2)
+#define PLAT_MAX_RET_STATE		U(3)
+
+#define PLAT_POWER_DOWN_OFF_STATE	U(4)
+#define PLAT_DEEP_POWER_DOWN_STATE	U(5)
+#define PLAT_MAX_OFF_STATE		U(6)
+
+#define BL31_BASE			0x20040000
+#define BL31_LIMIT			0x20070000
+
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 32)
+
+#ifdef SPD_trusty
+#define MAX_XLAT_TABLES			11
+#define MAX_MMAP_REGIONS		12
+#else
+#define MAX_XLAT_TABLES			10
+#define MAX_MMAP_REGIONS		11
+#endif
+
+#define PLAT_GICD_BASE			U(0x2d400000)
+#define PLAT_GICR_BASE			U(0x2d440000)
+#define DEVICE0_BASE			U(0x20000000)
+#define DEVICE0_SIZE			U(0x10000000)
+#define DEVICE1_BASE			U(0x30000000)
+#define DEVICE1_SIZE			U(0x10000000)
+#define DEVICE2_BASE			U(0x8ff00000)
+#define DEVICE2_SIZE			U(0x00001000)
+#define IMX_LPUART4_BASE		U(0x29390000)
+#define IMX_LPUART5_BASE		U(0x293a0000)
+#define IMX_LPUART_BASE			IMX_LPUART5_BASE
+#define IMX_CAAM_BASE			U(0x292e0000)
+#define IMX_BOOT_UART_CLK_IN_HZ		24000000
+#define IMX_CONSOLE_BAUDRATE		115200
+
+#define IMX_CGC1_BASE			U(0x292c0000)
+#define IMX_PCC3_BASE			U(0x292d0000)
+#define IMX_PCC4_BASE			U(0x29800000)
+#define IMX_SIM2_BASE			U(0x2da50000)
+#define IMX_CGC2_BASE			U(0x2da60000)
+#define IMX_PCC5_BASE			U(0x2da70000)
+#define IMX_MU0B_BASE			U(0x29220000)
+#define IMX_CMC1_BASE			U(0x29240000)
+#define IMX_WUU1_BASE			U(0x29260000)
+#define IMX_SIM1_BASE			U(0x29290000)
+#define IMX_GPIOD_BASE			U(0x2e200000)
+#define IMX_GPIOE_BASE			U(0x2d000000)
+#define IMX_GPIOF_BASE			U(0x2d010000)
+#define IMX_WDOG3_BASE			U(0x292a0000)
+#define IMX_TPM5_BASE			U(0x29340000)
+
+#define SRAM0_BASE			U(0x2201F000)
+
+#define IOMUXC_PTD_PCR_BASE		U(0x298c0000)
+#define IOMUXC_PTE_PCR_BASE		U(0x298c0080)
+#define IOMUXC_PTF_PCR_BASE		U(0x298c0100)
+#define IOMUXC_PSMI_BASE0		U(0x298c0800)
+#define IOMUXC_PSMI_BASE1		U(0x298c0838)
+#define IOMUXC_PSMI_BASE2		U(0x298c0954)
+#define IOMUXC_PSMI_BASE3		U(0x298c0994)
+#define IOMUXC_PSMI_BASE4		U(0x298c0a58)
+
+#define IMX_ROM_ENTRY			U(0x1000)
+#define COUNTER_FREQUENCY		1000000
+
+#define PLAT_NS_IMAGE_OFFSET		0x80200000
+
+#define BL31_NOBITS_BASE    0x20058000
+#define BL31_NOBITS_LIMIT   0x2006d000
+
+#define BL31_RWDATA_BASE    0x2006d000
+#define BL31_RWDATA_LIMIT   0x20070000
+
+#define BL32_FDT_OVERLAY_ADDR		0x9d000000
+
+#ifdef SPD_trusty
+#define IMX_TRUSTY_STACK_SIZE 0x100
+#endif
+
+/* system memory map define */
+#define DEVICE0_MAP	MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW)
+#define DEVICE1_MAP	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW)
+/* Map partial DRAM space for DRAM low-power mode control */
+#define DEVICE2_MAP	MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, MT_DEVICE | MT_RW)
+ /* MU and FSB */
+#define ELE_MAP		MAP_REGION_FLAT(0x27010000, 0x20000, MT_DEVICE | MT_RW | MT_NS)
+#define SEC_SIM_MAP	MAP_REGION_FLAT(0x2802B000, 0x1000, MT_DEVICE | MT_RW | MT_NS) /* SEC SIM */
+/* For SCMI shared memory region */
+#define SRAM0_MAP	MAP_REGION_FLAT(SRAM0_BASE, 0x1000, MT_RW | MT_DEVICE)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx8ulp/include/scmi.h b/plat/imx/imx8ulp/include/scmi.h
new file mode 100644
index 00000000..03e16f5e
--- /dev/null
+++ b/plat/imx/imx8ulp/include/scmi.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8_SCMI_H
+#define IMX8_SCMI_H
+
+#include <stdint.h>
+
+#define SCMI_SHMEM_CHANNEL_ERROR	BIT_32(1)
+#define SCMI_SHMEM_CHANNEL_FREE		BIT_32(0)
+
+#define SCMI_SHMEM_FLAG_INTR_ENABLED	BIT_32(0)
+
+enum scmi_std_protocol {
+	SCMI_PROTOCOL_BASE = 0x10,
+	SCMI_PROTOCOL_POWER_DOMAIN = 0x11,
+	SCMI_PROTOCOL_SYS_POWER = 0x12,
+	SCMI_PROTOCOL_PERF_DOMAIN = 0x13,
+	SCMI_PROTOCOL_CLK = 0x14,
+	SCMI_PROTOCOL_SENSOR = 0x15,
+	SCMI_PROTOCOL_RESET_DOMAIN = 0x16,
+};
+
+#define MSG_ID(m)	((m) & 0xff)
+#define MSG_TYPE(m)	(((m) >> 8) & 0x3)
+#define MSG_PRO_ID(m)	(((m) >> 10) & 0xff)
+#define MSG_TOKEN(m)	(((m) >> 18) & 0x3ff)
+
+enum {
+	SCMI_POWER_DOMAIN_PROTOCOL	= 0x11,
+	SCMI_SYS_PWR_DOMAIN_PROTOCOL	= 0x12,
+	SCMI_PER_DOMAIN_PROTOCOL	= 0x13,
+	SCMI_CLK_DOMAIN_PROTOCOL	= 0x14,
+	SCMI_SENSOR_PROTOCOL		= 0x15,
+};
+
+#define PROTOCOL_VERSION			0
+#define PROTOCOL_ATTRIBUTES			1
+#define PROTOCOL_MESSAGE_ATTRIBUTES		2
+#define BASE_DISCOVER_VENDOR			3
+#define BASE_DISCOVER_SUB_VENDOR		4
+#define BASE_DISCOVER_IMPLEMENTATION_VERSION	5
+#define BASE_DISCOVER_LIST_PROTOCOLS		6
+#define BASE_DISCOVER_AGENT			7
+#define BASE_NOTIFY_ERRORS			8
+#define BASE_SET_DEVICE_PERMISSIONS		9
+#define BASE_SET_PROTOCOL_PERMISSIONS		0xA
+#define BASE_RESET_AGENT_CONFIGURATION		0xB
+
+enum {
+	SCMI_RET_SUCCESS = 0,
+	SCMI_RET_NOT_SUPPORTED = -1,
+	SCMI_RET_INVALID_PARAMETERS = -2,
+	SCMI_RET_DENIED = -3,
+	SCMI_RET_NOT_FOUND = -4,
+	SCMI_RET_OUT_OF_RANGE = -5,
+	SCMI_RET_BUSY = -6,
+	SCMI_RET_COMMS_ERROR = -7,
+	SCMI_RET_GENERIC_ERROR = -8,
+	SCMI_RET_HARDWARE_ERROR = -9,
+	SCMI_RET_PROTOCOL_ERROR = -10,
+};
+
+#define POWER_DOMAIN_ATTRIBUTES			3
+#define POWER_DOMAIN_SUPPORT_NOTIFICATION	BIT(31)
+#define POWER_DOMAIN_SUPPORT_ASYNCHRONOUS	BIT(30)
+#define POWER_DOMAIN_SUPPORT_SYNCHRONOUS	BIT(29)
+
+#define POWER_STATE_SET			4
+#define POWER_STATE_GET			5
+#define POWER_STATE_NOTIFY		6
+#define	POWER_STATE_CHANGE_REQUESTED_NOTIFY	7
+
+int scmi_power_domain_handler(uint32_t msg_id, void *shmem);
+
+#define PERFORMANCE_DOMAIN_ATTRIBUTES		3
+#define PERFORMANCE_DESCRIBE_LEVELS		4
+#define PERFORMANCE_LIMITS_SET			5
+#define PERFORMANCE_LIMITS_GET			6
+#define PERFORMANCE_LEVEL_SET			7
+#define PERFORMANCE_LEVEL_GET			8
+#define PERFORMANCE_NOTIFY_LIMITS		9
+#define PERFORMANCE_NOTIFY_LEVEL		0xA
+#define PERFORMANCE_DESCRIBE_FAST_CHANNEL	0xB
+
+int scmi_perf_domain_handler(uint32_t msg_id, void *shmem);
+
+#define SENSOR_DESCRIPTION_GET			0x003
+#define SENSOR_CONFIG_SET			0x004
+#define SENSOR_TRIP_POINT_SET			0x005
+#define SENSOR_READING_GET			0x006
+
+int scmi_sensor_handler(uint32_t msg_id, void *shmem);
+
+#define SMC_SHMEM_BASE	0x2201f000
+
+#endif /* IMX8_SCMI_H */
diff --git a/plat/imx/imx8ulp/include/scmi_sensor.h b/plat/imx/imx8ulp/include/scmi_sensor.h
new file mode 100644
index 00000000..5dab8986
--- /dev/null
+++ b/plat/imx/imx8ulp/include/scmi_sensor.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ *      System Control and Management Interface (SCMI) support.
+ */
+
+#ifndef INTERNAL_SCMI_SENSOR_H
+#define INTERNAL_SCMI_SENSOR_H
+
+#include <stdint.h>
+
+#define SCMI_PROTOCOL_VERSION_SENSOR UINT32_C(0x10000)
+
+/*
+ * PROTOCOL_ATTRIBUTES
+ */
+struct scmi_sensor_protocol_attributes_p2a {
+	int32_t status;
+	uint32_t attributes;
+	uint32_t sensor_reg_address_low;
+	uint32_t sensor_reg_address_high;
+	uint32_t sensor_reg_len;
+};
+
+/*
+ * SENSOR_READING_GET
+ */
+#define SCMI_SENSOR_PROTOCOL_READING_GET_ASYNC_FLAG_MASK    (1 << 0)
+
+struct scmi_sensor_protocol_reading_get_a2p {
+	uint32_t sensor_id;
+	uint32_t flags;
+};
+
+struct scmi_sensor_protocol_reading_get_p2a {
+	int32_t status;
+	uint32_t sensor_value_low;
+	uint32_t sensor_value_high;
+};
+
+/*
+ * SENSOR_DESCRIPTION_GET
+ */
+ #define SCMI_SENSOR_DESCS_MAX(MAILBOX_SIZE) \
+	((sizeof(struct scmi_sensor_protocol_description_get_p2a) < MAILBOX_SIZE) \
+	? ((MAILBOX_SIZE - \
+	   sizeof(struct scmi_sensor_protocol_description_get_p2a)) \
+	   / sizeof(struct scmi_sensor_desc)) \
+	: 0)
+
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS              0
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS   11
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS 22
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS   27
+
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_MASK \
+	(UINT32_C(0xFF) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK \
+	(UINT32_C(0x1F) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MASK \
+	(UINT32_C(0x1F) << \
+	SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK \
+	(UINT32_C(0x1F) << SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS)
+
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MAX \
+	(int32_t)(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK >> 1)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MIN \
+	(-(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MAX + 1))
+
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MAX \
+	(int32_t)(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK >> 1)
+#define SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MIN \
+	(-(SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MAX + 1))
+
+#define SCMI_SENSOR_DESC_ATTRIBUTES_HIGH(SENSOR_TYPE, UNIT_MULTIPLIER, \
+					 UPDATE_MULTIPLIER, UPDATE_INTERVAL) \
+	( \
+	(((SENSOR_TYPE) << \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_POS) & \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_TYPE_MASK) | \
+	   (((UNIT_MULTIPLIER) << \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_POS) & \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UNIT_MULTIPLIER_MASK) | \
+	   (((UPDATE_MULTIPLIER) << \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_POS) & \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_MULTIPLIER_MASK) | \
+	   (((UPDATE_INTERVAL) << \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_POS) & \
+	   SCMI_SENSOR_DESC_ATTRS_HIGH_SENSOR_UPDATE_INTERVAL_MASK) \
+	)
+
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS              0
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS   16
+
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_MASK \
+	(UINT32_C(0xFFF) << SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS)
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_MASK \
+	(UINT32_C(0xFFFF) << SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS)
+
+#define SCMI_SENSOR_NUM_SENSOR_FLAGS(NUM_DESCS, NUM_REMAINING_DESCS) \
+	( \
+	(((NUM_DESCS) << \
+	  SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_POS) & \
+	  SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_DESCS_MASK) | \
+	  (((NUM_REMAINING_DESCS) << \
+	    SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_POS) & \
+	    SCMI_SENSOR_NUM_SENSOR_FLAGS_NUM_REMAINING_DESCS_MASK) \
+	)
+
+#define SCMI_SENSOR_NAME_LEN    16
+
+struct scmi_sensor_desc {
+	uint32_t sensor_id;
+	uint32_t sensor_attributes_low;
+	uint32_t sensor_attributes_high;
+	char sensor_name[SCMI_SENSOR_NAME_LEN];
+};
+
+struct scmi_sensor_protocol_description_get_a2p {
+	uint32_t desc_index;
+};
+
+struct scmi_sensor_protocol_description_get_p2a {
+	int32_t status;
+	uint32_t num_sensor_flags;
+	struct scmi_sensor_desc sensor_desc[];
+};
+
+/* Event indices */
+enum scmi_sensor_api_idx {
+	SCMI_SENSOR_EVENT_IDX_REQUEST,
+	SCMI_SENSOR_EVENT_IDX_COUNT,
+};
+
+#endif /* INTERNAL_SCMI_SENSOR_H */
diff --git a/plat/imx/imx8ulp/include/xrdc.h b/plat/imx/imx8ulp/include/xrdc.h
new file mode 100644
index 00000000..15250f03
--- /dev/null
+++ b/plat/imx/imx8ulp/include/xrdc.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IMX8ULP_XRDC_H
+#define IMX8ULP_XRDC_H
+
+#define DID_MAX 8
+#define PAC_SLOT_ALL 128
+#define MSC_SLOT_ALL 8
+
+enum xrdc_mda_sa {
+	MDA_SA_S,
+	MDA_SA_NS,
+	MDA_SA_PT, /* pass through master's secure/nonsecure attribute */
+};
+
+struct xrdc_mda_config {
+	uint16_t mda_id;
+	uint16_t did;
+	enum xrdc_mda_sa sa;
+};
+
+struct xrdc_pac_msc_config {
+	uint16_t pac_msc_id;
+	uint16_t slot_id;
+	uint8_t dsel[DID_MAX];
+};
+
+struct xrdc_mrc_config {
+	uint16_t mrc_id;
+	uint16_t region_id;
+	uint32_t region_start;
+	uint32_t region_size;
+	uint8_t dsel[DID_MAX];
+	uint16_t accset[2];
+};
+
+/* APIs to apply and enable XRDC */
+int xrdc_apply_lpav_config(void);
+int xrdc_apply_hifi_config(void);
+int xrdc_apply_apd_config(void);
+void xrdc_enable(void);
+
+#endif
diff --git a/plat/imx/imx8ulp/platform.mk b/plat/imx/imx8ulp/platform.mk
new file mode 100644
index 00000000..f1e53ca9
--- /dev/null
+++ b/plat/imx/imx8ulp/platform.mk
@@ -0,0 +1,69 @@
+#
+# Copyright 2021-2024 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+PLAT_INCLUDES		:=	-Iplat/imx/imx8ulp/include		\
+				-Iplat/imx/common/include		\
+				-Iplat/imx/imx8ulp/upower
+
+IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
+				plat/common/plat_gicv3.c		\
+				plat/common/plat_psci_common.c		\
+				plat/imx/common/plat_imx8_gic.c
+
+BL31_SOURCES		+=	plat/imx/common/lpuart_console.S	\
+				plat/imx/common/imx8_helpers.S		\
+				plat/imx/imx8ulp/imx8ulp_bl31_setup.c	\
+				plat/imx/imx8ulp/imx8ulp_psci.c		\
+				plat/imx/imx8ulp/apd_context.c		\
+				plat/imx/common/imx8_topology.c		\
+				plat/imx/common/imx_sip_svc.c		\
+				plat/imx/common/imx_sip_handler.c	\
+				plat/imx/common/imx_bl31_common.c	\
+				plat/common/plat_psci_common.c		\
+				lib/cpus/aarch64/cortex_a35.S		\
+				drivers/delay_timer/delay_timer.c	\
+				drivers/delay_timer/generic_delay_timer.c \
+				plat/imx/imx8ulp/xrdc/xrdc_core.c		\
+				plat/imx/imx8ulp/imx8ulp_caam.c         \
+				plat/imx/imx8ulp/dram.c 	        \
+				drivers/scmi-msg/base.c			\
+				drivers/scmi-msg/entry.c		\
+				drivers/scmi-msg/smt.c			\
+				drivers/scmi-msg/power_domain.c		\
+				drivers/scmi-msg/sensor.c		\
+				plat/imx/imx8ulp/scmi/scmi.c		\
+				plat/imx/imx8ulp/scmi/scmi_pd.c		\
+				plat/imx/imx8ulp/scmi/scmi_sensor.c	\
+				plat/imx/imx8ulp/upower/upower_api.c	\
+				plat/imx/imx8ulp/upower/upower_hal.c	\
+				${XLAT_TABLES_LIB_SRCS}			\
+				${IMX_GIC_SOURCES}
+
+ifeq ($(findstring clang,$(notdir $(CC))),)
+    TF_CFLAGS_aarch64	+=	-fno-strict-aliasing
+endif
+
+USE_COHERENT_MEM	:=	1
+RESET_TO_BL31		:=	1
+SEPARATE_NOBITS_REGION	:=	1
+SEPARATE_RWDATA_REGION	:=	1
+PROGRAMMABLE_RESET_ADDRESS	:=	1
+COLD_BOOT_SINGLE_CPU := 1
+WARMBOOT_ENABLE_DCACHE_EARLY	:=	1
+BL32_BASE		?=	0xa6000000
+BL32_SIZE		?=	0x2000000
+$(eval $(call add_define,BL32_BASE))
+$(eval $(call add_define,BL32_SIZE))
+
+ifeq (${SPD},trusty)
+	BL31_CFLAGS    +=      -DPLAT_XLAT_TABLES_DYNAMIC=1
+endif
diff --git a/plat/imx/imx8ulp/scmi/scmi.c b/plat/imx/imx8ulp/scmi/scmi.c
new file mode 100644
index 00000000..5d3e7d72
--- /dev/null
+++ b/plat/imx/imx8ulp/scmi/scmi.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <stdint.h>
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+
+#include <platform_def.h>
+
+#define SMT_BUFFER_BASE		0x2201f000
+#define SMT_BUFFER0_BASE	SMT_BUFFER_BASE
+#define SMT_BUFFER1_BASE	(SMT_BUFFER_BASE + 0x200)
+
+static struct scmi_msg_channel scmi_channel[] = {
+	[0] = {
+		.shm_addr = SMT_BUFFER0_BASE,
+		.shm_size = SMT_BUF_SLOT_SIZE,
+	},
+};
+
+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(scmi_channel));
+
+	return &scmi_channel[agent_id];
+}
+
+static const char vendor[] = "NXP";
+static const char sub_vendor[] = "";
+
+const char *plat_scmi_vendor_name(void)
+{
+	return vendor;
+}
+
+const char *plat_scmi_sub_vendor_name(void)
+{
+	return sub_vendor;
+}
+
+/* Currently supporting Clocks and Reset Domains */
+static const uint8_t plat_protocol_list[] = {
+	SCMI_PROTOCOL_ID_POWER_DOMAIN,
+	SCMI_PROTOCOL_ID_SENSOR,
+	0U /* Null termination */
+};
+
+size_t plat_scmi_protocol_count(void)
+{
+	return ARRAY_SIZE(plat_protocol_list) - 1U;
+}
+
+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
+{
+	return plat_protocol_list;
+}
+
+void imx8ulp_init_scmi_server(void)
+{
+	size_t i;
+
+	for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) {
+		scmi_smt_init_agent_channel(&scmi_channel[i]);
+	}
+}
diff --git a/plat/imx/imx8ulp/scmi/scmi_pd.c b/plat/imx/imx8ulp/scmi/scmi_pd.c
new file mode 100644
index 00000000..8e7e5d66
--- /dev/null
+++ b/plat/imx/imx8ulp/scmi/scmi_pd.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <inttypes.h>
+#include <lib/libc/errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <platform_def.h>
+#include <scmi.h>
+
+#include <upower_api.h>
+
+#define POWER_STATE_ON	(0 << 30)
+#define POWER_STATE_OFF	(1 << 30)
+
+extern bool is_lpav_owned_by_apd(void);
+
+enum {
+	PS0 = 0,
+	PS1 = 1,
+	PS2 = 2,
+	PS3 = 3,
+	PS4 = 4,
+	PS5 = 5,
+	PS6 = 6,
+	PS7 = 7,
+	PS8 = 8,
+	PS9 = 9,
+	PS10 = 10,
+	PS11 = 11,
+	PS12 = 12,
+	PS13 = 13,
+	PS14 = 14,
+	PS15 = 15,
+	PS16 = 16,
+	PS17 = 17,
+	PS18 = 18,
+	PS19 = 19,
+};
+
+#define SRAM_DMA1		BIT(6)
+#define SRAM_FLEXSPI2		BIT(7)
+#define SRAM_USB0		BIT(10)
+#define SRAM_USDHC0		BIT(11)
+#define SRAM_USDHC1		BIT(12)
+#define SRAM_USDHC2_USB1	BIT(13)
+#define SRAM_DCNANO		GENMASK_32(18, 17)
+#define SRAM_EPDC		GENMASK_32(20, 19)
+#define SRAM_DMA2		BIT(21)
+#define SRAM_GPU2D		GENMASK_32(23, 22)
+#define SRAM_GPU3D		GENMASK_32(25, 24)
+#define SRAM_HIFI4		BIT(26)
+#define SRAM_ISI_BUFFER		BIT(27)
+#define SRAM_MIPI_CSI_FIFO	BIT(28)
+#define SRAM_MIPI_DSI_FIFO	BIT(29)
+#define SRAM_PXP		BIT(30)
+
+#define SRAM_DMA0		BIT_64(33)
+#define SRAM_FLEXCAN		BIT_64(34)
+#define SRAM_FLEXSPI0		BIT_64(35)
+#define SRAM_FLEXSPI1		BIT_64(36)
+
+struct psw {
+	char *name;
+	uint32_t reg;
+	int power_state;
+	uint32_t count;
+	int flags;
+};
+
+#define ALWAYS_ON BIT(0)
+
+static struct psw imx8ulp_psw[] = {
+	[PS6] = { .name = "PS6", .reg = PS6, .flags = ALWAYS_ON, .power_state = POWER_STATE_ON },
+	[PS7] = { .name = "PS7", .reg = PS7, .power_state = POWER_STATE_OFF },
+	[PS8] = { .name = "PS8", .reg = PS8, .power_state = POWER_STATE_OFF },
+	[PS13] = { .name = "PS13", .reg = PS13, .power_state = POWER_STATE_OFF },
+	[PS14] = { .name = "PS14", .reg = PS14, .flags = ALWAYS_ON, .power_state = POWER_STATE_OFF },
+	[PS15] = { .name = "PS15", .reg = PS15, .power_state = POWER_STATE_OFF },
+	[PS16] = { .name = "PS16", .reg = PS16, .flags = ALWAYS_ON, .power_state = POWER_STATE_ON },
+};
+
+struct power_domain {
+	char *name;
+	uint32_t reg;
+	uint32_t psw_parent;
+	uint32_t sram_parent;
+	uint64_t bits;
+	uint32_t power_state;
+	bool lpav; /* belong to lpav domain */
+	uint32_t sw_rst_reg; /* pcc sw reset reg offset */
+};
+
+/* The Rich OS need flow the macro */
+#define IMX8ULP_PD_DMA1		0
+#define IMX8ULP_PD_FLEXSPI2	1
+#define IMX8ULP_PD_USB0		2
+#define IMX8ULP_PD_USDHC0	3
+#define IMX8ULP_PD_USDHC1	4
+#define IMX8ULP_PD_USDHC2_USB1	5
+#define IMX8ULP_PD_DCNANO	6
+#define IMX8ULP_PD_EPDC		7
+#define IMX8ULP_PD_DMA2		8
+#define IMX8ULP_PD_GPU2D	9
+#define IMX8ULP_PD_GPU3D	10
+#define IMX8ULP_PD_HIFI4	11
+#define IMX8ULP_PD_ISI		12
+#define IMX8ULP_PD_MIPI_CSI	13
+#define IMX8ULP_PD_MIPI_DSI	14
+#define IMX8ULP_PD_PXP		15
+
+#define IMX8ULP_PD_PS6		16
+#define IMX8ULP_PD_PS7		17
+#define IMX8ULP_PD_PS8		18
+#define IMX8ULP_PD_PS13		19
+#define IMX8ULP_PD_PS14		20
+#define IMX8ULP_PD_PS15		21
+#define IMX8ULP_PD_PS16		22
+#define IMX8ULP_PD_MAX		23
+
+/* LPAV peripheral PCC */
+#define PCC_GPU2D	(IMX_PCC5_BASE + 0xf0)
+#define PCC_GPU3D	(IMX_PCC5_BASE + 0xf4)
+#define PCC_EPDC	(IMX_PCC5_BASE + 0xcc)
+#define PCC_CSI		(IMX_PCC5_BASE + 0xbc)
+#define PCC_PXP		(IMX_PCC5_BASE + 0xd0)
+
+#define PCC_SW_RST	BIT(28)
+
+#define PWR_DOMAIN(_name, _reg, _psw_parent, _sram_parent, \
+		   _bits, _state, _lpav, _rst_reg) \
+	{ \
+		.name = _name, \
+		.reg = _reg, \
+		.psw_parent = _psw_parent, \
+		.sram_parent = _sram_parent, \
+		.bits = _bits, \
+		.power_state = _state, \
+		.lpav = _lpav, \
+		.sw_rst_reg = _rst_reg, \
+	}
+
+static struct power_domain scmi_power_domains[] = {
+	PWR_DOMAIN("DMA1", IMX8ULP_PD_DMA1, PS6, PS6, SRAM_DMA1, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("FLEXSPI2", IMX8ULP_PD_FLEXSPI2, PS6, PS6, SRAM_FLEXSPI2, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("USB0", IMX8ULP_PD_USB0, PS6, PS6, SRAM_USB0, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("USDHC0", IMX8ULP_PD_USDHC0, PS6, PS6, SRAM_USDHC0, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("USDHC1", IMX8ULP_PD_USDHC1, PS6, PS6, SRAM_USDHC1, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("USDHC2_USB1", IMX8ULP_PD_USDHC2_USB1, PS6, PS6, SRAM_USDHC2_USB1, POWER_STATE_OFF, false, 0U),
+	PWR_DOMAIN("DCNano", IMX8ULP_PD_DCNANO, PS16, PS16, SRAM_DCNANO, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("EPDC", IMX8ULP_PD_EPDC, PS13, PS13, SRAM_EPDC, POWER_STATE_OFF, true, PCC_EPDC),
+	PWR_DOMAIN("DMA2", IMX8ULP_PD_DMA2, PS16, PS16, SRAM_DMA2, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("GPU2D", IMX8ULP_PD_GPU2D, PS16, PS16, SRAM_GPU2D, POWER_STATE_OFF, true, PCC_GPU2D),
+	PWR_DOMAIN("GPU3D", IMX8ULP_PD_GPU3D, PS7, PS7, SRAM_GPU3D, POWER_STATE_OFF, true, PCC_GPU3D),
+	PWR_DOMAIN("HIFI4", IMX8ULP_PD_HIFI4, PS8, PS8, SRAM_HIFI4, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("ISI", IMX8ULP_PD_ISI, PS16, PS16, SRAM_ISI_BUFFER, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("MIPI_CSI", IMX8ULP_PD_MIPI_CSI, PS15, PS16, SRAM_MIPI_CSI_FIFO, POWER_STATE_OFF, true, PCC_CSI),
+	PWR_DOMAIN("MIPI_DSI", IMX8ULP_PD_MIPI_DSI, PS14, PS16, SRAM_MIPI_DSI_FIFO, POWER_STATE_OFF, true, 0U),
+	PWR_DOMAIN("PXP", IMX8ULP_PD_PXP, PS13, PS13, SRAM_PXP | SRAM_EPDC, POWER_STATE_OFF, true, PCC_PXP)
+};
+
+size_t plat_scmi_pd_count(unsigned int agent_id __unused)
+{
+	return ARRAY_SIZE(scmi_power_domains);
+}
+
+const char *plat_scmi_pd_get_name(unsigned int agent_id __unused,
+				  unsigned int pd_id)
+{
+	if (pd_id >= IMX8ULP_PD_PS6) {
+		return imx8ulp_psw[pd_id - IMX8ULP_PD_PS6].name;
+	}
+
+	return scmi_power_domains[pd_id].name;
+}
+
+unsigned int plat_scmi_pd_get_state(unsigned int agent_id __unused,
+				    unsigned int pd_id __unused)
+{
+	if (pd_id >= IMX8ULP_PD_PS6) {
+		return imx8ulp_psw[pd_id - IMX8ULP_PD_PS6].power_state;
+	}
+
+	return scmi_power_domains[pd_id].power_state;
+}
+
+extern void upower_wait_resp(void);
+int upwr_pwm_power(const uint32_t swton[], const uint32_t memon[], bool on)
+{
+	int ret_val;
+	int ret;
+
+	if (on == true) {
+		ret = upwr_pwm_power_on(swton, memon, NULL);
+	} else {
+		ret = upwr_pwm_power_off(swton, memon, NULL);
+	}
+
+	if (ret != 0U) {
+		WARN("%s failed: ret: %d, state: %x\n", __func__, ret, on);
+		return ret;
+	}
+
+	upower_wait_resp();
+
+	ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
+	if (ret != UPWR_REQ_OK) {
+		WARN("Failure %d, %s\n", ret, __func__);
+		if (ret == UPWR_REQ_BUSY) {
+			return -EBUSY;
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int32_t plat_scmi_pd_psw(unsigned int index, unsigned int state)
+{
+	uint32_t psw_parent = scmi_power_domains[index].psw_parent;
+	uint32_t sram_parent = scmi_power_domains[index].sram_parent;
+	uint64_t swt;
+	bool on;
+	int ret = 0;
+
+	if ((imx8ulp_psw[psw_parent].flags & ALWAYS_ON) != 0U &&
+	    (imx8ulp_psw[sram_parent].flags & ALWAYS_ON) != 0U) {
+		return 0;
+	}
+
+	on = (state == POWER_STATE_ON) ? true : false;
+
+	if ((imx8ulp_psw[psw_parent].flags & ALWAYS_ON) == 0U) {
+		swt = 1 << imx8ulp_psw[psw_parent].reg;
+		if (imx8ulp_psw[psw_parent].count == 0U) {
+			if (on == false) {
+				WARN("off PSW[%d] that already in off state\n", psw_parent);
+				ret = -EACCES;
+			} else {
+				ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
+				imx8ulp_psw[psw_parent].count++;
+			}
+		} else {
+			if (on == true) {
+				imx8ulp_psw[psw_parent].count++;
+			} else {
+				imx8ulp_psw[psw_parent].count--;
+			}
+
+			if (imx8ulp_psw[psw_parent].count == 0U) {
+				ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
+			}
+		}
+	}
+
+	if (!(imx8ulp_psw[sram_parent].flags & ALWAYS_ON) && (psw_parent != sram_parent)) {
+		swt = 1 << imx8ulp_psw[sram_parent].reg;
+		if (imx8ulp_psw[sram_parent].count == 0U) {
+			if (on == false) {
+				WARN("off PSW[%d] that already in off state\n", sram_parent);
+				ret = -EACCES;
+			} else {
+				ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
+				imx8ulp_psw[sram_parent].count++;
+			}
+		} else {
+			if (on == true) {
+				imx8ulp_psw[sram_parent].count++;
+			} else {
+				imx8ulp_psw[sram_parent].count--;
+			}
+
+			if (imx8ulp_psw[sram_parent].count == 0U) {
+				ret = upwr_pwm_power((const uint32_t *)&swt, NULL, on);
+			}
+		}
+	}
+
+	return ret;
+}
+
+bool pd_allow_power_off(unsigned int pd_id)
+{
+	if (scmi_power_domains[pd_id].lpav) {
+		if (!is_lpav_owned_by_apd()) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+void assert_pcc_reset(unsigned int pcc)
+{
+	/* if sw_rst_reg is valid, assert the pcc reset */
+	if (pcc != 0U) {
+		mmio_clrbits_32(pcc, PCC_SW_RST);
+	}
+}
+
+int32_t plat_scmi_pd_set_state(unsigned int agent_id __unused,
+			       unsigned int flags,
+			       unsigned int pd_id,
+			       unsigned int state)
+{
+	unsigned int ps_idx;
+	uint64_t mem;
+	bool on;
+	int ret;
+
+	if (flags != 0U || pd_id >= IMX8ULP_PD_PS6) {
+		return SCMI_NOT_SUPPORTED;
+	}
+
+	ps_idx = 0;
+	while (ps_idx < IMX8ULP_PD_PS6 && scmi_power_domains[ps_idx].reg != pd_id) {
+		ps_idx++;
+	}
+
+	if (ps_idx == IMX8ULP_PD_PS6) {
+		return SCMI_NOT_FOUND;
+	}
+
+	if (state == scmi_power_domains[ps_idx].power_state) {
+		return SCMI_SUCCESS;
+	}
+
+	mem = scmi_power_domains[ps_idx].bits;
+	on = (state == POWER_STATE_ON ? true : false);
+	if (on == true) {
+		/* Assert pcc sw reset if necessary */
+		assert_pcc_reset(scmi_power_domains[ps_idx].sw_rst_reg);
+
+		ret = plat_scmi_pd_psw(ps_idx, state);
+		if (ret != 0U) {
+			return SCMI_DENIED;
+		}
+
+		ret = upwr_pwm_power(NULL, (const uint32_t *)&mem, on);
+		if (ret != 0U) {
+			return SCMI_DENIED;
+		}
+	} else {
+		if (!pd_allow_power_off(ps_idx)) {
+			return SCMI_DENIED;
+		}
+
+		ret = upwr_pwm_power(NULL, (const uint32_t *)&mem, on);
+		if (ret != 0U) {
+			return SCMI_DENIED;
+		}
+
+		ret = plat_scmi_pd_psw(ps_idx, state);
+		if (ret != 0U) {
+			return SCMI_DENIED;
+		}
+	}
+
+	scmi_power_domains[pd_id].power_state = state;
+
+	return SCMI_SUCCESS;
+}
diff --git a/plat/imx/imx8ulp/scmi/scmi_sensor.c b/plat/imx/imx8ulp/scmi/scmi_sensor.c
new file mode 100644
index 00000000..6976b2e2
--- /dev/null
+++ b/plat/imx/imx8ulp/scmi/scmi_sensor.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/libc/errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../../drivers/scmi-msg/sensor.h"
+
+#include <common/debug.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <scmi.h>
+
+#include <upower_api.h>
+
+/* Only Temperature now */
+static uint16_t imx_scmi_sensor_count(unsigned int agent_id __unused)
+{
+	return 1U;
+}
+
+uint8_t imx_scmi_sensor_max_requests(unsigned int agent_id __unused)
+{
+	return 1U;
+}
+
+extern int upower_read_temperature(uint32_t sensor_id, int32_t *temperature);
+int imx_scmi_sensor_reading_get(uint32_t agent_id __unused, uint16_t sensor_id __unused,
+				 uint32_t *val)
+{
+	int32_t temperature;
+	int ret;
+
+	ret = upower_read_temperature(1, &temperature);
+	if (ret != 0U) {
+		val[0] = 0xFFFFFFFF;
+	} else {
+		val[0] = temperature;
+	}
+
+	val[1] = 0;
+	val[2] = 0;
+	val[3] = 0;
+
+	return ret;
+}
+
+#define SCMI_SENSOR_NAME_LENGTH_MAX	16U
+
+uint32_t imx_scmi_sensor_state(uint32_t agent_id __unused, uint16_t sensor_id __unused)
+{
+	return 1U;
+}
+
+uint32_t imx_scmi_sensor_description_get(uint32_t agent_id __unused, uint16_t desc_index __unused,
+					  struct scmi_sensor_desc *desc __unused)
+{
+	desc->id = 0;
+	desc->attr_low = 0;
+	desc->attr_high = 2;
+	strlcpy((char *)desc->name, "UPOWER-TEMP", 12);
+	desc->power = 0;
+	desc->resolution = 0;
+	desc->min_range_low = 0;
+	desc->min_range_high = 0x80000000;
+	desc->max_range_low = 0xffffffff;
+	desc->max_range_high = 0x7fffffff;
+
+	return 1U;
+}
+
+REGISTER_SCMI_SENSOR_OPS(imx_scmi_sensor_count,
+			 imx_scmi_sensor_max_requests,
+			 NULL,
+			 imx_scmi_sensor_reading_get,
+			 imx_scmi_sensor_description_get,
+			 NULL,
+			 imx_scmi_sensor_state,
+			 NULL);
diff --git a/plat/imx/imx8ulp/upower/upmu.h b/plat/imx/imx8ulp/upower/upmu.h
new file mode 100644
index 00000000..ce4f47ed
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upmu.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MU_H
+#define MU_H
+
+#include <stdint.h>
+
+typedef volatile unsigned int vuint32_t;
+
+/****************************************************************************/
+/*				MODULE: Message Unit			    */
+/****************************************************************************/
+/* VER Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t FEATURE : 16;
+		vuint32_t MINOR : 8;
+		vuint32_t MAJOR : 8;
+	} B;
+} MU_VER_t;
+
+/* PAR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t TR_NUM : 8;
+		vuint32_t RR_NUM : 8;
+		vuint32_t GIR_NUM : 8;
+		vuint32_t FLAG_WIDTH : 8;
+	} B;
+} MU_PAR_t;
+
+/* CR Register */
+typedef union  {
+	vuint32_t R;
+	struct {
+		vuint32_t MUR : 1;
+		vuint32_t MURIE : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_CR_t;
+
+/* SR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t MURS : 1;
+		vuint32_t MURIP : 1;
+		vuint32_t EP : 1;
+		vuint32_t FUP : 1;
+		vuint32_t GIRP : 1;
+		vuint32_t TEP : 1;
+		vuint32_t RFP : 1;
+		vuint32_t CEP : 1;
+		vuint32_t rsrv_1 : 24;
+
+	} B;
+} MU_SR_t;
+
+/* CCR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t NMI : 1;
+		vuint32_t HR  : 1;
+		vuint32_t HRM : 1;
+		vuint32_t CLKE : 1;
+		vuint32_t RSTH : 1;
+		vuint32_t BOOT : 2;
+		vuint32_t rsrv_1 : 25;
+
+	} B;
+} MU_CCR0_t;
+
+/* CIER0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t rsrv_1 : 1;
+		vuint32_t HRIE : 1;
+		vuint32_t RUNIE : 1;
+		vuint32_t RAIE : 1;
+		vuint32_t HALTIE : 1;
+		vuint32_t WAITIE : 1;
+		vuint32_t STOPIE : 1;
+		vuint32_t PDIE : 1;
+		vuint32_t rsrv_2 : 24;
+	} B;
+} MU_CIER0_t;
+
+/* CSSR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t NMIC : 1;
+		vuint32_t HRIP : 1;
+		vuint32_t RUN  : 1;
+		vuint32_t RAIP : 1;
+		vuint32_t HALT : 1;
+		vuint32_t WAIT : 1;
+		vuint32_t STOP : 1;
+		vuint32_t PD : 1;
+		vuint32_t rsrv_1 : 24;
+	} B;
+} MU_CSSR0_t;
+
+/* CSR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t rsrv_1 : 1;
+		vuint32_t HRIP : 1;
+		vuint32_t RUN : 1;
+		vuint32_t RAIP : 1;
+		vuint32_t HALT : 1;
+		vuint32_t WAIT : 1;
+		vuint32_t STOP : 1;
+		vuint32_t PD : 1;
+		vuint32_t rsrv_2 : 24;
+	} B;
+} MU_CSR0_t;
+
+/* FCR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t F0 : 1;
+		vuint32_t F1 : 1;
+		vuint32_t F2 : 1;
+		vuint32_t rsrv_1 : 29;
+	} B;
+} MU_FCR_t;
+
+/* FSR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t F0 : 1;
+		vuint32_t F1 : 1;
+		vuint32_t F2 : 1;
+		vuint32_t rsrv_1 : 29;
+	} B;
+} MU_FSR_t;
+
+/* GIER Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t GIE0 : 1;
+		vuint32_t GIE1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_GIER_t;
+
+/* GCR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t GIR0 : 1;
+		vuint32_t GIR1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_GCR_t;
+
+/* GSR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t GIP0 : 1;
+		vuint32_t GIP1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_GSR_t;
+
+/* TCR Register */
+typedef union{
+	vuint32_t R;
+	struct {
+		vuint32_t TIE0 : 1;
+		vuint32_t TIE1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_TCR_t;
+
+/* TSR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t TE0 : 1;
+		vuint32_t TE1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_TSR_t;
+
+/* RCR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t RIE0 : 1;
+		vuint32_t RIE1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_RCR_t;
+
+/* RSR Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t RF0 : 1;
+		vuint32_t RF1 : 1;
+		vuint32_t rsrv_1 : 30;
+	} B;
+} MU_RSR_t;
+
+/* TR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t TR_DATA : 32;
+	} B;
+} MU_TR0_t;
+
+/* TR1 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t TR_DATA : 32;
+	} B;
+} MU_TR1_t;
+
+/* RR0 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t RR_DATA : 32;
+	} B;
+} MU_RR0_t;
+
+/* RR1 Register */
+typedef union {
+	vuint32_t R;
+	struct {
+		vuint32_t RR_DATA : 32;
+	} B;
+} MU_RR1_t;
+
+struct MU_t {
+	MU_VER_t VER;
+	MU_PAR_t PAR;
+	MU_CR_t CR;
+	MU_SR_t SR;
+	MU_CCR0_t CCR0;
+	MU_CIER0_t CIER0;
+	MU_CSSR0_t CSSR0;
+	MU_CSR0_t CSR0;
+	uint8_t MU_reserved0[224];
+	MU_FCR_t FCR;
+	MU_FSR_t FSR;
+	uint8_t MU_reserved1[8];
+	MU_GIER_t GIER;
+	MU_GCR_t GCR;
+	MU_GSR_t GSR;
+	uint8_t MU_reserved2[4];
+	MU_TCR_t TCR;
+	MU_TSR_t TSR;
+	MU_RCR_t RCR;
+	MU_RSR_t RSR;
+	uint8_t MU_reserved3[208];
+	MU_TR0_t TR[2];
+	uint8_t MU_reserved4[120];
+	MU_RR0_t RR[2];
+};
+
+#endif /* MU_H */
diff --git a/plat/imx/imx8ulp/upower/upower_api.c b/plat/imx/imx8ulp/upower/upower_api.c
new file mode 100644
index 00000000..ce8c1c84
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_api.c
@@ -0,0 +1,3095 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
+ * Copyright 2019-2024 NXP
+ *
+ * KEYWORDS: micro-power uPower driver API
+ */
+
+#include <string.h>
+
+#include "upower_api.h"
+#include "upower_soc_defs.h"
+
+/* ---------------------------------------------------------------
+ * Common Macros
+ * ---------------------------------------------------------------
+ */
+
+/* tests Service Group busy */
+#define UPWR_SG_BUSY(sg) ((sg_busy & (1U << (sg))) == 1U)
+
+/* install user callback for the Service Group */
+#define UPWR_USR_CALLB(sg, cb) { user_callback[(sg)] = (cb); }
+
+/* fills up common message header info */
+#define UPWR_MSG_HDR(hdr, sg, fn)   {		\
+	(hdr).domain   = (uint32_t)pwr_domain;	\
+	(hdr).srvgrp   = (sg);			\
+	(hdr).function = (fn); }
+
+/* ---------------------------------------------------------------
+ * Common Data Structures
+ * ---------------------------------------------------------------
+ */
+static soc_domain_t pwr_domain;
+
+static upwr_code_vers_t fw_rom_version;
+static upwr_code_vers_t fw_ram_version;
+static uint32_t fw_launch_option;
+
+/* shared memory buffers */
+#define UPWR_API_BUFFER_SIZE	(MAX_SG_EXCEPT_MEM_SIZE + \
+				 MAX_SG_PWRMGMT_MEM_SIZE + MAX_SG_VOLTM_MEM_SIZE)
+
+/* service group shared mem buffer pointers */
+static void *sh_buffer[UPWR_SG_COUNT];
+
+/* Callbacks registered for each service group :
+ *
+ * NULL means no callback is registered;
+ * for sgrp_callback, it also means the service group is
+ * free to receive a new request.
+ */
+static upwr_callb user_callback[UPWR_SG_COUNT];
+static UPWR_RX_CALLB_FUNC_T sgrp_callback[UPWR_SG_COUNT];
+
+/* request data structures for each service group */
+/* message waiting for TX */
+static upwr_down_max_msg  sg_req_msg[UPWR_SG_COUNT];
+/* waiting message size */
+static unsigned int sg_req_siz[UPWR_SG_COUNT];
+/* response msg  */
+static upwr_up_max_msg sg_rsp_msg[UPWR_SG_COUNT];
+/* response msg size */
+static unsigned int sg_rsp_siz[UPWR_SG_COUNT];
+
+/* tx pending status for each (1 bit per service group) */
+static volatile uint32_t sg_tx_pend;
+/* serv.group of current ongoing Tx, if any */
+static volatile upwr_sg_t  sg_tx_curr;
+
+/* service group busy status, only for this domain (MU index 0) */
+/* SG bit = 1 if group is busy with a request */
+static volatile uint32_t sg_busy;
+
+/* OS-dependent memory allocation function */
+static upwr_malloc_ptr_t os_malloc;
+/* OS-dependent pointer->physical address conversion function */
+static upwr_phyadr_ptr_t os_ptr2phy;
+/* OS-dependent function to lock critical code */
+static upwr_lock_ptr_t os_lock;
+
+/* pointer to MU structure */
+static struct MU_t *mu;
+
+/*
+ * indicates that a transmission was done and is pending; this
+ * bit is necessary because the Tx and Rx interrupts are ORed
+ * together, and there is no way of telling if only Rx interrupt
+ * or both occurred just by looking at the MU status registers
+ */
+static uint32_t  mu_tx_pend;
+
+static UPWR_TX_CALLB_FUNC_T  mu_tx_callb;
+static UPWR_RX_CALLB_FUNC_T  mu_rx_callb;
+
+#define	UPWR_API_INIT_WAIT           (0U) /* waiting for ROM firmware initialization */
+#define	UPWR_API_INITLZED            (1U) /* ROM firmware initialized */
+#define	UPWR_API_START_WAIT          (2U) /* waiting for start services */
+#define	UPWR_API_SHUTDOWN_WAIT       (3U) /* waiting for shutdown */
+#define	UPWR_API_READY               (4U) /* ready to receive service requests */
+
+volatile upwr_api_state_t api_state;
+
+/* default pointer->physical address conversion, returns the same address */
+static void *ptr2phys(const void *ptr)
+{
+	return (void *)ptr;
+}
+
+/* ---------------------------------------------------------------
+ * SHARED MEMORY MANAGEMENT
+ * --------------------------------------------------------------
+ */
+
+/*
+ * upwr_ptr2offset() - converts a pointer (casted to uint64_t) to an
+ * address offset from the  shared memory start. If it does not point
+ * to a shared memory location, the structure pointed is copied to a
+ * buffer in the shared memory,  and the buffer offset is returned.
+ * The 2nd argument is the service group to which the buffer belongs;
+ * The 3rd argument is the size of structure to be copied. The 4th argument
+ * is an offset to apply to the copy destination address. The 5th argument
+ * is ptr before the conversion to physical address. 2nd, 3rd. 4th and 5th
+ * arguments are not used if the 1st one points to a location inside the
+ *  shared memory.
+ */
+
+static uint32_t upwr_ptr2offset(unsigned long ptr,
+				upwr_sg_t sg,
+				size_t siz,
+				size_t offset,
+				const void *vptr)
+{
+	if ((ptr >= UPWR_DRAM_SHARED_BASE_ADDR) &&
+	    ((ptr - UPWR_DRAM_SHARED_BASE_ADDR) < UPWR_DRAM_SHARED_SIZE)) {
+		return (uint32_t)(ptr - UPWR_DRAM_SHARED_BASE_ADDR);
+	}
+
+	/* pointer is outside the shared memory, copy the struct to buffer */
+	(void)memcpy((void *)(offset + (char *)sh_buffer[sg]), (void *)vptr, siz);
+	return (uint32_t)((unsigned long)sh_buffer[sg] + offset - UPWR_DRAM_SHARED_BASE_ADDR);
+}
+
+/*
+ * ---------------------------------------------------------------
+ * INTERRUPTS AND CALLBACKS
+ * Service-group specific callbacks are in their own sections
+ * --------------------------------------------------------------
+ */
+
+/*
+ * upwr_lock()- locks (lock=1) or unlocks (lock=0) a critical code section;
+ * for now it only needs to protect a portion of the code from being
+ * interrupted by the MU.
+ */
+static void upwr_lock(int lock)
+{
+	if (os_lock != NULL) {
+		os_lock(lock);
+	}
+}
+
+/* upwr_exp_isr()- handles the exception interrupt from uPower */
+static void upwr_exp_isr(void)
+{
+}
+
+/* upwr_copy2tr prototype; function definition in auxiliary function section */
+void upwr_copy2tr(struct MU_t *local_mu, const uint32_t *msg, unsigned int size);
+
+#define UPWR_MU_TSR_EMPTY ((uint32_t)((1UL << UPWR_MU_MSG_SIZE) - 1UL))
+
+/* upwr_txrx_isr()- handles both the Tx and Rx MU interrupts */
+void upwr_txrx_isr(void)
+{
+	/* Tx pending and TX register empty */
+	if ((mu_tx_pend != 0UL) && (mu->TSR.R == UPWR_MU_TSR_EMPTY)) {
+		mu_tx_pend = 0UL;
+		/* disable the tx interrupts */
+		mu->TCR.R = 0U;
+		/* urgency flag off, in case it was set */
+		mu->FCR.B.F0 = 0U;
+
+		if (mu_tx_callb != NULL) {
+			mu_tx_callb();
+		}
+	}
+
+	/* RX ISR occurred */
+	if (mu->RSR.R != 0UL) {
+		/* disable the interrupt until data is read */
+		mu->RCR.R = 0U;
+
+		if (mu_rx_callb != NULL) {
+			mu_rx_callb();
+		}
+	}
+}
+
+/**
+ * upwr_next_req() - sends the next pending service request message, if any.
+ *
+ * Called upon MU Tx interrupts, it checks if there is any service request
+ * pending amongst the service groups, and sends the request if needed.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void).
+ */
+static void upwr_next_req(void)
+{
+	upwr_sg_t sg = (upwr_sg_t)0U;
+
+	/* no lock needed here, this is called from an MU ISR */
+	sg_tx_pend &= ~((uint32_t)1UL << sg_tx_curr); /* no longer pending */
+
+	if (sg_tx_pend == 0U) {
+		return; /* no other pending */
+	}
+
+	/* find the next one pending */
+	for (uint32_t mask = 1UL; mask < (1UL << UPWR_SG_COUNT); mask = mask << 1UL) {
+		if ((sg_tx_pend & mask) != 0U) {
+			break;
+		}
+
+		sg = (upwr_sg_t)(sg + 1U);
+	}
+
+	sg_tx_curr = sg;
+	if (upwr_tx((uint32_t *)&sg_req_msg[sg], sg_req_siz[sg], upwr_next_req) < 0) {
+		return; /* leave the Tx pending */
+	}
+}
+
+/**
+ * upwr_mu_int_callback() - general MU interrupt callback.
+ *
+ * Called upon MU Rx interrupts, it calls the Service Group-specific callback,
+ * if any registered, based on the service group field in the received message.
+ * Otherwise, calls the user callback, if any registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void).
+ */
+static void upwr_mu_int_callback(void)
+{
+	upwr_sg_t sg;       /* service group number */
+	UPWR_RX_CALLB_FUNC_T sg_callb; /* service group callback */
+	upwr_up_max_msg rxmsg = {0};
+	unsigned int size; /* in words */
+
+	if (upwr_rx((char *)&rxmsg, &size) < 0) {
+		return;
+	}
+
+	sg = (upwr_sg_t)rxmsg.hdr.srvgrp;
+
+	/* copy msg to the service group buffer */
+	msg_copy((char *)&sg_rsp_msg[sg], (char *)&rxmsg, size);
+	sg_rsp_siz[sg] = size;
+
+	/* clear the service group busy status */
+	sg_busy &= ~(1UL << sg); /* no lock needed here, we're in the MU ISR */
+
+	sg_callb = sgrp_callback[sg];
+	if (sg_callb == NULL) {
+		upwr_callb user_callb = user_callback[sg];
+		/* no service group callback; call the user callback if any */
+		if (user_callb == NULL) {
+			goto done; /* no user callback */
+		}
+
+		/* make the user callback */
+		user_callb(sg, rxmsg.hdr.function,
+			   (upwr_resp_t)rxmsg.hdr.errcode,
+			   (size == 2U) ? rxmsg.word2 : rxmsg.hdr.ret);
+		goto done;
+	}
+
+	/*
+	 * finally make the group callback. don't uninstall the group
+	 * callback, it is permanent.
+	 */
+	sg_callb();
+done:
+	if (rxmsg.hdr.errcode == UPWR_RESP_SHUTDOWN) { /* shutdown error: */
+		/*
+		 * change the API state automatically. so new requests
+		 * are rejected by the API immediately
+		 */
+		api_state = UPWR_API_INITLZED;
+	}
+}
+
+/**
+ * upwr_srv_req() - sends a service request message.
+ * @sg: message service group.
+ * @msg: pointer to the message
+ * @size: message size in 32-bit words.
+ *
+ * The message is sent right away if possible, or gets pending to be sent later.
+ * If pending, the message is stored in sg_req_msg and will be sent when the
+ * MU transmission buffer is clear and there are no other pending messages
+ * from higher priority service groups.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void)
+ */
+static void upwr_srv_req(upwr_sg_t sg,
+			 uint32_t *msg,
+			 unsigned int size)
+{
+	int rc;
+
+	upwr_lock(1);
+	sg_busy |= (uint32_t)1U << sg;
+	upwr_lock(0);
+
+	rc = upwr_tx(msg, size, upwr_next_req);
+	if (rc  < 0) {
+		/* queue full, make the transmission pending */
+		msg_copy((char *)&sg_req_msg[sg], (char *)msg, size);
+		sg_req_siz[sg] = size;
+
+		upwr_lock(1);
+		sg_tx_curr = sg;
+		sg_tx_pend |= (uint32_t)1U << sg;
+		upwr_lock(0);
+
+		return;
+	}
+}
+
+/**---------------------------------------------------------------
+ * INITIALIZATION, CONFIGURATION
+ *
+ * A reference uPower initialization sequence goes as follows:
+ *
+ * 1. host CPU calls upwr_init.
+ * 2. (optional) host checks the ROM version and SoC code calling upwr_vers(...)
+ *    and optionally performs any configuration or workaround accordingly.
+ * 3. host CPU calls upwr_start to start the uPower services, passing a
+ *    service option number.
+ *    If no RAM code is loaded or it has no service options, the launch option
+ *    number passed must be 0, which will start the services available in ROM.
+ *    upwr_start also receives a pointer to a callback called by the API
+ *    when the firmware is ready to receive service requests.
+ *    The callback may be replaced by polling, calling upwr_req_status in a loop
+ *    or upwr_poll_req_status; in this case the callback pointer may be NULL.
+ *    A host may call upwr_start even if the services were already started by
+ *    any host: if the launch option is the same, the response will be ok,
+ *    but will indicate error if the services were already started with a
+ *    different launch option.
+ * 4. host waits for the callback calling, or polling finishing;
+ *    if no error is returned, it can start making service calls using the API.
+ *
+ * Variations on that reference sequence are possible:
+ *  - the uPower services can be started using the ROM code only, which includes
+ *    the basic Power Management services, among others, with launch option
+ *    number = 0.
+ *    The code RAM can be loaded while these services are running and,
+ *    when the loading is done, the services can be re-started with these 2
+ *    requests executed in order: upwr_xcp_shutdown and upwr_start,
+ *    using the newly loaded RAM code (launch option > 0).
+ *
+ * NOTE: the initialization call upwr_init is not effective and
+ *       returns error when called after the uPower services are started.
+ */
+
+/**
+ * upwr_start_callb() - internal callback for the Rx message from uPower
+ * that indicates the firmware is ready to receive the start commands.
+ * It calls the user callbacks registered in the upwr_start_boot and upwr_start
+ * call.
+ */
+void upwr_start_callb(void)
+{
+	switch (api_state) {
+	case UPWR_API_START_WAIT: {
+		upwr_rdy_callb start_callb = (upwr_rdy_callb)user_callback[UPWR_SG_EXCEPT];
+		upwr_ready_msg *msg = (upwr_ready_msg *)&sg_rsp_msg[UPWR_SG_EXCEPT];
+
+		fw_ram_version.soc_id = fw_rom_version.soc_id;
+		fw_ram_version.vmajor = msg->args.vmajor;
+		fw_ram_version.vminor = msg->args.vminor;
+		fw_ram_version.vfixes = msg->args.vfixes;
+
+		/*
+		 * vmajor == vminor == vfixes == 0 indicates start error
+		 * in this case, go back to the INITLZED state
+		 */
+		if ((fw_ram_version.vmajor != 0U) ||
+		    (fw_ram_version.vminor != 0U) ||
+		    (fw_ram_version.vfixes != 0U)) {
+			api_state = UPWR_API_READY;
+
+			/*
+			 * initialization is over:
+			 * uninstall the user callback just in case
+			 */
+			UPWR_USR_CALLB(UPWR_SG_EXCEPT, NULL);
+
+			if (fw_launch_option == 0U) {
+				/*
+				 * launched ROM firmware:
+				 * RAM fw versions must be all 0s
+				 */
+				fw_ram_version.vmajor = 0U;
+				fw_ram_version.vminor = 0U;
+				fw_ram_version.vfixes = 0U;
+			}
+		} else {
+			api_state = UPWR_API_INITLZED;
+		}
+
+		start_callb(msg->args.vmajor, msg->args.vminor, msg->args.vfixes);
+	}
+	break;
+
+	case UPWR_API_SHUTDOWN_WAIT: {
+		upwr_callb user_callb = (upwr_callb)user_callback[UPWR_SG_EXCEPT];
+		upwr_shutdown_msg *msg = (upwr_shutdown_msg *)&sg_rsp_msg[UPWR_SG_EXCEPT];
+
+		if ((upwr_resp_t)msg->hdr.errcode == UPWR_RESP_OK) {
+			api_state = UPWR_API_INITLZED;
+		}
+
+		if (user_callb != NULL) {
+			user_callb(UPWR_SG_EXCEPT, UPWR_XCP_SHUTDOWN,
+				   (upwr_resp_t)msg->hdr.errcode, 0U);
+		}
+	}
+	break;
+
+	case UPWR_API_READY:
+	{
+		upwr_callb user_callb = (upwr_callb)user_callback[UPWR_SG_EXCEPT];
+		upwr_up_max_msg *msg = (upwr_up_max_msg *)&sg_rsp_msg[UPWR_SG_EXCEPT];
+
+		if (user_callb != NULL) {
+			user_callb(UPWR_SG_EXCEPT, msg->hdr.function,
+				   (upwr_resp_t)msg->hdr.errcode,
+				   (int)((sg_rsp_siz[UPWR_SG_EXCEPT] == 2U) ?
+					 msg->word2 : msg->hdr.ret));
+		}
+	}
+	break;
+
+	default:
+		break;
+	}
+}
+
+/**
+ * upwr_init() - API initialization; must be the first API call after reset.
+ * @domain: SoC-dependent CPU domain id; identifier used by the firmware in
+ * many services. Defined by SoC-dependent type soc_domain_t found in
+ * upower_soc_defs.h.
+ * @muptr: pointer to the MU instance.
+ * @mallocptr: pointer to the memory allocation function
+ * @physaddrptr: pointer to the function to convert pointers to
+ * physical addresses. If NULL, no conversion is made (pointer=physical address)
+ * @isrinstptr: pointer to the function to install the uPower ISR callbacks;
+ * the function receives the pointers to the MU tx/rx and Exception ISRs
+ * callbacks, which must be called from the actual system ISRs.
+ * The function pointed by isrinstptr must also enable the interrupt at the
+ * core/interrupt controller, but must not enable the interrupt at the MU IP.
+ * The system ISRs are responsible for dealing with the interrupt controller,
+ * performing any other context save/restore, and any other housekeeping.
+ * @lockptr: pointer to a function that prevents MU interrupts (if argrument=1)
+ * or allows it (if argument=0). The API calls this function to make small
+ * specific code portions thread safe. Only MU interrupts must be avoided,
+ * the code may be suspended for other reasons.
+ * If no MU interrupts can happen during the execution of an API call or
+ * callback, even if enabled, for some other reason (e.g. interrupt priority),
+ * then this argument may be NULL.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if failed to allocate memory, or use some other resource.
+ *        -2 if any argument is invalid.
+ *        -3 if failed to send the ping message.
+ *        -4 if failed to receive the initialization message, or was invalid
+ */
+int upwr_init(soc_domain_t domain, struct MU_t *muptr,
+	      const upwr_malloc_ptr_t mallocptr,
+	      const upwr_phyadr_ptr_t phyadrptr,
+	      const upwr_inst_isr_ptr_t isrinstptr,
+	      const upwr_lock_ptr_t lockptr)
+{
+	uint32_t j;
+
+	upwr_sg_t sg; /* service group number */
+	unsigned int size;
+	unsigned long dom_buffer_base = (domain == RTD_DOMAIN) ? UPWR_API_BUFFER_BASE :
+					((UPWR_API_BUFFER_ENDPLUS + UPWR_API_BUFFER_BASE) / 2U);
+
+	upwr_init_msg *msg = (upwr_init_msg *)&sg_rsp_msg[UPWR_SG_EXCEPT];
+
+	mu = muptr;
+	/*
+	 * Disable tx and rx interrupts in case not called
+	 * 1st time after reset
+	 */
+	mu->TCR.R = mu->RCR.R = 0U;
+
+	os_malloc = mallocptr;
+	os_ptr2phy = (phyadrptr == (upwr_phyadr_ptr_t)NULL) ? ptr2phys : phyadrptr;
+
+	os_lock = lockptr;
+	api_state = UPWR_API_INIT_WAIT;
+	sg_busy = 0UL;
+	pwr_domain = domain;
+
+	/* initialize the versions, in case they are polled */
+	fw_rom_version.soc_id = 0U;
+	fw_rom_version.vmajor = 0U;
+	fw_rom_version.vminor = 0U;
+	fw_rom_version.vfixes = 0U;
+
+	fw_ram_version.soc_id = 0U;
+	fw_ram_version.vmajor = 0U;
+	fw_ram_version.vminor = 0U;
+	fw_ram_version.vfixes = 0U;
+
+	mu_tx_pend = (uint32_t)0U;
+	sg_tx_pend = (uint32_t)0U;
+
+	sg_tx_curr = UPWR_SG_COUNT; /* means none here */
+
+	sh_buffer[UPWR_SG_EXCEPT] = (void *)(unsigned long)dom_buffer_base;
+	sh_buffer[UPWR_SG_PWRMGMT] = (void *)(unsigned long)(dom_buffer_base +
+					      MAX_SG_EXCEPT_MEM_SIZE);
+	sh_buffer[UPWR_SG_DELAYM] = NULL;
+	sh_buffer[UPWR_SG_VOLTM] = (void *)(unsigned long)(dom_buffer_base +
+					    MAX_SG_EXCEPT_MEM_SIZE + MAX_SG_PWRMGMT_MEM_SIZE);
+	sh_buffer[UPWR_SG_CURRM] = NULL;
+	sh_buffer[UPWR_SG_TEMPM] = NULL;
+	sh_buffer[UPWR_SG_DIAG] = NULL;
+
+	/* (no buffers service groups other than xcp and pwm for now) */
+	for (j = 0; j < UPWR_SG_COUNT; j++) {
+		user_callback[j] = NULL;
+		/* service group Exception gets the initialization callbacks */
+		sgrp_callback[j] = (j == UPWR_SG_EXCEPT) ? upwr_start_callb : NULL;
+		/* response messages with an initial consistent content */
+		sg_rsp_msg[j].hdr.errcode = UPWR_RESP_SHUTDOWN;
+	}
+
+	/* init message already received, assume takss are running on upower */
+	if (mu->FSR.B.F0 != 0U) {
+		/* send a ping message down to get the ROM version back */
+		upwr_xcp_ping_msg ping_msg = {0};
+
+		ping_msg.hdr.domain = pwr_domain;
+		ping_msg.hdr.srvgrp = UPWR_SG_EXCEPT;
+		ping_msg.hdr.function = UPWR_XCP_PING;
+
+		if (mu->RSR.B.RF0 != 0U) { /* first clean any Rx message left over */
+			(void)upwr_rx((char *)msg, &size);
+		}
+
+		/* wait any TX left over to be sent */
+		while (mu->TSR.R != UPWR_MU_TSR_EMPTY) {
+		}
+
+		/*
+		 * now send the ping message;
+		 * do not use upwr_tx, which needs API initialized;
+		 * just write to the MU TR register(s)
+		 */
+		mu->FCR.B.F0 = 1U; /* flag urgency status */
+		upwr_copy2tr(mu, (uint32_t *)&ping_msg, sizeof(ping_msg) / 4U);
+	}
+
+	do {
+		/*
+		 * poll for the MU Rx status: wait for an init message, either
+		 * 1st sent from uPower after reset or as a response to a ping
+		 */
+		while (mu->RSR.B.RF0 == 0U) {
+		}
+
+		/* urgency status off, in case it was set */
+		mu->FCR.B.F0 = 0U;
+
+		if (upwr_rx((char *)msg, &size) < 0) {
+			return -4;
+		}
+
+		if (size != (sizeof(upwr_init_msg) / 4U)) {
+			if (mu->FSR.B.F0 != 0U) {
+				continue; /* discard left over msg */
+			} else {
+				return -4;
+			}
+		}
+
+		sg = (upwr_sg_t)msg->hdr.srvgrp;
+		if (sg != UPWR_SG_EXCEPT) {
+			if (mu->FSR.B.F0 != 0U) {
+				continue; /* discard left over msg */
+			} else {
+				return -4;
+			}
+		}
+
+		if ((upwr_xcp_f_t)msg->hdr.function != UPWR_XCP_INIT) {
+			if (mu->FSR.B.F0 != 0U) {
+				continue; /* discard left over msg */
+			} else {
+				return -4;
+			}
+		}
+
+		break;
+	} while (true);
+
+	fw_rom_version.soc_id = msg->args.soc;
+	fw_rom_version.vmajor = msg->args.vmajor;
+	fw_rom_version.vminor = msg->args.vminor;
+	fw_rom_version.vfixes = msg->args.vfixes;
+
+	if (upwr_rx_callback(upwr_mu_int_callback) < 0) {
+		/* catastrophic error, but is it possible to happen? */
+		return -1;
+	}
+
+	mu_tx_callb = NULL; /* assigned on upwr_tx */
+
+	/* install the ISRs and enable the interrupts */
+	isrinstptr(upwr_txrx_isr, upwr_exp_isr);
+
+	/* enable only RR[0] receive interrupt */
+	mu->RCR.R = 1U;
+
+	api_state = UPWR_API_INITLZED;
+
+	return 0;
+}
+
+/**
+ * upwr_start() - Starts the uPower services.
+ * @launchopt: a number to select between multiple launch options,
+ * that may define, among other things, which services will be started,
+ * or which services implementations, features etc.
+ * launchopt = 0 selects a subset of services implemented in ROM;
+ * any other number selects service sets implemented in RAM, launched
+ * by the firmware function ram_launch; if an invalid launchopt value is passed,
+ * no services are started, and the callback returns error (see below).
+ * @rdycallb: pointer to the callback to be called when the uPower is ready
+ * to receive service requests. NULL if no callback needed.
+ * The callback receives as arguments the RAM firmware version numbers.
+ * If all 3 numbers (vmajor, vminor, vfixes) are 0, that means the
+ * service launching failed.
+ * Firmware version numbers will be the same as ROM if launchopt = 0,
+ * selecting the ROM services.
+ *
+ * upwr_start can be called by any domain even if the services are already
+ * started: it has no effect, returning success, if the launch option is the
+ * same as the one that actually started the service, and returns error if
+ * called with a different option.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if a resource failed,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_start(uint32_t launchopt, const upwr_rdy_callb rdycallb)
+{
+	upwr_start_msg txmsg = {0};
+
+	if (api_state != UPWR_API_INITLZED) {
+		return -3;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, (upwr_callb)rdycallb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_START);
+
+	txmsg.hdr.arg = fw_launch_option = launchopt;
+
+	if (upwr_tx((uint32_t *)&txmsg, sizeof(txmsg) / 4U, NULL) < 0) {
+		/* catastrophic error, but is it possible to happen? */
+		return -1;
+	}
+
+	api_state = UPWR_API_START_WAIT;
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * EXCEPTION SERVICE GROUP
+ */
+
+/**
+ * upwr_xcp_config() - Applies general uPower configurations.
+ * @config: pointer to the uPower SoC-dependent configuration struct
+ * upwr_xcp_config_t defined in upower_soc_defs.h. NULL may be passed, meaning
+ * a request to read the configuration, in which case it appears in the callback
+ * argument ret, or can be pointed by argument retptr in the upwr_req_status and
+ * upwr_poll_req_status calls, casted to upwr_xcp_config_t.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the configuration, or NULL if no callback needed (polling used instead).
+ *
+ * Some configurations are targeted for a specific domain (see the struct
+ * upwr_xcp_config_t definition in upower_soc_defs.h); this call has implicit
+ * domain target (the same domain from which is called).
+ *
+ * The return value is always the current configuration value, either in a
+ * read-only request (config = NULL) or after setting a new configuration
+ * (non-NULL config).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_config(const upwr_xcp_config_t *config, const upwr_callb callb)
+{
+	upwr_xcp_config_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	if (config == NULL) {
+		txmsg.hdr.arg = 1U;         /* 1= read, txmsg.word2 ignored */
+	} else {
+		txmsg.hdr.arg = 0U;         /* 1= write */
+		txmsg.word2   = config->R;
+	}
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_CONFIG);
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_sw_alarm() - Makes uPower issue an alarm interrupt to given domain.
+ * @domain: identifier of the domain to alarm. Defined by SoC-dependent type
+ * soc_domain_t found in upower_soc_defs.h.
+ * @code: alarm code. Defined by SoC-dependent type upwr_alarm_t found in
+ * upower_soc_defs.h.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the alarm, or NULL if no callback needed (polling used instead).
+ *
+ * The function requests the uPower to issue an alarm of the given code as if
+ * it had originated internally. This service is useful mainly to test the
+ * system response to such alarms, or to make the system handle a similar alarm
+ * situation detected externally to uPower.
+ *
+ * The system ISR/code handling the alarm may retrieve the alarm code by calling
+ * the auxiliary function upwr_alarm_code.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_sw_alarm(soc_domain_t domain,
+		      upwr_alarm_t code,
+		      const upwr_callb callb)
+{
+	upwr_xcp_swalarm_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SW_ALARM);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)code;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_ddr_retention() - M33/A35 can use this API to set/clear ddr retention
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set ddr retention, false clear ddr retention.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_ddr_retention(soc_domain_t domain,
+			       uint32_t enable,
+			       const upwr_callb callb)
+{
+	upwr_xcp_ddr_retn_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_DDR_RETN);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)enable;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_mipi_dsi_ena() - M33/A35 can use this API to set/clear mipi dsi ena
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set ddr retention, false clear ddr retention.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_mipi_dsi_ena(soc_domain_t domain,
+			      uint32_t enable,
+			      const upwr_callb callb)
+{
+	upwr_xcp_set_mipi_dsi_ena_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_MIPI_DSI_ENA);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)enable;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_get_mipi_dsi_ena() - M33/A35 can use this API to get mipi dsi ena status
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_get_mipi_dsi_ena(soc_domain_t domain, const upwr_callb callb)
+{
+	upwr_xcp_get_mipi_dsi_ena_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_GET_MIPI_DSI_ENA);
+	txmsg.hdr.domain = (uint32_t)domain;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_osc_mode() - M33/A35 can use this API to set uPower OSC mode
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @osc_mode, 0 means low frequency, not 0 means high frequency.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_osc_mode(soc_domain_t domain,
+			  uint32_t osc_mode,
+			  const upwr_callb callb)
+{
+	upwr_xcp_set_osc_mode_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_OSC_MODE);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)osc_mode;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_rtd_use_ddr() - M33 call this API to inform uPower, M33 is using ddr
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @is_use_ddr: not 0, true, means that RTD is using ddr. 0, false, means that, RTD
+ * is not using ddr.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_rtd_use_ddr(soc_domain_t domain,
+			     uint32_t is_use_ddr,
+			     const upwr_callb callb)
+{
+	upwr_xcp_rtd_use_ddr_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_RTD_USE_DDR);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)is_use_ddr;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_set_rtd_apd_llwu() - M33/A35 can use this API to set/clear rtd_llwu apd_llwu
+ * @domain: set which domain (RTD_DOMAIN, APD_DOMAIN) LLWU.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set rtd_llwu or apd_llwu, false clear rtd_llwu or apd_llwu.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_rtd_apd_llwu(soc_domain_t domain,
+			      uint32_t enable,
+			      const upwr_callb callb)
+{
+	upwr_xcp_rtd_apd_llwu_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SET_RTD_APD_LLWU);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = (uint32_t)enable;
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_shutdown() - Shuts down all uPower services and power mode tasks.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the shutdown, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * At the callback the uPower/API is back to initialization/start-up phase,
+ * so service request calls return error.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_shutdown(const upwr_callb callb)
+{
+	upwr_xcp_shutdown_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_SHUTDOWN);
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	api_state = UPWR_API_SHUTDOWN_WAIT;
+
+	return 0;
+}
+
+/**
+ * upwr_xcp_i2c_access() - Performs an access through the uPower I2C interface.
+ * @addr: I2C slave address, up to 10 bits.
+ * @data_size: determines the access direction and data size in bytes, up to 4;
+ * negetive data_size determines a read  access with size -data_size;
+ * positive data_size determines a write access with size  data_size;
+ * data_size=0 is invalid, making the service return error UPWR_RESP_BAD_REQ.
+ * @subaddr_size: size of the sub-address in bytes, up to 4; if subaddr_size=0,
+ * no subaddress is used.
+ * @subaddr: sub-address, only used if subaddr_size > 0.
+ * @wdata: write data, up to 4 bytes; ignored if data_size < 0 (read)
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the access, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * The service performs a read (data_size < 0) or a write (data_size > 0) of
+ * up to 4 bytes on the uPower I2C interface. The data read from I2C comes via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * Sub-addressing is supported, with sub-address size determined by the argument
+ * subaddr_size, up to 4 bytes. Sub-addressing is not used if subaddr_size=0.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_i2c_access(uint16_t addr,
+			int8_t data_size,
+			uint8_t subaddr_size,
+			uint32_t subaddr,
+			uint32_t wdata,
+			const upwr_callb callb)
+{
+	unsigned long ptrval = (unsigned long)sh_buffer[UPWR_SG_EXCEPT];
+	upwr_i2c_access *i2c_acc_ptr = (upwr_i2c_access *)ptrval;
+	upwr_pwm_pmiccfg_msg  txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_EXCEPT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_EXCEPT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_EXCEPT, UPWR_XCP_I2C);
+
+	i2c_acc_ptr->addr = addr;
+	i2c_acc_ptr->subaddr = subaddr;
+	i2c_acc_ptr->subaddr_size = subaddr_size;
+	i2c_acc_ptr->data = wdata;
+	i2c_acc_ptr->data_size = data_size;
+
+	txmsg.ptr = upwr_ptr2offset(ptrval,
+				    UPWR_SG_EXCEPT,
+				    (size_t)sizeof(upwr_i2c_access),
+				    0U,
+				    i2c_acc_ptr);
+
+	upwr_srv_req(UPWR_SG_EXCEPT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * VOLTAGE MANAGERMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_vtm_pmic_cold_reset() -request cold reset the pmic.
+ * pmic will power cycle all the regulators
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to cold reset the pmic.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_pmic_cold_reset(upwr_callb callb)
+{
+	upwr_volt_pmic_cold_reset_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_PMIC_COLD_RESET);
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_set_pmic_mode() -request uPower set pmic mode
+ * @pmic_mode: the target mode need to be set
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to set pmic mode
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_set_pmic_mode(uint32_t pmic_mode, upwr_callb callb)
+{
+	upwr_volt_pmic_set_mode_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_SET_PMIC_MODE);
+
+	txmsg.hdr.arg = pmic_mode;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_chng_pmic_voltage() - Changes the voltage of a given rail.
+ * @rail: pmic rail id.
+ * @volt: the target voltage of the given rail, accurate to uV
+ * If pass volt value 0, means that power off this rail.
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to change the voltage of the given rail.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_chng_pmic_voltage(uint32_t rail, uint32_t volt, upwr_callb callb)
+{
+	upwr_volt_pmic_set_volt_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_CHNG_PMIC_RAIL_VOLT);
+
+	txmsg.args.rail = rail;
+
+	txmsg.args.volt = (volt + PMIC_VOLTAGE_MIN_STEP - 1U) / PMIC_VOLTAGE_MIN_STEP;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_get_pmic_voltage() - Get the voltage of a given rail.
+ * @rail: pmic rail id.
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to get the voltage of the given rail.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The voltage data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_get_pmic_voltage(uint32_t rail, upwr_callb callb)
+{
+	upwr_volt_pmic_get_volt_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_GET_PMIC_RAIL_VOLT);
+
+	txmsg.args.rail = rail;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_power_measure() - request uPower to measure power consumption
+ * @ssel: This field determines which power switches will have their currents
+ * sampled to be accounted for a
+ * current/power measurement. Support 0~7
+
+ * SSEL bit #	Power Switch
+ * 0	M33 core complex/platform/peripherals
+ * 1	Fusion Core and Peripherals
+ * 2	A35[0] core complex
+ * 3	A35[1] core complex
+ * 4	3DGPU
+ * 5	HiFi4
+ * 6	DDR Controller (PHY and PLL NOT included)
+ * 7	PXP, EPDC
+ *
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to measure power consumption
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The power consumption data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Accurate to uA
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_power_measure(uint32_t ssel, upwr_callb callb)
+{
+	upwr_volt_pmeter_meas_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_PMETER_MEAS);
+
+	txmsg.hdr.arg = ssel;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_vmeter_measure() - request uPower to measure voltage
+ * @vdetsel: Voltage Detector Selector, support 0~3
+ * 00b - RTD sense point
+   01b - LDO output
+   10b - APD domain sense point
+   11b - AVD domain sense point
+   Refer to upower_defs.h
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to use vmeter to measure voltage
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The voltage data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Refer to RM COREREGVL (Core Regulator Voltage Level)
+ * uPower return VDETLVL to user, user can calculate the real voltage:
+ *
+0b000000(0x00) - 0.595833V
+0b100110(0x26) - 1.007498V
+<value> - 0.595833V + <value>x10.8333mV
+0b110010(0x32) - 1.138V
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_vmeter_measure(uint32_t vdetsel, upwr_callb callb)
+{
+	upwr_volt_vmeter_meas_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_VMETER_MEAS);
+
+	txmsg.hdr.arg = vdetsel;
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_vtm_pmic_config() - Configures the SoC PMIC (Power Management IC).
+ * @config: pointer to a PMIC-dependent struct defining the PMIC configuration.
+ * @size:   size of the struct pointed by config, in bytes.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change/define the PMIC configuration.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_pmic_config(const void *config, uint32_t size, upwr_callb callb)
+{
+	upwr_pwm_pmiccfg_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_VOLTM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_VOLTM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_VOLTM, UPWR_VTM_PMIC_CONFIG);
+
+	ptrval = (unsigned long)os_ptr2phy(config);
+	if (ptrval == 0UL) {
+		return -2; /* pointer conversion failed */
+	}
+
+	txmsg.ptr = upwr_ptr2offset(ptrval,
+				    UPWR_SG_VOLTM,
+				    (size_t)size,
+				    0U,
+				    config);
+
+	upwr_srv_req(UPWR_SG_VOLTM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * TEMPERATURE MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_tpm_get_temperature() - request uPower to get temperature of one temperature sensor
+ * @sensor_id: temperature sensor ID, support 0~2
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to measure temperature
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_TEMPM as the service group argument.
+ *
+ * The temperature data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * uPower return TSEL to the caller (M33 or A35), caller calculate the real temperature
+ * Tsh = 0.000002673049*TSEL[7:0]^3 + 0.0003734262*TSEL[7:0]^2 +
+0.4487042*TSEL[7:0] - 46.98694
+ *
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_tpm_get_temperature(uint32_t sensor_id, upwr_callb callb)
+{
+	upwr_temp_get_cur_temp_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_TEMPM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_TEMPM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_TEMPM, UPWR_TEMP_GET_CUR_TEMP);
+
+	txmsg.args.sensor_id = sensor_id;
+
+	upwr_srv_req(UPWR_SG_TEMPM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * DELAY MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_dlm_get_delay_margin() - request uPower to get delay margin
+ * @path: The critical path
+ * @index: Use whitch delay meter
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to get delay margin
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The delay margin data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_get_delay_margin(uint32_t path, uint32_t index, upwr_callb callb)
+{
+	upwr_dmeter_get_delay_margin_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_DELAYM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_DELAYM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_DELAYM, UPWR_DMETER_GET_DELAY_MARGIN);
+
+	txmsg.args.path = path;
+	txmsg.args.index = index;
+
+	upwr_srv_req(UPWR_SG_DELAYM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_dlm_set_delay_margin() - request uPower to set delay margin
+ * @path: The critical path
+ * @index: Use whitch delay meter
+ * @delay_margin: the value of delay margin
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to set delay margin
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The result of the corresponding critical path,  failed or not  read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_set_delay_margin(uint32_t path, uint32_t index, uint32_t delay_margin,
+			      upwr_callb callb)
+{
+	upwr_dmeter_set_delay_margin_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_DELAYM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_DELAYM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_DELAYM, UPWR_DMETER_SET_DELAY_MARGIN);
+
+	txmsg.args.path = path;
+	txmsg.args.index = index;
+	txmsg.args.dm = delay_margin;
+
+	upwr_srv_req(UPWR_SG_DELAYM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_dlm_process_monitor() - request uPower to do process monitor
+ * @chain_sel: Chain Cell Type Selection
+ * Select the chain to be used for the clock signal generation.
+ * Support two types chain cell, 0~1
+0b - P4 type delay cells selected
+1b - P16 type delay cells selected
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to do process monitor
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The result of process monitor,  failed or not  read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_process_monitor(uint32_t chain_sel, upwr_callb callb)
+{
+	upwr_pmon_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_DELAYM)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_DELAYM, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_DELAYM, UPWR_PMON_REQ);
+
+	txmsg.args.chain_sel = chain_sel;
+
+	upwr_srv_req(UPWR_SG_DELAYM, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * POWER MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_pwm_dom_power_on() - Commands uPower to power on the platform of other
+ * domain (not necessarily its core(s)); does not release the core reset.
+ * @domain: identifier of the domain to power on. Defined by SoC-dependent type
+ * soc_domain_t found in upower_soc_defs.h.
+ * @boot_start: must be 1 to start the domain core(s) boot(s), releasing
+ * its (their) resets, or 0 otherwise.
+ * @pwroncallb: pointer to the callback to be called when the uPower has
+ * finished the power on procedure, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_dom_power_on(soc_domain_t domain,
+			  int boot_start,
+			  const upwr_callb pwroncallb)
+{
+	upwr_pwm_dom_pwron_msg txmsg = {0};
+
+	if (pwr_domain == domain) {
+		return -2;
+	}
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, (upwr_callb)pwroncallb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_DOM_PWRON);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg    = (uint32_t)boot_start;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_boot_start() - Commands uPower to release the reset of other CPU(s),
+ * starting their boots.
+ * @domain: identifier of the domain to release the reset. Defined by
+ * SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @bootcallb: pointer to the callback to be called when the uPower has finished
+ * the boot start procedure, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * The callback calling doesn't mean the CPUs boots have finished:
+ * it only indicates that uPower released the CPUs resets, and can receive
+ * other power management service group requests.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_boot_start(soc_domain_t domain, const upwr_callb  bootcallb)
+{
+	upwr_pwm_boot_start_msg txmsg = {0};
+
+	if (pwr_domain == domain) {
+		return -2;
+	}
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, (upwr_callb)bootcallb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_BOOT);
+	txmsg.hdr.domain = (uint32_t)domain;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_param() - Changes Power Management parameters.
+ * @param: pointer to a parameter structure upwr_pwm_param_t, SoC-dependent,
+ * defined in upwr_soc_defines.h. NULL may be passed, meaning
+ * a request to read the parameter set, in which case it appears in the callback
+ * argument ret, or can be pointed by argument retptr in the upwr_req_status and
+ * upwr_poll_req_status calls, casted to upwr_pwm_param_t.
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The return value is always the current parameter set value, either in a
+ * read-only request (param = NULL) or after setting a new parameter
+ * (non-NULL param).
+ *
+ * Some parameters may be targeted for a specific domain (see the struct
+ * upwr_pwm_param_t definition in upower_soc_defs.h); this call has implicit
+ * domain target (the same domain from which is called).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_param(upwr_pwm_param_t *param, const upwr_callb callb)
+{
+	upwr_pwm_param_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_PARAM);
+
+	if (param == NULL) {
+		txmsg.hdr.arg = 1U;        /* 1= read, txmsg.word2 ignored */
+	} else {
+		txmsg.hdr.arg = 0U;        /* 1= write */
+		txmsg.word2 = param->R; /* just 1 word, so that's ok */
+	}
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_chng_reg_voltage() - Changes the voltage at a given regulator.
+ * @reg: regulator id.
+ * @volt: voltage value; value unit is SoC-dependent, converted from mV by the
+ * macro UPWR_VTM_MILIV, or from micro-Volts by the macro UPWR_VTM_MICROV,
+ * both macros in upower_soc_defs.h
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to change the voltage of the given regulator.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_reg_voltage(uint32_t reg, uint32_t volt, upwr_callb callb)
+{
+	upwr_pwm_volt_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_VOLT);
+
+	txmsg.args.reg = reg;
+	txmsg.args.volt = volt;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_freq_setup() - Determines the next frequency target for a given
+ *                         domain and current frequency.
+ * @domain: identifier of the domain to change frequency. Defined by
+ * SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @rail: the pmic regulator number for the target domain.
+ * @stage: DVA adjust stage
+ * refer to upower_defs.h "DVA adjust stage"
+ * @target_freq: the target adjust frequency, accurate to MHz
+ *
+ * refer to upower_defs.h structure definition upwr_pwm_freq_msg
+ *
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The DVA algorithm is broken down into two phases.
+ * The first phase uses a look up table to get a safe operating voltage
+ * for the requested frequency.
+ * This voltage is guaranteed to work over process and temperature.
+ *
+ * The second step of the second phase is to measure the temperature
+ * using the uPower Temperature Sensor module.
+ * This is accomplished by doing a binary search of the TSEL bit field
+ * in the Temperature Measurement Register (TMR).
+ * The search is repeated until the THIGH bit fields in the same register change value.
+ * There are 3 temperature sensors in 8ULP (APD, AVD, and RTD).
+ *
+ *
+ * The second phase is the fine adjust of the voltage.
+ * This stage is entered only when the new frequency requested
+ * by application was already set as well as the voltage for that frequency.
+ * The first step of the fine adjust is to find what is the current margins
+ * for the monitored critical paths, or, in other words,
+ * how many delay cells will be necessary to generate a setup-timing violation.
+ * The function informs uPower that the given domain frequency has changed or
+ * will change to the given value. uPower firmware will then adjust voltage and
+ * bias to cope with the new frequency (if decreasing) or prepare for it
+ * (if increasing). The function must be called after decreasing the frequency,
+ * and before increasing it. The actual increase in frequency must not occur
+ * before the service returns its response.
+ *
+ * So, for increase clock frequency case, user need to call this API twice,
+ * the first stage gross adjust and the second stage fine adjust.
+ *
+ * for reduce clock frequency case, user can only call this API once,
+ * full stage (combine gross stage and fine adjust)
+ *
+ * The request is executed if arguments are within range.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_freq_setup(soc_domain_t domain, uint32_t rail, uint32_t stage, uint32_t target_freq,
+			upwr_callb   callb)
+{
+	upwr_pwm_freq_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_FREQ);
+
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.args.rail = rail;
+	txmsg.args.stage = stage;
+	txmsg.args.target_freq = target_freq;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_power_on()- Powers on (not off) one or more switches and ROM/RAMs.
+ * @swton: pointer to an array of words that tells which power switches to
+ *  turn on. Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective switch must be turned on,
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no switch will be changed,
+ *  unless a memory that it feeds must be turned on.
+ *  WARNING: swton must not point to the first shared memory address.
+ * @memon: pointer to an array of words that tells which memories to turn on.
+ *  Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective memory must be turned on, both array and
+ *  periphery logic;
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no memory will be changed.
+ *  WARNING: memon must not point to the first shared memory address.
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn on the PMC and memory array/peripheral
+ * switches that control their power, as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate memory power state related to overall system state.
+ *
+ * If a memory is requested to turn on, but the power switch that feeds that
+ * memory is not, the power switch will be turned on anyway, if the pwron
+ * array is not provided (that is, if pwron is NULL).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_power_on(const uint32_t swton[],
+		      const uint32_t memon[],
+		      upwr_callb     callb)
+{
+	upwr_pwm_pwron_msg txmsg = {0};
+	unsigned long  ptrval = 0UL; /* needed for X86, ARM64 */
+	size_t stsize = 0U;
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_PWR_ON);
+
+	ptrval = (unsigned long)os_ptr2phy((void *)swton);
+	if (swton == NULL) {
+		txmsg.ptrs.ptr0 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr0 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  (stsize = UPWR_PMC_SWT_WORDS * 4U),
+						  0U,
+						  swton);
+	}
+
+	ptrval = (unsigned long)os_ptr2phy((void *)memon);
+	if (memon == NULL) {
+		txmsg.ptrs.ptr1 = 0; /* NULL pointer -> 0 offset */
+
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr1 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  UPWR_PMC_MEM_WORDS * 4U,
+						  stsize,
+						  memon);
+	}
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_power_off()- Powers off (not on) one or more switches and ROM/RAMs.
+ * @swtoff: pointer to an array of words that tells which power switches to
+ *  turn off. Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective switch must be turned off,
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no switch will be changed.
+ *  WARNING: swtoff must not point to the first shared memory address.
+ * @memoff: pointer to an array of words that tells which memories to turn off.
+ *  Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective memory must be turned off, both array and
+ *  periphery logic;
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no memory will be changed,
+ *  but notice it may be turned off if the switch that feeds it is powered off.
+ *  WARNING: memoff must not point to the first shared memory address.
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn off the PMC and memory array/peripheral
+ * switches that control their power, as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate memory power state related to overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_power_off(const uint32_t swtoff[],
+		       const uint32_t memoff[],
+		       upwr_callb     callb)
+{
+	upwr_pwm_pwroff_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+	size_t stsize = 0;
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_PWR_OFF);
+
+	ptrval = (unsigned long)os_ptr2phy((void *)swtoff);
+	if (swtoff == NULL) {
+		txmsg.ptrs.ptr0 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr0 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  (stsize = UPWR_PMC_SWT_WORDS * 4U),
+						  0U,
+						  swtoff);
+	}
+
+	ptrval = (unsigned long)os_ptr2phy((void *)memoff);
+	if (memoff == NULL) {
+		txmsg.ptrs.ptr1 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr1 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  UPWR_PMC_MEM_WORDS * 4U,
+						  stsize,
+						  memoff);
+	}
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_mem_retain()- Configures one or more memory power switches to
+ * retain its contents, having the power array on, while its peripheral logic
+ * is turned off.
+ * @mem: pointer to an array of words that tells which memories to put in a
+ *  retention state. Each word in the array has 1 bit for each memory.
+ *  A bit=1 means the respective memory must be put in retention state,
+ *  bit = 0 means it will stay unchanged (retention, fully on or off).
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn off the memory peripheral and leave
+ * its array on, as specified above.
+ * The request is executed if arguments are within range.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_mem_retain(const uint32_t mem[], upwr_callb callb)
+{
+	upwr_pwm_retain_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_RETAIN);
+
+	ptrval = (unsigned long)os_ptr2phy((void *)mem);
+	if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	}
+
+	txmsg.ptr = upwr_ptr2offset(ptrval,
+				    UPWR_SG_PWRMGMT,
+				    UPWR_PMC_MEM_WORDS * 4U,
+				    0U,
+				    mem);
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_chng_switch_mem() - Turns on/off power on one or more PMC switches
+ * and memories, including their array and peripheral logic.
+ * @swt: pointer to a list of PMC switches to be opened/closed.
+ *  The list is structured as an array of struct upwr_switch_board_t
+ *  (see upower_defs.h), each one containing a word for up to 32 switches,
+ *  one per bit. A bit = 1 means switch closed, bit = 0 means switch open.
+ *  struct upwr_switch_board_t also specifies a mask with 1 bit for each
+ *  respective switch: mask bit = 1 means the open/close action is applied,
+ *  mask bit = 0 means the switch stays unchanged.
+ *  The pointer may be set to NULL, in which case no switch will be changed,
+ *  unless a memory that it feeds must be turned on.
+ *  WARNING: swt must not point to the first shared memory address.
+ * @mem: pointer to a list of switches to be turned on/off.
+ *  The list is structured as an array of struct upwr_mem_switches_t
+ *  (see upower_defs.h), each one containing 2 word for up to 32 switches,
+ *  one per bit, one word for the RAM array power switch, other for the
+ *  RAM peripheral logic power switch. A bit = 1 means switch closed,
+ *  bit = 0 means switch open.
+ *  struct upwr_mem_switches_t also specifies a mask with 1 bit for each
+ *  respective switch: mask bit = 1 means the open/close action is applied,
+ *  mask bit = 0 means the switch stays unchanged.
+ *  The pointer may be set to NULL, in which case no memory switch will be
+ *  changed, but notice it may be turned off if the switch that feeds it is
+ *  powered off.
+ *  WARNING: mem must not point to the first shared memory address.
+ * @callb: pointer to the callback called when the configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the PMC switches and/or memory power
+ * as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate switch combinations and overall system state.
+ *
+ * If a memory is requested to turn on, but the power switch that feeds that
+ * memory is not, the power switch will be turned on anyway, if the swt
+ * array is not provided (that is, if swt is NULL).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy.
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_chng_switch_mem(const struct upwr_switch_board_t  swt[],
+			     const struct upwr_mem_switches_t  mem[],
+			     upwr_callb callb)
+{
+	upwr_pwm_switch_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+	size_t stsize = 0U;
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_SWITCH);
+
+	ptrval = (unsigned long)os_ptr2phy((void *)swt);
+	if (swt == NULL) {
+		txmsg.ptrs.ptr0 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr0 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  (stsize = UPWR_PMC_SWT_WORDS * sizeof(struct upwr_switch_board_t)),
+						  0U,
+						  swt);
+	}
+
+	ptrval = (unsigned long)os_ptr2phy((void *)mem);
+	if (mem == NULL) {
+		txmsg.ptrs.ptr1 = 0; /* NULL pointer -> 0 offset */
+	} else if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	} else {
+		txmsg.ptrs.ptr1 = upwr_ptr2offset(ptrval,
+						  UPWR_SG_PWRMGMT,
+						  UPWR_PMC_MEM_WORDS * sizeof(struct upwr_mem_switches_t),
+						  stsize,
+						  mem);
+	}
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_pmode_config() - Configures a given power mode in a given domain.
+ * @domain: identifier of the domain to which the power mode belongs.
+ * Defined by SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @pmode: SoC-dependent power mode identifier defined by type abs_pwr_mode_t
+ * found in upower_soc_defs.h.
+ * @config: pointer to an SoC-dependent struct defining the power mode
+ * configuration, found in upower_soc_defs.h.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the power mode configuration as
+ * specified above. The request is executed if arguments are within range,
+ * and complies with SoC-dependent restrictions on value combinations.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_pmode_config(soc_domain_t domain,
+			  abs_pwr_mode_t pmode,
+			  const void *config,
+			  upwr_callb callb)
+{
+	upwr_pwm_pmode_cfg_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_CONFIG);
+	txmsg.hdr.domain = (uint32_t)domain;
+	txmsg.hdr.arg = pmode;
+
+	ptrval = (unsigned long)os_ptr2phy(config);
+	if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	}
+
+	/*
+	 * upwr_pwm_pmode_config is an exception: use the pointer
+	 * (physical addr) as is
+	 */
+
+	txmsg.ptr = (uint32_t)ptrval;
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_reg_config() - Configures the uPower internal regulators.
+ * @config: pointer to the struct defining the regulator configuration;
+ * the struct upwr_reg_config_t is defined in the file upower_defs.h.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change/define the configurations of the
+ * internal regulators.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * The service may fail with error UPWR_RESP_RESOURCE if a power mode transition
+ * or the same service (called from another domain) is executing simultaneously.
+ * This error should be interpreted as a "try later" response, as the service
+ * will succeed once those concurrent executions are done, and no other is
+ * started.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_reg_config(const struct upwr_reg_config_t *config,
+			upwr_callb   callb)
+{
+	upwr_pwm_regcfg_msg txmsg = {0};
+	unsigned long ptrval = 0UL; /* needed for X86, ARM64 */
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_REGCFG);
+
+	ptrval = (unsigned long)os_ptr2phy(config);
+	if (ptrval == 0U) {
+		return -2; /* pointer conversion failed */
+	}
+
+	txmsg.ptr = upwr_ptr2offset(ptrval,
+				    UPWR_SG_PWRMGMT,
+				    sizeof(struct upwr_reg_config_t),
+				    0U,
+				    config);
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_chng_dom_bias() - Changes the domain bias.
+ * @bias: pointer to a domain bias configuration struct (see upower_soc_defs.h).
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the domain bias configuration as
+ * specified above. The request is executed if arguments are within range,
+ * with no protections regarding the adequate value combinations and
+ * overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_dom_bias(const struct upwr_dom_bias_cfg_t *bias,
+			   upwr_callb callb)
+{
+	upwr_pwm_dom_bias_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_DOM_BIAS);
+
+	/* SoC-dependent argument filling, defined in upower_soc_defs.h */
+	UPWR_FILL_DOMBIAS_ARGS(txmsg.hdr.domain, bias, txmsg.args);
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**
+ * upwr_pwm_chng_mem_bias()- Changes a ROM/RAM power bias.
+ * @domain: identifier of the domain upon which the bias is applied.
+ * Defined by SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @bias: pointer to a memory bias configuration struct (see upower_soc_defs.h).
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the memory bias configuration as
+ * specified above. The request is executed if arguments are within range,
+ * with no protections regarding the adequate value combinations and
+ * overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_mem_bias(soc_domain_t domain,
+			   const struct upwr_mem_bias_cfg_t *bias,
+			   upwr_callb callb)
+{
+	upwr_pwm_mem_bias_msg txmsg = {0};
+
+	if (api_state != UPWR_API_READY) {
+		return -3;
+	}
+
+	if (UPWR_SG_BUSY(UPWR_SG_PWRMGMT)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_PWRMGMT, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_PWRMGMT, UPWR_PWM_MEM_BIAS);
+
+	txmsg.hdr.domain = (uint32_t)domain;
+
+	/* SoC-dependent argument filling, defined in upower_soc_defs.h */
+	UPWR_FILL_MEMBIAS_ARGS(bias, txmsg.args);
+
+	upwr_srv_req(UPWR_SG_PWRMGMT, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * DIAGNOSE SERVICE GROUP
+ */
+
+/**
+ * upwr_dgn_mode() - Sets the diagnostic mode.
+ * @mode:  diagnostic mode, which can be:
+ *  - UPWR_DGN_NONE:   no diagnostic recorded
+ *  - UPWR_DGN_TRACE:  warnings, errors, service, internal activity recorded
+ *  - UPWR_DGN_SRVREQ: warnings, errors, service activity recorded
+ *  - UPWR_DGN_WARN:   warnings and errors recorded
+ *  - UPWR_DGN_ALL:    trace, service, warnings, errors, task state recorded
+ *  - UPWR_DGN_ERROR:  only errors recorded
+ *  - UPWR_DGN_ALL2ERR: record all until an error occurs,
+ *    freeze recording on error
+ *  - UPWR_DGN_ALL2HLT: record all until an error occurs,
+ *    executes an ebreak on error, which halts the core if enabled through
+ *    the debug interface
+ * @callb: pointer to the callback called when mode is changed.
+ * NULL if no callback is required.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_dgn_mode(upwr_dgn_mode_t mode, const upwr_callb callb)
+{
+	upwr_dgn_mode_msg txmsg = {0};
+
+	if (UPWR_SG_BUSY(UPWR_SG_DIAG)) {
+		return -1;
+	}
+
+	UPWR_USR_CALLB(UPWR_SG_DIAG, callb);
+
+	UPWR_MSG_HDR(txmsg.hdr, UPWR_SG_DIAG, UPWR_DGN_MODE);
+
+	txmsg.hdr.arg = mode;
+
+	upwr_srv_req(UPWR_SG_DIAG, (uint32_t *)&txmsg, sizeof(txmsg) / 4U);
+
+	return 0;
+}
+
+/**---------------------------------------------------------------
+ * AUXILIARY CALLS
+ */
+
+/**
+ * upwr_rom_version() - informs the ROM firwmware version.
+ * @vmajor: pointer to the variable to get the firmware major version number.
+ * @vminor: pointer to the variable to get the firmware minor version number.
+ * @vfixes: pointer to the variable to get the firmware fixes number.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: SoC id.
+ */
+uint32_t upwr_rom_version(uint32_t *vmajor, uint32_t *vminor, uint32_t *vfixes)
+{
+	uint32_t soc;
+
+	upwr_lock(1);
+	soc = fw_rom_version.soc_id;
+	*vmajor = fw_rom_version.vmajor;
+	*vminor = fw_rom_version.vminor;
+	*vfixes = fw_rom_version.vfixes;
+	upwr_lock(0);
+	return soc;
+}
+
+/**
+ * upwr_ram_version() - informs the RAM firwmware version.
+ * @vminor: pointer to the variable to get the firmware minor version number.
+ * @vfixes: pointer to the variable to get the firmware fixes number.
+ *
+ * The 3 values returned are 0 if no RAM firmwmare was loaded and initialized.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: firmware major version number.
+ */
+uint32_t upwr_ram_version(uint32_t *vminor, uint32_t *vfixes)
+{
+	uint32_t vmajor;
+
+	upwr_lock(1);
+	vmajor = fw_ram_version.vmajor;
+	*vminor = fw_ram_version.vminor;
+	*vfixes = fw_ram_version.vfixes;
+	upwr_lock(0);
+
+	return vmajor;
+}
+
+/**
+ * upwr_req_status() - tells the status of the service group request, and
+ *                     returns a request return value, if any.
+ * @sg: service group of the request
+ * @sgfptr: pointer to the variable that will hold the function id of
+ * the last request completed; can be NULL, in which case it is not used.
+ * @errptr: pointer to the variable that will hold the error code;
+ * can be NULL, in which case it is not used.
+ * @retptr: pointer to the variable that will hold the value returned
+ * by the last request completed (invalid if the last request completed didn't
+ * return any value); can be NULL, in which case it is not used.
+ * Note that a request may return a value even if service error is returned
+ * (*errptr != UPWR_RESP_OK): that is dependent on the specific service.
+ *
+ * This call can be used in a poll loop of a service request completion in case
+ * a callback was not registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: service request status: succeeded, failed, or ongoing (busy)
+ */
+upwr_req_status_t upwr_req_status(upwr_sg_t sg,
+				  uint32_t *sgfptr,
+				  upwr_resp_t *errptr,
+				  int *retptr)
+{
+	upwr_req_status_t status;
+
+	upwr_lock(1);
+	if (sgfptr != NULL) {
+		*sgfptr = (uint32_t)sg_rsp_msg[sg].hdr.function;
+	}
+
+	if (errptr != NULL) {
+		*errptr = (upwr_resp_t)sg_rsp_msg[sg].hdr.errcode;
+	}
+
+	if (retptr != NULL) {
+		*retptr = (int)((sg_rsp_siz[sg] == 2U) ?
+			  sg_rsp_msg[sg].word2 : sg_rsp_msg[sg].hdr.ret);
+	}
+
+	status = ((sg_busy & (1UL << sg)) == 1U) ? UPWR_REQ_BUSY :
+		 (sg_rsp_msg[sg].hdr.errcode == UPWR_RESP_OK) ? UPWR_REQ_OK :
+								UPWR_REQ_ERR;
+	upwr_lock(0);
+	return status;
+}
+
+/**
+ * upwr_poll_req_status() - polls the status of the service group request, and
+ *                          returns a request return value, if any.
+ * @sg: service group of the request
+ * @sgfptr: pointer to the variable that will hold the function id of
+ * the last request completed; can be NULL, in which case it is not used.
+ * @errptr: pointer to the variable that will hold the error code;
+ * can be NULL, in which case it is not used.
+ * @retptr: pointer to the variable that will hold the value returned
+ * by the last request completed (invalid if the last request completed didn't
+ * return any value); can be NULL, in which case it is not used.
+ * Note that a request may return a value even if service error is returned
+ * (*errptr != UPWR_RESP_OK): that is dependent on the specific service.
+ * @attempts: maximum number of polling attempts; if attempts > 0 and is
+ * reached with no service response received, upwr_poll_req_status returns
+ * UPWR_REQ_BUSY and variables pointed by sgfptr, retptr and errptr are not
+ * updated; if attempts = 0, upwr_poll_req_status waits "forever".
+ *
+ * This call can be used to poll a service request completion in case a
+ * callback was not registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: service request status: succeeded, failed, or ongoing (busy)
+ */
+upwr_req_status_t upwr_poll_req_status(upwr_sg_t sg,
+				       uint32_t *sgfptr,
+				       upwr_resp_t *errptr,
+				       int *retptr,
+				       uint32_t attempts)
+{
+	uint32_t i;
+	upwr_req_status_t ret;
+
+	if (attempts == 0U) {
+		while ((ret = upwr_req_status(sg, sgfptr, errptr, retptr)) == UPWR_REQ_BUSY) {
+		};
+
+		return ret;
+	}
+
+	for (i = 0U; i < attempts; i++) {
+		ret = upwr_req_status(sg, sgfptr, errptr, retptr);
+		if (ret != UPWR_REQ_BUSY) {
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * upwr_alarm_code() - returns the alarm code of the last alarm occurrence.
+ *
+ * The value returned is not meaningful if no alarm was issued by uPower.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: alarm code, as defined by the type upwr_alarm_t in upwr_soc_defines.h
+ */
+upwr_alarm_t upwr_alarm_code(void)
+{
+	return (upwr_alarm_t)(3U & (mu->FSR.R >> 1U)); /* FSR[2:1] */
+}
+
+/**---------------------------------------------------------------
+ * TRANSMIT/RECEIVE PRIMITIVES
+ * ---------------------------------------------------------------
+ */
+
+/*
+ * upwr_copy2tr() - copies a message to the MU TR registers;
+ * fill the TR registers before writing TIEN to avoid early interrupts;
+ * also, fill them from the higher index to the lowest, so the receive
+ * interrupt flag RF[0] will be the last to set, regardless of message size;
+ */
+void upwr_copy2tr(struct MU_t *local_mu, const uint32_t *msg, unsigned int size)
+{
+	for (int i = (int)size - 1; i > -1; i--) {
+		local_mu->TR[i].R = msg[i];
+	}
+}
+
+/**
+ * upwr_tx() - queues a message for transmission.
+ * @msg : pointer to the message sent.
+ * @size: message size in 32-bit words
+ * @callback: pointer to a function to be called when transmission done;
+ *            can be NULL, in which case no callback is done.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: number of vacant positions left in the transmission queue, or
+ *         -1 if the queue was already full when upwr_tx was called, or
+ *         -2 if any argument is invalid (like size off-range)
+ */
+int upwr_tx(const uint32_t *msg,
+	    unsigned int size,
+	    UPWR_TX_CALLB_FUNC_T callback)
+{
+	if (size > UPWR_MU_MSG_SIZE) {
+		return -2;
+	}
+
+	if (size == 0U) {
+		return -2;
+	}
+
+	if (mu->TSR.R != UPWR_MU_TSR_EMPTY) {
+		return -1;  /* not all TE bits in 1: some data to send still */
+	}
+
+	mu_tx_callb = callback;
+
+	upwr_copy2tr(mu, msg, size);
+	mu->TCR.R = 1UL << (size - 1UL);
+
+	mu_tx_pend = 1UL;
+
+	return 0;
+}
+
+/**
+ * upwr_rx() - unqueues a received message from the reception queue.
+ * @msg: pointer to the message destination buffer.
+ * @size: pointer to variable to hold message size in 32-bit words.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: number of messages remaining in the reception queue, or
+ *         -1 if the queue was already empty when upwr_rx was called, or
+ *         -2 if any argument is invalid (like mu off-range)
+ */
+int upwr_rx(char *msg, unsigned int *size)
+{
+	unsigned int len = mu->RSR.R;
+
+	len = (len == 0x0U) ? 0U :
+	      (len == 0x1U) ? 1U :
+	      #if UPWR_MU_MSG_SIZE > 1
+	      (len == 0x3U) ? 2U :
+	      #if UPWR_MU_MSG_SIZE > 2
+	      (len == 0x7U) ? 3U :
+	      #if UPWR_MU_MSG_SIZE > 3
+	      (len == 0xFU) ? 4U :
+	      #endif
+	      #endif
+	      #endif
+	      0xFFFFFFFFU; /* something wrong */
+
+	if (len  == 0xFFFFFFFFU) {
+		return -3;
+	}
+
+	if (len == 0U) {
+		return -1;
+	}
+
+	*size = len;
+
+	/*
+	 * copy the received message to the rx queue,
+	 * so the interrupts are cleared.
+	 */
+	msg_copy(msg, (char *)&mu->RR[0], len);
+
+	mu->RCR.R = 1U; /* enable only RR[0] receive interrupt */
+
+	return 0;
+}
+
+/**
+ * upwr_rx_callback() - sets up a callback for a message receiving event.
+ * @callback: pointer to a function to be called when a message arrives;
+ *            can be NULL, in which case no callback is done.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok; -2 if any argument is invalid (mu off-range).
+ */
+int upwr_rx_callback(UPWR_RX_CALLB_FUNC_T callback)
+{
+	mu_rx_callb = callback;
+
+	return 0;
+}
+
+/**
+ * msg_copy() - copies a message.
+ * @dest: pointer to the destination message.
+ * @src : pointer to the source message.
+ * @size: message size in words.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void)
+ */
+void msg_copy(char *dest, char *src, unsigned int size)
+{
+	for (uint32_t i = 0U; i < size * sizeof(uint32_t); i++) {
+		dest[i] = src[i];
+	}
+}
diff --git a/plat/imx/imx8ulp/upower/upower_api.h b/plat/imx/imx8ulp/upower/upower_api.h
new file mode 100644
index 00000000..0069f5f0
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_api.h
@@ -0,0 +1,1629 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
+ * Copyright 2019-2024 NXP
+ *
+ * KEYWORDS: micro-power uPower driver API
+ * -----------------------------------------------------------------------------
+ * PURPOSE: uPower driver API
+ * -----------------------------------------------------------------------------
+ * PARAMETERS:
+ * PARAM NAME RANGE:DESCRIPTION:       DEFAULTS:                           UNITS
+ * -----------------------------------------------------------------------------
+ * REUSE ISSUES: no reuse issues
+ */
+#ifndef UPWR_API_H
+#define UPWR_API_H
+
+#include "upmu.h"
+#include "upower_soc_defs.h"
+/******************************************************************************
+ * uPower API Overview and Concepts
+ *
+ * This API is intended to be used by the OS drivers (Linux, FreeRTOS etc)
+ * as well as bare metal drivers to command and use services from the uPower.
+ * It aims to be OS-independent.
+ *
+ * The API functions fall in 3 categories:
+ *  - initialization/start-up
+ *  - service requests
+ *  - auxiliary
+ *
+ * The communication with the uPower is mostly made through the Message Unit
+ * (MU) IP. uPower provides one MU for each CPU cluster in a different
+ * power domain. An API instance runs on each CPU cluster.
+ *
+ * The API assumes each SoC power domain/CPU cluster receives 2 interrupts
+ * from the uPower MU:
+ *  1. Tx/Rx, which is issued on both transmission and reception
+ *  2. Exception interrupt, to handle critical alams, catastrophic errors, etc.
+ *     This interrupt should have a high priority, preferably an NMI.
+ *
+ * The normal uPower operation is done by service requests. There is an API
+ * function for each service request, and all service requests send back a
+ * response, at least to indicate success/failure.
+ * The service request functions are non-blocking, and their completion can be
+ * tracked in two ways:
+ *  1. by a callback, registered when the service request call is made by
+ *     passing the callback function pointer; a NULL pointer may be passed,
+ *     in which case no callback is made.
+ *  2. by polling, using the auxiliary functions upwr_req_status or
+ *     upwr_poll_req_status;
+ *     polling must be used if no callback is registered, but callbacks and
+ *     polling are completely independent.
+ *
+ * Note: a service request must not be started from a callback.
+ *
+ * uPower service requests are classified in Service Groups.
+ * Each Service Group has a set of related functions, named upwr_XXX_,
+ * where XXX is a 3-letter service group mnemonic. The service groups are:
+ *  - Exception Service Group - upwr_xcp_*
+ *     ~ gathers functions that deal with errors and other processes outside
+ *       the functional scope.
+ *  - Power Management Service Group - upwr_pwm_*
+ *     ~ functions to control switches, configure power modes, set internal voltage etc
+ *  - Delay Measurement Service Group - upwr_dlm_*
+ *     ~ delay measurements function using the process monitor and delay meter
+ *  - Voltage Measurement Service Group - upwr_vtm_*
+ *     ~ functions for voltage measurements, comparisons, alarms, power meter, set PMIC rail voltage
+ *  - Temperature Measurement Service Group - upwr_tpm_*
+ *     ~ functions for temperature measurements, comparisons, alarms
+ *  - Current Measurement Service Group  - upwr_crm_*
+ *     ~ functions for current and charge measurement
+ *  - Diagnostic Service Group - upwr_dgn_*
+ *     ~ functions for log configuration and statistics collecting
+ *
+ * Service requests follow this "golden rule":
+ * *** No two requests run simultaneously for the same service group,
+ *     on the same domain ***
+ * They can run simultaneously on different domains (RTD/APD), and can also run
+ * simultaneously if belong to different service groups (even on same domain).
+ * Therefore, requests to the same service group on the same domain must be
+ * serialized. A service request call returns error if there is another request
+ * on the same service group pending, waiting a response (on the same domain).
+ *
+ * A request for continuous service does not block the service group.
+ * For instance, a request to "measure the temperature each 10 miliseconds"
+ * responds quickly, unlocks the service group, and the temperature
+ * continues to be measured as requested, every 10 miliseconds from then on.
+ *
+ * Service Groups have a fixed priority in the API, from higher to lower:
+ *  1. Exception
+ *  2. Power Management
+ *  3. Delay Measurement
+ *  4. Voltage Measurement
+ *  5. Current Measurement
+ *  6. Temperature Measurement
+ *  7. Diagnostics
+ *
+ * The priority above only affects the order in which requests are sent to the
+ * uPower firmware: request to the higher priority Service Group is sent first,
+ * even if the call was made later, if there is an MU transmission pending,
+ * blocking it. The service priorities in the firmware depend on other factors.
+ *
+ * Services are requested using API functions. A service function returns with
+ * no error if a request was successfully made, but it doesn't mean the service
+ * was completed. The service is executed asynchronously, and returns a result
+ * (at least success/fail) via a callback or polling for service status.
+ * The possible service response codes are:
+ * - UPWR_RESP_OK = 0,     : no error
+ * - UPWR_RESP_SG_BUSY     : service group is busy
+ * - UPWR_RESP_SHUTDOWN    : services not up or shutting down
+ * - UPWR_RESP_BAD_REQ     : invalid request (usually invalid argumnents)
+ * - UPWR_RESP_BAD_STATE   : system state doesn't allow perform the request
+ * - UPWR_RESP_UNINSTALLD  : service or function not installed
+ * - UPWR_RESP_UNINSTALLED : service or function not installed (alias)
+ * - UPWR_RESP_RESOURCE    : resource not available
+ * - UPWR_RESP_TIMEOUT     : service timeout
+ */
+
+/**
+ * upwr_callb()-generic function pointer for a request return callback;
+ * @sg: request service group
+ * @func: service request function id.
+ * @errcode: error code.
+ * @ret: return value, if any. Note that a request may return a value even if
+ * service error is returned (errcode != UPWR_RESP_OK); that is dependent on
+ * the specific service.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void)
+ */
+typedef void (*upwr_callb)(upwr_sg_t sg, uint32_t func,
+			   upwr_resp_t errcode, ...);
+
+/**---------------------------------------------------------------
+ * INITIALIZATION, CONFIGURATION
+ *
+ * A reference uPower initialization sequence goes as follows:
+ *
+ * 1. host CPU calls upwr_init.
+ * 2. (optional) host checks the ROM version and SoC code calling upwr_vers(...)
+ *    and optionally performs any configuration or workaround accordingly.
+ * 3. host CPU calls upwr_start to start the uPower services, passing a
+ *    service option number.
+ *    If no RAM code is loaded or it has no service options, the launch option
+ *    number passed must be 0, which will start the services available in ROM.
+ *    upwr_start also receives a pointer to a callback called by the API
+ *    when the firmware is ready to receive service requests.
+ *    The callback may be replaced by polling, calling upwr_req_status in a loop
+ *    or upwr_poll_req_status; in this case the callback pointer may be NULL.
+ *    A host may call upwr_start even if the services were already started by
+ *    any host: if the launch option is the same, the response will be ok,
+ *    but will indicate error if the services were already started with a
+ *    different launch option.
+ * 4. host waits for the callback calling, or polling finishing;
+ *    if no error is returned, it can start making service calls using the API.
+ *
+ * Variations on that reference sequence are possible:
+ *  - the uPower services can be started using the ROM code only, which includes
+ *    the basic Power Management services, among others, with launch option
+ *    number = 0.
+ *    The code RAM can be loaded while these services are running and,
+ *    when the loading is done, the services can be re-started with these 2
+ *    requests executed in order: upwr_xcp_shutdown and upwr_start,
+ *    using the newly loaded RAM code (launch option > 0).
+ *
+ * NOTE: the initialization call upwr_init is not effective and
+ *       returns error when called after the uPower services are started.
+ */
+
+/**
+ * upwr_init() - API initialization; must be the first API call after reset.
+ * @domain: SoC-dependent CPU domain id; identifier used by the firmware in
+ * many services. Defined by SoC-dependent type soc_domain_t found in
+ * upower_soc_defs.h.
+ * @muptr: pointer to the MU instance.
+ * @mallocptr: pointer to the memory allocation function
+ * @physaddrptr: pointer to the function to convert pointers to
+ * physical addresses. If NULL, no conversion is made (pointer=physical address)
+ * @isrinstptr: pointer to the function to install the uPower ISR callbacks;
+ * the function receives the pointers to the MU tx/rx and Exception ISRs
+ * callbacks, which must be called from the actual system ISRs.
+ * The function pointed by isrinstptr must also enable the interrupt at the
+ * core/interrupt controller, but must not enable the interrupt at the MU IP.
+ * The system ISRs are responsible for dealing with the interrupt controller,
+ * performing any other context save/restore, and any other housekeeping.
+ * @lockptr: pointer to a function that prevents MU interrupts (if argrument=1)
+ * or allows it (if argument=0). The API calls this function to make small
+ * specific code portions thread safe. Only MU interrupts must be avoided,
+ * the code may be suspended for other reasons.
+ * If no MU interrupts can happen during the execution of an API call or
+ * callback, even if enabled, for some other reason (e.g. interrupt priority),
+ * then this argument may be NULL.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if failed to allocate memory, or use some other resource.
+ *        -2 if any argument is invalid.
+ *        -3 if failed to send the ping message.
+ *        -4 if failed to receive the initialization message, or was invalid
+ */
+
+/* malloc function ptr */
+typedef void* (*upwr_malloc_ptr_t)(unsigned int size);
+
+/* pointer->physical address conversion function ptr */
+typedef void* (*upwr_phyadr_ptr_t)(const void *addr);
+
+typedef uint32_t upwr_api_state_t;
+
+extern volatile upwr_api_state_t api_state;
+
+/*
+ * upwr_lock_ptr_t: pointer to a function that prevents MU interrupts
+ * (if argrument lock=1) or allows it (if argument lock=0).
+ * The API calls this function to make small specific code portions thread safe.
+ * Only MU interrupts must be avoided, the code may be suspended for other
+ * reasons.
+ */
+typedef void  (*upwr_lock_ptr_t)(int lock);
+
+typedef void (*upwr_isr_callb)(void);
+
+typedef void (*upwr_inst_isr_ptr_t)(upwr_isr_callb txrx_isr,
+				    upwr_isr_callb excp_isr);
+void upwr_start_callb(void);
+
+int upwr_init(soc_domain_t domain, struct MU_t *muptr,
+	      const upwr_malloc_ptr_t mallocptr,
+	      const upwr_phyadr_ptr_t phyadrptr,
+	      const upwr_inst_isr_ptr_t isrinstptr,
+	      const upwr_lock_ptr_t lockptr);
+
+/**
+ * upwr_start() - Starts the uPower services.
+ * @launchopt: a number to select between multiple launch options,
+ * that may define, among other things, which services will be started,
+ * or which services implementations, features etc.
+ * launchopt = 0 selects a subset of services implemented in ROM;
+ * any other number selects service sets implemented in RAM, launched
+ * by the firmware function ram_launch; if an invalid launchopt value is passed,
+ * no services are started, and the callback returns error (see below).
+ * @rdycallb: pointer to the callback to be called when the uPower is ready
+ * to receive service requests. NULL if no callback needed.
+ * The callback receives as arguments the RAM firmware version numbers.
+ * If all 3 numbers (vmajor, vminor, vfixes) are 0, that means the
+ * service launching failed.
+ * Firmware version numbers will be the same as ROM if launchopt = 0,
+ * selecting the ROM services.
+ *
+ * upwr_start can be called by any domain even if the services are already
+ * started: it has no effect, returning success, if the launch option is the
+ * same as the one that actually started the service, and returns error if
+ * called with a different option.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if a resource failed,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+
+extern void upwr_txrx_isr(void);
+
+typedef void (*upwr_rdy_callb)(uint32_t vmajor, uint32_t vminor, uint32_t vfixes);
+
+int upwr_start(uint32_t launchopt, const upwr_rdy_callb rdycallb);
+
+
+/**---------------------------------------------------------------
+ * EXCEPTION SERVICE GROUP
+ */
+
+/**
+ * upwr_xcp_config() - Applies general uPower configurations.
+ * @config: pointer to the uPower SoC-dependent configuration struct
+ * upwr_xcp_config_t defined in upower_soc_defs.h. NULL may be passed, meaning
+ * a request to read the configuration, in which case it appears in the callback
+ * argument ret, or can be pointed by argument retptr in the upwr_req_status and
+ * upwr_poll_req_status calls, casted to upwr_xcp_config_t.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the configuration, or NULL if no callback needed (polling used instead).
+ *
+ * Some configurations are targeted for a specific domain (see the struct
+ * upwr_xcp_config_t definition in upower_soc_defs.h); this call has implicit
+ * domain target (the same domain from which is called).
+ *
+ * The return value is always the current configuration value, either in a
+ * read-only request (config = NULL) or after setting a new configuration
+ * (non-NULL config).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_config(const upwr_xcp_config_t *config, const upwr_callb callb);
+
+/**
+ * upwr_xcp_sw_alarm() - Makes uPower issue an alarm interrupt to given domain.
+ * @domain: identifier of the domain to alarm. Defined by SoC-dependent type
+ * soc_domain_t found in upower_soc_defs.h.
+ * @code: alarm code. Defined by SoC-dependent type upwr_alarm_t found in
+ * upower_soc_defs.h.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the alarm, or NULL if no callback needed (polling used instead).
+ *
+ * The function requests the uPower to issue an alarm of the given code as if
+ * it had originated internally. This service is useful mainly to test the
+ * system response to such alarms, or to make the system handle a similar alarm
+ * situation detected externally to uPower.
+ *
+ * The system ISR/code handling the alarm may retrieve the alarm code by calling
+ * the auxiliary function upwr_alarm_code.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_sw_alarm(soc_domain_t domain, upwr_alarm_t code,
+		      const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_ddr_retention() - M33/A35 can use this API to set/clear ddr retention
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set ddr retention, false clear ddr retention.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_set_ddr_retention(soc_domain_t domain, uint32_t enable,
+			       const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_mipi_dsi_ena() - M33/A35 can use this API to set/clear mipi dsi ena
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set ddr retention, false clear ddr retention.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_set_mipi_dsi_ena(soc_domain_t domain, uint32_t enable,
+			      const upwr_callb callb);
+
+/**
+ * upwr_xcp_get_mipi_dsi_ena() - M33/A35 can use this API to get mipi dsi ena status
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+
+int upwr_xcp_get_mipi_dsi_ena(soc_domain_t domain, const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_osc_mode() - M33/A35 can use this API to set uPower OSC mode
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @osc_mode, 0 means low frequency, not 0 means high frequency.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_osc_mode(soc_domain_t domain, uint32_t osc_mode,
+			  const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_rtd_use_ddr() - M33 call this API to inform uPower, M33 is using ddr
+ * @domain: identifier of the caller domain.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @is_use_ddr: not 0, true, means that RTD is using ddr. 0, false, means that, RTD
+ * is not using ddr.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_rtd_use_ddr(soc_domain_t domain, uint32_t is_use_ddr,
+			     const upwr_callb callb);
+
+/**
+ * upwr_xcp_set_rtd_apd_llwu() - M33/A35 can use this API to set/clear rtd_llwu apd_llwu
+ * @domain: set which domain (RTD_DOMAIN, APD_DOMAIN) LLWU.
+ * soc_domain_t found in upower_soc_defs.h.
+ * @enable: true, means that set rtd_llwu or apd_llwu, false clear rtd_llwu or apd_llwu.
+ * @callb: NULL
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_set_rtd_apd_llwu(soc_domain_t domain, uint32_t enable,
+			      const upwr_callb callb);
+/**
+ * upwr_xcp_shutdown() - Shuts down all uPower services and power mode tasks.
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the shutdown, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * At the callback the uPower/API is back to initialization/start-up phase,
+ * so service request calls return error.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_shutdown(const upwr_callb callb);
+
+/**
+ * upwr_xcp_i2c_access() - Performs an access through the uPower I2C interface.
+ * @addr: I2C slave address, up to 10 bits.
+ * @data_size: determines the access direction and data size in bytes, up to 4;
+ * negetive data_size determines a read  access with size -data_size;
+ * positive data_size determines a write access with size  data_size;
+ * data_size=0 is invalid, making the service return error UPWR_RESP_BAD_REQ.
+ * @subaddr_size: size of the sub-address in bytes, up to 4; if subaddr_size=0,
+ * no subaddress is used.
+ * @subaddr: sub-address, only used if subaddr_size > 0.
+ * @wdata: write data, up to 4 bytes; ignored if data_size < 0 (read)
+ * @callb: pointer to the callback to be called when the uPower has finished
+ * the access, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_EXCEPT as the service group argument.
+ *
+ * The service performs a read (data_size < 0) or a write (data_size > 0) of
+ * up to 4 bytes on the uPower I2C interface. The data read from I2C comes via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * Sub-addressing is supported, with sub-address size determined by the argument
+ * subaddr_size, up to 4 bytes. Sub-addressing is not used if subaddr_size=0.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_xcp_i2c_access(uint16_t addr, int8_t data_size, uint8_t subaddr_size,
+			uint32_t subaddr, uint32_t wdata,
+			const upwr_callb callb);
+
+
+/**---------------------------------------------------------------
+ * POWER MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_pwm_dom_power_on() - Commands uPower to power on the platform of other
+ * domain (not necessarily its core(s)); does not release the core reset.
+ * @domain: identifier of the domain to power on. Defined by SoC-dependent type
+ * soc_domain_t found in upower_soc_defs.h.
+ * @boot_start: must be 1 to start the domain core(s) boot(s), releasing
+ * its (their) resets, or 0 otherwise.
+ * @pwroncallb: pointer to the callback to be called when the uPower has
+ * finished the power on procedure, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_dom_power_on(soc_domain_t domain, int boot_start,
+			  const upwr_callb pwroncallb);
+
+/**
+ * upwr_pwm_boot_start() - Commands uPower to release the reset of other CPU(s),
+ * starting their boots.
+ * @domain: identifier of the domain to release the reset. Defined by
+ * SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @bootcallb: pointer to the callback to be called when the uPower has finished
+ * the boot start procedure, or NULL if no callback needed
+ * (polling used instead).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * The callback calling doesn't mean the CPUs boots have finished:
+ * it only indicates that uPower released the CPUs resets, and can receive
+ * other power management service group requests.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -2 if the domain passed is the same as the caller,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_boot_start(soc_domain_t domain, const upwr_callb  bootcallb);
+
+/**
+ * upwr_pwm_param() - Changes Power Management parameters.
+ * @param: pointer to a parameter structure upwr_pwm_param_t, SoC-dependent,
+ * defined in upwr_soc_defines.h. NULL may be passed, meaning
+ * a request to read the parameter set, in which case it appears in the callback
+ * argument ret, or can be pointed by argument retptr in the upwr_req_status and
+ * upwr_poll_req_status calls, casted to upwr_pwm_param_t.
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The return value is always the current parameter set value, either in a
+ * read-only request (param = NULL) or after setting a new parameter
+ * (non-NULL param).
+ *
+ * Some parameters may be targeted for a specific domain (see the struct
+ * upwr_pwm_param_t definition in upower_soc_defs.h); this call has implicit
+ * domain target (the same domain from which is called).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded or
+ * not.
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_pwm_param(upwr_pwm_param_t *param, const upwr_callb callb);
+
+/**
+ * upwr_pwm_chng_reg_voltage() - Changes the voltage at a given regulator.
+ * @reg: regulator id.
+ * @volt: voltage value; value unit is SoC-dependent, converted from mV by the
+ * macro UPWR_VOLT_MILIV, or from micro-Volts by the macro UPWR_VOLT_MICROV,
+ * both macros in upower_soc_defs.h
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to change the voltage of the given regulator.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_reg_voltage(uint32_t reg, uint32_t volt, upwr_callb callb);
+
+/**
+ * upwr_pwm_freq_setup() - Determines the next frequency target for a given
+ *                         domain and current frequency.
+ * @domain: identifier of the domain to change frequency. Defined by
+ * SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @rail: the pmic regulator number for the target domain.
+ * @stage: DVA adjust stage
+ * refer to upower_defs.h "DVA adjust stage"
+ * @target_freq: the target adjust frequency, accurate to MHz
+ *
+ * refer to upower_defs.h structure definition upwr_pwm_freq_msg
+ *
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The DVA algorithm is broken down into two phases.
+ * The first phase uses a look up table to get a safe operating voltage
+ * for the requested frequency.
+ * This voltage is guaranteed to work over process and temperature.
+ *
+ * The second step of the second phase is to measure the temperature
+ * using the uPower Temperature Sensor module.
+ * This is accomplished by doing a binary search of the TSEL bit field
+ * in the Temperature Measurement Register (TMR).
+ * The search is repeated until the THIGH bit fields in the same register change value.
+ * There are 3 temperature sensors in 8ULP (APD, AVD, and RTD).
+ *
+ *
+ * The second phase is the fine adjust of the voltage.
+ * This stage is entered only when the new frequency requested
+ * by application was already set as well as the voltage for that frequency.
+ * The first step of the fine adjust is to find what is the current margins
+ * for the monitored critical paths, or, in other words,
+ * how many delay cells will be necessary to generate a setup-timing violation.
+ * The function informs uPower that the given domain frequency has changed or
+ * will change to the given value. uPower firmware will then adjust voltage and
+ * bias to cope with the new frequency (if decreasing) or prepare for it
+ * (if increasing). The function must be called after decreasing the frequency,
+ * and before increasing it. The actual increase in frequency must not occur
+ * before the service returns its response.
+ *
+ * So, for increase clock frequency case, user need to call this API twice,
+ * the first stage gross adjust and the second stage fine adjust.
+ *
+ * for reduce clock frequency case, user can only call this API once,
+ * full stage (combine gross stage and fine adjust)
+ *
+ * The request is executed if arguments are within range.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_freq_setup(soc_domain_t domain, uint32_t rail, uint32_t stage,
+			uint32_t target_freq, upwr_callb callb);
+
+/**
+ * upwr_pwm_power_on()- Powers on (not off) one or more switches and ROM/RAMs.
+ * @swton: pointer to an array of words that tells which power switches to
+ *  turn on. Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective switch must be turned on,
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no switch will be changed,
+ *  unless a memory that it feeds must be turned on.
+ *  WARNING: swton must not point to the first shared memory address.
+ * @memon: pointer to an array of words that tells which memories to turn on.
+ *  Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective memory must be turned on, both array and
+ *  periphery logic;
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no memory will be changed.
+ *  WARNING: memon must not point to the first shared memory address.
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn on the PMC and memory array/peripheral
+ * switches that control their power, as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate memory power state related to overall system state.
+ *
+ * If a memory is requested to turn on, but the power switch that feeds that
+ * memory is not, the power switch will be turned on anyway, if the pwron
+ * array is not provided (that is, if pwron is NULL).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_power_on(const uint32_t swton[], const uint32_t memon[],
+		      upwr_callb callb);
+
+/**
+ * upwr_pwm_power_off()- Powers off (not on) one or more switches and ROM/RAMs.
+ * @swtoff: pointer to an array of words that tells which power switches to
+ *  turn off. Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective switch must be turned off,
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no switch will be changed.
+ *  WARNING: swtoff must not point to the first shared memory address.
+ * @memoff: pointer to an array of words that tells which memories to turn off.
+ *  Each word in the array has 1 bit for each switch.
+ *  A bit=1 means the respective memory must be turned off, both array and
+ *  periphery logic;
+ *  bit = 0 means it will stay unchanged (on or off).
+ *  The pointer may be set to NULL, in which case no memory will be changed,
+ *  but notice it may be turned off if the switch that feeds it is powered off.
+ *  WARNING: memoff must not point to the first shared memory address.
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn off the PMC and memory array/peripheral
+ * switches that control their power, as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate memory power state related to overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_power_off(const uint32_t swtoff[], const uint32_t memoff[],
+		       upwr_callb callb);
+
+/**
+ * upwr_pwm_mem_retain()- Configures one or more memory power switches to
+ * retain its contents, having the power array on, while its peripheral logic
+ * is turned off.
+ * @mem: pointer to an array of words that tells which memories to put in a
+ *  retention state. Each word in the array has 1 bit for each memory.
+ *  A bit=1 means the respective memory must be put in retention state,
+ *  bit = 0 means it will stay unchanged (retention, fully on or off).
+ * @callb: pointer to the callback called when configurations are applyed.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to turn off the memory peripheral and leave
+ * its array on, as specified above.
+ * The request is executed if arguments are within range.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_mem_retain(const uint32_t mem[], upwr_callb callb);
+
+/**
+ * upwr_pwm_chng_switch_mem() - Turns on/off power on one or more PMC switches
+ * and memories, including their array and peripheral logic.
+ * @swt: pointer to a list of PMC switches to be opened/closed.
+ *  The list is structured as an array of struct upwr_switch_board_t
+ *  (see upower_defs.h), each one containing a word for up to 32 switches,
+ *  one per bit. A bit = 1 means switch closed, bit = 0 means switch open.
+ *  struct upwr_switch_board_t also specifies a mask with 1 bit for each
+ *  respective switch: mask bit = 1 means the open/close action is applied,
+ *  mask bit = 0 means the switch stays unchanged.
+ *  The pointer may be set to NULL, in which case no switch will be changed,
+ *  unless a memory that it feeds must be turned on.
+ *  WARNING: swt must not point to the first shared memory address.
+ * @mem: pointer to a list of switches to be turned on/off.
+ *  The list is structured as an array of struct upwr_mem_switches_t
+ *  (see upower_defs.h), each one containing 2 word for up to 32 switches,
+ *  one per bit, one word for the RAM array power switch, other for the
+ *  RAM peripheral logic power switch. A bit = 1 means switch closed,
+ *  bit = 0 means switch open.
+ *  struct upwr_mem_switches_t also specifies a mask with 1 bit for each
+ *  respective switch: mask bit = 1 means the open/close action is applied,
+ *  mask bit = 0 means the switch stays unchanged.
+ *  The pointer may be set to NULL, in which case no memory switch will be
+ *  changed, but notice it may be turned off if the switch that feeds it is
+ *  powered off.
+ *  WARNING: mem must not point to the first shared memory address.
+ * @callb: pointer to the callback called when the configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the PMC switches and/or memory power
+ * as specified above.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate switch combinations and overall system state.
+ *
+ * If a memory is requested to turn on, but the power switch that feeds that
+ * memory is not, the power switch will be turned on anyway, if the swt
+ * array is not provided (that is, if swt is NULL).
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Callback or polling may return error if the service contends for a resource
+ * already being used by a power mode transition or an ongoing service in
+ * another domain.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy.
+ *        -2 if a pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_chng_switch_mem(const struct upwr_switch_board_t swt[],
+			     const struct upwr_mem_switches_t mem[],
+			     upwr_callb callb);
+
+/**
+ * upwr_pwm_pmode_config() - Configures a given power mode in a given domain.
+ * @domain: identifier of the domain to which the power mode belongs.
+ * Defined by SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @pmode: SoC-dependent power mode identifier defined by type abs_pwr_mode_t
+ * found in upower_soc_defs.h.
+ * @config: pointer to an SoC-dependent struct defining the power mode
+ * configuration, found in upower_soc_defs.h.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the power mode configuration as
+ * specified above. The request is executed if arguments are within range,
+ * and complies with SoC-dependent restrictions on value combinations.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_pmode_config(soc_domain_t domain, abs_pwr_mode_t pmode,
+			  const void *config, upwr_callb callb);
+
+
+
+/**
+ * upwr_pwm_reg_config() - Configures the uPower internal regulators.
+ * @config: pointer to the struct defining the regulator configuration;
+ * the struct upwr_reg_config_t is defined in the file upower_defs.h.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change/define the configurations of the
+ * internal regulators.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * The service may fail with error UPWR_RESP_RESOURCE if a power mode transition
+ * or the same service (called from another domain) is executing simultaneously.
+ * This error should be interpreted as a "try later" response, as the service
+ * will succeed once those concurrent executions are done, and no other is
+ * started.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_pwm_reg_config(const struct upwr_reg_config_t *config,
+			upwr_callb callb);
+
+/**
+ * upwr_pwm_chng_dom_bias() - Changes the domain bias.
+ * @bias: pointer to a domain bias configuration struct (see upower_soc_defs.h).
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the domain bias configuration as
+ * specified above. The request is executed if arguments are within range,
+ * with no protections regarding the adequate value combinations and
+ * overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_chng_dom_bias(const struct upwr_dom_bias_cfg_t *bias,
+			   upwr_callb callb);
+
+/**
+ * upwr_pwm_chng_mem_bias()- Changes a ROM/RAM power bias.
+ * @domain: identifier of the domain upon which the bias is applied.
+ * Defined by SoC-dependent type soc_domain_t found in upower_soc_defs.h.
+ * @bias: pointer to a memory bias configuration struct (see upower_soc_defs.h).
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change the memory bias configuration as
+ * specified above. The request is executed if arguments are within range,
+ * with no protections regarding the adequate value combinations and
+ * overall system state.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+
+int upwr_pwm_chng_mem_bias(soc_domain_t domain,
+			   const struct upwr_mem_bias_cfg_t *bias,
+			   upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * VOLTAGE MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_vtm_pmic_cold_reset() -request cold reset the pmic.
+ * pmic will power cycle all the regulators
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to cold reset the pmic.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_pmic_cold_reset(upwr_callb callb);
+
+/**
+ * upwr_vtm_set_pmic_mode() -request uPower set pmic mode
+ * @pmic_mode: the target mode need to be set
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to set pmic mode
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_set_pmic_mode(uint32_t pmic_mode, upwr_callb callb);
+
+/**
+ * upwr_vtm_chng_pmic_voltage() - Changes the voltage of a given rail.
+ * @rail: pmic rail id.
+ * @volt: the target voltage of the given rail, accurate to uV
+ * If pass volt value 0, means that power off this rail.
+ * @callb: response callback pointer; NULL if no callback needed.
+ *
+ * The function requests uPower to change the voltage of the given rail.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_chng_pmic_voltage(uint32_t rail, uint32_t volt, upwr_callb callb);
+
+/**
+ * upwr_vtm_get_pmic_voltage() - Get the voltage of a given ral.
+ * @rail: pmic rail id.
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to get the voltage of the given rail.
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The voltage data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_get_pmic_voltage(uint32_t rail, upwr_callb callb);
+
+
+/**
+ * upwr_vtm_power_measure() - request uPower to measure power consumption
+ * @ssel: This field determines which power switches will have their currents
+ * sampled to be accounted for a
+ * current/power measurement. Support 0~7
+
+ * SSEL bit #	Power Switch
+ * 0	M33 core complex/platform/peripherals
+ * 1	Fusion Core and Peripherals
+ * 2	A35[0] core complex
+ * 3	A35[1] core complex
+ * 4	3DGPU
+ * 5	HiFi4
+ * 6	DDR Controller (PHY and PLL NOT included)
+ * 7	PXP, EPDC
+ *
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to measure power consumption
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The power consumption data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Accurate to uA
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_power_measure(uint32_t ssel, upwr_callb callb);
+
+/**
+ * upwr_vtm_vmeter_measure() - request uPower to measure voltage
+ * @vdetsel: Voltage Detector Selector, support 0~3
+ * 00b - RTD sense point
+ * 01b - LDO output
+ * 10b - APD domain sense point
+ * 11b - AVD domain sense point
+ * Refer to upower_defs.h
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to use vmeter to measure voltage
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_VOLTM as the service group argument.
+ *
+ * The voltage data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Refer to RM COREREGVL (Core Regulator Voltage Level)
+ * uPower return VDETLVL to user, user can calculate the real voltage:
+ *
+ * 0b000000(0x00) - 0.595833V
+ * 0b100110(0x26) - 1.007498V
+ * <value> - 0.595833V + <value>x10.8333mV
+ * 0b110010(0x32) - 1.138V
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_vmeter_measure(uint32_t vdetsel, upwr_callb callb);
+
+/**
+ * upwr_vtm_pmic_config() - Configures the SoC PMIC (Power Management IC).
+ * @config: pointer to a PMIC-dependent struct defining the PMIC configuration.
+ * @size:   size of the struct pointed by config, in bytes.
+ * @callb: pointer to the callback called when configurations are applied.
+ * NULL if no callback is required.
+ *
+ * The function requests uPower to change/define the PMIC configuration.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_PWRMGMT as the service group argument.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok, -1 if service group is busy,
+ *        -2 if the pointer conversion to physical address failed,
+ *        -3 if called in an invalid API state.
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_vtm_pmic_config(const void *config, uint32_t size, upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * TEMPERATURE MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_tpm_get_temperature() - request uPower to get temperature of one temperature sensor
+ * @sensor_id: temperature sensor ID, support 0~2
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to measure temperature
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_TEMPM as the service group argument.
+ *
+ * The temperature data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ *
+ * uPower return TSEL to the caller (M33 or A35), caller calculate the real temperature
+ * Tsh = 0.000002673049*TSEL[7:0]^3 + 0.0003734262*TSEL[7:0]^2 +
+0.4487042*TSEL[7:0] - 46.98694
+ *
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_tpm_get_temperature(uint32_t sensor_id, upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * DELAY MANAGEMENT SERVICE GROUP
+ */
+
+/**
+ * upwr_dlm_get_delay_margin() - request uPower to get delay margin
+ * @path: The critical path
+ * @index: Use whitch delay meter
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to get delay margin
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The delay margin data read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_get_delay_margin(uint32_t path, uint32_t index, upwr_callb callb);
+
+/**
+ * upwr_dlm_set_delay_margin() - request uPower to set delay margin
+ * @path: The critical path
+ * @index: Use whitch delay meter
+ * @delay_margin: the value of delay margin
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to set delay margin
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The result of the corresponding critical path,  failed or not  read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_set_delay_margin(uint32_t path, uint32_t index, uint32_t delay_margin, upwr_callb callb);
+
+/**
+ * upwr_dlm_process_monitor() - request uPower to do process monitor
+ * @chain_sel: Chain Cell Type Selection
+ * Select the chain to be used for the clock signal generation.
+ * Support two types chain cell, 0~1
+0b - P4 type delay cells selected
+1b - P16 type delay cells selected
+ * @callb: response callback pointer; NULL if no callback needed.
+ * (polling used instead)
+ *
+ * The function requests uPower to do process monitor
+ * The request is executed if arguments are within range, with no protections
+ * regarding the adequate voltage value for the given domain process,
+ * temperature and frequency.
+ *
+ * A callback can be optionally registered, and will be called upon the arrival
+ * of the request response from the uPower firmware, telling if it succeeded
+ * or not.
+ *
+ * A callback may not be registered (NULL pointer), in which case polling has
+ * to be used to check the response, by calling upwr_req_status or
+ * upwr_poll_req_status, using UPWR_SG_DELAYM as the service group argument.
+ *
+ * The result of process monitor,  failed or not  read from uPower via
+ * the callback argument ret, or written to the variable pointed by retptr,
+ * if polling is used (calls upwr_req_status or upwr_poll_req_status).
+ * ret (or *retptr) also returns the data written on writes.
+ * upower fw needs support cocurrent request from M33 and A35.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ * Note that this is not the error response from the request itself:
+ * it only tells if the request was successfully sent to the uPower.
+ */
+int upwr_dlm_process_monitor(uint32_t chain_sel, upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * DIAGNOSE SERVICE GROUP
+ */
+
+/**
+ * upwr_dgn_mode() - Sets the diagnostic mode.
+ * @mode:  diagnostic mode, which can be:
+ *  - UPWR_DGN_NONE:   no diagnostic recorded
+ *  - UPWR_DGN_TRACE:  warnings, errors, service, internal activity recorded
+ *  - UPWR_DGN_SRVREQ: warnings, errors, service activity recorded
+ *  - UPWR_DGN_WARN:   warnings and errors recorded
+ *  - UPWR_DGN_ALL:    trace, service, warnings, errors, task state recorded
+ *  - UPWR_DGN_ERROR:  only errors recorded
+ *  - UPWR_DGN_ALL2ERR: record all until an error occurs,
+ *    freeze recording on error
+ *  - UPWR_DGN_ALL2HLT: record all until an error occurs,
+ *    executes an ebreak on error, which halts the core if enabled through
+ *    the debug interface
+ * @callb: pointer to the callback called when mode is changed.
+ * NULL if no callback is required.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok,
+ *        -1 if service group is busy,
+ *        -3 if called in an invalid API state
+ */
+int upwr_dgn_mode(upwr_dgn_mode_t mode, const upwr_callb callb);
+
+/**---------------------------------------------------------------
+ * AUXILIARY CALLS
+ */
+
+/**
+ * upwr_rom_version() - informs the ROM firwmware version.
+ * @vmajor: pointer to the variable to get the firmware major version number.
+ * @vminor: pointer to the variable to get the firmware minor version number.
+ * @vfixes: pointer to the variable to get the firmware fixes number.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: SoC id.
+ */
+uint32_t upwr_rom_version(uint32_t *vmajor, uint32_t *vminor, uint32_t *vfixes);
+
+/**
+ * upwr_ram_version() - informs the RAM firwmware version.
+ * @vminor: pointer to the variable to get the firmware minor version number.
+ * @vfixes: pointer to the variable to get the firmware fixes number.
+ *
+ * The 3 values returned are 0 if no RAM firmwmare was loaded and initialized.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: firmware major version number.
+ */
+uint32_t upwr_ram_version(uint32_t *vminor, uint32_t *vfixes);
+
+/**
+ * upwr_req_status() - tells the status of the service group request, and
+ *                     returns a request return value, if any.
+ * @sg: service group of the request
+ * @sgfptr: pointer to the variable that will hold the function id of
+ * the last request completed; can be NULL, in which case it is not used.
+ * @errptr: pointer to the variable that will hold the error code;
+ * can be NULL, in which case it is not used.
+ * @retptr: pointer to the variable that will hold the value returned
+ * by the last request completed (invalid if the last request completed didn't
+ * return any value); can be NULL, in which case it is not used.
+ * Note that a request may return a value even if service error is returned
+ * (*errptr != UPWR_RESP_OK): that is dependent on the specific service.
+ *
+ * This call can be used in a poll loop of a service request completion in case
+ * a callback was not registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: service request status: succeeded, failed, or ongoing (busy)
+ */
+
+/* service request status */
+typedef enum {
+	UPWR_REQ_OK,     /* request succeeded */
+	UPWR_REQ_ERR,    /* request failed */
+	UPWR_REQ_BUSY    /* request execution ongoing */
+} upwr_req_status_t;
+
+upwr_req_status_t upwr_req_status(upwr_sg_t sg,
+				  uint32_t *sgfptr,
+				  upwr_resp_t *errptr,
+				  int *retptr);
+
+/**
+ * upwr_poll_req_status() - polls the status of the service group request, and
+ *                          returns a request return value, if any.
+ * @sg: service group of the request
+ * @sgfptr: pointer to the variable that will hold the function id of
+ * the last request completed; can be NULL, in which case it is not used.
+ * @errptr: pointer to the variable that will hold the error code;
+ * can be NULL, in which case it is not used.
+ * @retptr: pointer to the variable that will hold the value returned
+ * by the last request completed (invalid if the last request completed didn't
+ * return any value); can be NULL, in which case it is not used.
+ * Note that a request may return a value even if service error is returned
+ * (*errptr != UPWR_RESP_OK): that is dependent on the specific service.
+ * @attempts: maximum number of polling attempts; if attempts > 0 and is
+ * reached with no service response received, upwr_poll_req_status returns
+ * UPWR_REQ_BUSY and variables pointed by sgfptr, retptr and errptr are not
+ * updated; if attempts = 0, upwr_poll_req_status waits "forever".
+ *
+ * This call can be used to poll a service request completion in case a
+ * callback was not registered.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: service request status: succeeded, failed, or ongoing (busy)
+ */
+upwr_req_status_t upwr_poll_req_status(upwr_sg_t sg,
+				       uint32_t *sgfptr,
+				       upwr_resp_t *errptr,
+				       int *retptr,
+				       uint32_t attempts);
+
+/**
+ * upwr_alarm_code() - returns the alarm code of the last alarm occurrence.
+ *
+ * The value returned is not meaningful if no alarm was issued by uPower.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: alarm code, as defined by the type upwr_alarm_t in upwr_soc_defines.h
+ */
+upwr_alarm_t upwr_alarm_code(void);
+
+/**---------------------------------------------------------------
+ * TRANSMIT/RECEIVE PRIMITIVES
+ * ---------------------------------------------------------------
+ */
+
+typedef void (*UPWR_TX_CALLB_FUNC_T)(void);
+typedef void (*UPWR_RX_CALLB_FUNC_T)(void);
+
+/**
+ * upwr_tx() - queues a message for transmission.
+ * @msg : pointer to the message sent.
+ * @size: message size in 32-bit words
+ * @callback: pointer to a function to be called when transmission done;
+ *            can be NULL, in which case no callback is done.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: number of vacant positions left in the transmission queue, or
+ *         -1 if the queue was already full when upwr_tx was called, or
+ *         -2 if any argument is invalid (like size off-range)
+ */
+int upwr_tx(const uint32_t *msg, unsigned int size,
+	    UPWR_TX_CALLB_FUNC_T callback);
+
+/**
+ * upwr_rx() - unqueues a received message from the reception queue.
+ * @msg: pointer to the message destination buffer.
+ * @size: pointer to variable to hold message size in 32-bit words.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: number of messages remaining in the reception queue, or
+ *         -1 if the queue was already empty when upwr_rx was called, or
+ *         -2 if any argument is invalid (like mu off-range)
+ */
+int upwr_rx(char *msg, unsigned int *size);
+
+/**
+ * upwr_rx_callback() - sets up a callback for a message receiving event.
+ * @callback: pointer to a function to be called when a message arrives;
+ *            can be NULL, in which case no callback is done.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: 0 if ok; -2 if any argument is invalid (mu off-range).
+ */
+int upwr_rx_callback(UPWR_RX_CALLB_FUNC_T callback);
+
+/**
+ * msg_copy() - copies a message.
+ * @dest: pointer to the destination message.
+ * @src : pointer to the source message.
+ * @size: message size in words.
+ *
+ * This is an auxiliary function used by the rest of the API calls.
+ * It is normally not called by the driver code, unless maybe for test purposes.
+ *
+ * Context: no sleep, no locks taken/released.
+ * Return: none (void)
+ */
+void msg_copy(char *dest, char *src, unsigned int size);
+
+#endif /* UPWR_API_H */
diff --git a/plat/imx/imx8ulp/upower/upower_defs.h b/plat/imx/imx8ulp/upower/upower_defs.h
new file mode 100644
index 00000000..118d7e0c
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_defs.h
@@ -0,0 +1,742 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
+ * Copyright 2019-2024 NXP
+ *
+ * KEYWORDS: micro-power uPower driver API
+ * -----------------------------------------------------------------------------
+ * PURPOSE: uPower driver API #defines and typedefs shared with the firmware
+ * -----------------------------------------------------------------------------
+ * PARAMETERS:
+ * PARAM NAME RANGE:DESCRIPTION:       DEFAULTS:                           UNITS
+ * -----------------------------------------------------------------------------
+ * REUSE ISSUES: no reuse issues
+ */
+
+#ifndef UPWR_DEFS_H
+#define UPWR_DEFS_H
+
+#include <stdint.h>
+
+#ifndef UPWR_PMC_SWT_WORDS
+#define UPWR_PMC_SWT_WORDS              (1U)
+#endif
+
+#ifndef UPWR_PMC_MEM_WORDS
+#define UPWR_PMC_MEM_WORDS              (2U)
+#endif
+
+/* ****************************************************************************
+ * DOWNSTREAM MESSAGES - COMMANDS/FUNCTIONS
+ * ****************************************************************************
+ */
+#define UPWR_SRVGROUP_BITS  (4U)
+#define UPWR_FUNCTION_BITS  (4U)
+#define UPWR_PWDOMAIN_BITS  (4U)
+#define UPWR_HEADER_BITS   \
+		(UPWR_SRVGROUP_BITS + UPWR_FUNCTION_BITS + UPWR_PWDOMAIN_BITS)
+#define UPWR_ARG_BITS      (32U - UPWR_HEADER_BITS)
+#if   ((UPWR_ARG_BITS & 1U) > 0U)
+#error "UPWR_ARG_BITS must be an even number"
+#endif
+#define UPWR_ARG64_BITS          (64U - UPWR_HEADER_BITS)
+#define UPWR_HALF_ARG_BITS       (UPWR_ARG_BITS >> 1U)
+#define UPWR_DUAL_OFFSET_BITS    ((UPWR_ARG_BITS + 32U) >> 1U)
+
+/*
+ * message header: header fields common to all downstream messages.
+ */
+struct upwr_msg_hdr {
+	uint32_t domain   : UPWR_PWDOMAIN_BITS; /* power domain */
+	uint32_t srvgrp   : UPWR_SRVGROUP_BITS; /* service group */
+	uint32_t function : UPWR_FUNCTION_BITS; /* function */
+	uint32_t arg      : UPWR_ARG_BITS; /* function-specific argument */
+};
+
+/* generic 1-word downstream message format */
+typedef union {
+	struct upwr_msg_hdr  hdr;
+	uint32_t             word;  /* message first word */
+} upwr_down_1w_msg;
+
+/* generic 2-word downstream message format */
+typedef struct {
+	struct upwr_msg_hdr  hdr;
+	uint32_t             word2;  /* message second word */
+} upwr_down_2w_msg;
+
+/* message format for functions that receive a pointer/offset */
+typedef struct {
+	struct upwr_msg_hdr  hdr;
+	uint32_t             ptr; /* config struct offset */
+} upwr_pointer_msg;
+
+/* message format for functions that receive 2 pointers/offsets */
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint64_t rsv : UPWR_HEADER_BITS;
+		uint64_t ptr0 : UPWR_DUAL_OFFSET_BITS;
+		uint64_t ptr1 : UPWR_DUAL_OFFSET_BITS;
+	} ptrs;
+} upwr_2pointer_msg;
+
+#define UPWR_SG_EXCEPT   (0U) /* 0 = exception           */
+#define UPWR_SG_PWRMGMT  (1U) /* 1 = power management    */
+#define UPWR_SG_DELAYM   (2U) /* 2 = delay   measurement */
+#define	UPWR_SG_VOLTM    (3U) /* 3 = voltage measurement */
+#define UPWR_SG_CURRM    (4U) /* 4 = current measurement */
+#define	UPWR_SG_TEMPM    (5U) /* 5 = temperature measurement */
+#define	UPWR_SG_DIAG     (6U) /* 6 = diagnostic  */
+#define	UPWR_SG_COUNT    (7U)
+
+typedef uint32_t upwr_sg_t;
+
+/* *************************************************************************
+ * Initialization - downstream
+ ***************************************************************************/
+typedef upwr_down_1w_msg upwr_start_msg; /* start command message */
+typedef upwr_down_1w_msg upwr_power_on_msg;   /* power on   command message */
+typedef upwr_down_1w_msg upwr_boot_start_msg; /* boot start command message */
+typedef union {
+	struct upwr_msg_hdr hdr;
+	upwr_power_on_msg   power_on;
+	upwr_boot_start_msg boot_start;
+	upwr_start_msg      start;
+} upwr_startup_down_msg;
+
+/* *************************************************************************
+ * Service Group EXCEPTION - downstream
+ ***************************************************************************/
+
+#define	UPWR_XCP_INIT			(0U) /* 0 = init msg (not a service request itself) */
+#define	UPWR_XCP_PING			(0U) /* 0 = also ping request, since its response isan init msg */
+#define	UPWR_XCP_START			(1U) /* 1 = service start: upwr_start *(not a service request itself) */
+#define	UPWR_XCP_SHUTDOWN		(2U) /* 2 = service shutdown: upwr_xcp_shutdown */
+#define	UPWR_XCP_CONFIG			(3U) /* 3 = uPower configuration: upwr_xcp_config */
+#define	UPWR_XCP_SW_ALARM		(4U) /* 4 = uPower software alarm: upwr_xcp_sw_alarm */
+#define	UPWR_XCP_I2C			(5U) /* 5 = I2C access: upwr_xcp_i2c_access */
+#define	UPWR_XCP_SPARE_6		(6U) /* 6 = spare */
+#define	UPWR_XCP_SET_DDR_RETN		(7U) /* 7 = set/clear ddr retention */
+#define UPWR_XCP_SET_RTD_APD_LLWU	(8U) /* 8 = set/clear rtd/apd llwu */
+#define	UPWR_XCP_SPARE_8		(8U) /* 8 = spare */
+#define UPWR_XCP_SET_RTD_USE_DDR	(9U) /* 9 = M33 core set it is using DDR or not */
+#define	UPWR_XCP_SPARE_9		(9U)  /*  9 = spare */
+#define	UPWR_XCP_SPARE_10		(10U) /* 10 = spare */
+#define	UPWR_XCP_SET_MIPI_DSI_ENA	(10U) /* 10 = set/clear mipi dsi ena */
+#define	UPWR_XCP_SPARE_11		(11U) /* 11 = spare */
+#define	UPWR_XCP_GET_MIPI_DSI_ENA	(11U) /* 11 = get mipi dsi ena status */
+#define	UPWR_XCP_SPARE_12		(12U) /* 12 = spare */
+#define	UPWR_XCP_SET_OSC_MODE		(12U) /* 12 = set uPower OSC mode, high or low */
+#define	UPWR_XCP_SPARE_13		(13U) /* 13 = spare */
+#define	UPWR_XCP_SPARE_14		(14U) /* 14 = spare */
+#define	UPWR_XCP_SPARE_15		(15U) /* 15 = spare */
+#define	UPWR_XCP_F_COUNT		(16U)
+
+typedef uint32_t upwr_xcp_f_t;
+typedef upwr_down_1w_msg    upwr_xcp_ping_msg;
+typedef upwr_down_1w_msg    upwr_xcp_shutdown_msg;
+typedef upwr_power_on_msg   upwr_xcp_power_on_msg;
+typedef upwr_boot_start_msg upwr_xcp_boot_start_msg;
+typedef upwr_start_msg      upwr_xcp_start_msg;
+typedef upwr_down_2w_msg    upwr_xcp_config_msg;
+typedef upwr_down_1w_msg    upwr_xcp_swalarm_msg;
+typedef upwr_down_1w_msg    upwr_xcp_ddr_retn_msg;
+typedef upwr_down_1w_msg    upwr_xcp_set_mipi_dsi_ena_msg;
+typedef upwr_down_1w_msg    upwr_xcp_get_mipi_dsi_ena_msg;
+typedef upwr_down_1w_msg    upwr_xcp_rtd_use_ddr_msg;
+typedef upwr_down_1w_msg    upwr_xcp_rtd_apd_llwu_msg;
+typedef upwr_down_1w_msg    upwr_xcp_set_osc_mode_msg;
+typedef upwr_pointer_msg    upwr_xcp_i2c_msg;
+
+ /* structure pointed by message upwr_xcp_i2c_msg */
+typedef struct {
+	uint16_t addr;
+	int8_t data_size;
+	uint8_t subaddr_size;
+	uint32_t subaddr;
+	uint32_t data;
+} upwr_i2c_access;
+
+/* Exception all messages */
+typedef union {
+	struct upwr_msg_hdr       hdr;       /* message header */
+	upwr_xcp_ping_msg         ping;      /* ping */
+	upwr_xcp_start_msg        start;     /* service start */
+	upwr_xcp_shutdown_msg     shutdown;  /* shutdown */
+	upwr_xcp_boot_start_msg   bootstart; /* boot start */
+	upwr_xcp_config_msg       config;    /* uPower configuration */
+	upwr_xcp_swalarm_msg      swalarm;   /* software alarm */
+	upwr_xcp_i2c_msg          i2c;       /* I2C access */
+	upwr_xcp_ddr_retn_msg     set_ddr_retn;       /* set ddr retention msg */
+	upwr_xcp_set_mipi_dsi_ena_msg     set_mipi_dsi_ena; /* set mipi dsi ena msg */
+	upwr_xcp_get_mipi_dsi_ena_msg     get_mipi_dsi_ena; /* get mipi dsi ena msg */
+	upwr_xcp_rtd_use_ddr_msg     set_rtd_use_ddr; /* set rtd is using ddr msg */
+	upwr_xcp_rtd_apd_llwu_msg     set_llwu; /* set rtd/apd llwu msg */
+	upwr_xcp_set_osc_mode_msg     set_osc_mode; /* set osc_mode msg */
+} upwr_xcp_msg;
+
+/* structure pointed by message upwr_volt_dva_req_id_msg */
+typedef struct {
+	uint32_t id_word0;
+	uint32_t id_word1;
+	uint32_t mode;
+} upwr_dva_id_struct;
+
+/**
+ * PMIC voltage accuracy is 12.5 mV, 12500 uV
+ */
+#define PMIC_VOLTAGE_MIN_STEP 12500U
+
+/* *************************************************************************
+ * Service Group POWER MANAGEMENT - downstream
+ ***************************************************************************/
+
+#define	UPWR_PWM_REGCFG    (0U)     /* 0 = regulator config: upwr_pwm_reg_config */
+#define UPWR_PWM_DEVMODE   (0U)     /* deprecated, for old compile */
+#define	UPWR_PWM_VOLT      (1U)     /* 1 = voltage change: upwr_pwm_chng_reg_voltage */
+#define	UPWR_PWM_SWITCH    (2U)     /* 2 = switch control: upwr_pwm_chng_switch_mem */
+#define UPWR_PWM_PWR_ON    (3U)     /* 3 = switch/RAM/ROM power on: upwr_pwm_power_on  */
+#define	UPWR_PWM_PWR_OFF   (4U)     /* 4 = switch/RAM/ROM power off: upwr_pwm_power_off */
+#define	UPWR_PWM_RETAIN    (5U)     /* 5 = retain memory array: upwr_pwm_mem_retain */
+#define UPWR_PWM_DOM_BIAS  (6U)     /* 6 = Domain bias control: upwr_pwm_chng_dom_bias */
+#define	UPWR_PWM_MEM_BIAS  (7U)     /* 7 = Memory bias control: upwr_pwm_chng_mem_bias */
+#define	UPWR_PWM_PMICCFG   (8U)     /* 8 = PMIC configuration:  upwr_pwm_pmic_config */
+#define	UPWR_PWM_PMICMOD   (8U)     /* deprecated, for old compile */
+#define	UPWR_PWM_PES       (9U)     /* 9 so far, no use */
+#define	UPWR_PWM_CONFIG    (10U)    /* 10= apply power mode defined configuration */
+#define	UPWR_PWM_CFGPTR    (11U)    /* 11= configuration pointer */
+#define	UPWR_PWM_DOM_PWRON (12U)    /* 12 = domain power on: upwr_pwm_dom_power_on */
+#define	UPWR_PWM_BOOT      (13U)    /* 13 = boot start: upwr_pwm_boot_start */
+#define UPWR_PWM_FREQ      (14U)    /* 14 = domain frequency setup */
+#define	UPWR_PWM_PARAM     (15U)    /* 15 = power management parameters */
+#define	UPWR_PWM_F_COUNT (16U)
+
+typedef uint32_t upwr_pwm_f_t;
+
+#define MAX_PMETER_SSEL 7U
+
+#define	UPWR_VTM_CHNG_PMIC_RAIL_VOLT    (0U)      /* 0 = change pmic rail voltage */
+#define	UPWR_VTM_GET_PMIC_RAIL_VOLT     (1U)      /* 1 = get pmic rail voltage */
+#define UPWR_VTM_PMIC_CONFIG            (2U)      /* 2 = configure PMIC IC */
+#define UPWR_VTM_DVA_DUMP_INFO          (3U)      /* 3 = dump dva information */
+#define UPWR_VTM_DVA_REQ_ID             (4U)      /* 4 = dva request ID array */
+#define UPWR_VTM_DVA_REQ_DOMAIN         (5U)      /* 5 = dva request domain */
+#define UPWR_VTM_DVA_REQ_SOC            (6U)      /* 6 = dva request the whole SOC */
+#define UPWR_VTM_PMETER_MEAS            (7U)      /* 7 = pmeter measure */
+#define UPWR_VTM_VMETER_MEAS            (8U)      /* 8 = vmeter measure */
+#define UPWR_VTM_PMIC_COLD_RESET        (9U)      /* 9 = pmic cold reset */
+#define UPWR_VTM_SET_DVFS_PMIC_RAIL     (10U)     /* 10 = set which domain use which pmic rail, for DVFS use */
+#define UPWR_VTM_SET_PMIC_MODE          (11U)     /* 11 = set pmic mode */
+#define UPWR_VTM_F_COUNT                (16U)
+
+typedef uint32_t upwr_volt_f_t;
+
+#define VMETER_SEL_RTD 0U
+#define VMETER_SEL_LDO 1U
+#define VMETER_SEL_APD 2U
+#define VMETER_SEL_AVD 3U
+#define VMETER_SEL_MAX 3U
+
+/**
+ * The total TSEL count is 256
+ */
+#define MAX_TEMP_TSEL 256U
+
+/**
+ * Support 3 temperature sensor, sensor 0, 1, 2
+ */
+#define MAX_TEMP_SENSOR 2U
+
+#define UPWR_TEMP_GET_CUR_TEMP (0U)  /* 0 = get current temperature */
+#define UPWR_TEMP_F_COUNT      (1U)
+typedef uint32_t upwr_temp_f_t;
+
+#define UPWR_DMETER_GET_DELAY_MARGIN (0U)  /* 0 = get delay margin */
+#define UPWR_DMETER_SET_DELAY_MARGIN (1U) /* 1 = set delay margin */
+#define UPWR_PMON_REQ                (2U) /* 2 = process monitor service */
+#define UPWR_DMETER_F_COUNT          (3U)
+
+typedef uint32_t upwr_dmeter_f_t;
+
+typedef upwr_down_1w_msg upwr_volt_pmeter_meas_msg;
+typedef upwr_down_1w_msg upwr_volt_pmic_set_mode_msg;
+typedef upwr_down_1w_msg upwr_volt_vmeter_meas_msg;
+
+struct upwr_reg_config_t {
+	uint32_t reg;
+};
+
+ /* set of 32 switches */
+struct upwr_switch_board_t {
+	uint32_t on;   /* Switch on state,1 bit per instance */
+	uint32_t mask; /* actuation mask, 1 bit per instance */
+};
+
+ /* set of 32 RAM/ROM switches */
+struct upwr_mem_switches_t {
+	uint32_t array;   /* RAM/ROM array state, 1 bit per instance */
+	uint32_t perif;   /* RAM/ROM peripheral state, 1 bit per instance */
+	uint32_t mask;    /* actuation mask, 1 bit per instance */
+};
+
+typedef upwr_down_1w_msg upwr_pwm_dom_pwron_msg;  /* domain power on message */
+typedef upwr_down_1w_msg upwr_pwm_boot_start_msg; /* boot start message */
+
+/* functions with complex arguments use the pointer message formats: */
+typedef upwr_pointer_msg upwr_pwm_retain_msg;
+typedef upwr_pointer_msg upwr_pwm_pmode_cfg_msg;
+
+#if (UPWR_ARG_BITS < UPWR_DOMBIAS_ARG_BITS)
+#if ((UPWR_ARG_BITS + 32) < UPWR_DOMBIAS_ARG_BITS)
+#error "too few message bits for domain bias argument"
+#endif
+#endif
+
+/* service upwr_pwm_chng_dom_bias message argument fields */
+#define UPWR_DOMBIAS_MODE_BITS    (2U)
+#define UPWR_DOMBIAS_RBB_BITS     (8U)
+#define UPWR_DOMBIAS_RSV_BITS     (14U)
+#define UPWR_DOMBIAS_ARG_BITS     (UPWR_DOMBIAS_RSV_BITS + \
+				  (2U * UPWR_DOMBIAS_MODE_BITS) + \
+				  (4U * UPWR_DOMBIAS_RBB_BITS) + 2U)
+/*
+ * upwr_pwm_dom_bias_args is an SoC-dependent message,
+ */
+typedef struct {
+	uint32_t: 12U; /* TODO: find a way to use UPWR_HEADER_BITS */
+	uint32_t dommode : UPWR_DOMBIAS_MODE_BITS;
+	uint32_t avdmode : UPWR_DOMBIAS_MODE_BITS;
+	uint32_t domapply : 1U;
+	uint32_t avdapply : 1U;
+	uint32_t rsv : UPWR_DOMBIAS_RSV_BITS;
+	uint32_t domrbbn : UPWR_DOMBIAS_RBB_BITS; /* RTD/APD back bias N-well */
+	uint32_t domrbbp : UPWR_DOMBIAS_RBB_BITS; /* RTD/APD back bias P-well */
+	uint32_t avdrbbn : UPWR_DOMBIAS_RBB_BITS; /* AVD back bias N-well */
+	uint32_t avdrbbp : UPWR_DOMBIAS_RBB_BITS; /* AVD back bias P-well */
+} upwr_pwm_dom_bias_args;
+
+
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	struct {
+		upwr_pwm_dom_bias_args B;
+	} args;
+} upwr_pwm_dom_bias_msg;
+
+/* service upwr_pwm_chng_mem_bias message argument fields */
+/*
+ * upwr_pwm_mem_bias_args is an SoC-dependent message,
+ * defined in upower_soc_defs.h
+ */
+typedef struct {
+	uint32_t: 12U; /* TODO: find a way to use UPWR_HEADER_BITS */
+	uint32_t en : 1U;
+	uint32_t rsv : 19U;
+} upwr_pwm_mem_bias_args;
+
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	struct {
+		upwr_pwm_mem_bias_args B;
+	} args;
+} upwr_pwm_mem_bias_msg;
+
+typedef upwr_pointer_msg upwr_pwm_pes_seq_msg;
+
+/* upwr_pwm_reg_config-specific message format */
+typedef upwr_pointer_msg upwr_pwm_regcfg_msg;
+
+/* upwr_volt_pmic_volt-specific message format */
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t domain : 8U;
+		uint32_t rail : 8U;
+	} args;
+} upwr_volt_dom_pmic_rail_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t rail : 4U;  /* pmic rail id  */
+		uint32_t volt : 12U; /* voltage value, accurate to mV, support 0~3.3V */
+	} args;
+} upwr_volt_pmic_set_volt_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t rail : 16U;  /* pmic rail id  */
+	} args;
+} upwr_volt_pmic_get_volt_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv :UPWR_HEADER_BITS;
+		uint32_t domain : 8U;
+		uint32_t mode : 8U; /* work mode */
+	} args;
+} upwr_volt_dva_req_domain_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t mode : 16U;  /* work mode  */
+	} args;
+} upwr_volt_dva_req_soc_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t addr_offset : 16U;  /* addr_offset to 0x28330000  */
+	} args;
+} upwr_volt_dva_dump_info_msg;
+
+typedef upwr_pointer_msg upwr_volt_pmiccfg_msg;
+typedef upwr_pointer_msg upwr_volt_dva_req_id_msg;
+typedef upwr_down_1w_msg upwr_volt_pmic_cold_reset_msg;
+
+/* upwr_pwm_volt-specific message format */
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t reg : UPWR_HALF_ARG_BITS;  /* regulator id  */
+		uint32_t volt : UPWR_HALF_ARG_BITS; /* voltage value */
+	} args;
+} upwr_pwm_volt_msg;
+
+/* upwr_pwm_freq_setup-specific message format */
+/**
+ * DVA adjust stage
+ */
+#define DVA_ADJUST_STAGE_INVALID 0U
+/* first stage, gross adjust, for increase frequency use */
+#define DVA_ADJUST_STAGE_ONE 1U
+/* second stage, fine adjust for increase frequency use */
+#define DVA_ADJUST_STAGE_TWO 2U
+/* combine first + second stage, for descrese frequency use */
+#define DVA_ADJUST_STAGE_FULL 3U
+
+/**
+ * This message structure is used for DVFS feature
+ * 1. Because user may use different PMIC or different board,
+ * the pmic regulator of RTD/APD may change,
+ * so, user need to tell uPower the regulator number.
+ * The number must be matched with PMIC IC and board.
+ * use 4 bits for pmic regulator, support to 16 regulator.
+ *
+ * use 2 bits for DVA stage
+ *
+ * use 10 bits for target frequency, accurate to MHz, support to 1024 MHz
+ */
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t rail : 4; /* pmic regulator  */
+		uint32_t stage : 2; /* DVA stage */
+		uint32_t target_freq : 10; /* target frequency */
+	} args;
+} upwr_pwm_freq_msg;
+
+typedef upwr_down_2w_msg upwr_pwm_param_msg;
+
+/* upwr_pwm_pmiccfg-specific message format */
+typedef upwr_pointer_msg upwr_pwm_pmiccfg_msg;
+
+/* functions that pass a pointer use message format upwr_pointer_msg */
+typedef upwr_pointer_msg upwr_pwm_cfgptr_msg;
+
+/* functions that pass 2 pointers use message format upwr_2pointer_msg
+ */
+typedef upwr_2pointer_msg upwr_pwm_switch_msg;
+typedef upwr_2pointer_msg upwr_pwm_pwron_msg;
+typedef upwr_2pointer_msg upwr_pwm_pwroff_msg;
+
+/* Power Management all messages */
+typedef union {
+	struct upwr_msg_hdr     hdr;      /* message header */
+	upwr_pwm_param_msg      param;    /* power management parameters */
+	upwr_pwm_dom_bias_msg   dom_bias; /* domain bias message */
+	upwr_pwm_mem_bias_msg   mem_bias; /* memory bias message */
+	upwr_pwm_pes_seq_msg    pes;      /* PE seq. message */
+	upwr_pwm_pmode_cfg_msg  pmode;    /* power mode config message */
+	upwr_pwm_regcfg_msg     regcfg;   /* regulator config message */
+	upwr_pwm_volt_msg       volt;     /* set voltage message */
+	upwr_pwm_freq_msg       freq;     /* set frequency message */
+	upwr_pwm_switch_msg     switches; /* switch control message */
+	upwr_pwm_pwron_msg      pwron;    /* switch/RAM/ROM power on  message */
+	upwr_pwm_pwroff_msg     pwroff;   /* switch/RAM/ROM power off message */
+	upwr_pwm_retain_msg     retain;   /* memory retain message */
+	upwr_pwm_cfgptr_msg     cfgptr;   /* configuration pointer message*/
+	upwr_pwm_dom_pwron_msg  dompwron; /* domain power on message */
+	upwr_pwm_boot_start_msg boot;     /* boot start      message */
+} upwr_pwm_msg;
+
+typedef union {
+	struct upwr_msg_hdr     hdr;      /* message header */
+	upwr_volt_pmic_set_volt_msg  set_pmic_volt;     /* set pmic voltage message */
+	upwr_volt_pmic_get_volt_msg  get_pmic_volt;     /* set pmic voltage message */
+	upwr_volt_pmic_set_mode_msg  set_pmic_mode;     /* set pmic mode message */
+	upwr_volt_pmiccfg_msg    pmiccfg;  /* PMIC configuration message */
+	upwr_volt_dom_pmic_rail_msg   dom_pmic_rail; /* domain bias message */
+	upwr_volt_dva_dump_info_msg    dva_dump_info;  /* dump dva info message */
+	upwr_volt_dva_req_id_msg    dva_req_id;  /* dump dva request id array message */
+	upwr_volt_dva_req_domain_msg    dva_req_domain;  /* dump dva request domain message */
+	upwr_volt_dva_req_soc_msg    dva_req_soc;  /* dump dva request whole soc message */
+	upwr_volt_pmeter_meas_msg    pmeter_meas_msg;  /* pmeter measure message */
+	upwr_volt_vmeter_meas_msg    vmeter_meas_msg;  /* vmeter measure message */
+	upwr_volt_pmic_cold_reset_msg    cold_reset_msg;  /* pmic cold reset message */
+} upwr_volt_msg;
+
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t sensor_id : 16U; /* temperature sensor id  */
+	} args;
+} upwr_temp_get_cur_temp_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t index : 8U; /* the delay meter index  */
+		uint32_t path : 8U; /* the critical path number  */
+	} args;
+} upwr_dmeter_get_delay_margin_msg;
+
+#define MAX_DELAY_MARGIN 63U
+#define MAX_DELAY_CRITICAL_PATH 7U
+#define MAX_DELAY_METER_NUM 1U
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t index: 4U;  /* the delay meter index  */
+		uint32_t path: 4U;  /* the critical path number  */
+		uint32_t dm: 8U;  /* the delay margin value of delay meter  */
+	} args;
+} upwr_dmeter_set_delay_margin_msg;
+
+#define MAX_PMON_CHAIN_SEL 1U
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_HEADER_BITS;
+		uint32_t chain_sel : 16U;  /* the process monitor delay chain sel  */
+	} args;
+} upwr_pmon_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	upwr_temp_get_cur_temp_msg get_temp_msg; /* get current temperature message */
+} upwr_temp_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr; /* message header */
+	upwr_dmeter_get_delay_margin_msg  get_margin_msg; /* get delay margin message */
+	upwr_dmeter_set_delay_margin_msg  set_margin_msg; /* set delay margin message */
+	upwr_pmon_msg pmon_msg; /* process monitor message */
+} upwr_dmeter_msg;
+
+typedef upwr_down_2w_msg upwr_down_max_msg; /* longest downstream msg */
+
+/*
+ * upwr_dom_bias_cfg_t and upwr_mem_bias_cfg_t are SoC-dependent structs,
+ * defined in upower_soc_defs.h
+ */
+/* Power and mem switches */
+typedef struct {
+	volatile struct upwr_switch_board_t swt_board[UPWR_PMC_SWT_WORDS];
+	volatile struct upwr_mem_switches_t swt_mem[UPWR_PMC_MEM_WORDS];
+} swt_config_t;
+
+/* *************************************************************************
+ * Service Group DIAGNOSE - downstream
+ ***************************************************************************/
+/* Diagnose Functions */
+#define	UPWR_DGN_MODE              (0U) /* 0 = diagnose mode: upwr_dgn_mode */
+#define	UPWR_DGN_F_COUNT           (1U)
+#define UPWR_DGN_BUFFER_EN         (2U)
+typedef uint32_t upwr_dgn_f_t;
+
+#define UPWR_DGN_ALL2ERR            (0U) /* record all until an error occurs, freeze recording on error */
+#define UPWR_DGN_ALL2HLT            (1U) /* record all until an error occurs, halt core on error */
+#define UPWR_DGN_ALL                (2U) /* trace, warnings, errors, task state recorded */
+#define UPWR_DGN_MAX                UPWR_DGN_ALL
+#define UPWR_DGN_TRACE              (3U) /* trace, warnings, errors recorded */
+#define UPWR_DGN_SRVREQ             (4U) /* service request activity recorded */
+#define UPWR_DGN_WARN               (5U) /* warnings and errors recorded */
+#define UPWR_DGN_ERROR              (6U) /* only errors recorded */
+#define UPWR_DGN_NONE               (7U) /* no diagnostic recorded */
+#define UPWR_DGN_COUNT              (8U)
+typedef uint32_t upwr_dgn_mode_t;
+
+typedef upwr_down_1w_msg upwr_dgn_mode_msg;
+
+typedef union {
+	struct upwr_msg_hdr hdr;
+	upwr_dgn_mode_msg mode_msg;
+} upwr_dgn_msg;
+
+typedef struct {
+	struct upwr_msg_hdr hdr;
+	uint32_t buf_addr;
+} upwr_dgn_v2_msg;
+
+/* diagnostics log types in the shared RAM log buffer */
+
+typedef enum {
+	DGN_LOG_NONE       = 0x00000000,
+	DGN_LOG_INFO       = 0x10000000,
+	DGN_LOG_ERROR      = 0x20000000,
+	DGN_LOG_ASSERT     = 0x30000000,
+	DGN_LOG_EXCEPT     = 0x40000000,
+	DGN_LOG_EVENT      = 0x50000000, // old event trace
+	DGN_LOG_EVENTNEW   = 0x60000000, // new event trace
+	DGN_LOG_SERVICE    = 0x70000000,
+	DGN_LOG_TASKDEF    = 0x80000000,
+	DGN_LOG_TASKEXE    = 0x90000000,
+	DGN_LOG_MUTEX      = 0xA0000000,
+	DGN_LOG_SEMAPH     = 0xB0000000,
+	DGN_LOG_TIMER      = 0xC0000000,
+	DGN_LOG_CALLTRACE  = 0xD0000000,
+	DGN_LOG_DATA       = 0xE0000000,
+	DGN_LOG_PCTRACE    = 0xF0000000
+} upwr_dgn_log_t;
+
+/* ****************************************************************************
+ * UPSTREAM MESSAGES - RESPONSES
+ * ****************************************************************************
+ */
+/* generic ok/ko response message */
+#define UPWR_RESP_ERR_BITS (4U)
+#define UPWR_RESP_HDR_BITS (UPWR_RESP_ERR_BITS+\
+			    UPWR_SRVGROUP_BITS+UPWR_FUNCTION_BITS)
+#define UPWR_RESP_RET_BITS (32U - UPWR_RESP_HDR_BITS)
+
+#define UPWR_RESP_OK                (0U) /* no error */
+#define UPWR_RESP_SG_BUSY           (1U) /* service group is busy */
+#define UPWR_RESP_SHUTDOWN          (2U) /* services not up or shutting down */
+#define UPWR_RESP_BAD_REQ           (3U) /* invalid request */
+#define UPWR_RESP_BAD_STATE         (4U) /* system state doesn't allow perform the request */
+#define UPWR_RESP_UNINSTALLD        (5U) /* service or function not installed */
+#define UPWR_RESP_UNINSTALLED       (5U) /* service or function not installed (alias) */
+#define UPWR_RESP_RESOURCE          (6U) /* resource not available */
+#define UPWR_RESP_TIMEOUT           (7U) /* service timeout */
+#define UPWR_RESP_COUNT             (8U)
+
+typedef uint32_t upwr_resp_t;
+
+struct upwr_resp_hdr {
+	uint32_t errcode : UPWR_RESP_ERR_BITS;
+	uint32_t srvgrp  : UPWR_SRVGROUP_BITS;      /* service group */
+	uint32_t function: UPWR_FUNCTION_BITS;
+	uint32_t ret     : UPWR_RESP_RET_BITS;      /* return value, if any */
+};
+
+/* generic 1-word upstream message format */
+typedef union {
+	struct upwr_resp_hdr hdr;
+	uint32_t word;
+} upwr_resp_msg;
+
+/* generic 2-word upstream message format */
+typedef struct {
+	struct upwr_resp_hdr hdr;
+	uint32_t word2;  /* message second word */
+} upwr_up_2w_msg;
+
+typedef upwr_up_2w_msg upwr_up_max_msg;
+
+/* *************************************************************************
+ * Exception/Initialization - upstream
+ ***************************************************************************/
+#define UPWR_SOC_BITS    (7U)
+#define UPWR_VMINOR_BITS (4U)
+#define UPWR_VFIXES_BITS (4U)
+#define UPWR_VMAJOR_BITS \
+		(32U - UPWR_HEADER_BITS - UPWR_SOC_BITS - UPWR_VMINOR_BITS - UPWR_VFIXES_BITS)
+
+typedef struct {
+	uint32_t soc_id;
+	uint32_t vmajor;
+	uint32_t vminor;
+	uint32_t vfixes;
+} upwr_code_vers_t;
+
+/* message sent by firmware initialization, received by upwr_init */
+typedef union {
+	struct upwr_resp_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_RESP_HDR_BITS;
+		uint32_t soc : UPWR_SOC_BITS;        /* SoC identification */
+		uint32_t vmajor : UPWR_VMAJOR_BITS;  /* firmware major version */
+		uint32_t vminor : UPWR_VMINOR_BITS;  /* firmware minor version */
+		uint32_t vfixes : UPWR_VFIXES_BITS;  /* firmware fixes version */
+	} args;
+} upwr_init_msg;
+
+/* message sent by firmware when the core platform is powered up */
+typedef upwr_resp_msg upwr_power_up_msg;
+
+/* message sent by firmware when the core reset is released for boot */
+typedef upwr_resp_msg upwr_boot_up_msg;
+
+/* message sent by firmware when ready for service requests */
+#define UPWR_RAM_VMINOR_BITS (7)
+#define UPWR_RAM_VFIXES_BITS (6)
+#define UPWR_RAM_VMAJOR_BITS (32 - UPWR_HEADER_BITS \
+		- UPWR_RAM_VFIXES_BITS - UPWR_RAM_VMINOR_BITS)
+typedef union {
+	struct upwr_resp_hdr hdr;
+	struct {
+		uint32_t rsv : UPWR_RESP_HDR_BITS;
+		uint32_t vmajor : UPWR_RAM_VMAJOR_BITS; /* RAM fw major version */
+		uint32_t vminor : UPWR_RAM_VMINOR_BITS; /* RAM fw minor version */
+		uint32_t vfixes : UPWR_RAM_VFIXES_BITS; /* RAM fw fixes version */
+	} args;
+} upwr_ready_msg;
+
+/* message sent by firmware when shutdown finishes */
+typedef upwr_resp_msg upwr_shutdown_msg;
+
+typedef union {
+	struct upwr_resp_hdr hdr;
+	upwr_init_msg        init;
+	upwr_power_up_msg    pwrup;
+	upwr_boot_up_msg     booted;
+	upwr_ready_msg       ready;
+} upwr_startup_up_msg;
+
+/* message sent by firmware for uPower config setting */
+typedef upwr_resp_msg upwr_config_resp_msg;
+
+/* message sent by firmware for uPower alarm */
+typedef upwr_resp_msg upwr_alarm_resp_msg;
+
+/* *************************************************************************
+ * Power Management - upstream
+ ***************************************************************************/
+typedef upwr_resp_msg upwr_param_resp_msg;
+
+enum work_mode {
+	OVER_DRIVE,
+	NORMAL_DRIVE,
+	LOW_DRIVE
+};
+
+#define UTIMER3_MAX_COUNT 0xFFFFU
+
+#endif /* UPWR_DEFS_H */
diff --git a/plat/imx/imx8ulp/upower/upower_hal.c b/plat/imx/imx8ulp/upower/upower_hal.c
new file mode 100644
index 00000000..337857b7
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_hal.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2020-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "upower_api.h"
+#include "upower_defs.h"
+
+#define UPOWER_AP_MU1_ADDR	U(0x29280000)
+
+struct MU_t *muptr = (struct MU_t *)UPOWER_AP_MU1_ADDR;
+
+void upower_apd_inst_isr(upwr_isr_callb txrx_isr,
+			 upwr_isr_callb excp_isr)
+{
+	/* Do nothing */
+}
+
+int upower_status(int status)
+{
+	int ret = -1;
+
+	switch (status) {
+	case 0:
+		VERBOSE("finished successfully!\n");
+		ret = 0;
+		break;
+	case -1:
+		VERBOSE("memory allocation or resource failed!\n");
+		break;
+	case -2:
+		VERBOSE("invalid argument!\n");
+		break;
+	case -3:
+		VERBOSE("called in an invalid API state!\n");
+		break;
+	default:
+		VERBOSE("invalid return status\n");
+		break;
+	}
+
+	return ret;
+}
+
+
+void upower_wait_resp(void)
+{
+	while (muptr->RSR.B.RF0 == 0) {
+		udelay(100);
+	}
+	upwr_txrx_isr();
+}
+
+static void user_upwr_rdy_callb(uint32_t soc, uint32_t vmajor, uint32_t vminor)
+{
+	NOTICE("%s: soc=%x\n", __func__, soc);
+	NOTICE("%s: RAM version:%d.%d\n", __func__, vmajor, vminor);
+}
+
+int upower_init(void)
+{
+	int status;
+
+	status = upwr_init(APD_DOMAIN, muptr, NULL, NULL, upower_apd_inst_isr, NULL);
+	if (upower_status(status)) {
+		ERROR("%s: upower init failure\n", __func__);
+		return -EINVAL;
+	}
+
+	NOTICE("%s: start uPower RAM service\n", __func__);
+	status = upwr_start(1, user_upwr_rdy_callb);
+	upower_wait_resp();
+	/* poll status */
+	if (upower_status(status)) {
+		NOTICE("%s: upower init failure\n", __func__);
+		return status;
+	}
+
+	return 0;
+}
+
+int upower_pwm(int domain_id, bool pwr_on)
+{
+	int ret, ret_val;
+	uint32_t swt;
+
+	if (domain_id == 9U || domain_id == 11U || domain_id == 12U) {
+		swt = BIT_32(12) | BIT_32(11) | BIT_32(10) | BIT_32(9);
+	} else {
+		swt = BIT_32(domain_id);
+	}
+
+	if (pwr_on) {
+		ret = upwr_pwm_power_on(&swt, NULL, NULL);
+	} else {
+		ret = upwr_pwm_power_off(&swt, NULL, NULL);
+	}
+
+	if (ret) {
+		NOTICE("%s failed: ret: %d, pwr_on: %d\n", __func__, ret, pwr_on);
+		return ret;
+	}
+	upower_wait_resp();
+
+	ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
+	if (ret != UPWR_REQ_OK) {
+		NOTICE("Failure %d, %s\n", ret, __func__);
+		if (ret == UPWR_REQ_BUSY) {
+			return -EBUSY;
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int upower_read_temperature(uint32_t sensor_id, int32_t *temperature)
+{
+	int ret, ret_val;
+	upwr_resp_t err_code;
+	int64_t t;
+
+	ret = upwr_tpm_get_temperature(sensor_id, NULL);
+	if (ret) {
+		return ret;
+	}
+
+	upower_wait_resp();
+	ret = upwr_poll_req_status(UPWR_SG_TEMPM, NULL, &err_code, &ret_val, 1000);
+	if (ret > UPWR_REQ_OK) {
+		return ret;
+	}
+
+	t = ret_val & 0xff;
+	*temperature = (2673049 * t * t * t / 10000000 + 3734262 * t * t / 100000 +
+			4487042 * t / 100 - 4698694) / 100000;
+
+	return 0;
+}
+
+int upower_pmic_i2c_write(uint32_t reg_addr, uint32_t reg_val)
+{
+	int ret, ret_val;
+	upwr_resp_t err_code;
+
+	ret = upwr_xcp_i2c_access(0x32, 1, 1, reg_addr, reg_val, NULL);
+	if (ret) {
+		WARN("pmic i2c read failed ret %d\n", ret);
+		return ret;
+	}
+
+	upower_wait_resp();
+	ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, &err_code, &ret_val, 1000);
+	if (ret != UPWR_REQ_OK) {
+		WARN("i2c poll Failure %d, err_code %d, ret_val 0x%x\n",
+		     ret, err_code, ret_val);
+		return ret;
+	}
+
+	VERBOSE("PMIC write reg[0x%x], val[0x%x]\n", reg_addr, reg_val);
+
+	return 0;
+}
+
+int upower_pmic_i2c_read(uint32_t reg_addr, uint32_t *reg_val)
+{
+	int ret, ret_val;
+	upwr_resp_t err_code;
+
+	if (reg_val == NULL) {
+		return -1;
+	}
+
+	ret = upwr_xcp_i2c_access(0x32, -1, 1, reg_addr, 0, NULL);
+	if (ret) {
+		WARN("pmic i2c read failed ret %d\n", ret);
+		return ret;
+	}
+
+	upower_wait_resp();
+	ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, &err_code, &ret_val, 1000);
+	if (ret != UPWR_REQ_OK) {
+		WARN("i2c poll Failure %d, err_code %d, ret_val 0x%x\n",
+			ret, err_code, ret_val);
+		return ret;
+	}
+
+	*reg_val = ret_val;
+
+	VERBOSE("PMIC read reg[0x%x], val[0x%x]\n", reg_addr, *reg_val);
+
+	return 0;
+}
diff --git a/plat/imx/imx8ulp/upower/upower_soc_defs.h b/plat/imx/imx8ulp/upower/upower_soc_defs.h
new file mode 100644
index 00000000..111be148
--- /dev/null
+++ b/plat/imx/imx8ulp/upower/upower_soc_defs.h
@@ -0,0 +1,1154 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
+ * Copyright 2019-2024 NXP
+ *
+ * KEYWORDS: micro-power uPower driver API
+ * -----------------------------------------------------------------------------
+ * PURPOSE: SoC-dependent uPower driver API #defines and typedefs shared
+ *          with the firmware
+ * -----------------------------------------------------------------------------
+ * PARAMETERS:
+ * PARAM NAME RANGE:DESCRIPTION:       DEFAULTS:                           UNITS
+ * -----------------------------------------------------------------------------
+ * REUSE ISSUES: no reuse issues
+ */
+
+#ifndef UPWR_SOC_DEFS_H
+#define UPWR_SOC_DEFS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "upower_defs.h"
+
+#define UPWR_MU_MSG_SIZE            (2U) /* words */
+
+#ifdef NUM_PMC_SWT_WORDS
+#define UPWR_PMC_SWT_WORDS          NUM_PMC_SWT_WORDS
+#endif
+
+#ifdef NUM_PMC_RAM_WORDS
+#define UPWR_PMC_MEM_WORDS          NUM_PMC_RAM_WORDS
+#endif
+
+#ifndef UPWR_DRAM_SHARED_BASE_ADDR
+#define UPWR_DRAM_SHARED_BASE_ADDR      (0x28330000U)
+#endif
+
+#ifndef UPWR_DRAM_SHARED_SIZE
+#define UPWR_DRAM_SHARED_SIZE           (2048U)
+#endif
+
+#define UPWR_DRAM_SHARED_ENDPLUS        (UPWR_DRAM_SHARED_BASE_ADDR+\
+					 UPWR_DRAM_SHARED_SIZE)
+
+#ifndef UPWR_API_BUFFER_BASE
+#define UPWR_API_BUFFER_BASE            (0x28330600U)
+#endif
+
+#ifndef UPWR_API_BUFFER_ENDPLUS
+#define UPWR_API_BUFFER_ENDPLUS         (UPWR_DRAM_SHARED_ENDPLUS - 64U)
+#endif
+
+#ifndef UPWR_PMC_SWT_WORDS
+#define UPWR_PMC_SWT_WORDS              (1U)
+#endif
+
+#ifndef UPWR_PMC_MEM_WORDS
+#define UPWR_PMC_MEM_WORDS              (2U)
+#endif
+
+#define UPWR_OSC_HI_FREQ               (64U) // MHz
+#define UPWR_OSC_LO_FREQ               (16U) // MHz
+
+#ifndef UPWR_I2C_FREQ
+#define UPWR_I2C_FREQ                  (UPWR_OSC_HI_FREQ * 1000000U)
+#endif
+
+/*
+ * i.MX8ULP-dependent uPower API Definition
+ *
+ * This chapter documents the API definitions that are specific to the
+ * i.MX8ULP SoC.
+ *
+ */
+
+/**---------------------------------------------------------------
+ * INITIALIZATION, CONFIGURATION
+ *
+ * i.MX8ULP provides only one Message Unit (MU) for each core domain:
+ * Real Time Domain (RTD) and Application Domain (APD), which has two A35 cores.
+ * Both A35 cores in APD must share the same API instance, meaning upwr_init
+ * must be called only once for each domain. The API does not provide any
+ * mutually exclusion or locking mechanism for concurrent accesses from both
+ * APD cores, so any API arbitration, if needed, must be implemented by the
+ * API user code.
+ *
+ * A domain must not go to Power Down (PD) or Deep Power Down (DPD) power modes
+ * with any service still pending (response not received).
+ *
+ * Next sections describe the i.MX8ULP particularities of service calls.
+ *
+ */
+
+/**+
+ * upwr_start()
+ *
+ * i.MX8ULP ROM firmware provides only the launch option 0, which has no
+ * power mode transition support and provides the following services:
+ * - upwr_xcp_config
+ * - upwr_xcp_sw_alarm
+ * - upwr_pwm_param
+ * - upwr_pwm_power_on
+ * - upwr_pwm_power-off
+ * - upwr_pwm_mem_retain
+ * - upwr_pwm_chng_dom_bias
+ * - upwr_pwm_chng_mem_bias
+ *
+ * i.MX8ULP RAM firmware provides 2 launch options:
+ *
+ * 1. starts all tasks, services and power mode ones;
+ *    this is the full-featured firmware option.
+ * 2. starts only the power mode tasks; services are not available with
+ *    this option, and futher calls to upwr_start (from either domain)
+ *    have no response; this option is mostly used to accelerate power mode
+ *    mixed-signal simulations, and not intended to be used with silicon.
+ *
+ * Note: option 0 is also available if the RAM firmware is loaded.
+ */
+
+/* service upwr_pwm_set_domain_pmic_rail message argument fields*/
+typedef struct {
+	uint32_t domain : 16U;
+	uint32_t rail : 16U;
+} upwr_pwm_dom_pmic_rail_args;
+
+#define UPWR_FILL_DOMBIAS_ARGS(dom, bias, args)           \
+do {                                                      \
+	(args).B.domapply = (args).B.avdapply = 0U;            \
+	switch ((bias)->apply) {                            \
+	case BIAS_APPLY_RTD_AVD:                  \
+		(args).B.avdapply = 1U;              \
+	/* fall through */                        \
+	case BIAS_APPLY_RTD:                      \
+		(dom) = (uint32_t)RTD_DOMAIN;       \
+		(args).B.domapply = 1U;              \
+		break;                            \
+	case BIAS_APPLY_APD_AVD:                  \
+		(args).B.avdapply = 1U;              \
+	/* fall through */                      \
+	case BIAS_APPLY_APD:                      \
+		(dom) = (uint32_t)APD_DOMAIN;       \
+		(args).B.domapply = 1U;              \
+		break;                            \
+	case BIAS_APPLY_AVD:                      \
+		(args).B.avdapply = 1U;              \
+		break;                            \
+	default:                              \
+		break;                            \
+	}                                                 \
+	(args).B.dommode = (uint32_t)((bias)->dommode);         \
+	(args).B.avdmode = (uint32_t)((bias)->avdmode);         \
+	uint32_t sat = UPWR_BIAS2MILIV((1UL << UPWR_DOMBIAS_RBB_BITS) - 1UL);\
+	(args).B.domrbbn = ((bias)->dombias.rbbn > sat) ? sat : \
+			   UPWR_BIAS_MILIV((bias)->dombias.rbbn); \
+	(args).B.domrbbp = ((bias)->dombias.rbbp > sat) ? sat : \
+			   UPWR_BIAS_MILIV((bias)->dombias.rbbp); \
+	(args).B.avdrbbn = ((bias)->avdbias.rbbn > sat) ? sat : \
+			   UPWR_BIAS_MILIV((bias)->avdbias.rbbn); \
+	(args).B.avdrbbp = ((bias)->avdbias.rbbp > sat) ? sat : \
+			   UPWR_BIAS_MILIV((bias)->avdbias.rbbp); \
+} while (false)
+
+#define UPWR_FILL_MEMBIAS_ARGS(bias, args)		\
+do {							\
+	(args).B.en = (bias)->en;			\
+} while (false)
+
+
+#define UPWR_APD_CORES      (2U)
+#define UPWR_RTD_CORES      (1U)
+
+#define RTD_DOMAIN (0U)
+#define APD_DOMAIN (1U)
+#define UPWR_MAIN_DOMAINS (2U)
+#define AVD_DOMAIN (2U)
+#define UPWR_DOMAIN_COUNT (3U)
+#define PSD_DOMAIN (3U)
+#define UPWR_ALL_DOMAINS (4U)
+
+typedef uint32_t soc_domain_t;
+
+/*=========================================================================
+ * UNIT CONVERSION MACROS
+ *   These macros convert physical units to the values passed as arguments
+ *   in API functions.
+ *=========================================================================
+ */
+
+#define UPWR_VOLT_MILIV(v) (v)        /* voltage in mV    to argument value */
+#define UPWR_VOLT_MICROV(v)((v) / 1000U) /* voltage in uV    to argument value */
+#define UPWR_BIAS_MILIV(v) (((v) + 49UL) / 50UL)   /* bias voltage(mV) to argument value */
+#define UPWR_BIAS2MILIV(v) ((v) * 50UL)   /* inverse of UPWR_BIAS_MILIV         */
+#define UPWR_FREQ_KHZ(f)   (f)        /* frequency (kHz)  to argument value */
+
+#define UPWR_DOMBIAS_MAX_MV      (UPWR_BIAS2MILIV((1U << UPWR_DOMBIAS_RBB_BITS) - 1U))
+
+/**---------------------------------------------------------------
+ * EXCEPTION SERVICE GROUP
+ */
+
+/**+
+ * upwr_xcp_config()
+ *
+ * The i.MX8ULP uPower configuration struct contains the following bitfields:
+ *
+ *  - ALARM_INT (1 bit): tells which RTD MU interrupt should be used for alarms;
+ *    1= MU GPI1; 0= MU GPI0; APD alarms always use GPI0.
+ *  - CFG_IOMUX (1 bit): determintes if uPower configures i.MX8ULP IOMUX for
+ *    I2C and mode pins used to control an external PMIC;
+ *    1= uPower firmware or PMIC driver configures i.MX8ULP IOMUX and mode pins;
+ *    0= i.MX8ULP IOMUX and mode pins not configured by uPower;
+ *  - DGNBUFBITS (4 bits): determines the diagnostic buffer size according to
+ *    the formula: size = 2^(DGNBUFBITS+3) bytes;
+ *
+ *  Defaults are all zeroes; all other bits are reserved, and must be written 0.
+ */
+
+typedef union {
+	uint32_t R;
+	struct {
+		uint32_t ALARM_INT : 1U;
+		uint32_t CFG_IOMUX : 1U;
+		uint32_t DGNBUFBITS : 4U;
+		uint32_t RSV : 26U;
+	} B;
+} upwr_xcp_config_t;
+
+/**+
+ * upwr_xcp_sw_alarm()
+ *
+ * Argument code is defined by the enum upwr_alarm_t, with the values:
+ *  - UPWR_ALARM_INTERNAL: internal software error
+ *  - UPWR_ALARM_EXCEPTION: uPower core exception, either illegal instruction or
+ *    bus error
+ *  - UPWR_ALARM_SLACK: delay path too slow, meaning a timing violation occurred
+ *    or is iminent.
+ *  - UPWR_ALARM_VOLTAGE: one of the measured voltages is below safety margins.
+ *
+ * Note that this service emulates an alarm that would normally be issued by
+ * uPower when it detects one of the causes above. A request to alarm the APD
+ * domain when it is powered off returns success, but is ineffective.
+ *
+ */
+
+#define	UPWR_ALARM_INTERNAL   (0U) /* internal error */
+#define	UPWR_ALARM_EXCEPTION  (1U) /* core exception */
+#define	UPWR_ALARM_SLACK      (2U) /* delay path too slow */
+#define	UPWR_ALARM_VOLTAGE    (3U) /* voltage drop */
+#define	UPWR_ALARM_LAST       UPWR_ALARM_VOLTAGE
+
+typedef uint32_t upwr_alarm_t;
+
+/**---------------------------------------------------------------
+ * POWER MANAGEMENT SERVICE GROUP
+ */
+
+/* values in mV: */
+#define UPWR_RTD_RBBN_MAX     (1300U) /* max. RTD Reverse Back Bias N-Well */
+#define UPWR_RTD_RBBN_MIN      (100U) /* min. RTD Reverse Back Bias N-Well */
+
+#define UPWR_RTD_RBBP_MAX     (1300U) /* max. RTD Reverse Back Bias P-Well */
+#define UPWR_RTD_RBBP_MIN      (100U) /* min. RTD Reverse Back Bias P-Well */
+
+/* APD bias can only two values (mV): */
+#define UPWR_APD_RBBN_LO      (1000U) /* low  APD Reverse Back Bias N-Well */
+#define UPWR_APD_RBBN_HI      (1300U) /* high APD Reverse Back Bias N-Well */
+
+#define UPWR_APD_RBBP_LO      (1000U) /* low  APD Reverse Back Bias P-Well */
+#define UPWR_APD_RBBP_HI      (1300U) /* high APD Reverse Back Bias P-Well */
+
+/* AVD bias can only two values (mV): */
+#define UPWR_AVD_RBBN_LO      (1000U) /* low  AVD Reverse Back Bias N-Well */
+#define UPWR_AVD_RBBN_HI      (1300U) /* high AVD Reverse Back Bias N-Well */
+
+#define UPWR_AVD_RBBP_LO      (1000U) /* low  AVD Reverse Back Bias P-Well */
+#define UPWR_AVD_RBBP_HI      (1300U) /* high AVD Reverse Back Bias P-Well */
+
+/**+
+ * upwr_pwm_param()
+ *
+ * Argument param is defined by the struct/union upwr_pwm_param_t with the
+ * following i.MX8ULP-specific bitfields:
+ * - DPD_ALLOW (1 bit): 1= allows uPower power mode to go Deep Power Down (DPD);
+ *   uPower DPD also depends on other conditions, but if this bit is 0 uPower
+ *   won't go DPD even if those conditions are met; it can go either Sleep or
+ *   Deep Sleep (DSL) depending on the other configurations.
+ * - DSL_DIS (1 bit): if this bit is 1, uPower power mode won't go Deep Sleep
+ *   (DSL) even if the other conditions for that are met;
+ *   it may go Sleep instead.
+ * - SLP_ALLOW (1 bit): if this bit is 1, uPower power mode will go Sleep if
+ *   the conditions for Partial Active are met; it may also go Deep Sleep if bit
+ *   DSL_DIS=1.
+ * - DSL_BGAP_OFF (1 bit): 1= turns bandgap off when uPower goes Deep Sleep;
+ *   0= leaves bandgap on when uPower goes Deep Sleep (DSL).
+ * - DPD_BGAP_ON (1 bit): 1= leaves bandgap on when uPower goes Deep Power Down
+ *   (DPD); 0= powers off bandgap when uPower goes Deep Power Down (DPD).
+ *
+ *  Defaults are all zeroes; all other bits are reserved, and must be written 0.
+ */
+
+typedef union {
+	uint32_t R;
+	struct {
+		uint32_t DPD_ALLOW : 1U;
+		uint32_t DSL_DIS : 1U;
+		uint32_t SLP_ALLOW : 1U;
+		uint32_t DSL_BGAP_OFF : 1U;
+		uint32_t DPD_BGAP_ON : 1U;
+		uint32_t RSV : 27U;
+	} B;
+} upwr_pwm_param_t;
+
+/**+
+ * upwr_pwm_chng_reg_voltage()
+ *
+ * Argument reg is defined by the enum upwr_pmc_reg_t, with regulator ids:
+ *  - RTD_PMC_REG: RTD regulator
+ *  - APD_PMC_REG: APD regulator
+ *  - RTD_BIAS_PMC_REG: RTD bias regulator
+ *  - APD_BIAS_PMC_REG: APD bias regulator
+ *  - RTD_LVD_PMC_MON: RTD LVD regulator
+ *  - APD_LVD_PMC_MON: APD LVD regulator
+ *  - AVD_LVD_PMC_MON: AVD LVD regulator
+ *
+ * Argument volt is defined by the formula:
+ *
+ * argument = 92.30797633*V - 55.000138, rounded to the nearest integer,
+ * where V is the value in Volts, with a minimum of 0.595833 V (argument = 0).
+ *
+ */
+
+/* Regulator ids */
+typedef enum {
+	RTD_PMC_REG,
+	APD_PMC_REG,
+	RTD_BIAS_PMC_REG,
+	APD_BIAS_PMC_REG,
+	RTD_LVD_PMC_MON,
+	APD_LVD_PMC_MON,
+	AVD_LVD_PMC_MON
+} upwr_pmc_reg_t;
+
+/**+
+ * upwr_pwm_freq_setup()
+ *
+ * Argument domain is either RTD_DOMAIN or APD_DOMAIN.
+ * Arguments nextfq and currfq are to be defined (TBD).
+ */
+
+/**+
+ * upwr_pwm_dom_power_on()
+ *
+ * The arguments must comply with the restrictions below, otherwise the service
+ * is not executed and returns error UPWR_RESP_BAD_REQ:
+ * - argument domain can only be APD_DOMAIN, because in i.MX8ULP it is not
+ *   possible APD powered on (calling the service) with RTD completely
+ *   powered off.
+ * - the call can only be made from the RTD domain, for the same reason.
+ * - argument boot can only be 1, because in i.MX8ULP it is not possible to
+ *   power on the APD domain without starting the core boot.
+ *
+ * If APD is already powered on and booting/booted when the service is called,
+ * it returns success without doing anything.
+ */
+
+/**+
+ * upwr_pwm_boot_start()
+ *
+ * The arguments must comply with the restrictions below, otherwise the service
+ * is not executed and returns error UPWR_RESP_BAD_REQ:
+ * - argument domain can only be APD_DOMAIN, because in i.MX8ULP it is not
+ *   possible APD powered on (calling the service) with RTD completely
+ *   powered off.
+ * - the call can only be made from the RTD domain, for the same reason.
+ *
+ * If APD is already booted when the service is called, it returns success
+ * without doing anything. Otherwise, it returns the error UPWR_RESP_BAD_STATE,
+ * because in i.MX8ULP APD cannot be booted separately from power on.
+ */
+
+/**+
+ * upwr_pwm_power_on(),
+ * upwr_pwm_power_off(),
+ * upwr_pwm_mem_retain()
+ *
+ * These three service functions use the same arguments:
+ *
+ * argument swt is an array of one 32-bit word: uint32_t swt[1];
+ * naturally the pointer to a single uint32_t variable may be passed.
+ * Each bit of the word corresponds to a switch, according to the i.MX8ULP
+ * Reference Manual Rev B draft 2 table 64 Power switch reset state,
+ * and the following formula:
+ *
+ * if switch number < 10 bit number = switch number;
+ * if switch number >  9 bit number = switch number + 3;
+ *
+ * bits 9, 10, 11 and 12 must have the same value (corresponding to switch 9)
+ *
+ * Note: this argument is not used in upwr_pwm_mem_retain.
+ *
+ * argument mem is an array of two 32-bit words: uint32_t mem[2];
+ * naturally the pointer to a single uint64_t variable may be passed, since
+ * both ARM and RISC-V are little endian architectures.
+ * Each bit of the words corresponds to a memory, according to the i.MX8ULP
+ * Reference Manual table "Memory Partitions".
+ *
+ * Turning a memory completely on (array and peripheral) will automatically
+ * turn on its power switch, even if not explicitly commanded.
+ * Turning a memory's power switch off will automatically turn off its array
+ * and peripheral beforehand, even if not explicitly commanded.
+ *
+ * Argument restrictions:
+ *
+ * The swt and mem arguments must comply with the restrictions below, otherwise
+ * the service is not executed (no switch/memory is changed) and returns error
+ * UPWR_RESP_BAD_REQ:
+ *  1. one must not put a memory in retention coming from an off state.
+ *  2. switches 9, 10, 11 and 12 must be turned on/off simultaneously.
+ *  3. an AVD switch can only be turned off if all AVD switches belong to the
+ *     domain requesting the service (as defined by registers SYSCTRL0,
+ *     LPAV_MASTER_ALLOC_CTRL and LPAV_SLAVE_ALLOC_CTRL);
+ *     there is no such restriction to turn the switch on.
+ *  4. an AVD memory can only be turned off or put in retention if all
+ *     AVD memories belong to the domain requesting the service
+ *     (as defined by registers SYSCTRL0, LPAV_MASTER_ALLOC_CTRL and
+ *      LPAV_SLAVE_ALLOC_CTRL); there is no such restriction to turn on the
+ *     memories.
+ *  5. EdgeLock RAMs must not be turned off, unless RTD domain is in
+ *     Deep Power Down (DPD).
+ *  6. Power Switch 19 must be on to turn on switches 17 (MIPI/DSI),
+ *     18 (MIPI/CSI), and all AVD power switches.
+ *
+ * Service Errors:
+ *
+ * Besides the error UPWR_RESP_BAD_REQ caused by violations of the restrictions
+ * above, the services may fail with error UPWR_RESP_RESOURCE if a power mode
+ * transition or a similar service is executing at the same time.
+ * This error should be interpreted as a "try later" response, as the service
+ * will succeed once those concurrent executions are done, and no other is
+ * started.
+ */
+
+/**+
+ * upwr_pwm_chng_switch_mem()
+ *
+ * The bit numbers in the argument struct mask and on/off state fields
+ * are the same as for services upwr_pwm_power_on, upwr_pwm_power_off and
+ * upwr_pwm_mem_retain.
+ *
+ * Turning a memory completely on (array and peripheral) will automatically
+ * turn on its power switch, even if not explicitly commanded.
+ *
+ * Argument restrictions:
+ *
+ * Same argument restrictions as services upwr_pwm_power_on, upwr_pwm_power_off
+ * and upwr_pwm_mem_retain, plus the following:
+ *
+ *  1. one must not turn a memory peripheral on and a memory array off.
+ *  2. one must not put a memory in retention and switch its power switch off.
+ *
+ * Service Errors:
+ *
+ * Besides the error UPWR_RESP_BAD_REQ caused by violations of the restrictions
+ * above, the service may fail with error UPWR_RESP_RESOURCE if a power mode
+ * transition or a similar service is executing at the same time.
+ * This error should be interpreted as a "try later" response, as the service
+ * will succeed once those concurrent executions are done, and no other is
+ * started.
+ */
+
+/**+
+ * upwr_pwm_pmode_config()
+ *
+ * The same power switch and memory restrictions of service
+ * upwr_pwm_chng_switch_mem apply between power modes, however they are not
+ * enforced by this service, that is, it does not return service error.
+ *
+ * The default power mode configurations for RTD and APD are documented in the
+ * i.MX8ULP Reference Manual sections "Power mode details (real-time domain)"
+ * and "Power mode details (application domain)", respectively.
+ * If those configurations are satisfactory, this service does not have
+ * to be called.
+ *
+ * Power Mode Configuration Structure:
+ *
+ * Follows a description of the power mode configuration structure elements.
+ * - dom_swts: the same switch configuration structures used in service
+ *             upwr_pwm_chng_switch_mem argument swt.
+ * - mem_swts: the same memory configuration structures used in service
+ *             upwr_pwm_chng_switch_mem argument mem.
+ * - regs: an array of structs base_reg_cfg_t (see upower_soc_defs.h),
+ *         one element for each regulator; base_reg_cfg_t has fields
+ *         mode (regulator-dependent), lvl (voltage level in uV),
+ *         comp (regulator-dependent complamentary info).
+ * - pads: pad configuration in low power; see pad_cfg_t definition below.
+ * - mons: domain monitors (LVD and HVD) configuration;
+ *         see mon_cfg_t definition below.
+ * - avd_mons: same as mons for the AVD domain; see mon_cfg_t definition below.
+ * - dom_bbias: back-bias configuration for the domain;
+ *              see base_bbias_cfg_t definition below.
+ * - avd_bbias: back-bias configuration for the AVD domain;
+ *              see base_bbias_cfg_t definition below.
+ * - mem_bbias: back-bias configuration for the memory;
+ *              see base_bbias_cfg_t definition below.
+ * - mem_fbias: forward-bias configuration for the memory;
+ *              see base_fbias_cfg_t definition below.
+ * - pmic: PMIC-specific configuration
+ *
+ * Structure pad_cfg_t:
+ *
+ * Pad control for low power modes (power off, etc), 1 bit per pad segment.
+ * - rst  : put pad segment in reset.
+ * - iso  : put pad segment in isolation.
+ * - compl: specific pad segment information.
+ * - msk  : select which pads will be updated.
+ *
+ * Structure mon_cfg_t:
+ *
+ * Configures a voltage monitor and its actions.
+ * There are monitors for RTD, APD and AVD, monitoring LVD and HVD.
+ * - lvl  : Voltage level (in uV).
+ * - mode : Mode of monitor (ON, OFF, LP, etc).
+ * - compl: Extra info for the monitor.
+ *
+ * Structure base_bbias_cfg_t:
+ *
+ * Configures back-bias (for domain or memory).
+ * - mode : Back bias mode (OFF, RBB, ARBB, etc).
+ * - p_lvl: Voltage level of p-well (in mV).
+ * - n_lvl: Voltage level of n-well (in mV).
+ * - compl: Complementary bias-specific (enable reset, interrupt, clamp, etc).
+ *
+ * Structure base_fbias_cfg_t:
+ *
+ * Configure memory forward bias for a memory segment.
+ *
+ * - mode : Forward bias mode (OFF, ON).
+ * - msk  : Selects which memory will be updated
+ *
+ */
+
+/*=========================================================================
+ * Domain bias
+ *=========================================================================
+ */
+
+/**+
+ * upwr_pwm_chng_dom_bias()
+ *
+ * Argument bias is a pointer to a struct with fields:
+ *  - apply: tells to which domains the bias must be applied;
+ *    options are RTD only (BIAS_APPLY_RTD), RTD and AVD (BIAS_APPLY_RTD_AVD),
+ *    APD only (BIAS_APPLY_APD), APD and AVD (BIAS_APPLY_APD_AVD),
+ *    AVD only (BIAS_APPLY_AVD)
+ *  - dommode: bias mode of the main domain (RTD or APD, determined by apply);
+ *    options are disabled (NBB_BIAS_MODE), reverse back bias (RBB_BIAS_MODE),
+ *    asymmetrical forward bias (AFBB_BIAS_MODE), asymmetrical reverse bias
+ *    (ARBB_BIAS_MODE).
+ *  - avdmode: bias mode of Audio-Video Domain (AVD);
+ *    options are the same as dommode.
+ *  - dombias: bias voltage level(s) for the main domain (RTD or APD,
+ *    determined by apply); it is a structure with 2 fields, rbbn and rbbp,
+ *    for the N-well and P-well voltages, respectively; values are in mV.
+ *  - avdbias: bias voltage level(s) for the Audio-Video Domain (AVD);
+ *    same fields as dombias;
+ *
+ * Argument restrictions:
+ *
+ * Voltage levels must comply with the #define-determined limits/options:
+ * between UPWR_RTD_RBBN_MIN and UPWR_RTD_RBBN_MAX (inclusive) for RTD N-well;
+ * between UPWR_RTD_RBBP_MIN and UPWR_RTD_RBBP_MAX (inclusive) for RTD P-well;
+ * either UPWR_APD_RBBN_LO or UPWR_APD_RBBN_HI for APD N-well;
+ * either UPWR_APD_RBBP_LO or UPWR_APD_RBBP_HI for APD P-well;
+ * either UPWR_AVD_RBBN_LO or UPWR_AVD_RBBN_HI for AVD N-well;
+ * either UPWR_AVD_RBBP_LO or UPWR_AVD_RBBP_HI for AVD P-well;
+ *
+ * But note that the limits/options above do not apply to all bias modes:
+ * rbbn is used and checked only in mode RBB_BIAS_MODE;
+ * rbbp is used and checked only in modes RBB_BIAS_MODE and ARBB_BIAS_MODE;
+ * modes AFBB_BIAS_MODE and NBB_BIAS_MODE use or check neither rbbn nor rbbp;
+ *
+ * Service error UPWR_RESP_BAD_REQ is returned if the voltage limits/options
+ * above are violated.
+ */
+
+/* argument struct for service upwr_pwm_chng_dom_bias:
+ */
+
+typedef enum {               /* bias modes (both domain and memory): */
+	NBB_BIAS_MODE  = 0,  /* bias disabled */
+	RBB_BIAS_MODE  = 1,  /* reverse back bias enabled */
+	AFBB_BIAS_MODE = 2,  /* asymmetrical forward bias */
+	ARBB_BIAS_MODE = 3   /* asymmetrical reverse bias */
+} upwr_bias_mode_t;
+
+/* Domain Bias config (one per domain) */
+
+typedef enum {
+	BIAS_APPLY_RTD,      /* apply to RTD only    */
+	BIAS_APPLY_RTD_AVD,  /* apply to RTD and AVD */
+	BIAS_APPLY_APD,      /* apply to APD only    */
+	BIAS_APPLY_APD_AVD,  /* apply to APD and AVD */
+	BIAS_APPLY_AVD,      /* apply to AVD only    */
+	BIAS_APPLY_COUNT     /* number of apply options */
+} upwr_bias_apply_t;
+
+typedef struct {
+	uint16_t rbbn;    /* reverse back bias N well (mV) */
+	uint16_t rbbp;    /* reverse back bias P well (mV) */
+} upwr_rbb_t;
+
+struct upwr_dom_bias_cfg_t {
+	upwr_bias_apply_t apply;   /* bias application option  */
+	upwr_bias_mode_t  dommode; /* RTD/APD bias mode config */
+	upwr_bias_mode_t  avdmode; /* AVD     bias mode config */
+	upwr_rbb_t        dombias; /* RTD/APD reverse back bias */
+	upwr_rbb_t        avdbias; /* AVD     reverse back bias */
+};
+
+/* bias struct used in power mode config definitions */
+
+/**
+ * When write power mode transition program, please read below comments carefully.
+ * The structure and logic is complex, There is a lot of extension and reuse.
+ *
+ * First, for mode, extend "uint32_t mode" to a union struct, add support for AVD:
+ * typedef union {
+ *    uint32_t R;
+ *    struct {
+ *        uint32_t mode : 8;
+ *        uint32_t rsrv_1 : 8;
+ *        uint32_t avd_mode : 8;
+ *        uint32_t rsrv_2 : 8;
+ *    } B;
+ * } dom_bias_mode_cfg_t;
+
+  Second, if mode is AFBB mode, no need to configure rbbn and rbbp, uPower firmware
+  will configure all SRAM_AFBB_0 or SRAM_AFBB_1 for corresponding domain.
+
+  Third, if mode is RBB mode, extend "uint32_t rbbn" and "uint32_t rbbp" to a union
+  struct, add support for AVD:
+  typedef union {
+  uint32_t                  R;
+  struct {
+    uint32_t                  lvl       : 8;
+    uint32_t                  rsrv_1    : 8;
+    uint32_t                  avd_lvl   : 8;
+    uint32_t                  rsrv_2    : 8;
+  }                         B;
+} dom_bias_lvl_cfg_t;
+
+ *
+ */
+typedef struct {
+	uint32_t mode; /* Domain bias mode config, extend to dom_bias_mode_cfg_t to support RTD, APD, AVD */
+	uint32_t rbbn; /* reverse back bias N well */
+	uint32_t rbbp; /* reverse back bias P well */
+} UPWR_DOM_BIAS_CFG_T;
+
+/*=========================================================================
+ * Memory bias
+ *=========================================================================
+ */
+/**+
+ * upwr_pwm_chng_mem_bias()
+ *
+ * Argument struct contains only the field en, which can be either 1 (bias
+ * enabled) or 0 (bias disabled).
+ *
+ * Argument domain must be either RTD_DOMAIN (Real Time Domain) or APD_DOMAIN
+ * (Application Domain).
+ */
+
+/* Memory Bias config */
+struct upwr_mem_bias_cfg_t {
+	uint32_t en; /* Memory bias enable config */
+};
+
+/* bias struct used in power mode config definitions */
+typedef struct {
+	uint32_t en; /* Memory bias enable config */
+} UPWR_MEM_BIAS_CFG_T;
+
+/* Split different Bias */
+struct upwr_pmc_bias_cfg_t {
+	UPWR_DOM_BIAS_CFG_T dombias_cfg; /* Domain Bias config */
+	UPWR_MEM_BIAS_CFG_T membias_cfg; /* Memory Bias config */
+};
+
+/*=========================================================================
+ * Power modes
+ *=========================================================================
+ */
+
+/* from msb->lsb: Azure bit, dual boot bit, low power boot bit */
+typedef enum {
+	SOC_BOOT_SINGLE   = 0,
+	SOC_BOOT_LOW_PWR  = 1,
+	SOC_BOOT_DUAL     = 2,
+	SOC_BOOT_AZURE    = 4
+} SOC_BOOT_TYPE_T;
+
+#ifdef UPWR_COMP_RAM
+/* Power modes for RTD domain  */
+typedef enum {
+	DPD_RTD_PWR_MODE, /* Real Time Deep Power Down mode */
+	PD_RTD_PWR_MODE,  /* Real Time Power Down mode */
+	DSL_RTD_PWR_MODE, /* Real Time Domain Deep Sleep Mode */
+	HLD_RTD_PWR_MODE, /* Real Time Domain Hold Mode */
+	SLP_RTD_PWR_MODE, /* Sleep Mode */
+	ADMA_RTD_PWR_MODE,/* Active DMA Mode */
+	ACT_RTD_PWR_MODE, /* Active Domain Mode */
+	NUM_RTD_PWR_MODES
+} upwr_ps_rtd_pwr_mode_t;
+
+/* Abstract power modes */
+typedef enum {
+	DPD_PWR_MODE,
+	PD_PWR_MODE,
+	PACT_PWR_MODE,
+	DSL_PWR_MODE,
+	HLD_PWR_MODE,
+	SLP_PWR_MODE,
+	ADMA_PWR_MODE,
+	ACT_PWR_MODE,
+	NUM_PWR_MODES,
+	NUM_APD_PWR_MODES = NUM_PWR_MODES,
+	TRANS_PWR_MODE    = NUM_PWR_MODES,
+	INVALID_PWR_MODE  = TRANS_PWR_MODE + 1
+} abs_pwr_mode_t;
+#else /* UPWR_COMP_RAM */
+/* Power modes for RTD domain  */
+#define	DPD_RTD_PWR_MODE   (0U)  /* Real Time Deep Power Down mode */
+#define	PD_RTD_PWR_MODE    (1U)  /* Real Time Power Down mode */
+#define	DSL_RTD_PWR_MODE   (2U)  /* Real Time Domain Deep Sleep Mode */
+#define	HLD_RTD_PWR_MODE   (3U)  /* Real Time Domain Hold Mode */
+#define	SLP_RTD_PWR_MODE   (4U)  /* Sleep Mode */
+#define	ADMA_RTD_PWR_MODE  (5U)  /* Active DMA Mode */
+#define	ACT_RTD_PWR_MODE   (6U)  /* Active Domain Mode */
+#define	NUM_RTD_PWR_MODES  (7U)
+
+typedef uint32_t upwr_ps_rtd_pwr_mode_t;
+
+/* Abstract power modes */
+#define	DPD_PWR_MODE       (0U)
+#define	PD_PWR_MODE        (1U)
+#define	PACT_PWR_MODE      (2U)
+#define	DSL_PWR_MODE       (3U)
+#define	HLD_PWR_MODE       (4U)
+#define	SLP_PWR_MODE       (5U)
+#define	ADMA_PWR_MODE      (6U)
+#define	ACT_PWR_MODE       (7U)
+#define	NUM_PWR_MODES      (8U)
+#define	NUM_APD_PWR_MODES NUM_PWR_MODES
+#define	TRANS_PWR_MODE    NUM_PWR_MODES
+#define	INVALID_PWR_MODE  (TRANS_PWR_MODE + 1U)
+
+typedef uint32_t abs_pwr_mode_t;
+#endif /* UPWR_COMP_RAM */
+
+typedef struct {
+	abs_pwr_mode_t mode;
+	bool ok;
+} pch_trans_t;
+
+typedef pch_trans_t rtd_trans_t;
+
+typedef struct {
+	abs_pwr_mode_t mode;
+	pch_trans_t core[UPWR_APD_CORES];
+} apd_trans_t;
+
+/* Codes for APD pwr mode as programmed in LPMODE reg */
+typedef enum {
+	ACT_APD_LPM,
+	SLP_APD_LPM = 1,
+	DSL_APD_LPM = 3,
+	PACT_APD_LPM = 7,
+	PD_APD_LPM = 15,
+	DPD_APD_LPM = 31,
+	HLD_APD_LPM = 63
+} upwr_apd_lpm_t;
+
+/* PowerSys low power config */
+struct upwr_powersys_cfg_t {
+	uint32_t lpm_mode; /* Powersys low power mode */
+};
+
+/*=*************************************************************************
+ * RTD
+ *=*************************************************************************/
+/* Config pmc PADs */
+struct upwr_pmc_pad_cfg_t {
+	uint32_t pad_close;   /* PMC PAD close config */
+	uint32_t pad_reset;   /* PMC PAD reset config */
+	uint32_t pad_tqsleep; /* PMC PAD TQ Sleep config */
+};
+
+/* Config regulator (internal and external) */
+struct upwr_reg_cfg_t {
+	uint32_t volt;  /* Regulator voltage config */
+	uint32_t mode;  /* Regulator mode config */
+};
+
+/* Config pmc monitors */
+struct  upwr_pmc_mon_cfg_t {
+	uint32_t mon_hvd_en; /* PMC mon HVD */
+	uint32_t mon_lvd_en; /* PMC mon LVD */
+	uint32_t mon_lvdlvl; /* PMC mon LVDLVL */
+};
+
+/* Same monitor config for RTD (for compatibility) */
+#define upwr_pmc_mon_rtd_cfg_t upwr_pmc_mon_cfg_t
+
+typedef swt_config_t ps_rtd_swt_cfgs_t[NUM_RTD_PWR_MODES];
+typedef swt_config_t ps_apd_swt_cfgs_t[NUM_APD_PWR_MODES];
+
+/*=*************************************************************************
+ * APD
+ *=*************************************************************************/
+
+/* PowerSys PMIC config */
+struct upwr_pmic_cfg_t {
+	uint32_t volt;
+	uint32_t mode;
+	uint32_t mode_msk;
+};
+
+typedef uint32_t offs_t;
+
+struct ps_apd_pwr_mode_cfg_t {
+	#ifdef UPWR_SIMULATOR_ONLY
+	struct upwr_switch_board_t *swt_board_offs;
+	struct upwr_mem_switches_t *swt_mem_offs;
+	#else
+	offs_t swt_board_offs;
+	offs_t swt_mem_offs;
+	#endif
+	struct upwr_pmic_cfg_t pmic_cfg;
+	struct upwr_pmc_pad_cfg_t pad_cfg;
+	struct upwr_pmc_bias_cfg_t bias_cfg;
+};
+
+/* Get the pointer to swt config */
+static inline struct upwr_switch_board_t*
+get_apd_swt_cfg(volatile struct ps_apd_pwr_mode_cfg_t *cfg)
+{
+	char *ptr;
+
+	ptr = (char *)cfg;
+	ptr += (uint64_t)cfg->swt_board_offs;
+	return (struct upwr_switch_board_t *)ptr;
+}
+
+/* Get the pointer to mem config */
+static inline struct upwr_mem_switches_t*
+get_apd_mem_cfg(volatile struct ps_apd_pwr_mode_cfg_t *cfg)
+{
+	char *ptr;
+
+	ptr = (char *)cfg;
+	ptr += (uint64_t)cfg->swt_mem_offs;
+	return (struct upwr_mem_switches_t *)ptr;
+}
+
+/* Power Mode configuration */
+
+#define ps_rtd_pwr_mode_cfg_t upwr_power_mode_cfg_t
+
+/* these typedefs are just for RISC-V sizeof purpose */
+typedef uint32_t swt_board_ptr_t;
+typedef uint32_t swt_mem_ptr_t;
+
+struct upwr_power_mode_cfg_t {
+	#ifdef UPWR_SIMULATOR_ONLY
+	struct upwr_switch_board_t *swt_board; /* Swt board for mem. */
+	struct upwr_mem_switches_t *swt_mem;   /* Swt to mem. arrays, perif */
+	#else
+	#ifdef __LP64__
+	uint32_t swt_board;
+	uint32_t swt_mem;
+	#else
+	struct upwr_switch_board_t *swt_board; /* Swt board for mem. */
+	struct upwr_mem_switches_t *swt_mem;   /* Swt to mem. arrays, perif */
+	#endif
+	#endif
+	struct upwr_reg_cfg_t in_reg_cfg; /* internal regulator config*/
+	struct upwr_reg_cfg_t pmic_cfg;  /* external regulator - pmic*/
+	struct upwr_pmc_pad_cfg_t pad_cfg;  /* Pad conf for power trans*/
+	struct upwr_pmc_mon_rtd_cfg_t mon_cfg; /*monitor configuration */
+	struct upwr_pmc_bias_cfg_t bias_cfg; /* Memory/Domain Bias conf */
+	struct upwr_powersys_cfg_t pwrsys_lpm_cfg; /* pwrsys low power config*/
+};
+
+static inline unsigned int upwr_sizeof_pmode_cfg(uint32_t domain)
+{
+	switch (domain) {
+	case RTD_DOMAIN:
+		return sizeof(struct upwr_power_mode_cfg_t) +
+					(sizeof(struct upwr_switch_board_t)*
+					 UPWR_PMC_SWT_WORDS) +
+					(sizeof(struct upwr_mem_switches_t)*
+					 UPWR_PMC_MEM_WORDS) -
+					2U * (sizeof(void *) - sizeof(swt_board_ptr_t));
+
+		/* fall through */
+	case APD_DOMAIN:
+		return sizeof(struct ps_apd_pwr_mode_cfg_t) +
+					(sizeof(struct upwr_switch_board_t)*
+					 UPWR_PMC_SWT_WORDS) +
+					(sizeof(struct upwr_mem_switches_t)*
+					 UPWR_PMC_MEM_WORDS);
+
+		/* fall through */
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/*=*************************************************************************
+ * All configs
+ *=*************************************************************************/
+
+/* LVD/HVD monitor config for a single domain */
+
+/* Domain + AVD monitor config
+ * For RTD, mapped in mon_cfg.mon_hvd_en
+ * For APD, mapped temporarily in pad_cfg.pad_tqsleep
+ */
+typedef union upwr_mon_cfg_union_t {
+	volatile uint32_t R;
+	struct {
+		/* Original config, not change */
+		volatile uint32_t rsrv_1          : 8;
+		/* DOM */
+		volatile uint32_t dom_lvd_irq_ena : 1;
+		volatile uint32_t dom_lvd_rst_ena : 1;
+		volatile uint32_t dom_hvd_irq_ena : 1;
+		volatile uint32_t dom_hvd_rst_ena : 1;
+		volatile uint32_t dom_lvd_lvl     : 4;
+		volatile uint32_t dom_lvd_ena     : 1;
+		volatile uint32_t dom_hvd_ena     : 1;
+		/* AVD */
+		volatile uint32_t avd_lvd_irq_ena : 1;
+		volatile uint32_t avd_lvd_rst_ena : 1;
+		volatile uint32_t avd_hvd_irq_ena : 1;
+		volatile uint32_t avd_hvd_rst_ena : 1;
+		volatile uint32_t avd_lvd_lvl     : 4;
+		volatile uint32_t avd_lvd_ena     : 1;
+		volatile uint32_t avd_hvd_ena     : 1;
+	}                         B;
+} upwr_mon_cfg_t;
+
+/* Get the monitor config word from RAM (domaind and AVD) */
+static inline uint32_t get_mon_cfg(uint8_t dom, void *mode_cfg)
+{
+	if (dom == RTD_DOMAIN) {
+		return ((struct ps_rtd_pwr_mode_cfg_t *)mode_cfg)->mon_cfg.mon_hvd_en;
+	} else {
+		return ((struct ps_apd_pwr_mode_cfg_t *)mode_cfg)->pad_cfg.pad_tqsleep;
+	}
+}
+
+/* Set the monitor config word in RAM (domaind and AVD) */
+static inline void set_mon_cfg(uint8_t dom, void *mode_cfg,
+				upwr_mon_cfg_t mon_cfg)
+{
+	uint32_t *cfg;
+
+	if (dom == RTD_DOMAIN) {
+		cfg = (uint32_t *)&((struct ps_rtd_pwr_mode_cfg_t *)mode_cfg)->mon_cfg.mon_hvd_en;
+	} else {
+		cfg = (uint32_t *)&((struct ps_apd_pwr_mode_cfg_t *)mode_cfg)->pad_cfg.pad_tqsleep;
+	}
+
+	*cfg = mon_cfg.R;
+}
+
+#define PMIC_REG_VALID_TAG 0xAAU
+
+/**
+ * limit the max pmic register->value count to 8
+ * each data cost 4 Bytes, totally 32 Bytes
+ */
+#define MAX_PMIC_REG_COUNT 0x8U
+
+/**
+ * the configuration structure for PMIC register setting
+ *
+ * @ tag: The TAG number to judge if the data is valid or not, valid tag is PMIC_REG_VALID_TAG
+ * @ power_mode : corresponding to each domain's power mode
+ * RTD refer to upwr_ps_rtd_pwr_mode_t
+ * APD refer to abs_pwr_mode_t
+ * @ i2c_addr : i2c address
+ * @ i2c_data : i2c data value
+ */
+struct ps_pmic_reg_data_cfg_t {
+	uint32_t tag : 8;
+	uint32_t power_mode : 8;
+	uint32_t i2c_addr : 8;
+	uint32_t i2c_data : 8;
+};
+
+/* Uniformize access to PMIC cfg for RTD and APD */
+
+typedef union {
+	struct upwr_reg_cfg_t RTD;
+	struct upwr_pmic_cfg_t APD;
+} pmic_cfg_t;
+
+/* Access to PMIC mode mask and AVD mode */
+
+typedef union {
+	uint32_t R;
+	struct {
+		uint8_t mode;     /* Domain PMIC mode */
+		uint8_t msk;      /* Domain PMIC mode mask */
+		uint8_t avd_mode; /* AVD PMIC mode */
+		uint8_t avd_msk;  /* AVD PMIC mode mask */
+	} B;
+} pmic_mode_cfg_t;
+
+/* Access RTD, APD and AVD modes and masks */
+static inline pmic_mode_cfg_t *get_pmic_mode_cfg(uint8_t dom, pmic_cfg_t *cfg)
+{
+	uint32_t *mode_cfg;
+
+	if (dom == RTD_DOMAIN) {
+		mode_cfg = &cfg->RTD.mode;
+	} else {
+		mode_cfg = &cfg->APD.mode;
+	}
+
+	return (pmic_mode_cfg_t *)mode_cfg;
+}
+
+static inline uint8_t get_pmic_mode(uint8_t dom, pmic_cfg_t *cfg)
+{
+	return get_pmic_mode_cfg(dom, cfg)->B.mode;
+}
+
+static inline void set_pmic_mode(uint8_t dom, pmic_cfg_t *cfg, uint8_t mode)
+{
+	get_pmic_mode_cfg(dom, cfg)->B.mode = mode;
+}
+
+static inline uint32_t get_pmic_mode_msk(uint8_t dom, pmic_cfg_t *cfg)
+{
+	pmic_mode_cfg_t   *mode_cfg;
+
+	if (dom == RTD_DOMAIN) {
+		mode_cfg = (pmic_mode_cfg_t *)&cfg->RTD.mode;
+		return mode_cfg->B.msk;
+	} else {
+		return cfg->APD.mode_msk;
+	}
+}
+
+/* Getters and setters for AVD mode and mask */
+static inline uint8_t get_avd_pmic_mode(uint8_t dom, pmic_cfg_t *cfg)
+{
+	return get_pmic_mode_cfg(dom, cfg)->B.avd_mode;
+}
+
+static inline void set_avd_pmic_mode(uint8_t dom, pmic_cfg_t *cfg, uint8_t mode)
+{
+	get_pmic_mode_cfg(dom, cfg)->B.avd_mode = mode;
+}
+
+static inline uint8_t get_avd_pmic_mode_msk(uint8_t dom, pmic_cfg_t *cfg)
+{
+	return get_pmic_mode_cfg(dom, cfg)->B.avd_msk;
+}
+
+static inline void set_avd_pmic_mode_msk(uint8_t dom,
+					 pmic_cfg_t *cfg,
+					 uint8_t msk)
+{
+	get_pmic_mode_cfg(dom, cfg)->B.avd_msk = msk;
+}
+
+struct ps_delay_cfg_t {
+	uint32_t tag : 8U;
+	uint32_t rsv : 8U;
+	uint32_t exitdelay : 16U;   // exit delay in us
+};
+
+#define PS_DELAY_TAG 0xA5U
+
+/* max exit delay = 0xffff = 65535 us = 65.5 ms (it is enough...) */
+/* with 8 bits, 256 -> not enough */
+
+typedef struct ps_delay_cfg_t ps_rtd_delay_cfgs_t[NUM_RTD_PWR_MODES];
+typedef struct ps_delay_cfg_t ps_apd_delay_cfgs_t[NUM_APD_PWR_MODES];
+
+typedef struct ps_rtd_pwr_mode_cfg_t ps_rtd_pwr_mode_cfgs_t[NUM_RTD_PWR_MODES];
+typedef struct ps_apd_pwr_mode_cfg_t ps_apd_pwr_mode_cfgs_t[NUM_APD_PWR_MODES];
+typedef struct ps_pmic_reg_data_cfg_t ps_rtd_pmic_reg_data_cfgs_t[MAX_PMIC_REG_COUNT];
+typedef struct ps_pmic_reg_data_cfg_t ps_apd_pmic_reg_data_cfgs_t[MAX_PMIC_REG_COUNT];
+
+struct ps_pwr_mode_cfg_t {
+	ps_rtd_pwr_mode_cfgs_t  ps_rtd_pwr_mode_cfg;
+	ps_rtd_swt_cfgs_t       ps_rtd_swt_cfg;
+	ps_apd_pwr_mode_cfgs_t  ps_apd_pwr_mode_cfg;
+	ps_apd_swt_cfgs_t       ps_apd_swt_cfg;
+	ps_rtd_pmic_reg_data_cfgs_t ps_rtd_pmic_reg_data_cfg;
+	ps_apd_pmic_reg_data_cfgs_t ps_apd_pmic_reg_data_cfg;
+	ps_rtd_delay_cfgs_t    ps_rtd_delay_cfg;
+	ps_apd_delay_cfgs_t    ps_apd_delay_cfg;
+
+};
+
+#define UPWR_XCP_MIN_ADDR   (0x28350000U)
+#define UPWR_XCP_MAX_ADDR   (0x2836FFFCU)
+
+struct upwr_reg_access_t {
+	uint32_t addr;
+	uint32_t data;
+	uint32_t mask; /* mask=0 commands read */
+};
+
+typedef upwr_pointer_msg upwr_xcp_access_msg;
+
+/* unions for the shared memory buffer */
+
+typedef union {
+	struct upwr_reg_access_t reg_access;
+} upwr_xcp_union_t;
+
+typedef union {
+	struct {
+		struct ps_rtd_pwr_mode_cfg_t rtd_struct;
+		struct upwr_switch_board_t   rtd_switch;
+		struct upwr_mem_switches_t   rtd_memory;
+	} rtd_pwr_mode;
+	struct {
+		struct ps_apd_pwr_mode_cfg_t apd_struct;
+		struct upwr_switch_board_t   apd_switch;
+		struct upwr_mem_switches_t   apd_memory;
+	} apd_pwr_mode;
+} upwr_pwm_union_t;
+
+#define MAX_SG_EXCEPT_MEM_SIZE sizeof(upwr_xcp_union_t)
+#define MAX_SG_PWRMGMT_MEM_SIZE sizeof(upwr_pwm_union_t)
+
+/**
+ * VOLTM group need shared memory for PMIC IC configuration
+ * 256 Bytes is enough for PMIC register array
+ */
+#define MAX_SG_VOLTM_MEM_SIZE 256U
+
+#endif /* UPWR_SOC_DEFS_H */
diff --git a/plat/imx/imx8ulp/xrdc/xrdc_config.h b/plat/imx/imx8ulp/xrdc/xrdc_config.h
new file mode 100644
index 00000000..d2af55cd
--- /dev/null
+++ b/plat/imx/imx8ulp/xrdc/xrdc_config.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2020-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <xrdc.h>
+
+#define SP(X)		((X) << 9)
+#define SU(X)		((X) << 6)
+#define NP(X)		((X) << 3)
+#define NU(X)		((X) << 0)
+
+#define RWX		7
+#define RW		6
+#define R		4
+#define X		1
+
+struct xrdc_mda_config imx8ulp_mda[] = {
+	{ 0, 7, MDA_SA_PT }, /* A core */
+	{ 1, 1, MDA_SA_NS }, /* DMA1 */
+	{ 2, 1, MDA_SA_NS }, /* USB */
+	{ 3, 1, MDA_SA_NS }, /* PXP-> .M10 */
+	{ 4, 1, MDA_SA_NS }, /* ENET */
+	{ 5, 1, MDA_SA_PT }, /* CAAM */
+	{ 6, 1, MDA_SA_NS }, /* USDHC0 */
+	{ 7, 1, MDA_SA_NS }, /* USDHC1 */
+	{ 8, 1, MDA_SA_NS }, /* USDHC2 */
+	{ 9, 2, MDA_SA_NS }, /* HIFI4 */
+	{ 10, 3, MDA_SA_NS }, /* GPU3D */
+	{ 11, 3, MDA_SA_NS }, /* GPU2D */
+	{ 12, 3, MDA_SA_NS }, /* EPDC */
+	{ 13, 3, MDA_SA_NS }, /* DCNano */
+	{ 14, 3, MDA_SA_NS }, /* ISI */
+	{ 15, 3, MDA_SA_NS }, /* PXP->NIC_LPAV.M0 */
+	{ 16, 3, MDA_SA_NS }, /* DMA2 */
+};
+
+#ifdef SPD_opteed
+#define TEE_SHM_SIZE 0x400000
+#else
+#define TEE_SHM_SIZE 0x0
+#endif
+
+#if defined(SPD_opteed) || defined(SPD_trusty)
+#define DRAM_MEM_0_START (0x80000000)
+#define DRAM_MEM_0_SIZE (BL32_BASE - 0x80000000)
+
+#define DRAM_MEM_1_START (BL32_BASE)
+#define DRAM_MEM_1_SIZE (BL32_SIZE - TEE_SHM_SIZE)
+
+#ifndef SPD_trusty
+#define DRAM_MEM_2_START (DRAM_MEM_1_START + DRAM_MEM_1_SIZE)
+#define DRAM_MEM_2_SIZE (0x80000000 - DRAM_MEM_1_SIZE - DRAM_MEM_0_SIZE)
+#else
+#define SECURE_HEAP_START   (0xA9600000)
+#define SECURE_HEAP_SIZE    (0x6000000)
+#define DRAM_MEM_END        (0x100000000)
+
+#define DRAM_MEM_2_START (DRAM_MEM_1_START + DRAM_MEM_1_SIZE)
+#define DRAM_MEM_2_SIZE  (SECURE_HEAP_START - DRAM_MEM_2_START)
+#define DRAM_MEM_3_START (DRAM_MEM_2_START + DRAM_MEM_2_SIZE)
+#define DRAM_MEM_3_SIZE  (SECURE_HEAP_SIZE)
+#define DRAM_MEM_4_START (DRAM_MEM_3_START + DRAM_MEM_3_SIZE)
+#define DRAM_MEM_4_SIZE  (DRAM_MEM_END - DRAM_MEM_4_START)
+#endif
+#endif
+
+struct xrdc_mrc_config imx8ulp_mrc[] = {
+	{ 0, 0, 0x0,        0x30000,    {0, 0, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* ROM1 */
+	{ 1, 0, 0x60000000, 0x10000000, {1, 1, 0, 0, 1, 0, 1, 1}, {0xfff, 0} }, /* Flexspi2 */
+	{ 2, 0, 0x22020000, 0x40000,    {1, 1, 0, 0, 1, 0, 1, 1}, {0xfff, 0} }, /* SRAM2 */
+	{ 3, 0, 0x22010000, 0x10000,    {1, 1, 0, 0, 1, 0, 1, 1}, {0xfff, 0} }, /* SRAM0 */
+#if defined(SPD_opteed) || defined(SPD_trusty)
+	{ 4, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+	{ 4, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfc0, 0} }, /* TEE DRAM for A35, DMA1, USDHC0*/
+	{ 4, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+#ifdef SPD_trusty
+	{ 4, 3, DRAM_MEM_3_START, DRAM_MEM_3_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfc0, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+	{ 4, 4, DRAM_MEM_4_START, DRAM_MEM_4_SIZE, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+#endif
+
+	{ 5, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for NIC_PER */
+	{ 5, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfc0, 0} }, /* TEE DRAM for NIC_PER */
+	{ 5, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for NIC_PER */
+#ifdef SPD_trusty
+	{ 5, 3, DRAM_MEM_3_START, DRAM_MEM_3_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfc0, 0} }, /* DRAM for NIC_PER */
+	{ 5, 4, DRAM_MEM_4_START, DRAM_MEM_4_SIZE, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for NIC_PER */
+#endif
+
+#ifdef SPD_trusty
+	{ 6, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, {1, 1, 0, 2, 1, 0, 1, 1}, {0xfff, 0x93f} }, /* DRAM for LPAV and RTD*/
+	{ 6, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfc0, 0} }, /* TEE DRAM for LPAV and RTD*/
+	{ 6, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, {1, 1, 0, 2, 1, 0, 1, 1}, {0xfff, 0x93f} }, /* DRAM for LPAV and RTD*/
+	{ 6, 3, DRAM_MEM_3_START, DRAM_MEM_3_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfc0, 0} }, /* DRAM for LPAV and RTD*/
+	{ 6, 4, DRAM_MEM_4_START, DRAM_MEM_4_SIZE, {1, 1, 0, 2, 1, 0, 1, 1}, {0xfff, 0x93f} }, /* DRAM for LPAV and RTD*/
+#else
+	{ 6, 0, DRAM_MEM_0_START, DRAM_MEM_0_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfff, 0} }, /* DRAM for LPAV and RTD*/
+	{ 6, 1, DRAM_MEM_1_START, DRAM_MEM_1_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfc0, 0} }, /* TEE DRAM for LPAV and RTD*/
+	{ 6, 2, DRAM_MEM_2_START, DRAM_MEM_2_SIZE, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfff, 0} }, /* DRAM for LPAV and RTD*/
+#endif
+#else
+	{ 4, 0, 0x80000000, 0x80000000, {0, 1, 0, 0, 0, 0, 0, 1}, {0xfff, 0} }, /* DRAM for A35, DMA1, USDHC0*/
+	{ 5, 0, 0x80000000, 0x80000000, {0, 1, 0, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for NIC_PER */
+	{ 6, 0, 0x80000000, 0x80000000, {1, 1, 0, 1, 1, 0, 1, 1}, {0xfff, 0} }, /* DRAM for LPAV and RTD*/
+#endif
+	{ 7, 0, 0x80000000, 0x10000000, {0, 0, 1, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for HIFI4 */
+	{ 7, 1, 0x90000000, 0x10000000, {0, 0, 1, 0, 0, 0, 0, 0}, {0xfff, 0} }, /* DRAM for HIFI4 */
+	{ 8, 0, 0x21000000, 0x10000,    {1, 1, 1, 1, 1, 0, 1, 1}, {0xfff, 0} }, /* SRAM1 */
+	{ 9, 0, 0x1ffc0000, 0xc0000,    {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0} }, /* SSRAM for HIFI4 */
+	{ 10, 0, 0x1ffc0000, 0xc0000,   {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0} }, /* SSRAM for LPAV */
+	{ 11, 0, 0x21170000, 0x10000,   {0, 0, 1, 0, 0, 0, 0, 2}, {0xfff, SP(RW) | SU(RW) | NP(RW)} }, /* HIFI4 TCM */
+	{ 11, 1, 0x21180000, 0x10000,   {0, 0, 1, 0, 0, 0, 0, 2}, {SP(RW) | SU(RW) | NP(RW) | NU(RW), SP(RW) | SU(RW) | NP(RW)} }, /* HIFI4 TCM */
+	{ 12, 0, 0x2d400000, 0x100000,  {0, 0, 0, 0, 0, 0, 0, 1}, {SP(RW) | SU(RW) | NP(RW) | NU(RW), 0} }, /* GIC500 */
+};
+
+struct xrdc_pac_msc_config imx8ulp_pdac[] = {
+	{ 0, PAC_SLOT_ALL, {0, 7, 0, 0, 0, 0, 0, 7} }, /* PAC0 */
+	{ 0, 44, {0, 7, 7, 0, 0, 0, 0, 7} }, /* PAC0 slot 44 for CGC1 */
+	{ 0, 36, {0, 0, 0, 0, 0, 0, 7, 7} }, /* PAC0 slot 36 for CMC1 */
+	{ 0, 41, {0, 0, 0, 0, 0, 0, 7, 7} }, /* PAC0 slot 41 for SIM_AD */
+	{ 1, PAC_SLOT_ALL, {0, 7, 0, 0, 0, 0, 0, 7} }, /* PAC1 */
+	{ 1, 0, {0, 7, 7, 0, 0, 0, 7, 7} }, /* PAC1 slot 0 for PCC4 */
+	{ 1, 6, {0, 7, 7, 0, 0, 0, 0, 7} }, /* PAC1 slot 6 for LPUART6 */
+	{ 1, 7, {0, 7, 7, 0, 0, 0, 0, 7} }, /* PAC1 slot 7 for LPUART7 */
+	{ 1, 9,  {0, 7, 7, 7, 0, 0, 0, 7} }, /* SAI5 for HIFI4 and eDMA2 */
+	{ 1, 12, {0, 7, 7, 0, 0, 0, 7, 7} }, /* PAC1 slot 12 for IOMUXC1 */
+	{ 2, PAC_SLOT_ALL, {7, 7, 7, 7, 0, 0, 7, 7} }, /* PAC2 */
+};
+
+struct xrdc_pac_msc_config imx8ulp_msc[] = {
+	{ 0, 0, {0, 0, 0, 0, 0, 0, 7, 7} }, /* MSC0 GPIOE */
+	{ 0, 1, {0, 0, 0, 0, 0, 0, 7, 7} }, /* MSC0 GPIOF */
+	{ 1, MSC_SLOT_ALL, {0, 0, 0, 0, 0, 0, 7, 7} }, /* MSC1 GPIOD */
+	{ 2, MSC_SLOT_ALL, {0, 0, 0, 0, 0, 0, 7, 7} }, /* MSC2 GPU3D/2D/DCNANO/DDR registers */
+};
diff --git a/plat/imx/imx8ulp/xrdc/xrdc_core.c b/plat/imx/imx8ulp/xrdc/xrdc_core.c
new file mode 100644
index 00000000..d022e4ca
--- /dev/null
+++ b/plat/imx/imx8ulp/xrdc/xrdc_core.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2020-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include "xrdc_config.h"
+
+#define XRDC_ADDR	0x292f0000
+#define MRC_OFFSET	0x2000
+#define MRC_STEP	0x200
+
+#define XRDC_MGR_PAC_ID	  U(0)
+#define XRDC_MGR_PAC_SLOT U(47)
+
+enum xrdc_comp_type {
+	MDA_TYPE = (1 << 16),
+	MRC_TYPE = (2 << 16),
+	PAC_TYPE = (3 << 16),
+	MSC_TYPE = (4 << 16),
+};
+
+enum xrdc_pd_type {
+	XRDC_AD_PD,
+	XRDC_HIFI_PD,
+	XRDC_AV_PD,
+};
+
+#define XRDC_TYPE_MASK (0x7 << 16)
+#define XRDC_ID_MASK 0xFFFF
+#define XRDC_ID(id) ((id) & XRDC_ID_MASK)
+
+typedef bool (*xrdc_check_func)(enum xrdc_comp_type type, uint16_t id);
+
+/* Access below XRDC needs enable PS 8
+ * and HIFI clocks and release HIFI firstly
+ */
+uint32_t hifi_xrdc_list[] = {
+	(MDA_TYPE | XRDC_ID(9)),
+	(MRC_TYPE | XRDC_ID(7)),
+	(MRC_TYPE | XRDC_ID(9)),
+	(MRC_TYPE | XRDC_ID(11)),
+};
+
+/* Access below XRDC needs enable PS 16 firstly */
+uint32_t av_periph_xrdc_list[] = {
+	(MDA_TYPE | XRDC_ID(10)),
+	(MDA_TYPE | XRDC_ID(11)),
+	(MDA_TYPE | XRDC_ID(12)),
+	(MDA_TYPE | XRDC_ID(13)),
+	(MDA_TYPE | XRDC_ID(14)),
+	(MDA_TYPE | XRDC_ID(15)),
+	(MDA_TYPE | XRDC_ID(16)),
+
+	(PAC_TYPE | XRDC_ID(2)),
+
+	(MRC_TYPE | XRDC_ID(6)),
+	(MRC_TYPE | XRDC_ID(8)),
+	(MRC_TYPE | XRDC_ID(10)),
+
+	(MSC_TYPE | XRDC_ID(1)),
+	(MSC_TYPE | XRDC_ID(2)),
+};
+
+uint32_t imx8ulp_pac_slots[] = {
+	61, 23, 53
+};
+
+uint32_t imx8ulp_msc_slots[] = {
+	2, 1, 7
+};
+
+static int xrdc_config_mrc_w0_w1(uint32_t mrc_con, uint32_t region, uint32_t w0, uint32_t size)
+{
+
+	uint32_t w0_addr, w1_addr;
+
+	w0_addr = XRDC_ADDR + MRC_OFFSET + mrc_con * 0x200 + region * 0x20;
+	w1_addr = w0_addr + 4;
+
+	if ((size % 32) != 0) {
+		return -EINVAL;
+	}
+
+	mmio_write_32(w0_addr, w0 & ~0x1f);
+	mmio_write_32(w1_addr, w0 + size - 1);
+
+	return 0;
+}
+
+static int xrdc_config_mrc_w2(uint32_t mrc_con, uint32_t region, uint32_t dxsel_all)
+{
+	uint32_t w2_addr;
+
+	w2_addr = XRDC_ADDR + MRC_OFFSET + mrc_con * 0x200 + region * 0x20 + 0x8;
+
+	mmio_write_32(w2_addr, dxsel_all);
+
+	return 0;
+}
+
+static int xrdc_config_mrc_w3_w4(uint32_t mrc_con, uint32_t region, uint32_t w3, uint32_t w4)
+{
+	uint32_t w3_addr = XRDC_ADDR + MRC_OFFSET + mrc_con * 0x200 + region * 0x20 + 0xC;
+	uint32_t w4_addr = w3_addr + 4;
+
+	mmio_write_32(w3_addr, w3);
+	mmio_write_32(w4_addr, w4);
+
+	return 0;
+}
+
+static int xrdc_config_pac(uint32_t pac, uint32_t index, uint32_t dxacp)
+{
+	uint32_t w0_addr;
+	uint32_t val;
+
+	if (pac > 2U) {
+		return -EINVAL;
+	}
+
+	/* Skip the PAC slot for XRDC MGR, use Sentinel configuration */
+	if (pac == XRDC_MGR_PAC_ID && index == XRDC_MGR_PAC_SLOT) {
+		return 0;
+	}
+
+	w0_addr = XRDC_ADDR + 0x1000 + 0x400 * pac + 0x8 * index;
+
+	mmio_write_32(w0_addr, dxacp);
+
+	val = mmio_read_32(w0_addr + 4);
+	mmio_write_32(w0_addr + 4, val | BIT_32(31));
+
+	return 0;
+}
+
+static int xrdc_config_msc(uint32_t msc, uint32_t index, uint32_t dxacp)
+{
+	uint32_t w0_addr;
+	uint32_t val;
+
+	if (msc > 2) {
+		return -EINVAL;
+	}
+
+	w0_addr = XRDC_ADDR + 0x4000 + 0x400 * msc + 0x8 * index;
+
+	mmio_write_32(w0_addr, dxacp);
+
+	val = mmio_read_32(w0_addr + 4);
+	mmio_write_32(w0_addr + 4, val | BIT_32(31));
+
+	return 0;
+}
+
+static int xrdc_config_mda(uint32_t mda_con, uint32_t dom, enum xrdc_mda_sa sa)
+{
+	uint32_t w0_addr;
+	uint32_t val;
+
+	w0_addr = XRDC_ADDR + 0x800 + mda_con * 0x20;
+
+	val = mmio_read_32(w0_addr);
+
+	if (val & BIT_32(29)) {
+		mmio_write_32(w0_addr, (val & (~0xFF)) | dom |
+			      BIT_32(31) | 0x20 | ((sa & 0x3) << 6));
+	} else {
+		mmio_write_32(w0_addr, dom | BIT_32(31));
+		mmio_write_32(w0_addr + 0x4, dom | BIT_32(31));
+	}
+
+	return 0;
+}
+
+static bool xrdc_check_pd(enum xrdc_comp_type type,
+			  uint16_t id, enum xrdc_pd_type pd)
+{
+	unsigned int i, size;
+	uint32_t item = type | XRDC_ID(id);
+	uint32_t *list;
+
+	if (pd == XRDC_HIFI_PD) {
+		size = ARRAY_SIZE(hifi_xrdc_list);
+		list = hifi_xrdc_list;
+	} else if (pd == XRDC_AV_PD) {
+		size = ARRAY_SIZE(av_periph_xrdc_list);
+		list = av_periph_xrdc_list;
+	} else {
+		return false;
+	}
+
+	for (i = 0U; i < size; i++) {
+		if (item == list[i]) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static bool xrdc_check_lpav(enum xrdc_comp_type type, uint16_t id)
+{
+	return xrdc_check_pd(type, id, XRDC_AV_PD);
+}
+
+static bool xrdc_check_hifi(enum xrdc_comp_type type, uint16_t id)
+{
+	return xrdc_check_pd(type, id, XRDC_HIFI_PD);
+}
+
+static bool xrdc_check_ad(enum xrdc_comp_type type, uint16_t id)
+{
+	return (!xrdc_check_pd(type, id, XRDC_HIFI_PD) &&
+			!xrdc_check_pd(type, id, XRDC_AV_PD));
+}
+
+static int xrdc_apply_config(xrdc_check_func check_func)
+{
+	unsigned int i, j;
+	uint32_t val;
+
+	for (i = 0U; i < ARRAY_SIZE(imx8ulp_mda); i++) {
+		if (check_func(MDA_TYPE, imx8ulp_mda[i].mda_id)) {
+			xrdc_config_mda(imx8ulp_mda[i].mda_id,
+					imx8ulp_mda[i].did, imx8ulp_mda[i].sa);
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(imx8ulp_mrc); i++) {
+		if (check_func(MRC_TYPE, imx8ulp_mrc[i].mrc_id)) {
+			xrdc_config_mrc_w0_w1(imx8ulp_mrc[i].mrc_id,
+					      imx8ulp_mrc[i].region_id,
+					      imx8ulp_mrc[i].region_start,
+					      imx8ulp_mrc[i].region_size);
+
+			val = 0;
+			for (j = 0U; j < DID_MAX; j++) {
+				val |= imx8ulp_mrc[i].dsel[j] << (3 * j);
+			}
+
+			xrdc_config_mrc_w2(imx8ulp_mrc[i].mrc_id, imx8ulp_mrc[i].region_id, val);
+			xrdc_config_mrc_w3_w4(imx8ulp_mrc[i].mrc_id, imx8ulp_mrc[i].region_id,
+				0, imx8ulp_mrc[i].accset[0] | (imx8ulp_mrc[i].accset[1] << 16) | BIT_32(31));
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(imx8ulp_pdac); i++) {
+		if (check_func(PAC_TYPE, imx8ulp_pdac[i].pac_msc_id)) {
+			val = 0;
+			for (j = 0U; j < DID_MAX; j++) {
+				val |= imx8ulp_pdac[i].dsel[j] << (3 * j);
+			}
+
+			if (imx8ulp_pdac[i].slot_id == PAC_SLOT_ALL) {
+				/* Apply to all slots*/
+				for (j = 0U; j < imx8ulp_pac_slots[imx8ulp_pdac[i].pac_msc_id]; j++) {
+					xrdc_config_pac(imx8ulp_pdac[i].pac_msc_id, j, val);
+				}
+			} else {
+				if (imx8ulp_pdac[i].slot_id >= imx8ulp_pac_slots[imx8ulp_pdac[i].pac_msc_id]) {
+					return -EINVAL;
+				}
+
+				xrdc_config_pac(imx8ulp_pdac[i].pac_msc_id, imx8ulp_pdac[i].slot_id, val);
+			}
+		}
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(imx8ulp_msc); i++) {
+		if (check_func(MSC_TYPE, imx8ulp_msc[i].pac_msc_id)) {
+			val = 0;
+			for (j = 0U; j < DID_MAX; j++) {
+				val |= imx8ulp_msc[i].dsel[j] << (3 * j);
+			}
+
+			if (imx8ulp_msc[i].slot_id == MSC_SLOT_ALL) {
+				/* Apply to all slots*/
+				for (j = 0U; j < imx8ulp_msc_slots[imx8ulp_msc[i].pac_msc_id]; j++) {
+					xrdc_config_msc(imx8ulp_msc[i].pac_msc_id, j, val);
+				}
+			} else {
+				if (imx8ulp_msc[i].slot_id >= imx8ulp_msc_slots[imx8ulp_msc[i].pac_msc_id]) {
+					return -EINVAL;
+				}
+
+				xrdc_config_msc(imx8ulp_msc[i].pac_msc_id, imx8ulp_msc[i].slot_id, val);
+			}
+		}
+	}
+
+	return 0;
+}
+
+int xrdc_apply_lpav_config(void)
+{
+	/* Configure PAC2 to allow to access PCC5 */
+	xrdc_config_pac(2, 39, 0xe00000);
+
+	/* Enable the eDMA2 MP clock for MDA16 access */
+	mmio_write_32(IMX_PCC5_BASE + 0x0, 0xc0000000);
+	return xrdc_apply_config(xrdc_check_lpav);
+}
+
+int xrdc_apply_hifi_config(void)
+{
+	return xrdc_apply_config(xrdc_check_hifi);
+}
+
+int xrdc_apply_apd_config(void)
+{
+	return xrdc_apply_config(xrdc_check_ad);
+}
+
+void xrdc_enable(void)
+{
+	mmio_write_32(XRDC_ADDR, BIT(14) | BIT(15) | BIT(0));
+}
diff --git a/plat/imx/imx93/imx93_bl31_setup.c b/plat/imx/imx93/imx93_bl31_setup.c
index 8458f6c1..d997e9a8 100644
--- a/plat/imx/imx93/imx93_bl31_setup.c
+++ b/plat/imx/imx93/imx93_bl31_setup.c
@@ -20,6 +20,7 @@
 #include <plat/common/platform.h>
 
 #include <imx8_lpuart.h>
+#include <plat_common.h>
 #include <plat_imx8.h>
 #include <platform_def.h>
 
@@ -90,6 +91,9 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	bl33_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 	bl32_image_ep_info.args.arg3 = BL32_FDT_OVERLAY_ADDR;
 #endif
+
+	imx_bl31_params_parse(arg0, OCRAM_BASE, OCRAM_SIZE,
+				    &bl32_image_ep_info, &bl33_image_ep_info);
 }
 
 void bl31_plat_arch_setup(void)
@@ -136,11 +140,6 @@ void bl31_platform_setup(void)
 	plat_gic_init();
 }
 
-void bl31_plat_runtime_setup(void)
-{
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
-}
-
 entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
 {
 	if (type == NON_SECURE) {
diff --git a/plat/imx/imx93/include/platform_def.h b/plat/imx/imx93/include/platform_def.h
index 7efbf1c6..f0d53cde 100644
--- a/plat/imx/imx93/include/platform_def.h
+++ b/plat/imx/imx93/include/platform_def.h
@@ -31,6 +31,9 @@
 #define BL31_BASE			U(0x204E0000)
 #define BL31_LIMIT			U(0x20520000)
 
+#define OCRAM_BASE			U(0x20480000)
+#define OCRAM_SIZE			U(0xA0000)
+
 /* non-secure uboot base */
 /* TODO */
 #define PLAT_NS_IMAGE_OFFSET		U(0x80200000)
diff --git a/plat/imx/imx93/platform.mk b/plat/imx/imx93/platform.mk
index ed7e81f9..f506d8b1 100644
--- a/plat/imx/imx93/platform.mk
+++ b/plat/imx/imx93/platform.mk
@@ -19,9 +19,11 @@ IMX_GIC_SOURCES		:=	${GICV3_SOURCES}			\
 				plat/common/plat_psci_common.c		\
 				plat/imx/common/plat_imx8_gic.c
 
-BL31_SOURCES		+=	plat/common/aarch64/crash_console_helpers.S   \
+BL31_SOURCES		+=	common/desc_image_load.c			\
+				plat/common/aarch64/crash_console_helpers.S	\
 				plat/imx/imx93/aarch64/plat_helpers.S		\
 				plat/imx/imx93/plat_topology.c			\
+				plat/imx/common/imx_common.c			\
 				plat/imx/common/lpuart_console.S		\
 				plat/imx/imx93/trdc.c			\
 				plat/imx/imx93/pwr_ctrl.c			\
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 211a7b73..084539e8 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,7 +29,9 @@
 #include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 #include "socfpga_reset_manager.h"
+#include "socfpga_ros.h"
 #include "socfpga_system_manager.h"
+#include "socfpga_vab.h"
 #include "wdt/watchdog.h"
 
 static struct mmc_device_info mmc_info;
@@ -92,6 +95,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
 void bl2_el3_plat_arch_setup(void)
 {
 
+	unsigned long offset = 0;
 	const mmap_region_t bl_regions[] = {
 		MAP_REGION_FLAT(BL2_BASE, BL2_END - BL2_BASE,
 			MT_MEMORY | MT_RW | MT_SECURE),
@@ -110,7 +114,10 @@ void bl2_el3_plat_arch_setup(void)
 
 	setup_page_tables(bl_regions, agilex_plat_mmap);
 
-	enable_mmu_el3(0);
+	/*
+	 * TODO: mmu enable in latest phase
+	 */
+	// enable_mmu_el3(0);
 
 	dw_mmc_params_t params = EMMC_INIT_PARAMS(0x100000, get_mmc_clk());
 
@@ -122,15 +129,20 @@ void bl2_el3_plat_arch_setup(void)
 
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
+		NOTICE("SDMMC boot\n");
 		dw_mmc_init(&params, &mmc_info);
-		socfpga_io_setup(boot_source);
+		socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
 		break;
 
 	case BOOT_SOURCE_QSPI:
+		NOTICE("QSPI boot\n");
 		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
 			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
 			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
-		socfpga_io_setup(boot_source);
+		if (ros_qspi_get_ssbl_offset(&offset) != ROS_RET_OK) {
+			offset = PLAT_QSPI_DATA_BASE;
+		}
+		socfpga_io_setup(boot_source, offset);
 		break;
 
 	default:
@@ -168,6 +180,20 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 
 	assert(bl_mem_params);
 
+#if SOCFPGA_SECURE_VAB_AUTH
+	/*
+	 * VAB Authentication start here.
+	 * If failed to authenticate, shall not proceed to process BL31 and hang.
+	 */
+	int ret = 0;
+
+	ret = socfpga_vab_init(image_id);
+	if (ret < 0) {
+		ERROR("SOCFPGA VAB Authentication failed\n");
+		wfi();
+	}
+#endif
+
 	switch (image_id) {
 	case BL33_IMAGE_ID:
 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
@@ -186,4 +212,3 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 void bl2_platform_setup(void)
 {
 }
-
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index b4e19def..4c10e7bd 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,12 +14,16 @@
 #include <drivers/ti/uart/uart_16550.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables.h>
+#include <plat/common/platform.h>
 
 #include "ccu/ncore_ccu.h"
 #include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 #include "socfpga_sip_svc.h"
 
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void);
+
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
 
@@ -59,9 +64,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
 	static console_t console;
-
 	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
-
 	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
 		PLAT_BAUDRATE, &console);
 	/*
@@ -69,6 +72,33 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	 */
 	void *from_bl2 = (void *) arg0;
 
+#if RESET_TO_BL31
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(from_bl2 == NULL);
+	void *plat_params_from_bl2 = (void *) arg3;
+
+	assert(plat_params_from_bl2 == NULL);
+
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+
+# if ARM_LINUX_KERNEL_AS_BL33
+	/*
+	 * According to the file ``Documentation/arm64/booting.txt`` of the
+	 * Linux kernel tree, Linux expects the physical address of the device
+	 * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+	 * must be 0.
+	 */
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+# endif
+
+#else /* RESET_TO_BL31 */
 	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
 	assert(params_from_bl2 != NULL);
 
@@ -76,28 +106,38 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	 * Copy BL32 (if populated by BL31) and BL33 entry point information.
 	 * They are stored in Secure RAM, in BL31's address space.
 	 */
-
 	if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
 		params_from_bl2->h.version >= VERSION_2) {
-
 		bl_params_node_t *bl_params = params_from_bl2->head;
-
 		while (bl_params) {
 			if (bl_params->image_id == BL33_IMAGE_ID)
 				bl33_image_ep_info = *bl_params->ep_info;
-
 			bl_params = bl_params->next_params_info;
 		}
 	} else {
 		struct socfpga_bl31_params *arg_from_bl2 =
 			(struct socfpga_bl31_params *) from_bl2;
-
 		assert(arg_from_bl2->h.type == PARAM_BL31);
 		assert(arg_from_bl2->h.version >= VERSION_1);
-
 		bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
 		bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
 	}
+
+	bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
+	bl33_image_ep_info.args.arg1 = 0U;
+	bl33_image_ep_info.args.arg2 = 0U;
+	bl33_image_ep_info.args.arg3 = 0U;
+#endif
+
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+# if ARM_LINUX_KERNEL_AS_BL33
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry();
+#endif
+
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 }
 
@@ -136,8 +176,6 @@ void bl31_platform_setup(void)
 		(uint64_t)plat_secondary_cpus_bl31_entry);
 
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
-
-	ncore_enable_ocram_firewall();
 }
 
 const mmap_region_t plat_agilex_mmap[] = {
@@ -174,8 +212,34 @@ void bl31_plat_arch_setup(void)
 #endif
 		{0}
 	};
-
 	setup_page_tables(bl_regions, plat_agilex_mmap);
 	enable_mmu_el3(0);
 }
 
+/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+	return PRELOADED_BL33_BASE;
+#else
+	return PLAT_NS_IMAGE_OFFSET;
+#endif
+}
+
+/* Get non-secure SPSR for BL33. Zephyr and Linux */
+uint32_t arm_get_spsr_for_bl33_entry(void)
+{
+	unsigned int mode;
+	uint32_t spsr;
+
+	/* Figure out what mode we enter the non-secure world in */
+	mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h
index ee222418..2ca69478 100644
--- a/plat/intel/soc/agilex/include/agilex_clock_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h
@@ -129,5 +129,6 @@ uint32_t get_uart_clk(void);
 uint32_t get_mmc_clk(void);
 uint32_t get_mpu_clk(void);
 uint32_t get_cpu_clk(void);
+uint32_t get_mpu_periph_clk(void);
 
 #endif
diff --git a/plat/intel/soc/agilex/include/agilex_memory_controller.h b/plat/intel/soc/agilex/include/agilex_memory_controller.h
index 9db4292e..f0bbeea0 100644
--- a/plat/intel/soc/agilex/include/agilex_memory_controller.h
+++ b/plat/intel/soc/agilex/include/agilex_memory_controller.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +28,7 @@
 #define AGX_MPFE_HMC_ADP_ECCCTRL1			0xf8011100
 #define AGX_MPFE_HMC_ADP_ECCCTRL2			0xf8011104
 #define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT		0xf8011218
-#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x000000ff
+#define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x0000000f
 #define AGX_MPFE_HMC_ADP_RSTHANDSHAKECTRL		0xf8011214
 
 
diff --git a/plat/intel/soc/agilex/include/agilex_system_manager.h b/plat/intel/soc/agilex/include/agilex_system_manager.h
index cb9222d5..78aabde6 100644
--- a/plat/intel/soc/agilex/include/agilex_system_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -121,7 +122,7 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
 #define SOCFPGA_SYSMGR_MPFE_CONFIG			0x228
-#define SOCFPGA_SYSMGR_MPFE_status			0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS			0x22C
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0		0x230
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1		0x234
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2		0x238
@@ -143,6 +144,18 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_8		0x278
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_9		0x27C
 
+/* QSPI ECC from SDM register */
+#define SOCFPGA_ECC_QSPI_CTRL				0x08
+#define SOCFPGA_ECC_QSPI_ERRINTEN			0x10
+#define SOCFPGA_ECC_QSPI_ERRINTENS			0x14
+#define SOCFPGA_ECC_QSPI_ERRINTENR			0x18
+#define SOCFPGA_ECC_QSPI_INTMODE			0x1C
+#define SOCFPGA_ECC_QSPI_INTSTAT			0x20
+#define SOCFPGA_ECC_QSPI_INTTEST			0x24
+#define SOCFPGA_ECC_QSPI_ECC_ACCCTRL			0x78
+#define SOCFPGA_ECC_QSPI_ECC_STARTACC			0x7C
+#define SOCFPGA_ECC_QSPI_ECC_WDCTRL			0x80
+
 #define DMA0_STREAM_CTRL_REG				0x10D1217C
 #define DMA1_STREAM_CTRL_REG				0x10D12180
 #define SDM_STREAM_CTRL_REG				0x10D12184
@@ -183,6 +196,9 @@
 #define RMMUSECSID_REG_VAL				BIT(5)
 
 /* Macros */
+#define SOCFPGA_ECC_QSPI(_reg)				(SOCFPGA_ECC_QSPI_REG_BASE \
+								+ (SOCFPGA_ECC_QSPI_##_reg))
+
 #define SOCFPGA_SYSMGR(_reg)				(SOCFPGA_SYSMGR_REG_BASE \
 								+ (SOCFPGA_SYSMGR_##_reg))
 
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index a744d093..840ffdd6 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,14 +10,21 @@
 #define PLAT_SOCFPGA_DEF_H
 
 #include "agilex_system_manager.h"
+#include <lib/utils_def.h>
 #include <platform_def.h>
 
 /* Platform Setting */
-#define PLATFORM_MODEL						PLAT_SOCFPGA_AGILEX
-#define BOOT_SOURCE							BOOT_SOURCE_SDMMC
-#define PLAT_PRIMARY_CPU					0
+#define PLATFORM_MODEL				PLAT_SOCFPGA_AGILEX
+/* 1 = Flush cache, 0 = No cache flush.
+ * Default for Agilex is No cache flush.
+ * For Agilex FP8, set to Flush cache.
+ */
+#define CACHE_FLUSH				0
+#define PLAT_PRIMARY_CPU			0
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
-#define PLAT_CPU_ID_MPIDR_AFF_SHIFT			MPIDR_AFF0_SHIFT
+#define PLAT_CPU_ID_MPIDR_AFF_SHIFT		MPIDR_AFF0_SHIFT
+#define PLAT_HANDOFF_OFFSET			0xFFE3F000
+#define PLAT_TIMER_BASE_ADDR			0xFFD01000
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
@@ -26,6 +34,25 @@
 #define CAD_QSPIDATA_OFST			0xff900000
 #define CAD_QSPI_OFFSET				0xff8d2000
 
+/* FIP Setting */
+#define PLAT_FIP_BASE				(0)
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_FIP_MAX_SIZE			(0x8000000)
+#else
+#define PLAT_FIP_MAX_SIZE			(0x1000000)
+#endif
+
+/* SDMMC Setting */
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_MMC_DATA_BASE			(0x10000000)
+#define PLAT_MMC_DATA_SIZE			(0x100000)
+#define SOCFPGA_MMC_BLOCK_SIZE			U(32768)
+#else
+#define PLAT_MMC_DATA_BASE			(0xffe3c000)
+#define PLAT_MMC_DATA_SIZE			(0x2000
+#define SOCFPGA_MMC_BLOCK_SIZE			U(8192)
+#endif
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE		0xf7000000
 #define SOCFPGA_F2SDRAMMGR_REG_BASE		U(0xf8024000)
@@ -34,6 +61,7 @@
 #define SOCFPGA_MEMCTRL_REG_BASE		0xf8011100
 #define SOCFPGA_RSTMGR_REG_BASE			0xffd11000
 #define SOCFPGA_SYSMGR_REG_BASE			0xffd12000
+#define SOCFPGA_ECC_QSPI_REG_BASE		0xffa22000
 
 #define SOCFPGA_L4_PER_SCR_REG_BASE             0xffd21000
 #define SOCFPGA_L4_SYS_SCR_REG_BASE             0xffd21100
@@ -64,34 +92,39 @@
 #define DEVICE4_BASE				(0x2000000000)
 #define DEVICE4_SIZE				(0x0100000000)
 
-#define BL2_BASE		(0xffe00000)
-#define BL2_LIMIT		(0xffe1b000)
+#define BL2_BASE				(0xffe00000)
+#define BL2_LIMIT				(0xffe2b000)
 
-#define BL31_BASE		(0x1000)
-#define BL31_LIMIT		(0x81000)
+#define BL31_BASE				(0x1000)
+#define BL31_LIMIT				(0x81000)
 
 /*******************************************************************************
  * UART related constants
  ******************************************************************************/
-#define PLAT_UART0_BASE		(0xFFC02000)
-#define PLAT_UART1_BASE		(0xFFC02100)
+#define PLAT_UART0_BASE				(0xFFC02000)
+#define PLAT_UART1_BASE				(0xFFC02100)
+
+/*******************************************************************************
+ * WDT related constants
+ ******************************************************************************/
+#define WDT_BASE			(0xFFD00200)
 
 /*******************************************************************************
  * GIC related constants
  ******************************************************************************/
-#define PLAT_GIC_BASE			(0xFFFC0000)
-#define PLAT_GICC_BASE			(PLAT_GIC_BASE + 0x2000)
-#define PLAT_GICD_BASE			(PLAT_GIC_BASE + 0x1000)
-#define PLAT_GICR_BASE			0
+#define PLAT_GIC_BASE				(0xFFFC0000)
+#define PLAT_GICC_BASE				(PLAT_GIC_BASE + 0x2000)
+#define PLAT_GICD_BASE				(PLAT_GIC_BASE + 0x1000)
+#define PLAT_GICR_BASE				0
 
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
-#define PLAT_HZ_CONVERT_TO_MHZ	(1000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS		(400000000)
+#define PLAT_HZ_CONVERT_TO_MHZ		(1000000)
 
 /*******************************************************************************
  * SDMMC related pointer function
  ******************************************************************************/
-#define SDMMC_READ_BLOCKS	mmc_read_blocks
-#define SDMMC_WRITE_BLOCKS	mmc_write_blocks
+#define SDMMC_READ_BLOCKS			sdmmc_read_blocks
+#define SDMMC_WRITE_BLOCKS			mmc_write_blocks
 
 /*******************************************************************************
  * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
@@ -100,6 +133,6 @@
 #define L2_RESET_DONE_REG			0xFFD12218
 
 /* Platform specific system counter */
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ		U(400)
 
 #endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 5c92f725..d534b2ef 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -1,6 +1,7 @@
 #
 # Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2024, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -27,6 +28,8 @@ PLAT_BL_COMMON_SOURCES	:=	\
 			plat/intel/soc/common/aarch64/platform_common.c \
 			plat/intel/soc/common/aarch64/plat_helpers.S	\
 			plat/intel/soc/common/drivers/ccu/ncore_ccu.c	\
+			plat/intel/soc/common/drivers/sdmmc/sdmmc.c			\
+			plat/intel/soc/common/lib/sha/sha.c				\
 			plat/intel/soc/common/socfpga_delay_timer.c
 
 BL2_SOURCES     +=	\
@@ -47,12 +50,15 @@ BL2_SOURCES     +=	\
 		plat/intel/soc/agilex/soc/agilex_pinmux.c		\
 		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_image_load.c		\
+		plat/intel/soc/common/socfpga_ros.c			\
 		plat/intel/soc/common/socfpga_storage.c			\
+		plat/intel/soc/common/socfpga_vab.c				\
 		plat/intel/soc/common/soc/socfpga_emac.c		\
 		plat/intel/soc/common/soc/socfpga_firewall.c	\
 		plat/intel/soc/common/soc/socfpga_handoff.c		\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c	\
+		plat/intel/soc/common/drivers/ddr/ddr.c	\
 		plat/intel/soc/common/drivers/qspi/cadence_qspi.c	\
 		plat/intel/soc/common/drivers/wdt/watchdog.c
 
@@ -76,7 +82,38 @@ BL31_SOURCES	+=	\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33	:=	0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC		?=	0
+SOCFPGA_BOOT_SOURCE_QSPI		?=	0
+SOCFPGA_BOOT_SOURCE_NAND		?=	0
+
+$(eval $(call assert_booleans,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
+# Configs for VAB Authentication
+SOCFPGA_SECURE_VAB_AUTH  := 	0
+$(eval $(call assert_boolean,SOCFPGA_SECURE_VAB_AUTH))
+$(eval $(call add_define,SOCFPGA_SECURE_VAB_AUTH))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
 USE_COHERENT_MEM		:= 1
+
+HANDLE_EA_EL3_FIRST_NS			:= 1
\ No newline at end of file
diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
index d32c3f14..391eac63 100644
--- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
@@ -398,12 +398,36 @@ uint32_t get_mpu_clk(void)
 	return mpu_clk;
 }
 
+uint32_t get_l4_clk(void)
+{
+	uint32_t l4_clk;
+
+	l4_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC1,
+				CLKMGR_PERPLL_PLLC1);
+	return l4_clk;
+}
+
 /* Get cpu freq clock */
 uint32_t get_cpu_clk(void)
 {
 	uint32_t cpu_clk;
 
-	cpu_clk = get_mpu_clk()/PLAT_HZ_CONVERT_TO_MHZ;
+	cpu_clk = get_l4_clk()/PLAT_HZ_CONVERT_TO_MHZ;
 
 	return cpu_clk;
 }
+
+/* Return mpu_periph_clk clock frequency */
+uint32_t get_mpu_periph_clk(void)
+{
+	uint32_t mpu_periph_clk = 0;
+	/* mpu_periph_clk is mpu_clk, via a static /4 divider  */
+	mpu_periph_clk = (get_mpu_clk()/4)/PLAT_HZ_CONVERT_TO_MHZ;
+	return mpu_periph_clk;
+}
+
+/* Return mpu_periph_clk tick */
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return PLAT_SYS_COUNTER_FREQ_IN_TICKS;
+}
diff --git a/plat/intel/soc/agilex5/bl2_plat_setup.c b/plat/intel/soc/agilex5/bl2_plat_setup.c
index a2fafd2f..fe5dc6e7 100644
--- a/plat/intel/soc/agilex5/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl2_plat_setup.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,9 +20,11 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 #include "agilex5_clock_manager.h"
+#include "agilex5_ddr.h"
 #include "agilex5_memory_controller.h"
 #include "agilex5_mmc.h"
 #include "agilex5_pinmux.h"
+#include "agilex5_power_manager.h"
 #include "agilex5_system_manager.h"
 #include "ccu/ncore_ccu.h"
 #include "combophy/combophy.h"
@@ -34,6 +37,8 @@
 #include "socfpga_mailbox.h"
 #include "socfpga_private.h"
 #include "socfpga_reset_manager.h"
+#include "socfpga_ros.h"
+#include "socfpga_vab.h"
 #include "wdt/watchdog.h"
 
 
@@ -63,35 +68,94 @@ const mmap_region_t agilex_plat_mmap[] = {
 
 boot_source_type boot_source = BOOT_SOURCE;
 
-void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
-				u_register_t x2, u_register_t x4)
+void bl2_el3_early_platform_setup(u_register_t x0 __unused,
+				  u_register_t x1 __unused,
+				  u_register_t x2 __unused,
+				  u_register_t x3 __unused)
 {
 	static console_t console;
+	handoff reverse_handoff_ptr;
+
+	/* Enable nonsecure access for peripherals and other misc components */
+	enable_nonsecure_access();
+
+	/* Bring all the required peripherals out of reset */
+	deassert_peripheral_reset();
 
-	handoff reverse_handoff_ptr = { 0 };
+	/*
+	 * Initialize the UART console early in BL2 EL3 boot flow to get
+	 * the error/notice messages wherever required.
+	 */
+	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
+			       PLAT_BAUDRATE, &console);
 
+	/* Generic delay timer init */
 	generic_delay_timer_init();
-	config_clkmgr_handoff(&reverse_handoff_ptr);
+
+	socfpga_delay_timer_init();
+
+	/* Get the handoff data */
+	if ((socfpga_get_handoff(&reverse_handoff_ptr)) != 0) {
+		ERROR("SOCFPGA: Failed to get the correct handoff data\n");
+		panic();
+	}
+
+	/* Configure the pinmux */
+	config_pinmux(&reverse_handoff_ptr);
+
+	/* Configure OCRAM to NON SECURE ACCESS */
+	mmio_write_32(OCRAM_REGION_0_REG_BASE, OCRAM_NON_SECURE_ENABLE);
+	mmio_write_32(SOCFPGA_L4_PER_SCR_REG_BASE + SOCFPGA_SDMMC_SECU_BIT,
+		SOCFPGA_SDMMC_SECU_BIT_ENABLE);
+	mmio_write_32(SOCFPGA_L4_SYS_SCR_REG_BASE + SOCFPGA_SDMMC_SECU_BIT,
+		SOCFPGA_SDMMC_SECU_BIT_ENABLE);
+	mmio_write_32(SOCFPGA_LWSOC2FPGA_SCR_REG_BASE,
+		SOCFPGA_LWSOC2FPGA_ENABLE);
+
+	/* Configure the clock manager */
+	if ((config_clkmgr_handoff(&reverse_handoff_ptr)) != 0) {
+		ERROR("SOCFPGA: Failed to initialize the clock manager\n");
+		panic();
+	}
+
+	/* Configure power manager PSS SRAM power gate */
+	config_pwrmgr_handoff(&reverse_handoff_ptr);
+
+	/* Initialize the mailbox to enable communication between HPS and SDM */
 	mailbox_init();
-	enable_nonsecure_access();
 
-	deassert_peripheral_reset();
+	/* Perform a handshake with certain peripherals before issuing a reset */
+	config_hps_hs_before_warm_reset();
+
+	/* TODO: watchdog init */
+	//watchdog_init(clkmgr_get_rate(CLKMGR_WDT_CLK_ID));
+
+	/* Initialize the CCU module for hardware cache coherency */
+	init_ncore_ccu();
+
+	socfpga_emac_init();
+
+	/* DDR and IOSSM driver init */
+	agilex5_ddr_init(&reverse_handoff_ptr);
+
 	if (combo_phy_init(&reverse_handoff_ptr) != 0) {
-		ERROR("Combo Phy initialization failed\n");
+		ERROR("SOCFPGA: Combo Phy initialization failed\n");
 	}
 
-	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
-	PLAT_BAUDRATE, &console);
-
-	/* Store magic number */
-	mmio_write_32(L2_RESET_DONE_REG, PLAT_L2_RESET_REQ);
+	/* Enable FPGA bridges as required */
+	if (!intel_mailbox_is_fpga_not_ready()) {
+		socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
+				       FPGA2SOC_MASK | F2SDRAM0_MASK);
+	}
 }
 
 void bl2_el3_plat_arch_setup(void)
 {
 	handoff reverse_handoff_ptr;
+	unsigned long offset = 0;
 
-	struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc, get_mmc_clk());
+	struct cdns_sdmmc_params params = EMMC_INIT_PARAMS((uintptr_t) &cdns_desc,
+							   clkmgr_get_rate(CLKMGR_SDMMC_CLK_ID));
 
 	mmc_info.mmc_dev_type = MMC_DEVICE_TYPE;
 	mmc_info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3;
@@ -102,8 +166,8 @@ void bl2_el3_plat_arch_setup(void)
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
 		NOTICE("SDMMC boot\n");
-		sdmmc_init(&reverse_handoff_ptr, &params, &mmc_info);
-		socfpga_io_setup(boot_source);
+		cdns_mmc_init(&params, &mmc_info);
+		socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
 		break;
 
 	case BOOT_SOURCE_QSPI:
@@ -111,13 +175,16 @@ void bl2_el3_plat_arch_setup(void)
 		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
 			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
 			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
-		socfpga_io_setup(boot_source);
+		if (ros_qspi_get_ssbl_offset(&offset) != ROS_RET_OK) {
+			offset = PLAT_QSPI_DATA_BASE;
+		}
+		socfpga_io_setup(boot_source, offset);
 		break;
 
 	case BOOT_SOURCE_NAND:
 		NOTICE("NAND boot\n");
 		nand_init(&reverse_handoff_ptr);
-		socfpga_io_setup(boot_source);
+		socfpga_io_setup(boot_source, PLAT_NAND_DATA_BASE);
 		break;
 
 	default:
@@ -154,6 +221,20 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 
 	assert(bl_mem_params);
 
+#if SOCFPGA_SECURE_VAB_AUTH
+	/*
+	 * VAB Authentication start here.
+	 * If failed to authenticate, shall not proceed to process BL31 and hang.
+	 */
+	int ret = 0;
+
+	ret = socfpga_vab_init(image_id);
+	if (ret < 0) {
+		ERROR("SOCFPGA VAB Authentication failed\n");
+		wfi();
+	}
+#endif
+
 	switch (image_id) {
 	case BL33_IMAGE_ID:
 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index 5ae4bf77..c090117a 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -1,6 +1,7 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +18,7 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 
+#include "agilex5_cache.h"
 #include "agilex5_power_manager.h"
 #include "ccu/ncore_ccu.h"
 #include "socfpga_mailbox.h"
@@ -56,9 +58,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY);
 
 	console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK,
-	PLAT_BAUDRATE, &console);
+			       PLAT_BAUDRATE, &console);
 
-	init_ncore_ccu();
 	setup_smmu_stream_id();
 
 	/*
@@ -167,10 +168,6 @@ void bl31_platform_setup(void)
 	gicv3_rdistif_init(plat_my_core_pos());
 	gicv3_cpuif_enable(plat_my_core_pos());
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
-#if !defined(SIMICS_RUN)
-	ncore_enable_ocram_firewall();
-#endif
-
 }
 
 const mmap_region_t plat_agilex_mmap[] = {
@@ -186,18 +183,19 @@ const mmap_region_t plat_agilex_mmap[] = {
 
 /*******************************************************************************
  * Perform the very early platform specific architectural setup here. At the
- * moment this is only intializes the mmu in a quick and dirty way.
+ * moment this is only initializes the mmu in a quick and dirty way.
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
 	uint32_t boot_core = 0x00;
 	uint32_t cpuid = 0x00;
 
-	cpuid = read_mpidr();
-	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
+	cpuid = MPIDR_AFFLVL1_VAL(read_mpidr());
+	boot_core = ((mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00) >> 10);
 	NOTICE("BL31: Boot Core = %x\n", boot_core);
 	NOTICE("BL31: CPU ID = %x\n", cpuid);
-
+	INFO("BL31: Invalidate Data cache\n");
+	invalidate_dcache_all();
 }
 
 /* Get non-secure image entrypoint for BL33. Zephyr and Linux */
@@ -236,6 +234,9 @@ void bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id)
 	unsigned int pchctlr_new = 0x00;
 	uint32_t boot_core = 0x00;
 
+	/* Store magic number for SMP secondary cores boot */
+	mmio_write_32(L2_RESET_DONE_REG, SMP_SEC_CORE_BOOT_REQ);
+
 	boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00);
 	/* Update the p-channel based on cpu id */
 	pch_cpu = 1 << cpu_id;
diff --git a/plat/intel/soc/agilex5/include/agilex5_cache.h b/plat/intel/soc/agilex5/include/agilex5_cache.h
new file mode 100644
index 00000000..f7801b9a
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_cache.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGX5_CACHE_H
+#define AGX5_CACHE_H
+
+void invalidate_dcache_all(void);
+void invalidate_cache_low_el(void);
+
+#endif /* AGX5_CACHE_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_clock_manager.h b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
index 566a80d9..1165c904 100644
--- a/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_clock_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,141 +11,304 @@
 #include "socfpga_handoff.h"
 
 /* Clock Manager Registers */
-#define CLKMGR_OFFSET					0x10d10000
-
-#define CLKMGR_CTRL					0x0
-#define CLKMGR_STAT					0x4
-#define CLKMGR_TESTIOCTROL				0x8
-#define CLKMGR_INTRGEN					0xc
-#define CLKMGR_INTRMSK					0x10
-#define CLKMGR_INTRCLR					0x14
-#define CLKMGR_INTRSTS					0x18
-#define CLKMGR_INTRSTK					0x1c
-#define CLKMGR_INTRRAW					0x20
+#define CLKMGR_BASE				0x10D10000
+#define CLKMGR_CTRL				0x00
+#define CLKMGR_STAT				0x04
+#define CLKMGR_TESTIOCTROL			0x08
+#define CLKMGR_INTRGEN				0x0C
+#define CLKMGR_INTRMSK				0x10
+#define CLKMGR_INTRCLR				0x14
+#define CLKMGR_INTRSTS				0x18
+#define CLKMGR_INTRSTK				0x1C
+#define CLKMGR_INTRRAW				0x20
+
+/* Clock manager control related macros */
+#define CLKMGR(_reg)				(CLKMGR_BASE + (CLKMGR_##_reg))
+#define CLKMGR_STAT_MAINPLLLOCKED		BIT(8)
+#define CLKMGR_STAT_PERPLLLOCKED		BIT(16)
+
+#define CLKMGR_INTRCLR_MAINLOCKLOST		BIT(2)
+#define CLKMGR_INTRCLR_PERLOCKLOST		BIT(3)
+
+#define CLKMGR_STAT_ALLPLLLOCKED		(CLKMGR_STAT_MAINPLLLOCKED | \
+						CLKMGR_STAT_PERPLLLOCKED)
 
 /* Main PLL Group */
-#define CLKMGR_MAINPLL					0x10d10024
-#define CLKMGR_MAINPLL_EN				0x0
-#define CLKMGR_MAINPLL_ENS				0x4
-#define CLKMGR_MAINPLL_BYPASS				0xc
-#define CLKMGR_MAINPLL_BYPASSS				0x10
-#define CLKMGR_MAINPLL_BYPASSR				0x14
-#define CLKMGR_MAINPLL_NOCCLK				0x1c
-#define CLKMGR_MAINPLL_NOCDIV				0x20
-#define CLKMGR_MAINPLL_PLLGLOB				0x24
-#define CLKMGR_MAINPLL_FDBCK				0x28
-#define CLKMGR_MAINPLL_MEM				0x2c
-#define CLKMGR_MAINPLL_MEMSTAT				0x30
-#define CLKMGR_MAINPLL_VCOCALIB				0x34
-#define CLKMGR_MAINPLL_PLLC0				0x38
-#define CLKMGR_MAINPLL_PLLC1				0x3c
-#define CLKMGR_MAINPLL_PLLC2				0x40
-#define CLKMGR_MAINPLL_PLLC3				0x44
-#define CLKMGR_MAINPLL_PLLM				0x48
-#define CLKMGR_MAINPLL_FHOP				0x4c
-#define CLKMGR_MAINPLL_SSC				0x50
-#define CLKMGR_MAINPLL_LOSTLOCK				0x54
+#define CLKMGR_MAINPLL_BASE			0x10D10024
+#define CLKMGR_MAINPLL_EN			0x00
+#define CLKMGR_MAINPLL_ENS			0x04
+#define CLKMGR_MAINPLL_ENR			0x08
+#define CLKMGR_MAINPLL_BYPASS			0x0C
+#define CLKMGR_MAINPLL_BYPASSS			0x10
+#define CLKMGR_MAINPLL_BYPASSR			0x14
+#define CLKMGR_MAINPLL_NOCCLK			0x1C
+#define CLKMGR_MAINPLL_NOCDIV			0x20
+#define CLKMGR_MAINPLL_PLLGLOB			0x24
+#define CLKMGR_MAINPLL_FDBCK			0x28
+#define CLKMGR_MAINPLL_MEM			0x2C
+#define CLKMGR_MAINPLL_MEMSTAT			0x30
+#define CLKMGR_MAINPLL_VCOCALIB			0x34
+#define CLKMGR_MAINPLL_PLLC0			0x38
+#define CLKMGR_MAINPLL_PLLC1			0x3C
+#define CLKMGR_MAINPLL_PLLC2			0x40
+#define CLKMGR_MAINPLL_PLLC3			0x44
+#define CLKMGR_MAINPLL_PLLM			0x48
+#define CLKMGR_MAINPLL_FHOP			0x4C
+#define CLKMGR_MAINPLL_SSC			0x50
+#define CLKMGR_MAINPLL_LOSTLOCK			0x54
+
+#define CLKMGR_MAINPLL(_reg)			(CLKMGR_MAINPLL_BASE + \
+							(CLKMGR_MAINPLL_##_reg))
+
+#define CLKMGR_XPLL_LOSTLOCK_BYPASSCLEAR	BIT(0)
+#define CLKMGR_XPLLGLOB_CLR_LOSTLOCK_BYPASS	BIT(29)
 
 /* Peripheral PLL Group */
-#define CLKMGR_PERPLL					0x10d1007c
-#define CLKMGR_PERPLL_EN				0x0
-#define CLKMGR_PERPLL_ENS				0x4
-#define CLKMGR_PERPLL_BYPASS				0xc
-#define CLKMGR_PERPLL_EMACCTL				0x18
-#define CLKMGR_PERPLL_GPIODIV				0x1c
-#define CLKMGR_PERPLL_PLLGLOB				0x20
-#define CLKMGR_PERPLL_FDBCK				0x24
-#define CLKMGR_PERPLL_MEM				0x28
-#define CLKMGR_PERPLL_MEMSTAT				0x2c
-#define CLKMGR_PERPLL_PLLC0				0x30
-#define CLKMGR_PERPLL_PLLC1				0x34
-#define CLKMGR_PERPLL_VCOCALIB				0x38
-#define CLKMGR_PERPLL_PLLC2				0x3c
-#define CLKMGR_PERPLL_PLLC3				0x40
-#define CLKMGR_PERPLL_PLLM				0x44
-#define CLKMGR_PERPLL_LOSTLOCK				0x50
+#define CLKMGR_PERPLL_BASE			0x10D1007C
+#define CLKMGR_PERPLL_EN			0x00
+#define CLKMGR_PERPLL_ENS			0x04
+#define CLKMGR_PERPLL_ENR			0x08
+#define CLKMGR_PERPLL_BYPASS			0x0C
+#define CLKMGR_PERPLL_BYPASSS			0x10
+#define CLKMGR_PERPLL_BYPASSR			0x14
+#define CLKMGR_PERPLL_EMACCTL			0x18
+#define CLKMGR_PERPLL_GPIODIV			0x1C
+#define CLKMGR_PERPLL_PLLGLOB			0x20
+#define CLKMGR_PERPLL_FDBCK			0x24
+#define CLKMGR_PERPLL_MEM			0x28
+#define CLKMGR_PERPLL_MEMSTAT			0x2C
+#define CLKMGR_PERPLL_VCOCALIB			0x30
+#define CLKMGR_PERPLL_PLLC0			0x34
+#define CLKMGR_PERPLL_PLLC1			0x38
+#define CLKMGR_PERPLL_PLLC2			0x3C
+#define CLKMGR_PERPLL_PLLC3			0x40
+#define CLKMGR_PERPLL_PLLM			0x44
+#define CLKMGR_PERPLL_FHOP			0x48
+#define CLKMGR_PERPLL_SSC			0x4C
+#define CLKMGR_PERPLL_LOSTLOCK			0x50
+
+#define CLKMGR_PERPLL(_reg)			(CLKMGR_PERPLL_BASE + \
+							(CLKMGR_PERPLL_##_reg))
 
 /* Altera Group */
-#define CLKMGR_ALTERA					0x10d100d0
-#define CLKMGR_ALTERA_JTAG				0x0
-#define CLKMGR_ALTERA_EMACACTR				0x4
-#define CLKMGR_ALTERA_EMACBCTR				0x8
-#define CLKMGR_ALTERA_EMACPTPCTR			0xc
-#define CLKMGR_ALTERA_GPIODBCTR				0x10
-#define CLKMGR_ALTERA_S2FUSER0CTR			0x18
-#define CLKMGR_ALTERA_S2FUSER1CTR			0x1c
-#define CLKMGR_ALTERA_PSIREFCTR				0x20
-#define CLKMGR_ALTERA_EXTCNTRST				0x24
-#define CLKMGR_ALTERA_USB31CTR				0x28
-#define CLKMGR_ALTERA_DSUCTR				0x2c
-#define CLKMGR_ALTERA_CORE01CTR				0x30
-#define CLKMGR_ALTERA_CORE23CTR				0x34
-#define CLKMGR_ALTERA_CORE2CTR				0x38
-#define CLKMGR_ALTERA_CORE3CTR				0x3c
-
-/* Membus */
-#define CLKMGR_MEM_REQ					BIT(24)
-#define CLKMGR_MEM_WR					BIT(25)
-#define CLKMGR_MEM_ERR					BIT(26)
-#define CLKMGR_MEM_WDAT_OFFSET				16
-#define CLKMGR_MEM_ADDR					0x4027
-#define CLKMGR_MEM_WDAT					0x80
+#define CLKMGR_ALTERA_BASE			0x10D100D0
+#define CLKMGR_ALTERA_JTAG			0x00
+#define CLKMGR_ALTERA_EMACACTR			0x04
+#define CLKMGR_ALTERA_EMACBCTR			0x08
+#define CLKMGR_ALTERA_EMACPTPCTR		0x0C
+#define CLKMGR_ALTERA_GPIODBCTR			0x10
+#define CLKMGR_ALTERA_S2FUSER0CTR		0x18
+#define CLKMGR_ALTERA_S2FUSER1CTR		0x1C
+#define CLKMGR_ALTERA_PSIREFCTR			0x20
+#define CLKMGR_ALTERA_EXTCNTRST			0x24
+#define CLKMGR_ALTERA_USB31CTR			0x28
+#define CLKMGR_ALTERA_DSUCTR			0x2C
+#define CLKMGR_ALTERA_CORE01CTR			0x30
+#define CLKMGR_ALTERA_CORE23CTR			0x34
+#define CLKMGR_ALTERA_CORE2CTR			0x38
+#define CLKMGR_ALTERA_CORE3CTR			0x3C
+#define CLKMGR_ALTERA_SERIAL_CON_PLL_CTR	0x40
+
+#define CLKMGR_ALTERA(_reg)			(CLKMGR_ALTERA_BASE + \
+							(CLKMGR_ALTERA_##_reg))
+
+#define CLKMGR_ALTERA_EXTCNTRST_EMACACNTRST	BIT(0)
+#define CLKMGR_ALTERA_EXTCNTRST_EMACBCNTRST	BIT(1)
+#define CLKMGR_ALTERA_EXTCNTRST_EMACPTPCNTRST	BIT(2)
+#define CLKMGR_ALTERA_EXTCNTRST_GPIODBCNTRST	BIT(3)
+#define CLKMGR_ALTERA_EXTCNTRST_S2FUSER0CNTRST	BIT(5)
+#define CLKMGR_ALTERA_EXTCNTRST_S2FUSER1CNTRST	BIT(6)
+#define CLKMGR_ALTERA_EXTCNTRST_PSIREFCNTRST	BIT(7)
+#define CLKMGR_ALTERA_EXTCNTRST_USB31REFCNTRST	BIT(8)
+#define CLKMGR_ALTERA_EXTCNTRST_DSUCNTRST	BIT(10)
+#define CLKMGR_ALTERA_EXTCNTRST_CORE01CNTRST	BIT(11)
+#define CLKMGR_ALTERA_EXTCNTRST_CORE2CNTRST	BIT(12)
+#define CLKMGR_ALTERA_EXTCNTRST_CORE3CNTRST	BIT(13)
+
+#define CLKMGR_ALTERA_EXTCNTRST_ALLCNTRST	\
+						(CLKMGR_ALTERA_EXTCNTRST_EMACACNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_EMACBCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_EMACPTPCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_GPIODBCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_S2FUSER0CNTRST |\
+						CLKMGR_ALTERA_EXTCNTRST_S2FUSER1CNTRST |\
+						CLKMGR_ALTERA_EXTCNTRST_PSIREFCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_USB31REFCNTRST |\
+						CLKMGR_ALTERA_EXTCNTRST_DSUCNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_CORE01CNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_CORE2CNTRST |	\
+						CLKMGR_ALTERA_EXTCNTRST_CORE3CNTRST)
+
+#define CLKMGR_ALTERA_CORE0			0
+#define CLKMGR_ALTERA_CORE1			1
+#define CLKMGR_ALTERA_CORE2			2
+#define CLKMGR_ALTERA_CORE3			3
+
+/* PLL membus configuration macros */
+#define CLKMGR_MEM_REQ				BIT(24)
+#define CLKMGR_MEM_WR				BIT(25)
+#define CLKMGR_MEM_ERR				BIT(26)
+#define CLKMGR_MEM_WDAT_OFFSET			16
+#define CLKMGR_MEM_ADDR_MASK			GENMASK(15, 0)
+#define CLKMGR_MEM_ADDR_START			0x00004000
+#define CLKMGR_PLLCFG_SRC_SYNC_MODE		0x27
+#define CLKMGR_PLLCFG_OVRSHOOT_FREQ_LOCK	0xB3
+#define CLKMGR_PLLCFG_LOCK_SETTLE_TIME		0xE6
+#define CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE0	0x03
+#define CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE1	0x07
 
 /* Clock Manager Macros */
-#define CLKMGR_CTRL_BOOTMODE_SET_MSK			0x00000001
-#define CLKMGR_STAT_BUSY_E_BUSY				0x1
-#define CLKMGR_STAT_BUSY(x)				(((x) & 0x00000001) >> 0)
-#define CLKMGR_STAT_MAINPLLLOCKED(x)			(((x) & 0x00000100) >> 8)
-#define CLKMGR_STAT_PERPLLLOCKED(x)			(((x) & 0x00010000) >> 16)
-#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK		0x00000004
-#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK		0x00000008
-#define CLKMGR_INTOSC_HZ				460000000
+#define CLKMGR_CTRL_BOOTMODE_SET_MSK		0x00000001
+#define CLKMGR_STAT_BUSY_E_BUSY			0x1
+#define CLKMGR_STAT_BUSY(x)			(((x) & 0x00000001) >> 0)
+#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK	0x00000004
+#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK	0x00000008
+#define CLKMGR_INTOSC_HZ			460000000
+#define CLKMGR_CTRL_BOOTMODE			BIT(0)
+#define CLKMGR_STAT_MAINPLL_LOCKED		BIT(8)
+#define CLKMGR_STAT_MAIN_TRANS			BIT(9)
+#define CLKMGR_STAT_PERPLL_LOCKED		BIT(16)
+#define CLKMGR_STAT_PERF_TRANS			BIT(17)
+#define CLKMGR_STAT_BOOTMODE			BIT(24)
+#define CLKMGR_STAT_BOOTCLKSRC			BIT(25)
 
+#define CLKMGR_STAT_ALLPLL_LOCKED_MASK		(CLKMGR_STAT_MAINPLL_LOCKED | \
+						 CLKMGR_STAT_PERPLL_LOCKED)
 /* Main PLL Macros */
-#define CLKMGR_MAINPLL_EN_RESET				0x0000005e
-#define CLKMGR_MAINPLL_ENS_RESET			0x0000005e
+#define CLKMGR_MAINPLL_EN_RESET			0x0000005E
+#define CLKMGR_MAINPLL_ENS_RESET		0x0000005E
+#define CLKMGR_MAINPLL_PLLGLOB_PD_N		BIT(0)
+#define CLKMGR_MAINPLL_PLLGLOB_RST_N		BIT(1)
+#define CLKMGR_MAINPLL_PLLCX_EN			BIT(27)
+#define CLKMGR_MAINPLL_PLLCX_MUTE		BIT(28)
 
-/* Peripheral PLL Macros */
-#define CLKMGR_PERPLL_EN_RESET				0x040007FF
-#define CLKMGR_PERPLL_ENS_RESET			0x040007FF
-
-#define CLKMGR_PERPLL_EN_SDMMCCLK			BIT(5)
-#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x)		(((x) << 0) & 0x0000ffff)
+#define CLKMGR_PERPLL_EN_SDMMCCLK		BIT(5)
+#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x)	(((x) << 0) & 0x0000FFFF)
+#define CLKMGR_PERPLL_PLLGLOB_PD_N		BIT(0)
+#define CLKMGR_PERPLL_PLLGLOB_RST_N		BIT(1)
+#define CLKMGR_PERPLL_PLLCX_EN			BIT(27)
+#define CLKMGR_PERPLL_PLLCX_MUTE		BIT(28)
 
 /* Altera Macros */
-#define CLKMGR_ALTERA_EXTCNTRST_RESET			0xff
+#define CLKMGR_ALTERA_EXTCNTRST_RESET		0xFF
 
 /* Shared Macros */
-#define CLKMGR_PSRC(x)					(((x) & 0x00030000) >> 16)
-#define CLKMGR_PSRC_MAIN				0
-#define CLKMGR_PSRC_PER					1
+#define CLKMGR_PLLGLOB_PSRC(x)			(((x) & 0x00030000) >> 16)
+#define CLKMGR_PSRC_MAIN			0
+#define CLKMGR_PSRC_PER				1
+
+#define CLKMGR_PLLGLOB_PSRC_EOSC1		0x0
+#define CLKMGR_PLLGLOB_PSRC_INTOSC		0x1
+#define CLKMGR_PLLGLOB_PSRC_F2S			0x2
+
+#define CLKMGR_PLLM_MDIV(x)			((x) & 0x000003FF)
+#define CLKMGR_PLLGLOB_PD_SET_MSK		0x00000001
+#define CLKMGR_PLLGLOB_RST_SET_MSK		0x00000002
+
+#define CLKMGR_PLLGLOB_REFCLKDIV(x)		(((x) & 0x00003F00) >> 8)
+#define CLKMGR_PLLGLOB_AREFCLKDIV(x)		(((x) & 0x00000F00) >> 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV(x)		(((x) & 0x00003000) >> 12)
+
+#define CLKMGR_VCOCALIB_HSCNT_SET(x)		(((x) << 0) & 0x000003FF)
+#define CLKMGR_VCOCALIB_MSCNT_SET(x)		(((x) << 16) & 0x00FF0000)
+
+#define CLKMGR_CLR_LOSTLOCK_BYPASS		0x20000000
+
+#define CLKMGR_CLKSRC_MASK			GENMASK(18, 16)
+#define CLKMGR_CLKSRC_OFFSET			16
+#define CLKMGR_CLKSRC_MAIN			0
+#define CLKMGR_CLKSRC_PER			1
+#define CLKMGR_CLKSRC_OSC1			2
+#define CLKMGR_CLKSRC_INTOSC			3
+#define CLKMGR_CLKSRC_FPGA			4
+#define CLKMGR_PLLCX_DIV_MSK			GENMASK(10, 0)
+
+#define GET_CLKMGR_CLKSRC(x)			(((x) & CLKMGR_CLKSRC_MASK) >> \
+							CLKMGR_CLKSRC_OFFSET)
+
+#define CLKMGR_MAINPLL_NOCDIV_L4MP_MASK		GENMASK(5, 4)
+#define CLKMGR_MAINPLL_NOCDIV_L4MP_OFFSET	4
+#define GET_CLKMGR_MAINPLL_NOCDIV_L4MP(x)	(((x) & CLKMGR_MAINPLL_NOCDIV_L4MP_MASK) >> \
+						CLKMGR_MAINPLL_NOCDIV_L4MP_OFFSET)
+
+#define CLKMGR_MAINPLL_NOCDIV_L4SP_MASK		GENMASK(7, 6)
+#define CLKMGR_MAINPLL_NOCDIV_L4SP_OFFSET	6
+#define GET_CLKMGR_MAINPLL_NOCDIV_L4SP(x)	(((x) & CLKMGR_MAINPLL_NOCDIV_L4SP_MASK) >> \
+						CLKMGR_MAINPLL_NOCDIV_L4SP_OFFSET)
+
+#define CLKMGR_MAINPLL_NOCDIV_SPHY_MASK		GENMASK(17, 16)
+#define CLKMGR_MAINPLL_NOCDIV_SPHY_OFFSET	16
+#define GET_CLKMGR_MAINPLL_NOCDIV_SPHY(x)	(((x) & CLKMGR_MAINPLL_NOCDIV_SPHY_MASK) >> \
+						CLKMGR_MAINPLL_NOCDIV_SPHY_OFFSET)
+
+
+#define CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_MASK	GENMASK(3, 2)
+#define CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_OFFSET	2
+#define GET_CLKMGR_MAINPLL_NOCDIV_L4SYSFREE(x)	(((x) & CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_MASK) >> \
+						CLKMGR_MAINPLL_NOCDIV_L4SYSFREE_OFFSET)
+
+#define CLKMGR_PERPLL_EMAC0_CLK_SRC_MASK	BIT(26)
+#define CLKMGR_PERPLL_EMAC0_CLK_SRC_OFFSET	26
+#define GET_CLKMGR_PERPLL_EMAC0_CLK_SRC(x)	(((x) & CLKMGR_PERPLL_EMAC0_CLK_SRC_MASK) >> \
+						CLKMGR_PERPLL_EMAC0_CLK_SRC_OFFSET)
+
+#define CLKMGR_ALTERA_EMACACTR_CLK_SRC_MASK	GENMASK(18, 16)
+#define CLKMGR_ALTERA_EMACACTR_CLK_SRC_OFFSET	16
+#define GET_CLKMGR_EMACACTR_CLK_SRC(x)		(((x) & CLKMGR_ALTERA_EMACACTR_CLK_SRC_MASK) >> \
+						CLKMGR_ALTERA_EMACACTR_CLK_SRC_OFFSET)
+
+#define CLKMGR_MPU_CLK_ID			0
+#define CLKMGR_MPU_PERIPH_CLK_ID		1
+#define CLKMGR_L4_MAIN_CLK_ID			2
+#define CLKMGR_L4_MP_CLK_ID			3
+#define CLKMGR_L4_SP_CLK_ID			4
+#define CLKMGR_WDT_CLK_ID			5
+#define CLKMGR_UART_CLK_ID			6
+#define CLKMGR_EMAC0_CLK_ID			7
+#define CLKMGR_EMAC1_CLK_ID			8
+#define CLKMGR_EMAC2_CLK_ID			9
+#define CLKMGR_EMAC_PTP_CLK_ID			10
+#define CLKMGR_SDMMC_CLK_ID			11
 
-#define CLKMGR_PLLGLOB_PSRC_EOSC1			0x0
-#define CLKMGR_PLLGLOB_PSRC_INTOSC			0x1
-#define CLKMGR_PLLGLOB_PSRC_F2S				0x2
+#define CLKMGR_MAINPLL_BYPASS_ALL		(0xF6)
+#define CLKMGR_PERPLL_BYPASS_ALL		(0xEF)
+#define CLKMGR_PLLCX_STAT			BIT(29)
+#define GET_PLLCX_STAT(x)			((x) & CLKMGR_PLLCX_STAT)
 
-#define CLKMGR_PLLM_MDIV(x)				((x) & 0x000003ff)
-#define CLKMGR_PLLGLOB_PD_SET_MSK			0x00000001
-#define CLKMGR_PLLGLOB_RST_SET_MSK			0x00000002
+#define CLKMGR_MAINPLL_TYPE			(0)
+#define CLKMGR_PERPLL_TYPE			(1)
 
-#define CLKMGR_PLLGLOB_REFCLKDIV(x)			(((x) & 0x00003f00) >> 8)
-#define CLKMGR_PLLGLOB_AREFCLKDIV(x)			(((x) & 0x00000f00) >> 8)
-#define CLKMGR_PLLGLOB_DREFCLKDIV(x)			(((x) & 0x00003000) >> 12)
+#define CLKMGR_MAX_RETRY_COUNT			1000
 
-#define CLKMGR_VCOCALIB_HSCNT_SET(x)			(((x) << 0) & 0x000003ff)
-#define CLKMGR_VCOCALIB_MSCNT_SET(x)			(((x) << 16) & 0x00ff0000)
+#define CLKMGR_PLLM_MDIV_MASK			GENMASK(9, 0)
+#define CLKMGR_PLLGLOB_PD_MASK			BIT(0)
+#define CLKMGR_PLLGLOB_RST_MASK			BIT(1)
+#define CLKMGR_PLLGLOB_AREFCLKDIV_MASK		GENMASK(11, 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV_MASK		GENMASK(13, 12)
+#define CLKMGR_PLLGLOB_REFCLKDIV_MASK		GENMASK(13, 8)
+#define CLKMGR_PLLGLOB_MODCLKDIV_MASK		GENMASK(24, 27)
+#define CLKMGR_PLLGLOB_AREFCLKDIV_OFFSET	8
+#define CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET	12
+#define CLKMGR_PLLGLOB_REFCLKDIV_OFFSET		8
+#define CLKMGR_PLLGLOB_MODCLKDIV_OFFSET		24
+#define CLKMGR_PLLGLOB_VCO_PSRC_MASK		GENMASK(17, 16)
+#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET		16
+#define CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK	BIT(29)
 
-#define CLKMGR_CLR_LOSTLOCK_BYPASS			0x20000000
+#define CLKMGR_VCOCALIB_MSCNT_MASK		GENMASK(23, 16)
+#define CLKMGR_VCOCALIB_MSCNT_OFFSET		16
+#define CLKMGR_VCOCALIB_HSCNT_MASK		GENMASK(9, 0)
+#define CLKMGR_VCOCALIB_MSCNT_CONST		100
+#define CLKMGR_VCOCALIB_HSCNT_CONST		4
 
-typedef struct {
-	uint32_t  clk_freq_of_eosc1;
-	uint32_t  clk_freq_of_f2h_free;
-	uint32_t  clk_freq_of_cb_intosc_ls;
-} CLOCK_SOURCE_CONFIG;
+int config_clkmgr_handoff(handoff *hoff_ptr);
+uint32_t clkmgr_get_rate(uint32_t clk_id);
 
-void config_clkmgr_handoff(handoff *hoff_ptr);
-uint32_t get_wdt_clk(void);
-uint32_t get_uart_clk(void);
-uint32_t get_mmc_clk(void);
+/* PLL configuration data structure in power-down state */
+typedef struct pll_cfg {
+	uint32_t addr;
+	uint32_t data;
+	uint32_t mask;
+} pll_cfg_t;
 
 #endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_ddr.h b/plat/intel/soc/agilex5/include/agilex5_ddr.h
new file mode 100644
index 00000000..631e006e
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_ddr.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGILEX5_DDR_H
+#define AGILEX5_DDR_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <lib/utils_def.h>
+
+#include "socfpga_handoff.h"
+
+#define CONFIG_NR_DRAM_BANKS	1
+
+typedef unsigned long long phys_addr_t;
+typedef unsigned long long phys_size_t;
+typedef phys_addr_t fdt_addr_t;
+
+/* DDR/RAM configuration */
+struct ddr_info {
+	phys_addr_t start;
+	phys_size_t size;
+};
+
+int agilex5_ddr_init(handoff *hoff_ptr);
+
+#endif /* AGILEX5_DDR_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h b/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h
new file mode 100644
index 00000000..1fd8ef6f
--- /dev/null
+++ b/plat/intel/soc/agilex5/include/agilex5_iossm_mailbox.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AGILEX5_IOSSM_MAILBOX_H
+#define AGILEX5_IOSSM_MAILBOX_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "lib/mmio.h"
+#include "agilex5_ddr.h"
+
+#define TIMEOUT_5000MS					5000
+#define TIMEOUT						TIMEOUT_5000MS
+#define IOSSM_STATUS_CAL_SUCCESS			BIT(0)
+#define IOSSM_STATUS_CAL_FAIL				BIT(1)
+#define IOSSM_STATUS_CAL_BUSY				BIT(2)
+#define IOSSM_STATUS_COMMAND_RESPONSE_READY		1
+#define IOSSM_CMD_RESPONSE_STATUS_OFFSET		0x45C
+#define IOSSM_CMD_RESPONSE_DATA_0_OFFSET		0x458
+#define IOSSM_CMD_RESPONSE_DATA_1_OFFSET		0x454
+#define IOSSM_CMD_RESPONSE_DATA_2_OFFSET		0x450
+#define IOSSM_CMD_REQ_OFFSET				0x43C
+#define IOSSM_CMD_PARAM_0_OFFSET			0x438
+#define IOSSM_CMD_PARAM_1_OFFSET			0x434
+#define IOSSM_CMD_PARAM_2_OFFSET			0x430
+#define IOSSM_CMD_PARAM_3_OFFSET			0x42C
+#define IOSSM_CMD_PARAM_4_OFFSET			0x428
+#define IOSSM_CMD_PARAM_5_OFFSET			0x424
+#define IOSSM_CMD_PARAM_6_OFFSET			0x420
+#define IOSSM_STATUS_OFFSET				0x400
+#define IOSSM_CMD_RESPONSE_DATA_SHORT_MASK		GENMASK(31, 16)
+#define IOSSM_CMD_RESPONSE_DATA_SHORT(data)		(((data) & \
+							IOSSM_CMD_RESPONSE_DATA_SHORT_MASK) >> 16)
+#define MAX_IO96B_SUPPORTED				2
+#define MAX_MEM_INTERFACES_SUPPORTED			2
+
+/* supported mailbox command type */
+enum iossm_mailbox_cmd_type  {
+	CMD_NOP,
+	CMD_GET_SYS_INFO,
+	CMD_GET_MEM_INFO,
+	CMD_GET_MEM_CAL_INFO,
+	CMD_TRIG_CONTROLLER_OP,
+	CMD_TRIG_MEM_CAL_OP
+};
+
+/* supported mailbox command opcode */
+enum iossm_mailbox_cmd_opcode  {
+	GET_MEM_INTF_INFO = 0x0001,
+	GET_MEM_TECHNOLOGY,
+	GET_MEMCLK_FREQ_KHZ,
+	GET_MEM_WIDTH_INFO,
+	ECC_ENABLE_SET = 0x0101,
+	ECC_ENABLE_STATUS,
+	ECC_INTERRUPT_STATUS,
+	ECC_INTERRUPT_ACK,
+	ECC_INTERRUPT_MASK,
+	ECC_WRITEBACK_ENABLE,
+	ECC_SCRUB_IN_PROGRESS_STATUS = 0x0201,
+	ECC_SCRUB_MODE_0_START,
+	ECC_SCRUB_MODE_1_START,
+	BIST_STANDARD_MODE_START = 0x0301,
+	BIST_RESULTS_STATUS,
+	BIST_MEM_INIT_START,
+	BIST_MEM_INIT_STATUS,
+	BIST_SET_DATA_PATTERN_UPPER,
+	BIST_SET_DATA_PATTERN_LOWER,
+	TRIG_MEM_CAL = 0x000a,
+	GET_MEM_CAL_STATUS
+};
+
+/*
+ * IOSSM mailbox required information
+ *
+ * @num_mem_interface:	Number of memory interfaces instantiated
+ * @ip_type:		IP type implemented on the IO96B
+ * @ip_instance_id:	IP identifier for every IP instance implemented on the IO96B
+ */
+struct io96b_mb_ctrl {
+	uint32_t num_mem_interface;
+	uint32_t ip_type[2];
+	uint32_t ip_instance_id[2];
+};
+
+/*
+ * IOSSM mailbox response outputs
+ *
+ * @cmd_resp_status: Command Interface status
+ * @cmd_resp_data_*: More spaces for command response
+ */
+struct io96b_mb_resp {
+	uint32_t cmd_resp_status;
+	uint32_t cmd_resp_data_0;
+	uint32_t cmd_resp_data_1;
+	uint32_t cmd_resp_data_2;
+};
+
+/*
+ * IO96B instance specific information
+ *
+ * @size:		Memory size
+ * @io96b_csr_addr:	IO96B instance CSR address
+ * @cal_status:		IO96B instance calibration status
+ * @mb_ctrl:		IOSSM mailbox required information
+ */
+struct io96b_instance {
+	uint16_t size;
+	phys_addr_t io96b_csr_addr;
+	bool cal_status;
+	struct io96b_mb_ctrl mb_ctrl;
+};
+
+/*
+ * Overall IO96B instance(s) information
+ *
+ * @num_instance:	Number of instance(s) assigned to HPS
+ * @overall_cal_status: Overall calibration status for all IO96B instance(s)
+ * @ddr_type:		DDR memory type
+ * @ecc_status:		ECC enable status (false = disabled, true = enabled)
+ * @overall_size:	Total DDR memory size
+ * @io96b_0:		IO96B 0 instance specific information
+ * @io96b_1:		IO96B 1 instance specific information
+ */
+struct io96b_info {
+	uint8_t num_instance;
+	bool overall_cal_status;
+	const char *ddr_type;
+	bool ecc_status;
+	uint16_t overall_size;
+	struct io96b_instance io96b_0;
+	struct io96b_instance io96b_1;
+};
+
+int io96b_mb_req(phys_addr_t io96b_csr_addr, uint32_t ip_type, uint32_t instance_id,
+		 uint32_t usr_cmd_type, uint32_t usr_cmd_opcode, uint32_t cmd_param_0,
+		 uint32_t cmd_param_1, uint32_t cmd_param_2, uint32_t cmd_param_3,
+		 uint32_t cmd_param_4, uint32_t cmd_param_5, uint32_t cmd_param_6,
+		 uint32_t resp_data_len, struct io96b_mb_resp *resp);
+
+/* Supported IOSSM mailbox function */
+void io96b_mb_init(struct io96b_info *io96b_ctrl);
+int io96b_cal_status(phys_addr_t addr);
+void init_mem_cal(struct io96b_info *io96b_ctrl);
+int trig_mem_cal(struct io96b_info *io96b_ctrl);
+int get_mem_technology(struct io96b_info *io96b_ctrl);
+int get_mem_width_info(struct io96b_info *io96b_ctrl);
+int ecc_enable_status(struct io96b_info *io96b_ctrl);
+int bist_mem_init_start(struct io96b_info *io96b_ctrl);
+
+#endif /* AGILEX5_IOSSM_MAILBOX_H */
diff --git a/plat/intel/soc/agilex5/include/agilex5_pinmux.h b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
index 8a8e8c78..78d19af2 100644
--- a/plat/intel/soc/agilex5/include/agilex5_pinmux.h
+++ b/plat/intel/soc/agilex5/include/agilex5_pinmux.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,19 +8,13 @@
 #ifndef AGX5_PINMUX_H
 #define AGX5_PINMUX_H
 
-/* PINMUX REGISTER ADDRESS */
-#define AGX5_PINMUX_PIN0SEL					0x10d13000
-#define AGX5_PINMUX_IO0CTRL					0x10d13130
-#define AGX5_PINMUX_EMAC0_USEFPGA				0x10d13300
-#define AGX5_PINMUX_IO0_DELAY					0x10d13400
-#define AGX5_PERIPHERAL						0x10d14044
-
 #include "socfpga_handoff.h"
 
-/* PINMUX DEFINE */
-#define PINMUX_HANDOFF_ARRAY_SIZE(x)				(sizeof(x) / sizeof((x)[0]))
-#define PINMUX_HANDOFF_CONFIG_ADDR				0xbeec
-#define PINMUX_HANDOFF_CONFIG_VAL				0x7e000
+/* PINMUX REGISTER ADDRESS */
+#define AGX5_PINMUX_PIN0SEL					0x10D13000
+#define AGX5_PINMUX_IO0CTRL					0x10D13130
+#define AGX5_PINMUX_EMAC0_USEFPGA				0x10D13300
+#define AGX5_PINMUX_IO0_DELAY					0x10D13400
 
 /* Macros */
 #define SOCFPGA_PINMUX_SEL_NAND					(0x03)
@@ -142,6 +137,9 @@
 #define SOCFPGA_PINMUX_JTAG_USEFPGA				(0x50)
 #define SOCFPGA_PINMUX_SDMMC_USEFPGA				(0x54)
 
+#define SOCFPGA_PINUMX_USEFPGA(_reg)				(AGX5_PINMUX_EMAC0_USEFPGA \
+								+ SOCFPGA_PINMUX_##_reg)
+
 #define SOCFPGA_PINMUX_IO0DELAY					(0x00)
 #define SOCFPGA_PINMUX_IO1DELAY					(0x04)
 #define SOCFPGA_PINMUX_IO2DELAY					(0x08)
@@ -198,5 +196,4 @@
 								+ (SOCFPGA_PINMUX_##_reg))
 
 void config_pinmux(handoff *handoff);
-void config_peripheral(handoff *handoff);
 #endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_power_manager.h b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
index 1bba74be..178fd5b6 100644
--- a/plat/intel/soc/agilex5/include/agilex5_power_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_power_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -77,7 +78,5 @@
 #define AGX5_PWRMGR_PSS_STAT_BUSY_E_BUSY			0x0
 #define AGX5_PWRMGR_PSS_STAT_BUSY(x)				(((x) & 0x000000FF) >> 0)
 
-int pss_sram_power_off(handoff *hoff_ptr);
-int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff);
-
+void config_pwrmgr_handoff(handoff *hoff_ptr);
 #endif
diff --git a/plat/intel/soc/agilex5/include/agilex5_system_manager.h b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
index 9a58cdb1..ac4bf128 100644
--- a/plat/intel/soc/agilex5/include/agilex5_system_manager.h
+++ b/plat/intel/soc/agilex5/include/agilex5_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +25,7 @@
 #define SOCFPGA_SYSMGR_TSN_0_ACE					0x50
 #define SOCFPGA_SYSMGR_TSN_1_ACE					0x54
 #define SOCFPGA_SYSMGR_TSN_2_ACE					0x58
+#define SOCFPGA_SYSMGR_FPGA_BRIDGE_CTRL				0x5C
 #define SOCFPGA_SYSMGR_FPGAINTF_EN_1					0x68
 #define SOCFPGA_SYSMGR_FPGAINTF_EN_2					0x6C
 #define SOCFPGA_SYSMGR_FPGAINTF_EN_3					0x70
@@ -121,7 +123,7 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8				0x220
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9				0x224
 #define SOCFPGA_SYSMGR_MPFE_CONFIG					0x228
-#define SOCFPGA_SYSMGR_MPFE_status					0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS					0x22C
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0				0x230
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1				0x234
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2				0x238
@@ -142,6 +144,21 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_7				0x274
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_8				0x278
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_9				0x27C
+#define SOCFPGA_SYSMGR_SDM_BE_AWADDR_REMAP				0x280
+#define SOCFPGA_SYSMGR_SDM_BE_ARADDR_REMAP				0x284
+
+/* QSPI ECC from SDM register */
+#define SOCFPGA_ECC_QSPI_CTRL						0x08
+#define SOCFPGA_ECC_QSPI_INITSTAT					0x0C
+#define SOCFPGA_ECC_QSPI_ERRINTEN					0x10
+#define SOCFPGA_ECC_QSPI_ERRINTENS					0x14
+#define SOCFPGA_ECC_QSPI_ERRINTENR					0x18
+#define SOCFPGA_ECC_QSPI_INTMODE					0x1C
+#define SOCFPGA_ECC_QSPI_INTSTAT					0x20
+#define SOCFPGA_ECC_QSPI_INTTEST					0x24
+#define SOCFPGA_ECC_QSPI_ECC_ACCCTRL					0x78
+#define SOCFPGA_ECC_QSPI_ECC_STARTACC					0x7C
+#define SOCFPGA_ECC_QSPI_ECC_WDCTRL					0x80
 
 #define DMA0_STREAM_CTRL_REG						0x10D1217C
 #define DMA1_STREAM_CTRL_REG						0x10D12180
@@ -168,11 +185,28 @@
 #define SDM								0x000A000A
 #define CORE_SIGHT_DEBUG						0x000B000B
 
+/* JTAG ID value for Agilex5 */
+#define A590_JTAG_ID							0x9000
+#define A594_JTAG_ID							0x40009000
+#define A5C0_JTAG_ID							0xC000
+#define A5C4_JTAG_ID							0x4000C000
+#define A5D0_JTAG_ID							0xD000
+#define A5D4_JTAG_ID							0x4000D000
+#define A5F0_JTAG_ID							0xC000
+#define A5F4_JTAG_ID							0x4000F000
+#define A510_JTAG_ID							0x1000
+#define A514_JTAG_ID							0x40001000
+#define A530_JTAG_ID							0x3000
+#define A534_JTAG_ID							0x40003000
+#define JTAG_ID_MASK							0xC000F000
+
 /* Field Masking */
 #define SYSMGR_SDMMC_DRVSEL(x)						(((x) & 0x7) << 0)
 #define SYSMGR_SDMMC_SMPLSEL(x)						(((x) & 0x7) << 4)
 
 #define SYSMGR_F2S_BRIDGE_CTRL_EN					BIT(0)
+#define SYSMGR_SOC_BRIDGE_CTRL_EN					BIT(0)
+#define SYSMGR_LWSOC_BRIDGE_CTRL_EN					BIT(1)
 #define IDLE_DATA_LWSOC2FPGA						BIT(4)
 #define IDLE_DATA_SOC2FPGA						BIT(0)
 #define IDLE_DATA_MASK							(IDLE_DATA_LWSOC2FPGA \
@@ -187,9 +221,10 @@
 #define RMMUSECSID_REG_VAL						BIT(5)
 
 /* Macros */
+#define SOCFPGA_ECC_QSPI(_reg)						(SOCFPGA_ECC_QSPI_REG_BASE \
+									+ (SOCFPGA_ECC_QSPI_##_reg))
 #define SOCFPGA_SYSMGR(_reg)						(SOCFPGA_SYSMGR_REG_BASE \
 									+ (SOCFPGA_SYSMGR_##_reg))
-
 #define ENABLE_STREAMID							WSTREAMIDEN_REG_CTRL \
 									| RSTREAMIDEN_REG_CTRL
 #define ENABLE_STREAMID_SECURE_TX					WSTREAMIDEN_REG_CTRL \
diff --git a/plat/intel/soc/agilex5/include/socfpga_plat_def.h b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
index 8a49d613..c1f3cc50 100644
--- a/plat/intel/soc/agilex5/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex5/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,31 +11,59 @@
 
 #include "agilex5_memory_controller.h"
 #include "agilex5_system_manager.h"
+
 #include <platform_def.h>
 
 /* Platform Setting */
 #define PLATFORM_MODEL						PLAT_SOCFPGA_AGILEX5
-#define BOOT_SOURCE						BOOT_SOURCE_SDMMC
+/* 1 = Flush cache, 0 = No cache flush.
+ * Default for Agilex5 is Cache flush.
+ */
+#define CACHE_FLUSH							1
 #define MMC_DEVICE_TYPE						1  /* MMC = 0, SD = 1 */
 #define XLAT_TABLES_V2						U(1)
 #define PLAT_PRIMARY_CPU_A55					0x000
 #define PLAT_PRIMARY_CPU_A76					0x200
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT				MPIDR_AFF2_SHIFT
 #define PLAT_CPU_ID_MPIDR_AFF_SHIFT				MPIDR_AFF1_SHIFT
-#define PLAT_L2_RESET_REQ			0xB007C0DE
+#define PLAT_L2_RESET_REQ					0xB007C0DE
+#define PLAT_HANDOFF_OFFSET					0x0007F000
+#define PLAT_TIMER_BASE_ADDR					0x10D01000
 
-/* System Counter */ /* TODO: Update back to 400MHz */
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS				(80000000)
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ				(80)
+/* System Counter */
+/* TODO: Update back to 400MHz.
+ * This shall be updated to read from L4 clock instead of hardcoded.
+ */
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS				U(400000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ				U(400)
 
 /* FPGA config helpers */
-#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR				0x400000
-#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE				0x2000000
+#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR				0x80400000
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE				0x82000000
 
 /* QSPI Setting */
 #define CAD_QSPIDATA_OFST					0x10900000
 #define CAD_QSPI_OFFSET						0x108d2000
 
+/* FIP Setting */
+#define PLAT_FIP_BASE						(0)
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_FIP_MAX_SIZE					(0x8000000)
+#else
+#define PLAT_FIP_MAX_SIZE					(0x1000000)
+#endif
+
+/* SDMMC Setting */
+#if ARM_LINUX_KERNEL_AS_BL33
+#define PLAT_MMC_DATA_BASE					(0x90000000)
+#define PLAT_MMC_DATA_SIZE					(0x100000)
+#define SOCFPGA_MMC_BLOCK_SIZE					U(32768)
+#else
+#define PLAT_MMC_DATA_BASE					(0x0007D000)
+#define PLAT_MMC_DATA_SIZE					(0x2000)
+#define SOCFPGA_MMC_BLOCK_SIZE					U(8192)
+#endif
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE				0x1c000000
 #define SOCFPGA_F2SDRAMMGR_REG_BASE				0x18001000
@@ -45,14 +74,27 @@
 #define SOCFPGA_SYSMGR_REG_BASE					0x10d12000
 #define SOCFPGA_PINMUX_REG_BASE					0x10d13000
 #define SOCFPGA_NAND_REG_BASE					0x10B80000
+#define SOCFPGA_ECC_QSPI_REG_BASE				0x10A22000
 
 #define SOCFPGA_L4_PER_SCR_REG_BASE				0x10d21000
 #define SOCFPGA_L4_SYS_SCR_REG_BASE				0x10d21100
 #define SOCFPGA_SOC2FPGA_SCR_REG_BASE				0x10d21200
 #define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE				0x10d21300
+#define SOCFPGA_SDMMC_SECU_BIT					0x40
+#define SOCFPGA_LWSOC2FPGA_ENABLE				0xffe0301
+#define SOCFPGA_SDMMC_SECU_BIT_ENABLE				0x1010001
+
 
 /* Define maximum page size for NAND flash devices */
-#define PLATFORM_MTD_MAX_PAGE_SIZE				U(0x1000)
+#define PLATFORM_MTD_MAX_PAGE_SIZE				U(0x2000)
+
+/* OCRAM Register*/
+
+#define OCRAM_REG_BASE						0x108CC400
+#define OCRAM_REGION_0_OFFSET					0x18
+#define OCRAM_REGION_0_REG_BASE					(OCRAM_REG_BASE + \
+								OCRAM_REGION_0_OFFSET)
+#define OCRAM_NON_SECURE_ENABLE					0x0
 
 /*******************************************************************************
  * Platform memory map related constants
@@ -83,17 +125,21 @@
 #define GIC_SIZE						(0x00100000)
 
 #define BL2_BASE						(0x00000000)
-#define BL2_LIMIT						(0x0001b000)
+#define BL2_LIMIT						(0x0007E000)
 
 #define BL31_BASE						(0x80000000)
 #define BL31_LIMIT						(0x82000000)
-
 /*******************************************************************************
  * UART related constants
  ******************************************************************************/
 #define PLAT_UART0_BASE						(0x10C02000)
 #define PLAT_UART1_BASE						(0x10C02100)
 
+/*******************************************************************************
+ * WDT related constants
+ ******************************************************************************/
+#define WDT_BASE						(0x10D00200)
+
 /*******************************************************************************
  * GIC related constants
  ******************************************************************************/
@@ -107,13 +153,13 @@
 /*******************************************************************************
  * SDMMC related pointer function
  ******************************************************************************/
-#define SDMMC_READ_BLOCKS	sdmmc_read_blocks
-#define SDMMC_WRITE_BLOCKS	sdmmc_write_blocks
+#define SDMMC_READ_BLOCKS					sdmmc_read_blocks
+#define SDMMC_WRITE_BLOCKS					sdmmc_write_blocks
 
 /*******************************************************************************
  * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
  * is done and HPS should trigger warm reset via RMR_EL3.
  ******************************************************************************/
-#define L2_RESET_DONE_REG			0x10D12218
+#define L2_RESET_DONE_REG					0x10D12218
 
 #endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/agilex5/platform.mk b/plat/intel/soc/agilex5/platform.mk
index 546bc2e7..a831c393 100644
--- a/plat/intel/soc/agilex5/platform.mk
+++ b/plat/intel/soc/agilex5/platform.mk
@@ -1,6 +1,7 @@
 #
 # Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
 # Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2024, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,6 +9,7 @@ include lib/xlat_tables_v2/xlat_tables.mk
 PLAT_INCLUDES		:=	\
 			-Iplat/intel/soc/agilex5/include/		\
 			-Iplat/intel/soc/common/drivers/		\
+			-Iplat/intel/soc/common/lib/sha/		\
 			-Iplat/intel/soc/common/include/
 
 # GIC-600 configuration
@@ -33,6 +35,7 @@ PLAT_BL_COMMON_SOURCES	:=	\
 			plat/intel/soc/common/drivers/sdmmc/sdmmc.c			\
 			plat/intel/soc/common/drivers/ddr/ddr.c			\
 			plat/intel/soc/common/drivers/nand/nand.c			\
+			plat/intel/soc/common/lib/sha/sha.c				\
 			plat/intel/soc/common/socfpga_delay_timer.c
 
 BL2_SOURCES		+=	\
@@ -55,13 +58,16 @@ BL2_SOURCES		+=	\
 		lib/cpus/aarch64/cortex_a76.S				\
 		plat/intel/soc/agilex5/soc/agilex5_clock_manager.c	\
 		plat/intel/soc/agilex5/soc/agilex5_memory_controller.c	\
-		plat/intel/soc/agilex5/soc/agilex5_mmc.c			\
+		plat/intel/soc/agilex5/soc/agilex5_mmc.c		\
 		plat/intel/soc/agilex5/soc/agilex5_pinmux.c		\
 		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
+		plat/intel/soc/agilex5/soc/agilex5_ddr.c		\
+		plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c	\
 		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_image_load.c		\
+		plat/intel/soc/common/socfpga_ros.c			\
 		plat/intel/soc/common/socfpga_storage.c			\
-		plat/intel/soc/common/socfpga_vab.c				\
+		plat/intel/soc/common/socfpga_vab.c			\
 		plat/intel/soc/common/soc/socfpga_emac.c		\
 		plat/intel/soc/common/soc/socfpga_firewall.c		\
 		plat/intel/soc/common/soc/socfpga_handoff.c		\
@@ -83,6 +89,8 @@ BL31_SOURCES	+=	\
 		lib/cpus/aarch64/cortex_a76.S				\
 		plat/common/plat_psci_common.c				\
 		plat/intel/soc/agilex5/bl31_plat_setup.c		\
+		plat/intel/soc/agilex5/soc/agilex5_cache.S		\
+		plat/intel/soc/agilex5/soc/agilex5_clock_manager.c	\
 		plat/intel/soc/agilex5/soc/agilex5_power_manager.c	\
 		plat/intel/soc/common/socfpga_psci.c			\
 		plat/intel/soc/common/socfpga_sip_svc.c			\
@@ -91,6 +99,7 @@ BL31_SOURCES	+=	\
 		plat/intel/soc/common/sip/socfpga_sip_ecc.c		\
 		plat/intel/soc/common/sip/socfpga_sip_fcs.c		\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
+		plat/intel/soc/common/soc/socfpga_system_manager.c	\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
 # Configs for A76 and A55
@@ -99,8 +108,35 @@ USE_COHERENT_MEM := 0
 CTX_INCLUDE_AARCH32_REGS := 0
 ERRATA_A55_1530923 := 1
 
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33	:=	0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC		?=	0
+SOCFPGA_BOOT_SOURCE_QSPI		?=	0
+SOCFPGA_BOOT_SOURCE_NAND		?=	0
+
+$(eval $(call assert_booleans,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
+# Configs for VAB Authentication
+SOCFPGA_SECURE_VAB_AUTH  := 	0
+$(eval $(call assert_boolean,SOCFPGA_SECURE_VAB_AUTH))
+$(eval $(call add_define,SOCFPGA_SECURE_VAB_AUTH))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
-BL2_INV_DCACHE			:= 0
+BL2_INV_DCACHE			:= 0
\ No newline at end of file
diff --git a/plat/intel/soc/agilex5/soc/agilex5_cache.S b/plat/intel/soc/agilex5/soc/agilex5_cache.S
new file mode 100644
index 00000000..52ed5d35
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_cache.S
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+	.globl invalidate_dcache_all
+	.globl invalidate_cache_low_el
+	/* --------------------------------------------------------
+	 * Invalidate for NS EL2 and EL1
+	 * --------------------------------------------------------
+	 */
+func invalidate_cache_low_el
+	mrs	x0,SCR_EL3
+	orr	x1,x0,#SCR_NS_BIT
+	msr	SCR_EL3, x1
+	isb
+	tlbi	ALLE2
+	dsb	sy
+	tlbi	ALLE1
+	dsb	sy
+endfunc invalidate_cache_low_el
+
+.pushsection .text.asm_dcache_level, "ax"
+func asm_dcache_level
+	lsl	x12, x0, #1
+	msr	csselr_el1, x12		/* select cache level */
+	isb				/* sync change of cssidr_el1 */
+	mrs	x6, ccsidr_el1		/* read the new cssidr_el1 */
+	ubfx	x2, x6,  #0,  #3	/* x2 <- log2(cache line size)-4 */
+	ubfx	x3, x6,  #3, #10	/* x3 <- number of cache ways - 1 */
+	ubfx	x4, x6, #13, #15	/* x4 <- number of cache sets - 1 */
+	add	x2, x2, #4		/* x2 <- log2(cache line size) */
+	clz	w5, w3			/* bit position of #ways */
+	/* x12 <- cache level << 1 */
+	/* x2 <- line length offset */
+	/* x3 <- number of cache ways - 1 */
+	/* x4 <- number of cache sets - 1 */
+	/* x5 <- bit position of #ways */
+
+loop_set:
+	mov	x6, x3			/* x6 <- working copy of #ways */
+loop_way:
+	lsl	x7, x6, x5
+	orr	x9, x12, x7		/* map way and level to cisw value */
+	lsl	x7, x4, x2
+	orr	x9, x9, x7		/* map set number to cisw value */
+	tbz	w1, #0, 1f
+	dc	isw, x9
+	b	2f
+1:	dc	cisw, x9		/* clean & invalidate by set/way */
+2:	subs	x6, x6, #1		/* decrement the way */
+	b.ge	loop_way
+	subs	x4, x4, #1		/* decrement the set */
+	b.ge	loop_set
+
+	ret
+endfunc asm_dcache_level
+.popsection
+
+/*
+ * void __asm_flush_dcache_all(int invalidate_only)
+ *
+ * x0: 0 clean & invalidate, 1 invalidate only
+ *
+ * flush or invalidate all data cache by SET/WAY.
+ */
+.pushsection .text.asm_dcache_all, "ax"
+func asm_dcache_all
+	mov	x1, x0
+	dsb	sy
+	mrs	x10, clidr_el1		/* read clidr_el1 */
+	ubfx	x11, x10, #24, #3	/* x11 <- loc */
+	cbz	x11, finished		/* if loc is 0, exit */
+	mov	x15, x30
+	mov	x0, #0			/* start flush at cache level 0 */
+	/* x0  <- cache level */
+	/* x10 <- clidr_el1 */
+	/* x11 <- loc */
+	/* x15 <- return address */
+
+loop_level:
+	add	x12, x0, x0, lsl #1	/* x12 <- tripled cache level */
+	lsr	x12, x10, x12
+	and	x12, x12, #7		/* x12 <- cache type */
+	cmp	x12, #2
+	b.lt	skip			/* skip if no cache or icache */
+	bl	asm_dcache_level	/* x1 = 0 flush, 1 invalidate */
+skip:
+	add	x0, x0, #1		/* increment cache level */
+	cmp	x11, x0
+	b.gt	loop_level
+
+	mov	x0, #0
+	msr	csselr_el1, x0		/* restore csselr_el1 */
+	dsb	sy
+	isb
+	mov	x30, x15
+
+finished:
+	ret
+endfunc asm_dcache_all
+.popsection
+
+.pushsection .text.invalidate_dcache_all, "ax"
+func invalidate_dcache_all
+	mov	x0, #0x1
+	b	asm_dcache_all
+endfunc invalidate_dcache_all
+.popsection
diff --git a/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
index cc681532..603aaf8f 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_clock_manager.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,241 +14,643 @@
 
 #include "agilex5_clock_manager.h"
 #include "agilex5_system_manager.h"
-#include "socfpga_handoff.h"
-
-uint32_t wait_pll_lock(void)
+#include "socfpga_system_manager.h"
+
+/* Main and Peripheral PLL configurations in Power Down(PD) state. */
+static const pll_cfg_t pll_cfg_set[] = {
+	{
+		/* Enable source synchronous mode */
+		CLKMGR_PLLCFG_SRC_SYNC_MODE,
+		BIT(7),
+		BIT(7)
+	},
+	{
+		/* Limit the PLL overshoot frequency during lock */
+		CLKMGR_PLLCFG_OVRSHOOT_FREQ_LOCK,
+		BIT(0),
+		BIT(0)
+	},
+	{
+		/* To give the PLL more time to settle before lock is asserted */
+		CLKMGR_PLLCFG_LOCK_SETTLE_TIME,
+		BIT(0),
+		BIT(0)
+	},
+	{
+		/* To set the PLL centering duty cycle for clock slice 0 */
+		CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE0,
+		0x4A,
+		GENMASK(6, 0)
+	},
+	{
+		/* To set the PLL centering duty cycle for clock slice 1 */
+		CLKMGR_PLLCFG_DUTYCYCLE_CLKSLICE1,
+		0x4A,
+		GENMASK(6, 0)
+	},
+};
+
+static int wait_pll_lock(uint32_t mask)
 {
 	uint32_t data;
 	uint32_t count = 0;
+	uint32_t retry = 0U;
 
 	do {
-		data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
-		count++;
-		if (count >= 1000)
+		/* return time out */
+		if (count >= CLKMGR_MAX_RETRY_COUNT) {
+			ERROR("CLKMGR: Timed out to satisfy the PLL mask\n");
 			return -ETIMEDOUT;
+		}
+
+		data = mmio_read_32(CLKMGR(STAT)) & mask;
+		/* wait for stable lock, make sure it is stable for these counts */
+		if (data == mask) {
+			retry++;
+		} else {
+			retry = 0U;
+		}
+
+		/* we are good now, break */
+		if (retry >= 5U) {
+			break;
+		}
+
+		count++;
+	} while (1);
 
-	} while ((CLKMGR_STAT_MAINPLLLOCKED(data) == 0) ||
-			(CLKMGR_STAT_PERPLLLOCKED(data) == 0));
 	return 0;
 }
 
-uint32_t wait_fsm(void)
+static int wait_fsm(void)
 {
 	uint32_t data;
 	uint32_t count = 0;
 
 	do {
-		data = mmio_read_32(CLKMGR_OFFSET + CLKMGR_STAT);
+		data = mmio_read_32(CLKMGR(STAT));
 		count++;
-		if (count >= 1000)
+		if (count >= CLKMGR_MAX_RETRY_COUNT) {
+			ERROR("CLKMGR: Timed out on fsm state\n");
 			return -ETIMEDOUT;
-
+		}
 	} while (CLKMGR_STAT_BUSY(data) == CLKMGR_STAT_BUSY_E_BUSY);
 
 	return 0;
 }
 
-uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data)
+static uint32_t calc_pll_vcocalibration(uint32_t pllm, uint32_t pllglob)
 {
-	uint32_t val = 0;
-	uint32_t count = 0;
-	uint32_t req_status = 0;
+	uint32_t mdiv, refclkdiv, drefclkdiv, mscnt, hscnt, vcocalib;
+
+	mdiv = pllm & CLKMGR_PLLM_MDIV_MASK;
+	drefclkdiv = ((pllglob & CLKMGR_PLLGLOB_DREFCLKDIV_MASK) >>
+			CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET);
+	refclkdiv = ((pllglob & CLKMGR_PLLGLOB_REFCLKDIV_MASK) >>
+			CLKMGR_PLLGLOB_REFCLKDIV_OFFSET);
+	mscnt = CLKMGR_VCOCALIB_MSCNT_CONST / (mdiv * BIT(drefclkdiv));
+	if (mscnt == 0) {
+		mscnt = 1;
+	}
 
-	val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ |
-		(data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR);
-	mmio_write_32(pll_mem_offset, val);
+	hscnt = (mdiv * mscnt * BIT(drefclkdiv) / refclkdiv) -
+		CLKMGR_VCOCALIB_HSCNT_CONST;
 
-	do {
-		req_status = mmio_read_32(pll_mem_offset);
+	vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
+			((mscnt << CLKMGR_VCOCALIB_MSCNT_OFFSET) &
+			CLKMGR_VCOCALIB_MSCNT_MASK);
+
+	return vcocalib;
+}
+
+static int pll_source_sync_wait(uint32_t pll_type, int retry_count)
+{
+	int count = 0;
+	uint32_t req_status;
+
+	if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+		req_status = mmio_read_32(CLKMGR_MAINPLL(MEM));
+	} else {
+		req_status = mmio_read_32(CLKMGR_PERPLL(MEM));
+	}
+
+	/* Check for error bit set */
+	if ((req_status & CLKMGR_MEM_ERR) != 0) {
+		INFO("CLKMGR: %s: Memory Error Status Signal Assert\n", __func__);
+	}
+
+	while ((count < retry_count) && (req_status & CLKMGR_MEM_REQ)) {
+		if (pll_type == CLKMGR_MAINPLL_TYPE)
+			req_status = mmio_read_32(CLKMGR_MAINPLL(MEM));
+		else
+			req_status = mmio_read_32(CLKMGR_PERPLL(MEM));
 		count++;
-	} while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+	}
 
-	if (count >= 10)
+	if (count >= retry_count) {
+		ERROR("CLKMGR: %s: timeout with pll_type %d\n", __func__, pll_type);
 		return -ETIMEDOUT;
+	}
 
 	return 0;
 }
 
-uint32_t pll_source_sync_read(uint32_t pll_mem_offset)
+static int pll_source_sync_config(uint32_t pll_type, uint32_t addr_offset,
+				  uint32_t wdat, int retry_count)
 {
-	uint32_t val = 0;
-	uint32_t rdata = 0;
-	uint32_t count = 0;
-	uint32_t req_status = 0;
+	uint32_t addr;
+	uint32_t val;
 
-	val = (CLKMGR_MEM_REQ | CLKMGR_MEM_ADDR);
-	mmio_write_32(pll_mem_offset, val);
+	addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
+	val = (CLKMGR_MEM_REQ | CLKMGR_MEM_WR |
+		(wdat << CLKMGR_MEM_WDAT_OFFSET) | addr);
 
-	do {
-		req_status = mmio_read_32(pll_mem_offset);
-		count++;
-	} while ((req_status & CLKMGR_MEM_REQ) && (count < 10));
+	if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+		mmio_write_32(CLKMGR_MAINPLL(MEM), val);
+	} else {
+		mmio_write_32(CLKMGR_PERPLL(MEM), val);
+	}
 
-	if (count >= 10)
+	return pll_source_sync_wait(pll_type, retry_count);
+}
+
+static int pll_source_sync_read(uint32_t pll_type, uint32_t addr_offset,
+				uint32_t *rdata, int retry_count)
+{
+	uint32_t addr;
+	uint32_t val;
+
+	addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
+	val = ((CLKMGR_MEM_REQ & ~CLKMGR_MEM_WR) | addr);
+
+	if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+		mmio_write_32(CLKMGR_MAINPLL(MEM), val);
+	} else {
+		mmio_write_32(CLKMGR_PERPLL(MEM), val);
+	}
+
+	*rdata = 0;
+
+	if ((pll_source_sync_wait(pll_type, retry_count)) != 0) {
 		return -ETIMEDOUT;
+	}
 
-	rdata = mmio_read_32(pll_mem_offset + 0x4);
-	INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata);
+	if ((pll_type == CLKMGR_MAINPLL_TYPE) != 0) {
+		*rdata = mmio_read_32(CLKMGR_MAINPLL(MEMSTAT));
+	} else {
+		*rdata = mmio_read_32(CLKMGR_PERPLL(MEMSTAT));
+	}
 
-	return rdata;
+	return 0;
 }
 
-void config_clkmgr_handoff(handoff *hoff_ptr)
+static void config_pll_pd_state(uint32_t pll_type)
 {
-	/* Take both PLL out of reset and power up */
+	uint32_t rdata;
 
-	mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
-			CLKMGR_PLLGLOB_PD_SET_MSK |
-			CLKMGR_PLLGLOB_RST_SET_MSK);
-	mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
-			CLKMGR_PLLGLOB_PD_SET_MSK |
-			CLKMGR_PLLGLOB_RST_SET_MSK);
+	for (uint32_t i = 0; i < ARRAY_SIZE(pll_cfg_set); i++) {
+		(void)pll_source_sync_read(pll_type, pll_cfg_set[i].addr, &rdata,
+					   CLKMGR_MAX_RETRY_COUNT);
 
-	/* PLL lock */
-	wait_pll_lock();
+		(void)pll_source_sync_config(pll_type, pll_cfg_set[i].addr,
+				((rdata & ~pll_cfg_set[i].mask) | pll_cfg_set[i].data),
+				CLKMGR_MAX_RETRY_COUNT);
+	}
+}
+
+int config_clkmgr_handoff(handoff *hoff_ptr)
+{
+	int ret = 0;
+	uint32_t mainpll_vcocalib;
+	uint32_t perpll_vcocalib;
+
+	/* Enter boot mode before any configuration */
+	mmio_setbits_32(CLKMGR(CTRL), CLKMGR_CTRL_BOOTMODE);
 
 	/* Bypass all mainpllgrp's clocks to input clock ref */
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASSS, 0xff);
+	mmio_setbits_32(CLKMGR_MAINPLL(BYPASS), CLKMGR_MAINPLL_BYPASS_ALL);
+	ret = wait_fsm();
+	if (ret != 0)
+		return ret;
+
 	/* Bypass all perpllgrp's clocks to input clock ref */
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0xff);
+	mmio_setbits_32(CLKMGR_PERPLL(BYPASS), CLKMGR_PERPLL_BYPASS_ALL);
+	ret = wait_fsm();
+	if (ret != 0)
+		return ret;
+
+	/* Take both PLL out of reset and power down */
+	mmio_clrbits_32(CLKMGR_MAINPLL(PLLGLOB),
+			CLKMGR_MAINPLL_PLLGLOB_PD_N | CLKMGR_MAINPLL_PLLGLOB_RST_N);
+	mmio_clrbits_32(CLKMGR_PERPLL(PLLGLOB),
+			CLKMGR_PERPLL_PLLGLOB_PD_N | CLKMGR_PERPLL_PLLGLOB_RST_N);
+
+	/* Setup main PLL dividers */
+	mainpll_vcocalib = calc_pll_vcocalibration(hoff_ptr->main_pll_pllm,
+						hoff_ptr->main_pll_pllglob);
+	mmio_write_32(CLKMGR_MAINPLL(PLLGLOB),
+			hoff_ptr->main_pll_pllglob & ~CLKMGR_MAINPLL_PLLGLOB_RST_N);
+	mmio_write_32(CLKMGR_MAINPLL(FDBCK), hoff_ptr->main_pll_fdbck);
+	mmio_write_32(CLKMGR_MAINPLL(VCOCALIB), mainpll_vcocalib);
+	mmio_write_32(CLKMGR_MAINPLL(PLLC0), hoff_ptr->main_pll_pllc0);
+	mmio_write_32(CLKMGR_MAINPLL(PLLC1), hoff_ptr->main_pll_pllc1);
+	mmio_write_32(CLKMGR_MAINPLL(PLLC2), hoff_ptr->main_pll_pllc2);
+	mmio_write_32(CLKMGR_MAINPLL(PLLC3), hoff_ptr->main_pll_pllc3);
+	mmio_write_32(CLKMGR_MAINPLL(PLLM), hoff_ptr->main_pll_pllm);
+	mmio_write_32(CLKMGR_MAINPLL(NOCCLK), hoff_ptr->main_pll_nocclk);
+	mmio_write_32(CLKMGR_MAINPLL(NOCDIV), hoff_ptr->main_pll_nocdiv);
+
+	/* Setup peripheral PLL dividers */
+	perpll_vcocalib = calc_pll_vcocalibration(hoff_ptr->per_pll_pllm,
+						hoff_ptr->per_pll_pllglob);
+	mmio_write_32(CLKMGR_PERPLL(PLLGLOB),
+			hoff_ptr->per_pll_pllglob & ~CLKMGR_PERPLL_PLLGLOB_RST_N);
+	mmio_write_32(CLKMGR_PERPLL(FDBCK), hoff_ptr->per_pll_fdbck);
+	mmio_write_32(CLKMGR_PERPLL(VCOCALIB), perpll_vcocalib);
+	mmio_write_32(CLKMGR_PERPLL(PLLC0), hoff_ptr->per_pll_pllc0);
+	mmio_write_32(CLKMGR_PERPLL(PLLC1), hoff_ptr->per_pll_pllc1);
+	mmio_write_32(CLKMGR_PERPLL(PLLC2), hoff_ptr->per_pll_pllc2);
+	mmio_write_32(CLKMGR_PERPLL(PLLC3), hoff_ptr->per_pll_pllc3);
+	mmio_write_32(CLKMGR_PERPLL(PLLM), hoff_ptr->per_pll_pllm);
+	mmio_write_32(CLKMGR_PERPLL(EMACCTL), hoff_ptr->per_pll_emacctl);
+	mmio_write_32(CLKMGR_PERPLL(GPIODIV), hoff_ptr->per_pll_gpiodiv);
+
+	/* Configure ping pong counters */
+	mmio_write_32(CLKMGR_ALTERA(EMACACTR), hoff_ptr->alt_emacactr);
+	mmio_write_32(CLKMGR_ALTERA(EMACBCTR), hoff_ptr->alt_emacbctr);
+	mmio_write_32(CLKMGR_ALTERA(EMACPTPCTR), hoff_ptr->alt_emacptpctr);
+	mmio_write_32(CLKMGR_ALTERA(GPIODBCTR), hoff_ptr->alt_gpiodbctr);
+	mmio_write_32(CLKMGR_ALTERA(S2FUSER0CTR), hoff_ptr->alt_s2fuser0ctr);
+	mmio_write_32(CLKMGR_ALTERA(S2FUSER1CTR), hoff_ptr->alt_s2fuser1ctr);
+	mmio_write_32(CLKMGR_ALTERA(PSIREFCTR), hoff_ptr->alt_psirefctr);
+	mmio_write_32(CLKMGR_ALTERA(USB31CTR), hoff_ptr->alt_usb31ctr);
+	mmio_write_32(CLKMGR_ALTERA(DSUCTR), hoff_ptr->alt_dsuctr);
+	mmio_write_32(CLKMGR_ALTERA(CORE01CTR), hoff_ptr->alt_core01ctr);
+	mmio_write_32(CLKMGR_ALTERA(CORE23CTR), hoff_ptr->alt_core23ctr);
+	mmio_write_32(CLKMGR_ALTERA(CORE2CTR), hoff_ptr->alt_core2ctr);
+	mmio_write_32(CLKMGR_ALTERA(CORE3CTR), hoff_ptr->alt_core3ctr);
 
-	/* Pass clock source frequency into scratch register */
-	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1),
-		hoff_ptr->hps_osc_clk_hz);
-	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2),
-		hoff_ptr->fpga_clk_hz);
+	/* Take both PLL out of reset and power up */
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLGLOB),
+			CLKMGR_MAINPLL_PLLGLOB_PD_N | CLKMGR_MAINPLL_PLLGLOB_RST_N);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLGLOB),
+			CLKMGR_PERPLL_PLLGLOB_PD_N | CLKMGR_PERPLL_PLLGLOB_RST_N);
+
+	/* Main PLL configuration in Powed down state */
+	config_pll_pd_state(CLKMGR_MAINPLL_TYPE);
+
+	/* Peripheral PLL configuration in Powed down state */
+	config_pll_pd_state(CLKMGR_PERPLL_TYPE);
+
+	/* Enable main PLL clkslices */
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLC0), CLKMGR_MAINPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLC1), CLKMGR_MAINPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLC2), CLKMGR_MAINPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLC3), CLKMGR_MAINPLL_PLLCX_EN);
+
+	/* Enable periheral PLL clkslices */
+	mmio_setbits_32(CLKMGR_PERPLL(PLLC0), CLKMGR_PERPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLC1), CLKMGR_PERPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLC2), CLKMGR_PERPLL_PLLCX_EN);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLC3), CLKMGR_PERPLL_PLLCX_EN);
+
+	/* Wait for main and peri PLL lock state */
+	ret = wait_pll_lock(CLKMGR_STAT_ALLPLLLOCKED);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* Main PLL and per PLL lost lock */
+	mmio_setbits_32(CLKMGR_MAINPLL(LOSTLOCK), CLKMGR_XPLL_LOSTLOCK_BYPASSCLEAR);
+	mmio_setbits_32(CLKMGR_PERPLL(LOSTLOCK), CLKMGR_XPLL_LOSTLOCK_BYPASSCLEAR);
+
+	/* Main PLL and per PLL clear lostlock bypass */
+	mmio_setbits_32(CLKMGR_MAINPLL(PLLGLOB), CLKMGR_XPLLGLOB_CLR_LOSTLOCK_BYPASS);
+	mmio_setbits_32(CLKMGR_PERPLL(PLLGLOB), CLKMGR_XPLLGLOB_CLR_LOSTLOCK_BYPASS);
+
+	/* Pass clock source frequency into boot scratch register */
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1), hoff_ptr->hps_osc_clk_hz);
+	mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2), hoff_ptr->fpga_clk_hz);
 
 	/* Take all PLLs out of bypass */
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0);
-	wait_fsm();
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_BYPASS, 0);
-	wait_fsm();
+	mmio_clrbits_32(CLKMGR_MAINPLL(BYPASS), CLKMGR_MAINPLL_BYPASS_ALL);
+	ret = wait_fsm();
+	if (ret != 0) {
+		return ret;
+	}
+
+	mmio_clrbits_32(CLKMGR_PERPLL(BYPASS), CLKMGR_PERPLL_BYPASS_ALL);
+	ret = wait_fsm();
+	if (ret != 0) {
+		return ret;
+	}
 
-	/* Enable mainpllgrp's software-managed clock */
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_EN,
-			CLKMGR_MAINPLL_EN_RESET);
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
-			CLKMGR_PERPLL_EN_RESET);
+	/* Clear the loss of lock bits (write 1 to clear) */
+	mmio_write_32(CLKMGR(INTRCLR),
+			CLKMGR_INTRCLR_MAINLOCKLOST | CLKMGR_INTRCLR_PERLOCKLOST);
+
+	/* Take all ping pong counters out of reset */
+	mmio_clrbits_32(CLKMGR_ALTERA(EXTCNTRST), CLKMGR_ALTERA_EXTCNTRST_ALLCNTRST);
+
+	/* Exit boot mode */
+	mmio_clrbits_32(CLKMGR(CTRL), CLKMGR_CTRL_BOOTMODE);
+
+	return 0;
 }
 
 /* Extract reference clock from platform clock source */
-uint32_t get_ref_clk(uint32_t pllglob)
+uint32_t get_ref_clk(uint32_t pllglob_reg, uint32_t pllm_reg)
 {
-	uint32_t arefclkdiv, ref_clk;
-	uint32_t scr_reg;
+	uint32_t arefclkdiv, ref_clk, mdiv;
+	uint32_t pllglob_val, pllm_val;
+
+	/* Read pllglob and pllm registers */
+	pllglob_val = mmio_read_32(pllglob_reg);
+	pllm_val = mmio_read_32(pllm_reg);
 
-	switch (CLKMGR_PSRC(pllglob)) {
+	switch (CLKMGR_PLLGLOB_PSRC(pllglob_val)) {
 	case CLKMGR_PLLGLOB_PSRC_EOSC1:
-		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1);
-		ref_clk = mmio_read_32(scr_reg);
+		ref_clk = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1));
 		break;
+
 	case CLKMGR_PLLGLOB_PSRC_INTOSC:
 		ref_clk = CLKMGR_INTOSC_HZ;
 		break;
+
 	case CLKMGR_PLLGLOB_PSRC_F2S:
-		scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2);
-		ref_clk = mmio_read_32(scr_reg);
+		ref_clk = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2));
 		break;
+
 	default:
 		ref_clk = 0;
 		assert(0);
 		break;
 	}
 
-	arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob);
+	/* Get reference clock divider */
+	arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob_val);
 	ref_clk /= arefclkdiv;
 
+	/* Feedback clock divider */
+	mdiv = CLKMGR_PLLM_MDIV(pllm_val);
+	ref_clk *= mdiv;
+
+	VERBOSE("CLKMGR: %s: ref_clk %u\n", __func__, ref_clk);
 	return ref_clk;
 }
 
 /* Calculate clock frequency based on parameter */
-uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc)
+uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t mainpllc_reg,
+		      uint32_t perpllc_reg)
 {
-	uint32_t ref_clk = 0;
+	uint32_t clock = 0;
+	uint32_t clk_psrc;
+
+	/*
+	 * Select source for the active 5:1 clock selection when the PLL
+	 * is not bypassed
+	 */
+	clk_psrc = mmio_read_32(psrc_reg);
+	switch (GET_CLKMGR_CLKSRC(clk_psrc)) {
+	case CLKMGR_CLKSRC_MAIN:
+		clock = get_ref_clk(CLKMGR_MAINPLL(PLLGLOB), CLKMGR_MAINPLL(PLLM));
+		clock /= (mmio_read_32(mainpllc_reg) & CLKMGR_PLLCX_DIV_MSK);
+		break;
+
+	case CLKMGR_CLKSRC_PER:
+		clock = get_ref_clk(CLKMGR_PERPLL(PLLGLOB), CLKMGR_PERPLL(PLLM));
+		clock /= (mmio_read_32(perpllc_reg) & CLKMGR_PLLCX_DIV_MSK);
+		break;
 
-	uint32_t clk_psrc, mdiv;
-	uint32_t pllm_reg, pllc_reg, pllc_div, pllglob_reg;
+	case CLKMGR_CLKSRC_OSC1:
+		clock = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1));
+		break;
 
+	case CLKMGR_CLKSRC_INTOSC:
+		clock = CLKMGR_INTOSC_HZ;
+		break;
 
-	clk_psrc = mmio_read_32(CLKMGR_MAINPLL + psrc_reg);
-	clk_psrc = 0;
+	case CLKMGR_CLKSRC_FPGA:
+		clock = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2));
+		break;
 
-	switch (clk_psrc) {
-	case 0:
-		pllm_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLM;
-		pllc_reg = CLKMGR_MAINPLL + main_pllc;
-		pllglob_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB;
+	default:
+		ERROR("CLKMGR: Invalid clock source select\n");
+		assert(0);
 		break;
 	}
 
-	ref_clk = get_ref_clk(mmio_read_32(pllglob_reg));
-	mdiv = CLKMGR_PLLM_MDIV(mmio_read_32(pllm_reg));
-	ref_clk *= mdiv;
+	VERBOSE("CLKMGR: %s: clock type %lu and its value %u\n",
+			__func__, GET_CLKMGR_CLKSRC(clk_psrc), clock);
 
-	pllc_div = mmio_read_32(pllc_reg) & 0x7ff;
-	NOTICE("return = %d Hz\n", (ref_clk / pllc_div));
+	return clock;
+}
 
-	ref_clk = 200000000;
-	return (uint32_t) ref_clk;
+/* Get L3 free clock */
+static uint32_t get_l3_main_free_clk(void)
+{
+	return get_clk_freq(CLKMGR_MAINPLL(NOCCLK),
+			    CLKMGR_MAINPLL(PLLC3),
+			    CLKMGR_PERPLL(PLLC1));
+}
 
+/* Get L4 main clock */
+static uint32_t get_l4_main_clk(void)
+{
+	return get_l3_main_free_clk();
 }
 
-/* Return L3 interconnect clock */
-uint32_t get_l3_clk(void)
+/* Get L4 mp clock */
+static uint32_t get_l4_mp_clk(void)
 {
-	uint32_t l3_clk;
+	uint32_t l3_main_free_clk = get_l3_main_free_clk();
+	uint32_t mainpll_nocdiv_l4mp = BIT(GET_CLKMGR_MAINPLL_NOCDIV_L4MP(
+					mmio_read_32(CLKMGR_MAINPLL(NOCDIV))));
+
+	uint32_t l4_mp_clk = (l3_main_free_clk / mainpll_nocdiv_l4mp);
 
-	l3_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC1,
-				CLKMGR_PERPLL_PLLC1);
-	return l3_clk;
+	return l4_mp_clk;
 }
 
-/* Calculate clock frequency to be used for watchdog timer */
-uint32_t get_wdt_clk(void)
+/* Get L4 sp clock */
+static uint32_t get_l4_sp_clk(void)
 {
-	uint32_t l3_clk, l4_sys_clk;
+	uint32_t l3_main_free_clk = get_l3_main_free_clk();
+	uint32_t mainpll_nocdiv_l4sp = BIT(GET_CLKMGR_MAINPLL_NOCDIV_L4SP(
+					mmio_read_32(CLKMGR_MAINPLL(NOCDIV))));
 
-	l3_clk = get_l3_clk();
-	l4_sys_clk = l3_clk / 4;
+	uint32_t l4_sp_clk = (l3_main_free_clk / mainpll_nocdiv_l4sp);
 
-	return l4_sys_clk;
+	return l4_sp_clk;
 }
 
-/* Calculate clock frequency to be used for UART driver */
-uint32_t get_uart_clk(void)
+/* Calculate clock frequency to be used for SDMMC driver */
+uint32_t get_sdmmc_clk(void)
+{
+	uint32_t l4_mp_clk = get_l4_mp_clk();
+	uint32_t mainpll_nocdiv = mmio_read_32(CLKMGR_MAINPLL(NOCDIV));
+	uint32_t sdmmc_clk = l4_mp_clk / BIT(GET_CLKMGR_MAINPLL_NOCDIV_SPHY(mainpll_nocdiv));
+
+	return sdmmc_clk;
+}
+
+/* Get clock for ethernet mac0 */
+static uint32_t get_emaca_clk(void)
 {
-	uint32_t data32, l3_clk, l4_sp_clk;
+	uint32_t emaca_ctr = mmio_read_32(CLKMGR_ALTERA(EMACACTR));
+	uint32_t perpll_emacctl = mmio_read_32(CLKMGR_PERPLL(EMACCTL));
+	uint32_t perpll_emac_src = GET_CLKMGR_PERPLL_EMAC0_CLK_SRC(perpll_emacctl);
+	uint32_t emac_ctr_reg;
+	uint32_t emac_clock;
+
+	if (perpll_emac_src != 0) {
+		emac_ctr_reg = CLKMGR_ALTERA(EMACBCTR);
+	} else {
+		emac_ctr_reg = CLKMGR_ALTERA(EMACACTR);
+	}
 
-	l3_clk = get_l3_clk();
+	/* Get EMACA clock source */
+	uint32_t emacactr_src = GET_CLKMGR_EMACACTR_CLK_SRC(emaca_ctr);
 
-	data32 = mmio_read_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV);
-	data32 = (data32 >> 16) & 0x3;
+	/* Read the desired EMAC register again */
+	emaca_ctr = mmio_read_32(emac_ctr_reg);
 
-	l4_sp_clk = l3_clk >> data32;
+	/* Get the divider now */
+	uint32_t emaca_ctr_div = emaca_ctr & GENMASK(10, 0);
 
-	return l4_sp_clk;
+	switch (emacactr_src) {
+	case CLKMGR_CLKSRC_MAIN:
+		emac_clock = get_ref_clk(CLKMGR_MAINPLL(PLLGLOB), CLKMGR_MAINPLL(PLLM));
+		emac_clock /= (mmio_read_32(CLKMGR_MAINPLL(PLLC1)) & GENMASK(10, 0));
+		break;
+
+	case CLKMGR_CLKSRC_PER:
+		emac_clock = get_ref_clk(CLKMGR_PERPLL(PLLGLOB), CLKMGR_PERPLL(PLLM));
+		emac_clock /= (mmio_read_32(CLKMGR_PERPLL(PLLC3)) & GENMASK(10, 0));
+		break;
+
+	default:
+		ERROR("CLKMGR: %s invalid clock source\n", __func__);
+		emac_clock = 0;
+		return emac_clock;
+	}
+
+	emac_clock /= 1 + emaca_ctr_div;
+
+	return emac_clock;
 }
 
-/* Calculate clock frequency to be used for SDMMC driver */
-uint32_t get_mmc_clk(void)
+/* Get MPU clock */
+static uint32_t get_mpu_clk(void)
+{
+	uint32_t cpu_id = MPIDR_AFFLVL1_VAL(read_mpidr());
+	uint32_t ctr_reg = 0U;
+	uint32_t clock;
+
+	if (cpu_id > CLKMGR_ALTERA_CORE1) {
+		clock = get_clk_freq(CLKMGR_ALTERA(CORE23CTR),
+				     CLKMGR_MAINPLL(PLLC0),
+				     CLKMGR_PERPLL(PLLC0));
+	} else {
+		clock = get_clk_freq(CLKMGR_ALTERA(CORE01CTR),
+				     CLKMGR_MAINPLL(PLLC1),
+				     CLKMGR_PERPLL(PLLC0));
+	}
+
+	switch (cpu_id) {
+	case CLKMGR_ALTERA_CORE0:
+	case CLKMGR_ALTERA_CORE1:
+		ctr_reg = CLKMGR_ALTERA(CORE01CTR);
+		break;
+
+	case CLKMGR_ALTERA_CORE2:
+		ctr_reg = CLKMGR_ALTERA(CORE2CTR);
+		break;
+
+	case CLKMGR_ALTERA_CORE3:
+		ctr_reg = CLKMGR_ALTERA(CORE3CTR);
+		break;
+
+	default:
+		break;
+	}
+
+	/* Division setting for ping pong counter in clock slice */
+	clock /= 1 + (mmio_read_32(ctr_reg) & CLKMGR_PLLCX_DIV_MSK);
+
+	return clock;
+}
+
+/* Calculate clock frequency to be used for watchdog timer */
+static uint32_t get_wdt_clk(void)
+{
+	uint32_t l3_main_free_clk = get_l3_main_free_clk();
+	uint32_t mainpll_nocdiv_l4sysfreeclk = BIT(GET_CLKMGR_MAINPLL_NOCDIV_L4SYSFREE(
+						mmio_read_32(CLKMGR_MAINPLL(NOCDIV))));
+	uint32_t l4_sys_free_clk = (l3_main_free_clk / mainpll_nocdiv_l4sysfreeclk);
+
+	return l4_sys_free_clk;
+}
+
+/*
+ * Calculate clock frequency to be used for UART driver.
+ * 'l4_sp_clk' (100MHz) will be used for slow peripherals like UART, I2C
+ * and Timers.
+ */
+static uint32_t get_uart_clk(void)
+{
+	return get_l4_sp_clk();
+}
+
+/* Return the clock value of a given system component */
+uint32_t clkmgr_get_rate(uint32_t clk_id)
 {
-	uint32_t mmc_clk;
+	uint32_t clk_rate;
 
-	//TODO: To update when handoff data is ready
-	//uint32_t data32;
+	switch (clk_id) {
+	case CLKMGR_MPU_CLK_ID:
+		clk_rate = get_mpu_clk();
+		break;
 
-	//mmc_clk = get_clk_freq(CLKMGR_ALTERA_SDMMCCTR, CLKMGR_MAINPLL_PLLC3, CLKMGR_PERPLL_PLLC3);
+	case CLKMGR_L4_MAIN_CLK_ID:
+		clk_rate = get_l4_main_clk();
+		break;
 
-	//data32 = mmio_read_32(CLKMGR_ALTERA + CLKMGR_ALTERA_SDMMCCTR);
-	//data32 = (data32 & 0x7ff) + 1;
-	//mmc_clk = (mmc_clk / data32) / 4;
+	case CLKMGR_L4_MP_CLK_ID:
+		clk_rate = get_l4_mp_clk();
+		break;
 
+	case CLKMGR_L4_SP_CLK_ID:
+		clk_rate = get_l4_sp_clk();
+		break;
 
-	mmc_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC3,
-				CLKMGR_PERPLL_PLLC3);
+	case CLKMGR_EMAC0_CLK_ID:
+		clk_rate = get_emaca_clk();
+		break;
 
-	// TODO: To update when handoff data is ready
-	NOTICE("mmc_clk = %d Hz\n", mmc_clk);
+	case CLKMGR_SDMMC_CLK_ID:
+		clk_rate = get_sdmmc_clk();
+		break;
+
+	case CLKMGR_UART_CLK_ID:
+		clk_rate = get_uart_clk();
+		break;
 
-	return mmc_clk;
+	case CLKMGR_WDT_CLK_ID:
+		clk_rate = get_wdt_clk();
+		break;
+
+	default:
+		ERROR("CLKMGR: %s: Invalid clock ID\n", __func__);
+		clk_rate = 0;
+		break;
+	}
+
+	return clk_rate;
+}
+
+/* Return mpu_periph_clk tick */
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return PLAT_SYS_COUNTER_FREQ_IN_TICKS;
 }
diff --git a/plat/intel/soc/agilex5/soc/agilex5_ddr.c b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
new file mode 100644
index 00000000..ef2ae57f
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_ddr.c
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include "lib/mmio.h"
+
+#include "agilex5_ddr.h"
+#include "agilex5_iossm_mailbox.h"
+
+/*
+ * TODO: We need to leverage the legacy products DDR drivers and consider
+ * the upcoming products like KM and then come up with common source code/driver
+ * architecture to address all the products in one view.
+ */
+
+#define SYSMGR_BS_COLD3_DDR_RESET_TYPE_MASK		GENMASK(31, 29)
+#define SYSMGR_BS_COLD3_DDR_RESET_TYPE_SHIFT		29
+#define SYSMGR_BS_COLD3_DDR_DBE_MASK			(1 << 1)
+#define SYSMGR_BS_COLD3_OCRAM_DBE_MASK			(1)
+#define SYSMGR_BS_POR0_DDR_PROGRESS_MASK		(1)
+
+/* MPFE NOC registers */
+#define F2SDRAM_SIDEBAND_FLAGOUTSET0			0x50
+#define F2SDRAM_SIDEBAND_FLAGOUTCLR0			0x54
+#define F2SDRAM_SIDEBAND_FLAGOUTSTATUS0			0x58
+
+#define SOCFPGA_F2SDRAM_MGR_ADDRESS			0x18001000
+#define SOCFPGA_MPFE_SCR_IO96B0				0x18000D00
+#define SOCFPGA_MPFE_SCR_IO96B1				0x18000D04
+#define SOCFPGA_MPFE_NOC_SCHED_CSR			0x18000D08
+
+#define SIDEBANDMGR_FLAGOUTSET0_REG			(SOCFPGA_F2SDRAM_MGR_ADDRESS \
+							+ F2SDRAM_SIDEBAND_FLAGOUTSET0)
+#define SIDEBANDMGR_FLAGOUTSTATUS0_REG			(SOCFPGA_F2SDRAM_MGR_ADDRESS \
+							+F2SDRAM_SIDEBAND_FLAGOUTSTATUS0)
+#define SIDEBANDMGR_FLAGOUTCLR0_REG			(SOCFPGA_F2SDRAM_MGR_ADDRESS \
+							+ F2SDRAM_SIDEBAND_FLAGOUTCLR0)
+#define SZ_8						0x00000008
+
+
+/* Firewall MPU DDR SCR registers */
+#define FW_MPU_DDR_SCR_EN				0x00
+#define FW_MPU_DDR_SCR_EN_SET				0x04
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE		0x10
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT		0x14
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT		0x18
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT		0x1c
+
+#define SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS			0x18000800
+#define SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS			0x18000A00
+#define SOCFPGA_FW_TBU2NOC_ADDRESS			0x18000C00
+
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE		0x90
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT	0x94
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT		0x98
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT	0x9c
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT_FIELD	0xff
+
+/* Firewall F2SDRAM DDR SCR registers */
+#define FW_F2SDRAM_DDR_SCR_EN				0x00
+#define FW_F2SDRAM_DDR_SCR_EN_SET			0x04
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE		0x10
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT		0x14
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT		0x18
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT		0x1c
+
+#define FW_MPU_DDR_SCR_WRITEL(data, reg)					\
+	do {									\
+		mmio_write_32(SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS + (reg), data);	\
+		mmio_write_32(SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS + (reg), data);	\
+	} while (0)
+
+#define FW_F2SDRAM_DDR_SCR_WRITEL(data, reg)				\
+	mmio_write_32(SOCFPGA_FW_TBU2NOC_ADDRESS + (reg), data)
+
+/* DDR banks info set */
+static struct ddr_info ddr_info_set[CONFIG_NR_DRAM_BANKS];
+
+/* Reset type */
+enum reset_type {
+	POR_RESET,
+	WARM_RESET,
+	COLD_RESET,
+	NCONFIG,
+	JTAG_CONFIG,
+	RSU_RECONFIG
+};
+
+/* Get reset type by reading boot scratch register cold3 */
+static inline enum reset_type get_reset_type(uint32_t sys_reg)
+{
+	return ((sys_reg & SYSMGR_BS_COLD3_DDR_RESET_TYPE_MASK) >>
+		 SYSMGR_BS_COLD3_DDR_RESET_TYPE_SHIFT);
+}
+
+/* DDR hang check before the reset */
+static inline bool is_ddr_init_hang(void)
+{
+	uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0));
+
+	if ((sys_reg & SYSMGR_BS_POR0_DDR_PROGRESS_MASK) != 0) {
+		INFO("DDR: Hang before this reset\n");
+		return true;
+	}
+
+	return false;
+}
+
+/* Set the DDR init progress bit */
+static inline void ddr_init_inprogress(bool start)
+{
+	if (start) {
+		mmio_setbits_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0),
+				SYSMGR_BS_POR0_DDR_PROGRESS_MASK);
+	} else {
+		mmio_clrbits_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_0),
+				SYSMGR_BS_POR0_DDR_PROGRESS_MASK);
+	}
+}
+
+/* Configure the IO96B CSRs address based on the handoff data */
+static void config_io96b_csr_addr(bool is_dualemif, struct io96b_info *io96b_ctrl)
+{
+	if (is_dualemif)
+		io96b_ctrl->num_instance = 2;
+	else
+		io96b_ctrl->num_instance = 1;
+
+	/* Assign IO96B CSR base address if it is valid */
+	for (int i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			io96b_ctrl->io96b_0.io96b_csr_addr = 0x18400000;
+			INFO("DDR: IO96B0 0x%llx CSR enabled\n",
+			     io96b_ctrl->io96b_0.io96b_csr_addr);
+			break;
+
+		case 1:
+			io96b_ctrl->io96b_1.io96b_csr_addr = 0x18800000;
+			INFO("DDR: IO96B1 0x%llx CSR enabled\n",
+			     io96b_ctrl->io96b_1.io96b_csr_addr);
+			break;
+
+		default:
+			ERROR("%s: Invalid IO96B CSR\n", __func__);
+		} /* switch */
+	} /* for */
+}
+
+static inline bool hps_ocram_dbe_status(void)
+{
+	uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_3));
+
+	if ((sys_reg & SYSMGR_BS_COLD3_OCRAM_DBE_MASK) != 0)
+		return true;
+
+	return false;
+}
+
+static inline bool ddr_ecc_dbe_status(void)
+{
+	uint32_t sys_reg = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_3));
+
+	if ((sys_reg & SYSMGR_BS_COLD3_DDR_DBE_MASK) != 0)
+		return true;
+
+	return false;
+}
+
+static void sdram_set_firewall_non_f2sdram(void)
+{
+	uint32_t i;
+	phys_size_t value;
+	uint32_t lower, upper;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (ddr_info_set[i].size == 0) {
+			continue;
+		}
+
+		value = ddr_info_set[i].start;
+
+		/*
+		 * Keep first 1MB of SDRAM memory region as secure region when
+		 * using ATF flow, where the ATF code is located.
+		 */
+		value += SZ_1M;
+
+		/* Setting non-secure MPU region base and base extended */
+		lower = LO(value);
+		upper = HI(value);
+
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		/* Setting non-secure Non-MPU region base and base extended */
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		/* Setting non-secure MPU limit and limit extended */
+		value = ddr_info_set[i].start + ddr_info_set[i].size - 1;
+
+		lower = LO(value);
+		upper = HI(value);
+
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		/* Setting non-secure Non-MPU limit and limit extended */
+		FW_MPU_DDR_SCR_WRITEL(lower,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT +
+				      (i * 4 * sizeof(uint32_t)));
+		FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
+				      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT +
+				      (i * 4 * sizeof(uint32_t)));
+
+		FW_MPU_DDR_SCR_WRITEL(BIT(i) | BIT(i + 8),
+				      FW_MPU_DDR_SCR_EN_SET);
+	}
+}
+
+static void sdram_set_firewall_f2sdram(void)
+{
+	uint32_t i;
+	phys_size_t value;
+	uint32_t lower, upper;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (ddr_info_set[i].size == 0) {
+			continue;
+		}
+
+		value = ddr_info_set[i].start;
+
+		/* Keep first 1MB of SDRAM memory region as secure region when
+		 * using ATF flow, where the ATF code is located.
+		 */
+		value += SZ_1M;
+
+		/* Setting base and base extended */
+		lower = LO(value);
+		upper = HI(value);
+		FW_F2SDRAM_DDR_SCR_WRITEL(lower,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE +
+					  (i * 4 * sizeof(uint32_t)));
+		FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT +
+					  (i * 4 * sizeof(uint32_t)));
+
+		/* Setting limit and limit extended */
+		value = ddr_info_set[i].start + ddr_info_set[i].size - 1;
+
+		lower = LO(value);
+		upper = HI(value);
+
+		FW_F2SDRAM_DDR_SCR_WRITEL(lower,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT +
+					  (i * 4 * sizeof(uint32_t)));
+		FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff,
+					  FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT +
+					  (i * 4 * sizeof(uint32_t)));
+
+		FW_F2SDRAM_DDR_SCR_WRITEL(BIT(i), FW_F2SDRAM_DDR_SCR_EN_SET);
+	}
+}
+
+static void sdram_set_firewall(void)
+{
+	sdram_set_firewall_non_f2sdram();
+	sdram_set_firewall_f2sdram();
+}
+
+/*
+ * Agilex5 DDR/IOSSM controller initialization routine
+ */
+int agilex5_ddr_init(handoff *hoff_ptr)
+{
+	int ret;
+	bool full_mem_init = false;
+	phys_size_t hw_ddr_size;
+	phys_size_t config_ddr_size;
+	struct io96b_info io96b_ctrl;
+	enum reset_type reset_t = get_reset_type(mmio_read_32(SOCFPGA_SYSMGR(
+						BOOT_SCRATCH_COLD_3)));
+	bool is_dualport = hoff_ptr->ddr_config & BIT(0);
+	bool is_dualemif = hoff_ptr->ddr_config & BIT(1);
+
+	NOTICE("DDR: Reset type is '%s'\n",
+	       (reset_t == POR_RESET ? "Power-On" : (reset_t == COLD_RESET ? "Cold" : "Warm")));
+
+	/* DDR initialization progress status tracking */
+	bool is_ddr_hang_bfr_rst = is_ddr_init_hang();
+
+	/* Set the DDR initialization progress */
+	ddr_init_inprogress(true);
+
+	/* Configure the IO96B CSR address based on the handoff data */
+	config_io96b_csr_addr(is_dualemif, &io96b_ctrl);
+
+	/* Configuring MPFE sideband manager registers */
+	/* Dual port setting */
+	if (is_dualport)
+		mmio_setbits_32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(4));
+
+	/* Dual EMIF setting */
+	if (is_dualemif) {
+		/* Set mpfe_lite_active in the system manager */
+		/* TODO: recheck on the bit value?? */
+		mmio_setbits_32(SOCFPGA_SYSMGR(MPFE_CONFIG), BIT(8));
+
+		mmio_setbits_32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(5));
+	}
+
+	if (is_dualport || is_dualemif)
+		INFO("DDR: SIDEBANDMGR_FLAGOUTSTATUS0: 0x%x\n",
+		     mmio_read_32(SIDEBANDMGR_FLAGOUTSTATUS0_REG));
+
+	/* Ensure calibration status passing */
+	init_mem_cal(&io96b_ctrl);
+
+	/* Initiate IOSSM mailbox */
+	io96b_mb_init(&io96b_ctrl);
+
+	/* Need to trigger re-calibration for DDR DBE */
+	if (ddr_ecc_dbe_status()) {
+		io96b_ctrl.io96b_0.cal_status = false;
+		io96b_ctrl.io96b_1.cal_status = false;
+		io96b_ctrl.overall_cal_status = io96b_ctrl.io96b_0.cal_status ||
+						io96b_ctrl.io96b_1.cal_status;
+	}
+
+	/* Trigger re-calibration if calibration failed */
+	if (!(io96b_ctrl.overall_cal_status)) {
+		NOTICE("DDR: Re-calibration in progress...\n");
+		trig_mem_cal(&io96b_ctrl);
+	}
+	NOTICE("DDR: Calibration success\n");
+
+	/* DDR type, DDR size and ECC status) */
+	ret = get_mem_technology(&io96b_ctrl);
+	if (ret != 0) {
+		ERROR("DDR: Failed to get DDR type\n");
+		return ret;
+	}
+
+	ret = get_mem_width_info(&io96b_ctrl);
+	if (ret != 0) {
+		ERROR("DDR: Failed to get DDR size\n");
+		return ret;
+	}
+
+	/* DDR size queried from the IOSSM controller */
+	hw_ddr_size = (phys_size_t)io96b_ctrl.overall_size * SZ_1G / SZ_8;
+
+	/* TODO: Hard code 1GB as of now, and DDR start and end address */
+	config_ddr_size = 0x40000000;
+	ddr_info_set[0].start = 0x80000000;
+	ddr_info_set[0].size = 0x40000000;
+
+	if (config_ddr_size != hw_ddr_size) {
+		WARN("DDR: DDR size configured is (%lld MiB)\n", config_ddr_size >> 20);
+		WARN("DDR: Mismatch with hardware size (%lld MiB).\n", hw_ddr_size >> 20);
+	}
+
+	if (config_ddr_size > hw_ddr_size) {
+		ERROR("DDR: Confgured DDR size is greater than the hardware size - HANG!!!\n");
+		while (1)
+			;
+	}
+
+	ret = ecc_enable_status(&io96b_ctrl);
+	if (ret != 0) {
+		ERROR("DDR: Failed to get DDR ECC status\n");
+		return ret;
+	}
+
+	/*
+	 * HPS cold or warm reset? If yes, skip full memory initialization if
+	 * ECC is enabled to preserve memory content.
+	 */
+	if (io96b_ctrl.ecc_status != 0) {
+		full_mem_init = hps_ocram_dbe_status() | ddr_ecc_dbe_status() |
+				is_ddr_hang_bfr_rst;
+		if ((full_mem_init == true) || (reset_t == WARM_RESET ||
+			reset_t == COLD_RESET) == 0) {
+			ret = bist_mem_init_start(&io96b_ctrl);
+			if (ret != 0) {
+				ERROR("DDR: Failed to fully initialize DDR memory\n");
+				return ret;
+			}
+		}
+		INFO("DDR: ECC initialized successfully\n");
+	}
+
+	sdram_set_firewall();
+
+	/*
+	 * Firewall setting for MPFE CSRs, allow both secure and non-secure
+	 * transactions.
+	 */
+	/* IO96B0_reg */
+	mmio_setbits_32(SOCFPGA_MPFE_SCR_IO96B0, BIT(0));
+	/* IO96B1_reg */
+	mmio_setbits_32(SOCFPGA_MPFE_SCR_IO96B1, BIT(0));
+	/* noc_scheduler_csr */
+	mmio_setbits_32(SOCFPGA_MPFE_NOC_SCHED_CSR, BIT(0));
+
+	INFO("DDR: firewall init done\n");
+
+	/* Ending DDR driver initialization success tracking */
+	ddr_init_inprogress(false);
+
+	NOTICE("###DDR:init success###\n");
+
+	return 0;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c b/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c
new file mode 100644
index 00000000..c2ab0472
--- /dev/null
+++ b/plat/intel/soc/agilex5/soc/agilex5_iossm_mailbox.c
@@ -0,0 +1,811 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+
+#include "agilex5_iossm_mailbox.h"
+
+/* supported DDR type list */
+static const char *ddr_type_list[7] = {
+	"DDR4", "DDR5", "DDR5_RDIMM", "LPDDR4", "LPDDR5", "QDRIV", "UNKNOWN"
+};
+
+static inline int wait_for_bit(const void *reg,
+			       const uint32_t mask,
+			       const bool set,
+			       const unsigned int timeout_ms)
+{
+	uint32_t val;
+	uint32_t timeout_sec = (timeout_ms / 1000);
+
+	while (timeout_sec > 0) {
+		val = mmio_read_32((uintptr_t)reg);
+
+		INFO("IOSSM: timeout_sec %d, val %x\n", timeout_sec, val);
+
+		if (!set) {
+			val = ~val;
+		}
+
+		if ((val & mask) == mask) {
+			INFO("IOSSM: %s, success\n", __func__);
+			return 0;
+		}
+
+		/* one second delay */
+		mdelay(1000);
+
+		timeout_sec--;
+	}
+
+	ERROR("IOSSM: %s, failed, time out\n", __func__);
+	return -ETIMEDOUT;
+}
+
+int io96b_mb_req(phys_addr_t io96b_csr_addr, uint32_t ip_type, uint32_t instance_id,
+		 uint32_t usr_cmd_type, uint32_t usr_cmd_opcode, uint32_t cmd_param_0,
+		 uint32_t cmd_param_1, uint32_t cmd_param_2, uint32_t cmd_param_3,
+		 uint32_t cmd_param_4, uint32_t cmd_param_5, uint32_t cmd_param_6,
+		 uint32_t resp_data_len, struct io96b_mb_resp *resp)
+{
+	int i;
+	int ret;
+	uint32_t cmd_req, cmd_resp;
+
+	/* Initialized zeros for responses*/
+	resp->cmd_resp_status = 0;
+	resp->cmd_resp_data_0 = 0;
+	resp->cmd_resp_data_1 = 0;
+	resp->cmd_resp_data_2 = 0;
+
+	/* Ensure CMD_REQ is cleared before write any command request */
+	ret = wait_for_bit((const void *)(io96b_csr_addr + IOSSM_CMD_REQ_OFFSET),
+			   GENMASK(31, 0), 0, 10000);
+
+	if (ret != 0) {
+		ERROR("%s: CMD_REQ not ready\n", __func__);
+		return -1;
+	}
+
+	/* Write CMD_PARAM_* */
+	for (i = 0; i < 6 ; i++) {
+		switch (i) {
+		case 0:
+			if (cmd_param_0 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_0_OFFSET,
+					      cmd_param_0);
+			}
+			break;
+		case 1:
+			if (cmd_param_1 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_1_OFFSET,
+					      cmd_param_1);
+			}
+			break;
+		case 2:
+			if (cmd_param_2 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_2_OFFSET,
+					      cmd_param_2);
+			}
+			break;
+		case 3:
+			if (cmd_param_3 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_3_OFFSET,
+					      cmd_param_3);
+			}
+			break;
+		case 4:
+			if (cmd_param_4 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_4_OFFSET,
+					      cmd_param_4);
+			}
+			break;
+		case 5:
+			if (cmd_param_5 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_5_OFFSET,
+					      cmd_param_5);
+			}
+			break;
+		case 6:
+			if (cmd_param_6 != 0) {
+				mmio_write_32(io96b_csr_addr + IOSSM_CMD_PARAM_6_OFFSET,
+					      cmd_param_6);
+			}
+			break;
+		default:
+			ERROR("IOSSM: %s: Invalid command parameter\n", __func__);
+		}
+	}
+
+	/* Write CMD_REQ (IP_TYPE, IP_INSTANCE_ID, CMD_TYPE and CMD_OPCODE) */
+	cmd_req = (usr_cmd_opcode << 0) | (usr_cmd_type << 16) | (instance_id << 24) |
+		  (ip_type << 29);
+	mmio_write_32(io96b_csr_addr + IOSSM_CMD_REQ_OFFSET, cmd_req);
+	INFO("IOSSM: %s: Write 0x%x to IOSSM_CMD_REQ_OFFSET 0x%llx\n",
+		__func__, cmd_req, io96b_csr_addr + IOSSM_CMD_REQ_OFFSET);
+
+	/* Read CMD_RESPONSE_READY in CMD_RESPONSE_STATUS*/
+	ret = wait_for_bit((const void *)(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET),
+			   IOSSM_STATUS_COMMAND_RESPONSE_READY, 1, 10000);
+
+	if (ret != 0) {
+		ERROR("%s: CMD_RESPONSE ERROR:\n", __func__);
+		cmd_resp = (io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+		ERROR("%s: STATUS_GENERAL_ERROR: 0x%x\n", __func__, (cmd_resp >> 1) & 0xF);
+		ERROR("%s: STATUS_CMD_RESPONSE_ERROR: 0x%x\n", __func__, (cmd_resp >> 5) & 0x7);
+	}
+
+	/* read CMD_RESPONSE_STATUS*/
+	resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+	INFO("IOSSM: %s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n",
+		__func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+	/* read CMD_RESPONSE_DATA_* */
+	for (i = 0; i < resp_data_len; i++) {
+		switch (i) {
+		case 0:
+			resp->cmd_resp_data_0 =
+				mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET);
+
+			break;
+		case 1:
+			resp->cmd_resp_data_1 =
+				mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET);
+
+			break;
+		case 2:
+			resp->cmd_resp_data_2 =
+				mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET);
+			break;
+		default:
+			ERROR("%s: Invalid response data\n", __func__);
+		}
+	}
+
+	resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+	INFO("IOSSM: %s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n",
+		__func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+	/* write CMD_RESPONSE_READY = 0 */
+	mmio_clrbits_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET,
+			IOSSM_STATUS_COMMAND_RESPONSE_READY);
+
+	resp->cmd_resp_status = mmio_read_32(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+	INFO("IOSSM: %s: CMD_RESPONSE_READY 0x%llx: 0x%x\n",
+		__func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+	return 0;
+}
+
+/*
+ * Initial function to be called to set memory interface IP type and instance ID
+ * IP type and instance ID need to be determined before sending mailbox command
+ */
+void io96b_mb_init(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	uint8_t ip_type_ret, instance_id_ret;
+	int i, j, k;
+
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			/* Get memory interface IP type & instance ID (IP identifier) */
+			io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+				     CMD_GET_SYS_INFO, GET_MEM_INTF_INFO, 0, 0,
+				     0, 0, 0, 0, 0, 2, &usr_resp);
+			/* Retrieve number of memory interface(s) */
+			io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface =
+				IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+
+			/* Retrieve memory interface IP type and instance ID (IP identifier) */
+			j = 0;
+			for (k = 0; k < MAX_MEM_INTERFACES_SUPPORTED; k++) {
+				switch (k) {
+				case 0:
+					ip_type_ret = (usr_resp.cmd_resp_data_0 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_0 >> 24) & 0x1F;
+					break;
+				case 1:
+					ip_type_ret = (usr_resp.cmd_resp_data_1 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_1 >> 24) & 0x1F;
+					break;
+				}
+
+				if (ip_type_ret != 0) {
+					io96b_ctrl->io96b_0.mb_ctrl.ip_type[j] = ip_type_ret;
+					io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j] =
+						instance_id_ret;
+					j++;
+				}
+			}
+			break;
+		case 1:
+			/* Get memory interface IP type and instance ID (IP identifier) */
+			io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0, CMD_GET_SYS_INFO,
+				     GET_MEM_INTF_INFO, 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+			/* Retrieve number of memory interface(s) */
+			io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface =
+				IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+
+			/* Retrieve memory interface IP type and instance ID (IP identifier) */
+			j = 0;
+			for (k = 0; k < MAX_MEM_INTERFACES_SUPPORTED; k++) {
+				switch (k) {
+				case 0:
+					ip_type_ret = (usr_resp.cmd_resp_data_0 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_0 >> 24) & 0x1F;
+					break;
+				case 1:
+					ip_type_ret = (usr_resp.cmd_resp_data_1 >> 29) & 0x7;
+					instance_id_ret = (usr_resp.cmd_resp_data_1 >> 24) & 0x1F;
+					break;
+				}
+
+				if (ip_type_ret != 0) {
+					io96b_ctrl->io96b_1.mb_ctrl.ip_type[j] = ip_type_ret;
+					io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j] =
+						instance_id_ret;
+					j++;
+				}
+			}
+			break;
+		}
+
+	}
+}
+
+static inline void hang(void)
+{
+	ERROR("IOSSM: %s: system is going to die :(\n", __func__);
+	while (1)
+		;
+}
+
+int io96b_cal_status(phys_addr_t addr)
+{
+	int cal_busy_status, cal_success_status;
+	phys_addr_t status_addr = addr + IOSSM_STATUS_OFFSET;
+
+	/* Ensure calibration busy status */
+	cal_busy_status = wait_for_bit((const void *)status_addr, IOSSM_STATUS_CAL_BUSY,
+					false, 15000);
+	if (cal_busy_status != 0) {
+		ERROR("IOSSM: One or more EMIF instances are busy with calibration\n");
+		return -EBUSY;
+	}
+
+	/* Calibration success status check */
+	NOTICE("IOSSM: Calibration success status check...\n");
+	cal_success_status = wait_for_bit((const void *)status_addr, IOSSM_STATUS_CAL_SUCCESS,
+					  true, 15000);
+	if (cal_success_status != 0) {
+		ERROR("IOSSM: One/more EMIF instances either failed to calibrate/not completed\n");
+		return -EBUSY;
+	}
+
+	NOTICE("IOSSM: All EMIF instances within the IO96 have calibrated successfully!\n");
+	return 0;
+}
+
+void init_mem_cal(struct io96b_info *io96b_ctrl)
+{
+	int count, i, ret;
+
+	/* Initialize overall calibration status */
+	io96b_ctrl->overall_cal_status = false;
+
+	/* Check initial calibration status for the assigned IO96B */
+	count = 0;
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			ret = io96b_cal_status(io96b_ctrl->io96b_0.io96b_csr_addr);
+			if (ret != 0) {
+				io96b_ctrl->io96b_0.cal_status = false;
+				ERROR("%s: Initial DDR calibration IO96B_0 failed %d\n",
+					__func__, ret);
+				break;
+			}
+			io96b_ctrl->io96b_0.cal_status = true;
+			INFO("IOSSM: %s: Initial DDR calibration IO96B_0 succeed\n", __func__);
+			count++;
+			break;
+		case 1:
+			ret = io96b_cal_status(io96b_ctrl->io96b_1.io96b_csr_addr);
+			if (ret != 0) {
+				io96b_ctrl->io96b_1.cal_status = false;
+				ERROR("%s: Initial DDR calibration IO96B_1 failed %d\n",
+					__func__, ret);
+				break;
+			}
+			io96b_ctrl->io96b_1.cal_status = true;
+			INFO("IOSSM: %s: Initial DDR calibration IO96B_1 succeed\n", __func__);
+			count++;
+			break;
+		}
+	}
+
+	if (count == io96b_ctrl->num_instance)
+		io96b_ctrl->overall_cal_status = true;
+}
+
+/*
+ * Trying 3 times re-calibration if initial calibration failed
+ */
+int trig_mem_cal(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	bool recal_success;
+	int i;
+	uint8_t cal_stat;
+
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			if (!(io96b_ctrl->io96b_0.cal_status)) {
+				/* Get the memory calibration status for first memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0,
+					     0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration first memory interface with failed calibration */
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_type[0],
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[0],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("%s: Error as SDRAM calibration failed\n", __func__);
+					hang();
+				}
+
+				/* Get the memory calibration status for second memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration second memory interface with failed calibration*/
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_1 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_type[1],
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[1],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("IOSSMM: Error as SDRAM calibration failed\n");
+					hang();
+				}
+
+				io96b_ctrl->io96b_0.cal_status = true;
+			}
+			break;
+		case 1:
+			if (!(io96b_ctrl->io96b_1.cal_status)) {
+				/* Get the memory calibration status for first memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0,
+					     0, 0, 0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration first memory interface with failed calibration */
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_type[0],
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[0],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("IOSSM: Error as SDRAM calibration failed\n");
+					hang();
+				}
+
+				/* Get the memory calibration status for second memory interface */
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+					     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				recal_success = false;
+
+				/* Re-calibration second memory interface with failed calibration*/
+				for (i = 0; i < 3; i++) {
+					cal_stat = usr_resp.cmd_resp_data_0 & GENMASK(2, 0);
+					if (cal_stat < 0x2) {
+						recal_success = true;
+						break;
+					}
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_type[1],
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[1],
+						     CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0,
+						     0, 0, 0, 2, &usr_resp);
+					mdelay(1000);
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr, 0, 0,
+						     CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+				}
+
+				if (!recal_success) {
+					ERROR("IOSSM: Error as SDRAM calibration failed\n");
+					hang();
+				}
+
+				io96b_ctrl->io96b_1.cal_status = true;
+			}
+			break;
+		}
+	}
+
+	if (io96b_ctrl->io96b_0.cal_status && io96b_ctrl->io96b_1.cal_status) {
+		INFO("IOSSM: %s: Overall SDRAM calibration success\n", __func__);
+		io96b_ctrl->overall_cal_status = true;
+	}
+
+	return 0;
+}
+
+int get_mem_technology(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	uint8_t ddr_type_ret;
+
+	/* Initialize ddr type */
+	io96b_ctrl->ddr_type = ddr_type_list[6];
+
+	/* Get and ensure all memory interface(s) same DDR type */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, 0, 0, 0, 0,
+					     0, 0, 0, 0, &usr_resp);
+
+				ddr_type_ret =
+					IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 0);
+
+				if (strcmp(io96b_ctrl->ddr_type, "UNKNOWN") == 0)
+					io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
+
+				if (ddr_type_list[ddr_type_ret] != io96b_ctrl->ddr_type) {
+					ERROR("IOSSM: Mismatch DDR type on IO96B_0\n");
+					return -ENOEXEC;
+				}
+			}
+			break;
+		case 1:
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, 0, 0, 0,
+					     0, 0, 0, 0, 0, &usr_resp);
+
+				ddr_type_ret =
+					IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 0);
+
+				if (strcmp(io96b_ctrl->ddr_type, "UNKNOWN") == 0)
+					io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
+
+				if (ddr_type_list[ddr_type_ret] != io96b_ctrl->ddr_type) {
+					ERROR("IOSSM: Mismatch DDR type on IO96B_1\n");
+					return -ENOEXEC;
+				}
+			}
+			break;
+		}
+	}
+
+	return 0;
+}
+
+int get_mem_width_info(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	uint16_t memory_size = 0U;
+	uint16_t total_memory_size = 0U;
+
+	/* Get all memory interface(s) total memory size on all instance(s) */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			memory_size = 0;
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				memory_size = memory_size +
+						(usr_resp.cmd_resp_data_1 & GENMASK(7, 0));
+			}
+
+			if (memory_size == 0U) {
+				ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+				return -ENOEXEC;
+			}
+
+			io96b_ctrl->io96b_0.size = memory_size;
+
+			break;
+		case 1:
+			memory_size = 0;
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, 0, 0, 0,
+					     0, 0, 0, 0, 2, &usr_resp);
+
+				memory_size = memory_size +
+						(usr_resp.cmd_resp_data_1 & GENMASK(7, 0));
+			}
+
+			if (memory_size == 0U) {
+				ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+				return -ENOEXEC;
+			}
+
+			io96b_ctrl->io96b_1.size = memory_size;
+
+			break;
+		}
+
+		total_memory_size = total_memory_size + memory_size;
+	}
+
+	if (total_memory_size == 0U) {
+		ERROR("IOSSM: %s: Failed to get valid memory size\n", __func__);
+		return -ENOEXEC;
+	}
+
+	io96b_ctrl->overall_size = total_memory_size;
+
+	return 0;
+}
+
+int ecc_enable_status(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	bool ecc_stat_set = false;
+	bool ecc_stat;
+
+	/* Initialize ECC status */
+	io96b_ctrl->ecc_status = false;
+
+	/* Get and ensure all memory interface(s) same ECC status */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS, 0, 0,
+					     0, 0, 0, 0, 0, 0, &usr_resp);
+
+				ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+						& GENMASK(1, 0)) == 0 ? false : true);
+
+				if (!ecc_stat_set) {
+					io96b_ctrl->ecc_status = ecc_stat;
+					ecc_stat_set = true;
+				}
+
+				if (ecc_stat != io96b_ctrl->ecc_status) {
+					ERROR("IOSSM: %s: Mismatch DDR ECC status on IO96B_0\n",
+						__func__);
+					return -ENOEXEC;
+				}
+			}
+			break;
+		case 1:
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS, 0, 0,
+					     0, 0, 0, 0, 0, 0, &usr_resp);
+
+				ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+						& GENMASK(1, 0)) == 0 ? false : true);
+
+				if (!ecc_stat_set) {
+					io96b_ctrl->ecc_status = ecc_stat;
+					ecc_stat_set = true;
+				}
+
+				if (ecc_stat != io96b_ctrl->ecc_status) {
+					ERROR("%s: Mismatch DDR ECC status on IO96B_1\n"
+						, __func__);
+					return -ENOEXEC;
+				}
+			}
+			break;
+		}
+	}
+	return 0;
+}
+
+int bist_mem_init_start(struct io96b_info *io96b_ctrl)
+{
+	struct io96b_mb_resp usr_resp;
+	int i, j;
+	bool bist_start, bist_success;
+	uint32_t read_count;
+	uint32_t read_interval_ms;
+
+	/* Full memory initialization BIST performed on all memory interface(s) */
+	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		switch (i) {
+		case 0:
+			for (j = 0; j < io96b_ctrl->io96b_0.mb_ctrl.num_mem_interface; j++) {
+				bist_start = false;
+				bist_success = false;
+				read_interval_ms = 500U;
+
+				/* Start memory initialization BIST on full memory address */
+				io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0x40,
+					     0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+				bist_start =
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& 1);
+
+				if (!bist_start) {
+					ERROR("IOSSM: %s: Failed to initialized memory on IO96B_0\n"
+					, __func__);
+					ERROR("IOSSM: %s: BIST_MEM_INIT_START Error code 0x%x\n",
+					__func__,
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 1)) > 0x1);
+					return -ENOEXEC;
+				}
+
+				/* Polling for the initiated memory initialization BIST status */
+				read_count = read_interval_ms / TIMEOUT;
+				while (!bist_success) {
+					io96b_mb_req(io96b_ctrl->io96b_0.io96b_csr_addr,
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_type[j],
+						     io96b_ctrl->io96b_0.mb_ctrl.ip_instance_id[j],
+						     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+					bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status) & 1);
+
+					if ((!bist_success) && (read_count == 0U)) {
+						ERROR("IOSSM: %s: Timeout init memory on IO96B_0\n"
+							, __func__);
+						ERROR("IOSSM: %s: BIST_MEM_INIT_STATUS Err code%x\n"
+							, __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status)
+							& GENMASK(2, 1)) > 0x1);
+						return -ETIMEDOUT;
+					}
+					read_count--;
+					mdelay(read_interval_ms);
+				}
+			}
+
+			NOTICE("IOSSM: %s: Memory initialized successfully on IO96B_0\n", __func__);
+			break;
+
+		case 1:
+			for (j = 0; j < io96b_ctrl->io96b_1.mb_ctrl.num_mem_interface; j++) {
+				bist_start = false;
+				bist_success = false;
+				read_interval_ms = 500U;
+
+				/* Start memory initialization BIST on full memory address */
+				io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+					     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+					     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0x40,
+					     0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+				bist_start =
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& 1);
+
+				if (!bist_start) {
+					ERROR("IOSSM: %s: Failed to initialized memory on IO96B_1\n"
+						, __func__);
+					ERROR("IOSSM: %s: BIST_MEM_INIT_START Error code 0x%x\n",
+					__func__,
+					(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+					& GENMASK(2, 1)) > 0x1);
+					return -ENOEXEC;
+				}
+
+				/* Polling for the initiated memory initialization BIST status */
+				read_count = read_interval_ms / TIMEOUT;
+				while (!bist_success) {
+					io96b_mb_req(io96b_ctrl->io96b_1.io96b_csr_addr,
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_type[j],
+						     io96b_ctrl->io96b_1.mb_ctrl.ip_instance_id[j],
+						     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_STATUS,
+						     0, 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+					bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status) & 1);
+
+					if ((!bist_success) && (read_count == 0U)) {
+						ERROR("IOSSM: %s: Timeout init memory on IO96B_1\n"
+							, __func__);
+						ERROR("IOSSM: %s: BIST_MEM_INIT_STATUS ErrCode %x\n"
+							, __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
+							(usr_resp.cmd_resp_status)
+							& GENMASK(2, 1)) > 0x1);
+						return -ETIMEDOUT;
+					}
+					read_count--;
+					mdelay(read_interval_ms);
+				}
+			}
+
+			NOTICE("IOSSM: %s: Memory initialized successfully on IO96B_1\n", __func__);
+			break;
+		}
+	}
+	return 0;
+}
diff --git a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
index 50d9e360..317b4d88 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_pinmux.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -186,40 +187,72 @@ const uint32_t sysmgr_pinmux_array_iodelay[] = {
 	0x0000011c, 0x00000000
 };
 
-void config_fpgaintf_mod(void)
+static void config_fpgaintf_mod(void)
 {
-	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8);
+	uint32_t fpgaintf_en_val;
+
+	/*
+	 * System manager FPGA interface enable2 register, disable individual
+	 * interfaces between the FPGA and HPS.
+	 */
+	fpgaintf_en_val = 0U;
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(NAND_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(4);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(SDMMC_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(8);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(SPIM0_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(16);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(SPIM1_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(24);
+	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), fpgaintf_en_val);
+
+	/*
+	 * System manager FPGA interface enable3 register, disable individual
+	 * interfaces between the FPGA and HPS.
+	 */
+	fpgaintf_en_val = 0U;
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(EMAC0_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(0);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(EMAC1_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(8);
+	if ((mmio_read_32(SOCFPGA_PINUMX_USEFPGA(EMAC2_USEFPGA)) & 0x01) != 0)
+		fpgaintf_en_val |= BIT(16);
+	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_3), fpgaintf_en_val);
 }
 
 void config_pinmux(handoff *hoff_ptr)
 {
-	unsigned int i;
+	uint32_t i;
 
-	mmio_write_32(PINMUX_HANDOFF_CONFIG_ADDR, PINMUX_HANDOFF_CONFIG_VAL);
-	for (i = 0; i < PINMUX_HANDOFF_ARRAY_SIZE(hoff_ptr->pinmux_sel_array); i += 2) {
-		mmio_write_32(AGX5_PINMUX_PIN0SEL +
-			hoff_ptr->pinmux_sel_array[i],
-			hoff_ptr->pinmux_sel_array[i + 1]);
+	/* Configure the pin selection */
+	for (i = 0; i < ARRAY_SIZE(hoff_ptr->pinmux_sel_array); i += 2) {
+		mmio_write_32(AGX5_PINMUX_PIN0SEL + hoff_ptr->pinmux_sel_array[i],
+			      hoff_ptr->pinmux_sel_array[i+1]);
 	}
 
-	config_fpgaintf_mod();
-}
-
-void config_peripheral(handoff *hoff_ptr)
-{
-
-	// TODO: This need to be update due to peripheral_pwr_gate_array handoff change
-	// Pending SDM to pass over handoff data
-	// unsigned int i;
+	/* Configure the pin control */
+	for (i = 0; i < ARRAY_SIZE(hoff_ptr->pinmux_io_array); i += 2) {
+		mmio_write_32(AGX5_PINMUX_IO0CTRL + hoff_ptr->pinmux_io_array[i],
+			      hoff_ptr->pinmux_io_array[i+1]);
+	}
 
-	// for (i = 0; i < 4; i += 2) {
-	//	mmio_write_32(AGX_EDGE_PERIPHERAL +
-	//	hoff_ptr->peripheral_pwr_gate_array[i],
-	//	hoff_ptr->peripheral_pwr_gate_array[i+1]);
-	// }
+	/*
+	 * Configure the FPGA use.
+	 * The actual generic handoff contains extra 4 elements, and these 4 elements
+	 * are not applicable to the Agilex5 platform. Writing these extra 4 elements
+	 * will cause the system to crash, so let's avoid writing them here.
+	 */
+	for (i = 0; i < (ARRAY_SIZE(hoff_ptr->pinmux_fpga_array) - 4); i += 2) {
+		mmio_write_32(AGX5_PINMUX_EMAC0_USEFPGA + hoff_ptr->pinmux_fpga_array[i],
+			      hoff_ptr->pinmux_fpga_array[i+1]);
+	}
 
+	/* Configure the IO delay */
+	for (i = 0; i < ARRAY_SIZE(hoff_ptr->pinmux_iodelay_array); i += 2) {
+		mmio_write_32(AGX5_PINMUX_IO0_DELAY + hoff_ptr->pinmux_iodelay_array[i],
+			      hoff_ptr->pinmux_iodelay_array[i+1]);
+	}
 
-	// TODO: This need to be update due to peripheral_pwr_gate_array handoff change
-	mmio_write_32(AGX5_PERIPHERAL,
-	hoff_ptr->peripheral_pwr_gate_array);
+	/* Enable/Disable individual interfaces between the FPGA and HPS */
+	config_fpgaintf_mod();
 }
diff --git a/plat/intel/soc/agilex5/soc/agilex5_power_manager.c b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
index 0d81970e..ef3acf90 100644
--- a/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
+++ b/plat/intel/soc/agilex5/soc/agilex5_power_manager.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +14,7 @@
 #include "agilex5_power_manager.h"
 #include "socfpga_reset_manager.h"
 
-int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff)
+static int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff)
 {
 	uint32_t data = 0;
 	uint32_t count = 0;
@@ -38,7 +39,7 @@ int wait_verify_fsm(uint16_t timeout, uint32_t peripheral_handoff)
 	return 0;
 }
 
-int pss_sram_power_off(handoff *hoff_ptr)
+static int pss_sram_power_off(handoff *hoff_ptr)
 {
 	int ret = 0;
 	uint32_t peripheral_handoff = 0;
@@ -66,7 +67,7 @@ void config_pwrmgr_handoff(handoff *hoff_ptr)
 {
 	int ret = 0;
 
-	switch (hoff_ptr->header_magic) {
+	switch (hoff_ptr->peripheral_pwr_gate_magic) {
 	case HANDOFF_MAGIC_PERIPHERAL:
 		ret = pss_sram_power_off(hoff_ptr);
 		break;
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index cbd01212..b3d5665b 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -96,18 +98,6 @@ func plat_my_core_pos
 endfunc plat_my_core_pos
 
 func warm_reset_req
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-	bl	plat_is_my_cpu_primary
-	cbnz	x0, warm_reset
-warm_reset:
-	mov_imm x1, PLAT_SEC_ENTRY
-	str	xzr, [x1]
-	mrs	x1, rmr_el3
-	orr	x1, x1, #0x02
-	msr	rmr_el3, x1
-	isb
-	dsb	sy
-#else
 	str	xzr, [x4]
 	bl	plat_is_my_cpu_primary
 	cbz	x0, cpu_in_wfi
@@ -121,22 +111,35 @@ warm_reset:
 cpu_in_wfi:
 	wfi
 	b	cpu_in_wfi
-#endif
 endfunc warm_reset_req
 
-/* TODO: Zephyr warm reset test */
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 func plat_get_my_entrypoint
 	ldr	x4, =L2_RESET_DONE_REG
 	ldr	x5, [x4]
-	ldr	x1, =PLAT_L2_RESET_REQ
+
+	/* Check for warm reset request */
+	ldr	x1, =L2_RESET_DONE_STATUS
+	cmp	x1, x5
+	b.eq	warm_reset_req
+
+	/* Check for SMP secondary cores boot request */
+	ldr	x1, =SMP_SEC_CORE_BOOT_REQ
 	cmp	x1, x5
-	b.eq	zephyr_reset_req
+	b.eq	smp_request
+
+	/* Otherwise it is cold reset */
+	mov	x0, #0
+	ret
+smp_request:
+	/*
+	 * Return the address 'bl31_warm_entrypoint', which is passed to
+	 * 'psci_setup' routine as part of BL31 initialization.
+	 */
 	mov_imm	x1, PLAT_SEC_ENTRY
 	ldr	x0, [x1]
-	ret
-zephyr_reset_req:
-	ldr	x0, =0x00
+	/* Clear the mark up before return */
+	str	xzr, [x4]
 	ret
 endfunc plat_get_my_entrypoint
 #else
diff --git a/plat/intel/soc/common/aarch64/platform_common.c b/plat/intel/soc/common/aarch64/platform_common.c
index b79a63c8..a0f50dcd 100644
--- a/plat/intel/soc/common/aarch64/platform_common.c
+++ b/plat/intel/soc/common/aarch64/platform_common.c
@@ -11,12 +11,6 @@
 
 #include "socfpga_private.h"
 
-
-unsigned int plat_get_syscnt_freq2(void)
-{
-	return PLAT_SYS_COUNTER_FREQ_IN_TICKS;
-}
-
 unsigned long socfpga_get_ns_image_entrypoint(void)
 {
 	return PLAT_NS_IMAGE_OFFSET;
diff --git a/plat/intel/soc/common/bl2_plat_mem_params_desc.c b/plat/intel/soc/common/bl2_plat_mem_params_desc.c
index 187c53ac..a09fb709 100644
--- a/plat/intel/soc/common/bl2_plat_mem_params_desc.c
+++ b/plat/intel/soc/common/bl2_plat_mem_params_desc.c
@@ -88,9 +88,27 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
 		.image_info.image_base = PLAT_NS_IMAGE_OFFSET,
 		.image_info.image_max_size =
 			0x0 + 0x40000000 - PLAT_NS_IMAGE_OFFSET,
+# if ARM_LINUX_KERNEL_AS_BL33 != 0
+		.next_handoff_image_id = NT_FW_CONFIG_ID,
+	},
+
+	{
+		.image_id = NT_FW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+			VERSION_2, entry_point_info_t,
+			NON_SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+			VERSION_2, image_info_t, 0),
+		.image_info.image_base = ARM_PRELOADED_DTB_BASE,
+		.image_info.image_max_size =
+			0x0 + 0x40000000 - ARM_PRELOADED_DTB_BASE,
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
+#else
+	.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+# endif
 };
 
 REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index 684a6256..931ffcf9 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -1,22 +1,522 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <assert.h>
 #include <common/debug.h>
+#include <drivers/delay_timer.h>
 #include <errno.h>
 #include <lib/mmio.h>
 #include <platform_def.h>
 
 #include "ncore_ccu.h"
+#include "socfpga_mailbox.h"
 #include "socfpga_plat_def.h"
 #include "socfpga_system_manager.h"
 
 uint32_t poll_active_bit(uint32_t dir);
 
-#define SMMU_DMI			1
+#define SMMU_DMI					1
+#define CCU_DMI0_DMIUSMCMCR				SOCFPGA_CCU_NOC_REG_BASE + 0x7340
+#define CCU_DMI0_DMIUSMCMAR				SOCFPGA_CCU_NOC_REG_BASE + 0x7344
+#define CCU_DMI0_DMIUSMCMCR_MNTOP			GENMASK(3, 0)
+#define MAX_DISTRIBUTED_MEM_INTERFACE			2
+#define FLUSH_ALL_ENTRIES				0x4
+#define CCU_DMI0_DMIUSMCMCR_ARRAY_ID			GENMASK(21, 16)
+#define ARRAY_ID_TAG					0x0
+#define ARRAY_ID_DATA					0x1
+#define CACHE_OPERATION_DONE				BIT(0)
+#define TIMEOUT_200MS					200
 
+#define __bf_shf(x)					(__builtin_ffsll(x) - 1)
+
+#define FIELD_PREP(_mask, _val)						\
+	({ \
+		((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask);	\
+	})
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+ncore_ccu_reg_t ncore_ccu_modules[] = {
+				{"caiu0@1c000000",             0x1C000000, 0x00001000},
+				{"ncaiu0@1c001000",            0x1C001000, 0x00001000},
+				{"ncaiu1@1c002000",            0x1C002000, 0x00001000},
+				{"ncaiu2@1c003000",            0x1C003000, 0x00001000},
+				{"ncaiu3@1c004000",            0x1C004000, 0x00001000},
+				{"dce0@1c005000",              0x1C005000, 0x00001000},
+				{"dce1@1c006000",              0x1C006000, 0x00001000},
+				{"dmi0@1c007000",              0x1C007000, 0x00001000},
+				{"dmi1@1c008000",              0x1C008000, 0x00001000},
+				{"noc_fw_l4_per@10d21000",     0x10D21000, 0x0000008C},
+				{"noc_fw_l4_sys@10d21100",     0x10D21100, 0x00000098},
+				{"noc_fw_lwsoc2fpga@10d21300", 0x10D21300, 0x00000004},
+				{"noc_fw_soc2fpga@10d21200",   0x10D21200, 0x00000004},
+				{"noc_fw_tcu@10d21400",        0x10D21400, 0x00000004}
+				};
+
+ncore_ccu_t ccu_caiu0[] = {
+				/* CAIUAMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* CAIUMIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DII1_MPFEREGS */
+				{0x00000414, 0x00018000, 0xFFFFFFFF},
+				{0x00000418, 0x00000000, 0x000000FF},
+				{0x00000410, 0xC0E00200, 0xC1F03E1F},
+				/* DII2_GICREGS */
+				{0x00000424, 0x0001D000, 0xFFFFFFFF},
+				{0x00000428, 0x00000000, 0x000000FF},
+				{0x00000420, 0xC0800400, 0xC1F03E1F},
+				/* NCAIU0_LWSOC2FPGA */
+				{0x00000444, 0x00020000, 0xFFFFFFFF},
+				{0x00000448, 0x00000000, 0x000000FF},
+				{0x00000440, 0xC1100006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_1G */
+				{0x00000454, 0x00040000, 0xFFFFFFFF},
+				{0x00000458, 0x00000000, 0x000000FF},
+				{0x00000450, 0xC1200006, 0xC1F03E1F},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_16G */
+				{0x00000474, 0x00400000, 0xFFFFFFFF},
+				{0x00000478, 0x00000000, 0x000000FF},
+				{0x00000470, 0xC1600006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_256G */
+				{0x00000494, 0x04000000, 0xFFFFFFFF},
+				{0x00000498, 0x00000000, 0x000000FF},
+				{0x00000490, 0xC1A00006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_ncaiu0[] = {
+				/* NCAIU0AMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* NCAIU0MIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* PSS */
+				{0x00000404, 0x00010000, 0xFFFFFFFF},
+				{0x00000408, 0x00000000, 0x000000FF},
+				{0x00000400, 0xC0F00000, 0xC1F03E1F},
+				/* DII1_MPFEREGS */
+				{0x00000414, 0x00018000, 0xFFFFFFFF},
+				{0x00000418, 0x00000000, 0x000000FF},
+				{0x00000410, 0xC0E00200, 0xC1F03E1F},
+				/* NCAIU0_LWSOC2FPGA */
+				{0x00000444, 0x00020000, 0xFFFFFFFF},
+				{0x00000448, 0x00000000, 0x000000FF},
+				{0x00000440, 0xC1100006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_1G */
+				{0x00000454, 0x00040000, 0xFFFFFFFF},
+				{0x00000458, 0x00000000, 0x000000FF},
+				{0x00000450, 0xC1200006, 0xC1F03E1F},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_16G */
+				{0x00000474, 0x00400000, 0xFFFFFFFF},
+				{0x00000478, 0x00000000, 0x000000FF},
+				{0x00000470, 0xC1600006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* NCAIU0_SOC2FPGA_256G */
+				{0x00000494, 0x04000000, 0xFFFFFFFF},
+				{0x00000498, 0x00000000, 0x000000FF},
+				{0x00000490, 0xC1A00006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_ncaiu1[] = {
+				/* NCAIU1AMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* NCAIU1MIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_ncaiu2[] = {
+				/* NCAIU2AMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* NCAIU2MIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_ncaiu3[] = {
+				/* NCAIU3AMIGR */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* NCAIU3MIFSR */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DII1_MPFEREGS */
+				{0x00000414, 0x00018000, 0xFFFFFFFF},
+				{0x00000418, 0x00000000, 0x000000FF},
+				{0x00000410, 0xC0E00200, 0xC1F03E1F},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_dce0[] = {
+				/* DCEUAMIGR0 */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* DCEUMIFSR0 */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_dce1[] = {
+				/* DCEUAMIGR1 */
+				{0x000003C0, 0x00000003, 0x0000001F},
+				/* DCEUMIFSR1 */
+				{0x000003C4, 0x00000000, 0x07070777},
+				/* DMI_SDRAM_2G */
+				{0x00000464, 0x00080000, 0xFFFFFFFF},
+				{0x00000468, 0x00000000, 0x000000FF},
+				{0x00000460, 0x81300006, 0xC1F03E1F},
+				/* DMI_SDRAM_30G */
+				{0x00000484, 0x00800000, 0xFFFFFFFF},
+				{0x00000488, 0x00000000, 0x000000FF},
+				{0x00000480, 0x81700006, 0xC1F03E1F},
+				/* DMI_SDRAM_480G */
+				{0x000004A4, 0x08000000, 0xFFFFFFFF},
+				{0x000004A8, 0x00000000, 0x000000FF},
+				{0x000004A0, 0x81B00006, 0xC1F03E1F}
+			};
+
+ncore_ccu_t ccu_dmi0[] = {
+				/* DMIUSMCTCR */
+				{0x00000300, 0x00000001, 0x00000003},
+				{0x00000300, 0x00000003, 0x00000003}
+			};
+
+ncore_ccu_t ccu_dmi1[] = {
+				/* DMIUSMCTCR */
+				{0x00000300, 0x00000001, 0x00000003},
+				{0x00000300, 0x00000003, 0x00000003}
+			};
+
+ncore_ccu_t ccu_noc_fw_l4_per[] = {
+				/* NAND */
+				{0x00000000, 0x01010001, 0x01010001},
+				/* USB0 */
+				{0x0000000C, 0x01010001, 0x01010001},
+				/* USB1 */
+				{0x00000010, 0x01010001, 0x01010001},
+				/* SPI_MAIN0 */
+				{0x0000001C, 0x01010301, 0x01010301},
+				/* SPI_MAIN1 */
+				{0x00000020, 0x01010301, 0x01010301},
+				/* SPI_SECONDARY0 */
+				{0x00000024, 0x01010301, 0x01010301},
+				/* SPI_SECONDARY1 */
+				{0x00000028, 0x01010301, 0x01010301},
+				/* EMAC0 */
+				{0x0000002C, 0x01010001, 0x01010001},
+				/* EMAC1 */
+				{0x00000030, 0x01010001, 0x01010001},
+				/* EMAC2 */
+				{0x00000034, 0x01010001, 0x01010001},
+				/* SDMMC */
+				{0x00000040, 0x01010001, 0x01010001},
+				/* GPIO0 */
+				{0x00000044, 0x01010301, 0x01010301},
+				/* GPIO1 */
+				{0x00000048, 0x01010301, 0x01010301},
+				/* I2C0 */
+				{0x00000050, 0x01010301, 0x01010301},
+				/* I2C1 */
+				{0x00000054, 0x01010301, 0x01010301},
+				/* I2C2 */
+				{0x00000058, 0x01010301, 0x01010301},
+				/* I2C3 */
+				{0x0000005C, 0x01010301, 0x01010301},
+				/* I2C4 */
+				{0x00000060, 0x01010301, 0x01010301},
+				/* SP_TIMER0 */
+				{0x00000064, 0x01010301, 0x01010301},
+				/* SP_TIMER1 */
+				{0x00000068, 0x01010301, 0x01010301},
+				/* UART0 */
+				{0x0000006C, 0x01010301, 0x01010301},
+				/* UART1 */
+				{0x00000070, 0x01010301, 0x01010301},
+				/* I3C0 */
+				{0x00000074, 0x01010301, 0x01010301},
+				/* I3C1 */
+				{0x00000078, 0x01010301, 0x01010301},
+				/* DMA0 */
+				{0x0000007C, 0x01010001, 0x01010001},
+				/* DMA1 */
+				{0x00000080, 0x01010001, 0x01010001},
+				/* COMBO_PHY */
+				{0x00000084, 0x01010001, 0x01010001},
+				/* NAND_SDMA */
+				{0x00000088, 0x01010301, 0x01010301}
+			};
+
+ncore_ccu_t ccu_noc_fw_l4_sys[] = {
+				/* DMA_ECC */
+				{0x00000008, 0x01010001, 0x01010001},
+				/* EMAC0RX_ECC */
+				{0x0000000C, 0x01010001, 0x01010001},
+				/* EMAC0TX_ECC */
+				{0x00000010, 0x01010001, 0x01010001},
+				/* EMAC1RX_ECC */
+				{0x00000014, 0x01010001, 0x01010001},
+				/* EMAC1TX_ECC */
+				{0x00000018, 0x01010001, 0x01010001},
+				/* EMAC2RX_ECC */
+				{0x0000001C, 0x01010001, 0x01010001},
+				/* EMAC2TX_ECC */
+				{0x00000020, 0x01010001, 0x01010001},
+				/* NAND_ECC */
+				{0x0000002C, 0x01010001, 0x01010001},
+				/* NAND_READ_ECC */
+				{0x00000030, 0x01010001, 0x01010001},
+				/* NAND_WRITE_ECC */
+				{0x00000034, 0x01010001, 0x01010001},
+				/* OCRAM_ECC */
+				{0x00000038, 0x01010001, 0x01010001},
+				/* SDMMC_ECC */
+				{0x00000040, 0x01010001, 0x01010001},
+				/* USB0_ECC */
+				{0x00000044, 0x01010001, 0x01010001},
+				/* USB1_CACHEECC */
+				{0x00000048, 0x01010001, 0x01010001},
+				/* CLOCK_MANAGER */
+				{0x0000004C, 0x01010001, 0x01010001},
+				/* IO_MANAGER */
+				{0x00000054, 0x01010001, 0x01010001},
+				/* RESET_MANAGER */
+				{0x00000058, 0x01010001, 0x01010001},
+				/* SYSTEM_MANAGER */
+				{0x0000005C, 0x01010001, 0x01010001},
+				/* OSC0_TIMER */
+				{0x00000060, 0x01010301, 0x01010301},
+				/* OSC1_TIMER0*/
+				{0x00000064, 0x01010301, 0x01010301},
+				/* WATCHDOG0 */
+				{0x00000068, 0x01010301, 0x01010301},
+				/* WATCHDOG1 */
+				{0x0000006C, 0x01010301, 0x01010301},
+				/* WATCHDOG2 */
+				{0x00000070, 0x01010301, 0x01010301},
+				/* WATCHDOG3 */
+				{0x00000074, 0x01010301, 0x01010301},
+				/* DAP */
+				{0x00000078, 0x03010001, 0x03010001},
+				/* WATCHDOG4 */
+				{0x0000007C, 0x01010301, 0x01010301},
+				/* POWER_MANAGER */
+				{0x00000080, 0x01010001, 0x01010001},
+				/* USB1_RXECC */
+				{0x00000084, 0x01010001, 0x01010001},
+				/* USB1_TXECC */
+				{0x00000088, 0x01010001, 0x01010001},
+				/* L4_NOC_PROBES */
+				{0x00000090, 0x01010001, 0x01010001},
+				/* L4_NOC_QOS */
+				{0x00000094, 0x01010001, 0x01010001}
+			};
+
+ncore_ccu_t ccu_noc_fw_lwsoc2fpga[] = {
+				/* LWSOC2FPGA_CSR */
+				{0x00000000, 0x0FFE0301, 0x0FFE0301}
+			};
+
+ncore_ccu_t ccu_noc_fw_soc2fpga[] = {
+				/* SOC2FPGA_CSR */
+				{0x00000000, 0x0FFE0301, 0x0FFE0301}
+			};
+
+ncore_ccu_t ccu_noc_fw_tcu[] = {
+				/* TCU_CSR */
+				{0x00000000, 0x01010001, 0x01010001}
+			};
+
+uint32_t init_ncore_ccu(void)
+{
+	ncore_ccu_t *ccu_module_table = NULL;
+	uint32_t base;
+	uint32_t size;
+	uint32_t val;
+	uint32_t offset;
+	uint32_t mask;
+	uint32_t set_mask = 0U;
+	uint32_t reg = 0U;
+
+	for (int index = 0; index < ARRAY_SIZE(ncore_ccu_modules); index++) {
+		base = ncore_ccu_modules[index].base;
+		size = ncore_ccu_modules[index].size;
+
+		switch (index) {
+		case 0:
+			ccu_module_table = ccu_caiu0;
+			size = (sizeof(ccu_caiu0) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 1:
+			ccu_module_table = ccu_ncaiu0;
+			size = (sizeof(ccu_ncaiu0) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 2:
+			ccu_module_table = ccu_ncaiu1;
+			size = (sizeof(ccu_ncaiu1) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 3:
+			ccu_module_table = ccu_ncaiu2;
+			size = (sizeof(ccu_ncaiu2) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 4:
+			ccu_module_table = ccu_ncaiu3;
+			size = (sizeof(ccu_ncaiu3) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 5:
+			ccu_module_table = ccu_dce0;
+			size = (sizeof(ccu_dce0) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 6:
+			ccu_module_table = ccu_dce1;
+			size = (sizeof(ccu_dce1) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 7:
+			ccu_module_table = ccu_dmi0;
+			size = (sizeof(ccu_dmi0) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 8:
+			ccu_module_table = ccu_dmi1;
+			size = (sizeof(ccu_dmi1) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 9:
+			ccu_module_table = ccu_noc_fw_l4_per;
+			size = (sizeof(ccu_noc_fw_l4_per) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 10:
+			ccu_module_table = ccu_noc_fw_l4_sys;
+			size = (sizeof(ccu_noc_fw_l4_sys) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 11:
+			ccu_module_table = ccu_noc_fw_lwsoc2fpga;
+			size = (sizeof(ccu_noc_fw_lwsoc2fpga) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 12:
+			ccu_module_table = ccu_noc_fw_soc2fpga;
+			size = (sizeof(ccu_noc_fw_soc2fpga) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		case 13:
+			ccu_module_table = ccu_noc_fw_tcu;
+			size = (sizeof(ccu_noc_fw_tcu) / CCU_WORD_BYTE) / CCU_OFFSET_VAL_MASK;
+			break;
+
+		default:
+			break;
+		}
+
+		VERBOSE("CCU node base addr 0x%x, name %s, size 0x%x and module table %p\n",
+			base, ncore_ccu_modules[index].name, size, (uint32_t *)ccu_module_table);
+
+		/*
+		 * First element: offset
+		 * Second element: val
+		 * Third element: mask
+		 */
+		for (int i = 0; i < size; i++) {
+			offset = ccu_module_table[i].offset;
+			val = ccu_module_table[i].val;
+
+			/* Reads the masking bit value from the list */
+			mask = ccu_module_table[i].mask;
+
+			if (mask != 0) {
+				if (mask == 0xFFFFFFFF) {
+					reg = base + offset;
+					mmio_write_32((uintptr_t)reg, val);
+				} else {
+					/* Mask the value with the masking bits */
+					set_mask = val & mask;
+					reg = base + offset;
+
+					/* Clears and sets specific bits in the register */
+					mmio_clrsetbits_32((uintptr_t)reg, mask, set_mask);
+				}
+			}
+
+		}
+
+	}
+
+	return 0;
+}
+#endif
 
 static coh_ss_id_t subsystem_id;
 void get_subsystem_id(void)
@@ -29,6 +529,7 @@ void get_subsystem_id(void)
 	subsystem_id.num_directory = directory;
 	subsystem_id.num_coh_agent = coh_agent;
 }
+
 uint32_t directory_init(void)
 {
 	uint32_t dir_sf_mtn, dir_sf_en;
@@ -42,7 +543,7 @@ uint32_t directory_init(void)
 			/* Poll Active Bit */
 			ret = poll_active_bit(dir);
 			if (ret != 0) {
-				ERROR("Timeout during active bit polling");
+				ERROR("Timeout during active bit polling\n");
 				return -ETIMEDOUT;
 			}
 			/* Disable snoop filter, a bit per snoop filter */
@@ -51,6 +552,7 @@ uint32_t directory_init(void)
 	}
 	return 0;
 }
+
 uint32_t coherent_agent_intfc_init(void)
 {
 	uint32_t dir, ca, ca_id, ca_type, ca_snoop_en;
@@ -65,11 +567,12 @@ uint32_t coherent_agent_intfc_init(void)
 			ca_type = CACHING_AGENT_TYPE(ca_id);
 			if (ca_type == ACE_W_DVM || ca_type == ACE_L_W_DVM)
 				mmio_setbits_32(NCORE_CCU_CSR(NCORE_CSADSER0),
-				BIT(ca));
+						BIT(ca));
 		}
 	}
 	return 0;
 }
+
 uint32_t poll_active_bit(uint32_t dir)
 {
 	uint32_t timeout = 80000;
@@ -81,6 +584,7 @@ uint32_t poll_active_bit(uint32_t dir)
 	}
 	return -1;
 }
+
 void bypass_ocram_firewall(void)
 {
 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
@@ -92,6 +596,7 @@ void bypass_ocram_firewall(void)
 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
 }
+
 void ncore_enable_ocram_firewall(void)
 {
 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
@@ -103,6 +608,8 @@ void ncore_enable_ocram_firewall(void)
 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
 }
+
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 uint32_t init_ncore_ccu(void)
 {
 	uint32_t status;
@@ -112,6 +619,7 @@ uint32_t init_ncore_ccu(void)
 	bypass_ocram_firewall();
 	return status;
 }
+#endif
 
 void setup_smmu_stream_id(void)
 {
@@ -130,11 +638,10 @@ void setup_smmu_stream_id(void)
 	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN0), TSN0);
 	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN1), TSN1);
 	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_ID_AX_REG_2_TSN2), TSN2);
-
 	/* Enabled Stream ctrl register for Agilex5 */
 	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_CTRL_REG_0_DMA0), ENABLE_STREAMID);
 	mmio_write_32(SOCFPGA_SYSMGR(DMA_TBU_STREAM_CTRL_REG_0_DMA1), ENABLE_STREAMID);
-	mmio_write_32(SOCFPGA_SYSMGR(SDM_TBU_STREAM_CTRL_REG_1_SDM), ENABLE_STREAMID_SECURE_TX);
+	mmio_write_32(SOCFPGA_SYSMGR(SDM_TBU_STREAM_CTRL_REG_1_SDM), ENABLE_STREAMID);
 	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_USB2), ENABLE_STREAMID);
 	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_USB3), ENABLE_STREAMID);
 	mmio_write_32(SOCFPGA_SYSMGR(IO_TBU_STREAM_CTRL_REG_2_SDMMC), ENABLE_STREAMID);
@@ -144,3 +651,61 @@ void setup_smmu_stream_id(void)
 	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN1), ENABLE_STREAMID);
 	mmio_write_32(SOCFPGA_SYSMGR(TSN_TBU_STREAM_CTRL_REG_3_TSN2), ENABLE_STREAMID);
 }
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+/* TODO: Temp added this here*/
+static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match, uint32_t delay_ms)
+{
+	int time_out = delay_ms;
+
+	while (time_out-- > 0) {
+
+		if ((mmio_read_32(addr) & mask) == match) {
+			return 0;
+		}
+		udelay(1000);
+	}
+
+	return -ETIMEDOUT;
+}
+
+int flush_l3_dcache(void)
+{
+	int i;
+	int ret = 0;
+
+	/* Flushing all entries in CCU system memory cache */
+	for (i = 0; i < MAX_DISTRIBUTED_MEM_INTERFACE; i++) {
+		mmio_write_32(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES) |
+			   FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID, ARRAY_ID_TAG),
+			   (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000)));
+
+		/* Wait for cache maintenance operation done */
+		ret = poll_idle_status((CCU_DMI0_DMIUSMCMAR +
+				(i * 0x1000)), CACHE_OPERATION_DONE,
+				CACHE_OPERATION_DONE, TIMEOUT_200MS);
+
+		if (ret != 0) {
+			VERBOSE("%s: Timeout while waiting for flushing tag in DMI%d done\n",
+					__func__, i);
+			return ret;
+		}
+
+		mmio_write_32(FIELD_PREP(CCU_DMI0_DMIUSMCMCR_MNTOP, FLUSH_ALL_ENTRIES) |
+			   FIELD_PREP(CCU_DMI0_DMIUSMCMCR_ARRAY_ID, ARRAY_ID_DATA),
+			   (uintptr_t)(CCU_DMI0_DMIUSMCMCR + (i * 0x1000)));
+
+		/* Wait for cache maintenance operation done */
+		ret = poll_idle_status((CCU_DMI0_DMIUSMCMAR +
+				(i * 0x1000)), CACHE_OPERATION_DONE,
+				CACHE_OPERATION_DONE, TIMEOUT_200MS);
+
+		if (ret != 0) {
+			VERBOSE("%s: Timeout while waiting for flushing data in DMI%d done\n",
+					__func__, i);
+		}
+	}
+
+	return ret;
+}
+#endif
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
index 6cdbeb8c..a89c098d 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,192 +10,206 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include "socfpga_plat_def.h"
+
 #ifndef CCU_ACTIVATE_COH_FPGA
-#define CCU_ACTIVATE_COH_FPGA 0
+#define CCU_ACTIVATE_COH_FPGA			0
 #endif
-// Address map for ccu init
-#define addr_CAIUIDR1				(0x1C000000)
-#define addr_GRBUNRRUCR				(0x1c0ffff8)
-#define base_addr_NRS_CAIU0			(0x1c000000)
-#define base_addr_NRS_NCAIU0			(0x1c001000)
-#define base_addr_NRS_NCAIU1			(0x1c002000)
-#define base_addr_NRS_NCAIU2			(0x1c003000)
-#define base_addr_NRS_NCAIU3			(0x1c004000)
-#define base_addr_NRS_DCE0			(0x1c005000)
-#define base_addr_NRS_DCE1			(0x1c006000)
-//#define base_addr_NRS_DMI0			(0x1c007000)
-//#define base_addr_NRS_DMI1			(0x1c008000)
-//DMI
-#define ALT_CCU_CCU_DMI0_DMIUSMCTCR_ADDR	0x1C007300
-#define ALT_CCU_CCU_DMI1_DMIUSMCTCR_ADDR	0x1C008300
-//DSU
-#define ALT_CCU_DSU_CAIUAMIGR_ADDR		0x1C0003C0
-#define ALT_CCU_DSU_CAIUMIFSR_ADDR		0x1C0003C4
-#define ALT_CCU_DSU_CAIUGPRBLR1_ADDR		0x1C000414
-#define ALT_CCU_DSU_CAIUGPRBHR1_ADDR		0x1C000418
-#define ALT_CCU_DSU_CAIUGPRAR1_ADDR		0x1C000410
-#define ALT_CCU_DSU_CAIUGPRBLR2_ADDR		0x1C000424
-#define ALT_CCU_DSU_CAIUGPRBHR2_ADDR		0x1C000428
-#define ALT_CCU_DSU_CAIUGPRAR2_ADDR		0x1C000420
-#define ALT_CCU_DSU_CAIUGPRBLR4_ADDR		0x1C000444
-#define ALT_CCU_DSU_CAIUGPRBHR4_ADDR		0x1C000448
-#define ALT_CCU_DSU_CAIUGPRAR4_ADDR		0x1C000440
-#define ALT_CCU_DSU_CAIUGPRBLR5_ADDR		0x1C000454
-#define ALT_CCU_DSU_CAIUGPRBHR5_ADDR		0x1C000458
-#define ALT_CCU_DSU_CAIUGPRAR5_ADDR		0x1C000450
-#define ALT_CCU_DSU_CAIUGPRBLR6_ADDR		0x1C000464
-#define ALT_CCU_DSU_CAIUGPRBHR6_ADDR		0x1C000468
-#define ALT_CCU_DSU_CAIUGPRAR6_ADDR		0x1C000460
-#define ALT_CCU_DSU_CAIUGPRBLR7_ADDR		0x1C000474
-#define ALT_CCU_DSU_CAIUGPRBHR7_ADDR		0x1C000478
-#define ALT_CCU_DSU_CAIUGPRAR7_ADDR		0x1C000470
-#define ALT_CCU_DSU_CAIUGPRBLR8_ADDR		0x1C000484
-#define ALT_CCU_DSU_CAIUGPRBHR8_ADDR		0x1C000488
-#define ALT_CCU_DSU_CAIUGPRAR8_ADDR		0x1C000480
-#define ALT_CCU_DSU_CAIUGPRBLR9_ADDR		0x1C000494
-#define ALT_CCU_DSU_CAIUGPRBHR9_ADDR		0x1C000498
-#define ALT_CCU_DSU_CAIUGPRAR9_ADDR		0x1C000490
-#define ALT_CCU_DSU_CAIUGPRBLR10_ADDR		0x1C0004A4
-#define ALT_CCU_DSU_CAIUGPRBHR10_ADDR		0x1C0004A8
-#define ALT_CCU_DSU_CAIUGPRAR10_ADDR		0x1C0004A0
-//GIC
-#define ALT_CCU_GIC_M_XAIUAMIGR_ADDR		0x1C0023C0
-#define ALT_CCU_GIC_M_XAIUMIFSR_ADDR		0x1C0023C4
-#define ALT_CCU_GIC_M_XAIUGPRBLR1_ADDR		0x1C002414
-#define ALT_CCU_GIC_M_XAIUGPRBHR1_ADDR		0x1C002418
-#define ALT_CCU_GIC_M_XAIUGPRAR1_ADDR		0x1C002410
-#define ALT_CCU_GIC_M_XAIUGPRBLR6_ADDR		0x1C002464
-#define ALT_CCU_GIC_M_XAIUGPRBHR6_ADDR		0x1C002468
-#define ALT_CCU_GIC_M_XAIUGPRAR6_ADDR		0x1C002460
-#define ALT_CCU_GIC_M_XAIUGPRBLR8_ADDR		0x1C002484
-#define ALT_CCU_GIC_M_XAIUGPRBHR8_ADDR		0x1C002488
-#define ALT_CCU_GIC_M_XAIUGPRAR8_ADDR		0x1C002480
-#define ALT_CCU_GIC_M_XAIUGPRBLR10_ADDR		0x1C0024A4
-#define ALT_CCU_GIC_M_XAIUGPRBHR10_ADDR		0x1C0024A8
-#define ALT_CCU_GIC_M_XAIUGPRAR10_ADDR		0x1C0024A0
-//FPGA2SOC
-#define ALT_CCU_FPGA2SOC_XAIUAMIGR_ADDR		0x1C0013C0
-#define ALT_CCU_FPGA2SOC_XAIUMIFSR_ADDR		0x1C0013C4
-#define ALT_CCU_FPGA2SOC_XAIUGPRBLR1_ADDR	0x1C001414
-#define ALT_CCU_FPGA2SOC_XAIUGPRBHR1_ADDR	0x1C001418
-#define ALT_CCU_FPGA2SOC_XAIUGPRAR1_ADDR	0x1C001410
-#define ALT_CCU_FPGA2SOC_XAIUGPRBLR6_ADDR	0x1C001464
-#define ALT_CCU_FPGA2SOC_XAIUGPRBHR6_ADDR	0x1C001468
-#define ALT_CCU_FPGA2SOC_XAIUGPRAR6_ADDR	0x1C001460
-#define ALT_CCU_FPGA2SOC_XAIUGPRBLR8_ADDR	0x1C001484
-#define ALT_CCU_FPGA2SOC_XAIUGPRBHR8_ADDR	0x1C001488
-#define ALT_CCU_FPGA2SOC_XAIUGPRAR8_ADDR	0x1C001480
-#define ALT_CCU_FPGA2SOC_XAIUGPRBLR10_ADDR	0x1C0014A4
-#define ALT_CCU_FPGA2SOC_XAIUGPRBHR10_ADDR	0x1C0014A8
-#define ALT_CCU_FPGA2SOC_XAIUGPRAR10_ADDR	0x1C0014A0
-//TCU
-#define ALT_CCU_TCU_BASE 0x1C003000
-#define ALT_CCU_TCU_XAIUAMIGR_ADDR		ALT_CCU_TCU_BASE + 0x03C0
-#define ALT_CCU_TCU_XAIUMIFSR_ADDR		ALT_CCU_TCU_BASE + 0x03C4
-#define ALT_CCU_TCU_XAIUGPRBLR0_ADDR		ALT_CCU_TCU_BASE + 0x0404
-#define ALT_CCU_TCU_XAIUGPRBHR0_ADDR		ALT_CCU_TCU_BASE + 0x0408
-#define ALT_CCU_TCU_XAIUGPRAR0_ADDR		ALT_CCU_TCU_BASE + 0x0400
-#define ALT_CCU_TCU_XAIUGPRBLR1_ADDR		ALT_CCU_TCU_BASE + 0x0414
-#define ALT_CCU_TCU_XAIUGPRBHR1_ADDR		ALT_CCU_TCU_BASE + 0x0418
-#define ALT_CCU_TCU_XAIUGPRAR1_ADDR		ALT_CCU_TCU_BASE + 0x0410
-#define ALT_CCU_TCU_XAIUGPRBLR2_ADDR		ALT_CCU_TCU_BASE + 0x0424
-#define ALT_CCU_TCU_XAIUGPRBHR2_ADDR		ALT_CCU_TCU_BASE + 0x0428
-#define ALT_CCU_TCU_XAIUGPRAR2_ADDR		ALT_CCU_TCU_BASE + 0x0420
-#define ALT_CCU_TCU_XAIUGPRBLR6_ADDR		0x1C003464
-#define ALT_CCU_TCU_XAIUGPRBHR6_ADDR		0x1C003468
-#define ALT_CCU_TCU_XAIUGPRAR6_ADDR		0x1C003460
-#define ALT_CCU_TCU_XAIUGPRBLR8_ADDR		0x1C003484
-#define ALT_CCU_TCU_XAIUGPRBHR8_ADDR		0x1C003488
-#define ALT_CCU_TCU_XAIUGPRAR8_ADDR		0x1C003480
-#define ALT_CCU_TCU_XAIUGPRBLR10_ADDR		0x1C0034A4
-#define ALT_CCU_TCU_XAIUGPRBHR10_ADDR		0x1C0034A8
-#define ALT_CCU_TCU_XAIUGPRAR10_ADDR		0x1C0034A0
-//IOM
-#define ALT_CCU_CCU_IOM_XAIUAMIGR_ADDR		0x1C0043C0
-#define ALT_CCU_CCU_IOM_XAIUMIFSR_ADDR		0x1C0013C4
-#define ALT_CCU_IOM_XAIUGPRBLR1_ADDR		0x1C001414
-#define ALT_CCU_IOM_XAIUGPRBHR1_ADDR		0x1C001418
-#define ALT_CCU_IOM_XAIUGPRAR1_ADDR		0x1C001410
-#define ALT_CCU_CCU_IOM_XAIUGPRBLR6_ADDR	0x1C001464
-#define ALT_CCU_CCU_IOM_XAIUGPRBHR6_ADDR	0x1C001468
-#define ALT_CCU_CCU_IOM_XAIUGPRAR6_ADDR		0x1C001460
-#define ALT_CCU_CCU_IOM_XAIUGPRBLR8_ADDR	0x1C001484
-#define ALT_CCU_CCU_IOM_XAIUGPRBHR8_ADDR	0x1C001488
-#define ALT_CCU_CCU_IOM_XAIUGPRAR8_ADDR		0x1C001480
-#define ALT_CCU_CCU_IOM_XAIUGPRBLR10_ADDR	0x1C0014A4
-#define ALT_CCU_CCU_IOM_XAIUGPRBHR10_ADDR	0x1C0014A8
-#define ALT_CCU_CCU_IOM_XAIUGPRAR10_ADDR	0x1C0014A0
-//DCE
-#define ALT_CCU_DCE0_DCEUAMIGR_ADDR		0x1C0053C0
-#define ALT_CCU_DCE0_DCEUMIFSR_ADDR		0x1C0053C4
-#define ALT_CCU_DCE0_DCEUGPRBLR6_ADDR		0x1C005464
-#define ALT_CCU_DCE0_DCEUGPRBHR6_ADDR		0x1C005468
-#define ALT_CCU_DCE0_DCEUGPRAR6_ADDR		0x1C005460
-#define ALT_CCU_DCE0_DCEUGPRBLR8_ADDR		0x1C005484
-#define ALT_CCU_DCE0_DCEUGPRBHR8_ADDR		0x1C005488
-#define ALT_CCU_DCE0_DCEUGPRAR8_ADDR		0x1C005480
-#define ALT_CCU_DCE0_DCEUGPRBLR10_ADDR		0x1C0054A4
-#define ALT_CCU_DCE0_DCEUGPRBHR10_ADDR		0x1C0054A8
-#define ALT_CCU_DCE0_DCEUGPRAR10_ADDR		0x1C0054A0
-#define ALT_CCU_DCE1_DCEUAMIGR_ADDR		0x1C0063C0
-#define ALT_CCU_DCE1_DCEUMIFSR_ADDR		0x1C0063C4
-#define ALT_CCU_DCE1_DCEUGPRBLR6_ADDR		0x1C006464
-#define ALT_CCU_DCE1_DCEUGPRBHR6_ADDR		0x1C006468
-#define ALT_CCU_DCE1_DCEUGPRAR6_ADDR		0x1C006460
-#define ALT_CCU_DCE1_DCEUGPRBLR8_ADDR		0x1C006484
-#define ALT_CCU_DCE1_DCEUGPRBHR8_ADDR		0x1C006488
-#define ALT_CCU_DCE1_DCEUGPRAR8_ADDR		0x1C006480
-#define ALT_CCU_DCE1_DCEUGPRBLR10_ADDR		0x1C0064A4
-#define ALT_CCU_DCE1_DCEUGPRBHR10_ADDR		0x1C0064A8
-#define ALT_CCU_DCE1_DCEUGPRAR10_ADDR		0x1C0064A0
-#define offset_NRS_GPRAR0			(0x400)
-#define offset_NRS_GPRBLR0			(0x404)
-#define offset_NRS_GPRBHR0			(0x408)
-#define offset_NRS_GPRAR1			(0x410)
-#define offset_NRS_GPRBLR1			(0x414)
-#define offset_NRS_GPRBHR1			(0x418)
-#define offset_NRS_GPRAR2			(0x420)
-#define offset_NRS_GPRBLR2			(0x424)
-#define offset_NRS_GPRBHR2			(0x428)
-#define offset_NRS_GPRAR3			(0x430)
-#define offset_NRS_GPRBLR3			(0x434)
-#define offset_NRS_GPRBHR3			(0x438)
-#define offset_NRS_GPRAR4			(0x440)
-#define offset_NRS_GPRBLR4			(0x444)
-#define offset_NRS_GPRBHR4			(0x448)
-#define offset_NRS_GPRAR5			(0x450)
-#define offset_NRS_GPRBLR5			(0x454)
-#define offset_NRS_GPRBHR5			(0x458)
-#define offset_NRS_GPRAR6			(0x460)
-#define offset_NRS_GPRBLR6			(0x464)
-#define offset_NRS_GPRBHR6			(0x468)
-#define offset_NRS_GPRAR7			(0x470)
-#define offset_NRS_GPRBLR7			(0x474)
-#define offset_NRS_GPRBHR7			(0x478)
-#define offset_NRS_GPRAR8			(0x480)
-#define offset_NRS_GPRBLR8			(0x484)
-#define offset_NRS_GPRBHR8			(0x488)
-#define offset_NRS_GPRAR9			(0x490)
-#define offset_NRS_GPRBLR9			(0x494)
-#define offset_NRS_GPRBHR9			(0x498)
-#define offset_NRS_GPRAR10			(0x4a0)
-#define offset_NRS_GPRBLR10			(0x4a4)
-#define offset_NRS_GPRBHR10			(0x4a8)
-#define offset_NRS_AMIGR			(0x3c0)
-#define offset_NRS_MIFSR			(0x3c4)
-#define offset_NRS_DMIUSMCTCR			(0x300)
-#define base_addr_DII0_PSSPERIPHS		(0x10000)
-#define base_addr_DII0_LWHPS2FPGA		(0x20000)
-#define base_addr_DII0_HPS2FPGA_1G		(0x40000)
-#define base_addr_DII0_HPS2FPGA_15G		(0x400000)
-#define base_addr_DII0_HPS2FPGA_240G		(0x4000000)
-#define base_addr_DII1_MPFEREGS			(0x18000)
-#define base_addr_DII2_GICREGS			(0x1D000)
-#define base_addr_DII3_OCRAM			(0x0)
-#define base_addr_BHR				(0x0)
-#define base_addr_DMI_SDRAM_2G			(0x80000)
-#define base_addr_DMI_SDRAM_30G			(0x800000)
-#define base_addr_DMI_SDRAM_480G		(0x8000000)
+
+/* Macros */
+#define CCU_OFFSET_VAL_MASK				3U
+#define CCU_WORD_BYTE					4U
+
+// Address Map for CCU Init
+#define addr_CAIUIDR1				SOCFPGA_CCU_NOC_REG_BASE + 0x00000
+#define addr_GRBUNRRUCR				SOCFPGA_CCU_NOC_REG_BASE + 0xFFFF8
+#define base_addr_NRS_CAIU0			SOCFPGA_CCU_NOC_REG_BASE + 0x00000
+#define base_addr_NRS_NCAIU0			SOCFPGA_CCU_NOC_REG_BASE + 0x01000
+#define base_addr_NRS_NCAIU1			SOCFPGA_CCU_NOC_REG_BASE + 0x02000
+#define base_addr_NRS_NCAIU2			SOCFPGA_CCU_NOC_REG_BASE + 0x03000
+#define base_addr_NRS_NCAIU3			SOCFPGA_CCU_NOC_REG_BASE + 0x04000
+#define base_addr_NRS_DCE0			SOCFPGA_CCU_NOC_REG_BASE + 0x05000
+#define base_addr_NRS_DCE1			SOCFPGA_CCU_NOC_REG_BASE + 0x06000
+//#define base_addr_NRS_DMI0			SOCFPGA_CCU_NOC_REG_BASE + 0x07000
+//#define base_addr_NRS_DMI1			SOCFPGA_CCU_NOC_REG_BASE + 0x08000
+
+/* DMI */
+#define ALT_CCU_CCU_DMI0_DMIUSMCTCR_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x7300
+#define ALT_CCU_CCU_DMI1_DMIUSMCTCR_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x8300
+
+/* DSU */
+#define ALT_CCU_DSU_CAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3C0
+#define ALT_CCU_DSU_CAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3C4
+#define ALT_CCU_DSU_CAIUGPRBLR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x414
+#define ALT_CCU_DSU_CAIUGPRBHR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x418
+#define ALT_CCU_DSU_CAIUGPRAR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x410
+#define ALT_CCU_DSU_CAIUGPRBLR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x424
+#define ALT_CCU_DSU_CAIUGPRBHR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x428
+#define ALT_CCU_DSU_CAIUGPRAR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x420
+#define ALT_CCU_DSU_CAIUGPRBLR4_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x444
+#define ALT_CCU_DSU_CAIUGPRBHR4_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x448
+#define ALT_CCU_DSU_CAIUGPRAR4_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x440
+#define ALT_CCU_DSU_CAIUGPRBLR5_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x454
+#define ALT_CCU_DSU_CAIUGPRBHR5_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x458
+#define ALT_CCU_DSU_CAIUGPRAR5_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x450
+#define ALT_CCU_DSU_CAIUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x464
+#define ALT_CCU_DSU_CAIUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x468
+#define ALT_CCU_DSU_CAIUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x460
+#define ALT_CCU_DSU_CAIUGPRBLR7_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x474
+#define ALT_CCU_DSU_CAIUGPRBHR7_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x478
+#define ALT_CCU_DSU_CAIUGPRAR7_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x470
+#define ALT_CCU_DSU_CAIUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x484
+#define ALT_CCU_DSU_CAIUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x488
+#define ALT_CCU_DSU_CAIUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x480
+#define ALT_CCU_DSU_CAIUGPRBLR9_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x494
+#define ALT_CCU_DSU_CAIUGPRBHR9_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x498
+#define ALT_CCU_DSU_CAIUGPRAR9_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x490
+#define ALT_CCU_DSU_CAIUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x4A4
+#define ALT_CCU_DSU_CAIUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x4A8
+#define ALT_CCU_DSU_CAIUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x4A0
+
+/* GIC */
+#define ALT_CCU_GIC_M_XAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x23C0
+#define ALT_CCU_GIC_M_XAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x23C4
+#define ALT_CCU_GIC_M_XAIUGPRBLR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2414
+#define ALT_CCU_GIC_M_XAIUGPRBHR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2418
+#define ALT_CCU_GIC_M_XAIUGPRAR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2410
+#define ALT_CCU_GIC_M_XAIUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2464
+#define ALT_CCU_GIC_M_XAIUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2468
+#define ALT_CCU_GIC_M_XAIUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2460
+#define ALT_CCU_GIC_M_XAIUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2484
+#define ALT_CCU_GIC_M_XAIUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2488
+#define ALT_CCU_GIC_M_XAIUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x2480
+#define ALT_CCU_GIC_M_XAIUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x24A4
+#define ALT_CCU_GIC_M_XAIUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x24A8
+#define ALT_CCU_GIC_M_XAIUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x24A0
+
+/* FPGA2SOC */
+#define ALT_CCU_FPGA2SOC_BASE			SOCFPGA_CCU_NOC_REG_BASE + 0x1000
+#define ALT_CCU_FPGA2SOC_XAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x13C0
+#define ALT_CCU_FPGA2SOC_XAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x13C4
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR1_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1414
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR1_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1418
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR1_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1410
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1464
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1468
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1460
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1484
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1488
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1480
+#define ALT_CCU_FPGA2SOC_XAIUGPRBLR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A4
+#define ALT_CCU_FPGA2SOC_XAIUGPRBHR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A8
+#define ALT_CCU_FPGA2SOC_XAIUGPRAR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A0
+
+/* TCU */
+#define ALT_CCU_TCU_XAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x33C0
+#define ALT_CCU_TCU_XAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x33C4
+#define ALT_CCU_TCU_XAIUGPRBLR0_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3404
+#define ALT_CCU_TCU_XAIUGPRBHR0_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3408
+#define ALT_CCU_TCU_XAIUGPRAR0_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3400
+#define ALT_CCU_TCU_XAIUGPRBLR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3414
+#define ALT_CCU_TCU_XAIUGPRBHR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3418
+#define ALT_CCU_TCU_XAIUGPRAR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3410
+#define ALT_CCU_TCU_XAIUGPRBLR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3424
+#define ALT_CCU_TCU_XAIUGPRBHR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3428
+#define ALT_CCU_TCU_XAIUGPRAR2_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3420
+#define ALT_CCU_TCU_XAIUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3464
+#define ALT_CCU_TCU_XAIUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3468
+#define ALT_CCU_TCU_XAIUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3460
+#define ALT_CCU_TCU_XAIUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3484
+#define ALT_CCU_TCU_XAIUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3488
+#define ALT_CCU_TCU_XAIUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x3480
+#define ALT_CCU_TCU_XAIUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x34A4
+#define ALT_CCU_TCU_XAIUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x34A8
+#define ALT_CCU_TCU_XAIUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x34A0
+
+/* IOM */
+#define ALT_CCU_CCU_IOM_XAIUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x43C0
+#define ALT_CCU_CCU_IOM_XAIUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x13C4
+#define ALT_CCU_IOM_XAIUGPRBLR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1414
+#define ALT_CCU_IOM_XAIUGPRBHR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1418
+#define ALT_CCU_IOM_XAIUGPRAR1_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1410
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1464
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR6_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1468
+#define ALT_CCU_CCU_IOM_XAIUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1460
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1484
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR8_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x1488
+#define ALT_CCU_CCU_IOM_XAIUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x1480
+#define ALT_CCU_CCU_IOM_XAIUGPRBLR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A4
+#define ALT_CCU_CCU_IOM_XAIUGPRBHR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A8
+#define ALT_CCU_CCU_IOM_XAIUGPRAR10_ADDR	SOCFPGA_CCU_NOC_REG_BASE + 0x14A0
+
+/* DCE */
+#define ALT_CCU_DCE0_DCEUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x53C0
+#define ALT_CCU_DCE0_DCEUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x53C4
+#define ALT_CCU_DCE0_DCEUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5464
+#define ALT_CCU_DCE0_DCEUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5468
+#define ALT_CCU_DCE0_DCEUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5460
+#define ALT_CCU_DCE0_DCEUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5484
+#define ALT_CCU_DCE0_DCEUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5488
+#define ALT_CCU_DCE0_DCEUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x5480
+#define ALT_CCU_DCE0_DCEUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x54A4
+#define ALT_CCU_DCE0_DCEUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x54A8
+#define ALT_CCU_DCE0_DCEUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x54A0
+#define ALT_CCU_DCE1_DCEUAMIGR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x63C0
+#define ALT_CCU_DCE1_DCEUMIFSR_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x63C4
+#define ALT_CCU_DCE1_DCEUGPRBLR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6464
+#define ALT_CCU_DCE1_DCEUGPRBHR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6468
+#define ALT_CCU_DCE1_DCEUGPRAR6_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6460
+#define ALT_CCU_DCE1_DCEUGPRBLR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6484
+#define ALT_CCU_DCE1_DCEUGPRBHR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6488
+#define ALT_CCU_DCE1_DCEUGPRAR8_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x6480
+#define ALT_CCU_DCE1_DCEUGPRBLR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x64A4
+#define ALT_CCU_DCE1_DCEUGPRBHR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x64A8
+#define ALT_CCU_DCE1_DCEUGPRAR10_ADDR		SOCFPGA_CCU_NOC_REG_BASE + 0x64A0
+#define offset_NRS_GPRAR0			0x400
+#define offset_NRS_GPRBLR0			0x404
+#define offset_NRS_GPRBHR0			0x408
+#define offset_NRS_GPRAR1			0x410
+#define offset_NRS_GPRBLR1			0x414
+#define offset_NRS_GPRBHR1			0x418
+#define offset_NRS_GPRAR2			0x420
+#define offset_NRS_GPRBLR2			0x424
+#define offset_NRS_GPRBHR2			0x428
+#define offset_NRS_GPRAR3			0x430
+#define offset_NRS_GPRBLR3			0x434
+#define offset_NRS_GPRBHR3			0x438
+#define offset_NRS_GPRAR4			0x440
+#define offset_NRS_GPRBLR4			0x444
+#define offset_NRS_GPRBHR4			0x448
+#define offset_NRS_GPRAR5			0x450
+#define offset_NRS_GPRBLR5			0x454
+#define offset_NRS_GPRBHR5			0x458
+#define offset_NRS_GPRAR6			0x460
+#define offset_NRS_GPRBLR6			0x464
+#define offset_NRS_GPRBHR6			0x468
+#define offset_NRS_GPRAR7			0x470
+#define offset_NRS_GPRBLR7			0x474
+#define offset_NRS_GPRBHR7			0x478
+#define offset_NRS_GPRAR8			0x480
+#define offset_NRS_GPRBLR8			0x484
+#define offset_NRS_GPRBHR8			0x488
+#define offset_NRS_GPRAR9			0x490
+#define offset_NRS_GPRBLR9			0x494
+#define offset_NRS_GPRBHR9			0x498
+#define offset_NRS_GPRAR10			0x4A0
+#define offset_NRS_GPRBLR10			0x4A4
+#define offset_NRS_GPRBHR10			0x4A8
+#define offset_NRS_AMIGR			0x3C0
+#define offset_NRS_MIFSR			0x3C4
+#define offset_NRS_DMIUSMCTCR			0x300
+#define base_addr_DII0_PSSPERIPHS		0x10000
+#define base_addr_DII0_LWHPS2FPGA		0x20000
+#define base_addr_DII0_HPS2FPGA_1G		0x40000
+#define base_addr_DII0_HPS2FPGA_15G		0x400000
+#define base_addr_DII0_HPS2FPGA_240G		0x4000000
+#define base_addr_DII1_MPFEREGS			0x18000
+#define base_addr_DII2_GICREGS			0x1D000
+#define base_addr_DII3_OCRAM			0x0
+#define base_addr_BHR				0x0
+#define base_addr_DMI_SDRAM_2G			0x80000
+#define base_addr_DMI_SDRAM_30G			0x800000
+#define base_addr_DMI_SDRAM_480G		0x8000000
 // ((0x0<<9) | (0xf<<20) | (0x1<<30) | (0x1<<31))
 #define wr_DII0_PSSPERIPHS			0xC0F00000
 // ((0x0<<9) | (0x11<<20) | (0x1<<30) | (0x1<<31))
@@ -228,54 +243,46 @@
 // ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x17<<20) | (0x0<<30) | (0x1<<31))
 #define wr_DMI_SDRAM_30G			0x81700006
 // ((0x0<<9) | (0x1a<<20) | (0x0<<30) | (0x1<<31))
-#define wr_DMI_SDRAM_240G_ORDERED		0x81a00000
+#define wr_DMI_SDRAM_240G_ORDERED		0x81A00000
 // ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x1a<<20) | (0x0<<30) | (0x1<<31))
-#define wr_DMI_SDRAM_240G			0x81a00006
+#define wr_DMI_SDRAM_240G			0x81A00006
 // ((0x0<<9) | (0x1b<<20) | (0x0<<30) | (0x1<<31))
-#define wr_DMI_SDRAM_480G_ORDERED		0x81b00000
+#define wr_DMI_SDRAM_480G_ORDERED		0x81B00000
 // ((0x1<<1) | (0x1<<2) | (0x0<<9) | (0x1b<<20) | (0x0<<30) | (0x1<<31))
-#define wr_DMI_SDRAM_480G			0x81b00006
+#define wr_DMI_SDRAM_480G			0x81B00006
 
 typedef enum CCU_REGION_SECURITY_e {
-    //
-    // Allow secure accesses only.
-    //
+	/* Allow secure accesses only. */
 	CCU_REGION_SECURITY_SECURE_ONLY,
-    //
-    // Allow non-secure accesses only.
-    //
+
+	/* Allow non-secure accesses only. */
 	CCU_REGION_SECURITY_NON_SECURE_ONLY,
-    //
-    // Allow accesses of any security state.
-    //
+
+	/* Allow accesses of any security state. */
 	CCU_REGION_SECURITY_DONT_CARE
 } CCU_REGION_SECURITY_t;
+
 typedef enum CCU_REGION_PRIVILEGE_e {
-    //
-    // Allow privileged accesses only.
-    //
+	/* Allow privileged accesses only. */
 	CCU_REGION_PRIVILEGE_PRIVILEGED_ONLY,
-    //
-    // Allow unprivileged accesses only.
-    //
+	/* Allow unprivileged accesses only. */
 	CCU_REGION_PRIVILEGE_NON_PRIVILEGED_ONLY,
-    //
-    // Allow accesses of any privilege.
-    //
+	/* Allow accesses of any privilege. */
 	CCU_REGION_PRIVILEGE_DONT_CARE
 } CCU_REGION_PRIVILEGE_t;
-//
-// Initializes the CCU by enabling all regions except RAM 1 - 5.
-// This is needed because of an RTL change around 2016.02.24.
-//
-// Runtime measurement:
-//  - arm     : 14,830,000 ps (2016.05.31; sanity/printf_aarch32)
-//  - aarch64 : 14,837,500 ps (2016.05.31; sanity/printf)
-//
-// Runtime history:
-//  - arm     : 20,916,668 ps (2016.05.30; sanity/printf_aarch32)
-//  - aarch64 : 20,924,168 ps (2016.05.30; sanity/printf)
-//
+
+/*
+ * Initializes the CCU by enabling all regions except RAM 1 - 5.
+ * This is needed because of an RTL change around 2016.02.24.
+ *
+ * Runtime measurement:
+ *  - arm     : 14,830,000 ps (2016.05.31; sanity/printf_aarch32)
+ *  - aarch64 : 14,837,500 ps (2016.05.31; sanity/printf)
+ *
+ * Runtime history:
+ *  - arm     : 20,916,668 ps (2016.05.30; sanity/printf_aarch32)
+ *  - aarch64 : 20,924,168 ps (2016.05.30; sanity/printf)
+ */
 int ccu_hps_init(void);
 
 typedef enum ccu_hps_ram_region_e {
@@ -287,19 +294,21 @@ typedef enum ccu_hps_ram_region_e {
 	ccu_hps_ram_region_ramspace5 = 5,
 } ccu_hps_ram_region_t;
 
-// Disables a RAM (OCRAM) region with the given ID.
+/* Disables a RAM (OCRAM) region with the given ID. */
 int ccu_hps_ram_region_disable(int id);
 
-// Enables a RAM (OCRAM) region with the given ID.
+/* Enables a RAM (OCRAM) region with the given ID. */
 int ccu_hps_ram_region_enable(int id);
 
-// Attempts to remap a RAM (OCRAM) region with the given ID to span the given
-// start and end address. It also assigns the security and privilege policy.
-// Regions must be a power-of-two size with a minimum size of 64B.
+/*
+ * Attempts to remap a RAM (OCRAM) region with the given ID to span the given
+ * start and end address. It also assigns the security and privilege policy.
+ * Regions must be a power-of-two size with a minimum size of 64B.
+ */
 int ccu_hps_ram_region_remap(int id, uintptr_t start, uintptr_t end,
-CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
+	CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
 
-// Verifies that all enabled RAM (OCRAM) regions does not overlap.
+/* Verifies that all enabled RAM (OCRAM) regions does not overlap. */
 int ccu_hps_ram_validate(void);
 
 typedef enum ccu_hps_mem_region_e {
@@ -312,19 +321,21 @@ typedef enum ccu_hps_mem_region_e {
 	ccu_hps_mem_region_memspace1e = 6,
 } ccu_hps_mem_region_t;
 
-// Disables mem0 (DDR) region with the given ID.
+/* Disables mem0 (DDR) region with the given ID. */
 int ccu_hps_mem0_region_disable(int id);
 
-// Enables mem0 (DDR) region with the given ID.
+/* Enables mem0 (DDR) region with the given ID. */
 int ccu_hps_mem0_region_enable(int id);
 
-// Attempts to remap mem0 (DDR) region with the given ID to span the given
-// start and end address. It also assigns the security nad privlege policy.
-// Regions must be a power-of-two in size with a minimum size of 64B.
+/*
+ * Attempts to remap mem0 (DDR) region with the given ID to span the given
+ * start and end address. It also assigns the security nad privlege policy.
+ * Regions must be a power-of-two in size with a minimum size of 64B.
+ */
 int ccu_hps_mem0_region_remap(int id, uintptr_t start, uintptr_t end,
-CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
+	CCU_REGION_SECURITY_t security, CCU_REGION_PRIVILEGE_t privilege);
 
-// Verifies that all enabled mem0 (DDR) regions does not overlap.
+/* Verifies that all enabled mem0 (DDR) regions does not overlap. */
 int ccu_hps_mem0_validate(void);
 
 typedef enum ccu_hps_ios_region_e {
@@ -342,14 +353,23 @@ typedef enum ccu_hps_ios_region_e {
 	ccu_hps_ios_region_iospace2c = 11,
 } ccu_hps_ios_region_t;
 
-// Disables the IOS (IO Slave) region with the given ID.
+/* Disables the IOS (IO Slave) region with the given ID. */
 int ccu_hps_ios_region_disable(int id);
 
-// Enables the IOS (IO Slave) region with the given ID.
+/* Enables the IOS (IO Slave) region with the given ID. */
 int ccu_hps_ios_region_enable(int id);
 
+typedef struct ncore_ccu_reg {
+			char name[50];
+			uint32_t base;
+			uint32_t size;
+		} ncore_ccu_reg_t;
 
-#define NCORE_CCU_OFFSET			0xf7000000
+typedef struct ncore_ccu {
+			uint32_t offset;
+			uint32_t val;
+			uint32_t mask;
+		} ncore_ccu_t;
 
 /* Coherent Sub-System Address Map */
 #define NCORE_CAIU_OFFSET			0x00000
@@ -358,43 +378,49 @@ int ccu_hps_ios_region_enable(int id);
 #define NCORE_NCBU_SIZE				0x01000
 #define NCORE_DIRU_OFFSET			0x80000
 #define NCORE_DIRU_SIZE				0x01000
-#define NCORE_CMIU_OFFSET			0xc0000
+#define NCORE_CMIU_OFFSET			0xC0000
 #define NCORE_CMIU_SIZE				0x01000
-#define NCORE_CSR_OFFSET			0xff000
+#define NCORE_CSR_OFFSET			0xFF000
 #define NCORE_CSADSERO				0x00040
-#define NCORE_CSUIDR				0x00ff8
-#define NCORE_CSIDR				0x00ffc
+#define NCORE_CSUIDR				0x00FF8
+#define NCORE_CSIDR				0x00FFC
+
 /* Directory Unit Register Map */
 #define NCORE_DIRUSFER				0x00010
 #define NCORE_DIRUMRHER				0x00070
 #define NCORE_DIRUSFMCR				0x00080
 #define NCORE_DIRUSFMAR				0x00084
+
 /* Coherent Agent Interface Unit Register Map */
-#define NCORE_CAIUIDR				0x00ffc
+#define NCORE_CAIUIDR				0x00FFC
+
 /* Snoop Enable Register */
 #define NCORE_DIRUCASER0			0x00040
 #define NCORE_DIRUCASER1			0x00044
 #define NCORE_DIRUCASER2			0x00048
-#define NCORE_DIRUCASER3			0x0004c
+#define NCORE_DIRUCASER3			0x0004C
 #define NCORE_CSADSER0				0x00040
 #define NCORE_CSADSER1				0x00044
 #define NCORE_CSADSER2				0x00048
-#define NCORE_CSADSER3				0x0004c
+#define NCORE_CSADSER3				0x0004C
+
 /* Protocols Definition */
 #define ACE_W_DVM				0
 #define ACE_L_W_DVM				1
 #define ACE_WO_DVM				2
 #define ACE_L_WO_DVM				3
-/* Bypass OC Ram Firewall */
+
+/* Bypass OCRAM Firewall */
 #define NCORE_FW_OCRAM_BLK_BASE			0x100200
 #define NCORE_FW_OCRAM_BLK_CGF1			0x04
 #define NCORE_FW_OCRAM_BLK_CGF2			0x08
-#define NCORE_FW_OCRAM_BLK_CGF3			0x0c
+#define NCORE_FW_OCRAM_BLK_CGF3			0x0C
 #define NCORE_FW_OCRAM_BLK_CGF4			0x10
 #define OCRAM_PRIVILEGED_MASK			BIT(29)
 #define OCRAM_SECURE_MASK			BIT(30)
+
 /* Macros */
-#define NCORE_CCU_REG(base)			(NCORE_CCU_OFFSET + (base))
+#define NCORE_CCU_REG(base)			(SOCFPGA_CCU_NOC_REG_BASE + (base))
 #define NCORE_CCU_CSR(reg)			(NCORE_CCU_REG(NCORE_CSR_OFFSET)\
 						+ (reg))
 #define NCORE_CCU_DIR(reg)			(NCORE_CCU_REG(NCORE_DIRU_OFFSET)\
@@ -407,14 +433,14 @@ int ccu_hps_ios_region_enable(int id);
 						+ NCORE_CAIU_SIZE * (x))
 #define COH_CPU0_BYPASS_REG(reg)		(NCORE_CCU_REG(NCORE_FW_OCRAM_BLK_BASE)\
 						+ (reg))
-#define CSUIDR_NUM_CMI(x)			(((x) & 0x3f000000) >> 24)
-#define CSUIDR_NUM_DIR(x)			(((x) & 0x003f0000) >> 16)
-#define CSUIDR_NUM_NCB(x)			(((x) & 0x00003f00) >> 8)
-#define CSUIDR_NUM_CAI(x)			(((x) & 0x0000007f) >> 0)
-#define CSIDR_NUM_SF(x)				(((x) & 0x007c0000) >> 18)
+#define CSUIDR_NUM_CMI(x)			(((x) & 0x3F000000) >> 24)
+#define CSUIDR_NUM_DIR(x)			(((x) & 0x003F0000) >> 16)
+#define CSUIDR_NUM_NCB(x)			(((x) & 0x00003F00) >> 8)
+#define CSUIDR_NUM_CAI(x)			(((x) & 0x0000007F) >> 0)
+#define CSIDR_NUM_SF(x)				(((x) & 0x007C0000) >> 18)
 #define SNOOP_FILTER_ID(x)			(((x) << 16))
 #define CACHING_AGENT_BIT(x)			(((x) & 0x08000) >> 15)
-#define CACHING_AGENT_TYPE(x)			(((x) & 0xf0000) >> 16)
+#define CACHING_AGENT_TYPE(x)			(((x) & 0xF0000) >> 16)
 
 typedef struct coh_ss_id {
 	uint8_t num_coh_mem;
@@ -427,5 +453,6 @@ typedef struct coh_ss_id {
 uint32_t init_ncore_ccu(void);
 void ncore_enable_ocram_firewall(void);
 void setup_smmu_stream_id(void);
+int flush_l3_dcache(void);
 
 #endif
diff --git a/plat/intel/soc/common/drivers/ddr/ddr.c b/plat/intel/soc/common/drivers/ddr/ddr.c
index 188302f7..62f03ef2 100644
--- a/plat/intel/soc/common/drivers/ddr/ddr.c
+++ b/plat/intel/soc/common/drivers/ddr/ddr.c
@@ -7,6 +7,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <common/debug.h>
+#include <drivers/delay_timer.h>
 #include "ddr.h"
 #include <lib/mmio.h>
 #include "socfpga_handoff.h"
@@ -340,3 +341,143 @@ int ddr_init(void)
 	NOTICE("DDR init successfully\n");
 	return status;
 }
+
+int ddr_config_scrubber(phys_addr_t umctl2_base, enum ddr_type umctl2_type)
+{
+	uint32_t temp[9] = {0};
+	int ret = 0;
+
+	/* Write default value to prevent scrubber stop due to lower power */
+	mmio_write_32(0, umctl2_base + DDR4_PWRCTL_OFFSET);
+
+	/* To backup user configurations in temp array */
+	temp[0] = mmio_read_32(umctl2_base + DDR4_SBRCTL_OFFSET);
+	temp[1] = mmio_read_32(umctl2_base + DDR4_SBRWDATA0_OFFSET);
+	temp[2] = mmio_read_32(umctl2_base + DDR4_SBRSTART0_OFFSET);
+	if (umctl2_type == DDR_TYPE_DDR4) {
+		temp[3] = mmio_read_32(umctl2_base + DDR4_SBRWDATA1_OFFSET);
+		temp[4] = mmio_read_32(umctl2_base + DDR4_SBRSTART1_OFFSET);
+	}
+	temp[5] = mmio_read_32(umctl2_base + DDR4_SBRRANGE0_OFFSET);
+	temp[6] = mmio_read_32(umctl2_base + DDR4_SBRRANGE1_OFFSET);
+	temp[7] = mmio_read_32(umctl2_base + DDR4_ECCCFG0_OFFSET);
+	temp[8] = mmio_read_32(umctl2_base + DDR4_ECCCFG1_OFFSET);
+
+	if (umctl2_type != DDR_TYPE_DDR4) {
+		/* Lock ECC region, ensure this regions is not being accessed */
+		mmio_setbits_32(umctl2_base + DDR4_ECCCFG1_OFFSET,
+			     LPDDR4_ECCCFG1_ECC_REGIONS_PARITY_LOCK);
+	}
+	/* Disable input traffic per port */
+	mmio_clrbits_32(umctl2_base + DDR4_PCTRL0_OFFSET, DDR4_PCTRL0_PORT_EN);
+	/* Disables scrubber */
+	mmio_clrbits_32(umctl2_base + DDR4_SBRCTL_OFFSET, DDR4_SBRCTL_SCRUB_EN);
+	/* Polling all scrub writes data have been sent */
+	ret = poll_idle_status((umctl2_base + DDR4_SBRSTAT_OFFSET),
+			       DDR4_SBRSTAT_SCRUB_BUSY, true, 5000);
+
+	if (ret) {
+		INFO("%s: Timeout while waiting for", __func__);
+		INFO(" sending all scrub data\n");
+		return ret;
+	}
+
+	/* LPDDR4 supports inline ECC only */
+	if (umctl2_type != DDR_TYPE_DDR4) {
+		/*
+		 * Setting all regions for protected, this is required for
+		 * srubber to init whole LPDDR4 expect ECC region
+		 */
+		mmio_write_32(((ONE_EIGHT <<
+		       LPDDR4_ECCCFG0_ECC_REGION_MAP_GRANU_SHIFT) |
+		       (ALL_PROTECTED << LPDDR4_ECCCFG0_ECC_REGION_MAP_SHIFT)),
+		       umctl2_base + DDR4_ECCCFG0_OFFSET);
+	}
+
+	/* Scrub_burst = 1, scrub_mode = 1(performs writes) */
+	mmio_write_32(DDR4_SBRCTL_SCRUB_BURST_1 | DDR4_SBRCTL_SCRUB_WRITE,
+	       umctl2_base + DDR4_SBRCTL_OFFSET);
+
+	/* Wipe DDR content after calibration */
+	ret = ddr_zerofill_scrubber(umctl2_base, umctl2_type);
+	if (ret) {
+		ERROR("Failed to clear DDR content\n");
+	}
+
+	/* Polling all scrub writes data have been sent */
+	ret = poll_idle_status((umctl2_base + DDR4_SBRSTAT_OFFSET),
+			       DDR4_SBRSTAT_SCRUB_BUSY, true, 5000);
+	if (ret) {
+		INFO("%s: Timeout while waiting for", __func__);
+		INFO(" sending all scrub data\n");
+		return ret;
+	}
+
+	/* Disables scrubber */
+	mmio_clrbits_32(umctl2_base + DDR4_SBRCTL_OFFSET, DDR4_SBRCTL_SCRUB_EN);
+
+	/* Restore user configurations */
+	mmio_write_32(temp[0], umctl2_base + DDR4_SBRCTL_OFFSET);
+	mmio_write_32(temp[1], umctl2_base + DDR4_SBRWDATA0_OFFSET);
+	mmio_write_32(temp[2], umctl2_base + DDR4_SBRSTART0_OFFSET);
+	if (umctl2_type == DDR_TYPE_DDR4) {
+		mmio_write_32(temp[3], umctl2_base + DDR4_SBRWDATA1_OFFSET);
+		mmio_write_32(temp[4], umctl2_base + DDR4_SBRSTART1_OFFSET);
+	}
+	mmio_write_32(temp[5], umctl2_base + DDR4_SBRRANGE0_OFFSET);
+	mmio_write_32(temp[6], umctl2_base + DDR4_SBRRANGE1_OFFSET);
+	mmio_write_32(temp[7], umctl2_base + DDR4_ECCCFG0_OFFSET);
+	mmio_write_32(temp[8], umctl2_base + DDR4_ECCCFG1_OFFSET);
+
+	/* Enables ECC scrub on scrubber */
+	if (!(mmio_read_32(umctl2_base + DDR4_SBRCTL_OFFSET) & DDR4_SBRCTL_SCRUB_WRITE)) {
+		/* Enables scrubber */
+		mmio_setbits_32(umctl2_base + DDR4_SBRCTL_OFFSET, DDR4_SBRCTL_SCRUB_EN);
+	}
+
+	return 0;
+}
+
+int ddr_zerofill_scrubber(phys_addr_t umctl2_base, enum ddr_type umctl2_type)
+{
+	int ret = 0;
+
+	/* Zeroing whole DDR */
+	mmio_write_32(0, umctl2_base + DDR4_SBRWDATA0_OFFSET);
+	mmio_write_32(0, umctl2_base + DDR4_SBRSTART0_OFFSET);
+	if (umctl2_type == DDR_TYPE_DDR4) {
+		mmio_write_32(0, umctl2_base + DDR4_SBRWDATA1_OFFSET);
+		mmio_write_32(0, umctl2_base + DDR4_SBRSTART1_OFFSET);
+	}
+	mmio_write_32(0, umctl2_base + DDR4_SBRRANGE0_OFFSET);
+	mmio_write_32(0, umctl2_base + DDR4_SBRRANGE1_OFFSET);
+
+	NOTICE("Enabling scrubber (zeroing whole DDR) ...\n");
+
+	/* Enables scrubber */
+	mmio_setbits_32(umctl2_base + DDR4_SBRCTL_OFFSET, DDR4_SBRCTL_SCRUB_EN);
+	/* Polling all scrub writes commands have been sent */
+	ret = poll_idle_status((umctl2_base + DDR4_SBRSTAT_OFFSET),
+			       DDR4_SBRSTAT_SCRUB_DONE, true, 5000);
+	if (ret) {
+		INFO("%s: Timeout while waiting for", __func__);
+		INFO(" sending all scrub commands\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match, uint32_t delay_ms)
+{
+	int time_out = delay_ms;
+
+	while (time_out-- > 0) {
+
+		if ((mmio_read_32(addr) & mask) == match) {
+			return 0;
+		}
+		udelay(1000);
+	}
+	return -ETIMEDOUT;
+}
diff --git a/plat/intel/soc/common/drivers/ddr/ddr.h b/plat/intel/soc/common/drivers/ddr/ddr.h
index 416b64e8..e50cda83 100644
--- a/plat/intel/soc/common/drivers/ddr/ddr.h
+++ b/plat/intel/soc/common/drivers/ddr/ddr.h
@@ -10,6 +10,28 @@
 #include <lib/mmio.h>
 #include "socfpga_handoff.h"
 
+enum ddr_type {
+	DDR_TYPE_LPDDR4_0,
+	DDR_TYPE_LPDDR4_1,
+	DDR_TYPE_DDR4,
+	DDR_TYPE_LPDDR5_0,
+	DDR_TYPE_LPDDR5_1,
+	DDR_TYPE_DDR5,
+	DDR_TYPE_UNKNOWN
+};
+
+/* Region size for ECCCFG0.ecc_region_map */
+enum region_size {
+	ONE_EIGHT,
+	ONE_SIXTEENTH,
+	ONE_THIRTY_SECOND,
+	ONE_SIXTY_FOURTH
+};
+
+/* DATATYPE DEFINATION */
+typedef unsigned long long phys_addr_t;
+typedef unsigned long long phys_size_t;
+
 /* MACRO DEFINATION */
 #define IO96B_0_REG_BASE				0x18400000
 #define IO96B_1_REG_BASE				0x18800000
@@ -86,6 +108,34 @@
 
 #define IOSSM_MB_WRITE(addr, data)			mmio_write_32(addr, data)
 
+/* DDR4 Register */
+#define DDR4_PWRCTL_OFFSET				0x30
+#define DDR4_SBRCTL_OFFSET				0x0F24
+#define DDR4_SBRSTAT_OFFSET				0x0F28
+#define DDR4_SBRWDATA0_OFFSET				0x0F2C
+#define DDR4_SBRSTART0_OFFSET				0x0F38
+#define DDR4_SBRWDATA1_OFFSET				0x0F30
+#define DDR4_SBRSTART1_OFFSET				0x0F3C
+#define DDR4_SBRRANGE0_OFFSET				0x0F40
+#define DDR4_SBRRANGE1_OFFSET				0x0F44
+#define DDR4_ECCCFG0_OFFSET				0x70
+#define DDR4_ECCCFG1_OFFSET				0x74
+#define DDR4_PCTRL0_OFFSET				0x0490
+
+#define LPDDR4_ECCCFG0_ECC_REGION_MAP_GRANU_SHIFT	30
+#define ALL_PROTECTED					0x7F
+#define LPDDR4_ECCCFG0_ECC_REGION_MAP_SHIFT		8
+
+
+
+#define LPDDR4_ECCCFG1_ECC_REGIONS_PARITY_LOCK		BIT(4)
+#define DDR4_PCTRL0_PORT_EN				BIT(0)
+#define DDR4_SBRCTL_SCRUB_EN				BIT(0)
+#define DDR4_SBRSTAT_SCRUB_BUSY				BIT(0)
+#define DDR4_SBRCTL_SCRUB_BURST_1			BIT(4)
+#define DDR4_SBRCTL_SCRUB_WRITE				BIT(2)
+#define DDR4_SBRSTAT_SCRUB_DONE				BIT(1)
+
 /* FUNCTION DEFINATION */
 int ddr_calibration_check(void);
 
@@ -109,4 +159,10 @@ void ddr_enable_firewall(void);
 
 bool is_ddr_init_in_progress(void);
 
+int ddr_zerofill_scrubber(phys_addr_t umctl2_base, enum ddr_type umctl2_type);
+
+int ddr_config_scrubber(phys_addr_t umctl2_base, enum ddr_type umctl2_type);
+
+int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match, uint32_t delay_ms);
+
 #endif
diff --git a/plat/intel/soc/common/drivers/nand/nand.c b/plat/intel/soc/common/drivers/nand/nand.c
index c6acbe3b..7fd955a5 100644
--- a/plat/intel/soc/common/drivers/nand/nand.c
+++ b/plat/intel/soc/common/drivers/nand/nand.c
@@ -38,18 +38,12 @@ static void nand_pinmux_config(void)
 	mmio_write_32(SOCFPGA_PINMUX(PIN12SEL), SOCFPGA_PINMUX_SEL_NAND);
 	mmio_write_32(SOCFPGA_PINMUX(PIN13SEL), SOCFPGA_PINMUX_SEL_NAND);
 	mmio_write_32(SOCFPGA_PINMUX(PIN14SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN16SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN17SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN18SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN19SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN20SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN21SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN22SEL), SOCFPGA_PINMUX_SEL_NAND);
-	mmio_write_32(SOCFPGA_PINMUX(PIN23SEL), SOCFPGA_PINMUX_SEL_NAND);
 }
 
 int nand_init(handoff *hoff_ptr)
 {
+	(void)(hoff_ptr);
+
 	/* NAND pin mux configuration */
 	nand_pinmux_config();
 
diff --git a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
index da8a8bde..18aa48e0 100644
--- a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
+++ b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
@@ -14,6 +14,7 @@
 
 #include "cadence_qspi.h"
 #include "socfpga_plat_def.h"
+#include "wdt/watchdog.h"
 
 #define LESS(a, b)   (((a) < (b)) ? (a) : (b))
 #define MORE(a, b)   (((a) > (b)) ? (a) : (b))
@@ -634,8 +635,9 @@ int cad_qspi_indirect_page_bound_write(uint32_t offset,
 int cad_qspi_read_bank(uint8_t *buffer, uint32_t offset, uint32_t size)
 {
 	int status;
-	uint32_t read_count = 0, *read_data;
+	uint32_t read_count = 0;
 	int level = 1, count = 0, i;
+	uint8_t *read_data;
 
 	status = cad_qspi_indirect_read_start_bank(offset, size);
 
@@ -647,12 +649,15 @@ int cad_qspi_read_bank(uint8_t *buffer, uint32_t offset, uint32_t size)
 			level = CAD_QSPI_SRAMFILL_INDRDPART(
 				mmio_read_32(CAD_QSPI_OFFSET +
 					CAD_QSPI_SRAMFILL));
-			read_data = (uint32_t *)(buffer + read_count);
+			read_data = (uint8_t *)(buffer + read_count);
 			for (i = 0; i < level; ++i)
-				*read_data++ = mmio_read_32(CAD_QSPIDATA_OFST);
+				*read_data++ = mmio_read_8(CAD_QSPIDATA_OFST);
 
-			read_count += level * sizeof(uint32_t);
+			read_count += level * sizeof(uint8_t);
 			count++;
+#if ARM_LINUX_KERNEL_AS_BL33
+			watchdog_sw_rst();
+#endif
 		} while (level > 0);
 	}
 
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.c b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
index 8666f54c..62698a90 100644
--- a/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,52 +18,26 @@
 #include <lib/mmio.h>
 #include <lib/utils.h>
 
-#include "agilex5_pinmux.h"
 #include "sdmmc.h"
+#include "socfpga_mailbox.h"
+#include "wdt/watchdog.h"
 
 static const struct mmc_ops *ops;
 static unsigned int mmc_ocr_value;
-static struct mmc_csd_emmc mmc_csd;
-static struct sd_switch_status sd_switch_func_status;
-static unsigned char mmc_ext_csd[512] __aligned(16);
 static unsigned int mmc_flags;
-static struct mmc_device_info *mmc_dev_info;
 static unsigned int rca;
-static unsigned int scr[2]__aligned(16) = { 0 };
 
 extern const struct mmc_ops cdns_sdmmc_ops;
 extern struct cdns_sdmmc_params cdns_params;
 extern struct cdns_sdmmc_combo_phy sdmmc_combo_phy_reg;
 extern struct cdns_sdmmc_sdhc sdmmc_sdhc_reg;
 
-static bool is_cmd23_enabled(void)
+bool is_cmd23_enabled(void)
 {
 	return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
 }
 
-static bool is_sd_cmd6_enabled(void)
-{
-	return ((mmc_flags & MMC_FLAG_SD_CMD6) != 0U);
-}
-
-/* TODO: Will romove once ATF driver is developed */
-void sdmmc_pin_config(void)
-{
-	/* temp use base + addr. Official must change to common method */
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x00, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x04, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x08, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x0C, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x10, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x14, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x18, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x1C, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x20, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x24, 0x0);
-	mmio_write_32(AGX5_PINMUX_PIN0SEL+0x28, 0x0);
-}
-
-static int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
+int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
 			unsigned int r_type, unsigned int *r_data)
 {
 	struct mmc_cmd cmd;
@@ -92,7 +67,7 @@ static int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
 	return ret;
 }
 
-static int sdmmc_device_state(void)
+int sdmmc_device_state(void)
 {
 	int retries = DEFAULT_SDMMC_MAX_RETRIES;
 	unsigned int resp_data[4];
@@ -123,520 +98,12 @@ static int sdmmc_device_state(void)
 	return MMC_GET_STATE(resp_data[0]);
 }
 
-static int sdmmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
-{
-	int ret;
-
-	ret = sdmmc_send_cmd(MMC_CMD(6),
-			   EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) |
-			   EXTCSD_VALUE(value) | EXTCSD_CMD_SET_NORMAL,
-			   MMC_RESPONSE_R1B, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	do {
-		ret = sdmmc_device_state();
-		if (ret < 0) {
-			return ret;
-		}
-	} while (ret == MMC_STATE_PRG);
-
-	return 0;
-}
-
-static int sdmmc_mmc_sd_switch(unsigned int bus_width)
-{
-	int ret;
-	int retries = DEFAULT_SDMMC_MAX_RETRIES;
-	unsigned int bus_width_arg = 0;
-
-	/* CMD55: Application Specific Command */
-	ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
-			   MMC_RESPONSE_R5, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	ret = ops->prepare(0, (uintptr_t)&scr, sizeof(scr));
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* ACMD51: SEND_SCR */
-	do {
-		ret = sdmmc_send_cmd(MMC_ACMD(51), 0, MMC_RESPONSE_R1, NULL);
-		if ((ret != 0) && (retries == 0)) {
-			ERROR("ACMD51 failed after %d retries (ret=%d)\n",
-			      DEFAULT_SDMMC_MAX_RETRIES, ret);
-			return ret;
-		}
-
-		retries--;
-	} while (ret != 0);
-
-	ret = ops->read(0, (uintptr_t)&scr, sizeof(scr));
-	if (ret != 0) {
-		return ret;
-	}
-
-	if (((scr[0] & SD_SCR_BUS_WIDTH_4) != 0U) &&
-	    (bus_width == MMC_BUS_WIDTH_4)) {
-		bus_width_arg = 2;
-	}
-
-	/* CMD55: Application Specific Command */
-	ret = sdmmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
-			   MMC_RESPONSE_R5, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* ACMD6: SET_BUS_WIDTH */
-	ret = sdmmc_send_cmd(MMC_ACMD(6), bus_width_arg, MMC_RESPONSE_R1, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	do {
-		ret = sdmmc_device_state();
-		if (ret < 0) {
-			return ret;
-		}
-	} while (ret == MMC_STATE_PRG);
-
-	return 0;
-}
-
-static int sdmmc_set_ios(unsigned int clk, unsigned int bus_width)
-{
-	int ret;
-	unsigned int width = bus_width;
-
-	if (mmc_dev_info->mmc_dev_type != MMC_IS_EMMC) {
-		if (width == MMC_BUS_WIDTH_8) {
-			WARN("Wrong bus config for SD-card, force to 4\n");
-			width = MMC_BUS_WIDTH_4;
-		}
-		ret = sdmmc_mmc_sd_switch(width);
-		if (ret != 0) {
-			return ret;
-		}
-	} else if (mmc_csd.spec_vers == 4U) {
-		ret = sdmmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH,
-				      (unsigned int)width);
-		if (ret != 0) {
-			return ret;
-		}
-	} else {
-		VERBOSE("Wrong MMC type or spec version\n");
-	}
-
-	return ops->set_ios(clk, width);
-}
-
-static int sdmmc_fill_device_info(void)
-{
-	unsigned long long c_size;
-	unsigned int speed_idx;
-	unsigned int nb_blocks;
-	unsigned int freq_unit;
-	int ret = 0;
-	struct mmc_csd_sd_v2 *csd_sd_v2;
-
-	switch (mmc_dev_info->mmc_dev_type) {
-	case MMC_IS_EMMC:
-		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
-
-		ret = ops->prepare(0, (uintptr_t)&mmc_ext_csd,
-				   sizeof(mmc_ext_csd));
-		if (ret != 0) {
-			return ret;
-		}
-
-		/* MMC CMD8: SEND_EXT_CSD */
-		ret = sdmmc_send_cmd(MMC_CMD(8), 0, MMC_RESPONSE_R1, NULL);
-		if (ret != 0) {
-			return ret;
-		}
-
-		ret = ops->read(0, (uintptr_t)&mmc_ext_csd,
-				sizeof(mmc_ext_csd));
-		if (ret != 0) {
-			return ret;
-		}
-
-		do {
-			ret = sdmmc_device_state();
-			if (ret < 0) {
-				return ret;
-			}
-		} while (ret != MMC_STATE_TRAN);
-
-		nb_blocks = (mmc_ext_csd[CMD_EXTCSD_SEC_CNT] << 0) |
-			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 1] << 8) |
-			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 2] << 16) |
-			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 3] << 24);
-
-		mmc_dev_info->device_size = (unsigned long long)nb_blocks *
-			mmc_dev_info->block_size;
-
-		break;
-
-	case MMC_IS_SD:
-		/*
-		 * Use the same mmc_csd struct, as required fields here
-		 * (READ_BL_LEN, C_SIZE, CSIZE_MULT) are common with eMMC.
-		 */
-		mmc_dev_info->block_size = BIT_32(mmc_csd.read_bl_len);
-
-		c_size = ((unsigned long long)mmc_csd.c_size_high << 2U) |
-			 (unsigned long long)mmc_csd.c_size_low;
-		assert(c_size != 0xFFFU);
-
-		mmc_dev_info->device_size = (c_size + 1U) *
-					    BIT_64(mmc_csd.c_size_mult + 2U) *
-					    mmc_dev_info->block_size;
-
-		break;
-
-	case MMC_IS_SD_HC:
-		assert(mmc_csd.csd_structure == 1U);
-
-		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
-
-		/* Need to use mmc_csd_sd_v2 struct */
-		csd_sd_v2 = (struct mmc_csd_sd_v2 *)&mmc_csd;
-		c_size = ((unsigned long long)csd_sd_v2->c_size_high << 16) |
-			 (unsigned long long)csd_sd_v2->c_size_low;
-
-		mmc_dev_info->device_size = (c_size + 1U) << SDMMC_MULT_BY_512K_SHIFT;
-
-		break;
-
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	if (ret < 0) {
-		return ret;
-	}
-
-	speed_idx = (mmc_csd.tran_speed & CSD_TRAN_SPEED_MULT_MASK) >>
-			 CSD_TRAN_SPEED_MULT_SHIFT;
-
-	assert(speed_idx > 0U);
-
-	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
-		mmc_dev_info->max_bus_freq = tran_speed_base[speed_idx];
-	} else {
-		mmc_dev_info->max_bus_freq = sd_tran_speed_base[speed_idx];
-	}
-
-	freq_unit = mmc_csd.tran_speed & CSD_TRAN_SPEED_UNIT_MASK;
-	while (freq_unit != 0U) {
-		mmc_dev_info->max_bus_freq *= 10U;
-		--freq_unit;
-	}
-
-	mmc_dev_info->max_bus_freq *= 10000U;
-
-	return 0;
-}
-
-static int sdmmc_sd_switch(unsigned int mode, unsigned char group,
-		     unsigned char func)
-{
-	unsigned int group_shift = (group - 1U) * 4U;
-	unsigned int group_mask = GENMASK(group_shift + 3U,  group_shift);
-	unsigned int arg;
-	int ret;
-
-	ret = ops->prepare(0, (uintptr_t)&sd_switch_func_status,
-			   sizeof(sd_switch_func_status));
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* MMC CMD6: SWITCH_FUNC */
-	arg = mode | SD_SWITCH_ALL_GROUPS_MASK;
-	arg &= ~group_mask;
-	arg |= func << group_shift;
-	ret = sdmmc_send_cmd(MMC_CMD(6), arg, MMC_RESPONSE_R1, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	return ops->read(0, (uintptr_t)&sd_switch_func_status,
-			 sizeof(sd_switch_func_status));
-}
-
-static int sdmmc_sd_send_op_cond(void)
-{
-	int n;
-	unsigned int resp_data[4];
-
-	for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
-		int ret;
-
-		/* CMD55: Application Specific Command */
-		ret = sdmmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R1, NULL);
-		if (ret != 0) {
-			return ret;
-		}
-
-		/* ACMD41: SD_SEND_OP_COND */
-		ret = sdmmc_send_cmd(MMC_ACMD(41), OCR_HCS |
-			mmc_dev_info->ocr_voltage, MMC_RESPONSE_R3,
-			&resp_data[0]);
-		if (ret != 0) {
-			return ret;
-		}
-
-		if ((resp_data[0] & OCR_POWERUP) != 0U) {
-			mmc_ocr_value = resp_data[0];
-
-			if ((mmc_ocr_value & OCR_HCS) != 0U) {
-				mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
-			} else {
-				mmc_dev_info->mmc_dev_type = MMC_IS_SD;
-			}
-
-			return 0;
-		}
-
-		mdelay(10);
-	}
-
-	ERROR("ACMD41 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
-
-	return -EIO;
-}
-
-static int sdmmc_reset_to_idle(void)
-{
-	int ret;
-
-	/* CMD0: reset to IDLE */
-	ret = sdmmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	mdelay(2);
-
-	return 0;
-}
-
-static int sdmmc_send_op_cond(void)
-{
-	int ret, n;
-	unsigned int resp_data[4];
-
-	ret = sdmmc_reset_to_idle();
-	if (ret != 0) {
-		return ret;
-	}
-
-	for (n = 0; n < SEND_SDMMC_OP_COND_MAX_RETRIES; n++) {
-		ret = sdmmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
-				   OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
-				   MMC_RESPONSE_R3, &resp_data[0]);
-		if (ret != 0) {
-			return ret;
-		}
-
-		if ((resp_data[0] & OCR_POWERUP) != 0U) {
-			mmc_ocr_value = resp_data[0];
-			return 0;
-		}
-
-		mdelay(10);
-	}
-
-	ERROR("CMD1 failed after %d retries\n", SEND_SDMMC_OP_COND_MAX_RETRIES);
-
-	return -EIO;
-}
-
-static int sdmmc_enumerate(unsigned int clk, unsigned int bus_width)
-{
-	int ret;
-	unsigned int resp_data[4];
-
-	ops->init();
-
-	ret = sdmmc_reset_to_idle();
-	if (ret != 0) {
-		return ret;
-	}
-
-	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
-		ret = sdmmc_send_op_cond();
-	} else {
-		/* CMD8: Send Interface Condition Command */
-		ret = sdmmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
-				   MMC_RESPONSE_R5, &resp_data[0]);
-
-		if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
-			ret = sdmmc_sd_send_op_cond();
-		}
-	}
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* CMD2: Card Identification */
-	ret = sdmmc_send_cmd(MMC_CMD(2), 0, MMC_RESPONSE_R2, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	/* CMD3: Set Relative Address */
-	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
-		rca = MMC_FIX_RCA;
-		ret = sdmmc_send_cmd(MMC_CMD(3), rca << RCA_SHIFT_OFFSET,
-				   MMC_RESPONSE_R1, NULL);
-		if (ret != 0) {
-			return ret;
-		}
-	} else {
-		ret = sdmmc_send_cmd(MMC_CMD(3), 0,
-				   MMC_RESPONSE_R6, &resp_data[0]);
-		if (ret != 0) {
-			return ret;
-		}
-
-		rca = (resp_data[0] & 0xFFFF0000U) >> 16;
-	}
-
-	/* CMD9: CSD Register */
-	ret = sdmmc_send_cmd(MMC_CMD(9), rca << RCA_SHIFT_OFFSET,
-			   MMC_RESPONSE_R2, &resp_data[0]);
-	if (ret != 0) {
-		return ret;
-	}
-
-	memcpy(&mmc_csd, &resp_data, sizeof(resp_data));
-
-	/* CMD7: Select Card */
-	ret = sdmmc_send_cmd(MMC_CMD(7), rca << RCA_SHIFT_OFFSET,
-			   MMC_RESPONSE_R1, NULL);
-	if (ret != 0) {
-		return ret;
-	}
-
-	do {
-		ret = sdmmc_device_state();
-		if (ret < 0) {
-			return ret;
-		}
-	} while (ret != MMC_STATE_TRAN);
-
-	ret = sdmmc_set_ios(clk, bus_width);
-	if (ret != 0) {
-		return ret;
-	}
-
-	ret = sdmmc_fill_device_info();
-	if (ret != 0) {
-		return ret;
-	}
-
-	if (is_sd_cmd6_enabled() &&
-	    (mmc_dev_info->mmc_dev_type == MMC_IS_SD_HC)) {
-		/* Try to switch to High Speed Mode */
-		ret = sdmmc_sd_switch(SD_SWITCH_FUNC_CHECK, 1U, 1U);
-		if (ret != 0) {
-			return ret;
-		}
-
-		if ((sd_switch_func_status.support_g1 & BIT(9)) == 0U) {
-			/* High speed not supported, keep default speed */
-			return 0;
-		}
-
-		ret = sdmmc_sd_switch(SD_SWITCH_FUNC_SWITCH, 1U, 1U);
-		if (ret != 0) {
-			return ret;
-		}
-
-		if ((sd_switch_func_status.sel_g2_g1 & 0x1U) == 0U) {
-			/* Cannot switch to high speed, keep default speed */
-			return 0;
-		}
-
-		mmc_dev_info->max_bus_freq = 50000000U;
-		ret = ops->set_ios(clk, bus_width);
-	}
-
-	return ret;
-}
-
 size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size)
 {
-	int ret;
-	unsigned int cmd_idx, cmd_arg;
-
-	assert((ops != NULL) &&
-	       (ops->read != NULL) &&
-	       (size != 0U) &&
-	       ((size & MMC_BLOCK_MASK) == 0U));
-
-	ret = ops->prepare(lba, buf, size);
-	if (ret != 0) {
-		return 0;
-	}
-
-	if (is_cmd23_enabled()) {
-		/* Set block count */
-		ret = sdmmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
-				   MMC_RESPONSE_R1, NULL);
-		if (ret != 0) {
-			return 0;
-		}
-
-		cmd_idx = MMC_CMD(18);
-	} else {
-		if (size > MMC_BLOCK_SIZE) {
-			cmd_idx = MMC_CMD(18);
-		} else {
-			cmd_idx = MMC_CMD(17);
-		}
-	}
+	mmc_read_blocks(lba, buf, size);
 
-	if (((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) &&
-	    (mmc_dev_info->mmc_dev_type != MMC_IS_SD_HC)) {
-		cmd_arg = lba * MMC_BLOCK_SIZE;
-	} else {
-		cmd_arg = lba;
-	}
-
-	ret = sdmmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
-	if (ret != 0) {
-		return 0;
-	}
-
-	ret = ops->read(lba, buf, size);
-	if (ret != 0) {
-		return 0;
-	}
-
-	/* Wait buffer empty */
-	do {
-		ret = sdmmc_device_state();
-		if (ret < 0) {
-			return 0;
-		}
-	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_DATA));
-
-	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
-		ret = sdmmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
-		if (ret != 0) {
-			return 0;
-		}
-	}
+	/* Restart watchdog for reading each chunk byte */
+	watchdog_sw_rst();
 
 	return size;
 }
@@ -707,63 +174,3 @@ size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size)
 
 	return size;
 }
-
-int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
-	     unsigned int width, unsigned int flags,
-	     struct mmc_device_info *device_info)
-{
-	assert((ops_ptr != NULL) &&
-	       (ops_ptr->init != NULL) &&
-	       (ops_ptr->send_cmd != NULL) &&
-	       (ops_ptr->set_ios != NULL) &&
-	       (ops_ptr->prepare != NULL) &&
-	       (ops_ptr->read != NULL) &&
-	       (ops_ptr->write != NULL) &&
-	       (device_info != NULL) &&
-	       (clk != 0) &&
-	       ((width == MMC_BUS_WIDTH_1) ||
-		(width == MMC_BUS_WIDTH_4) ||
-		(width == MMC_BUS_WIDTH_8) ||
-		(width == MMC_BUS_WIDTH_DDR_4) ||
-		(width == MMC_BUS_WIDTH_DDR_8)));
-
-	ops = ops_ptr;
-	mmc_flags = flags;
-	mmc_dev_info = device_info;
-
-	return sdmmc_enumerate(clk, width);
-}
-
-int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params, struct mmc_device_info *info)
-{
-	int result = 0;
-
-	/* SDMMC pin mux configuration */
-	sdmmc_pin_config();
-	cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
-	result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg);
-	if (result < 0) {
-		return result;
-	}
-
-	assert((params != NULL) &&
-	       ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
-	       ((params->desc_base & MMC_BLOCK_MASK) == 0) &&
-	       ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
-		   ((params->reg_pinmux & MMC_BLOCK_MASK) == 0) &&
-		   ((params->reg_phy & MMC_BLOCK_MASK) == 0) &&
-	       (params->desc_size > 0) &&
-	       (params->clk_rate > 0) &&
-	       ((params->bus_width == MMC_BUS_WIDTH_1) ||
-		(params->bus_width == MMC_BUS_WIDTH_4) ||
-		(params->bus_width == MMC_BUS_WIDTH_8)));
-
-	memcpy(&cdns_params, params, sizeof(struct cdns_sdmmc_params));
-	cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type;
-	cdns_params.cdn_sdmmc_dev_mode = SD_DS;
-
-	result = sd_or_mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width,
-		params->flags, info);
-
-	return result;
-}
diff --git a/plat/intel/soc/common/drivers/sdmmc/sdmmc.h b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
index 16c6b04b..3f6119c4 100644
--- a/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
+++ b/plat/intel/soc/common/drivers/sdmmc/sdmmc.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,10 +34,12 @@ static const unsigned char sd_tran_speed_base[16] = {
  * @hoff_ptr: Pointer to the hand-off data
  * Return: 0 on success, a negative errno on failure
  */
-int sdmmc_init(handoff *hoff_ptr, struct cdns_sdmmc_params *params,
-	     struct mmc_device_info *info);
-int sd_or_mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
-	     unsigned int width, unsigned int flags,
-	     struct mmc_device_info *device_info);
 void sdmmc_pin_config(void);
+size_t sdmmc_read_blocks(int lba, uintptr_t buf, size_t size);
+size_t sdmmc_write_blocks(int lba, const uintptr_t buf, size_t size);
+int sdmmc_device_state(void);
+bool is_cmd23_enabled(void);
+int sdmmc_send_cmd(unsigned int idx, unsigned int arg,
+			unsigned int r_type, unsigned int *r_data);
+
 #endif
diff --git a/plat/intel/soc/common/drivers/wdt/watchdog.h b/plat/intel/soc/common/drivers/wdt/watchdog.h
index 4ee4cff5..940ebf39 100644
--- a/plat/intel/soc/common/drivers/wdt/watchdog.h
+++ b/plat/intel/soc/common/drivers/wdt/watchdog.h
@@ -7,11 +7,8 @@
 #ifndef CAD_WATCHDOG_H
 #define CAD_WATCHDOG_H
 
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-#define WDT_BASE			(0x10D00200)
-#else
-#define WDT_BASE			(0xFFD00200)
-#endif
+#include "socfpga_plat_def.h"
+
 #define WDT_REG_SIZE_OFFSET		(0x4)
 #define WDT_MIN_CYCLES			(65536)
 #define WDT_PERIOD			(20)
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 49fc567a..a820e414 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,6 +22,18 @@
 #define PLAT_SOCFPGA_AGILEX5			4
 #define SIMICS_RUN				1
 #define MAX_IO_MTD_DEVICES			U(1)
+/* Boot Source configuration
+ * TODO: Shall consider "assert_numeric" in the future
+ */
+#if SOCFPGA_BOOT_SOURCE_NAND
+#define BOOT_SOURCE						BOOT_SOURCE_NAND
+#elif SOCFPGA_BOOT_SOURCE_SDMMC
+#define BOOT_SOURCE						BOOT_SOURCE_SDMMC
+#elif SOCFPGA_BOOT_SOURCE_QSPI
+#define BOOT_SOURCE						BOOT_SOURCE_QSPI
+#else
+#define BOOT_SOURCE						BOOT_SOURCE_SDMMC
+#endif
 
 /* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
 #define PLAT_CPU_RELEASE_ADDR			0xffd12210
@@ -28,21 +41,25 @@
 /* Magic word to indicate L2 reset is completed */
 #define L2_RESET_DONE_STATUS			0x1228E5E7
 
+/* Magic word to differentiate for SMP secondary core boot request */
+#define SMP_SEC_CORE_BOOT_REQ			0x1228E5E8
+
 /* Define next boot image name and offset */
 /* Get non-secure image entrypoint for BL33. Zephyr and Linux */
-#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-
-#ifndef PRELOADED_BL33_BASE
-#define PLAT_NS_IMAGE_OFFSET			0x80200000
-#else
+#ifdef PRELOADED_BL33_BASE
 #define PLAT_NS_IMAGE_OFFSET			PRELOADED_BL33_BASE
-#endif
-#define PLAT_HANDOFF_OFFSET 0x0003F000
-
+#else
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#define PLAT_NS_IMAGE_OFFSET			0x80200000
 #else
 #define PLAT_NS_IMAGE_OFFSET			0x10000000
-#define PLAT_HANDOFF_OFFSET			0xFFE3F000
 #endif
+#endif /* #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5 */
+
+#define PLAT_QSPI_DATA_BASE			(0x3C00000)
+#define PLAT_NAND_DATA_BASE			(0x0200000)
+#define PLAT_SDMMC_DATA_BASE			(0x0)
+
 
 /*******************************************************************************
  * Platform binary types for linking
diff --git a/plat/intel/soc/common/include/socfpga_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
index b2913c7f..7e1d0c0b 100644
--- a/plat/intel/soc/common/include/socfpga_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,12 +11,12 @@
 #define HANDOFF_MAGIC_HEADER			0x424f4f54	/* BOOT */
 #define HANDOFF_MAGIC_PINMUX_SEL		0x504d5558	/* PMUX */
 #define HANDOFF_MAGIC_IOCTLR			0x494f4354	/* IOCT */
-#define HANDOFF_MAGIC_FPGA				0x46504741	/* FPGA */
+#define HANDOFF_MAGIC_FPGA			0x46504741	/* FPGA */
 #define HANDOFF_MAGIC_IODELAY			0x444c4159	/* DLAY */
-#define HANDOFF_MAGIC_CLOCK				0x434c4b53	/* CLKS */
-#define HANDOFF_MAGIC_MISC				0x4d495343	/* MISC */
+#define HANDOFF_MAGIC_CLOCK			0x434c4b53	/* CLKS */
+#define HANDOFF_MAGIC_MISC			0x4d495343	/* MISC */
 #define HANDOFF_MAGIC_PERIPHERAL		0x50455249	/* PERIPHERAL */
-#define HANDOFF_MAGIC_DDR				0x5344524d	/* DDR */
+#define HANDOFF_MAGIC_DDR			0x5344524d	/* DDR */
 
 #include <socfpga_plat_def.h>
 
@@ -126,6 +127,8 @@ typedef struct handoff_t {
 	uint32_t	clock_magic;
 	uint32_t	clock_length;
 	uint32_t	_pad_0x588_0x590[2];
+
+	/* main group PLL */
 	uint32_t	main_pll_nocclk;
 	uint32_t	main_pll_nocdiv;
 	uint32_t	main_pll_pllglob;
@@ -135,6 +138,8 @@ typedef struct handoff_t {
 	uint32_t	main_pll_pllc2;
 	uint32_t	main_pll_pllc3;
 	uint32_t	main_pll_pllm;
+
+	/* peripheral group PLL */
 	uint32_t	per_pll_emacctl;
 	uint32_t	per_pll_gpiodiv;
 	uint32_t	per_pll_pllglob;
@@ -144,29 +149,25 @@ typedef struct handoff_t {
 	uint32_t	per_pll_pllc2;
 	uint32_t	per_pll_pllc3;
 	uint32_t	per_pll_pllm;
+
+	/* control group */
 	uint32_t	alt_emacactr;
 	uint32_t	alt_emacbctr;
 	uint32_t	alt_emacptpctr;
 	uint32_t	alt_gpiodbctr;
-	uint32_t	alt_sdmmcctr;
 	uint32_t	alt_s2fuser0ctr;
 	uint32_t	alt_s2fuser1ctr;
 	uint32_t	alt_psirefctr;
-	/* TODO: Temp added for clk manager. */
-	uint32_t	qspi_clk_khz;
+	uint32_t	alt_usb31ctr;
+	uint32_t	alt_dsuctr;
+	uint32_t	alt_core01ctr;
+	uint32_t	alt_core23ctr;
+	uint32_t	alt_core2ctr;
+	uint32_t	alt_core3ctr;
 	uint32_t	hps_osc_clk_hz;
 	uint32_t	fpga_clk_hz;
-	/* TODO: Temp added for clk manager. */
-	uint32_t	ddr_reset_type;
-	/* TODO: Temp added for clk manager. */
-	uint32_t	hps_status_coldreset;
-	/* TODO: Temp remove due to add in extra handoff data */
-	//uint32_t	_pad_0x604_0x610[3];
+	uint32_t	_pad_0x604_0x610[3];
 #endif
-	/* misc configuration */
-	uint32_t	misc_magic;
-	uint32_t	misc_length;
-	uint32_t	_pad_0x618_0x620[2];
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 	/* peripheral configuration - select */
@@ -179,7 +180,7 @@ typedef struct handoff_t {
 	uint32_t	ddr_magic;
 	uint32_t	ddr_length;
 	uint32_t	_pad_0x1C_0x20[2];
-	uint32_t	ddr_array[4];	/* offset, value */
+	uint32_t	ddr_config;	/* BIT[0]-Dual Port. BIT[1]-Dual EMIF */
 #endif
 } handoff;
 
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 77d3af95..82f9fd3a 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,12 +69,14 @@
 
 /* SEU Commands */
 #define MBOX_CMD_SEU_ERR_READ				0x3C
+#define MBOX_CMD_SAFE_INJECT_SEU_ERR			0x41
 
 /* RSU Commands */
 #define MBOX_GET_SUBPARTITION_TABLE			0x5A
 #define MBOX_RSU_STATUS					0x5B
 #define MBOX_RSU_UPDATE					0x5C
 #define MBOX_HPS_STAGE_NOTIFY				0x5D
+#define MBOX_RSU_GET_DEVICE_INFO			0x74
 
 /* FCS Command */
 #define MBOX_FCS_GET_PROVISION				0x7B
@@ -107,7 +110,7 @@
 #define MBOX_GET_MEASUREMENT				0x183
 
 /* Miscellaneous commands */
-#define MBOX_GET_ROM_PATCH_SHA384	0x1B0
+#define MBOX_GET_ROM_PATCH_SHA384			0x1B0
 
 /* Mailbox Definitions */
 
@@ -196,9 +199,9 @@
 #define RSU_VERSION_ACMF_MASK				0xff00
 
 /* Config Status Macros */
-#define CONFIG_STATUS_WORD_SIZE			16U
-#define CONFIG_STATUS_FW_VER_OFFSET		1
-#define CONFIG_STATUS_FW_VER_MASK		0x00FFFFFF
+#define CONFIG_STATUS_WORD_SIZE				16U
+#define CONFIG_STATUS_FW_VER_OFFSET			1
+#define CONFIG_STATUS_FW_VER_MASK			0x00FFFFFF
 
 /* Data structure */
 
@@ -242,12 +245,19 @@ void mailbox_clear_response(void);
 int intel_mailbox_get_config_status(uint32_t cmd, bool init_done);
 int intel_mailbox_is_fpga_not_ready(void);
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+void intel_smmu_hps_remapper_init(uint64_t *mem);
+int intel_smmu_hps_remapper_config(uint32_t remapper_bypass);
+#endif
+
 int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len);
 int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len);
+int mailbox_rsu_get_device_info(uint32_t *resp_buf, uint32_t resp_buf_len);
 int mailbox_rsu_update(uint32_t *flash_offset);
 int mailbox_hps_stage_notify(uint32_t execution_stage);
 int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf);
 int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf);
 int mailbox_seu_err_status(uint32_t *resp_buf, uint32_t resp_buf_len);
+int mailbox_safe_inject_seu_err(uint32_t *arg, unsigned int len);
 
 #endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index 9d389e3c..fbe18c3e 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +8,6 @@
 #ifndef SOCFPGA_PRIVATE_H
 #define SOCFPGA_PRIVATE_H
 
-#include "socfpga_plat_def.h"
 
 #define EMMC_DESC_SIZE		(1<<20)
 
@@ -24,8 +24,8 @@ typedef enum {
 	BOOT_SOURCE_FPGA = 0,
 	BOOT_SOURCE_SDMMC,
 	BOOT_SOURCE_NAND,
-	BOOT_SOURCE_RSVD,
-	BOOT_SOURCE_QSPI
+	BOOT_SOURCE_QSPI,
+	BOOT_SOURCE_RSVD
 } boot_source_type;
 
 /*******************************************************************************
@@ -34,7 +34,7 @@ typedef enum {
 
 void enable_nonsecure_access(void);
 
-void socfpga_io_setup(int boot_source);
+void socfpga_io_setup(int boot_source, unsigned long offset);
 
 void socfgpa_configure_mmu_el3(unsigned long total_base,
 			unsigned long total_size,
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
index 9d06a3d3..93cc9456 100644
--- a/plat/intel/soc/common/include/socfpga_reset_manager.h
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -155,6 +155,8 @@
 #define RSTMGR_HDSKACK_F2SDRAM0ACK		0x00000800
 #define RSTMGR_HDSKACK_FPGA2SOCACK		0x00001000
 #define RSTMGR_HDSKACK_FPGAHSACK_DASRT		0x00000000
+#define RSTMGR_HDSKACK_LWSOC2FPGAACK_DASRT	0x00000000
+#define RSTMGR_HDSKACK_SOC2FPGAACK_DASRT	0x00000000
 #define RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT	0x00000000
 #define RSTMGR_HDSKACK_FPGA2SOCACK_DASRT	0x00000000
 
diff --git a/plat/intel/soc/common/include/socfpga_ros.h b/plat/intel/soc/common/include/socfpga_ros.h
new file mode 100644
index 00000000..10cabd31
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_ros.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2024, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_ROS_H
+#define SOCFPGA_ROS_H
+
+#include <arch_helpers.h>
+#include <lib/utils_def.h>
+
+/** status response*/
+#define ROS_RET_OK			(0x00U)
+#define ROS_RET_INVALID			(0x01U)
+#define ROS_RET_NOT_RSU_MODE		(0x02U)
+#define ROS_QSPI_READ_ERROR		(0x03U)
+#define ROS_SPT_BAD_MAGIC_NUM		(0x04U)
+#define ROS_SPT_CRC_ERROR		(0x05U)
+#define ROS_IMAGE_INDEX_ERR		(0x06U)
+#define ROS_IMAGE_PARTNUM_OVFL		(0x07U)
+
+#define ADDR_64(h, l)			(((((unsigned long)(h)) & 0xffffffff) << 32) | \
+						(((unsigned long)(l)) & 0xffffffff))
+
+#define RSU_GET_SPT_RESP_SIZE		(4U)
+
+#define RSU_STATUS_RES_SIZE		(9U)
+
+#define SPT_MAGIC_NUMBER		(0x57713427U)
+#define SPT_VERSION			(0U)
+#define SPT_FLAG_RESERVED		(1U)
+#define SPT_FLAG_READONLY		(2U)
+
+#define SPT_MAX_PARTITIONS		(127U)
+#define SPT_PARTITION_NAME_LENGTH	(16U)
+#define SPT_RSVD_LENGTH			(4U)
+#define SPT_SIZE			(4096U)
+/*BOOT_INFO + FACTORY_IMAGE + SPT0 + SPT1 + CPB0 + CPB1 + FACTORY_IM.SSBL+ *APP* + *APP*.SSBL*/
+#define SPT_MIN_PARTITIONS		(9U)
+
+#define FACTORY_IMAGE			"FACTORY_IMAGE"
+#define FACTORY_SSBL			"FACTORY_IM.SSBL"
+#define SSBL_SUFFIX			".SSBL"
+
+typedef struct {
+	const uint32_t magic_number;
+	const uint32_t version;
+	const uint32_t partitions;
+	uint32_t checksum;
+	const uint32_t __RSVD[SPT_RSVD_LENGTH];
+	struct {
+		const char name[SPT_PARTITION_NAME_LENGTH];
+		const uint64_t offset;
+		const uint32_t length;
+		const uint32_t flags;
+	} partition[SPT_MAX_PARTITIONS];
+} __packed spt_table_t;
+
+uint32_t ros_qspi_get_ssbl_offset(unsigned long *offset);
+
+#endif /* SOCFPGA_ROS_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 06683010..31474c46 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,82 +10,83 @@
 
 
 /* SiP status response */
-#define INTEL_SIP_SMC_STATUS_OK					0
-#define INTEL_SIP_SMC_STATUS_BUSY				0x1
-#define INTEL_SIP_SMC_STATUS_REJECTED				0x2
-#define INTEL_SIP_SMC_STATUS_NO_RESPONSE			0x3
-#define INTEL_SIP_SMC_STATUS_ERROR				0x4
-#define INTEL_SIP_SMC_RSU_ERROR					0x7
-#define INTEL_SIP_SMC_SEU_ERR_READ_ERROR		0x8
+#define INTEL_SIP_SMC_STATUS_OK						0
+#define INTEL_SIP_SMC_STATUS_BUSY					0x1
+#define INTEL_SIP_SMC_STATUS_REJECTED					0x2
+#define INTEL_SIP_SMC_STATUS_NO_RESPONSE				0x3
+#define INTEL_SIP_SMC_STATUS_ERROR					0x4
+#define INTEL_SIP_SMC_RSU_ERROR						0x7
+#define INTEL_SIP_SMC_SEU_ERR_READ_ERROR				0x8
 
 /* SiP mailbox error code */
-#define GENERIC_RESPONSE_ERROR					0x3FF
+#define GENERIC_RESPONSE_ERROR						0x3FF
 
 /* SiP V2 command code range */
-#define INTEL_SIP_SMC_CMD_MASK					0xFFFF
-#define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN			0x400
-#define INTEL_SIP_SMC_CMD_V2_RANGE_END				0x4FF
+#define INTEL_SIP_SMC_CMD_MASK						0xFFFF
+#define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN				0x400
+#define INTEL_SIP_SMC_CMD_V2_RANGE_END					0x4FF
 
 /* SiP V2 protocol header */
-#define INTEL_SIP_SMC_HEADER_JOB_ID_MASK			0xF
-#define INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET			0U
-#define INTEL_SIP_SMC_HEADER_CID_MASK				0xF
-#define INTEL_SIP_SMC_HEADER_CID_OFFSET				4U
-#define INTEL_SIP_SMC_HEADER_VERSION_MASK			0xF
-#define INTEL_SIP_SMC_HEADER_VERSION_OFFSET			60U
+#define INTEL_SIP_SMC_HEADER_JOB_ID_MASK				0xF
+#define INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET				0U
+#define INTEL_SIP_SMC_HEADER_CID_MASK					0xF
+#define INTEL_SIP_SMC_HEADER_CID_OFFSET					4U
+#define INTEL_SIP_SMC_HEADER_VERSION_MASK				0xF
+#define INTEL_SIP_SMC_HEADER_VERSION_OFFSET				60U
 
 /* SMC SiP service function identifier for version 1 */
 
 /* FPGA Reconfig */
-#define INTEL_SIP_SMC_FPGA_CONFIG_START				0xC2000001
-#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE				0x42000002
-#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE		0xC2000003
-#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE			0xC2000004
-#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM			0xC2000005
+#define INTEL_SIP_SMC_FPGA_CONFIG_START					0xC2000001
+#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE					0x42000002
+#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE			0xC2000003
+#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE				0xC2000004
+#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM				0xC2000005
 
 /* FPGA Bitstream Flag */
-#define FLAG_PARTIAL_CONFIG					BIT(0)
-#define FLAG_AUTHENTICATION					BIT(1)
-#define CONFIG_TEST_FLAG(_flag, _type)				(((flag) & FLAG_##_type) \
-								== FLAG_##_type)
+#define FLAG_PARTIAL_CONFIG						BIT(0)
+#define FLAG_AUTHENTICATION						BIT(1)
+#define CONFIG_TEST_FLAG(_flag, _type)					(((flag) & FLAG_##_type) \
+									== FLAG_##_type)
 
 /* Secure Register Access */
-#define INTEL_SIP_SMC_REG_READ				0xC2000007
-#define INTEL_SIP_SMC_REG_WRITE				0xC2000008
-#define INTEL_SIP_SMC_REG_UPDATE			0xC2000009
+#define INTEL_SIP_SMC_REG_READ						0xC2000007
+#define INTEL_SIP_SMC_REG_WRITE						0xC2000008
+#define INTEL_SIP_SMC_REG_UPDATE					0xC2000009
 
 /* Remote System Update */
-#define INTEL_SIP_SMC_RSU_STATUS				0xC200000B
-#define INTEL_SIP_SMC_RSU_UPDATE				0xC200000C
-#define INTEL_SIP_SMC_RSU_NOTIFY				0xC200000E
-#define INTEL_SIP_SMC_RSU_RETRY_COUNTER				0xC200000F
-#define INTEL_SIP_SMC_RSU_DCMF_VERSION				0xC2000010
-#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION			0xC2000011
-#define INTEL_SIP_SMC_RSU_MAX_RETRY				0xC2000012
-#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY			0xC2000013
-#define INTEL_SIP_SMC_RSU_DCMF_STATUS				0xC2000014
-#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS			0xC2000015
+#define INTEL_SIP_SMC_RSU_STATUS					0xC200000B
+#define INTEL_SIP_SMC_RSU_UPDATE					0xC200000C
+#define INTEL_SIP_SMC_RSU_NOTIFY					0xC200000E
+#define INTEL_SIP_SMC_RSU_RETRY_COUNTER					0xC200000F
+#define INTEL_SIP_SMC_RSU_DCMF_VERSION					0xC2000010
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION				0xC2000011
+#define INTEL_SIP_SMC_RSU_MAX_RETRY					0xC2000012
+#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY				0xC2000013
+#define INTEL_SIP_SMC_RSU_DCMF_STATUS					0xC2000014
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS				0xC2000015
+#define INTEL_SIP_SMC_RSU_GET_DEVICE_INFO				0xC2000016
 
 /* Hardware monitor */
-#define INTEL_SIP_SMC_HWMON_READTEMP				0xC2000020
-#define INTEL_SIP_SMC_HWMON_READVOLT				0xC2000021
-#define TEMP_CHANNEL_MAX					(1 << 15)
-#define VOLT_CHANNEL_MAX					(1 << 15)
+#define INTEL_SIP_SMC_HWMON_READTEMP					0xC2000020
+#define INTEL_SIP_SMC_HWMON_READVOLT					0xC2000021
+#define TEMP_CHANNEL_MAX						(1 << 15)
+#define VOLT_CHANNEL_MAX						(1 << 15)
 
 /* ECC */
-#define INTEL_SIP_SMC_ECC_DBE					0xC200000D
+#define INTEL_SIP_SMC_ECC_DBE						0xC200000D
 
 /* Generic Command */
-#define INTEL_SIP_SMC_SERVICE_COMPLETED				0xC200001E
-#define INTEL_SIP_SMC_FIRMWARE_VERSION				0xC200001F
-#define INTEL_SIP_SMC_HPS_SET_BRIDGES				0xC2000032
-#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384			0xC2000040
+#define INTEL_SIP_SMC_SERVICE_COMPLETED					0xC200001E
+#define INTEL_SIP_SMC_FIRMWARE_VERSION					0xC200001F
+#define INTEL_SIP_SMC_HPS_SET_BRIDGES					0xC2000032
+#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384				0xC2000040
 
-#define SERVICE_COMPLETED_MODE_ASYNC				0x00004F4E
+#define SERVICE_COMPLETED_MODE_ASYNC					0x00004F4E
 
 /* Mailbox Command */
-#define INTEL_SIP_SMC_MBOX_SEND_CMD				0xC200003C
-#define INTEL_SIP_SMC_GET_USERCODE				0xC200003D
+#define INTEL_SIP_SMC_MBOX_SEND_CMD					0xC200003C
+#define INTEL_SIP_SMC_GET_USERCODE					0xC200003D
 
 /* FPGA Crypto Services */
 #define INTEL_SIP_SMC_FCS_RANDOM_NUMBER					0xC200005A
@@ -138,23 +140,25 @@
 #define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE			0xC200008B
 #define INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT				0xC200008C
 #define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE				0xC200008E
+#define INTEL_SIP_SMC_FCS_SDM_REMAPPER_CONFIG				0xC2000201
 
 /* SEU ERR */
-#define INTEL_SIP_SMC_SEU_ERR_STATUS				0xC2000099
+#define INTEL_SIP_SMC_SEU_ERR_STATUS					0xC2000099
+#define INTEL_SIP_SMC_SAFE_INJECT_SEU_ERR				0xC200009A
 
-#define INTEL_SIP_SMC_FCS_SHA_MODE_MASK				0xF
-#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK			0xF
-#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET			4U
-#define INTEL_SIP_SMC_FCS_ECC_ALGO_MASK				0xF
+#define INTEL_SIP_SMC_FCS_SHA_MODE_MASK					0xF
+#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK				0xF
+#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET				4U
+#define INTEL_SIP_SMC_FCS_ECC_ALGO_MASK					0xF
 
 /* ECC DBE */
-#define WARM_RESET_WFI_FLAG					BIT(31)
-#define SYSMGR_ECC_DBE_COLD_RST_MASK				(SYSMGR_ECC_OCRAM_MASK |\
-								SYSMGR_ECC_DDR0_MASK |\
-								SYSMGR_ECC_DDR1_MASK)
+#define WARM_RESET_WFI_FLAG						BIT(31)
+#define SYSMGR_ECC_DBE_COLD_RST_MASK					(SYSMGR_ECC_OCRAM_MASK |\
+									SYSMGR_ECC_DDR0_MASK |\
+									SYSMGR_ECC_DDR1_MASK)
 
 /* Non-mailbox SMC Call */
-#define INTEL_SIP_SMC_SVC_VERSION				0xC2000200
+#define INTEL_SIP_SMC_SVC_VERSION					0xC2000200
 
 /**
  * SMC SiP service function identifier for version 2
@@ -162,31 +166,31 @@
  */
 
 /* V2: Non-mailbox function identifier */
-#define INTEL_SIP_SMC_V2_GET_SVC_VERSION			0xC2000400
-#define INTEL_SIP_SMC_V2_REG_READ				0xC2000401
-#define INTEL_SIP_SMC_V2_REG_WRITE				0xC2000402
-#define INTEL_SIP_SMC_V2_REG_UPDATE				0xC2000403
-#define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES			0xC2000404
-#define INTEL_SIP_SMC_V2_RSU_UPDATE_ADDR			0xC2000405
+#define INTEL_SIP_SMC_V2_GET_SVC_VERSION				0xC2000400
+#define INTEL_SIP_SMC_V2_REG_READ					0xC2000401
+#define INTEL_SIP_SMC_V2_REG_WRITE					0xC2000402
+#define INTEL_SIP_SMC_V2_REG_UPDATE					0xC2000403
+#define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES				0xC2000404
+#define INTEL_SIP_SMC_V2_RSU_UPDATE_ADDR				0xC2000405
 
 /* V2: Mailbox function identifier */
-#define INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND			0xC2000420
-#define INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE			0xC2000421
+#define INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND				0xC2000420
+#define INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE				0xC2000421
 
 /* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT					0x8200ff00
-#define SIP_SVC_UID						0x8200ff01
-#define SIP_SVC_VERSION						0x8200ff03
+#define SIP_SVC_CALL_COUNT						0x8200ff00
+#define SIP_SVC_UID							0x8200ff01
+#define SIP_SVC_VERSION							0x8200ff03
 
 /* SiP Service Calls version numbers */
 /*
  * Increase if there is any backward compatibility impact
  */
-#define SIP_SVC_VERSION_MAJOR					2
+#define SIP_SVC_VERSION_MAJOR						2
 /*
  * Increase if there is new SMC function ID being added
  */
-#define SIP_SVC_VERSION_MINOR					2
+#define SIP_SVC_VERSION_MINOR						2
 
 
 /* Structure Definitions */
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index f860f575..346cfe10 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,7 +15,6 @@
 #define SOCFPGA_SYSMGR_SDMMC				0x28
 
 /* Field Masking */
-
 #define SYSMGR_SDMMC_DRVSEL(x)			(((x) & 0x7) << 0)
 #define SYSMGR_SDMMC_SMPLSEL(x)			(((x) & 0x7) << 4)
 
@@ -33,4 +33,8 @@
 #define SOCFPGA_SYSMGR(_reg)		(SOCFPGA_SYSMGR_REG_BASE \
 						+ (SOCFPGA_SYSMGR_##_reg))
 
+/* Function Prototype */
+uint32_t intel_hps_get_jtag_id(void);
+bool is_agilex5_A5F0(void);
+
 #endif /* SOCFPGA_SYSTEMMANAGER_H */
diff --git a/plat/intel/soc/common/include/socfpga_vab.h b/plat/intel/soc/common/include/socfpga_vab.h
index f6081df7..4587d7fc 100644
--- a/plat/intel/soc/common/include/socfpga_vab.h
+++ b/plat/intel/soc/common/include/socfpga_vab.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,10 +8,28 @@
 #ifndef SOCFPGA_VAB_H
 #define SOCFPGA_VAB_H
 
-
 #include <stdlib.h>
 #include "socfpga_fcs.h"
 
+/* Macros */
+#define IS_BYTE_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)
+#define BYTE_ALIGN(x, a)		__ALIGN_MASK((x), (typeof(x))(a)-1)
+#define __ALIGN_MASK(x, mask)		(((x)+(mask))&~(mask))
+#define VAB_CERT_HEADER_SIZE		sizeof(struct fcs_hps_vab_certificate_header)
+#define VAB_CERT_MAGIC_OFFSET		offsetof(struct fcs_hps_vab_certificate_header, d)
+#define VAB_CERT_FIT_SHA384_OFFSET	offsetof(struct fcs_hps_vab_certificate_data, fcs_sha384[0])
+#define SDM_CERT_MAGIC_NUM		0x25D04E7F
+#define CHUNKSZ_PER_WD_RESET		(256 * 1024)
+#define CCERT_CMD_TEST_PGM_MASK		0x80000000 //TODO: ATF FDT location
+
+/* SHA related return Macro */
+#define ENOVABCERT			1 /* VAB certificate not available */
+#define EIMGERR				2 /* Image format/size not valid */
+#define ETIMEOUT			3 /* Execution timeout */
+#define EPROCESS			4 /* Process error */
+#define EKEYREJECTED			5 /* Key was rejected by service */
+#define EINITREJECTED			6 /* VAB init was rejected */
+
 struct fcs_hps_vab_certificate_data {
 	uint32_t vab_cert_magic_num;			/* offset 0x10 */
 	uint32_t flags;
@@ -27,28 +46,9 @@ struct fcs_hps_vab_certificate_header {
 	/* keychain starts at offset 0x50 */
 };
 
-/* Macros */
-#define IS_BYTE_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)
-#define BYTE_ALIGN(x, a)		__ALIGN_MASK((x), (typeof(x))(a)-1)
-#define __ALIGN_MASK(x, mask)		(((x)+(mask))&~(mask))
-#define VAB_CERT_HEADER_SIZE		sizeof(struct fcs_hps_vab_certificate_header)
-#define VAB_CERT_MAGIC_OFFSET		offsetof(struct fcs_hps_vab_certificate_header, d)
-#define VAB_CERT_FIT_SHA384_OFFSET	offsetof(struct fcs_hps_vab_certificate_data, fcs_sha384[0])
-#define SDM_CERT_MAGIC_NUM		0x25D04E7F
-#define CHUNKSZ_PER_WD_RESET		(256 * 1024)
-
-/* SHA related return Macro */
-#define ENOVABIMG		1 /* VAB certificate not available */
-#define EIMGERR		2 /* Image format/size not valid */
-#define ETIMEOUT		3 /* Execution timeout */
-#define EPROCESS		4 /* Process error */
-#define EKEYREJECTED		5/* Key was rejected by service */
-
 /* Function Definitions */
-static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz);
-int socfpga_vendor_authentication(void **p_image, size_t *p_size);
-static uint32_t get_unaligned_le32(const void *p);
-void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
-unsigned char *output, unsigned int chunk_sz);
-
+size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz);
+uint32_t get_unaligned_le32(const void *p);
+int socfpga_vab_authentication(void **p_image, size_t *p_size);
+int socfpga_vab_init(unsigned int image_id);
 #endif
diff --git a/plat/intel/soc/common/lib/sha/sha.c b/plat/intel/soc/common/lib/sha/sha.c
new file mode 100644
index 00000000..9a6adc6f
--- /dev/null
+++ b/plat/intel/soc/common/lib/sha/sha.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+#include <tools_share/firmware_image_package.h>
+
+#include "sha.h"
+#include "wdt/watchdog.h"
+
+/* SHA384 certificate ID */
+#define SHA384_H0	0xcbbb9d5dc1059ed8ULL
+#define SHA384_H1	0x629a292a367cd507ULL
+#define SHA384_H2	0x9159015a3070dd17ULL
+#define SHA384_H3	0x152fecd8f70e5939ULL
+#define SHA384_H4	0x67332667ffc00b31ULL
+#define SHA384_H5	0x8eb44a8768581511ULL
+#define SHA384_H6	0xdb0c2e0d64f98fa7ULL
+#define SHA384_H7	0x47b5481dbefa4fa4ULL
+
+/* SHA512 certificate ID */
+#define SHA512_H0	0x6a09e667f3bcc908ULL
+#define SHA512_H1	0xbb67ae8584caa73bULL
+#define SHA512_H2	0x3c6ef372fe94f82bULL
+#define SHA512_H3	0xa54ff53a5f1d36f1ULL
+#define SHA512_H4	0x510e527fade682d1ULL
+#define SHA512_H5	0x9b05688c2b3e6c1fULL
+#define SHA512_H6	0x1f83d9abfb41bd6bULL
+#define SHA512_H7	0x5be0cd19137e2179ULL
+
+void sha384_init(sha512_context *ctx)
+{
+	ctx->state[0] = SHA384_H0;
+	ctx->state[1] = SHA384_H1;
+	ctx->state[2] = SHA384_H2;
+	ctx->state[3] = SHA384_H3;
+	ctx->state[4] = SHA384_H4;
+	ctx->state[5] = SHA384_H5;
+	ctx->state[6] = SHA384_H6;
+	ctx->state[7] = SHA384_H7;
+	ctx->count[0] = ctx->count[1] = 0;
+}
+
+void sha384_update(sha512_context *ctx, const uint8_t *input, uint32_t length)
+{
+	sha512_base_do_update(ctx, input, length);
+}
+
+void sha384_finish(sha512_context *ctx, uint8_t digest[SHA384_SUM_LEN])
+{
+	int i;
+
+	sha512_base_do_finalize(ctx);
+	for (i = 0; i < SHA384_SUM_LEN / sizeof(uint64_t); i++)
+		PUT_UINT64_BE(ctx->state[i], digest, i * 8);
+}
+
+void sha384_start(const unsigned char *input, unsigned int len,
+					unsigned char *output, unsigned int chunk_sz)
+{
+	/* TODO: Shall trigger watchdog for each chuck byte. */
+	sha512_context ctx;
+	const unsigned char *end;
+	unsigned char *curr;
+	int chunk;
+
+	sha384_init(&ctx);
+
+	curr = (unsigned char *)input;
+	end = input + len;
+	while (curr < end) {
+		chunk = end - curr;
+		if (chunk > chunk_sz) {
+			chunk = chunk_sz;
+		}
+		sha384_update(&ctx, curr, chunk);
+		curr += chunk;
+		watchdog_sw_rst();
+	}
+
+	sha384_finish(&ctx, output);
+}
+
+/* SHA512 Start Here */
+void sha512_init(sha512_context *ctx)
+{
+	ctx->state[0] = SHA512_H0;
+	ctx->state[1] = SHA512_H1;
+	ctx->state[2] = SHA512_H2;
+	ctx->state[3] = SHA512_H3;
+	ctx->state[4] = SHA512_H4;
+	ctx->state[5] = SHA512_H5;
+	ctx->state[6] = SHA512_H6;
+	ctx->state[7] = SHA512_H7;
+	ctx->count[0] = ctx->count[1] = 0;
+}
+
+void sha512_update(sha512_context *ctx, const uint8_t *input, uint32_t length)
+{
+	sha512_base_do_update(ctx, input, length);
+}
+
+void sha512_finish(sha512_context *ctx, uint8_t digest[SHA512_SUM_LEN])
+{
+	int i;
+
+	sha512_base_do_finalize(ctx);
+	for (i = 0; i < SHA512_SUM_LEN / sizeof(uint64_t); i++)
+		PUT_UINT64_BE(ctx->state[i], digest, i * 8);
+}
+
+void sha512_start(const unsigned char *input, unsigned int len, unsigned char *output)
+{
+	/* TODO: Shall trigger watchdog for each chuck byte. */
+	sha512_context ctx;
+
+	sha384_init(&ctx);
+	sha512_update(&ctx, input, len);
+	sha512_finish(&ctx, output);
+}
+
+void sha512_transform(uint64_t *state, const uint8_t *input)
+{
+	uint64_t a, b, c, d, e, f, g, h, t1, t2;
+
+	int i;
+	uint64_t W[16];
+
+	/* load the state into our registers */
+	a = state[0];   b = state[1];   c = state[2];   d = state[3];
+	e = state[4];   f = state[5];   g = state[6];   h = state[7];
+
+	/* now iterate */
+	for (i = 0 ; i < 80; i += 8) {
+		if (!(i & 8)) {
+			int j;
+
+			if (i < 16) {
+				/* load the input */
+				for (j = 0; j < 16; j++)
+					LOAD_OP(i + j, W, input);
+			} else {
+				for (j = 0; j < 16; j++) {
+					BLEND_OP(i + j, W);
+				}
+			}
+		}
+
+		t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i & 15)];
+		t2 = e0(a) + Maj(a, b, c);    d += t1;    h = t1 + t2;
+		t1 = g + e1(d) + Ch(d, e, f) + sha512_K[i+1] + W[(i & 15) + 1];
+		t2 = e0(h) + Maj(h, a, b);    c += t1;    g = t1 + t2;
+		t1 = f + e1(c) + Ch(c, d, e) + sha512_K[i+2] + W[(i & 15) + 2];
+		t2 = e0(g) + Maj(g, h, a);    b += t1;    f = t1 + t2;
+		t1 = e + e1(b) + Ch(b, c, d) + sha512_K[i+3] + W[(i & 15) + 3];
+		t2 = e0(f) + Maj(f, g, h);    a += t1;    e = t1 + t2;
+		t1 = d + e1(a) + Ch(a, b, c) + sha512_K[i+4] + W[(i & 15) + 4];
+		t2 = e0(e) + Maj(e, f, g);    h += t1;    d = t1 + t2;
+		t1 = c + e1(h) + Ch(h, a, b) + sha512_K[i+5] + W[(i & 15) + 5];
+		t2 = e0(d) + Maj(d, e, f);    g += t1;    c = t1 + t2;
+		t1 = b + e1(g) + Ch(g, h, a) + sha512_K[i+6] + W[(i & 15) + 6];
+		t2 = e0(c) + Maj(c, d, e);    f += t1;    b = t1 + t2;
+		t1 = a + e1(f) + Ch(f, g, h) + sha512_K[i+7] + W[(i & 15) + 7];
+		t2 = e0(b) + Maj(b, c, d);    e += t1;    a = t1 + t2;
+	}
+
+	state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+	state[4] += e; state[5] += f; state[6] += g; state[7] += h;
+
+	/* erase our data */
+	a = b = c = d = e = f = g = h = t1 = t2 = 0;
+}
+
+void sha512_block_fn(sha512_context *sst, const uint8_t *src,
+				    int blocks)
+{
+	while (blocks--) {
+		sha512_transform(sst->state, src);
+		src += SHA512_BLOCK_SIZE;
+	}
+}
+
+
+void sha512_base_do_finalize(sha512_context *sctx)
+{
+	const int bit_offset = SHA512_BLOCK_SIZE - sizeof(uint64_t[2]);
+	uint64_t *bits = (uint64_t *)(sctx->buf + bit_offset);
+	unsigned int partial = sctx->count[0] % SHA512_BLOCK_SIZE;
+
+	sctx->buf[partial++] = 0x80;
+	if (partial > bit_offset) {
+		memset(sctx->buf + partial, 0x0, SHA512_BLOCK_SIZE - partial);
+		partial = 0;
+
+		sha512_block_fn(sctx, sctx->buf, 1);
+	}
+
+	memset(sctx->buf + partial, 0x0, bit_offset - partial);
+	bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61);
+	bits[1] = cpu_to_be64(sctx->count[0] << 3);
+
+	sha512_block_fn(sctx, sctx->buf, 1);
+}
+
+void sha512_base_do_update(sha512_context *sctx,
+					const uint8_t *data,
+					unsigned int len)
+{
+	unsigned int partial = sctx->count[0] % SHA512_BLOCK_SIZE;
+
+	sctx->count[0] += len;
+	if (sctx->count[0] < len)
+		sctx->count[1]++;
+
+	if (((partial + len) >= SHA512_BLOCK_SIZE)) {
+		int blocks;
+
+		if (partial) {
+			int p = SHA512_BLOCK_SIZE - partial;
+
+			memcpy(sctx->buf + partial, data, p);
+			data += p;
+			len -= p;
+
+			sha512_block_fn(sctx, sctx->buf, 1);
+		}
+
+		blocks = len / SHA512_BLOCK_SIZE;
+		len %= SHA512_BLOCK_SIZE;
+
+		if (blocks) {
+			sha512_block_fn(sctx, data, blocks);
+			data += blocks * SHA512_BLOCK_SIZE;
+		}
+		partial = 0;
+	}
+	if (len)
+		memcpy(sctx->buf + partial, data, len);
+}
diff --git a/plat/intel/soc/common/lib/sha/sha.h b/plat/intel/soc/common/lib/sha/sha.h
new file mode 100644
index 00000000..41b5fa8d
--- /dev/null
+++ b/plat/intel/soc/common/lib/sha/sha.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_SHA_H
+#define SOCFPGA_SHA_H
+
+#include <stdlib.h>
+
+
+#define SHA384_SUM_LEN			48
+#define SHA384_DER_LEN			19
+#define SHA512_SUM_LEN			64
+#define SHA512_DER_LEN			19
+#define SHA512_BLOCK_SIZE		128
+
+
+/* MACRO Function */
+#define GET_UINT64_BE(n, b, i) {	\
+	(n) = ((unsigned long long) (b)[(i)] << 56) |\
+	((unsigned long long) (b)[(i) + 1] << 48) |\
+	((unsigned long long) (b)[(i) + 2] << 40) |\
+	((unsigned long long) (b)[(i) + 3] << 32) |\
+	((unsigned long long) (b)[(i) + 4] << 24) |\
+	((unsigned long long) (b)[(i) + 5] << 16) |\
+	((unsigned long long) (b)[(i) + 6] <<  8) |\
+	((unsigned long long) (b)[(i) + 7]);\
+}
+
+#define PUT_UINT64_BE(n, b, i) {	\
+	(b)[(i)] = (unsigned char) ((n) >> 56);\
+	(b)[(i) + 1] = (unsigned char) ((n) >> 48);\
+	(b)[(i) + 2] = (unsigned char) ((n) >> 40);\
+	(b)[(i) + 3] = (unsigned char) ((n) >> 32);\
+	(b)[(i) + 4] = (unsigned char) ((n) >> 24);\
+	(b)[(i) + 5] = (unsigned char) ((n) >> 16);\
+	(b)[(i) + 6] = (unsigned char) ((n) >>  8);\
+	(b)[(i) + 7] = (unsigned char) ((n));\
+}
+
+#define e0(x)		(ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39))
+#define e1(x)		(ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41))
+#define s0(x)		(ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
+#define s1(x)		(ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6))
+
+/* Inline Function Definitions */
+/* ror64() to rotate its right in 64 bits. */
+static inline uint64_t ror64(uint64_t input, unsigned int shift)
+{
+	return (input >> (shift & 63)) | (input << ((-shift) & 63));
+}
+
+static inline uint64_t Ch(uint64_t x, uint64_t y, uint64_t z)
+{
+	return z ^ (x & (y ^ z));
+}
+
+static inline uint64_t Maj(uint64_t x, uint64_t y, uint64_t z)
+{
+	return (x & y) | (z & (x | y));
+}
+
+static inline void LOAD_OP(int I, uint64_t *W, const uint8_t *input)
+{
+	GET_UINT64_BE(W[I], input, I*8);
+}
+
+static inline void BLEND_OP(int I, uint64_t *W)
+{
+	W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]);
+}
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+inline uint32_t le32_to_cpue(const uint32_t *p)
+{
+	return (uint32_t)*p;
+}
+#else
+inline uint32_t le32_to_cpue(const uint32_t *p)
+{
+	return swab32(*p);
+}
+#endif
+
+static const uint64_t sha512_K[80] = {
+	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+	0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+	0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+	0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+	0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+	0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+	0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+	0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+	0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+	0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+	0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+	0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+	0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+	0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
+};
+
+#define	__cpu_to_le64(x)	((__force __le64)(__u64)(x))
+
+#define _uswap_64(x, sfx)	\
+	((((x) & 0xff00000000000000##sfx) >> 56) |\
+	(((x) & 0x00ff000000000000##sfx) >> 40) |\
+	(((x) & 0x0000ff0000000000##sfx) >> 24) |\
+	(((x) & 0x000000ff00000000##sfx) >>  8) |\
+	(((x) & 0x00000000ff000000##sfx) <<  8) |\
+	(((x) & 0x0000000000ff0000##sfx) << 24) |\
+	(((x) & 0x000000000000ff00##sfx) << 40) |\
+	(((x) & 0x00000000000000ff##sfx) << 56))
+
+#if defined(__GNUC__)
+#define uswap_64(x)		_uswap_64(x, ull)
+#else
+#define uswap_64(x)		_uswap_64(x)
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_be64(x)		uswap_64(x)
+#else
+#define cpu_to_be64(x)		(x)
+#endif
+
+typedef struct {
+	uint64_t state[SHA512_SUM_LEN / 8];
+	uint64_t count[2];
+	uint8_t buf[SHA512_BLOCK_SIZE];
+} sha512_context;
+
+/* Function Definitions */
+/* SHA384 Start Here */
+void sha384_init(sha512_context *ctx);
+void sha384_update(sha512_context *ctx, const uint8_t *input, uint32_t length);
+void sha384_finish(sha512_context *ctx, uint8_t digest[SHA384_SUM_LEN]);
+void sha384_start(const unsigned char *input, unsigned int len,
+			unsigned char *output, unsigned int chunk_sz);
+/* SHA512 Start Here */
+void sha512_init(sha512_context *ctx);
+void sha512_update(sha512_context *ctx, const uint8_t *input, uint32_t length);
+void sha512_finish(sha512_context *ctx, uint8_t digest[SHA512_SUM_LEN]);
+void sha512_start(const unsigned char *input, unsigned int len,
+			unsigned char *output);
+void sha512_transform(uint64_t *state, const uint8_t *input);
+void sha512_block_fn(sha512_context *sst, const uint8_t *src, int blocks);
+void sha512_base_do_finalize(sha512_context *sctx);
+void sha512_base_do_update(sha512_context *sctx, const uint8_t *data,
+				unsigned int len);
+
+#endif
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index beaa7208..91df934f 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -247,14 +248,6 @@ uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
 	int status;
 	uint32_t load_size;
 
-	fcs_encrypt_payload payload = {
-		FCS_ENCRYPTION_DATA_0,
-		src_addr,
-		src_size,
-		dst_addr,
-		dst_size };
-	load_size = sizeof(payload) / MBOX_WORD_BYTE;
-
 	if (!is_address_in_ddr_range(src_addr, src_size) ||
 		!is_address_in_ddr_range(dst_addr, dst_size)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -264,6 +257,14 @@ uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	fcs_encrypt_payload payload = {
+		FCS_ENCRYPTION_DATA_0,
+		src_addr,
+		src_size,
+		dst_addr,
+		dst_size };
+	load_size = sizeof(payload) / MBOX_WORD_BYTE;
+
 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
 				(uint32_t *) &payload, load_size,
 				CMD_INDIRECT);
@@ -283,6 +284,15 @@ uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
 	uint32_t load_size;
 	uintptr_t id_offset;
 
+	if (!is_address_in_ddr_range(src_addr, src_size) ||
+		!is_address_in_ddr_range(dst_addr, dst_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	if (!is_size_4_bytes_aligned(src_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	inv_dcache_range(src_addr, src_size); /* flush cache before mmio read to avoid reading old values */
 	id_offset = src_addr + FCS_OWNER_ID_OFFSET;
 	fcs_decrypt_payload payload = {
@@ -295,15 +305,6 @@ uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
 		dst_size };
 	load_size = sizeof(payload) / MBOX_WORD_BYTE;
 
-	if (!is_address_in_ddr_range(src_addr, src_size) ||
-		!is_address_in_ddr_range(dst_addr, dst_size)) {
-		return INTEL_SIP_SMC_STATUS_REJECTED;
-	}
-
-	if (!is_size_4_bytes_aligned(src_size)) {
-		return INTEL_SIP_SMC_STATUS_REJECTED;
-	}
-
 	status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
 				(uint32_t *) &payload, load_size,
 				CMD_INDIRECT);
@@ -1164,8 +1165,8 @@ int intel_fcs_mac_verify_update_finalize(uint32_t session_id,
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
-		src_size - data_size);
+		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
+			(void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE);
 
 		i += (src_size - data_size) / MBOX_WORD_BYTE;
 	}
@@ -1298,8 +1299,8 @@ int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id,
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
-		src_size - data_size);
+		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
+			(void *) mac_offset, (src_size - data_size) / MBOX_WORD_BYTE);
 
 		memset((void *) dst_addr, 0, *dst_size);
 
@@ -1401,8 +1402,8 @@ int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
-			src_size);
+	memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
+		(void *) hash_data_addr, src_size / MBOX_WORD_BYTE);
 
 	i += src_size / MBOX_WORD_BYTE;
 
@@ -1502,8 +1503,8 @@ int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t conte
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	memcpy((uint8_t *) &payload[i],
-			(uint8_t *) hash_sig_pubkey_addr, src_size);
+	memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
+		(void *) hash_sig_pubkey_addr, src_size / MBOX_WORD_BYTE);
 
 	i += (src_size / MBOX_WORD_BYTE);
 
@@ -1839,8 +1840,8 @@ int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
-			src_size - data_size);
+		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
+			(void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE);
 
 		i += (src_size - data_size) / MBOX_WORD_BYTE;
 	}
@@ -1971,8 +1972,8 @@ int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_i
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
-			src_size - data_size);
+		memcpy_s(&payload[i], (src_size - data_size) / MBOX_WORD_BYTE,
+			(void *) sig_pubkey_offset, (src_size - data_size) / MBOX_WORD_BYTE);
 
 		memset((void *) dst_addr, 0, *dst_size);
 
@@ -2023,6 +2024,10 @@ int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+	if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
 		fcs_ecdsa_get_pubkey_param.context_id != context_id) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
@@ -2141,7 +2146,8 @@ int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
+	memcpy_s(&payload[i], src_size / MBOX_WORD_BYTE,
+		(void *) pubkey, src_size / MBOX_WORD_BYTE);
 	i += src_size / MBOX_WORD_BYTE;
 
 	status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
@@ -2171,14 +2177,28 @@ int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
 
 	param_addr_ptr = (uint64_t *) param_addr;
 
+	/* Check if mbox_error is not NULL or 0xF or 0x3FF */
+	if (mbox_error == NULL || *mbox_error > 0xF ||
+		(*mbox_error != 0 && *mbox_error != 0x3FF)) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
+	/* Check if param_addr is not 0 or larger that 0xFFFFFFFFFF */
+	if (param_addr == 0 || param_addr > 0xFFFFFFFFFF) {
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+	}
+
 	/*
-	 * Since crypto param size vary between mode.
-	 * Check ECB here and limit to size 12 bytes
+	 * Check if not ECB, CBC and CTR mode, addr ptr is NULL.
+	 * Return "Reject" status
 	 */
-	if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
-		(param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
+	if ((param_addr_ptr == NULL) ||
+		(((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_ECB_MODE) &&
+		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CBC_MODE) &&
+		((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) != FCS_CRYPTO_CTR_MODE))) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
+
 	/*
 	 * Since crypto param size vary between mode.
 	 * Check CBC/CTR here and limit to size 28 bytes
@@ -2189,7 +2209,12 @@ int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
-	if (mbox_error == NULL) {
+	/*
+	 * Since crypto param size vary between mode.
+	 * Check ECB here and limit to size 12 bytes
+	 */
+	if (((*param_addr_ptr & FCS_CRYPTO_BLOCK_MODE_MASK) == FCS_CRYPTO_ECB_MODE) &&
+		(param_size > FCS_CRYPTO_ECB_BUFFER_SIZE)) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
@@ -2200,8 +2225,8 @@ int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
 	fcs_aes_init_payload.param_size = param_size;
 	fcs_aes_init_payload.key_id	= key_id;
 
-	memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
-		(uint8_t *) param_addr, param_size);
+	memcpy_s(fcs_aes_init_payload.crypto_param, param_size / MBOX_WORD_BYTE,
+		(void *) param_addr, param_size / MBOX_WORD_BYTE);
 
 	fcs_aes_init_payload.is_updated = 0;
 
@@ -2234,7 +2259,8 @@ int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
 	}
 
 	if ((!is_8_bytes_aligned(dst_addr)) ||
-		(!is_32_bytes_aligned(dst_size))) {
+		(!is_32_bytes_aligned(dst_size)) ||
+		(!is_address_in_ddr_range(dst_addr, dst_size))) {
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
@@ -2280,9 +2306,10 @@ int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
 			return INTEL_SIP_SMC_STATUS_REJECTED;
 		}
 
-		memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
-			(uint8_t *) fcs_aes_init_payload.crypto_param,
-			fcs_aes_init_payload.param_size);
+		memcpy_s(&fcs_aes_crypt_payload[i],
+			fcs_aes_init_payload.param_size / MBOX_WORD_BYTE,
+			(void *) fcs_aes_init_payload.crypto_param,
+			fcs_aes_init_payload.param_size / MBOX_WORD_BYTE);
 
 		i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
 	}
diff --git a/plat/intel/soc/common/soc/socfpga_handoff.c b/plat/intel/soc/common/soc/socfpga_handoff.c
index 526c6e11..69747688 100644
--- a/plat/intel/soc/common/soc/socfpga_handoff.c
+++ b/plat/intel/soc/common/soc/socfpga_handoff.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,15 +16,21 @@
 int socfpga_get_handoff(handoff *reverse_hoff_ptr)
 {
 	int i;
+	int j;
 	uint32_t *buffer;
-	handoff *handoff_ptr = (handoff *) PLAT_HANDOFF_OFFSET;
+	uint32_t *handoff_ptr = (uint32_t *) PLAT_HANDOFF_OFFSET;
+	uint32_t *reverse_hoff_ptr_dst = (uint32_t *) reverse_hoff_ptr;
 
 	if (sizeof(*handoff_ptr) > sizeof(handoff)) {
 		return -EOVERFLOW;
 	}
 
-	memcpy(reverse_hoff_ptr, handoff_ptr, sizeof(handoff));
-	buffer = (uint32_t *)reverse_hoff_ptr;
+	for (j = 0; j < sizeof(handoff) / 4; j++) {
+		memcpy_s((void *) (reverse_hoff_ptr_dst + j), 1,
+			(void *) (handoff_ptr + j), 1);
+	}
+
+	buffer = (uint32_t *)reverse_hoff_ptr_dst;
 
 	/* convert big endian to little endian */
 	for (i = 0; i < sizeof(handoff) / 4; i++)
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index d93fc8a5..5d31e999 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -167,7 +168,7 @@ int mailbox_read_response(unsigned int *job_id, uint32_t *response,
 		}
 
 		if (MBOX_RESP_ERR(resp_data) > 0U) {
-			INFO("Error in response: %x\n", resp_data);
+			INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
 			return -MBOX_RESP_ERR(resp_data);
 		}
 
@@ -251,7 +252,7 @@ int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
 				return MBOX_RET_ERROR;
 			}
 
-			memcpy((uint8_t *) response,
+			memcpy_s((uint8_t *) response, *resp_len * MBOX_WORD_BYTE,
 				(uint8_t *) mailbox_resp_ctr.payload->data,
 				*resp_len * MBOX_WORD_BYTE);
 		}
@@ -336,7 +337,7 @@ int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
 			}
 
 			if (MBOX_RESP_ERR(resp_data) > 0U) {
-				INFO("Error in response: %x\n", resp_data);
+				INFO("SDM response: Return Code: 0x%x\n", MBOX_RESP_ERR(resp_data));
 				return -MBOX_RESP_ERR(resp_data);
 			}
 
@@ -578,6 +579,13 @@ int mailbox_rsu_status(uint32_t *resp_buf, unsigned int resp_buf_len)
 	return ret;
 }
 
+int mailbox_rsu_get_device_info(uint32_t *resp_buf, unsigned int resp_buf_len)
+{
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_GET_DEVICE_INFO, NULL, 0U,
+				CMD_CASUAL, resp_buf,
+				&resp_buf_len);
+}
+
 int mailbox_rsu_update(uint32_t *flash_offset)
 {
 	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
@@ -644,7 +652,7 @@ int intel_mailbox_get_config_status(uint32_t cmd, bool init_done)
 
 	res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
 	if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
-		ERROR("SoftFunction Status SEU ERROR\n");
+		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
 	}
 
 	if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
@@ -696,3 +704,9 @@ int mailbox_seu_err_status(uint32_t *resp_buf, unsigned int resp_buf_len)
 				CMD_CASUAL, resp_buf,
 				&resp_buf_len);
 }
+
+int mailbox_safe_inject_seu_err(uint32_t *arg, unsigned int len)
+{
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SAFE_INJECT_SEU_ERR, arg, len,
+			CMD_CASUAL, NULL, NULL);
+}
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index 7db86c78..c7d70767 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -75,7 +76,7 @@ void deassert_peripheral_reset(void)
 			RSTMGR_FIELD(PER0, DMAIF6) |
 			RSTMGR_FIELD(PER0, DMAIF7));
 
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
+#if (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || (PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5)
 	mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_FIELD(BRG, MPFE));
 #endif
@@ -106,30 +107,11 @@ static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match, uint32
 		}
 		udelay(1000);
 	}
-	return -ETIMEDOUT;
-}
-
-#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-static int poll_idle_status_by_counter(uint32_t addr, uint32_t mask,
-					uint32_t match, uint32_t delay_ms)
-{
-	int time_out = delay_ms;
-
-	while (time_out-- > 0) {
-
-		if ((mmio_read_32(addr) & mask) == match) {
-			return 0;
-		}
 
-		/* ToDo: Shall use udelay for product release */
-		for (int i = 0; i < 2000; i++) {
-			/* dummy delay */
-		}
-	}
 	return -ETIMEDOUT;
 }
-#endif
 
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 static int poll_idle_status_by_clkcycles(uint32_t addr, uint32_t mask,
 					 uint32_t match, uint32_t delay_clk_cycles)
 {
@@ -144,6 +126,7 @@ static int poll_idle_status_by_clkcycles(uint32_t addr, uint32_t mask,
 	}
 	return -ETIMEDOUT;
 }
+#endif
 
 static void socfpga_s2f_bridge_mask(uint32_t mask,
 				    uint32_t *brg_mask,
@@ -404,9 +387,11 @@ int socfpga_bridges_reset(uint32_t mask)
 	return ret;
 }
 
+/* TODO: Function too long, shall refactor */
 int socfpga_bridges_enable(uint32_t mask)
 {
 	int ret = 0;
+	int ret_hps = 0;
 	uint32_t brg_mask = 0;
 	uint32_t noc_mask = 0;
 	uint32_t f2s_idlereq = 0;
@@ -416,84 +401,182 @@ int socfpga_bridges_enable(uint32_t mask)
 	uint32_t f2s_respempty = 0;
 	uint32_t f2s_cmdidle = 0;
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-	uint32_t delay = 0;
+	uint32_t brg_lst = 0;
 #endif
 
 	/* Enable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
-	/* Enable SOC2FPGA bridge */
-	if (brg_mask & RSTMGR_BRGMODRSTMASK_SOC2FPGA) {
-		/* Write Reset Manager hdskreq[soc2fpga_flush_req] = 1 */
-		NOTICE("Set S2F hdskreq ...\n");
+/**************** SOC2FPGA ****************/
+	brg_lst = mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST));
+	if ((brg_mask & RSTMGR_BRGMODRSTMASK_SOC2FPGA)
+		&& ((brg_lst & RSTMGR_BRGMODRSTMASK_SOC2FPGA) != 0)) {
+		/*
+		 * To request handshake
+		 * Write Reset Manager hdskreq[soc2fpga_flush_req] = 1
+		 */
+		VERBOSE("Set S2F hdskreq ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_SOC2FPGAREQ);
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKREQ_SOC2FPGAREQ));
 
-		/* Read Reset Manager hdskack[soc2fpga] = 1 */
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_SOC2FPGAACK, RSTMGR_HDSKACK_SOC2FPGAACK,
-			300);
+		udelay(1000);
+
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[soc2fpga] = 1
+		 */
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_SOC2FPGA) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKREQ_SOC2FPGAREQ, RSTMGR_HDSKREQ_SOC2FPGAREQ,
+				300);
+		}
+
+		udelay(1000);
 
 		if (ret < 0) {
 			ERROR("S2F bridge enable: Timeout hdskack\n");
 		}
 
-		/* Write Reset Manager hdskreq[soc2fpga_flush_req] = 0 */
-		NOTICE("Clear S2F hdskreq ...\n");
+		/*
+		 * To assert reset
+		 * Write Reset Manager hdskreq[soc2fpga_flush_req] = 0
+		 */
+		VERBOSE("Assert S2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+		(~brg_lst & 0x3) | RSTMGR_BRGMODRST_SOC2FPGA);
+
+		udelay(1000);
+
+		/*
+		 * To clear idle request
+		 * Write Reset Manager hdskreq[soc2fpga_flush_req] = 0
+		 */
+		VERBOSE("Clear S2F hdskreq ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_SOC2FPGAREQ);
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKREQ_SOC2FPGAREQ));
 
-		/* Write Reset Manager brgmodrst[soc2fpga] = 1 */
-		NOTICE("Assert S2F ...\n");
-		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
-			RSTMGR_BRGMODRST_SOC2FPGA);
+		udelay(1000);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		/*
+		 * To clear ack status
+		 * Write Reset Manager hdskack[soc2fpga_flush_ack] = 1
+		 * This bit is W1S/W1C
+		 */
+		VERBOSE("Clear S2F hdskack ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKACK),
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKACK_SOC2FPGAACK));
+
+		udelay(1000);
 
-		/* Write Reset Manager brgmodrst[soc2fpga] = 0 */
-		NOTICE("Deassert S2F ...\n");
+		/*
+		 * To deassert reset
+		 * Write Reset Manager brgmodrst[soc2fpga] = 0
+		 */
+		VERBOSE("Deassert S2F ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
-			RSTMGR_BRGMODRST_SOC2FPGA);
+				(~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
+				| RSTMGR_BRGMODRST_LWHPS2FPGA))
+				| RSTMGR_BRGMODRST_SOC2FPGA);
+
+		/* Set System Manager soc bridge control register[soc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Set SOC soc2fpga_ready_latency_enable ...\n");
+		mmio_setbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_SOC_BRIDGE_CTRL_EN);
 	}
 
+/**************** LWSOCFPGA ****************/
+
 	/* Enable LWSOC2FPGA bridge */
-	if (brg_mask & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA) {
-		/* Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 1 */
-		NOTICE("Set LWS2F hdskreq ...\n");
+	brg_lst = mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST));
+	if ((brg_mask & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA)
+			&& ((brg_lst & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA) != 0)) {
+		/*
+		 * To request handshake
+		 * Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 1
+		 */
+		VERBOSE("Set LWS2F hdskreq ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_LWSOC2FPGAREQ);
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKREQ_LWSOC2FPGAREQ));
 
-		/* Read Reset Manager hdskack[lwsoc2fpga] = 1 */
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_LWSOC2FPGAACK, RSTMGR_HDSKACK_LWSOC2FPGAACK,
-			300);
+		udelay(1000);
+
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[lwsoc2fpga] = 1
+		 */
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_LWHPS2FPGA) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKREQ_LWSOC2FPGAREQ, RSTMGR_HDSKREQ_LWSOC2FPGAREQ,
+				300);
+		}
+
+		udelay(1000);
 
 		if (ret < 0) {
 			ERROR("LWS2F bridge enable: Timeout hdskack\n");
 		}
 
-		/* Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 0 */
-		NOTICE("Clear LWS2F hdskreq ...\n");
+		/*
+		 * To assert reset
+		 * Write Reset Manager brgmodrst[lwsoc2fpga] = 1
+		 */
+		VERBOSE("Assert LWS2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+				(~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
+				| RSTMGR_BRGMODRST_LWHPS2FPGA))
+				| RSTMGR_BRGMODRST_LWHPS2FPGA);
+
+		udelay(1000);
+
+		/*
+		 * To clear idle request
+		 * Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 0
+		 */
+		VERBOSE("Clear LWS2F hdskreq ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-			RSTMGR_HDSKREQ_LWSOC2FPGAREQ);
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKREQ_LWSOC2FPGAREQ));
 
-		/* Write Reset Manager brgmodrst[lwsoc2fpga] = 1 */
-		NOTICE("Assert LWS2F ...\n");
-		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
-			RSTMGR_BRGMODRST_LWHPS2FPGA);
+		udelay(1000);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		/*
+		 * To clear ack status
+		 * Write Reset Manager hdskack[lwsoc2fpga_flush_ack] = 1
+		 * This bit is W1S/W1C
+		 */
+		VERBOSE("Clear LWS2F hdskack ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKACK),
+				((~(brg_lst) << 9) & (RSTMGR_HDSKREQ_LWSOC2FPGAREQ
+				| RSTMGR_HDSKREQ_SOC2FPGAREQ))
+				| (RSTMGR_HDSKACK_SOC2FPGAACK));
 
-		/* Write Reset Manager brgmodrst[lwsoc2fpga] = 0 */
-		NOTICE("Deassert LWS2F ...\n");
+		udelay(1000);
+
+		/*
+		 * To deassert reset
+		 * Write Reset Manager brgmodrst[lwsoc2fpga] = 0
+		 */
+		VERBOSE("Deassert LWS2F ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
-			RSTMGR_BRGMODRST_LWHPS2FPGA);
+				((~brg_lst & (RSTMGR_BRGMODRST_SOC2FPGA
+				| RSTMGR_BRGMODRST_LWHPS2FPGA)))
+				| RSTMGR_BRGMODRST_LWHPS2FPGA);
+
+		/* Set System Manager lwsoc bridge control register[lwsoc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Set LWSOC lwsoc2fpga_ready_latency_enable ...\n");
+		mmio_setbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_LWSOC_BRIDGE_CTRL_EN);
 	}
 #else
 	if (brg_mask != 0U) {
@@ -505,11 +588,8 @@ int socfpga_bridges_enable(uint32_t mask)
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
 
 		/* Wait until idle ack becomes 0 */
-		ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
-				       noc_mask, 0, 300);
-		if (ret < 0) {
-			ERROR("S2F bridge enable: Timeout idle ack\n");
-		}
+		ret_hps = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
+				       noc_mask, 0, 1000);
 	}
 #endif
 
@@ -519,173 +599,252 @@ int socfpga_bridges_enable(uint32_t mask)
 				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 	/* Enable FPGA2SOC bridge */
-	if (brg_mask & RSTMGR_BRGMODRSTMASK_FPGA2SOC) {
-		/* Write Reset Manager hdsken[fpgahsen] = 1 */
-		NOTICE("Set FPGA hdsken(fpgahsen) ...\n");
+
+	if ((brg_mask & RSTMGR_BRGMODRSTMASK_FPGA2SOC)
+		&& ((brg_lst & RSTMGR_BRGMODRSTMASK_FPGA2SOC) != 0)) {
+		/*
+		 * To request handshake
+		 * Write Reset Manager hdsken[fpgahsen] = 1
+		 */
+		VERBOSE("Set FPGA hdsken(fpgahsen) ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
 
-		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
-		NOTICE("Set FPGA hdskreq(fpgahsreq) ...\n");
+		/*
+		 * To request handshake
+		 * Write Reset Manager hdskreq[fpgahsreq] = 1
+		 */
+		VERBOSE("Set FPGA hdskreq(fpgahsreq) ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
 
-		/* Read Reset Manager hdskack[fpgahsack] = 1 */
-		NOTICE("Get FPGA hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
-			300);
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[fpgahsack] = 1
+		 */
+		VERBOSE("Get FPGA hdskack(fpgahsack) ...\n");
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("FPGA bridge fpga handshake fpgahsreq: Timeout\n");
 		}
 
-		/* Write Reset Manager hdskreq[f2s_flush_req] = 1 */
-		NOTICE("Set F2S hdskreq(f2s_flush_req) ...\n");
+		/*
+		 * To fence and drain traffic
+		 * Write Reset Manager hdskreq[f2s_flush_req] = 1
+		 */
+		VERBOSE("Set F2S hdskreq(f2s_flush_req) ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
 			RSTMGR_HDSKREQ_FPGA2SOCREQ);
 
-		/* Read Reset Manager hdskack[f2s_flush_ack] = 1 */
-		NOTICE("Get F2S hdskack(f2s_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK,
-			300);
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[f2s_flush_ack] = 1
+		 */
+		VERBOSE("Get F2S hdskack(f2s_flush_ack) ...\n");
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2S bridge fpga handshake f2sdram_flush_req: Timeout\n");
 		}
 
-		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
-		NOTICE("Clear FPGA hdskreq(fpgahsreq) ...\n");
+		/*
+		 * To clear idle request
+		 * Write Reset Manager hdskreq[fpgahsreq] = 1
+		 */
+		VERBOSE("Clear FPGA hdskreq(fpgahsreq) ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
 
-		/* Write Reset Manager hdskreq[f2s_flush_req] = 1 */
-		NOTICE("Clear F2S hdskreq(f2s_flush_req) ...\n");
+		/*
+		 * To clear idle request
+		 * Write Reset Manager hdskreq[f2s_flush_req] = 1
+		 */
+		VERBOSE("Clear F2S hdskreq(f2s_flush_req) ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
 			RSTMGR_HDSKREQ_FPGA2SOCREQ);
 
-		/* Read Reset Manager hdskack[f2s_flush_ack] = 0 */
-		NOTICE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
-			300);
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[f2s_flush_ack] = 0
+		 */
+		VERBOSE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
 		}
 
-		/* Read Reset Manager hdskack[fpgahsack] = 0 */
-		NOTICE("Get FPGA hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
-			300);
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[fpgahsack] = 0
+		 */
+		VERBOSE("Get FPGA hdskack(fpgahsack) ...\n");
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRST_FPGA2SOC) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+				300);
+				}
 
 		if (ret < 0) {
 			ERROR("F2S bridge fpga handshake fpgahsack: Timeout\n");
 		}
 
-		/* Write Reset Manager brgmodrst[fpga2soc] = 1 */
-		NOTICE("Assert F2S ...\n");
+		/*
+		 * To assert reset
+		 * Write Reset Manager brgmodrst[fpga2soc] = 1
+		 */
+		VERBOSE("Assert F2S ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
+		udelay(1000);
 
-		/* Write Reset Manager brgmodrst[fpga2soc] = 0 */
-		NOTICE("Deassert F2S ...\n");
+		/*
+		 * To deassert reset
+		 * Write Reset Manager brgmodrst[fpga2soc] = 0
+		 */
+		VERBOSE("Deassert F2S ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
 
 		/* Write System Manager f2s bridge control register[f2soc_enable] = 1 */
-		NOTICE("Deassert F2S f2soc_enable ...\n");
+		VERBOSE("Deassert F2S f2soc_enable ...\n");
 		mmio_setbits_32(SOCFPGA_SYSMGR(F2S_BRIDGE_CTRL),
 			SYSMGR_F2S_BRIDGE_CTRL_EN);
 	}
 
 	/* Enable FPGA2SDRAM bridge */
-	if (brg_mask & RSTMGR_BRGMODRSTMASK_F2SDRAM0) {
-		/* Write Reset Manager hdsken[fpgahsen] = 1 */
-		NOTICE("Set F2SDRAM hdsken(fpgahsen) ...\n");
+	if ((brg_mask & RSTMGR_BRGMODRSTMASK_F2SDRAM0)
+		&& ((brg_lst & RSTMGR_BRGMODRSTMASK_F2SDRAM0) != 0)) {
+		/*
+		 * To request handshake
+		 * Write Reset Manager hdsken[fpgahsen] = 1
+		 */
+		VERBOSE("Set F2SDRAM hdsken(fpgahsen) ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
 
-		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
-		NOTICE("Set F2SDRAM hdskreq(fpgahsreq) ...\n");
+		/*
+		 * To request handshake
+		 * Write Reset Manager hdskreq[fpgahsreq] = 1
+		 */
+		VERBOSE("Set F2SDRAM hdskreq(fpgahsreq) ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
 
-		/* Read Reset Manager hdskack[fpgahsack] = 1 */
-		NOTICE("Get F2SDRAM hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
-			300);
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[fpgahsack] = 1
+		 */
+		VERBOSE("Get F2SDRAM hdskack(fpgahsack) ...\n");
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRSTMASK_F2SDRAM0) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2SDRAM bridge fpga handshake fpgahsreq: Timeout\n");
 		}
 
-		/* Write Reset Manager hdskreq[f2sdram_flush_req] = 1 */
-		NOTICE("Set F2SDRAM hdskreq(f2sdram_flush_req) ...\n");
+		/*
+		 * To fence and drain traffic
+		 * Write Reset Manager hdskreq[f2sdram_flush_req] = 1
+		 */
+		VERBOSE("Set F2SDRAM hdskreq(f2sdram_flush_req) ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
 			RSTMGR_HDSKREQ_F2SDRAM0REQ);
 
-		/* Read Reset Manager hdskack[f2sdram_flush_ack] = 1 */
-		NOTICE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK,
-			300);
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[f2sdram_flush_ack] = 1
+		 */
+		VERBOSE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRSTMASK_F2SDRAM0) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2SDRAM bridge fpga handshake f2sdram_flush_req: Timeout\n");
 		}
 
-		/* Write Reset Manager hdskreq[fpgahsreq] = 1 */
-		NOTICE("Clear F2SDRAM hdskreq(fpgahsreq) ...\n");
+		/*
+		 * To clear idle request
+		 * Write Reset Manager hdskreq[fpgahsreq] = 1
+		 */
+		VERBOSE("Clear F2SDRAM hdskreq(fpgahsreq) ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
 
-		/* Write Reset Manager hdskreq[f2sdram_flush_req] = 1 */
-		NOTICE("Clear F2SDRAM hdskreq(f2sdram_flush_req) ...\n");
+		/*
+		 * To clear idle request
+		 * Write Reset Manager hdskreq[f2sdram_flush_req] = 1
+		 */
+		VERBOSE("Clear F2SDRAM hdskreq(f2sdram_flush_req) ...\n");
 		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_F2SDRAM0REQ);
 
-		/* Read Reset Manager hdskack[f2sdram_flush_ack] = 0 */
-		NOTICE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT,
-			300);
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[f2sdram_flush_ack] = 0
+		 */
+		VERBOSE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRSTMASK_F2SDRAM0) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2SDRAM bridge fpga handshake f2sdram_flush_ack: Timeout\n");
 		}
 
-		/* Read Reset Manager hdskack[fpgahsack] = 0 */
-		NOTICE("Get F2SDRAM hdskack(fpgahsack) ...\n");
-		ret = poll_idle_status_by_counter(SOCFPGA_RSTMGR(HDSKACK),
-			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
-			300);
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[fpgahsack] = 0
+		 */
+		VERBOSE("Get F2SDRAM hdskack(fpgahsack) ...\n");
+		if ((mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST))
+				& RSTMGR_BRGMODRSTMASK_F2SDRAM0) == 0x00) {
+			ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+				RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+				300);
+		}
 
 		if (ret < 0) {
 			ERROR("F2SDRAM bridge fpga handshake fpgahsack: Timeout\n");
 		}
 
-		/* Write Reset Manager brgmodrst[fpga2sdram] = 1 */
-		NOTICE("Assert F2SDRAM ...\n");
+		/*
+		 * To assert reset
+		 * Write Reset Manager brgmodrst[fpga2sdram] = 1
+		 */
+		VERBOSE("Assert F2SDRAM ...\n");
 		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
 			RSTMGR_BRGMODRST_F2SSDRAM0);
 
-		/* ToDo: Shall use udelay for product release */
-		for (delay = 0; delay < 1000; delay++) {
-			/* dummy delay */
-		}
-
-		/* Write Reset Manager brgmodrst[fpga2sdram] = 0 */
-		NOTICE("Deassert F2SDRAM ...\n");
-		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
-			RSTMGR_BRGMODRST_F2SSDRAM0);
+		udelay(1000);
 
 		/*
-		 * Clear fpga2sdram_manager_main_SidebandManager_FlagOutClr0
-		 * f2s_ready_latency_enable
+		 * To deassert reset
+		 * Write Reset Manager brgmodrst[fpga2sdram] = 0
 		 */
-		NOTICE("Clear F2SDRAM f2s_ready_latency_enable ...\n");
-		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
-			FLAGOUTCLR0_F2SDRAM0_ENABLE);
+		VERBOSE("Deassert F2SDRAM ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_F2SSDRAM0);
 	}
 #else
 	if (brg_mask != 0U) {
@@ -711,6 +870,7 @@ int socfpga_bridges_enable(uint32_t mask)
 		udelay(5);
 	}
 #endif
+	ret = ret | ret_hps;
 	return ret;
 }
 
@@ -774,6 +934,83 @@ int socfpga_bridges_disable(uint32_t mask)
 
 	/* Disable s2f bridge */
 	socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* Disable SOC2FPGA bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_SOC2FPGA) {
+		/*
+		 * To clear handshake
+		 * Write Reset Manager hdskreq[soc2fpga_flush_req] = 0
+		 */
+		VERBOSE("Set S2F hdskreq ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_SOC2FPGAREQ);
+
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[soc2fpga] = 0
+		 */
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_SOC2FPGAACK, RSTMGR_HDSKACK_SOC2FPGAACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("S2F bridge enable: Timeout hdskack\n");
+		}
+
+		/*
+		 * To assert reset
+		 * Write Reset Manager brgmodrst[soc2fpga] = 1
+		 */
+		VERBOSE("Assert S2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_SOC2FPGA);
+
+		/* Clear System Manager soc bridge control register[soc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Clear SOC soc2fpga_ready_latency_enable ...\n");
+		mmio_clrbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_SOC_BRIDGE_CTRL_EN);
+
+		udelay(1000);
+	}
+
+	/* Disable LWSOC2FPGA bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_LWHPS2FPGA) {
+		/*
+		 * To clear handshake
+		 * Write Reset Manager hdskreq[lwsoc2fpga_flush_req] = 0
+		 */
+		VERBOSE("Set LWS2F hdskreq ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_LWSOC2FPGAREQ);
+
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[lwsoc2fpga] = 0
+		 */
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_LWSOC2FPGAACK, RSTMGR_HDSKACK_LWSOC2FPGAACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("LWS2F bridge enable: Timeout hdskack\n");
+		}
+
+		/*
+		 * To assert reset
+		 * Write Reset Manager brgmodrst[lwsoc2fpga] = 1
+		 */
+		VERBOSE("Assert LWS2F ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_LWHPS2FPGA);
+
+		/* Clear System Manager lwsoc bridge control register[lwsoc2fpga_ready_latency_enable] = 1 */
+		VERBOSE("Clear LWSOC lwsoc2fpga_ready_latency_enable ...\n");
+		mmio_clrbits_32(SOCFPGA_SYSMGR(FPGA_BRIDGE_CTRL),
+			SYSMGR_LWSOC_BRIDGE_CTRL_EN);
+
+		udelay(1000);
+	}
+#else
 	if (brg_mask != 0U) {
 		mmio_setbits_32(SOCFPGA_SYSMGR(NOC_IDLEREQ_SET),
 				noc_mask);
@@ -796,11 +1033,146 @@ int socfpga_bridges_disable(uint32_t mask)
 
 		mmio_write_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 0);
 	}
+#endif
 
 	/* Disable f2s bridge */
 	socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
 				&f2s_force_drain, &f2s_en,
 				&f2s_idleack, &f2s_respempty, &f2s_cmdidle);
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	/* Disable FPGA2SOC bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_FPGA2SOC) {
+		/*
+		 * To request handshake
+		 * Write Reset Manager hdsken[fpgahsen] = 1
+		 */
+		VERBOSE("Set FPGA hdsken(fpgahsen) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
+
+		/*
+		 * To clear handshake request
+		 * Write Reset Manager hdskreq[fpgahsreq] = 0
+		 */
+		VERBOSE("Clear FPGA hdskreq(fpgahsreq) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/*
+		 * To clear handshake request
+		 * Write Reset Manager hdskreq[f2s_flush_req] = 0
+		 */
+		VERBOSE("Clear F2S hdskreq(f2s_flush_req) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
+			RSTMGR_HDSKREQ_FPGA2SOCREQ);
+
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[f2s_flush_ack] = 0
+		 */
+		VERBOSE("Get F2SDRAM hdskack(f2s_flush_ack) ...\n");
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGA2SOCACK, RSTMGR_HDSKACK_FPGA2SOCACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake f2s_flush_ack: Timeout\n");
+		}
+
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[fpgahsack] = 0
+		 */
+		VERBOSE("Get FPGA hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2S bridge fpga handshake fpgahsack: Timeout\n");
+		}
+
+		/*
+		 * To assert reset
+		 * Write Reset Manager brgmodrst[fpga2soc] = 1
+		 */
+		VERBOSE("Assert F2S ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_BRGMODRST_FPGA2SOC);
+
+		udelay(1000);
+
+		/* Write System Manager f2s bridge control register[f2soc_enable] = 0 */
+		VERBOSE("Assert F2S f2soc_enable ...\n");
+		mmio_clrbits_32(SOCFPGA_SYSMGR(F2S_BRIDGE_CTRL),
+			SYSMGR_F2S_BRIDGE_CTRL_EN);
+	}
+
+	/* Disable FPGA2SDRAM bridge */
+	if (brg_mask & RSTMGR_BRGMODRSTMASK_F2SDRAM0) {
+		/*
+		 * To request handshake
+		 * Write Reset Manager hdsken[fpgahsen] = 1
+		 */
+		VERBOSE("Set F2SDRAM hdsken(fpgahsen) ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_FPGAHSEN);
+
+		/*
+		 * To clear handshake request
+		 * Write Reset Manager hdskreq[fpgahsreq] = 0
+		 */
+		VERBOSE("Clear F2SDRAM hdskreq(fpgahsreq) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_FPGAHSREQ);
+
+		/*
+		 * To clear handshake request
+		 * Write Reset Manager hdskreq[f2sdram_flush_req] = 0
+		 */
+		VERBOSE("Clear F2SDRAM hdskreq(f2sdram_flush_req) ...\n");
+		mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ), RSTMGR_HDSKREQ_F2SDRAM0REQ);
+
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[f2sdram_flush_ack] = 0
+		 */
+		VERBOSE("Get F2SDRAM hdskack(f2sdram_flush_ack) ...\n");
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_F2SDRAM0ACK, RSTMGR_HDSKACK_F2SDRAM0ACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake f2sdram_flush_ack: Timeout\n");
+		}
+
+		/*
+		 * To poll idle status
+		 * Read Reset Manager hdskack[fpgahsack] = 0
+		 */
+		VERBOSE("Get F2SDRAM hdskack(fpgahsack) ...\n");
+		ret = poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
+			RSTMGR_HDSKACK_FPGAHSACK, RSTMGR_HDSKACK_FPGAHSACK_DASRT,
+			300);
+
+		if (ret < 0) {
+			ERROR("F2SDRAM bridge fpga handshake fpgahsack: Timeout\n");
+		}
+
+		/*
+		 * To assert reset
+		 * Write Reset Manager brgmodrst[fpga2sdram] = 1
+		 */
+		VERBOSE("Assert F2SDRAM ...\n");
+		mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
+			RSTMGR_BRGMODRST_F2SSDRAM0);
+
+		udelay(1000);
+
+		/*
+		 * Assert fpga2sdram_manager_main_SidebandManager_FlagOutClr0
+		 * f2s_ready_latency_enable
+		 */
+		VERBOSE("Assert F2SDRAM f2s_ready_latency_enable ...\n");
+		mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+			FLAGOUTCLR0_F2SDRAM0_ENABLE);
+	}
+#else
 	if (brg_mask != 0U) {
 
 		if (mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST)) & brg_mask) {
@@ -843,6 +1215,7 @@ int socfpga_bridges_disable(uint32_t mask)
 		mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
 				f2s_idlereq);
 	}
+#endif
 
 	return ret;
 }
@@ -910,4 +1283,4 @@ int socfpga_cpurstrelease(unsigned int cpu_id)
 	} while (timeout-- > 0);
 
 	return RSTMGR_RET_ERROR;
-}
+}
\ No newline at end of file
diff --git a/plat/intel/soc/common/soc/socfpga_system_manager.c b/plat/intel/soc/common/soc/socfpga_system_manager.c
new file mode 100644
index 00000000..4223b2b1
--- /dev/null
+++ b/plat/intel/soc/common/soc/socfpga_system_manager.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include "socfpga_system_manager.h"
+
+uint32_t intel_hps_get_jtag_id(void)
+{
+	uint32_t jtag_id = 0x00;
+
+	jtag_id = (mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_4)));
+
+	INFO("%s: JTAG ID: 0x%x\n", __func__, jtag_id);
+
+	return jtag_id;
+}
+
+/* Check for Agilex5 SM4 */
+bool is_agilex5_A5F0(void)
+{
+	return ((intel_hps_get_jtag_id() & JTAG_ID_MASK) == A5F0_JTAG_ID);
+}
diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c
index 8fce5cf8..37590094 100644
--- a/plat/intel/soc/common/socfpga_delay_timer.c
+++ b/plat/intel/soc/common/socfpga_delay_timer.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +11,6 @@
 #include <lib/mmio.h>
 #include "socfpga_plat_def.h"
 
-
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
 #include "agilex_clock_manager.h"
 #elif PLATFORM_MODEL == PLAT_SOCFPGA_N5X
@@ -19,7 +19,7 @@
 #include "s10_clock_manager.h"
 #endif
 
-#define SOCFPGA_GLOBAL_TIMER		0xffd01000
+#define SOCFPGA_GLOBAL_TIMER		PLAT_TIMER_BASE_ADDR
 #define SOCFPGA_GLOBAL_TIMER_EN		0x3
 
 static timer_ops_t plat_timer_ops;
@@ -44,7 +44,6 @@ void socfpga_delay_timer_init_args(void)
 	plat_timer_ops.clk_div		= PLAT_SYS_COUNTER_FREQ_IN_MHZ;
 
 	timer_init(&plat_timer_ops);
-
 }
 
 void socfpga_delay_timer_init(void)
@@ -52,9 +51,6 @@ void socfpga_delay_timer_init(void)
 	socfpga_delay_timer_init_args();
 	mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN);
 
-	NOTICE("BL31 CLK freq = %d MHz\n", PLAT_SYS_COUNTER_FREQ_IN_MHZ);
-
 	asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
 	asm volatile("msr cntp_tval_el0, %0" : : "r" (~0));
-
 }
diff --git a/plat/intel/soc/common/socfpga_image_load.c b/plat/intel/soc/common/socfpga_image_load.c
index a5c32799..ee791584 100644
--- a/plat/intel/soc/common/socfpga_image_load.c
+++ b/plat/intel/soc/common/socfpga_image_load.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,7 +13,13 @@
  ******************************************************************************/
 void plat_flush_next_bl_params(void)
 {
+	/*
+	 * We cannot flush these descriptors on the Agilex5 platform,
+	 * since the BL2 runs on the OCRAM and this OCRAM is not cache coherent.
+	 */
+#if PLATFORM_MODEL != PLAT_SOCFPGA_AGILEX5
 	flush_bl_params_desc();
+#endif
 }
 
 /*******************************************************************************
diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index c93e13f5..50d4820a 100644
--- a/plat/intel/soc/common/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,8 +17,13 @@
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
 #include <plat/common/platform.h>
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+#include "agilex5_cache.h"
+#endif
+#include "ccu/ncore_ccu.h"
 #include "socfpga_mailbox.h"
 #include "socfpga_plat_def.h"
+#include "socfpga_private.h"
 #include "socfpga_reset_manager.h"
 #include "socfpga_sip_svc.h"
 #include "socfpga_system_manager.h"
@@ -183,11 +189,20 @@ static void __dead2 socfpga_system_reset(void)
 {
 	uint32_t addr_buf[2];
 
-	memcpy(addr_buf, &intel_rsu_update_address,
-			sizeof(intel_rsu_update_address));
+	memcpy_s(addr_buf, sizeof(intel_rsu_update_address),
+		&intel_rsu_update_address, sizeof(intel_rsu_update_address));
+
 	if (intel_rsu_update_address) {
 		mailbox_rsu_update(addr_buf);
 	} else {
+#if CACHE_FLUSH
+		/* ATF Flush and Invalidate Cache */
+		dcsw_op_all(DCCISW);
+		invalidate_cache_low_el();
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+		flush_l3_dcache();
+#endif
+#endif
 		mailbox_reset_cold();
 	}
 
@@ -198,6 +213,16 @@ static void __dead2 socfpga_system_reset(void)
 static int socfpga_system_reset2(int is_vendor, int reset_type,
 					u_register_t cookie)
 {
+
+#if CACHE_FLUSH
+	/*
+	 * ATF Flush and Invalidate Cache due to hardware limitation
+	 * of auto Flush and Invalidate Cache.
+	 */
+	dcsw_op_all(DCCISW);
+	invalidate_cache_low_el();
+#endif
+
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
 	mailbox_reset_warm(reset_type);
 #else
diff --git a/plat/intel/soc/common/socfpga_ros.c b/plat/intel/soc/common/socfpga_ros.c
new file mode 100644
index 00000000..ea373845
--- /dev/null
+++ b/plat/intel/soc/common/socfpga_ros.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2024, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* system header files*/
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+/* CRC function header */
+#include <common/tf_crc32.h>
+
+/* Cadense qspi driver*/
+#include <qspi/cadence_qspi.h>
+
+/* Mailbox driver*/
+#include <socfpga_mailbox.h>
+
+#include <socfpga_ros.h>
+
+static void swap_bits(char *const data, uint32_t len)
+{
+	uint32_t x, y;
+	char tmp;
+
+	for (x = 0U; x < len; x++) {
+		tmp = 0U;
+		for (y = 0U; y < 8; y++) {
+			tmp <<= 1;
+			if (data[x] & 1) {
+				tmp |= 1;
+			}
+			data[x] >>= 1;
+		}
+		data[x] = tmp;
+	}
+}
+
+static uint32_t get_current_image_index(spt_table_t *spt_buf, uint32_t *const img_index)
+{
+	if (spt_buf == NULL || img_index == NULL) {
+		return ROS_RET_INVALID;
+	}
+
+	uint32_t ret;
+	unsigned long current_image;
+	uint32_t rsu_status[RSU_STATUS_RES_SIZE];
+
+	if (spt_buf->partitions < SPT_MIN_PARTITIONS || spt_buf->partitions > SPT_MAX_PARTITIONS) {
+		return ROS_IMAGE_PARTNUM_OVFL;
+	}
+
+	ret = mailbox_rsu_status(rsu_status, RSU_STATUS_RES_SIZE);
+	if (ret != MBOX_RET_OK) {
+		return ROS_RET_NOT_RSU_MODE;
+	}
+
+	current_image = ADDR_64(rsu_status[1], rsu_status[0]);
+	NOTICE("ROS: Current image is at 0x%08lx\n", current_image);
+
+	*img_index = 0U;
+	for (uint32_t index = 0U ; index < spt_buf->partitions; index++) {
+		if (spt_buf->partition[index].offset == current_image) {
+			*img_index = index;
+			break;
+		}
+	}
+
+	if (*img_index == 0U) {
+		return ROS_IMAGE_INDEX_ERR;
+	}
+
+	return ROS_RET_OK;
+}
+
+static uint32_t load_and_check_spt(spt_table_t *spt_ptr, size_t offset)
+{
+
+	if (spt_ptr == NULL || offset == 0U) {
+		return ROS_RET_INVALID;
+	}
+
+	int ret;
+	uint32_t calc_crc;
+	static spt_table_t spt_data;
+
+	ret = cad_qspi_read(spt_ptr, offset, SPT_SIZE);
+	if (ret != 0U) {
+		return ROS_QSPI_READ_ERROR;
+	}
+
+	if (spt_ptr->magic_number != SPT_MAGIC_NUMBER) {
+		return ROS_SPT_BAD_MAGIC_NUM;
+	}
+
+	if (spt_ptr->partitions < SPT_MIN_PARTITIONS || spt_ptr->partitions > SPT_MAX_PARTITIONS) {
+		return ROS_IMAGE_PARTNUM_OVFL;
+	}
+
+	memcpy_s(&spt_data, SPT_SIZE, spt_ptr, SPT_SIZE);
+	spt_data.checksum = 0U;
+	swap_bits((char *)&spt_data, SPT_SIZE);
+
+	calc_crc = tf_crc32(0, (uint8_t *)&spt_data, SPT_SIZE);
+	if (bswap32(spt_ptr->checksum) != calc_crc) {
+		return ROS_SPT_CRC_ERROR;
+	}
+
+	NOTICE("ROS: SPT table at 0x%08lx is verified\n", offset);
+	return ROS_RET_OK;
+}
+
+static uint32_t get_spt(spt_table_t *spt_buf)
+{
+	if (spt_buf == NULL) {
+		return ROS_RET_INVALID;
+	}
+
+	uint32_t ret;
+	uint32_t spt_offset[RSU_GET_SPT_RESP_SIZE];
+
+	/* Get SPT offset from SDM via mailbox commands */
+	ret = mailbox_rsu_get_spt_offset(spt_offset, RSU_GET_SPT_RESP_SIZE);
+	if (ret != MBOX_RET_OK) {
+		WARN("ROS: Not booted in RSU mode\n");
+		return ROS_RET_NOT_RSU_MODE;
+	}
+
+	/* Print the SPT table addresses */
+	VERBOSE("ROS: SPT0 0x%08lx\n", ADDR_64(spt_offset[0], spt_offset[1]));
+	VERBOSE("ROS: SPT1 0x%08lx\n", ADDR_64(spt_offset[2], spt_offset[3]));
+
+	/* Load and validate SPT1*/
+	ret = load_and_check_spt(spt_buf, ADDR_64(spt_offset[2], spt_offset[3]));
+	if (ret != ROS_RET_OK) {
+		/* Load and validate SPT0*/
+		ret = load_and_check_spt(spt_buf, ADDR_64(spt_offset[0], spt_offset[1]));
+		if (ret != ROS_RET_OK) {
+			WARN("Both SPT tables are unusable\n");
+			return ret;
+		}
+	}
+
+	return ROS_RET_OK;
+}
+
+uint32_t ros_qspi_get_ssbl_offset(unsigned long *offset)
+{
+	if (offset == NULL) {
+		return ROS_RET_INVALID;
+	}
+
+	uint32_t ret, img_index;
+	char ssbl_name[SPT_PARTITION_NAME_LENGTH];
+	static spt_table_t spt;
+
+	ret = get_spt(&spt);
+	if (ret != ROS_RET_OK) {
+		return ret;
+	}
+
+	ret = get_current_image_index(&spt, &img_index);
+	if (ret != ROS_RET_OK) {
+		return ret;
+	}
+
+	if (strncmp(spt.partition[img_index].name, FACTORY_IMAGE,
+		SPT_PARTITION_NAME_LENGTH) == 0U) {
+		strlcpy(ssbl_name, FACTORY_SSBL, SPT_PARTITION_NAME_LENGTH);
+	} else {
+		strlcpy(ssbl_name, spt.partition[img_index].name,
+			SPT_PARTITION_NAME_LENGTH);
+		strlcat(ssbl_name, SSBL_SUFFIX, SPT_PARTITION_NAME_LENGTH);
+	}
+
+	for (uint32_t index = 0U; index < spt.partitions; index++) {
+		if (strncmp(spt.partition[index].name, ssbl_name,
+			SPT_PARTITION_NAME_LENGTH) == 0U) {
+			*offset = spt.partition[index].offset;
+			NOTICE("ROS: Corresponding SSBL is at 0x%08lx\n", *offset);
+			return ROS_RET_OK;
+		}
+	}
+
+	return ROS_IMAGE_INDEX_ERR;
+}
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index c6530cf3..3c223c14 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,6 +28,9 @@ static int read_block, max_blocks;
 static uint32_t send_id, rcv_id;
 static uint32_t bytes_per_block, blocks_submitted;
 static bool bridge_disable;
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+static uint32_t g_remapper_bypass;
+#endif
 
 /* RSU static variables */
 static uint32_t rsu_dcmf_ver[4] = {0};
@@ -229,6 +234,10 @@ static int intel_fpga_config_start(uint32_t flag)
 		request_type = BITSTREAM_AUTH;
 	}
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	intel_smmu_hps_remapper_init(0U);
+#endif
+
 	mailbox_clear_response();
 
 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_CANCEL, NULL, 0U,
@@ -280,6 +289,9 @@ static bool is_fpga_config_buffer_full(void)
 
 bool is_address_in_ddr_range(uint64_t addr, uint64_t size)
 {
+	uint128_t dram_max_sz = (uint128_t)DRAM_BASE + (uint128_t)DRAM_SIZE;
+	uint128_t dram_region_end = (uint128_t)addr + (uint128_t)size;
+
 	if (!addr && !size) {
 		return true;
 	}
@@ -289,7 +301,7 @@ bool is_address_in_ddr_range(uint64_t addr, uint64_t size)
 	if (addr < BL31_LIMIT) {
 		return false;
 	}
-	if (addr + size > DRAM_BASE + DRAM_SIZE) {
+	if (dram_region_end > dram_max_sz) {
 		return false;
 	}
 
@@ -307,6 +319,10 @@ static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
 		return INTEL_SIP_SMC_STATUS_REJECTED;
 	}
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	intel_smmu_hps_remapper_init(&mem);
+#endif
+
 	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
 		int j = (i + current_buffer) % FPGA_CONFIG_BUFFER_SIZE;
 
@@ -406,6 +422,7 @@ static int is_out_of_sec_range(uint64_t reg_addr)
 	case(SOCFPGA_MEMCTRL(DIAGINTTEST)):	/* DIAGINTTEST */
 	case(SOCFPGA_MEMCTRL(DERRADDRA)):	/* DERRADDRA */
 
+	case(SOCFPGA_ECC_QSPI(INITSTAT)):	/* ECC_QSPI_INITSTAT */
 	case(SOCFPGA_SYSMGR(EMAC_0)):	/* EMAC0 */
 	case(SOCFPGA_SYSMGR(EMAC_1)):	/* EMAC1 */
 	case(SOCFPGA_SYSMGR(EMAC_2)):	/* EMAC2 */
@@ -420,8 +437,19 @@ static int is_out_of_sec_range(uint64_t reg_addr)
 	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1)):	/* BOOT_SCRATCH_COLD1 */
 	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_8)):	/* BOOT_SCRATCH_COLD8 */
 	case(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_9)):	/* BOOT_SCRATCH_COLD9 */
-		return 0;
 #endif
+	case(SOCFPGA_ECC_QSPI(CTRL)):			/* ECC_QSPI_CTRL */
+	case(SOCFPGA_ECC_QSPI(ERRINTEN)):		/* ECC_QSPI_ERRINTEN */
+	case(SOCFPGA_ECC_QSPI(ERRINTENS)):		/* ECC_QSPI_ERRINTENS */
+	case(SOCFPGA_ECC_QSPI(ERRINTENR)):		/* ECC_QSPI_ERRINTENR */
+	case(SOCFPGA_ECC_QSPI(INTMODE)):		/* ECC_QSPI_INTMODE */
+	case(SOCFPGA_ECC_QSPI(ECC_ACCCTRL)):	/* ECC_QSPI_ECC_ACCCTRL */
+	case(SOCFPGA_ECC_QSPI(ECC_STARTACC)):	/* ECC_QSPI_ECC_STARTACC */
+	case(SOCFPGA_ECC_QSPI(ECC_WDCTRL)):		/* ECC_QSPI_ECC_WDCTRL */
+	case(SOCFPGA_ECC_QSPI(INTSTAT)):		/* ECC_QSPI_INTSTAT */
+	case(SOCFPGA_ECC_QSPI(INTTEST)):		/* ECC_QSPI_INTMODE */
+		return 0;
+
 	default:
 		break;
 	}
@@ -448,7 +476,15 @@ uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val,
 		return INTEL_SIP_SMC_STATUS_ERROR;
 	}
 
-	mmio_write_32(reg_addr, val);
+	switch (reg_addr) {
+	case(SOCFPGA_ECC_QSPI(INTSTAT)):		/* ECC_QSPI_INTSTAT */
+	case(SOCFPGA_ECC_QSPI(INTTEST)):		/* ECC_QSPI_INTMODE */
+		mmio_write_16(reg_addr, val);
+		break;
+	default:
+		mmio_write_32(reg_addr, val);
+		break;
+	}
 
 	return intel_secure_reg_read(reg_addr, retval);
 }
@@ -477,6 +513,16 @@ static uint32_t intel_rsu_status(uint64_t *respbuf, unsigned int respbuf_sz)
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+static uint32_t intel_rsu_get_device_info(uint32_t *respbuf,
+					  unsigned int respbuf_sz)
+{
+	if (mailbox_rsu_get_device_info((uint32_t *)respbuf, respbuf_sz) < 0) {
+		return INTEL_SIP_SMC_RSU_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 uint32_t intel_rsu_update(uint64_t update_address)
 {
 	if (update_address > SIZE_MAX) {
@@ -689,15 +735,56 @@ uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask)
 }
 
 /* SDM SEU Error services */
-static uint32_t intel_sdm_seu_err_read(uint64_t *respbuf, unsigned int respbuf_sz)
+static uint32_t intel_sdm_seu_err_read(uint32_t *respbuf, unsigned int respbuf_sz)
 {
-	if (mailbox_seu_err_status((uint32_t *)respbuf, respbuf_sz) < 0) {
+	if (mailbox_seu_err_status(respbuf, respbuf_sz) < 0) {
 		return INTEL_SIP_SMC_SEU_ERR_READ_ERROR;
 	}
 
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+/* SDM SAFE SEU Error inject services */
+static uint32_t intel_sdm_safe_inject_seu_err(uint32_t *command, uint32_t len)
+{
+	if (mailbox_safe_inject_seu_err(command, len) < 0) {
+		return INTEL_SIP_SMC_SEU_ERR_READ_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+/* SMMU HPS Remapper */
+void intel_smmu_hps_remapper_init(uint64_t *mem)
+{
+	/* Read out Bit 1 value */
+	uint32_t remap = (mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_POR_1)) & 0x02);
+
+	if ((remap == 0x00) && (g_remapper_bypass == 0x00)) {
+		/* Update DRAM Base address for SDM SMMU */
+		mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_ARADDR_REMAP), DRAM_BASE);
+		mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_AWADDR_REMAP), DRAM_BASE);
+		*mem = *mem - DRAM_BASE;
+	} else {
+		*mem = *mem - DRAM_BASE;
+	}
+}
+
+int intel_smmu_hps_remapper_config(uint32_t remapper_bypass)
+{
+	/* Read out the JTAG-ID from boot scratch register */
+	if (is_agilex5_A5F0() != 0) {
+		if (remapper_bypass == 0x01) {
+			g_remapper_bypass = remapper_bypass;
+			mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_ARADDR_REMAP), 0);
+			mmio_write_32(SOCFPGA_SYSMGR(SDM_BE_AWADDR_REMAP), 0);
+		}
+	}
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+#endif
+
 /*
  * This function is responsible for handling all SiP calls from the NS world
  */
@@ -714,7 +801,8 @@ uintptr_t sip_smc_handler_v1(uint32_t smc_fid,
 	uint32_t retval = 0, completed_addr[3];
 	uint32_t retval2 = 0;
 	uint32_t mbox_error = 0;
-	uint64_t retval64, rsu_respbuf[9], seu_respbuf[3];
+	uint64_t retval64, rsu_respbuf[9];
+	uint32_t seu_respbuf[3];
 	int status = INTEL_SIP_SMC_STATUS_OK;
 	int mbox_status;
 	unsigned int len_in_resp;
@@ -819,6 +907,16 @@ uintptr_t sip_smc_handler_v1(uint32_t smc_fid,
 		status = intel_rsu_copy_dcmf_version(x1, x2);
 		SMC_RET1(handle, status);
 
+	case INTEL_SIP_SMC_RSU_GET_DEVICE_INFO:
+		status = intel_rsu_get_device_info((uint32_t *)rsu_respbuf,
+					ARRAY_SIZE(rsu_respbuf));
+		if (status) {
+			SMC_RET1(handle, status);
+		} else {
+			SMC_RET5(handle, status, rsu_respbuf[0], rsu_respbuf[1],
+				 rsu_respbuf[2], rsu_respbuf[3]);
+		}
+
 	case INTEL_SIP_SMC_RSU_DCMF_STATUS:
 		SMC_RET2(handle, INTEL_SIP_SMC_STATUS_OK,
 			 ((uint64_t)rsu_dcmf_stat[3] << 48) |
@@ -1210,6 +1308,12 @@ uintptr_t sip_smc_handler_v1(uint32_t smc_fid,
 					x5, x6, true, &send_id);
 		SMC_RET1(handle, status);
 
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
+	case INTEL_SIP_SMC_FCS_SDM_REMAPPER_CONFIG:
+		status = intel_smmu_hps_remapper_config(x1);
+		SMC_RET1(handle, status);
+#endif
+
 	case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384:
 		status = intel_fcs_get_rom_patch_sha384(x1, &retval64,
 							&mbox_error);
@@ -1229,6 +1333,10 @@ uintptr_t sip_smc_handler_v1(uint32_t smc_fid,
 			SMC_RET3(handle, seu_respbuf[0], seu_respbuf[1], seu_respbuf[2]);
 		}
 
+	case INTEL_SIP_SMC_SAFE_INJECT_SEU_ERR:
+		status = intel_sdm_safe_inject_seu_err((uint32_t *)&x1, (uint32_t)x2);
+		SMC_RET1(handle, status);
+
 	default:
 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);
diff --git a/plat/intel/soc/common/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
index e80f0747..66b5216c 100644
--- a/plat/intel/soc/common/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,17 +25,9 @@
 
 #include "drivers/sdmmc/sdmmc.h"
 #include "socfpga_private.h"
+#include "socfpga_ros.h"
 
 
-#define PLAT_FIP_BASE		(0)
-#define PLAT_FIP_MAX_SIZE	(0x1000000)
-#define PLAT_MMC_DATA_BASE	(0xffe3c000)
-#define PLAT_MMC_DATA_SIZE	(0x2000)
-#define PLAT_QSPI_DATA_BASE	(0x3C00000)
-#define PLAT_QSPI_DATA_SIZE	(0x1000000)
-#define PLAT_NAND_DATA_BASE	(0x0200000)
-#define PLAT_NAND_DATA_SIZE	(0x1000000)
-
 static const io_dev_connector_t *fip_dev_con;
 static const io_dev_connector_t *boot_dev_con;
 
@@ -55,6 +48,12 @@ static const io_uuid_spec_t bl33_uuid_spec = {
 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
 };
 
+# if ARM_LINUX_KERNEL_AS_BL33 != 0
+static const io_uuid_spec_t nt_fw_config_uuid_spec = {
+	.uuid = UUID_NT_FW_CONFIG,
+};
+# endif
+
 uintptr_t a2_lba_offset;
 const char a2[] = {0xa2, 0x0};
 
@@ -101,6 +100,13 @@ static const struct plat_io_policy policies[] = {
 		(uintptr_t) &bl33_uuid_spec,
 		check_fip
 	},
+# if ARM_LINUX_KERNEL_AS_BL33 != 0
+	[NT_FW_CONFIG_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&nt_fw_config_uuid_spec,
+		check_fip
+	},
+# endif
 	[GPT_IMAGE_ID] = {
 		&boot_dev_handle,
 		(uintptr_t) &gpt_block_spec,
@@ -136,9 +142,10 @@ static int check_fip(const uintptr_t spec)
 	return result;
 }
 
-void socfpga_io_setup(int boot_source)
+void socfpga_io_setup(int boot_source, unsigned long offset)
 {
 	int result;
+	fip_spec.offset = offset;
 
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
@@ -152,7 +159,6 @@ void socfpga_io_setup(int boot_source)
 
 	case BOOT_SOURCE_QSPI:
 		register_io_dev = &register_io_dev_memmap;
-		fip_spec.offset = PLAT_QSPI_DATA_BASE;
 		break;
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
@@ -161,7 +167,6 @@ void socfpga_io_setup(int boot_source)
 		nand_dev_spec.ops.init = cdns_nand_init_mtd;
 		nand_dev_spec.ops.read = cdns_nand_read;
 		nand_dev_spec.ops.write = NULL;
-		fip_spec.offset = PLAT_NAND_DATA_BASE;
 		break;
 #endif
 
diff --git a/plat/intel/soc/common/socfpga_vab.c b/plat/intel/soc/common/socfpga_vab.c
index e16610ca..969abb34 100644
--- a/plat/intel/soc/common/socfpga_vab.c
+++ b/plat/intel/soc/common/socfpga_vab.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,18 +9,23 @@
 #include <assert.h>
 #include <errno.h>
 
+#include "../lib/sha/sha.h"
+
 #include <arch_helpers.h>
+#include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/desc_image_load.h>
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
+#include <plat/common/platform.h>
 #include <tools_share/firmware_image_package.h>
 
 #include "socfpga_mailbox.h"
 #include "socfpga_vab.h"
 
-static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz)
+size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz)
 {
 	uint8_t *img_buf_end = img_buf + img_buf_sz;
 	uint32_t cert_sz = get_unaligned_le32(img_buf_end - sizeof(uint32_t));
@@ -35,9 +41,33 @@ static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz)
 	return 0;
 }
 
+int socfpga_vab_init(unsigned int image_id)
+{
+	int ret = 0;
+	size_t image_size;
+	void *image_base_ptr;
+	/*
+	 * Get information about the images to load.
+	 */
+	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
+	assert(bl_mem_params);
+
+	if (bl_mem_params == NULL) {
+		ERROR("SOCFPGA VAB Init failed\n");
+		return -EINITREJECTED;
+	}
+
+	if ((image_id == BL31_IMAGE_ID) || (image_id == BL33_IMAGE_ID)) {
+		image_base_ptr = (void *)bl_mem_params->image_info.image_base;
+		image_size = bl_mem_params->image_info.image_size;
+		ret = socfpga_vab_authentication(&image_base_ptr, &image_size);
+	}
 
+	return ret;
+}
 
-int socfpga_vendor_authentication(void **p_image, size_t *p_size)
+int socfpga_vab_authentication(void **p_image, size_t *p_size)
 {
 	int retry_count = 20;
 	uint8_t hash384[FCS_SHA384_WORD_SIZE];
@@ -46,51 +76,47 @@ int socfpga_vendor_authentication(void **p_image, size_t *p_size)
 	uint8_t *cert_hash_ptr, *mbox_relocate_data_addr;
 	uint32_t resp = 0, resp_len = 1;
 	int ret = 0;
+	uint8_t u8_buf_static[MBOX_DATA_MAX_LEN];
+
+	mbox_relocate_data_addr = u8_buf_static;
 
 	img_addr = (uintptr_t)*p_image;
 	img_sz = get_img_size((uint8_t *)img_addr, *p_size);
 
 	if (!img_sz) {
-		NOTICE("VAB certificate not found in image!\n");
-		return -ENOVABIMG;
+		ERROR("VAB certificate not found in image!\n");
+		return -ENOVABCERT;
 	}
 
 	if (!IS_BYTE_ALIGNED(img_sz, sizeof(uint32_t))) {
-		NOTICE("Image size (%d bytes) not aliged to 4 bytes!\n", img_sz);
+		ERROR("Image size (%d bytes) not aliged to 4 bytes!\n", img_sz);
 		return -EIMGERR;
 	}
 
 	/* Generate HASH384 from the image */
-	/* TODO: This part need to cross check !!!!!! */
-	sha384_csum_wd((uint8_t *)img_addr, img_sz, hash384, CHUNKSZ_PER_WD_RESET);
-	cert_hash_ptr = (uint8_t *)(img_addr + img_sz +
-	VAB_CERT_MAGIC_OFFSET + VAB_CERT_FIT_SHA384_OFFSET);
+	sha384_start((uint8_t *)img_addr, img_sz, hash384, CHUNKSZ_PER_WD_RESET);
+	cert_hash_ptr = (uint8_t *)(img_addr + img_sz + VAB_CERT_MAGIC_OFFSET +
+								VAB_CERT_FIT_SHA384_OFFSET);
 
 	/*
 	 * Compare the SHA384 found in certificate against the SHA384
 	 * calculated from image
 	 */
 	if (memcmp(hash384, cert_hash_ptr, FCS_SHA384_WORD_SIZE)) {
-		NOTICE("SHA384 does not match!\n");
+		ERROR("SHA384 does not match!\n");
 		return -EKEYREJECTED;
 	}
 
-
 	mbox_data_addr = img_addr + img_sz - sizeof(uint32_t);
 	/* Size in word (32bits) */
 	mbox_data_sz = (BYTE_ALIGN(*p_size - img_sz, sizeof(uint32_t))) >> 2;
 
-	NOTICE("mbox_data_addr = %lx    mbox_data_sz = %d\n", mbox_data_addr, mbox_data_sz);
+	VERBOSE("mbox_data_addr = %lx    mbox_data_sz = %d\n", mbox_data_addr, mbox_data_sz);
 
-	/* TODO: This part need to cross check !!!!!! */
-	// mbox_relocate_data_addr = (uint8_t *)malloc(mbox_data_sz * sizeof(uint32_t));
-	// if (!mbox_relocate_data_addr) {
-		// NOTICE("Cannot allocate memory for VAB certificate relocation!\n");
-		// return -ENOMEM;
-	// }
+	memcpy_s(mbox_relocate_data_addr, mbox_data_sz * sizeof(uint32_t),
+		(uint8_t *)mbox_data_addr, mbox_data_sz * sizeof(uint32_t));
 
-	memcpy(mbox_relocate_data_addr, (uint8_t *)mbox_data_addr, mbox_data_sz * sizeof(uint32_t));
-	*(uint32_t *)mbox_relocate_data_addr = 0;
+	*((unsigned int *)mbox_relocate_data_addr) = CCERT_CMD_TEST_PGM_MASK;
 
 	do {
 		/* Invoke SMC call to ATF to send the VAB certificate to SDM */
@@ -109,7 +135,6 @@ int socfpga_vendor_authentication(void **p_image, size_t *p_size)
 	/* Free the relocate certificate memory space */
 	zeromem((void *)&mbox_relocate_data_addr, sizeof(uint32_t));
 
-
 	/* Exclude the size of the VAB certificate from image size */
 	*p_size = img_sz;
 
@@ -121,40 +146,32 @@ int socfpga_vendor_authentication(void **p_image, size_t *p_size)
 		 /* 0x85 = Not allowed under current security setting */
 		if (ret == MBOX_RESP_ERR(0x85)) {
 			/* SDM bypass authentication */
-			NOTICE("Image Authentication bypassed at address\n");
+			ERROR("Image Authentication bypassed at address\n");
 			return 0;
 		}
-		NOTICE("VAB certificate authentication failed in SDM\n");
+		ERROR("VAB certificate authentication failed in SDM\n");
 		/* 0x1FF = The device is busy */
 		if (ret == MBOX_RESP_ERR(0x1FF)) {
-			NOTICE("Operation timed out\n");
+			ERROR("Operation timed out\n");
 			return -ETIMEOUT;
 		} else if (ret == MBOX_WRONG_ID) {
-			NOTICE("No such process\n");
+			ERROR("No such process\n");
 			return -EPROCESS;
 		}
+		return -EAUTH;
 	} else {
 		/* If Certificate Process Status has error */
 		if (resp) {
-			NOTICE("VAB certificate execution format error\n");
+			ERROR("VAB certificate execution format error\n");
 			return -EIMGERR;
 		}
 	}
 
-	NOTICE("Image Authentication bypassed at address\n");
+	NOTICE("%s 0x%lx (%d bytes)\n", "Image Authentication passed at address", img_addr, img_sz);
 	return ret;
-
-}
-
-static uint32_t get_unaligned_le32(const void *p)
-{
-	/* TODO: Temp for testing */
-	//return le32_to_cpup((__le32 *)p);
-	return 0;
 }
 
-void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
-		unsigned char *output, unsigned int chunk_sz)
+uint32_t get_unaligned_le32(const void *p)
 {
-	/* TODO: Update sha384 start, update and finish */
+	return le32_to_cpue((uint32_t *)p);
 }
diff --git a/plat/intel/soc/n5x/bl31_plat_setup.c b/plat/intel/soc/n5x/bl31_plat_setup.c
index a5337cee..cb5ced6f 100644
--- a/plat/intel/soc/n5x/bl31_plat_setup.c
+++ b/plat/intel/soc/n5x/bl31_plat_setup.c
@@ -116,8 +116,6 @@ void bl31_platform_setup(void)
 		(uint64_t)plat_secondary_cpus_bl31_entry);
 
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
-
-	ncore_enable_ocram_firewall();
 }
 
 const mmap_region_t plat_dm_mmap[] = {
diff --git a/plat/intel/soc/n5x/include/n5x_clock_manager.h b/plat/intel/soc/n5x/include/n5x_clock_manager.h
index 14a57173..95a3d5c9 100644
--- a/plat/intel/soc/n5x/include/n5x_clock_manager.h
+++ b/plat/intel/soc/n5x/include/n5x_clock_manager.h
@@ -1,16 +1,15 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef CLOCKMANAGER_H
-#define CLOCKMANAGER_H
+#ifndef N5X_SOCFPGA_CLOCKMANAGER_H
+#define N5X_SOCFPGA_CLOCKMANAGER_H
 
-#include "socfpga_handoff.h"
 
 /* MACRO DEFINITION */
-#define SOCFPGA_GLOBAL_TIMER				0xffd01000
 #define SOCFPGA_GLOBAL_TIMER_EN				0x3
 
 #define CLKMGR_PLLGLOB_VCO_PSRC_MASK			GENMASK(17, 16)
@@ -56,5 +55,6 @@ uint64_t get_l4_clk(void);
 uint32_t get_clk_freq(uint32_t psrc_reg);
 uint32_t get_mpu_clk(void);
 uint32_t get_cpu_clk(void);
+uint32_t get_mpu_periph_clk(void);
 
-#endif
+#endif /* N5X_SOCFPGA_CLOCKMANAGER_H */
diff --git a/plat/intel/soc/n5x/include/n5x_system_manager.h b/plat/intel/soc/n5x/include/n5x_system_manager.h
index b6282197..fd789a27 100644
--- a/plat/intel/soc/n5x/include/n5x_system_manager.h
+++ b/plat/intel/soc/n5x/include/n5x_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -121,7 +122,7 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
 #define SOCFPGA_SYSMGR_MPFE_CONFIG			0x228
-#define SOCFPGA_SYSMGR_MPFE_status			0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS			0x22C
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0		0x230
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1		0x234
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2		0x238
@@ -143,6 +144,18 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_8		0x278
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_9		0x27C
 
+/* QSPI ECC from SDM register */
+#define SOCFPGA_ECC_QSPI_CTRL						0x08
+#define SOCFPGA_ECC_QSPI_ERRINTEN					0x10
+#define SOCFPGA_ECC_QSPI_ERRINTENS					0x14
+#define SOCFPGA_ECC_QSPI_ERRINTENR					0x18
+#define SOCFPGA_ECC_QSPI_INTMODE					0x1C
+#define SOCFPGA_ECC_QSPI_INTSTAT					0x20
+#define SOCFPGA_ECC_QSPI_INTTEST					0x24
+#define SOCFPGA_ECC_QSPI_ECC_ACCCTRL					0x78
+#define SOCFPGA_ECC_QSPI_ECC_STARTACC					0x7C
+#define SOCFPGA_ECC_QSPI_ECC_WDCTRL					0x80
+
 #define DMA0_STREAM_CTRL_REG				0x10D1217C
 #define DMA1_STREAM_CTRL_REG				0x10D12180
 #define SDM_STREAM_CTRL_REG				0x10D12184
@@ -186,6 +199,9 @@
 #define RMMUSECSID_REG_VAL				BIT(5)
 
 /* Macros */
+#define SOCFPGA_ECC_QSPI(_reg)						(SOCFPGA_ECC_QSPI_REG_BASE \
+									+ (SOCFPGA_ECC_QSPI_##_reg))
+
 #define SOCFPGA_SYSMGR(_reg)				(SOCFPGA_SYSMGR_REG_BASE \
 								+ (SOCFPGA_SYSMGR_##_reg))
 #define ENABLE_STREAMID					WSTREAMIDEN_REG_CTRL | \
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index a06bbc4c..6f0a40be 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,15 +9,17 @@
 #ifndef PLAT_SOCFPGA_DEF_H
 #define PLAT_SOCFPGA_DEF_H
 
-#include "n5x_system_manager.h"
 #include <platform_def.h>
+#include <lib/utils_def.h>
+#include "n5x_system_manager.h"
 
 /* Platform Setting */
-#define PLATFORM_MODEL						PLAT_SOCFPGA_N5X
-#define BOOT_SOURCE							BOOT_SOURCE_SDMMC
-#define PLAT_PRIMARY_CPU					0
+#define PLATFORM_MODEL				PLAT_SOCFPGA_N5X
+#define PLAT_PRIMARY_CPU			0
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
-#define PLAT_CPU_ID_MPIDR_AFF_SHIFT			MPIDR_AFF0_SHIFT
+#define PLAT_CPU_ID_MPIDR_AFF_SHIFT		MPIDR_AFF0_SHIFT
+#define PLAT_HANDOFF_OFFSET			0xFFE3F000
+#define PLAT_TIMER_BASE_ADDR			0xFFD01000
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
@@ -26,19 +29,27 @@
 #define CAD_QSPIDATA_OFST			0xff900000
 #define CAD_QSPI_OFFSET				0xff8d2000
 
+/* FIP Setting */
+#define PLAT_FIP_BASE				(0)
+#define PLAT_FIP_MAX_SIZE			(0x1000000)
+
+/* SDMMC Setting */
+#define PLAT_MMC_DATA_BASE			(0xffe3c000)
+#define PLAT_MMC_DATA_SIZE			(0x2000)
+#define SOCFPGA_MMC_BLOCK_SIZE			U(8192)
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE		U(0xf7000000)
 #define SOCFPGA_F2SDRAMMGR_REG_BASE		U(0xf8024000)
-
 #define SOCFPGA_MMC_REG_BASE			U(0xff808000)
-
 #define SOCFPGA_RSTMGR_REG_BASE			U(0xffd11000)
 #define SOCFPGA_SYSMGR_REG_BASE			U(0xffd12000)
+#define SOCFPGA_ECC_QSPI_REG_BASE				U(0xffa22000)
 
-#define SOCFPGA_L4_PER_SCR_REG_BASE			U(0xffd21000)
-#define SOCFPGA_L4_SYS_SCR_REG_BASE			U(0xffd21100)
-#define SOCFPGA_SOC2FPGA_SCR_REG_BASE			U(0xffd21200)
-#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE			U(0xffd21300)
+#define SOCFPGA_L4_PER_SCR_REG_BASE		U(0xffd21000)
+#define SOCFPGA_L4_SYS_SCR_REG_BASE		U(0xffd21100)
+#define SOCFPGA_SOC2FPGA_SCR_REG_BASE		U(0xffd21200)
+#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE		U(0xffd21300)
 
 
 /*******************************************************************************
@@ -65,34 +76,39 @@
 #define DEVICE4_BASE				(0x2000000000)
 #define DEVICE4_SIZE				(0x0100000000)
 
-#define BL2_BASE		(0xffe00000)
-#define BL2_LIMIT		(0xffe1b000)
+#define BL2_BASE				(0xffe00000)
+#define BL2_LIMIT				(0xffe1b000)
 
-#define BL31_BASE		(0x1000)
-#define BL31_LIMIT		(0x81000)
+#define BL31_BASE				(0x1000)
+#define BL31_LIMIT				(0x81000)
 
 /*******************************************************************************
  * UART related constants
  ******************************************************************************/
-#define PLAT_UART0_BASE		(0xFFC02000)
-#define PLAT_UART1_BASE		(0xFFC02100)
+#define PLAT_UART0_BASE				(0xFFC02000)
+#define PLAT_UART1_BASE				(0xFFC02100)
+
+/*******************************************************************************
+ * WDT related constants
+ ******************************************************************************/
+#define WDT_BASE			(0xFFD00200)
 
 /*******************************************************************************
  * GIC related constants
  ******************************************************************************/
-#define PLAT_GIC_BASE			(0xFFFC0000)
-#define PLAT_GICC_BASE			(PLAT_GIC_BASE + 0x2000)
-#define PLAT_GICD_BASE			(PLAT_GIC_BASE + 0x1000)
-#define PLAT_GICR_BASE			0
+#define PLAT_GIC_BASE				(0xFFFC0000)
+#define PLAT_GICC_BASE				(PLAT_GIC_BASE + 0x2000)
+#define PLAT_GICD_BASE				(PLAT_GIC_BASE + 0x1000)
+#define PLAT_GICR_BASE				0
 
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
-#define PLAT_HZ_CONVERT_TO_MHZ	(1000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS		(400000000)
+#define PLAT_HZ_CONVERT_TO_MHZ		(1000000)
 
 /*******************************************************************************
  * SDMMC related pointer function
  ******************************************************************************/
-#define SDMMC_READ_BLOCKS	mmc_read_blocks
-#define SDMMC_WRITE_BLOCKS	mmc_write_blocks
+#define SDMMC_READ_BLOCKS			mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS			mmc_write_blocks
 
 /*******************************************************************************
  * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
@@ -101,6 +117,6 @@
 #define L2_RESET_DONE_REG			0xFFD12218
 
 /* Platform specific system counter */
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ		U(400)
 
 #endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index 95f076fa..4770f8d3 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -1,5 +1,6 @@
 #
-# Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2024, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -46,6 +47,30 @@ BL31_SOURCES	+=	\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33	:=	0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC		?=	0
+SOCFPGA_BOOT_SOURCE_QSPI		?=	0
+SOCFPGA_BOOT_SOURCE_NAND		?=	0
+
+$(eval $(call assert_booleans,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 BL2_INV_DCACHE			:= 0
diff --git a/plat/intel/soc/n5x/soc/n5x_clock_manager.c b/plat/intel/soc/n5x/soc/n5x_clock_manager.c
index f32e0f8b..c33140d4 100644
--- a/plat/intel/soc/n5x/soc/n5x_clock_manager.c
+++ b/plat/intel/soc/n5x/soc/n5x_clock_manager.c
@@ -12,8 +12,7 @@
 
 #include "n5x_clock_manager.h"
 #include "n5x_system_manager.h"
-
-
+#include "socfpga_handoff.h"
 
 uint64_t clk_get_pll_output_hz(void)
 {
@@ -151,7 +150,22 @@ uint32_t get_cpu_clk(void)
 {
 	uint32_t cpu_clk = 0;
 
-	cpu_clk = get_mpu_clk()/PLAT_HZ_CONVERT_TO_MHZ;
+	cpu_clk = get_l4_clk()/PLAT_HZ_CONVERT_TO_MHZ;
 
 	return cpu_clk;
 }
+
+/* Return mpu_periph_clk clock frequency */
+uint32_t get_mpu_periph_clk(void)
+{
+	uint32_t mpu_periph_clk = 0;
+	/* mpu_periph_clk is mpu_clk, via a static /4 divider  */
+	mpu_periph_clk = (get_mpu_clk()/4)/PLAT_HZ_CONVERT_TO_MHZ;
+	return mpu_periph_clk;
+}
+
+/* Return mpu_periph_clk tick */
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return PLAT_SYS_COUNTER_FREQ_IN_TICKS;
+}
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index 73e3216a..d140394d 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -122,14 +122,14 @@ void bl2_el3_plat_arch_setup(void)
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
 		dw_mmc_init(&params, &mmc_info);
-		socfpga_io_setup(boot_source);
+		socfpga_io_setup(boot_source, PLAT_SDMMC_DATA_BASE);
 		break;
 
 	case BOOT_SOURCE_QSPI:
 		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
 			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
 			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
-		socfpga_io_setup(boot_source);
+		socfpga_io_setup(boot_source, PLAT_QSPI_DATA_BASE);
 		break;
 
 	default:
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index ba00e820..d0aa9729 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -123,8 +123,6 @@ void bl31_platform_setup(void)
 		(uint64_t)plat_secondary_cpus_bl31_entry);
 
 	mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
-
-	enable_ocram_firewall();
 }
 
 const mmap_region_t plat_stratix10_mmap[] = {
diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h
index 5f763755..c7632bed 100644
--- a/plat/intel/soc/stratix10/include/s10_clock_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h
@@ -95,7 +95,8 @@ uint32_t get_wdt_clk(void);
 uint32_t get_uart_clk(void);
 uint32_t get_mmc_clk(void);
 uint32_t get_l3_clk(uint32_t ref_clk);
-uint32_t get_ref_clk(uint32_t pllglob);
 uint32_t get_cpu_clk(void);
+uint32_t get_ref_clk(uint32_t pllglob);
+uint32_t get_mpu_periph_clk(void);
 
 #endif
diff --git a/plat/intel/soc/stratix10/include/s10_memory_controller.h b/plat/intel/soc/stratix10/include/s10_memory_controller.h
index 155b2795..056f6cf7 100644
--- a/plat/intel/soc/stratix10/include/s10_memory_controller.h
+++ b/plat/intel/soc/stratix10/include/s10_memory_controller.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,7 +27,7 @@
 #define S10_MPFE_HMC_ADP_ECCCTRL1			0xf8011100
 #define S10_MPFE_HMC_ADP_ECCCTRL2			0xf8011104
 #define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT		0xf8011218
-#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x000000ff
+#define S10_MPFE_HMC_ADP_RSTHANDSHAKESTAT_SEQ2CORE	0x0000000f
 #define S10_MPFE_HMC_ADP_RSTHANDSHAKECTRL		0xf8011214
 
 
diff --git a/plat/intel/soc/stratix10/include/s10_system_manager.h b/plat/intel/soc/stratix10/include/s10_system_manager.h
index 88c0b469..dcc1517e 100644
--- a/plat/intel/soc/stratix10/include/s10_system_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_system_manager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -120,7 +121,7 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8		0x220
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9		0x224
 #define SOCFPGA_SYSMGR_MPFE_CONFIG			0x228
-#define SOCFPGA_SYSMGR_MPFE_status			0x22C
+#define SOCFPGA_SYSMGR_MPFE_STATUS			0x22C
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_0		0x230
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_1		0x234
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_WARM_2		0x238
@@ -142,6 +143,18 @@
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_8		0x278
 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_POR_9		0x27C
 
+/* QSPI ECC from SDM register */
+#define SOCFPGA_ECC_QSPI_CTRL						0x08
+#define SOCFPGA_ECC_QSPI_ERRINTEN					0x10
+#define SOCFPGA_ECC_QSPI_ERRINTENS					0x14
+#define SOCFPGA_ECC_QSPI_ERRINTENR					0x18
+#define SOCFPGA_ECC_QSPI_INTMODE					0x1C
+#define SOCFPGA_ECC_QSPI_INTSTAT					0x20
+#define SOCFPGA_ECC_QSPI_INTTEST					0x24
+#define SOCFPGA_ECC_QSPI_ECC_ACCCTRL					0x78
+#define SOCFPGA_ECC_QSPI_ECC_STARTACC					0x7C
+#define SOCFPGA_ECC_QSPI_ECC_WDCTRL					0x80
+
 #define DMA0_STREAM_CTRL_REG				0x10D1217C
 #define DMA1_STREAM_CTRL_REG				0x10D12180
 #define SDM_STREAM_CTRL_REG				0x10D12184
@@ -182,6 +195,8 @@
 #define RMMUSECSID_REG_VAL				BIT(5)
 
 /* Macros */
+#define SOCFPGA_ECC_QSPI(_reg)						(SOCFPGA_ECC_QSPI_REG_BASE \
+									+ (SOCFPGA_ECC_QSPI_##_reg))
 
 #define SOCFPGA_SYSMGR(_reg)				(SOCFPGA_SYSMGR_REG_BASE \
 								+ (SOCFPGA_SYSMGR_##_reg))
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 7c9f15ac..90345c3b 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Altera Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,14 +9,16 @@
 #define PLAT_SOCFPGA_DEF_H
 
 #include <platform_def.h>
+#include <lib/utils_def.h>
 #include "s10_system_manager.h"
 
 /* Platform Setting */
-#define PLATFORM_MODEL						PLAT_SOCFPGA_STRATIX10
-#define BOOT_SOURCE							BOOT_SOURCE_SDMMC
-#define PLAT_PRIMARY_CPU					0
+#define PLATFORM_MODEL				PLAT_SOCFPGA_STRATIX10
+#define PLAT_PRIMARY_CPU			0
 #define PLAT_CLUSTER_ID_MPIDR_AFF_SHIFT		MPIDR_AFF1_SHIFT
-#define PLAT_CPU_ID_MPIDR_AFF_SHIFT			MPIDR_AFF0_SHIFT
+#define PLAT_CPU_ID_MPIDR_AFF_SHIFT		MPIDR_AFF0_SHIFT
+#define PLAT_HANDOFF_OFFSET			0xFFE3F000
+#define PLAT_TIMER_BASE_ADDR			0xFFD01000
 
 /* FPGA config helpers */
 #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR		0x400000
@@ -25,6 +28,15 @@
 #define CAD_QSPIDATA_OFST			0xff900000
 #define CAD_QSPI_OFFSET				0xff8d2000
 
+/* FIP Setting */
+#define PLAT_FIP_BASE				(0)
+#define PLAT_FIP_MAX_SIZE			(0x1000000)
+
+/* SDMMC Setting */
+#define PLAT_MMC_DATA_BASE			(0xffe3c000)
+#define PLAT_MMC_DATA_SIZE			(0x2000)
+#define SOCFPGA_MMC_BLOCK_SIZE			U(8192)
+
 /* Register Mapping */
 #define SOCFPGA_CCU_NOC_REG_BASE		0xf7000000
 #define SOCFPGA_F2SDRAMMGR_REG_BASE		U(0xf8024000)
@@ -33,6 +45,7 @@
 
 #define SOCFPGA_RSTMGR_REG_BASE			0xffd11000
 #define SOCFPGA_SYSMGR_REG_BASE			0xffd12000
+#define SOCFPGA_ECC_QSPI_REG_BASE				0xffa22000
 
 #define SOCFPGA_L4_PER_SCR_REG_BASE		0xffd21000
 #define SOCFPGA_L4_SYS_SCR_REG_BASE		0xffd21100
@@ -63,34 +76,39 @@
 #define DEVICE4_BASE				(0x2000000000)
 #define DEVICE4_SIZE				(0x0100000000)
 
-#define BL2_BASE		(0xffe00000)
-#define BL2_LIMIT		(0xffe1b000)
+#define BL2_BASE				(0xffe00000)
+#define BL2_LIMIT				(0xffe2b000)
 
-#define BL31_BASE		(0x1000)
-#define BL31_LIMIT		(0x81000)
+#define BL31_BASE				(0x1000)
+#define BL31_LIMIT				(0x81000)
 
 /*******************************************************************************
  * UART related constants
  ******************************************************************************/
-#define PLAT_UART0_BASE		(0xFFC02000)
-#define PLAT_UART1_BASE		(0xFFC02100)
+#define PLAT_UART0_BASE				(0xFFC02000)
+#define PLAT_UART1_BASE				(0xFFC02100)
+
+/*******************************************************************************
+ * WDT related constants
+ ******************************************************************************/
+#define WDT_BASE			(0xFFD00200)
 
 /*******************************************************************************
  * GIC related constants
  ******************************************************************************/
-#define PLAT_GIC_BASE			(0xFFFC0000)
-#define PLAT_GICC_BASE			(PLAT_GIC_BASE + 0x2000)
-#define PLAT_GICD_BASE			(PLAT_GIC_BASE + 0x1000)
-#define PLAT_GICR_BASE			0
+#define PLAT_GIC_BASE				(0xFFFC0000)
+#define PLAT_GICC_BASE				(PLAT_GIC_BASE + 0x2000)
+#define PLAT_GICD_BASE				(PLAT_GIC_BASE + 0x1000)
+#define PLAT_GICR_BASE				0
 
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
-#define PLAT_HZ_CONVERT_TO_MHZ	(1000000)
+#define PLAT_SYS_COUNTER_FREQ_IN_TICKS		(400000000)
+#define PLAT_HZ_CONVERT_TO_MHZ		(1000000)
 
 /*******************************************************************************
  * SDMMC related pointer function
  ******************************************************************************/
-#define SDMMC_READ_BLOCKS	mmc_read_blocks
-#define SDMMC_WRITE_BLOCKS	mmc_write_blocks
+#define SDMMC_READ_BLOCKS			mmc_read_blocks
+#define SDMMC_WRITE_BLOCKS			mmc_write_blocks
 
 /*******************************************************************************
  * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
@@ -99,7 +117,7 @@
 #define L2_RESET_DONE_REG			0xFFD12218
 
 /* Platform specific system counter */
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ		U(400)
 
 #endif /* PLATSOCFPGA_DEF_H */
 
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 6bc96fb6..4cd7032e 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -1,6 +1,7 @@
 #
 # Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+# Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+# Copyright (c) 2024, Altera Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -26,6 +27,7 @@ PLAT_BL_COMMON_SOURCES	:=	\
 			lib/xlat_tables/xlat_tables_common.c 		\
 			plat/intel/soc/common/aarch64/platform_common.c \
 			plat/intel/soc/common/aarch64/plat_helpers.S	\
+			plat/intel/soc/common/drivers/ccu/ncore_ccu.c	\
 			plat/intel/soc/common/socfpga_delay_timer.c	\
 			plat/intel/soc/common/soc/socfpga_firewall.c
 
@@ -53,6 +55,7 @@ BL2_SOURCES     +=	\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c	\
 		plat/intel/soc/common/drivers/qspi/cadence_qspi.c	\
+		plat/intel/soc/common/drivers/ddr/ddr.c	\
 		plat/intel/soc/common/drivers/wdt/watchdog.c
 
 include lib/zlib/zlib.mk
@@ -75,6 +78,30 @@ BL31_SOURCES	+=	\
 		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/soc/socfpga_reset_manager.c
 
+# Don't have the Linux kernel as a BL33 image by default
+ARM_LINUX_KERNEL_AS_BL33	:=	0
+$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33))
+$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
+
+# Configs for Boot Source
+SOCFPGA_BOOT_SOURCE_SDMMC		?=	0
+SOCFPGA_BOOT_SOURCE_QSPI		?=	0
+SOCFPGA_BOOT_SOURCE_NAND		?=	0
+
+$(eval $(call assert_booleans,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+$(eval $(call add_defines,\
+	$(sort \
+		SOCFPGA_BOOT_SOURCE_SDMMC \
+		SOCFPGA_BOOT_SOURCE_QSPI \
+		SOCFPGA_BOOT_SOURCE_NAND \
+)))
+
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 RESET_TO_BL2			:= 1
 USE_COHERENT_MEM		:= 1
diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
index 416d3592..0a3b77b1 100644
--- a/plat/intel/soc/stratix10/soc/s10_clock_manager.c
+++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -230,6 +230,40 @@ uint32_t get_ref_clk(uint32_t pllglob)
 	return ref_clk;
 }
 
+/* Calculate clock frequency based on parameter */
+uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc)
+{
+	uint32_t clk_psrc, ref_clk;
+	uint32_t pllc_reg, pllc_div, pllglob_reg;
+
+	clk_psrc = mmio_read_32(ALT_CLKMGR_MAINPLL + psrc_reg);
+
+	switch (ALT_CLKMGR_PSRC(clk_psrc)) {
+	case ALT_CLKMGR_SRC_MAIN:
+		pllc_reg = ALT_CLKMGR_MAINPLL + main_pllc;
+		pllglob_reg = ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB;
+		break;
+	case ALT_CLKMGR_SRC_PER:
+		pllc_reg = ALT_CLKMGR_PERPLL + per_pllc;
+		pllglob_reg = ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB;
+		break;
+	default:
+		return 0;
+	}
+
+	ref_clk = get_ref_clk(mmio_read_32(pllglob_reg));
+
+	pllc_div = mmio_read_32(pllc_reg) & 0xff;
+
+	if (pllc_div != 0) {
+		ref_clk = (ref_clk / pllc_div) / (clk_psrc + 1);
+		return ref_clk;
+	} else {
+		VERBOSE("PLL DIV is 0\n");
+		return 0;
+	}
+}
+
 /* Calculate L3 interconnect main clock */
 uint32_t get_l3_clk(uint32_t ref_clk)
 {
@@ -308,6 +342,17 @@ uint32_t get_mmc_clk(void)
 	return mmc_clk;
 }
 
+/* Return MPU clock */
+uint32_t get_mpu_clk(void)
+{
+	uint32_t mpu_clk;
+
+	mpu_clk = get_clk_freq(ALT_CLKMGR_MAINPLL_NOCCLK, ALT_CLKMGR_MAINPLL_PLLC0,
+				ALT_CLKMGR_PERPLL_PLLC0);
+
+	return mpu_clk;
+}
+
 /* Get cpu freq clock */
 uint32_t get_cpu_clk(void)
 {
@@ -320,3 +365,18 @@ uint32_t get_cpu_clk(void)
 
 	return cpu_clk;
 }
+
+/* Return mpu_periph_clk clock frequency */
+uint32_t get_mpu_periph_clk(void)
+{
+	uint32_t mpu_periph_clk = 0;
+	/* mpu_periph_clk is mpu_clk, via a static /4 divider  */
+	mpu_periph_clk = (get_mpu_clk()/4)/PLAT_HZ_CONVERT_TO_MHZ;
+	return mpu_periph_clk;
+}
+
+/* Return mpu_periph_clk tick */
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return PLAT_SYS_COUNTER_FREQ_IN_TICKS;
+}
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index b9c28de1..e8f892d2 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -150,90 +150,89 @@ $(TBB): FORCE
 	$(if $(wildcard $(CRYPTOPP_LIBDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_LIB' was set to '$(CRYPTOPP_LIBDIR)', but '$(CRYPTOPP_LIBDIR)' does not exist"))
 	$(if $(wildcard $(CRYPTOPP_INCDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_INCDIR' was set to '$(CRYPTOPP_INCDIR)', but '$(CRYPTOPP_INCDIR)' does not exist"))
 ifdef CRYPTOPP_PATH
-	$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile
+	$(q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile
 endif
-	$(Q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_LIBDIR) INCDIR=$(CRYPTOPP_INCDIR)
+	$(q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak LIBDIR=$(CRYPTOPP_LIBDIR) INCDIR=$(CRYPTOPP_INCDIR)
 
 $(WTMI_MULTI_IMG): FORCE
-	$(Q)$(MAKE) --no-print-directory -C $(WTP) WTMI_IMG=$(WTMI_IMG) DDR_TOPOLOGY=$(DDR_TOPOLOGY) CLOCKSPRESET=$(CLOCKSPRESET) WTMI
+	$(q)$(MAKE) --no-print-directory -C $(WTP) WTMI_IMG=$(WTMI_IMG) DDR_TOPOLOGY=$(DDR_TOPOLOGY) CLOCKSPRESET=$(CLOCKSPRESET) WTMI
 
 $(BUILD_PLAT)/wtmi.bin: $(WTMI_MULTI_IMG)
-	$(Q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin
+	$(q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin
 
 $(TIMDDRTOOL): FORCE
 #	Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds
 	$(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for ddr tool requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
 	$(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
 	$(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))
-	$(Q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr
-
-$(BUILD_PLAT)/$(UART_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(TBB) $(TIMBUILD) $(TIMDDRTOOL)
-	@$(ECHO_BLANK_LINE)
-	@echo "Building uart images"
-	$(Q)mkdir -p $(BUILD_PLAT)/$(BUILD_UART)
-	$(Q)cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin
-	$(Q)cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE)
-	$(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_UART_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_UART_CFG)
+	$(q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) DDR_TOPOLOGY=$(DDR_TOPOLOGY) mv_ddr
+
+$(BUILD_PLAT)/$(UART_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(TBB) $(TIMBUILD) $(TIMDDRTOOL) | $(BUILD_PLAT)/$(BUILD_UART)/ $$(@D)/
+	$(s)echo
+	$(s)echo "Building uart images"
+	$(q)cp -a $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/$(BUILD_UART)/wtmi.bin
+	$(q)cp -a $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/$(BUILD_UART)/$(BOOT_IMAGE)
+	$(q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TIMBUILD) $(TIMBLDUARTARGS)
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_UART_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_UART_CFG)
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_UART_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_UART_CFG)
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_UART_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_UART_CFG)
 endif
-	$(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIM_UART_CFG) -v -D
+	$(q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIM_UART_CFG) -v -D
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIMN_UART_CFG)
+	$(q)cd $(BUILD_PLAT)/$(BUILD_UART) && $(TBB) -r $(TIMN_UART_CFG)
 endif
-	$(Q)tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(UART_IMAGES)
-	@$(ECHO_BLANK_LINE)
-	@echo "Built $@ successfully"
-	@$(ECHO_BLANK_LINE)
+	$(q)tar czf $(BUILD_PLAT)/$(UART_IMAGE) -C $(BUILD_PLAT) $(UART_IMAGES)
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 $(BUILD_PLAT)/$(FLASH_IMAGE): $(BUILD_PLAT)/$(BOOT_IMAGE) $(BUILD_PLAT)/wtmi.bin $(TBB) $(TIMBUILD) $(TIMDDRTOOL) $(TIM2IMG)
-	@$(ECHO_BLANK_LINE)
-	@echo "Building flash image"
-	$(Q)cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_CFG)
+	$(s)echo
+	$(s)echo "Building flash image"
+	$(q)cd $(BUILD_PLAT) && $(TIMBUILD) $(TIMBLDARGS)
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIM_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIM_CFG)
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_CFG)
-	$(Q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_CFG)
-	@$(ECHO_BLANK_LINE)
-	@echo "=======================================================";
-	@echo "  Secure boot. Encrypting wtmi and boot-image";
-	@echo "=======================================================";
-	@$(ECHO_BLANK_LINE)
-	$(Q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin
-	$(Q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin
-	$(Q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \
+	$(q)sed -i 's|WTMI_IMG|wtmi.bin|1' $(TIMN_CFG)
+	$(q)sed -i 's|BOOT_IMAGE|$(BOOT_IMAGE)|1' $(TIMN_CFG)
+	$(s)echo
+	$(s)echo "=======================================================";
+	$(s)echo "  Secure boot. Encrypting wtmi and boot-image";
+	$(s)echo "=======================================================";
+	$(s)echo
+	$(q)cp $(BUILD_PLAT)/wtmi.bin $(BUILD_PLAT)/wtmi-align.bin
+	$(q)truncate -s %16 $(BUILD_PLAT)/wtmi-align.bin
+	$(q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/wtmi-align.bin \
 	-out $(BUILD_PLAT)/$(WTMI_ENC_IMG) \
 	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
-	$(Q)truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
-	$(Q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
+	$(q)truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
+	$(q)${OPENSSL_BIN_PATH}/openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
 	-out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \
 	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
 endif
-	$(Q)cd $(BUILD_PLAT) && $(TBB) -r $(TIM_CFG) -v -D
+	$(q)cd $(BUILD_PLAT) && $(TBB) -r $(TIM_CFG) -v -D
 ifeq ($(MARVELL_SECURE_BOOT),1)
-	$(Q)cd $(BUILD_PLAT) && $(TBB) -r $(TIMN_CFG)
-	$(Q)sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMN_CFG)
-	$(Q)sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMN_CFG)
+	$(q)cd $(BUILD_PLAT) && $(TBB) -r $(TIMN_CFG)
+	$(q)sed -i 's|wtmi.bin|$(WTMI_ENC_IMG)|1' $(TIMN_CFG)
+	$(q)sed -i 's|$(BOOT_IMAGE)|$(BOOT_ENC_IMAGE)|1' $(TIMN_CFG)
 endif
-	$(Q)cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE)
-	@$(ECHO_BLANK_LINE)
-	@echo "Built $@ successfully"
-	@$(ECHO_BLANK_LINE)
+	$(q)cd $(BUILD_PLAT) && $(TIM2IMG) $(TIM2IMGARGS) -o $(BUILD_PLAT)/$(FLASH_IMAGE)
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 clean realclean distclean: mrvl_clean
 
 .PHONY: mrvl_clean
 mrvl_clean:
-	-$(Q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) clean
-	-$(Q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak clean
+	-$(q)$(MAKE) --no-print-directory -C $(WTP) MV_DDR_PATH=$(MV_DDR_PATH) clean
+	-$(q)$(MAKE) --no-print-directory -C $(WTP)/wtptp/src/TBB_Linux -f TBB_linux.mak clean
 ifdef CRYPTOPP_PATH
-	-$(Q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean
+	-$(q)$(MAKE) --no-print-directory -C $(CRYPTOPP_PATH) -f GNUmakefile clean
 endif
 
 else # WTP
diff --git a/plat/marvell/armada/a3k/common/cm3_system_reset.c b/plat/marvell/armada/a3k/common/cm3_system_reset.c
index f105d599..030a614c 100644
--- a/plat/marvell/armada/a3k/common/cm3_system_reset.c
+++ b/plat/marvell/armada/a3k/common/cm3_system_reset.c
@@ -8,11 +8,22 @@
 #include <stdbool.h>
 
 #include <common/debug.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv3.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
+#include <lib/utils_def.h>
 
+#include <a3700_pm.h>
+#include <platform_def.h>
 #include <mvebu_def.h>
 
+/* IO Decoder Error Interrupt Status Registers */
+#define MVEBU_DEC_WIN_REGS_BASE(p)		(MVEBU_REGS_BASE + 0xC000 + \
+						 (p) * 0x100)
+#define MVEBU_DEC_WIN_ERR_INT_STS_REG(p)	(MVEBU_DEC_WIN_REGS_BASE(p) + \
+						 0xF8)
+
 /* Cortex-M3 Secure Processor Mailbox Registers */
 #define MVEBU_RWTM_PARAM0_REG			(MVEBU_RWTM_REG_BASE)
 #define MVEBU_RWTM_CMD_REG			(MVEBU_RWTM_REG_BASE + 0x40)
@@ -23,6 +34,122 @@
 #define MVEBU_RWTM_REBOOT_CMD		0x0009
 #define MVEBU_RWTM_REBOOT_MAGIC		0xDEADBEEF
 
+static inline uint32_t a3700_gicd_read(uint32_t reg)
+{
+	return mmio_read_32(PLAT_MARVELL_GICD_BASE + reg);
+}
+
+static inline void a3700_gicd_write(uint32_t reg, uint32_t value)
+{
+	mmio_write_32(PLAT_MARVELL_GICD_BASE + reg, value);
+}
+
+static void a3700_gicd_ctlr_clear_bits(uint32_t bits)
+{
+	uint32_t val;
+
+	val = a3700_gicd_read(GICD_CTLR);
+	if ((val & bits) != 0U) {
+		a3700_gicd_write(GICD_CTLR, val & ~bits);
+		mdelay(1);
+
+		if ((a3700_gicd_read(GICD_CTLR) & GICD_CTLR_RWP_BIT) != 0U) {
+			ERROR("could not clear bits 0x%x in GIC distributor control\n",
+			      bits);
+		}
+	}
+}
+
+static void a3700_gic_dist_disable_irqs(void)
+{
+	int i;
+
+	for (i = 32; i < 224; i += 32) {
+		a3700_gicd_write(GICD_ICENABLER + (i >> 3), GENMASK_32(31, 0));
+	}
+}
+
+static inline uintptr_t a3700_rdist_base(unsigned int proc)
+{
+	return PLAT_MARVELL_GICR_BASE + (proc << GICR_V3_PCPUBASE_SHIFT);
+}
+
+static inline uint32_t a3700_gicr_read(unsigned int proc, uint32_t reg)
+{
+	return mmio_read_32(a3700_rdist_base(proc) + reg);
+}
+
+static inline void a3700_gicr_write(unsigned int proc, uint32_t reg,
+				    uint32_t value)
+{
+	mmio_write_32(a3700_rdist_base(proc) + reg, value);
+}
+
+static void a3700_gic_redist_disable_irqs(unsigned int proc)
+{
+	a3700_gicr_write(proc, GICR_ICENABLER0, GENMASK_32(31, 0));
+	mdelay(1);
+
+	if ((a3700_gicr_read(proc, GICR_CTLR) & GICR_CTLR_RWP_BIT) != 0U) {
+		ERROR("could not disable core %u PPIs & SGIs\n", proc);
+	}
+}
+
+static void a3700_gic_redist_mark_asleep(unsigned int proc)
+{
+	a3700_gicr_write(proc, GICR_WAKER,
+			 a3700_gicr_read(proc, GICR_WAKER) | WAKER_PS_BIT);
+	mdelay(1);
+
+	if ((a3700_gicr_read(proc, GICR_WAKER) & WAKER_CA_BIT) == 0U) {
+		ERROR("could not mark core %u redistributor asleep\n", proc);
+	}
+}
+
+static void a3700_io_addr_dec_ack_err_irq(void)
+{
+	unsigned int periph;
+
+	for (periph = 0; periph < 16; ++periph) {
+		/* periph 6 does not exist */
+		if (periph == 6)
+			continue;
+
+		mmio_write_32(MVEBU_DEC_WIN_ERR_INT_STS_REG(periph),
+			      GENMASK_32(1, 0));
+	}
+}
+
+static void a3700_gic_reset(void)
+{
+	a3700_gic_redist_disable_irqs(0);
+	a3700_gic_redist_disable_irqs(1);
+
+	a3700_gic_redist_mark_asleep(0);
+	a3700_gic_redist_mark_asleep(1);
+
+	a3700_io_addr_dec_ack_err_irq();
+
+	a3700_pm_ack_irq();
+
+	a3700_gic_dist_disable_irqs();
+
+	a3700_gicd_ctlr_clear_bits(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1NS_BIT |
+				   CTLR_ENABLE_G1S_BIT);
+
+	/* Clearing ARE_S and ARE_NS bits is undefined in the specification, but
+	 * works if the previous operations are successful. We need to do it in
+	 * order to put GIC into the same state it was in just after reset. If
+	 * this is successful, the rWTM firmware in the secure coprocessor will
+	 * reset all other peripherals one by one, load new firmware and boot
+	 * it, all without triggering the true warm reset via the WARM_RESET
+	 * register (which may hang the board).
+	 */
+
+	a3700_gicd_ctlr_clear_bits(CTLR_ARE_S_BIT);
+	a3700_gicd_ctlr_clear_bits(CTLR_ARE_NS_BIT);
+}
+
 static inline bool rwtm_completed(void)
 {
 	return (mmio_read_32(MVEBU_RWTM_HOST_INT_RESET_REG) &
@@ -43,6 +170,11 @@ void cm3_system_reset(void)
 {
 	int tries = 5;
 
+	/* Put GIC into the same state it was just after reset. This is needed
+	 * for the reset issue workaround to work.
+	 */
+	a3700_gic_reset();
+
 	for (; tries > 0; --tries) {
 		mmio_clrbits_32(MVEBU_RWTM_HOST_INT_RESET_REG,
 				MVEBU_RWTM_HOST_INT_SP_COMPLETE);
diff --git a/plat/marvell/armada/a3k/common/include/a3700_pm.h b/plat/marvell/armada/a3k/common/include/a3700_pm.h
index 44dbb9f7..1be82b2b 100644
--- a/plat/marvell/armada/a3k/common/include/a3700_pm.h
+++ b/plat/marvell/armada/a3k/common/include/a3700_pm.h
@@ -48,6 +48,8 @@ struct pm_wake_up_src_config {
 
 struct pm_wake_up_src_config *mv_wake_up_src_config_get(void);
 
+void a3700_pm_ack_irq(void);
+
 void cm3_system_reset(void);
 
 #endif /* A3700_PM_H */
diff --git a/plat/marvell/armada/a3k/common/plat_pm.c b/plat/marvell/armada/a3k/common/plat_pm.c
index e2d15abf..d573b79f 100644
--- a/plat/marvell/armada/a3k/common/plat_pm.c
+++ b/plat/marvell/armada/a3k/common/plat_pm.c
@@ -197,7 +197,7 @@ void marvell_psci_arch_init(int die_index)
 {
 }
 
-static void a3700_pm_ack_irq(void)
+void a3700_pm_ack_irq(void)
 {
 	uint32_t reg;
 
diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk
index 4d8a87fd..bdad8b5f 100644
--- a/plat/marvell/armada/a8k/common/a8k_common.mk
+++ b/plat/marvell/armada/a8k/common/a8k_common.mk
@@ -176,17 +176,17 @@ clean realclean distclean: mrvl_clean
 
 .PHONY: mrvl_clean
 mrvl_clean:
-	@echo "  Doimage CLEAN"
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean
+	$(s)echo "  Doimage CLEAN"
+	$(q)${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean
 
 ${DOIMAGETOOL}: FORCE
-	@$(DOIMAGE_LIBS_CHECK)
-	${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH}
+	$(q)$(DOIMAGE_LIBS_CHECK)
+	$(q)${MAKE} --no-print-directory -C ${DOIMAGEPATH}
 
 ${BUILD_PLAT}/${FLASH_IMAGE}: ${ROM_BIN_EXT} ${BUILD_PLAT}/${BOOT_IMAGE} ${DOIMAGETOOL}
-	@${ECHO_BLANK_LINE}
-	@echo "Building flash image"
-	${Q}${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Building flash image"
+	$(q)${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk
index 752ab419..5ab61239 100644
--- a/plat/marvell/armada/a8k/common/ble/ble.mk
+++ b/plat/marvell/armada/a8k/common/ble/ble.mk
@@ -32,4 +32,4 @@ $(MV_DDR_LIB): FORCE
 	$(if $(value MV_DDR_PATH),,$(error "Platform '$(PLAT)' for BLE requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory"))
 	$(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist"))
 	$(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository"))
-	@+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(MV_DDR_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble
+	$(q)+make -C $(MV_DDR_PATH) --no-print-directory PLAT_INCLUDES="$(MV_DDR_INCLUDES)" PLATFORM=$(PLAT) ARCH=AARCH64 OBJ_DIR=$(BUILD_PLAT)/ble
diff --git a/plat/marvell/armada/common/marvell_bl31_setup.c b/plat/marvell/armada/common/marvell_bl31_setup.c
index 26ba9065..b3641e30 100644
--- a/plat/marvell/armada/common/marvell_bl31_setup.c
+++ b/plat/marvell/armada/common/marvell_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Marvell International Ltd.
+ * Copyright (C) 2018-2024 Marvell International Ltd.
  *
  * SPDX-License-Identifier:     BSD-3-Clause
  * https://spdx.org/licenses
@@ -181,8 +181,6 @@ void marvell_bl31_platform_setup(void)
  */
 void marvell_bl31_plat_runtime_setup(void)
 {
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
-
 	/* Initialize the runtime console */
 	marvell_console_runtime_init();
 }
diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk
index f0e6edf2..25612321 100644
--- a/plat/marvell/armada/common/marvell_common.mk
+++ b/plat/marvell/armada/common/marvell_common.mk
@@ -84,13 +84,13 @@ endif
 
 $(BUILD_PLAT)/$(BOOT_IMAGE): $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(FIP_NAME)
 	$(if $(shell find $(BUILD_PLAT)/bl1.bin -type f -size +128k),$(error "Image '$(BUILD_PLAT)/bl1.bin' is bigger than 128kB"))
-	@cp $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
-	@$(ECHO_BLANK_LINE)
-	@echo "Built $@ successfully"
-	@$(ECHO_BLANK_LINE)
+	$(q)cp $(BUILD_PLAT)/bl1.bin $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(q)truncate -s %128K $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(q)cat $(BUILD_PLAT)/$(FIP_NAME) >> $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(q)truncate -s %4 $(BUILD_PLAT)/$(BOOT_IMAGE) || { rm -f $(BUILD_PLAT)/$(BOOT_IMAGE); false; }
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 .PHONY: mrvl_bootimage
 mrvl_bootimage: $(BUILD_PLAT)/$(BOOT_IMAGE)
diff --git a/plat/mediatek/build_helpers/mtk_build_helpers.mk b/plat/mediatek/build_helpers/mtk_build_helpers.mk
index 83a4dd2a..0cb2014a 100644
--- a/plat/mediatek/build_helpers/mtk_build_helpers.mk
+++ b/plat/mediatek/build_helpers/mtk_build_helpers.mk
@@ -27,12 +27,10 @@ endef
 # Determine option variable is defined or not then define it
 define add_defined_option
 ifdef $(1)
-ifeq ($(findstring $(value $(1)), $(uppercase_table)),)
-DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
-else
 ifeq ($(strip $(value $(1))),y)
 DEFINES += -D$(1)$(if $(value $(1)),=1,)
-endif
+else ifneq ($(strip $(value $(1))),n)
+DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
 endif
 endif
 endef
@@ -73,15 +71,6 @@ define MAKE_MODULE
         $(eval SOURCES    := $(2))
         $(eval OBJS_TEMP  := $(addprefix $(BUILD_DIR)/$(MODULE)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
         $(eval MODULE_OBJS += $(OBJS_TEMP))
-        # We use sort only to get a list of unique object directory names.
-        # ordering is not relevant but sort removes duplicates.
-        $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS_TEMP} ${LINKERFILE})))
-        # The $(dir ) function leaves a trailing / on the directory names
-        # Rip off the / to match directory names with make rule targets.
-        $(eval OBJ_DIRS := $(patsubst %/,%,$(TEMP_OBJ_DIRS)))
-
-$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
-${3}_dirs: | ${OBJ_DIRS}
 
 $(eval $(call MAKE_OBJS,$(BUILD_DIR)/$(MODULE),$(SOURCES),${3}))
 
@@ -103,12 +92,8 @@ MTK_PROJECT_CFG := $(MTK_PLAT)/project/$(PLAT)/project_config.mk
 MTK_OPTIONS := $(MTK_PLAT)/build_helpers/options.mk
 MTK_COND_EVAL := $(MTK_PLAT)/build_helpers/conditional_eval_options.mk
 
-# Indicate which BL should be built in command line
-ifeq (${NEED_BL32},yes)
-MTK_BL := bl32
-else
 MTK_BL := bl31
-endif
+
 # Include common, platform, board level config
 include $(MTK_COMMON_CFG)
 include $(MTK_PLAT_CFG)
diff --git a/plat/mediatek/common/mtk_bl31_setup.c b/plat/mediatek/common/mtk_bl31_setup.c
index 7c9db8bb..0d264b9d 100644
--- a/plat/mediatek/common/mtk_bl31_setup.c
+++ b/plat/mediatek/common/mtk_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2022-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -166,7 +166,6 @@ void bl31_platform_setup(void)
 void bl31_plat_runtime_setup(void)
 {
 	mtk_init_one_level(MTK_INIT_LVL_PLAT_RUNTIME);
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 unsigned int plat_get_syscnt_freq2(void)
diff --git a/plat/mediatek/common/mtk_smc_handlers.c b/plat/mediatek/common/mtk_smc_handlers.c
index 5a3ad1fb..beb06da8 100644
--- a/plat/mediatek/common/mtk_smc_handlers.c
+++ b/plat/mediatek/common/mtk_smc_handlers.c
@@ -99,13 +99,13 @@ static void print_smc_descriptor(const struct smc_descriptor pool[])
 {
 	const struct smc_descriptor *p_smc_desc;
 
-	INFO("print smc descriptor pool\n");
+	VERBOSE("print smc descriptor pool\n");
 	for (p_smc_desc = &pool[0];
 	     (char *)p_smc_desc < (char *)MTK_SMC_POOL_END_UNALIGNED;
 	     p_smc_desc++) {
-		INFO("descriptor name:%s\n", p_smc_desc->smc_name);
-		INFO("descriptor index:%d\n", *p_smc_desc->smc_descriptor_index);
-		INFO("smc id 32:0x%x, smc id 64:0x%x\n",
+		VERBOSE("descriptor name:%s\n", p_smc_desc->smc_name);
+		VERBOSE("descriptor index:%d\n", *p_smc_desc->smc_descriptor_index);
+		VERBOSE("smc id 32:0x%x, smc id 64:0x%x\n",
 		     p_smc_desc->smc_id_aarch32, p_smc_desc->smc_id_aarch64);
 	}
 }
diff --git a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
index 86c4b81c..cb57668f 100644
--- a/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
+++ b/plat/mediatek/drivers/apusys/apusys_rv/2.0/apusys_rv.c
@@ -37,18 +37,8 @@ void apusys_rv_mbox_mpu_init(void)
 
 int apusys_kernel_apusys_rv_setup_reviser(void)
 {
-	static bool apusys_rv_setup_reviser_called;
-
 	spin_lock(&apusys_rv_lock);
 
-	if (apusys_rv_setup_reviser_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_setup_reviser_called = true;
-
 	mmio_write_32(USERFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
 	mmio_write_32(SECUREFW_CTXT, CFG_4GB_SEL_EN | CFG_4GB_SEL);
 
@@ -74,18 +64,8 @@ int apusys_kernel_apusys_rv_setup_reviser(void)
 
 int apusys_kernel_apusys_rv_reset_mp(void)
 {
-	static bool apusys_rv_reset_mp_called;
-
 	spin_lock(&apusys_rv_lock);
 
-	if (apusys_rv_reset_mp_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_reset_mp_called = true;
-
 	mmio_write_32(MD32_SYS_CTRL, MD32_SYS_CTRL_RST);
 
 	dsb();
@@ -106,18 +86,8 @@ int apusys_kernel_apusys_rv_reset_mp(void)
 
 int apusys_kernel_apusys_rv_setup_boot(void)
 {
-	static bool apusys_rv_setup_boot_called;
-
 	spin_lock(&apusys_rv_lock);
 
-	if (apusys_rv_setup_boot_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_setup_boot_called = true;
-
 	mmio_write_32(MD32_BOOT_CTRL, APU_SEC_FW_IOVA);
 
 	mmio_write_32(MD32_PRE_DEFINE, (PREDEFINE_CACHE_TCM << PREDEF_1G_OFS) |
@@ -130,55 +100,17 @@ int apusys_kernel_apusys_rv_setup_boot(void)
 
 int apusys_kernel_apusys_rv_start_mp(void)
 {
-	static bool apusys_rv_start_mp_called;
-
 	spin_lock(&apusys_rv_lock);
-
-	if (apusys_rv_start_mp_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_start_mp_called = true;
-
 	mmio_write_32(MD32_RUNSTALL, MD32_RUN);
-
 	spin_unlock(&apusys_rv_lock);
 
 	return 0;
 }
 
-static bool watch_dog_is_timeout(void)
-{
-	if (mmio_read_32(WDT_INT) != WDT_INT_W1C) {
-		ERROR(MODULE_TAG "%s: WDT does not timeout\n", __func__);
-		return false;
-	}
-	return true;
-}
-
 int apusys_kernel_apusys_rv_stop_mp(void)
 {
-	static bool apusys_rv_stop_mp_called;
-
 	spin_lock(&apusys_rv_lock);
-
-	if (apusys_rv_stop_mp_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	if (watch_dog_is_timeout() == false) {
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_stop_mp_called = true;
-
 	mmio_write_32(MD32_RUNSTALL, MD32_STALL);
-
 	spin_unlock(&apusys_rv_lock);
 
 	return 0;
@@ -186,19 +118,10 @@ int apusys_kernel_apusys_rv_stop_mp(void)
 
 int apusys_kernel_apusys_rv_setup_sec_mem(void)
 {
-	static bool apusys_rv_setup_sec_mem_called;
 	int ret;
 
 	spin_lock(&apusys_rv_lock);
 
-	if (apusys_rv_setup_sec_mem_called) {
-		WARN(MODULE_TAG "%s: already initialized\n", __func__);
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
-	apusys_rv_setup_sec_mem_called = true;
-
 	ret = set_apu_emi_mpu_region();
 	if (ret != 0) {
 		ERROR(MODULE_TAG "%s: set emimpu protection failed\n", __func__);
@@ -230,12 +153,6 @@ int apusys_kernel_apusys_rv_clear_wdt_isr(void)
 int apusys_kernel_apusys_rv_cg_gating(void)
 {
 	spin_lock(&apusys_rv_lock);
-
-	if (watch_dog_is_timeout() == false) {
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
 	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_DIS);
 	spin_unlock(&apusys_rv_lock);
 
@@ -245,12 +162,6 @@ int apusys_kernel_apusys_rv_cg_gating(void)
 int apusys_kernel_apusys_rv_cg_ungating(void)
 {
 	spin_lock(&apusys_rv_lock);
-
-	if (watch_dog_is_timeout() == false) {
-		spin_unlock(&apusys_rv_lock);
-		return -1;
-	}
-
 	mmio_write_32(MD32_CLK_CTRL, MD32_CLK_EN);
 	spin_unlock(&apusys_rv_lock);
 
diff --git a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c
index da5242a7..f4ff7630 100644
--- a/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c
+++ b/plat/mediatek/drivers/apusys/mt8188/apusys_devapc.c
@@ -271,15 +271,8 @@ int apusys_devapc_ao_init(void)
 
 int apusys_devapc_rcx_init(void)
 {
-	static bool apusys_devapc_rcx_init_called;
 	enum apusys_apc_err_status ret;
 
-	if (apusys_devapc_rcx_init_called == true) {
-		INFO(MODULE_TAG "%s: init more than once!\n", __func__);
-		return -1;
-	}
-	apusys_devapc_rcx_init_called = true;
-
 	apusys_devapc_init("APUAPC_CTRL_RCX", APU_CTRL_DAPC_RCX_BASE);
 	apusys_devapc_init("APUAPC_NOC_RCX", APU_NOC_DAPC_RCX_BASE);
 
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
index ef7134cb..329a45e7 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu.h
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu.h
@@ -18,7 +18,7 @@
 #define FORBIDDEN			(5)
 #define SEC_R_NSEC_RW			(6)
 
-#define LOCK				(1)
+#define LOCK				(1UL)
 #define UNLOCK				(0)
 
 #if (EMI_MPU_DGROUP_NUM == 1)
@@ -69,6 +69,7 @@ int emi_mpu_init(void);
 int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
 						  uint64_t zone_info);
 int emi_mpu_set_protection(struct emi_region_info_t *region_info);
+int emi_mpu_clear_protection(unsigned int region);
 void set_emi_mpu_regions(void);
 int set_apu_emi_mpu_region(void);
 #endif
diff --git a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
index 8810be32..1e732f08 100644
--- a/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
+++ b/plat/mediatek/drivers/emi_mpu/emi_mpu_common.c
@@ -39,13 +39,13 @@ static int _emi_mpu_set_protection(unsigned int start, unsigned int end,
 	}
 
 #if ENABLE_EMI_MPU_SW_LOCK
-	if (region_lock_state[region] == 1) {
+	if (region_lock_state[region] == LOCK) {
 		WARN("invalid region\n");
 		return -1;
 	}
 
 	if ((dgroup == 0) && ((apc >> 31) & 0x1)) {
-		region_lock_state[region] = 1;
+		region_lock_state[region] = LOCK;
 	}
 
 	apc &= EMI_MPU_APC_SW_LOCK_MASK;
@@ -73,6 +73,50 @@ static int _emi_mpu_set_protection(unsigned int start, unsigned int end,
 	return 0;
 }
 
+int emi_mpu_clear_protection(unsigned int region)
+{
+	unsigned int dgroup;
+
+	if (region >= EMI_MPU_REGION_NUM) {
+		WARN("invalid region number\n");
+		return -1;
+	}
+
+#if ENABLE_EMI_MPU_SW_LOCK
+	if (region_lock_state[region] == LOCK) {
+		WARN("SW:region is locked\n");
+		return -1;
+	}
+#endif
+	if (mmio_read_32(EMI_MPU_APC(region, 0)) & (LOCK << 31UL)) {
+		WARN("HW:EMI-MPU region is locked\n");
+		return -1;
+	}
+
+#if defined(SUB_EMI_MPU_BASE)
+	if (mmio_read_32(SUB_EMI_MPU_APC(region, 0)) & (LOCK << 31UL)) {
+		WARN("HW:SUB EMI-MPU region is locked\n");
+		return -1;
+	}
+#endif
+
+	for (dgroup = 0; dgroup < EMI_MPU_DGROUP_NUM; dgroup++)
+		mmio_write_32(EMI_MPU_APC(region, dgroup), 0x0);
+
+	mmio_write_32(EMI_MPU_SA(region), 0x0);
+	mmio_write_32(EMI_MPU_EA(region), 0x0);
+
+#if defined(SUB_EMI_MPU_BASE)
+	for (dgroup = 0; dgroup < EMI_MPU_DGROUP_NUM; dgroup++)
+		mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), 0x0);
+
+	mmio_write_32(SUB_EMI_MPU_SA(region), 0);
+	mmio_write_32(SUB_EMI_MPU_EA(region), 0);
+#endif
+	return 0;
+}
+
+
 static void dump_emi_mpu_regions(void)
 {
 	int region, i;
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
index e8882f07..c46cca8f 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu.c
@@ -14,11 +14,35 @@ void set_emi_mpu_regions(void)
 {
 	struct emi_region_info_t region_info;
 
+	/* BL31 address */
+	region_info.start = TZRAM_BASE;
+	region_info.end = TZRAM_BASE + TZRAM_SIZE - 1;
+	region_info.region = BL31_EMI_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
+	emi_mpu_set_protection(&region_info);
+
+#ifndef SPD_NONE
+	/* BL32 address */
+	region_info.start = BL32_REGION_BASE;
+	region_info.end = BL32_REGION_BASE + BL32_REGION_SIZE - 1;
+	region_info.region = BL32_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+			      FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
+	emi_mpu_set_protection(&region_info);
+#endif
+
 	/* SCP core0 DRAM */
-	region_info.start = 0x50000000ULL;
-	region_info.end = 0x528FFFFFULL;
-	region_info.region = 2;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = SCP_CORE0_REGION_BASE;
+	region_info.end = SCP_CORE0_REGION_BASE + SCP_CORE0_REGION_SIZE - 1;
+	region_info.region = SCP_CORE0_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -26,10 +50,10 @@ void set_emi_mpu_regions(void)
 	emi_mpu_set_protection(&region_info);
 
 	/* SCP core1 DRAM */
-	region_info.start = 0x70000000ULL;
-	region_info.end = 0x729FFFFFULL;
-	region_info.region = 3;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = SCP_CORE1_REGION_BASE;
+	region_info.end = SCP_CORE1_REGION_BASE + SCP_CORE1_REGION_SIZE - 1;
+	region_info.region = SCP_CORE1_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -37,10 +61,10 @@ void set_emi_mpu_regions(void)
 	emi_mpu_set_protection(&region_info);
 
 	/* DSP protect address */
-	region_info.start = 0x60000000ULL;
-	region_info.end = 0x610FFFFFULL;
-	region_info.region = 4;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = DSP_PROTECT_REGION_BASE;
+	region_info.end = DSP_PROTECT_REGION_BASE + DSP_PROTECT_REGION_SIZE - 1;
+	region_info.region = DSP_PROTECT_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
@@ -48,10 +72,10 @@ void set_emi_mpu_regions(void)
 	emi_mpu_set_protection(&region_info);
 
 	/* All default settings */
-	region_info.start = 0x40000000ULL;
-	region_info.end = 0x1FFFF0000ULL;
-	region_info.region = 31;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
+	region_info.start = DRAM_START_ADDR;
+	region_info.end = DRAM_START_ADDR + DRAM_MAX_SIZE - 1;
+	region_info.region = ALL_DEFAULT_REGION_ID;
+	SET_ACCESS_PERMISSION(region_info.apc, LOCK,
 			      FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
 			      NO_PROTECTION, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
 			      NO_PROTECTION, SEC_R_NSEC_RW, NO_PROTECTION, FORBIDDEN,
@@ -65,7 +89,7 @@ int set_apu_emi_mpu_region(void)
 
 	region_info.start = (unsigned long long)APUSYS_SEC_BUF_PA;
 	region_info.end = (unsigned long long)(APUSYS_SEC_BUF_PA + APUSYS_SEC_BUF_SZ) - 1;
-	region_info.region = APUSYS_SEC_BUF_EMI_REGION;
+	region_info.region = APUSYS_SEC_BUF_EMI_REGION_ID;
 
 	SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
 			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     FORBIDDEN,
@@ -86,32 +110,42 @@ static inline uint32_t get_decoded_zone_id(uint32_t info)
 	return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS);
 }
 
+static inline uint32_t get_decoded_set_clear_info(uint32_t info)
+{
+	return (info & 0x0000FFFF);
+}
+
 int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
 						  uint64_t zone_info)
 {
 	uint64_t phys_addr = get_decoded_phys_addr(encoded_addr);
 	struct emi_region_info_t region_info;
-	enum MPU_REQ_ORIGIN_ZONE_ID zone_id = get_decoded_zone_id(zone_info);
+	enum region_ids zone_id = get_decoded_zone_id(zone_info);
+	uint32_t is_set = get_decoded_set_clear_info(zone_info);
 
 	INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n",
 	     encoded_addr, zone_size, zone_info);
 
-	if (zone_id != MPU_REQ_ORIGIN_TEE_ZONE_SVP) {
+	if (zone_id < SVP_DRAM_REGION_ID_START || zone_id > SVP_DRAM_REGION_ID_END) {
 		ERROR("Invalid param %s, %d\n", __func__, __LINE__);
 		return MTK_SIP_E_INVALID_PARAM;
 	}
 
-	/* SVP DRAM */
-	region_info.start = phys_addr;
-	region_info.end = phys_addr + zone_size;
-	region_info.region = 4;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
-
-	emi_mpu_set_protection(&region_info);
+	if (is_set > 0) {
+		/* SVP DRAM */
+		region_info.start = phys_addr;
+		region_info.end = phys_addr + zone_size - 1;
+		region_info.region = zone_id;
+		SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
+					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+					  FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
+					  FORBIDDEN, SEC_RW, FORBIDDEN, FORBIDDEN,
+					  FORBIDDEN, FORBIDDEN, SEC_RW, SEC_RW);
+
+		emi_mpu_set_protection(&region_info);
+	} else { /* clear region protection */
+		emi_mpu_clear_protection(zone_id);
+	}
 
 	return 0;
-}
\ No newline at end of file
+}
diff --git a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
index cc7f7f1e..b64020d7 100644
--- a/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
+++ b/plat/mediatek/drivers/emi_mpu/mt8188/emi_mpu_priv.h
@@ -7,7 +7,7 @@
 #ifndef EMI_MPU_PRIV_H
 #define EMI_MPU_PRIV_H
 
-#define ENABLE_EMI_MPU_SW_LOCK		(1)
+#define ENABLE_EMI_MPU_SW_LOCK		(0)
 
 #define EMI_MPU_CTRL			(EMI_MPU_BASE + 0x000)
 #define EMI_MPU_DBG			(EMI_MPU_BASE + 0x004)
@@ -38,13 +38,37 @@
 #define EMI_MPU_DOMAIN_NUM		(16)
 #define EMI_MPU_REGION_NUM		(32)
 #define EMI_MPU_ALIGN_BITS		(16)
-#define DRAM_OFFSET			(0x40000000 >> EMI_MPU_ALIGN_BITS)
+#define DRAM_START_ADDR                 (0x40000000ULL)
+#define DRAM_OFFSET			(DRAM_START_ADDR >> EMI_MPU_ALIGN_BITS)
+#define DRAM_MAX_SIZE			(0x200000000ULL)
+#define BL32_REGION_BASE		(0x43000000ULL)
+#define BL32_REGION_SIZE		(0x4600000ULL)
+#define SCP_CORE0_REGION_BASE		(0x50000000ULL)
+#define SCP_CORE0_REGION_SIZE		(0x800000ULL)
+#define SCP_CORE1_REGION_BASE		(0x70000000ULL)
+#define SCP_CORE1_REGION_SIZE		(0xa000000ULL)
+#define DSP_PROTECT_REGION_BASE		(0x60000000ULL)
+#define DSP_PROTECT_REGION_SIZE		(0x1100000ULL)
 
 #define EMI_MPU_DGROUP_NUM		(EMI_MPU_DOMAIN_NUM / 8)
 
 /* APU EMI MPU Setting */
-#define APUSYS_SEC_BUF_EMI_REGION	(21)
 #define APUSYS_SEC_BUF_PA		(0x55000000)
 #define APUSYS_SEC_BUF_SZ		(0x100000)
 
+#define SVP_DRAM_REGION_COUNT		(10)
+
+enum region_ids {
+	BL31_EMI_REGION_ID = 0,
+	BL32_REGION_ID,
+	SCP_CORE0_REGION_ID,
+	SCP_CORE1_REGION_ID,
+	DSP_PROTECT_REGION_ID,
+	SVP_DRAM_REGION_ID_START = 5,
+	SVP_DRAM_REGION_ID_END = SVP_DRAM_REGION_ID_START + SVP_DRAM_REGION_COUNT - 1,
+
+	APUSYS_SEC_BUF_EMI_REGION_ID = 21,
+
+	ALL_DEFAULT_REGION_ID = 31,
+};
 #endif
diff --git a/plat/mediatek/drivers/gic600/mt_gic_v3.c b/plat/mediatek/drivers/gic600/mt_gic_v3.c
index 85f9e37e..2f9765c1 100644
--- a/plat/mediatek/drivers/gic600/mt_gic_v3.c
+++ b/plat/mediatek/drivers/gic600/mt_gic_v3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2020-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,6 +27,10 @@ static uint32_t rdist_has_saved[PLATFORM_CORE_COUNT];
 /* we save and restore the GICv3 context on system suspend */
 gicv3_dist_ctx_t dist_ctx;
 
+static const interrupt_prop_t mtk_interrupt_props[] = {
+	PLAT_MTK_G1S_IRQ_PROPS(INTR_GROUP1S)
+};
+
 static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr)
 {
 	return plat_core_pos_by_mpidr(mpidr);
@@ -35,6 +39,8 @@ static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr)
 gicv3_driver_data_t mt_gicv3_data = {
 	.gicd_base = MT_GIC_BASE,
 	.gicr_base = MT_GIC_RDIST_BASE,
+	.interrupt_props = mtk_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(mtk_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
 	.rdistif_base_addrs = rdistif_base_addrs,
 	.mpidr_to_core_pos = mt_mpidr_to_core_pos,
diff --git a/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c
index 1d6863ff..64a10f1a 100644
--- a/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c
+++ b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.c
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <mtk_iommu_plat.h>
+#include <mtk_iommu_priv.h>
 #include <mtk_mmap_pool.h>
 #include <platform_def.h>
 
@@ -42,7 +42,7 @@
 #define MMU_DEV_PCIE_0		(0)
 #define IFR_CFG_GROUP_NUM	(1)
 
-static struct mtk_smi_larb_config mt8188_larb_cfg[SMI_LARB_NUM] = {
+static struct mtk_smi_larb_config mt8188_larb_cfg[] = {
 	[SMI_L0_ID] = LARB_CFG_ENTRY(SMI_LARB_0_BASE, 7, 0),
 	[SMI_L1_ID] = LARB_CFG_ENTRY(SMI_LARB_1_BASE, 7, 0),
 	[SMI_L2_ID] = LARB_CFG_ENTRY(SMI_LARB_2_BASE, 5, 0),
@@ -80,12 +80,24 @@ static uint32_t mt8188_ifr_mst_cfg_base[IFR_CFG_GROUP_NUM] = {
 static uint32_t mt8188_ifr_mst_cfg_offs[IFR_CFG_GROUP_NUM] = {
 	PERICFG_AO_IOMMU_1,
 };
-static struct mtk_ifr_mst_config mt8188_ifr_mst_cfg[MMU_DEV_NUM] = {
+static struct mtk_ifr_mst_config mt8188_ifr_mst_cfg[] = {
 	[MMU_DEV_PCIE_0] = IFR_MST_CFG_ENTRY(0, 18),
 };
 
 struct mtk_smi_larb_config *g_larb_cfg = &mt8188_larb_cfg[0];
+const unsigned int g_larb_num = ARRAY_SIZE(mt8188_larb_cfg);
+
+static struct mtk_secure_iommu_config mt8188_secure_iommu_config[] = {
+	SEC_IOMMU_CFG_ENTRY(VDO_SECURE_IOMMU_BASE),
+	SEC_IOMMU_CFG_ENTRY(VPP_SECURE_IOMMU_BASE),
+};
+
+struct mtk_secure_iommu_config *g_sec_iommu_cfg = &mt8188_secure_iommu_config[0];
+const unsigned int g_sec_iommu_num = ARRAY_SIZE(mt8188_secure_iommu_config);
+
 struct mtk_ifr_mst_config *g_ifr_mst_cfg = &mt8188_ifr_mst_cfg[0];
+const unsigned int g_ifr_mst_num = ARRAY_SIZE(mt8188_ifr_mst_cfg);
+
 uint32_t *g_ifr_mst_cfg_base = &mt8188_ifr_mst_cfg_base[0];
 uint32_t *g_ifr_mst_cfg_offs = &mt8188_ifr_mst_cfg_offs[0];
 
diff --git a/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h
index a59e0c78..a3f38a53 100644
--- a/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h
+++ b/plat/mediatek/drivers/iommu/mt8188/mtk_iommu_plat.h
@@ -7,18 +7,13 @@
 #ifndef IOMMU_PLAT_H
 #define IOMMU_PLAT_H
 
-#include <mtk_iommu_priv.h>
-
 /* mm iommu */
-#define SMI_LARB_NUM	(26)
-extern struct mtk_smi_larb_config *g_larb_cfg;
+#define ATF_MTK_SMI_LARB_CFG_SUPPORT
 
-/* infra iommu */
-#define MMU_DEV_NUM	(1)
-extern struct mtk_ifr_mst_config *g_ifr_mst_cfg;
-extern uint32_t *g_ifr_mst_cfg_base;
-extern uint32_t *g_ifr_mst_cfg_offs;
+/* mm iommu, sec bank dump */
+#define ATF_MTK_IOMMU_CFG_SUPPORT
 
-extern void mtk_infra_iommu_enable_protect(void);
+/* infra iommu */
+#define ATF_MTK_INFRA_MASTER_CFG_SUPPORT
 
 #endif /* IOMMU_PLAT_H */
diff --git a/plat/mediatek/drivers/iommu/mtk_iommu_priv.h b/plat/mediatek/drivers/iommu/mtk_iommu_priv.h
index 3404d313..bae36948 100644
--- a/plat/mediatek/drivers/iommu/mtk_iommu_priv.h
+++ b/plat/mediatek/drivers/iommu/mtk_iommu_priv.h
@@ -9,6 +9,7 @@
 
 #include <common/debug.h>
 #include <lib/mmio.h>
+#include <mtk_iommu_plat.h>
 #include <mtk_sip_svc.h>
 
 #define LARB_CFG_ENTRY(bs, p_nr, dom)			\
@@ -22,9 +23,13 @@
 #define IFR_MST_CFG_ENTRY(idx, bit)	\
 	{ .cfg_addr_idx = (idx), .r_mmu_en_bit = (bit), }
 
+#define SEC_IOMMU_CFG_ENTRY(s_bs)	\
+	{ .base = (s_bs), }
+
 enum IOMMU_ATF_CMD {
 	IOMMU_ATF_CMD_CONFIG_SMI_LARB,		/* For mm master to enable iommu */
 	IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU,	/* For infra master to enable iommu */
+	IOMMU_ATF_CMD_GET_SECURE_IOMMU_STATUS,	/* For secure iommu translation fault report */
 	IOMMU_ATF_CMD_COUNT,
 };
 
@@ -41,4 +46,30 @@ struct mtk_ifr_mst_config {
 	uint8_t r_mmu_en_bit;
 };
 
+struct mtk_secure_iommu_config {
+	uint32_t base;
+};
+
+
+#ifdef ATF_MTK_SMI_LARB_CFG_SUPPORT
+/* mm smi larb security feature is used */
+extern struct mtk_smi_larb_config *g_larb_cfg;
+extern const unsigned int g_larb_num;
+#endif
+
+#ifdef ATF_MTK_INFRA_MASTER_CFG_SUPPORT
+/* infra iommu is used */
+extern struct mtk_ifr_mst_config *g_ifr_mst_cfg;
+extern const unsigned int g_ifr_mst_num;
+extern uint32_t *g_ifr_mst_cfg_base;
+extern uint32_t *g_ifr_mst_cfg_offs;
+extern void mtk_infra_iommu_enable_protect(void);
+#endif
+
+#ifdef ATF_MTK_IOMMU_CFG_SUPPORT
+/* secure iommu is used */
+extern struct mtk_secure_iommu_config *g_sec_iommu_cfg;
+extern const unsigned int g_sec_iommu_num;
+#endif
+
 #endif	/* IOMMU_PRIV_H */
diff --git a/plat/mediatek/drivers/iommu/mtk_iommu_smc.c b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
index e9987254..7d701143 100644
--- a/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
+++ b/plat/mediatek/drivers/iommu/mtk_iommu_smc.c
@@ -5,7 +5,7 @@
  */
 
 #include <stddef.h>
-#include <mtk_iommu_plat.h>
+#include <mtk_iommu_priv.h>
 
 /* defination */
 /* smi larb */
@@ -23,12 +23,23 @@
 /* infra master */
 #define IFR_CFG_MMU_EN_MSK(r_bit)	(0x3 << (r_bit))
 
+/* secure iommu */
+#define MMU_INT_CONTROL0		(0x120)
+#define INT_CLR				BIT(12)
+#define MMU_FAULT_ST1			(0x134)
+#define MMU_AXI_0_ERR_MASK		GENMASK(6, 0)
+#define MMU_AXI_FAULT_STATUS(bus)	(0x13c + (bus) * 8)
+#define MMU_AXI_INVLD_PA(bus)		(0x140 + (bus) * 8)
+#define MMU_AXI_INT_ID(bus)		(0x150 + (bus) * 4)
+
 /* smi larb configure */
 /*
  * If multimedia security config is enabled, the SMI config register must be
  * configurated in security world.
  * And the SRAM path is also configurated here to enhance security.
  */
+#ifdef ATF_MTK_SMI_LARB_CFG_SUPPORT
+
 static void mtk_smi_larb_port_config_to_sram(
 				const struct mtk_smi_larb_config *larb,
 				uint32_t port_id)
@@ -55,7 +66,7 @@ static int mtk_smi_larb_port_config_sec(uint32_t larb_id, uint32_t mmu_en_msk)
 	uint32_t to_sram;
 	uint8_t mmu_en;
 
-	if (larb_id >= SMI_LARB_NUM) {
+	if (larb_id >= g_larb_num) {
 		return MTK_SIP_E_INVALID_PARAM;
 	}
 
@@ -75,6 +86,11 @@ static int mtk_smi_larb_port_config_sec(uint32_t larb_id, uint32_t mmu_en_msk)
 	return MTK_SIP_E_SUCCESS;
 }
 
+#endif /* ATF_MTK_SMI_LARB_CFG_SUPPORT */
+
+/* infra iommu configure */
+#ifdef ATF_MTK_INFRA_MASTER_CFG_SUPPORT
+
 static int mtk_infra_master_config_sec(uint32_t dev_id_msk, uint32_t enable)
 {
 	const struct mtk_ifr_mst_config *ifr_cfg;
@@ -82,11 +98,11 @@ static int mtk_infra_master_config_sec(uint32_t dev_id_msk, uint32_t enable)
 
 	mtk_infra_iommu_enable_protect();
 
-	if (dev_id_msk >= BIT(MMU_DEV_NUM)) {
+	if (dev_id_msk >= BIT(g_ifr_mst_num)) {
 		return MTK_SIP_E_INVALID_PARAM;
 	}
 
-	for (dev_id = 0U; dev_id < MMU_DEV_NUM; dev_id++) {
+	for (dev_id = 0U; dev_id < g_ifr_mst_num; dev_id++) {
 		if ((dev_id_msk & BIT(dev_id)) == 0U) {
 			continue;
 		}
@@ -105,10 +121,50 @@ static int mtk_infra_master_config_sec(uint32_t dev_id_msk, uint32_t enable)
 
 	return MTK_SIP_E_SUCCESS;
 }
+#endif /* ATF_MTK_INFRA_MASTER_CFG_SUPPORT */
+
+/* secure iommu */
+#ifdef ATF_MTK_IOMMU_CFG_SUPPORT
+/* Report secure IOMMU fault status to normal world for the debug version */
+static int mtk_secure_iommu_fault_report(uint32_t sec_mmu_base,
+					 uint32_t *f_sta, uint32_t *f_pa,
+					 uint32_t *f_id)
+{
+	const struct mtk_secure_iommu_config *mmu_cfg = NULL;
+	uint32_t __maybe_unused bus_id, fault_type;
+	uint32_t i;
+	int ret = MTK_SIP_E_NOT_SUPPORTED;
 
-static u_register_t mtk_iommu_handler(u_register_t x1, u_register_t x2,
-				      u_register_t x3, u_register_t x4,
-				      void *handle, struct smccc_res *smccc_ret)
+	for (i = 0; i < g_sec_iommu_num; i++) {
+		if (g_sec_iommu_cfg[i].base == sec_mmu_base) {
+			mmu_cfg = &g_sec_iommu_cfg[i];
+			break;
+		}
+	}
+
+	if (!mmu_cfg)
+		return MTK_SIP_E_INVALID_PARAM;
+#if DEBUG
+	fault_type = mmio_read_32(mmu_cfg->base + MMU_FAULT_ST1);
+	bus_id = (fault_type & MMU_AXI_0_ERR_MASK) ? 0 : 1;
+
+	if (f_sta)
+		*f_sta = mmio_read_32(mmu_cfg->base + MMU_AXI_FAULT_STATUS(bus_id));
+	if (f_pa)
+		*f_pa = mmio_read_32(mmu_cfg->base + MMU_AXI_INVLD_PA(bus_id));
+	if (f_id)
+		*f_id = mmio_read_32(mmu_cfg->base + MMU_AXI_INT_ID(bus_id));
+	ret = MTK_SIP_E_SUCCESS;
+#endif
+	mmio_setbits_32(mmu_cfg->base + MMU_INT_CONTROL0, INT_CLR);
+
+	return ret;
+}
+#endif /* ATF_MTK_IOMMU_CFG_SUPPORT */
+
+u_register_t mtk_iommu_handler(u_register_t x1, u_register_t x2,
+			u_register_t x3, u_register_t x4,
+			void *handle, struct smccc_res *smccc_ret)
 {
 	uint32_t cmd_id = x1, mdl_id = x2, val = x3;
 	int ret = MTK_SIP_E_NOT_SUPPORTED;
@@ -117,12 +173,25 @@ static u_register_t mtk_iommu_handler(u_register_t x1, u_register_t x2,
 	(void)handle;
 
 	switch (cmd_id) {
+#ifdef ATF_MTK_SMI_LARB_CFG_SUPPORT
 	case IOMMU_ATF_CMD_CONFIG_SMI_LARB:
 		ret = mtk_smi_larb_port_config_sec(mdl_id, val);
 		break;
+#endif
+#ifdef ATF_MTK_INFRA_MASTER_CFG_SUPPORT
 	case IOMMU_ATF_CMD_CONFIG_INFRA_IOMMU:
 		ret = mtk_infra_master_config_sec(mdl_id, val);
 		break;
+#endif
+#ifdef ATF_MTK_IOMMU_CFG_SUPPORT
+	case IOMMU_ATF_CMD_GET_SECURE_IOMMU_STATUS:
+		(void)val;
+		ret = mtk_secure_iommu_fault_report(mdl_id,
+					(uint32_t *)&smccc_ret->a1,
+					(uint32_t *)&smccc_ret->a2,
+					(uint32_t *)&smccc_ret->a3);
+		break;
+#endif
 	default:
 		break;
 	}
diff --git a/plat/mediatek/drivers/iommu/mtk_iommu_smc.h b/plat/mediatek/drivers/iommu/mtk_iommu_smc.h
new file mode 100644
index 00000000..9537dbe9
--- /dev/null
+++ b/plat/mediatek/drivers/iommu/mtk_iommu_smc.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2023, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IOMMU_SMC_H
+#define IOMMU_SMC_H
+
+#include <mtk_sip_svc.h>
+
+u_register_t mtk_iommu_handler(u_register_t x1, u_register_t x2,
+			u_register_t x3, u_register_t x4,
+			void *handle, struct smccc_res *smccc_ret);
+#endif
diff --git a/plat/mediatek/drivers/rng/mt8186/rng_plat.c b/plat/mediatek/drivers/rng/mt8186/rng_plat.c
new file mode 100644
index 00000000..691b9233
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8186/rng_plat.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <lib/spinlock.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <services/trng_svc.h>
+#include <smccc_helpers.h>
+
+#include <mtk_mmap_pool.h>
+#include <mtk_sip_svc.h>
+#include "rng_plat.h"
+
+static spinlock_t rng_lock;
+
+static int trng_wait(uint32_t reg, uint32_t expected_value)
+{
+	uint64_t timeout = timeout_init_us(TRNG_TIME_OUT);
+	uint32_t value = 0;
+
+	do {
+		value = mmio_read_32(reg);
+		if ((value & expected_value) == expected_value)
+			return 0;
+
+		udelay(10);
+	} while (!timeout_elapsed(timeout));
+
+	return -ETIMEDOUT;
+}
+
+static int trng_write(uint32_t reg, uint32_t value,
+			   uint32_t read_reg, uint32_t expected_value)
+{
+	int retry = MTK_TRNG_MAX_ROUND;
+	uint32_t read_value = 0;
+
+	do {
+		mmio_write_32(reg, value);
+
+		read_value = mmio_read_32(read_reg);
+		if ((read_value & value) == expected_value)
+			return 0;
+
+		udelay(10);
+	} while (--retry > 0);
+
+	return -ETIMEDOUT;
+}
+
+static uint32_t trng_prng(uint32_t *rand)
+{
+	int32_t ret = 0;
+	uint32_t seed[4] = {0};
+
+	if (rand == NULL)
+		return MTK_SIP_E_INVALID_PARAM;
+
+	/* ungate */
+	ret = trng_write(TRNG_PDN_CLR, TRNG_PDN_VALUE, TRNG_PDN_STATUS, 0);
+	if (ret) {
+		ERROR("%s: ungate fail\n", __func__);
+		return MTK_SIP_E_NOT_SUPPORTED;
+	}
+
+	/* read random data once and drop it */
+	seed[0] = mmio_read_32(TRNG_DATA);
+
+	/* enable von-neumann extractor */
+	mmio_setbits_32(TRNG_CONF, TRNG_CONF_VON_EN);
+
+	/* start */
+	mmio_setbits_32(TRNG_CTRL, TRNG_CTRL_START);
+
+	/* get seeds from trng */
+	for (int i = 0; i < ARRAY_SIZE(seed); i++) {
+		ret = trng_wait(TRNG_CTRL, TRNG_CTRL_RDY);
+		if (ret) {
+			ERROR("%s: trng NOT ready\n", __func__);
+			return MTK_SIP_E_NOT_SUPPORTED;
+		}
+
+		seed[i] = mmio_read_32(TRNG_DATA);
+	}
+
+	/* stop */
+	mmio_clrbits_32(TRNG_CTRL, TRNG_CTRL_START);
+
+	/* gate */
+	ret = trng_write(TRNG_PDN_SET, TRNG_PDN_VALUE, TRNG_PDN_STATUS, TRNG_PDN_VALUE);
+	if (ret) {
+		ERROR("%s: gate fail\n", __func__);
+		return MTK_SIP_E_NOT_SUPPORTED;
+	}
+
+	for (int i = 0; i < ARRAY_SIZE(seed); i++)
+		rand[i] = seed[i];
+
+	return 0;
+}
+
+static uint32_t get_true_rnd(uint32_t *val, uint32_t num)
+{
+	uint32_t rand[4] = {0};
+	uint32_t ret;
+
+	if (val == NULL || num > ARRAY_SIZE(rand))
+		return MTK_SIP_E_INVALID_PARAM;
+
+	spin_lock(&rng_lock);
+	ret = trng_prng(rand);
+	spin_unlock(&rng_lock);
+
+	for (int i = 0; i < num; i++)
+		val[i] = rand[i];
+
+	return ret;
+}
+
+/*
+ * plat_get_entropy - get 64-bit random number data which is used form
+ * atf early stage
+ * output - out: output 64-bit entropy combine with 2 32-bit random number
+ */
+bool plat_get_entropy(uint64_t *out)
+{
+	uint32_t entropy_pool[2] = {0};
+	uint32_t ret;
+
+	assert(out);
+	assert(!check_uptr_overflow((uintptr_t)out, sizeof(*out)));
+
+	/* Get 2 32-bits entropy */
+	ret = get_true_rnd(entropy_pool, ARRAY_SIZE(entropy_pool));
+	if (ret)
+		return false;
+
+	/* Output 8 bytes entropy combine with 2 32-bit random number. */
+	*out = ((uint64_t)entropy_pool[0] << 32) | entropy_pool[1];
+
+	return true;
+}
diff --git a/plat/mediatek/drivers/rng/mt8186/rng_plat.h b/plat/mediatek/drivers/rng/mt8186/rng_plat.h
new file mode 100644
index 00000000..ab22c45d
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8186/rng_plat.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RNG_PLAT_H
+#define RNG_PLAT_H
+
+#define TRNG_TIME_OUT		1000
+#define MTK_TRNG_MAX_ROUND	4
+
+/*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE_SIZE		0x1000
+#define TRNG_CTRL		(TRNG_BASE + 0x0000)
+#define TRNG_TIME		(TRNG_BASE + 0x0004)
+#define TRNG_DATA		(TRNG_BASE + 0x0008)
+#define TRNG_CONF		(TRNG_BASE + 0x000C)
+#define TRNG_CTRL_RDY		0x80000000
+#define TRNG_CTRL_START		0x00000001
+#define TRNG_CONF_VON_EN	0x00000020
+#define TRNG_PDN_BASE_SIZE	0x1000
+#define TRNG_PDN_SET		(INFRACFG_AO_BASE + 0x0088)
+#define TRNG_PDN_CLR		(INFRACFG_AO_BASE + 0x008C)
+#define TRNG_PDN_STATUS		(INFRACFG_AO_BASE + 0x0094)
+#define TRNG_PDN_VALUE		0x200
+
+#endif /* RNG_PLAT_H */
diff --git a/plat/mediatek/drivers/rng/mt8188/rng_plat.c b/plat/mediatek/drivers/rng/mt8188/rng_plat.c
new file mode 100644
index 00000000..361be222
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8188/rng_plat.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/smccc.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <services/trng_svc.h>
+#include <smccc_helpers.h>
+
+#include "rng_plat.h"
+
+static void trng_external_swrst(void)
+{
+	/* External swrst to reset whole rng module */
+	mmio_setbits_32(TRNG_SWRST_SET_REG, RNG_SWRST_B);
+	mmio_setbits_32(TRNG_SWRST_CLR_REG, RNG_SWRST_B);
+
+	/* Disable irq */
+	mmio_clrbits_32(RNG_IRQ_CFG, IRQ_EN);
+	/* Set default cutoff value */
+	mmio_write_32(RNG_HTEST, RNG_DEFAULT_CUTOFF);
+	/* Enable rng */
+	mmio_setbits_32(RNG_EN, DRBG_EN | NRBG_EN);
+}
+
+static bool get_entropy_32(uint32_t *out)
+{
+	uint64_t time = timeout_init_us(MTK_TIMEOUT_POLL);
+	int retry_times = 0;
+
+	while (!(mmio_read_32(RNG_STATUS) & DRBG_VALID)) {
+		if (mmio_read_32(RNG_STATUS) & (RNG_ERROR | APB_ERROR)) {
+			mmio_clrbits_32(RNG_EN, DRBG_EN | NRBG_EN);
+
+			mmio_clrbits_32(RNG_SWRST, SWRST_B);
+			mmio_setbits_32(RNG_SWRST, SWRST_B);
+
+			mmio_setbits_32(RNG_EN, DRBG_EN | NRBG_EN);
+		}
+
+		if (timeout_elapsed(time)) {
+			trng_external_swrst();
+			time = timeout_init_us(MTK_TIMEOUT_POLL);
+			retry_times++;
+		}
+
+		if (retry_times > MTK_RETRY_CNT) {
+			ERROR("%s: trng NOT ready\n", __func__);
+			return false;
+		}
+	}
+
+	*out = mmio_read_32(RNG_OUT);
+
+	return true;
+}
+
+/* Get random number from HWRNG and return 8 bytes of entropy.
+ * Return 'true' when random value generated successfully, otherwise return
+ * 'false'.
+ */
+bool plat_get_entropy(uint64_t *out)
+{
+	uint32_t seed[2] = { 0 };
+	int i = 0;
+
+	assert(out);
+	assert(!check_uptr_overflow((uintptr_t)out, sizeof(*out)));
+
+	/* Disable interrupt mode */
+	mmio_clrbits_32(RNG_IRQ_CFG, IRQ_EN);
+	/* Set rng health test cutoff value */
+	mmio_write_32(RNG_HTEST, RNG_DEFAULT_CUTOFF);
+	/* Enable rng module */
+	mmio_setbits_32(RNG_EN, DRBG_EN | NRBG_EN);
+
+	for (i = 0; i < ARRAY_SIZE(seed); i++) {
+		if (!get_entropy_32(&seed[i]))
+			return false;
+	}
+
+	/* Output 8 bytes entropy by combining 2 32-bit random numbers. */
+	*out = ((uint64_t)seed[0] << 32) | seed[1];
+
+	return true;
+}
diff --git a/plat/mediatek/drivers/rng/mt8188/rng_plat.h b/plat/mediatek/drivers/rng/mt8188/rng_plat.h
new file mode 100644
index 00000000..37ef2711
--- /dev/null
+++ b/plat/mediatek/drivers/rng/mt8188/rng_plat.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RNG_PLAT_H
+#define RNG_PLAT_H
+
+#include <lib/utils_def.h>
+
+#define MTK_TIMEOUT_POLL	1000
+
+#define MTK_RETRY_CNT		10
+
+#define RNG_DEFAULT_CUTOFF	0x04871C0B
+
+/*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define RNG_STATUS		(TRNG_BASE + 0x0004)
+#define RNG_SWRST		(TRNG_BASE + 0x0010)
+#define RNG_IRQ_CFG		(TRNG_BASE + 0x0014)
+#define RNG_EN			(TRNG_BASE + 0x0020)
+#define RNG_HTEST		(TRNG_BASE + 0x0028)
+#define RNG_OUT			(TRNG_BASE + 0x0030)
+#define RNG_RAW			(TRNG_BASE + 0x0038)
+#define RNG_SRC			(TRNG_BASE + 0x0050)
+
+#define RAW_VALID		BIT(12)
+#define DRBG_VALID		BIT(4)
+#define RAW_EN			BIT(8)
+#define NRBG_EN			BIT(4)
+#define DRBG_EN			BIT(0)
+#define IRQ_EN			BIT(0)
+#define SWRST_B			BIT(0)
+/* Error conditions */
+#define RNG_ERROR		GENMASK_32(28, 24)
+#define APB_ERROR		BIT(16)
+
+/* External swrst */
+#define TRNG_SWRST_SET_REG	(INFRACFG_AO_BASE + 0x150)
+#define TRNG_SWRST_CLR_REG	(INFRACFG_AO_BASE + 0x154)
+#define RNG_SWRST_B		BIT(13)
+
+#endif /* RNG_PLAT_H */
diff --git a/plat/mediatek/drivers/rng/rng.c b/plat/mediatek/drivers/rng/rng.c
new file mode 100644
index 00000000..d611168b
--- /dev/null
+++ b/plat/mediatek/drivers/rng/rng.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2024, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <lib/smccc.h>
+#include <plat/common/plat_trng.h>
+
+#include <mtk_sip_svc.h>
+
+DEFINE_SVC_UUID2(_plat_trng_uuid,
+	0xf6b2c8d9, 0x1abb, 0x4d83, 0xb2, 0x3f,
+	0x5c, 0x51, 0xb6, 0xef, 0xfc, 0xaf
+);
+uuid_t plat_trng_uuid;
+
+void plat_entropy_setup(void)
+{
+	uint64_t placeholder;
+
+	plat_trng_uuid = _plat_trng_uuid;
+
+	/* Initialise the entropy source and trigger RNG generation */
+	plat_get_entropy(&placeholder);
+}
diff --git a/plat/mediatek/drivers/rng/rules.mk b/plat/mediatek/drivers/rng/rules.mk
new file mode 100644
index 00000000..5bcd2cd7
--- /dev/null
+++ b/plat/mediatek/drivers/rng/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2024, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := rng
+
+PLAT_INCLUDES += -I${LOCAL_DIR}/${MTK_SOC}
+PLAT_INCLUDES += -I${LOCAL_DIR}
+
+LOCAL_SRCS-y := ${LOCAL_DIR}/rng.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/rng_plat.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/mt8188/include/plat_helpers.h b/plat/mediatek/include/plat_helpers.h
similarity index 71%
rename from plat/mediatek/mt8188/include/plat_helpers.h
rename to plat/mediatek/include/plat_helpers.h
index eb78623c..b86ed239 100644
--- a/plat/mediatek/mt8188/include/plat_helpers.h
+++ b/plat/mediatek/include/plat_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mediatek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/mediatek/mt8186/include/plat_helpers.h b/plat/mediatek/mt8186/include/plat_helpers.h
deleted file mode 100644
index ebc9fa01..00000000
--- a/plat/mediatek/mt8186/include/plat_helpers.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __PLAT_HELPERS_H__
-#define __PLAT_HELPERS_H__
-
-unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
-
-#endif /* __PLAT_HELPERS_H__ */
diff --git a/plat/mediatek/mt8186/include/platform_def.h b/plat/mediatek/mt8186/include/platform_def.h
index 850ce2fc..707f4a5b 100644
--- a/plat/mediatek/mt8186/include/platform_def.h
+++ b/plat/mediatek/mt8186/include/platform_def.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2021-2022, MediaTek Inc. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, MediaTek Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -76,6 +76,11 @@
  ******************************************************************************/
 #define MSDC0_BASE		(IO_PHYS + 0x01230000)
 
+/*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE		(IO_PHYS + 0x0020F000)
+
 /*******************************************************************************
  * GIC-600 & interrupt handling related constants
  ******************************************************************************/
@@ -83,6 +88,8 @@
 #define BASE_GICD_BASE		MT_GIC_BASE
 #define MT_GIC_RDIST_BASE	(MT_GIC_BASE + 0x40000)
 
+#define PLAT_MTK_G1S_IRQ_PROPS(grp)
+
 #define SYS_CIRQ_BASE		(IO_PHYS + 0x204000)
 #define CIRQ_REG_NUM		(11)
 #define CIRQ_IRQ_NUM		(326)
diff --git a/plat/mediatek/mt8186/platform.mk b/plat/mediatek/mt8186/platform.mk
index 2bd2fb4d..9c03340c 100644
--- a/plat/mediatek/mt8186/platform.mk
+++ b/plat/mediatek/mt8186/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2021-2024, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,6 +7,9 @@
 MTK_PLAT     := plat/mediatek
 MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT}
 
+# True Random Number Generator firmware Interface
+TRNG_SUPPORT := 1
+
 PLAT_INCLUDES := -I${MTK_PLAT}/common/                            \
                  -I${MTK_PLAT}/drivers/cirq/                      \
                  -I${MTK_PLAT}/drivers/gic600/                    \
@@ -79,6 +82,11 @@ BL31_SOURCES += common/desc_image_load.c                              \
                 ${MTK_PLAT_SOC}/plat_sip_calls.c                      \
                 ${MTK_PLAT_SOC}/plat_topology.c
 
+ifeq (${TRNG_SUPPORT},1)
+BL31_SOURCES += ${MTK_PLAT}/drivers/rng/rng.c                         \
+                ${MTK_PLAT}/drivers/rng/${PLAT}/rng_plat.c
+endif
+
 # Build SPM drivers
 include ${MTK_PLAT_SOC}/drivers/spm/build.mk
 
diff --git a/plat/mediatek/mt8188/include/platform_def.h b/plat/mediatek/mt8188/include/platform_def.h
index 0a7ae6d4..dccb052f 100644
--- a/plat/mediatek/mt8188/include/platform_def.h
+++ b/plat/mediatek/mt8188/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -96,6 +96,11 @@
 /* Base MTK_platform compatible GIC memory map */
 #define BASE_GICD_BASE		(MT_GIC_BASE)
 #define MT_GIC_RDIST_BASE	(MT_GIC_BASE + 0x40000)
+#define DEV_IRQ_ID		580
+
+#define PLAT_MTK_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(DEV_IRQ_ID, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
 
 /*******************************************************************************
  * CIRQ related constants
@@ -107,7 +112,13 @@
 #define CIRQ_SPI_START		(96)
 
 /*******************************************************************************
- * MM IOMMU & SMI related constants
+ * MM IOMMU related constants
+ ******************************************************************************/
+#define VDO_SECURE_IOMMU_BASE	(IO_PHYS + 0x0c028000 + 0x4000)
+#define VPP_SECURE_IOMMU_BASE	(IO_PHYS + 0x04018000 + 0x4000)
+
+/*******************************************************************************
+ * SMI larb constants
  ******************************************************************************/
 #define SMI_LARB_0_BASE		(IO_PHYS + 0x0c022000)
 #define SMI_LARB_1_BASE		(IO_PHYS + 0x0c023000)
@@ -178,6 +189,11 @@
 #define EMI_MPU_BASE		(IO_PHYS + 0x00226000)
 #define SUB_EMI_MPU_BASE	(IO_PHYS + 0x00225000)
 
+/*******************************************************************************
+ * TRNG related constants
+ ******************************************************************************/
+#define TRNG_BASE		(IO_PHYS + 0x0020F000)
+
 /*******************************************************************************
  * System counter frequency related constants
  ******************************************************************************/
diff --git a/plat/mediatek/mt8188/plat_config.mk b/plat/mediatek/mt8188/plat_config.mk
index 2e3392f1..82ef7e8f 100644
--- a/plat/mediatek/mt8188/plat_config.mk
+++ b/plat/mediatek/mt8188/plat_config.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2022-2024, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -46,5 +46,8 @@ CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND := y
 CPU_PM_TINYSYS_SUPPORT := y
 MTK_PUBEVENT_ENABLE := y
 
+# True Random Number Generator firmware Interface
+TRNG_SUPPORT := 1
+
 MACH_MT8188 := 1
 $(eval $(call add_define,MACH_MT8188))
diff --git a/plat/mediatek/mt8188/platform.mk b/plat/mediatek/mt8188/platform.mk
index 5096e15a..b7764476 100644
--- a/plat/mediatek/mt8188/platform.mk
+++ b/plat/mediatek/mt8188/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2022-2023, MediaTek Inc. All rights reserved.
+# Copyright (c) 2022-2024, MediaTek Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -39,6 +39,9 @@ MODULES-y += $(MTK_PLAT)/drivers/mcusys
 MODULES-y += $(MTK_PLAT)/drivers/pmic
 MODULES-y += $(MTK_PLAT)/drivers/pmic_wrap
 MODULES-y += $(MTK_PLAT)/drivers/ptp3
+ifeq (${TRNG_SUPPORT},1)
+MODULES-y += $(MTK_PLAT)/drivers/rng
+endif
 MODULES-y += $(MTK_PLAT)/drivers/rtc
 MODULES-y += $(MTK_PLAT)/drivers/spm
 MODULES-y += $(MTK_PLAT)/drivers/timer
diff --git a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
index 26bed29e..7b867d86 100644
--- a/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8192/drivers/emi_mpu/emi_mpu.c
@@ -97,7 +97,7 @@ void emi_mpu_init(void)
 
 	/* PCI-e protect address(64MB) */
 	region_info.start = 0xC0000000ULL;
-	region_info.end = 0xC3FF0000ULL;
+	region_info.end = 0xC3FFFFFFULL;
 	region_info.region = 1;
 	SET_ACCESS_PERMISSION(region_info.apc, 1,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -108,7 +108,7 @@ void emi_mpu_init(void)
 
 	/* SCP protect address */
 	region_info.start = 0x50000000ULL;
-	region_info.end = 0x513F0000ULL;
+	region_info.end = 0x513FFFFFULL;
 	region_info.region = 2;
 	SET_ACCESS_PERMISSION(region_info.apc, 1,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
@@ -117,21 +117,10 @@ void emi_mpu_init(void)
 			      NO_PROT, FORBIDDEN, FORBIDDEN, NO_PROT);
 	emi_mpu_set_protection(&region_info);
 
-	/* DSP protect address */
-	region_info.start = 0x40000000ULL;	/* dram base addr */
-	region_info.end = 0x1FFFF0000ULL;
-	region_info.region = 3;
-	SET_ACCESS_PERMISSION(region_info.apc, 1,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
-			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROT);
-	emi_mpu_set_protection(&region_info);
-
 	/* Forbidden All */
 	region_info.start = 0x40000000ULL;	/* dram base addr */
-	region_info.end = 0x1FFFF0000ULL;
-	region_info.region = 4;
+	region_info.end = 0x1FFFFFFFFULL;
+	region_info.region = 3;
 	SET_ACCESS_PERMISSION(region_info.apc, 1,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
diff --git a/plat/mediatek/mt8192/include/plat_helpers.h b/plat/mediatek/mt8192/include/plat_helpers.h
deleted file mode 100644
index 9b550ee2..00000000
--- a/plat/mediatek/mt8192/include/plat_helpers.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __PLAT_HELPERS_H__
-#define __PLAT_HELPERS_H__
-
-unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
-
-#endif /* __PLAT_HELPERS_H__ */
diff --git a/plat/mediatek/mt8192/include/platform_def.h b/plat/mediatek/mt8192/include/platform_def.h
index ec377b5a..1b25e00c 100644
--- a/plat/mediatek/mt8192/include/platform_def.h
+++ b/plat/mediatek/mt8192/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -82,6 +82,8 @@
 #define BASE_GICD_BASE        MT_GIC_BASE
 #define MT_GIC_RDIST_BASE     (MT_GIC_BASE + 0x40000)
 
+#define PLAT_MTK_G1S_IRQ_PROPS(grp)
+
 #define SYS_CIRQ_BASE         (IO_PHYS + 0x204000)
 #define CIRQ_REG_NUM          14
 #define CIRQ_IRQ_NUM          439
diff --git a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
index b6e5a2d9..8e4a6754 100644
--- a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
+++ b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c
@@ -118,7 +118,7 @@ void emi_mpu_init(void)
 
 	/* SCP DRAM */
 	region_info.start = 0x50000000ULL;
-	region_info.end = 0x51400000ULL;
+	region_info.end = 0x513FFFFFULL;
 	region_info.region = 2;
 	SET_ACCESS_PERMISSION(region_info.apc, 1,
 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
diff --git a/plat/mediatek/mt8195/include/plat_helpers.h b/plat/mediatek/mt8195/include/plat_helpers.h
deleted file mode 100644
index ebc9fa01..00000000
--- a/plat/mediatek/mt8195/include/plat_helpers.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __PLAT_HELPERS_H__
-#define __PLAT_HELPERS_H__
-
-unsigned int plat_mediatek_calc_core_pos(u_register_t mpidr);
-
-#endif /* __PLAT_HELPERS_H__ */
diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h
index 8696f2a1..a70abecd 100644
--- a/plat/mediatek/mt8195/include/platform_def.h
+++ b/plat/mediatek/mt8195/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -95,6 +95,11 @@
 /* Base MTK_platform compatible GIC memory map */
 #define BASE_GICD_BASE			MT_GIC_BASE
 #define MT_GIC_RDIST_BASE		(MT_GIC_BASE + 0x40000)
+#define DEV_IRQ_ID			580
+
+#define PLAT_MTK_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(DEV_IRQ_ID, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
 
 #define SYS_CIRQ_BASE			(IO_PHYS + 0x204000)
 #define CIRQ_REG_NUM			23
diff --git a/plat/nuvoton/common/nuvoton_helpers.S b/plat/nuvoton/common/nuvoton_helpers.S
index 09035a19..9c788158 100644
--- a/plat/nuvoton/common/nuvoton_helpers.S
+++ b/plat/nuvoton/common/nuvoton_helpers.S
@@ -151,9 +151,9 @@ func plat_wait_for_warm_boot
 	 */
 	bl	plat_my_core_pos
 	lsl	x0, x0, #3
-	mov x8, x0
 	mov_imm	x2, PLAT_NPCM_TM_HOLD_BASE
 	add	x0, x0, x2
+	mov x8, x0
 	mov_imm	x2, PLAT_NPCM_TRUSTED_NOTIFICATION_BASE
 	add	x8, x8, x2
 	/*
diff --git a/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c b/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c
index 08448db6..4b29bbca 100644
--- a/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c
+++ b/plat/nuvoton/npcm845x/npcm845x_bl31_setup.c
@@ -47,6 +47,20 @@ static entry_point_info_t bl33_image_ep_info;
 					BL31_END - BL31_START, \
 					MT_MEMORY | MT_RW | EL3_PAS)
 
+#if RECLAIM_INIT_CODE
+IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
+IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED);
+
+#define	BL_INIT_CODE_END	((BL_CODE_END_UNALIGNED + PAGE_SIZE - 1) & \
+					~(PAGE_SIZE - 1))
+
+#define MAP_BL_INIT_CODE	MAP_REGION_FLAT( \
+					BL_INIT_CODE_BASE, \
+					BL_INIT_CODE_END - \
+					BL_INIT_CODE_BASE, \
+					MT_CODE | MT_SECURE)
+#endif /* RECLAIM_INIT_CODE */
+
 #if SEPARATE_NOBITS_REGION
 #define MAP_BL31_NOBITS		MAP_REGION_FLAT( \
 					BL31_NOBITS_BASE, \
@@ -103,7 +117,10 @@ int board_uart_init(void)
 
 unsigned int plat_get_syscnt_freq2(void)
 {
-	return (unsigned int)COUNTER_FREQUENCY;
+	/*
+	 * Do not overwrite the value set by BootBlock
+	 */
+	return (unsigned int)read_cntfrq_el0();
 }
 
 /******************************************************************************
@@ -117,6 +134,7 @@ unsigned int plat_get_syscnt_freq2(void)
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		u_register_t arg2, u_register_t arg3)
 {
+	arg0 = arg1 = arg2 = arg3 = 0;
 #if RESET_TO_BL31
 	void *from_bl2 = (void *)arg0;
 	void *plat_params_from_bl2 = (void *)arg3;
@@ -309,24 +327,11 @@ void __init npcm845x_bl31_plat_arch_setup(void)
 {
 	const mmap_region_t bl_regions[] = {
 		MAP_BL31_TOTAL,
-#if SEPARATE_NOBITS_REGION
-		MAP_BL31_NOBITS,
-#endif /* SEPARATE_NOBITS_REGION */
 		ARM_MAP_BL_RO,
-#if USE_ROMLIB
-		ARM_MAP_ROMLIB_CODE,
-		ARM_MAP_ROMLIB_DATA,
-#endif /* USE_ROMLIB */
 #if USE_COHERENT_MEM
 		ARM_MAP_BL_COHERENT_RAM,
 #endif /* USE_COHERENT_MEM */
 		ARM_MAP_SHARED_RAM,
-#ifdef SECONDARY_BRINGUP
-		ARM_MAP_NS_DRAM1,
-	#ifdef BL32_BASE
-		ARM_MAP_BL32_CORE_MEM
-	#endif /* BL32_BASE */
-#endif /* SECONDARY_BRINGUP */
 		{0}
 	};
 	setup_page_tables(bl_regions, plat_arm_get_mmap());
diff --git a/plat/nuvoton/npcm845x/platform.mk b/plat/nuvoton/npcm845x/platform.mk
index 92c7e2fe..1959aacf 100644
--- a/plat/nuvoton/npcm845x/platform.mk
+++ b/plat/nuvoton/npcm845x/platform.mk
@@ -12,6 +12,7 @@ RESET_TO_BL31	:=	1
 SPMD_SPM_AT_SEL2	:= 0
 #temporary until the RAM size is reduced
 USE_COHERENT_MEM	:=	1
+INIT_UNUSED_NS_EL2  := 1
 
 
 $(eval $(call add_define,RESET_TO_BL31))
@@ -21,12 +22,29 @@ ifeq (${ARCH}, aarch64)
 # Trusted DRAM (if available) or the TZC secured area of DRAM.
 # TZC secured DRAM is the default.
 
+ARM_TSP_RAM_LOCATION	?=	dram
+
+ifeq (${ARM_TSP_RAM_LOCATION}, tsram)
+ARM_TSP_RAM_LOCATION_ID	=	ARM_TRUSTED_SRAM_ID
+else ifeq (${ARM_TSP_RAM_LOCATION}, tdram)
+ARM_TSP_RAM_LOCATION_ID	=	ARM_TRUSTED_DRAM_ID
+else ifeq (${ARM_TSP_RAM_LOCATION}, dram)
+ARM_TSP_RAM_LOCATION_ID	=	ARM_DRAM_ID
+else
+$(error "Unsupported ARM_TSP_RAM_LOCATION value")
+endif
+
+# Process flags
 # Process ARM_BL31_IN_DRAM flag
 ARM_BL31_IN_DRAM	:=	0
 $(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
 $(eval $(call add_define,ARM_BL31_IN_DRAM))
+else
+ARM_TSP_RAM_LOCATION_ID	=	ARM_TRUSTED_SRAM_ID
 endif
 
+$(eval $(call add_define,ARM_TSP_RAM_LOCATION_ID))
+
 # For the original power-state parameter format, the State-ID can be encoded
 # according to the recommended encoding or zero. This flag determines which
 # State-ID encoding to be parsed.
@@ -140,11 +158,25 @@ $(error For SEPARATE_NOBITS_REGION, RECLAIM_INIT_CODE cannot be supported)
 endif
 endif
 
+# Disable ARM Cryptocell by default
+ARM_CRYPTOCELL_INTEG	:=	0
+$(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG))
+$(eval $(call add_define,ARM_CRYPTOCELL_INTEG))
+
 # Enable PIE support for RESET_TO_BL31 case
 ifeq (${RESET_TO_BL31},1)
 ENABLE_PIE	:=	1
 endif
 
+# CryptoCell integration relies on coherent buffers for passing data from
+# the AP CPU to the CryptoCell
+
+ifeq (${ARM_CRYPTOCELL_INTEG},1)
+ifeq (${USE_COHERENT_MEM},0)
+$(error "ARM_CRYPTOCELL_INTEG needs USE_COHERENT_MEM to be set.")
+endif
+endif
+
 PLAT_INCLUDES	:=	-Iinclude/plat/nuvoton/npcm845x \
 		-Iinclude/plat/nuvoton/common \
 		-Iinclude/drivers/nuvoton/npcm845x \
@@ -287,7 +319,8 @@ endif
 
 # Pointer Authentication sources
 ifeq (${ENABLE_PAUTH}, 1)
-PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c
+PLAT_BL_COMMON_SOURCES	+=	plat/arm/common/aarch64/arm_pauth.c \
+		lib/extensions/pauth/pauth_helpers.S
 endif
 
 ifeq (${SPD},spmd)
@@ -325,7 +358,11 @@ BL2_SOURCES	+=	${AUTH_SOURCES} \
 $(eval $(call TOOL_ADD_IMG,ns_bl2u,--fwu,FWU_))
 
 # We expect to locate the *.mk files under the directories specified below
+ifeq (${ARM_CRYPTOCELL_INTEG},0)
 CRYPTO_LIB_MK	:=	drivers/auth/mbedtls/mbedtls_crypto.mk
+else
+CRYPTO_LIB_MK	:=	drivers/auth/cryptocell/cryptocell_crypto.mk
+endif
 
 IMG_PARSER_LIB_MK := drivers/auth/mbedtls/mbedtls_x509.mk
 
@@ -336,6 +373,12 @@ $(info Including ${IMG_PARSER_LIB_MK})
 include ${IMG_PARSER_LIB_MK}
 endif
 
+ifeq (${RECLAIM_INIT_CODE}, 1)
+ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
+$(error "To reclaim init code xlat tables v2 must be used")
+endif
+endif
+
 ifeq (${MEASURED_BOOT},1)
 MEASURED_BOOT_MK := drivers/measured_boot/measured_boot.mk
 $(info Including ${MEASURED_BOOT_MK})
@@ -352,3 +395,6 @@ BL2U_SOURCES	:=
 
 DEBUG_CONSOLE	?=	0
 $(eval $(call add_define,DEBUG_CONSOLE))
+
+$(eval $(call add_define,ARM_TSP_RAM_LOCATION_ID))
+
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index e3068b69..09eda84b 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index 5309d98c..4ff98883 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -142,7 +142,7 @@ int32_t tegra_fiq_get_intr_context(void)
 	val = read_ctx_reg((gpregs_ctx), (uint32_t)(CTX_GPREG_SP_EL0));
 	write_ctx_reg((gpregs_ctx), (uint32_t)(CTX_GPREG_X2), (val));
 
-	val = read_ctx_reg((el1state_ctx), (uint32_t)(CTX_SP_EL1));
+	val = read_el1_ctx_common(el1state_ctx, sp_el1);
 	write_ctx_reg((gpregs_ctx), (uint32_t)(CTX_GPREG_X3), (val));
 
 	return 0;
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index 23655649..6ca90a0a 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
@@ -82,7 +82,7 @@ override LIBC_SRCS :=	$(addprefix lib/libc/,		\
 INCLUDES	+=	-Iinclude/lib/libc		\
 			-Iinclude/lib/libc/$(ARCH)	\
 
-ifneq ($(findstring armlink,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),arm-link)
 # o suppress warnings for section mismatches, undefined symbols
 # o use only those libraries that are specified in the input file
 #   list to resolve references
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index 83d815af..82328831 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -356,10 +356,10 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
 	 * will re-init this info from non-secure software when the
 	 * core come online.
 	 */
-	actlr_elx = read_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1));
+	actlr_elx = read_el1_ctx_common((get_el1_sysregs_ctx(ctx)), actlr_el1);
 	actlr_elx &= ~DENVER_CPU_PMSTATE_MASK;
 	actlr_elx |= DENVER_CPU_PMSTATE_C1;
-	write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx));
+	write_el1_ctx_common((get_el1_sysregs_ctx(ctx)), actlr_el1, actlr_elx);
 
 	/*
 	 * Check if we are exiting from deep sleep and restore SE
diff --git a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
index 4e84d020..14ddefd2 100644
--- a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
+++ b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
@@ -1,6 +1,6 @@
 #
 # Copyright 2018-2020 NXP
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -73,7 +73,7 @@ endif
 ifeq (${FUSE_PROV_FILE},)
 else
 ${BUILD_PLAT}/${FUSE_PROV_FILE_SB}: ${FUSE_PROV_FILE}
-	@echo " Generating CSF Header for $@ $<"
+	$(s)echo " Generating CSF Header for $@ $<"
 	$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
 					--app $< ${FUSE_INPUT_FILE}
 endif
@@ -81,7 +81,7 @@ endif
 ifeq (${FUSE_UP_FILE},)
 else
 ${BUILD_PLAT}/${FUSE_UP_FILE_SB}: ${FUSE_UP_FILE}
-	@echo " Generating CSF Header for $@ $<"
+	$(s)echo " Generating CSF Header for $@ $<"
 	$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
 					--app $< ${FUSE_INPUT_FILE}
 endif
@@ -94,6 +94,6 @@ ifeq (${FUSE_FIP_DEPS},)
 endif
 	${FIPTOOL} create ${FUSE_FIP_ARGS} $@
 	${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
diff --git a/plat/nxp/common/tbbr/tbbr.mk b/plat/nxp/common/tbbr/tbbr.mk
index 4aac9d63..02333986 100644
--- a/plat/nxp/common/tbbr/tbbr.mk
+++ b/plat/nxp/common/tbbr/tbbr.mk
@@ -130,15 +130,15 @@ else
     $(BUILD_PLAT)/bl2/nxp_rotpk.o: $(ROTPK_HASH)
 
     certificates: $(ROT_KEY)
-    $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	@if [ ! -f $(ROT_KEY) ]; then \
+    $(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)if [ ! -f $(ROT_KEY) ]; then \
 		${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null; \
 	fi
 
-    $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+    $(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 
 endif #MBEDTLS_DIR
diff --git a/plat/nxp/s32/s32g274ardb2/include/plat_console.h b/plat/nxp/s32/s32g274ardb2/include/plat_console.h
new file mode 100644
index 00000000..43c2bfd8
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/plat_console.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_CONSOLE_H
+#define PLAT_CONSOLE_H
+
+void console_s32g2_register(void);
+
+#endif
diff --git a/plat/nxp/s32/s32g274ardb2/include/plat_helpers.h b/plat/nxp/s32/s32g274ardb2/include/plat_helpers.h
new file mode 100644
index 00000000..18582ec4
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/plat_helpers.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_HELPERS_H
+#define PLAT_HELPERS_H
+
+unsigned int s32g2_core_pos_by_mpidr(u_register_t mpidr);
+
+#endif /* PLAT_HELPERS_H */
diff --git a/plat/nxp/s32/s32g274ardb2/include/plat_io_storage.h b/plat/nxp/s32/s32g274ardb2/include/plat_io_storage.h
new file mode 100644
index 00000000..ea013009
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/plat_io_storage.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_IO_STORAGE_H
+#define PLAT_IO_STORAGE_H
+
+void plat_s32g2_io_setup(void);
+
+#endif
diff --git a/plat/nxp/s32/s32g274ardb2/include/plat_macros.S b/plat/nxp/s32/s32g274ardb2/include/plat_macros.S
new file mode 100644
index 00000000..8f0c4726
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/plat_macros.S
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant GIC and CCI registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ * Clobbers: x0 - x10, x16, x17, sp
+ * ---------------------------------------------
+ */
+.macro plat_crash_print_regs
+.endm
+
+#endif /* PLAT_MACROS_S */
+
diff --git a/plat/nxp/s32/s32g274ardb2/include/platform_def.h b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
new file mode 100644
index 00000000..1a4c495a
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/platform_def.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat/common/common_def.h>
+
+#define PLATFORM_STACK_SIZE		U(0x1000)
+
+/* Caches */
+#define CACHE_WRITEBACK_SHIFT		U(6)
+#define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
+
+/* CPU Topology */
+#define PLATFORM_CORE_COUNT		U(4)
+#define PLATFORM_SYSTEM_COUNT		U(1)
+#define PLATFORM_CLUSTER_COUNT		U(2)
+#define PLATFORM_PRIMARY_CPU		U(0)
+#define PLATFORM_MPIDR_CPU_MASK_BITS	U(1)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(2)
+
+/* Power Domains */
+#define PLAT_NUM_PWR_DOMAINS		(PLATFORM_SYSTEM_COUNT + \
+					 PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+#define PLAT_MAX_OFF_STATE		U(2)
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_PWR_LVL_STATES		U(2)
+
+/* BL2 stage */
+#define BL2_BASE			UL(0x34078000)
+#define BL2_LIMIT			UL(0x34100000)
+
+/* BL31 stage */
+#define BL31_BASE			UL(0x34200000)
+#define BL31_LIMIT			UL(0x34300000)
+
+/* It is a dummy value for now, given the missing DDR */
+#define BL33_BASE			UL(0x34500000)
+#define BL33_LIMIT			UL(0x345FF000)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 36)
+/* We'll be doing a 1:1 mapping anyway */
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 36)
+
+#define MAX_MMAP_REGIONS		U(8)
+#define MAX_XLAT_TABLES			U(32)
+
+/* Console settings */
+#define UART_BASE			UL(0x401C8000)
+#define UART_BAUDRATE			U(115200)
+#define UART_CLOCK_HZ			U(125000000)
+
+#define S32G_FIP_BASE			UL(0x34100000)
+#define S32G_FIP_SIZE			UL(0x100000)
+
+#define MAX_IO_HANDLES			U(2)
+#define MAX_IO_DEVICES			U(2)
+
+/* GIC settings */
+#define S32G_GIC_BASE			UL(0x50800000)
+#define PLAT_GICD_BASE			S32G_GIC_BASE
+#define PLAT_GICR_BASE			(S32G_GIC_BASE + UL(0x80000))
+
+/* Generic timer frequency; this goes directly into CNTFRQ_EL0.
+ * Its end-value is 5MHz; this is based on the assumption that
+ * GPR00[CA53_COUNTER_CLK_DIV_VAL] contains the reset value of 0x7, hence
+ * producing a divider value of 8, applied to the FXOSC frequency of 40MHz.
+ */
+#define COUNTER_FREQUENCY		U(5000000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h b/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
new file mode 100644
index 00000000..0c0870f7
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019-2021, 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef S32G2_NCORE_H
+#define S32G2_NCORE_H
+
+#include <stdbool.h>
+
+#define NCORE_BASE_ADDR			UL(0x50400000)
+
+#define A53_CLUSTER0_CAIU		U(0)
+#define A53_CLUSTER1_CAIU		U(1)
+
+/**
+ * Directory Unit Registers
+ *
+ * The directory provides a point of serialization for establishing transaction
+ * ordering and sequences coherence operations and memory accesses.
+ */
+#define NCORE_DIRU(N)			(NCORE_BASE_ADDR + UL(0x80000) + ((N) * UL(0x1000)))
+
+/* DIRU Snoop Filtering Enable */
+#define NCORE_DIRUSFE(N)		(NCORE_DIRU(N) + UL(0x10))
+#define NCORE_DIRUSFE_SFEN(SF)		BIT_32(SF)
+
+/* DIRU Caching Agent Snoop Enable */
+#define NCORE_DIRUCASE(N)		(NCORE_DIRU(N) + UL(0x40))
+#define NCORE_DIRUCASE_CASNPEN(CAIU)	BIT_32(CAIU)
+
+/* DIRU Snoop Filter Maintenance Control */
+#define NCORE_DIRUSFMC(N)		(NCORE_DIRU(N) + UL(0x80))
+#define NCORE_DIRUSFMC_SFID(SF)		((SF) << 16U)
+#define NCORE_DIRUSFMC_SFMNTOP_ALL	U(0x0)
+
+/* DIRU Snoop Filter Maintenance Activity */
+#define NCORE_DIRUSFMA(N)		(NCORE_DIRU(N) + UL(0x84))
+#define NCORE_DIRUSFMA_MNTOPACTV	BIT_32(0)
+
+/**
+ * Coherent Agent Interface Unit Registers
+ *
+ * CAI provides a means for a fully-coherent agent to be connected to the Ncore.
+ * The CAI behaves as a fully-coherent slave.
+ */
+#define NCORE_CAIU(N)			(NCORE_BASE_ADDR + ((N) * UL(0x1000)))
+#define NCORE_CAIU0_BASE_ADDR		NCORE_BASE_ADDR
+
+/* CAIU Transaction Control */
+#define NCORE_CAIUTC_OFF		UL(0x0)
+#define NCORE_CAIUTC_ISOLEN_SHIFT	U(1)
+#define NCORE_CAIUTC_ISOLEN_MASK	BIT_32(NCORE_CAIUTC_ISOLEN_SHIFT)
+
+#define NCORE_CAIUTC(N)			(NCORE_CAIU(N) + NCORE_CAIUTC_OFF)
+
+/* CAIU Identification */
+#define NCORE_CAIUID(n)			(NCORE_CAIU(n) + UL(0xFFC))
+#define NCORE_CAIUID_TYPE		GENMASK_32(U(19), U(16))
+#define NCORE_CAIUID_TYPE_ACE_DVM	U(0x0)
+
+/**
+ * Coherent Subsystem Registers
+ */
+#define NCORE_CSR			(NCORE_BASE_ADDR + UL(0xFF000))
+
+/* Coherent Subsystem ACE DVM Snoop Enable */
+#define NCORE_CSADSE			(NCORE_CSR + UL(0x40))
+#define NCORE_CSADSE_DVMSNPEN(CAIU)	BIT_32(CAIU)
+
+/* Coherent Subsystem Identification */
+#define NCORE_CSID			(NCORE_CSR + UL(0xFFC))
+#define NCORE_CSID_NUMSFS_SHIFT		U(18)
+#define NCORE_CSID_NUMSFS_MASK		GENMASK_32(U(22), NCORE_CSID_NUMSFS_SHIFT)
+#define NCORE_CSID_NUMSFS(CSIDR)	(((CSIDR) & NCORE_CSID_NUMSFS_MASK) \
+					  >> NCORE_CSID_NUMSFS_SHIFT)
+
+/* Coherent Subsystem Unit Identification */
+#define NCORE_CSUID			(NCORE_CSR + UL(0xFF8))
+#define NCORE_CSUID_NUMCMIUS_SHIFT	U(24)
+#define NCORE_CSUID_NUMCMIUS_MASK	GENMASK_32(U(29), NCORE_CSUID_NUMCMIUS_SHIFT)
+#define NCORE_CSUID_NUMCMIUS(CSUIDR)	(((CSUIDR) & NCORE_CSUID_NUMCMIUS_MASK) \
+					 >> NCORE_CSUID_NUMCMIUS_SHIFT)
+#define NCORE_CSUID_NUMDIRUS_SHIFT	U(16)
+#define NCORE_CSUID_NUMDIRUS_MASK	GENMASK_32(U(21), NCORE_CSUID_NUMDIRUS_SHIFT)
+#define NCORE_CSUID_NUMDIRUS(CSUIDR)	(((CSUIDR) & NCORE_CSUID_NUMDIRUS_MASK) \
+					 >> NCORE_CSUID_NUMDIRUS_SHIFT)
+#define NCORE_CSUID_NUMNCBUS_SHIFT	U(8)
+#define NCORE_CSUID_NUMNCBUS_MASK	GENMASK_32(U(13), NCORE_CSUID_NUMNCBUS_SHIFT)
+#define NCORE_CSUID_NUMNCBUS(CSUIDR)	(((CSUIDR) & NCORE_CSUID_NUMNCBUS_MASK) \
+					 >> NCORE_CSUID_NUMNCBUS_SHIFT)
+
+#ifndef __ASSEMBLER__
+void ncore_caiu_online(uint32_t caiu);
+void ncore_caiu_offline(uint32_t caiu);
+void ncore_init(void);
+bool ncore_is_caiu_online(uint32_t caiu);
+void ncore_disable_caiu_isolation(uint32_t caiu);
+#endif /* __ASSEMBLER__ */
+
+#endif /* S32G2_NCORE_H */
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
new file mode 100644
index 00000000..4645f01e
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <plat_console.h>
+#include <s32cc-clk-drv.h>
+#include <plat_io_storage.h>
+#include <s32cc-ncore.h>
+
+#define SIUL2_PC09_MSCR		UL(0x4009C2E4)
+#define SIUL2_PC10_MSCR		UL(0x4009C2E8)
+#define SIUL2_PC10_LIN0_IMCR	UL(0x4009CA40)
+
+#define LIN0_TX_MSCR_CFG	U(0x00214001)
+#define LIN0_RX_MSCR_CFG	U(0x00094000)
+#define LIN0_RX_IMCR_CFG	U(0x00000002)
+
+struct bl_load_info *plat_get_bl_image_load_info(void)
+{
+	return get_bl_load_info_from_mem_params_desc();
+}
+
+struct bl_params *plat_get_next_bl_params(void)
+{
+	return get_next_bl_params_from_mem_params_desc();
+}
+
+void plat_flush_next_bl_params(void)
+{
+	flush_bl_params_desc();
+}
+
+void bl2_platform_setup(void)
+{
+}
+
+static void linflex_config_pinctrl(void)
+{
+	/* set PC09 - MSCR[41] - for UART0 TXD */
+	mmio_write_32(SIUL2_PC09_MSCR, LIN0_TX_MSCR_CFG);
+	/* set PC10 - MSCR[42] - for UART0 RXD */
+	mmio_write_32(SIUL2_PC10_MSCR, LIN0_RX_MSCR_CFG);
+	/* set PC10 - MSCR[512]/IMCR[0] - for UART0 RXD */
+	mmio_write_32(SIUL2_PC10_LIN0_IMCR, LIN0_RX_IMCR_CFG);
+}
+
+void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
+				  u_register_t arg2, u_register_t arg3)
+{
+	int ret;
+
+	ret = s32cc_init_early_clks();
+	if (ret != 0) {
+		panic();
+	}
+
+	linflex_config_pinctrl();
+	console_s32g2_register();
+
+	/* Restore (clear) the CAIUTC[IsolEn] bit for the primary cluster, which
+	 * we have manually set during early BL2 boot.
+	 */
+	ncore_disable_caiu_isolation(A53_CLUSTER0_CAIU);
+
+	ncore_init();
+	ncore_caiu_online(A53_CLUSTER0_CAIU);
+
+	plat_s32g2_io_setup();
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+}
+
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_image_desc.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_image_desc.c
new file mode 100644
index 00000000..1fc77941
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_image_desc.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+	{
+		.image_id = BL31_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+				      entry_point_info_t,
+				      SECURE | EXECUTABLE | EP_FIRST_EXE),
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS),
+		.ep_info.pc = BL31_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+				      image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+		.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+		.image_info.image_base = BL31_BASE,
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+	{
+		.image_id = BL33_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
+				      entry_point_info_t,
+				      NON_SECURE | EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
+				      image_info_t, 0),
+		.image_info.image_max_size = BL33_LIMIT - BL33_BASE,
+		.image_info.image_base = BL33_BASE,
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
new file mode 100644
index 00000000..03bf35cc
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/gicv3.h>
+#include <plat/common/platform.h>
+#include <plat_console.h>
+
+static entry_point_info_t bl33_image_ep_info;
+
+static unsigned int s32g2_mpidr_to_core_pos(unsigned long mpidr);
+
+static uint32_t get_spsr_for_bl33_entry(void)
+{
+	unsigned long mode = MODE_EL1;
+	uint32_t spsr;
+
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+
+	return spsr;
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	console_s32g2_register();
+
+	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
+	bl33_image_ep_info.pc = BL33_BASE;
+	bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+}
+
+void bl31_plat_arch_setup(void)
+{
+}
+
+struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	return &bl33_image_ep_info;
+}
+
+void bl31_platform_setup(void)
+{
+	static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+	static gicv3_driver_data_t plat_gic_data = {
+		.gicd_base = PLAT_GICD_BASE,
+		.gicr_base = PLAT_GICR_BASE,
+		.rdistif_num = PLATFORM_CORE_COUNT,
+		.rdistif_base_addrs = rdistif_base_addrs,
+		.mpidr_to_core_pos = s32g2_mpidr_to_core_pos,
+	};
+
+	unsigned int pos = plat_my_core_pos();
+
+	gicv3_driver_init(&plat_gic_data);
+	gicv3_distif_init();
+	gicv3_rdistif_init(pos);
+	gicv3_cpuif_enable(pos);
+}
+
+static unsigned int s32g2_mpidr_to_core_pos(unsigned long mpidr)
+{
+	int core;
+
+	core = plat_core_pos_by_mpidr(mpidr);
+	if (core < 0) {
+		return 0;
+	}
+
+	return (unsigned int)core;
+}
+
diff --git a/plat/nxp/s32/s32g274ardb2/plat_console.c b/plat/nxp/s32/s32g274ardb2/plat_console.c
new file mode 100644
index 00000000..542fa7be
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_console.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <linflex.h>
+#include <plat_console.h>
+#include <platform_def.h>
+
+void console_s32g2_register(void)
+{
+	static console_t s32g2_console = {
+		.next = NULL,
+		.flags = 0u,
+	};
+	int ret;
+
+	ret = console_linflex_register(UART_BASE, UART_CLOCK_HZ,
+				       UART_BAUDRATE, &s32g2_console);
+	if (ret == 0) {
+		panic();
+	}
+
+	console_set_scope(&s32g2_console,
+			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH |
+			  CONSOLE_FLAG_TRANSLATE_CRLF);
+}
diff --git a/plat/nxp/s32/s32g274ardb2/plat_helpers.S b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
new file mode 100644
index 00000000..71219004
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_helpers.S
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <platform_def.h>
+#include <s32cc-ncore.h>
+
+.globl	plat_crash_console_flush
+.globl	plat_crash_console_init
+.globl	plat_crash_console_putc
+.globl	plat_is_my_cpu_primary
+.globl	plat_my_core_pos
+.globl	plat_reset_handler
+.globl	plat_secondary_cold_boot_setup
+.globl	platform_mem_init
+.globl	s32g2_core_pos_by_mpidr
+
+/* int plat_crash_console_init(void); */
+func plat_crash_console_init
+	mov_imm	x0, UART_BASE
+	mov_imm	x1, UART_CLOCK_HZ
+	mov_imm	x2, UART_BAUDRATE
+	b	console_linflex_core_init
+endfunc plat_crash_console_init
+
+/* int plat_crash_console_putc(int); */
+func plat_crash_console_putc
+	mov_imm	x1, UART_BASE
+	b	console_linflex_core_putc
+	ret
+endfunc plat_crash_console_putc
+
+/* void plat_crash_console_flush(void); */
+func plat_crash_console_flush
+	mov_imm	x0, UART_BASE
+	b	console_linflex_core_flush
+	ret
+endfunc plat_crash_console_flush
+
+/**
+ * unsigned int s32g2_core_pos_by_mpidr(u_register_t mpidr);
+ *
+ * In: x0 -  MPIDR_EL1
+ * Out: x0
+ * Clobber list: x0, x1
+ */
+func s32g2_core_pos_by_mpidr
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	lsr	x0, x0, #MPIDR_AFF1_SHIFT
+	add	x0, x1, x0, lsl #PLATFORM_MPIDR_CPU_MASK_BITS
+	ret
+endfunc s32g2_core_pos_by_mpidr
+
+/**
+ * unsigned int plat_my_core_pos(void);
+ *
+ * Out: x0
+ * Clobber list: x0, x1, x8
+ */
+func plat_my_core_pos
+	mov	x8, x30
+	mrs x0, mpidr_el1
+	bl	s32g2_core_pos_by_mpidr
+	mov	x30, x8
+	ret
+endfunc plat_my_core_pos
+
+/**
+ * unsigned int plat_is_my_cpu_primary(void);
+ *
+ * Clobber list: x0, x1, x7, x8
+ */
+func plat_is_my_cpu_primary
+	mov	x7, x30
+	bl	plat_my_core_pos
+	cmp	x0, #PLATFORM_PRIMARY_CPU
+	cset	x0, eq
+	mov	x30, x7
+	ret
+endfunc plat_is_my_cpu_primary
+
+
+/**
+ * void plat_secondary_cold_boot_setup (void);
+ */
+func plat_secondary_cold_boot_setup
+	ret
+endfunc plat_secondary_cold_boot_setup
+
+/**
+ * void plat_reset_handler(void);
+ *
+ * Set the CAIUTC[IsolEn] bit for the primary A53 cluster.
+ * This is so cache invalidate operations from the early TF-A boot code
+ * won't cause Ncore to crash.
+ *
+ * Clobber list: x0, x1, x2
+ */
+func plat_reset_handler
+	mov	x0, #NCORE_CAIU0_BASE_ADDR
+	ldr	w1, [x0, #NCORE_CAIUTC_OFF]
+	movz	w2, #1
+	lsl	w2, w2, #NCORE_CAIUTC_ISOLEN_SHIFT
+	orr	w1, w1, w2
+	str	w1, [x0, #NCORE_CAIUTC_OFF]
+	ret
+endfunc plat_reset_handler
+
+/* void platform_mem_init(void); */
+func platform_mem_init
+	mov	x10, x30
+	mov	x0, #BL31_BASE
+	mov	x1, #(BL31_LIMIT & 0xFFFFU)
+	movk	x1, #(BL31_LIMIT >> 16), lsl #16
+	sub	x1, x1, x0
+	bl	zeromem
+	mov	x0, #BL33_BASE
+	mov	x1, #(BL33_LIMIT & 0xFFFFU)
+	movk	x1, #(BL33_LIMIT >> 16), lsl #16
+	sub	x1, x1, x0
+	bl	zeromem
+	mov	x30, x10
+	ret
+endfunc platform_mem_init
+
diff --git a/plat/nxp/s32/s32g274ardb2/plat_io_storage.c b/plat/nxp/s32/s32g274ardb2/plat_io_storage.c
new file mode 100644
index 00000000..db6bcc51
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/plat_io_storage.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_fip.h>
+#include <drivers/io/io_memmap.h>
+#include <plat/common/platform.h>
+#include <tools_share/firmware_image_package.h>
+
+#include <plat_io_storage.h>
+
+struct plat_io_policy {
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	int (*check)(const uintptr_t spec);
+};
+
+static int open_memmap(const uintptr_t spec);
+static int open_fip(const uintptr_t spec);
+
+static uintptr_t fip_dev_handle;
+
+static uintptr_t memmap_dev_handle;
+
+static int open_memmap(const uintptr_t spec)
+{
+	uintptr_t temp_handle = 0U;
+	int result;
+
+	result = io_dev_init(memmap_dev_handle, (uintptr_t)0);
+	if (result != 0) {
+		return result;
+	}
+
+	result = io_open(memmap_dev_handle, spec, &temp_handle);
+	if (result == 0) {
+		(void)io_close(temp_handle);
+	}
+
+	return result;
+}
+
+static int open_fip(const uintptr_t spec)
+{
+	uintptr_t temp_handle = 0U;
+	int result;
+
+	/* See if a Firmware Image Package is available */
+	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+	if (result != 0) {
+		return result;
+	}
+
+	result = io_open(fip_dev_handle, spec, &temp_handle);
+	if (result == 0) {
+		(void)io_close(temp_handle);
+	}
+
+	return result;
+}
+
+void plat_s32g2_io_setup(void)
+{
+	static const io_dev_connector_t *memmap_dev_con;
+	static const io_dev_connector_t *fip_dev_con;
+
+	int result __unused;
+
+	result = register_io_dev_memmap(&memmap_dev_con);
+	assert(result == 0);
+
+	result = io_dev_open(memmap_dev_con, (uintptr_t)0,
+			     &memmap_dev_handle);
+	assert(result == 0);
+
+	result = register_io_dev_fip(&fip_dev_con);
+	assert(result == 0);
+
+	result = io_dev_open(fip_dev_con, (uintptr_t)0,
+			     &fip_dev_handle);
+	assert(result == 0);
+}
+
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	static const io_block_spec_t fip_block_spec = {
+		.offset = S32G_FIP_BASE,
+		.length = S32G_FIP_SIZE,
+	};
+
+	static const io_uuid_spec_t bl31_uuid_spec = {
+		.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+	};
+
+	static const io_uuid_spec_t bl33_uuid_spec = {
+		.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+	};
+
+	static const struct plat_io_policy policies[BL33_IMAGE_ID + 1] = {
+		[FIP_IMAGE_ID] = {
+			.dev_handle = &memmap_dev_handle,
+			.image_spec = (uintptr_t)&fip_block_spec,
+			.check = open_memmap,
+		},
+		[BL31_IMAGE_ID] = {
+			.dev_handle = &fip_dev_handle,
+			.image_spec = (uintptr_t)&bl31_uuid_spec,
+			.check = open_fip,
+		},
+		[BL33_IMAGE_ID] = {
+			.dev_handle = &fip_dev_handle,
+			.image_spec = (uintptr_t)&bl33_uuid_spec,
+			.check = open_fip,
+		},
+	};
+	const struct plat_io_policy *policy;
+	int result;
+
+	assert(image_id < ARRAY_SIZE(policies));
+
+	policy = &policies[image_id];
+	result = policy->check(policy->image_spec);
+	assert(result == 0);
+
+	*image_spec = policy->image_spec;
+	*dev_handle = *policy->dev_handle;
+
+	return result;
+}
diff --git a/plat/nxp/s32/s32g274ardb2/platform.mk b/plat/nxp/s32/s32g274ardb2/platform.mk
new file mode 100644
index 00000000..7d6e960a
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/platform.mk
@@ -0,0 +1,76 @@
+#
+# Copyright 2024 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include drivers/arm/gic/v3/gicv3.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_DRIVERS_PATH := drivers/nxp
+PLAT_COMMON_PATH  := plat/nxp/common
+PLAT_S32G274ARDB2 := plat/nxp/s32/s32g274ardb2
+
+CONSOLE           := LINFLEX
+
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+# Flag to apply S32 erratum ERR051700. This erratum applies to all S32
+# revisions.
+S32_ERRATA_LIST += ERRATA_S32_051700
+
+PLAT_INCLUDES = \
+	-I${PLAT_S32G274ARDB2}/include
+
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+COLD_BOOT_SINGLE_CPU := 0
+
+ENABLE_SVE_FOR_NS := 0
+
+RESET_TO_BL2 := 1
+
+INIT_UNUSED_NS_EL2 := 1
+
+ERRATA_A53_855873 := 1
+ERRATA_A53_836870 := 1
+ERRATA_A53_1530924 := 1
+ERRATA_SPECULATIVE_AT := 1
+ERRATA_S32_051700 := 1
+
+# Selecting Drivers for SoC
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,CLK_NEEDED,BL_COMM))
+
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+BL_COMMON_SOURCES += \
+	${PLAT_S32G274ARDB2}/plat_console.c \
+	${PLAT_S32G274ARDB2}/plat_helpers.S \
+
+BL2_SOURCES += \
+	${BL_COMMON_SOURCES} \
+	${PLAT_S32G274ARDB2}/plat_bl2_el3_setup.c \
+	${PLAT_S32G274ARDB2}/plat_bl2_image_desc.c \
+	${PLAT_S32G274ARDB2}/plat_io_storage.c \
+	${PLAT_S32G274ARDB2}/s32cc_ncore.c \
+	common/desc_image_load.c \
+	drivers/io/io_fip.c \
+	drivers/io/io_memmap.c \
+	drivers/io/io_storage.c \
+	lib/cpus/aarch64/cortex_a53.S \
+
+BL31_SOURCES += \
+	${GICV3_SOURCES} \
+	${PLAT_S32G274ARDB2}/plat_bl31_setup.c \
+	${PLAT_S32G274ARDB2}/s32g2_psci.c \
+	${PLAT_S32G274ARDB2}/s32g2_soc.c \
+	${XLAT_TABLES_LIB_SRCS} \
+	lib/cpus/aarch64/cortex_a53.S \
+	plat/common/plat_gicv3.c \
+	plat/common/plat_psci_common.c \
+
+# process all errata flags
+$(eval $(call default_zeros, $(S32_ERRATA_LIST)))
+$(eval $(call add_defines, $(S32_ERRATA_LIST)))
+$(eval $(call assert_booleans, $(S32_ERRATA_LIST)))
diff --git a/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c b/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
new file mode 100644
index 00000000..aa60ac46
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2019-2021, 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <s32cc-ncore.h>
+
+static void ncore_diru_online(uint32_t diru)
+{
+	uint32_t numsfs, sf;
+
+	numsfs = NCORE_CSID_NUMSFS(mmio_read_32(NCORE_CSID)) + 1U;
+
+	/* Initialize all entries maintenance operation for each snoop filter */
+	for (sf = 0U; sf < numsfs; sf++) {
+		mmio_write_32(NCORE_DIRUSFMC(diru), NCORE_DIRUSFMC_SFID(sf) |
+			      NCORE_DIRUSFMC_SFMNTOP_ALL);
+
+		while ((mmio_read_32(NCORE_DIRUSFMA(diru)) & NCORE_DIRUSFMA_MNTOPACTV) != 0U) {
+		}
+
+		mmio_setbits_32(NCORE_DIRUSFE(diru), NCORE_DIRUSFE_SFEN(sf));
+	}
+}
+
+void ncore_disable_caiu_isolation(uint32_t caiu)
+{
+	/* Exit from low-power state */
+	mmio_clrbits_32(NCORE_CAIUTC(caiu), NCORE_CAIUTC_ISOLEN_MASK);
+}
+
+static void set_caiu(uint32_t caiu, bool on)
+{
+	uint32_t dirucase, csadser, caiuidr;
+	uint32_t numdirus, diru;
+
+	/* Enable or disable snoop messages to the CAI for each DIRU */
+	numdirus = NCORE_CSUID_NUMDIRUS(mmio_read_32(NCORE_CSUID));
+	for (diru = 0; diru < numdirus; diru++) {
+		dirucase = mmio_read_32(NCORE_DIRUCASE(diru));
+
+		if (on) {
+			dirucase |= NCORE_DIRUCASE_CASNPEN(caiu);
+		} else {
+			dirucase &= ~NCORE_DIRUCASE_CASNPEN(caiu);
+		}
+
+		mmio_write_32(NCORE_DIRUCASE(diru), dirucase);
+	}
+
+	/* Enable or disable DVM messages to the CAI */
+	caiuidr = mmio_read_32(NCORE_CAIUID(caiu));
+	if ((caiuidr & NCORE_CAIUID_TYPE) == NCORE_CAIUID_TYPE_ACE_DVM) {
+		csadser = mmio_read_32(NCORE_CSADSE);
+
+		if (on) {
+			csadser |= NCORE_CSADSE_DVMSNPEN(caiu);
+		} else {
+			csadser &= ~NCORE_CSADSE_DVMSNPEN(caiu);
+		}
+
+		mmio_write_32(NCORE_CSADSE, csadser);
+	}
+}
+
+void ncore_caiu_online(uint32_t caiu)
+{
+	set_caiu(caiu, true);
+}
+
+void ncore_caiu_offline(uint32_t caiu)
+{
+	set_caiu(caiu, false);
+}
+
+bool ncore_is_caiu_online(uint32_t caiu)
+{
+	uint32_t stat = mmio_read_32(NCORE_CSADSE);
+
+	return ((stat & NCORE_CSADSE_DVMSNPEN(caiu)) != 0U);
+}
+
+void ncore_init(void)
+{
+	uint32_t csuidr = mmio_read_32(NCORE_CSUID);
+	uint32_t numdirus, diru;
+
+	numdirus = NCORE_CSUID_NUMDIRUS(csuidr);
+	for (diru = 0U; diru < numdirus; diru++) {
+		/**
+		 * Transition the directory to an online state by ensuring that
+		 * all DIRUs within the interface are operational.
+		 */
+		ncore_diru_online(diru);
+	}
+}
diff --git a/plat/nxp/s32/s32g274ardb2/s32g2_psci.c b/plat/nxp/s32/s32g274ardb2/s32g2_psci.c
new file mode 100644
index 00000000..2d02d94b
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32g2_psci.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	static const plat_psci_ops_t s32g2_psci_ops = {
+	};
+
+	*psci_ops = &s32g2_psci_ops;
+
+	return 0;
+}
+
diff --git a/plat/nxp/s32/s32g274ardb2/s32g2_soc.c b/plat/nxp/s32/s32g274ardb2/s32g2_soc.c
new file mode 100644
index 00000000..00013523
--- /dev/null
+++ b/plat/nxp/s32/s32g274ardb2/s32g2_soc.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+#include <plat_helpers.h>
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	static const unsigned char s32g_power_domain_tree_desc[] = {
+		PLATFORM_SYSTEM_COUNT,
+		PLATFORM_CLUSTER_COUNT,
+		PLATFORM_CORE_COUNT / U(2),
+		PLATFORM_CORE_COUNT / U(2),
+	};
+
+	return s32g_power_domain_tree_desc;
+}
+
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id, core_id;
+	u_register_t mpidr_priv = mpidr;
+
+	mpidr_priv &= MPIDR_AFFINITY_MASK;
+
+	if ((mpidr_priv & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0) {
+		return -1;
+	}
+
+	cluster_id = MPIDR_AFFLVL1_VAL(mpidr_priv);
+	cpu_id = MPIDR_AFFLVL0_VAL(mpidr_priv);
+
+	if ((cluster_id >= PLATFORM_CLUSTER_COUNT) ||
+	    (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)) {
+		return -1;
+	}
+
+	core_id = s32g2_core_pos_by_mpidr(mpidr_priv);
+	if (core_id >= PLATFORM_CORE_COUNT) {
+		return -1;
+	}
+
+	return (int)core_id;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return COUNTER_FREQUENCY;
+}
diff --git a/plat/nxp/soc-lx2160a/ddr_fip.mk b/plat/nxp/soc-lx2160a/ddr_fip.mk
index f14a9e86..c303cedb 100644
--- a/plat/nxp/soc-lx2160a/ddr_fip.mk
+++ b/plat/nxp/soc-lx2160a/ddr_fip.mk
@@ -38,8 +38,6 @@ ifeq (${DDR_DMEM_RDIMM_2D},)
     DDR_DMEM_RDIMM_2D	:=	${DDR_PHY_BIN_PATH}/ddr4_rdimm2d_pmu_train_dmem.bin
 endif
 
-$(shell mkdir -p '${BUILD_PLAT}')
-
 ifeq (${DDR_FIP_NAME},)
 ifeq (${TRUSTED_BOARD_BOOT},1)
 	DDR_FIP_NAME	:= ddr_fip_sec.bin
@@ -73,11 +71,11 @@ CRTTOOL		?=	${CRTTOOLPATH}/cert_create${BIN_EXT}
 
 ifneq (${GENERATE_COT},0)
 ddr_certificates: ${DDR_CRT_DEPS} ${CRTTOOL}
-	${Q}${CRTTOOL} ${DDR_CRT_ARGS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@echo "DDR certificates can be found in ${BUILD_PLAT}"
-	@${ECHO_BLANK_LINE}
+	$(q)${CRTTOOL} ${DDR_CRT_ARGS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo "DDR certificates can be found in ${BUILD_PLAT}"
+	$(s)echo
 endif
 endif
 endif
@@ -88,10 +86,10 @@ FIPTOOL		?=	${FIPTOOLPATH}/fiptool${BIN_EXT}
 
 ${BUILD_PLAT}/${DDR_FIP_NAME}: ${DDR_FIP_DEPS} ${FIPTOOL}
 	$(eval ${CHECK_DDR_FIP_CMD})
-	${Q}${FIPTOOL} create ${DDR_FIP_ARGS} $@
-	${Q}${FIPTOOL} info $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(q)${FIPTOOL} create ${DDR_FIP_ARGS} $@
+	$(q)${FIPTOOL} info $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 fip_ddr: ${BUILD_PLAT}/${DDR_FIP_NAME}
diff --git a/plat/nxp/soc-lx2160a/ddr_sb.mk b/plat/nxp/soc-lx2160a/ddr_sb.mk
index c11651e3..119fc089 100644
--- a/plat/nxp/soc-lx2160a/ddr_sb.mk
+++ b/plat/nxp/soc-lx2160a/ddr_sb.mk
@@ -36,7 +36,7 @@ DDR_INPUT_FILE:= drivers/nxp/auth/csf_hdr_parser/${CSF_FILE}
 endif
 
 %.sb: %
-	@echo " Generating CSF Header for $@ $<"
+	$(s)echo " Generating CSF Header for $@ $<"
 	$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
 					--app $< ${DDR_INPUT_FILE}
 
diff --git a/plat/nxp/soc-lx2160a/ddr_tbbr.mk b/plat/nxp/soc-lx2160a/ddr_tbbr.mk
index deb475b0..836a431f 100644
--- a/plat/nxp/soc-lx2160a/ddr_tbbr.mk
+++ b/plat/nxp/soc-lx2160a/ddr_tbbr.mk
@@ -39,8 +39,6 @@ NTFW_NVCTR_VAL		?=	0
 # Pass the non-volatile counters to the cert_create tool
 $(eval $(call CERT_ADD_CMD_OPT,${TFW_NVCTR_VAL},--tfw-nvctr,DDR_))
 
-$(shell mkdir -p '${BUILD_PLAT}')
-
 ifeq (${DDR_KEY},)
 DDR_KEY=${BUILD_PLAT}/ddr.pem
 endif
diff --git a/plat/qemu/common/common.mk b/plat/qemu/common/common.mk
index 2dcac69b..ed95bc67 100644
--- a/plat/qemu/common/common.mk
+++ b/plat/qemu/common/common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Linaro Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -88,8 +88,8 @@ ifeq (${ARCH},aarch64)
 #
 # We go v8.0 by default and will enable all features we want
 
-ARM_ARCH_MAJOR		:=	8
-ARM_ARCH_MINOR		:=	0
+ARM_ARCH_MAJOR		?=	8
+ARM_ARCH_MINOR		?=	0
 
 # 8.0
 ENABLE_FEAT_CSV2_2	:=	2
@@ -106,12 +106,16 @@ ENABLE_FEAT_RAS		:=	0
 # 8.4
 ENABLE_FEAT_SEL2	:=	2
 ENABLE_FEAT_DIT		:=	2
+ENABLE_TRF_FOR_NS	:=	2
 
 # 8.5
 ENABLE_FEAT_RNG		:=	2
-ENABLE_FEAT_SB		:=	2
+# TF-A currently does not do dynamic detection of FEAT_SB.
+# Compiler puts SB instruction when it is enabled.
+ENABLE_FEAT_SB		:=	0
 
 # 8.6
+ENABLE_FEAT_ECV		:=	2
 ENABLE_FEAT_FGT		:=	2
 
 # 8.7
@@ -126,6 +130,11 @@ else
 	ENABLE_SME_FOR_NS	:= 2
 endif
 
+ifeq (${ENABLE_RME},1)
+BL31_SOURCES			+= plat/qemu/common/qemu_plat_attest_token.c \
+				   plat/qemu/common/qemu_realm_attest_key.c
+endif
+
 # Treating this as a memory-constrained port for now
 USE_COHERENT_MEM	:=	0
 
diff --git a/plat/qemu/common/qemu_bl2_mem_params_desc.c b/plat/qemu/common/qemu_bl2_mem_params_desc.c
index bb1797d1..c444be41 100644
--- a/plat/qemu/common/qemu_bl2_mem_params_desc.c
+++ b/plat/qemu/common/qemu_bl2_mem_params_desc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -67,11 +67,28 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
 
 # ifdef QEMU_LOAD_BL32
 	  .next_handoff_image_id = BL32_IMAGE_ID,
+# elif ENABLE_RME
+	  .next_handoff_image_id = RMM_IMAGE_ID,
 # else
 	  .next_handoff_image_id = BL33_IMAGE_ID,
 # endif
 	},
 #endif /* __aarch64__ */
+
+#if ENABLE_RME
+	/* Fill RMM related information */
+	{ .image_id = RMM_IMAGE_ID,
+	  SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+		VERSION_2, entry_point_info_t, EP_REALM | EXECUTABLE),
+	  .ep_info.pc = RMM_BASE,
+	  SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+		VERSION_2, image_info_t, 0),
+	  .image_info.image_base = RMM_BASE,
+	  .image_info.image_max_size = RMM_LIMIT - RMM_BASE,
+	  .next_handoff_image_id = BL33_IMAGE_ID,
+	},
+#endif /* ENABLE_RME */
+
 # ifdef QEMU_LOAD_BL32
 
 #ifdef __aarch64__
@@ -95,7 +112,11 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
 	  .image_info.image_base = BL32_BASE,
 	  .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
 
+#if ENABLE_RME
+	  .next_handoff_image_id = RMM_IMAGE_ID,
+#else
 	  .next_handoff_image_id = BL33_IMAGE_ID,
+#endif
 	},
 
 	/*
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index 231f23a7..c96e4b95 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 
 #include <platform_def.h>
 
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
@@ -18,42 +19,41 @@
 #include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
 #include <lib/optee_utils.h>
-#if TRANSFER_LIST
 #include <lib/transfer_list.h>
-#endif
 #include <lib/utils.h>
 #include <plat/common/platform.h>
+#if ENABLE_RME
+#include <qemu_pas_def.h>
+#endif
 
 #include "qemu_private.h"
 
 #define MAP_BL2_TOTAL		MAP_REGION_FLAT(			\
 					bl2_tzram_layout.total_base,	\
 					bl2_tzram_layout.total_size,	\
-					MT_MEMORY | MT_RW | MT_SECURE)
+					MT_MEMORY | MT_RW | EL3_PAS)
 
 #define MAP_BL2_RO		MAP_REGION_FLAT(			\
 					BL_CODE_BASE,			\
 					BL_CODE_END - BL_CODE_BASE,	\
-					MT_CODE | MT_SECURE),		\
+					MT_CODE | EL3_PAS),		\
 				MAP_REGION_FLAT(			\
 					BL_RO_DATA_BASE,		\
 					BL_RO_DATA_END			\
 						- BL_RO_DATA_BASE,	\
-					MT_RO_DATA | MT_SECURE)
+					MT_RO_DATA | EL3_PAS)
 
 #if USE_COHERENT_MEM
 #define MAP_BL_COHERENT_RAM	MAP_REGION_FLAT(			\
 					BL_COHERENT_RAM_BASE,		\
 					BL_COHERENT_RAM_END		\
 						- BL_COHERENT_RAM_BASE,	\
-					MT_DEVICE | MT_RW | MT_SECURE)
+					MT_DEVICE | MT_RW | EL3_PAS)
 #endif
 
 /* Data structure which holds the extents of the trusted SRAM for BL2 */
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
-#if TRANSFER_LIST
 static struct transfer_list_header *bl2_tl;
-#endif
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 			       u_register_t arg2, u_register_t arg3)
@@ -101,12 +101,24 @@ static void update_dt(void)
 		return;
 	}
 
+#if ENABLE_RME
+	if (fdt_add_reserved_memory(fdt, "rmm", REALM_DRAM_BASE,
+				    REALM_DRAM_SIZE)) {
+		ERROR("Failed to reserve RMM memory in Device Tree\n");
+		return;
+	}
+
+	INFO("Reserved RMM memory [0x%lx, 0x%lx] in Device tree\n",
+	     (uintptr_t)REALM_DRAM_BASE,
+	     (uintptr_t)REALM_DRAM_BASE + REALM_DRAM_SIZE - 1);
+#endif
+
 	ret = fdt_pack(fdt);
 	if (ret < 0)
 		ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
 
 #if TRANSFER_LIST
-	// create a TE
+	/* create a TE */
 	te = transfer_list_add(bl2_tl, TL_TAG_FDT, fdt_totalsize(fdt), fdt);
 	if (!te) {
 		ERROR("Failed to add FDT entry to Transfer List\n");
@@ -138,6 +150,54 @@ void qemu_bl2_sync_transfer_list(void)
 #endif
 }
 
+#if ENABLE_RME
+static void bl2_plat_gpt_setup(void)
+{
+	/*
+	 * The GPT library might modify the gpt regions structure to optimize
+	 * the layout, so the array cannot be constant.
+	 */
+	pas_region_t pas_regions[] = {
+		QEMU_PAS_ROOT,
+		QEMU_PAS_SECURE,
+		QEMU_PAS_GPTS,
+		QEMU_PAS_NS0,
+		QEMU_PAS_REALM,
+		QEMU_PAS_NS1,
+	};
+
+	/*
+	 * Initialize entire protected space to GPT_GPI_ANY. With each L0 entry
+	 * covering 1GB (currently the only supported option), then covering
+	 * 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the
+	 * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
+	 */
+	if (gpt_init_l0_tables(GPCCR_PPS_1TB, PLAT_QEMU_L0_GPT_BASE,
+			       PLAT_QEMU_L0_GPT_SIZE +
+			       PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
+		ERROR("gpt_init_l0_tables() failed!\n");
+		panic();
+	}
+
+	/* Carve out defined PAS ranges. */
+	if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
+				   PLAT_QEMU_L1_GPT_BASE,
+				   PLAT_QEMU_L1_GPT_SIZE,
+				   pas_regions,
+				   (unsigned int)(sizeof(pas_regions) /
+						  sizeof(pas_region_t))) < 0) {
+		ERROR("gpt_init_pas_l1_tables() failed!\n");
+		panic();
+	}
+
+	INFO("Enabling Granule Protection Checks\n");
+	if (gpt_enable() < 0) {
+		ERROR("gpt_enable() failed!\n");
+		panic();
+	}
+}
+#endif
+
 void bl2_plat_arch_setup(void)
 {
 	const mmap_region_t bl_regions[] = {
@@ -145,17 +205,32 @@ void bl2_plat_arch_setup(void)
 		MAP_BL2_RO,
 #if USE_COHERENT_MEM
 		MAP_BL_COHERENT_RAM,
+#endif
+#if ENABLE_RME
+		MAP_RMM_DRAM,
+		MAP_GPT_L0_REGION,
+		MAP_GPT_L1_REGION,
 #endif
 		{0}
 	};
 
 	setup_page_tables(bl_regions, plat_qemu_get_mmap());
 
+#if ENABLE_RME
+	/* BL2 runs in EL3 when RME enabled. */
+	assert(is_feat_rme_present());
+	enable_mmu_el3(0);
+
+	/* Initialise and enable granule protection after MMU. */
+	bl2_plat_gpt_setup();
+#else /* ENABLE_RME */
+
 #ifdef __aarch64__
 	enable_mmu_el1(0);
 #else
 	enable_mmu_svc_mon(0);
 #endif
+#endif /* ENABLE_RME */
 }
 
 /*******************************************************************************
@@ -243,6 +318,23 @@ static int load_sps_from_tb_fw_config(struct image_info *image_info)
 }
 #endif /*defined(SPD_spmd) && SPMD_SPM_AT_SEL2*/
 
+#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
+static int handoff_pageable_part(uint64_t pagable_part)
+{
+#if TRANSFER_LIST
+	struct transfer_list_entry *te;
+
+	te = transfer_list_add(bl2_tl, TL_TAG_OPTEE_PAGABLE_PART,
+			       sizeof(pagable_part), &pagable_part);
+	if (!te) {
+		INFO("Cannot add TE for pageable part\n");
+		return -1;
+	}
+#endif
+	return 0;
+}
+#endif
+
 static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 {
 	int err = 0;
@@ -256,12 +348,32 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 #endif
 #if TRANSFER_LIST
 	struct transfer_list_header *ns_tl = NULL;
-	struct transfer_list_entry *te = NULL;
 #endif
 
 	assert(bl_mem_params);
 
 	switch (image_id) {
+#if TRANSFER_LIST
+	case BL31_IMAGE_ID:
+		/*
+		 * arg0 is a bl_params_t reserved for bl31_early_platform_setup2
+		 * we just need arg1 and arg3 for BL31 to update the TL from S
+		 * to NS memory before it exits
+		 */
+#ifdef __aarch64__
+		if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_64) {
+			bl_mem_params->ep_info.args.arg1 =
+				TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
+		} else
+#endif
+		{
+			bl_mem_params->ep_info.args.arg1 =
+				TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+		}
+
+		bl_mem_params->ep_info.args.arg3 = (uintptr_t)bl2_tl;
+		break;
+#endif
 	case BL32_IMAGE_ID:
 #if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) || defined(SPMC_OPTEE)
 		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
@@ -276,8 +388,21 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 		if (err != 0) {
 			WARN("OPTEE header parse error.\n");
 		}
+
+		/* add TL_TAG_OPTEE_PAGABLE_PART entry to the TL */
+		if (handoff_pageable_part(bl_mem_params->ep_info.args.arg1)) {
+			return -1;
+		}
 #endif
 
+		INFO("Handoff to BL32\n");
+		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
+		if (TRANSFER_LIST &&
+			transfer_list_set_handoff_args(bl2_tl,
+				&bl_mem_params->ep_info))
+			break;
+
+		INFO("Using default arguments\n");
 #if defined(SPMC_OPTEE)
 		/*
 		 * Explicit zeroes to unused registers since they may have
@@ -301,7 +426,6 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 		bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE;
 		bl_mem_params->ep_info.args.arg3 = 0;
 #endif
-		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
 		break;
 
 	case BL33_IMAGE_ID:
@@ -328,7 +452,7 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 		bl_mem_params->ep_info.args.arg3 = 0U;
 #elif TRANSFER_LIST
 		if (bl2_tl) {
-			// relocate the tl to pre-allocate NS memory
+			/* relocate the tl to pre-allocate NS memory */
 			ns_tl = transfer_list_relocate(bl2_tl,
 					(void *)(uintptr_t)FW_NS_HANDOFF_BASE,
 					bl2_tl->max_size);
@@ -337,37 +461,18 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
 					(unsigned long)FW_NS_HANDOFF_BASE);
 				return -1;
 			}
-			NOTICE("Transfer list handoff to BL33\n");
-			transfer_list_dump(ns_tl);
-
-			te = transfer_list_find(ns_tl, TL_TAG_FDT);
+		}
 
-			bl_mem_params->ep_info.args.arg1 =
-				TRANSFER_LIST_SIGNATURE |
-				REGISTER_CONVENTION_VERSION_MASK;
-			bl_mem_params->ep_info.args.arg3 = (uintptr_t)ns_tl;
-
-			if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_32) {
-				// aarch32
-				bl_mem_params->ep_info.args.arg0 = 0;
-				bl_mem_params->ep_info.args.arg2 = te ?
-					(uintptr_t)transfer_list_entry_data(te)
-					: 0;
-			} else {
-				// aarch64
-				bl_mem_params->ep_info.args.arg0 = te ?
-					(uintptr_t)transfer_list_entry_data(te)
-					: 0;
-				bl_mem_params->ep_info.args.arg2 = 0;
-			}
-		} else {
-			// Legacy handoff
+		INFO("Handoff to BL33\n");
+		if (!transfer_list_set_handoff_args(ns_tl,
+						    &bl_mem_params->ep_info)) {
+			INFO("Invalid TL, fallback to default arguments\n");
 			bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
 		}
 #else
 		/* BL33 expects to receive the primary CPU MPID (through r0) */
 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
-#endif // ARM_LINUX_KERNEL_AS_BL33
+#endif /* ARM_LINUX_KERNEL_AS_BL33 */
 
 		break;
 #ifdef SPD_spmd
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index f309efdc..0a70cc29 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,8 @@
 
 #include <common/bl_common.h>
 #include <drivers/arm/pl061_gpio.h>
+#include <lib/gpt_rme/gpt_rme.h>
+#include <lib/transfer_list.h>
 #include <plat/common/platform.h>
 
 #include "qemu_private.h"
@@ -40,6 +42,10 @@
  */
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
+#if ENABLE_RME
+static entry_point_info_t rmm_image_ep_info;
+#endif
+static struct transfer_list_header *bl31_tl;
 
 /*******************************************************************************
  * Perform any BL3-1 early platform setup.  Here is an opportunity to copy
@@ -72,13 +78,18 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	bl_params_node_t *bl_params = params_from_bl2->head;
 
 	/*
-	 * Copy BL33 and BL32 (if present), entry point information.
+	 * Copy BL33, BL32 and RMM (if present), entry point information.
 	 * They are stored in Secure RAM, in BL2's address space.
 	 */
 	while (bl_params) {
 		if (bl_params->image_id == BL32_IMAGE_ID)
 			bl32_image_ep_info = *bl_params->ep_info;
 
+#if ENABLE_RME
+		if (bl_params->image_id == RMM_IMAGE_ID)
+			rmm_image_ep_info = *bl_params->ep_info;
+#endif
+
 		if (bl_params->image_id == BL33_IMAGE_ID)
 			bl33_image_ep_info = *bl_params->ep_info;
 
@@ -87,6 +98,16 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 
 	if (!bl33_image_ep_info.pc)
 		panic();
+#if ENABLE_RME
+	if (!rmm_image_ep_info.pc)
+		panic();
+#endif
+
+	if (TRANSFER_LIST && arg1 == (TRANSFER_LIST_SIGNATURE |
+				      REGISTER_CONVENTION_VERSION_MASK) &&
+	    transfer_list_check_header((void *)arg3) != TL_OPS_NON) {
+		bl31_tl = (void *)arg3; /* saved TL address from BL2 */
+	}
 }
 
 void bl31_plat_arch_setup(void)
@@ -96,6 +117,11 @@ void bl31_plat_arch_setup(void)
 		MAP_BL31_RO,
 #if USE_COHERENT_MEM
 		MAP_BL_COHERENT_RAM,
+#endif
+#if ENABLE_RME
+		MAP_GPT_L0_REGION,
+		MAP_GPT_L1_REGION,
+		MAP_RMM_SHARED_MEM,
 #endif
 		{0}
 	};
@@ -103,6 +129,20 @@ void bl31_plat_arch_setup(void)
 	setup_page_tables(bl_regions, plat_qemu_get_mmap());
 
 	enable_mmu_el3(0);
+
+#if ENABLE_RME
+	/*
+	 * Initialise Granule Protection library and enable GPC for the primary
+	 * processor. The tables have already been initialized by a previous BL
+	 * stage, so there is no need to provide any PAS here. This function
+	 * sets up pointers to those tables.
+	 */
+	if (gpt_runtime_init() < 0) {
+		ERROR("gpt_runtime_init() failed!\n");
+		panic();
+	}
+#endif /* ENABLE_RME */
+
 }
 
 static void qemu_gpio_init(void)
@@ -121,7 +161,7 @@ void bl31_platform_setup(void)
 
 unsigned int plat_get_syscnt_freq2(void)
 {
-	return SYS_COUNTER_FREQ_IN_TICKS;
+	return read_cntfrq_el0();
 }
 
 /*******************************************************************************
@@ -135,8 +175,18 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
 	entry_point_info_t *next_image_info;
 
 	assert(sec_state_is_valid(type));
-	next_image_info = (type == NON_SECURE)
-			? &bl33_image_ep_info : &bl32_image_ep_info;
+	if (type == NON_SECURE) {
+		next_image_info = &bl33_image_ep_info;
+	}
+#if ENABLE_RME
+	else if (type == REALM) {
+		next_image_info = &rmm_image_ep_info;
+	}
+#endif
+	else {
+		next_image_info =  &bl32_image_ep_info;
+	}
+
 	/*
 	 * None of the images on the ARM development platforms can have 0x0
 	 * as the entrypoint
@@ -146,3 +196,19 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
 	else
 		return NULL;
 }
+
+void bl31_plat_runtime_setup(void)
+{
+#if TRANSFER_LIST
+	if (bl31_tl) {
+		/*
+		 * update the TL from S to NS memory before jump to BL33
+		 * to reflect all changes in TL done by BL32
+		 */
+		memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size);
+	}
+#endif
+
+	console_flush();
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
+}
diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c
index d4488a4b..9ccb2c8a 100644
--- a/plat/qemu/common/qemu_common.c
+++ b/plat/qemu/common/qemu_common.c
@@ -1,55 +1,60 @@
 
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <string.h>
+
 #include <platform_def.h>
 
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <services/el3_spmc_ffa_memory.h>
+#if ENABLE_RME
+#include <services/rmm_core_manifest.h>
+#endif
 
 #include <plat/common/platform.h>
 #include "qemu_private.h"
 
 #define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
 					DEVICE0_SIZE,			\
-					MT_DEVICE | MT_RW | MT_SECURE)
+					MT_DEVICE | MT_RW | EL3_PAS)
 
 #ifdef DEVICE1_BASE
 #define MAP_DEVICE1	MAP_REGION_FLAT(DEVICE1_BASE,			\
 					DEVICE1_SIZE,			\
-					MT_DEVICE | MT_RW | MT_SECURE)
+					MT_DEVICE | MT_RW | EL3_PAS)
 #endif
 
 #ifdef DEVICE2_BASE
 #define MAP_DEVICE2	MAP_REGION_FLAT(DEVICE2_BASE,			\
 					DEVICE2_SIZE,			\
-					MT_DEVICE | MT_RW | MT_SECURE)
+					MT_DEVICE | MT_RW | EL3_PAS)
 #endif
 
 #define MAP_SHARED_RAM	MAP_REGION_FLAT(SHARED_RAM_BASE,		\
 					SHARED_RAM_SIZE,		\
-					MT_DEVICE  | MT_RW | MT_SECURE)
+					MT_DEVICE  | MT_RW | EL3_PAS)
 
 #define MAP_BL32_MEM	MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE,	\
-					MT_MEMORY | MT_RW | MT_SECURE)
+					MT_MEMORY | MT_RW | EL3_PAS)
 
 #define MAP_NS_DRAM0	MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE,	\
 					MT_MEMORY | MT_RW | MT_NS)
 
 #define MAP_FLASH0	MAP_REGION_FLAT(QEMU_FLASH0_BASE, QEMU_FLASH0_SIZE, \
-					MT_MEMORY | MT_RO | MT_SECURE)
+					MT_MEMORY | MT_RO | EL3_PAS)
 
 #define MAP_FLASH1	MAP_REGION_FLAT(QEMU_FLASH1_BASE, QEMU_FLASH1_SIZE, \
-					MT_MEMORY | MT_RO | MT_SECURE)
+					MT_MEMORY | MT_RO | EL3_PAS)
 
 #ifdef FW_HANDOFF_BASE
 #define MAP_FW_HANDOFF MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_SIZE, \
-				       MT_MEMORY | MT_RW | MT_SECURE)
+				       MT_MEMORY | MT_RW | EL3_PAS)
 #endif
 #ifdef FW_NS_HANDOFF_BASE
 #define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE, \
@@ -138,6 +143,19 @@ static const mmap_region_t plat_qemu_mmap[] = {
 };
 #endif
 
+#ifdef IMAGE_RMM
+const mmap_region_t plat_qemu_mmap[] = {
+	MAP_DEVICE0,
+#ifdef MAP_DEVICE1
+	MAP_DEVICE1,
+#endif
+#ifdef MAP_DEVICE2
+	MAP_DEVICE2,
+#endif
+	{0}
+};
+#endif
+
 /*******************************************************************************
  * Returns QEMU platform specific memory map regions.
  ******************************************************************************/
@@ -160,7 +178,7 @@ int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
  */
 #define PLAT_SPMC_SHMEM_DATASTORE_SIZE 64 * 1024
 
-uint8_t plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE];
+uint8_t plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE] __aligned(2 * sizeof(long));
 
 int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
 {
@@ -180,13 +198,137 @@ int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
 }
 #endif
 
-#if defined(SPD_spmd) && (SPMC_AT_EL3 == 0)
-/*
- * A dummy implementation of the platform handler for Group0 secure interrupt.
- */
+#if defined(SPD_spmd)
 int plat_spmd_handle_group0_interrupt(uint32_t intid)
 {
+	/*
+	 * Currently, there are no sources of Group0 secure interrupt
+	 * enabled for QEMU.
+	 */
 	(void)intid;
 	return -1;
 }
-#endif /*defined(SPD_spmd) && (SPMC_AT_EL3 == 0)*/
+#endif /*defined(SPD_spmd)*/
+
+#if ENABLE_RME
+/*
+ * Get a pointer to the RMM-EL3 Shared buffer and return it
+ * through the pointer passed as parameter.
+ *
+ * This function returns the size of the shared buffer.
+ */
+size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
+{
+	*shared = (uintptr_t)RMM_SHARED_BASE;
+
+	return (size_t)RMM_SHARED_SIZE;
+}
+
+int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
+{
+	uint64_t checksum;
+	uintptr_t base;
+	uint64_t size;
+	size_t num_banks = 1;
+	size_t num_consoles = 1;
+	struct ns_dram_bank *bank_ptr;
+	struct console_info *console_ptr;
+
+	assert(manifest != NULL);
+
+	manifest->version = RMMD_MANIFEST_VERSION;
+	manifest->padding = 0U; /* RES0 */
+	manifest->plat_data = (uintptr_t)NULL;
+	manifest->plat_dram.num_banks = num_banks;
+	manifest->plat_console.num_consoles = num_consoles;
+
+	/*
+	 * Boot manifest structure illustration:
+	 *
+	 * +----------------------------------------+
+	 * |  offset  |   field      |  comment     |
+	 * +----------+--------------+--------------+
+	 * |    0     |  version     | 0x00000003   |
+	 * +----------+--------------+--------------+
+	 * |    4     |  padding     | 0x00000000   |
+	 * +----------+--------------+--------------+
+	 * |    8     | plat_data    |    NULL      |
+	 * +----------+--------------+--------------+
+	 * |    16    | num_banks    |              |
+	 * +----------+--------------+              |
+	 * |    24    |   banks      | plat_dram    |
+	 * +----------+--------------+              |
+	 * |    32    | checksum     |              |
+	 * +----------+--------------+--------------+
+	 * |    40    | num_consoles |              |
+	 * +----------+--------------+              |
+	 * |    48    | consoles     | plat_console |
+	 * +----------+--------------+              |
+	 * |    56    | checksum     |              |
+	 * +----------+--------------+--------------+
+	 * |    64    |  base 0      |              |
+	 * +----------+--------------+   bank[0]    |
+	 * |    72    |  size 0      |              |
+	 * +----------+--------------+--------------+
+	 * |    80    |  base        |              |
+	 * +----------+--------------+              |
+	 * |    88    |  map_pages   |              |
+	 * +----------+--------------+              |
+	 * |    96    |  name        |              |
+	 * +----------+--------------+  consoles[0] |
+	 * |   104    |  clk_in_hz   |              |
+	 * +----------+--------------+              |
+	 * |   112    |  baud_rate   |              |
+	 * +----------+--------------+              |
+	 * |   120    |  flags       |              |
+	 * +----------+--------------+--------------+
+	 */
+	bank_ptr = (struct ns_dram_bank *)
+		(((uintptr_t)manifest) + sizeof(*manifest));
+
+	console_ptr = (struct console_info *)
+		((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
+
+	manifest->plat_dram.banks = bank_ptr;
+	manifest->plat_console.consoles = console_ptr;
+
+	/* Ensure the manifest is not larger than the shared buffer */
+	assert((sizeof(struct rmm_manifest) +
+		(sizeof(struct console_info) * num_consoles) +
+		(sizeof(struct ns_dram_bank) * num_banks)) <= RMM_SHARED_SIZE);
+
+	/* Calculate checksum of plat_dram structure */
+	checksum = num_banks + (uint64_t)bank_ptr;
+
+	base = NS_DRAM0_BASE;
+	size = NS_DRAM0_SIZE;
+	bank_ptr[0].base = base;
+	bank_ptr[0].size = size;
+	checksum += base + size;
+
+	/* Checksum must be 0 */
+	manifest->plat_dram.checksum = ~checksum + 1UL;
+
+	/* Calculate the checksum of the plat_consoles structure */
+	checksum = num_consoles + (uint64_t)console_ptr;
+
+	/* Zero out the console info struct */
+	memset((void *)console_ptr, 0, sizeof(struct console_info) * num_consoles);
+
+	console_ptr[0].map_pages = 1;
+	console_ptr[0].base = PLAT_QEMU_BOOT_UART_BASE;
+	console_ptr[0].clk_in_hz = PLAT_QEMU_BOOT_UART_CLK_IN_HZ;
+	console_ptr[0].baud_rate = PLAT_QEMU_CONSOLE_BAUDRATE;
+
+	strlcpy(console_ptr[0].name, "pl011", sizeof(console_ptr[0].name));
+
+	/* Update checksum */
+	checksum += console_ptr[0].base + console_ptr[0].map_pages +
+		console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
+
+	/* Checksum must be 0 */
+	manifest->plat_console.checksum = ~checksum + 1UL;
+
+	return 0;
+}
+#endif  /* ENABLE_RME */
diff --git a/plat/qemu/common/qemu_io_storage.c b/plat/qemu/common/qemu_io_storage.c
index 4c61b146..59bba867 100644
--- a/plat/qemu/common/qemu_io_storage.c
+++ b/plat/qemu/common/qemu_io_storage.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,6 +33,7 @@
 #define BL32_EXTRA1_IMAGE_NAME		"bl32_extra1.bin"
 #define BL32_EXTRA2_IMAGE_NAME		"bl32_extra2.bin"
 #define BL33_IMAGE_NAME			"bl33.bin"
+#define RMM_IMAGE_NAME			"rmm.bin"
 
 #if TRUSTED_BOARD_BOOT
 #define TRUSTED_BOOT_FW_CERT_NAME	"tb_fw.crt"
@@ -96,6 +97,10 @@ static const io_uuid_spec_t bl33_uuid_spec = {
 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
 };
 
+static const io_uuid_spec_t rmm_uuid_spec = {
+	.uuid = UUID_REALM_MONITOR_MGMT_FIRMWARE,
+};
+
 #if TRUSTED_BOARD_BOOT
 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
@@ -163,6 +168,10 @@ static const io_file_spec_t sh_file_spec[] = {
 		.path = BL33_IMAGE_NAME,
 		.mode = FOPEN_MODE_RB
 	},
+	[RMM_IMAGE_ID] = {
+		.path = RMM_IMAGE_NAME,
+		.mode = FOPEN_MODE_RB
+	},
 #if TRUSTED_BOARD_BOOT
 	[TRUSTED_BOOT_FW_CERT_ID] = {
 		.path = TRUSTED_BOOT_FW_CERT_NAME,
@@ -289,6 +298,12 @@ static const struct plat_io_policy policies[] = {
 		(uintptr_t)&bl33_uuid_spec,
 		open_fip
 	},
+	[RMM_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&rmm_uuid_spec,
+		open_fip
+	},
+
 #if TRUSTED_BOARD_BOOT
 	[TRUSTED_BOOT_FW_CERT_ID] = {
 		&fip_dev_handle,
diff --git a/plat/qemu/common/qemu_plat_attest_token.c b/plat/qemu/common/qemu_plat_attest_token.c
new file mode 100644
index 00000000..7b54271e
--- /dev/null
+++ b/plat/qemu/common/qemu_plat_attest_token.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Linaro Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <plat/common/platform.h>
+
+/*
+ * This is the CBOR serialization of the CCA platform token described at
+ * https://git.trustedfirmware.org/TF-M/tf-m-tools/+/refs/heads/main/iat-verifier/tests/data/cca_example_platform_token.yaml
+ */
+static const uint8_t sample_platform_token[] = {
+	0xd2, 0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0,
+	0x59, 0x05, 0x81, 0xa9, 0x19, 0x01, 0x09, 0x78,
+	0x23, 0x74, 0x61, 0x67, 0x3a, 0x61, 0x72, 0x6d,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x32, 0x30, 0x32,
+	0x33, 0x3a, 0x63, 0x63, 0x61, 0x5f, 0x70, 0x6c,
+	0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x23, 0x31,
+	0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x58, 0x20, 0x0d,
+	0x22, 0xe0, 0x8a, 0x98, 0x46, 0x90, 0x58, 0x48,
+	0x63, 0x18, 0x28, 0x34, 0x89, 0xbd, 0xb3, 0x6f,
+	0x09, 0xdb, 0xef, 0xeb, 0x18, 0x64, 0xdf, 0x43,
+	0x3f, 0xa6, 0xe5, 0x4e, 0xa2, 0xd7, 0x11, 0x19,
+	0x09, 0x5c, 0x58, 0x20, 0x7f, 0x45, 0x4c, 0x46,
+	0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3e, 0x00,
+	0x01, 0x00, 0x00, 0x00, 0x50, 0x58, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00, 0x58,
+	0x21, 0x01, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
+	0x01, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a,
+	0x09, 0x08, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12,
+	0x11, 0x10, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a,
+	0x19, 0x18, 0x19, 0x09, 0x61, 0x44, 0xcf, 0xcf,
+	0xcf, 0xcf, 0x19, 0x09, 0x5b, 0x19, 0x30, 0x03,
+	0x19, 0x09, 0x62, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0x19, 0x09, 0x60, 0x78, 0x3a,
+	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f,
+	0x76, 0x65, 0x72, 0x61, 0x69, 0x73, 0x6f, 0x6e,
+	0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+	0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b,
+	0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x76, 0x65, 0x72,
+	0x61, 0x69, 0x73, 0x6f, 0x6e, 0x2f, 0x76, 0x65,
+	0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x19, 0x09, 0x5f, 0x8d, 0xa4, 0x01,
+	0x69, 0x52, 0x53, 0x45, 0x5f, 0x42, 0x4c, 0x31,
+	0x5f, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0x9a, 0x27, 0x1f, 0x2a, 0x91, 0x6b, 0x0b, 0x6e,
+	0xe6, 0xce, 0xcb, 0x24, 0x26, 0xf0, 0xb3, 0x20,
+	0x6e, 0xf0, 0x74, 0x57, 0x8b, 0xe5, 0x5d, 0x9b,
+	0xc9, 0x4f, 0x6f, 0x3f, 0xe3, 0xab, 0x86, 0xaa,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x67, 0x52, 0x53, 0x45, 0x5f,
+	0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x53, 0xc2, 0x34, 0xe5, 0xe8, 0x47, 0x2b,
+	0x6a, 0xc5, 0x1c, 0x1a, 0xe1, 0xca, 0xb3, 0xfe,
+	0x06, 0xfa, 0xd0, 0x53, 0xbe, 0xb8, 0xeb, 0xfd,
+	0x89, 0x77, 0xb0, 0x10, 0x65, 0x5b, 0xfd, 0xd3,
+	0xc3, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x65, 0x52, 0x53, 0x45,
+	0x5f, 0x53, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0x11, 0x21, 0xcf, 0xcc, 0xd5, 0x91, 0x3f, 0x0a,
+	0x63, 0xfe, 0xc4, 0x0a, 0x6f, 0xfd, 0x44, 0xea,
+	0x64, 0xf9, 0xdc, 0x13, 0x5c, 0x66, 0x63, 0x4b,
+	0xa0, 0x01, 0xd1, 0x0b, 0xcf, 0x43, 0x02, 0xa2,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f, 0x42,
+	0x4c, 0x31, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0x15, 0x71, 0xb5, 0xec, 0x78, 0xbd, 0x68, 0x51,
+	0x2b, 0xf7, 0x83, 0x0b, 0xb6, 0xa2, 0xa4, 0x4b,
+	0x20, 0x47, 0xc7, 0xdf, 0x57, 0xbc, 0xe7, 0x9e,
+	0xb8, 0xa1, 0xc0, 0xe5, 0xbe, 0xa0, 0xa5, 0x01,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x66, 0x41, 0x50, 0x5f, 0x42,
+	0x4c, 0x32, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0x10, 0x15, 0x9b, 0xaf, 0x26, 0x2b, 0x43, 0xa9,
+	0x2d, 0x95, 0xdb, 0x59, 0xda, 0xe1, 0xf7, 0x2c,
+	0x64, 0x51, 0x27, 0x30, 0x16, 0x61, 0xe0, 0xa3,
+	0xce, 0x4e, 0x38, 0xb2, 0x95, 0xa9, 0x7c, 0x58,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x67, 0x53, 0x43, 0x50, 0x5f,
+	0x42, 0x4c, 0x31, 0x05, 0x58, 0x20, 0x53, 0x78,
+	0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d,
+	0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41,
+	0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38,
+	0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58,
+	0x20, 0x10, 0x12, 0x2e, 0x85, 0x6b, 0x3f, 0xcd,
+	0x49, 0xf0, 0x63, 0x63, 0x63, 0x17, 0x47, 0x61,
+	0x49, 0xcb, 0x73, 0x0a, 0x1a, 0xa1, 0xcf, 0xaa,
+	0xd8, 0x18, 0x55, 0x2b, 0x72, 0xf5, 0x6d, 0x6f,
+	0x68, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32,
+	0x35, 0x36, 0xa4, 0x01, 0x67, 0x53, 0x43, 0x50,
+	0x5f, 0x42, 0x4c, 0x32, 0x05, 0x58, 0x20, 0xf1,
+	0x4b, 0x49, 0x87, 0x90, 0x4b, 0xcb, 0x58, 0x14,
+	0xe4, 0x45, 0x9a, 0x05, 0x7e, 0xd4, 0xd2, 0x0f,
+	0x58, 0xa6, 0x33, 0x15, 0x22, 0x88, 0xa7, 0x61,
+	0x21, 0x4d, 0xcd, 0x28, 0x78, 0x0b, 0x56, 0x02,
+	0x58, 0x20, 0xaa, 0x67, 0xa1, 0x69, 0xb0, 0xbb,
+	0xa2, 0x17, 0xaa, 0x0a, 0xa8, 0x8a, 0x65, 0x34,
+	0x69, 0x20, 0xc8, 0x4c, 0x42, 0x44, 0x7c, 0x36,
+	0xba, 0x5f, 0x7e, 0xa6, 0x5f, 0x42, 0x2c, 0x1f,
+	0xe5, 0xd8, 0x06, 0x67, 0x73, 0x68, 0x61, 0x2d,
+	0x32, 0x35, 0x36, 0xa4, 0x01, 0x67, 0x41, 0x50,
+	0x5f, 0x42, 0x4c, 0x33, 0x31, 0x05, 0x58, 0x20,
+	0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3,
+	0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56,
+	0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3,
+	0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3,
+	0x02, 0x58, 0x20, 0x2e, 0x6d, 0x31, 0xa5, 0x98,
+	0x3a, 0x91, 0x25, 0x1b, 0xfa, 0xe5, 0xae, 0xfa,
+	0x1c, 0x0a, 0x19, 0xd8, 0xba, 0x3c, 0xf6, 0x01,
+	0xd0, 0xe8, 0xa7, 0x06, 0xb4, 0xcf, 0xa9, 0x66,
+	0x1a, 0x6b, 0x8a, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x63, 0x52,
+	0x4d, 0x4d, 0x05, 0x58, 0x20, 0x53, 0x78, 0x79,
+	0x63, 0x07, 0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b,
+	0x15, 0xa2, 0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c,
+	0x3d, 0x30, 0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0,
+	0xfa, 0x97, 0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20,
+	0xa1, 0xfb, 0x50, 0xe6, 0xc8, 0x6f, 0xae, 0x16,
+	0x79, 0xef, 0x33, 0x51, 0x29, 0x6f, 0xd6, 0x71,
+	0x34, 0x11, 0xa0, 0x8c, 0xf8, 0xdd, 0x17, 0x90,
+	0xa4, 0xfd, 0x05, 0xfa, 0xe8, 0x68, 0x81, 0x64,
+	0x06, 0x67, 0x73, 0x68, 0x61, 0x2d, 0x32, 0x35,
+	0x36, 0xa4, 0x01, 0x69, 0x48, 0x57, 0x5f, 0x43,
+	0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58, 0x20,
+	0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3,
+	0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56,
+	0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3,
+	0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3,
+	0x02, 0x58, 0x20, 0x1a, 0x25, 0x24, 0x02, 0x97,
+	0x2f, 0x60, 0x57, 0xfa, 0x53, 0xcc, 0x17, 0x2b,
+	0x52, 0xb9, 0xff, 0xca, 0x69, 0x8e, 0x18, 0x31,
+	0x1f, 0xac, 0xd0, 0xf3, 0xb0, 0x6e, 0xca, 0xae,
+	0xf7, 0x9e, 0x17, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x69, 0x46,
+	0x57, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47,
+	0x05, 0x58, 0x20, 0x53, 0x78, 0x79, 0x63, 0x07,
+	0x53, 0x5d, 0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2,
+	0xe2, 0xdc, 0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30,
+	0x60, 0xcf, 0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97,
+	0x3f, 0x7a, 0xa3, 0x02, 0x58, 0x20, 0x9a, 0x92,
+	0xad, 0xbc, 0x0c, 0xee, 0x38, 0xef, 0x65, 0x8c,
+	0x71, 0xce, 0x1b, 0x1b, 0xf8, 0xc6, 0x56, 0x68,
+	0xf1, 0x66, 0xbf, 0xb2, 0x13, 0x64, 0x4c, 0x89,
+	0x5c, 0xcb, 0x1a, 0xd0, 0x7a, 0x25, 0x06, 0x67,
+	0x73, 0x68, 0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4,
+	0x01, 0x6c, 0x54, 0x42, 0x5f, 0x46, 0x57, 0x5f,
+	0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58,
+	0x20, 0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d,
+	0xf3, 0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc,
+	0x56, 0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf,
+	0xe3, 0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a,
+	0xa3, 0x02, 0x58, 0x20, 0x23, 0x89, 0x03, 0x18,
+	0x0c, 0xc1, 0x04, 0xec, 0x2c, 0x5d, 0x8b, 0x3f,
+	0x20, 0xc5, 0xbc, 0x61, 0xb3, 0x89, 0xec, 0x0a,
+	0x96, 0x7d, 0xf8, 0xcc, 0x20, 0x8c, 0xdc, 0x7c,
+	0xd4, 0x54, 0x17, 0x4f, 0x06, 0x67, 0x73, 0x68,
+	0x61, 0x2d, 0x32, 0x35, 0x36, 0xa4, 0x01, 0x6d,
+	0x53, 0x4f, 0x43, 0x5f, 0x46, 0x57, 0x5f, 0x43,
+	0x4f, 0x4e, 0x46, 0x49, 0x47, 0x05, 0x58, 0x20,
+	0x53, 0x78, 0x79, 0x63, 0x07, 0x53, 0x5d, 0xf3,
+	0xec, 0x8d, 0x8b, 0x15, 0xa2, 0xe2, 0xdc, 0x56,
+	0x41, 0x41, 0x9c, 0x3d, 0x30, 0x60, 0xcf, 0xe3,
+	0x22, 0x38, 0xc0, 0xfa, 0x97, 0x3f, 0x7a, 0xa3,
+	0x02, 0x58, 0x20, 0xe6, 0xc2, 0x1e, 0x8d, 0x26,
+	0x0f, 0xe7, 0x18, 0x82, 0xde, 0xbd, 0xb3, 0x39,
+	0xd2, 0x40, 0x2a, 0x2c, 0xa7, 0x64, 0x85, 0x29,
+	0xbc, 0x23, 0x03, 0xf4, 0x86, 0x49, 0xbc, 0xe0,
+	0x38, 0x00, 0x17, 0x06, 0x67, 0x73, 0x68, 0x61,
+	0x2d, 0x32, 0x35, 0x36, 0x58, 0x60, 0x31, 0xd0,
+	0x4d, 0x52, 0xcc, 0xde, 0x95, 0x2c, 0x1e, 0x32,
+	0xcb, 0xa1, 0x81, 0x88, 0x5a, 0x40, 0xb8, 0xcc,
+	0x38, 0xe0, 0x52, 0x8c, 0x1e, 0x89, 0x58, 0x98,
+	0x07, 0x64, 0x2a, 0xa5, 0xe3, 0xf2, 0xbc, 0x37,
+	0xf9, 0x53, 0x74, 0x50, 0x6b, 0xff, 0x4d, 0x2e,
+	0x4b, 0xe7, 0x06, 0x3c, 0x4d, 0x72, 0x41, 0x92,
+	0x70, 0xc7, 0x22, 0xe8, 0xd4, 0xd9, 0x3e, 0xe8,
+	0xb6, 0xc9, 0xfa, 0xce, 0x3b, 0x43, 0xc9, 0x76,
+	0x1a, 0x49, 0x94, 0x1a, 0xb6, 0xf3, 0x8f, 0xfd,
+	0xff, 0x49, 0x6a, 0xd4, 0x63, 0xb4, 0xcb, 0xfa,
+	0x11, 0xd8, 0x3e, 0x23, 0xe3, 0x1f, 0x7f, 0x62,
+	0x32, 0x9d, 0xe3, 0x0c, 0x1c, 0xc8
+};
+
+/*
+ * Get the hardcoded platform attestation token as QEMU does not support
+ * RSE.
+ */
+int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
+				   uintptr_t hash, size_t hash_size,
+				   size_t *remaining_len)
+{
+	const size_t token_size = sizeof(sample_platform_token);
+	(void)hash;
+	(void)hash_size;
+
+	/* Shouldn't happen because RMM uses the whole 4kB shared buffer */
+	if (*len < token_size) {
+		return -EINVAL;
+	}
+
+	memcpy((void *)buf, sample_platform_token, token_size);
+	*len = token_size;
+	*remaining_len = 0;
+
+	return 0;
+}
diff --git a/plat/qemu/common/qemu_pm.c b/plat/qemu/common/qemu_pm.c
index c2b5091d..5f64d70c 100644
--- a/plat/qemu/common/qemu_pm.c
+++ b/plat/qemu/common/qemu_pm.c
@@ -101,22 +101,6 @@ static int qemu_validate_power_state(unsigned int power_state,
 	return PSCI_E_SUCCESS;
 }
 
-/*******************************************************************************
- * Platform handler called to check the validity of the non secure
- * entrypoint.
- ******************************************************************************/
-static int qemu_validate_ns_entrypoint(uintptr_t entrypoint)
-{
-	/*
-	 * Check if the non secure entrypoint lies within the non
-	 * secure DRAM.
-	 */
-	if ((entrypoint >= NS_DRAM0_BASE) &&
-	    (entrypoint < (NS_DRAM0_BASE + NS_DRAM0_SIZE)))
-		return PSCI_E_SUCCESS;
-	return PSCI_E_INVALID_ADDRESS;
-}
-
 /*******************************************************************************
  * Platform handler called when a CPU is about to enter standby.
  ******************************************************************************/
@@ -241,7 +225,6 @@ static const plat_psci_ops_t plat_qemu_psci_pm_ops = {
 	.system_off = qemu_system_off,
 	.system_reset = qemu_system_reset,
 	.validate_power_state = qemu_validate_power_state,
-	.validate_ns_entrypoint = qemu_validate_ns_entrypoint
 };
 
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
diff --git a/plat/qemu/common/qemu_realm_attest_key.c b/plat/qemu/common/qemu_realm_attest_key.c
new file mode 100644
index 00000000..7da04d15
--- /dev/null
+++ b/plat/qemu/common/qemu_realm_attest_key.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <plat/common/platform.h>
+
+static const uint8_t sample_delegated_key[] = {
+	0x20, 0x11, 0xC7, 0xF0, 0x3C, 0xEE, 0x43, 0x25, 0x17, 0x6E,
+	0x52, 0x4F, 0x03, 0x3C, 0x0C, 0xE1, 0xE2, 0x1A, 0x76, 0xE6,
+	0xC1, 0xA4, 0xF0, 0xB8, 0x39, 0xAA, 0x1D, 0xF6, 0x1E, 0x0E,
+	0x8A, 0x5C, 0x8A, 0x05, 0x74, 0x0F, 0x9B, 0x69, 0xEF, 0xA7,
+	0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
+};
+
+/*
+ * Get the hardcoded delegated realm attestation key as QEMU
+ * does not support RSE.
+ */
+int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
+				       unsigned int type)
+{
+	if (*len < sizeof(sample_delegated_key)) {
+		return -EINVAL;
+	}
+
+	(void)memcpy((void *)buf, (const void *)sample_delegated_key,
+		     sizeof(sample_delegated_key));
+	*len = sizeof(sample_delegated_key);
+
+	return 0;
+}
diff --git a/plat/qemu/common/trp/qemu_trp_setup.c b/plat/qemu/common/trp/qemu_trp_setup.c
new file mode 100644
index 00000000..0b914ee0
--- /dev/null
+++ b/plat/qemu/common/trp/qemu_trp_setup.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <platform_def.h>
+#include <services/rmm_core_manifest.h>
+#include <services/rmmd_svc.h>
+#include <services/trp/platform_trp.h>
+#include <trp_helpers.h>
+
+#include "../qemu_private.h"
+
+/*******************************************************************************
+ * Received from boot manifest and populated here
+ ******************************************************************************/
+extern uint32_t trp_boot_manifest_version;
+
+static int qemu_trp_process_manifest(struct rmm_manifest *manifest)
+{
+	/* padding field on the manifest must be RES0 */
+	assert(manifest->padding == 0U);
+
+	/* Verify the Boot Manifest Version. Only the Major is considered */
+	if (RMMD_MANIFEST_VERSION_MAJOR !=
+		RMMD_GET_MANIFEST_VERSION_MAJOR(manifest->version)) {
+		return E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED;
+	}
+
+	trp_boot_manifest_version = manifest->version;
+	flush_dcache_range((uintptr_t)manifest, sizeof(struct rmm_manifest));
+
+	return 0;
+}
+
+void trp_early_platform_setup(struct rmm_manifest *manifest)
+{
+	int rc;
+
+	rc = qemu_trp_process_manifest(manifest);
+	if (rc != 0) {
+		trp_boot_abort(rc);
+	}
+
+	qemu_console_init();
+}
diff --git a/plat/qemu/common/trp/trp-qemu-common.mk b/plat/qemu/common/trp/trp-qemu-common.mk
new file mode 100644
index 00000000..081ba558
--- /dev/null
+++ b/plat/qemu/common/trp/trp-qemu-common.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# TRP source files common to QEMU platforms
+RMM_SOURCES		+=	plat/qemu/common/trp/qemu_trp_setup.c	\
+				plat/common/aarch64/platform_mp_stack.S	\
+				plat/qemu/common/aarch64/plat_helpers.S
+
+INCLUDES		+=	-Iinclude/services/trp
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index 903c809d..0c85b1ed 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -150,7 +150,7 @@
  * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the
  * current BL3-1 debug size plus a little space for growth.
  */
-#define BL31_BASE			(BL31_LIMIT - 0x60000)
+#define BL31_BASE			(BL31_LIMIT - 0x70000)
 #define BL31_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE - FW_HANDOFF_SIZE)
 #define BL31_PROGBITS_LIMIT		BL1_RW_BASE
 
@@ -171,7 +171,8 @@
 #define BL32_SRAM_BASE			BL_RAM_BASE
 #define BL32_SRAM_LIMIT			BL31_BASE
 #define BL32_DRAM_BASE			SEC_DRAM_BASE
-#define BL32_DRAM_LIMIT			(SEC_DRAM_BASE + SEC_DRAM_SIZE)
+#define BL32_DRAM_LIMIT			(SEC_DRAM_BASE + SEC_DRAM_SIZE - \
+					 RME_GPT_DRAM_SIZE)
 
 #define SEC_SRAM_ID			0
 #define SEC_DRAM_ID			1
@@ -183,7 +184,7 @@
 # define BL32_LIMIT			(BL32_SRAM_LIMIT - FW_HANDOFF_SIZE)
 #elif BL32_RAM_LOCATION_ID == SEC_DRAM_ID
 # define BL32_MEM_BASE			SEC_DRAM_BASE
-# define BL32_MEM_SIZE			SEC_DRAM_SIZE
+# define BL32_MEM_SIZE			(SEC_DRAM_SIZE - RME_GPT_DRAM_SIZE)
 # define BL32_BASE			BL32_DRAM_BASE
 # define BL32_LIMIT			(BL32_DRAM_LIMIT - FW_HANDOFF_SIZE)
 #else
@@ -199,7 +200,7 @@
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#define MAX_MMAP_REGIONS		(11 + MAX_MMAP_REGIONS_SPMC)
+#define MAX_MMAP_REGIONS		(13 + MAX_MMAP_REGIONS_SPMC)
 #define MAX_XLAT_TABLES			(6 + MAX_XLAT_TABLES_SPMC)
 #define MAX_IO_DEVICES			4
 #define MAX_IO_HANDLES			4
@@ -226,7 +227,7 @@
 #define QEMU_FLASH1_SIZE		0x04000000
 
 #define PLAT_QEMU_FIP_BASE		0x00040000
-#define PLAT_QEMU_FIP_MAX_SIZE		0x00400000
+#define PLAT_QEMU_FIP_MAX_SIZE		(QEMU_FLASH0_SIZE - PLAT_QEMU_FIP_BASE)
 
 #define DEVICE0_BASE			0x08000000
 #define DEVICE0_SIZE			0x01000000
@@ -300,11 +301,6 @@
 #define PLAT_SDEI_NORMAL_PRI		0x70
 #define PLAT_SDEI_SGI_PRIVATE		QEMU_IRQ_SEC_SGI_0
 
-/*
- * System counter
- */
-#define SYS_COUNTER_FREQ_IN_TICKS	((1000 * 1000 * 1000) / 16)
-
 /*
  * Maximum size of Event Log buffer used in Measured Boot Event Log driver
  */
@@ -338,4 +334,77 @@
 #define MAX_MMAP_REGIONS_SPMC		0
 #define MAX_XLAT_TABLES_SPMC		0
 #endif
+
+#if ENABLE_RME
+
+/*
+ * Reserve some space at the end of secure DRAM for the Granule Protection
+ * Tables
+ */
+#define PLAT_QEMU_L0_GPT_BASE		(PLAT_QEMU_L1_GPT_BASE -	\
+					 (PLAT_QEMU_L0_GPT_SIZE +	\
+					  PLAT_QEMU_GPT_BITLOCK_SIZE))
+#define PLAT_QEMU_L0_GPT_SIZE		(2 * PAGE_SIZE)
+/* Two pages so the L0 GPT is naturally aligned.  */
+#define PLAT_QEMU_GPT_BITLOCK_SIZE	(2 * PAGE_SIZE)
+
+#define PLAT_QEMU_L1_GPT_BASE		(SEC_DRAM_BASE + SEC_DRAM_SIZE - \
+					 PLAT_QEMU_L1_GPT_SIZE)
+#define PLAT_QEMU_L1_GPT_END		(PLAT_QEMU_L1_GPT_BASE +	\
+					 PLAT_QEMU_L1_GPT_SIZE - 1U)
+#define PLAT_QEMU_L1_GPT_SIZE		UL(0x00100000)	/* 1MB */
+
+#define RME_GPT_DRAM_BASE		PLAT_QEMU_L0_GPT_BASE
+#define RME_GPT_DRAM_SIZE		(PLAT_QEMU_L1_GPT_SIZE +	\
+					 PLAT_QEMU_L0_GPT_SIZE +	\
+					 PLAT_QEMU_GPT_BITLOCK_SIZE)
+
+#ifndef __ASSEMBLER__
+/* L0 table greater than 4KB must be naturally aligned */
+CASSERT((PLAT_QEMU_L0_GPT_BASE & (PLAT_QEMU_L0_GPT_SIZE - 1)) == 0,
+	assert_l0_gpt_naturally_aligned);
+#endif
+
+/* Reserved some DRAM space for RMM (24MB) */
+#define REALM_DRAM_BASE			(NS_DRAM0_BASE + PLAT_QEMU_DT_MAX_SIZE)
+#define REALM_DRAM_SIZE			0x01800000
+
+#define PLAT_QEMU_RMM_SIZE		(REALM_DRAM_SIZE - RMM_SHARED_SIZE)
+#define PLAT_QEMU_RMM_SHARED_SIZE	(PAGE_SIZE)	/* 4KB */
+
+#define RMM_BASE			(REALM_DRAM_BASE)
+#define RMM_LIMIT			(RMM_BASE + PLAT_QEMU_RMM_SIZE)
+#define RMM_SHARED_BASE			(RMM_LIMIT)
+#define RMM_SHARED_SIZE			PLAT_QEMU_RMM_SHARED_SIZE
+
+#define MAP_GPT_L0_REGION	MAP_REGION_FLAT(			\
+					PLAT_QEMU_L0_GPT_BASE,		\
+					PLAT_QEMU_L0_GPT_SIZE +		\
+					PLAT_QEMU_GPT_BITLOCK_SIZE,	\
+					MT_MEMORY | MT_RW | EL3_PAS)
+
+#define MAP_GPT_L1_REGION	MAP_REGION_FLAT(			\
+					PLAT_QEMU_L1_GPT_BASE,		\
+					PLAT_QEMU_L1_GPT_SIZE,		\
+					MT_MEMORY | MT_RW | EL3_PAS)
+/*
+ * We add the RMM_SHARED size to RMM mapping to map the region as a block.
+ * Else we end up requiring more pagetables in BL2 for ROMLIB build.
+ */
+#define MAP_RMM_DRAM		MAP_REGION_FLAT(			\
+					RMM_BASE,			\
+					(PLAT_QEMU_RMM_SIZE +		\
+					 RMM_SHARED_SIZE),		\
+					MT_MEMORY | MT_RW | MT_REALM)
+
+#define MAP_RMM_SHARED_MEM	MAP_REGION_FLAT(			\
+					RMM_SHARED_BASE,		\
+					RMM_SHARED_SIZE,		\
+					MT_MEMORY | MT_RW | MT_REALM)
+#else /* !ENABLE_RME */
+
+#define RME_GPT_DRAM_SIZE		0
+
+#endif /* ENABLE_RME */
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu/include/qemu_pas_def.h b/plat/qemu/qemu/include/qemu_pas_def.h
new file mode 100644
index 00000000..bcbea210
--- /dev/null
+++ b/plat/qemu/qemu/include/qemu_pas_def.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QEMU_PAS_DEF_H
+#define QEMU_PAS_DEF_H
+
+#include <lib/gpt_rme/gpt_rme.h>
+#include "platform_def.h"
+
+/*****************************************************************************
+ * PAS regions used to initialize the Granule Protection Table (GPT)
+ ****************************************************************************/
+
+/*
+ * The PA space is initially mapped in the GPT as follows:
+ *
+ * ===========================================================================
+ * Base Addr   | Size    |L? GPT|PAS   |Content          |Comment
+ * ===========================================================================
+ *             | 1GB     |L0 GPT|ANY   |Flash            |
+ *    00000000 |         |      |      |IO               |
+ * ---------------------------------------------------------------------------
+ *       224MB | 1KB     |L1 GPT|ANY   |Secure RAM (EL3) |
+ *    0e000000 |         |      |      |  (shared)       |
+ * ---------------------------------------------------------------------------
+ *             | 1MB-1KB |L1 GPT|ROOT  |Secure RAM (EL3) |
+ *    0e001000 |         |      |      |                 |
+ * ---------------------------------------------------------------------------
+ *       225MB | 14MB    |L1 GPT|SECURE|Secure RAM       |
+ *    0e100000 |         |      |      |  (EL2, EL1)     |
+ * ---------------------------------------------------------------------------
+ *             | 2MB     |L1 GPT|ROOT  |L0 and L1 GPTs,  |
+ *    0edfc000 |  +16KB  |      |      | bitlocks        |
+ * ---------------------------------------------------------------------------
+ *       240MB | 800MB   |L1 GPT|ANY   |IO               |
+ *    0f000000 |         |      |      |                 |
+ * ---------------------------------------------------------------------------
+ *         1GB | 1MB     |L1 GPT|NS    |DRAM             |
+ *    40000000 |         |      |      | (device tree)   |
+ * ---------------------------------------------------------------------------
+ *     1GB+1MB | 24MB    |L1 GPT|REALM |DRAM (RMM)       |
+ *    40100000 |         |      |      |                 |
+ * ---------------------------------------------------------------------------
+ *    1GB+25MB | 3GB     |L1 GPT|NS    |DRAM (kernel)    | Limit set by
+ *    41900000 |         |      |      |                 |  NS_DRAM0_SIZE
+ * ---------------------------------------------------------------------------
+ *       256GB | 512+GB  |L0 GPT|ANY   |IO               | Floating. Higher
+ * 40000000000 |         |      |      |                 |  when RAM>256GB
+ * ----------------------------------------------------------------------------
+ */
+
+/* EL3 SRAM */
+#define QEMU_PAS_ROOT_BASE		BL_RAM_BASE
+#define QEMU_PAS_ROOT_SIZE		BL_RAM_SIZE
+
+/* Secure DRAM */
+#define QEMU_PAS_SEC_BASE		SEC_DRAM_BASE
+#define QEMU_PAS_SEC_SIZE		(SEC_DRAM_SIZE - RME_GPT_DRAM_SIZE)
+
+/* GPTs */
+#define QEMU_PAS_GPT_BASE		RME_GPT_DRAM_BASE
+#define QEMU_PAS_GPT_SIZE		RME_GPT_DRAM_SIZE
+
+/* RMM */
+#define QEMU_PAS_RMM_BASE		RMM_BASE
+#define QEMU_PAS_RMM_SIZE		PLAT_QEMU_RMM_SIZE
+
+/* Shared area between EL3 and RMM */
+#define QEMU_PAS_RMM_SHARED_BASE	RMM_SHARED_BASE
+#define QEMU_PAS_RMM_SHARED_SIZE	RMM_SHARED_SIZE
+
+#define QEMU_PAS_NS0_BASE		NS_DRAM0_BASE
+#define QEMU_PAS_NS0_SIZE		PLAT_QEMU_DT_MAX_SIZE
+#define QEMU_PAS_NS1_BASE		(REALM_DRAM_BASE + REALM_DRAM_SIZE)
+#define QEMU_PAS_NS1_SIZE		(NS_DRAM0_SIZE - \
+					 (QEMU_PAS_NS0_SIZE + REALM_DRAM_SIZE))
+
+#define QEMU_PAS_ROOT			GPT_MAP_REGION_GRANULE(QEMU_PAS_ROOT_BASE, \
+							       QEMU_PAS_ROOT_SIZE, \
+							       GPT_GPI_ROOT)
+
+#define QEMU_PAS_SECURE			GPT_MAP_REGION_GRANULE(QEMU_PAS_SEC_BASE, \
+							       QEMU_PAS_SEC_SIZE, \
+							       GPT_GPI_SECURE)
+
+#define QEMU_PAS_GPTS			GPT_MAP_REGION_GRANULE(QEMU_PAS_GPT_BASE, \
+							       QEMU_PAS_GPT_SIZE, \
+							       GPT_GPI_ROOT)
+
+#define QEMU_PAS_NS0			GPT_MAP_REGION_GRANULE(QEMU_PAS_NS0_BASE, \
+							       QEMU_PAS_NS0_SIZE, \
+							       GPT_GPI_NS)
+
+#define QEMU_PAS_NS1			GPT_MAP_REGION_GRANULE(QEMU_PAS_NS1_BASE, \
+							       QEMU_PAS_NS1_SIZE, \
+							       GPT_GPI_NS)
+
+#define QEMU_PAS_REALM			GPT_MAP_REGION_GRANULE(QEMU_PAS_RMM_BASE, \
+							       QEMU_PAS_RMM_SIZE + \
+							       QEMU_PAS_RMM_SHARED_SIZE, \
+							       GPT_GPI_REALM)
+
+/* GPT Configuration options */
+#define PLATFORM_L0GPTSZ		GPCCR_L0GPTSZ_30BITS
+
+#endif /* QEMU_PAS_DEF_H */
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index e902c121..0d4cdb8f 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -78,13 +78,13 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
 
     certificates: $(ROT_KEY)
 
-    $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+    $(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-    $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+    $(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
 
@@ -96,10 +96,6 @@ ifeq (${MEASURED_BOOT},1)
     $(info Including ${MEASURED_BOOT_MK})
     include ${MEASURED_BOOT_MK}
 
-    ifneq (${MBOOT_EL_HASH_ALG}, sha256)
-        $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512))
-    endif
-
     BL2_SOURCES		+=	plat/qemu/qemu/qemu_measured_boot.c	\
 				plat/qemu/qemu/qemu_helpers.c		\
 				${EVENT_LOG_SOURCES}
@@ -204,6 +200,10 @@ endif
 BL32_RAM_LOCATION	:=	tdram
 ifeq (${BL32_RAM_LOCATION}, tsram)
   BL32_RAM_LOCATION_ID = SEC_SRAM_ID
+  ifeq (${ENABLE_RME},1)
+	# Avoid overlap between BL2 and BL32 to ease GPT partition
+	$(error "With RME, BL32 must use secure DRAM")
+  endif
 else ifeq (${BL32_RAM_LOCATION}, tdram)
   BL32_RAM_LOCATION_ID = SEC_DRAM_ID
 else
@@ -222,14 +222,14 @@ ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE
 $(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
 
 qemu_fw.bios: bl1 fip
-	$(ECHO) "  DD      $@"
-	$(Q)cp ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/$@
-	$(Q)dd if=${BUILD_PLAT}/fip.bin of=${BUILD_PLAT}/$@ bs=64k seek=4 status=none
+	$(s)echo "  DD      $@"
+	$(q)cp ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/$@
+	$(q)dd if=${BUILD_PLAT}/fip.bin of=${BUILD_PLAT}/$@ bs=64k seek=4 status=none
 
 qemu_fw.rom: qemu_fw.bios
-	$(ECHO) "  DD      $@"
-	$(Q)cp ${BUILD_PLAT}/$^ ${BUILD_PLAT}/$@
-	$(Q)dd if=/dev/zero of=${BUILD_PLAT}/$@ bs=1M seek=64 count=0 status=none
+	$(s)echo "  DD      $@"
+	$(q)cp ${BUILD_PLAT}/$^ ${BUILD_PLAT}/$@
+	$(q)dd if=/dev/zero of=${BUILD_PLAT}/$@ bs=1M seek=64 count=0 status=none
 
 ifneq (${BL33},)
 all: qemu_fw.bios qemu_fw.rom
diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c
index 077f7a48..76a4da17 100644
--- a/plat/qemu/qemu/qemu_measured_boot.c
+++ b/plat/qemu/qemu/qemu_measured_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  * Copyright (c) 2022-2023, Linaro.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <drivers/measured_boot/event_log/event_log.h>
+#include <drivers/measured_boot/metadata.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <tools_share/tbbr_oid.h>
@@ -20,16 +21,16 @@ static uint64_t event_log_base;
 
 /* QEMU table with platform specific image IDs, names and PCRs */
 static const event_log_metadata_t qemu_event_log_metadata[] = {
-	{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
-	{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
-	{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
-	{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
-	{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
-	{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
-	{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
-	{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
-	{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
-	{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
+	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
+	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
+	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
+	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
+	{ HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
+	{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
+	{ SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
+	{ SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
+	{ TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
 
 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
 };
diff --git a/plat/qemu/qemu/trp/trp-qemu.mk b/plat/qemu/qemu/trp/trp-qemu.mk
new file mode 100644
index 00000000..e0f530ef
--- /dev/null
+++ b/plat/qemu/qemu/trp/trp-qemu.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/qemu/common/trp/trp-qemu-common.mk
+
diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h
index 14030e35..d2300954 100644
--- a/plat/qemu/qemu_sbsa/include/platform_def.h
+++ b/plat/qemu/qemu_sbsa/include/platform_def.h
@@ -61,6 +61,11 @@
 #define CACHE_WRITEBACK_SHIFT		6
 #define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
 
+/*
+ * Define the max number of memory nodes.
+ */
+#define PLAT_MAX_MEM_NODES	128
+
 /*
  * Partition memory into secure ROM, non-secure DRAM, secure "SRAM",
  * and secure DRAM.
@@ -261,11 +266,6 @@
 #define PLAT_QEMU_DT_BASE		NS_DRAM0_BASE
 #define PLAT_QEMU_DT_MAX_SIZE		0x100000
 
-/*
- * System counter
- */
-#define SYS_COUNTER_FREQ_IN_TICKS	((1000 * 1000 * 1000) / 16)
-
 #if SPM_MM
 #define PLAT_QEMU_SP_IMAGE_BASE		BL_RAM_BASE
 #define PLAT_QEMU_SP_IMAGE_SIZE		ULL(0x300000)
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
index 05ebec47..83e66f3a 100644
--- a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
+++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c
@@ -28,13 +28,233 @@ static int platform_version_minor;
 #define SIP_SVC_VERSION  SIP_FUNCTION_ID(1)
 #define SIP_SVC_GET_GIC  SIP_FUNCTION_ID(100)
 #define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101)
+#define SIP_SVC_GET_CPU_COUNT SIP_FUNCTION_ID(200)
+#define SIP_SVC_GET_CPU_NODE SIP_FUNCTION_ID(201)
+#define SIP_SVC_GET_CPU_TOPOLOGY SIP_FUNCTION_ID(202)
+#define SIP_SVC_GET_MEMORY_NODE_COUNT SIP_FUNCTION_ID(300)
+#define SIP_SVC_GET_MEMORY_NODE SIP_FUNCTION_ID(301)
 
 static uint64_t gic_its_addr;
 
+typedef struct {
+	uint32_t nodeid;
+	uint32_t mpidr;
+} cpu_data;
+
+typedef struct{
+	uint32_t nodeid;
+	uint64_t addr_base;
+	uint64_t addr_size;
+} memory_data;
+
+/*
+ * sockets: the number of sockets on sbsa-ref platform.
+ * clusters: the number of clusters in one socket.
+ * cores: the number of cores in one cluster.
+ * threads: the number of threads in one core.
+ */
+typedef struct {
+	uint32_t sockets;
+	uint32_t clusters;
+	uint32_t cores;
+	uint32_t threads;
+} cpu_topology;
+
+static struct {
+	uint32_t num_cpus;
+	uint32_t num_memnodes;
+	cpu_data cpu[PLATFORM_CORE_COUNT];
+	cpu_topology cpu_topo;
+	memory_data memory[PLAT_MAX_MEM_NODES];
+} dynamic_platform_info;
+
 void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base);
 uintptr_t sbsa_get_gicd(void);
 uintptr_t sbsa_get_gicr(void);
 
+/*
+ * QEMU provides us with minimal information about hardware platform using
+ * minimalistic DeviceTree. This is not a Linux DeviceTree. It is not even
+ * a firmware DeviceTree.
+ *
+ * It is information passed from QEMU to describe the information a hardware
+ * platform would have other mechanisms to discover at runtime, that are
+ * affected by the QEMU command line.
+ *
+ * Ultimately this device tree will be replaced by IPC calls to an emulated SCP.
+ * And when we do that, we won't then have to rewrite Normal world firmware to
+ * cope.
+ */
+
+static void read_cpu_topology_from_dt(void *dtb)
+{
+	int node;
+
+	/*
+	 * QEMU gives us this DeviceTree node when we config:
+	 * -smp 16,sockets=2,clusters=2,cores=2,threads=2
+	 *
+	 * topology {
+	 *	threads = <0x02>;
+	 *	cores = <0x02>;
+	 *	clusters = <0x02>;
+	 *	sockets = <0x02>;
+	 * };
+	 */
+
+	node = fdt_path_offset(dtb, "/cpus/topology");
+	if (node > 0) {
+		dynamic_platform_info.cpu_topo.sockets =
+			fdt_read_uint32_default(dtb, node, "sockets", 0);
+		dynamic_platform_info.cpu_topo.clusters =
+			fdt_read_uint32_default(dtb, node, "clusters", 0);
+		dynamic_platform_info.cpu_topo.cores =
+			fdt_read_uint32_default(dtb, node, "cores", 0);
+		dynamic_platform_info.cpu_topo.threads =
+			fdt_read_uint32_default(dtb, node, "threads", 0);
+	}
+
+	INFO("Cpu topology: sockets: %d, clusters: %d, cores: %d, threads: %d\n",
+		dynamic_platform_info.cpu_topo.sockets,
+		dynamic_platform_info.cpu_topo.clusters,
+		dynamic_platform_info.cpu_topo.cores,
+		dynamic_platform_info.cpu_topo.threads);
+}
+
+void read_cpuinfo_from_dt(void *dtb)
+{
+	int node;
+	int prev;
+	int cpu = 0;
+	uintptr_t mpidr;
+
+	/*
+	 * QEMU gives us this DeviceTree node:
+	 * numa-node-id entries are only when NUMA config is used
+	 *
+	 *  cpus {
+	 *  	#size-cells = <0x00>;
+	 *  	#address-cells = <0x02>;
+	 *
+	 *  	cpu@0 {
+	 *  	        numa-node-id = <0x00>;
+	 *  		reg = <0x00 0x00>;
+	 *  	};
+	 *
+	 *  	cpu@1 {
+	 *  	        numa-node-id = <0x03>;
+	 *  		reg = <0x00 0x01>;
+	 *  	};
+	 *  };
+	 */
+	node = fdt_path_offset(dtb, "/cpus");
+	if (node < 0) {
+		ERROR("No information about cpus in DeviceTree.\n");
+		panic();
+	}
+
+	/*
+	 * QEMU numbers cpus from 0 and there can be /cpus/cpu-map present so we
+	 * cannot use fdt_first_subnode() here
+	 */
+	node = fdt_path_offset(dtb, "/cpus/cpu@0");
+
+	while (node > 0) {
+		if (fdt_getprop(dtb, node, "reg", NULL)) {
+			fdt_get_reg_props_by_index(dtb, node, 0, &mpidr, NULL);
+		} else {
+			ERROR("Incomplete information for cpu %d in DeviceTree.\n", cpu);
+			panic();
+		}
+
+		dynamic_platform_info.cpu[cpu].mpidr = mpidr;
+		dynamic_platform_info.cpu[cpu].nodeid =
+			fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
+
+		INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpu,
+				dynamic_platform_info.cpu[cpu].nodeid, mpidr);
+
+		cpu++;
+
+		prev = node;
+		node = fdt_next_subnode(dtb, prev);
+	}
+
+	dynamic_platform_info.num_cpus = cpu;
+	INFO("Found %d cpus\n", dynamic_platform_info.num_cpus);
+
+	read_cpu_topology_from_dt(dtb);
+}
+
+void read_meminfo_from_dt(void *dtb)
+{
+	const fdt32_t *prop;
+	const char *type;
+	int prev, node;
+	int len;
+	uint32_t memnode = 0;
+	uint32_t higher_value, lower_value;
+	uint64_t cur_base, cur_size;
+
+	/*
+	 * QEMU gives us this DeviceTree node:
+	 *
+	 *	memory@100c0000000 {
+	 *		numa-node-id = <0x01>;
+	 *		reg = <0x100 0xc0000000 0x00 0x40000000>;
+	 *		device_type = "memory";
+	 *	};
+	 *
+	 *	memory@10000000000 {
+	 *		numa-node-id = <0x00>;
+	 *		reg = <0x100 0x00 0x00 0xc0000000>;
+	 *		device_type = "memory";
+	 *	}
+	 */
+
+	for (prev = 0;; prev = node) {
+		node = fdt_next_node(dtb, prev, NULL);
+		if (node < 0) {
+			break;
+		}
+
+		type = fdt_getprop(dtb, node, "device_type", &len);
+		if (type && strncmp(type, "memory", len) == 0) {
+			dynamic_platform_info.memory[memnode].nodeid =
+				fdt_read_uint32_default(dtb, node, "numa-node-id", 0);
+
+			/*
+			 * Get the 'reg' property of this node and
+			 * assume two 8 bytes for base and size.
+			 */
+			prop = fdt_getprop(dtb, node, "reg", &len);
+			if (prop != 0 && len == (2 * sizeof(int64_t))) {
+				higher_value = fdt32_to_cpu(*prop);
+				lower_value = fdt32_to_cpu(*(prop + 1));
+				cur_base = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
+
+				higher_value = fdt32_to_cpu(*(prop + 2));
+				lower_value = fdt32_to_cpu(*(prop + 3));
+				cur_size = (uint64_t)(lower_value | ((uint64_t)higher_value) << 32);
+
+				dynamic_platform_info.memory[memnode].addr_base = cur_base;
+				dynamic_platform_info.memory[memnode].addr_size = cur_size;
+
+				INFO("RAM %d: node-id: %d, address: 0x%lx - 0x%lx\n",
+					memnode,
+					dynamic_platform_info.memory[memnode].nodeid,
+					dynamic_platform_info.memory[memnode].addr_base,
+					dynamic_platform_info.memory[memnode].addr_base +
+					dynamic_platform_info.memory[memnode].addr_size - 1);
+			}
+
+			memnode++;
+		}
+	}
+
+	dynamic_platform_info.num_memnodes = memnode;
+}
+
 void read_platform_config_from_dt(void *dtb)
 {
 	int node;
@@ -99,10 +319,10 @@ void read_platform_version(void *dtb)
 
 	node = fdt_path_offset(dtb, "/");
 	if (node >= 0) {
-		platform_version_major = fdt32_ld(fdt_getprop(dtb, node,
-							      "machine-version-major", NULL));
-		platform_version_minor = fdt32_ld(fdt_getprop(dtb, node,
-							      "machine-version-minor", NULL));
+		platform_version_major =
+			fdt_read_uint32_default(dtb, node, "machine-version-major", 0);
+		platform_version_minor =
+			fdt_read_uint32_default(dtb, node, "machine-version-minor", 0);
 	}
 }
 
@@ -129,6 +349,8 @@ void sip_svc_init(void)
 	INFO("Platform version: %d.%d\n", platform_version_major, platform_version_minor);
 
 	read_platform_config_from_dt(dtb);
+	read_cpuinfo_from_dt(dtb);
+	read_meminfo_from_dt(dtb);
 }
 
 /*
@@ -144,6 +366,7 @@ uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid,
 			       u_register_t flags)
 {
 	uint32_t ns;
+	uint64_t index;
 
 	/* Determine which security state this SMC originated from */
 	ns = is_caller_non_secure(flags);
@@ -163,6 +386,45 @@ uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid,
 	case SIP_SVC_GET_GIC_ITS:
 		SMC_RET2(handle, NULL, gic_its_addr);
 
+	case SIP_SVC_GET_CPU_COUNT:
+		SMC_RET2(handle, NULL, dynamic_platform_info.num_cpus);
+
+	case SIP_SVC_GET_CPU_NODE:
+		index = x1;
+		if (index < PLATFORM_CORE_COUNT) {
+			SMC_RET3(handle, NULL,
+				dynamic_platform_info.cpu[index].nodeid,
+				dynamic_platform_info.cpu[index].mpidr);
+		} else {
+			SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
+		}
+
+	case SIP_SVC_GET_CPU_TOPOLOGY:
+		if (dynamic_platform_info.cpu_topo.cores > 0) {
+			SMC_RET5(handle, NULL,
+			dynamic_platform_info.cpu_topo.sockets,
+			dynamic_platform_info.cpu_topo.clusters,
+			dynamic_platform_info.cpu_topo.cores,
+			dynamic_platform_info.cpu_topo.threads);
+		} else {
+			/* we do not know topology so we report SMC as unknown */
+			SMC_RET1(handle, SMC_UNK);
+		}
+
+	case SIP_SVC_GET_MEMORY_NODE_COUNT:
+		SMC_RET2(handle, NULL, dynamic_platform_info.num_memnodes);
+
+	case SIP_SVC_GET_MEMORY_NODE:
+		index = x1;
+		if (index < PLAT_MAX_MEM_NODES) {
+			SMC_RET4(handle, NULL,
+				dynamic_platform_info.memory[index].nodeid,
+				dynamic_platform_info.memory[index].addr_base,
+				dynamic_platform_info.memory[index].addr_size);
+		} else {
+			SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
+		}
+
 	default:
 		ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid,
 		      smc_fid - SIP_FUNCTION);
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_gold.S b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
index 9bcdf542..49b7cf01 100644
--- a/plat/qti/common/src/aarch64/qti_kryo4_gold.S
+++ b/plat/qti/common/src/aarch64/qti_kryo4_gold.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -41,16 +41,6 @@ func qti_kryo4_gold_cluster_pwr_dwn
 	ret
 endfunc qti_kryo4_gold_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Kryo4 Gold. Must follow AAPCS.
- */
-func qti_kryo4_gold_errata_report
-	/* TODO : Need to add support. Required only for debug bl31 image.*/
-	ret
-endfunc qti_kryo4_gold_errata_report
-#endif
-
 /* ---------------------------------------------
  * This function provides kryo4_gold specific
  * register information for crash reporting.
diff --git a/plat/qti/common/src/aarch64/qti_kryo4_silver.S b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
index 36374b73..4a98912d 100644
--- a/plat/qti/common/src/aarch64/qti_kryo4_silver.S
+++ b/plat/qti/common/src/aarch64/qti_kryo4_silver.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -35,17 +35,6 @@ func qti_kryo4_silver_cluster_pwr_dwn
 	ret
 endfunc qti_kryo4_silver_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Kryo4 Silver. Must follow AAPCS.
- */
-func qti_kryo4_silver_errata_report
-	/* TODO : Need to add support. Required only for debug bl31 image.*/
-	ret
-endfunc qti_kryo4_silver_errata_report
-#endif
-
-
 /* ---------------------------------------------
  * This function provides kryo4_silver specific
  * register information for crash reporting.
diff --git a/plat/qti/common/src/aarch64/qti_kryo6_gold.S b/plat/qti/common/src/aarch64/qti_kryo6_gold.S
index 577e7ff6..5f9463f6 100644
--- a/plat/qti/common/src/aarch64/qti_kryo6_gold.S
+++ b/plat/qti/common/src/aarch64/qti_kryo6_gold.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -41,16 +41,6 @@ func qti_kryo6_gold_cluster_pwr_dwn
 	ret
 endfunc qti_kryo6_gold_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Kryo4 Gold. Must follow AAPCS.
- */
-func qti_kryo6_gold_errata_report
-	/* TODO : Need to add support. Required only for debug bl31 image.*/
-	ret
-endfunc qti_kryo6_gold_errata_report
-#endif
-
 /* ---------------------------------------------
  * This function provides kryo4_gold specific
  * register information for crash reporting.
diff --git a/plat/qti/common/src/aarch64/qti_kryo6_silver.S b/plat/qti/common/src/aarch64/qti_kryo6_silver.S
index 6ad0bcae..4a54a64c 100644
--- a/plat/qti/common/src/aarch64/qti_kryo6_silver.S
+++ b/plat/qti/common/src/aarch64/qti_kryo6_silver.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -35,17 +35,6 @@ func qti_kryo6_silver_cluster_pwr_dwn
 	ret
 endfunc qti_kryo6_silver_cluster_pwr_dwn
 
-#if REPORT_ERRATA
-/*
- * Errata printing function for Kryo4 Silver. Must follow AAPCS.
- */
-func qti_kryo6_silver_errata_report
-	/* TODO : Need to add support. Required only for debug bl31 image.*/
-	ret
-endfunc qti_kryo6_silver_errata_report
-#endif
-
-
 /* ---------------------------------------------
  * This function provides kryo4_silver specific
  * register information for crash reporting.
diff --git a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
index c4cd2597..804ad42f 100644
--- a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
+++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c
@@ -142,10 +142,10 @@ void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *qti_ns_ctx)
 	qti_ns_ctx->elr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_ELR_EL3);
 
 	qti_ns_ctx->spsr_el1 =
-	    read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SPSR_EL1);
+	    read_el1_ctx_common(get_el1_sysregs_ctx(ctx), spsr_el1);
 	qti_ns_ctx->elr_el1 =
-	    read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_ELR_EL1);
-	qti_ns_ctx->sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SP_EL1);
+	    read_el1_ctx_common(get_el1_sysregs_ctx(ctx), elr_el1);
+	qti_ns_ctx->sp_el1 = read_el1_ctx_common(get_el1_sysregs_ctx(ctx), sp_el1);
 
 	qti_ns_ctx->x0 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0);
 	qti_ns_ctx->x1 = read_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1);
diff --git a/plat/renesas/common/aarch64/plat_helpers.S b/plat/renesas/common/aarch64/plat_helpers.S
index a7fdfa07..572620db 100644
--- a/plat/renesas/common/aarch64/plat_helpers.S
+++ b/plat/renesas/common/aarch64/plat_helpers.S
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -172,15 +172,16 @@ func bl2_enter_bl31
          * BL31 will initialize the address space according to its
          * own requirement.
          */
-#if RCAR_BL2_DCACHE == 1
 	/* Disable mmu and data cache */
 	bl	disable_mmu_el3
+#if RCAR_BL2_DCACHE == 1
 	/* Data cache clean and invalidate */
 	mov	x0, #DCCISW
 	bl	dcsw_op_all
+#endif /* RCAR_BL2_DCACHE == 1 */
 	/* TLB invalidate all, EL3 */
 	tlbi	alle3
-#endif /* RCAR_BL2_DCACHE == 1 */
+
 	bl	disable_mmu_icache_el3
 	/* Invalidate instruction cache */
 	ic	iallu
diff --git a/plat/renesas/common/aarch64/platform_common.c b/plat/renesas/common/aarch64/platform_common.c
index 17ccb282..9e7d5260 100644
--- a/plat/renesas/common/aarch64/platform_common.c
+++ b/plat/renesas/common/aarch64/platform_common.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,13 +30,19 @@ extern int32_t rcar_get_certificate(const int32_t name, uint32_t *cert);
 const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]
 		__attribute__ ((__section__(".ro"))) = VERSION_OF_RENESAS;
 
+#if (IMAGE_BL2) && (RCAR_BL2_DCACHE != 1)
+#define RCAR_DCACHE MT_NON_CACHEABLE
+#else
+#define RCAR_DCACHE MT_MEMORY
+#endif
+
 #define MAP_SHARED_RAM		MAP_REGION_FLAT(RCAR_SHARED_MEM_BASE,	\
 					RCAR_SHARED_MEM_SIZE,		\
 					MT_MEMORY | MT_RW | MT_SECURE)
 
 #define MAP_FLASH0		MAP_REGION_FLAT(FLASH0_BASE,		\
 					FLASH0_SIZE,			\
-					MT_MEMORY | MT_RO | MT_SECURE)
+					RCAR_DCACHE | MT_RO | MT_SECURE)
 
 #define MAP_DRAM1_NS		MAP_REGION_FLAT(DRAM1_NS_BASE,		\
 					DRAM1_NS_SIZE,			\
@@ -68,7 +74,7 @@ const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]
 #if IMAGE_BL2
 #define MAP_DRAM0		MAP_REGION_FLAT(DRAM1_BASE,		\
 					DRAM1_SIZE,			\
-					MT_MEMORY | MT_RW | MT_SECURE)
+					RCAR_DCACHE | MT_RW | MT_SECURE)
 
 #define MAP_REG0		MAP_REGION_FLAT(DEVICE_RCAR_BASE,	\
 					DEVICE_RCAR_SIZE,		\
@@ -76,7 +82,7 @@ const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]
 
 #define MAP_RAM0		MAP_REGION_FLAT(RCAR_SYSRAM_BASE,	\
 					RCAR_SYSRAM_SIZE,		\
-					MT_MEMORY | MT_RW | MT_SECURE)
+					RCAR_DCACHE | MT_RW | MT_SECURE)
 
 #define MAP_REG1		MAP_REGION_FLAT(REG1_BASE,		\
 					REG1_SIZE,			\
@@ -84,7 +90,7 @@ const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]
 
 #define MAP_ROM			MAP_REGION_FLAT(ROM0_BASE,		\
 					ROM0_SIZE,			\
-					MT_MEMORY | MT_RO | MT_SECURE)
+					RCAR_DCACHE | MT_RO | MT_SECURE)
 
 #define MAP_REG2		MAP_REGION_FLAT(REG2_BASE,		\
 					REG2_SIZE,			\
@@ -92,7 +98,7 @@ const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN]
 
 #define MAP_DRAM1		MAP_REGION_FLAT(DRAM_40BIT_BASE,	\
 					DRAM_40BIT_SIZE,		\
-					MT_MEMORY | MT_RW | MT_SECURE)
+					RCAR_DCACHE | MT_RW | MT_SECURE)
 #endif
 
 #ifdef BL32_BASE
@@ -152,9 +158,9 @@ void rcar_configure_mmu_el3(unsigned long total_base,
 			    unsigned long coh_limit)
 {
 	mmap_add_region(total_base, total_base, total_size,
-			MT_MEMORY | MT_RW | MT_SECURE);
+			RCAR_DCACHE | MT_RW | MT_SECURE);
 	mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
-			MT_MEMORY | MT_RO | MT_SECURE);
+			RCAR_DCACHE | MT_RO | MT_SECURE);
 	mmap_add_region(coh_start, coh_start, coh_limit - coh_start,
 			MT_DEVICE | MT_RW | MT_SECURE);
 	mmap_add(rcar_mmap);
@@ -169,9 +175,9 @@ void rcar_configure_mmu_el3(unsigned long total_base,
 			    unsigned long ro_limit)
 {
 	mmap_add_region(total_base, total_base, total_size,
-			MT_MEMORY | MT_RW | MT_SECURE);
+			RCAR_DCACHE | MT_RW | MT_SECURE);
 	mmap_add_region(ro_start, ro_start, ro_limit - ro_start,
-			MT_MEMORY | MT_RO | MT_SECURE);
+			RCAR_DCACHE | MT_RO | MT_SECURE);
 	mmap_add(rcar_mmap);
 
 	init_xlat_tables();
diff --git a/plat/renesas/common/bl2_secure_setting.c b/plat/renesas/common/bl2_secure_setting.c
index 2f8b0011..297b1a9e 100644
--- a/plat/renesas/common/bl2_secure_setting.c
+++ b/plat/renesas/common/bl2_secure_setting.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -107,8 +107,10 @@ static const struct {
 	/*
 	 * Security group 0 attribute setting for master ports 3
 	 * Security group 1 attribute setting for master ports 3
-	 *	{SEC_GRP0CR3,           0x00000000U},
-	 *	{SEC_GRP1CR3,           0x00000000U},
+	 */
+	{ SEC_GRP0CR3, 0x00003780U },
+	{ SEC_GRP1CR3, 0x00003780U },
+	/*
 	 * Security group 0 attribute setting for slave ports 0
 	 * Security group 1 attribute setting for slave ports 0
 	 *	{SEC_GRP0COND0,         0x00000000U},
@@ -259,10 +261,51 @@ static const struct {
 };
 
 /* AXI settings */
-static const struct {
+struct axi_t {
 	uint32_t reg;
 	uint32_t val;
-} axi[] = {
+};
+
+static const struct axi_t axi[] = {
+	/*
+	 * SRAM ptotection
+	 * AXI sram protected area division
+	 */
+	{AXI_SPTDIVCR0,  0x0E0E6304U},
+	{AXI_SPTDIVCR1,  0x0E0E6360U},
+	{AXI_SPTDIVCR2,  0x0E0E6360U},
+	{AXI_SPTDIVCR3,  0x0E0E6360U},
+	{AXI_SPTDIVCR4,  0x0E0E6360U},
+	{AXI_SPTDIVCR5,  0x0E0E6360U},
+	{AXI_SPTDIVCR6,  0x0E0E6360U},
+	{AXI_SPTDIVCR7,  0x0E0E6360U},
+	{AXI_SPTDIVCR8,  0x0E0E6360U},
+	{AXI_SPTDIVCR9,  0x0E0E6360U},
+	{AXI_SPTDIVCR10, 0x0E0E6360U},
+	{AXI_SPTDIVCR11, 0x0E0E6360U},
+	{AXI_SPTDIVCR12, 0x0E0E6360U},
+	{AXI_SPTDIVCR13, 0x0E0E6360U},
+	{AXI_SPTDIVCR14, 0x0E0E6360U},
+	/* AXI sram protected area setting */
+	{AXI_SPTCR0,  0x0E000E0EU},
+	{AXI_SPTCR1,  0x0E000000U},
+	{AXI_SPTCR2,  0x0E000000U},
+	{AXI_SPTCR3,  0x0E000000U},
+	{AXI_SPTCR4,  0x0E000000U},
+	{AXI_SPTCR5,  0x0E000000U},
+	{AXI_SPTCR6,  0x0E000000U},
+	{AXI_SPTCR7,  0x0E000000U},
+	{AXI_SPTCR8,  0x0E000000U},
+	{AXI_SPTCR9,  0x0E000000U},
+	{AXI_SPTCR10, 0x0E000000U},
+	{AXI_SPTCR11, 0x0E000000U},
+	{AXI_SPTCR12, 0x0E000000U},
+	{AXI_SPTCR13, 0x0E000000U},
+	{AXI_SPTCR14, 0x0E000000U},
+	{AXI_SPTCR15, 0x0E000000U}
+};
+
+static const struct axi_t axi_dram[] = {
 	/*
 	 * DRAM protection
 	 * AXI dram protected area division
@@ -299,41 +342,7 @@ static const struct {
 	{AXI_DPTCR13, 0x0E000000U},
 	{AXI_DPTCR14, 0x0E000000U},
 	{AXI_DPTCR15, 0x0E000000U},
-	/*
-	 * SRAM ptotection
-	 * AXI sram protected area division
-	 */
-	{AXI_SPTDIVCR0,  0x0E0E6304U},
-	{AXI_SPTDIVCR1,  0x0E0E6360U},
-	{AXI_SPTDIVCR2,  0x0E0E6360U},
-	{AXI_SPTDIVCR3,  0x0E0E6360U},
-	{AXI_SPTDIVCR4,  0x0E0E6360U},
-	{AXI_SPTDIVCR5,  0x0E0E6360U},
-	{AXI_SPTDIVCR6,  0x0E0E6360U},
-	{AXI_SPTDIVCR7,  0x0E0E6360U},
-	{AXI_SPTDIVCR8,  0x0E0E6360U},
-	{AXI_SPTDIVCR9,  0x0E0E6360U},
-	{AXI_SPTDIVCR10, 0x0E0E6360U},
-	{AXI_SPTDIVCR11, 0x0E0E6360U},
-	{AXI_SPTDIVCR12, 0x0E0E6360U},
-	{AXI_SPTDIVCR13, 0x0E0E6360U},
-	{AXI_SPTDIVCR14, 0x0E0E6360U},
 	/* AXI sram protected area setting */
-	{AXI_SPTCR0,  0x0E000E0EU},
-	{AXI_SPTCR1,  0x0E000000U},
-	{AXI_SPTCR2,  0x0E000000U},
-	{AXI_SPTCR3,  0x0E000000U},
-	{AXI_SPTCR4,  0x0E000000U},
-	{AXI_SPTCR5,  0x0E000000U},
-	{AXI_SPTCR6,  0x0E000000U},
-	{AXI_SPTCR7,  0x0E000000U},
-	{AXI_SPTCR8,  0x0E000000U},
-	{AXI_SPTCR9,  0x0E000000U},
-	{AXI_SPTCR10, 0x0E000000U},
-	{AXI_SPTCR11, 0x0E000000U},
-	{AXI_SPTCR12, 0x0E000000U},
-	{AXI_SPTCR13, 0x0E000000U},
-	{AXI_SPTCR14, 0x0E000000U},
 	{AXI_SPTCR15, 0x0E000000U}
 };
 
@@ -345,7 +354,7 @@ static void lifec_security_setting(void)
 		mmio_write_32(lifec[i].reg, lifec[i].val);
 }
 
-/* SRAM/DRAM protection setting */
+/* SRAM protection setting */
 static void axi_security_setting(void)
 {
 	uint32_t i;
@@ -354,6 +363,15 @@ static void axi_security_setting(void)
 		mmio_write_32(axi[i].reg, axi[i].val);
 }
 
+/* DRAM protection setting */
+void bl2_ram_security_setting_finish(void)
+{
+	uint32_t i;
+
+	for (i = 0; i < ARRAY_SIZE(axi_dram); i++)
+		mmio_write_32(axi_dram[i].reg, axi_dram[i].val);
+}
+
 void bl2_secure_setting(void)
 {
 	lifec_security_setting();
diff --git a/plat/renesas/common/include/platform_def.h b/plat/renesas/common/include/platform_def.h
index ab071ec0..8178f3a7 100644
--- a/plat/renesas/common/include/platform_def.h
+++ b/plat/renesas/common/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -144,7 +144,8 @@
  ******************************************************************************/
 #ifndef SPD_NONE
 #define BL32_BASE		U(0x44100000)
-#define BL32_LIMIT		(BL32_BASE + U(0x200000))
+#define BL32_SIZE		U(0x200000)
+#define BL32_LIMIT		(BL32_BASE + BL32_SIZE)
 #endif
 
 /*******************************************************************************
@@ -152,7 +153,8 @@
  ******************************************************************************/
 #define BL33_BASE		DRAM1_NS_BASE
 #define BL33_COMP_SIZE		U(0x200000)
-#define BL33_COMP_BASE		(BL33_BASE - BL33_COMP_SIZE)
+#define BL33_DECOMP_SIZE	(BL33_COMP_SIZE * 32)
+#define BL33_COMP_BASE		(BL33_BASE + BL33_DECOMP_SIZE)
 
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
diff --git a/plat/renesas/common/include/rcar_def.h b/plat/renesas/common/include/rcar_def.h
index 2cd26edb..86764442 100644
--- a/plat/renesas/common/include/rcar_def.h
+++ b/plat/renesas/common/include/rcar_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,7 +31,7 @@
 #define DRAM_LIMIT			ULL(0x0000010000000000)
 #define DRAM1_BASE			U(0x40000000)
 #define DRAM1_SIZE			U(0x80000000)
-#define DRAM1_NS_BASE			(DRAM1_BASE + U(0x10000000))
+#define DRAM1_NS_BASE			(DRAM1_BASE + U(0x08000000))
 #define DRAM1_NS_SIZE			(DRAM1_SIZE - DRAM1_NS_BASE)
 #define DRAM_40BIT_BASE			ULL(0x0400000000)
 #define DRAM_40BIT_SIZE			ULL(0x0400000000)
@@ -310,4 +310,31 @@
 #define LOSSY_FMT2			LOSSY_FMT_YUV422INTLV
 #define LOSSY_ENA_DIS2			LOSSY_DISABLE
 
+#define RCAR_CC63_BASE			0xE6600000U
+#define CC63_TRNG_ISR_REG_ADDR			0x104U
+#define CC63_TRNG_ISR_REG_EHR_VALID			BIT_32(0)
+#define CC63_TRNG_ISR_REG_AUTOCORR_ERR			BIT_32(1)
+#define CC63_TRNG_ICR_REG_ADDR			0x108U
+#define CC63_TRNG_CONFIG_REG_ADDR		0x10CU
+#define CC63_TRNG_CONFIG_REG_ROSC_MAX_LENGTH		3
+#define CC63_TRNG_VALID_REG_ADDR		0x110U
+#define CC63_TRNG_VALID_REG_EHR_NOT_READY		0x0
+#define CC63_TRNG_EHR_DATA_ADDR_0_REG_ADDR	0x114U
+#define CC63_TRNG_SOURCE_ENABLE_REG_ADDR	0x12CU
+#define CC63_TRNG_SOURCE_ENABLE_REG_SET			0x1
+#define CC63_TRNG_SOURCE_ENABLE_REG_CLR			0x0
+#define CC63_TRNG_SAMPLE_CNT1_REG_ADDR		0x130U
+#define CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT		100
+#define CC63_TRNG_DEBUG_CONTROL_REG_ADDR	0x138U
+#define CC63_TRNG_DEBUG_CONTROL_REG_VNC_BYPASS		BIT_32(1)
+#define CC63_TRNG_DEBUG_CONTROL_REG_AUTOCORR_BYPASS	BIT_32(3)
+#define CC63_TRNG_DEBUG_CONTROL_REG_80090B		\
+	(CC63_TRNG_DEBUG_CONTROL_REG_VNC_BYPASS |	\
+	 CC63_TRNG_DEBUG_CONTROL_REG_AUTOCORR_BYPASS)
+#define CC63_TRNG_SW_RESET_REG_ADDR		0x140U
+#define CC63_TRNG_SW_RESET_REG_SET			0x1
+#define CC63_TRNG_VERSION_REG_ADDR		0x1C0U
+#define CC63_TRNG_CLK_ENABLE_REG_ADDR		0x1C4U
+#define CC63_TRNG_CLK_ENABLE_REG_SET			0x1
+
 #endif /* RCAR_DEF_H */
diff --git a/plat/renesas/common/include/rcar_version.h b/plat/renesas/common/include/rcar_version.h
index 5a0ca31c..777ec6aa 100644
--- a/plat/renesas/common/include/rcar_version.h
+++ b/plat/renesas/common/include/rcar_version.h
@@ -9,7 +9,7 @@
 
 #include <arch_helpers.h>
 
-#define VERSION_OF_RENESAS		"3.0.3"
+#define VERSION_OF_RENESAS		"4.0.0"
 #define VERSION_OF_RENESAS_MAXLEN	128
 
 extern const uint8_t version_of_renesas[VERSION_OF_RENESAS_MAXLEN];
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 81ee93e5..c5482403 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2018-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -48,10 +48,8 @@
 #include "rcar_version.h"
 #include "rom_api.h"
 
-#if RCAR_BL2_DCACHE == 1
 /*
- * Following symbols are only used during plat_arch_setup() only
- * when RCAR_BL2_DCACHE is enabled.
+ * Following symbols are only used during plat_arch_setup()
  */
 static const uint64_t BL2_RO_BASE		= BL_CODE_BASE;
 static const uint64_t BL2_RO_LIMIT		= BL_CODE_END;
@@ -61,13 +59,12 @@ static const uint64_t BL2_COHERENT_RAM_BASE	= BL_COHERENT_RAM_BASE;
 static const uint64_t BL2_COHERENT_RAM_LIMIT	= BL_COHERENT_RAM_END;
 #endif
 
-#endif
-
 extern void plat_rcar_gic_driver_init(void);
 extern void plat_rcar_gic_init(void);
 extern void bl2_enter_bl31(const struct entry_point_info *bl_ep_info);
 extern void bl2_system_cpg_init(void);
 extern void bl2_secure_setting(void);
+extern void bl2_ram_security_setting_finish(void);
 extern void bl2_cpg_init(void);
 extern void rcar_io_emmc_setup(void);
 extern void rcar_io_setup(void);
@@ -371,10 +368,16 @@ mmu:
 	rcar_swdt_release();
 	bl2_system_cpg_init();
 
-#if RCAR_BL2_DCACHE == 1
 	/* Disable data cache (clean and invalidate) */
 	disable_mmu_el3();
+#if RCAR_BL2_DCACHE == 1
+	dcsw_op_all(DCCISW);
 #endif
+	tlbialle3();
+	disable_mmu_icache_el3();
+	plat_invalidate_icache();
+	dsbsy();
+	isb();
 }
 
 static uint32_t is_ddr_backup_mode(void)
@@ -417,44 +420,61 @@ void bl2_plat_preload_setup(void)
 }
 #endif
 
-int bl2_plat_handle_pre_image_load(unsigned int image_id)
+static uint64_t check_secure_load_area(uintptr_t base, uint32_t size,
+		uintptr_t dest, uint32_t len)
 {
-	u_register_t *boot_kind = (void *) BOOT_KIND_BASE;
-	bl_mem_params_node_t *bl_mem_params;
+	uintptr_t free_end, requested_end;
 
-	bl_mem_params = get_bl_mem_params_node(image_id);
-
-#if RCAR_GEN3_BL33_GZIP == 1
-	if (image_id == BL33_IMAGE_ID) {
-		image_decompress_prepare(&bl_mem_params->image_info);
+	/*
+	 * Handle corner cases first.
+	 *
+	 * The order of the 2 tests is important, because if there's no space
+	 * left (i.e. free_size == 0) but we don't ask for any memory
+	 * (i.e. size == 0) then we should report that the memory is free.
+	 */
+	if (len == 0U) {
+		WARN("BL2: load data size is zero\n");
+		return 0;	/* A zero-byte region is always free */
+	}
+	if (size == 0U) {
+		goto err;
 	}
-#endif
-
-	if (image_id != BL31_IMAGE_ID)
-		return 0;
-
-	if (is_ddr_backup_mode() == RCAR_COLD_BOOT)
-		goto cold_boot;
-
-	*boot_kind  = RCAR_WARM_BOOT;
-	flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
 
-	console_flush();
-	bl2_plat_flush_bl31_params();
+	/*
+	 * Check that the end addresses don't overflow.
+	 * If they do, consider that this memory region is not free, as this
+	 * is an invalid scenario.
+	 */
+	if (check_uptr_overflow(base, size - 1U)) {
+		goto err;
+	}
+	free_end = base + (size - 1U);
 
-	/* will not return */
-	bl2_enter_bl31(&bl_mem_params->ep_info);
+	if (check_uptr_overflow(dest, len - 1U)) {
+		goto err;
+	}
+	requested_end = dest + (len - 1U);
 
-cold_boot:
-	*boot_kind  = RCAR_COLD_BOOT;
-	flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
+	/*
+	 * Finally, check that the requested memory region lies within the free
+	 * region.
+	 */
+	if ((dest < base) || (requested_end > free_end)) {
+		goto err;
+	}
 
 	return 0;
+
+err:
+	ERROR("BL2: load data is outside the loadable area.\n");
+	ERROR("BL2: dst=0x%lx, len=%d(0x%x)\n", dest, len, len);
+	return 1;
 }
 
-static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest)
+static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest,
+		uint32_t *len)
 {
-	uint32_t cert, len;
+	uint32_t cert;
 	int ret;
 
 	ret = rcar_get_certificate(certid, &cert);
@@ -463,7 +483,104 @@ static uint64_t rcar_get_dest_addr_from_cert(uint32_t certid, uintptr_t *dest)
 		return 1;
 	}
 
-	rcar_read_certificate((uint64_t) cert, &len, dest);
+	rcar_read_certificate((uint64_t) cert, len, dest);
+
+	return 0;
+}
+
+int bl2_plat_handle_pre_image_load(unsigned int image_id)
+{
+	u_register_t *boot_kind = (void *) BOOT_KIND_BASE;
+	bl_mem_params_node_t *bl_mem_params;
+	uintptr_t dev_handle;
+	uintptr_t image_spec;
+	uintptr_t dest;
+	uint32_t len;
+	uint64_t ui64_ret;
+	int iret;
+
+	bl_mem_params = get_bl_mem_params_node(image_id);
+	if (bl_mem_params == NULL) {
+		ERROR("BL2: Failed to get loading parameter.\n");
+		return 1;
+	}
+
+	switch (image_id) {
+	case BL31_IMAGE_ID:
+		if (is_ddr_backup_mode() == RCAR_COLD_BOOT) {
+			iret = plat_get_image_source(image_id, &dev_handle,
+					&image_spec);
+			if (iret != 0) {
+				return 1;
+			}
+
+			ui64_ret = rcar_get_dest_addr_from_cert(
+					SOC_FW_CONTENT_CERT_ID, &dest, &len);
+			if (ui64_ret != 0U) {
+				return 1;
+			}
+
+			ui64_ret = check_secure_load_area(
+					BL31_BASE, BL31_LIMIT - BL31_BASE,
+					dest, len);
+			if (ui64_ret != 0U) {
+				return 1;
+			}
+
+			*boot_kind = RCAR_COLD_BOOT;
+			flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
+
+			bl_mem_params->image_info.image_base = dest;
+			bl_mem_params->image_info.image_size = len;
+		} else {
+			*boot_kind = RCAR_WARM_BOOT;
+			flush_dcache_range(BOOT_KIND_BASE, sizeof(*boot_kind));
+
+			console_flush();
+			bl2_plat_flush_bl31_params();
+
+			/* will not return */
+			bl2_enter_bl31(&bl_mem_params->ep_info);
+		}
+
+		return 0;
+#ifndef SPD_NONE
+	case BL32_IMAGE_ID:
+		ui64_ret = rcar_get_dest_addr_from_cert(
+				TRUSTED_OS_FW_CONTENT_CERT_ID, &dest, &len);
+		if (ui64_ret != 0U) {
+			return 1;
+		}
+
+		ui64_ret = check_secure_load_area(
+				BL32_BASE, BL32_LIMIT - BL32_BASE, dest, len);
+		if (ui64_ret != 0U) {
+			return 1;
+		}
+
+		bl_mem_params->image_info.image_base = dest;
+		bl_mem_params->image_info.image_size = len;
+
+		return 0;
+#endif
+	case BL33_IMAGE_ID:
+		/* case of image_id == BL33_IMAGE_ID */
+		ui64_ret = rcar_get_dest_addr_from_cert(
+				NON_TRUSTED_FW_CONTENT_CERT_ID,
+				&dest, &len);
+
+		if (ui64_ret != 0U) {
+			return 1;
+		}
+
+#if RCAR_GEN3_BL33_GZIP == 1
+		image_decompress_prepare(&bl_mem_params->image_info);
+#endif
+
+		return 0;
+	default:
+		return 1;
+	}
 
 	return 0;
 }
@@ -472,8 +589,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 {
 	static bl2_to_bl31_params_mem_t *params;
 	bl_mem_params_node_t *bl_mem_params;
-	uintptr_t dest;
-	int ret;
 
 	if (!params) {
 		params = (bl2_to_bl31_params_mem_t *) PARAMS_BASE;
@@ -481,25 +596,23 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 	}
 
 	bl_mem_params = get_bl_mem_params_node(image_id);
+	if (!bl_mem_params) {
+		ERROR("BL2: Failed to get loading parameter.\n");
+		return 1;
+	}
 
 	switch (image_id) {
 	case BL31_IMAGE_ID:
-		ret = rcar_get_dest_addr_from_cert(SOC_FW_CONTENT_CERT_ID,
-						   &dest);
-		if (!ret)
-			bl_mem_params->image_info.image_base = dest;
-		break;
+		bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
+		return 0;
 	case BL32_IMAGE_ID:
-		ret = rcar_get_dest_addr_from_cert(TRUSTED_OS_FW_CONTENT_CERT_ID,
-						   &dest);
-		if (!ret)
-			bl_mem_params->image_info.image_base = dest;
-
+		bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
 		memcpy(&params->bl32_ep_info, &bl_mem_params->ep_info,
 			sizeof(entry_point_info_t));
-		break;
+		return 0;
 	case BL33_IMAGE_ID:
 #if RCAR_GEN3_BL33_GZIP == 1
+		int ret;
 		if ((mmio_read_32(BL33_COMP_BASE) & 0xffff) == 0x8b1f) {
 			/* decompress gzip-compressed image */
 			ret = image_decompress(&bl_mem_params->image_info);
@@ -514,7 +627,9 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 #endif
 		memcpy(&params->bl33_ep_info, &bl_mem_params->ep_info,
 			sizeof(entry_point_info_t));
-		break;
+		return 0;
+	default:
+		return 1;
 	}
 
 	return 0;
@@ -641,6 +756,69 @@ err:
 #endif
 }
 
+static void bl2_add_kaslr_seed(void)
+{
+	uint32_t cnt, isr, prr;
+	uint64_t seed;
+	int ret, node;
+
+	/* SCEG is only available on H3/M3-W/M3-N */
+	prr = mmio_read_32(RCAR_PRR);
+	switch (prr & PRR_PRODUCT_MASK) {
+	case PRR_PRODUCT_H3:
+	case PRR_PRODUCT_M3:
+	case PRR_PRODUCT_M3N:
+		break;
+	default:
+		return;
+	}
+
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SW_RESET_REG_ADDR,
+		      CC63_TRNG_SW_RESET_REG_SET);
+
+	do {
+		mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_CLK_ENABLE_REG_ADDR,
+			      CC63_TRNG_CLK_ENABLE_REG_SET);
+		mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SAMPLE_CNT1_REG_ADDR,
+			      CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT);
+		cnt = mmio_read_32(RCAR_CC63_BASE + CC63_TRNG_SAMPLE_CNT1_REG_ADDR);
+	} while (cnt != CC63_TRNG_SAMPLE_CNT1_REG_SAMPLE_COUNT);
+
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_CONFIG_REG_ADDR,
+		      CC63_TRNG_CONFIG_REG_ROSC_MAX_LENGTH);
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_DEBUG_CONTROL_REG_ADDR,
+		      CC63_TRNG_DEBUG_CONTROL_REG_80090B);
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SOURCE_ENABLE_REG_ADDR,
+		      CC63_TRNG_SOURCE_ENABLE_REG_SET);
+
+	do {
+		isr = mmio_read_32(RCAR_CC63_BASE + CC63_TRNG_ISR_REG_ADDR);
+		if ((isr & CC63_TRNG_ISR_REG_AUTOCORR_ERR) != 0U) {
+			panic();
+		}
+	} while ((isr & CC63_TRNG_ISR_REG_EHR_VALID) == 0U);
+
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_ICR_REG_ADDR, UINT32_MAX);
+	seed = mmio_read_64(RCAR_CC63_BASE + CC63_TRNG_EHR_DATA_ADDR_0_REG_ADDR);
+	mmio_write_32(RCAR_CC63_BASE + CC63_TRNG_SOURCE_ENABLE_REG_ADDR,
+		      CC63_TRNG_SOURCE_ENABLE_REG_CLR);
+
+	node = ret = fdt_add_subnode(fdt, 0, "chosen");
+	if (ret < 0) {
+		goto err;
+	}
+
+	ret = fdt_setprop_u64(fdt, node, "kaslr-seed", seed);
+	if (ret < 0) {
+		goto err;
+	}
+
+	return;
+err:
+	NOTICE("BL2: Cannot add KASLR seed to FDT (ret=%i)\n", ret);
+	panic();
+}
+
 static void bl2_add_dram_entry(uint64_t start, uint64_t size)
 {
 	char nodename[32] = { 0 };
@@ -1100,6 +1278,9 @@ lcm_state:
 	/* Print DRAM layout */
 	bl2_advertise_dram_size(product);
 
+	/* Add KASLR seed */
+	bl2_add_kaslr_seed();
+
 	if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
 	    boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) {
 		if (rcar_emmc_init() != EMMC_SUCCESS) {
@@ -1161,8 +1342,6 @@ lcm_state:
 
 void bl2_el3_plat_arch_setup(void)
 {
-#if RCAR_BL2_DCACHE == 1
-	NOTICE("BL2: D-Cache enable\n");
 	rcar_configure_mmu_el3(BL2_BASE,
 			       BL2_END - BL2_BASE,
 			       BL2_RO_BASE, BL2_RO_LIMIT
@@ -1170,7 +1349,11 @@ void bl2_el3_plat_arch_setup(void)
 			       , BL2_COHERENT_RAM_BASE, BL2_COHERENT_RAM_LIMIT
 #endif
 	    );
-#endif
+}
+
+void bl2_el3_plat_prepare_exit(void)
+{
+	bl2_ram_security_setting_finish();
 }
 
 void bl2_platform_setup(void)
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 670d4993..48139494 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -6,6 +6,8 @@
 
 include plat/renesas/common/common.mk
 
+ENABLE_STACK_PROTECTOR	:= strong
+
 ifndef LSI
   $(error "Error: Unknown LSI. Please use LSI=<LSI name> to specify the LSI")
 else
@@ -333,6 +335,10 @@ BL2_SOURCES	+=	common/image_decompress.c               \
 			$(ZLIB_SOURCES)
 endif
 
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+BL_COMMON_SOURCES	+=	plat/renesas/rcar/rcar_stack_protector.c
+endif
+
 ifeq (${RCAR_GEN3_ULCB},1)
 BL31_SOURCES		+=	drivers/renesas/rcar/cpld/ulcb_cpld.c
 endif
@@ -345,13 +351,13 @@ distclean realclean clean: clean_layout_tool clean_srecord
 LAYOUT_TOOLPATH ?= tools/renesas/rcar_layout_create
 
 clean_layout_tool:
-	@echo "clean layout tool"
-	${Q}${MAKE} -C ${LAYOUT_TOOLPATH} clean
+	$(s)echo "clean layout tool"
+	$(q)${MAKE} -C ${LAYOUT_TOOLPATH} clean
 
 .PHONY: rcar_layout_tool
 rcar_layout_tool:
-	@echo "generating layout srecs"
-	${Q}${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
+	$(s)echo "generating layout srecs"
+	$(q)${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
 
 # srecords
 SREC_PATH	= ${BUILD_PLAT}
@@ -359,13 +365,16 @@ BL2_ELF_SRC	= ${SREC_PATH}/bl2/bl2.elf
 BL31_ELF_SRC	= ${SREC_PATH}/bl31/bl31.elf
 
 clean_srecord:
-	@echo "clean bl2 and bl31 srecs"
+	$(s)echo "clean bl2 and bl31 srecs"
 	rm -f ${SREC_PATH}/bl2.srec ${SREC_PATH}/bl31.srec
 
-.PHONY: rcar_srecord
-rcar_srecord: $(BL2_ELF_SRC) $(BL31_ELF_SRC)
-	@echo "generating srec: ${SREC_PATH}/bl2.srec"
-	$(Q)$(OC) -O srec --srec-forceS3 ${BL2_ELF_SRC}  ${SREC_PATH}/bl2.srec
-	@echo "generating srec: ${SREC_PATH}/bl31.srec"
-	$(Q)$(OC) -O srec --srec-forceS3 ${BL31_ELF_SRC} ${SREC_PATH}/bl31.srec
+$(SREC_PATH)/bl2.srec: $(BL2_ELF_SRC)
+	$(s)echo "generating srec: $(SREC_PATH)/bl2.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL2_ELF_SRC)  $(SREC_PATH)/bl2.srec
+
+$(SREC_PATH)/bl31.srec: $(BL31_ELF_SRC)
+	$(s)echo "generating srec: $(SREC_PATH)/bl31.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL31_ELF_SRC) $(SREC_PATH)/bl31.srec
 
+.PHONY: rcar_srecord
+rcar_srecord: $(SREC_PATH)/bl2.srec $(SREC_PATH)/bl31.srec
diff --git a/plat/renesas/rcar/rcar_stack_protector.c b/plat/renesas/rcar/rcar_stack_protector.c
new file mode 100644
index 00000000..ecceef4b
--- /dev/null
+++ b/plat/renesas/rcar/rcar_stack_protector.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021-2023, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t)0xDFF5FC8A720E205EULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+	u_register_t cnt;
+	u_register_t seed;
+	u_register_t mul;
+	u_register_t ret;
+	uintptr_t val1 = (uintptr_t)__builtin_return_address(0U);
+	uintptr_t val2 = (uintptr_t)__builtin_frame_address(0U);
+
+	cnt = read_cntpct_el0();
+	seed = (cnt ^ RANDOM_CANARY_VALUE) & ULONG_MAX;
+	ret = seed;
+
+	if ((ULONG_MAX/val1) > seed) {
+		mul = (u_register_t)(val1 * seed);
+		if ((mul < ULONG_MAX) &&
+				((ULONG_MAX - (u_register_t)mul) > val2)) {
+			ret = mul + val2;
+		}
+	}
+
+	return ret;
+}
diff --git a/plat/renesas/rzg/platform.mk b/plat/renesas/rzg/platform.mk
index f37d7d0c..5da60529 100644
--- a/plat/renesas/rzg/platform.mk
+++ b/plat/renesas/rzg/platform.mk
@@ -249,13 +249,13 @@ distclean realclean clean: clean_layout_tool clean_srecord
 LAYOUT_TOOLPATH ?= tools/renesas/rzg_layout_create
 
 clean_layout_tool:
-	@echo "clean layout tool"
-	${Q}${MAKE} -C ${LAYOUT_TOOLPATH} clean
+	$(s)echo "clean layout tool"
+	$(q)${MAKE} -C ${LAYOUT_TOOLPATH} clean
 
 .PHONY: rzg_layout_create
 rzg_layout_create:
-	@echo "generating layout srecs"
-	${Q}${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
+	$(s)echo "generating layout srecs"
+	$(q)${MAKE} CPPFLAGS="-D=AARCH64" --no-print-directory -C ${LAYOUT_TOOLPATH}
 
 # srecords
 SREC_PATH	= ${BUILD_PLAT}
@@ -263,12 +263,16 @@ BL2_ELF_SRC	= ${SREC_PATH}/bl2/bl2.elf
 BL31_ELF_SRC	= ${SREC_PATH}/bl31/bl31.elf
 
 clean_srecord:
-	@echo "clean bl2 and bl31 srecs"
+	$(s)echo "clean bl2 and bl31 srecs"
 	rm -f ${SREC_PATH}/bl2.srec ${SREC_PATH}/bl31.srec
 
+$(SREC_PATH)/bl2.srec: $(BL2_ELF_SRC)
+	$(s)echo "generating srec: $(SREC_PATH)/bl2.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL2_ELF_SRC)  $(SREC_PATH)/bl2.srec
+
+$(SREC_PATH)/bl31.srec: $(BL31_ELF_SRC)
+	$(s)echo "generating srec: $(SREC_PATH)/bl31.srec"
+	$(q)$($(ARCH)-oc) -O srec --srec-forceS3 $(BL31_ELF_SRC) $(SREC_PATH)/bl31.srec
+
 .PHONY: rzg_srecord
-rzg_srecord: $(BL2_ELF_SRC) $(BL31_ELF_SRC)
-	@echo "generating srec: ${SREC_PATH}/bl2.srec"
-	$(Q)$(OC) -O srec --srec-forceS3 ${BL2_ELF_SRC}  ${SREC_PATH}/bl2.srec
-	@echo "generating srec: ${SREC_PATH}/bl31.srec"
-	$(Q)$(OC) -O srec --srec-forceS3 ${BL31_ELF_SRC} ${SREC_PATH}/bl31.srec
+rzg_srecord: $(SREC_PATH)/bl2.srec $(SREC_PATH)/bl31.srec
diff --git a/plat/rockchip/common/aarch32/platform_common.c b/plat/rockchip/common/aarch32/platform_common.c
index 9030951e..25ee964f 100644
--- a/plat/rockchip/common/aarch32/platform_common.c
+++ b/plat/rockchip/common/aarch32/platform_common.c
@@ -12,7 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 
 #include <plat_private.h>
 
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index c4c0dec3..9b8c9711 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,6 +32,17 @@
 	 *
 	 */
 func plat_reset_handler
+#ifdef PLAT_RK_CPU_RESET_EARLY
+	mov	x18, x30
+	msr	spsel, #0
+	bl	plat_set_my_stack
+	mov	x0, x20
+	mov	x1, x21
+	mov	x2, x22
+	mov	x3, x23
+	bl	rockchip_cpu_reset_early
+	mov	x30, x18
+#endif
 	mrs x0, midr_el1
 	ubfx x0, x0, MIDR_PN_SHIFT, #12
 	cmp w0, #((CORTEX_A72_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
@@ -150,7 +161,12 @@ endfunc platform_cpu_warmboot
 	 * Per-CPU Secure entry point - resume or power up
 	 * --------------------------------------------------------------------
 	 */
+
+#if USE_COHERENT_MEM
 	.section .tzfw_coherent_mem, "a"
+#else
+	.data
+#endif
 	.align  3
 cpuson_entry_point:
 	.rept	PLATFORM_CORE_COUNT
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index 81e85206..df51d895 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,7 @@
 #include <common/debug.h>
 #include <drivers/arm/cci.h>
 #include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 
 #include <plat_private.h>
 
@@ -42,9 +42,10 @@ static const int cci_map[] = {
 		mmap_add_region(ro_start, ro_start,			\
 				ro_limit - ro_start,			\
 				MT_MEMORY | MT_RO | MT_SECURE);		\
-		mmap_add_region(coh_start, coh_start,			\
-				coh_limit - coh_start,			\
-				MT_DEVICE | MT_RW | MT_SECURE);		\
+		if ((coh_limit - coh_start) != 0)			\
+			mmap_add_region(coh_start, coh_start,		\
+					coh_limit - coh_start,		\
+					MT_DEVICE | MT_RW | MT_SECURE);	\
 		mmap_add(plat_rk_mmap);					\
 		rockchip_plat_mmu_el##_el();				\
 		init_xlat_tables();					\
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 59db3d85..62147226 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -93,10 +93,19 @@ void bl31_plat_arch_setup(void)
 {
 	plat_cci_init();
 	plat_cci_enable();
+#if USE_COHERENT_MEM
 	plat_configure_mmu_el3(BL_CODE_BASE,
 			       BL_COHERENT_RAM_END - BL_CODE_BASE,
 			       BL_CODE_BASE,
 			       BL_CODE_END,
 			       BL_COHERENT_RAM_BASE,
 			       BL_COHERENT_RAM_END);
+#else
+	plat_configure_mmu_el3(BL31_START,
+			       BL31_END - BL31_START,
+			       BL_CODE_BASE,
+			       BL_CODE_END,
+			       0,
+			       0);
+#endif
 }
diff --git a/plat/rockchip/common/include/plat_macros.S b/plat/rockchip/common/include/plat_macros.S
index 691beeb4..548e3d90 100644
--- a/plat/rockchip/common/include/plat_macros.S
+++ b/plat/rockchip/common/include/plat_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,8 +23,8 @@ icc_regs:
 
 /* Registers common to both GICv2 and GICv3 */
 gicd_pend_reg:
-	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n"	\
-		" Offset:\t\t\tvalue\n"
+	.ascii "gicd_ispendr regs (Offsets 0x200 - 0x278)\n"	\
+		" Offset:\t\t\tvalue\n\0"
 newline:
 	.asciz "\n"
 spacer:
diff --git a/plat/rockchip/common/include/plat_pm_helpers.h b/plat/rockchip/common/include/plat_pm_helpers.h
new file mode 100644
index 00000000..2204a65d
--- /dev/null
+++ b/plat/rockchip/common/include/plat_pm_helpers.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_PM_HELPERS_H
+#define PLAT_PM_HELPERS_H
+
+#include <stdint.h>
+
+/**
+ * Use this macro to define a register region.
+ * start: start offset from the base address.
+ * end: end offset from the base address.
+ * stride: stride of registers in region.
+ * base: base address of registers in region.
+ * wmsk: write mask of registers in region.
+ */
+#define REG_REGION(_start, _end, _stride, _base, _wmsk)	\
+{							\
+	.start = (_base) + (_start),			\
+	.end   = (_base) + (_end),			\
+	.stride   = _stride,				\
+	.wmsk  = _wmsk					\
+}
+
+struct reg_region {
+	/* Start address of region */
+	uint32_t start;
+	/* End address of region */
+	uint32_t end;
+	/* Stride of registers in region */
+	uint32_t stride;
+	/* Write mask of registers in region */
+	uint32_t wmsk;
+	/* Buffer to save/restore registers in region */
+	uint32_t *buf;
+};
+
+void rockchip_alloc_region_mem(struct reg_region *rgns, uint32_t rgn_num);
+void rockchip_reg_rgn_save(struct reg_region *rgns, uint32_t rgn_num);
+void rockchip_reg_rgn_restore(struct reg_region *rgns, uint32_t rgn_num);
+void rockchip_reg_rgn_restore_reverse(struct reg_region *rgns, uint32_t rgn_num);
+void rockchip_regs_dump(uint32_t base,
+			uint32_t start_offset,
+			uint32_t end_offset,
+			uint32_t stride);
+void rockchip_dump_reg_rgns(struct reg_region *rgns, uint32_t rgn_num);
+
+#endif /* PLAT_PM_HELPERS_H */
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index 990d1065..1e13a9e8 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,9 +11,9 @@
 
 #include <stdint.h>
 
-#include <lib/psci/psci.h>
-#include <lib/xlat_tables/xlat_tables.h>
 #include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat_params.h>
 
 #define __sramdata __attribute__((section(".sram.data")))
@@ -49,7 +49,7 @@ extern uint32_t __sram_incbin_real_end;
 #endif
 
 #ifndef BITS_SHIFT
-#define BITS_SHIFT(bits, shift)	(bits << (shift))
+#define BITS_SHIFT(bits, shift)	((bits) << (shift))
 #endif
 
 #ifndef BITS_WITH_WMASK
@@ -135,13 +135,13 @@ extern const unsigned char rockchip_power_domain_tree_desc[];
 extern void *pmu_cpuson_entrypoint;
 extern u_register_t cpuson_entry_point[PLATFORM_CORE_COUNT];
 extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
-
 extern const mmap_region_t plat_rk_mmap[];
 
 uint32_t rockchip_get_uart_base(void);
 uint32_t rockchip_get_uart_baudrate(void);
 uint32_t rockchip_get_uart_clock(void);
 
+void rockchip_init_scmi_server(void);
 #endif /* __ASSEMBLER__ */
 
 /******************************************************************************
diff --git a/plat/rockchip/common/include/rockchip_sip_svc.h b/plat/rockchip/common/include/rockchip_sip_svc.h
index 340d6538..8836f9b5 100644
--- a/plat/rockchip/common/include/rockchip_sip_svc.h
+++ b/plat/rockchip/common/include/rockchip_sip_svc.h
@@ -11,6 +11,7 @@
 #define SIP_SVC_CALL_COUNT		0x8200ff00
 #define SIP_SVC_UID			0x8200ff01
 #define SIP_SVC_VERSION			0x8200ff03
+#define RK_SIP_SCMI_AGENT0		0x82000010
 
 /* rockchip SiP Service Calls version numbers */
 #define RK_SIP_SVC_VERSION_MAJOR	0x0
diff --git a/plat/rockchip/common/plat_pm_helpers.c b/plat/rockchip/common/plat_pm_helpers.c
new file mode 100644
index 00000000..191b0cae
--- /dev/null
+++ b/plat/rockchip/common/plat_pm_helpers.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#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 <plat_pm_helpers.h>
+
+#define ROCKCHIP_PM_REG_REGION_MEM_LEN	(ROCKCHIP_PM_REG_REGION_MEM_SIZE / sizeof(uint32_t))
+
+/* REG region */
+#define RGN_LEN(_rgn)		(((_rgn)->end - (_rgn)->start) / (_rgn)->stride + 1)
+
+#ifndef ROCKCHIP_PM_REG_REGION_MEM_SIZE
+#define ROCKCHIP_PM_REG_REGION_MEM_SIZE		0
+#endif
+
+#ifdef ROCKCHIP_REG_RGN_MEM_BASE
+static uint32_t *region_mem = (uint32_t *)ROCKCHIP_REG_RGN_MEM_BASE;
+#else
+static uint32_t region_mem[ROCKCHIP_PM_REG_REGION_MEM_LEN];
+#endif
+
+static int region_mem_idx;
+
+static int alloc_region_mem(uint32_t *buf, int max_len,
+			    struct reg_region *rgns, uint32_t rgn_num)
+{
+	int i;
+	int total_len = 0, len = 0;
+	struct reg_region *r = rgns;
+
+	assert(buf && rgns && rgn_num);
+
+	for (i = 0; i < rgn_num; i++, r++) {
+		if (total_len < max_len)
+			r->buf = &buf[total_len];
+
+		len = RGN_LEN(r);
+		total_len += len;
+	}
+
+	if (total_len > max_len) {
+		ERROR("%s The buffer remain length:%d is too small for region:0x%x, at least %d\n",
+		      __func__, max_len, rgns[0].start, total_len);
+		panic();
+	}
+
+	return total_len;
+}
+
+/**
+ * Alloc memory to reg_region->buf from region_mem.
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_alloc_region_mem(struct reg_region *rgns, uint32_t rgn_num)
+{
+	int max_len = 0, len;
+
+	assert(rgns && rgn_num);
+
+	max_len = ROCKCHIP_PM_REG_REGION_MEM_LEN - region_mem_idx;
+
+	len = alloc_region_mem(region_mem + region_mem_idx, max_len,
+			       rgns, rgn_num);
+
+	region_mem_idx += len;
+}
+
+/**
+ * Save (reg_region->start ~ reg_region->end) to reg_region->buf.
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_reg_rgn_save(struct reg_region *rgns, uint32_t rgn_num)
+{
+	struct reg_region *r;
+	uint32_t addr;
+	int i, j;
+
+	assert(rgns && rgn_num);
+
+	for (i = 0; i < rgn_num; i++) {
+		r = &rgns[i];
+		for (j = 0, addr = r->start; addr <= r->end; addr += r->stride, j++)
+			r->buf[j] = mmio_read_32(addr);
+	}
+}
+
+/**
+ * Restore reg_region->buf to (reg_region->start ~ reg_region->end).
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_reg_rgn_restore(struct reg_region *rgns, uint32_t rgn_num)
+{
+	struct reg_region *r;
+	uint32_t addr;
+	int i, j;
+
+	assert(rgns && rgn_num);
+
+	for (i = 0; i < rgn_num; i++) {
+		r = &rgns[i];
+		for (j = 0, addr = r->start; addr <= r->end; addr += r->stride, j++)
+			mmio_write_32(addr, r->buf[j] | r->wmsk);
+
+		dsb();
+	}
+}
+
+/**
+ * Restore reg_region->buf to (reg_region->start ~ reg_region->end) reversely.
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_reg_rgn_restore_reverse(struct reg_region *rgns, uint32_t rgn_num)
+{
+	struct reg_region *r;
+	uint32_t addr;
+	int i, j;
+
+	assert(rgns && rgn_num);
+
+	for (i = rgn_num - 1; i >= 0; i--) {
+		r = &rgns[i];
+		j = RGN_LEN(r) - 1;
+		for (addr = r->end; addr >= r->start; addr -= r->stride, j--)
+			mmio_write_32(addr, r->buf[j] | r->wmsk);
+
+		dsb();
+	}
+}
+
+static void rockchip_print_hex(uint32_t val)
+{
+	int i;
+	unsigned char tmp;
+
+	putchar('0');
+	putchar('x');
+	for (i = 0; i < 8; val <<= 4, ++i) {
+		tmp = (val & 0xf0000000) >> 28;
+		if (tmp < 10)
+			putchar('0' + tmp);
+		else
+			putchar('a' + tmp - 10);
+	}
+}
+
+/**
+ * Dump registers (base + start_offset ~ base + end_offset)
+ * @base - the base addr of the register.
+ * @start_offset - the start offset to dump.
+ * @end_offset - the end offset to dump.
+ * @stride - the stride of the registers.
+ */
+void rockchip_regs_dump(uint32_t base,
+			uint32_t start_offset,
+			uint32_t end_offset,
+			uint32_t stride)
+{
+	uint32_t i;
+
+	for (i = start_offset; i <= end_offset; i += stride) {
+		if ((i - start_offset) % 16 == 0) {
+			putchar('\n');
+			rockchip_print_hex(base + i);
+			putchar(':');
+			putchar(' ');
+			putchar(' ');
+			putchar(' ');
+			putchar(' ');
+		}
+		rockchip_print_hex(mmio_read_32(base + i));
+		putchar(' ');
+		putchar(' ');
+		putchar(' ');
+		putchar(' ');
+	}
+	putchar('\n');
+}
+
+/**
+ * Dump reg regions
+ * @rgns - struct reg_region array.
+ * @rgn_num - struct reg_region array length.
+ */
+void rockchip_dump_reg_rgns(struct reg_region *rgns, uint32_t rgn_num)
+{
+	struct reg_region *r;
+	int i;
+
+	assert(rgns && rgn_num);
+
+	for (i = 0; i < rgn_num; i++) {
+		r = &rgns[i];
+		rockchip_regs_dump(0x0, r->start, r->end, r->stride);
+	}
+}
diff --git a/plat/rockchip/common/scmi/scmi.c b/plat/rockchip/common/scmi/scmi.c
new file mode 100644
index 00000000..5c43c511
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+#include <lib/utils.h>
+#include <lib/utils_def.h>
+
+#define MAX_PROTOCOL_IN_LIST		8U
+
+static const char vendor[] = "rockchip";
+static const char sub_vendor[] = "";
+
+#pragma weak rockchip_scmi_protocol_table
+
+const uint8_t rockchip_scmi_protocol_table[1][MAX_PROTOCOL_IN_LIST] = {
+	{
+		SCMI_PROTOCOL_ID_CLOCK,
+		SCMI_PROTOCOL_ID_RESET_DOMAIN,
+		0
+	}
+};
+
+const char *plat_scmi_vendor_name(void)
+{
+	return vendor;
+}
+
+const char *plat_scmi_sub_vendor_name(void)
+{
+	return sub_vendor;
+}
+
+size_t plat_scmi_protocol_count(void)
+{
+	unsigned int count = 0U;
+	const uint8_t *protocol_list = rockchip_scmi_protocol_table[0];
+
+	while (protocol_list[count])
+		count++;
+
+	return count;
+}
+
+const uint8_t *plat_scmi_protocol_list(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(rockchip_scmi_protocol_table));
+
+	return rockchip_scmi_protocol_table[agent_id];
+}
+
+static struct scmi_msg_channel scmi_channel[] = {
+	[0] = {
+		.shm_addr = SMT_BUFFER0_BASE,
+		.shm_size = SMT_BUF_SLOT_SIZE,
+	},
+
+#ifdef SMT_BUFFER1_BASE
+	[1] = {
+		.shm_addr = SMT_BUFFER1_BASE,
+		.shm_size = SMT_BUF_SLOT_SIZE,
+	},
+#endif
+};
+
+struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
+{
+	assert(agent_id < ARRAY_SIZE(scmi_channel));
+
+	return &scmi_channel[agent_id];
+}
+
+#pragma weak rockchip_init_scmi_server
+
+void rockchip_init_scmi_server(void)
+{
+	size_t i;
+
+	for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++)
+		scmi_smt_init_agent_channel(&scmi_channel[i]);
+}
diff --git a/plat/rockchip/common/scmi/scmi_clock.c b/plat/rockchip/common/scmi/scmi_clock.c
new file mode 100644
index 00000000..d6d4b375
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi_clock.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+
+#include "scmi_clock.h"
+
+#pragma weak rockchip_scmi_clock_count
+#pragma weak rockchip_scmi_get_clock
+
+size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
+{
+	return 0;
+}
+
+rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
+					 uint32_t scmi_id __unused)
+{
+	return NULL;
+}
+
+size_t plat_scmi_clock_count(unsigned int agent_id)
+{
+	return rockchip_scmi_clock_count(agent_id);
+}
+
+const char *plat_scmi_clock_get_name(unsigned int agent_id,
+				     unsigned int scmi_id)
+{
+	rk_scmi_clock_t *clock;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return NULL;
+
+	return clock->name;
+}
+
+int32_t plat_scmi_clock_rates_array(unsigned int agent_id,
+				    unsigned int scmi_id,
+				    unsigned long *rates,
+				    size_t *nb_elts,
+				    uint32_t start_idx)
+{
+	uint32_t i;
+	unsigned long *rate_table;
+	rk_scmi_clock_t *clock;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return SCMI_NOT_FOUND;
+
+	rate_table = clock->rate_table;
+	if (rate_table == NULL)
+		return SCMI_NOT_SUPPORTED;
+
+	if (rates == 0) {
+		*nb_elts = clock->rate_cnt;
+		goto out;
+	}
+
+	if (start_idx + *nb_elts > clock->rate_cnt)
+		return SCMI_OUT_OF_RANGE;
+
+	for (i = 0; i < *nb_elts; i++)
+		rates[i] = rate_table[start_idx + i];
+
+out:
+	return SCMI_SUCCESS;
+}
+
+int32_t plat_scmi_clock_rates_by_step(unsigned int agent_id __unused,
+				      unsigned int scmi_id __unused,
+				      unsigned long *steps __unused)
+{
+	return SCMI_NOT_SUPPORTED;
+}
+
+unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
+				       unsigned int scmi_id)
+{
+	rk_scmi_clock_t *clock;
+	unsigned long rate = 0;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return 0;
+
+	if (clock->clk_ops && clock->clk_ops->get_rate)
+		rate = clock->clk_ops->get_rate(clock);
+
+	/* return cur_rate if no get_rate ops or get_rate return 0 */
+	if (rate == 0)
+		rate = clock->cur_rate;
+
+	return rate;
+}
+
+int32_t plat_scmi_clock_set_rate(unsigned int agent_id,
+				 unsigned int scmi_id,
+				 unsigned long rate)
+{
+	rk_scmi_clock_t *clock;
+	int32_t status = 0;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return SCMI_NOT_FOUND;
+
+	if (clock->clk_ops && clock->clk_ops->set_rate) {
+		status = clock->clk_ops->set_rate(clock, rate);
+		if (status == SCMI_SUCCESS)
+			clock->cur_rate = rate;
+	} else {
+		status = SCMI_NOT_SUPPORTED;
+	}
+
+	return status;
+}
+
+int32_t plat_scmi_clock_get_state(unsigned int agent_id,
+				  unsigned int scmi_id)
+{
+	rk_scmi_clock_t *clock;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return 0;
+
+	return clock->enable;
+}
+
+int32_t plat_scmi_clock_set_state(unsigned int agent_id,
+				  unsigned int scmi_id,
+				  bool enable_not_disable)
+{
+	rk_scmi_clock_t *clock;
+	int32_t status = 0;
+
+	clock = rockchip_scmi_get_clock(agent_id, scmi_id);
+	if (clock == NULL)
+		return SCMI_NOT_FOUND;
+
+	if (clock->clk_ops && clock->clk_ops->set_status) {
+		status = clock->clk_ops->set_status(clock, enable_not_disable);
+		if (status == SCMI_SUCCESS)
+			clock->enable = enable_not_disable;
+	} else {
+		status = SCMI_NOT_SUPPORTED;
+	}
+
+	return status;
+}
diff --git a/plat/rockchip/common/scmi/scmi_clock.h b/plat/rockchip/common/scmi/scmi_clock.h
new file mode 100644
index 00000000..e640fe19
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi_clock.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RK_SCMI_CLOCK_H
+#define RK_SCMI_CLOCK_H
+
+#include <stdint.h>
+
+#include <common.h>
+
+struct rk_scmi_clock;
+
+struct rk_clk_ops {
+	unsigned long (*get_rate)(struct rk_scmi_clock *clock);
+	int (*set_rate)(struct rk_scmi_clock *clock, unsigned long rate);
+	int (*set_status)(struct rk_scmi_clock *clock, bool status);
+};
+
+typedef struct rk_scmi_clock {
+	char name[SCMI_CLOCK_NAME_LENGTH_MAX];
+	uint8_t enable;
+	int8_t is_security;
+	uint32_t id;
+	uint32_t rate_cnt;
+	uint64_t cur_rate;
+	uint32_t enable_count;
+	const struct rk_clk_ops *clk_ops;
+	unsigned long *rate_table;
+} rk_scmi_clock_t;
+
+/*
+ * Return number of clock controllers for an agent
+ * @agent_id: SCMI agent ID
+ * Return number of clock controllers
+ */
+size_t rockchip_scmi_clock_count(unsigned int agent_id);
+
+/*
+ * Get rk_scmi_clock_t point
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI clock ID
+ * Return a rk_scmi_clock_t point
+ */
+rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id,
+					 uint32_t scmi_id);
+
+#endif /* RK_SCMI_CLOCK_H */
diff --git a/plat/rockchip/common/scmi/scmi_rstd.c b/plat/rockchip/common/scmi/scmi_rstd.c
new file mode 100644
index 00000000..35c5e0b2
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi_rstd.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/scmi-msg.h>
+#include <drivers/scmi.h>
+
+#include "scmi_rstd.h"
+
+#pragma weak rockchip_scmi_rstd_count
+#pragma weak rockchip_scmi_get_rstd
+
+size_t rockchip_scmi_rstd_count(unsigned int agent_id __unused)
+{
+	return 0U;
+}
+
+rk_scmi_rstd_t *rockchip_scmi_get_rstd(unsigned int agent_id __unused,
+				       unsigned int scmi_id __unused)
+{
+	return NULL;
+}
+
+size_t plat_scmi_rstd_count(unsigned int agent_id)
+{
+	return rockchip_scmi_rstd_count(agent_id);
+}
+
+const char *plat_scmi_rstd_get_name(unsigned int agent_id,
+				    unsigned int scmi_id)
+{
+	rk_scmi_rstd_t *rstd;
+
+	rstd = rockchip_scmi_get_rstd(agent_id, scmi_id);
+	if (rstd == NULL)
+		return NULL;
+
+	return rstd->name;
+}
+
+int32_t plat_scmi_rstd_autonomous(unsigned int agent_id,
+				  unsigned int scmi_id,
+				  unsigned int state)
+{
+	rk_scmi_rstd_t *rstd;
+
+	rstd = rockchip_scmi_get_rstd(agent_id, scmi_id);
+	if (rstd == NULL)
+		return SCMI_NOT_FOUND;
+
+	if ((rstd->rstd_ops && rstd->rstd_ops->reset_auto) != 0)
+		return rstd->rstd_ops->reset_auto(rstd, state);
+	else
+		return SCMI_NOT_SUPPORTED;
+}
+
+int32_t plat_scmi_rstd_set_state(unsigned int agent_id,
+				 unsigned int scmi_id,
+				 bool assert_not_deassert)
+{
+	rk_scmi_rstd_t *rstd;
+
+	rstd = rockchip_scmi_get_rstd(agent_id, scmi_id);
+	if (rstd == NULL)
+		return SCMI_NOT_FOUND;
+
+	if ((rstd->rstd_ops && rstd->rstd_ops->reset_explicit) != 0)
+		return rstd->rstd_ops->reset_explicit(rstd,
+						      assert_not_deassert);
+	else
+		return SCMI_NOT_SUPPORTED;
+}
diff --git a/plat/rockchip/common/scmi/scmi_rstd.h b/plat/rockchip/common/scmi/scmi_rstd.h
new file mode 100644
index 00000000..1af58813
--- /dev/null
+++ b/plat/rockchip/common/scmi/scmi_rstd.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RK_SCMI_RESET_DOMAIN_H
+#define RK_SCMI_RESET_DOMAIN_H
+
+#include <stdint.h>
+
+#include <common.h>
+
+struct rk_scmi_rstd;
+
+struct rk_scmi_rstd_ops {
+	int (*reset_auto)(struct rk_scmi_rstd *rstd, uint32_t state);
+	int (*reset_explicit)(struct rk_scmi_rstd *rstd, bool assert_not_deassert);
+};
+
+typedef struct rk_scmi_rstd {
+	char name[SCMI_RESET_DOMAIN_ATTR_NAME_SZ];
+	uint32_t id;
+	uint32_t attribute;
+	uint32_t latency;
+	struct rk_scmi_rstd_ops *rstd_ops;
+} rk_scmi_rstd_t;
+
+/*
+ * Return number of reset domain for an agent
+ * @agent_id: SCMI agent ID
+ * Return number of reset domain
+ */
+size_t rockchip_scmi_rstd_count(unsigned int agent_id);
+
+/*
+ * Get rk_scmi_rstd_t point
+ * @agent_id: SCMI agent ID
+ * @scmi_id: SCMI rstd ID
+ * Return a rk_scmi_rstd_t point
+ */
+rk_scmi_rstd_t *rockchip_scmi_get_rstd(unsigned int agent_id,
+				       unsigned int scmi_id);
+
+#endif /* RK_SCMI_RESET_DOMAIN_H */
diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk
index 5b4766d5..f96e18bb 100644
--- a/plat/rockchip/rk3328/platform.mk
+++ b/plat/rockchip/rk3328/platform.mk
@@ -65,6 +65,7 @@ include lib/libfdt/libfdt.mk
 
 # Enable workarounds for selected Cortex-A53 errata
 ERRATA_A53_855873	:=	1
+ERRATA_A53_1530924	:=      1
 
 $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
 $(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile
index 79e09f0e..32446efb 100644
--- a/plat/rockchip/rk3399/drivers/m0/Makefile
+++ b/plat/rockchip/rk3399/drivers/m0/Makefile
@@ -1,9 +1,12 @@
 #
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include ../../../../../make_helpers/common.mk
+include ../../../../../make_helpers/toolchain.mk
+
 # Cross Compile
 M0_CROSS_COMPILE ?= arm-none-eabi-
 
@@ -14,13 +17,6 @@ ARCH		:= cortex-m0
 PLAT_M0		?= rk3399m0
 PLAT_M0_PMU	?= rk3399m0pmu
 
-ifeq (${V},0)
-	Q=@
-else
-	Q=
-endif
-export Q
-
 .SUFFIXES:
 
 INCLUDES		+= -Iinclude/ \
@@ -38,14 +34,6 @@ CFLAGS			:= -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-common
 ASFLAGS			:= -Wa,--gdwarf-2
 LDFLAGS			:= -Wl,--gc-sections -Wl,--build-id=none
 
-# Cross tool
-CC			:= ${M0_CROSS_COMPILE}gcc
-CPP			:= ${M0_CROSS_COMPILE}cpp
-AR			:= ${M0_CROSS_COMPILE}ar
-OC			:= ${M0_CROSS_COMPILE}objcopy
-OD			:= ${M0_CROSS_COMPILE}objdump
-NM			:= ${M0_CROSS_COMPILE}nm
-
 # NOTE: The line continuation '\' is required in the next define otherwise we
 # end up with a line-feed characer at the end of the last c filename.
 # Also bare this issue in mind if extending the list of supported filetypes.
@@ -75,16 +63,16 @@ $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 -include $(patsubst %.o,%.d,$(OBJ))
 
 $(OBJ) : $(2)
-	@echo "  CC      $$<"
-	$$(Q)$$(CC) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
+	$(s)echo "  CC      $$<"
+	$$(q)$(rk3399-m0-cc) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
 endef
 
 define MAKE_S
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 
 $(OBJ) : $(2)
-	@echo "  AS      $$<"
-	$$(Q)$$(CC) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
+	$(s)echo "  AS      $$<"
+	$$(q)$(rk3399-m0-cc) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
 endef
 
 define MAKE_OBJS
@@ -105,20 +93,20 @@ all: $(BIN) $(BIN_PMU)
 .DEFAULT_GOAL := all
 
 $(LINKERFILE): $(LINKERFILE_SRC)
-	$(CC) $(COMMON_FLAGS) $(INCLUDES) -P -E -D__LINKER__ -MMD -MF $@.d -MT $@ -o $@ $<
+	$(rk3399-m0-cc) $(COMMON_FLAGS) $(INCLUDES) -P -E -D__LINKER__ -MMD -MF $@.d -MT $@ -o $@ $<
 -include $(LINKERFILE).d
 
 $(ELF) : $(OBJS) $(OBJS_COMMON) $(LINKERFILE)
-	@echo "  LD      $@"
-	$(Q)$(CC) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
+	$(s)echo "  LD      $@"
+	$(q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
 
 %.bin : %.elf
-	@echo "  BIN     $@"
-	$(Q)$(OC) -O binary $< $@
+	$(s)echo "  BIN     $@"
+	$(q)$(rk3399-m0-oc) -O binary $< $@
 
 $(ELF_PMU) : $(OBJS_COMMON) $(OBJS_PMU) $(LINKERFILE)
-	@echo "  LD      $@"
-	$(Q)$(CC) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
+	$(s)echo "  LD      $@"
+	$(q)$(rk3399-m0-cc) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
 
 $(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES_COMMON),$(1)))
 $(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES),$(1)))
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S
new file mode 100644
index 00000000..26f33131
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* convoluted way to make sure that the define is pasted just the right way */
+.macro INCBIN file sym sec
+	.section \sec
+	.global \sym
+	.type \sym, @object
+	.align 4
+\sym :
+	.incbin \file
+	.size \sym , .-\sym
+	.global \sym\()_end
+\sym\()_end :
+.endm
+
+INCBIN ""RK3399M0FW"", "rk3399m0_bin", ".sram.incbin"
+INCBIN ""RK3399M0PMUFW"", "rk3399m0pmu_bin", ".pmusram.incbin"
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
deleted file mode 100644
index 25596b18..00000000
--- a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/* convoluted way to make sure that the define is pasted just the right way */
-#define INCBIN(file, sym, sec) \
-	__asm__( \
-		".section " sec "\n" \
-		".global " sym "\n" \
-		".type " sym ", %object\n" \
-		".align 4\n" \
-		sym ":\n" \
-		".incbin \"" file "\"\n" \
-		".size " sym ", .-" sym "\n" \
-		".global " sym "_end\n" \
-		sym "_end:\n" \
-	)
-
-INCBIN(RK3399M0FW, "rk3399m0_bin", ".sram.incbin");
-INCBIN(RK3399M0PMUFW, "rk3399m0pmu_bin", ".pmusram.incbin");
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index aba67c2f..9d0e2157 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -61,7 +61,7 @@ BL31_SOURCES	+=	${RK_GIC_SOURCES}				\
 			${RK_PLAT_SOC}/plat_sip_calls.c			\
 			${RK_PLAT_SOC}/drivers/gpio/rk3399_gpio.c	\
 			${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
-			${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c		\
+			${RK_PLAT_SOC}/drivers/pmu/pmu_fw.S		\
 			${RK_PLAT_SOC}/drivers/pmu/m0_ctl.c		\
 			${RK_PLAT_SOC}/drivers/pwm/pwm.c		\
 			${RK_PLAT_SOC}/drivers/secure/secure.c		\
@@ -102,11 +102,10 @@ endif
 # CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin
 export CCACHE_EXTRAFILES
 ${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW):$(RK3399M0PMUFW)
-${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW)
+${RK_PLAT_SOC}/drivers/pmu/pmu_fw.S: $(RK3399M0FW)
 
-$(eval $(call MAKE_PREREQ_DIR,${BUILD_M0},${BUILD_PLAT}))
 .PHONY: $(RK3399M0FW)
-$(RK3399M0FW): | ${BUILD_M0}
+$(RK3399M0FW): | $$(@D)/
 	$(MAKE) -C ${RK_PLAT_SOC}/drivers/m0 BUILD=$(abspath ${BUILD_PLAT}/m0)
 
 # Do not enable SVE
diff --git a/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 00000000..8ddea0ee
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+.macro	func_rockchip_clst_warmboot
+	/* Nothing to do for rk3568 */
+.endm
+
+.macro rockchip_clst_warmboot_data
+	/* Nothing to do for rk3568 */
+.endm
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.c b/plat/rockchip/rk3568/drivers/pmu/pmu.c
new file mode 100644
index 00000000..970caec5
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * The power management unit (PMU) is designed for controlling power resources.
+ * The PMU is dedicated for managing the power of the whole chip.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <bakery_lock.h>
+#include <cortex_a55.h>
+#include <dsu_def.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <cpus_on_fixed_addr.h>
+#include <plat_private.h>
+#include <soc.h>
+
+/*
+ * Use this macro to instantiate lock before it is used in below
+ * rockchip_pd_lock_xxx() macros
+ */
+DECLARE_BAKERY_LOCK(rockchip_pd_lock);
+
+static uint32_t grf_ddr_con3;
+static struct psram_data_t *psram_sleep_cfg =
+	(struct psram_data_t *)&sys_sleep_flag_sram;
+
+/*
+ * These are wrapper macros to the powe domain Bakery Lock API.
+ */
+#define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock)
+#define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock)
+#define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock)
+
+void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
+{
+	uint64_t ctrl;
+
+	__asm__ volatile ("mrs %0, " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) : "=r" (ctrl));
+	ctrl |= 0x01;
+	__asm__ volatile ("msr " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) ", %0" : : "r" (ctrl));
+	isb();
+
+	while (1)
+		wfi();
+}
+
+static void pmu_pmic_sleep_mode_config(void)
+{
+	/* pmic sleep function selection
+	 * 1'b0: From reset pulse generator, can reset external PMIC
+	 * 1'b1: From pmu block, only support sleep function for external PMIC
+	 */
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0),  WRITE_MASK_SET(BIT(7)));
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_GPIO0A_IOMUX_L, PMIC_SLEEP_FUN);
+}
+
+static void pmu_wakeup_source_config(void)
+{
+	/* config wakeup source */
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, WRITE_MASK_SET(BIT(WAKEUP_GPIO0_INT_EN)));
+
+	INFO("WAKEUP: PMU_WAKEUP_INT_CON:0x%x, reg: 0x%x\n",
+	     mmio_read_32(PMU_BASE + PMU_WAKEUP_INT_CON), PMU_WAKEUP_INT_CON);
+}
+
+static void pmu_pll_powerdown_config(void)
+{
+	uint32_t pll_id;
+
+	/* PLL power down by PMU */
+	pll_id = BIT(APLL_PD_ENA) |
+		BIT(CPLL_PD_ENA) |
+		BIT(GPLL_PD_ENA) |
+		BIT(MPLL_PD_ENA) |
+		BIT(NPLL_PD_ENA) |
+		BIT(HPLL_PD_ENA) |
+		BIT(PPLL_PD_ENA) |
+		BIT(VPLL_PD_ENA);
+	mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(pll_id));
+	INFO("PLL: PMU_PLLPD_CON(0x%x):0x%x\n",
+	     PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+}
+
+static void pmu_stable_count_config(void)
+{
+	mmio_write_32(PMU_BASE + PMU_DSU_STABLE_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_PMIC_STABLE_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_OSC_STABLE_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_RSTCLR_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_PLL_LOCK_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWRUP_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWRDN_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_GPU_VOLUP_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_GPU_VOLDN_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_PWM_SWITCH_CNT, 0x180);
+	mmio_write_32(PMU_BASE + PMU_DBG_RST_CNT, 0x180);
+}
+
+static void pmu_pd_powerdown_config(void)
+{
+	uint32_t pwr_gate_con, pwr_dwn_st, pmu_bus_idle_con0 = 0;
+	uint32_t pmu_bus_idle_con1;
+
+	/* Pd power down by PMU */
+	pwr_dwn_st = mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST);
+	pwr_gate_con = ~pwr_dwn_st & 0x3ff;
+
+	if (pwr_gate_con & BIT(PD_GPU_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_GPU);
+	}
+
+	if (pwr_gate_con & BIT(PD_NPU_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_NPU);
+	}
+
+	if (pwr_gate_con & BIT(PD_RKVENC_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVENC);
+	}
+
+	if (pwr_gate_con & BIT(PD_RKVDEC_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVDEC);
+	}
+
+	if (pwr_gate_con & BIT(PD_RGA_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_RGA);
+	}
+
+	if (pwr_gate_con & BIT(PD_VI_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_VI);
+	}
+
+	if (pwr_gate_con & BIT(PD_VO_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_VO);
+	}
+
+	if (pwr_gate_con & BIT(PD_PIPE_DWN_ENA)) {
+		pmu_bus_idle_con0 |= BIT(IDLE_REQ_PIPE);
+	}
+
+	pmu_bus_idle_con0 |= BIT(IDLE_REQ_GIC_AUDIO) |
+		BIT(IDLE_REQ_MSCH) |
+		BIT(IDLE_REQ_PHP) |
+		BIT(IDLE_REQ_SECURE_FLASH) |
+		BIT(IDLE_REQ_PERIMID) |
+		BIT(IDLE_REQ_USB) |
+		BIT(IDLE_REQ_BUS);
+
+	/* Enable power down PD by PMU automatically */
+	pwr_gate_con |= (BIT(PD_GPU_DWN_ENA) |
+		BIT(PD_NPU_DWN_ENA) |
+		BIT(PD_VPU_DWN_ENA) |
+		BIT(PD_RKVENC_DWN_ENA) |
+		BIT(PD_RKVDEC_DWN_ENA) |
+		BIT(PD_RGA_DWN_ENA) |
+		BIT(PD_VI_DWN_ENA) |
+		BIT(PD_VO_DWN_ENA) |
+		BIT(PD_PIPE_DWN_ENA)) << 16;
+
+	pmu_bus_idle_con1 = 0;
+
+	mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, pwr_gate_con);
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, WRITE_MASK_SET(pmu_bus_idle_con0));
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, WRITE_MASK_SET(pmu_bus_idle_con1));
+
+	/* When perform idle operation,
+	 * corresponding clock can be opened or gated automatically
+	 */
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+	mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, WRITE_MASK_SET(BIT(VD_NPU_ENA)));
+
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(PWRDN_BYPASS)));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(BUS_BYPASS)));
+
+	INFO("PD & BUS:PMU_PWR_DWN_ST(0x%x):0x%x\n",
+	     PMU_PWR_DWN_ST, mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST));
+	INFO("PD & BUS:PMU_PWR_GATE_CON(0x%x):0x%x\n",
+	     PMU_PWR_GATE_CON, mmio_read_32(PMU_BASE + PMU_PWR_GATE_CON));
+	INFO("PD & BUS:PMU_BUS_IDLE_CON0(0x%x):0x%x\n",
+	     PMU_BUS_IDLE_CON0, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON0));
+	INFO("PD & BUS:PMU_BUS_IDLE_CON1(0x%x):0x%x\n",
+	     PMU_BUS_IDLE_CON1, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON1));
+	INFO("PD & BUS:PMU_PWR_CON(0x%x):0x%x\n",
+	     PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_ddr_suspend_config(void)
+{
+	uint32_t pmu_ddr_pwr_con;
+
+	pmu_ddr_pwr_con = BIT(DDR_SREF_ENA) |
+		BIT(DDRIO_RET_ENTER_ENA) |
+		BIT(DDRIO_RET_EXIT_ENA) |
+		BIT(DDRPHY_AUTO_GATING_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, WRITE_MASK_SET(pmu_ddr_pwr_con));
+	/* DPLL power down by PMU */
+	mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(BIT(DPLL_PD_ENA)));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DDR_BYPASS)));
+
+	grf_ddr_con3 = mmio_read_32(DDRGRF_BASE + GRF_DDR_CON3);
+
+	mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, 0x00600020);
+
+	pmu_ddr_pwr_con = mmio_read_32(PMU_BASE + PMU_DDR_PWR_CON);
+
+	INFO("DDR: PMU_PLLPD_CON(0x%x):0x%x\n",
+	     PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+	INFO("DDR: PMU_DDR_PWR_CON(0x%x):\t0x%x\n",
+	     PMU_DDR_PWR_CON, pmu_ddr_pwr_con);
+
+	if (pmu_ddr_pwr_con & BIT(DDR_SREF_ENA)) {
+		INFO("\t DDR_SREF_ENA\n");
+	}
+
+	if (pmu_ddr_pwr_con & BIT(DDRIO_RET_ENTER_ENA)) {
+		INFO("\t DDRIO_RET_ENTER_ENA\n");
+	}
+
+	if (pmu_ddr_pwr_con & BIT(DDRIO_RET_EXIT_ENA)) {
+		INFO("\t DDRIO_RET_EXIT_ENA\n");
+	}
+
+	if (pmu_ddr_pwr_con & BIT(DDRPHY_AUTO_GATING_ENA)) {
+		INFO("\t DDRPHY_AUTO_GATING_ENA\n");
+	}
+}
+
+static void pmu_dsu_suspend_config(void)
+{
+	uint32_t pmu_dsu_pwr_con;
+
+	pmu_dsu_pwr_con = BIT(DSU_PWRDN_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0x000f000f);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, WRITE_MASK_SET(pmu_dsu_pwr_con));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DSU_BYPASS)));
+	dsu_pwr_dwn();
+
+	INFO("DSU: PMU_DSU_PWR_CON(0x%x): 0x%x\n",
+	     PMU_DSU_PWR_CON, mmio_read_32(PMU_BASE + PMU_DSU_PWR_CON));
+	INFO("DSU: PMU_CLUSTER_IDLE_CON(0x%x),: 0x%x\n",
+	     PMU_CLUSTER_IDLE_CON,  mmio_read_32(PMU_BASE + PMU_CLUSTER_IDLE_CON));
+	INFO("DSU: PMU_PWR_CON(0x%x),: 0x%x\n",
+	     PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_cpu_powerdown_config(void)
+{
+	uint32_t pmu_cluster_pwr_st, cpus_state, cpus_bypass;
+
+	pmu_cluster_pwr_st = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+	cpus_state = pmu_cluster_pwr_st & 0x0f;
+
+	cpus_bypass = cpus_state << CPU0_BYPASS;
+
+	INFO("CPU: PMU_CLUSTER_PWR_ST(0x%x):0x%x\n",
+	     PMU_CLUSTER_PWR_ST, mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST));
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, (0xf << (16 + CPU0_BYPASS)) | cpus_bypass);
+
+	INFO("CPU: PMU_PWR_CON(0x%x), 0x%x\n",
+	     PMU_PWR_CON,  mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pvtm_32k_config(void)
+{
+	uint32_t pmu_cru_pwr_con;
+	uint32_t pvtm_freq_khz, pvtm_div;
+
+	mmio_write_32(PMUCRU_BASE + PMUCRU_PMUGATE_CON01, 0x38000000);
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00020002);
+	dsb();
+
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x001c0000);
+
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON1, PVTM_CALC_CNT);
+	dsb();
+
+	mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00010001);
+	dsb();
+
+	while (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) < 30) {
+		;
+	}
+
+	dsb();
+	while (!(mmio_read_32(PMUPVTM_BASE + PVTM_STATUS0) & 0x1)) {
+		;
+	}
+
+	pvtm_freq_khz = (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) * 24000 +
+		PVTM_CALC_CNT / 2) / PVTM_CALC_CNT;
+	pvtm_div = (pvtm_freq_khz + 16) / 32;
+
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_DLL_CON0, pvtm_div);
+
+	mmio_write_32(PMUCRU_BASE + PMUCRU_PMUCLKSEL_CON00, 0x00c00000);
+
+	pmu_cru_pwr_con = BIT(ALIVE_32K_ENA) | BIT(OSC_DIS_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 32000 * 10);
+
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+	INFO("PVTM: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+	     PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_cru_suspendmode_config(void)
+{
+	uint32_t pmu_cru_pwr_con;
+
+	pmu_cru_pwr_con = BIT(ALIVE_OSC_ENA);
+
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+	INFO("CRU: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+	     PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_suspend_cru_fsm(void)
+{
+	pmu_pmic_sleep_mode_config();
+
+	/* Global interrupt disable */
+	mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, CLB_INT_DISABLE);
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, CPUS_BYPASS);
+
+	pmu_stable_count_config();
+	pmu_wakeup_source_config();
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x5dc0 * 20000);
+	/* default cru config */
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(BIT(ALIVE_OSC_ENA)));
+
+	pmu_cru_suspendmode_config();
+	pmu_cpu_powerdown_config();
+	pmu_pll_powerdown_config();
+	pmu_pd_powerdown_config();
+	pmu_ddr_suspend_config();
+	pmu_dsu_suspend_config();
+	pvtm_32k_config();
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, 0x00010001);
+}
+
+static void pmu_reinit(void)
+{
+	mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, grf_ddr_con3 | 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, 0xffff0000);
+
+	mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, 0xffff0000);
+
+	mmio_write_32(PMU_BASE + PMU_PLLPD_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_INFO_TX_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0xffff0000);
+}
+
+void rockchip_plat_mmu_el3(void)
+{
+}
+
+int rockchip_soc_cores_pwr_dm_suspend(void)
+{
+	return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_resume(void)
+{
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+	psram_sleep_cfg->pm_flag = 0;
+	flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+			   sizeof(uint32_t));
+	pmu_suspend_cru_fsm();
+
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+	pmu_reinit();
+	plat_rockchip_gic_cpuif_enable();
+	psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+	flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+			   sizeof(uint32_t));
+
+	return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
+{
+	uint32_t apm_value, offset, idx;
+
+	apm_value = BIT(core_pm_en) | BIT(core_pm_int_wakeup_glb_msk);
+
+	if (pd_cfg == core_pwr_wfi_int) {
+		apm_value |= BIT(core_pm_int_wakeup_en);
+	}
+
+	idx = cpu_id / 2;
+	offset = (cpu_id % 2) << 3;
+
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      BITS_WITH_WMASK(apm_value, 0xf, offset));
+	dsb();
+
+	return 0;
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+	uint32_t offset, idx;
+
+	idx = cpu_id / 2;
+	offset = (cpu_id % 2) << 3;
+
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      WMSK_BIT(core_pm_en + offset));
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      BIT_WITH_WMSK(core_pm_sft_wakeup_en + offset));
+	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);
+
+	cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+	cpuson_entry_point[cpu_id] = entrypoint;
+	flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
+	flush_dcache_range((uintptr_t)cpuson_entry_point,
+			   sizeof(cpuson_entry_point));
+
+	cpus_power_domain_on(cpu_id);
+	return 0;
+}
+
+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 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+	uint32_t offset, idx;
+
+	/* Disable core_pm */
+	idx = cpu_id / 2;
+	offset = (cpu_id % 2) << 3;
+	mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+		      BITS_WITH_WMASK(0, 0xf, offset));
+
+	return 0;
+}
+
+static void nonboot_cpus_off(void)
+{
+	uint32_t tmp;
+
+	cpus_power_domain_off(1, 0);
+	cpus_power_domain_off(2, 0);
+	cpus_power_domain_off(3, 0);
+
+	mmio_write_32(SYSSRAM_BASE + 0x04, 0xdeadbeaf);
+	mmio_write_32(SYSSRAM_BASE + 0x08, (uintptr_t)&rockchip_soc_sys_pd_pwr_dn_wfi);
+	sev();
+
+	do {
+		tmp = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+	} while ((tmp & 0xe) != 0xe);
+}
+
+void plat_rockchip_pmu_init(void)
+{
+	uint32_t cpu;
+
+	rockchip_pd_lock_init();
+	nonboot_cpus_off();
+	for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+		cpuson_flags[cpu] = PMU_CPU_HOTPLUG;
+
+	psram_sleep_cfg->ddr_data = (uint64_t)0;
+	psram_sleep_cfg->sp = PSRAM_SP_TOP;
+	psram_sleep_cfg->ddr_flag = 0x00;
+	psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
+	psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+
+	/*
+	 * When perform idle operation, corresponding clock can be
+	 * opened or gated automatically.
+	 */
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+	/* grf_con_pmic_sleep_sel
+	 * pmic sleep function selection
+	 * 1'b0: From reset pulse generator, can reset external PMIC
+	 * 1'b1: From pmu block, only support sleep function for external PMIC
+	 */
+	mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), 0x00800080);
+
+	/*
+	 * force jtag control
+	 * 1'b0: CPU debug port IO mux is controlled by sdmmc_detect_en status
+	 * 1'b0: CPU debug port IO mux IS controlled by GRF
+	 */
+	mmio_write_32(SGRF_BASE + 0x008, 0x00100000);
+
+	/*
+	 * remap
+	 * 2'b00: Boot from boot-rom.
+	 * 2'b01: Boot from pmu mem.
+	 * 2'b10: Boot from sys mem.
+	 */
+	mmio_write_32(PMUSGRF_BASE + PMU_SGRF_SOC_CON1, 0x18000800);
+}
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.h b/plat/rockchip/rk3568/drivers/pmu/pmu.h
new file mode 100644
index 00000000..5821514b
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#define PMU_VERSION			0x0000
+#define PMU_PWR_CON			0x0004
+#define PMU_MAIN_PWR_STATE		0x0008
+#define PMU_INT_MASK_CON		0x000C
+#define PMU_WAKEUP_INT_CON		0x0010
+#define PMU_WAKEUP_INT_ST		0x0014
+#define PMU_WAKEUP_EDGE_CON		0x0018
+#define PMU_WAKEUP_EDGE_ST		0x001C
+#define PMU_BUS_IDLE_CON0		0x0040
+#define PMU_BUS_IDLE_CON1		0x0044
+#define PMU_BUS_IDLE_SFTCON0		0x0050
+#define PMU_BUS_IDLE_SFTCON1		0x0054
+#define PMU_BUS_IDLE_ACK		0x0060
+#define PMU_BUS_IDLE_ST			0x0068
+#define PMU_NOC_AUTO_CON0		0x0070
+#define PMU_NOC_AUTO_CON1		0x0074
+#define PMU_DDR_PWR_CON			0x0080
+#define PMU_DDR_PWR_SFTCON		0x0084
+#define PMU_DDR_PWR_STATE		0x0088
+#define PMU_DDR_PWR_ST			0x008C
+#define PMU_PWR_GATE_CON		0x0090
+#define PMU_PWR_GATE_STATE		0x0094
+#define PMU_PWR_DWN_ST			0x0098
+#define PMU_PWR_GATE_SFTCON		0x00A0
+#define PMU_VOL_GATE_SFTCON		0x00A8
+#define PMU_CRU_PWR_CON			0x00B0
+#define PMU_CRU_PWR_SFTCON		0x00B4
+#define PMU_CRU_PWR_STATE		0x00B8
+#define PMU_PLLPD_CON			0x00C0
+#define PMU_PLLPD_SFTCON		0x00C4
+#define PMU_INFO_TX_CON			0x00D0
+#define PMU_DSU_STABLE_CNT		0x0100
+#define PMU_PMIC_STABLE_CNT		0x0104
+#define PMU_OSC_STABLE_CNT		0x0108
+#define PMU_WAKEUP_RSTCLR_CNT		0x010C
+#define PMU_PLL_LOCK_CNT		0x0110
+#define PMU_DSU_PWRUP_CNT		0x0118
+#define PMU_DSU_PWRDN_CNT		0x011C
+#define PMU_GPU_VOLUP_CNT		0x0120
+#define PMU_GPU_VOLDN_CNT		0x0124
+#define PMU_WAKEUP_TIMEOUT_CNT		0x0128
+#define PMU_PWM_SWITCH_CNT		0x012C
+#define PMU_DBG_RST_CNT			0x0130
+#define PMU_SYS_REG0			0x0180
+#define PMU_SYS_REG1			0x0184
+#define PMU_SYS_REG2			0x0188
+#define PMU_SYS_REG3			0x018C
+#define PMU_SYS_REG4			0x0190
+#define PMU_SYS_REG5			0x0194
+#define PMU_SYS_REG6			0x0198
+#define PMU_SYS_REG7			0x019C
+#define PMU_DSU_PWR_CON			0x0300
+#define PMU_DSU_PWR_SFTCON		0x0304
+#define PMU_DSU_AUTO_CON		0x0308
+#define PMU_DSU_PWR_STATE		0x030C
+#define PMU_CPU_AUTO_PWR_CON0		0x0310
+#define PMU_CPU_AUTO_PWR_CON1		0x0314
+#define PMU_CPU_PWR_SFTCON		0x0318
+#define PMU_CLUSTER_PWR_ST		0x031C
+#define PMU_CLUSTER_IDLE_CON		0x0320
+#define PMU_CLUSTER_IDLE_SFTCON		0x0324
+#define PMU_CLUSTER_IDLE_ACK		0x0328
+#define PMU_CLUSTER_IDLE_ST		0x032C
+#define PMU_DBG_PWR_CON			0x0330
+
+/* PMU_SGRF */
+#define PMU_SGRF_SOC_CON1		0x0004
+#define PMU_SGRF_FAST_BOOT_ADDR		0x0180
+
+/* sys grf */
+#define GRF_CPU_STATUS0			0x0420
+
+#define CRU_SOFTRST_CON00		0x0400
+
+#define CORES_PM_DISABLE		0x0
+#define PD_CHECK_LOOP			500
+#define WFEI_CHECK_LOOP			500
+
+#define PMUSGRF_SOC_CON(i)		((i) * 0x4)
+/* Needed aligned 16 bytes for sp stack top */
+#define PSRAM_SP_TOP			((PMUSRAM_BASE + PMUSRAM_RSIZE) & ~0xf)
+#define PMU_CPUAPM_CON(cpu)		(0x0310 + (cpu) * 0x4)
+
+#define PMIC_SLEEP_FUN			0x07000100
+#define PMIC_SLEEP_GPIO			0x07000000
+#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 PMIC_SLEEP_HIGH_LEVEL		0x00040004
+#define PMIC_SLEEP_LOW_LEVEL		0x00040000
+#define PMIC_SLEEP_OUT			0x00040004
+#define CPUS_BYPASS			0x007e4f7e
+#define CLB_INT_DISABLE			0x00010001
+#define WRITE_MASK_SET(value)		((value << 16) | value)
+#define WRITE_MASK_CLR(value)		((value << 16))
+
+enum pmu_cores_pm_by_wfi {
+	core_pm_en = 0,
+	core_pm_int_wakeup_en,
+	core_pm_int_wakeup_glb_msk,
+	core_pm_sft_wakeup_en,
+};
+
+/* The ways of cores power domain contorlling */
+enum cores_pm_ctr_mode {
+	core_pwr_pd = 0,
+	core_pwr_wfi = 1,
+	core_pwr_wfi_int = 2
+};
+
+/* PMU_PWR_DWN_ST */
+enum pmu_pdid {
+	PD_GPU,
+	PD_NPU,
+	PD_VPU,
+	PD_RKVENC,
+	PD_RKVDEC,
+	PD_RGA,
+	PD_VI,
+	PD_VO,
+	PD_PIPE,
+	PD_CENTER,
+	PD_END
+};
+
+/* PMU_PWR_CON */
+enum pmu_pwr_con {
+	POWRMODE_EN,
+	DSU_BYPASS,
+	BUS_BYPASS = 4,
+	DDR_BYPASS,
+	PWRDN_BYPASS,
+	CRU_BYPASS,
+	CPU0_BYPASS,
+	CPU1_BYPASS,
+	CPU2_BYPASS,
+	CPU3_BYPASS,
+	PMU_SLEEP_LOW = 15,
+};
+
+/* PMU_CRU_PWR_CON */
+enum pmu_cru_pwr_con {
+	ALIVE_32K_ENA,
+	OSC_DIS_ENA,
+	WAKEUP_RST_ENA,
+	INPUT_CLAMP_ENA,
+
+	ALIVE_OSC_ENA,
+	POWER_OFF_ENA,
+	PWM_SWITCH_ENA,
+	PWM_GPIO_IOE_ENA,
+
+	PWM_SWITCH_IOUT,
+	PD_BUS_CLK_SRC_GATE_ENA,
+	PD_PERI_CLK_SRC_GATE_ENA,
+	PD_PMU_CLK_SRC_GATE_ENA,
+
+	PMUMEM_CLK_SRC_GATE_ENA,
+	PWR_CON_END
+};
+
+/* PMU_PLLPD_CON */
+enum pmu_pllpd_con {
+	APLL_PD_ENA,
+	DPLL_PD_ENA,
+	CPLL_PD_ENA,
+	GPLL_PD_ENA,
+	MPLL_PD_ENA,
+	NPLL_PD_ENA,
+	HPLL_PD_ENA,
+	PPLL_PD_ENA,
+	VPLL_PD_ENA,
+	PLL_PD_END
+};
+
+/* PMU_DSU_PWR_CON */
+enum pmu_dsu_pwr_con {
+	DSU_PWRDN_ENA = 2,
+	DSU_PWROFF_ENA,
+	DSU_RET_ENA = 6,
+	CLUSTER_CLK_SRC_GATE_ENA,
+	DSU_PWR_CON_END
+};
+
+enum cpu_power_state {
+	CPU_POWER_ON,
+	CPU_POWER_OFF,
+	CPU_EMULATION_OFF,
+	CPU_RETENTION,
+	CPU_DEBUG
+};
+
+enum dsu_power_state {
+	DSU_POWER_ON,
+	CLUSTER_TRANSFER_IDLE,
+	DSU_POWER_DOWN,
+	DSU_OFF,
+	DSU_WAKEUP,
+	DSU_POWER_UP,
+	CLUSTER_TRANSFER_RESUME,
+	DSU_FUNCTION_RETENTION
+};
+
+enum pmu_wakeup_int_con {
+	WAKEUP_CPU0_INT_EN,
+	WAKEUP_CPU1_INT_EN,
+	WAKEUP_CPU2_INT_EN,
+	WAKEUP_CPU3_INT_EN,
+	WAKEUP_GPIO0_INT_EN,
+	WAKEUP_UART0_EN,
+	WAKEUP_SDMMC0_EN,
+	WAKEUP_SDMMC1_EN,
+	WAKEUP_SDMMC2_EN,
+	WAKEUP_USB_EN,
+	WAKEUP_PCIE_EN,
+	WAKEUP_VAD_EN,
+	WAKEUP_TIMER_EN,
+	WAKEUP_PWM0_EN,
+	WAKEUP_TIMEROUT_EN,
+	WAKEUP_MCU_SFT_EN,
+};
+
+enum pmu_wakeup_int_st {
+	WAKEUP_CPU0_INT_ST,
+	WAKEUP_CPU1_INT_ST,
+	WAKEUP_CPU2_INT_ST,
+	WAKEUP_CPU3_INT_ST,
+	WAKEUP_GPIO0_INT_ST,
+	WAKEUP_UART0_ST,
+	WAKEUP_SDMMC0_ST,
+	WAKEUP_SDMMC1_ST,
+	WAKEUP_SDMMC2_ST,
+	WAKEUP_USB_ST,
+	WAKEUP_PCIE_ST,
+	WAKEUP_VAD_ST,
+	WAKEUP_TIMER_ST,
+	WAKEUP_PWM0_ST,
+	WAKEUP_TIMEOUT_ST,
+	WAKEUP_SYS_INT_ST,
+};
+
+enum pmu_bus_idle_con0 {
+	IDLE_REQ_MSCH,
+	IDLE_REQ_GPU,
+	IDLE_REQ_NPU,
+	IDLE_REQ_VI,
+	IDLE_REQ_VO,
+	IDLE_REQ_RGA,
+	IDLE_REQ_VPU,
+	IDLE_REQ_RKVENC,
+	IDLE_REQ_RKVDEC,
+	IDLE_REQ_GIC_AUDIO,
+	IDLE_REQ_PHP,
+	IDLE_REQ_PIPE,
+	IDLE_REQ_SECURE_FLASH,
+	IDLE_REQ_PERIMID,
+	IDLE_REQ_USB,
+	IDLE_REQ_BUS,
+};
+
+enum pmu_bus_idle_con1 {
+	IDLE_REQ_TOP1,
+	IDLE_REQ_TOP2,
+	IDLE_REQ_PMU,
+};
+
+enum pmu_pwr_gate_con {
+	PD_GPU_DWN_ENA,
+	PD_NPU_DWN_ENA,
+	PD_VPU_DWN_ENA,
+	PD_RKVENC_DWN_ENA,
+
+	PD_RKVDEC_DWN_ENA,
+	PD_RGA_DWN_ENA,
+	PD_VI_DWN_ENA,
+	PD_VO_DWN_ENA,
+
+	PD_PIPE_DWN_ENA,
+	PD_CENTER_DWN_ENA,
+};
+
+enum pmu_ddr_pwr_con {
+	DDR_SREF_ENA,
+	DDRIO_RET_ENTER_ENA,
+	DDRIO_RET_EXIT_ENA = 2,
+	DDRPHY_AUTO_GATING_ENA = 4,
+};
+
+enum pmu_vol_gate_soft_con {
+	VD_GPU_ENA,
+	VD_NPU_ENA,
+};
+
+#endif /* __PMU_H__ */
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.c b/plat/rockchip/rk3568/drivers/soc/soc.c
new file mode 100644
index 00000000..2af38873
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <mmio.h>
+#include <platform_def.h>
+
+#include <soc.h>
+
+const mmap_region_t plat_rk_mmap[] = {
+	MAP_REGION_FLAT(RKFPGA_DEV_RNG0_BASE, RKFPGA_DEV_RNG0_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+
+	{ 0 }
+};
+
+/* The RockChip power domain tree descriptor */
+const unsigned char rockchip_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	PLATFORM_SYSTEM_COUNT,
+	/* No of children for the root node */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of children for the first cluster node */
+	PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+static void secure_timer_init(void)
+{
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_DIS);
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+	/* auto reload & enable the timer */
+	mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_EN);
+}
+
+static void sgrf_init(void)
+{
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(0), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(1), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(2), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(3), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(4), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(5), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(6), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(7), 0xffff0000);
+	mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(8), 0xffff0000);
+
+	mmio_write_32(DDRSGRF_BASE + FIREWALL_DDR_FW_DDR_CON_REG, 0xffff0000);
+}
+
+static void set_pll_slow_mode(uint32_t clk_pll)
+{
+	mmio_write_32(CRU_BASE + CRU_MODE_CON00, 0x03 << (16 + clk_pll * 2));
+}
+
+static void __dead2 soc_global_soft_reset(void)
+{
+	set_pll_slow_mode(CLK_CPLL);
+	set_pll_slow_mode(CLK_GPLL);
+	set_pll_slow_mode(CLK_NPLL);
+	set_pll_slow_mode(CLK_VPLL);
+	set_pll_slow_mode(CLK_USBPLL);
+	set_pll_slow_mode(CLK_APLL);
+	mmio_write_32(PMUCRU_BASE + PMUCRU_MODE_CON00, 0x000f0000);
+
+	dsb();
+	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 excute valid codes.
+	 */
+	while (1) {
+		;
+	}
+}
+
+static void rockchip_system_reset_init(void)
+{
+	mmio_write_32(GRF_BASE + 0x0508, 0x00100010);
+	mmio_write_32(CRU_BASE + 0x00dc, 0x01030103);
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+	soc_global_soft_reset();
+}
+
+void plat_rockchip_soc_init(void)
+{
+	secure_timer_init();
+	sgrf_init();
+	rockchip_system_reset_init();
+	NOTICE("BL31: Rockchip release version: v%d.%d\n",
+		MAJOR_VERSION, MINOR_VERSION);
+}
+
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.h b/plat/rockchip/rk3568/drivers/soc/soc.h
new file mode 100644
index 00000000..41a2586a
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SOC_H__
+#define __SOC_H__
+
+#define RKFPGA_DEV_RNG0_BASE		0xf8000000
+#define RKFPGA_DEV_RNG0_SIZE		0x07fff000
+
+#define CRU_MODE_CON00			0x00c0
+#define PMUCRU_MODE_CON00		0x0080
+
+#define CRU_GLB_SRST_FST		0x00d4
+#define GLB_SRST_FST_CFG_VAL		0xfdb9
+
+#define PMU_GRF_GPIO0A_IOMUX_L		0x00
+#define PMU_GRF_SOC_CON(i)		(0x0100 + i * 4)
+
+#define CRU_SOFTRST_CON			0x300
+#define CRU_SOFTRSTS_CON(n)		(CRU_SOFTRST_CON + ((n) * 4))
+#define CRU_SOFTRSTS_CON_CNT		26
+#define GRF_DDR_CON3			0x000c
+#define SGRF_FIREWALL_SLV_CON(i)	(0x240 + i * 4)
+
+#define FIREWALL_DDR_FW_DDR_CON_REG	0x80
+
+ /* low 32 bits */
+#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 STIMER0_CHN_BASE(n)		(STIME_BASE + 0x20 * (n))
+
+#define PMU_GRF_GPIO0B_IOMUX_L		0x0008
+#define PMUCRU_PMUCLKSEL_CON00		0x0100
+#define PMUPVTM_BASE			0xfdd80000
+#define PVTM_CON0			0x0004
+#define PVTM_CON1			0x0008
+#define PVTM_STATUS0			0x0080
+#define PVTM_STATUS1			0x0084
+#define PMUCRU_PMUGATE_CON01		0x0184
+#define PVTM_CALC_CNT			0x200
+#define PMU_GRF_DLL_CON0		0x0180
+
+enum cru_mode_con00 {
+	CLK_APLL,
+	CLK_DPLL,
+	CLK_CPLL,
+	CLK_GPLL,
+	CLK_REVSERVED,
+	CLK_NPLL,
+	CLK_VPLL,
+	CLK_USBPLL,
+};
+
+#endif /* __SOC_H__ */
diff --git a/plat/rockchip/rk3568/include/plat.ld.S b/plat/rockchip/rk3568/include/plat.ld.S
new file mode 100644
index 00000000..ddd584d4
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat.ld.S
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#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
+	 */
+	.pmusram : {
+		ASSERT(. == ALIGN(64 * 1024),
+			".pmusram.entry request 64K aligned.");
+		KEEP(*(.pmusram.entry))
+
+		__bl31_pmusram_text_start = .;
+		*(.pmusram.text)
+		*(.pmusram.rodata)
+		__bl31_pmusram_text_end = .;
+		__bl31_pmusram_data_start = .;
+		*(.pmusram.data)
+		__bl31_pmusram_data_end = .;
+	} >PMUSRAM
+}
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3568/include/plat_sip_calls.h b/plat/rockchip/rk3568/include/plat_sip_calls.h
new file mode 100644
index 00000000..6acb8762
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat_sip_calls.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_SIP_CALLS_H__
+#define __PLAT_SIP_CALLS_H__
+
+#define RK_PLAT_SIP_NUM_CALLS	0
+
+#endif /* __PLAT_SIP_CALLS_H__ */
diff --git a/plat/rockchip/rk3568/include/platform_def.h b/plat/rockchip/rk3568/include/platform_def.h
new file mode 100644
index 00000000..19363a42
--- /dev/null
+++ b/plat/rockchip/rk3568/include/platform_def.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <rk3568_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		1
+#define PLATFORM_CLUSTER0_CORE_COUNT	4
+
+#define PLATFORM_CLUSTER1_CORE_COUNT	0
+#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	8
+
+/*
+ * 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		(0x0)
+#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 a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+
+#define PLAT_RK_GICV3_G1S_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+		       INTR_GROUP1S, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_GICV3_G0_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+		       INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_UART_BASE		FPGA_UART_BASE
+#define PLAT_RK_UART_CLOCK		FPGA_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE	FPGA_BAUDRATE
+
+#define PLAT_RK_PRIMARY_CPU	0x0
+
+#define ATAGS_PHYS_SIZE		0x2000
+#define ATAGS_PHYS_BASE		(0x200000 - ATAGS_PHYS_SIZE)/* [2M-8K, 2M] */
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/rockchip/rk3568/plat_sip_calls.c b/plat/rockchip/rk3568/plat_sip_calls.c
new file mode 100644
index 00000000..b0f3a03d
--- /dev/null
+++ b/plat/rockchip/rk3568/plat_sip_calls.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_sip_calls.h>
+#include <rockchip_sip_svc.h>
+
+uintptr_t rockchip_plat_sip_handler(uint32_t smc_fid,
+				    u_register_t x1,
+				    u_register_t x2,
+				    u_register_t x3,
+				    u_register_t x4,
+				    void *cookie,
+				    void *handle,
+				    u_register_t flags)
+{
+	ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+	SMC_RET1(handle, SMC_UNK);
+}
diff --git a/plat/rockchip/rk3568/platform.mk b/plat/rockchip/rk3568/platform.mk
new file mode 100644
index 00000000..1155ff84
--- /dev/null
+++ b/plat/rockchip/rk3568/platform.mk
@@ -0,0 +1,96 @@
+#
+# Copyright (c) 2023, 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
+GICV3_SUPPORT_GIC600	:=	1
+include lib/coreboot/coreboot.mk
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+# GIC-600 configuration
+GICV3_IMPL		:=	GIC600
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+PLAT_INCLUDES		:=	-Iinclude/bl31					\
+				-Iinclude/common				\
+				-Iinclude/drivers				\
+				-Iinclude/drivers/arm				\
+				-Iinclude/drivers/auth				\
+				-Iinclude/drivers/io				\
+				-Iinclude/drivers/ti/uart			\
+				-Iinclude/lib					\
+				-Iinclude/lib/cpus/${ARCH}			\
+				-Iinclude/lib/el3_runtime			\
+				-Iinclude/lib/pmf				\
+				-Iinclude/lib/psci				\
+				-Iinclude/plat/common				\
+				-Iinclude/services				\
+				-Iinclude/plat/common/				\
+				-Idrivers/arm/gic/v3/				\
+				-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_SOC}/				\
+				-I${RK_PLAT_SOC}/drivers/pmu/			\
+				-I${RK_PLAT_SOC}/drivers/soc/			\
+				-I${RK_PLAT_SOC}/include/
+
+RK_GIC_SOURCES		:=	${GICV3_SOURCES}				\
+				plat/common/plat_gicv3.c			\
+				${RK_PLAT}/common/rockchip_gicv3.c
+
+PLAT_BL_COMMON_SOURCES	:=	${XLAT_TABLES_LIB_SRCS}				\
+				common/desc_image_load.c			\
+				plat/common/aarch64/crash_console_helpers.S	\
+				lib/bl_aux_params/bl_aux_params.c		\
+				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				\
+				lib/cpus/aarch64/cortex_a55.S			\
+				drivers/ti/uart/aarch64/16550_console.S		\
+				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
+				$(LIBFDT_SRCS)					\
+				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
+				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
+				${RK_PLAT_COMMON}/params_setup.c		\
+				${RK_PLAT_COMMON}/plat_pm.c			\
+				${RK_PLAT_COMMON}/plat_topology.c		\
+				${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
+				${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S	\
+				${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c	\
+				${RK_PLAT_COMMON}/aarch64/platform_common.c	\
+				${RK_PLAT_SOC}/drivers/soc/soc.c		\
+				${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
+				${RK_PLAT_SOC}/plat_sip_calls.c
+
+ENABLE_PLAT_COMPAT	:=	0
+MULTI_CONSOLE_API	:=	1
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY	:=	1
+#Enable errata for cortex_a55
+ERRATA_A55_1530923	:=	1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM	:=	0
+
+$(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS	:=	0
diff --git a/plat/rockchip/rk3568/rk3568_def.h b/plat/rockchip/rk3568/rk3568_def.h
new file mode 100644
index 00000000..0d1e5d1a
--- /dev/null
+++ b/plat/rockchip/rk3568/rk3568_def.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_DEF_H__
+#define __PLAT_DEF_H__
+
+#define MAJOR_VERSION		(1)
+#define MINOR_VERSION		(0)
+
+#define SIZE_K(n)		((n) * 1024)
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define RK_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
+
+#define GIC600_BASE		0xfd400000
+#define GIC600_SIZE		SIZE_K(64)
+
+#define PMUSGRF_BASE		0xfdc00000
+#define SYSSGRF_BASE		0xfdc10000
+#define PMUGRF_BASE		0xfdc20000
+#define CPUGRF_BASE		0xfdc30000
+#define DDRGRF_BASE		0xfdc40000
+#define PIPEGRF_BASE		0xfdc50000
+#define GRF_BASE		0xfdc60000
+#define PIPEPHY_GRF0		0xfdc70000
+#define PIPEPHY_GRF1		0xfdc80000
+#define PIPEPHY_GRF2		0xfdc90000
+#define USBPHY_U3_GRF		0xfdca0000
+#define USB2PHY_U2_GRF		0xfdca8000
+#define EDPPHY_GRF		0xfdcb0000
+#define SYSSRAM_BASE		0xfdcc0000
+#define PCIE30PHY_GRF		0xfdcb8000
+#define USBGRF_BASE		0xfdcf0000
+
+#define PMUCRU_BASE		0xfdd00000
+#define SCRU_BASE		0xfdd10000
+#define SGRF_BASE		0xfdd18000
+#define STIME_BASE		0xfdd1c000
+#define CRU_BASE		0xfdd20000
+#define PMUSCRU_BASE		0xfdd30000
+#define I2C0_BASE		0xfdd40000
+
+#define UART0_BASE		0xfdd50000
+#define GPIO0_BASE		0xfdd60000
+#define PMUPVTM_BASE		0xfdd80000
+#define PMU_BASE		0xfdd90000
+#define PMUSRAM_BASE		0xfdcd0000
+#define PMUSRAM_SIZE		SIZE_K(128)
+#define PMUSRAM_RSIZE		SIZE_K(8)
+
+#define DDRSGRF_BASE		0xfe200000
+#define UART1_BASE		0xfe650000
+#define UART2_BASE		0xfe660000
+#define GPIO1_BASE		0xfe740000
+#define GPIO2_BASE		0xfe750000
+#define GPIO3_BASE		0xfe760000
+#define GPIO4_BASE		0xfe770000
+
+#define REMAP_BASE		0xffff0000
+#define REMAP_SIZE		SIZE_K(64)
+/**************************************************************************
+ * UART related constants
+ **************************************************************************/
+#define FPGA_UART_BASE		UART2_BASE
+#define FPGA_BAUDRATE		1500000
+#define FPGA_UART_CLOCK		24000000
+
+/******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_TICKS	24000000
+#define SYS_COUNTER_FREQ_IN_MHZ		24
+
+/******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+
+/* Base rk_platform compatible GIC memory map */
+#define PLAT_GICD_BASE		GIC600_BASE
+#define PLAT_GICC_BASE		0
+#define PLAT_GICR_BASE		(GIC600_BASE + 0x60000)
+
+/******************************************************************************
+ * 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 SHARE_MEM_BASE		0x100000/* [1MB, 1MB+60K]*/
+#define SHARE_MEM_PAGE_NUM	15
+#define SHARE_MEM_SIZE		SIZE_K(SHARE_MEM_PAGE_NUM * 4)
+
+#endif /* __PLAT_DEF_H__ */
diff --git a/plat/rockchip/rk3588/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3588/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 00000000..c2788997
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#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/rk3588/drivers/pmu/pm_pd_regs.c b/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.c
new file mode 100644
index 00000000..78e85004
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.c
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#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 <soc.h>
+
+#define WMSK_VAL		0xffff0000
+
+static struct reg_region qos_reg_rgns[] = {
+	[QOS_ISP0_MWO] = REG_REGION(0x08, 0x18, 4, 0xfdf40500, 0),
+	[QOS_ISP0_MRO] = REG_REGION(0x08, 0x18, 4, 0xfdf40400, 0),
+	[QOS_ISP1_MWO] = REG_REGION(0x08, 0x18, 4, 0xfdf41000, 0),
+	[QOS_ISP1_MRO] = REG_REGION(0x08, 0x18, 4, 0xfdf41100, 0),
+	[QOS_VICAP_M0] = REG_REGION(0x08, 0x18, 4, 0xfdf40600, 0),
+	[QOS_VICAP_M1] = REG_REGION(0x08, 0x18, 4, 0xfdf40800, 0),
+	[QOS_FISHEYE0] = REG_REGION(0x08, 0x18, 4, 0xfdf40000, 0),
+	[QOS_FISHEYE1] = REG_REGION(0x08, 0x18, 4, 0xfdf40200, 0),
+	[QOS_VOP_M0] = REG_REGION(0x08, 0x18, 4, 0xfdf82000, 0),
+	[QOS_VOP_M1] = REG_REGION(0x08, 0x18, 4, 0xfdf82200, 0),
+	[QOS_RKVDEC0] = REG_REGION(0x08, 0x18, 4, 0xfdf62000, 0),
+	[QOS_RKVDEC1] = REG_REGION(0x08, 0x18, 4, 0xfdf63000, 0),
+	[QOS_AV1] = REG_REGION(0x08, 0x18, 4, 0xfdf64000, 0),
+	[QOS_RKVENC0_M0RO] = REG_REGION(0x08, 0x18, 4, 0xfdf60000, 0),
+	[QOS_RKVENC0_M1RO] = REG_REGION(0x08, 0x18, 4, 0xfdf60200, 0),
+	[QOS_RKVENC0_M2WO] = REG_REGION(0x08, 0x18, 4, 0xfdf60400, 0),
+	[QOS_RKVENC1_M0RO] = REG_REGION(0x08, 0x18, 4, 0xfdf61000, 0),
+	[QOS_RKVENC1_M1RO] = REG_REGION(0x08, 0x18, 4, 0xfdf61200, 0),
+	[QOS_RKVENC1_M2WO] = REG_REGION(0x08, 0x18, 4, 0xfdf61400, 0),
+	[QOS_DSU_M0] = REG_REGION(0x08, 0x18, 4, 0xfe008000, 0),
+	[QOS_DSU_M1] = REG_REGION(0x08, 0x18, 4, 0xfe008800, 0),
+	[QOS_DSU_MP] = REG_REGION(0x08, 0x18, 4, 0xfdf34200, 0),
+	[QOS_DEBUG] = REG_REGION(0x08, 0x18, 4, 0xfdf34400, 0),
+	[QOS_GPU_M0] = REG_REGION(0x08, 0x18, 4, 0xfdf35000, 0),
+	[QOS_GPU_M1] = REG_REGION(0x08, 0x18, 4, 0xfdf35200, 0),
+	[QOS_GPU_M2] = REG_REGION(0x08, 0x18, 4, 0xfdf35400, 0),
+	[QOS_GPU_M3] = REG_REGION(0x08, 0x18, 4, 0xfdf35600, 0),
+	[QOS_NPU1] = REG_REGION(0x08, 0x18, 4, 0xfdf70000, 0),
+	[QOS_NPU0_MRO] = REG_REGION(0x08, 0x18, 4, 0xfdf72200, 0),
+	[QOS_NPU2] = REG_REGION(0x08, 0x18, 4, 0xfdf71000, 0),
+	[QOS_NPU0_MWR] = REG_REGION(0x08, 0x18, 4, 0xfdf72000, 0),
+	[QOS_MCU_NPU] = REG_REGION(0x08, 0x18, 4, 0xfdf72400, 0),
+	[QOS_JPEG_DEC] = REG_REGION(0x08, 0x18, 4, 0xfdf66200, 0),
+	[QOS_JPEG_ENC0] = REG_REGION(0x08, 0x18, 4, 0xfdf66400, 0),
+	[QOS_JPEG_ENC1] = REG_REGION(0x08, 0x18, 4, 0xfdf66600, 0),
+	[QOS_JPEG_ENC2] = REG_REGION(0x08, 0x18, 4, 0xfdf66800, 0),
+	[QOS_JPEG_ENC3] = REG_REGION(0x08, 0x18, 4, 0xfdf66a00, 0),
+	[QOS_RGA2_MRO] = REG_REGION(0x08, 0x18, 4, 0xfdf66c00, 0),
+	[QOS_RGA2_MWO] = REG_REGION(0x08, 0x18, 4, 0xfdf66e00, 0),
+	[QOS_RGA3_0] = REG_REGION(0x08, 0x18, 4, 0xfdf67000, 0),
+	[QOS_RGA3_1] = REG_REGION(0x08, 0x18, 4, 0xfdf36000, 0),
+	[QOS_VDPU] = REG_REGION(0x08, 0x18, 4, 0xfdf67200, 0),
+	[QOS_IEP] = REG_REGION(0x08, 0x18, 4, 0xfdf66000, 0),
+	[QOS_HDCP0] = REG_REGION(0x08, 0x18, 4, 0xfdf80000, 0),
+	[QOS_HDCP1] = REG_REGION(0x08, 0x18, 4, 0xfdf81000, 0),
+	[QOS_HDMIRX] = REG_REGION(0x08, 0x18, 4, 0xfdf81200, 0),
+	[QOS_GIC600_M0] = REG_REGION(0x08, 0x18, 4, 0xfdf3a000, 0),
+	[QOS_GIC600_M1] = REG_REGION(0x08, 0x18, 4, 0xfdf3a200, 0),
+	[QOS_MMU600PCIE_TCU] = REG_REGION(0x08, 0x18, 4, 0xfdf3a400, 0),
+	[QOS_MMU600PHP_TBU] = REG_REGION(0x08, 0x18, 4, 0xfdf3a600, 0),
+	[QOS_MMU600PHP_TCU] = REG_REGION(0x08, 0x18, 4, 0xfdf3a800, 0),
+	[QOS_USB3_0] = REG_REGION(0x08, 0x18, 4, 0xfdf3e200, 0),
+	[QOS_USB3_1] = REG_REGION(0x08, 0x18, 4, 0xfdf3e000, 0),
+	[QOS_USBHOST_0] = REG_REGION(0x08, 0x18, 4, 0xfdf3e400, 0),
+	[QOS_USBHOST_1] = REG_REGION(0x08, 0x18, 4, 0xfdf3e600, 0),
+	[QOS_EMMC] = REG_REGION(0x08, 0x18, 4, 0xfdf38200, 0),
+	[QOS_FSPI] = REG_REGION(0x08, 0x18, 4, 0xfdf38000, 0),
+	[QOS_SDIO] = REG_REGION(0x08, 0x18, 4, 0xfdf39000, 0),
+	[QOS_DECOM] = REG_REGION(0x08, 0x18, 4, 0xfdf32000, 0),
+	[QOS_DMAC0] = REG_REGION(0x08, 0x18, 4, 0xfdf32200, 0),
+	[QOS_DMAC1] = REG_REGION(0x08, 0x18, 4, 0xfdf32400, 0),
+	[QOS_DMAC2] = REG_REGION(0x08, 0x18, 4, 0xfdf32600, 0),
+	[QOS_GIC600M] = REG_REGION(0x08, 0x18, 4, 0xfdf32800, 0),
+	[QOS_DMA2DDR] = REG_REGION(0x08, 0x18, 4, 0xfdf52000, 0),
+	[QOS_MCU_DDR] = REG_REGION(0x08, 0x18, 4, 0xfdf52200, 0),
+	[QOS_VAD] = REG_REGION(0x08, 0x18, 4, 0xfdf3b200, 0),
+	[QOS_MCU_PMU] = REG_REGION(0x08, 0x18, 4, 0xfdf3b000, 0),
+	[QOS_CRYPTOS] = REG_REGION(0x08, 0x18, 4, 0xfdf3d200, 0),
+	[QOS_CRYPTONS] = REG_REGION(0x08, 0x18, 4, 0xfdf3d000, 0),
+	[QOS_DCF] = REG_REGION(0x08, 0x18, 4, 0xfdf3d400, 0),
+	[QOS_SDMMC] = REG_REGION(0x08, 0x18, 4, 0xfdf3d800, 0),
+};
+
+static struct reg_region pd_crypto_reg_rgns[] = {
+	/* SECURE CRU */
+	REG_REGION(0x300, 0x30c, 4, SCRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x80c, 4, SCRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa0c, 4, SCRU_BASE, WMSK_VAL),
+	REG_REGION(0xd00, 0xd20, 8, SCRU_BASE, 0),
+	REG_REGION(0xd04, 0xd24, 8, SCRU_BASE, WMSK_VAL),
+
+	/* S TIMER0 6 channel */
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x00, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x00, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x20, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x20, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x40, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x40, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x60, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x60, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0x80, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0x80, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER0_BASE + 0xa0, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER0_BASE + 0xa0, 0),
+
+	/* S TIMER1 6 channel */
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x00, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x00, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x20, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x20, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x40, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x40, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x60, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x60, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0x80, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0x80, 0),
+	REG_REGION(0x00, 0x04, 4, STIMER1_BASE + 0xa0, 0),
+	REG_REGION(0x10, 0x10, 4, STIMER1_BASE + 0xa0, 0),
+
+	/* wdt_s */
+	REG_REGION(0x04, 0x04, 4, WDT_S_BASE, 0),
+	REG_REGION(0x00, 0x00, 4, WDT_S_BASE, 0),
+};
+
+static struct reg_region pd_dsu_reg_rgns[] = {
+	/* dsucru */
+	REG_REGION(0x040, 0x054, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0x300, 0x31c, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x80c, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa0c, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0xd00, 0xd20, 8, DSUCRU_BASE, 0),
+	REG_REGION(0xd04, 0xd24, 8, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0xf00, 0xf00, 4, DSUCRU_BASE, WMSK_VAL),
+	REG_REGION(0xf10, 0xf1c, 4, DSUCRU_BASE, 0),
+
+	/* bcore0cru */
+	REG_REGION(0x000, 0x014, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+	REG_REGION(0x300, 0x304, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x804, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa04, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+	REG_REGION(0xcc0, 0xcc4, 4, BIGCORE0CRU_BASE, 0),
+	REG_REGION(0xd00, 0xd00, 4, BIGCORE0CRU_BASE, 0),
+	REG_REGION(0xd04, 0xd04, 4, BIGCORE0CRU_BASE, WMSK_VAL),
+
+	/* bcore1cru */
+	REG_REGION(0x020, 0x034, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+	REG_REGION(0x300, 0x304, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x804, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa04, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+	REG_REGION(0xcc0, 0xcc4, 4, BIGCORE1CRU_BASE, 0),
+	REG_REGION(0xd00, 0xd00, 4, BIGCORE1CRU_BASE, 0),
+	REG_REGION(0xd04, 0xd04, 4, BIGCORE1CRU_BASE, WMSK_VAL),
+
+	/* dsugrf */
+	REG_REGION(0x00, 0x18, 4, DSUGRF_BASE, WMSK_VAL),
+	REG_REGION(0x20, 0x20, 4, DSUGRF_BASE, WMSK_VAL),
+	REG_REGION(0x28, 0x30, 4, DSUGRF_BASE, WMSK_VAL),
+	REG_REGION(0x38, 0x38, 4, DSUGRF_BASE, WMSK_VAL),
+
+	/* lcore_grf */
+	REG_REGION(0x20, 0x20, 4, LITCOREGRF_BASE, WMSK_VAL),
+	REG_REGION(0x28, 0x30, 4, LITCOREGRF_BASE, WMSK_VAL),
+
+	/* bcore0_grf */
+	REG_REGION(0x20, 0x20, 4, BIGCORE0GRF_BASE, WMSK_VAL),
+	REG_REGION(0x28, 0x30, 4, BIGCORE0GRF_BASE, WMSK_VAL),
+
+	/* bcore1_grf */
+	REG_REGION(0x20, 0x20, 4, BIGCORE1GRF_BASE, WMSK_VAL),
+	REG_REGION(0x28, 0x28, 4, BIGCORE1GRF_BASE, WMSK_VAL),
+};
+
+static struct reg_region pd_php_reg_rgns[] = {
+	/* php_grf */
+	REG_REGION(0x000, 0x008, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x014, 0x024, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x028, 0x02c, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x030, 0x03c, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x05c, 0x060, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x064, 0x068, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x070, 0x070, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x074, 0x0d0, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x0d4, 0x0d4, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x0e0, 0x0e0, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x0e4, 0x0ec, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x100, 0x104, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x10c, 0x130, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x138, 0x138, 4, PHPGRF_BASE, WMSK_VAL),
+	REG_REGION(0x144, 0x168, 4, PHPGRF_BASE, 0),
+	REG_REGION(0x16c, 0x174, 4, PHPGRF_BASE, WMSK_VAL),
+
+	/* php_cru */
+	REG_REGION(0x200, 0x218, 4, PHP_CRU_BASE, WMSK_VAL),
+	REG_REGION(0x800, 0x800, 4, PHP_CRU_BASE, WMSK_VAL),
+	REG_REGION(0xa00, 0xa00, 4, PHP_CRU_BASE, WMSK_VAL),
+
+	/* pcie3phy_grf_cmn_con0 */
+	REG_REGION(0x00, 0x00, 4, PCIE3PHYGRF_BASE, WMSK_VAL),
+};
+
+void qos_save(void)
+{
+	uint32_t pmu_pd_st0 = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(0));
+
+	if ((pmu_pd_st0 & BIT(PD_GPU)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GPU_M0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GPU_M1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GPU_M2], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GPU_M3], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_NPU1)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_NPU1], 1);
+	if ((pmu_pd_st0 & BIT(PD_NPU2)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_NPU2], 1);
+	if ((pmu_pd_st0 & BIT(PD_NPUTOP)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_NPU0_MRO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_NPU0_MWR], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_MCU_NPU], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RKVDEC1)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVDEC1], 1);
+	if ((pmu_pd_st0 & BIT(PD_RKVDEC0)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVDEC0], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_VENC1)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC1_M0RO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC1_M1RO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC1_M2WO], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VENC0)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC0_M0RO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC0_M1RO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RKVENC0_M2WO], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RGA30)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RGA3_0], 1);
+	if ((pmu_pd_st0 & BIT(PD_AV1)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_AV1], 1);
+	if ((pmu_pd_st0 & BIT(PD_VDPU)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_DEC], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_ENC0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_ENC1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_ENC2], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_JPEG_ENC3], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RGA2_MRO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RGA2_MWO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VDPU], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_IEP], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_VO0)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_HDCP0], 1);
+	if ((pmu_pd_st0 & BIT(PD_VO1)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_HDCP1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_HDMIRX], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VOP)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VOP_M0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VOP_M1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_FEC)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_FISHEYE0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_FISHEYE1], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_ISP1)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_ISP1_MWO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_ISP1_MRO], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VI)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_ISP0_MWO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_ISP0_MRO], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VICAP_M0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_VICAP_M1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RGA31)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_RGA3_1], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_USB)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_USB3_0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_USB3_1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_USBHOST_0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_USBHOST_1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_PHP)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GIC600_M0], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_GIC600_M1], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_MMU600PCIE_TCU], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_MMU600PHP_TBU], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_MMU600PHP_TCU], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_SDIO)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_SDIO], 1);
+	if ((pmu_pd_st0 & BIT(PD_NVM0)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_FSPI], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_EMMC], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_SDMMC)) == 0)
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_SDMMC], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_CRYPTO)) == 0) {
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_CRYPTONS], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_CRYPTOS], 1);
+		rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DCF], 1);
+	}
+
+	/* PD_DSU */
+	rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DSU_M0], 1);
+	rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DSU_M1], 1);
+	rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DSU_MP], 1);
+	rockchip_reg_rgn_save(&qos_reg_rgns[QOS_DEBUG], 1);
+}
+
+void qos_restore(void)
+{
+	uint32_t pmu_pd_st0 = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(0));
+
+	if ((pmu_pd_st0 & BIT(PD_GPU)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GPU_M0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GPU_M1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GPU_M2], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GPU_M3], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_NPU1)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_NPU1], 1);
+	if ((pmu_pd_st0 & BIT(PD_NPU2)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_NPU2], 1);
+	if ((pmu_pd_st0 & BIT(PD_NPUTOP)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_NPU0_MRO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_NPU0_MWR], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_MCU_NPU], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RKVDEC1)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVDEC1], 1);
+	if ((pmu_pd_st0 & BIT(PD_RKVDEC0)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVDEC0], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_VENC1)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC1_M0RO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC1_M1RO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC1_M2WO], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VENC0)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC0_M0RO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC0_M1RO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RKVENC0_M2WO], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RGA30)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RGA3_0], 1);
+	if ((pmu_pd_st0 & BIT(PD_AV1)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_AV1], 1);
+	if ((pmu_pd_st0 & BIT(PD_VDPU)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_DEC], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_ENC0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_ENC1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_ENC2], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_JPEG_ENC3], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RGA2_MRO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RGA2_MWO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VDPU], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_IEP], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_VO0)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_HDCP0], 1);
+	if ((pmu_pd_st0 & BIT(PD_VO1)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_HDCP1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_HDMIRX], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VOP)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VOP_M0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VOP_M1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_FEC)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_FISHEYE0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_FISHEYE1], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_ISP1)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_ISP1_MWO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_ISP1_MRO], 1);
+	}
+	if ((pmu_pd_st0 & BIT(PD_VI)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_ISP0_MWO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_ISP0_MRO], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VICAP_M0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_VICAP_M1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_RGA31)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_RGA3_1], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_USB)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_USB3_0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_USB3_1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_USBHOST_0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_USBHOST_1], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_PHP)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GIC600_M0], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_GIC600_M1], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_MMU600PCIE_TCU], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_MMU600PHP_TBU], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_MMU600PHP_TCU], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_SDIO)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_SDIO], 1);
+	if ((pmu_pd_st0 & BIT(PD_NVM0)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_FSPI], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_EMMC], 1);
+	}
+
+	if ((pmu_pd_st0 & BIT(PD_SDMMC)) == 0)
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_SDMMC], 1);
+
+	if ((pmu_pd_st0 & BIT(PD_CRYPTO)) == 0) {
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_CRYPTONS], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_CRYPTOS], 1);
+		rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DCF], 1);
+	}
+
+	/* PD_DSU */
+	rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DSU_M0], 1);
+	rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DSU_M1], 1);
+	rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DSU_MP], 1);
+	rockchip_reg_rgn_restore(&qos_reg_rgns[QOS_DEBUG], 1);
+}
+
+void pd_crypto_save(void)
+{
+	rockchip_reg_rgn_save(pd_crypto_reg_rgns, ARRAY_SIZE(pd_crypto_reg_rgns));
+}
+
+void pd_crypto_restore(void)
+{
+	rockchip_reg_rgn_restore(pd_crypto_reg_rgns, ARRAY_SIZE(pd_crypto_reg_rgns));
+}
+
+static uint32_t b0_cru_mode;
+static uint32_t b1_cru_mode;
+static uint32_t dsu_cru_mode;
+static uint32_t bcore0_cru_sel_con2, bcore1_cru_sel_con2;
+
+void pd_dsu_core_save(void)
+{
+	b0_cru_mode = mmio_read_32(BIGCORE0CRU_BASE + 0x280);
+	b1_cru_mode = mmio_read_32(BIGCORE1CRU_BASE + 0x280);
+	dsu_cru_mode = mmio_read_32(DSUCRU_BASE + 0x280);
+	bcore0_cru_sel_con2 = mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2));
+	bcore1_cru_sel_con2 = mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2));
+
+	rockchip_reg_rgn_save(pd_dsu_reg_rgns, ARRAY_SIZE(pd_dsu_reg_rgns));
+}
+
+void pd_dsu_core_restore(void)
+{
+	/* switch bcore0/1 pclk root to 24M */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(2, 0x3, 0));
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(2, 0x3, 0));
+
+	/* slow mode */
+	mmio_write_32(BIGCORE0CRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(BIGCORE1CRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(DSUCRU_BASE + 0x280, 0x00030000);
+
+	rockchip_reg_rgn_restore(pd_dsu_reg_rgns, ARRAY_SIZE(pd_dsu_reg_rgns));
+
+	/* trigger dsu/lcore/bcore mem_cfg */
+	mmio_write_32(DSUGRF_BASE + 0x18, BITS_WITH_WMASK(1, 0x1, 14));
+	mmio_write_32(LITCOREGRF_BASE + 0x30, BITS_WITH_WMASK(1, 0x1, 5));
+	mmio_write_32(BIGCORE0GRF_BASE + 0x30, BITS_WITH_WMASK(1, 0x1, 5));
+	mmio_write_32(BIGCORE1GRF_BASE + 0x30, BITS_WITH_WMASK(1, 0x1, 5));
+	udelay(1);
+	mmio_write_32(DSUGRF_BASE + 0x18, BITS_WITH_WMASK(0, 0x1, 14));
+	mmio_write_32(LITCOREGRF_BASE + 0x30, BITS_WITH_WMASK(0, 0x1, 5));
+	mmio_write_32(BIGCORE0GRF_BASE + 0x30, BITS_WITH_WMASK(0, 0x1, 5));
+	mmio_write_32(BIGCORE1GRF_BASE + 0x30, BITS_WITH_WMASK(0, 0x1, 5));
+
+	/* wait lock */
+	pm_pll_wait_lock(BIGCORE0CRU_BASE + 0x00);
+	pm_pll_wait_lock(BIGCORE1CRU_BASE + 0x20);
+	pm_pll_wait_lock(DSUCRU_BASE + 0x40);
+
+	/* restore mode */
+	mmio_write_32(BIGCORE0CRU_BASE + 0x280, WITH_16BITS_WMSK(b0_cru_mode));
+	mmio_write_32(BIGCORE1CRU_BASE + 0x280, WITH_16BITS_WMSK(b1_cru_mode));
+	mmio_write_32(DSUCRU_BASE + 0x280, WITH_16BITS_WMSK(dsu_cru_mode));
+
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+		      WITH_16BITS_WMSK(bcore0_cru_sel_con2));
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+		      WITH_16BITS_WMSK(bcore1_cru_sel_con2));
+}
+
+static uint32_t php_ppll_con0;
+
+void pd_php_save(void)
+{
+	php_ppll_con0 = mmio_read_32(PHP_CRU_BASE + 0x200);
+
+	/* php_ppll bypass */
+	mmio_write_32(PHP_CRU_BASE + 0x200, BITS_WITH_WMASK(1u, 1u, 15));
+	dsb();
+	isb();
+	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));
+
+	pm_pll_wait_lock(PHP_CRU_BASE + 0x200);
+
+	/* restore php_ppll bypass */
+	mmio_write_32(PHP_CRU_BASE + 0x200, WITH_16BITS_WMSK(php_ppll_con0));
+}
+
+void pm_reg_rgns_init(void)
+{
+	rockchip_alloc_region_mem(qos_reg_rgns, ARRAY_SIZE(qos_reg_rgns));
+	rockchip_alloc_region_mem(pd_crypto_reg_rgns, ARRAY_SIZE(pd_crypto_reg_rgns));
+	rockchip_alloc_region_mem(pd_dsu_reg_rgns, ARRAY_SIZE(pd_dsu_reg_rgns));
+	rockchip_alloc_region_mem(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+}
diff --git a/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.h b/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.h
new file mode 100644
index 00000000..8baf69a7
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/pm_pd_regs.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PM_PD_REGS_H
+#define PM_PD_REGS_H
+
+#include <stdint.h>
+
+void qos_save(void);
+void qos_restore(void);
+void pd_crypto_save(void);
+void pd_crypto_restore(void);
+void pd_dsu_core_save(void);
+void pd_dsu_core_restore(void);
+void pd_php_save(void);
+void pd_php_restore(void);
+
+void pm_reg_rgns_init(void);
+
+#endif
diff --git a/plat/rockchip/rk3588/drivers/pmu/pmu.c b/plat/rockchip/rk3588/drivers/pmu/pmu.c
new file mode 100644
index 00000000..f693dbdf
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/pmu.c
@@ -0,0 +1,1512 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv3.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <cpus_on_fixed_addr.h>
+#include <plat_pm_helpers.h>
+#include <plat_private.h>
+#include <pm_pd_regs.h>
+#include <rk3588_clk.h>
+#include <rockchip_sip_svc.h>
+#include <secure.h>
+#include <soc.h>
+
+#define PSRAM_SP_TOP	((PMUSRAM_BASE + PMUSRAM_RSIZE) & ~0xf)
+#define NONBOOT_CPUS_OFF_LOOP (500000)
+
+#define DSUGRF_REG_CNT			(0x78 / 4 + 1)
+#define BCORE_GRF_REG_CNT		(0x30 / 4 + 1)
+#define LCORE_GRF_REG_CNT		(0x30 / 4 + 1)
+
+#define CENTER_GRF_REG_CNT		(0x20 / 4 + 1)
+
+static struct psram_data_t *psram_sleep_cfg =
+	(struct psram_data_t *)&sys_sleep_flag_sram;
+
+static int8_t pd_repair_map[] = {
+	[PD_GPU] = PD_RPR_GPU,
+	[PD_NPU] = -1,
+	[PD_VCODEC] = -1,
+	[PD_NPUTOP] = PD_RPR_NPUTOP,
+	[PD_NPU1] = PD_RPR_NPU1,
+	[PD_NPU2] = PD_RPR_NPU2,
+	[PD_VENC0] = PD_RPR_VENC0,
+	[PD_VENC1] = PD_RPR_VENC1,
+	[PD_RKVDEC0] = PD_RPR_RKVDEC0,
+	[PD_RKVDEC1] = PD_RPR_RKVDEC1,
+	[PD_VDPU] = PD_RPR_VDPU,
+	[PD_RGA30] = PD_RPR_RGA30,
+	[PD_AV1] = PD_RPR_AV1,
+	[PD_VI] = PD_RPR_VI,
+	[PD_FEC] = PD_RPR_FEC,
+	[PD_ISP1] = PD_RPR_ISP1,
+	[PD_RGA31] = PD_RPR_RGA31,
+	[PD_VOP] = PD_RPR_VOP,
+	[PD_VO0] = PD_RPR_VO0,
+	[PD_VO1] = PD_RPR_VO1,
+	[PD_AUDIO] = PD_RPR_AUDIO,
+	[PD_PHP] = PD_RPR_PHP,
+	[PD_GMAC] = PD_RPR_GMAC,
+	[PD_PCIE] = PD_RPR_PCIE,
+	[PD_NVM] = -1,
+	[PD_NVM0] = PD_RPR_NVM0,
+	[PD_SDIO] = PD_RPR_SDIO,
+	[PD_USB] = PD_RPR_USB,
+	[PD_SECURE] = -1,
+	[PD_SDMMC] = PD_RPR_SDMMC,
+	[PD_CRYPTO] = PD_RPR_CRYPTO,
+	[PD_CENTER] = PD_RPR_CENTER,
+	[PD_DDR01] = PD_RPR_DDR01,
+	[PD_DDR23] = PD_RPR_DDR23,
+};
+
+struct rk3588_sleep_ddr_data {
+	uint32_t gpio0a_iomux_l, gpio0a_iomux_h, gpio0b_iomux_l;
+	uint32_t pmu_pd_st0, bus_idle_st0, qch_pwr_st;
+	uint32_t pmu2_vol_gate_con[3], pmu2_submem_gate_sft_con0;
+	uint32_t pmu2_bisr_con0;
+	uint32_t cpll_con0;
+	uint32_t cru_mode_con, busscru_mode_con;
+	uint32_t bussgrf_soc_con7;
+	uint32_t pmu0grf_soc_con0, pmu0grf_soc_con1, pmu0grf_soc_con3;
+	uint32_t pmu1grf_soc_con2, pmu1grf_soc_con7, pmu1grf_soc_con8, pmu1grf_soc_con9;
+	uint32_t pmu0sgrf_soc_con1;
+	uint32_t pmu1sgrf_soc_con14;
+	uint32_t ddrgrf_chn_con0[4], ddrgrf_chn_con1[4],
+		ddrgrf_chn_con2[4], pmu1_ddr_pwr_sft_con[4];
+	uint32_t pmu1cru_clksel_con1;
+};
+
+static struct rk3588_sleep_ddr_data ddr_data;
+
+struct rk3588_sleep_pmusram_data {
+	uint32_t dsusgrf_soc_con[DSUSGRF_SOC_CON_CNT],
+		dsusgrf_ddr_hash_con[DSUSGRF_DDR_HASH_CON_CNT];
+	uint32_t dsu_ddr_fw_rgn_reg[FIREWALL_DSU_RGN_CNT],
+		dsu_ddr_fw_mst_reg[FIREWALL_DSU_MST_CNT],
+		dsu_ddr_fw_con_reg[FIREWALL_DSU_CON_CNT];
+	uint32_t busioc_gpio0b_iomux_h;
+};
+
+static __pmusramdata struct rk3588_sleep_pmusram_data pmusram_data;
+
+static __pmusramfunc void dsu_restore_early(void)
+{
+	int i;
+
+	/* dsusgrf */
+	for (i = 0; i < DSUSGRF_SOC_CON_CNT; i++)
+		mmio_write_32(DSUSGRF_BASE + DSUSGRF_SOC_CON(i),
+			      WITH_16BITS_WMSK(pmusram_data.dsusgrf_soc_con[i]));
+
+	for (i = 0; i < DSUSGRF_DDR_HASH_CON_CNT; i++)
+		mmio_write_32(DSUSGRF_BASE + DSUSGRF_DDR_HASH_CON(i),
+			      pmusram_data.dsusgrf_ddr_hash_con[i]);
+
+	/* dsu ddr firewall */
+	for (i = 0; i < FIREWALL_DSU_RGN_CNT; i++)
+		mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_RGN(i),
+			      pmusram_data.dsu_ddr_fw_rgn_reg[i]);
+
+	for (i = 0; i < FIREWALL_DSU_MST_CNT; i++)
+		mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_MST(i),
+			      pmusram_data.dsu_ddr_fw_mst_reg[i]);
+
+	for (i = 0; i < FIREWALL_DSU_CON_CNT; i++)
+		mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_CON(i),
+			      pmusram_data.dsu_ddr_fw_con_reg[i]);
+}
+
+static __pmusramfunc void ddr_resume(void)
+{
+	/* check the crypto function had been enabled or not */
+	if ((mmio_read_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4)) & BIT(4)) != 0) {
+		/* enable the crypto function */
+		mmio_write_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4), BITS_WITH_WMASK(0, 0x1, 4));
+		dsb();
+		isb();
+
+		__asm__ volatile ("mov	x0, #3\n"
+				  "dsb	sy\n"
+				  "msr	rmr_el3, x0\n"
+				  "1:\n"
+				  "isb\n"
+				  "wfi\n"
+				  "b 1b\n");
+	}
+
+	dsu_restore_early();
+}
+
+static void dsu_core_save(void)
+{
+	int i;
+
+	/* dsusgrf */
+	for (i = 0; i < DSUSGRF_SOC_CON_CNT; i++)
+		pmusram_data.dsusgrf_soc_con[i] =
+			mmio_read_32(DSUSGRF_BASE + DSUSGRF_SOC_CON(i));
+
+	for (i = 0; i < DSUSGRF_DDR_HASH_CON_CNT; i++)
+		pmusram_data.dsusgrf_ddr_hash_con[i] =
+			mmio_read_32(DSUSGRF_BASE + DSUSGRF_DDR_HASH_CON(i));
+
+	/* dsu ddr firewall */
+	for (i = 0; i < FIREWALL_DSU_RGN_CNT; i++)
+		pmusram_data.dsu_ddr_fw_rgn_reg[i] =
+			mmio_read_32(FIREWALL_DSU_BASE + FIREWALL_DSU_RGN(i));
+
+	for (i = 0; i < FIREWALL_DSU_MST_CNT; i++)
+		pmusram_data.dsu_ddr_fw_mst_reg[i] =
+			mmio_read_32(FIREWALL_DSU_BASE + FIREWALL_DSU_MST(i));
+
+	for (i = 0; i < FIREWALL_DSU_CON_CNT; i++)
+		pmusram_data.dsu_ddr_fw_con_reg[i] =
+			mmio_read_32(FIREWALL_DSU_BASE + FIREWALL_DSU_CON(i));
+
+	pvtplls_suspend();
+	pd_dsu_core_save();
+}
+
+static void dsu_core_restore(void)
+{
+	pd_dsu_core_restore();
+	pvtplls_resume();
+}
+
+static uint32_t clk_save[CRU_CLKGATE_CON_CNT + PHPCRU_CLKGATE_CON_CNT +
+			 SECURECRU_CLKGATE_CON_CNT + PMU1CRU_CLKGATE_CON_CNT];
+
+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));
+
+	clk_save[j] = mmio_read_32(PHP_CRU_BASE + PHPCRU_CLKGATE_CON);
+
+	for (i = 0; i < SECURECRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(SCRU_BASE + SECURECRU_CLKGATE_CON(i));
+
+	for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++, j++)
+		clk_save[j] = mmio_read_32(PMU1CRU_BASE + CRU_CLKGATE_CON(i));
+}
+
+void clk_gate_con_disable(void)
+{
+	int i;
+
+	for (i = 0; i < CRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i), 0xffff0000);
+
+	 mmio_write_32(PHP_CRU_BASE + PHPCRU_CLKGATE_CON, 0xffff0000);
+
+	for (i = 0; i < SECURECRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(SCRU_BASE + SECURECRU_CLKGATE_CON(i), 0xffff0000);
+
+	for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++)
+		mmio_write_32(PMU1CRU_BASE + CRU_CLKGATE_CON(i), 0xffff0000);
+}
+
+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]));
+
+	mmio_write_32(PHP_CRU_BASE + PHPCRU_CLKGATE_CON,
+		      WITH_16BITS_WMSK(clk_save[j]));
+
+	for (i = 0; i < SECURECRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(SCRU_BASE + SECURECRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+
+	for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++, j++)
+		mmio_write_32(PMU1CRU_BASE + CRU_CLKGATE_CON(i),
+			      WITH_16BITS_WMSK(clk_save[j]));
+}
+
+static 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(bus / 32)));
+}
+
+static void pmu_qch_pwr_ctlr(uint32_t msk, uint32_t state)
+{
+	uint32_t wait_cnt = 0;
+
+	if (state != 0)
+		state = msk;
+
+	mmio_write_32(PMU_BASE + PMU2_QCHANNEL_PWR_SFTCON,
+		      BITS_WITH_WMASK(state, msk, 0));
+
+	while ((mmio_read_32(PMU_BASE + PMU2_QCHANNEL_STATUS) & msk) != state) {
+		if (++wait_cnt > QCH_PWR_LOOP)
+			break;
+		udelay(1);
+	}
+
+	if (wait_cnt > BUS_IDLE_LOOP)
+		WARN("%s: can't wait qch:0x%x to state:0x%x (0x%x)\n",
+		     __func__, msk, state,
+		     mmio_read_32(PMU_BASE + PMU2_QCHANNEL_STATUS));
+}
+
+static inline uint32_t pmu_power_domain_chain_st(uint32_t pd)
+{
+	return mmio_read_32(PMU_BASE + PMU2_PWR_CHAIN1_ST(pd / 32)) & BIT(pd % 32) ?
+	       pmu_pd_on :
+	       pmu_pd_off;
+}
+
+static inline uint32_t pmu_power_domain_mem_st(uint32_t pd)
+{
+	return mmio_read_32(PMU_BASE + PMU2_PWR_MEM_ST(pd / 32)) & BIT(pd % 32) ?
+	       pmu_pd_off :
+	       pmu_pd_on;
+}
+
+static inline uint32_t pmu_power_domain_st(uint32_t pd)
+{
+	int8_t pd_repair = pd_repair_map[pd];
+
+	if (pd_repair >= 0)
+		return mmio_read_32(PMU_BASE + PMU2_BISR_STATUS(4)) & BIT(pd_repair) ?
+		       pmu_pd_on :
+		       pmu_pd_off;
+	else
+		return mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(pd / 32)) & BIT(pd % 32) ?
+		       pmu_pd_off :
+		       pmu_pd_on;
+}
+
+static int pmu_power_domain_pd_to_mem_st(uint32_t pd, uint32_t *pd_mem_st)
+{
+	uint32_t mem_st;
+
+	switch (pd) {
+	case PD_NPUTOP:
+		mem_st = PD_NPU_TOP_MEM_ST;
+		break;
+	case PD_NPU1:
+		mem_st = PD_NPU1_MEM_ST;
+		break;
+	case PD_NPU2:
+		mem_st = PD_NPU2_MEM_ST;
+		break;
+	case PD_VENC0:
+		mem_st = PD_VENC0_MEM_ST;
+		break;
+	case PD_VENC1:
+		mem_st = PD_VENC1_MEM_ST;
+		break;
+	case PD_RKVDEC0:
+		mem_st = PD_RKVDEC0_MEM_ST;
+		break;
+	case PD_RKVDEC1:
+		mem_st = PD_RKVDEC1_MEM_ST;
+		break;
+	case PD_RGA30:
+		mem_st = PD_RGA30_MEM_ST;
+		break;
+	case PD_AV1:
+		mem_st = PD_AV1_MEM_ST;
+		break;
+	case PD_VI:
+		mem_st = PD_VI_MEM_ST;
+		break;
+	case PD_FEC:
+		mem_st = PD_FEC_MEM_ST;
+		break;
+	case PD_ISP1:
+		mem_st = PD_ISP1_MEM_ST;
+		break;
+	case PD_RGA31:
+		mem_st = PD_RGA31_MEM_ST;
+		break;
+	case PD_VOP:
+		mem_st = PD_VOP_MEM_ST;
+		break;
+	case PD_VO0:
+		mem_st = PD_VO0_MEM_ST;
+		break;
+	case PD_VO1:
+		mem_st = PD_VO1_MEM_ST;
+		break;
+	case PD_AUDIO:
+		mem_st = PD_AUDIO_MEM_ST;
+		break;
+	case PD_PHP:
+		mem_st = PD_PHP_MEM_ST;
+		break;
+	case PD_GMAC:
+		mem_st = PD_GMAC_MEM_ST;
+		break;
+	case PD_PCIE:
+		mem_st = PD_PCIE_MEM_ST;
+		break;
+	case PD_NVM0:
+		mem_st = PD_NVM0_MEM_ST;
+		break;
+	case PD_SDIO:
+		mem_st = PD_SDIO_MEM_ST;
+		break;
+	case PD_USB:
+		mem_st = PD_USB_MEM_ST;
+		break;
+	case PD_SDMMC:
+		mem_st = PD_SDMMC_MEM_ST;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	*pd_mem_st = mem_st;
+
+	return 0;
+}
+
+static int pmu_power_domain_reset_mem(uint32_t pd, uint32_t pd_mem_st)
+{
+	uint32_t loop = 0;
+	int ret = 0;
+
+	while (pmu_power_domain_chain_st(pd_mem_st) != pmu_pd_on) {
+		udelay(1);
+		loop++;
+		if (loop >= PD_CTR_LOOP) {
+			WARN("%s: %d chain up time out\n", __func__, pd);
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+
+	udelay(60);
+
+	mmio_write_32(PMU_BASE + PMU2_MEMPWR_GATE_SFTCON(pd / 16),
+		      BITS_WITH_WMASK(pmu_pd_off, 0x1, pd % 16));
+	dsb();
+
+	loop = 0;
+	while (pmu_power_domain_mem_st(pd_mem_st) != pmu_pd_off) {
+		udelay(1);
+		loop++;
+		if (loop >= PD_CTR_LOOP) {
+			WARN("%s: %d mem down time out\n", __func__, pd);
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+
+	mmio_write_32(PMU_BASE + PMU2_MEMPWR_GATE_SFTCON(pd / 16),
+		      BITS_WITH_WMASK(pmu_pd_on, 0x1, pd % 16));
+	dsb();
+
+	loop = 0;
+	while (pmu_power_domain_mem_st(pd_mem_st) != pmu_pd_on) {
+		udelay(1);
+		loop++;
+		if (loop >= PD_CTR_LOOP) {
+			WARN("%s: %d mem up time out\n", __func__, pd);
+			ret = -EINVAL;
+			goto error;
+		}
+	}
+
+	return 0;
+
+error:
+	return ret;
+}
+
+static int pmu_power_domain_ctr(uint32_t pd, uint32_t pd_state)
+{
+	uint32_t loop = 0;
+	uint32_t is_mem_on = pmu_pd_off;
+	uint32_t pd_mem_st;
+	int ret = 0;
+
+	if (pd_state == pmu_pd_on) {
+		ret = pmu_power_domain_pd_to_mem_st(pd, &pd_mem_st);
+		if (ret == 0) {
+			is_mem_on = pmu_power_domain_mem_st(pd_mem_st);
+			if (is_mem_on == pmu_pd_on)
+				WARN("%s: %d mem is up\n", __func__, pd);
+		}
+	}
+
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_SFTCON(pd / 16),
+		      BITS_WITH_WMASK(pd_state, 0x1, pd % 16));
+	dsb();
+
+	if (is_mem_on == pmu_pd_on) {
+		ret = pmu_power_domain_reset_mem(pd, pd_mem_st);
+		if (ret != 0)
+			goto out;
+		WARN("%s: %d mem reset ok\n", __func__, pd);
+	}
+
+	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, 0x%x) error!\n", __func__, pd, pd_state,
+		     mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(0)),
+		     mmio_read_32(PMU_BASE + PMU2_BISR_STATUS(4)));
+		ret = -EINVAL;
+	}
+
+out:
+	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) ? bus_idle : bus_active;
+
+	switch (pd_id) {
+	case PD_GPU:
+		pmu_bus_idle_req(BUS_ID_GPU, state);
+		break;
+	case PD_NPUTOP:
+		pmu_bus_idle_req(BUS_ID_NPUTOP, state);
+		break;
+	case PD_NPU1:
+		pmu_bus_idle_req(BUS_ID_NPU1, state);
+		break;
+	case PD_NPU2:
+		pmu_bus_idle_req(BUS_ID_NPU2, state);
+		break;
+	case PD_VENC0:
+		pmu_bus_idle_req(BUS_ID_RKVENC0, state);
+		break;
+	case PD_VENC1:
+		pmu_bus_idle_req(BUS_ID_RKVENC1, state);
+		break;
+	case PD_RKVDEC0:
+		pmu_bus_idle_req(BUS_ID_RKVDEC0, state);
+		break;
+	case PD_RKVDEC1:
+		pmu_bus_idle_req(BUS_ID_RKVDEC1, state);
+		break;
+	case PD_VDPU:
+		pmu_bus_idle_req(BUS_ID_VDPU, state);
+		break;
+	case PD_AV1:
+		pmu_bus_idle_req(BUS_ID_AV1, state);
+		break;
+	case PD_VI:
+		pmu_bus_idle_req(BUS_ID_VI, state);
+		break;
+	case PD_ISP1:
+		pmu_bus_idle_req(BUS_ID_ISP, state);
+		break;
+	case PD_RGA31:
+		pmu_bus_idle_req(BUS_ID_RGA31, state);
+		break;
+	case PD_VOP:
+		pmu_bus_idle_req(BUS_ID_VOP_CHANNEL, state);
+		pmu_bus_idle_req(BUS_ID_VOP, state);
+		break;
+	case PD_VO0:
+		pmu_bus_idle_req(BUS_ID_VO0, state);
+		break;
+	case PD_VO1:
+		pmu_bus_idle_req(BUS_ID_VO1, state);
+		break;
+	case PD_AUDIO:
+		pmu_bus_idle_req(BUS_ID_AUDIO, state);
+		break;
+	case PD_PHP:
+		pmu_bus_idle_req(BUS_ID_PHP, state);
+		break;
+	case PD_NVM:
+		pmu_bus_idle_req(BUS_ID_NVM, state);
+		break;
+	case PD_SDIO:
+		pmu_bus_idle_req(BUS_ID_SDIO, state);
+		break;
+	case PD_USB:
+		pmu_bus_idle_req(BUS_ID_USB, state);
+		break;
+	case PD_SECURE:
+		pmu_bus_idle_req(BUS_ID_SECURE, 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.qch_pwr_st =
+		mmio_read_32(PMU_BASE + PMU2_QCHANNEL_STATUS) & PMU2_QCH_PWR_MSK;
+	ddr_data.pmu_pd_st0 = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST(0));
+	ddr_data.bus_idle_st0 = mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST(0));
+
+	qos_save();
+
+	if ((ddr_data.pmu_pd_st0 & BIT(PD_PHP)) == 0)
+		pd_php_save();
+
+	if ((ddr_data.pmu_pd_st0 & BIT(PD_CRYPTO)) == 0)
+		pd_crypto_save();
+
+	pmu_qch_pwr_ctlr(0x20, 1);
+	pmu_qch_pwr_ctlr(0x40, 1);
+	pmu_qch_pwr_ctlr(0x1, 1);
+	pmu_qch_pwr_ctlr(0x2, 1);
+	pmu_qch_pwr_ctlr(0x4, 1);
+	pmu_qch_pwr_ctlr(0x8, 1);
+	pmu_qch_pwr_ctlr(0x10, 1);
+
+	pmu_bus_idle_req(BUS_ID_VO1USBTOP, bus_idle);
+	pmu_bus_idle_req(BUS_ID_SECURE_VO1USB_CHANNEL, bus_idle);
+
+	pmu_bus_idle_req(BUS_ID_USB, bus_idle);
+
+	pmu_set_power_domain(PD_GPU, pmu_pd_off);
+
+	pmu_set_power_domain(PD_NPU1, pmu_pd_off);
+	pmu_set_power_domain(PD_NPU2, pmu_pd_off);
+	pmu_set_power_domain(PD_NPUTOP, pmu_pd_off);
+	pmu_set_power_domain(PD_NPU, pmu_pd_off);
+
+	pmu_set_power_domain(PD_RKVDEC1, pmu_pd_off);
+	pmu_set_power_domain(PD_RKVDEC0, pmu_pd_off);
+	pmu_set_power_domain(PD_VENC1, pmu_pd_off);
+	pmu_set_power_domain(PD_VENC0, pmu_pd_off);
+	pmu_set_power_domain(PD_VCODEC, pmu_pd_off);
+
+	pmu_set_power_domain(PD_RGA30, pmu_pd_off);
+	pmu_set_power_domain(PD_AV1, pmu_pd_off);
+	pmu_set_power_domain(PD_VDPU, pmu_pd_off);
+
+	pmu_set_power_domain(PD_VO0, pmu_pd_off);
+	pmu_set_power_domain(PD_VO1, pmu_pd_off);
+	pmu_set_power_domain(PD_VOP, pmu_pd_off);
+
+	pmu_set_power_domain(PD_FEC, pmu_pd_off);
+	pmu_set_power_domain(PD_ISP1, pmu_pd_off);
+	pmu_set_power_domain(PD_VI, pmu_pd_off);
+
+	pmu_set_power_domain(PD_RGA31, pmu_pd_off);
+
+	pmu_set_power_domain(PD_AUDIO, pmu_pd_off);
+
+	pmu_set_power_domain(PD_GMAC, pmu_pd_off);
+	pmu_set_power_domain(PD_PCIE, pmu_pd_off);
+	pmu_set_power_domain(PD_PHP, pmu_pd_off);
+
+	pmu_set_power_domain(PD_SDIO, pmu_pd_off);
+
+	pmu_set_power_domain(PD_NVM0, pmu_pd_off);
+	pmu_set_power_domain(PD_NVM, pmu_pd_off);
+
+	pmu_set_power_domain(PD_SDMMC, pmu_pd_off);
+	pmu_set_power_domain(PD_CRYPTO, pmu_pd_off);
+}
+
+static void pmu_power_domains_resume(void)
+{
+	int i;
+
+	pmu_set_power_domain(PD_CRYPTO, !!(ddr_data.pmu_pd_st0 & BIT(PD_CRYPTO)));
+	pmu_set_power_domain(PD_SDMMC, !!(ddr_data.pmu_pd_st0 & BIT(PD_SDMMC)));
+
+	pmu_set_power_domain(PD_NVM, !!(ddr_data.pmu_pd_st0 & BIT(PD_NVM)));
+	pmu_set_power_domain(PD_NVM0, !!(ddr_data.pmu_pd_st0 & BIT(PD_NVM0)));
+
+	pmu_set_power_domain(PD_SDIO, !!(ddr_data.pmu_pd_st0 & BIT(PD_SDIO)));
+
+	pmu_set_power_domain(PD_PHP, !!(ddr_data.pmu_pd_st0 & BIT(PD_PHP)));
+	pmu_set_power_domain(PD_PCIE, !!(ddr_data.pmu_pd_st0 & BIT(PD_PCIE)));
+	pmu_set_power_domain(PD_GMAC, !!(ddr_data.pmu_pd_st0 & BIT(PD_GMAC)));
+
+	pmu_set_power_domain(PD_AUDIO, !!(ddr_data.pmu_pd_st0 & BIT(PD_AUDIO)));
+
+	pmu_set_power_domain(PD_USB, !!(ddr_data.pmu_pd_st0 & BIT(PD_USB)));
+
+	pmu_set_power_domain(PD_RGA31, !!(ddr_data.pmu_pd_st0 & BIT(PD_RGA31)));
+
+	pmu_set_power_domain(PD_VI, !!(ddr_data.pmu_pd_st0 & BIT(PD_VI)));
+	pmu_set_power_domain(PD_ISP1, !!(ddr_data.pmu_pd_st0 & BIT(PD_ISP1)));
+	pmu_set_power_domain(PD_FEC, !!(ddr_data.pmu_pd_st0 & BIT(PD_FEC)));
+
+	pmu_set_power_domain(PD_VOP, !!(ddr_data.pmu_pd_st0 & BIT(PD_VOP)));
+
+	pmu_set_power_domain(PD_VO1, !!(ddr_data.pmu_pd_st0 & BIT(PD_VO1)));
+
+	pmu_set_power_domain(PD_VO0, !!(ddr_data.pmu_pd_st0 & BIT(PD_VO0)));
+
+	pmu_set_power_domain(PD_VDPU, !!(ddr_data.pmu_pd_st0 & BIT(PD_VDPU)));
+	pmu_set_power_domain(PD_AV1, !!(ddr_data.pmu_pd_st0 & BIT(PD_AV1)));
+	pmu_set_power_domain(PD_RGA30, !!(ddr_data.pmu_pd_st0 & BIT(PD_RGA30)));
+
+	pmu_set_power_domain(PD_VCODEC, !!(ddr_data.pmu_pd_st0 & BIT(PD_VCODEC)));
+	pmu_set_power_domain(PD_VENC0, !!(ddr_data.pmu_pd_st0 & BIT(PD_VENC0)));
+	pmu_set_power_domain(PD_VENC1, !!(ddr_data.pmu_pd_st0 & BIT(PD_VENC1)));
+	pmu_set_power_domain(PD_RKVDEC0, !!(ddr_data.pmu_pd_st0 & BIT(PD_RKVDEC0)));
+	pmu_set_power_domain(PD_RKVDEC1, !!(ddr_data.pmu_pd_st0 & BIT(PD_RKVDEC1)));
+
+	pmu_set_power_domain(PD_NPU, !!(ddr_data.pmu_pd_st0 & BIT(PD_NPU)));
+	pmu_set_power_domain(PD_NPUTOP, !!(ddr_data.pmu_pd_st0 & BIT(PD_NPUTOP)));
+	pmu_set_power_domain(PD_NPU2, !!(ddr_data.pmu_pd_st0 & BIT(PD_NPU2)));
+	pmu_set_power_domain(PD_NPU1, !!(ddr_data.pmu_pd_st0 & BIT(PD_NPU1)));
+
+	pmu_set_power_domain(PD_GPU, !!(ddr_data.pmu_pd_st0 & BIT(PD_GPU)));
+
+	for (i = 0; i < 32; i++)
+		pmu_bus_idle_req(i, !!(ddr_data.bus_idle_st0 & BIT(i)));
+
+	pmu_qch_pwr_ctlr(0x10, !!(ddr_data.qch_pwr_st & 0x10));
+	pmu_qch_pwr_ctlr(0x8, !!(ddr_data.qch_pwr_st & 0x8));
+	pmu_qch_pwr_ctlr(0x4, !!(ddr_data.qch_pwr_st & 0x4));
+	pmu_qch_pwr_ctlr(0x2, !!(ddr_data.qch_pwr_st & 0x2));
+	pmu_qch_pwr_ctlr(0x1, !!(ddr_data.qch_pwr_st & 0x1));
+	pmu_qch_pwr_ctlr(0x40, !!(ddr_data.qch_pwr_st & 0x40));
+	pmu_qch_pwr_ctlr(0x20, !!(ddr_data.qch_pwr_st & 0x20));
+
+	if ((ddr_data.pmu_pd_st0 & BIT(PD_CRYPTO)) == 0)
+		pd_crypto_restore();
+
+	if ((ddr_data.pmu_pd_st0 & BIT(PD_PHP)) == 0)
+		pd_php_restore();
+
+	qos_restore();
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(0, 0x1, core_pm_en));
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(1, 0x1, core_pm_sft_wakeup_en));
+	dsb();
+
+	return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
+{
+	uint32_t apm_value = BIT(core_pm_en);
+
+	if (pd_cfg == core_pwr_wfi_int)
+		apm_value |= BIT(core_pm_int_wakeup_en);
+
+	mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+		      BITS_WITH_WMASK(apm_value, 0x3, 0));
+	dsb();
+
+	return 0;
+}
+
+static inline void cpus_pd_req_enter_wfi(void)
+{
+	/* CORTEX_A55_CPUACTLR_EL1 */
+	__asm__ volatile ("msr	DBGPRCR_EL1, xzr\n"
+			  "mrs	x0, S3_0_C15_C2_7\n"
+			  "orr	x0, x0, #0x1\n"
+			  "msr	S3_0_C15_C2_7, x0\n"
+			  "wfi_loop:\n"
+			  "isb\n"
+			  "wfi\n"
+			  "b wfi_loop\n");
+}
+
+static void nonboot_cpus_off(void)
+{
+	uint32_t boot_cpu, cpu, tmp;
+	uint32_t exp_st;
+	uint32_t bcore0_rst_msk = 0, bcore1_rst_msk = 0;
+	int wait_cnt;
+
+	bcore0_rst_msk = CRU_BIGCPU02_RST_MSK | CRU_BIGCPU13_RST_MSK;
+	bcore1_rst_msk = CRU_BIGCPU02_RST_MSK | CRU_BIGCPU13_RST_MSK;
+
+	mmio_write_32(BIGCORE0CRU_BASE + 0xa00, BITS_WITH_WMASK(0, bcore0_rst_msk, 0));
+	mmio_write_32(BIGCORE1CRU_BASE + 0xa00, BITS_WITH_WMASK(0, bcore1_rst_msk, 0));
+
+	wait_cnt = NONBOOT_CPUS_OFF_LOOP;
+	exp_st = SYS_GRF_BIG_CPUS_WFE;
+	do {
+		wait_cnt--;
+		tmp = mmio_read_32(SYSGRF_BASE + SYS_GRF_SOC_STATUS(3));
+		tmp &= SYS_GRF_BIG_CPUS_WFE;
+	} while (tmp != exp_st && wait_cnt);
+
+	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_wfi);
+	}
+
+	mmio_write_32(SRAM_BASE + 0x08, (uintptr_t)&cpus_pd_req_enter_wfi);
+	mmio_write_32(SRAM_BASE + 0x04, 0xdeadbeaf);
+
+	dsb();
+	isb();
+
+	sev();
+
+	wait_cnt = NONBOOT_CPUS_OFF_LOOP;
+	do {
+		wait_cnt--;
+		tmp = mmio_read_32(PMU_BASE + PMU2_CLUSTER_ST);
+		tmp &= CLUSTER_STS_NONBOOT_CPUS_DWN;
+	} while (tmp != CLUSTER_STS_NONBOOT_CPUS_DWN && wait_cnt);
+
+	if (tmp != CLUSTER_STS_NONBOOT_CPUS_DWN)
+		ERROR("nonboot cpus status(%x) error!\n", tmp);
+}
+
+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();
+
+	flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
+	flush_dcache_range((uintptr_t)cpuson_entry_point,
+			   sizeof(cpuson_entry_point));
+	dsb();
+	isb();
+
+	cpus_power_domain_on(cpu_id);
+
+	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_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_suspend(void)
+{
+	uint32_t cpu_id = plat_my_core_pos();
+
+	assert(cpu_id < PLATFORM_CORE_COUNT);
+
+	cpuson_flags[cpu_id] = PMU_CPU_AUTO_PWRDN;
+	cpuson_entry_point[cpu_id] = plat_get_sec_entrypoint();
+	dsb();
+	flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
+	flush_dcache_range((uintptr_t)cpuson_entry_point,
+			   sizeof(cpuson_entry_point));
+	dsb();
+	isb();
+
+	cpus_power_domain_off(cpu_id, core_pwr_wfi_int);
+
+	__asm__ volatile ("msr	DBGPRCR_EL1, xzr\n"
+			  "mrs	x0, S3_0_C15_C2_7\n"
+			  "orr	x0, x0, #0x1\n"
+			  "msr	S3_0_C15_C2_7, x0\n");
+
+	return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_resume(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, 0x3, 0));
+
+	dsb();
+
+	return PSCI_E_SUCCESS;
+}
+
+static void ddr_sleep_config(void)
+{
+	int i;
+
+	if (pmu_power_domain_st(PD_DDR01) == 0) {
+		ddr_data.ddrgrf_chn_con0[0] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHA_CON(0));
+		ddr_data.ddrgrf_chn_con0[1] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHB_CON(0));
+		ddr_data.ddrgrf_chn_con1[0] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHA_CON(1));
+		ddr_data.ddrgrf_chn_con1[1] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHB_CON(1));
+		ddr_data.ddrgrf_chn_con2[0] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHA_CON(2));
+		ddr_data.ddrgrf_chn_con2[1] =
+			mmio_read_32(DDR01GRF_BASE + DDRGRF_CHB_CON(2));
+
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(2), 0x20002000);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(2), 0x20002000);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(2), 0x08000000);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(2), 0x08000000);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(0), 0x00200020);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(0), 0x00200020);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(1), 0x00400040);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(1), 0x00400040);
+	}
+
+	if (pmu_power_domain_st(PD_DDR23) == 0) {
+		ddr_data.ddrgrf_chn_con0[2] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHA_CON(0));
+		ddr_data.ddrgrf_chn_con0[3] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHB_CON(0));
+		ddr_data.ddrgrf_chn_con1[2] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHA_CON(1));
+		ddr_data.ddrgrf_chn_con1[3] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHB_CON(1));
+		ddr_data.ddrgrf_chn_con2[2] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHA_CON(2));
+		ddr_data.ddrgrf_chn_con2[3] =
+			mmio_read_32(DDR23GRF_BASE + DDRGRF_CHB_CON(2));
+
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(2), 0x20002000);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(2), 0x20002000);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(2), 0x08000000);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(2), 0x08000000);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(0), 0x00200020);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(0), 0x00200020);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(1), 0x00400040);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(1), 0x00400040);
+	}
+
+	for (i = 0; i < DDR_CHN_CNT; i++) {
+		ddr_data.pmu1_ddr_pwr_sft_con[i] =
+			mmio_read_32(PMU_BASE + PMU1_DDR_PWR_SFTCON(i));
+		mmio_write_32(PMU_BASE + PMU1_DDR_PWR_SFTCON(i), 0x0fff0900);
+	}
+}
+
+static void ddr_sleep_config_restore(void)
+{
+	int i;
+
+	for (i = 0; i < DDR_CHN_CNT; i++) {
+		mmio_write_32(PMU_BASE + PMU1_DDR_PWR_SFTCON(i),
+			      0x0fff0000 | ddr_data.pmu1_ddr_pwr_sft_con[i]);
+	}
+
+	if (pmu_power_domain_st(PD_DDR01) == 0) {
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(1),
+			      0x00400000 | ddr_data.ddrgrf_chn_con1[0]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(1),
+			      0x00400000 | ddr_data.ddrgrf_chn_con1[1]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(0),
+			      0x00200000 | ddr_data.ddrgrf_chn_con0[0]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(0),
+			      0x00200000 | ddr_data.ddrgrf_chn_con0[1]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHA_CON(2),
+			      0x28000000 | ddr_data.ddrgrf_chn_con2[0]);
+		mmio_write_32(DDR01GRF_BASE + DDRGRF_CHB_CON(2),
+			      0x28000000 | ddr_data.ddrgrf_chn_con2[1]);
+	}
+
+	if (pmu_power_domain_st(PD_DDR23) == 0) {
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(1),
+			      0x00400000 | ddr_data.ddrgrf_chn_con1[2]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(1),
+			      0x00400000 | ddr_data.ddrgrf_chn_con1[3]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(0),
+			      0x00200000 | ddr_data.ddrgrf_chn_con0[2]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(0),
+			      0x00200000 | ddr_data.ddrgrf_chn_con0[3]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHA_CON(2),
+			      0x28000000 | ddr_data.ddrgrf_chn_con2[2]);
+		mmio_write_32(DDR23GRF_BASE + DDRGRF_CHB_CON(2),
+			      0x28000000 | ddr_data.ddrgrf_chn_con2[3]);
+	}
+}
+
+static void pmu_sleep_config(void)
+{
+	uint32_t pmu1_pwr_con, pmu1_wkup_int_con, pmu1_cru_pwr_con;
+	uint32_t pmu1_ddr_pwr_con, pmu1_pll_pd_con[2] = {0};
+	uint32_t pmu2_dsu_pwr_con, pmu2_core_pwr_con, pmu2_clst_idle_con;
+	uint32_t pmu2_bus_idle_con[3] = {0}, pmu2_pwr_gate_con[3] = {0};
+	uint32_t pmu2_vol_gate_con[3] = {0}, pmu2_qch_pwr_con = 0;
+	int i;
+
+	ddr_data.pmu1grf_soc_con7 = mmio_read_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(7));
+	ddr_data.pmu1grf_soc_con8 = mmio_read_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(8));
+	ddr_data.pmu1grf_soc_con9 = mmio_read_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(9));
+	ddr_data.pmu1sgrf_soc_con14 = mmio_read_32(PMU1SGRF_BASE + PMU1_SGRF_SOC_CON(14));
+	ddr_data.pmu0sgrf_soc_con1 = mmio_read_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(1));
+	ddr_data.pmu0grf_soc_con1 = mmio_read_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(1));
+
+	ddr_data.pmu2_vol_gate_con[0] = mmio_read_32(PMU_BASE + PMU2_VOL_GATE_CON(0));
+	ddr_data.pmu2_vol_gate_con[1] = mmio_read_32(PMU_BASE + PMU2_VOL_GATE_CON(1));
+	ddr_data.pmu2_vol_gate_con[2] = mmio_read_32(PMU_BASE + PMU2_VOL_GATE_CON(2));
+
+	ddr_data.pmu2_submem_gate_sft_con0 =
+		mmio_read_32(PMU_BASE + PMU2_MEMPWR_MD_GATE_SFTCON(0));
+
+	/* save pmic_sleep iomux gpio0_a4 */
+	ddr_data.gpio0a_iomux_l = mmio_read_32(PMU0IOC_BASE + 0);
+	ddr_data.gpio0a_iomux_h = mmio_read_32(PMU0IOC_BASE + 4);
+	ddr_data.pmu0grf_soc_con3 = mmio_read_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(3));
+
+	/* PMU1 repair disable */
+	mmio_write_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(0), 0x00010000);
+
+	/* set pmic_sleep iomux */
+	mmio_write_32(PMU0IOC_BASE + 0,
+		      BITS_WITH_WMASK(1, 0xf, 8) |
+		      BITS_WITH_WMASK(1, 0xfu, 12));
+
+	/* set tsadc_shut_m0 pin iomux to gpio */
+	mmio_write_32(PMU0IOC_BASE + 0,
+		      BITS_WITH_WMASK(0, 0xf, 4));
+
+	/* set spi2_cs0/1 pin iomux to gpio */
+	mmio_write_32(PMU0IOC_BASE + 8,
+		      BITS_WITH_WMASK(0, 0xff, 0));
+
+	/* sleep 1~2 src select */
+	mmio_write_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(3),
+		      BITS_WITH_WMASK(0x8, 0xf, 0) |
+		      BITS_WITH_WMASK(0x8, 0xf, 4) |
+		      BITS_WITH_WMASK(0x0, 0x3, 8));
+
+	pmu1_wkup_int_con = BIT(WAKEUP_GPIO0_INT_EN) |
+			    BIT(WAKEUP_CPU0_INT_EN);
+
+	pmu1_pwr_con = BIT(powermode_en);
+
+	pmu1_cru_pwr_con =
+		BIT(alive_osc_mode_en) |
+		BIT(power_off_en) |
+		BIT(pd_clk_src_gate_en);
+
+	pmu1_ddr_pwr_con = 0;
+
+	pmu2_dsu_pwr_con =
+		BIT(DSU_PWRDN_EN) |
+		BIT(DSU_PWROFF_EN);
+
+	pmu2_core_pwr_con = BIT(CORE_PWRDN_EN);
+
+	pmu2_clst_idle_con =
+		BIT(IDLE_REQ_BIGCORE0_EN) |
+		BIT(IDLE_REQ_BIGCORE1_EN) |
+		BIT(IDLE_REQ_DSU_EN) |
+		BIT(IDLE_REQ_LITDSU_EN) |
+		BIT(IDLE_REQ_ADB400_CORE_QCH_EN);
+
+	pmu1_pll_pd_con[0] =
+		BIT(B0PLL_PD_EN) |
+		BIT(B1PLL_PD_EN) |
+		BIT(LPLL_PD_EN) |
+		BIT(V0PLL_PD_EN) |
+		BIT(AUPLL_PD_EN) |
+		BIT(GPLL_PD_EN) |
+		BIT(CPLL_PD_EN) |
+		BIT(NPLL_PD_EN);
+
+	pmu1_pll_pd_con[1] =
+		BIT(PPLL_PD_EN) |
+		BIT(SPLL_PD_EN);
+
+	pmu2_bus_idle_con[0] = 0;
+
+	pmu2_bus_idle_con[1] =
+		BIT(BUS_ID_SECURE - 16) |
+		BIT(BUS_ID_SECURE_CENTER_CHANNEL - 16) |
+		BIT(BUS_ID_CENTER_CHANNEL - 16);
+
+	pmu2_bus_idle_con[2] =
+		BIT(BUS_ID_MSCH - 32) |
+		BIT(BUS_ID_BUS - 32) |
+		BIT(BUS_ID_TOP - 32);
+
+	pmu2_pwr_gate_con[0] = 0;
+	pmu2_pwr_gate_con[1] = BIT(PD_SECURE - 16);
+	pmu2_pwr_gate_con[2] = 0;
+
+	pmu2_qch_pwr_con = 0;
+
+	pmu2_vol_gate_con[0] = 0x7;
+	pmu2_vol_gate_con[2] = 0;
+
+	mmio_write_32(PMU_BASE + PMU2_CORE_AUTO_PWR_CON(0), 0x00030000);
+	mmio_write_32(PMU_BASE + PMU2_CORE_AUTO_PWR_CON(1), 0x00030000);
+	mmio_write_32(PMU_BASE + PMU2_CORE_PWR_CON(0),
+		      WITH_16BITS_WMSK(pmu2_core_pwr_con));
+	mmio_write_32(PMU_BASE + PMU2_CORE_PWR_CON(1),
+		      WITH_16BITS_WMSK(pmu2_core_pwr_con));
+	mmio_write_32(PMU_BASE + PMU2_CLUSTER_IDLE_CON,
+		      WITH_16BITS_WMSK(pmu2_clst_idle_con));
+	mmio_write_32(PMU_BASE + PMU2_DSU_AUTO_PWR_CON, 0x00030000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_PWR_CON,
+		      WITH_16BITS_WMSK(pmu2_dsu_pwr_con));
+
+	mmio_write_32(PMU_BASE + PMU1_OSC_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU1_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU1_WAKEUP_RST_CLR_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU1_PLL_LOCK_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU1_PWM_SWITCH_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE0_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE0_PWRUP_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE0_PWRDN_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE1_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE1_PWRUP_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_CORE1_PWRDN_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_STABLE_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_PWRUP_CNT_THRESH, 24000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_PWRDN_CNT_THRESH, 24000);
+
+	/* Config pmu power mode and pmu wakeup source */
+	mmio_write_32(PMU_BASE + PMU1_INT_MASK_CON,
+		      BITS_WITH_WMASK(1, 0x1, 0));
+
+	/* pmu1_pwr_con */
+	mmio_write_32(PMU_BASE + PMU1_PWR_CON,
+		      WITH_16BITS_WMSK(pmu1_pwr_con));
+
+	/* cru_pwr_con */
+	mmio_write_32(PMU_BASE + PMU1_CRU_PWR_CON,
+		      WITH_16BITS_WMSK(pmu1_cru_pwr_con));
+
+	/* wakeup source */
+	mmio_write_32(PMU_BASE + PMU1_WAKEUP_INT_CON, pmu1_wkup_int_con);
+
+	/* ddr pwr con */
+	for (i = 0; i < DDR_CHN_CNT; i++) {
+		mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(i),
+			      WITH_16BITS_WMSK(pmu1_ddr_pwr_con));
+		pmu2_bus_idle_con[1] |=
+			BIT(BUS_ID_MSCH0 - 16 + i);
+	}
+
+	/* pll_pd */
+	mmio_write_32(PMU_BASE + PMU1_PLLPD_CON(0),
+		      WITH_16BITS_WMSK(pmu1_pll_pd_con[0]));
+	mmio_write_32(PMU_BASE + PMU1_PLLPD_CON(1),
+		      WITH_16BITS_WMSK(pmu1_pll_pd_con[1]));
+
+	/* bypass cpu1~7*/
+	mmio_write_32(PMU_BASE + PMU2_PWR_CON1, 0x00ff00fe);
+
+	/* 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]));
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(2),
+		      WITH_16BITS_WMSK(pmu2_bus_idle_con[2]));
+	mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(2),
+		      0xf000f000);
+	/* power gate */
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(0),
+		      WITH_16BITS_WMSK(pmu2_pwr_gate_con[0]));
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(1),
+		      WITH_16BITS_WMSK(pmu2_pwr_gate_con[1]));
+	mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(2),
+		      WITH_16BITS_WMSK(pmu2_pwr_gate_con[2]));
+	/* vol gate */
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(0),
+		      BITS_WITH_WMASK(pmu2_vol_gate_con[0], 0x7, 0));
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(1), 0);
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(2),
+		      BITS_WITH_WMASK(pmu2_vol_gate_con[2], 0x3, 0));
+	/* qch */
+	mmio_write_32(PMU_BASE + PMU2_QCHANNEL_PWR_CON,
+		      BITS_WITH_WMASK(pmu2_qch_pwr_con, 0x7f, 0));
+
+	mmio_write_32(PMU_BASE + PMU2_MEMPWR_MD_GATE_SFTCON(0),
+		      0x000f000f);
+}
+
+static void pmu_sleep_restore(void)
+{
+	mmio_write_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(7),
+		      WITH_16BITS_WMSK(ddr_data.pmu1grf_soc_con7));
+	mmio_write_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(8),
+		      WITH_16BITS_WMSK(ddr_data.pmu1grf_soc_con8));
+	mmio_write_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(9),
+		      WITH_16BITS_WMSK(ddr_data.pmu1grf_soc_con9));
+	mmio_write_32(PMU1SGRF_BASE + PMU1_SGRF_SOC_CON(14),
+		      WITH_16BITS_WMSK(ddr_data.pmu1sgrf_soc_con14));
+
+	mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(1),
+		      WITH_16BITS_WMSK(ddr_data.pmu0sgrf_soc_con1));
+	mmio_write_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(1),
+		      WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con1));
+
+	mmio_write_32(PMU_BASE + PMU2_CORE_PWR_CON(0), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_CORE_PWR_CON(1), 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_CLUSTER_IDLE_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_DSU_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU2_PWR_CON1, 0xffff0000);
+
+	/* Must clear PMU1_WAKEUP_INT_CON because the wakeup source
+	 * in PMU1_WAKEUP_INT_CON will wakeup cpus in cpu_auto_pd state.
+	 */
+	mmio_write_32(PMU_BASE + PMU1_WAKEUP_INT_CON, 0);
+	mmio_write_32(PMU_BASE + PMU1_PWR_CON, 0xffff0000);
+	mmio_write_32(PMU_BASE + PMU1_INT_MASK_CON, 0x00010000);
+	mmio_write_32(PMU_BASE + PMU0_WAKEUP_INT_CON, 0x00010000);
+	mmio_write_32(PMU_BASE + PMU0_PWR_CON, 0xffff0000);
+
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(0),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_vol_gate_con[0]));
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(1),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_vol_gate_con[1]));
+	mmio_write_32(PMU_BASE + PMU2_VOL_GATE_CON(2),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_vol_gate_con[2]));
+
+	mmio_write_32(PMU_BASE + PMU2_MEMPWR_MD_GATE_SFTCON(0),
+		      WITH_16BITS_WMSK(ddr_data.pmu2_submem_gate_sft_con0));
+
+	mmio_write_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(3),
+		      WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con3));
+	mmio_write_32(PMU1GRF_BASE + PMU1_GRF_SOC_CON(2),
+		      WITH_16BITS_WMSK(ddr_data.pmu1grf_soc_con2));
+
+	mmio_write_32(PMU0IOC_BASE + 0x4,
+		      WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h));
+	mmio_write_32(PMU0IOC_BASE + 0,
+		      WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l));
+}
+
+static void soc_sleep_config(void)
+{
+	ddr_data.gpio0b_iomux_l = mmio_read_32(PMU0IOC_BASE + 0x8);
+
+	pmu_sleep_config();
+	ddr_sleep_config();
+}
+
+static void soc_sleep_restore(void)
+{
+	ddr_sleep_config_restore();
+	pmu_sleep_restore();
+
+	mmio_write_32(PMU0IOC_BASE + 0x8, WITH_16BITS_WMSK(ddr_data.gpio0b_iomux_l));
+}
+
+static void pm_pll_suspend(void)
+{
+	ddr_data.cru_mode_con = mmio_read_32(CRU_BASE + 0x280);
+	ddr_data.busscru_mode_con = mmio_read_32(BUSSCRU_BASE + 0x280);
+	ddr_data.pmu2_bisr_con0 = mmio_read_32(PMU_BASE + PMU2_BISR_CON(0));
+	ddr_data.cpll_con0 = mmio_read_32(CRU_BASE + CRU_PLLS_CON(2, 0));
+	ddr_data.pmu1cru_clksel_con1 = mmio_read_32(PMU1CRU_BASE + CRU_CLKSEL_CON(1));
+
+	/* disable bisr_init */
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(0), BITS_WITH_WMASK(0, 0x1, 0));
+	/* cpll bypass */
+	mmio_write_32(CRU_BASE + CRU_PLLS_CON(2, 0), BITS_WITH_WMASK(1u, 1u, 15));
+}
+
+static void pm_pll_restore(void)
+{
+	pm_pll_wait_lock(CRU_BASE + CRU_PLLS_CON(2, 0));
+
+	mmio_write_32(CRU_BASE + 0x280, WITH_16BITS_WMSK(ddr_data.cru_mode_con));
+	mmio_write_32(BUSSCRU_BASE + 0x280, WITH_16BITS_WMSK(ddr_data.busscru_mode_con));
+	mmio_write_32(CRU_BASE + CRU_PLLS_CON(2, 0), WITH_16BITS_WMSK(ddr_data.cpll_con0));
+	dsb();
+	isb();
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(0), WITH_16BITS_WMSK(ddr_data.pmu2_bisr_con0));
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+	clk_gate_con_save();
+	clk_gate_con_disable();
+
+	psram_sleep_cfg->pm_flag &= ~PM_WARM_BOOT_BIT;
+
+	pmu_power_domains_suspend();
+	soc_sleep_config();
+	dsu_core_save();
+	pm_pll_suspend();
+
+	return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+	pm_pll_restore();
+	dsu_core_restore();
+	soc_sleep_restore();
+	pmu_power_domains_resume();
+	plat_rockchip_gic_cpuif_enable();
+
+	psram_sleep_cfg->pm_flag |= PM_WARM_BOOT_BIT;
+
+	clk_gate_con_restore();
+
+	return 0;
+}
+
+void __dead2 rockchip_soc_cores_pd_pwr_dn_wfi(const
+					psci_power_state_t *target_state)
+{
+	psci_power_down_wfi();
+}
+
+void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
+{
+	cpus_pd_req_enter_wfi();
+	psci_power_down_wfi();
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+	/* pll slow mode */
+	mmio_write_32(CRU_BASE + 0x280, 0x03ff0000);
+	mmio_write_32(BIGCORE0CRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(BIGCORE0CRU_BASE + 0x300, 0x60000000);
+	mmio_write_32(BIGCORE0CRU_BASE + 0x304, 0x00600000);
+	mmio_write_32(BIGCORE1CRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(BIGCORE1CRU_BASE + 0x300, 0x60000000);
+	mmio_write_32(BIGCORE1CRU_BASE + 0x304, 0x00600000);
+	mmio_write_32(DSUCRU_BASE + 0x280, 0x00030000);
+	mmio_write_32(DSUCRU_BASE + 0x318, 0x30600000);
+	mmio_write_32(DSUCRU_BASE + 0x31c, 0x30600000);
+	mmio_write_32(DSUCRU_BASE + 0x304, 0x00010000);
+	mmio_write_32(BUSSCRU_BASE + 0x280, 0x0003000);
+	dsb();
+	isb();
+
+	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();
+}
+
+void __dead2 rockchip_soc_system_off(void)
+{
+	/* set pmic_sleep pin(gpio0_a2) to gpio mode */
+	mmio_write_32(PMU0IOC_BASE + 0, BITS_WITH_WMASK(0, 0xf, 8));
+
+	/* config output */
+	mmio_write_32(GPIO0_BASE + GPIO_SWPORT_DDR_L,
+		      BITS_WITH_WMASK(1, 0x1, 2));
+
+	/* config output high level */
+	mmio_write_32(GPIO0_BASE + GPIO_SWPORT_DR_L,
+		      BITS_WITH_WMASK(1, 0x1, 2));
+	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();
+}
+
+static void rockchip_pmu_pd_init(void)
+{
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(1), 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(2), 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU2_BISR_CON(3), 0xffffffff);
+
+	pmu_set_power_domain(PD_PHP, pmu_pd_on);
+	pmu_set_power_domain(PD_PCIE, pmu_pd_on);
+	pmu_set_power_domain(PD_GMAC, pmu_pd_on);
+	pmu_set_power_domain(PD_SECURE, pmu_pd_on);
+	pmu_set_power_domain(PD_VOP, pmu_pd_on);
+	pmu_set_power_domain(PD_VO0, pmu_pd_on);
+	pmu_set_power_domain(PD_VO1, pmu_pd_on);
+}
+
+#define PLL_LOCKED_TIMEOUT 600000U
+
+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)
+			break;
+		udelay(1);
+	}
+
+	if (delay <= 0)
+		ERROR("Can't wait pll(0x%x) lock\n", pll_base);
+}
+
+void rockchip_plat_mmu_el3(void)
+{
+	/* Nothing todo */
+}
+
+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_BIU_AUTO_CON(0), 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU2_BIU_AUTO_CON(1), 0xffffffff);
+	mmio_write_32(PMU_BASE + PMU2_BIU_AUTO_CON(2), 0x00070007);
+
+	rockchip_pmu_pd_init();
+
+	/* grf_con_pmic_sleep_sel
+	 * pmic sleep function selection
+	 * 1'b0: From reset pulse generator, can reset external PMIC
+	 * 1'b1: From pmu block, only support sleep function for external PMIC
+	 */
+	mmio_write_32(PMU0GRF_BASE + PMU0_GRF_SOC_CON(3), 0x03ff0000);
+
+	/* pmusram remap to 0xffff0000 */
+	mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(2), 0x00030001);
+
+	pm_reg_rgns_init();
+}
+
+static uint64_t boot_cpu_save[4];
+/* define in .data section */
+static uint32_t need_en_crypto = 1;
+
+void rockchip_cpu_reset_early(u_register_t arg0, u_register_t arg1,
+			      u_register_t arg2, u_register_t arg3)
+{
+	if (need_en_crypto == 0)
+		return;
+
+	/* check the crypto function had been enabled or not */
+	if ((mmio_read_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4)) & BIT(4)) != 0) {
+		/* save x0~x3 */
+		boot_cpu_save[0] = arg0;
+		boot_cpu_save[1] = arg1;
+		boot_cpu_save[2] = arg2;
+		boot_cpu_save[3] = arg3;
+
+		/* enable the crypto function */
+		mmio_write_32(DSUSGRF_BASE + DSU_SGRF_SOC_CON(4),
+			      BITS_WITH_WMASK(0, 0x1, 4));
+
+		/* remap pmusram to 0xffff0000 */
+		mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(2), 0x00030001);
+		psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+		cpuson_flags[0] = PMU_CPU_HOTPLUG;
+		cpuson_entry_point[0] = (uintptr_t)BL31_BASE;
+		dsb();
+
+		/* Must reset core0 to enable the crypto function.
+		 * Core0 will boot from pmu_sram and jump to BL31_BASE.
+		 */
+		__asm__ volatile ("mov	x0, #3\n"
+				  "dsb	sy\n"
+				  "msr	rmr_el3, x0\n"
+				  "1:\n"
+				  "isb\n"
+				  "wfi\n"
+				  "b	1b\n");
+	} else {
+		need_en_crypto = 0;
+
+		/* remap bootrom to 0xffff0000 */
+		mmio_write_32(PMU0SGRF_BASE + PMU0_SGRF_SOC_CON(2), 0x00030000);
+
+		/*
+		 * the crypto function has been enabled,
+		 * restore the x0~x3.
+		 */
+		__asm__ volatile ("ldr	x20, [%0]\n"
+				  "ldr	x21, [%0, 0x8]\n"
+				  "ldr	x22, [%0, 0x10]\n"
+				  "ldr	x23, [%0, 0x18]\n"
+				  : : "r" (&boot_cpu_save[0]));
+	}
+}
diff --git a/plat/rockchip/rk3588/drivers/pmu/pmu.h b/plat/rockchip/rk3588/drivers/pmu/pmu.h
new file mode 100644
index 00000000..7d8288c5
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/pmu/pmu.h
@@ -0,0 +1,589 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#include <lib/mmio.h>
+
+#define PMU0_PWR_CON			0x0000
+#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_CHAIN_STABLE_CON	0x001c
+#define PMU0_DDR_RET_CON(i)		(0x0020 + (i) * 4)
+#define PMU0_INFO_TX_CON		0x0030
+
+#define PMU1_VERSION_ID			0x4000
+#define PMU1_PWR_CON			0x4004
+#define PMU1_PWR_FSM			0x4008
+#define PMU1_INT_MASK_CON		0x400c
+#define PMU1_WAKEUP_INT_CON		0x4010
+#define PMU1_WAKEUP_INT_ST		0x4014
+#define PMU1_WAKEUP_EDGE_CON		0x4018
+#define PMU1_WAKEUP_EDGE_ST		0x401c
+#define PMU1_DDR_PWR_CON(i)		(0x4020 + (i) * 4)
+#define PMU1_DDR_PWR_SFTCON(i)		(0x4030 + (i) * 4)
+#define PMU1_DDR_PWR_FSM		0x4040
+#define PMU1_DDR_PWR_ST			0x4044
+#define PMU1_CRU_PWR_CON		0x4050
+#define PMU1_CRU_PWR_SFTCON		0x4054
+#define PMU1_CRU_PWR_FSM		0x4058
+#define PMU1_PLLPD_CON(i)		(0x4060 + (i) * 4)
+#define PMU1_PLLPD_SFTCON(i)		(0x4068 + (i) * 4)
+#define PMU1_STABLE_CNT_THRESH		0x4080
+#define PMU1_OSC_STABLE_CNT_THRESH	0x4084
+#define PMU1_WAKEUP_RST_CLR_CNT_THRESH	0x4088
+#define PMU1_PLL_LOCK_CNT_THRESH	0x408c
+#define PMU1_WAKEUP_TIMEOUT_THRESH	0x4094
+#define PMU1_PWM_SWITCH_CNT_THRESH	0x4098
+#define PMU1_SYS_REG(i)			(0x4100 + (i) * 4)
+
+#define PMU2_PWR_CON1			0x8000
+#define PMU2_DSU_PWR_CON		0x8004
+#define PMU2_DSU_PWR_SFTCON		0x8008
+#define PMU2_DSU_AUTO_PWR_CON		0x800c
+#define PMU2_CPU_AUTO_PWR_CON(i)	(0x8010 + (i) * 4)
+#define PMU2_CPU_PWR_SFTCON(i)		(0x8030 + (i) * 4)
+#define PMU2_CORE_PWR_CON(i)		(0x8050 + (i) * 4)
+#define PMU2_CORE_PWR_SFTCON(i)		(0x8058 + (i) * 4)
+#define PMU2_CORE_AUTO_PWR_CON(i)	(0x8060 + (i) * 4)
+#define PMU2_CLUSTER_NOC_AUTO_CON	0x8068
+#define PMU2_CLUSTER_DBG_PWR_CON	0x806c
+#define PMU2_CLUSTER_IDLE_CON		0x8070
+#define PMU2_CLUSTER_IDLE_SFTCON	0x8074
+#define PMU2_CLUSTER_IDLE_ACK		0x8078
+#define PMU2_CLUSTER_IDLE_ST		0x807c
+#define PMU2_CLUSTER_ST			0x8080
+#define PMU2_SCU_PWR_FSM_STATUS(i)	(0x8084 + (i) * 4)
+#define PMU2_CORE_PCHANNEL_STATUS(i)	(0x808c + (i) * 4)
+#define PMU2_CPU_PWR_CHAIN_STABLE_CON	0x8098
+#define PMU2_CLUSTER_MEMPWR_GATE_SFTCON	0x809c
+#define PMU2_DSU_STABLE_CNT_THRESH	0x80b0
+#define PMU2_DSU_PWRUP_CNT_THRESH	0x80b4
+#define PMU2_DSU_PWRDN_CNT_THRESH	0x80b8
+#define PMU2_CORE0_STABLE_CNT_THRESH	0x80bc
+#define PMU2_CORE0_PWRUP_CNT_THRESH	0x80c0
+#define PMU2_CORE0_PWRDN_CNT_THRESH	0x80c4
+#define PMU2_CORE1_STABLE_CNT_THRESH	0x80c8
+#define PMU2_CORE1_PWRUP_CNT_THRESH	0x80cc
+#define PMU2_CORE1_PWRDN_CNT_THRESH	0x80d0
+#define PMU2_DBG_RST_CNT_THRESH(i)	(0x80d4 + (i) * 4)
+#define PMU2_BUS_IDLE_CON(i)		(0x8100 + (i) * 4)
+#define PMU2_BUS_IDLE_SFTCON(i)		(0x810c + (i) * 4)
+#define PMU2_BUS_IDLE_ACK(i)		(0x8118 + (i) * 4)
+#define PMU2_BUS_IDLE_ST(i)		(0x8120 + (i) * 4)
+#define PMU2_BIU_AUTO_CON(i)		(0x8128 + (i) * 4)
+#define PMU2_PWR_GATE_CON(i)		(0x8140 + (i) * 4)
+#define PMU2_PWR_GATE_SFTCON(i)		(0x814c + (i) * 4)
+#define PMU2_VOL_GATE_CON(i)		(0x8158 + (i) * 4)
+#define PMU2_PWR_UP_CHAIN_STABLE_CON(i)	(0x8164 + (i) * 4)
+#define PMU2_PWR_DWN_CHAIN_STABLE_CON(i)(0x8170 + (i) * 4)
+#define PMU2_PWR_STABLE_CHAIN_CNT_THRES	0x817c
+#define PMU2_PWR_GATE_ST(i)		(0x8180 + (i) * 4)
+#define PMU2_PWR_GATE_FSM		0x8188
+#define PMU2_VOL_GATE_FAST_CON		0x818c
+#define PMU2_GPU_PWRUP_CNT		0x8190
+#define PMU2_GPU_PWRDN_CNT		0x8194
+#define PMU2_NPU_PWRUP_CNT		0x8198
+#define PMU2_NPU_PWRDN_CNT		0x819c
+#define PMU2_MEMPWR_GATE_SFTCON(i)	(0x81a0 + (i) * 4)
+#define PMU2_MEMPWR_MD_GATE_SFTCON(i)	(0x81b0 + (i) * 4)
+#define PMU2_MEMPWR_MD_GATE_STATUS	0x81bc
+#define PMU2_SUBMEM_PWR_ACK_BYPASS(i)	(0x81c0 + (i) * 4)
+#define PMU2_QCHANNEL_PWR_CON		0x81d0
+#define PMU2_QCHANNEL_PWR_SFTCON	0x81d4
+#define PMU2_QCHANNEL_STATUS		0x81d8
+#define PMU2_DEBUG_INFO_SEL		0x81e0
+#define PMU2_VOP_SUBPD_STATE		0x81e4
+#define PMU2_PWR_CHAIN0_ST(i)		(0x81e8 + (i) * 4)
+#define PMU2_PWR_CHAIN1_ST(i)		(0x81f0 + (i) * 4)
+#define PMU2_PWR_MEM_ST(i)		(0x81f8 + (i) * 4)
+#define PMU2_BISR_CON(i)		(0x8200 + (i) * 4)
+#define PMU2_BISR_STATUS(i)		(0x8280 + (i) * 4)
+
+#define PMU2_QCH_PWR_MSK		0x7f
+
+#define PD_CTR_LOOP			500
+#define PD_CHECK_LOOP			500
+#define WFEI_CHECK_LOOP			500
+#define BUS_IDLE_LOOP			1000
+#define QCH_PWR_LOOP			5000
+
+/* PMU1SCRU */
+#define PMU1SCRU_GATE_CON(i)		(0x800 + (i) * 4)
+
+/* PMU_GRF */
+#define PMU0_GRF_SOC_CON(i)		((i) * 4)
+#define PMU0_GRF_OS_REGS(i)		(0x80 + ((i) - 8) * 4)
+#define PMU1_GRF_SOC_CON(i)		((i) * 4)
+#define PMU0_GRF_IO_RET_CON(i)		(0x20 + (i) * 4)
+
+/* PMU_SGRF */
+#define PMU0_SGRF_SOC_CON(i)		((i) * 4)
+#define PMU1_SGRF_SOC_CON(i)		((i) * 4)
+
+/* sys grf */
+#define GRF_CPU_STATUS0			0x0420
+
+#define CORES_PM_DISABLE		0x0
+#define PD_CHECK_LOOP			500
+#define WFEI_CHECK_LOOP			500
+
+/* The ways of cores power domain contorlling */
+enum cores_pm_ctr_mode {
+	core_pwr_pd = 0,
+	core_pwr_wfi = 1,
+	core_pwr_wfi_int = 2
+};
+
+/* PMU0_PWR_CON */
+enum pmu0_pwr_con {
+	pmu0_powermode_en = 0,
+	pmu0_pmu1_pwr_bypass = 1,
+	pmu0_pmu1_bus_bypass = 2,
+	pmu0_wkup_bypass = 3,
+	pmu0_pmic_bypass = 4,
+	pmu0_reset_bypass = 5,
+	pmu0_freq_sw_bypass = 6,
+	pmu0_osc_dis_bypass = 7,
+	pmu0_pmu1_pwr_gt_en = 8,
+	pmu0_pmu1_pwr_gt_sft_en = 9,
+	pmu0_pmu1_mem_gt_sft_en = 10,
+	pmu0_pmu1_bus_idle_en = 11,
+	pmu0_pmu1_bus_idle_sft_en = 12,
+	pmu0_pmu1_biu_auto_en = 13,
+	pmu0_pwr_off_io_en = 14,
+};
+
+/* PMU1_PWR_CON */
+enum pmu1_pwr_con {
+	powermode_en = 0,
+	dsu_bypass = 1,
+	bus_bypass = 4,
+	ddr_bypass = 5,
+	pwrdn_bypass = 6,
+	cru_bypass = 7,
+	qch_bypass = 8,
+	core_bypass = 9,
+	cpu_sleep_wfi_dis = 12,
+};
+
+/* PMU1_DDR_PWR_CON */
+enum pmu1_ddr_pwr_con {
+	ddr_sref_en = 0,
+	ddr_sref_a_en = 1,
+	ddrio_ret_en = 2,
+	ddrio_ret_exit_en = 5,
+	ddrio_rstiov_en = 6,
+	ddrio_rstiov_exit_en = 7,
+	ddr_gating_a_en = 8,
+	ddr_gating_c_en = 9,
+	ddr_gating_p_en = 10,
+};
+
+/* PMU_CRU_PWR_CON */
+enum pmu1_cru_pwr_con {
+	alive_32k_en = 0,
+	osc_dis_en = 1,
+	wakeup_rst_en = 2,
+	input_clamp_en = 3,
+	alive_osc_mode_en = 4,
+	power_off_en = 5,
+	pwm_switch_en = 6,
+	pwm_gpio_ioe_en = 7,
+	pwm_switch_io = 8,
+	pd_clk_src_gate_en = 9,
+};
+
+/* PMU_PLLPD_CON */
+enum pmu1_pllpd_con {
+	B0PLL_PD_EN,
+	B1PLL_PD_EN,
+	LPLL_PD_EN,
+	D0APLL_PD_EN,
+	D0BPLL_PD_EN,
+	D1APLL_PD_EN,
+	D1BPLL_PD_EN,
+	D2APLL_PD_EN,
+	D2BPLL_PD_EN,
+	D3APLL_PD_EN,
+	D3BPLL_PD_EN,
+	V0PLL_PD_EN,
+	AUPLL_PD_EN,
+	GPLL_PD_EN,
+	CPLL_PD_EN,
+	NPLL_PD_EN,
+	PPLL_PD_EN = 0,
+	SPLL_PD_EN = 1,
+};
+
+enum pmu1_wakeup_int {
+	WAKEUP_CPU0_INT_EN,
+	WAKEUP_CPU1_INT_EN,
+	WAKEUP_CPU2_INT_EN,
+	WAKEUP_CPU3_INT_EN,
+	WAKEUP_CPU4_INT_EN,
+	WAKEUP_CPU5_INT_EN,
+	WAKEUP_CPU6_INT_EN,
+	WAKEUP_CPU7_INT_EN,
+	WAKEUP_GPIO0_INT_EN,
+	WAKEUP_SDMMC_EN,
+	WAKEUP_SDIO_EN,
+	WAKEUP_USBDEV_EN,
+	WAKEUP_UART0_EN,
+	WAKEUP_VAD_EN,
+	WAKEUP_TIMER_EN,
+	WAKEUP_SOC_INT_EN,
+	WAKEUP_TIMEROUT_EN,
+	WAKEUP_PMUMCU_CEC_EN = 20,
+};
+
+enum pmu2_dsu_auto_pwr_con {
+	dsu_pm_en = 0,
+	dsu_pm_int_wakeup_en = 1,
+	dsu_pm_sft_wakeup_en = 3,
+};
+
+enum pmu2_cpu_auto_pwr_con {
+	cpu_pm_en = 0,
+	cpu_pm_int_wakeup_en = 1,
+	cpu_pm_sft_wakeup_en = 3,
+};
+
+enum pmu2_core_auto_pwr_con {
+	core_pm_en = 0,
+	core_pm_int_wakeup_en = 1,
+	core_pm_int_wakeup_glb_msk = 2,
+	core_pm_sft_wakeup_en = 3,
+};
+
+enum pmu2_dsu_power_con {
+	DSU_PWRDN_EN,
+	DSU_PWROFF_EN,
+	BIT_FULL_EN,
+	DSU_RET_EN,
+	CLUSTER_CLK_SRC_GT_EN,
+};
+
+enum pmu2_core_power_con {
+	CORE_PWRDN_EN,
+	CORE_PWROFF_EN,
+	CORE_CPU_PWRDN_EN,
+	CORE_PWR_CNT_EN,
+};
+
+enum pmu2_cluster_idle_con {
+	IDLE_REQ_BIGCORE0_EN = 0,
+	IDLE_REQ_BIGCORE1_EN = 2,
+	IDLE_REQ_DSU_EN = 4,
+	IDLE_REQ_LITDSU_EN = 5,
+	IDLE_REQ_ADB400_CORE_QCH_EN = 6,
+};
+
+enum qos_id {
+	QOS_ISP0_MWO = 0,
+	QOS_ISP0_MRO = 1,
+	QOS_ISP1_MWO = 2,
+	QOS_ISP1_MRO = 3,
+	QOS_VICAP_M0 = 4,
+	QOS_VICAP_M1 = 5,
+	QOS_FISHEYE0 = 6,
+	QOS_FISHEYE1 = 7,
+	QOS_VOP_M0 = 8,
+	QOS_VOP_M1 = 9,
+	QOS_RKVDEC0 = 10,
+	QOS_RKVDEC1 = 11,
+	QOS_AV1 = 12,
+	QOS_RKVENC0_M0RO = 13,
+	QOS_RKVENC0_M1RO = 14,
+	QOS_RKVENC0_M2WO = 15,
+	QOS_RKVENC1_M0RO = 16,
+	QOS_RKVENC1_M1RO = 17,
+	QOS_RKVENC1_M2WO = 18,
+	QOS_DSU_M0 = 19,
+	QOS_DSU_M1 = 20,
+	QOS_DSU_MP = 21,
+	QOS_DEBUG = 22,
+	QOS_GPU_M0 = 23,
+	QOS_GPU_M1 = 24,
+	QOS_GPU_M2 = 25,
+	QOS_GPU_M3 = 26,
+	QOS_NPU1 = 27,
+	QOS_NPU0_MRO = 28,
+	QOS_NPU2 = 29,
+	QOS_NPU0_MWR = 30,
+	QOS_MCU_NPU = 31,
+	QOS_JPEG_DEC = 32,
+	QOS_JPEG_ENC0 = 33,
+	QOS_JPEG_ENC1 = 34,
+	QOS_JPEG_ENC2 = 35,
+	QOS_JPEG_ENC3 = 36,
+	QOS_RGA2_MRO = 37,
+	QOS_RGA2_MWO = 38,
+	QOS_RGA3_0 = 39,
+	QOS_RGA3_1 = 40,
+	QOS_VDPU = 41,
+	QOS_IEP = 42,
+	QOS_HDCP0 = 43,
+	QOS_HDCP1 = 44,
+	QOS_HDMIRX = 45,
+	QOS_GIC600_M0 = 46,
+	QOS_GIC600_M1 = 47,
+	QOS_MMU600PCIE_TCU = 48,
+	QOS_MMU600PHP_TBU = 49,
+	QOS_MMU600PHP_TCU = 50,
+	QOS_USB3_0 = 51,
+	QOS_USB3_1 = 52,
+	QOS_USBHOST_0 = 53,
+	QOS_USBHOST_1 = 54,
+	QOS_EMMC = 55,
+	QOS_FSPI = 56,
+	QOS_SDIO = 57,
+	QOS_DECOM = 58,
+	QOS_DMAC0 = 59,
+	QOS_DMAC1 = 60,
+	QOS_DMAC2 = 61,
+	QOS_GIC600M = 62,
+	QOS_DMA2DDR = 63,
+	QOS_MCU_DDR = 64,
+	QOS_VAD = 65,
+	QOS_MCU_PMU = 66,
+	QOS_CRYPTOS = 67,
+	QOS_CRYPTONS = 68,
+	QOS_DCF = 69,
+	QOS_SDMMC = 70,
+};
+
+enum pmu2_pdid {
+	PD_GPU = 0,
+	PD_NPU = 1,
+	PD_VCODEC = 2,
+	PD_NPUTOP = 3,
+	PD_NPU1 = 4,
+	PD_NPU2 = 5,
+	PD_VENC0 = 6,
+	PD_VENC1 = 7,
+	PD_RKVDEC0 = 8,
+	PD_RKVDEC1 = 9,
+	PD_VDPU = 10,
+	PD_RGA30 = 11,
+	PD_AV1 = 12,
+	PD_VI = 13,
+	PD_FEC = 14,
+	PD_ISP1 = 15,
+	PD_RGA31 = 16,
+	PD_VOP = 17,
+	PD_VO0 = 18,
+	PD_VO1 = 19,
+	PD_AUDIO = 20,
+	PD_PHP = 21,
+	PD_GMAC = 22,
+	PD_PCIE = 23,
+	PD_NVM = 24,
+	PD_NVM0 = 25,
+	PD_SDIO = 26,
+	PD_USB = 27,
+	PD_SECURE = 28,
+	PD_SDMMC = 29,
+	PD_CRYPTO = 30,
+	PD_CENTER = 31,
+	PD_DDR01 = 32,
+	PD_DDR23 = 33,
+};
+
+enum pmu2_pd_repair_id {
+	PD_RPR_PMU = 0,
+	PD_RPR_GPU = 1,
+	PD_RPR_NPUTOP = 2,
+	PD_RPR_NPU1 = 3,
+	PD_RPR_NPU2 = 4,
+	PD_RPR_VENC0 = 5,
+	PD_RPR_VENC1 = 6,
+	PD_RPR_RKVDEC0 = 7,
+	PD_RPR_RKVDEC1 = 8,
+	PD_RPR_VDPU = 9,
+	PD_RPR_RGA30 = 10,
+	PD_RPR_AV1 = 11,
+	PD_RPR_VI = 12,
+	PD_RPR_FEC = 13,
+	PD_RPR_ISP1 = 14,
+	PD_RPR_RGA31 = 15,
+	PD_RPR_VOP = 16,
+	PD_RPR_VO0 = 17,
+	PD_RPR_VO1 = 18,
+	PD_RPR_AUDIO = 19,
+	PD_RPR_PHP = 20,
+	PD_RPR_GMAC = 21,
+	PD_RPR_PCIE = 22,
+	PD_RPR_NVM0 = 23,
+	PD_RPR_SDIO = 24,
+	PD_RPR_USB = 25,
+	PD_RPR_SDMMC = 26,
+	PD_RPR_CRYPTO = 27,
+	PD_RPR_CENTER = 28,
+	PD_RPR_DDR01 = 29,
+	PD_RPR_DDR23 = 30,
+	PD_RPR_BUS = 31,
+};
+
+enum pmu2_bus_id {
+	BUS_ID_GPU = 0,
+	BUS_ID_NPUTOP = 1,
+	BUS_ID_NPU1 = 2,
+	BUS_ID_NPU2 = 3,
+	BUS_ID_RKVENC0 = 4,
+	BUS_ID_RKVENC1 = 5,
+	BUS_ID_RKVDEC0 = 6,
+	BUS_ID_RKVDEC1 = 7,
+	BUS_ID_VDPU = 8,
+	BUS_ID_AV1 = 9,
+	BUS_ID_VI = 10,
+	BUS_ID_ISP = 11,
+	BUS_ID_RGA31 = 12,
+	BUS_ID_VOP = 13,
+	BUS_ID_VOP_CHANNEL = 14,
+	BUS_ID_VO0 = 15,
+	BUS_ID_VO1 = 16,
+	BUS_ID_AUDIO = 17,
+	BUS_ID_NVM = 18,
+	BUS_ID_SDIO = 19,
+	BUS_ID_USB = 20,
+	BUS_ID_PHP = 21,
+	BUS_ID_VO1USBTOP = 22,
+	BUS_ID_SECURE = 23,
+	BUS_ID_SECURE_CENTER_CHANNEL = 24,
+	BUS_ID_SECURE_VO1USB_CHANNEL = 25,
+	BUS_ID_CENTER = 26,
+	BUS_ID_CENTER_CHANNEL = 27,
+	BUS_ID_MSCH0 = 28,
+	BUS_ID_MSCH1 = 29,
+	BUS_ID_MSCH2 = 30,
+	BUS_ID_MSCH3 = 31,
+	BUS_ID_MSCH = 32,
+	BUS_ID_BUS = 33,
+	BUS_ID_TOP = 34,
+};
+
+enum pmu2_mem_st {
+	PD_NPU_TOP_MEM_ST = 11,
+	PD_NPU1_MEM_ST = 12,
+	PD_NPU2_MEM_ST = 13,
+	PD_VENC0_MEM_ST = 14,
+	PD_VENC1_MEM_ST = 15,
+	PD_RKVDEC0_MEM_ST = 16,
+	PD_RKVDEC1_MEM_ST = 17,
+	PD_RGA30_MEM_ST = 19,
+	PD_AV1_MEM_ST = 20,
+	PD_VI_MEM_ST = 21,
+	PD_FEC_MEM_ST = 22,
+	PD_ISP1_MEM_ST = 23,
+	PD_RGA31_MEM_ST = 24,
+	PD_VOP_MEM_ST = 25,
+	PD_VO0_MEM_ST = 26,
+	PD_VO1_MEM_ST = 27,
+	PD_AUDIO_MEM_ST = 28,
+	PD_PHP_MEM_ST = 29,
+	PD_GMAC_MEM_ST = 30,
+	PD_PCIE_MEM_ST = 31,
+	PD_NVM0_MEM_ST = 33,
+	PD_SDIO_MEM_ST = 34,
+	PD_USB_MEM_ST = 35,
+	PD_SDMMC_MEM_ST = 37,
+};
+
+enum pmu2_qid {
+	QID_PHPMMU_TBU = 0,
+	QID_PHPMMU_TCU = 1,
+	QID_PCIEMMU_TBU0 = 2,
+	QID_PCIEMU_TCU = 3,
+	QID_PHP_GICITS = 4,
+	QID_BUS_GICITS0 = 5,
+	QID_BUS_GICITS1 = 6,
+};
+
+/* PMU_DSU_PWR_CON */
+enum pmu_dsu_pwr_con {
+	DSU_PWRDN_ENA = 2,
+	DSU_PWROFF_ENA,
+	DSU_RET_ENA = 6,
+	CLUSTER_CLK_SRC_GATE_ENA,
+	DSU_PWR_CON_END
+};
+
+enum cpu_power_state {
+	CPU_POWER_ON,
+	CPU_POWER_OFF,
+	CPU_EMULATION_OFF,
+	CPU_RETENTION,
+	CPU_DEBUG
+};
+
+enum dsu_power_state {
+	DSU_POWER_ON,
+	CLUSTER_TRANSFER_IDLE,
+	DSU_POWER_DOWN,
+	DSU_OFF,
+	DSU_WAKEUP,
+	DSU_POWER_UP,
+	CLUSTER_TRANSFER_RESUME,
+	DSU_FUNCTION_RETENTION
+};
+
+/* PMU2_CLUSTER_STS 0x8080 */
+enum pmu2_cluster_sts_bits {
+	pd_cpu0_dwn = 0,
+	pd_cpu1_dwn,
+	pd_cpu2_dwn,
+	pd_cpu3_dwn,
+	pd_cpu4_dwn,
+	pd_cpu5_dwn,
+	pd_cpu6_dwn,
+	pd_cpu7_dwn,
+	pd_core0_dwn,
+	pd_core1_dwn
+};
+
+#define CLUSTER_STS_NONBOOT_CPUS_DWN	0xfe
+
+enum cpu_off_trigger {
+	CPU_OFF_TRIGGER_WFE = 0,
+	CPU_OFF_TRIGGER_REQ_EML,
+	CPU_OFF_TRIGGER_REQ_WFI,
+	CPU_OFF_TRIGGER_REQ_WFI_NBT_CPU,
+	CPU_OFF_TRIGGER_REQ_WFI_NBT_CPU_SRAM
+};
+
+/*****************************************************************************
+ * power domain on or off
+ *****************************************************************************/
+enum pmu_pd_state {
+	pmu_pd_on = 0,
+	pmu_pd_off = 1
+};
+
+enum bus_state {
+	bus_active,
+	bus_idle,
+};
+
+#define RK_CPU_STATUS_OFF		0
+#define RK_CPU_STATUS_ON		1
+#define RK_CPU_STATUS_BUSY		-1
+
+#define PD_CTR_LOOP			500
+#define MAX_WAIT_COUNT			500
+
+#define pmu_bus_idle_st(id)	\
+	(!!(mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST((id) / 32)) & BIT((id) % 32)))
+
+#define pmu_bus_idle_ack(id)	\
+	(!!(mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ACK((id) / 32)) & BIT((id) % 32)))
+
+void pm_pll_wait_lock(uint32_t pll_base);
+#endif /* __PMU_H__ */
diff --git a/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c
new file mode 100644
index 00000000..ab3af5f3
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c
@@ -0,0 +1,2463 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include "rk3588_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 RK3588_CPUL_PVTPLL_CON0_L	0x40
+#define RK3588_CPUL_PVTPLL_CON0_H	0x44
+#define RK3588_CPUL_PVTPLL_CON1		0x48
+#define RK3588_CPUL_PVTPLL_CON2		0x4c
+#define RK3588_CPUB_PVTPLL_CON0_L	0x00
+#define RK3588_CPUB_PVTPLL_CON0_H	0x04
+#define RK3588_CPUB_PVTPLL_CON1		0x08
+#define RK3588_CPUB_PVTPLL_CON2		0x0c
+#define RK3588_DSU_PVTPLL_CON0_L	0x60
+#define RK3588_DSU_PVTPLL_CON0_H	0x64
+#define RK3588_DSU_PVTPLL_CON1		0x70
+#define RK3588_DSU_PVTPLL_CON2		0x74
+#define RK3588_GPU_PVTPLL_CON0_L	0x00
+#define RK3588_GPU_PVTPLL_CON0_H	0x04
+#define RK3588_GPU_PVTPLL_CON1		0x08
+#define RK3588_GPU_PVTPLL_CON2		0x0c
+#define RK3588_NPU_PVTPLL_CON0_L	0x0c
+#define RK3588_NPU_PVTPLL_CON0_H	0x10
+#define RK3588_NPU_PVTPLL_CON1		0x14
+#define RK3588_NPU_PVTPLL_CON2		0x18
+#define RK3588_PVTPLL_MAX_LENGTH	0x3f
+
+#define GPLL_RATE			1188000000
+#define CPLL_RATE			1500000000
+#define SPLL_RATE			702000000
+#define AUPLL_RATE			786431952
+#define NPLL_RATE			850000000
+
+#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)
+
+/* core_i: from gpll or apll */
+#define CLK_CORE_I_SEL_APLL		WMSK_BIT(6)
+#define CLK_CORE_I_SEL_GPLL		BIT_WITH_WMSK(6)
+
+/* clk_core:
+ * from normal pll(core_i: gpll or apll) path or direct pass from apll
+ */
+
+/* cpul clk path */
+#define CPUL_CLK_PATH_NOR_XIN		BITS_WITH_WMASK(0U, 0x3U, 14)
+#define CPUL_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(1U, 0x3U, 14)
+#define CPUL_CLK_PATH_NOR_LPLL		BITS_WITH_WMASK(2U, 0x3U, 14)
+
+#define CPUL_CLK_PATH_LPLL		(BITS_WITH_WMASK(0U, 0x3U, 5) | \
+					BITS_WITH_WMASK(0U, 0x3U, 12))
+#define CPUL_CLK_PATH_DIR_LPLL		(BITS_WITH_WMASK(0x1, 0x3U, 5) | \
+					BITS_WITH_WMASK(1U, 0x3U, 12))
+#define CPUL_CLK_PATH_PVTPLL		(BITS_WITH_WMASK(0x2, 0x3U, 5) | \
+					BITS_WITH_WMASK(2U, 0x3U, 12))
+
+#define CPUL_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 14)
+#define CPUL_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x1U, 14)
+
+/* cpub01 clk path */
+#define CPUB01_CLK_PATH_NOR_XIN		BITS_WITH_WMASK(0U, 0x3U, 6)
+#define CPUB01_CLK_PATH_NOR_GPLL	BITS_WITH_WMASK(1U, 0x3U, 6)
+#define CPUB01_CLK_PATH_NOR_B0PLL	BITS_WITH_WMASK(2U, 0x3U, 6)
+
+#define CPUB01_CLK_PATH_B0PLL		BITS_WITH_WMASK(0U, 0x3U, 13)
+#define CPUB01_CLK_PATH_DIR_B0PLL	BITS_WITH_WMASK(1U, 0x3U, 13)
+#define CPUB01_CLK_PATH_B0_PVTPLL	BITS_WITH_WMASK(2U, 0x3U, 13)
+
+#define CPUB01_CLK_PATH_B1PLL		BITS_WITH_WMASK(0U, 0x3U, 5)
+#define CPUB01_CLK_PATH_DIR_B1PLL	BITS_WITH_WMASK(1U, 0x3U, 5)
+#define CPUB01_CLK_PATH_B1_PVTPLL	BITS_WITH_WMASK(2U, 0x3U, 5)
+
+#define CPUB01_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 2)
+#define CPUB01_PVTPLL_PATH_PVTPLL	BITS_WITH_WMASK(1U, 0x1U, 2)
+
+#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)
+
+/* dsu clk path */
+#define SCLK_DSU_PATH_NOR_B0PLL		BITS_WITH_WMASK(0U, 0x3U, 12)
+#define SCLK_DSU_PATH_NOR_B1PLL		BITS_WITH_WMASK(1U, 0x3U, 12)
+#define SCLK_DSU_PATH_NOR_LPLL		BITS_WITH_WMASK(2U, 0x3U, 12)
+#define SCLK_DSU_PATH_NOR_GPLL		BITS_WITH_WMASK(3U, 0x3U, 12)
+
+#define DSU_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 15)
+#define DSU_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x1U, 15)
+
+#define SCLK_DSU_PATH_NOR_PLL		WMSK_BIT(0)
+#define SCLK_DSU_PATH_PVTPLL		BIT_WITH_WMSK(0)
+
+/* 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_NPLL		BITS_WITH_WMASK(3U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_SPLL		BITS_WITH_WMASK(4U, 0x7U, 7)
+
+#define NPU_CLK_PATH_NOR_PLL		WMSK_BIT(0)
+#define NPU_CLK_PATH_PVTPLL		BIT_WITH_WMSK(0)
+
+/* 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_NPLL		BITS_WITH_WMASK(3U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_SPLL		BITS_WITH_WMASK(4U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_PLL		WMSK_BIT(14)
+#define GPU_CLK_PATH_PVTPLL		BIT_WITH_WMSK(14)
+
+#define PVTPLL_NEED(type, length)	(((type) == PLL_SEL_PVT || \
+					  (type) == PLL_SEL_AUTO) && \
+					 (length))
+
+struct pvtpll_table {
+	unsigned int rate;
+	uint32_t length;
+	uint32_t ring_sel;
+};
+
+struct sys_clk_info_t {
+	struct pvtpll_table *cpul_table;
+	struct pvtpll_table *cpub01_table;
+	struct pvtpll_table *cpub23_table;
+	struct pvtpll_table *gpu_table;
+	struct pvtpll_table *npu_table;
+	unsigned int cpul_rate_count;
+	unsigned int cpub01_rate_count;
+	unsigned int cpub23_rate_count;
+	unsigned int gpu_rate_count;
+	unsigned int npu_rate_count;
+	unsigned long cpul_rate;
+	unsigned long dsu_rate;
+	unsigned long cpub01_rate;
+	unsigned long cpub23_rate;
+	unsigned long gpu_rate;
+	unsigned long npu_rate;
+};
+
+#define RK3588_SCMI_CLOCK(_id, _name, _data, _table, _cnt, _is_s)	\
+{									\
+	.id	= _id,							\
+	.name = _name,							\
+	.clk_ops = _data,						\
+	.rate_table = _table,						\
+	.rate_cnt = _cnt,						\
+	.is_security = _is_s,						\
+}
+
+#define ROCKCHIP_PVTPLL(_rate, _sel, _len)				\
+{									\
+	.rate = _rate##U,						\
+	.ring_sel = _sel,						\
+	.length = _len,							\
+}
+
+static struct pvtpll_table rk3588_cpul_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length */
+	ROCKCHIP_PVTPLL(1800000000, 1, 15),
+	ROCKCHIP_PVTPLL(1704000000, 1, 15),
+	ROCKCHIP_PVTPLL(1608000000, 1, 15),
+	ROCKCHIP_PVTPLL(1416000000, 1, 15),
+	ROCKCHIP_PVTPLL(1200000000, 1, 17),
+	ROCKCHIP_PVTPLL(1008000000, 1, 22),
+	ROCKCHIP_PVTPLL(816000000, 1, 32),
+	ROCKCHIP_PVTPLL(600000000, 0, 0),
+	ROCKCHIP_PVTPLL(408000000, 0, 0),
+	{ /* sentinel */ },
+};
+
+static struct pvtpll_table rk3588_cpub0_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length */
+	ROCKCHIP_PVTPLL(2400000000, 1, 11),
+	ROCKCHIP_PVTPLL(2352000000, 1, 11),
+	ROCKCHIP_PVTPLL(2304000000, 1, 11),
+	ROCKCHIP_PVTPLL(2256000000, 1, 11),
+	ROCKCHIP_PVTPLL(2208000000, 1, 11),
+	ROCKCHIP_PVTPLL(2112000000, 1, 11),
+	ROCKCHIP_PVTPLL(2016000000, 1, 11),
+	ROCKCHIP_PVTPLL(1800000000, 1, 11),
+	ROCKCHIP_PVTPLL(1608000000, 1, 11),
+	ROCKCHIP_PVTPLL(1416000000, 1, 13),
+	ROCKCHIP_PVTPLL(1200000000, 1, 17),
+	ROCKCHIP_PVTPLL(1008000000, 1, 23),
+	ROCKCHIP_PVTPLL(816000000, 1, 33),
+	ROCKCHIP_PVTPLL(600000000, 0, 0),
+	ROCKCHIP_PVTPLL(408000000, 0, 0),
+	{ /* sentinel */ },
+};
+
+static struct
+pvtpll_table rk3588_cpub1_pvtpll_table[ARRAY_SIZE(rk3588_cpub0_pvtpll_table)] = { 0 };
+
+static struct pvtpll_table rk3588_gpu_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length */
+	ROCKCHIP_PVTPLL(1000000000, 1, 12),
+	ROCKCHIP_PVTPLL(900000000, 1, 12),
+	ROCKCHIP_PVTPLL(800000000, 1, 12),
+	ROCKCHIP_PVTPLL(700000000, 1, 13),
+	ROCKCHIP_PVTPLL(600000000, 1, 17),
+	ROCKCHIP_PVTPLL(500000000, 1, 25),
+	ROCKCHIP_PVTPLL(400000000, 1, 38),
+	ROCKCHIP_PVTPLL(300000000, 1, 55),
+	ROCKCHIP_PVTPLL(200000000, 0, 0),
+	{ /* sentinel */ },
+};
+
+static struct pvtpll_table rk3588_npu_pvtpll_table[] = {
+	/* rate_hz, ring_sel, length */
+	ROCKCHIP_PVTPLL(1000000000, 1, 12),
+	ROCKCHIP_PVTPLL(900000000, 1, 12),
+	ROCKCHIP_PVTPLL(800000000, 1, 12),
+	ROCKCHIP_PVTPLL(700000000, 1, 13),
+	ROCKCHIP_PVTPLL(600000000, 1, 17),
+	ROCKCHIP_PVTPLL(500000000, 1, 25),
+	ROCKCHIP_PVTPLL(400000000, 1, 38),
+	ROCKCHIP_PVTPLL(300000000, 1, 55),
+	ROCKCHIP_PVTPLL(200000000, 0, 0),
+	{ /* sentinel */ },
+};
+
+static unsigned long rk3588_cpul_rates[] = {
+	408000000, 600000000, 816000000, 1008000000,
+	1200000000, 1416000000, 1608000000, 1800000063,
+};
+
+static unsigned long rk3588_cpub_rates[] = {
+	408000000, 816000000, 1008000000, 1200000000,
+	1416000000, 1608000000, 1800000000, 2016000000,
+	2208000000, 2304000000, 2400000063
+};
+
+static unsigned long rk3588_gpu_rates[] = {
+	200000000, 300000000, 400000000, 500000000,
+	600000000, 700000000, 800000000, 900000000,
+	1000000063
+};
+
+static unsigned long rk3588_sbus_rates[] = {
+	24000000, 50000000, 100000000, 150000000, 200000000,
+	250000000, 350000000, 700000000
+};
+
+static unsigned long rk3588_sdmmc_rates[] = {
+	400000, 24000000, 50000000, 100000000, 150000000, 200000000,
+	300000000, 400000000, 600000000, 700000000
+};
+
+static struct sys_clk_info_t sys_clk_info;
+static int clk_scmi_dsu_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_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;
+
+	/* set lpll */
+	if (PVTPLL_NEED(type, pvtpll->length) != 0) {
+		/* set clock gating interval */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set corel mux pvtpll */
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+			      CPUL_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
+			      CPUL_CLK_PATH_PVTPLL);
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+			      CPUL_CLK_PATH_PVTPLL);
+		return 0;
+	}
+
+	/* set clk corel div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
+		      CLKDIV_5BITS_SHF(div, 0) | CLKDIV_5BITS_SHF(div, 7));
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+		      CLKDIV_5BITS_SHF(div, 0) | CLKDIV_5BITS_SHF(div, 7));
+	/* set corel mux gpll */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5),
+		      CPUL_CLK_PATH_NOR_GPLL);
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
+		      CPUL_CLK_PATH_LPLL);
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+		      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_dsu_set_rate(clock, rate);
+	}
+
+	return ret;
+}
+
+static unsigned long rk3588_lpll_get_rate(void)
+{
+	unsigned int m, p, s, k;
+	uint64_t rate64 = 24000000, postdiv;
+	int mode;
+
+	mode = (mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(5)) >> 14) &
+	       0x3;
+
+	if (mode == 0)
+		return rate64;
+
+	m = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(16)) >>
+		 CRU_PLLCON0_M_SHIFT) &
+		CRU_PLLCON0_M_MASK;
+	p = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(17)) >>
+		    CRU_PLLCON1_P_SHIFT) &
+		   CRU_PLLCON1_P_MASK;
+	s = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(17)) >>
+		  CRU_PLLCON1_S_SHIFT) &
+		 CRU_PLLCON1_S_MASK;
+	k = (mmio_read_32(DSUCRU_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 * 65535;
+		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(DSUCRU_BASE + CRU_CLKSEL_CON(6)) & 0x0060;
+	src = src >> 5;
+	if (src == 2) {
+		return sys_clk_info.cpul_rate;
+	} else {
+		src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(5)) & 0xc000;
+		src = src >> 14;
+		div = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(6)) & 0x1f;
+		switch (src) {
+		case 0:
+			return 24000000;
+		case 1:
+			/* Make the return rate is equal to the set rate */
+			if (sys_clk_info.cpul_rate)
+				return sys_clk_info.cpul_rate;
+			else
+				return GPLL_RATE / (div + 1);
+		case 2:
+			return rk3588_lpll_get_rate();
+		default:
+			return 0;
+		}
+	}
+}
+
+static int clk_scmi_cpul_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static void clk_scmi_b0pll_disable(void)
+{
+	static bool is_b0pll_disabled;
+
+	if (is_b0pll_disabled != 0)
+		return;
+
+	/* set coreb01 mux gpll */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_NOR_GPLL);
+	 /* pll enter slow mode */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
+	/* set pll power down */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1), CRU_PLL_POWER_DOWN);
+
+	is_b0pll_disabled = true;
+}
+
+static int clk_cpub01_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.cpub01_table,
+					 sys_clk_info.cpub01_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	/* set b0pll */
+	if (PVTPLL_NEED(type, pvtpll->length)) {
+		/* set clock gating interval */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set core mux pvtpll */
+		mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+			      CPUB01_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+			      CPUB01_CLK_PATH_B0_PVTPLL);
+		mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
+			      CPUB01_CLK_PATH_B1_PVTPLL);
+		goto out;
+	}
+
+	/* set clk coreb01 div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div, 8));
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
+		      CLKDIV_5BITS_SHF(div, 0));
+	/* set coreb01 mux gpll */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_NOR_GPLL);
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_B0PLL);
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
+		      CPUB01_CLK_PATH_B1PLL);
+
+out:
+	clk_scmi_b0pll_disable();
+
+	return 0;
+}
+
+static int clk_scmi_cpub01_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_cpub01_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0)
+		sys_clk_info.cpub01_rate = rate;
+
+	return ret;
+}
+
+static unsigned long rk3588_b0pll_get_rate(void)
+{
+	unsigned int m, p, s, k;
+	uint64_t rate64 = 24000000, postdiv;
+	int mode;
+
+	mode = (mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0)) >> 6) &
+	       0x3;
+
+	if (mode == 0)
+		return rate64;
+
+	m = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(0)) >>
+		 CRU_PLLCON0_M_SHIFT) &
+		CRU_PLLCON0_M_MASK;
+	p = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1)) >>
+		    CRU_PLLCON1_P_SHIFT) &
+		   CRU_PLLCON1_P_MASK;
+	s = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1)) >>
+		  CRU_PLLCON1_S_SHIFT) &
+		 CRU_PLLCON1_S_MASK;
+	k = (mmio_read_32(BIGCORE0CRU_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 * 65535;
+		frac_rate64 = frac_rate64 / postdiv;
+		rate64 += frac_rate64;
+	}
+	rate64 = rate64 >> s;
+
+	return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpub01_get_rate(rk_scmi_clock_t *clock)
+{
+	int value, src, div;
+
+	value = mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0));
+	src = (value & 0x6000) >> 13;
+	if (src == 2) {
+		return sys_clk_info.cpub01_rate;
+	} else {
+		src = (value & 0x00c0) >> 6;
+		div = (value & 0x1f00) >> 8;
+		switch (src) {
+		case 0:
+			return 24000000;
+		case 1:
+			/* Make the return rate is equal to the set rate */
+			if (sys_clk_info.cpub01_rate)
+				return sys_clk_info.cpub01_rate;
+			else
+				return GPLL_RATE / (div + 1);
+		case 2:
+			return rk3588_b0pll_get_rate();
+		default:
+			return 0;
+		}
+	}
+}
+
+static int clk_scmi_cpub01_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static void clk_scmi_b1pll_disable(void)
+{
+	static bool is_b1pll_disabled;
+
+	if (is_b1pll_disabled != 0)
+		return;
+
+	/* set coreb23 mux gpll */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_NOR_GPLL);
+	 /* pll enter slow mode */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
+	/* set pll power down */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9), CRU_PLL_POWER_DOWN);
+
+	is_b1pll_disabled = true;
+}
+
+static int clk_cpub23_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.cpub23_table,
+					 sys_clk_info.cpub23_rate_count, rate);
+	if (pvtpll == NULL)
+		return SCMI_INVALID_PARAMETERS;
+
+	/* set b1pll */
+	if (PVTPLL_NEED(type, pvtpll->length)) {
+		/* set clock gating interval */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set core mux pvtpll */
+		mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+			      CPUB01_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+			      CPUB01_CLK_PATH_B0_PVTPLL);
+		mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
+			      CPUB01_CLK_PATH_B1_PVTPLL);
+		goto out;
+	}
+
+	/* set clk coreb23 div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div, 8));
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
+		      CLKDIV_5BITS_SHF(div, 0));
+	/* set coreb23 mux gpll */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_NOR_GPLL);
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CPUB01_CLK_PATH_B0PLL);
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
+		      CPUB01_CLK_PATH_B1PLL);
+
+out:
+	clk_scmi_b1pll_disable();
+
+	return 0;
+}
+
+static int clk_scmi_cpub23_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_cpub23_set_rate(rate, PLL_SEL_AUTO);
+	if (ret == 0)
+		sys_clk_info.cpub23_rate = rate;
+
+	return ret;
+}
+
+static unsigned long rk3588_b1pll_get_rate(void)
+{
+	unsigned int m, p, s, k;
+	uint64_t rate64 = 24000000, postdiv;
+	int mode;
+
+	mode = (mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0)) >> 6) &
+	       0x3;
+
+	if (mode == 0)
+		return rate64;
+
+	m = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(8)) >>
+		 CRU_PLLCON0_M_SHIFT) &
+		CRU_PLLCON0_M_MASK;
+	p = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9)) >>
+		    CRU_PLLCON1_P_SHIFT) &
+		   CRU_PLLCON1_P_MASK;
+	s = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9)) >>
+		  CRU_PLLCON1_S_SHIFT) &
+		 CRU_PLLCON1_S_MASK;
+	k = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(10)) >>
+		    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 * 65535;
+		frac_rate64 = frac_rate64 / postdiv;
+		rate64 += frac_rate64;
+	}
+	rate64 = rate64 >> s;
+
+	return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpub23_get_rate(rk_scmi_clock_t *clock)
+{
+	int value, src, div;
+
+	value = mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0));
+	src = (value & 0x6000) >> 13;
+	if (src == 2) {
+		return sys_clk_info.cpub23_rate;
+	} else {
+		src = (value & 0x00c0) >> 6;
+		div = (value & 0x1f00) >> 8;
+		switch (src) {
+		case 0:
+			return 24000000;
+		case 1:
+			/* Make the return rate is equal to the set rate */
+			if (sys_clk_info.cpub23_rate)
+				return sys_clk_info.cpub23_rate;
+			else
+				return GPLL_RATE / (div + 1);
+		case 2:
+			return rk3588_b1pll_get_rate();
+		default:
+			return 0;
+		}
+	}
+}
+
+static int clk_scmi_cpub23_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_dsu_get_rate(rk_scmi_clock_t *clock)
+{
+	int src, div;
+
+	src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(1)) & 0x1;
+	if (src != 0) {
+		return sys_clk_info.dsu_rate;
+	} else {
+		src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(0)) & 0x3000;
+		src = src >> 12;
+		div = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(0)) & 0xf80;
+		div = div >> 7;
+		switch (src) {
+		case 0:
+			return rk3588_b0pll_get_rate() / (div + 1);
+		case 1:
+			return rk3588_b1pll_get_rate() / (div + 1);
+		case 2:
+			return rk3588_lpll_get_rate() / (div + 1);
+		case 3:
+			return GPLL_RATE / (div + 1);
+		default:
+			return 0;
+		}
+	}
+}
+
+static void clk_scmi_lpll_disable(void)
+{
+	static bool is_lpll_disabled;
+
+	if (is_lpll_disabled)
+		return;
+
+	/* set corel mux gpll */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5),
+		      CPUL_CLK_PATH_NOR_GPLL);
+	/* set dsu mux gpll */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
+		      SCLK_DSU_PATH_NOR_GPLL);
+	/* pll enter slow mode */
+	mmio_write_32(DSUCRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
+	/* set pll power down */
+	mmio_write_32(DSUCRU_BASE + CRU_PLL_CON(17), CRU_PLL_POWER_DOWN);
+
+	is_lpll_disabled = true;
+}
+
+static int clk_dsu_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;
+
+	/* set pvtpll */
+	if (PVTPLL_NEED(type, pvtpll->length)) {
+		/* set clock gating interval */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set dsu mux pvtpll */
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+			      DSU_PVTPLL_PATH_PVTPLL);
+		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(1),
+			      SCLK_DSU_PATH_PVTPLL);
+		goto out;
+	}
+	/* set dsu div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div, 7));
+	/* set dsu mux gpll */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
+		      SCLK_DSU_PATH_NOR_GPLL);
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(1),
+		      SCLK_DSU_PATH_NOR_PLL);
+
+out:
+	clk_scmi_lpll_disable();
+
+	return 0;
+}
+
+static int clk_scmi_dsu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int ret;
+
+	if (rate == 0)
+		return SCMI_INVALID_PARAMETERS;
+
+	ret = clk_dsu_set_rate(rate, PLL_SEL_AUTO);
+
+	if (ret == 0)
+		sys_clk_info.dsu_rate = rate;
+	return ret;
+}
+
+static int clk_scmi_dsu_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(158)) & 0x4000) != 0) {
+		return sys_clk_info.gpu_rate;
+	} else {
+		div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x1f;
+		src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x00e0;
+		src = src >> 5;
+		switch (src) {
+		case 0:
+			/* Make the return rate is equal to the set rate */
+			if (sys_clk_info.gpu_rate)
+				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 NPLL_RATE / (div + 1);
+		case 4:
+			return SPLL_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)) {
+		/* set clock gating interval */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set gpu mux pvtpll */
+		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+			      GPU_CLK_PATH_PVTPLL);
+		return 0;
+	}
+
+	/* set gpu div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+		      CLKDIV_5BITS_SHF(div - 1, 0));
+	/* set gpu mux gpll */
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+		      GPU_CLK_PATH_NOR_GPLL);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+		      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;
+
+	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;
+
+	if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(74)) & 0x1) != 0) {
+		return sys_clk_info.npu_rate;
+	} else {
+		div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(73)) & 0x007c;
+		div = div >> 2;
+		src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(73)) & 0x0380;
+		src = src >> 7;
+		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 + 1);
+		case 1:
+			return CPLL_RATE / (div + 1);
+		case 2:
+			return AUPLL_RATE / (div + 1);
+		case 3:
+			return NPLL_RATE / (div + 1);
+		case 4:
+			return SPLL_RATE / (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)) {
+		/* set clock gating interval */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON2,
+			      0x00040000);
+		/* set ring sel */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
+			      0x07000000 | (pvtpll->ring_sel << 8));
+		/* set length */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_H,
+			      0x003f0000 | pvtpll->length);
+		/* set cal cnt = 24, T = 1us */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON1,
+			      0x18);
+		/* enable pvtpll */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
+			      0x00020002);
+		/* start monitor */
+		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
+			      0x00010001);
+		/* set npu mux pvtpll */
+		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(74),
+			      NPU_CLK_PATH_PVTPLL);
+		return 0;
+	}
+
+	/* set npu div */
+	div = DIV_ROUND_UP(GPLL_RATE, rate);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(73),
+		      CLKDIV_5BITS_SHF(div - 1, 2));
+	/* set npu mux gpll */
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(73),
+		      NPU_CLK_PATH_NOR_GPLL);
+	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(74),
+		      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;
+
+	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;
+}
+
+static unsigned long clk_scmi_sbus_get_rate(rk_scmi_clock_t *clock)
+{
+	int div;
+
+	if ((mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0)) & 0x0800) != 0) {
+		div = mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0));
+		div = (div & 0x03e0) >> 5;
+		return SPLL_RATE / (div + 1);
+	} else {
+		return OSC_HZ;
+	}
+}
+
+static int clk_scmi_sbus_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int div;
+
+	if (rate == OSC_HZ) {
+		mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+			      WMSK_BIT(11));
+		return 0;
+	}
+
+	div = DIV_ROUND_UP(SPLL_RATE, rate);
+	mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div - 1, 5));
+	mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+		      BIT_WITH_WMSK(11) | WMSK_BIT(10));
+	return 0;
+}
+
+static int clk_scmi_sbus_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_pclk_sbus_get_rate(rk_scmi_clock_t *clock)
+{
+	int div;
+
+	div = mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0));
+	div = div & 0x001f;
+	return SPLL_RATE / (div + 1);
+
+}
+
+static int clk_scmi_pclk_sbus_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int div;
+
+	div = DIV_ROUND_UP(SPLL_RATE, rate);
+	mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(div - 1, 0));
+	return 0;
+}
+
+static int clk_scmi_pclk_sbus_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_cclk_sdmmc_get_rate(rk_scmi_clock_t *clock)
+{
+	int div;
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x3000;
+	src = src >> 12;
+	div = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x0fc0;
+	div = div >> 6;
+	if (src == 1) {
+		return SPLL_RATE / (div + 1);
+	} else if (src == 2) {
+		return OSC_HZ / (div + 1);
+	} else {
+		return GPLL_RATE / (div + 1);
+	}
+}
+
+static int clk_scmi_cclk_sdmmc_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int div;
+
+	if ((OSC_HZ % rate) == 0) {
+		div = DIV_ROUND_UP(OSC_HZ, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_6BITS_SHF(div - 1, 6) |
+			      BITS_WITH_WMASK(2U, 0x3U, 12));
+	} else if ((SPLL_RATE % rate) == 0) {
+		div = DIV_ROUND_UP(SPLL_RATE, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_6BITS_SHF(div - 1, 6) |
+			      BITS_WITH_WMASK(1U, 0x3U, 12));
+	} else {
+		div = DIV_ROUND_UP(GPLL_RATE, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_6BITS_SHF(div - 1, 6) |
+			      BITS_WITH_WMASK(0U, 0x3U, 12));
+	}
+
+	return 0;
+}
+
+static int clk_scmi_cclk_sdmmc_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+		      BITS_WITH_WMASK(!status, 0x1U, 4));
+	return 0;
+}
+
+static unsigned long clk_scmi_dclk_sdmmc_get_rate(rk_scmi_clock_t *clock)
+{
+	int div;
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x0020;
+	div = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x001f;
+	if (src != 0) {
+		return SPLL_RATE / (div + 1);
+	} else {
+		return GPLL_RATE / (div + 1);
+	}
+}
+
+static int clk_scmi_dclk_sdmmc_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	int div;
+
+	if ((SPLL_RATE % rate) == 0) {
+		div = DIV_ROUND_UP(SPLL_RATE, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_5BITS_SHF(div - 1, 0) |
+			      BITS_WITH_WMASK(1U, 0x1U, 5));
+	} else {
+		div = DIV_ROUND_UP(GPLL_RATE, rate);
+		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+			      CLKDIV_5BITS_SHF(div - 1, 0) |
+			      BITS_WITH_WMASK(0U, 0x1U, 5));
+	}
+	return 0;
+}
+
+static int clk_scmi_dclk_sdmmc_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+		      BITS_WITH_WMASK(!status, 0x1U, 1));
+	return 0;
+}
+
+static unsigned long clk_scmi_aclk_secure_ns_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0003;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 200 * MHz;
+	case 2:
+		return 100 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_aclk_secure_ns_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 200 * MHz)
+		src = 1;
+	else if (rate >= 100 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 0));
+
+	return 0;
+}
+
+static int clk_scmi_aclk_secure_ns_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_hclk_secure_ns_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x000c;
+	src = src >> 2;
+	switch (src) {
+	case 0:
+		return 150 * MHz;
+	case 1:
+		return 100 * MHz;
+	case 2:
+		return 50 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_hclk_secure_ns_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 150 * MHz)
+		src = 0;
+	else if (rate >= 100 * MHz)
+		src = 1;
+	else if (rate >= 50 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 2));
+	return 0;
+}
+
+static int clk_scmi_hclk_secure_ns_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_tclk_wdt_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_tclk_wdt_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+		      BITS_WITH_WMASK(!status, 0x1U, 0));
+	return 0;
+}
+
+static unsigned long clk_scmi_keyladder_core_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x00c0;
+	src = src >> 6;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_keyladder_core_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 6));
+	return 0;
+}
+
+static int clk_scmi_keyladder_core_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 9));
+	return 0;
+}
+
+static unsigned long clk_scmi_keyladder_rng_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x0300;
+	src = src >> 8;
+	switch (src) {
+	case 0:
+		return 175 * MHz;
+	case 1:
+		return 116 * MHz;
+	case 2:
+		return 58 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_keyladder_rng_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 175 * MHz)
+		src = 0;
+	else if (rate >= 116 * MHz)
+		src = 1;
+	else if (rate >= 58 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 8));
+	return 0;
+}
+
+static int clk_scmi_keyladder_rng_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 10));
+	return 0;
+}
+
+static unsigned long clk_scmi_aclk_secure_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0030;
+	src = src >> 4;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_aclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 4));
+	return 0;
+}
+
+static int clk_scmi_aclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_hclk_secure_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x00c0;
+	src = src >> 6;
+	switch (src) {
+	case 0:
+		return 175 * MHz;
+	case 1:
+		return 116 * MHz;
+	case 2:
+		return 58 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_hclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 175 * MHz)
+		src = 0;
+	else if (rate >= 116 * MHz)
+		src = 1;
+	else if (rate >= 58 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 6));
+	return 0;
+}
+
+static int clk_scmi_hclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_pclk_secure_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0300;
+	src = src >> 8;
+	switch (src) {
+	case 0:
+		return 116 * MHz;
+	case 1:
+		return 58 * MHz;
+	case 2:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_pclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 116 * MHz)
+		src = 0;
+	else if (rate >= 58 * MHz)
+		src = 1;
+	else
+		src = 2;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 8));
+	return 0;
+}
+
+static int clk_scmi_pclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_rng_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0xc000;
+	src = src >> 14;
+	switch (src) {
+	case 0:
+		return 175 * MHz;
+	case 1:
+		return 116 * MHz;
+	case 2:
+		return 58 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_rng_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 175 * MHz)
+		src = 0;
+	else if (rate >= 116 * MHz)
+		src = 1;
+	else if (rate >= 58 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 14));
+	return 0;
+}
+
+static int clk_scmi_crypto_rng_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 1));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_core_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0c00;
+	src = src >> 10;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_core_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 10));
+	return 0;
+}
+
+static int clk_scmi_crypto_core_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(0),
+		      BITS_WITH_WMASK(!status, 0x1U, 15));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_pka_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x3000;
+	src = src >> 12;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_pka_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+		      BITS_WITH_WMASK(src, 0x3U, 12));
+	return 0;
+}
+
+static int clk_scmi_crypto_pka_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 0));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_spll_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(BUSSCRU_BASE + CRU_MODE_CON0) & 0x3;
+	switch (src) {
+	case 0:
+		return OSC_HZ;
+	case 1:
+		return 702 * MHz;
+	case 2:
+		return 32768;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_spll_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 700 * MHz)
+		src = 1;
+	else
+		src = 0;
+
+	mmio_write_32(BUSSCRU_BASE + CRU_MODE_CON0,
+		      BITS_WITH_WMASK(0, 0x3U, 0));
+	mmio_write_32(BUSSCRU_BASE + CRU_PLL_CON(137),
+		      BITS_WITH_WMASK(2, 0x7U, 6));
+
+	mmio_write_32(BUSSCRU_BASE + CRU_MODE_CON0,
+		      BITS_WITH_WMASK(src, 0x3U, 0));
+	return 0;
+}
+
+static int clk_scmi_spll_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	return 0;
+}
+
+static unsigned long clk_scmi_hclk_sd_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_ns_get_rate(clock);
+}
+
+static int clk_scmi_hclk_sd_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+		      BITS_WITH_WMASK(!status, 0x1U, 2));
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_rng_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x0030;
+	src = src >> 4;
+	switch (src) {
+	case 0:
+		return 175 * MHz;
+	case 1:
+		return 116 * MHz;
+	case 2:
+		return 58 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_rng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 175 * MHz)
+		src = 0;
+	else if (rate >= 116 * MHz)
+		src = 1;
+	else if (rate >= 58 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 4));
+	return 0;
+}
+
+static int clk_scmi_crypto_rng_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 6));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_core_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x3;
+	src = src >> 0;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_core_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 0));
+	return 0;
+}
+
+static int clk_scmi_crypto_core_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 4));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_crypto_pka_s_get_rate(rk_scmi_clock_t *clock)
+{
+	uint32_t src;
+
+	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x000c;
+	src = src >> 2;
+	switch (src) {
+	case 0:
+		return 350 * MHz;
+	case 1:
+		return 233 * MHz;
+	case 2:
+		return 116 * MHz;
+	case 3:
+		return OSC_HZ;
+	default:
+		return 0;
+	}
+}
+
+static int clk_scmi_crypto_pka_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	uint32_t src;
+
+	if (rate >= 350 * MHz)
+		src = 0;
+	else if (rate >= 233 * MHz)
+		src = 1;
+	else if (rate >= 116 * MHz)
+		src = 2;
+	else
+		src = 3;
+
+	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+		      BITS_WITH_WMASK(src, 0x3U, 2));
+	return 0;
+}
+
+static int clk_scmi_crypto_pka_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 5));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_a_crypto_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_aclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_a_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_aclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_a_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 7));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_h_crypto_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_h_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_h_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 8));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_p_crypto_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_pclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_p_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_pclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_p_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+		      BITS_WITH_WMASK(!status, 0x1U, 13));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_a_keylad_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_aclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_a_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_aclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_a_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 11));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_h_keylad_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_h_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_h_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 12));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_p_keylad_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_pclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_p_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_pclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_p_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+		      BITS_WITH_WMASK(!status, 0x1U, 14));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_trng_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_trng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_trng_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+		      BITS_WITH_WMASK(!status, 0x1U, 6));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_h_trng_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_h_trng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_h_trng_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+		      BITS_WITH_WMASK(!status, 0x1U, 15));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_p_otpc_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return clk_scmi_pclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_p_otpc_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+	return clk_scmi_pclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_p_otpc_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 13));
+
+	return 0;
+}
+
+static unsigned long clk_scmi_otpc_s_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_otpc_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+		      BITS_WITH_WMASK(!status, 0x1U, 14));
+	return 0;
+}
+
+static unsigned long clk_scmi_otp_phy_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_otp_phy_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
+		      BITS_WITH_WMASK(!status, 0x1U, 13));
+	return 0;
+}
+
+static unsigned long clk_scmi_otpc_rd_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_otpc_rd_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
+		      BITS_WITH_WMASK(!status, 0x1U, 12));
+	return 0;
+}
+
+static unsigned long clk_scmi_otpc_arb_get_rate(rk_scmi_clock_t *clock)
+{
+	return OSC_HZ;
+}
+
+static int clk_scmi_otpc_arb_set_status(rk_scmi_clock_t *clock, bool status)
+{
+	mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
+		      BITS_WITH_WMASK(!status, 0x1U, 11));
+	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_dsu_ops = {
+	.get_rate = clk_scmi_dsu_get_rate,
+	.set_rate = clk_scmi_dsu_set_rate,
+	.set_status = clk_scmi_dsu_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cpub01_ops = {
+	.get_rate = clk_scmi_cpub01_get_rate,
+	.set_rate = clk_scmi_cpub01_set_rate,
+	.set_status = clk_scmi_cpub01_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cpub23_ops = {
+	.get_rate = clk_scmi_cpub23_get_rate,
+	.set_rate = clk_scmi_cpub23_set_rate,
+	.set_status = clk_scmi_cpub23_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_sbus_ops = {
+	.get_rate = clk_scmi_sbus_get_rate,
+	.set_rate = clk_scmi_sbus_set_rate,
+	.set_status = clk_scmi_sbus_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_pclk_sbus_ops = {
+	.get_rate = clk_scmi_pclk_sbus_get_rate,
+	.set_rate = clk_scmi_pclk_sbus_set_rate,
+	.set_status = clk_scmi_pclk_sbus_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cclk_sdmmc_ops = {
+	.get_rate = clk_scmi_cclk_sdmmc_get_rate,
+	.set_rate = clk_scmi_cclk_sdmmc_set_rate,
+	.set_status = clk_scmi_cclk_sdmmc_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_dclk_sdmmc_ops = {
+	.get_rate = clk_scmi_dclk_sdmmc_get_rate,
+	.set_rate = clk_scmi_dclk_sdmmc_set_rate,
+	.set_status = clk_scmi_dclk_sdmmc_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_aclk_secure_ns_ops = {
+	.get_rate = clk_scmi_aclk_secure_ns_get_rate,
+	.set_rate = clk_scmi_aclk_secure_ns_set_rate,
+	.set_status = clk_scmi_aclk_secure_ns_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_hclk_secure_ns_ops = {
+	.get_rate = clk_scmi_hclk_secure_ns_get_rate,
+	.set_rate = clk_scmi_hclk_secure_ns_set_rate,
+	.set_status = clk_scmi_hclk_secure_ns_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_tclk_wdt_ops = {
+	.get_rate = clk_scmi_tclk_wdt_get_rate,
+	.set_status = clk_scmi_tclk_wdt_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_keyladder_core_ops = {
+	.get_rate = clk_scmi_keyladder_core_get_rate,
+	.set_rate = clk_scmi_keyladder_core_set_rate,
+	.set_status = clk_scmi_keyladder_core_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_keyladder_rng_ops = {
+	.get_rate = clk_scmi_keyladder_rng_get_rate,
+	.set_rate = clk_scmi_keyladder_rng_set_rate,
+	.set_status = clk_scmi_keyladder_rng_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_aclk_secure_s_ops = {
+	.get_rate = clk_scmi_aclk_secure_s_get_rate,
+	.set_rate = clk_scmi_aclk_secure_s_set_rate,
+	.set_status = clk_scmi_aclk_secure_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_hclk_secure_s_ops = {
+	.get_rate = clk_scmi_hclk_secure_s_get_rate,
+	.set_rate = clk_scmi_hclk_secure_s_set_rate,
+	.set_status = clk_scmi_hclk_secure_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_pclk_secure_s_ops = {
+	.get_rate = clk_scmi_pclk_secure_s_get_rate,
+	.set_rate = clk_scmi_pclk_secure_s_set_rate,
+	.set_status = clk_scmi_pclk_secure_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_rng_ops = {
+	.get_rate = clk_scmi_crypto_rng_get_rate,
+	.set_rate = clk_scmi_crypto_rng_set_rate,
+	.set_status = clk_scmi_crypto_rng_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_core_ops = {
+	.get_rate = clk_scmi_crypto_core_get_rate,
+	.set_rate = clk_scmi_crypto_core_set_rate,
+	.set_status = clk_scmi_crypto_core_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_pka_ops = {
+	.get_rate = clk_scmi_crypto_pka_get_rate,
+	.set_rate = clk_scmi_crypto_pka_set_rate,
+	.set_status = clk_scmi_crypto_pka_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_spll_ops = {
+	.get_rate = clk_scmi_spll_get_rate,
+	.set_rate = clk_scmi_spll_set_rate,
+	.set_status = clk_scmi_spll_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_hclk_sd_ops = {
+	.get_rate = clk_scmi_hclk_sd_get_rate,
+	.set_status = clk_scmi_hclk_sd_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_rng_s_ops = {
+	.get_rate = clk_scmi_crypto_rng_s_get_rate,
+	.set_rate = clk_scmi_crypto_rng_s_set_rate,
+	.set_status = clk_scmi_crypto_rng_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_core_s_ops = {
+	.get_rate = clk_scmi_crypto_core_s_get_rate,
+	.set_rate = clk_scmi_crypto_core_s_set_rate,
+	.set_status = clk_scmi_crypto_core_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_pka_s_ops = {
+	.get_rate = clk_scmi_crypto_pka_s_get_rate,
+	.set_rate = clk_scmi_crypto_pka_s_set_rate,
+	.set_status = clk_scmi_crypto_pka_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_a_crypto_s_ops = {
+	.get_rate = clk_scmi_a_crypto_s_get_rate,
+	.set_rate = clk_scmi_a_crypto_s_set_rate,
+	.set_status = clk_scmi_a_crypto_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_h_crypto_s_ops = {
+	.get_rate = clk_scmi_h_crypto_s_get_rate,
+	.set_rate = clk_scmi_h_crypto_s_set_rate,
+	.set_status = clk_scmi_h_crypto_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_p_crypto_s_ops = {
+	.get_rate = clk_scmi_p_crypto_s_get_rate,
+	.set_rate = clk_scmi_p_crypto_s_set_rate,
+	.set_status = clk_scmi_p_crypto_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_a_keylad_s_ops = {
+	.get_rate = clk_scmi_a_keylad_s_get_rate,
+	.set_rate = clk_scmi_a_keylad_s_set_rate,
+	.set_status = clk_scmi_a_keylad_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_h_keylad_s_ops = {
+	.get_rate = clk_scmi_h_keylad_s_get_rate,
+	.set_rate = clk_scmi_h_keylad_s_set_rate,
+	.set_status = clk_scmi_h_keylad_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_p_keylad_s_ops = {
+	.get_rate = clk_scmi_p_keylad_s_get_rate,
+	.set_rate = clk_scmi_p_keylad_s_set_rate,
+	.set_status = clk_scmi_p_keylad_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_trng_s_ops = {
+	.get_rate = clk_scmi_trng_s_get_rate,
+	.set_rate = clk_scmi_trng_s_set_rate,
+	.set_status = clk_scmi_trng_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_h_trng_s_ops = {
+	.get_rate = clk_scmi_h_trng_s_get_rate,
+	.set_rate = clk_scmi_h_trng_s_set_rate,
+	.set_status = clk_scmi_h_trng_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_p_otpc_s_ops = {
+	.get_rate = clk_scmi_p_otpc_s_get_rate,
+	.set_rate = clk_scmi_p_otpc_s_set_rate,
+	.set_status = clk_scmi_p_otpc_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otpc_s_ops = {
+	.get_rate = clk_scmi_otpc_s_get_rate,
+	.set_status = clk_scmi_otpc_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otp_phy_ops = {
+	.get_rate = clk_scmi_otp_phy_get_rate,
+	.set_status = clk_scmi_otp_phy_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otpc_rd_ops = {
+	.get_rate = clk_scmi_otpc_rd_get_rate,
+	.set_status = clk_scmi_otpc_rd_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otpc_arb_ops = {
+	.get_rate = clk_scmi_otpc_arb_get_rate,
+	.set_status = clk_scmi_otpc_arb_set_status,
+};
+
+rk_scmi_clock_t clock_table[] = {
+	RK3588_SCMI_CLOCK(SCMI_CLK_CPUL, "scmi_clk_cpul", &clk_scmi_cpul_ops, rk3588_cpul_rates, ARRAY_SIZE(rk3588_cpul_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_DSU, "scmi_clk_dsu", &clk_scmi_dsu_ops, rk3588_cpul_rates, ARRAY_SIZE(rk3588_cpul_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_CPUB01, "scmi_clk_cpub01", &clk_scmi_cpub01_ops, rk3588_cpub_rates, ARRAY_SIZE(rk3588_cpub_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_CPUB23, "scmi_clk_cpub23", &clk_scmi_cpub23_ops, rk3588_cpub_rates, ARRAY_SIZE(rk3588_cpub_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_DDR, "scmi_clk_ddr", NULL, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_GPU, "scmi_clk_gpu", &clk_scmi_gpu_ops, rk3588_gpu_rates, ARRAY_SIZE(rk3588_gpu_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_NPU, "scmi_clk_npu", &clk_scmi_npu_ops, rk3588_gpu_rates, ARRAY_SIZE(rk3588_gpu_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CLK_SBUS, "scmi_clk_sbus", &clk_scmi_sbus_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_PCLK_SBUS, "scmi_pclk_sbus", &clk_scmi_pclk_sbus_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_CCLK_SD, "scmi_cclk_sd", &clk_scmi_cclk_sdmmc_ops, rk3588_sdmmc_rates, ARRAY_SIZE(rk3588_sdmmc_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_DCLK_SD, "scmi_dclk_sd", &clk_scmi_dclk_sdmmc_ops, rk3588_sdmmc_rates, ARRAY_SIZE(rk3588_sdmmc_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_ACLK_SECURE_NS, "scmi_aclk_se_ns", &clk_scmi_aclk_secure_ns_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_HCLK_SECURE_NS, "scmi_hclk_se_ns", &clk_scmi_hclk_secure_ns_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_TCLK_WDT, "scmi_tclk_wdt", &clk_scmi_tclk_wdt_ops, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_KEYLADDER_CORE, "scmi_keylad_c", &clk_scmi_keyladder_core_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_KEYLADDER_RNG, "scmi_keylad_r", &clk_scmi_keyladder_rng_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_ACLK_SECURE_S, "scmi_aclk_se_s", &clk_scmi_aclk_secure_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_HCLK_SECURE_S, "scmi_hclk_se_s", &clk_scmi_hclk_secure_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_PCLK_SECURE_S, "scmi_pclk_se_s", &clk_scmi_pclk_secure_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_RNG, "scmi_crypto_r", &clk_scmi_crypto_rng_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_CORE, "scmi_crypto_c", &clk_scmi_crypto_core_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_PKA, "scmi_crypto_p", &clk_scmi_crypto_pka_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_SPLL, "scmi_spll", &clk_scmi_spll_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+	RK3588_SCMI_CLOCK(SCMI_HCLK_SD, "scmi_hclk_sd", &clk_scmi_hclk_sd_ops, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_RNG_S, "scmi_crypto_r_s", &clk_scmi_crypto_rng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_CORE_S, "scmi_crypto_c_s", &clk_scmi_crypto_core_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_CRYPTO_PKA_S, "scmi_crypto_p_s", &clk_scmi_crypto_pka_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_A_CRYPTO_S, "scmi_a_crypto_s", &clk_scmi_a_crypto_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_H_CRYPTO_S, "scmi_h_crypto_s", &clk_scmi_h_crypto_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_P_CRYPTO_S, "scmi_p_crypto_s", &clk_scmi_p_crypto_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_A_KEYLADDER_S, "scmi_a_keylad_s", &clk_scmi_a_keylad_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_H_KEYLADDER_S, "scmi_h_keylad_s", &clk_scmi_h_keylad_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_P_KEYLADDER_S, "scmi_p_keylad_s", &clk_scmi_p_keylad_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_TRNG_S, "scmi_trng_s", &clk_scmi_trng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_H_TRNG_S, "scmi_h_trng_s", &clk_scmi_h_trng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_P_OTPC_S, "scmi_p_otpc_s", &clk_scmi_p_otpc_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+	RK3588_SCMI_CLOCK(SCMI_OTPC_S, "scmi_otpc_s", &clk_scmi_otpc_s_ops, NULL, 0, true),
+	RK3588_SCMI_CLOCK(SCMI_OTP_PHY, "scmi_otp_phy", &clk_scmi_otp_phy_ops, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_OTPC_AUTO_RD, "scmi_otpc_rd", &clk_scmi_otpc_rd_ops, NULL, 0, false),
+	RK3588_SCMI_CLOCK(SCMI_OTPC_ARB, "scmi_otpc_arb", &clk_scmi_otpc_arb_ops, NULL, 0, false),
+};
+
+size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
+{
+	return ARRAY_SIZE(clock_table);
+}
+
+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 && !table->is_security)
+		return table;
+	else
+		return NULL;
+}
+
+void pvtplls_suspend(void)
+{
+	clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+	clk_dsu_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub01_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub23_set_rate(408000000, PLL_SEL_NOR);
+}
+
+void pvtplls_resume(void)
+{
+	clk_cpul_set_rate(sys_clk_info.cpul_rate, PLL_SEL_AUTO);
+	clk_dsu_set_rate(sys_clk_info.dsu_rate, PLL_SEL_AUTO);
+	clk_cpub01_set_rate(sys_clk_info.cpub01_rate, PLL_SEL_AUTO);
+	clk_cpub23_set_rate(sys_clk_info.cpub23_rate, PLL_SEL_AUTO);
+}
+
+void sys_reset_pvtplls_prepare(void)
+{
+	clk_gpu_set_rate(100000000, PLL_SEL_NOR);
+	clk_npu_set_rate(100000000, PLL_SEL_NOR);
+	clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub01_set_rate(408000000, PLL_SEL_NOR);
+	clk_cpub23_set_rate(408000000, PLL_SEL_NOR);
+	clk_dsu_set_rate(408000000, PLL_SEL_NOR);
+}
+
+void rockchip_clock_init(void)
+{
+	/* set gpll src div to 0 for cpul */
+	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5), CLKDIV_5BITS_SHF(0U, 9));
+	/* set gpll src div to 0 for cpub01 */
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(0U, 1));
+	/* set gpll src div to 0 for cpu23 */
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+		      CLKDIV_5BITS_SHF(0U, 1));
+
+	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+		      CPUB_PCLK_PATH_50M);
+	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+		      CPUB_PCLK_PATH_50M);
+
+	mmio_write_32(DSUCRU_BASE + DSUCRU_CLKSEL_CON(4),
+		      CLKDIV_5BITS_SHF(5U, 0));
+	mmio_write_32(DSUCRU_BASE + DSUCRU_CLKSEL_CON(4),
+		      BITS_WITH_WMASK(PCLK_DSU_ROOT_SEL_GPLL,
+				      PCLK_DSU_ROOT_SEL_MASK,
+				      PCLK_DSU_ROOT_SEL_SHIFT));
+
+	sys_clk_info.cpul_table = rk3588_cpul_pvtpll_table;
+	sys_clk_info.cpul_rate_count = ARRAY_SIZE(rk3588_cpul_pvtpll_table);
+	sys_clk_info.cpub01_table = rk3588_cpub0_pvtpll_table;
+	sys_clk_info.cpub01_rate_count = ARRAY_SIZE(rk3588_cpub0_pvtpll_table);
+	sys_clk_info.cpub23_table = rk3588_cpub1_pvtpll_table;
+	sys_clk_info.cpub23_rate_count = ARRAY_SIZE(rk3588_cpub1_pvtpll_table);
+	memcpy(sys_clk_info.cpub23_table, sys_clk_info.cpub01_table,
+	       sys_clk_info.cpub01_rate_count * sizeof(*sys_clk_info.cpub01_table));
+	sys_clk_info.gpu_table = rk3588_gpu_pvtpll_table;
+	sys_clk_info.gpu_rate_count = ARRAY_SIZE(rk3588_gpu_pvtpll_table);
+	sys_clk_info.npu_table = rk3588_npu_pvtpll_table;
+	sys_clk_info.npu_rate_count = ARRAY_SIZE(rk3588_npu_pvtpll_table);
+}
diff --git a/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h
new file mode 100644
index 00000000..66fddaa3
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CLOCK_H__
+#define __CLOCK_H__
+
+/* scmi-clocks indices */
+
+#define SCMI_CLK_CPUL			0
+#define SCMI_CLK_DSU			1
+#define SCMI_CLK_CPUB01			2
+#define SCMI_CLK_CPUB23			3
+#define SCMI_CLK_DDR			4
+#define SCMI_CLK_GPU			5
+#define SCMI_CLK_NPU			6
+#define SCMI_CLK_SBUS			7
+#define SCMI_PCLK_SBUS			8
+#define SCMI_CCLK_SD			9
+#define SCMI_DCLK_SD			10
+#define SCMI_ACLK_SECURE_NS		11
+#define SCMI_HCLK_SECURE_NS		12
+#define SCMI_TCLK_WDT			13
+#define SCMI_KEYLADDER_CORE		14
+#define SCMI_KEYLADDER_RNG		15
+#define SCMI_ACLK_SECURE_S		16
+#define SCMI_HCLK_SECURE_S		17
+#define SCMI_PCLK_SECURE_S		18
+#define SCMI_CRYPTO_RNG			19
+#define SCMI_CRYPTO_CORE		20
+#define SCMI_CRYPTO_PKA			21
+#define SCMI_SPLL			22
+#define SCMI_HCLK_SD			23
+#define SCMI_CRYPTO_RNG_S		24
+#define SCMI_CRYPTO_CORE_S		25
+#define SCMI_CRYPTO_PKA_S		26
+#define SCMI_A_CRYPTO_S			27
+#define SCMI_H_CRYPTO_S			28
+#define SCMI_P_CRYPTO_S			29
+#define SCMI_A_KEYLADDER_S		30
+#define SCMI_H_KEYLADDER_S		31
+#define SCMI_P_KEYLADDER_S		32
+#define SCMI_TRNG_S			33
+#define SCMI_H_TRNG_S			34
+#define SCMI_P_OTPC_S			35
+#define SCMI_OTPC_S			36
+#define SCMI_OTP_PHY			37
+#define SCMI_OTPC_AUTO_RD		38
+#define SCMI_OTPC_ARB			39
+
+/******** DSUCRU **************************************/
+#define DSUCRU_CLKSEL_CON(n)		(0x0300 + (n) * 4)
+
+/********Name=DSUCRU_CLKSEL_CON04,Offset=0x310********/
+#define PCLK_DSU_ROOT_SEL_SHIFT		5
+#define PCLK_DSU_ROOT_SEL_MASK		0x3
+#define PCLK_DSU_ROOT_SEL_GPLL		0x3
+
+/********Name=SECURE_SOFTRST_CON00,Offset=0xA00********/
+#define SRST_A_SECURE_NS_BIU		10
+#define SRST_H_SECURE_NS_BIU		11
+#define SRST_A_SECURE_S_BIU		12
+#define SRST_H_SECURE_S_BIU		13
+#define SRST_P_SECURE_S_BIU		14
+#define SRST_CRYPTO_CORE		15
+/********Name=SECURE_SOFTRST_CON01,Offset=0xA04********/
+#define SRST_CRYPTO_PKA			16
+#define SRST_CRYPTO_RNG			17
+#define SRST_A_CRYPTO			18
+#define SRST_H_CRYPTO			19
+#define SRST_KEYLADDER_CORE		25
+#define SRST_KEYLADDER_RNG		26
+#define SRST_A_KEYLADDER		27
+#define SRST_H_KEYLADDER		28
+#define SRST_P_OTPC_S			29
+#define SRST_OTPC_S			30
+#define SRST_WDT_S			31
+/********Name=SECURE_SOFTRST_CON02,Offset=0xA08********/
+#define SRST_T_WDT_S			32
+#define SRST_H_BOOTROM			33
+#define SRST_A_DCF			34
+#define SRST_P_DCF			35
+#define SRST_H_BOOTROM_NS		37
+#define SRST_P_KEYLADDER		46
+#define SRST_H_TRNG_S			47
+/********Name=SECURE_SOFTRST_CON03,Offset=0xA0C********/
+#define SRST_H_TRNG_NS			48
+#define SRST_D_SDMMC_BUFFER		49
+#define SRST_H_SDMMC			50
+#define SRST_H_SDMMC_BUFFER		51
+#define SRST_SDMMC			52
+#define SRST_P_TRNG_CHK			53
+#define SRST_TRNG_S			54
+
+#define SRST_INVALID			55
+
+void pvtplls_suspend(void);
+void pvtplls_resume(void);
+
+void rockchip_clock_init(void);
+
+#endif
diff --git a/plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c b/plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c
new file mode 100644
index 00000000..50b99e72
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include "rk3588_clk.h"
+#include <scmi_rstd.h>
+#include <soc.h>
+
+#define DEFAULT_RESET_DOM_ATTRIBUTE	0
+
+#define RK3588_SCMI_RESET(_id, _name, _attribute, _ops)		\
+{								\
+	.id = _id,						\
+	.name = _name,						\
+	.attribute = _attribute,				\
+	.rstd_ops = _ops,					\
+}
+
+static int rk3588_reset_explicit(rk_scmi_rstd_t *reset_domain,
+				 bool assert_not_deassert)
+{
+	int bank = reset_domain->id / 16;
+	int offset = reset_domain->id % 16;
+
+	mmio_write_32(SCRU_BASE + CRU_SOFTRST_CON(bank),
+		      BITS_WITH_WMASK(assert_not_deassert, 0x1U, offset));
+	return SCMI_SUCCESS;
+}
+
+static struct rk_scmi_rstd_ops rk3588_reset_domain_ops = {
+	.reset_explicit = rk3588_reset_explicit,
+};
+
+static rk_scmi_rstd_t rk3588_reset_domain_table[] = {
+	RK3588_SCMI_RESET(SRST_CRYPTO_CORE, "scmi_sr_cy_core", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_CRYPTO_PKA, "scmi_sr_cy_pka", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_CRYPTO_RNG, "scmi_sr_cy_rng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_A_CRYPTO, "scmi_sr_a_cy", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_CRYPTO, "scmi_sr_h_cy", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_KEYLADDER_CORE, "scmi_sr_k_core", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_KEYLADDER_RNG, "scmi_sr_k_rng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_P_OTPC_S, "scmi_sr_p_otp", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_OTPC_S, "scmi_sr_otp", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_WDT_S, "scmi_sr_wdt", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_T_WDT_S, "scmi_sr_t_wdt", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_BOOTROM, "scmi_sr_h_boot", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_P_KEYLADDER, "scmi_sr_p_ky", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_TRNG_S, "scmi_sr_h_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_TRNG_NS, "scmi_sr_t_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_D_SDMMC_BUFFER, "scmi_sr_d_sd", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_SDMMC, "scmi_sr_h_sd", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_H_SDMMC_BUFFER, "scmi_sr_h_sd_b", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_SDMMC, "scmi_sr_sd", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_P_TRNG_CHK, "scmi_sr_p_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_TRNG_S, "scmi_sr_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+	RK3588_SCMI_RESET(SRST_INVALID, "scmi_sr_invalid", DEFAULT_RESET_DOM_ATTRIBUTE, NULL),
+};
+
+static rk_scmi_rstd_t *
+rockchip_get_reset_domain_table(int id)
+{
+	rk_scmi_rstd_t *reset = rk3588_reset_domain_table;
+	int i = 0, cnt = ARRAY_SIZE(rk3588_reset_domain_table);
+
+	for (i = 0; i < cnt; i++) {
+		if (reset->id == id)
+			return &rk3588_reset_domain_table[i];
+		reset++;
+	}
+
+	return &rk3588_reset_domain_table[cnt - 1];
+}
+
+rk_scmi_rstd_t *rockchip_scmi_get_rstd(unsigned int agent_id,
+				       unsigned int scmi_id)
+
+{
+	return rockchip_get_reset_domain_table(scmi_id);
+}
+
+size_t rockchip_scmi_rstd_count(unsigned int agent_id)
+{
+	return SRST_TRNG_S;
+}
+
diff --git a/plat/rockchip/rk3588/drivers/secure/secure.c b/plat/rockchip/rk3588/drivers/secure/secure.c
new file mode 100644
index 00000000..fc9f2114
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/secure/secure.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#include <secure.h>
+#include <soc.h>
+
+static void secure_fw_master_init(void)
+{
+	uint32_t i;
+
+	/* ddr_mcu can access all ddr-regions */
+	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_MST(1), 0x0000ffff);
+	/* dcf/crypto_s can access all ddr-regions */
+	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_MST(14), 0x00000000);
+	/* dsu_mp_sec can access all ddr-regions.
+	 * DSU access memory [f000_0000~ff00_0000] through MP in firewall_ddr.
+	 */
+	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_MST(36), 0xffff0000);
+
+	/* all other ns-master can't access all ddr-regions */
+	for (i = 0; i < FIREWALL_DDR_MST_CNT; i++) {
+		if (i == 1 || i == 14 || i == 36)
+			continue;
+
+		mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_MST(i), 0xffffffff);
+	}
+
+	/* mcu_pmu can access all sram-regions */
+	mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_MST(19), 0x000000ff);
+	/* dsu mp-sec can access all sram-regions */
+	mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_MST(38), 0x000000ff);
+	/* nsp_dsu2main_sec can access all sram-regions */
+	mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_MST(41), 0x00000000);
+
+	/* all ns-master can't access all sram-regions */
+	for (i = 0; i < FIREWALL_SYSMEM_MST_CNT; i++) {
+		if (i == 19 || i == 38 || i == 41)
+			continue;
+
+		mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_MST(i),
+			      0x00ff00ff);
+	}
+
+	/* dsu-ns can't access all ddr-regions, dsu-s can access all ddr-regions */
+	mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_MST(0), 0xffffffff);
+	mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_MST(1), 0x00000000);
+	dsb();
+	isb();
+}
+
+/* unit: Mb */
+static void dsu_fw_rgn_config(uint64_t base_mb, uint64_t top_mb, int rgn_id)
+{
+	int i;
+
+	if (rgn_id >= FIREWALL_DSU_RGN_CNT || rgn_id < 0) {
+		ERROR("%s regions-id:%d is invalid!\n", __func__, rgn_id);
+		panic();
+	}
+
+	mmio_write_32(FIREWALL_DSU_BASE + FIREWALL_DSU_RGN(rgn_id),
+		      RG_MAP_SECURE(top_mb, base_mb));
+
+	for (i = 0; i < DDR_CHN_CNT; i++)
+		mmio_setbits_32(FIREWALL_DSU_BASE + FIREWALL_DSU_CON(i),
+				BIT(rgn_id));
+}
+
+/* unit: Mb */
+static void ddr_fw_rgn_config(uint64_t base_mb, uint64_t top_mb, int rgn_id)
+{
+	if (rgn_id >= FIREWALL_DDR_RGN_CNT || rgn_id < 0) {
+		ERROR("%s regions-id:%d is invalid!\n", __func__, rgn_id);
+		panic();
+	}
+
+	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_RGN(rgn_id),
+		      RG_MAP_SECURE(top_mb, base_mb));
+
+	/* enable region */
+	mmio_setbits_32(FIREWALL_DDR_BASE + FIREWALL_DDR_CON,
+			BIT(rgn_id));
+}
+
+/* Unit: Kb */
+static void sram_fw_rgn_config(uint64_t base_kb, uint64_t top_kb, int rgn_id)
+{
+	if (rgn_id >= FIREWALL_SYSMEM_RGN_CNT || rgn_id < 0) {
+		ERROR("%s regions-id:%d is invalid!\n", __func__, rgn_id);
+		panic();
+	}
+
+	mmio_write_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_RGN(rgn_id),
+		      RG_MAP_SRAM_SECURE(top_kb, base_kb));
+
+	/* enable region */
+	mmio_setbits_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_CON, BIT(rgn_id));
+}
+
+static void secure_region_init(void)
+{
+	uint32_t i;
+
+	/* disable all region first except region0 */
+	mmio_clrbits_32(FIREWALL_DDR_BASE + FIREWALL_DDR_CON, 0xfffe);
+	for (i = 0; i < FIREWALL_DSU_CON_CNT; i++)
+		mmio_clrbits_32(FIREWALL_DSU_BASE + FIREWALL_DSU_CON(i), 0xfffe);
+	mmio_clrbits_32(FIREWALL_SYSMEM_BASE + FIREWALL_SYSMEM_CON, 0xfe);
+
+	secure_fw_master_init();
+
+	/* Use FW_DDR_RGN0_REG to config 0~1M space to secure */
+	dsu_fw_rgn_config(0, 1, 0);
+	ddr_fw_rgn_config(0, 1, 0);
+
+	/* Use FIREWALL_SYSMEM_RGN0 to config SRAM_ENTRY code(0~4k of sram) to secure */
+	sram_fw_rgn_config(0, 4, 0);
+	/* For 0xffff0000~0xffffffff, use FIREWALL_SYSMEM_RGN7 to config
+	 * 960~1024k of sram to secure.
+	 */
+	sram_fw_rgn_config(960, 1024, 7);
+}
+
+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 sgrf_init(void)
+{
+	uint32_t i;
+
+	secure_region_init();
+
+	/* config master ddr_mcu_prot|dcf_wr|dcf_rd as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(14), 0x001f0011);
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(15), 0xffffffff);
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(16), 0x03ff03ff);
+
+	/* config slave mailbox_mcu_ddr as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(4), 0xffff2000);
+	/* config slave int256mux4_mcu_ddr|int256mux4_mcu_pmu as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(5), 0xffff0060);
+	/* config slave ddrgrf*|dma2ddr|ddrphy*_cru|umctl* as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(24), 0xffff0fbf);
+	/* config slave ddrphy*|ddr_stanby*|ddr_mcu_timer|ddr_mcu_wdt as secure */
+	mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(25), 0xffff03ff);
+
+	/* config all other slave as ns */
+	for (i = 0; i < SGRF_FIREWALL_CON_CNT; i++) {
+		if (i == 4 || i == 5 || i == 24 || i == 25)
+			continue;
+
+		mmio_write_32(BUSSGRF_BASE + SGRF_FIREWALL_CON(i), 0xffff0000);
+	}
+
+	/* config vad_hprot non-secure, pmu_mcu_hprot as secure */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(0), 0x00180010);
+	/* config pmu1, pmu0, pmu_sram as secure */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(1), 0xefbe6020);
+	/* config remap_pmu_mem, h_pmu_mem as secure */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(2), 0x01f900c0);
+
+	/* disable dp encryption */
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(13), 0x00180018);
+
+	/* select grf config for pcie ats */
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(17), 0x11111111);
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(18), 0x11111111);
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(19), 0x00110011);
+}
diff --git a/plat/rockchip/rk3588/drivers/secure/secure.h b/plat/rockchip/rk3588/drivers/secure/secure.h
new file mode 100644
index 00000000..d9c234fd
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/secure/secure.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURE_H
+#define SECURE_H
+
+/* DSUSGRF */
+#define DSU_SGRF_SOC_CON(i)		((i) * 4)
+#define DSUSGRF_SOC_CON(i)		((i) * 4)
+#define DSUSGRF_SOC_CON_CNT		13
+#define DSUSGRF_DDR_HASH_CON(i)		(0x240 + (i) * 4)
+#define DSUSGRF_DDR_HASH_CON_CNT	8
+
+/* PMUSGRF */
+#define PMU1SGRF_SOC_CON(n)		((n) * 4)
+
+/* SGRF */
+#define SGRF_SOC_CON(i)			((i) * 4)
+#define SGRF_FIREWALL_CON(i)		(0x240 + (i) * 4)
+#define SGRF_FIREWALL_CON_CNT		32
+
+/* ddr firewall */
+#define FIREWALL_DDR_RGN(i)		((i) * 0x4)
+#define FIREWALL_DDR_RGN_CNT		16
+#define FIREWALL_DDR_MST(i)		(0x40 + (i) * 0x4)
+#define FIREWALL_DDR_MST_CNT		42
+#define FIREWALL_DDR_CON		0xf0
+
+#define FIREWALL_SYSMEM_RGN(i)		((i) * 0x4)
+#define FIREWALL_SYSMEM_RGN_CNT		8
+#define FIREWALL_SYSMEM_MST(i)		(0x40 + (i) * 0x4)
+#define FIREWALL_SYSMEM_MST_CNT		43
+#define FIREWALL_SYSMEM_CON		0xf0
+
+#define FIREWALL_DSU_RGN(i)		((i) * 0x4)
+#define FIREWALL_DSU_RGN_CNT		16
+#define FIREWALL_DSU_MST(i)		(0x40 + (i) * 0x4)
+#define FIREWALL_DSU_MST_CNT		2
+#define FIREWALL_DSU_CON(i)		(0xf0 + (i) * 4)
+#define FIREWALL_DSU_CON_CNT		4
+
+#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) << 16) | ((base_kb) / 4 & 0xff))
+
+void secure_timer_init(void);
+void sgrf_init(void);
+
+#endif /* SECURE_H */
diff --git a/plat/rockchip/rk3588/drivers/soc/soc.c b/plat/rockchip/rk3588/drivers/soc/soc.c
new file mode 100644
index 00000000..6db81eeb
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/soc/soc.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#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 <rk3588_clk.h>
+#include <secure.h>
+#include <soc.h>
+
+#define RK3588_DEV_RNG0_BASE	0xf0000000
+#define RK3588_DEV_RNG0_SIZE	0x0ffff000
+
+const mmap_region_t plat_rk_mmap[] = {
+	MAP_REGION_FLAT(RK3588_DEV_RNG0_BASE, RK3588_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
+};
+
+void timer_hp_init(void)
+{
+	if ((mmio_read_32(TIMER_HP_BASE + TIMER_HP_CTRL) & 0x1) != 0)
+		return;
+
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_CTRL, 0x0);
+	dsb();
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_LOAD_COUNT1, 0xffffffff);
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_INT_EN, 0);
+	dsb();
+	mmio_write_32(TIMER_HP_BASE + TIMER_HP_CTRL, 0x1);
+}
+
+static void system_reset_init(void)
+{
+	/* enable wdt_ns0~4 trigger global reset and select first reset.
+	 * enable tsadc trigger global reset and select first reset.
+	 * enable global reset and wdt trigger pmu reset.
+	 * select first reset trigger pmu reset.s
+	 */
+	mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, 0xffdf);
+
+	/* enable wdt_s, wdt_ns reset */
+	mmio_write_32(BUSSGRF_BASE + SGRF_SOC_CON(2), 0x0c000c00);
+
+	/* reset width = 0xffff */
+	mmio_write_32(PMU1GRF_BASE + PMU1GRF_SOC_CON(1), 0xffffffff);
+
+	/* enable first/tsadc/wdt reset output */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(0), 0x00070007);
+
+	/* pmu1_grf pmu1_ioc hold */
+	mmio_write_32(PMU1GRF_BASE + PMU1GRF_SOC_CON(7), 0x30003000);
+
+	/* pmu1sgrf hold */
+	mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(14), 0x00200020);
+
+	/* select tsadc_shut_m0 ionmux*/
+	mmio_write_32(PMU0IOC_BASE + 0x0, 0x00f00020);
+}
+
+void plat_rockchip_soc_init(void)
+{
+	rockchip_clock_init();
+	secure_timer_init();
+	timer_hp_init();
+	system_reset_init();
+	sgrf_init();
+	rockchip_init_scmi_server();
+}
diff --git a/plat/rockchip/rk3588/drivers/soc/soc.h b/plat/rockchip/rk3588/drivers/soc/soc.h
new file mode 100644
index 00000000..9af179a4
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/soc/soc.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SOC_H__
+#define __SOC_H__
+
+enum pll_id {
+	APLL_ID,
+	DPLL_ID,
+	GPLL_ID,
+	CPLL_ID,
+	NPLL_ID,
+	VPLL_ID,
+};
+
+enum pmu_pll_id {
+	PPLL_ID = 0,
+	HPLL_ID
+};
+
+enum cru_mode_con00 {
+	CLK_APLL,
+	CLK_DPLL,
+	CLK_CPLL,
+	CLK_GPLL,
+	CLK_REVSERVED,
+	CLK_NPLL,
+	CLK_VPLL,
+	CLK_USBPLL,
+};
+
+#define KHz				1000
+#define MHz				(1000 * KHz)
+#define OSC_HZ				(24 * MHz)
+
+/* CRU */
+#define GLB_SRST_FST_CFG_VAL		0xfdb9
+
+#define CRU_PLLS_CON(pll_id, i)		(0x160 + (pll_id) * 0x20 + (i) * 0x4)
+#define CRU_PLL_CON(i)			((i) * 0x4)
+#define CRU_MODE_CON0			0x280
+#define CRU_CLKSEL_CON(i)		((i) * 0x4 + 0x300)
+#define CRU_CLKGATE_CON(i)		((i) * 0x4 + 0x800)
+#define CRU_CLKGATE_CON_CNT		78
+#define CRU_SOFTRST_CON(i)		((i) * 0x4 + 0xa00)
+#define CRU_GLB_CNT_TH			0xc00
+#define CRU_GLB_SRST_FST		0xc08
+#define CRU_GLB_SRST_SND		0xc0c
+#define CRU_GLB_RST_CON			0xc10
+#define CRU_GLB_RST_ST			0xc04
+#define CRU_SDIO_CON0			0xc24
+#define CRU_SDIO_CON1			0xc28
+#define CRU_SDMMC_CON0			0xc30
+#define CRU_SDMMC_CON1			0xc34
+#define CRU_AUTOCS_CON0(id)		(0xd00 + (id) * 8)
+#define CRU_AUTOCS_CON1(id)		(0xd04 + (id) * 8)
+
+#define CRU_AUTOCS_ID_CNT		74
+
+#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)
+
+#define CRU_BIGCPU02_RST_MSK		0x30
+#define CRU_BIGCPU13_RST_MSK		0x300
+
+#define PHPCRU_CLKGATE_CON		0x800
+#define PHPCRU_CLKGATE_CON_CNT		1
+
+#define SECURECRU_CLKGATE_CON(i)	((i) * 0x4 + 0x800)
+#define SECURECRU_CLKGATE_CON_CNT	4
+
+#define PMU1CRU_CLKGATE_CON_CNT		6
+
+/* CENTER GRF */
+#define CENTER_GRF_CON(i)		((i) * 4)
+
+/* PMU1GRF */
+#define PMU1GRF_SOC_CON(n)		((n) * 4)
+#define PMU1GRF_SOC_ST			0x60
+#define PMU1GRF_OS_REG(n)		(0x200 + ((n) * 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)
+
+/* SYSGRF */
+#define SYS_GRF_NOC_CON(n)		(0x100 + (n) * 4)
+#define SYS_GRF_SOC_CON(n)		(0x300 + (n) * 4)
+#define SYS_GRF_SOC_STATUS(n)		(0x380 + (n) * 4)
+
+#define SYS_GRF_LITTLE_CPUS_WFE		0xf
+#define SYS_GRF_CORE0_CPUS_WFE		0x30
+#define SYS_GRF_CORE1_CPUS_WFE		0xc0
+#define SYS_GRF_BIG_CPUS_WFE		0xf0
+#define SYS_GRF_LITTLE_CPUS_WFI		0xf00
+#define SYS_GRF_CORE0_CPUS_WFI		0x3000
+#define SYS_GRF_CORE1_CPUS_WFI		0xc000
+
+/* 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,
+};
+
+/* 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)
+
+#define STIMER0_CHN_BASE(n)		(STIMER0_BASE + 0x20 * (n))
+#define STIMER1_CHN_BASE(n)		(STIMER1_BASE + 0x20 * (n))
+
+/* cpu timer */
+#define TIMER_HP_REVISION		0x0
+#define TIMER_HP_CTRL			0x4
+#define TIMER_HP_INT_EN			0x8
+#define TIMER_HP_T24_GCD		0xc
+#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
+
+ /* 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
+
+/* DDRGRF */
+#define DDRGRF_CHA_CON(i)		((i) * 4)
+#define DDRGRF_CHB_CON(i)		(0x30 + (i) * 4)
+
+#define DDR_CHN_CNT			4
+
+#endif /* __SOC_H__ */
diff --git a/plat/rockchip/rk3588/include/plat.ld.S b/plat/rockchip/rk3588/include/plat.ld.S
new file mode 100644
index 00000000..e3ea9ccf
--- /dev/null
+++ b/plat/rockchip/rk3588/include/plat.ld.S
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#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/rk3588/include/plat_sip_calls.h b/plat/rockchip/rk3588/include/plat_sip_calls.h
new file mode 100644
index 00000000..bc4455f9
--- /dev/null
+++ b/plat/rockchip/rk3588/include/plat_sip_calls.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_SIP_CALLS_H__
+#define __PLAT_SIP_CALLS_H__
+
+#define RK_PLAT_SIP_NUM_CALLS	0
+
+#endif /* __PLAT_SIP_CALLS_H__ */
diff --git a/plat/rockchip/rk3588/include/platform_def.h b/plat/rockchip/rk3588/include/platform_def.h
new file mode 100644
index 00000000..5946af0b
--- /dev/null
+++ b/plat/rockchip/rk3588/include/platform_def.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <plat/common/common_def.h>
+
+#include <rk3588_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		1
+#define PLATFORM_CLUSTER0_CORE_COUNT	8
+#define PLATFORM_CLUSTER1_CORE_COUNT	0
+#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	8
+
+/*
+ * 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		(0x0)
+#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/rk3588/plat_sip_calls.c b/plat/rockchip/rk3588/plat_sip_calls.c
new file mode 100644
index 00000000..496e8d75
--- /dev/null
+++ b/plat/rockchip/rk3588/plat_sip_calls.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#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/rk3588/platform.mk b/plat/rockchip/rk3588/platform.mk
new file mode 100644
index 00000000..2fadb5a5
--- /dev/null
+++ b/plat/rockchip/rk3588/platform.mk
@@ -0,0 +1,98 @@
+#
+# Copyright (c) 2024, Rockchip, Inc. 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 lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+# GIC-600 configuration
+GICV3_IMPL		:=	GIC600
+GICV3_SUPPORT_GIC600   	:=      1
+
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+PLAT_INCLUDES		:=	-Iinclude/plat/common				\
+				-Idrivers/arm/gic/v3/				\
+				-Idrivers/scmi-msg/				\
+				-I${RK_PLAT_COMMON}/				\
+				-I${RK_PLAT_COMMON}/drivers/pmu/		\
+				-I${RK_PLAT_COMMON}/drivers/parameter/		\
+				-I${RK_PLAT_COMMON}/include/			\
+				-I${RK_PLAT_COMMON}/pmusram/			\
+				-I${RK_PLAT_COMMON}/scmi/			\
+				-I${RK_PLAT_SOC}/				\
+				-I${RK_PLAT_SOC}/drivers/pmu/			\
+				-I${RK_PLAT_SOC}/drivers/scmi/			\
+				-I${RK_PLAT_SOC}/drivers/secure/		\
+				-I${RK_PLAT_SOC}/drivers/soc/			\
+				-I${RK_PLAT_SOC}/include/
+
+RK_GIC_SOURCES		:=	${GICV3_SOURCES}				\
+				plat/common/plat_gicv3.c			\
+				${RK_PLAT}/common/rockchip_gicv3.c
+
+PLAT_BL_COMMON_SOURCES	:=	${XLAT_TABLES_LIB_SRCS}				\
+				common/desc_image_load.c			\
+				plat/common/aarch64/crash_console_helpers.S	\
+				lib/bl_aux_params/bl_aux_params.c		\
+				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/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_a55.S			\
+				lib/cpus/aarch64/cortex_a76.S			\
+				${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}/params_setup.c                \
+				${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S	\
+				${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
+				${RK_PLAT_COMMON}/scmi/scmi.c			\
+				${RK_PLAT_COMMON}/scmi/scmi_clock.c		\
+				${RK_PLAT_COMMON}/scmi/scmi_rstd.c		\
+				${RK_PLAT_SOC}/plat_sip_calls.c         	\
+				${RK_PLAT_SOC}/drivers/secure/secure.c		\
+				${RK_PLAT_SOC}/drivers/soc/soc.c		\
+				${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
+				${RK_PLAT_SOC}/drivers/pmu/pm_pd_regs.c		\
+				${RK_PLAT_SOC}/drivers/scmi/rk3588_clk.c	\
+				${RK_PLAT_SOC}/drivers/scmi/rk3588_rstd.c
+
+CTX_INCLUDE_AARCH32_REGS :=     0
+ENABLE_PLAT_COMPAT	:=	0
+MULTI_CONSOLE_API	:=	1
+ERRATA_A55_1530923	:=	1
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY	:=	1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM	:=	0
+
+ENABLE_SPE_FOR_LOWER_ELS	:= 0
+
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+$(eval $(call add_define,PLAT_RK_CPU_RESET_EARLY))
diff --git a/plat/rockchip/rk3588/rk3588_def.h b/plat/rockchip/rk3588/rk3588_def.h
new file mode 100644
index 00000000..412495a8
--- /dev/null
+++ b/plat/rockchip/rk3588/rk3588_def.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_DEF_H__
+#define __PLAT_DEF_H__
+
+#define SIZE_K(n)		((n) * 1024)
+
+#define WITH_16BITS_WMSK(bits)	(0xffff0000 | (bits))
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define RK_BL31_PLAT_PARAM_VAL	0x0f1e2d3c4b5a6978ULL
+
+#define UMCTL0_BASE		0xf7000000
+#define UMCTL1_BASE		0xf8000000
+#define UMCTL2_BASE		0xf9000000
+#define UMCTL3_BASE		0xfa000000
+
+#define GIC600_BASE		0xfe600000
+#define GIC600_SIZE		SIZE_K(64)
+
+#define DAPLITE_BASE		0xfd100000
+#define PMU0SGRF_BASE		0xfd580000
+#define PMU1SGRF_BASE		0xfd582000
+#define BUSSGRF_BASE		0xfd586000
+#define DSUSGRF_BASE		0xfd587000
+#define PMU0GRF_BASE		0xfd588000
+#define PMU1GRF_BASE		0xfd58a000
+
+#define SYSGRF_BASE		0xfd58c000
+#define BIGCORE0GRF_BASE	0xfd590000
+#define BIGCORE1GRF_BASE	0xfd592000
+#define LITCOREGRF_BASE		0xfd594000
+#define DSUGRF_BASE		0xfd598000
+#define DDR01GRF_BASE		0xfd59c000
+#define DDR23GRF_BASE		0xfd59d000
+#define CENTERGRF_BASE		0xfd59e000
+#define GPUGRF_BASE		0xfd5a0000
+#define NPUGRF_BASE		0xfd5a2000
+#define USBGRF_BASE		0xfd5ac000
+#define PHPGRF_BASE		0xfd5b0000
+#define PCIE3PHYGRF_BASE	0xfd5b8000
+#define USB2PHY0_GRF_BASE	0xfd5d0000
+#define USB2PHY1_GRF_BASE	0xfd5d4000
+#define USB2PHY2_GRF_BASE	0xfd5d8000
+#define USB2PHY3_GRF_BASE	0xfd5dc000
+
+#define PMU0IOC_BASE		0xfd5f0000
+#define PMU1IOC_BASE		0xfd5f4000
+#define BUSIOC_BASE		0xfd5f8000
+#define VCCIO1_4_IOC_BASE	0xfd5f9000
+#define VCCIO3_5_IOC_BASE	0xfd5fa000
+#define VCCIO2_IOC_BASE		0xfd5fb000
+#define VCCIO6_IOC_BASE		0xfd5fc000
+
+#define SRAM_BASE		0xff000000
+#define PMUSRAM_BASE		0xff100000
+#define PMUSRAM_SIZE		SIZE_K(128)
+#define PMUSRAM_RSIZE		SIZE_K(64)
+
+#define CRU_BASE		0xfd7c0000
+#define PHP_CRU_BASE		0xfd7c8000
+#define SCRU_BASE		0xfd7d0000
+#define BUSSCRU_BASE		0xfd7d8000
+#define PMU1SCRU_BASE		0xfd7e0000
+#define PMU1CRU_BASE		0xfd7f0000
+
+#define DDR0CRU_BASE		0xfd800000
+#define DDR1CRU_BASE		0xfd804000
+#define DDR2CRU_BASE		0xfd808000
+#define DDR3CRU_BASE		0xfd80c000
+
+#define BIGCORE0CRU_BASE	0xfd810000
+#define BIGCORE1CRU_BASE	0xfd812000
+#define LITCRU_BASE		0xfd814000
+#define DSUCRU_BASE		0xfd818000
+
+#define I2C0_BASE		0xfd880000
+#define UART0_BASE		0xfd890000
+#define GPIO0_BASE		0xfd8a0000
+#define PWM0_BASE		0xfd8b0000
+#define PMUPVTM_BASE		0xfd8c0000
+#define TIMER_HP_BASE		0xfd8c8000
+#define PMU0_BASE		0xfd8d0000
+#define PMU1_BASE		0xfd8d4000
+#define PMU2_BASE		0xfd8d8000
+#define PMU_BASE		PMU0_BASE
+#define PMUWDT_BASE		0xfd8e0000
+#define PMUTIMER_BASE		0xfd8f0000
+#define OSC_CHK_BASE		0xfd9b0000
+#define VOP_BASE		0xfdd90000
+#define HDMIRX_BASE		0xfdee0000
+
+#define MSCH0_BASE		0xfe000000
+#define MSCH1_BASE		0xfe002000
+#define MSCH2_BASE		0xfe004000
+#define MSCH3_BASE		0xfe006000
+#define FIREWALL_DSU_BASE	0xfe010000
+#define FIREWALL_DDR_BASE	0xfe030000
+#define FIREWALL_SYSMEM_BASE	0xfe038000
+#define DDRPHY0_BASE		0xfe0c0000
+#define DDRPHY1_BASE		0xfe0d0000
+#define DDRPHY2_BASE		0xfe0e0000
+#define DDRPHY3_BASE		0xfe0f0000
+#define TIMER_DDR_BASE		0xfe118000
+#define KEYLADDER_BASE		0xfe380000
+#define CRYPTO_S_BASE		0xfe390000
+#define OTP_S_BASE		0xfe3a0000
+#define DCF_BASE		0xfe3c0000
+#define STIMER0_BASE		0xfe3d0000
+#define WDT_S_BASE		0xfe3e0000
+#define CRYPTO_S_BY_KEYLAD_BASE	0xfe420000
+#define NSTIMER0_BASE		0xfeae0000
+#define NSTIMER1_BASE		0xfeae8000
+#define WDT_NS_BASE		0xfeaf0000
+
+#define UART1_BASE		0xfeb40000
+#define UART2_BASE		0xfeb50000
+#define UART3_BASE		0xfeb60000
+#define UART4_BASE		0xfeb70000
+#define UART5_BASE		0xfeb80000
+#define UART6_BASE		0xfeb90000
+#define UART7_BASE		0xfeba0000
+#define UART8_BASE		0xfebb0000
+#define UART9_BASE		0xfebc0000
+
+#define GPIO1_BASE		0xfec20000
+#define GPIO2_BASE		0xfec30000
+#define GPIO3_BASE		0xfec40000
+#define GPIO4_BASE		0xfec50000
+
+#define MAILBOX1_BASE		0xfec70000
+#define OTP_NS_BASE		0xfecc0000
+#define INTMUX0_DDR_BASE	0Xfecf8000
+#define INTMUX1_DDR_BASE	0Xfecfc000
+#define STIMER1_BASE		0xfed30000
+
+/**************************************************************************
+ * sys sram allocation
+ **************************************************************************/
+#define SRAM_ENTRY_BASE		SRAM_BASE
+#define SRAM_PMUM0_SHMEM_BASE	(SRAM_ENTRY_BASE + SIZE_K(3))
+#define SRAM_LD_BASE		(SRAM_ENTRY_BASE + SIZE_K(4))
+#define SRAM_LD_SIZE		SIZE_K(64)
+
+#define SRAM_LD_SP		(SRAM_LD_BASE + SRAM_LD_SIZE -\
+				 128)
+
+/**************************************************************************
+ * share mem region allocation: 1M~2M
+ **************************************************************************/
+#define DDR_SHARE_MEM		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
+
+/**************************************************************************
+ * UART related constants
+ **************************************************************************/
+#define RK_DBG_UART_BASE		UART2_BASE
+#define RK_DBG_UART_BAUDRATE		1500000
+#define RK_DBG_UART_CLOCK		24000000
+
+/******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_TICKS	24000000
+#define SYS_COUNTER_FREQ_IN_MHZ		24
+
+/******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+
+/* Base rk_platform compatible GIC memory map */
+#define PLAT_GICD_BASE			GIC600_BASE
+#define PLAT_GICC_BASE			0
+#define PLAT_GICR_BASE			(GIC600_BASE + 0x80000)
+#define PLAT_GICITS0_BASE		0xfe640000
+#define PLAT_GICITS1_BASE		0xfe660000
+
+/******************************************************************************
+ * sgi, ppi
+ ******************************************************************************/
+#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 RK_IRQ_SEC_PHY_TIMER		29
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+
+#define PLAT_RK_GICV3_G1S_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,	\
+		       INTR_GROUP1S, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_GICV3_G0_IRQS						\
+	INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
+		       INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+/******************************************************************************
+ * pm reg region memory
+ ******************************************************************************/
+#define ROCKCHIP_PM_REG_REGION_MEM_SIZE		SIZE_K(4)
+
+#endif /* __PLAT_DEF_H__ */
diff --git a/plat/rpi/rpi4/aarch64/armstub8_header.S b/plat/rpi/common/aarch64/armstub8_header.S
similarity index 89%
rename from plat/rpi/rpi4/aarch64/armstub8_header.S
rename to plat/rpi/common/aarch64/armstub8_header.S
index 246358d0..dc1e54e1 100644
--- a/plat/rpi/rpi4/aarch64/armstub8_header.S
+++ b/plat/rpi/common/aarch64/armstub8_header.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/rpi/common/aarch64/plat_helpers.S b/plat/rpi/common/aarch64/plat_helpers.S
index f045e211..18873af7 100644
--- a/plat/rpi/common/aarch64/plat_helpers.S
+++ b/plat/rpi/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,10 +27,19 @@
 	 *
 	 *  This function uses the plat_rpi3_calc_core_pos()
 	 *  definition to get the index of the calling CPU.
+	 *
+	 *  When MT is set, lowest affinity represents the thread ID.
+	 *  Since we only support one thread per core, discard this field
+	 *  so cluster and core IDs go back into Aff1 and Aff0 respectively.
+	 *  The upper bits are also affected, but plat_rpi3_calc_core_pos()
+	 *  does not use them.
 	 * -----------------------------------------------------
 	 */
 func plat_my_core_pos
 	mrs	x0, mpidr_el1
+	tst	x0, #MPIDR_MT_MASK
+	lsr	x1, x0, #MPIDR_AFFINITY_BITS
+	csel	x0, x1, x0, ne
 	b	plat_rpi3_calc_core_pos
 endfunc plat_my_core_pos
 
@@ -164,10 +173,16 @@ endfunc platform_mem_init
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_init
-	mov_imm	x0, PLAT_RPI_MINI_UART_BASE
+	mov_imm	x0, PLAT_RPI_CRASH_UART_BASE
+#if PLAT_RPI_CRASH_UART_BASE == PLAT_RPI_PL011_UART_BASE
+	mov_imm	x1, RPI4_PL011_UART_CLOCK
+	mov_imm	x2, PLAT_RPI_UART_BAUDRATE
+	b	console_pl011_core_init
+#else
 	mov	x1, xzr
 	mov	x2, xzr
 	b	console_16550_core_init
+#endif
 endfunc plat_crash_console_init
 
 	/* ---------------------------------------------
@@ -178,8 +193,12 @@ endfunc plat_crash_console_init
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_putc
-	mov_imm	x1, PLAT_RPI_MINI_UART_BASE
+	mov_imm	x1, PLAT_RPI_CRASH_UART_BASE
+#if PLAT_RPI_CRASH_UART_BASE == PLAT_RPI_PL011_UART_BASE
+	b	console_pl011_core_putc
+#else
 	b	console_16550_core_putc
+#endif
 endfunc plat_crash_console_putc
 
 	/* ---------------------------------------------
@@ -191,8 +210,12 @@ endfunc plat_crash_console_putc
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_flush
-	mov_imm	x0, PLAT_RPI_MINI_UART_BASE
+	mov_imm	x0, PLAT_RPI_CRASH_UART_BASE
+#if PLAT_RPI_CRASH_UART_BASE == PLAT_RPI_PL011_UART_BASE
+	b	console_pl011_core_flush
+#else
 	b	console_16550_core_flush
+#endif
 endfunc plat_crash_console_flush
 
 	/* ---------------------------------------------
diff --git a/plat/rpi/rpi4/include/plat_macros.S b/plat/rpi/common/include/plat_macros.S
similarity index 87%
rename from plat/rpi/rpi4/include/plat_macros.S
rename to plat/rpi/common/include/plat_macros.S
index 6007d031..576d0ffc 100644
--- a/plat/rpi/rpi4/include/plat_macros.S
+++ b/plat/rpi/common/include/plat_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/rpi/common/include/rpi_shared.h b/plat/rpi/common/include/rpi_shared.h
index ddf239eb..8562c3d5 100644
--- a/plat/rpi/common/include/rpi_shared.h
+++ b/plat/rpi/common/include/rpi_shared.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,14 +7,20 @@
 #ifndef RPI_SHARED_H
 #define RPI_SHARED_H
 
+#include <stddef.h>
 #include <stdint.h>
 
+#include <drivers/console.h>
+
 /*******************************************************************************
  * Function and variable prototypes
  ******************************************************************************/
 
-/* Utility functions */
+/* Serial console functions */
 void rpi3_console_init(void);
+int rpi3_register_used_uart(console_t *console);
+
+/* Utility functions */
 void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
 			    uintptr_t code_start, uintptr_t code_limit,
 			    uintptr_t rodata_start, uintptr_t rodata_limit
@@ -23,6 +29,8 @@ void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
 #endif
 			    );
 
+uintptr_t rpi4_get_dtb_address(void);
+
 /* Optional functions required in the Raspberry Pi 3 port */
 unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr);
 
@@ -38,4 +46,10 @@ int rpi3_vc_hardware_get_board_revision(uint32_t *revision);
 
 int plat_rpi_get_model(void);
 
+/*******************************************************************************
+ * Platform implemented functions
+ ******************************************************************************/
+
+void plat_rpi_bl31_custom_setup(void);
+
 #endif /* RPI3_PRIVATE_H */
diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c
index ef88bf10..89764969 100644
--- a/plat/rpi/common/rpi3_common.c
+++ b/plat/rpi/common/rpi3_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,9 +13,6 @@
 #include <common/debug.h>
 #include <bl31/interrupt_mgmt.h>
 #include <drivers/console.h>
-#include <drivers/rpi3/gpio/rpi3_gpio.h>
-#include <drivers/ti/uart/uart_16550.h>
-#include <drivers/arm/pl011.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 #include <rpi_hw.h>
@@ -106,12 +103,6 @@ static const mmap_region_t plat_rpi3_mmap[] = {
  ******************************************************************************/
 static console_t rpi3_console;
 
-
-static bool rpi3_use_mini_uart(void)
-{
-	return rpi3_gpio_get_select(14) == RPI3_GPIO_FUNC_ALT5;
-}
-
 void rpi3_console_init(void)
 {
 	int console_scope = CONSOLE_FLAG_BOOT;
@@ -120,18 +111,7 @@ void rpi3_console_init(void)
 	if (RPI3_RUNTIME_UART != -1)
 		console_scope |= CONSOLE_FLAG_RUNTIME;
 
-	rpi3_gpio_init();
-
-	if (rpi3_use_mini_uart())
-		rc = console_16550_register(PLAT_RPI_MINI_UART_BASE,
-					    0,
-					    PLAT_RPI_UART_BAUDRATE,
-					    &rpi3_console);
-	else
-		rc = console_pl011_register(PLAT_RPI_PL011_UART_BASE,
-					    PLAT_RPI_PL011_UART_CLOCK,
-					    PLAT_RPI_UART_BAUDRATE,
-					    &rpi3_console);
+	rc = rpi3_register_used_uart(&rpi3_console);
 
 	if (rc == 0) {
 		/*
diff --git a/plat/rpi/common/rpi3_console_dual.c b/plat/rpi/common/rpi3_console_dual.c
new file mode 100644
index 00000000..15ee3e70
--- /dev/null
+++ b/plat/rpi/common/rpi3_console_dual.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <platform_def.h>
+
+#include <rpi_shared.h>
+
+static bool rpi3_use_mini_uart(void)
+{
+	return rpi3_gpio_get_select(14) == RPI3_GPIO_FUNC_ALT5;
+}
+
+int rpi3_register_used_uart(console_t *console)
+{
+	rpi3_gpio_init();
+
+	if (rpi3_use_mini_uart())
+		return console_16550_register(PLAT_RPI_MINI_UART_BASE,
+					      0,
+					      PLAT_RPI_UART_BAUDRATE,
+					      console);
+	else
+		return console_pl011_register(PLAT_RPI_PL011_UART_BASE,
+					      PLAT_RPI_PL011_UART_CLOCK,
+					      PLAT_RPI_UART_BAUDRATE,
+					      console);
+}
diff --git a/plat/rpi/common/rpi3_console_pl011.c b/plat/rpi/common/rpi3_console_pl011.c
new file mode 100644
index 00000000..6ab72097
--- /dev/null
+++ b/plat/rpi/common/rpi3_console_pl011.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <platform_def.h>
+
+#include <rpi_shared.h>
+
+int rpi3_register_used_uart(console_t *console)
+{
+	return console_pl011_register(PLAT_RPI_PL011_UART_BASE,
+				      PLAT_RPI_PL011_UART_CLOCK,
+				      PLAT_RPI_UART_BAUDRATE,
+				      console);
+}
diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c
index d98ac66f..456e1603 100644
--- a/plat/rpi/common/rpi3_pm.c
+++ b/plat/rpi/common/rpi3_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,6 +21,22 @@
 #include <drivers/arm/gicv2.h>
 #endif
 
+/* Registers on top of RPI3_PM_BASE. */
+#define RPI3_PM_RSTC_OFFSET		ULL(0x0000001C)
+#define RPI3_PM_RSTS_OFFSET		ULL(0x00000020)
+#define RPI3_PM_WDOG_OFFSET		ULL(0x00000024)
+/* Watchdog constants */
+#define RPI3_PM_PASSWORD		U(0x5A000000)
+#define RPI3_PM_RSTC_WRCFG_MASK		U(0x00000030)
+#define RPI3_PM_RSTC_WRCFG_FULL_RESET	U(0x00000020)
+/*
+ * The RSTS register is used by the VideoCore firmware when booting the
+ * Raspberry Pi to know which partition to boot from. The partition value is
+ * formed by bits 0, 2, 4, 6, 8 and 10. Partition 63 is used by said firmware
+ * to indicate halt.
+ */
+#define RPI3_PM_RSTS_WRCFG_HALT		U(0x00000555)
+
 /* Make composite power state parameter till power level 0 */
 #if PSCI_EXTENDED_STATE_ID
 
diff --git a/plat/rpi/common/rpi3_topology.c b/plat/rpi/common/rpi3_topology.c
index 3747287c..5fef777c 100644
--- a/plat/rpi/common/rpi3_topology.c
+++ b/plat/rpi/common/rpi3_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -39,12 +39,27 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
 	unsigned int cluster_id, cpu_id;
 
 	mpidr &= MPIDR_AFFINITY_MASK;
+
+	/*
+	 * When MT is set, lowest affinity represents the thread ID.
+	 * Since we only support one thread per core, discard this field
+	 * so cluster and core IDs go back into Aff1 and Aff0 respectively.
+	 * The upper bits are also affected, but plat_rpi3_calc_core_pos()
+	 * does not use them.
+	 */
+	if ((read_mpidr() & MPIDR_MT_MASK) != 0) {
+		if (MPIDR_AFFLVL0_VAL(mpidr) != 0) {
+			return -1;
+		}
+		mpidr >>= MPIDR_AFFINITY_BITS;
+	}
+
 	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
 		return -1;
 	}
 
-	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+	cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+	cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
 	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
 		return -1;
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/common/rpi4_bl31_setup.c
similarity index 67%
rename from plat/rpi/rpi4/rpi4_bl31_setup.c
rename to plat/rpi/common/rpi4_bl31_setup.c
index 2fb4d3df..a7228fd4 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/plat/rpi/common/rpi4_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,21 +8,15 @@
 #include <inttypes.h>
 #include <stdint.h>
 
-#include <libfdt.h>
-
-#include <platform_def.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
+#include <drivers/arm/gicv2.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
-#include <common/fdt_fixup.h>
-#include <common/fdt_wrappers.h>
-#include <libfdt.h>
-
-#include <drivers/arm/gicv2.h>
+#include <platform_def.h>
 
 #include <rpi_shared.h>
 
@@ -85,7 +79,7 @@ uintptr_t plat_get_ns_image_entrypoint(void)
 #endif
 }
 
-static uintptr_t rpi4_get_dtb_address(void)
+uintptr_t rpi4_get_dtb_address(void)
 {
 #ifdef RPI3_PRELOADED_DTB_BASE
 	return RPI3_PRELOADED_DTB_BASE;
@@ -151,7 +145,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	 * r1 = machine type number, optional in DT-only platforms (~0 if so)
 	 * r2 = Physical address of the device tree blob
 	 */
-	VERBOSE("rpi4: Preparing to boot 32-bit Linux kernel\n");
+	VERBOSE("rpi: Preparing to boot 32-bit Linux kernel\n");
 	bl33_image_ep_info.args.arg0 = 0U;
 	bl33_image_ep_info.args.arg1 = ~0U;
 	bl33_image_ep_info.args.arg2 = rpi4_get_dtb_address();
@@ -162,7 +156,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	 * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
 	 * must be 0.
 	 */
-	VERBOSE("rpi4: Preparing to boot 64-bit Linux kernel\n");
+	VERBOSE("rpi: Preparing to boot 64-bit Linux kernel\n");
 	bl33_image_ep_info.args.arg0 = rpi4_get_dtb_address();
 	bl33_image_ep_info.args.arg1 = 0ULL;
 	bl33_image_ep_info.args.arg2 = 0ULL;
@@ -203,102 +197,13 @@ void bl31_plat_arch_setup(void)
 	enable_mmu_el3(0);
 }
 
-/*
- * Remove the FDT /memreserve/ entry that covers the region at the very
- * beginning of memory (if that exists). This is where the secondaries
- * originally spin, but we pull them out there.
- * Having overlapping /reserved-memory and /memreserve/ regions confuses
- * the Linux kernel, so we need to get rid of this one.
- */
-static void remove_spintable_memreserve(void *dtb)
-{
-	uint64_t addr, size;
-	int regions = fdt_num_mem_rsv(dtb);
-	int i;
-
-	for (i = 0; i < regions; i++) {
-		if (fdt_get_mem_rsv(dtb, i, &addr, &size) != 0) {
-			return;
-		}
-		if (size == 0U) {
-			return;
-		}
-		/* We only look for the region at the beginning of DRAM. */
-		if (addr != 0U) {
-			continue;
-		}
-		/*
-		 * Currently the region in the existing DTs is exactly 4K
-		 * in size. Should this value ever change, there is probably
-		 * a reason for that, so inform the user about this.
-		 */
-		if (size == 4096U) {
-			fdt_del_mem_rsv(dtb, i);
-			return;
-		}
-		WARN("Keeping unknown /memreserve/ region at 0, size: %" PRId64 "\n",
-		     size);
-	}
-}
-
-static void rpi4_prepare_dtb(void)
-{
-	void *dtb = (void *)rpi4_get_dtb_address();
-	uint32_t gic_int_prop[3];
-	int ret, offs;
-
-	/* Return if no device tree is detected */
-	if (fdt_check_header(dtb) != 0)
-		return;
-
-	ret = fdt_open_into(dtb, dtb, 0x100000);
-	if (ret < 0) {
-		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
-		return;
-	}
-
-	if (dt_add_psci_node(dtb)) {
-		ERROR("Failed to add PSCI Device Tree node\n");
-		return;
-	}
-
-	if (dt_add_psci_cpu_enable_methods(dtb)) {
-		ERROR("Failed to add PSCI cpu enable methods in Device Tree\n");
-		return;
-	}
-
-	/*
-	 * Remove the original reserved region (used for the spintable), and
-	 * replace it with a region describing the whole of Trusted Firmware.
-	 */
-	remove_spintable_memreserve(dtb);
-	if (fdt_add_reserved_memory(dtb, "atf@0", 0, 0x80000))
-		WARN("Failed to add reserved memory nodes to DT.\n");
-
-	offs = fdt_node_offset_by_compatible(dtb, 0, "arm,gic-400");
-	gic_int_prop[0] = cpu_to_fdt32(1);		// PPI
-	gic_int_prop[1] = cpu_to_fdt32(9);		// PPI #9
-	gic_int_prop[2] = cpu_to_fdt32(0x0f04);		// all cores, level high
-	fdt_setprop(dtb, offs, "interrupts", gic_int_prop, 12);
-
-	offs = fdt_path_offset(dtb, "/chosen");
-	fdt_setprop_string(dtb, offs, "stdout-path", "serial0");
-
-	ret = fdt_pack(dtb);
-	if (ret < 0)
-		ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret);
-
-	clean_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb));
-	INFO("Changed device tree to advertise PSCI.\n");
-}
-
 void bl31_platform_setup(void)
 {
-	rpi4_prepare_dtb();
-
 	/* Configure the interrupt controller */
 	gicv2_driver_init(&rpi4_gic_data);
 	gicv2_distif_init();
 	gicv2_pcpu_distif_init();
 	gicv2_cpuif_enable();
+
+	plat_rpi_bl31_custom_setup();
 }
diff --git a/plat/rpi/rpi4/rpi4_pci_svc.c b/plat/rpi/common/rpi_pci_svc.c
similarity index 76%
rename from plat/rpi/rpi4/rpi4_pci_svc.c
rename to plat/rpi/common/rpi_pci_svc.c
index e4ef5c1a..c22f6d89 100644
--- a/plat/rpi/rpi4/rpi4_pci_svc.c
+++ b/plat/rpi/common/rpi_pci_svc.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
- * The RPi4 has a single nonstandard PCI config region. It is broken into two
+ * The RPi has a single nonstandard PCI config region. It is broken into two
  * pieces, the root port config registers and a window to a single device's
  * config space which can move between devices. There isn't (yet) an
  * authoritative public document on this since the available BCM2711 reference
@@ -29,62 +30,63 @@
 
 #include <lib/mmio.h>
 
-static spinlock_t pci_lock;
-
-#define PCIE_REG_BASE		U(RPI_IO_BASE + 0x01500000)
 #define PCIE_MISC_PCIE_STATUS	0x4068
 #define PCIE_EXT_CFG_INDEX	0x9000
-/* A small window pointing at the ECAM of the device selected by CFG_INDEX */
 #define PCIE_EXT_CFG_DATA	0x8000
+#define	PCIE_EXT_CFG_BDF_SHIFT	12
+
 #define INVALID_PCI_ADDR	0xFFFFFFFF
 
-#define	PCIE_EXT_BUS_SHIFT	20
-#define	PCIE_EXT_DEV_SHIFT	15
-#define	PCIE_EXT_FUN_SHIFT	12
+static spinlock_t pci_lock;
 
+static uint64_t pcie_rc_bases[] = { RPI_PCIE_RC_BASES };
 
 static uint64_t pci_segment_lib_get_base(uint32_t address, uint32_t offset)
 {
-	uint64_t	base;
-	uint32_t	bus, dev, fun;
-	uint32_t	status;
+	uint64_t base;
+	uint32_t seg, bus, dev, fun;
 
-	base = PCIE_REG_BASE;
+	seg = PCI_ADDR_SEG(address);
 
-	offset &= PCI_OFFSET_MASK;  /* Pick off the 4k register offset */
+	if (seg >= ARRAY_SIZE(pcie_rc_bases)) {
+		return INVALID_PCI_ADDR;
+	}
 
 	/* The root port is at the base of the PCIe register space */
-	if (address != 0U) {
-		/*
-		 * The current device must be at CFG_DATA, a 4K window mapped,
-		 * via CFG_INDEX, to the device we are accessing. At the same
-		 * time we must avoid accesses to certain areas of the cfg
-		 * space via CFG_DATA. Detect those accesses and report that
-		 * the address is invalid.
-		 */
-		base += PCIE_EXT_CFG_DATA;
-		bus = PCI_ADDR_BUS(address);
-		dev = PCI_ADDR_DEV(address);
-		fun = PCI_ADDR_FUN(address);
-		address = (bus << PCIE_EXT_BUS_SHIFT) |
-			  (dev << PCIE_EXT_DEV_SHIFT) |
-			  (fun << PCIE_EXT_FUN_SHIFT);
-
-		/* Allow only dev = 0 on root port and bus 1 */
-		if ((bus < 2U) && (dev > 0U)) {
-			return INVALID_PCI_ADDR;
-		}
+	base = pcie_rc_bases[seg];
+
+	bus = PCI_ADDR_BUS(address);
+	dev = PCI_ADDR_DEV(address);
+	fun = PCI_ADDR_FUN(address);
 
-		/* Assure link up before reading bus 1 */
-		status = mmio_read_32(PCIE_REG_BASE + PCIE_MISC_PCIE_STATUS);
-		if ((status & 0x30) != 0x30) {
+	/* There can only be the root port on bus 0 */
+	if ((bus == 0U) && ((dev > 0U) || (fun > 0U))) {
+		return INVALID_PCI_ADDR;
+	}
+
+	/* There can only be one device on bus 1 */
+	if ((bus == 1U) && (dev > 0U)) {
+		return INVALID_PCI_ADDR;
+	}
+
+	if (bus > 0) {
+#if RPI_PCIE_ECAM_SERROR_QUIRK
+		uint32_t status = mmio_read_32(base + PCIE_MISC_PCIE_STATUS);
+
+		/* Assure link up before accessing downstream of root port */
+		if ((status & 0x30) == 0U) {
 			return INVALID_PCI_ADDR;
 		}
-
-		/* Adjust which device the CFG_DATA window is pointing at */
-		mmio_write_32(PCIE_REG_BASE + PCIE_EXT_CFG_INDEX, address);
+#endif
+		/*
+		 * Device function is mapped at CFG_DATA, a 4 KB window
+		 * movable by writing its B/D/F location to CFG_INDEX.
+		 */
+		mmio_write_32(base + PCIE_EXT_CFG_INDEX, address << PCIE_EXT_CFG_BDF_SHIFT);
+		base += PCIE_EXT_CFG_DATA;
 	}
-	return base + offset;
+
+	return base + (offset & PCI_OFFSET_MASK);
 }
 
 /**
@@ -130,7 +132,7 @@ uint32_t pci_read_config(uint32_t addr, uint32_t off, uint32_t sz, uint32_t *val
 			*val = mmio_read_32(base);
 			break;
 		default: /* should be unreachable */
-			*val = 0;
+			*val = 0U;
 			ret = SMC_PCI_CALL_INVAL_PARAM;
 		}
 	}
@@ -204,9 +206,12 @@ uint32_t pci_write_config(uint32_t addr, uint32_t off, uint32_t sz, uint32_t val
 uint32_t pci_get_bus_for_seg(uint32_t seg, uint32_t *bus_range, uint32_t *nseg)
 {
 	uint32_t ret = SMC_PCI_CALL_SUCCESS;
-	*nseg = 0U; /* only a single segment */
-	if (seg == 0U) {
-		*bus_range = 0xFF00; /* start 0, end 255 */
+	uint32_t rc_count = ARRAY_SIZE(pcie_rc_bases);
+
+	*nseg = (seg < rc_count - 1U) ? seg + 1U : 0U;
+
+	if (seg < rc_count) {
+		*bus_range = 0U + (0xFF << 8); /* start 0, end 255 */
 	} else {
 		*bus_range = 0U;
 		ret = SMC_PCI_CALL_NOT_IMPL;
diff --git a/plat/rpi/rpi3/include/plat_macros.S b/plat/rpi/rpi3/include/plat_macros.S
deleted file mode 100644
index c0c39679..00000000
--- a/plat/rpi/rpi3/include/plat_macros.S
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef PLAT_MACROS_S
-#define PLAT_MACROS_S
-
-	/* ---------------------------------------------
-	 * The below required platform porting macro
-	 * prints out relevant platform registers
-	 * whenever an unhandled exception is taken in
-	 * BL31.
-	 * Clobbers: x0 - x10, x16, x17, sp
-	 * ---------------------------------------------
-	 */
-	.macro plat_crash_print_regs
-	.endm
-
-#endif /* PLAT_MACROS_S */
diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h
index f44d1f52..757c64ad 100644
--- a/plat/rpi/rpi3/include/platform_def.h
+++ b/plat/rpi/rpi3/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -254,6 +254,7 @@
 #define PLAT_RPI_PL011_UART_BASE	RPI3_PL011_UART_BASE
 #define PLAT_RPI_PL011_UART_CLOCK	RPI3_PL011_UART_CLOCK
 #define PLAT_RPI_UART_BAUDRATE		ULL(115200)
+#define PLAT_RPI_CRASH_UART_BASE	PLAT_RPI_MINI_UART_BASE
 
 /*
  * System counter
diff --git a/plat/rpi/rpi3/include/rpi_hw.h b/plat/rpi/rpi3/include/rpi_hw.h
index 2aecab37..dec59633 100644
--- a/plat/rpi/rpi3/include/rpi_hw.h
+++ b/plat/rpi/rpi3/include/rpi_hw.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,60 +21,18 @@
  */
 #define RPI3_MBOX_OFFSET		ULL(0x0000B880)
 #define RPI3_MBOX_BASE			(RPI_IO_BASE + RPI3_MBOX_OFFSET)
-/* VideoCore -> ARM */
-#define RPI3_MBOX0_READ_OFFSET		ULL(0x00000000)
-#define RPI3_MBOX0_PEEK_OFFSET		ULL(0x00000010)
-#define RPI3_MBOX0_SENDER_OFFSET	ULL(0x00000014)
-#define RPI3_MBOX0_STATUS_OFFSET	ULL(0x00000018)
-#define RPI3_MBOX0_CONFIG_OFFSET	ULL(0x0000001C)
-/* ARM -> VideoCore */
-#define RPI3_MBOX1_WRITE_OFFSET		ULL(0x00000020)
-#define RPI3_MBOX1_PEEK_OFFSET		ULL(0x00000030)
-#define RPI3_MBOX1_SENDER_OFFSET	ULL(0x00000034)
-#define RPI3_MBOX1_STATUS_OFFSET	ULL(0x00000038)
-#define RPI3_MBOX1_CONFIG_OFFSET	ULL(0x0000003C)
-/* Mailbox status constants */
-#define RPI3_MBOX_STATUS_FULL_MASK	U(0x80000000) /* Set if full */
-#define RPI3_MBOX_STATUS_EMPTY_MASK	U(0x40000000) /* Set if empty */
 
 /*
  * Power management, reset controller, watchdog.
  */
 #define RPI3_IO_PM_OFFSET		ULL(0x00100000)
 #define RPI3_PM_BASE			(RPI_IO_BASE + RPI3_IO_PM_OFFSET)
-/* Registers on top of RPI3_PM_BASE. */
-#define RPI3_PM_RSTC_OFFSET		ULL(0x0000001C)
-#define RPI3_PM_RSTS_OFFSET		ULL(0x00000020)
-#define RPI3_PM_WDOG_OFFSET		ULL(0x00000024)
-/* Watchdog constants */
-#define RPI3_PM_PASSWORD		U(0x5A000000)
-#define RPI3_PM_RSTC_WRCFG_MASK		U(0x00000030)
-#define RPI3_PM_RSTC_WRCFG_FULL_RESET	U(0x00000020)
-/*
- * The RSTS register is used by the VideoCore firmware when booting the
- * Raspberry Pi to know which partition to boot from. The partition value is
- * formed by bits 0, 2, 4, 6, 8 and 10. Partition 63 is used by said firmware
- * to indicate halt.
- */
-#define RPI3_PM_RSTS_WRCFG_HALT		U(0x00000555)
 
 /*
  * Hardware random number generator.
  */
 #define RPI3_IO_RNG_OFFSET		ULL(0x00104000)
 #define RPI3_RNG_BASE			(RPI_IO_BASE + RPI3_IO_RNG_OFFSET)
-#define RPI3_RNG_CTRL_OFFSET		ULL(0x00000000)
-#define RPI3_RNG_STATUS_OFFSET		ULL(0x00000004)
-#define RPI3_RNG_DATA_OFFSET		ULL(0x00000008)
-#define RPI3_RNG_INT_MASK_OFFSET	ULL(0x00000010)
-/* Enable/disable RNG */
-#define RPI3_RNG_CTRL_ENABLE		U(0x1)
-#define RPI3_RNG_CTRL_DISABLE		U(0x0)
-/* Number of currently available words */
-#define RPI3_RNG_STATUS_NUM_WORDS_SHIFT	U(24)
-#define RPI3_RNG_STATUS_NUM_WORDS_MASK	U(0xFF)
-/* Value to mask interrupts caused by the RNG */
-#define RPI3_RNG_INT_MASK_DISABLE	U(0x1)
 
 /*
  * Serial ports:
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index 06393e40..fc51bec6 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -17,11 +17,13 @@ PLAT_BL_COMMON_SOURCES	:=	drivers/ti/uart/aarch64/16550_console.S	\
 				drivers/rpi3/gpio/rpi3_gpio.c		\
 				plat/rpi/common/aarch64/plat_helpers.S	\
 				plat/rpi/common/rpi3_common.c		\
+				plat/rpi/common/rpi3_console_dual.c	\
 				${XLAT_TABLES_LIB_SRCS}
 
 BL1_SOURCES		+=	drivers/io/io_fip.c			\
 				drivers/io/io_memmap.c			\
 				drivers/io/io_storage.c			\
+				drivers/delay_timer/generic_delay_timer.c \
 				lib/cpus/aarch64/cortex_a53.S		\
 				plat/common/aarch64/platform_mp_stack.S	\
 				plat/rpi/rpi3/rpi3_bl1_setup.c		\
@@ -52,9 +54,9 @@ BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
 				${LIBFDT_SRCS}
 
 # Tune compiler for Cortex-A53
-ifeq ($(notdir $(CC)),armclang)
+ifeq ($($(ARCH)-cc-id),arm-clang)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
-else ifneq ($(findstring clang,$(notdir $(CC))),)
+else ifneq ($(filter %-clang,$($(ARCH)-cc-id)),)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
 else
     TF_CFLAGS_aarch64	+=	-mtune=cortex-a53
@@ -72,13 +74,13 @@ all: armstub
 # This target concatenates BL1 and the FIP so that the base addresses match the
 # ones defined in the memory map
 armstub: bl1 fip
-	@echo "  CAT     $@"
-	${Q}cp ${BUILD_PLAT}/bl1.bin ${RPI3_BL1_PAD_BIN}
-	${Q}truncate --size=131072 ${RPI3_BL1_PAD_BIN}
-	${Q}cat ${RPI3_BL1_PAD_BIN} ${BUILD_PLAT}/fip.bin > ${RPI3_ARMSTUB8_BIN}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  CAT     $@"
+	$(q)cp ${BUILD_PLAT}/bl1.bin ${RPI3_BL1_PAD_BIN}
+	$(q)truncate --size=131072 ${RPI3_BL1_PAD_BIN}
+	$(q)cat ${RPI3_BL1_PAD_BIN} ${BUILD_PLAT}/fip.bin > ${RPI3_ARMSTUB8_BIN}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 # Build config flags
 # ------------------
@@ -211,12 +213,12 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
 
     certificates: $(ROT_KEY)
 
-    $(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+    $(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-    $(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+    $(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 endif
diff --git a/plat/rpi/rpi3/rpi3_bl1_setup.c b/plat/rpi/rpi3/rpi3_bl1_setup.c
index 3ac30e0f..6c8fb2d0 100644
--- a/plat/rpi/rpi3/rpi3_bl1_setup.c
+++ b/plat/rpi/rpi3/rpi3_bl1_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,8 @@
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
+#include <drivers/generic_delay_timer.h>
+#include <plat/common/platform.h>
 
 #include <rpi_shared.h>
 
@@ -37,6 +39,15 @@ void bl1_early_platform_setup(void)
 	/* Initialize the console to provide early debug support */
 	rpi3_console_init();
 
+	/*
+	 * Write the System Timer Frequency to CNTFRQ manually, this
+	 * is required to use the delay_timer functionality.
+	 */
+	write_cntfrq_el0(plat_get_syscnt_freq2());
+
+	/* Enable arch timer */
+	generic_delay_timer_init();
+
 	/* Allow BL1 to see the whole Trusted RAM */
 	bl1_tzram_layout.total_base = BL_RAM_BASE;
 	bl1_tzram_layout.total_size = BL_RAM_SIZE;
diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h
index 6787ebfe..b72aedcf 100644
--- a/plat/rpi/rpi4/include/platform_def.h
+++ b/plat/rpi/rpi4/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -131,6 +131,7 @@
 #define PLAT_RPI_PL011_UART_BASE	RPI4_PL011_UART_BASE
 #define PLAT_RPI_PL011_UART_CLOCK       RPI4_PL011_UART_CLOCK
 #define PLAT_RPI_UART_BAUDRATE          ULL(115200)
+#define PLAT_RPI_CRASH_UART_BASE	PLAT_RPI_MINI_UART_BASE
 
 /*
  * System counter
diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h
index 0430d464..53ce0f8b 100644
--- a/plat/rpi/rpi4/include/rpi_hw.h
+++ b/plat/rpi/rpi4/include/rpi_hw.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,60 +23,18 @@
  */
 #define RPI3_MBOX_OFFSET		ULL(0x0000B880)
 #define RPI3_MBOX_BASE			(RPI_LEGACY_BASE + RPI3_MBOX_OFFSET)
-/* VideoCore -> ARM */
-#define RPI3_MBOX0_READ_OFFSET		ULL(0x00000000)
-#define RPI3_MBOX0_PEEK_OFFSET		ULL(0x00000010)
-#define RPI3_MBOX0_SENDER_OFFSET	ULL(0x00000014)
-#define RPI3_MBOX0_STATUS_OFFSET	ULL(0x00000018)
-#define RPI3_MBOX0_CONFIG_OFFSET	ULL(0x0000001C)
-/* ARM -> VideoCore */
-#define RPI3_MBOX1_WRITE_OFFSET		ULL(0x00000020)
-#define RPI3_MBOX1_PEEK_OFFSET		ULL(0x00000030)
-#define RPI3_MBOX1_SENDER_OFFSET	ULL(0x00000034)
-#define RPI3_MBOX1_STATUS_OFFSET	ULL(0x00000038)
-#define RPI3_MBOX1_CONFIG_OFFSET	ULL(0x0000003C)
-/* Mailbox status constants */
-#define RPI3_MBOX_STATUS_FULL_MASK	U(0x80000000) /* Set if full */
-#define RPI3_MBOX_STATUS_EMPTY_MASK	U(0x40000000) /* Set if empty */
 
 /*
  * Power management, reset controller, watchdog.
  */
 #define RPI3_IO_PM_OFFSET		ULL(0x00100000)
 #define RPI3_PM_BASE			(RPI_LEGACY_BASE + RPI3_IO_PM_OFFSET)
-/* Registers on top of RPI3_PM_BASE. */
-#define RPI3_PM_RSTC_OFFSET		ULL(0x0000001C)
-#define RPI3_PM_RSTS_OFFSET		ULL(0x00000020)
-#define RPI3_PM_WDOG_OFFSET		ULL(0x00000024)
-/* Watchdog constants */
-#define RPI3_PM_PASSWORD		U(0x5A000000)
-#define RPI3_PM_RSTC_WRCFG_MASK		U(0x00000030)
-#define RPI3_PM_RSTC_WRCFG_FULL_RESET	U(0x00000020)
-/*
- * The RSTS register is used by the VideoCore firmware when booting the
- * Raspberry Pi to know which partition to boot from. The partition value is
- * formed by bits 0, 2, 4, 6, 8 and 10. Partition 63 is used by said firmware
- * to indicate halt.
- */
-#define RPI3_PM_RSTS_WRCFG_HALT		U(0x00000555)
 
 /*
  * Hardware random number generator.
  */
 #define RPI3_IO_RNG_OFFSET		ULL(0x00104000)
 #define RPI3_RNG_BASE			(RPI_LEGACY_BASE + RPI3_IO_RNG_OFFSET)
-#define RPI3_RNG_CTRL_OFFSET		ULL(0x00000000)
-#define RPI3_RNG_STATUS_OFFSET		ULL(0x00000004)
-#define RPI3_RNG_DATA_OFFSET		ULL(0x00000008)
-#define RPI3_RNG_INT_MASK_OFFSET	ULL(0x00000010)
-/* Enable/disable RNG */
-#define RPI3_RNG_CTRL_ENABLE		U(0x1)
-#define RPI3_RNG_CTRL_DISABLE		U(0x0)
-/* Number of currently available words */
-#define RPI3_RNG_STATUS_NUM_WORDS_SHIFT	U(24)
-#define RPI3_RNG_STATUS_NUM_WORDS_MASK	U(0xFF)
-/* Value to mask interrupts caused by the RNG */
-#define RPI3_RNG_INT_MASK_DISABLE	U(0x1)
 
 /*
  * Serial ports:
@@ -111,4 +69,11 @@
 #define	RPI4_LOCAL_CONTROL_BASE_ADDRESS		ULL(0xff800000)
 #define	RPI4_LOCAL_CONTROL_PRESCALER		ULL(0xff800008)
 
+/*
+ * PCI Express
+ */
+#define RPI_PCIE_RC_BASES		(RPI_IO_BASE + ULL(0x01500000))
+
+#define RPI_PCIE_ECAM_SERROR_QUIRK	1
+
 #endif /* RPI_HW_H */
diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk
index 528eb1d2..c39a5877 100644
--- a/plat/rpi/rpi4/platform.mk
+++ b/plat/rpi/rpi4/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -15,20 +15,23 @@ PLAT_INCLUDES		:=	-Iplat/rpi/common/include		\
 PLAT_BL_COMMON_SOURCES	:=	drivers/ti/uart/aarch64/16550_console.S	\
 				drivers/arm/pl011/aarch64/pl011_console.S \
 				plat/rpi/common/rpi3_common.c		\
+				plat/rpi/common/rpi3_console_dual.c	\
 				${XLAT_TABLES_LIB_SRCS}
 
 BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a72.S		\
 				plat/rpi/common/aarch64/plat_helpers.S	\
-				plat/rpi/rpi4/aarch64/armstub8_header.S	\
+				plat/rpi/common/aarch64/armstub8_header.S \
 				drivers/delay_timer/delay_timer.c	\
 				drivers/gpio/gpio.c			\
 				drivers/rpi3/gpio/rpi3_gpio.c		\
 				plat/common/plat_gicv2.c                \
-				plat/rpi/rpi4/rpi4_bl31_setup.c		\
+				plat/rpi/common/rpi4_bl31_setup.c	\
+				plat/rpi/rpi4/rpi4_setup.c		\
 				plat/rpi/common/rpi3_pm.c		\
 				plat/common/plat_psci_common.c		\
 				plat/rpi/common/rpi3_topology.c		\
 				common/fdt_fixup.c			\
+				common/fdt_wrappers.c			\
 				${LIBFDT_SRCS}				\
 				${GICV2_SOURCES}
 
@@ -39,9 +42,9 @@ RESET_TO_BL31		:=	1
 COLD_BOOT_SINGLE_CPU	:=	0
 
 # Tune compiler for Cortex-A72
-ifeq ($(notdir $(CC)),armclang)
+ifeq ($($(ARCH)-cc-id),arm-clang)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a72
-else ifneq ($(findstring clang,$(notdir $(CC))),)
+else ifneq ($(filter %-clang,$($(ARCH)-cc-id)),)
     TF_CFLAGS_aarch64	+=	-mcpu=cortex-a72
 else
     TF_CFLAGS_aarch64	+=	-mtune=cortex-a72
@@ -111,6 +114,5 @@ PLAT_BL_COMMON_SOURCES	+=	drivers/rpi3/rng/rpi3_rng.c		\
 endif
 
 ifeq ($(SMC_PCI_SUPPORT), 1)
-BL31_SOURCES            +=      plat/rpi/rpi4/rpi4_pci_svc.c
+BL31_SOURCES            +=      plat/rpi/common/rpi_pci_svc.c
 endif
-
diff --git a/plat/rpi/rpi4/rpi4_setup.c b/plat/rpi/rpi4/rpi4_setup.c
new file mode 100644
index 00000000..82200b97
--- /dev/null
+++ b/plat/rpi/rpi4/rpi4_setup.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
+
+#include <rpi_shared.h>
+
+/*
+ * Remove the FDT /memreserve/ entry that covers the region at the very
+ * beginning of memory (if that exists). This is where the secondaries
+ * originally spin, but we pull them out there.
+ * Having overlapping /reserved-memory and /memreserve/ regions confuses
+ * the Linux kernel, so we need to get rid of this one.
+ */
+static void remove_spintable_memreserve(void *dtb)
+{
+	uint64_t addr, size;
+	int regions = fdt_num_mem_rsv(dtb);
+	int i;
+
+	for (i = 0; i < regions; i++) {
+		if (fdt_get_mem_rsv(dtb, i, &addr, &size) != 0) {
+			return;
+		}
+		if (size == 0U) {
+			return;
+		}
+		/* We only look for the region at the beginning of DRAM. */
+		if (addr != 0U) {
+			continue;
+		}
+		/*
+		 * Currently the region in the existing DTs is exactly 4K
+		 * in size. Should this value ever change, there is probably
+		 * a reason for that, so inform the user about this.
+		 */
+		if (size == 4096U) {
+			fdt_del_mem_rsv(dtb, i);
+			return;
+		}
+		WARN("Keeping unknown /memreserve/ region at 0, size: %" PRId64 "\n",
+		     size);
+	}
+}
+
+static void rpi4_prepare_dtb(void)
+{
+	void *dtb = (void *)rpi4_get_dtb_address();
+	uint32_t gic_int_prop[3];
+	int ret, offs;
+
+	/* Return if no device tree is detected */
+	if (fdt_check_header(dtb) != 0)
+		return;
+
+	ret = fdt_open_into(dtb, dtb, 0x100000);
+	if (ret < 0) {
+		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
+		return;
+	}
+
+	if (dt_add_psci_node(dtb)) {
+		ERROR("Failed to add PSCI Device Tree node\n");
+		return;
+	}
+
+	if (dt_add_psci_cpu_enable_methods(dtb)) {
+		ERROR("Failed to add PSCI cpu enable methods in Device Tree\n");
+		return;
+	}
+
+	/*
+	 * Remove the original reserved region (used for the spintable), and
+	 * replace it with a region describing the whole of Trusted Firmware.
+	 */
+	remove_spintable_memreserve(dtb);
+	if (fdt_add_reserved_memory(dtb, "atf@0", 0, 0x80000))
+		WARN("Failed to add reserved memory nodes to DT.\n");
+
+	offs = fdt_node_offset_by_compatible(dtb, 0, "arm,gic-400");
+	gic_int_prop[0] = cpu_to_fdt32(1);		// PPI
+	gic_int_prop[1] = cpu_to_fdt32(9);		// PPI #9
+	gic_int_prop[2] = cpu_to_fdt32(0x0f04);		// all cores, level high
+	fdt_setprop(dtb, offs, "interrupts", gic_int_prop, 12);
+
+	offs = fdt_path_offset(dtb, "/chosen");
+	fdt_setprop_string(dtb, offs, "stdout-path", "serial0");
+
+	ret = fdt_pack(dtb);
+	if (ret < 0)
+		ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret);
+
+	clean_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb));
+	INFO("Changed device tree to advertise PSCI.\n");
+}
+
+void plat_rpi_bl31_custom_setup(void)
+{
+	rpi4_prepare_dtb();
+}
diff --git a/plat/rpi/rpi5/include/plat.ld.S b/plat/rpi/rpi5/include/plat.ld.S
new file mode 100644
index 00000000..961c630c
--- /dev/null
+++ b/plat/rpi/rpi5/include/plat.ld.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Stub linker script to provide the armstub8.bin header before the actual
+ * code. If the GPU firmware finds a magic value at offset 240 in
+ * armstub8.bin, it will put the DTB and kernel load address in subsequent
+ * words. We can then read those values to find the proper NS entry point
+ * and find our DTB more flexibly.
+ */
+
+MEMORY {
+    PRERAM (rwx): ORIGIN = 0, LENGTH = 4096
+}
+
+SECTIONS
+{
+    .armstub8 . : {
+        *armstub8_header.o(.text*)
+        KEEP(*(.armstub8))
+    } >PRERAM
+}
diff --git a/plat/rpi/rpi5/include/platform_def.h b/plat/rpi/rpi5/include/platform_def.h
new file mode 100644
index 00000000..a4c2f5b9
--- /dev/null
+++ b/plat/rpi/rpi5/include/platform_def.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <lib/utils_def.h>
+#include <plat/common/common_def.h>
+
+#include "rpi_hw.h"
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define RPI3_BL31_PLAT_PARAM_VAL	ULL(0x0F1E2D3C4B5A6978)
+
+#define PLATFORM_STACK_SIZE		ULL(0x1000)
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(4)
+#define PLATFORM_CLUSTER_COUNT		U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
+#define PLATFORM_CORE_COUNT		PLATFORM_CLUSTER0_CORE_COUNT
+
+#define RPI_PRIMARY_CPU			U(0)
+
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL1
+#define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN		U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET		U(1)
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains.
+ */
+#define PLAT_LOCAL_STATE_OFF		U(2)
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH		U(4)
+#define PLAT_LOCAL_PSTATE_MASK		((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_SHIFT		U(6)
+#define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * I/O registers.
+ */
+#define DEVICE0_BASE			RPI_IO_BASE
+#define DEVICE0_SIZE			RPI_IO_SIZE
+
+/*
+ * Mailbox to control the secondary cores. All secondary cores are held in a
+ * wait loop in cold boot. To release them perform the following steps (plus
+ * any additional barriers that may be needed):
+ *
+ *     uint64_t *entrypoint = (uint64_t *)PLAT_RPI3_TM_ENTRYPOINT;
+ *     *entrypoint = ADDRESS_TO_JUMP_TO;
+ *
+ *     uint64_t *mbox_entry = (uint64_t *)PLAT_RPI3_TM_HOLD_BASE;
+ *     mbox_entry[cpu_id] = PLAT_RPI3_TM_HOLD_STATE_GO;
+ *
+ *     sev();
+ */
+/* The secure entry point to be used on warm reset by all CPUs. */
+#define PLAT_RPI3_TM_ENTRYPOINT		0x100
+#define PLAT_RPI3_TM_ENTRYPOINT_SIZE	ULL(8)
+
+/* Hold entries for each CPU. */
+#define PLAT_RPI3_TM_HOLD_BASE		(PLAT_RPI3_TM_ENTRYPOINT + \
+					 PLAT_RPI3_TM_ENTRYPOINT_SIZE)
+#define PLAT_RPI3_TM_HOLD_ENTRY_SIZE	ULL(8)
+#define PLAT_RPI3_TM_HOLD_SIZE		(PLAT_RPI3_TM_HOLD_ENTRY_SIZE * \
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_RPI3_TRUSTED_MAILBOX_SIZE	(PLAT_RPI3_TM_ENTRYPOINT_SIZE + \
+					 PLAT_RPI3_TM_HOLD_SIZE)
+
+#define PLAT_RPI3_TM_HOLD_STATE_WAIT	ULL(0)
+#define PLAT_RPI3_TM_HOLD_STATE_GO	ULL(1)
+#define PLAT_RPI3_TM_HOLD_STATE_BSP_OFF	ULL(2)
+
+/*
+ * BL31 specific defines.
+ *
+ * Put BL31 at the top of the Trusted SRAM. BL31_BASE is calculated using the
+ * current BL31 debug size plus a little space for growth.
+ */
+#define PLAT_MAX_BL31_SIZE		ULL(0x80000)
+
+#define BL31_BASE			ULL(0x1000)
+#define BL31_LIMIT			ULL(0x80000)
+#define BL31_PROGBITS_LIMIT		ULL(0x80000)
+
+#define SEC_SRAM_ID			0
+#define SEC_DRAM_ID			1
+
+/*
+ * Other memory-related defines.
+ */
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 40)
+
+#define MAX_MMAP_REGIONS		8
+#define MAX_XLAT_TABLES			4
+
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+#define MAX_IO_BLOCK_DEVICES		U(1)
+
+/*
+ * Serial-related constants.
+ */
+#define PLAT_RPI_PL011_UART_BASE	RPI4_PL011_UART_BASE
+#define PLAT_RPI_PL011_UART_CLOCK	RPI4_PL011_UART_CLOCK
+#define PLAT_RPI_UART_BAUDRATE		ULL(115200)
+#define PLAT_RPI_CRASH_UART_BASE	PLAT_RPI_PL011_UART_BASE
+
+/*
+ * System counter
+ */
+#define SYS_COUNTER_FREQ_IN_TICKS	ULL(54000000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/rpi/rpi5/include/rpi_hw.h b/plat/rpi/rpi5/include/rpi_hw.h
new file mode 100644
index 00000000..a7376765
--- /dev/null
+++ b/plat/rpi/rpi5/include/rpi_hw.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPI_HW_H
+#define RPI_HW_H
+
+#include <lib/utils_def.h>
+
+/*
+ * Peripherals
+ */
+
+#define RPI_IO_BASE			ULL(0x1000000000)
+#define RPI_IO_SIZE			ULL(0x1000000000)
+
+/*
+ * ARM <-> VideoCore mailboxes
+ */
+#define RPI3_MBOX_BASE			(RPI_IO_BASE + ULL(0x7c013880))
+
+/*
+ * Power management, reset controller, watchdog.
+ */
+#define RPI3_PM_BASE			(RPI_IO_BASE + ULL(0x7d200000))
+
+/*
+ * Hardware random number generator.
+ */
+#define RPI3_RNG_BASE			(RPI_IO_BASE + ULL(0x7d208000))
+
+/*
+ * PL011 system serial port
+ */
+#define RPI4_PL011_UART_BASE		(RPI_IO_BASE + ULL(0x7d001000))
+#define RPI4_PL011_UART_CLOCK		ULL(44000000)
+
+/*
+ * GIC interrupt controller
+ */
+#define RPI_HAVE_GIC
+#define RPI4_GIC_GICD_BASE		(RPI_IO_BASE + ULL(0x7fff9000))
+#define RPI4_GIC_GICC_BASE		(RPI_IO_BASE + ULL(0x7fffa000))
+
+#define	RPI4_LOCAL_CONTROL_BASE_ADDRESS		(RPI_IO_BASE + ULL(0x7c280000))
+#define	RPI4_LOCAL_CONTROL_PRESCALER		(RPI_IO_BASE + ULL(0x7c280008))
+
+/*
+ * PCI Express
+ */
+#define RPI_PCIE_RC_BASES		RPI_IO_BASE + ULL(0x00100000), \
+					RPI_IO_BASE + ULL(0x00110000), \
+					RPI_IO_BASE + ULL(0x00120000)
+
+#endif /* RPI_HW_H */
diff --git a/plat/rpi/rpi5/platform.mk b/plat/rpi/rpi5/platform.mk
new file mode 100644
index 00000000..70c5add2
--- /dev/null
+++ b/plat/rpi/rpi5/platform.mk
@@ -0,0 +1,115 @@
+#
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+include drivers/arm/gic/v2/gicv2.mk
+
+PLAT_INCLUDES		:=	-Iplat/rpi/common/include			\
+				-Iplat/rpi/rpi5/include
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/arm/pl011/aarch64/pl011_console.S 	\
+				plat/rpi/common/rpi3_common.c			\
+				plat/rpi/common/rpi3_console_pl011.c		\
+				${XLAT_TABLES_LIB_SRCS}
+
+BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a76.S			\
+				plat/rpi/common/aarch64/plat_helpers.S		\
+				plat/rpi/common/aarch64/armstub8_header.S 	\
+				drivers/delay_timer/delay_timer.c		\
+				plat/common/plat_gicv2.c			\
+				plat/rpi/common/rpi4_bl31_setup.c		\
+				plat/rpi/rpi5/rpi5_setup.c			\
+				plat/rpi/common/rpi3_pm.c			\
+				plat/common/plat_psci_common.c			\
+				plat/rpi/common/rpi3_topology.c			\
+				${GICV2_SOURCES}
+
+# For now we only support BL31, using the kernel loaded by the GPU firmware.
+RESET_TO_BL31		:=	1
+
+# All CPUs enter armstub8.bin.
+COLD_BOOT_SINGLE_CPU	:=	0
+
+# Tune compiler for Cortex-A76
+ifeq ($(notdir $(CC)),armclang)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a76
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a76
+else
+    TF_CFLAGS_aarch64	+=	-mtune=cortex-a76
+endif
+
+# Add support for platform supplied linker script for BL31 build
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+# Enable all errata workarounds for Cortex-A76 r4p1
+ERRATA_A76_1946160		:= 1
+ERRATA_A76_2743102		:= 1
+
+# Add new default target when compiling this platform
+all: bl31
+
+# Build config flags
+# ------------------
+
+# Disable stack protector by default
+ENABLE_STACK_PROTECTOR	 	:= 0
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA	:= 1
+
+# Hardware-managed coherency
+HW_ASSISTED_COHERENCY		:= 1
+USE_COHERENT_MEM		:= 0
+
+# Cortex-A76 is 64-bit only
+CTX_INCLUDE_AARCH32_REGS	:= 0
+
+# Platform build flags
+# --------------------
+
+# There is not much else than a Linux kernel to load at the moment.
+RPI3_DIRECT_LINUX_BOOT		:= 1
+
+# BL33 images can only be AArch64 on this platform.
+RPI3_BL33_IN_AARCH32		:= 0
+
+# UART to use at runtime. -1 means the runtime UART is disabled.
+# Any other value means the default UART will be used.
+RPI3_RUNTIME_UART		:= 0
+
+# Use normal memory mapping for ROM, FIP, SRAM and DRAM
+RPI3_USE_UEFI_MAP		:= 0
+
+# SMCCC PCI support (should be enabled for ACPI builds)
+SMC_PCI_SUPPORT			:= 0
+
+# Process platform flags
+# ----------------------
+
+$(eval $(call add_define,RPI3_BL33_IN_AARCH32))
+$(eval $(call add_define,RPI3_DIRECT_LINUX_BOOT))
+ifdef RPI3_PRELOADED_DTB_BASE
+$(eval $(call add_define,RPI3_PRELOADED_DTB_BASE))
+endif
+$(eval $(call add_define,RPI3_RUNTIME_UART))
+$(eval $(call add_define,RPI3_USE_UEFI_MAP))
+$(eval $(call add_define,SMC_PCI_SUPPORT))
+
+ifeq (${ARCH},aarch32)
+  $(error Error: AArch32 not supported on rpi5)
+endif
+
+ifneq ($(ENABLE_STACK_PROTECTOR), 0)
+PLAT_BL_COMMON_SOURCES	+=	drivers/rpi3/rng/rpi3_rng.c		\
+				plat/rpi/common/rpi3_stack_protector.c
+endif
+
+ifeq ($(SMC_PCI_SUPPORT), 1)
+BL31_SOURCES		+=	plat/rpi/common/rpi_pci_svc.c
+endif
diff --git a/plat/rpi/rpi5/rpi5_setup.c b/plat/rpi/rpi5/rpi5_setup.c
new file mode 100644
index 00000000..de82300d
--- /dev/null
+++ b/plat/rpi/rpi5/rpi5_setup.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <rpi_shared.h>
+
+void plat_rpi_bl31_custom_setup(void)
+{
+	/* Nothing to do here yet. */
+}
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index a6d9bef7..e4ae87bd 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -71,13 +71,13 @@ $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
 $(BUILD_PLAT)/bl2/sq_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
-$(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+$(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-$(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 
 endif	# TRUSTED_BOARD_BOOT
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index 967437b2..e46d8779 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index d466aa1c..21d95cf1 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -105,13 +105,13 @@ $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
 $(BUILD_PLAT)/bl2/uniphier_rotpk.o: $(ROTPK_HASH)
 
 certificates: $(ROT_KEY)
-$(ROT_KEY): | $(BUILD_PLAT)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
+$(ROT_KEY): | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl genrsa 2048 > $@ 2>/dev/null
 
-$(ROTPK_HASH): $(ROT_KEY)
-	@echo "  OPENSSL $@"
-	$(Q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+$(ROTPK_HASH): $(ROT_KEY) | $$(@D)/
+	$(s)echo "  OPENSSL $@"
+	$(q)${OPENSSL_BIN_PATH}/openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
 	${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
 
 endif
@@ -136,5 +136,5 @@ endif
 .PHONY: bl2_gzip
 bl2_gzip: $(BUILD_PLAT)/bl2.bin.gz
 %.gz: %
-	@echo "  GZIP    $@"
-	$(Q)gzip -n -f -9 $< --stdout > $@
+	$(s)echo "  GZIP    $@"
+	$(q)gzip -n -f -9 $< --stdout > $@
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 86795d71..c17ac7eb 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,6 +47,7 @@ uintptr_t fip_dev_handle;
 uintptr_t storage_dev_handle;
 
 static const io_dev_connector_t *fip_dev_con;
+static uint32_t nand_block_sz __maybe_unused;
 
 #ifndef DECRYPTION_SUPPORT_none
 static const io_dev_connector_t *enc_dev_con;
@@ -310,11 +311,55 @@ static void boot_spi_nor(boot_api_context_t *boot_context)
 }
 #endif /* STM32MP_SPI_NOR */
 
+#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
+/*
+ * This function returns 0 if it can find an alternate
+ * image to be loaded or a negative errno otherwise.
+ */
+static int try_nand_backup_partitions(unsigned int image_id)
+{
+	static unsigned int backup_id;
+	static unsigned int backup_block_nb;
+
+	/* Check if NAND storage used */
+	if (nand_block_sz == 0U) {
+		return -ENODEV;
+	}
+
+	if (backup_id != image_id) {
+		backup_block_nb = PLATFORM_MTD_MAX_PART_SIZE / nand_block_sz;
+		backup_id = image_id;
+	}
+
+	if (backup_block_nb-- == 0U) {
+		return -ENOSPC;
+	}
+
+#if PSA_FWU_SUPPORT
+	if (((image_block_spec.offset < STM32MP_NAND_FIP_B_OFFSET) &&
+	     ((image_block_spec.offset + nand_block_sz) >= STM32MP_NAND_FIP_B_OFFSET)) ||
+	    (image_block_spec.offset + nand_block_sz >= STM32MP_NAND_FIP_B_MAX_OFFSET)) {
+		return 0;
+	}
+#endif
+
+	image_block_spec.offset += nand_block_sz;
+
+	return 0;
+}
+
+static const struct plat_try_images_ops try_img_ops = {
+	.next_instance = try_nand_backup_partitions,
+};
+#endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */
+
 #if STM32MP_RAW_NAND
 static void boot_fmc2_nand(boot_api_context_t *boot_context)
 {
 	int io_result __maybe_unused;
 
+	plat_setup_try_img_ops(&try_img_ops);
+
 	io_result = stm32_fmc2_init();
 	assert(io_result == 0);
 
@@ -326,6 +371,8 @@ static void boot_fmc2_nand(boot_api_context_t *boot_context)
 	io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
 				&storage_dev_handle);
 	assert(io_result == 0);
+
+	nand_block_sz = nand_dev_spec.erase_size;
 }
 #endif /* STM32MP_RAW_NAND */
 
@@ -334,6 +381,8 @@ static void boot_spi_nand(boot_api_context_t *boot_context)
 {
 	int io_result __maybe_unused;
 
+	plat_setup_try_img_ops(&try_img_ops);
+
 	io_result = stm32_qspi_init();
 	assert(io_result == 0);
 
@@ -345,6 +394,8 @@ static void boot_spi_nand(boot_api_context_t *boot_context)
 				(uintptr_t)&spi_nand_dev_spec,
 				&storage_dev_handle);
 	assert(io_result == 0);
+
+	nand_block_sz = spi_nand_dev_spec.erase_size;
 }
 #endif /* STM32MP_SPI_NAND */
 
@@ -493,12 +544,10 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id)
  */
 #if !PSA_FWU_SUPPORT
 			const partition_entry_t *entry;
-			const struct efi_guid img_type_guid = STM32MP_FIP_GUID;
-			uuid_t img_type_uuid;
+			const struct efi_guid fip_guid = STM32MP_FIP_GUID;
 
-			guidcpy(&img_type_uuid, &img_type_guid);
 			partition_init(GPT_IMAGE_ID);
-			entry = get_partition_entry_by_type(&img_type_uuid);
+			entry = get_partition_entry_by_type(&fip_guid);
 			if (entry == NULL) {
 				entry = get_partition_entry(FIP_IMAGE_NAME);
 				if (entry == NULL) {
@@ -532,7 +581,14 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id)
 #if STM32MP_SPI_NAND
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
 #endif
+/*
+ * With FWU Multi Bank feature enabled, the selection of
+ * the image to boot will be done by fwu_init calling the
+ * platform hook, plat_fwu_set_images_source.
+ */
+#if !PSA_FWU_SUPPORT
 		image_block_spec.offset = STM32MP_NAND_FIP_OFFSET;
+#endif
 		break;
 #endif
 
@@ -598,7 +654,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
 	return rc;
 }
 
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
 /*
  * In each boot in non-trial mode, we set the BKP register to
  * FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
@@ -613,8 +669,6 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
  *     - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode.
  * we select the previous_active_index.
  */
-#define INVALID_BOOT_IDX		0xFFFFFFFFU
-
 uint32_t plat_fwu_get_boot_idx(void)
 {
 	/*
@@ -622,32 +676,38 @@ uint32_t plat_fwu_get_boot_idx(void)
 	 * even if this function is called several times.
 	 */
 	static uint32_t boot_idx = INVALID_BOOT_IDX;
-	const struct fwu_metadata *data;
-
-	data = fwu_get_metadata();
 
 	if (boot_idx == INVALID_BOOT_IDX) {
+		const struct fwu_metadata *data = fwu_get_metadata();
+
 		boot_idx = data->active_index;
-		if (fwu_is_trial_run_state()) {
+
+		if (data->bank_state[boot_idx] == FWU_BANK_STATE_VALID) {
 			if (stm32_get_and_dec_fwu_trial_boot_cnt() == 0U) {
 				WARN("Trial FWU fails %u times\n",
 				     FWU_MAX_TRIAL_REBOOT);
-				boot_idx = data->previous_active_index;
+				boot_idx = fwu_get_alternate_boot_bank();
 			}
-		} else {
+		} else if (data->bank_state[boot_idx] ==
+			   FWU_BANK_STATE_ACCEPTED) {
 			stm32_set_max_fwu_trial_boot_cnt();
+		} else {
+			ERROR("The active bank(%u) of the platform is in Invalid State.\n",
+				boot_idx);
+			boot_idx = fwu_get_alternate_boot_bank();
+			stm32_clear_fwu_trial_boot_cnt();
 		}
 	}
 
 	return boot_idx;
 }
 
-static void *stm32_get_image_spec(const uuid_t *img_type_uuid)
+static void *stm32_get_image_spec(const struct efi_guid *img_type_guid)
 {
 	unsigned int i;
 
 	for (i = 0U; i < MAX_NUMBER_IDS; i++) {
-		if ((guidcmp(&policies[i].img_type_guid, img_type_uuid)) == 0) {
+		if ((guidcmp(&policies[i].img_type_guid, img_type_guid)) == 0) {
 			return (void *)policies[i].image_spec;
 		}
 	}
@@ -660,20 +720,23 @@ void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
 	unsigned int i;
 	uint32_t boot_idx;
 	const partition_entry_t *entry __maybe_unused;
-	const uuid_t *img_type_uuid;
-	const uuid_t *img_uuid __maybe_unused;
+	const struct fwu_image_entry *img_entry;
+	const void *img_type_guid;
+	const void *img_guid;
 	io_block_spec_t *image_spec;
 	const uint16_t boot_itf = stm32mp_get_boot_itf_selected();
 
 	boot_idx = plat_fwu_get_boot_idx();
 	assert(boot_idx < NR_OF_FW_BANKS);
+	VERBOSE("Selecting to boot from bank %u\n", boot_idx);
 
+	img_entry = (void *)&metadata->fw_desc.img_entry;
 	for (i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
-		img_type_uuid = &metadata->img_entry[i].img_type_uuid;
+		img_type_guid = &img_entry[i].img_type_guid;
 
-		img_uuid = &metadata->img_entry[i].img_props[boot_idx].img_uuid;
+		img_guid = &img_entry[i].img_bank_info[boot_idx].img_guid;
 
-		image_spec = stm32_get_image_spec(img_type_uuid);
+		image_spec = stm32_get_image_spec(img_type_guid);
 		if (image_spec == NULL) {
 			ERROR("Unable to get image spec for the image in the metadata\n");
 			panic();
@@ -683,7 +746,7 @@ void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
 #if (STM32MP_SDMMC || STM32MP_EMMC)
 		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
 		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
-			entry = get_partition_entry_by_uuid(img_uuid);
+			entry = get_partition_entry_by_guid(img_guid);
 			if (entry == NULL) {
 				ERROR("No partition with the uuid mentioned in metadata\n");
 				panic();
@@ -695,15 +758,28 @@ void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
 #endif
 #if STM32MP_SPI_NOR
 		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI:
-			if (guidcmp(img_uuid, &STM32MP_NOR_FIP_A_GUID) == 0) {
+			if (guidcmp(img_guid, &STM32MP_NOR_FIP_A_GUID) == 0) {
 				image_spec->offset = STM32MP_NOR_FIP_A_OFFSET;
-			} else if (guidcmp(img_uuid, &STM32MP_NOR_FIP_B_GUID) == 0) {
+			} else if (guidcmp(img_guid, &STM32MP_NOR_FIP_B_GUID) == 0) {
 				image_spec->offset = STM32MP_NOR_FIP_B_OFFSET;
 			} else {
 				ERROR("Invalid uuid mentioned in metadata\n");
 				panic();
 			}
 			break;
+#endif
+#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
+		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+		case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
+			if (guidcmp(img_guid, &STM32MP_NAND_FIP_A_GUID) == 0) {
+				image_spec->offset = STM32MP_NAND_FIP_A_OFFSET;
+			} else if (guidcmp(img_guid, &STM32MP_NAND_FIP_B_GUID) == 0) {
+				image_spec->offset = STM32MP_NAND_FIP_B_OFFSET;
+			} else {
+				ERROR("Invalid uuid mentioned in metadata\n");
+				panic();
+			}
+			break;
 #endif
 		default:
 			panic();
@@ -712,9 +788,9 @@ void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
 	}
 }
 
-static int plat_set_image_source(unsigned int image_id,
-				 uintptr_t *handle,
-				 uintptr_t *image_spec)
+static int set_metadata_image_source(unsigned int image_id,
+				     uintptr_t *handle,
+				     uintptr_t *image_spec)
 {
 	struct plat_io_policy *policy;
 	io_block_spec_t *spec __maybe_unused;
@@ -757,6 +833,19 @@ static int plat_set_image_source(unsigned int image_id,
 		spec->length = sizeof(struct fwu_metadata);
 		break;
 #endif
+
+#if (STM32MP_RAW_NAND || STM32MP_SPI_NAND)
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI:
+		if (image_id == FWU_METADATA_IMAGE_ID) {
+			spec->offset = STM32MP_NAND_METADATA1_OFFSET;
+		} else {
+			spec->offset = STM32MP_NAND_METADATA2_OFFSET;
+		}
+
+		spec->length = sizeof(struct fwu_metadata);
+		break;
+#endif
 	default:
 		panic();
 		break;
@@ -775,6 +864,6 @@ int plat_fwu_set_metadata_image_source(unsigned int image_id,
 	assert((image_id == FWU_METADATA_IMAGE_ID) ||
 	       (image_id == BKUP_FWU_METADATA_IMAGE_ID));
 
-	return plat_set_image_source(image_id, handle, image_spec);
+	return set_metadata_image_source(image_id, handle, image_spec);
 }
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/common/common.mk b/plat/st/common/common.mk
index 7f93961d..7395a367 100644
--- a/plat/st/common/common.mk
+++ b/plat/st/common/common.mk
@@ -1,12 +1,11 @@
 #
-# Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 RESET_TO_BL2			:=	1
 
-STM32MP_EARLY_CONSOLE		?=	0
 STM32MP_RECONFIGURE_CONSOLE	?=	0
 STM32MP_UART_BAUDRATE		?=	115200
 
@@ -29,6 +28,24 @@ STM32_HEADER_BL2_BINARY_TYPE	:=	0x10
 TF_CFLAGS			+=	-Wsign-compare
 TF_CFLAGS			+=	-Wformat-signedness
 
+# Number of TF-A copies in the device
+STM32_TF_A_COPIES		:=	2
+
+# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
+PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + $(STM32_EXTRA_PARTS))))
+
+ifeq (${PSA_FWU_SUPPORT},1)
+# Number of banks of updatable firmware
+NR_OF_FW_BANKS			:=	2
+NR_OF_IMAGES_IN_FW_BANK		:=	1
+
+FWU_MAX_PART = $(shell echo $$(($(STM32_TF_A_COPIES) + 2 + $(NR_OF_FW_BANKS))))
+ifeq ($(shell test $(FWU_MAX_PART) -gt $(PLAT_PARTITION_MAX_ENTRIES); echo $$?),0)
+$(error "Required partition number is $(FWU_MAX_PART) where PLAT_PARTITION_MAX_ENTRIES is only \
+$(PLAT_PARTITION_MAX_ENTRIES)")
+endif
+endif
+
 # Boot devices
 STM32MP_EMMC			?=	0
 STM32MP_SDMMC			?=	0
@@ -43,7 +60,7 @@ STM32MP_EMMC_BOOT		?=	0
 STM32MP_UART_PROGRAMMER		?=	0
 STM32MP_USB_PROGRAMMER		?=	0
 
-$(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
+$(eval DTC_V = $(shell $($(ARCH)-dtc) -v | awk '{print $$NF}'))
 $(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o "[0-9]*")))
 DTC_CPPFLAGS			+=	${INCLUDES}
 DTC_FLAGS			+=	-Wno-unit_address_vs_reg
@@ -82,7 +99,6 @@ endif
 $(eval $(call assert_booleans,\
 	$(sort \
 		PLAT_XLAT_TABLES_DYNAMIC \
-		STM32MP_EARLY_CONSOLE \
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \
@@ -104,7 +120,6 @@ $(eval $(call add_defines,\
 	$(sort \
 		PLAT_XLAT_TABLES_DYNAMIC \
 		STM32_TF_VERSION \
-		STM32MP_EARLY_CONSOLE \
 		STM32MP_EMMC \
 		STM32MP_EMMC_BOOT \
 		STM32MP_RAW_NAND \
@@ -123,6 +138,9 @@ PLAT_INCLUDES			+=	-Iplat/st/common/include/
 include lib/fconf/fconf.mk
 include lib/libfdt/libfdt.mk
 include lib/zlib/zlib.mk
+ifeq (${PSA_FWU_SUPPORT},1)
+include drivers/fwu/fwu.mk
+endif
 
 PLAT_BL_COMMON_SOURCES		+=	common/uuid.c					\
 					plat/st/common/stm32mp_common.c
@@ -183,12 +201,10 @@ ifneq (${MBEDTLS_DIR},)
 MBEDTLS_MAJOR=$(shell grep -hP "define MBEDTLS_VERSION_MAJOR" \
 ${MBEDTLS_DIR}/include/mbedtls/*.h | grep -oe '\([0-9.]*\)')
 
-ifeq (${MBEDTLS_MAJOR}, 2)
-MBEDTLS_CONFIG_FILE		?=	"<stm32mp_mbedtls_config-2.h>"
-endif
-
 ifeq (${MBEDTLS_MAJOR}, 3)
 MBEDTLS_CONFIG_FILE		?=	"<stm32mp_mbedtls_config-3.h>"
+else
+$(error Error: TF-A only supports MbedTLS versions > 3.x)
 endif
 endif
 
diff --git a/plat/st/common/common_rules.mk b/plat/st/common/common_rules.mk
index f39caab8..9070a16a 100644
--- a/plat/st/common/common_rules.mk
+++ b/plat/st/common/common_rules.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -15,7 +15,7 @@ distclean realclean clean: clean_stm32image
 bl2: check_boot_device
 
 check_boot_device:
-	@if [ ${STM32MP_EMMC} != 1 ] && \
+	$(q)if [ ${STM32MP_EMMC} != 1 ] && \
 	    [ ${STM32MP_SDMMC} != 1 ] && \
 	    [ ${STM32MP_RAW_NAND} != 1 ] && \
 	    [ ${STM32MP_SPI_NAND} != 1 ] && \
@@ -29,55 +29,55 @@ check_boot_device:
 stm32image: ${STM32IMAGE}
 
 ${STM32IMAGE}: ${STM32IMAGE_SRC}
-	${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
+	$(q)${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
 
 clean_stm32image:
-	${Q}${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
+	$(q)${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
 
 check_dtc_version:
-	@if [ ${DTC_VERSION} -lt 10407 ]; then \
+	$(q)if [ ${DTC_VERSION} -lt 10407 ]; then \
 		echo "dtc version too old (${DTC_V}), you need at least version 1.4.7"; \
 		false; \
 	fi
 
 # Create DTB file for BL2
-${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs
-	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
-	@echo '#include "${BL2_DTSI}"' >> $@
+${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | $$(@D)/
+	$(q)echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	$(q)echo '#include "${BL2_DTSI}"' >> $@
 
 ${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts
 
 ${BUILD_PLAT}/$(PLAT)-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb $(STM32_BINARY_MAPPING) bl2
-	@echo "  AS      $${PLAT}.S"
-	${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
+	$(s)echo "  AS      $${PLAT}.S"
+	$(q)$($(ARCH)-as) -x assembler-with-cpp $(TF_CFLAGS_$(ARCH)) ${ASFLAGS} ${TF_CFLAGS} \
 		-DDTB_BIN_PATH=\"$<\" \
 		-c $(word 2,$^) -o $@
 
 $(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},$(STM32_LD_FILE),bl2))
 
 tf-a-%.elf: $(PLAT)-%.o ${STM32_TF_LINKERFILE}
-	@echo "  LDS     $<"
-ifneq ($(findstring gcc,$(notdir $(LD))),)
-	${Q}${LD} -o $@ $(subst --,-Wl$(comma)--,${STM32_TF_ELF_LDFLAGS}) -nostartfiles -Wl,-Map=$(@:.elf=.map) -Wl,-dT ${STM32_TF_LINKERFILE} $<
+	$(s)echo "  LDS     $<"
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
+	$(q)$($(ARCH)-ld) -o $@ $(subst --,-Wl$(comma)--,${STM32_TF_ELF_LDFLAGS}) -nostartfiles -no-pie -Wl,-Map=$(@:.elf=.map) -Wl,-dT ${STM32_TF_LINKERFILE} $<
 else
-	${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
+	$(q)$($(ARCH)-ld) -o $@ ${STM32_TF_ELF_LDFLAGS} -no-pie -Map=$(@:.elf=.map) --script ${STM32_TF_LINKERFILE} $<
 endif
 
 tf-a-%.bin: tf-a-%.elf
-	${Q}${OC} -O binary $< $@
-	@echo
-	@echo "Built $@ successfully"
-	@echo
+	$(q)$($(ARCH)-oc) -O binary $< $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 tf-a-%.stm32: tf-a-%.bin ${STM32_DEPS}
-	@echo
-	@echo "Generate $@"
+	$(s)echo
+	$(s)echo "Generate $@"
 	$(eval LOADADDR = $(shell cat $(@:.stm32=.map) | grep '^RAM' | awk '{print $$2}'))
 	$(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
-	${Q}${STM32IMAGE} -s $< -d $@ \
+	$(q)${STM32IMAGE} -s $< -d $@ \
 		-l $(LOADADDR) -e ${ENTRY} \
 		-v ${STM32_TF_VERSION} \
 		-m ${STM32_HEADER_VERSION_MAJOR} \
 		-n ${STM32_HEADER_VERSION_MINOR} \
 		-b ${STM32_HEADER_BL2_BINARY_TYPE}
-	@echo
+	$(s)echo
diff --git a/plat/st/stm32mp1/include/plat_def_fip_uuid.h b/plat/st/common/include/plat_def_fip_uuid.h
similarity index 59%
rename from plat/st/stm32mp1/include/plat_def_fip_uuid.h
rename to plat/st/common/include/plat_def_fip_uuid.h
index e5fbc2df..096fd952 100644
--- a/plat/st/stm32mp1/include/plat_def_fip_uuid.h
+++ b/plat/st/common/include/plat_def_fip_uuid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,10 @@
 #ifndef PLAT_DEF_FIP_UUID_H
 #define PLAT_DEF_FIP_UUID_H
 
+#define UUID_DDR_FW \
+	{{0xb1, 0x12, 0x49, 0xbe}, {0x92, 0xdd}, {0x4b, 0x10}, 0x86, 0x7c, \
+	 {0x2c, 0x6a, 0x4b, 0x47, 0xa7, 0xfb} }
+
 #define UUID_STM32MP_CONFIG_CERT \
 	{{0x50, 0x1d, 0x8d, 0xd2}, {0x8b, 0xce}, {0x49, 0xa5}, 0x84, 0xeb, \
 	 {0x55, 0x9a, 0x9f, 0x2e, 0xae, 0xaf} }
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index e334f225..f65301ff 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,17 +14,26 @@
 #define JEDEC_ST_BKID U(0x0)
 #define JEDEC_ST_MFID U(0x20)
 
+#define STM32MP_CHIP_SEC_CLOSED		U(0x34D9CCC5)
+#define STM32MP_CHIP_SEC_OPEN		U(0xA764D182)
+
 /* FWU configuration (max supported value is 15) */
 #define FWU_MAX_TRIAL_REBOOT		U(3)
 
+/* Define maximum page size for NAND devices */
+#define PLATFORM_MTD_MAX_PAGE_SIZE	U(0x1000)
+
+/* Needed by STM32CubeProgrammer support */
+#define DWL_BUFFER_SIZE			U(0x01000000)
+
 /* Functions to save and get boot context address given by ROM code */
 void stm32mp_save_boot_ctx_address(uintptr_t address);
 uintptr_t stm32mp_get_boot_ctx_address(void);
 uint16_t stm32mp_get_boot_itf_selected(void);
 
 bool stm32mp_is_single_core(void);
-bool stm32mp_is_closed_device(void);
 bool stm32mp_is_auth_supported(void);
+uint32_t stm32mp_check_closed_device(void);
 
 /* Return the base address of the DDR controller */
 uintptr_t stm32mp_ddrctrl_base(void);
@@ -68,13 +77,7 @@ uintptr_t get_uart_address(uint32_t instance_nb);
 /* Setup the UART console */
 int stm32mp_uart_console_setup(void);
 
-#if STM32MP_EARLY_CONSOLE
-void stm32mp_setup_early_console(void);
-#else
-static inline void stm32mp_setup_early_console(void)
-{
-}
-#endif
+bool stm32mp_is_wakeup_from_standby(void);
 
 /*
  * Platform util functions for the GPIO driver
@@ -119,6 +122,10 @@ void stm32mp_io_setup(void);
 int stm32mp_map_ddr_non_cacheable(void);
 int stm32mp_unmap_ddr(void);
 
+/* Functions to map RETRAM, and unmap it */
+int stm32mp_map_retram(void);
+int stm32mp_unmap_retram(void);
+
 /* Function to save boot info */
 void stm32_save_boot_info(boot_api_context_t *boot_context);
 /* Function to get boot peripheral info */
@@ -130,9 +137,11 @@ uintptr_t stm32_get_bkpr_boot_mode_addr(void);
 void stm32_display_board_info(uint32_t board_id);
 
 #if PSA_FWU_SUPPORT
-void stm32mp1_fwu_set_boot_idx(void);
+uintptr_t stm32_get_bkpr_fwu_info_addr(void);
+void stm32_fwu_set_boot_idx(void);
 uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void);
 void stm32_set_max_fwu_trial_boot_cnt(void);
+void stm32_clear_fwu_trial_boot_cnt(void);
 #endif /* PSA_FWU_SUPPORT */
 
 #endif /* STM32MP_COMMON_H */
diff --git a/plat/st/common/include/stm32mp_mbedtls_config-2.h b/plat/st/common/include/stm32mp_mbedtls_config-2.h
deleted file mode 100644
index 66ff3465..00000000
--- a/plat/st/common/include/stm32mp_mbedtls_config-2.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef MBEDTLS_CONFIG_H
-#define MBEDTLS_CONFIG_H
-
-/*
- * Key algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_USE_RSA	0
-#define TF_MBEDTLS_USE_ECDSA	1
-
-/*
- * Hash algorithms currently supported on mbed TLS libraries
- */
-#define TF_MBEDTLS_SHA256		1
-#define TF_MBEDTLS_SHA384		2
-#define TF_MBEDTLS_SHA512		3
-
-/*
- * Configuration file to build mbed TLS with the required features for
- * Trusted Boot
- */
-
-#define MBEDTLS_PLATFORM_MEMORY
-#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
-/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */
-#define MBEDTLS_PLATFORM_SNPRINTF_ALT
-
-#define MBEDTLS_PKCS1_V21
-
-#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
-#define MBEDTLS_X509_CHECK_KEY_USAGE
-#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
-
-#define MBEDTLS_ASN1_PARSE_C
-#define MBEDTLS_ASN1_WRITE_C
-
-#define MBEDTLS_BASE64_C
-#define MBEDTLS_BIGNUM_C
-
-#define MBEDTLS_ERROR_C
-#define MBEDTLS_MD_C
-
-#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
-#define MBEDTLS_OID_C
-
-#define MBEDTLS_PK_C
-#define MBEDTLS_PK_PARSE_C
-#define MBEDTLS_PK_WRITE_C
-
-#define MBEDTLS_PLATFORM_C
-
-#if TF_MBEDTLS_USE_ECDSA
-#define MBEDTLS_ECDSA_C
-#define MBEDTLS_ECP_C
-#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#define MBEDTLS_ECP_NO_INTERNAL_RNG
-#endif
-#if TF_MBEDTLS_USE_RSA
-#define MBEDTLS_RSA_C
-#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
-#endif
-
-#define MBEDTLS_SHA256_C
-#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256)
-#define MBEDTLS_SHA512_C
-#endif
-
-#define MBEDTLS_VERSION_C
-
-#define MBEDTLS_X509_USE_C
-#define MBEDTLS_X509_CRT_PARSE_C
-
-#if TF_MBEDTLS_USE_AES_GCM
-#define MBEDTLS_AES_C
-#define MBEDTLS_CIPHER_C
-#define MBEDTLS_GCM_C
-#endif
-
-/* MPI / BIGNUM options */
-#define MBEDTLS_MPI_WINDOW_SIZE			2
-
-#if TF_MBEDTLS_USE_RSA
-#if TF_MBEDTLS_KEY_SIZE <= 2048
-#define MBEDTLS_MPI_MAX_SIZE			256
-#else
-#define MBEDTLS_MPI_MAX_SIZE			512
-#endif
-#else
-#define MBEDTLS_MPI_MAX_SIZE			256
-#endif
-
-/* Memory buffer allocator options */
-#define MBEDTLS_MEMORY_ALIGN_MULTIPLE		8
-
-/*
- * Prevent the use of 128-bit division which
- * creates dependency on external libraries.
- */
-#define MBEDTLS_NO_UDBL_DIVISION
-
-#ifndef __ASSEMBLER__
-/* System headers required to build mbed TLS with the current configuration */
-#include <stdlib.h>
-#include <mbedtls/check_config.h>
-#endif
-
-/*
- * Mbed TLS heap size is smal as we only use the asn1
- * parsing functions
- * digest, signature and crypto algorithm are done by
- * other library.
- */
-
-#define TF_MBEDTLS_HEAP_SIZE           U(5120)
-#endif /* MBEDTLS_CONFIG_H */
diff --git a/plat/st/common/include/stm32mp_mbedtls_config-3.h b/plat/st/common/include/stm32mp_mbedtls_config-3.h
index a812671b..2dbf0689 100644
--- a/plat/st/common/include/stm32mp_mbedtls_config-3.h
+++ b/plat/st/common/include/stm32mp_mbedtls_config-3.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -102,7 +102,6 @@
 #ifndef __ASSEMBLER__
 /* System headers required to build mbed TLS with the current configuration */
 #include <stdlib.h>
-#include <mbedtls/check_config.h>
 #endif
 
 /*
diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c
index 2163aaf1..d2f87844 100644
--- a/plat/st/common/stm32mp_common.c
+++ b/plat/st/common/stm32mp_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -55,6 +55,12 @@
 #define BOOT_INST_MASK			GENMASK_32(11, 8)
 #define BOOT_INST_SHIFT			8
 
+/* Layout for fwu update information. */
+#define FWU_INFO_IDX_MSK		GENMASK(3, 0)
+#define FWU_INFO_IDX_OFF		U(0)
+#define FWU_INFO_CNT_MSK		GENMASK(7, 4)
+#define FWU_INFO_CNT_OFF		U(4)
+
 static console_t console;
 
 uintptr_t plat_get_ns_image_entrypoint(void)
@@ -168,9 +174,9 @@ int stm32_get_otp_value_from_idx(const uint32_t otp_idx, uint32_t *otp_val)
 	assert(otp_val != NULL);
 
 #if defined(IMAGE_BL2)
-	ret = bsec_shadow_read_otp(otp_val, otp_idx);
-#elif defined(IMAGE_BL32)
-	ret = bsec_read_otp(otp_val, otp_idx);
+	ret = stm32_otp_shadow_read(otp_val, otp_idx);
+#elif defined(IMAGE_BL31) || defined(IMAGE_BL32)
+	ret = stm32_otp_read(otp_val, otp_idx);
 #else
 #error "Not supported"
 #endif
@@ -269,8 +275,8 @@ int stm32mp_uart_console_setup(void)
 	return 0;
 }
 
-#if STM32MP_EARLY_CONSOLE
-void stm32mp_setup_early_console(void)
+#if EARLY_CONSOLE
+void plat_setup_early_console(void)
 {
 #if defined(IMAGE_BL2) || STM32MP_RECONFIGURE_CONSOLE
 	plat_crash_console_init();
@@ -278,7 +284,7 @@ void stm32mp_setup_early_console(void)
 	set_console(STM32MP_DEBUG_USART_BASE, STM32MP_DEBUG_USART_CLK_FRQ);
 	NOTICE("Early console setup\n");
 }
-#endif /* STM32MP_EARLY_CONSOLE */
+#endif /* EARLY_CONSOLE */
 
 /*****************************************************************************
  * plat_is_smccc_feature_available() - This function checks whether SMCCC
@@ -378,3 +384,53 @@ void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
 	*interface = (itf & BOOT_ITF_MASK) >> BOOT_ITF_SHIFT;
 	*instance = (itf & BOOT_INST_MASK) >> BOOT_INST_SHIFT;
 }
+
+#if PSA_FWU_SUPPORT
+void stm32_fwu_set_boot_idx(void)
+{
+	clk_enable(TAMP_BKP_REG_CLK);
+	mmio_clrsetbits_32(stm32_get_bkpr_fwu_info_addr(),
+			   FWU_INFO_IDX_MSK,
+			   (plat_fwu_get_boot_idx() << FWU_INFO_IDX_OFF) &
+			   FWU_INFO_IDX_MSK);
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+
+uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
+	uint32_t try_cnt;
+
+	clk_enable(TAMP_BKP_REG_CLK);
+	try_cnt = (mmio_read_32(bkpr_fwu_cnt) & FWU_INFO_CNT_MSK) >> FWU_INFO_CNT_OFF;
+
+	assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
+
+	if (try_cnt != 0U) {
+		mmio_clrsetbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK,
+				   (try_cnt - 1U) << FWU_INFO_CNT_OFF);
+	}
+	clk_disable(TAMP_BKP_REG_CLK);
+
+	return try_cnt;
+}
+
+void stm32_set_max_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
+
+	clk_enable(TAMP_BKP_REG_CLK);
+	mmio_clrsetbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK,
+			   (FWU_MAX_TRIAL_REBOOT << FWU_INFO_CNT_OFF) & FWU_INFO_CNT_MSK);
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+
+void stm32_clear_fwu_trial_boot_cnt(void)
+{
+	uintptr_t bkpr_fwu_cnt = stm32_get_bkpr_fwu_info_addr();
+
+	clk_enable(TAMP_BKP_REG_CLK);
+	mmio_clrbits_32(bkpr_fwu_cnt, FWU_INFO_CNT_MSK);
+	clk_disable(TAMP_BKP_REG_CLK);
+}
+#endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/common/stm32mp_crypto_lib.c b/plat/st/common/stm32mp_crypto_lib.c
index e282115d..7223022e 100644
--- a/plat/st/common/stm32mp_crypto_lib.c
+++ b/plat/st/common/stm32mp_crypto_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,6 @@
 #include <common/debug.h>
 #include <drivers/auth/crypto_mod.h>
 #include <drivers/io/io_storage.h>
-#include <drivers/st/bsec.h>
 #include <drivers/st/stm32_hash.h>
 #include <drivers/st/stm32_pka.h>
 #include <drivers/st/stm32_rng.h>
@@ -58,7 +57,8 @@ static void crypto_lib_init(void)
 		panic();
 	}
 
-	if (stm32mp_is_closed_device() || stm32mp_is_auth_supported()) {
+	if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) ||
+	    stm32mp_is_auth_supported()) {
 #if STM32MP_CRYPTO_ROM_LIB
 		boot_context = (boot_api_context_t *)stm32mp_get_boot_ctx_address();
 		auth_ops.verify_signature = boot_context->bootrom_ecdsa_verify_signature;
@@ -322,7 +322,8 @@ static int crypto_verify_signature(void *data_ptr, unsigned int data_len,
 	size_t bignum_len = sizeof(sig) / 2U;
 	unsigned int seq_num = 0U;
 
-	if (!stm32mp_is_closed_device() && !stm32mp_is_auth_supported()) {
+	if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) &&
+	    !stm32mp_is_auth_supported()) {
 		return CRYPTO_SUCCESS;
 	}
 
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index 1cbf51ba..282f53fa 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -243,7 +243,11 @@ size_t dt_get_ddr_size(void)
 		return 0U;
 	}
 
+#ifdef __aarch64__
+	size = (size_t)fdt_read_uint64_default(fdt, node, "st,mem-size", 0ULL);
+#else /* __aarch64__ */
 	size = (size_t)fdt_read_uint32_default(fdt, node, "st,mem-size", 0U);
+#endif /* __aarch64__ */
 
 	flush_dcache_range((uintptr_t)&size, sizeof(size_t));
 
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 5514c09c..644275e3 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,12 +27,12 @@ static io_block_spec_t gpt_block_spec = {
 };
 #endif
 
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
 static io_block_spec_t metadata_block_spec = {
 	.offset = 0,    /* To be filled at runtime */
 	.length = 0,    /* To be filled at runtime */
 };
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
 
 /* By default, STM32 platforms load images from the FIP */
 struct plat_io_policy policies[MAX_NUMBER_IDS] = {
@@ -58,7 +58,7 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
 		.check = open_storage
 	},
 #endif
-#if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT
+#if PSA_FWU_SUPPORT
 	[FWU_METADATA_IMAGE_ID] = {
 		.dev_handle = &storage_dev_handle,
 		.image_spec = (uintptr_t)&metadata_block_spec,
@@ -71,19 +71,33 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
 		.img_type_guid = NULL_GUID,
 		.check = open_storage
 	},
-#endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */
+#endif /* PSA_FWU_SUPPORT */
 };
 
 #define DEFAULT_UUID_NUMBER	U(7)
 
+#ifdef __aarch64__
+#define BL31_UUID_NUMBER	U(2)
+#else
+#define BL31_UUID_NUMBER	U(0)
+#endif
+
 #if TRUSTED_BOARD_BOOT
 #define TBBR_UUID_NUMBER	U(6)
 #else
 #define TBBR_UUID_NUMBER	U(0)
 #endif
 
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define DDR_FW_UUID_NUMBER	U(1)
+#else
+#define DDR_FW_UUID_NUMBER	U(0)
+#endif
+
 #define FCONF_ST_IO_UUID_NUMBER	(DEFAULT_UUID_NUMBER + \
-				 TBBR_UUID_NUMBER)
+				 BL31_UUID_NUMBER + \
+				 TBBR_UUID_NUMBER + \
+				 DDR_FW_UUID_NUMBER)
 
 static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER];
 static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids);
@@ -95,7 +109,14 @@ struct policies_load_info {
 
 /* image id to property name table */
 static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = {
+#if STM32MP_DDR_FIP_IO_STORAGE
+	{DDR_FW_ID, "ddr_fw_uuid"},
+#endif
 	{FW_CONFIG_ID, "fw_cfg_uuid"},
+#ifdef __aarch64__
+	{BL31_IMAGE_ID, "bl31_uuid"},
+	{SOC_FW_CONFIG_ID, "soc_fw_cfg_uuid"},
+#endif
 	{BL32_IMAGE_ID, "bl32_uuid"},
 	{BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"},
 	{BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"},
diff --git a/plat/st/common/stm32mp_gic.c b/plat/st/common/stm32mp_gic.c
index d02b635a..a4cc4a5e 100644
--- a/plat/st/common/stm32mp_gic.c
+++ b/plat/st/common/stm32mp_gic.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/fdt_wrappers.h>
 #include <drivers/arm/gicv2.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <lib/utils.h>
@@ -45,25 +46,29 @@ void stm32mp_gic_init(void)
 	int node;
 	void *fdt;
 	const fdt32_t *cuint;
-	struct dt_node_info dt_gic;
+	uintptr_t addr;
+	int err;
 
 	if (fdt_get_address(&fdt) == 0) {
 		panic();
 	}
 
-	node = dt_get_node(&dt_gic, -1, "arm,cortex-a7-gic");
+	node = fdt_node_offset_by_compatible(fdt, -1, "arm,cortex-a7-gic");
 	if (node < 0) {
 		panic();
 	}
 
-	platform_gic_data.gicd_base = dt_gic.base;
-
-	cuint = fdt_getprop(fdt, node, "reg", NULL);
-	if (cuint == NULL) {
+	err = fdt_get_reg_props_by_index(fdt, node, 0, &addr, NULL);
+	if (err < 0) {
 		panic();
 	}
+	platform_gic_data.gicd_base = addr;
 
-	platform_gic_data.gicc_base = fdt32_to_cpu(*(cuint + 2));
+	err = fdt_get_reg_props_by_index(fdt, node, 1, &addr, NULL);
+	if (err < 0) {
+		panic();
+	}
+	platform_gic_data.gicc_base = addr;
 
 	cuint = fdt_getprop(fdt, node, "#interrupt-cells", NULL);
 	if (cuint == NULL) {
diff --git a/plat/st/common/stm32mp_trusted_boot.c b/plat/st/common/stm32mp_trusted_boot.c
index 6d89290e..d40fc558 100644
--- a/plat/st/common/stm32mp_trusted_boot.c
+++ b/plat/st/common/stm32mp_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -67,14 +67,14 @@ static int copy_hash_from_otp(const char *otp_name, uint8_t *hash, size_t len)
 		 * Check if key hash values in OTP are 0 or 0xFFFFFFFFF
 		 * programmed : Invalid Key
 		 */
-		if (!stm32mp_is_closed_device() && !valid) {
+		if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) && !valid) {
 			if ((tmp != 0U) && (tmp != 0xFFFFFFFFU) && (tmp != first)) {
 				valid = true;
 			}
 		}
 	}
 
-	if (!stm32mp_is_closed_device() && !valid) {
+	if ((stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN) && !valid) {
 		return 0;
 	}
 
@@ -163,7 +163,7 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
 	*key_ptr = &root_pk_hash;
 	*flags = ROTPK_IS_HASH;
 
-	if ((res == 0) && !stm32mp_is_closed_device()) {
+	if ((res == 0) && (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_OPEN)) {
 		*flags |= ROTPK_NOT_DEPLOYED;
 	}
 
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index eeabd09d..9da311e2 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -142,8 +142,6 @@ void bl2_el3_early_platform_setup(u_register_t arg0,
 				  u_register_t arg2 __unused,
 				  u_register_t arg3 __unused)
 {
-	stm32mp_setup_early_console();
-
 	stm32mp_save_boot_ctx_address(arg0);
 }
 
@@ -255,11 +253,6 @@ void bl2_el3_plat_arch_setup(void)
 		mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST);
 	}
 
-#if STM32MP15
-	/* Disable MCKPROT */
-	mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT);
-#endif
-
 	/*
 	 * Set minimum reset pulse duration to 31ms for discrete power
 	 * supplied boards.
@@ -318,7 +311,7 @@ void bl2_el3_plat_arch_setup(void)
 
 skip_console_init:
 #if !TRUSTED_BOARD_BOOT
-	if (stm32mp_is_closed_device()) {
+	if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
 		/* Closed chip mandates authentication */
 		ERROR("Secure chip: TRUSTED_BOARD_BOOT must be enabled\n");
 		panic();
@@ -338,7 +331,7 @@ skip_console_init:
 		print_pmic_info_and_debug();
 	}
 
-	stm32mp1_syscfg_init();
+	stm32mp_syscfg_init();
 
 	if (stm32_iwdg_init() < 0) {
 		panic();
@@ -347,7 +340,7 @@ skip_console_init:
 	stm32_iwdg_refresh();
 
 	if (bsec_read_debug_conf() != 0U) {
-		if (stm32mp_is_closed_device()) {
+		if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
 #if DEBUG
 			WARN("\n%s", debug_msg);
 #else
@@ -367,10 +360,12 @@ skip_console_init:
 	print_reset_reason();
 
 #if STM32MP15
-	update_monotonic_counter();
+	if (stm32mp_check_closed_device() == STM32MP_CHIP_SEC_CLOSED) {
+		update_monotonic_counter();
+	}
 #endif
 
-	stm32mp1_syscfg_enable_io_compensation_finish();
+	stm32mp_syscfg_enable_io_compensation_finish();
 
 	fconf_populate("TB_FW", STM32MP_DTB_BASE);
 
@@ -445,8 +440,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 				paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
 				if (paged_mem_params != NULL) {
 					paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
-						(dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
-						 STM32MP_DDR_SHMEM_SIZE);
+						(dt_get_ddr_size() - STM32MP_DDR_S_SIZE);
 					paged_mem_params->image_info.image_max_size =
 						STM32MP_DDR_S_SIZE;
 				}
@@ -467,7 +461,8 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 		break;
 
 	case BL32_IMAGE_ID:
-		if (optee_header_is_valid(bl_mem_params->image_info.image_base)) {
+		if ((bl_mem_params->image_info.image_base != 0UL) &&
+		    (optee_header_is_valid(bl_mem_params->image_info.image_base))) {
 			image_info_t *paged_image_info = NULL;
 
 			/* BL32 is OP-TEE header */
@@ -513,7 +508,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id)
 		assert(bl32_mem_params != NULL);
 		bl32_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
 #if PSA_FWU_SUPPORT
-		stm32mp1_fwu_set_boot_idx();
+		stm32_fwu_set_boot_idx();
 #endif /* PSA_FWU_SUPPORT */
 		break;
 
diff --git a/plat/st/stm32mp1/cert_create_tbbr.mk b/plat/st/stm32mp1/cert_create_tbbr.mk
index 5b1a3ed9..fb9e5ecf 100644
--- a/plat/st/stm32mp1/cert_create_tbbr.mk
+++ b/plat/st/stm32mp1/cert_create_tbbr.mk
@@ -11,9 +11,8 @@ $(eval $(call add_define,PDEF_CERTS))
 PLAT_INCLUDE	+= -I${PLAT_DIR}include
 
 src/stm32mp1_tbb_cert.o: ${PLAT_DIR}stm32mp1_tbb_cert.c
-	${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
 PLAT_OBJECTS	= src/stm32mp1_tbb_cert.o
 
 OBJECTS		+= $(PLAT_OBJECTS)
-
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 75c8219a..7e6d91fe 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -77,20 +77,6 @@
  ******************************************************************************/
 #define BL33_BASE			STM32MP_BL33_BASE
 
-/*
- * Load address of BL33 for this platform port
- */
-#define PLAT_STM32MP_NS_IMAGE_OFFSET	BL33_BASE
-
-/* Needed by STM32CubeProgrammer support */
-#define DWL_BUFFER_SIZE			U(0x01000000)
-
-/*
- * SSBL offset in case it's stored in eMMC boot partition.
- * We can fix it to 256K because TF-A size can't be bigger than SRAM
- */
-#define PLAT_EMMC_BOOT_SSBL_OFFSET		U(0x40000)
-
 /*******************************************************************************
  * DTB specific defines.
  ******************************************************************************/
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 4a522555..55227fb3 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,22 +14,49 @@ void configure_mmu(void);
 void stm32mp1_arch_security_setup(void);
 void stm32mp1_security_setup(void);
 
-void stm32mp1_syscfg_init(void);
-void stm32mp1_syscfg_enable_io_compensation_start(void);
-void stm32mp1_syscfg_enable_io_compensation_finish(void);
-void stm32mp1_syscfg_disable_io_compensation(void);
-uint32_t stm32mp1_syscfg_get_chip_version(void);
-uint32_t stm32mp1_syscfg_get_chip_dev_id(void);
+void stm32mp_syscfg_init(void);
+void stm32mp_syscfg_enable_io_compensation_start(void);
+void stm32mp_syscfg_enable_io_compensation_finish(void);
+void stm32mp_syscfg_disable_io_compensation(void);
+uint32_t stm32mp_syscfg_get_chip_version(void);
+uint32_t stm32mp_syscfg_get_chip_dev_id(void);
 #if STM32MP13
-void stm32mp1_syscfg_boot_mode_enable(void);
-void stm32mp1_syscfg_boot_mode_disable(void);
+void stm32mp_syscfg_boot_mode_enable(void);
+void stm32mp_syscfg_boot_mode_disable(void);
 #endif
 #if STM32MP15
-static inline void stm32mp1_syscfg_boot_mode_enable(void){}
-static inline void stm32mp1_syscfg_boot_mode_disable(void){}
+static inline void stm32mp_syscfg_boot_mode_enable(void){}
+static inline void stm32mp_syscfg_boot_mode_disable(void){}
 #endif
 
 void stm32mp1_deconfigure_uart_pins(void);
 
 void stm32mp1_init_scmi_server(void);
+
+/* Wrappers for OTP / BSEC functions */
+static inline uint32_t stm32_otp_read(uint32_t *val, uint32_t otp)
+{
+	return bsec_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_shadow_read(uint32_t *val, uint32_t otp)
+{
+	return bsec_shadow_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_write(uint32_t val, uint32_t otp)
+{
+	return bsec_write_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_set_sr_lock(uint32_t otp)
+{
+	return bsec_set_sr_lock(otp);
+}
+
+static inline uint32_t stm32_otp_read_sw_lock(uint32_t otp, bool *value)
+{
+	return bsec_read_sw_lock(otp, value);
+}
+
 #endif /* STM32MP1_PRIVATE_H */
diff --git a/plat/st/stm32mp1/plat_ddr.c b/plat/st/stm32mp1/plat_ddr.c
new file mode 100644
index 00000000..a6a0cdb9
--- /dev/null
+++ b/plat/st/stm32mp1/plat_ddr.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <drivers/st/regulator.h>
+#include <drivers/st/stm32mp_ddr.h>
+#include <drivers/st/stm32mp_pmic.h>
+
+/* configure the STPMIC1 regulators on STMicroelectronics boards */
+static int pmic_ddr_power_init(enum ddr_type ddr_type)
+{
+	int status;
+	uint16_t buck3_min_mv __maybe_unused;
+	struct rdev *buck2, *buck3 __maybe_unused, *vref;
+	struct rdev *ldo3 __maybe_unused;
+
+	buck2 = regulator_get_by_name("buck2");
+	if (buck2 == NULL) {
+		return -ENOENT;
+	}
+
+#if STM32MP15
+	ldo3 = regulator_get_by_name("ldo3");
+	if (ldo3 == NULL) {
+		return -ENOENT;
+	}
+#endif
+
+	vref = regulator_get_by_name("vref_ddr");
+	if (vref == NULL) {
+		return -ENOENT;
+	}
+
+	switch (ddr_type) {
+	case STM32MP_DDR3:
+#if STM32MP15
+		status = regulator_set_flag(ldo3, REGUL_SINK_SOURCE);
+		if (status != 0) {
+			return status;
+		}
+#endif
+
+		status = regulator_set_min_voltage(buck2);
+		if (status != 0) {
+			return status;
+		}
+
+		status = regulator_enable(buck2);
+		if (status != 0) {
+			return status;
+		}
+
+		status = regulator_enable(vref);
+		if (status != 0) {
+			return status;
+		}
+
+#if STM32MP15
+		status = regulator_enable(ldo3);
+		if (status != 0) {
+			return status;
+		}
+#endif
+		break;
+
+	case STM32MP_LPDDR2:
+	case STM32MP_LPDDR3:
+#if STM32MP15
+		/*
+		 * Set LDO3 to 1.8V according  BUCK3 voltage
+		 * => bypass mode if BUCK3 = 1.8V
+		 * => normal mode if BUCK3 != 1.8V
+		 */
+		buck3 = regulator_get_by_name("buck3");
+		if (buck3 == NULL) {
+			return -ENOENT;
+		}
+
+		regulator_get_range(buck3, &buck3_min_mv, NULL);
+
+		if (buck3_min_mv != 1800) {
+			status = regulator_set_min_voltage(ldo3);
+			if (status != 0) {
+				return status;
+			}
+		} else {
+			status = regulator_set_flag(ldo3, REGUL_ENABLE_BYPASS);
+			if (status != 0) {
+				return status;
+			}
+		}
+#endif
+
+		status = regulator_set_min_voltage(buck2);
+		if (status != 0) {
+			return status;
+		}
+
+#if STM32MP15
+		status = regulator_enable(ldo3);
+		if (status != 0) {
+			return status;
+		}
+#endif
+
+		status = regulator_enable(buck2);
+		if (status != 0) {
+			return status;
+		}
+
+		status = regulator_enable(vref);
+		if (status != 0) {
+			return status;
+		}
+		break;
+
+	default:
+		break;
+	};
+
+	return 0;
+}
+
+int stm32mp_board_ddr_power_init(enum ddr_type ddr_type)
+{
+	if (dt_pmic_status() > 0) {
+		return pmic_ddr_power_init(ddr_type);
+	}
+
+	return 0;
+}
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index ddc52892..3d377389 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -1,9 +1,13 @@
 #
-# Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# Extra partitions used to find FIP, contains:
+# metadata (2) and the FIP partitions (default is 2).
+STM32_EXTRA_PARTS	:=	4
+
 include plat/st/common/common.mk
 
 ARM_CORTEX_A7		:=	yes
@@ -60,11 +64,6 @@ STM32MP_DDR_32BIT_INTERFACE:=	1
 # STM32 image header version v1.0
 STM32_HEADER_VERSION_MAJOR:=	1
 STM32_HEADER_VERSION_MINOR:=	0
-
-# Add OP-TEE reserved shared memory area in mapping
-STM32MP15_OPTEE_RSV_SHM	:=	0
-$(eval $(call add_defines,STM32MP15_OPTEE_RSV_SHM))
-
 STM32MP_CRYPTO_ROM_LIB :=	1
 
 # Decryption support
@@ -85,25 +84,6 @@ endif
 WORKAROUND_CVE_2017_5715:=	0
 WORKAROUND_CVE_2022_23960:=	0
 
-# Number of TF-A copies in the device
-STM32_TF_A_COPIES		:=	2
-
-# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
-# such as metadata (2) to find all the FIP partitions (default is 2).
-PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + 4)))
-
-ifeq (${PSA_FWU_SUPPORT},1)
-# Number of banks of updatable firmware
-NR_OF_FW_BANKS			:=	2
-NR_OF_IMAGES_IN_FW_BANK		:=	1
-
-FWU_MAX_PART = $(shell echo $$(($(STM32_TF_A_COPIES) + 2 + $(NR_OF_FW_BANKS))))
-ifeq ($(shell test $(FWU_MAX_PART) -gt $(PLAT_PARTITION_MAX_ENTRIES); echo $$?),0)
-$(error "Required partition number is $(FWU_MAX_PART) where PLAT_PARTITION_MAX_ENTRIES is only \
-$(PLAT_PARTITION_MAX_ENTRIES)")
-endif
-endif
-
 ifeq ($(STM32MP13),1)
 STM32_HASH_VER		:=	4
 STM32_RNG_VER		:=	4
@@ -233,10 +213,6 @@ endif
 BL2_SOURCES		+=	plat/st/stm32mp1/plat_bl2_mem_params_desc.c		\
 				plat/st/stm32mp1/stm32mp1_fconf_firewall.c
 
-ifeq (${PSA_FWU_SUPPORT},1)
-include drivers/fwu/fwu.mk
-endif
-
 BL2_SOURCES		+=	drivers/st/crypto/stm32_hash.c				\
 				plat/st/stm32mp1/bl2_plat_setup.c
 
@@ -277,13 +253,15 @@ endif
 BL2_SOURCES		+=	drivers/st/ddr/stm32mp1_ddr.c				\
 				drivers/st/ddr/stm32mp1_ram.c
 
+BL2_SOURCES		+=	plat/st/stm32mp1/plat_ddr.c
+
 ifeq ($(AARCH32_SP),sp_min)
 # Create DTB file for BL32
-${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | ${BUILD_PLAT} fdt_dirs
-	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
-	@echo '#include "${BL32_DTSI}"' >> $@
+${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | $$(@D)/
+	$(q)echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	$(q)echo '#include "${BL32_DTSI}"' >> $@
 
-${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts
+${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts | $$(@D)/
 endif
 
 include plat/st/common/common_rules.mk
diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c
index 1fb44b48..7cc00138 100644
--- a/plat/st/stm32mp1/services/bsec_svc.c
+++ b/plat/st/stm32mp1/services/bsec_svc.c
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2016-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <platform_def.h>
 
 #include <common/debug.h>
 #include <drivers/st/bsec.h>
 #include <drivers/st/bsec2_reg.h>
 
+#include <platform_def.h>
 #include <stm32mp1_smc.h>
 
 #include "bsec_svc.h"
@@ -39,12 +39,7 @@ uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3,
 			break;
 		}
 
-		result = bsec_shadow_register(x2);
-		if (result != BSEC_OK) {
-			break;
-		}
-
-		result = bsec_read_otp(ret_otp_value, x2);
+		result = bsec_shadow_read_otp(ret_otp_value, x2);
 		if (result != BSEC_OK) {
 			break;
 		}
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index b46f4af4..7bfe6ba5 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -116,8 +116,6 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
 	uintptr_t dt_addr = arg1;
 
-	stm32mp_setup_early_console();
-
 	/* Imprecise aborts can be masked in NonSecure */
 	write_scr(read_scr() | SCR_AW_BIT);
 
@@ -182,6 +180,9 @@ void sp_min_platform_setup(void)
 
 	stm32mp_gic_init();
 
+	/* Disable MCU subsystem protection */
+	stm32mp1_clk_mcuss_protect(false);
+
 	if (stm32_iwdg_init() < 0) {
 		panic();
 	}
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 6530957c..824563fe 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,7 @@
 #include <common/tbbr/tbbr_img_def.h>
 #include <drivers/st/stm32mp1_rcc.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
+#include <dt-bindings/gpio/stm32-gpio.h>
 #include <dt-bindings/reset/stm32mp1-resets.h>
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
@@ -186,9 +187,6 @@ enum ddr_type {
 #endif
 #define STM32MP_BL33_MAX_SIZE		U(0x400000)
 
-/* Define maximum page size for NAND devices */
-#define PLATFORM_MTD_MAX_PAGE_SIZE	U(0x1000)
-
 /* Define location for the MTD scratch buffer */
 #if STM32MP13
 #define STM32MP_MTD_BUFFER		(SRAM1_BASE + \
@@ -234,21 +232,7 @@ enum ddr_type {
 #endif
 #define GPIO_BANK_OFFSET		U(0x1000)
 
-/* Bank IDs used in GPIO driver API */
-#define GPIO_BANK_A			U(0)
-#define GPIO_BANK_B			U(1)
-#define GPIO_BANK_C			U(2)
-#define GPIO_BANK_D			U(3)
-#define GPIO_BANK_E			U(4)
-#define GPIO_BANK_F			U(5)
-#define GPIO_BANK_G			U(6)
-#define GPIO_BANK_H			U(7)
-#define GPIO_BANK_I			U(8)
 #if STM32MP15
-#define GPIO_BANK_J			U(9)
-#define GPIO_BANK_K			U(10)
-#define GPIO_BANK_Z			U(25)
-
 #define STM32MP_GPIOZ_PIN_MAX_COUNT	8
 #endif
 
@@ -426,24 +410,24 @@ enum ddr_type {
 #define OTP_MAX_SIZE			(STM32MP1_OTP_MAX_ID + 1U)
 
 /* OTP labels */
-#define CFG0_OTP			"cfg0_otp"
+#define CFG0_OTP			"cfg0-otp"
 #define PART_NUMBER_OTP			"part-number-otp"
 #if STM32MP15
-#define PACKAGE_OTP			"package_otp"
+#define PACKAGE_OTP			"package-otp"
 #endif
-#define HW2_OTP				"hw2_otp"
+#define HW2_OTP				"hw2-otp"
 #if STM32MP13
-#define NAND_OTP			"cfg9_otp"
-#define NAND2_OTP			"cfg10_otp"
+#define NAND_OTP			"cfg9-otp"
+#define NAND2_OTP			"cfg10-otp"
 #endif
 #if STM32MP15
-#define NAND_OTP			"nand_otp"
+#define NAND_OTP			"nand-otp"
 #endif
-#define MONOTONIC_OTP			"monotonic_otp"
-#define UID_OTP				"uid_otp"
-#define PKH_OTP				"pkh_otp"
-#define ENCKEY_OTP			"enckey_otp"
-#define BOARD_ID_OTP			"board_id"
+#define MONOTONIC_OTP			"monotonic-otp"
+#define UID_OTP				"uid-otp"
+#define PKH_OTP				"pkh-otp"
+#define ENCKEY_OTP			"oem-enc-key"
+#define BOARD_ID_OTP			"board-id"
 
 /* OTP mask */
 /* CFG0 */
@@ -636,6 +620,11 @@ static inline uintptr_t tamp_bkpr(uint32_t idx)
 /* 2 FIXED */
 #define PLAT_NB_FIXED_REGUS		U(2)
 
+/*******************************************************************************
+ * STM32MP1 CLOCKS
+ ******************************************************************************/
+#define PLL1_NOMINAL_FREQ_IN_KHZ	U(650000) /* 650MHz */
+
 /*******************************************************************************
  * Device Tree defines
  ******************************************************************************/
diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h
index e37e2e65..165f1523 100644
--- a/plat/st/stm32mp1/stm32mp1_fip_def.h
+++ b/plat/st/stm32mp1/stm32mp1_fip_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,13 +7,7 @@
 #ifndef STM32MP1_FIP_DEF_H
 #define STM32MP1_FIP_DEF_H
 
-#if STM32MP15_OPTEE_RSV_SHM
-#define STM32MP_DDR_S_SIZE		U(0x01E00000)	/* 30 MB */
-#define STM32MP_DDR_SHMEM_SIZE		U(0x00200000)	/* 2 MB */
-#else
 #define STM32MP_DDR_S_SIZE		U(0x02000000)	/* 32 MB */
-#define STM32MP_DDR_SHMEM_SIZE		U(0)		/* empty */
-#endif
 
 #if TRUSTED_BOARD_BOOT && !STM32MP_USE_EXTERNAL_HEAP
 #if STM32MP15
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
index ff2218fd..97e1ac61 100644
--- a/plat/st/stm32mp1/stm32mp1_pm.c
+++ b/plat/st/stm32mp1/stm32mp1_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <drivers/arm/gic_common.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/clk.h>
+#include <drivers/st/stm32mp_reset.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
@@ -149,13 +150,7 @@ static void __dead2 stm32_system_off(void)
 
 static void __dead2 stm32_system_reset(void)
 {
-	mmio_setbits_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR,
-			RCC_MP_GRSTCSETR_MPSYSRST);
-
-	/* Loop in case system reset is not immediately caught */
-	for ( ; ; ) {
-		;
-	}
+	stm32mp_system_reset();
 }
 
 static int stm32_validate_power_state(unsigned int power_state,
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index ea35055a..45446dc6 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,10 +29,6 @@
  * (so it should be in Zone 2).
  */
 #define TAMP_BOOT_FWU_INFO_REG_ID	U(10)
-#define TAMP_BOOT_FWU_INFO_IDX_MSK	GENMASK(3, 0)
-#define TAMP_BOOT_FWU_INFO_IDX_OFF	U(0)
-#define TAMP_BOOT_FWU_INFO_CNT_MSK	GENMASK(7, 4)
-#define TAMP_BOOT_FWU_INFO_CNT_OFF	U(4)
 
 #if defined(IMAGE_BL2)
 #define MAP_SEC_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
@@ -115,14 +111,14 @@ void configure_mmu(void)
 uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
 {
 #if STM32MP13
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+	assert(bank <= GPIO_BANK_I);
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return GPIOZ_BASE;
 	}
 
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+	assert(bank <= GPIO_BANK_K);
 #endif
 
 	return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
@@ -131,14 +127,14 @@ uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
 uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
 {
 #if STM32MP13
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+	assert(bank <= GPIO_BANK_I);
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return 0;
 	}
 
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+	assert(bank <= GPIO_BANK_K);
 #endif
 
 	return bank * GPIO_BANK_OFFSET;
@@ -161,14 +157,14 @@ bool stm32_gpio_is_secure_at_reset(unsigned int bank)
 unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
 {
 #if STM32MP13
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
+	assert(bank <= GPIO_BANK_I);
 #endif
 #if STM32MP15
 	if (bank == GPIO_BANK_Z) {
 		return GPIOZ;
 	}
 
-	assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
+	assert(bank <= GPIO_BANK_K);
 #endif
 
 	return GPIOA + (bank - GPIO_BANK_A);
@@ -284,7 +280,7 @@ void stm32mp1_deconfigure_uart_pins(void)
 uint32_t stm32mp_get_chip_version(void)
 {
 #if STM32MP13
-	return stm32mp1_syscfg_get_chip_version();
+	return stm32mp_syscfg_get_chip_version();
 #endif
 #if STM32MP15
 	uint32_t version = 0U;
@@ -301,7 +297,7 @@ uint32_t stm32mp_get_chip_version(void)
 uint32_t stm32mp_get_chip_dev_id(void)
 {
 #if STM32MP13
-	return stm32mp1_syscfg_get_chip_dev_id();
+	return stm32mp_syscfg_get_chip_dev_id();
 #endif
 #if STM32MP15
 	uint32_t dev_id;
@@ -531,12 +527,12 @@ bool stm32mp_is_single_core(void)
 }
 
 /* Return true when device is in closed state */
-bool stm32mp_is_closed_device(void)
+uint32_t stm32mp_check_closed_device(void)
 {
 	uint32_t value;
 
 	if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
-		return true;
+		return STM32MP_CHIP_SEC_CLOSED;
 	}
 
 #if STM32MP13
@@ -544,17 +540,22 @@ bool stm32mp_is_closed_device(void)
 
 	switch (value) {
 	case CFG0_OPEN_DEVICE:
-		return false;
+		return STM32MP_CHIP_SEC_OPEN;
 	case CFG0_CLOSED_DEVICE:
 	case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
 	case CFG0_CLOSED_DEVICE_NO_JTAG:
-		return true;
+		return STM32MP_CHIP_SEC_CLOSED;
 	default:
 		panic();
 	}
 #endif
 #if STM32MP15
-	return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
+	if ((value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE) {
+		return STM32MP_CHIP_SEC_CLOSED;
+	} else {
+		return STM32MP_CHIP_SEC_OPEN;
+	}
+
 #endif
 }
 
@@ -663,50 +664,20 @@ uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
 }
 #endif
 
-uintptr_t stm32_get_bkpr_boot_mode_addr(void)
-{
-	return tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
-}
-
-#if PSA_FWU_SUPPORT
-void stm32mp1_fwu_set_boot_idx(void)
+bool stm32mp_is_wakeup_from_standby(void)
 {
-	clk_enable(RTCAPB);
-	mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
-			   TAMP_BOOT_FWU_INFO_IDX_MSK,
-			   (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
-			   TAMP_BOOT_FWU_INFO_IDX_MSK);
-	clk_disable(RTCAPB);
+	/* TODO add source code to determine if platform is waking up from standby mode */
+	return false;
 }
 
-uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
+uintptr_t stm32_get_bkpr_boot_mode_addr(void)
 {
-	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
-	uint32_t try_cnt;
-
-	clk_enable(RTCAPB);
-	try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
-		TAMP_BOOT_FWU_INFO_CNT_OFF;
-
-	assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
-
-	if (try_cnt != 0U) {
-		mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
-				   (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
-	}
-	clk_disable(RTCAPB);
-
-	return try_cnt;
+	return tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
 }
 
-void stm32_set_max_fwu_trial_boot_cnt(void)
+#if PSA_FWU_SUPPORT
+uintptr_t stm32_get_bkpr_fwu_info_addr(void)
 {
-	uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
-
-	clk_enable(RTCAPB);
-	mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
-			   (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
-			   TAMP_BOOT_FWU_INFO_CNT_MSK);
-	clk_disable(RTCAPB);
+	return tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
 }
 #endif /* PSA_FWU_SUPPORT */
diff --git a/plat/st/stm32mp1/stm32mp1_syscfg.c b/plat/st/stm32mp1/stm32mp1_syscfg.c
index 75dd7093..199bdc9c 100644
--- a/plat/st/stm32mp1/stm32mp1_syscfg.c
+++ b/plat/st/stm32mp1/stm32mp1_syscfg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -261,7 +261,7 @@ static void enable_high_speed_mode_low_voltage(void)
 #endif
 }
 
-static void stm32mp1_syscfg_set_hslv(void)
+static void stm32mp_syscfg_set_hslv(void)
 {
 	uint32_t otp_value;
 	uint32_t vdd_voltage;
@@ -310,7 +310,7 @@ static void stm32mp1_syscfg_set_hslv(void)
 	}
 }
 
-void stm32mp1_syscfg_init(void)
+void stm32mp_syscfg_init(void)
 {
 #if STM32MP15
 	uint32_t bootr;
@@ -328,12 +328,12 @@ void stm32mp1_syscfg_init(void)
 			   bootr << SYSCFG_BOOTR_BOOTPD_SHIFT);
 #endif
 
-	stm32mp1_syscfg_set_hslv();
+	stm32mp_syscfg_set_hslv();
 
-	stm32mp1_syscfg_enable_io_compensation_start();
+	stm32mp_syscfg_enable_io_compensation_start();
 }
 
-void stm32mp1_syscfg_enable_io_compensation_start(void)
+void stm32mp_syscfg_enable_io_compensation_start(void)
 {
 	/*
 	 * Activate automatic I/O compensation.
@@ -353,7 +353,7 @@ void stm32mp1_syscfg_enable_io_compensation_start(void)
 #endif
 }
 
-void stm32mp1_syscfg_enable_io_compensation_finish(void)
+void stm32mp_syscfg_enable_io_compensation_finish(void)
 {
 	enable_io_comp_cell_finish(SYSCFG_CMPCR);
 #if STM32MP13
@@ -362,7 +362,7 @@ void stm32mp1_syscfg_enable_io_compensation_finish(void)
 #endif
 }
 
-void stm32mp1_syscfg_disable_io_compensation(void)
+void stm32mp_syscfg_disable_io_compensation(void)
 {
 	clk_enable(SYSCFG);
 
@@ -385,7 +385,7 @@ void stm32mp1_syscfg_disable_io_compensation(void)
  * @brief  Get silicon revision from SYSCFG registers.
  * @retval chip version (REV_ID).
  */
-uint32_t stm32mp1_syscfg_get_chip_version(void)
+uint32_t stm32mp_syscfg_get_chip_version(void)
 {
 	return (mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) &
 		SYSCFG_IDC_REV_ID_MASK) >> SYSCFG_IDC_REV_ID_SHIFT;
@@ -395,18 +395,18 @@ uint32_t stm32mp1_syscfg_get_chip_version(void)
  * @brief  Get device ID from SYSCFG registers.
  * @retval device ID (DEV_ID).
  */
-uint32_t stm32mp1_syscfg_get_chip_dev_id(void)
+uint32_t stm32mp_syscfg_get_chip_dev_id(void)
 {
 	return mmio_read_32(SYSCFG_BASE + SYSCFG_IDC) & SYSCFG_IDC_DEV_ID_MASK;
 }
 
 #if STM32MP13
-void stm32mp1_syscfg_boot_mode_enable(void)
+void stm32mp_syscfg_boot_mode_enable(void)
 {
 	mmio_setbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
 }
 
-void stm32mp1_syscfg_boot_mode_disable(void)
+void stm32mp_syscfg_boot_mode_disable(void)
 {
 	mmio_clrbits_32(SYSCFG_BASE + SYSCFG_BOOTCR, SYSCFG_BOOTCR_BMEN);
 }
diff --git a/plat/st/stm32mp2/aarch64/stm32mp2_helper.S b/plat/st/stm32mp2/aarch64/stm32mp2_helper.S
index 66333ad7..0df3e088 100644
--- a/plat/st/stm32mp2/aarch64/stm32mp2_helper.S
+++ b/plat/st/stm32mp2/aarch64/stm32mp2_helper.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 	.globl	platform_mem_init
 	.globl	plat_secondary_cold_boot_setup
 	.globl	plat_is_my_cpu_primary
+	.globl	plat_my_core_pos
 	.globl	plat_crash_console_init
 	.globl	plat_crash_console_flush
 	.globl	plat_crash_console_putc
@@ -32,9 +33,14 @@ endfunc platform_mem_init
 	 */
 func plat_secondary_cold_boot_setup
 	dsb	sy
+1:
 	wfi
-	/* This shouldn't be reached */
-	b	.
+	/*
+	 * This shouldn't be reached, but when a debugger halts the
+	 * secondary core it causes exit from wfi.
+	 * Put back the core in wfi.
+	 */
+	b	1b
 endfunc plat_secondary_cold_boot_setup
 
 	/* ----------------------------------------------
@@ -50,6 +56,31 @@ func plat_is_my_cpu_primary
 	ret
 endfunc plat_is_my_cpu_primary
 
+	/* -----------------------------------------------------------
+	 *  unsigned int plat_stm32mp_get_core_pos(u_register_t mpidr)
+	 *  Helper function to calculate the core position.
+	 *  With this function: CorePos = (ClusterId * 4) +
+	 *  				  CoreId
+	 * -----------------------------------------------------------
+	 */
+func plat_stm32mp_get_core_pos
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+endfunc plat_stm32mp_get_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_stm32mp_get_core_pos()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_stm32mp_get_core_pos
+endfunc plat_my_core_pos
+
 	/* ---------------------------------------------
 	 * int plat_crash_console_init(void)
 	 *
@@ -65,13 +96,13 @@ func plat_crash_console_init
 	str	x0, [x1]
 1:
 	ldr	x0, [x1]
-	ands	x2, x0, x2
+	tst	x0, #DEBUG_UART_RST_BIT
 	beq	1b
-	bic	x2, x2, #DEBUG_UART_RST_BIT
-	str	x2, [x1]
+	bic	x0, x0, #DEBUG_UART_RST_BIT
+	str	x0, [x1]
 2:
 	ldr	x0, [x1]
-	ands	x2, x0, x2
+	tst	x0, #DEBUG_UART_RST_BIT
 	bne	2b
 	/* Enable GPIOs for UART TX */
 	mov_imm	x1, (RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 08057568..2fabc418 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -1,26 +1,394 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <cdefs.h>
+#include <errno.h>
 #include <stdint.h>
 
+#include <common/debug.h>
+#include <common/desc_image_load.h>
+#include <drivers/clk.h>
+#include <drivers/mmc.h>
+#include <drivers/st/regulator_fixed.h>
+#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp2_ram.h>
+#include <drivers/st/stm32mp_pmic2.h>
+#include <drivers/st/stm32mp_risab_regs.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/mmio.h>
+#include <lib/optee_utils.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
 #include <stm32mp_common.h>
+#include <stm32mp_dt.h>
+
+#define BOOT_CTX_ADDR	0x0e000020UL
+
+static void print_reset_reason(void)
+{
+	uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_C1BOOTRSTSCLRR);
+
+	if (rstsr == 0U) {
+		WARN("Reset reason unknown\n");
+		return;
+	}
+
+	INFO("Reset reason (0x%x):\n", rstsr);
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_PADRSTF) == 0U) {
+		if ((rstsr & RCC_C1BOOTRSTSCLRR_STBYC1RSTF) != 0U) {
+			INFO("System exits from Standby for CA35\n");
+			return;
+		}
+
+		if ((rstsr & RCC_C1BOOTRSTSCLRR_D1STBYRSTF) != 0U) {
+			INFO("D1 domain exits from DStandby\n");
+			return;
+		}
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_PORRSTF) != 0U) {
+		INFO("  Power-on Reset (rst_por)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_BORRSTF) != 0U) {
+		INFO("  Brownout Reset (rst_bor)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSSETR_SYSC2RSTF) != 0U) {
+		INFO("  System reset (SYSRST) by M33\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSSETR_SYSC1RSTF) != 0U) {
+		INFO("  System reset (SYSRST) by A35\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_HCSSRSTF) != 0U) {
+		INFO("  Clock failure on HSE\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG1SYSRSTF) != 0U) {
+		INFO("  IWDG1 system reset (rst_iwdg1)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG2SYSRSTF) != 0U) {
+		INFO("  IWDG2 system reset (rst_iwdg2)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG3SYSRSTF) != 0U) {
+		INFO("  IWDG3 system reset (rst_iwdg3)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG4SYSRSTF) != 0U) {
+		INFO("  IWDG4 system reset (rst_iwdg4)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_IWDG5SYSRSTF) != 0U) {
+		INFO("  IWDG5 system reset (rst_iwdg5)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_C1P1RSTF) != 0U) {
+		INFO("  A35 processor core 1 reset\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_PADRSTF) != 0U) {
+		INFO("  Pad Reset from NRST\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_VCORERSTF) != 0U) {
+		INFO("  Reset due to a failure of VDD_CORE\n");
+		return;
+	}
+
+	if ((rstsr & RCC_C1BOOTRSTSCLRR_C1RSTF) != 0U) {
+		INFO("  A35 processor reset\n");
+		return;
+	}
+
+	ERROR("  Unidentified reset reason\n");
+}
 
 void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
 				  u_register_t arg1 __unused,
 				  u_register_t arg2 __unused,
 				  u_register_t arg3 __unused)
 {
-	stm32mp_setup_early_console();
+	stm32mp_save_boot_ctx_address(BOOT_CTX_ADDR);
 }
 
 void bl2_platform_setup(void)
 {
+	int ret;
+
+	ret = stm32mp2_ddr_probe();
+	if (ret != 0) {
+		ERROR("DDR probe: error %d\n", ret);
+		panic();
+	}
+
+	/* Map DDR for binary load, now with cacheable attribute */
+	ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE,
+				      STM32MP_DDR_MAX_SIZE, MT_MEMORY | MT_RW | MT_SECURE);
+	if (ret < 0) {
+		ERROR("DDR mapping: error %d\n", ret);
+		panic();
+	}
+}
+
+static void reset_backup_domain(void)
+{
+	uintptr_t pwr_base = stm32mp_pwr_base();
+	uintptr_t rcc_base = stm32mp_rcc_base();
+
+	/*
+	 * Disable the backup domain write protection.
+	 * The protection is enable at each reset by hardware
+	 * and must be disabled by software.
+	 */
+	mmio_setbits_32(pwr_base + PWR_BDCR1, PWR_BDCR1_DBD3P);
+
+	while ((mmio_read_32(pwr_base + PWR_BDCR1) & PWR_BDCR1_DBD3P) == 0U) {
+		;
+	}
+
+	/* Reset backup domain on cold boot cases */
+	if ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_RTCCKEN) == 0U) {
+		mmio_setbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST);
+
+		while ((mmio_read_32(rcc_base + RCC_BDCR) & RCC_BDCR_VSWRST) == 0U) {
+			;
+		}
+
+		mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST);
+	}
 }
 
 void bl2_el3_plat_arch_setup(void)
 {
+	const char *board_model;
+	boot_api_context_t *boot_context =
+		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
+
+	if (stm32_otp_probe() != 0U) {
+		EARLY_ERROR("OTP probe failed\n");
+		panic();
+	}
+
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+
+	configure_mmu();
+
+	if (dt_open_and_check(STM32MP_DTB_BASE) < 0) {
+		panic();
+	}
+
+	reset_backup_domain();
+
+	/*
+	 * Initialize DDR sub-system clock. This needs to be done before enabling DDR PLL (PLL2),
+	 * and so before stm32mp2_clk_init().
+	 */
+	ddr_sub_system_clk_init();
+
+	if (stm32mp2_clk_init() < 0) {
+		panic();
+	}
+
+#if STM32MP_DDR_FIP_IO_STORAGE
+	/*
+	 * RISAB3 setup (dedicated for SRAM1)
+	 *
+	 * Allow secure read/writes data accesses to non-secure
+	 * blocks or pages, all RISAB registers are writable.
+	 * DDR firmwares are saved there before being loaded in DDRPHY memory.
+	 */
+	mmio_write_32(RISAB3_BASE + RISAB_CR, RISAB_CR_SRWIAD);
+#endif
+
+	stm32_save_boot_info(boot_context);
+
+	if (stm32mp_uart_console_setup() != 0) {
+		goto skip_console_init;
+	}
+
+	stm32mp_print_cpuinfo();
+
+	board_model = dt_get_board_model();
+	if (board_model != NULL) {
+		NOTICE("Model: %s\n", board_model);
+	}
+
+	stm32mp_print_boardinfo();
+
+	print_reset_reason();
+
+skip_console_init:
+	if (fixed_regulator_register() != 0) {
+		panic();
+	}
+
+	if (dt_pmic_status() > 0) {
+		initialize_pmic();
+	}
+
+	fconf_populate("TB_FW", STM32MP_DTB_BASE);
+
+	/*
+	 * RISAB5 setup (dedicated for RETRAM)
+	 *
+	 * Allow secure read/writes data accesses to non-secure
+	 * blocks or pages, all RISAB registers are writable.
+	 * DDR retention registers are saved there and restored
+	 * when exiting standby low power state.
+	 */
+	mmio_write_32(RISAB5_BASE + RISAB_CR, RISAB_CR_SRWIAD);
+
+	stm32mp_io_setup();
+}
+
+/*******************************************************************************
+ * This function can be used by the platforms to update/use image
+ * information for given `image_id`.
+ ******************************************************************************/
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	int err = 0;
+	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+	bl_mem_params_node_t *pager_mem_params;
+	const struct dyn_cfg_dtb_info_t *config_info;
+	unsigned int i;
+	const unsigned int image_ids[] = {
+		BL31_IMAGE_ID,
+		SOC_FW_CONFIG_ID,
+		BL32_IMAGE_ID,
+		BL33_IMAGE_ID,
+		HW_CONFIG_ID,
+	};
+
+	assert(bl_mem_params != NULL);
+
+#if STM32MP_SDMMC || STM32MP_EMMC
+	/*
+	 * Invalidate remaining data read from MMC but not flushed by load_image_flush().
+	 * We take the worst case which is 2 MMC blocks.
+	 */
+	if ((image_id != FW_CONFIG_ID) &&
+	    ((bl_mem_params->image_info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U)) {
+		inv_dcache_range(bl_mem_params->image_info.image_base +
+				 bl_mem_params->image_info.image_size,
+				 2U * MMC_BLOCK_SIZE);
+	}
+#endif /* STM32MP_SDMMC || STM32MP_EMMC */
+
+	switch (image_id) {
+	case FW_CONFIG_ID:
+		/* Set global DTB info for fixed fw_config information */
+		set_config_info(STM32MP_FW_CONFIG_BASE, ~0UL, STM32MP_FW_CONFIG_MAX_SIZE,
+				FW_CONFIG_ID);
+		fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE);
+
+		/* Iterate through all the fw config IDs */
+		for (i = 0U; i < ARRAY_SIZE(image_ids); i++) {
+			bl_mem_params = get_bl_mem_params_node(image_ids[i]);
+			assert(bl_mem_params != NULL);
+
+			config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_ids[i]);
+			if (config_info == NULL) {
+				continue;
+			}
+
+			bl_mem_params->image_info.image_base = config_info->config_addr;
+			bl_mem_params->image_info.image_max_size = config_info->config_max_size;
+
+			bl_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+
+			switch (image_ids[i]) {
+			case BL31_IMAGE_ID:
+				bl_mem_params->ep_info.pc = config_info->config_addr;
+				break;
+
+			case BL32_IMAGE_ID:
+				bl_mem_params->ep_info.pc = config_info->config_addr;
+
+				/* In case of OPTEE, initialize address space with tos_fw addr */
+				pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+				if (pager_mem_params != NULL) {
+					pager_mem_params->image_info.image_base =
+						config_info->config_addr;
+					pager_mem_params->image_info.image_max_size =
+						config_info->config_max_size;
+				}
+				break;
+
+			case BL33_IMAGE_ID:
+				bl_mem_params->ep_info.pc = config_info->config_addr;
+				break;
+
+			case HW_CONFIG_ID:
+			case SOC_FW_CONFIG_ID:
+				break;
+
+			default:
+				return -EINVAL;
+			}
+		}
+
+		/*
+		 * After this step, the BL2 device tree area will be overwritten
+		 * with BL31 binary, no other data should be read from BL2 DT.
+		 */
+
+		break;
+
+	case BL32_IMAGE_ID:
+		if ((bl_mem_params->image_info.image_base != 0UL) &&
+		    (optee_header_is_valid(bl_mem_params->image_info.image_base))) {
+			/* BL32 is OP-TEE header */
+			bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base;
+			pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+			assert(pager_mem_params != NULL);
+
+			err = parse_optee_header(&bl_mem_params->ep_info,
+						 &pager_mem_params->image_info,
+						 NULL);
+			if (err != 0) {
+				ERROR("OPTEE header parse error.\n");
+				panic();
+			}
+
+			/* Set optee boot info from parsed header data */
+			bl_mem_params->ep_info.args.arg0 = 0U; /* Unused */
+			bl_mem_params->ep_info.args.arg1 = 0U; /* Unused */
+			bl_mem_params->ep_info.args.arg2 = 0U; /* No DT supported */
+		}
+		break;
+
+	case BL33_IMAGE_ID:
+	default:
+		/* Do nothing in default case */
+		break;
+	}
+
+	return err;
 }
diff --git a/plat/st/stm32mp2/bl31_plat_setup.c b/plat/st/stm32mp2/bl31_plat_setup.c
new file mode 100644
index 00000000..a7a3721b
--- /dev/null
+++ b/plat/st/stm32mp2/bl31_plat_setup.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common/bl_common.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/st/stm32_console.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	bl_params_t *params_from_bl2;
+	int ret;
+
+	/*
+	 * Invalidate remaining data from second half of SYSRAM (used by BL2) as this area will
+	 * be later used as non-secure.
+	 */
+	inv_dcache_range(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+			 STM32MP_SYSRAM_SIZE / 2U);
+
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+
+	/*
+	 * Map soc_fw_config device tree with secure property, i.e. default region.
+	 * DDR region definitions will be finalized at BL32 level.
+	 */
+	mmap_add_region(arg1, arg1, STM32MP_SOC_FW_CONFIG_MAX_SIZE, MT_RO_DATA | MT_SECURE);
+
+#if USE_COHERENT_MEM
+	/* Map coherent memory */
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
+	configure_mmu();
+
+	ret = dt_open_and_check(arg1);
+	if (ret < 0) {
+		EARLY_ERROR("%s: failed to open DT (%d)\n", __func__, ret);
+		panic();
+	}
+
+	ret = stm32mp2_clk_init();
+	if (ret < 0) {
+		EARLY_ERROR("%s: failed init clocks (%d)\n", __func__, ret);
+		panic();
+	}
+
+	generic_delay_timer_init();
+
+	(void)stm32mp_uart_console_setup();
+
+	/*
+	 * Map upper SYSRAM where bl_params_t are stored in BL2
+	 */
+	ret = mmap_add_dynamic_region(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+				      STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+				      STM32MP_SYSRAM_SIZE / 2U, MT_RO_DATA | MT_SECURE);
+	if (ret < 0) {
+		ERROR("BL2 params area mapping: %d\n", ret);
+		panic();
+	}
+
+	assert(arg0 != 0UL);
+	params_from_bl2 = (bl_params_t *)arg0;
+	assert(params_from_bl2 != NULL);
+	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
+	assert(params_from_bl2->h.version >= VERSION_2);
+
+	bl_params_node_t *bl_params = params_from_bl2->head;
+
+	while (bl_params != NULL) {
+		/*
+		 * Copy BL33 entry point information.
+		 * They are stored in Secure RAM, in BL2's address space.
+		 */
+		if (bl_params->image_id == BL33_IMAGE_ID) {
+			bl33_image_ep_info = *bl_params->ep_info;
+			/*
+			 *  Check if hw_configuration is given to BL32 and
+			 *  share it to BL33
+			 */
+			if (arg2 != 0U) {
+				bl33_image_ep_info.args.arg0 = 0U;
+				bl33_image_ep_info.args.arg1 = 0U;
+				bl33_image_ep_info.args.arg2 = arg2;
+			}
+		}
+
+		if (bl_params->image_id == BL32_IMAGE_ID) {
+			bl32_image_ep_info = *bl_params->ep_info;
+
+			if (arg2 != 0U) {
+				bl32_image_ep_info.args.arg3 = arg2;
+			}
+		}
+
+		bl_params = bl_params->next_params_info;
+	}
+
+	ret = mmap_remove_dynamic_region(STM32MP_SYSRAM_BASE + STM32MP_SYSRAM_SIZE / 2U,
+					 STM32MP_SYSRAM_SIZE / 2U);
+	if (ret < 0) {
+		ERROR("BL2 params area unmapping: %d\n", ret);
+		panic();
+	}
+}
+
+void bl31_plat_arch_setup(void)
+{
+	stm32mp_gic_init();
+}
+
+void bl31_platform_setup(void)
+{
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+	entry_point_info_t *next_image_info = NULL;
+
+	assert(sec_state_is_valid(type));
+
+	switch (type) {
+	case NON_SECURE:
+		next_image_info = &bl33_image_ep_info;
+		break;
+
+	case SECURE:
+		next_image_info = &bl32_image_ep_info;
+		break;
+
+	default:
+		break;
+	}
+
+	/* None of the next images on ST platforms can have 0x0 as the entrypoint */
+	if ((next_image_info == NULL) || (next_image_info->pc == 0UL)) {
+		return NULL;
+	}
+
+	return next_image_info;
+}
diff --git a/plat/st/stm32mp2/include/boot_api.h b/plat/st/stm32mp2/include/boot_api.h
index d3bed763..580a65b5 100644
--- a/plat/st/stm32mp2/include/boot_api.h
+++ b/plat/st/stm32mp2/include/boot_api.h
@@ -86,7 +86,7 @@
 /* Image Header related definitions */
 
 /* Definition of header version */
-#define BOOT_API_HEADER_VERSION					0x00020000U
+#define BOOT_API_HEADER_VERSION					0x00020200U
 
 /*
  * Magic number used to detect header in memory
diff --git a/plat/st/stm32mp2/include/plat_tbbr_img_def.h b/plat/st/stm32mp2/include/plat_tbbr_img_def.h
new file mode 100644
index 00000000..830bf88b
--- /dev/null
+++ b/plat/st/stm32mp2/include/plat_tbbr_img_def.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_TBBR_IMG_DEF_H
+#define PLAT_TBBR_IMG_DEF_H
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+/* Undef the existing values */
+#undef BKUP_FWU_METADATA_IMAGE_ID
+#undef FWU_METADATA_IMAGE_ID
+#undef FW_CONFIG_ID
+#undef ENC_IMAGE_ID
+#undef GPT_IMAGE_ID
+#undef NT_FW_CONFIG_ID
+#undef SOC_FW_CONFIG_ID
+#undef TB_FW_CONFIG_ID
+#undef HW_CONFIG_ID
+#undef TRUSTED_BOOT_FW_CERT_ID
+#undef SOC_FW_CONTENT_CERT_ID
+#undef BL32_EXTRA1_IMAGE_ID
+#undef TOS_FW_CONFIG_ID
+
+/* Define the STM32MP2 used ID */
+#define FW_CONFIG_ID			U(1)
+#define HW_CONFIG_ID			U(2)
+#define ENC_IMAGE_ID			U(6)
+#define BL32_EXTRA1_IMAGE_ID		U(8)
+#define FWU_METADATA_IMAGE_ID		U(12)
+#define BKUP_FWU_METADATA_IMAGE_ID	U(13)
+#define TOS_FW_CONFIG_ID		U(16)
+#define NT_FW_CONFIG_ID			U(18)
+#define SOC_FW_CONFIG_ID		U(19)
+#define TB_FW_CONFIG_ID			U(20)
+#define TRUSTED_BOOT_FW_CERT_ID		U(21)
+#define SOC_FW_CONTENT_CERT_ID		U(23)
+#define STM32MP_CONFIG_CERT_ID		U(24)
+#define GPT_IMAGE_ID			U(25)
+
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define DDR_FW_ID			U(26)
+/* Increase the MAX_NUMBER_IDS to match the authentication pool required */
+#define MAX_NUMBER_IDS			U(27)
+
+#else
+/* Increase the MAX_NUMBER_IDS to match the authentication pool required */
+#define MAX_NUMBER_IDS			U(26)
+
+#endif
+
+#endif /* PLAT_TBBR_IMG_DEF_H */
+
diff --git a/plat/st/stm32mp2/include/platform_def.h b/plat/st/stm32mp2/include/platform_def.h
index 404c384f..e720c02c 100644
--- a/plat/st/stm32mp2/include/platform_def.h
+++ b/plat/st/stm32mp2/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 #define PLATFORM_DEF_H
 
 #include <arch.h>
+#include <drivers/arm/gic_common.h>
 #include <lib/utils_def.h>
 #include <plat/common/common_def.h>
 
@@ -32,9 +33,9 @@
 #define PLATFORM_CORE_COUNT		U(2)
 #define PLATFORM_MAX_CPUS_PER_CLUSTER	U(2)
 
-#define PLAT_MAX_PWR_LVL		U(5)
-#define PLAT_MAX_CPU_SUSPEND_PWR_LVL	U(5)
-#define PLAT_NUM_PWR_DOMAINS		U(7)
+#define PLAT_MAX_PWR_LVL		U(1)
+#define PLAT_MIN_SUSPEND_PWR_LVL	U(2)
+#define PLAT_NUM_PWR_DOMAINS		U(6)
 
 /* Local power state for power domains in Run state. */
 #define STM32MP_LOCAL_STATE_RUN		U(0)
@@ -61,6 +62,20 @@
 #define BL2_LIMIT			(STM32MP_BL2_BASE + \
 					 STM32MP_BL2_SIZE)
 
+#define BL2_RO_BASE			STM32MP_BL2_RO_BASE
+#define BL2_RO_LIMIT			(STM32MP_BL2_RO_BASE + \
+					 STM32MP_BL2_RO_SIZE)
+
+#define BL2_RW_BASE			STM32MP_BL2_RW_BASE
+#define BL2_RW_LIMIT			(STM32MP_BL2_RW_BASE + \
+					 STM32MP_BL2_RW_SIZE)
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+#define BL31_BASE			0
+#define BL31_LIMIT			(STM32MP_SEC_SYSRAM_SIZE / 2)
+
 /*******************************************************************************
  * BL33 specific defines.
  ******************************************************************************/
@@ -84,4 +99,59 @@
 #define CACHE_WRITEBACK_SHIFT		6
 #define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
 
+/*
+ * Secure Interrupt: based on the standard ARM mapping
+ */
+#define ARM_IRQ_SEC_PHY_TIMER		U(29)
+
+#define ARM_IRQ_NON_SEC_SGI_0		U(0)
+
+#define ARM_IRQ_SEC_SGI_0		U(8)
+#define ARM_IRQ_SEC_SGI_1		U(9)
+#define ARM_IRQ_SEC_SGI_2		U(10)
+#define ARM_IRQ_SEC_SGI_3		U(11)
+#define ARM_IRQ_SEC_SGI_4		U(12)
+#define ARM_IRQ_SEC_SGI_5		U(13)
+#define ARM_IRQ_SEC_SGI_6		U(14)
+#define ARM_IRQ_SEC_SGI_7		U(15)
+
+/* Platform IRQ Priority */
+#define STM32MP_IRQ_SEC_SPI_PRIO	U(0x10)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLATFORM_G1S_PROPS(grp) \
+	INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_LEVEL),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE)
+
+#define PLATFORM_G0_PROPS(grp) \
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE),	\
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6,		\
+		       GIC_HIGHEST_SEC_PRIORITY,	\
+		       (grp), GIC_INTR_CFG_EDGE)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/st/stm32mp2/include/stm32mp2_private.h b/plat/st/stm32mp2/include/stm32mp2_private.h
new file mode 100644
index 00000000..4bb8c523
--- /dev/null
+++ b/plat/st/stm32mp2/include/stm32mp2_private.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP2_PRIVATE_H
+#define STM32MP2_PRIVATE_H
+
+void configure_mmu(void);
+
+uint32_t stm32mp_syscfg_get_chip_dev_id(void);
+
+/* Get DDRDBG peripheral IO memory base address */
+uintptr_t stm32_ddrdbg_get_base(void);
+
+/* Wrappers for OTP / BSEC functions */
+static inline uint32_t stm32_otp_probe(void)
+{
+	return bsec_probe();
+}
+
+static inline uint32_t stm32_otp_read(uint32_t *val, uint32_t otp)
+{
+	return bsec_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_shadow_read(uint32_t *val, uint32_t otp)
+{
+	return bsec_shadow_read_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_write(uint32_t val, uint32_t otp)
+{
+	return bsec_write_otp(val, otp);
+}
+
+static inline uint32_t stm32_otp_set_sr_lock(uint32_t otp)
+{
+	return bsec_set_sr_lock(otp);
+}
+
+static inline uint32_t stm32_otp_read_sw_lock(uint32_t otp, bool *value)
+{
+	return bsec_read_sw_lock(otp, value);
+}
+
+static inline bool stm32_otp_is_closed_device(void)
+{
+	return bsec_mode_is_closed_device();
+}
+
+#endif /* STM32MP2_PRIVATE_H */
diff --git a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
index 630cc84d..8ca582ec 100644
--- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
@@ -1,10 +1,20 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/bl_common.h>
 #include <common/desc_image_load.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+#if STM32MP_BL33_EL1
+#define BL33_MODE MODE_EL1
+#else
+#define BL33_MODE MODE_EL2
+#endif
 
 /*******************************************************************************
  * Following descriptor provides BL image/ep information that gets used
@@ -15,6 +25,133 @@
  * the next executable image id.
  ******************************************************************************/
 static bl_mem_params_node_t bl2_mem_params_descs[] = {
+#if STM32MP_DDR_FIP_IO_STORAGE
+	/* Fill FW_DDR related information if it exists */
+	{
+		.image_id = DDR_FW_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      0),
+
+		.image_info.image_base = STM32MP_DDR_FW_BASE,
+		.image_info.image_max_size = STM32MP_DDR_FW_MAX_SIZE,
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+#endif
+
+	/* Fill FW_CONFIG related information if it exists */
+	{
+		.image_id = FW_CONFIG_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_PLAT_SETUP),
+
+		.image_info.image_base = STM32MP_FW_CONFIG_BASE,
+		.image_info.image_max_size = STM32MP_FW_CONFIG_MAX_SIZE,
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/* Fill BL31 related information */
+	{
+		.image_id = BL31_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE | EP_FIRST_EXE),
+
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = BL32_IMAGE_ID,
+	},
+
+	/* Fill SoC FW config related information */
+	{
+		.image_id = SOC_FW_CONFIG_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/* Fill BL32 related information */
+	{
+		.image_id = BL32_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+
+	/* Fill BL32 external 1 image related information */
+	{
+		.image_id = BL32_EXTRA1_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/* Fill HW_CONFIG related information if it exists */
+	{
+		.image_id = HW_CONFIG_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, entry_point_info_t,
+				      NON_SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/* Fill BL33 related information */
+	{
+		.image_id = BL33_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      NON_SECURE | EXECUTABLE),
+
+		.ep_info.spsr = SPSR_64(BL33_MODE, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	}
 };
 
 REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/st/stm32mp2/plat_ddr.c b/plat/st/stm32mp2/plat_ddr.c
new file mode 100644
index 00000000..5302e45b
--- /dev/null
+++ b/plat/st/stm32mp2/plat_ddr.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2023-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <common/fdt_wrappers.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/st/regulator.h>
+#include <drivers/st/stm32mp_ddr.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#if STM32MP_DDR3_TYPE
+struct ddr3_supply {
+	struct rdev *vdd;
+	struct rdev *vref;
+	struct rdev *vtt;
+};
+
+static void ddr3_supply_read(void *fdt, int node, struct ddr3_supply *supply)
+{
+	supply->vdd = regulator_get_by_supply_name(fdt, node, "vdd");
+	supply->vref = regulator_get_by_supply_name(fdt, node, "vref");
+	supply->vtt = regulator_get_by_supply_name(fdt, node, "vtt");
+}
+
+static int ddr_power_init(void *fdt, int node)
+{
+	int status;
+	struct ddr3_supply supply;
+
+	ddr3_supply_read(fdt, node, &supply);
+	if ((supply.vdd == NULL) || (supply.vref == NULL) || (supply.vtt == NULL)) {
+		return -ENOENT;
+	}
+
+	/*
+	 * DDR3 power on sequence is:
+	 * enable VREF_DDR, VTT_DDR, VPP_DDR
+	 */
+	status = regulator_set_min_voltage(supply.vdd);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vdd);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vref);
+	if (status != 0) {
+		return status;
+	}
+
+	return regulator_enable(supply.vtt);
+}
+#endif /* STM32MP_DDR3_TYPE */
+
+#if STM32MP_DDR4_TYPE
+struct ddr4_supply {
+	struct rdev *vdd;
+	struct rdev *vref;
+	struct rdev *vtt;
+	struct rdev *vpp;
+};
+
+static void ddr4_supply_read(void *fdt, int node, struct ddr4_supply *supply)
+{
+	supply->vpp = regulator_get_by_supply_name(fdt, node, "vpp");
+	supply->vdd = regulator_get_by_supply_name(fdt, node, "vdd");
+	supply->vref = regulator_get_by_supply_name(fdt, node, "vref");
+	supply->vtt = regulator_get_by_supply_name(fdt, node, "vtt");
+}
+
+static int ddr_power_init(void *fdt, int node)
+{
+	int status;
+	struct ddr4_supply supply;
+
+	ddr4_supply_read(fdt, node, &supply);
+	if ((supply.vpp == NULL) || (supply.vdd == NULL) || (supply.vref == NULL) ||
+	    (supply.vtt == NULL)) {
+		return -ENOENT;
+	}
+
+	/*
+	 * DDR4 power on sequence is:
+	 * enable VPP_DDR
+	 * enable VREF_DDR, VTT_DDR, VPP_DDR
+	 */
+	status = regulator_set_min_voltage(supply.vpp);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_set_min_voltage(supply.vdd);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vpp);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vdd);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vref);
+	if (status != 0) {
+		return status;
+	}
+
+	return regulator_enable(supply.vtt);
+}
+#endif /* STM32MP_DDR4_TYPE */
+
+#if STM32MP_LPDDR4_TYPE
+struct lpddr4_supply {
+	struct rdev *vdd1;
+	struct rdev *vdd2;
+	struct rdev *vddq;
+};
+
+static void lpddr4_supply_read(void *fdt, int node, struct lpddr4_supply *supply)
+{
+	supply->vdd1 = regulator_get_by_supply_name(fdt, node, "vdd1");
+	supply->vdd2 = regulator_get_by_supply_name(fdt, node, "vdd2");
+	supply->vddq = regulator_get_by_supply_name(fdt, node, "vddq");
+}
+
+static int ddr_power_init(void *fdt, int node)
+{
+	int status;
+	struct lpddr4_supply supply;
+
+	lpddr4_supply_read(fdt, node, &supply);
+	if ((supply.vdd1 == NULL) || (supply.vdd2 == NULL) || (supply.vddq == NULL)) {
+		return -ENOENT;
+	}
+
+	/*
+	 * LPDDR4 power on sequence is:
+	 * enable VDD1_DDR
+	 * enable VDD2_DDR
+	 * enable VDDQ_DDR
+	 */
+	status = regulator_set_min_voltage(supply.vdd1);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_set_min_voltage(supply.vdd2);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_set_min_voltage(supply.vddq);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vdd1);
+	if (status != 0) {
+		return status;
+	}
+
+	status = regulator_enable(supply.vdd2);
+	if (status != 0) {
+		return status;
+	}
+
+	return regulator_enable(supply.vddq);
+}
+#endif /* STM32MP_LPDDR4_TYPE */
+
+int stm32mp_board_ddr_power_init(enum ddr_type ddr_type)
+{
+	void *fdt = NULL;
+	int node;
+
+	VERBOSE("DDR power init, ddr_type = %u\n", ddr_type);
+
+#if STM32MP_DDR3_TYPE
+	assert(ddr_type == STM32MP_DDR3);
+#elif STM32MP_DDR4_TYPE
+	assert(ddr_type == STM32MP_DDR4);
+#elif STM32MP_LPDDR4_TYPE
+	assert(ddr_type == STM32MP_LPDDR4);
+#else
+	ERROR("DDR type (%u) not supported\n", ddr_type);
+	panic();
+#endif
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
+	if (node < 0) {
+		ERROR("%s: Cannot read DDR node in DT\n", __func__);
+		return -EINVAL;
+	}
+
+	return ddr_power_init(fdt, node);
+}
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index 6ea4638c..f4616562 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -1,14 +1,28 @@
 #
-# Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# Extra partitions used to find FIP, contains:
+# metadata (2) and fsbl-m (2) and the FIP partitions (default is 2).
+STM32_EXTRA_PARTS		:=	6
+
 include plat/st/common/common.mk
 
 CRASH_REPORTING			:=	1
 ENABLE_PIE			:=	1
 PROGRAMMABLE_RESET_ADDRESS	:=	1
+BL2_IN_XIP_MEM			:=	1
+
+STM32MP_BL33_EL1		?=	1
+ifeq ($(STM32MP_BL33_EL1),1)
+INIT_UNUSED_NS_EL2		:=	1
+endif
+
+# Disable features unsupported in ARMv8.0
+ENABLE_SPE_FOR_NS		:=	0
+ENABLE_SVE_FOR_NS		:=	0
 
 # Default Device tree
 DTB_FILE_NAME			?=	stm32mp257f-ev1.dtb
@@ -19,34 +33,193 @@ STM32MP25			:=	1
 STM32_HEADER_VERSION_MAJOR	:=	2
 STM32_HEADER_VERSION_MINOR	:=	2
 
-# Number of TF-A copies in the device
-STM32_TF_A_COPIES		:=	2
+# Set load address for serial boot devices
+DWL_BUFFER_BASE 		?=	0x87000000
+
+# DDR types
+STM32MP_DDR3_TYPE		?=	0
+STM32MP_DDR4_TYPE		?=	0
+STM32MP_LPDDR4_TYPE		?=	0
+ifeq (${STM32MP_DDR3_TYPE},1)
+DDR_TYPE			:=	ddr3
+endif
+ifeq (${STM32MP_DDR4_TYPE},1)
+DDR_TYPE			:=	ddr4
+endif
+ifeq (${STM32MP_LPDDR4_TYPE},1)
+DDR_TYPE			:=	lpddr4
+endif
 
-# PLAT_PARTITION_MAX_ENTRIES must take care of STM32_TF-A_COPIES and other partitions
-# such as metadata (2) and fsbl-m (2) to find all the FIP partitions (default is 2).
-PLAT_PARTITION_MAX_ENTRIES	:=	$(shell echo $$(($(STM32_TF_A_COPIES) + 6)))
+# DDR features
+STM32MP_DDR_DUAL_AXI_PORT	:=	1
+STM32MP_DDR_FIP_IO_STORAGE	:=	1
 
 # Device tree
 BL2_DTSI			:=	stm32mp25-bl2.dtsi
 FDT_SOURCES			:=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
+BL31_DTSI			:=	stm32mp25-bl31.dtsi
+FDT_SOURCES			+=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dts,$(DTB_FILE_NAME)))
 
 # Macros and rules to build TF binary
 STM32_TF_STM32			:=	$(addprefix ${BUILD_PLAT}/tf-a-, $(patsubst %.dtb,%.stm32,$(DTB_FILE_NAME)))
 STM32_LD_FILE			:=	plat/st/stm32mp2/${ARCH}/stm32mp2.ld.S
 STM32_BINARY_MAPPING		:=	plat/st/stm32mp2/${ARCH}/stm32mp2.S
 
+STM32MP_FW_CONFIG_NAME		:=	$(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
+STM32MP_FW_CONFIG		:=	${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
+STM32MP_SOC_FW_CONFIG		:=	$(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl31.dtb,$(DTB_FILE_NAME)))
+ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
+STM32MP_DDR_FW_PATH		?=	drivers/st/ddr/phy/firmware/bin/stm32mp2
+STM32MP_DDR_FW_NAME		:=	${DDR_TYPE}_pmu_train.bin
+STM32MP_DDR_FW			:=	${STM32MP_DDR_FW_PATH}/${STM32MP_DDR_FW_NAME}
+endif
+FDT_SOURCES			+=	$(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
+
+# Add the FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
+
+# Add the SOC_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_IMG_PAYLOAD,STM32MP_SOC_FW_CONFIG,$(STM32MP_SOC_FW_CONFIG),--soc-fw-config,$(patsubst %.dtb,%.dts,$(STM32MP_SOC_FW_CONFIG))))
+
+ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
+# Add the FW_DDR to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_IMG,STM32MP_DDR_FW,--ddr-fw))
+endif
+
+# Enable flags for C files
+$(eval $(call assert_booleans,\
+	$(sort \
+		STM32MP_DDR_DUAL_AXI_PORT \
+		STM32MP_DDR_FIP_IO_STORAGE \
+		STM32MP_DDR3_TYPE \
+		STM32MP_DDR4_TYPE \
+		STM32MP_LPDDR4_TYPE \
+		STM32MP25 \
+		STM32MP_BL33_EL1 \
+)))
+
+$(eval $(call assert_numerics,\
+	$(sort \
+		PLAT_PARTITION_MAX_ENTRIES \
+		STM32_HEADER_VERSION_MAJOR \
+		STM32_TF_A_COPIES \
+)))
+
+$(eval $(call add_defines,\
+	$(sort \
+		DWL_BUFFER_BASE \
+		PLAT_DEF_FIP_UUID \
+		PLAT_PARTITION_MAX_ENTRIES \
+		PLAT_TBBR_IMG_DEF \
+		STM32_TF_A_COPIES \
+		STM32MP_DDR_DUAL_AXI_PORT \
+		STM32MP_DDR_FIP_IO_STORAGE \
+		STM32MP_DDR3_TYPE \
+		STM32MP_DDR4_TYPE \
+		STM32MP_LPDDR4_TYPE \
+		STM32MP25 \
+		STM32MP_BL33_EL1 \
+)))
+
 # STM32MP2x is based on Cortex-A35, which is Armv8.0, and does not support BTI
 # Disable mbranch-protection to avoid adding useless code
 TF_CFLAGS			+=	-mbranch-protection=none
 
 # Include paths and source files
 PLAT_INCLUDES			+=	-Iplat/st/stm32mp2/include/
+PLAT_INCLUDES			+=	-Idrivers/st/ddr/phy/phyinit/include/
+PLAT_INCLUDES			+=	-Idrivers/st/ddr/phy/firmware/include/
 
 PLAT_BL_COMMON_SOURCES		+=	lib/cpus/${ARCH}/cortex_a35.S
 PLAT_BL_COMMON_SOURCES		+=	drivers/st/uart/${ARCH}/stm32_console.S
 PLAT_BL_COMMON_SOURCES		+=	plat/st/stm32mp2/${ARCH}/stm32mp2_helper.S
 
+PLAT_BL_COMMON_SOURCES		+=	drivers/st/pmic/stm32mp_pmic2.c				\
+					drivers/st/pmic/stpmic2.c				\
+
+PLAT_BL_COMMON_SOURCES		+=	drivers/st/i2c/stm32_i2c.c
+
+PLAT_BL_COMMON_SOURCES		+=	plat/st/stm32mp2/stm32mp2_private.c
+
+PLAT_BL_COMMON_SOURCES		+=	drivers/st/bsec/bsec3.c					\
+					drivers/st/reset/stm32mp2_reset.c			\
+					plat/st/stm32mp2/stm32mp2_syscfg.c
+
+PLAT_BL_COMMON_SOURCES		+=	drivers/st/clk/clk-stm32-core.c				\
+					drivers/st/clk/clk-stm32mp2.c
+
 BL2_SOURCES			+=	plat/st/stm32mp2/plat_bl2_mem_params_desc.c
-BL2_SOURCES			+=	plat/st/stm32mp2/bl2_plat_setup.c
+
+BL2_SOURCES			+=	plat/st/stm32mp2/bl2_plat_setup.c			\
+					plat/st/stm32mp2/plat_ddr.c
+
+ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
+BL2_SOURCES			+=	drivers/st/mmc/stm32_sdmmc2.c
+endif
+
+ifeq (${STM32MP_USB_PROGRAMMER},1)
+BL2_SOURCES			+=	plat/st/stm32mp2/stm32mp2_usb_dfu.c
+endif
+
+BL2_SOURCES			+=	drivers/st/ddr/stm32mp2_ddr.c				\
+					drivers/st/ddr/stm32mp2_ddr_helpers.c			\
+					drivers/st/ddr/stm32mp2_ram.c
+
+BL2_SOURCES			+=	drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_c_initphyconfig.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_calcmb.c					\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_i_loadpieimage.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_initstruct.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_isdbytedisabled.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_loadpieprodcode.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_mapdrvstren.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_progcsrskiptrain.c			\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_reginterface.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_restore_sequence.c			\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_sequence.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_softsetmb.c				\
+					drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_custompretrain.c	\
+					drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_saveretregs.c
+
+BL2_SOURCES			+=	drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_d_loadimem.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_f_loaddmem.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_g_execfw.c				\
+					drivers/st/ddr/phy/phyinit/src/ddrphy_phyinit_writeoutmem.c				\
+					drivers/st/ddr/phy/phyinit/usercustom/ddrphy_phyinit_usercustom_g_waitfwdone.c
+
+# BL31 sources
+BL31_SOURCES			+=	${FDT_WRAPPERS_SOURCES}
+
+BL31_SOURCES			+=	plat/st/stm32mp2/bl31_plat_setup.c			\
+					plat/st/stm32mp2/stm32mp2_pm.c				\
+					plat/st/stm32mp2/stm32mp2_topology.c
+# Generic GIC v2
+include drivers/arm/gic/v2/gicv2.mk
+
+BL31_SOURCES			+=	${GICV2_SOURCES}					\
+					plat/common/plat_gicv2.c				\
+					plat/st/common/stm32mp_gic.c
+
+# Generic PSCI
+BL31_SOURCES			+=	plat/common/plat_psci_common.c
+
+# Compilation rules
+.PHONY: check_ddr_type
+.SUFFIXES:
+
+bl2: check_ddr_type
+
+check_ddr_type:
+	$(eval DDR_TYPE = $(shell echo $$(($(STM32MP_DDR3_TYPE) + \
+					   $(STM32MP_DDR4_TYPE) + \
+					   $(STM32MP_LPDDR4_TYPE)))))
+	@if [ ${DDR_TYPE} != 1 ]; then \
+		echo "One and only one DDR type must be defined"; \
+		false; \
+	fi
+
+# Create DTB file for BL31
+${BUILD_PLAT}/fdts/%-bl31.dts: fdts/%.dts fdts/${BL31_DTSI} | $$(@D)/
+	@echo '#include "$(patsubst fdts/%,%,$<)"' > $@
+	@echo '#include "${BL31_DTSI}"' >> $@
 
 include plat/st/common/common_rules.mk
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 66514fcf..b4415021 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,24 +12,70 @@
 #include <drivers/st/bsec.h>
 #endif
 #include <drivers/st/stm32mp25_rcc.h>
+#ifndef __ASSEMBLER__
+#include <drivers/st/stm32mp2_clk.h>
+#endif
+#include <drivers/st/stm32mp2_pwr.h>
 #include <dt-bindings/clock/stm32mp25-clks.h>
 #include <dt-bindings/clock/stm32mp25-clksrc.h>
+#include <dt-bindings/gpio/stm32-gpio.h>
 #include <dt-bindings/reset/stm32mp25-resets.h>
 
 #ifndef __ASSEMBLER__
 #include <boot_api.h>
+#include <stm32mp2_private.h>
 #include <stm32mp_common.h>
 #include <stm32mp_dt.h>
 #include <stm32mp_shared_resources.h>
 #endif
 
+/*******************************************************************************
+ * CHIP ID
+ ******************************************************************************/
+#define STM32MP2_CHIP_ID			U(0x505)
+
+#define STM32MP251A_PART_NB			U(0x400B3E6D)
+#define STM32MP251C_PART_NB			U(0x000B306D)
+#define STM32MP251D_PART_NB			U(0xC00B3E6D)
+#define STM32MP251F_PART_NB			U(0x800B306D)
+#define STM32MP253A_PART_NB			U(0x400B3E0C)
+#define STM32MP253C_PART_NB			U(0x000B300C)
+#define STM32MP253D_PART_NB			U(0xC00B3E0C)
+#define STM32MP253F_PART_NB			U(0x800B300C)
+#define STM32MP255A_PART_NB			U(0x40082E00)
+#define STM32MP255C_PART_NB			U(0x00082000)
+#define STM32MP255D_PART_NB			U(0xC0082E00)
+#define STM32MP255F_PART_NB			U(0x80082000)
+#define STM32MP257A_PART_NB			U(0x40002E00)
+#define STM32MP257C_PART_NB			U(0x00002000)
+#define STM32MP257D_PART_NB			U(0xC0002E00)
+#define STM32MP257F_PART_NB			U(0x80002000)
+
+#define STM32MP2_REV_A				U(0x08)
+#define STM32MP2_REV_B				U(0x10)
+#define STM32MP2_REV_X				U(0x12)
+#define STM32MP2_REV_Y				U(0x11)
+#define STM32MP2_REV_Z				U(0x09)
+
+/*******************************************************************************
+ * PACKAGE ID
+ ******************************************************************************/
+#define STM32MP25_PKG_CUSTOM			U(0)
+#define STM32MP25_PKG_AL_VFBGA361		U(1)
+#define STM32MP25_PKG_AK_VFBGA424		U(3)
+#define STM32MP25_PKG_AI_TFBGA436		U(5)
+#define STM32MP25_PKG_UNKNOWN			U(7)
+
 /*******************************************************************************
  * STM32MP2 memory map related constants
  ******************************************************************************/
 #define STM32MP_SYSRAM_BASE			U(0x0E000000)
 #define STM32MP_SYSRAM_SIZE			U(0x00040000)
+#define SRAM1_BASE				U(0x0E040000)
+#define SRAM1_SIZE_FOR_TFA			U(0x00010000)
+#define RETRAM_BASE				U(0x0E080000)
+#define RETRAM_SIZE				U(0x00020000)
 
-#define STM32MP_SEC_SYSRAM_BASE			STM32MP_SYSRAM_BASE
 #define STM32MP_SEC_SYSRAM_SIZE			STM32MP_SYSRAM_SIZE
 
 /* DDR configuration */
@@ -47,28 +93,44 @@ enum ddr_type {
 
 /* Section used inside TF binaries */
 #define STM32MP_PARAM_LOAD_SIZE			U(0x00002400) /* 9 KB for param */
-/* 512 Octets reserved for header */
+/* 512 Bytes reserved for header */
 #define STM32MP_HEADER_SIZE			U(0x00000200)
-#define STM32MP_HEADER_BASE			(STM32MP_SEC_SYSRAM_BASE +	\
+#define STM32MP_HEADER_BASE			(STM32MP_SYSRAM_BASE +	\
 						 STM32MP_PARAM_LOAD_SIZE)
 
 /* round_up(STM32MP_PARAM_LOAD_SIZE + STM32MP_HEADER_SIZE, PAGE_SIZE) */
 #define STM32MP_HEADER_RESERVED_SIZE		U(0x3000)
 
-#define STM32MP_BINARY_BASE			(STM32MP_SEC_SYSRAM_BASE +	\
+#define STM32MP_BINARY_BASE			(STM32MP_SYSRAM_BASE +	\
 						 STM32MP_PARAM_LOAD_SIZE +	\
 						 STM32MP_HEADER_SIZE)
 
-#define STM32MP_BINARY_SIZE			(STM32MP_SEC_SYSRAM_SIZE -	\
+#define STM32MP_BINARY_SIZE			(STM32MP_SYSRAM_SIZE -	\
 						 (STM32MP_PARAM_LOAD_SIZE +	\
 						  STM32MP_HEADER_SIZE))
 
-#define STM32MP_BL2_SIZE			U(0x0002A000) /* 168 KB for BL2 */
+#define STM32MP_BL2_RO_SIZE			U(0x00020000) /* 128 KB */
+#define STM32MP_BL2_SIZE			U(0x00029000) /* 164 KB for BL2 */
 
-#define STM32MP_BL2_BASE			(STM32MP_SEC_SYSRAM_BASE + \
-						 STM32MP_SEC_SYSRAM_SIZE - \
+/* Allocate remaining sysram to BL31 Binary only */
+#define STM32MP_BL31_SIZE			(STM32MP_SEC_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)
+
+#define STM32MP_BL2_RO_BASE			STM32MP_BL2_BASE
+
+#define STM32MP_BL2_RW_BASE			(STM32MP_BL2_RO_BASE + \
+						 STM32MP_BL2_RO_SIZE)
+
+#define STM32MP_BL2_RW_SIZE			(STM32MP_SYSRAM_BASE + \
+						 STM32MP_SYSRAM_SIZE - \
+						 STM32MP_BL2_RW_BASE)
+
 /* BL2 and BL32/sp_min require 4 tables */
 #define MAX_XLAT_TABLES				U(4)	/* 16 KB for mapping */
 
@@ -76,16 +138,45 @@ enum ddr_type {
  * MAX_MMAP_REGIONS is usually:
  * BL stm32mp2_mmap size + mmap regions in *_plat_arch_setup
  */
+#if defined(IMAGE_BL31)
+#define MAX_MMAP_REGIONS			7
+#else
 #define MAX_MMAP_REGIONS			6
+#endif
 
 /* DTB initialization value */
-#define STM32MP_BL2_DTB_SIZE			U(0x00005000) /* 20 KB for DTB */
+#define STM32MP_BL2_DTB_SIZE			U(0x00006000)	/* 24 KB for DTB */
 
 #define STM32MP_BL2_DTB_BASE			(STM32MP_BL2_BASE - \
 						 STM32MP_BL2_DTB_SIZE)
 
+#if defined(IMAGE_BL2)
+#define STM32MP_DTB_SIZE			STM32MP_BL2_DTB_SIZE
+#define STM32MP_DTB_BASE			STM32MP_BL2_DTB_BASE
+#endif
+
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define STM32MP_DDR_FW_BASE			SRAM1_BASE
+#define STM32MP_DDR_FW_DMEM_OFFSET		U(0x400)
+#define STM32MP_DDR_FW_IMEM_OFFSET		U(0x800)
+#define STM32MP_DDR_FW_MAX_SIZE			U(0x8800)
+#endif
+
+#define STM32MP_FW_CONFIG_MAX_SIZE		PAGE_SIZE
+#define STM32MP_FW_CONFIG_BASE			STM32MP_SYSRAM_BASE
+
 #define STM32MP_BL33_BASE			(STM32MP_DDR_BASE + U(0x04000000))
 #define STM32MP_BL33_MAX_SIZE			U(0x400000)
+#define STM32MP_HW_CONFIG_BASE			(STM32MP_BL33_BASE + \
+						STM32MP_BL33_MAX_SIZE)
+#define STM32MP_HW_CONFIG_MAX_SIZE		U(0x40000)
+#define STM32MP_SOC_FW_CONFIG_MAX_SIZE		U(0x10000) /* 64kB for BL31 DT */
+
+/*******************************************************************************
+ * STM32MP2 device/io map related constants (used for MMU)
+ ******************************************************************************/
+#define STM32MP_DEVICE_BASE			U(0x40000000)
+#define STM32MP_DEVICE_SIZE			U(0x40000000)
 
 /*******************************************************************************
  * STM32MP2 RCC
@@ -156,6 +247,97 @@ enum ddr_type {
 #define STM32MP_SDMMC2_BASE			U(0x48230000)
 #define STM32MP_SDMMC3_BASE			U(0x48240000)
 
+/*******************************************************************************
+ * STM32MP2 BSEC / OTP
+ ******************************************************************************/
+/*
+ * 367 available OTPs, the other are masked
+ * - ECIES key: 368 to 375 (only readable by bootrom)
+ * - HWKEY: 376 to 383 (never reloadable or readable)
+ */
+#define STM32MP2_OTP_MAX_ID			U(0x16F)
+#define STM32MP2_MID_OTP_START			U(0x80)
+#define STM32MP2_UPPER_OTP_START		U(0x100)
+
+/* OTP labels */
+#define PART_NUMBER_OTP				"part-number-otp"
+#define REVISION_OTP				"rev_otp"
+#define PACKAGE_OTP				"package-otp"
+#define HCONF1_OTP				"otp124"
+#define NAND_OTP				"otp16"
+#define NAND2_OTP				"otp20"
+#define BOARD_ID_OTP				"board-id"
+#define UID_OTP					"uid-otp"
+#define LIFECYCLE2_OTP				"otp18"
+#define PKH_OTP					"otp144"
+#define ENCKEY_OTP				"otp260"
+
+/* OTP mask */
+/* PACKAGE */
+#define PACKAGE_OTP_PKG_MASK			GENMASK_32(2, 0)
+#define PACKAGE_OTP_PKG_SHIFT			U(0)
+
+/* IWDG OTP */
+#define HCONF1_OTP_IWDG_HW_POS			U(0)
+#define HCONF1_OTP_IWDG_FZ_STOP_POS		U(1)
+#define HCONF1_OTP_IWDG_FZ_STANDBY_POS		U(2)
+
+/* NAND OTP */
+/* NAND parameter storage flag */
+#define NAND_PARAM_STORED_IN_OTP		BIT_32(31)
+
+/* NAND page size in bytes */
+#define NAND_PAGE_SIZE_MASK			GENMASK_32(30, 29)
+#define NAND_PAGE_SIZE_SHIFT			U(29)
+#define NAND_PAGE_SIZE_2K			U(0)
+#define NAND_PAGE_SIZE_4K			U(1)
+#define NAND_PAGE_SIZE_8K			U(2)
+
+/* NAND block size in pages */
+#define NAND_BLOCK_SIZE_MASK			GENMASK_32(28, 27)
+#define NAND_BLOCK_SIZE_SHIFT			U(27)
+#define NAND_BLOCK_SIZE_64_PAGES		U(0)
+#define NAND_BLOCK_SIZE_128_PAGES		U(1)
+#define NAND_BLOCK_SIZE_256_PAGES		U(2)
+
+/* NAND number of block (in unit of 256 blocks) */
+#define NAND_BLOCK_NB_MASK			GENMASK_32(26, 19)
+#define NAND_BLOCK_NB_SHIFT			U(19)
+#define NAND_BLOCK_NB_UNIT			U(256)
+
+/* NAND bus width in bits */
+#define NAND_WIDTH_MASK				BIT_32(18)
+#define NAND_WIDTH_SHIFT			U(18)
+
+/* NAND number of ECC bits per 512 bytes */
+#define NAND_ECC_BIT_NB_MASK			GENMASK_32(17, 15)
+#define NAND_ECC_BIT_NB_SHIFT			U(15)
+#define NAND_ECC_BIT_NB_UNSET			U(0)
+#define NAND_ECC_BIT_NB_1_BITS			U(1)
+#define NAND_ECC_BIT_NB_4_BITS			U(2)
+#define NAND_ECC_BIT_NB_8_BITS			U(3)
+#define NAND_ECC_ON_DIE				U(4)
+
+/* NAND number of planes */
+#define NAND_PLANE_BIT_NB_MASK			BIT_32(14)
+
+/* NAND2 OTP */
+#define NAND2_PAGE_SIZE_SHIFT			U(16)
+
+/* NAND2 config distribution */
+#define NAND2_CONFIG_DISTRIB			BIT_32(0)
+#define NAND2_PNAND_NAND2_SNAND_NAND1		U(0)
+#define NAND2_PNAND_NAND1_SNAND_NAND2		U(1)
+
+/* MONOTONIC OTP */
+#define MAX_MONOTONIC_VALUE			U(32)
+
+/* UID OTP */
+#define UID_WORD_NB				U(3)
+
+/* Lifecycle OTP */
+#define SECURE_BOOT_CLOSED_SECURE		GENMASK_32(3, 0)
+
 /*******************************************************************************
  * STM32MP2 TAMP
  ******************************************************************************/
@@ -200,6 +382,17 @@ static inline uintptr_t tamp_bkpr(uint32_t idx)
 #define STGEN_BASE				U(0x48080000)
 #define SYSCFG_BASE				U(0x44230000)
 
+/*******************************************************************************
+ * STM32MP RIF
+ ******************************************************************************/
+#define RISAB3_BASE				U(0x42110000)
+#define RISAB5_BASE				U(0x42130000)
+
+/*******************************************************************************
+ * STM32MP CA35SSC
+ ******************************************************************************/
+#define A35SSC_BASE				U(0x48800000)
+
 /*******************************************************************************
  * REGULATORS
  ******************************************************************************/
@@ -217,6 +410,7 @@ static inline uintptr_t tamp_bkpr(uint32_t idx)
 #define DT_DDR_COMPAT				"st,stm32mp2-ddr"
 #define DT_PWR_COMPAT				"st,stm32mp25-pwr"
 #define DT_RCC_CLK_COMPAT			"st,stm32mp25-rcc"
+#define DT_SDMMC2_COMPAT			"st,stm32mp25-sdmmc2"
 #define DT_UART_COMPAT				"st,stm32h7-uart"
 
 #endif /* STM32MP2_DEF_H */
diff --git a/plat/st/stm32mp2/stm32mp2_pm.c b/plat/st/stm32mp2/stm32mp2_pm.c
new file mode 100644
index 00000000..5bb381d0
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_pm.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+static uintptr_t stm32_sec_entrypoint;
+
+static void stm32_cpu_standby(plat_local_state_t cpu_state)
+{
+}
+
+static int stm32_pwr_domain_on(u_register_t mpidr)
+{
+	return PSCI_E_INTERN_FAIL;
+}
+
+static void stm32_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	/* Nothing to do */
+}
+
+static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	/* Nothing to do, power domain is not disabled */
+}
+
+static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+}
+
+/*******************************************************************************
+ * STM32MP2 handler called when a power domain has just been powered on after
+ * having been suspended earlier. The target_state encodes the low power state
+ * that each level has woken up from.
+ ******************************************************************************/
+static void stm32_pwr_domain_suspend_finish(const psci_power_state_t
+					    *target_state)
+{
+	/* Nothing to do, power domain is not disabled */
+}
+
+static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t
+						  *target_state)
+{
+	ERROR("stm32mp2 Power Down WFI: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 stm32_system_off(void)
+{
+	ERROR("stm32mp2 System Off: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 stm32_system_reset(void)
+{
+	stm32mp_system_reset();
+}
+
+static int stm32_validate_power_state(unsigned int power_state,
+				      psci_power_state_t *req_state)
+{
+	return PSCI_E_INVALID_PARAMS;
+}
+
+static int stm32_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/* The non-secure entry point must be in DDR */
+	if (entrypoint < STM32MP_DDR_BASE) {
+		return PSCI_E_INVALID_ADDRESS;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+static void stm32_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+}
+
+/*******************************************************************************
+ * Export the platform handlers. The ARM Standard platform layer will take care
+ * of registering the handlers with PSCI.
+ ******************************************************************************/
+static const plat_psci_ops_t stm32_psci_ops = {
+	.cpu_standby = stm32_cpu_standby,
+	.pwr_domain_on = stm32_pwr_domain_on,
+	.pwr_domain_off = stm32_pwr_domain_off,
+	.pwr_domain_suspend = stm32_pwr_domain_suspend,
+	.pwr_domain_on_finish = stm32_pwr_domain_on_finish,
+	.pwr_domain_suspend_finish = stm32_pwr_domain_suspend_finish,
+	.pwr_domain_pwr_down_wfi = stm32_pwr_domain_pwr_down_wfi,
+	.system_off = stm32_system_off,
+	.system_reset = stm32_system_reset,
+	.validate_power_state = stm32_validate_power_state,
+	.validate_ns_entrypoint = stm32_validate_ns_entrypoint,
+	.get_sys_suspend_power_state = stm32_get_sys_suspend_power_state,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	stm32_sec_entrypoint = sec_entrypoint;
+	*psci_ops = &stm32_psci_ops;
+
+	return 0;
+}
diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c
new file mode 100644
index 00000000..5be4c5a3
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_private.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <platform_def.h>
+
+#define BKPR_BOOT_MODE	96U
+
+#if defined(IMAGE_BL31)
+/* BL31 only uses the first half of the SYSRAM */
+#define MAP_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
+					STM32MP_SYSRAM_SIZE / 2U, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+#else
+#define MAP_SYSRAM	MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
+					STM32MP_SYSRAM_SIZE, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+#endif
+
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define MAP_SRAM1	MAP_REGION_FLAT(SRAM1_BASE, \
+					SRAM1_SIZE_FOR_TFA, \
+					MT_MEMORY | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+#endif
+
+#define MAP_DEVICE	MAP_REGION_FLAT(STM32MP_DEVICE_BASE, \
+					STM32MP_DEVICE_SIZE, \
+					MT_DEVICE | \
+					MT_RW | \
+					MT_SECURE | \
+					MT_EXECUTE_NEVER)
+
+#if defined(IMAGE_BL2)
+static const mmap_region_t stm32mp2_mmap[] = {
+	MAP_SYSRAM,
+#if STM32MP_DDR_FIP_IO_STORAGE
+	MAP_SRAM1,
+#endif
+	MAP_DEVICE,
+	{0}
+};
+#endif
+#if defined(IMAGE_BL31)
+static const mmap_region_t stm32mp2_mmap[] = {
+	MAP_SYSRAM,
+	MAP_DEVICE,
+	{0}
+};
+#endif
+
+void configure_mmu(void)
+{
+	mmap_add(stm32mp2_mmap);
+	init_xlat_tables();
+
+	enable_mmu_el3(0);
+}
+
+int stm32mp_map_retram(void)
+{
+	return  mmap_add_dynamic_region(RETRAM_BASE, RETRAM_BASE,
+					RETRAM_SIZE,
+					MT_RW | MT_SECURE);
+}
+
+int stm32mp_unmap_retram(void)
+{
+	return  mmap_remove_dynamic_region(RETRAM_BASE,
+					   RETRAM_SIZE);
+}
+
+uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
+{
+	if (bank == GPIO_BANK_Z) {
+		return GPIOZ_BASE;
+	}
+
+	assert(bank <= GPIO_BANK_K);
+
+	return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
+}
+
+uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
+{
+	if (bank == GPIO_BANK_Z) {
+		return 0;
+	}
+
+	assert(bank <= GPIO_BANK_K);
+
+	return bank * GPIO_BANK_OFFSET;
+}
+
+unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
+{
+	if (bank == GPIO_BANK_Z) {
+		return CK_BUS_GPIOZ;
+	}
+
+	assert(bank <= GPIO_BANK_K);
+
+	return CK_BUS_GPIOA + (bank - GPIO_BANK_A);
+}
+
+#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
+/*
+ * UART Management
+ */
+static const uintptr_t stm32mp2_uart_addresses[STM32MP_NB_OF_UART] = {
+	USART1_BASE,
+	USART2_BASE,
+	USART3_BASE,
+	UART4_BASE,
+	UART5_BASE,
+	USART6_BASE,
+	UART7_BASE,
+	UART8_BASE,
+	UART9_BASE,
+};
+
+uintptr_t get_uart_address(uint32_t instance_nb)
+{
+	if ((instance_nb == 0U) ||
+	    (instance_nb > STM32MP_NB_OF_UART)) {
+		return 0U;
+	}
+
+	return stm32mp2_uart_addresses[instance_nb - 1U];
+}
+#endif
+
+uint32_t stm32mp_get_chip_version(void)
+{
+	static uint32_t rev;
+
+	if (rev != 0U) {
+		return rev;
+	}
+
+	if (stm32_get_otp_value(REVISION_OTP, &rev) != 0) {
+		panic();
+	}
+
+	return rev;
+}
+
+uint32_t stm32mp_get_chip_dev_id(void)
+{
+	return stm32mp_syscfg_get_chip_dev_id();
+}
+
+static uint32_t get_part_number(void)
+{
+	static uint32_t part_number;
+
+	if (part_number != 0U) {
+		return part_number;
+	}
+
+	if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
+		panic();
+	}
+
+	return part_number;
+}
+
+static uint32_t get_cpu_package(void)
+{
+	static uint32_t package = UINT32_MAX;
+
+	if (package == UINT32_MAX) {
+		if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
+			panic();
+		}
+	}
+
+	return (package & PACKAGE_OTP_PKG_MASK) >> PACKAGE_OTP_PKG_SHIFT;
+}
+
+void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
+{
+	char *cpu_s, *cpu_r, *pkg;
+
+	/* MPUs Part Numbers */
+	switch (get_part_number()) {
+	case STM32MP251A_PART_NB:
+		cpu_s = "251A";
+		break;
+	case STM32MP251C_PART_NB:
+		cpu_s = "251C";
+		break;
+	case STM32MP251D_PART_NB:
+		cpu_s = "251D";
+		break;
+	case STM32MP251F_PART_NB:
+		cpu_s = "251F";
+		break;
+	case STM32MP253A_PART_NB:
+		cpu_s = "253A";
+		break;
+	case STM32MP253C_PART_NB:
+		cpu_s = "253C";
+		break;
+	case STM32MP253D_PART_NB:
+		cpu_s = "253D";
+		break;
+	case STM32MP253F_PART_NB:
+		cpu_s = "253F";
+		break;
+	case STM32MP255A_PART_NB:
+		cpu_s = "255A";
+		break;
+	case STM32MP255C_PART_NB:
+		cpu_s = "255C";
+		break;
+	case STM32MP255D_PART_NB:
+		cpu_s = "255D";
+		break;
+	case STM32MP255F_PART_NB:
+		cpu_s = "255F";
+		break;
+	case STM32MP257A_PART_NB:
+		cpu_s = "257A";
+		break;
+	case STM32MP257C_PART_NB:
+		cpu_s = "257C";
+		break;
+	case STM32MP257D_PART_NB:
+		cpu_s = "257D";
+		break;
+	case STM32MP257F_PART_NB:
+		cpu_s = "257F";
+		break;
+	default:
+		cpu_s = "????";
+		break;
+	}
+
+	/* Package */
+	switch (get_cpu_package()) {
+	case STM32MP25_PKG_CUSTOM:
+		pkg = "XX";
+		break;
+	case STM32MP25_PKG_AL_VFBGA361:
+		pkg = "AL";
+		break;
+	case STM32MP25_PKG_AK_VFBGA424:
+		pkg = "AK";
+		break;
+	case STM32MP25_PKG_AI_TFBGA436:
+		pkg = "AI";
+		break;
+	default:
+		pkg = "??";
+		break;
+	}
+
+	/* REVISION */
+	switch (stm32mp_get_chip_version()) {
+	case STM32MP2_REV_A:
+		cpu_r = "A";
+		break;
+	case STM32MP2_REV_B:
+		cpu_r = "B";
+		break;
+	case STM32MP2_REV_X:
+		cpu_r = "X";
+		break;
+	case STM32MP2_REV_Y:
+		cpu_r = "Y";
+		break;
+	case STM32MP2_REV_Z:
+		cpu_r = "Z";
+		break;
+	default:
+		cpu_r = "?";
+		break;
+	}
+
+	snprintf(name, STM32_SOC_NAME_SIZE,
+		 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
+}
+
+void stm32mp_print_cpuinfo(void)
+{
+	char name[STM32_SOC_NAME_SIZE];
+
+	stm32mp_get_soc_name(name);
+	NOTICE("CPU: %s\n", name);
+}
+
+void stm32mp_print_boardinfo(void)
+{
+	uint32_t board_id = 0U;
+
+	if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
+		return;
+	}
+
+	if (board_id != 0U) {
+		stm32_display_board_info(board_id);
+	}
+}
+
+bool stm32mp_is_wakeup_from_standby(void)
+{
+	/* TODO add source code to determine if platform is waking up from standby mode */
+	return false;
+}
+
+uintptr_t stm32_get_bkpr_boot_mode_addr(void)
+{
+	return tamp_bkpr(BKPR_BOOT_MODE);
+}
+
+uintptr_t stm32_ddrdbg_get_base(void)
+{
+	return DDRDBG_BASE;
+}
diff --git a/plat/st/stm32mp2/stm32mp2_syscfg.c b/plat/st/stm32mp2/stm32mp2_syscfg.c
new file mode 100644
index 00000000..46c75a68
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_syscfg.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+#include <platform_def.h>
+#include <stm32mp2_private.h>
+
+/*
+ * SYSCFG register offsets (base relative)
+ */
+#define SYSCFG_DEVICEID			0x6400U
+
+/*
+ * SYSCFG_DEVICEID Register
+ */
+#define SYSCFG_DEVICEID_DEV_ID_MASK	GENMASK_32(11, 0)
+
+/*
+ * @brief  Get device ID from SYSCFG registers.
+ * @retval device ID (DEV_ID).
+ */
+uint32_t stm32mp_syscfg_get_chip_dev_id(void)
+{
+	return mmio_read_32(SYSCFG_BASE + SYSCFG_DEVICEID) & SYSCFG_DEVICEID_DEV_ID_MASK;
+}
diff --git a/plat/st/stm32mp2/stm32mp2_topology.c b/plat/st/stm32mp2/stm32mp2_topology.c
new file mode 100644
index 00000000..cc2d58c0
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_topology.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/psci/psci.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+
+/* 1 cluster, all cores into */
+static const unsigned char stm32mp2_power_domain_tree_desc[] = {
+	PLATFORM_CLUSTER_COUNT,
+	PLATFORM_CORE_COUNT,
+};
+
+/* This function returns the platform topology */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return stm32mp2_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+	u_register_t mpidr_copy = mpidr;
+
+	mpidr_copy &= MPIDR_AFFINITY_MASK;
+
+	if ((mpidr_copy & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) {
+		return -1;
+	}
+
+	cluster_id = (mpidr_copy >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr_copy >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -1;
+	}
+
+	/*
+	 * Validate cpu_id by checking whether it represents a CPU in one
+	 * of the two clusters present on the platform.
+	 */
+	if (cpu_id >= PLATFORM_CORE_COUNT) {
+		return -1;
+	}
+
+	return (int)cpu_id;
+}
diff --git a/plat/st/stm32mp2/stm32mp2_usb_dfu.c b/plat/st/stm32mp2/stm32mp2_usb_dfu.c
new file mode 100644
index 00000000..e9679640
--- /dev/null
+++ b/plat/st/stm32mp2/stm32mp2_usb_dfu.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+#include <drivers/usb_device.h>
+
+#include <usb_dfu.h>
+
+struct usb_handle *usb_dfu_plat_init(void)
+{
+	return NULL;
+}
+
+uint8_t usb_dfu_get_phase(uint8_t alt)
+{
+	return 0;
+}
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
index 1bed229b..fb27336e 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
@@ -320,7 +320,7 @@ int k3_sec_proxy_recv(enum k3_sec_proxy_chan_id id, struct k3_sec_proxy_msg *msg
 
 		i = msg->len - trail_bytes;
 		while (trail_bytes--) {
-			msg->buf[i] = data_trail & 0xff;
+			msg->buf[i++] = data_trail & 0xff;
 			data_trail >>= 8;
 		}
 	}
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index d04d8059..5c6ba6b3 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -2,7 +2,7 @@
  * Texas Instruments System Control Interface Driver
  *   Based on Linux and U-Boot implementation
  *
- * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -185,17 +185,20 @@ unlock:
  *
  * Updates the SCI information in the internal data structure.
  *
+ * @version: Structure containing the version info
+ *
  * Return: 0 if all goes well, else appropriate error message
  */
-int ti_sci_get_revision(struct ti_sci_msg_resp_version *rev_info)
+int ti_sci_get_revision(struct ti_sci_msg_version *version)
 {
+	struct ti_sci_msg_resp_version rev_info;
 	struct ti_sci_msg_hdr hdr;
 	struct ti_sci_xfer xfer;
 	int ret;
 
 	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_VERSION, 0x0,
 				    &hdr, sizeof(hdr),
-				    rev_info, sizeof(*rev_info),
+				    &rev_info, sizeof(rev_info),
 				    &xfer);
 	if (ret) {
 		ERROR("Message alloc failed (%d)\n", ret);
@@ -208,6 +211,14 @@ int ti_sci_get_revision(struct ti_sci_msg_resp_version *rev_info)
 		return ret;
 	}
 
+	memcpy(version->firmware_description, rev_info.firmware_description,
+		sizeof(rev_info.firmware_description));
+	version->abi_major = rev_info.abi_major;
+	version->abi_minor = rev_info.abi_minor;
+	version->firmware_revision = rev_info.firmware_revision;
+	version->sub_version = rev_info.sub_version;
+	version->patch_version = rev_info.patch_version;
+
 	return 0;
 }
 
@@ -1731,25 +1742,39 @@ int ti_sci_enter_sleep(uint8_t proc_id,
 }
 
 /**
- * ti_sci_init() - Basic initialization
+ * ti_sci_lpm_get_next_sys_mode() - Get next LPM system mode
+ *
+ * @next_mode:	pointer to a variable that will store the next mode
  *
  * Return: 0 if all goes well, else appropriate error message
  */
-int ti_sci_init(void)
+int ti_sci_lpm_get_next_sys_mode(uint8_t *next_mode)
 {
-	struct ti_sci_msg_resp_version rev_info;
+	struct ti_sci_msg_req_lpm_get_next_sys_mode req;
+	struct ti_sci_msg_resp_lpm_get_next_sys_mode resp;
+	struct ti_sci_xfer xfer;
 	int ret;
 
-	ret = ti_sci_get_revision(&rev_info);
-	if (ret) {
-		ERROR("Unable to communicate with control firmware (%d)\n", ret);
+	if (next_mode == NULL) {
+		return -EINVAL;
+	}
+
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE, 0,
+				    &req, sizeof(req),
+				    &resp, sizeof(resp),
+				    &xfer);
+	if (ret != 0) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
+	}
+
+	ret = ti_sci_do_xfer(&xfer);
+	if (ret != 0) {
+		ERROR("Transfer send failed (%d)\n", ret);
 		return ret;
 	}
 
-	INFO("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n",
-	     rev_info.abi_major, rev_info.abi_minor,
-	     rev_info.firmware_revision,
-	     rev_info.firmware_description);
+	*next_mode = resp.mode;
 
 	return 0;
 }
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
index c702a711..06d1f8d6 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -2,7 +2,7 @@
  * Texas Instruments System Control Interface API
  *   Based on Linux and U-Boot implementation
  *
- * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,41 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+/**
+ * User exported structures.
+ *
+ * The structures in ti_sci_protocol.h are used by the internal drivers.
+ * These are the structures that are exported for outside use and populated
+ * by the internal drivers.
+ *
+ * struct ti_sci_msg_version - Structure containing version info
+ *
+ * @firmware_description: String describing the firmware
+ * @firmware_revision:	Firmware revision
+ * @abi_major:		Major version of the ABI that firmware supports
+ * @abi_minor:		Minor version of the ABI that firmware supports
+ * @sub_version:	Sub-version number of the firmware
+ * @patch_version:	Patch-version number of the firmware.
+ */
+struct ti_sci_msg_version {
+#define FIRMWARE_DESCRIPTION_LENGTH 32
+	char firmware_description[FIRMWARE_DESCRIPTION_LENGTH];
+	uint16_t firmware_revision;
+	uint8_t abi_major;
+	uint8_t abi_minor;
+	uint8_t sub_version;
+	uint8_t patch_version;
+};
+
+/**
+ * General Message
+ *
+ * ti_sci_get_revision - Get the revision of the SCI entity
+ *			@version: Structure containing the version info
+ *
+ **/
+int ti_sci_get_revision(struct ti_sci_msg_version *version);
+
 /**
  * Device control operations
  *
@@ -217,6 +252,11 @@ int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id,
  *		@mode: Low power mode to enter.
  *		@core_resume_addr: Address that core should be resumed from
  *				   after low power transition.
+ * - ti_sci_lpm_get_next_sys_mode - Get next LPM system mode
+ *
+ * @next_mode:	pointer to a variable that will store the next mode
+ *
+ * Return: 0 if all goes well, else appropriate error message
  *
  * NOTE: for all these functions, the following are generic in nature:
  * Returns 0 for successful request, else returns corresponding error message.
@@ -224,12 +264,6 @@ int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id,
 int ti_sci_enter_sleep(uint8_t proc_id,
 		       uint8_t mode,
 		       uint64_t core_resume_addr);
-
-/**
- * ti_sci_init() - Basic initialization
- *
- * Return: 0 if all goes good, else appropriate error message.
- */
-int ti_sci_init(void);
+int ti_sci_lpm_get_next_sys_mode(uint8_t *next_mode);
 
 #endif /* TI_SCI_H */
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index 7f1c3683..cc71eac6 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -31,6 +31,7 @@
 
 /* Low Power Mode Requests */
 #define TI_SCI_MSG_ENTER_SLEEP		0x0301
+#define TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE 0x030d
 
 /* Clock requests */
 #define TI_SCI_MSG_SET_CLOCK_STATE	0x0100
@@ -133,6 +134,7 @@ struct ti_sci_msg_req_reboot {
  *		MSG_FLAG_CAPS_LPM_MCU_ONLY: MCU only LPM
  *		MSG_FLAG_CAPS_LPM_STANDBY: Standby LPM
  *		MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM
+ *		MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM
  *
  * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS
  * providing currently available SOC/firmware capabilities. SoC that don't
@@ -145,6 +147,7 @@ struct ti_sci_msg_resp_query_fw_caps {
 #define MSG_FLAG_CAPS_LPM_MCU_ONLY	TI_SCI_MSG_FLAG(2)
 #define MSG_FLAG_CAPS_LPM_STANDBY	TI_SCI_MSG_FLAG(3)
 #define MSG_FLAG_CAPS_LPM_PARTIAL_IO	TI_SCI_MSG_FLAG(4)
+#define MSG_FLAG_CAPS_LPM_DM_MANAGED	TI_SCI_MSG_FLAG(5)
 	uint64_t fw_caps;
 } __packed;
 
@@ -764,10 +767,35 @@ struct ti_sci_msg_req_wait_proc_boot_status {
  */
 struct ti_sci_msg_req_enter_sleep {
 	struct ti_sci_msg_hdr hdr;
+#define MSG_VALUE_SLEEP_MODE_DEEP_SLEEP 0x0
 	uint8_t mode;
 	uint8_t processor_id;
 	uint32_t core_resume_lo;
 	uint32_t core_resume_hi;
 } __packed;
 
+/**
+ * struct ti_sci_msg_req_lpm_get_next_sys_mode - Request for TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE.
+ *
+ * @hdr Generic Header
+ *
+ * This message is used to enquire DM for selected system wide low power mode.
+ */
+struct ti_sci_msg_req_lpm_get_next_sys_mode {
+	struct ti_sci_msg_hdr hdr;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_lpm_get_next_sys_mode - Response for TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE.
+ *
+ * @hdr Generic Header
+ * @mode The selected system wide low power mode.
+ *
+ * Note: If the mode selection is not yet locked, this API returns "not selected" mode.
+ */
+struct ti_sci_msg_resp_lpm_get_next_sys_mode {
+	struct ti_sci_msg_hdr hdr;
+	uint8_t mode;
+} __packed;
+
 #endif /* TI_SCI_PROTOCOL_H */
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index c5f60fee..63fe0206 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -119,10 +119,44 @@ void bl31_plat_arch_setup(void)
 
 void bl31_platform_setup(void)
 {
+	struct ti_sci_msg_version version;
+	int ret;
+
 	k3_gic_driver_init(K3_GIC_BASE);
 	k3_gic_init();
 
-	ti_sci_init();
+	ret = ti_sci_get_revision(&version);
+	if (ret) {
+		ERROR("Unable to communicate with the control firmware (%d)\n", ret);
+		return;
+	}
+
+	INFO("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n",
+	     version.abi_major, version.abi_minor,
+	     version.firmware_revision,
+	     version.firmware_description);
+
+	/*
+	 * Older firmware have a timing issue with DM that crashes few TF-A
+	 * lite devices while trying to make calls to DM. Since there is no way
+	 * to detect what current DM version we are running - we rely on the
+	 * corresponding TIFS versioning to handle this check and ensure that
+	 * the platform boots up
+	 *
+	 * Upgrading to TIFS version 9.1.7 along with the corresponding DM from
+	 * ti-linux-firmware will enable this functionality.
+	 */
+	if (version.firmware_revision > 9 ||
+	    (version.firmware_revision == 9 && version.sub_version > 1) ||
+	    (version.firmware_revision == 9 && version.sub_version == 1 &&
+		 version.patch_version >= 7)
+	) {
+		if (ti_sci_device_get(PLAT_BOARD_DEVICE_ID)) {
+			WARN("Unable to take system power reference\n");
+		}
+	} else {
+		NOTICE("Upgrade Firmwares for Power off functionality\n");
+	}
 }
 
 void platform_mem_init(void)
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index e8d73dbd..df49f489 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -234,7 +234,7 @@ static int k3_validate_power_state(unsigned int power_state,
 	return PSCI_E_SUCCESS;
 }
 
-static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
+static void k3_pwr_domain_suspend_to_mode(const psci_power_state_t *target_state, uint8_t mode)
 {
 	unsigned int core, proc_id;
 
@@ -247,7 +247,25 @@ static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
 
 	k3_pwr_domain_off(target_state);
 
-	ti_sci_enter_sleep(proc_id, 0, k3_sec_entrypoint);
+	ti_sci_enter_sleep(proc_id, mode, k3_sec_entrypoint);
+}
+
+static void k3_pwr_domain_suspend_dm_managed(const psci_power_state_t *target_state)
+{
+	uint8_t mode = MSG_VALUE_SLEEP_MODE_DEEP_SLEEP;
+	int ret;
+
+	ret = ti_sci_lpm_get_next_sys_mode(&mode);
+	if (ret != 0) {
+		ERROR("Failed to fetch next system mode\n");
+	}
+
+	k3_pwr_domain_suspend_to_mode(target_state, mode);
+}
+
+static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	k3_pwr_domain_suspend_to_mode(target_state, MSG_VALUE_SLEEP_MODE_DEEP_SLEEP);
 }
 
 static void k3_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
@@ -301,6 +319,8 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
 		k3_plat_psci_ops.pwr_domain_suspend = NULL;
 		k3_plat_psci_ops.pwr_domain_suspend_finish = NULL;
 		k3_plat_psci_ops.get_sys_suspend_power_state = NULL;
+	} else if (fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
+		k3_plat_psci_ops.pwr_domain_suspend = k3_pwr_domain_suspend_dm_managed;
 	}
 
 	*psci_ops = &k3_plat_psci_ops;
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index 23efa319..8db732cb 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -28,6 +28,8 @@ ERRATA_A72_1319367	:=	1
 
 CRASH_REPORTING		:= 1
 
+NS_TIMER_SWITCH		:=	0
+
 # Split out RO data into a non-executable section
 SEPARATE_CODE_AND_RODATA :=    1
 
diff --git a/plat/xilinx/common/include/plat_clkfunc.h b/plat/xilinx/common/include/plat_clkfunc.h
new file mode 100644
index 00000000..a182f915
--- /dev/null
+++ b/plat/xilinx/common/include/plat_clkfunc.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_CLKFUNC_H
+#define PLAT_CLKFUNC_H
+
+void set_cnt_freq(void);
+
+#endif /* PLAT_CLKFUNC_H */
diff --git a/plat/xilinx/common/include/plat_common.h b/plat/xilinx/common/include/plat_common.h
index 676baa2c..2958868f 100644
--- a/plat/xilinx/common/include/plat_common.h
+++ b/plat/xilinx/common/include/plat_common.h
@@ -14,4 +14,16 @@
 		(typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask));	\
 	})
 
+/*******************************************************************************
+ * interrupt handling related constants
+ ******************************************************************************/
+#define ARM_IRQ_SEC_SGI_0	8U
+#define ARM_IRQ_SEC_SGI_1	9U
+#define ARM_IRQ_SEC_SGI_2	10U
+#define ARM_IRQ_SEC_SGI_3	11U
+#define ARM_IRQ_SEC_SGI_4	12U
+#define ARM_IRQ_SEC_SGI_5	13U
+#define ARM_IRQ_SEC_SGI_6	14U
+#define ARM_IRQ_SEC_SGI_7	15U
+
 #endif /* PLAT_COMMON_H */
diff --git a/plat/xilinx/common/include/plat_console.h b/plat/xilinx/common/include/plat_console.h
index 0f8320e0..fa6021d4 100644
--- a/plat/xilinx/common/include/plat_console.h
+++ b/plat/xilinx/common/include/plat_console.h
@@ -8,18 +8,30 @@
 #define PLAT_DT_UART_H
 
 #define DT_UART_DCC_COMPAT	"arm,dcc"
+#define DT_UART_CAD_COMPAT	"xlnx,zynqmp-uart"
+#define DT_UART_PL011_COMPAT	"arm,pl011"
 
-#if defined(PLAT_zynqmp)
-#define DT_UART_COMPAT	"xlnx,zynqmp-uart"
-#else
-#define DT_UART_COMPAT	"arm,pl011"
-#endif
+/* Default console type is either CADENCE0 or CADENCE1 or PL011_0 or PL011_1
+ * Debug console type is DCC
+ */
+#define CONSOLE_NONE	0
+#define CONSOLE_CDNS	1
+#define CONSOLE_PL011   2
+#define CONSOLE_DCC	3
+
+typedef struct console_hd {
+	uint32_t clk;
+	uint32_t baud_rate;
+	uintptr_t base;
+	uint32_t console_scope;
+	uint8_t console_type;
+} console_holder;
 
 typedef struct dt_uart_info_s {
 	char compatible[30];
 	uintptr_t base;
 	uint32_t baud_rate;
-	int32_t status;
+	uint8_t console_type;
 } dt_uart_info_t;
 
 void setup_console(void);
diff --git a/plat/xilinx/common/include/plat_fdt.h b/plat/xilinx/common/include/plat_fdt.h
index a1ee1e19..47a678c7 100644
--- a/plat/xilinx/common/include/plat_fdt.h
+++ b/plat/xilinx/common/include/plat_fdt.h
@@ -9,4 +9,8 @@
 
 void prepare_dtb(void);
 
+#if defined(XILINX_OF_BOARD_DTB_ADDR)
+int32_t is_valid_dtb(void *fdt);
+#endif
+
 #endif /* PLAT_FDT_H */
diff --git a/plat/xilinx/common/include/plat_xfer_list.h b/plat/xilinx/common/include/plat_xfer_list.h
new file mode 100644
index 00000000..cc79a2c6
--- /dev/null
+++ b/plat/xilinx/common/include/plat_xfer_list.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_XFER_LIST_H
+#define PLAT_XFER_LIST_H
+
+#include <lib/transfer_list.h>
+
+int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
+				       entry_point_info_t *bl33);
+
+#endif /* PLAT_XFER_LIST_H */
diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
index 3fcb62f7..029bb438 100644
--- a/plat/xilinx/common/include/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -53,9 +53,6 @@ enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack,
 				      uint32_t flag);
 enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
 				      uint32_t flag);
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
-				uint32_t arg1, uint32_t arg2, uint32_t arg3,
-				uint32_t *value, uint32_t flag);
 enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
 				 uint32_t arg3, uint32_t *data, uint32_t flag);
 uint32_t pm_get_shutdown_scope(void);
@@ -67,6 +64,7 @@ enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event,
 					uint32_t wake, uint32_t enable,
 					uint32_t flag);
 enum pm_ret_status pm_get_chipid(uint32_t *value);
+enum pm_ret_status eemi_feature_check(uint32_t api_id, uint32_t *ret_payload);
 
 /*
  * Assigning of argument values into array elements.
@@ -100,4 +98,9 @@ enum pm_ret_status pm_get_chipid(uint32_t *value);
 	PM_PACK_PAYLOAD5(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4));		\
 }
 
+#define PM_PACK_PAYLOAD7(pl, mid, flag, arg0, arg1, arg2, arg3, arg4, arg5, arg6) {	\
+	pl[6] = (uint32_t)(arg6);							\
+	PM_PACK_PAYLOAD6(pl, (mid), (flag), (arg0), (arg1), (arg2), (arg3), (arg4), (arg5));	\
+}
+
 #endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/common/include/pm_client.h b/plat/xilinx/common/include/pm_client.h
index a87923ff..e9c36c3b 100644
--- a/plat/xilinx/common/include/pm_client.h
+++ b/plat/xilinx/common/include/pm_client.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,7 +31,6 @@ extern const struct pm_proc *primary_proc;
 
 #if defined(PLAT_zynqmp)
 enum pm_ret_status pm_set_suspend_mode(uint32_t mode);
-const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
 #endif /* PLAT_zynqmp */
 
 #endif /* PM_CLIENT_H */
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
index c0308ab6..68d1db29 100644
--- a/plat/xilinx/common/include/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,8 +24,9 @@
 #define CRC_ORDER               16U
 #define CRC_POLYNOM             0x8005U
 #else
-#define PAYLOAD_ARG_CNT         6U
+#define PAYLOAD_ARG_CNT		7U
 #endif
+#define RET_PAYLOAD_ARG_CNT	6U
 #define PAYLOAD_ARG_SIZE	4U	/* size in bytes */
 
 #define TZ_VERSION_MAJOR	1
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index 9cdb0ba0..99206114 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,7 @@
 
 /* State arguments of the self suspend */
 #define PM_STATE_CPU_IDLE	0x0U
+#define PM_STATE_CPU_OFF	0x1U
 #define PM_STATE_SUSPEND_TO_RAM	0xFU
 
 #define MAX_LATENCY		(~0U)
@@ -34,6 +35,7 @@
 				       (uint32_t)XPM_NODESUBCL_DEV_PERIPH, \
 				       (uint32_t)XPM_NODETYPE_DEV_PERIPH, (IDX))
 
+#define TF_A_FEATURE_CHECK		0xa00U
 #define PM_GET_CALLBACK_DATA		0xa01U
 #define PM_GET_TRUSTZONE_VERSION	0xa03U
 #define TF_A_PM_REGISTER_SGI		0xa04U
@@ -94,8 +96,8 @@ enum {
 	IOCTL_GET_LAST_RESET_REASON = 23,
 	/* AI engine NPI ISR clear */
 	IOCTL_AIE_ISR_CLEAR = 24,
-	/* Register SGI to TF-A */
-	IOCTL_SET_SGI = 25,
+	IOCTL_UFS_TXRX_CFGRDY_GET = 40,
+	IOCTL_UFS_SRAM_CSR_SEL = 41,
 };
 
 /**
diff --git a/plat/xilinx/common/include/pm_svc_main.h b/plat/xilinx/common/include/pm_svc_main.h
index 4cf77276..000f198e 100644
--- a/plat/xilinx/common/include/pm_svc_main.h
+++ b/plat/xilinx/common/include/pm_svc_main.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,10 @@
 
 #include <pm_common.h>
 
+extern bool pwrdwn_req_received;
+
+#define PASS_THROUGH_FW_CMD_ID	U(0xfff)
+
 /******************************************************************************/
 /**
  * SECURE_REDUNDANT_CALL() - Adds redundancy to the function call. This is to
@@ -30,6 +34,7 @@
 		status_tmp = function(__VA_ARGS__); \
 	}
 
+void request_cpu_pwrdwn(void);
 int32_t pm_setup(void);
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle,
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 399d283d..d7c70f32 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -70,7 +70,7 @@ static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
 {
 	int ret = 1;
 
-	if (remote >= ipi_total || local >= ipi_total) {
+	if ((remote >= ipi_total) || (local >= ipi_total)) {
 		ret = 0;
 	}
 
@@ -144,11 +144,11 @@ int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
 	uint32_t status;
 
 	status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
-	if (status & IPI_BIT_MASK(remote)) {
+	if ((status & IPI_BIT_MASK(remote)) != 0U) {
 		ret |= IPI_MB_STATUS_SEND_PENDING;
 	}
 	status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
-	if (status & IPI_BIT_MASK(remote)) {
+	if ((status & IPI_BIT_MASK(remote)) != 0U) {
 		ret |= IPI_MB_STATUS_RECV_PENDING;
 	}
 
@@ -170,11 +170,11 @@ void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
 
 	mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
 		      IPI_BIT_MASK(remote));
-	if (is_blocking) {
+	if (is_blocking != 0U) {
 		do {
 			status = mmio_read_32(IPI_REG_BASE(local) +
 					      IPI_OBR_OFFSET);
-		} while (status & IPI_BIT_MASK(remote));
+		} while ((status & IPI_BIT_MASK(remote)) != 0U);
 	}
 }
 
diff --git a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
index 434cd888..9a0149be 100644
--- a/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -70,6 +70,9 @@ uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 			 uint64_t x3, uint64_t x4, const void *cookie,
 			 void *handle, uint64_t flags)
 {
+	(void) x4;
+	(void) flags;
+	(void) cookie;
 	int32_t ret;
 	uint32_t ipi_local_id;
 	uint32_t ipi_remote_id;
@@ -91,7 +94,7 @@ uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 
 	/* Validate IPI mailbox access */
 	ret = ipi_mb_validate(ipi_local_id, ipi_remote_id, is_secure);
-	if (ret)
+	if (ret != 0)
 		SMC_RET1(handle, ret);
 
 	switch (GET_SMC_NUM(smc_fid)) {
@@ -103,11 +106,11 @@ uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 		SMC_RET1(handle, 0);
 	case IPI_MAILBOX_STATUS_ENQUIRY:
 	{
-		int32_t disable_irq;
+		int32_t disable_interrupt;
 
-		disable_irq = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
+		disable_interrupt = (x3 & IPI_SMC_ENQUIRY_DIRQ_MASK) ? 1 : 0;
 		ret = ipi_mb_enquire_status(ipi_local_id, ipi_remote_id);
-		if ((ret & IPI_MB_STATUS_RECV_PENDING) && disable_irq)
+		if ((ret & IPI_MB_STATUS_RECV_PENDING) && disable_interrupt)
 			ipi_mb_disable_irq(ipi_local_id, ipi_remote_id);
 		SMC_RET1(handle, ret);
 	}
@@ -121,11 +124,11 @@ uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 	}
 	case IPI_MAILBOX_ACK:
 	{
-		int32_t enable_irq;
+		int32_t enable_interrupt;
 
-		enable_irq = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
+		enable_interrupt = (x3 & IPI_SMC_ACK_EIRQ_MASK) ? 1 : 0;
 		ipi_mb_ack(ipi_local_id, ipi_remote_id);
-		if (enable_irq)
+		if (enable_interrupt != 0)
 			ipi_mb_enable_irq(ipi_local_id, ipi_remote_id);
 		SMC_RET1(handle, 0);
 	}
diff --git a/plat/xilinx/common/plat_clkfunc.c b/plat/xilinx/common/plat_clkfunc.c
new file mode 100644
index 00000000..f7910de6
--- /dev/null
+++ b/plat/xilinx/common/plat_clkfunc.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+#include <plat_clkfunc.h>
+#include <plat_private.h>
+
+uint32_t plat_get_syscnt_freq2(void)
+{
+	uint32_t counter_freq = 0;
+	uint32_t ret = 0;
+
+	counter_freq = mmio_read_32(IOU_SCNTRS_BASE +
+				    IOU_SCNTRS_BASE_FREQ_OFFSET);
+	if (counter_freq != 0U) {
+		ret = counter_freq;
+	} else {
+		INFO("Indicates counter frequency %dHz setting to %dHz\n",
+		     counter_freq, cpu_clock);
+		ret = cpu_clock;
+	}
+
+	return ret;
+}
+
+void set_cnt_freq(void)
+{
+	uint64_t counter_freq;
+
+	/* Configure counter frequency */
+	counter_freq = read_cntfrq_el0();
+	if (counter_freq == 0U) {
+		write_cntfrq_el0(plat_get_syscnt_freq2());
+	}
+}
diff --git a/plat/xilinx/common/plat_console.c b/plat/xilinx/common/plat_console.c
index 0c0e74b9..681226f9 100644
--- a/plat/xilinx/common/plat_console.c
+++ b/plat/xilinx/common/plat_console.c
@@ -18,13 +18,69 @@
 #include <drivers/console.h>
 #include <libfdt.h>
 #include <plat_console.h>
+#include <plat_fdt.h>
 
 #include <platform_def.h>
 #include <plat_private.h>
 
-static console_t console;
+#if !(CONSOLE_IS(none))
+static console_t boot_console;
+static console_holder boot_hd_console;
+#if defined(CONSOLE_RUNTIME)
+static console_t runtime_console;
+static console_holder rt_hd_console;
+#endif
+
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
+static dt_uart_info_t dt_uart_info;
+#endif
 
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
+/**
+ * register_console() - Registers the uart with console list.
+ * @consoleh: Console holder structure with UART base address,
+ *  UART clock, UART buad rate, flags & console type
+ * @console: Pointer to the console information structure.
+ */
+static void register_console(const console_holder *consoleh, console_t *console)
+{
+	int32_t rc = 0;
+
+	switch (consoleh->console_type) {
+#if defined(PLAT_zynqmp)
+	case CONSOLE_CDNS:
+		rc = console_cdns_register(consoleh->base,
+				consoleh->clk,
+				consoleh->baud_rate,
+				console);
+		break;
+#else
+	case CONSOLE_PL011:
+		rc = console_pl011_register(consoleh->base,
+				consoleh->clk,
+				consoleh->baud_rate,
+				console);
+		break;
+#endif
+	case CONSOLE_DCC:
+		rc = console_dcc_register(console);
+		break;
+	default:
+		INFO("Invalid console type\n");
+		break;
+	}
+
+	if (rc == 0) {
+		panic();
+	}
+
+	console_set_scope(console, consoleh->console_scope);
+}
+
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
 /**
  * get_baudrate() - Get the baudrate form DTB.
  * @dtb: Address of the Device Tree Blob (DTB).
@@ -102,34 +158,56 @@ static uint32_t get_node_status(void *dtb, int node)
  * @node: Node address in the device tree.
  * @dtb: Address of the Device Tree Blob(DTB).
  *
- * Return: On success, it returns 1; on failure, it returns an 0.
+ * Return: On success, it returns 0; on failure, it returns -1 or -FDT_ERR_NOTFOUND.
  */
-static uint32_t fdt_add_uart_info(dt_uart_info_t *info, int node, void *dtb)
+static int32_t fdt_add_uart_info(dt_uart_info_t *info, int node, void *dtb)
 {
 	uintptr_t base_addr;
 	const char *com;
-	uint32_t ret = 0;
+	int32_t ret = 0;
+	uint32_t status;
 
 	com = fdt_getprop(dtb, node, "compatible", NULL);
 	if (com != NULL) {
 		strlcpy(info->compatible, com, sizeof(info->compatible));
 	} else {
 		ERROR("Compatible property not found in DTB node\n");
-		ret  = -FDT_ERR_NOTFOUND;
+		ret = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
-	ret = fdt_get_reg_props_by_index(dtb, node, 0, &base_addr, NULL);
-	if (ret >= 0) {
-		info->base = base_addr;
-	} else {
-		ERROR("Failed to retrieve base address. Error code: %d\n", ret);
-		ret  = -FDT_ERR_NOTFOUND;
+	status = get_node_status(dtb, node);
+	if (status == 0) {
+		ERROR("Uart node is disabled in DTB\n");
+		ret = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
-	info->status = get_node_status(dtb, node);
-	info->baud_rate = get_baudrate(dtb);
+	if (strncmp(info->compatible, DT_UART_DCC_COMPAT, strlen(DT_UART_DCC_COMPAT)) != 0) {
+		ret = fdt_get_reg_props_by_index(dtb, node, 0, &base_addr, NULL);
+		if (ret >= 0) {
+			info->base = base_addr;
+		} else {
+			ERROR("Failed to retrieve base address. Error code: %d\n", ret);
+			ret = -FDT_ERR_NOTFOUND;
+			goto error;
+		}
+
+		info->baud_rate = get_baudrate(dtb);
+
+		if (strncmp(info->compatible, DT_UART_CAD_COMPAT,
+					strlen(DT_UART_CAD_COMPAT)) == 0) {
+			info->console_type = CONSOLE_CDNS;
+		} else if (strncmp(info->compatible, DT_UART_PL011_COMPAT,
+					strlen(DT_UART_PL011_COMPAT)) == 0) {
+			info->console_type = CONSOLE_PL011;
+		} else {
+			ERROR("Incompatible uart node in DTB\n");
+			ret = -FDT_ERR_NOTFOUND;
+		}
+	} else {
+		info->console_type = CONSOLE_DCC;
+	}
 
 error:
 	return ret;
@@ -143,204 +221,93 @@ error:
  */
 static int fdt_get_uart_info(dt_uart_info_t *info)
 {
-	int node, ret = 0;
+	int node = 0, ret = 0;
 	void *dtb = (void *)XILINX_OF_BOARD_DTB_ADDR;
 
-	if (fdt_check_header(dtb) != 0) {
-		ERROR("Can't read DT at %p\n", dtb);
-		ret  = -FDT_ERR_NOTFOUND;
-		goto error;
-	}
-
-	ret = fdt_open_into(dtb, dtb, XILINX_OF_BOARD_DTB_MAX_SIZE);
+	ret = is_valid_dtb(dtb);
 	if (ret < 0) {
 		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
-		ret  = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
 	node = fdt_get_stdout_node_offset(dtb);
 	if (node < 0) {
 		ERROR("DT get stdout node failed : %d\n", node);
-		ret  = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
 	ret = fdt_add_uart_info(info, node, dtb);
 	if (ret < 0) {
 		ERROR("Failed to add DT UART info: %d\n", ret);
-		ret  = -FDT_ERR_NOTFOUND;
 		goto error;
 	}
 
 error:
 	return ret;
 }
-
-/**
- * check_fdt_uart_info() - Check early uart info with DTB uart info.
- * @info: Pointer to the UART information structure.
- *
- * Return: On success, it returns 0; on failure, it returns an error+reason.
- */
-static int check_fdt_uart_info(dt_uart_info_t *info)
-{
-	uint32_t ret = 0;
-
-	if (info->status == 0) {
-		ret = -ENODEV;
-		goto error;
-	}
-
-	if ((info->base == console.base) &&
-	   (info->baud_rate == UART_BAUDRATE) && !CONSOLE_IS(dcc)) {
-		ret = -ENODEV;
-		goto error;
-	}
-
-error:
-	return ret;
-}
-
-/**
- * console_boot_end() - Unregister the console_t instance form the console list.
- * @boot_console: Pointer to the console information structure.
- */
-static void console_boot_end(console_t *boot_console)
-{
-	if (CONSOLE_IS(dcc)) {
-		console_dcc_unregister();
-	} else {
-		console_flush();
-		(void)console_unregister(boot_console);
-	}
-}
-
-/**
- * setup_runtime_console() - Registers the runtime uart with console list.
- * @clock: UART clock.
- * @info: Pointer to the UART information structure.
- */
-static void setup_runtime_console(uint32_t clock, dt_uart_info_t *info)
-{
-	static console_t bl31_runtime_console;
-	uint32_t rc;
-
-#if defined(PLAT_zynqmp)
-	rc = console_cdns_register(info->base,
-				   clock,
-				   info->baud_rate,
-				   &bl31_runtime_console);
-#else
-	rc = console_pl011_register(info->base,
-				    clock,
-				    info->baud_rate,
-				    &bl31_runtime_console);
 #endif
-	if (rc == 0) {
-		panic();
-	}
-
-	console_set_scope(&bl31_runtime_console,
-			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME |
-			  CONSOLE_FLAG_CRASH);
-}
 
-
-/**
- * runtime_console_init() - Initializes the run time console information.
- * @uart_info: Pointer to the UART information structure.
- * @bl31_boot_console: Pointer to the console information structure.
- * @clock: UART clock.
- *
- * Return: On success, it returns 0; on failure, it returns an error+reason;
- */
-static int32_t runtime_console_init(dt_uart_info_t *uart_info,
-			  console_t *bl31_boot_console,
-			  uint32_t clock)
+void setup_console(void)
 {
-	int32_t rc = 0;
-
-	/* Parse UART information from Device Tree Blob (DTB) */
-	rc = fdt_get_uart_info(uart_info);
-	if (rc < 0) {
-		rc = -FDT_ERR_NOTFOUND;
-	}
-
-	if (strncmp(uart_info->compatible, DT_UART_COMPAT,
-		   strlen(DT_UART_COMPAT)) == 0) {
-
-		if (check_fdt_uart_info(uart_info) == 0) {
-			setup_runtime_console(clock, uart_info);
-			console_boot_end(bl31_boot_console);
-			INFO("Runtime console setup\n");
-		} else {
-			INFO("Early console and DTB console are same\n");
-		}
-	} else if (strncmp(uart_info->compatible, DT_UART_DCC_COMPAT,
-			  strlen(DT_UART_DCC_COMPAT)) == 0) {
-		rc = console_dcc_register();
-		if (rc == 0) {
-			panic();
+	/* This is hardcoded console setup just in case that DTB console fails */
+	boot_hd_console.base = (uintptr_t)UART_BASE;
+	boot_hd_console.baud_rate = (uint32_t)UART_BAUDRATE;
+	boot_hd_console.clk = get_uart_clk();
+	boot_hd_console.console_scope = CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH;
+	boot_hd_console.console_type = UART_TYPE;
+
+	/* For DT code decoding uncomment console registration below */
+	/* register_console(&boot_hd_console, &boot_console); */
+
+#if ((CONSOLE_IS(dtb) || RT_CONSOLE_IS(dtb)) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	(!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+				   !IS_TFA_IN_OCM(BL31_BASE)))
+	/* Parse DTB console for UART information  */
+	if (fdt_get_uart_info(&dt_uart_info) == 0) {
+		if (CONSOLE_IS(dtb)) {
+			boot_hd_console.base = dt_uart_info.base;
+			boot_hd_console.baud_rate = dt_uart_info.baud_rate;
+			boot_hd_console.console_type = dt_uart_info.console_type;
 		}
-		console_boot_end(bl31_boot_console);
 	} else {
-		WARN("BL31: No console device found in DT.\n");
+		ERROR("Failed to initialize DT console or console node is disabled\n");
 	}
-
-	return rc;
-}
 #endif
 
-void setup_console(void)
-{
-	uint32_t rc;
-	uint32_t uart_clk = get_uart_clk();
+	/* Initialize the boot console */
+	register_console(&boot_hd_console, &boot_console);
 
-#if defined(PLAT_zynqmp)
-	if (CONSOLE_IS(cadence) || (CONSOLE_IS(cadence1))) {
-		rc = console_cdns_register(UART_BASE,
-					   uart_clk,
-					   UART_BAUDRATE,
-					   &console);
-		if (rc == 0) {
-			panic();
-		}
+	INFO("BL31: Early console setup\n");
 
-		console_set_scope(&console, CONSOLE_FLAG_BOOT |
-				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	}
+#ifdef CONSOLE_RUNTIME
+#if (RT_CONSOLE_IS(dtb) && defined(XILINX_OF_BOARD_DTB_ADDR)) && \
+	       (!defined(PLAT_zynqmp) || (defined(PLAT_zynqmp) && \
+					!IS_TFA_IN_OCM(BL31_BASE)))
+	rt_hd_console.base = dt_uart_info.base;
+	rt_hd_console.baud_rate = dt_uart_info.baud_rate;
+	rt_hd_console.console_type = dt_uart_info.console_type;
 #else
-	if (CONSOLE_IS(pl011) || (CONSOLE_IS(pl011_1))) {
-		/* Initialize the console to provide early debug support */
-		rc = console_pl011_register((uint32_t)UART_BASE,
-					   uart_clk,
-					   (uint32_t)UART_BAUDRATE,
-					   &console);
-		if (rc == 0) {
-			panic();
-		}
-
-		console_set_scope(&console, CONSOLE_FLAG_BOOT |
-				  CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	}
+	rt_hd_console.base = (uintptr_t)RT_UART_BASE;
+	rt_hd_console.baud_rate = (uint32_t)UART_BAUDRATE;
+	rt_hd_console.console_type = RT_UART_TYPE;
 #endif
-	if (CONSOLE_IS(dcc)) {
-		/* Initialize the dcc console for debug */
-		rc = console_dcc_register();
-		if (rc == 0) {
-			panic();
-		}
-	}
-	INFO("BL31: Early console setup\n");
 
-#if (defined(XILINX_OF_BOARD_DTB_ADDR) && !IS_TFA_IN_OCM(BL31_BASE))
-	static dt_uart_info_t uart_info = {0};
+	if ((rt_hd_console.console_type == boot_hd_console.console_type) &&
+			(rt_hd_console.base == boot_hd_console.base)) {
+		console_set_scope(&boot_console,
+				CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH | CONSOLE_FLAG_RUNTIME);
+		INFO("Successfully initialized runtime console\n");
+	} else {
+		rt_hd_console.clk = get_uart_clk();
+		rt_hd_console.console_scope = CONSOLE_FLAG_RUNTIME;
 
-	/* Initialize the runtime console using UART information from the DTB */
-	rc = runtime_console_init(&uart_info, &console, uart_clk);
-	if (rc < 0) {
-		ERROR("Failed to initialize runtime console: %d\n", rc);
+		register_console(&rt_hd_console, &runtime_console);
+		INFO("Successfully initialized new runtime console\n");
 	}
 #endif
 }
+#else
+void setup_console(void)
+{
+}
+#endif
diff --git a/plat/xilinx/common/plat_fdt.c b/plat/xilinx/common/plat_fdt.c
index de5d1a1f..4ad7b2d0 100644
--- a/plat/xilinx/common/plat_fdt.c
+++ b/plat/xilinx/common/plat_fdt.c
@@ -13,6 +13,91 @@
 #include <plat_fdt.h>
 #include <platform_def.h>
 
+#if defined(XILINX_OF_BOARD_DTB_ADDR)
+
+#define FIT_CONFS_PATH	"/configurations"
+
+static uint8_t is_fit_image(void *dtb)
+{
+	int64_t confs_noffset;
+	uint8_t status = 0;
+
+	confs_noffset = fdt_path_offset(dtb, FIT_CONFS_PATH);
+	/*confs_noffset is only present on FIT image */
+	if (confs_noffset < 0) {
+		status = 0;
+	} else {
+		status = 1;
+	}
+
+	return status;
+}
+
+int32_t is_valid_dtb(void *fdt)
+{
+	int32_t ret = 0;
+
+	if (fdt_check_header(fdt) != 0) {
+		ERROR("Can't read DT at %p\n", fdt);
+		ret = -FDT_ERR_NOTFOUND;
+		goto error;
+	}
+
+	ret = fdt_open_into(fdt, fdt, XILINX_OF_BOARD_DTB_MAX_SIZE);
+	if (ret < 0) {
+		ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
+		ret = -FDT_ERR_NOTFOUND;
+		goto error;
+	}
+
+	if (is_fit_image(fdt) != 0U) {
+		WARN("FIT image detected, TF-A will not update DTB for DDR address space\n");
+		ret = -FDT_ERR_NOTFOUND;
+	}
+error:
+	return ret;
+}
+
+static int add_mmap_dynamic_region(unsigned long long base_pa, uintptr_t base_va,
+			    size_t size, unsigned int attr)
+{
+	int ret = 0;
+#if defined(PLAT_XLAT_TABLES_DYNAMIC)
+	ret = mmap_add_dynamic_region(base_pa, base_va, size, attr);
+	if (ret != 0) {
+		WARN("Failed to add dynamic region for dtb: error %d\n",
+		     ret);
+	}
+#endif
+	return ret;
+}
+
+static int remove_mmap_dynamic_region(uintptr_t base_va, size_t size)
+{
+	int ret = 0;
+#if defined(PLAT_XLAT_TABLES_DYNAMIC)
+	ret = mmap_remove_dynamic_region(base_va, size);
+	if (ret != 0) {
+		WARN("Failed to remove dynamic region for dtb:error %d\n",
+		     ret);
+	}
+#endif
+	return ret;
+}
+#endif
+
+#if defined(XILINX_OF_BOARD_DTB_ADDR)
+static int check_fdt_reserved_memory(void *dtb, const char *node_name)
+{
+	int offset = fdt_path_offset(dtb, "/reserved-memory");
+
+	if (offset >= 0) {
+		offset = fdt_subnode_offset(dtb, offset, node_name);
+	}
+	return offset;
+}
+#endif
+
 void prepare_dtb(void)
 {
 #if defined(XILINX_OF_BOARD_DTB_ADDR)
@@ -24,75 +109,51 @@ void prepare_dtb(void)
 
 	if (!IS_TFA_IN_OCM(BL31_BASE)) {
 
-#if defined(PLAT_XLAT_TABLES_DYNAMIC)
-		map_ret = mmap_add_dynamic_region((unsigned long long)dtb,
-						 (uintptr_t)dtb,
-						 XILINX_OF_BOARD_DTB_MAX_SIZE,
-						 MT_MEMORY | MT_RW | MT_NS);
-		if (map_ret != 0) {
-			WARN("Failed to add dynamic region for dtb: error %d\n",
-			     map_ret);
-		}
-#endif
-
-		if (!map_ret) {
+		map_ret = add_mmap_dynamic_region((unsigned long long)dtb,
+						  (uintptr_t)dtb,
+						  XILINX_OF_BOARD_DTB_MAX_SIZE,
+						  MT_MEMORY | MT_RW | MT_NS);
+		if (map_ret == 0) {
 			/* Return if no device tree is detected */
-			if (fdt_check_header(dtb) != 0) {
-				NOTICE("Can't read DT at %p\n", dtb);
-			} else {
-				ret = fdt_open_into(dtb, dtb, XILINX_OF_BOARD_DTB_MAX_SIZE);
-
-				if (ret < 0) {
-					ERROR("Invalid Device Tree at %p: error %d\n",
-					      dtb, ret);
-				} else {
-
-					if (dt_add_psci_node(dtb)) {
-						WARN("Failed to add PSCI Device Tree node\n");
-					}
+			if (is_valid_dtb(dtb) == 0) {
+				if (dt_add_psci_node(dtb)) {
+					WARN("Failed to add PSCI Device Tree node\n");
+				}
 
-					if (dt_add_psci_cpu_enable_methods(dtb)) {
-						WARN("Failed to add PSCI cpu enable methods in DT\n");
-					}
+				if (dt_add_psci_cpu_enable_methods(dtb)) {
+					WARN("Failed to add PSCI cpu enable methods in DT\n");
+				}
 
+				/* Check reserved memory set in DT*/
+				ret = check_fdt_reserved_memory(dtb, "tf-a");
+				if (ret < 0) {
 					/* Reserve memory used by Trusted Firmware. */
-					ret = fdt_add_reserved_memory(dtb,
-								     "tf-a",
-								     BL31_BASE,
-								     BL31_LIMIT
-								     -
-								     BL31_BASE);
+					ret = fdt_add_reserved_memory(dtb, "tf-a",
+							BL31_BASE,
+							BL31_LIMIT - BL31_BASE);
 					if (ret < 0) {
 						WARN("Failed to add reserved memory nodes for BL31 to DT.\n");
 					}
 
-					ret = fdt_pack(dtb);
-					if (ret < 0) {
-						WARN("Failed to pack dtb at %p: error %d\n",
-						     dtb, ret);
-					}
-					flush_dcache_range((uintptr_t)dtb,
-							   fdt_blob_size(dtb));
-
-					INFO("Changed device tree to advertise PSCI and reserved memories.\n");
-
+				} else {
+					WARN("Reserved memory pre-exists in DT.\n");
 				}
-			}
 
-		}
+				ret = fdt_pack(dtb);
+				if (ret < 0) {
+					WARN("Failed to pack dtb at %p: error %d\n", dtb, ret);
+				}
+				flush_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb));
 
+				INFO("Changed device tree to advertise PSCI and reserved memories.\n");
+			}
 
-#if defined(PLAT_XLAT_TABLES_DYNAMIC)
-		if (!map_ret) {
-			ret = mmap_remove_dynamic_region((uintptr_t)dtb,
-					 XILINX_OF_BOARD_DTB_MAX_SIZE);
+			ret = remove_mmap_dynamic_region((uintptr_t)dtb,
+							 XILINX_OF_BOARD_DTB_MAX_SIZE);
 			if (ret != 0) {
-				WARN("Failed to remove dynamic region for dtb:error %d\n",
-					ret);
+				WARN("Failed to remove mmap dynamic regions.\n");
 			}
 		}
-#endif
 	}
-
 #endif
 }
diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c
index 5beb7658..149ba2dc 100644
--- a/plat/xilinx/common/plat_startup.c
+++ b/plat/xilinx/common/plat_startup.c
@@ -237,8 +237,8 @@ enum xbl_handoff xbl_handover(entry_point_info_t *bl32,
 		}
 
 		target_secure = get_xbl_ss(&HandoffParams->partition[i]);
-		if (target_secure == XBL_FLAGS_SECURE &&
-		    target_el == XBL_FLAGS_EL2) {
+		if ((target_secure == XBL_FLAGS_SECURE) &&
+		    (target_el == XBL_FLAGS_EL2)) {
 			WARN("BL31: invalid security state (%i) for exception level (%i)\n",
 			     target_secure, target_el);
 			continue;
@@ -284,7 +284,7 @@ enum xbl_handoff xbl_handover(entry_point_info_t *bl32,
 		}
 
 		VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n",
-			target_secure == XBL_FLAGS_SECURE ? "BL32" : "BL33",
+			(target_secure == XBL_FLAGS_SECURE) ? "BL32" : "BL33",
 			HandoffParams->partition[i].entry_point,
 			target_el);
 		image->pc = HandoffParams->partition[i].entry_point;
diff --git a/plat/xilinx/common/plat_xfer_list.c b/plat/xilinx/common/plat_xfer_list.c
new file mode 100644
index 00000000..eae7ce4e
--- /dev/null
+++ b/plat/xilinx/common/plat_xfer_list.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stddef.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/transfer_list.h>
+
+/*
+ * FIXME: This address should come from firmware before TF-A runs
+ * Having this to make sure the transfer list functionality works
+ */
+#define FW_HANDOFF_BASE		U(0x1200000)
+#define FW_HANDOFF_SIZE		U(0x600000)
+
+static struct transfer_list_header *tl_hdr;
+
+int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
+				       entry_point_info_t *bl33)
+{
+	struct transfer_list_entry *te = NULL;
+	struct entry_point_info *ep;
+	int32_t ret;
+
+	tl_hdr = (struct transfer_list_header *)FW_HANDOFF_BASE;
+	ret = transfer_list_check_header(tl_hdr);
+	if ((ret == TL_OPS_ALL) || (ret == TL_OPS_RO)) {
+		transfer_list_dump(tl_hdr);
+		while ((te = transfer_list_next(tl_hdr, te)) != NULL) {
+			ep = transfer_list_entry_data(te);
+			if (te->tag_id == TL_TAG_EXEC_EP_INFO64) {
+				switch (GET_SECURITY_STATE(ep->h.attr)) {
+				case NON_SECURE:
+					*bl33 = *ep;
+					continue;
+				case SECURE:
+					*bl32 = *ep;
+					continue;
+				default:
+					ERROR("Unrecognized Image Security State %lu\n",
+					      GET_SECURITY_STATE(ep->h.attr));
+					ret = TL_OPS_NON;
+				}
+			}
+		}
+	}
+	return ret;
+}
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index ffc39bbe..e9c5f138 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,7 +50,7 @@ void pm_client_set_wakeup_sources(uint32_t node_id)
 {
 	uint32_t reg_num, device_id;
 	uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = {0U};
-	uint32_t isenabler1 = PLAT_GICD_BASE_VALUE + GICD_ISENABLER + 4U;
+	uint32_t isenabler1 = PLAT_ARM_GICD_BASE + GICD_ISENABLER + 4U;
 
 	zeromem(&pm_wakeup_nodes_set, (u_register_t)sizeof(pm_wakeup_nodes_set));
 
@@ -122,7 +122,7 @@ enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1,
 	}
 
 	PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5);
-	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT);
+	return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, RET_PAYLOAD_ARG_CNT);
 }
 
 /**
@@ -286,112 +286,6 @@ enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t fl
 	return ret;
 }
 
-/**
- * pm_pll_set_param() - Set PLL parameter.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Value to set for PLL parameter.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
-				    uint32_t value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
-			 clk_id, param, value);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_param() - Get PLL parameter value.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Buffer to store PLL parameter value.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
-				    uint32_t *value, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
-			 clk_id, param);
-
-	return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_pll_set_mode() - Set PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: PLL mode.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
-				   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
-			 clk_id, mode);
-
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_mode() - Get PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: Buffer to store PLL mode.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
-				   uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
-			 clk_id);
-
-	return pm_ipi_send_sync(primary_proc, payload, mode, 1);
-}
-
 /**
  * pm_force_powerdown() - PM call to request for another PU or subsystem to
  *                        be powered down forcefully.
@@ -448,131 +342,58 @@ enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
 }
 
 /**
- * pm_query_data() -  PM API for querying firmware data.
- * @qid: The type of data to query.
- * @arg1: Argument 1 to requested query data call.
- * @arg2: Argument 2 to requested query data call.
- * @arg3: Argument 3 to requested query data call.
- * @data: Returned output data.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
+ * pm_set_wakeup_source() - PM call to specify the wakeup source while
+ *                          suspended.
+ * @target: Device id of the targeted PU or subsystem
+ * @wkup_device: Device id of the wakeup peripheral
+ * @enable: Enable or disable the specified peripheral as wake source
+ * @flag: 0 - Call from secure source
+ *        1 - Call from non-secure source
  *
- * Return: 0 if success else non-zero error code of type
- *         enum pm_ret_status.
+ * Return: Returns status, either success or error+reason.
  *
  */
-enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
-				 uint32_t arg3, uint32_t *data, uint32_t flag)
+enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
+					uint8_t enable, uint32_t flag)
 {
-	uint32_t ret;
-	uint32_t version[PAYLOAD_ARG_CNT] = {0};
 	uint32_t payload[PAYLOAD_ARG_CNT];
-	uint32_t fw_api_version;
 
-	/* Send request to the PMC */
-	PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
-			 arg1, arg2, arg3);
-
-	ret = pm_feature_check((uint32_t)PM_QUERY_DATA, &version[0], flag);
-	if (ret == PM_RET_SUCCESS) {
-		fw_api_version = version[0] & 0xFFFFU;
-		if ((fw_api_version == 2U) &&
-		    ((qid == XPM_QID_CLOCK_GET_NAME) ||
-		     (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
-			if (ret == PM_RET_SUCCESS) {
-				ret = data[0];
-				data[0] = data[1];
-				data[1] = data[2];
-				data[2] = data[3];
-			}
-		} else {
-			ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
-		}
-	}
-	return ret;
+	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE,
+			 target, wkup_device, enable);
+	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
 }
+
 /**
- * pm_api_ioctl() -  PM IOCTL API for device control and configs.
- * @device_id: Device ID.
- * @ioctl_id: ID of the requested IOCTL.
- * @arg1: Argument 1 to requested IOCTL call.
- * @arg2: Argument 2 to requested IOCTL call.
- * @arg3: Argument 3 to requested IOCTL call.
- * @value: Returned output value.
- * @flag: 0 - Call from secure source.
- *        1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * This function calls IOCTL to firmware for device control and configuration.
- *
- * Return: Returns status, either 0 on success or non-zero error code
- *         of type enum pm_ret_status.
+ * eemi_feature_check() - Returns the supported API version if supported.
+ * @api_id: API ID to check.
+ * @ret_payload: pointer to array of PAYLOAD_ARG_CNT number of
+ *               words Returned supported API version
  *
+ * Return: Returns status, either success or error+reason.
  */
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
-				uint32_t arg1, uint32_t arg2, uint32_t arg3,
-				uint32_t *value, uint32_t flag)
+enum pm_ret_status eemi_feature_check(uint32_t api_id, uint32_t *ret_payload)
 {
 	enum pm_ret_status ret;
 
-	switch (ioctl_id) {
-	case IOCTL_SET_PLL_FRAC_MODE:
-		ret =  pm_pll_set_mode(arg1, arg2, flag);
-		break;
-	case IOCTL_GET_PLL_FRAC_MODE:
-		ret =  pm_pll_get_mode(arg1, value, flag);
-		break;
-	case IOCTL_SET_PLL_FRAC_DATA:
-		ret =  pm_pll_set_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, arg2, flag);
-		break;
-	case IOCTL_GET_PLL_FRAC_DATA:
-		ret =  pm_pll_get_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, value, flag);
+	/* Return version of API which are implemented in TF-A only */
+	switch (api_id) {
+	case PM_GET_CALLBACK_DATA:
+	case PM_GET_TRUSTZONE_VERSION:
+		ret_payload[0] = PM_API_VERSION_2;
+		ret = PM_RET_SUCCESS;
 		break;
-	case IOCTL_SET_SGI:
-		/* Get the sgi number */
-		ret = pm_register_sgi(arg1, arg2);
-		if (ret != 0) {
-			return PM_RET_ERROR_ARGS;
-		}
+	case TF_A_PM_REGISTER_SGI:
+	case TF_A_FEATURE_CHECK:
+		ret_payload[0] = PM_API_BASE_VERSION;
 		ret = PM_RET_SUCCESS;
 		break;
 	default:
-		return PM_RET_ERROR_NOTSUPPORTED;
+		ret = PM_RET_ERROR_NO_FEATURE;
 	}
 
 	return ret;
 }
 
-/**
- * pm_set_wakeup_source() - PM call to specify the wakeup source while
- *                          suspended.
- * @target: Device id of the targeted PU or subsystem
- * @wkup_device: Device id of the wakeup peripheral
- * @enable: Enable or disable the specified peripheral as wake source
- * @flag: 0 - Call from secure source
- *        1 - Call from non-secure source
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device,
-					uint8_t enable, uint32_t flag)
-{
-	uint32_t payload[PAYLOAD_ARG_CNT];
-
-	PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE,
-			 target, wkup_device, enable);
-	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
 /**
  * pm_feature_check() - Returns the supported API version if supported.
  * @api_id: API ID to check.
@@ -616,7 +437,7 @@ enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload,
 
 	PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
 			 PM_FEATURE_CHECK, api_id);
-	return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT);
+	return pm_ipi_send_sync(primary_proc, payload, ret_payload, RET_PAYLOAD_ARG_CNT);
 }
 
 /**
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 56567dd6..c3872fc0 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -169,9 +169,7 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
 	size_t i;
 	enum pm_ret_status ret;
 #if IPI_CRC_CHECK
-	uint32_t *payload_ptr = value;
-	size_t j;
-	uint32_t response_payload[PAYLOAD_ARG_CNT];
+	uint32_t crc;
 #endif
 	uintptr_t buffer_base = proc->ipi->buffer_base +
 				IPI_BUFFER_TARGET_REMOTE_OFFSET +
@@ -184,27 +182,20 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
 	 * buf-2: unused
 	 * buf-3: unused
 	 */
-	for (i = 1; i <= count; i++) {
-		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
-		value++;
+	for (i = 0U; i < count; i++) {
+		value[i] = mmio_read_32(buffer_base + ((i + 1U) * PAYLOAD_ARG_SIZE));
 	}
 
 	ret = mmio_read_32(buffer_base);
 #if IPI_CRC_CHECK
-	for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
-		response_payload[j] = mmio_read_32(buffer_base +
-						(j * PAYLOAD_ARG_SIZE));
-	}
-
-	if (response_payload[PAYLOAD_CRC_POS] !=
-			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
-		NOTICE("ERROR in CRC response payload value:0x%x\n",
-					response_payload[PAYLOAD_CRC_POS]);
+	crc = mmio_read_32(buffer_base + (PAYLOAD_CRC_POS * PAYLOAD_ARG_SIZE));
+	if (crc != calculate_crc((uint32_t *)buffer_base, IPI_W0_TO_W6_SIZE)) {
+		NOTICE("ERROR in CRC response payload value:0x%x\n", crc);
 		ret = PM_RET_ERROR_INVALID_CRC;
 		/* Payload data is invalid as CRC validation failed
 		 * Clear the payload to avoid leakage of data to upper layers
 		 */
-		memset(payload_ptr, 0, count);
+		memset(value, 0, count);
 	}
 #endif
 
@@ -226,39 +217,31 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
 enum pm_ret_status pm_ipi_buff_read_callb(uint32_t *value, size_t count)
 {
 	size_t i;
+	size_t local_count = count;
 #if IPI_CRC_CHECK
-	uint32_t *payload_ptr = value;
-	size_t j;
-	unsigned int response_payload[PAYLOAD_ARG_CNT] = {0};
+	uint32_t crc;
 #endif
 	uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE +
 				IPI_BUFFER_TARGET_LOCAL_OFFSET +
 				IPI_BUFFER_REQ_OFFSET;
 	enum pm_ret_status ret = PM_RET_SUCCESS;
 
-	if (count > IPI_BUFFER_MAX_WORDS) {
-		count = IPI_BUFFER_MAX_WORDS;
+	if (local_count > IPI_BUFFER_MAX_WORDS) {
+		local_count = IPI_BUFFER_MAX_WORDS;
 	}
 
-	for (i = 0; i <= count; i++) {
-		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
-		value++;
+	for (i = 0; i < count; i++) {
+		value[i] = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
 	}
 #if IPI_CRC_CHECK
-	for (j = 0; j < PAYLOAD_ARG_CNT; j++) {
-		response_payload[j] = mmio_read_32(buffer_base +
-						(j * PAYLOAD_ARG_SIZE));
-	}
-
-	if (response_payload[PAYLOAD_CRC_POS] !=
-			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) {
-		NOTICE("ERROR in CRC response payload value:0x%x\n",
-					response_payload[PAYLOAD_CRC_POS]);
+	crc = mmio_read_32(buffer_base + (PAYLOAD_CRC_POS * PAYLOAD_ARG_SIZE));
+	if (crc != calculate_crc((uint32_t *)buffer_base, IPI_W0_TO_W6_SIZE)) {
+		NOTICE("ERROR in CRC response payload value:0x%x\n", crc);
 		ret = PM_RET_ERROR_INVALID_CRC;
 		/* Payload data is invalid as CRC validation failed
 		 * Clear the payload to avoid leakage of data to upper layers
 		 */
-		memset(payload_ptr, 0, count);
+		memset(value, 0, local_count);
 	}
 #endif
 	return ret;
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 1e5808cf..afb9a967 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,8 @@
 
 #include <common/runtime_svc.h>
 #include <drivers/arm/gicv3.h>
+#include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
 #include <plat_private.h>
@@ -31,33 +33,131 @@
 #define INVALID_SGI    0xFFU
 #define PM_INIT_SUSPEND_CB	(30U)
 #define PM_NOTIFY_CB		(32U)
+#define EVENT_CPU_PWRDWN	(4U)
+#define MBOX_SGI_SHARED_IPI	(7U)
+
+/**
+ * upper_32_bits - return bits 32-63 of a number
+ * @n: the number we're accessing
+ */
+#define upper_32_bits(n)	((uint32_t)((n) >> 32U))
+
+/**
+ * lower_32_bits - return bits 0-31 of a number
+ * @n: the number we're accessing
+ */
+#define lower_32_bits(n)	((uint32_t)((n) & 0xffffffffU))
+
+/**
+ * EXTRACT_SMC_ARGS - extracts 32-bit payloads from 64-bit SMC arguments
+ * @pm_arg: array of 32-bit payloads
+ * @x: array of 64-bit SMC arguments
+ */
+#define EXTRACT_ARGS(pm_arg, x)						\
+	for (uint32_t i = 0U; i < (PAYLOAD_ARG_CNT - 1U); i++) {	\
+		if ((i % 2U) != 0U) {					\
+			pm_arg[i] = lower_32_bits(x[(i / 2U) + 1U]);	\
+		} else {						\
+			pm_arg[i] = upper_32_bits(x[i / 2U]);		\
+		}							\
+	}
+
+/* 1 sec of wait timeout for secondary core down */
+#define PWRDWN_WAIT_TIMEOUT	(1000U)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_asgi1r_el1, S3_0_C12_C11_6)
 
 /* pm_up = true - UP, pm_up = false - DOWN */
 static bool pm_up;
 static uint32_t sgi = (uint32_t)INVALID_SGI;
+bool pwrdwn_req_received;
 
 static void notify_os(void)
 {
-	int32_t cpu;
-	uint32_t reg;
+	plat_ic_raise_ns_sgi(sgi, read_mpidr_el1());
+}
 
-	cpu = plat_my_core_pos() + 1U;
+static uint64_t cpu_pwrdwn_req_handler(uint32_t id, uint32_t flags,
+				       void *handle, void *cookie)
+{
+	(void)id;
+	(void)flags;
+	(void)handle;
+	(void)cookie;
+	uint32_t cpu_id = plat_my_core_pos();
+
+	VERBOSE("Powering down CPU %d\n", cpu_id);
+
+	/* Deactivate CPU power down SGI */
+	plat_ic_end_of_interrupt(CPU_PWR_DOWN_REQ_INTR);
 
-	reg = (cpu | (sgi << XSCUGIC_SGIR_EL1_INITID_SHIFT));
-	write_icc_asgi1r_el1(reg);
+	return psci_cpu_off();
+}
+
+/**
+ * raise_pwr_down_interrupt() - Callback function to raise SGI.
+ * @mpidr: MPIDR for the target CPU.
+ *
+ * Raise SGI interrupt to trigger the CPU power down sequence on all the
+ * online secondary cores.
+ */
+static void raise_pwr_down_interrupt(u_register_t mpidr)
+{
+	plat_ic_raise_el3_sgi(CPU_PWR_DOWN_REQ_INTR, mpidr);
+}
+
+void request_cpu_pwrdwn(void)
+{
+	enum pm_ret_status ret;
+
+	VERBOSE("CPU power down request received\n");
+
+	/* Send powerdown request to online secondary core(s) */
+	ret = psci_stop_other_cores(PWRDWN_WAIT_TIMEOUT, raise_pwr_down_interrupt);
+	if (ret != PSCI_E_SUCCESS) {
+		ERROR("Failed to powerdown secondary core(s)\n");
+	}
+
+	/* Clear IPI IRQ */
+	pm_ipi_irq_clear(primary_proc);
+
+	/* Deactivate IPI IRQ */
+	plat_ic_end_of_interrupt(PLAT_VERSAL_IPI_IRQ);
 }
 
 static uint64_t ipi_fiq_handler(uint32_t id, uint32_t flags, void *handle,
 				void *cookie)
 {
+	(void)flags;
+	(void)handle;
+	(void)cookie;
 	uint32_t payload[4] = {0};
 	enum pm_ret_status ret;
+	int ipi_status, i;
 
 	VERBOSE("Received IPI FIQ from firmware\n");
 
+	console_flush();
 	(void)plat_ic_acknowledge_interrupt();
 
+	/* Check status register for each IPI except PMC */
+	for (i = IPI_ID_APU; i <= IPI_ID_5; i++) {
+		ipi_status = ipi_mb_enquire_status(IPI_ID_APU, i);
+
+		/* If any agent other than PMC has generated IPI FIQ then send SGI to mbox driver */
+		if (ipi_status & IPI_MB_STATUS_RECV_PENDING) {
+			plat_ic_raise_ns_sgi(MBOX_SGI_SHARED_IPI, read_mpidr_el1());
+			break;
+		}
+	}
+
+	/* If PMC has not generated interrupt then end ISR */
+	ipi_status = ipi_mb_enquire_status(IPI_ID_APU, IPI_ID_PMC);
+	if ((ipi_status & IPI_MB_STATUS_RECV_PENDING) == 0) {
+		plat_ic_end_of_interrupt(id);
+		return 0;
+	}
+
+	/* Handle PMC case */
 	ret = pm_get_callbackdata(payload, ARRAY_SIZE(payload), 0, 0);
 	if (ret != PM_RET_SUCCESS) {
 		payload[0] = ret;
@@ -65,9 +165,26 @@ static uint64_t ipi_fiq_handler(uint32_t id, uint32_t flags, void *handle,
 
 	switch (payload[0]) {
 	case PM_INIT_SUSPEND_CB:
+		if (sgi != INVALID_SGI) {
+			notify_os();
+		}
+		break;
 	case PM_NOTIFY_CB:
 		if (sgi != INVALID_SGI) {
+			if (payload[2] == EVENT_CPU_PWRDWN) {
+				if (pwrdwn_req_received) {
+					pwrdwn_req_received = false;
+					request_cpu_pwrdwn();
+					(void)psci_cpu_off();
+					break;
+				} else {
+					pwrdwn_req_received = true;
+				}
+			}
 			notify_os();
+		} else if (payload[2] == EVENT_CPU_PWRDWN) {
+			request_cpu_pwrdwn();
+			(void)psci_cpu_off();
 		}
 		break;
 	case PM_RET_ERROR_INVALID_CRC:
@@ -139,6 +256,12 @@ int32_t pm_setup(void)
 	pm_ipi_init(primary_proc);
 	pm_up = true;
 
+	/* register SGI handler for CPU power down request */
+	ret = request_intr_type_el3(CPU_PWR_DOWN_REQ_INTR, cpu_pwrdwn_req_handler);
+	if (ret != 0) {
+		WARN("BL31: registering SGI interrupt failed\n");
+	}
+
 	/*
 	 * Enable IPI IRQ
 	 * assume the rich OS is OK to handle callback IRQs now.
@@ -153,6 +276,14 @@ int32_t pm_setup(void)
 	}
 
 	gicd_write_irouter(gicv3_driver_data->gicd_base, PLAT_VERSAL_IPI_IRQ, MODE);
+
+	/* Register for idle callback during force power down/restart */
+	ret = pm_register_notifier(primary_proc->node_id, EVENT_CPU_PWRDWN,
+				   0x0U, 0x1U, SECURE_FLAG);
+	if (ret != 0) {
+		WARN("BL31: registering idle callback for restart/force power down failed\n");
+	}
+
 	return ret;
 }
 
@@ -178,33 +309,9 @@ static uintptr_t eemi_for_compatibility(uint32_t api_id, uint32_t *pm_arg,
 
 	switch (api_id) {
 
-	case (uint32_t)PM_IOCTL:
-	{
-		uint32_t value = 0U;
-
-		ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
-				   pm_arg[3], pm_arg[4],
-				   &value, security_flag);
-		if (ret == PM_RET_ERROR_NOTSUPPORTED)
-			return (uintptr_t)0;
-
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
-	}
-
-	case (uint32_t)PM_QUERY_DATA:
-	{
-		uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
-
-		ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
-				    pm_arg[3], data, security_flag);
-
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32U),
-			 (uint64_t)data[1] | ((uint64_t)data[2] << 32U));
-	}
-
 	case (uint32_t)PM_FEATURE_CHECK:
 	{
-		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
+		uint32_t result[RET_PAYLOAD_ARG_CNT] = {0U};
 
 		ret = pm_feature_check(pm_arg[0], result, security_flag);
 		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
@@ -293,6 +400,15 @@ static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg,
 {
 	switch (api_id) {
 
+	case TF_A_FEATURE_CHECK:
+	{
+		enum pm_ret_status ret;
+		uint32_t result[PAYLOAD_ARG_CNT] = {0U};
+
+		ret = eemi_feature_check(pm_arg[0], result);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U));
+	}
+
 	case TF_A_PM_REGISTER_SGI:
 	{
 		int32_t ret;
@@ -350,7 +466,7 @@ static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
 			      void *handle, uint32_t security_flag)
 {
 	enum pm_ret_status ret;
-	uint32_t buf[PAYLOAD_ARG_CNT] = {0};
+	uint32_t buf[RET_PAYLOAD_ARG_CNT] = {0};
 
 	ret = pm_handle_eemi_call(security_flag, api_id, pm_arg[0], pm_arg[1],
 				  pm_arg[2], pm_arg[3], pm_arg[4],
@@ -362,9 +478,9 @@ static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
 	 * than other eemi calls.
 	 */
 	if (api_id == (uint32_t)PM_QUERY_DATA) {
-		if ((pm_arg[0] == XPM_QID_CLOCK_GET_NAME ||
-		    pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME) &&
-		    ret == PM_RET_SUCCESS) {
+		if (((pm_arg[0] == XPM_QID_CLOCK_GET_NAME) ||
+		    (pm_arg[0] == XPM_QID_PINCTRL_GET_FUNCTION_NAME)) &&
+		    (ret == PM_RET_SUCCESS)) {
 			SMC_RET2(handle, (uint64_t)buf[0] | ((uint64_t)buf[1] << 32U),
 				(uint64_t)buf[2] | ((uint64_t)buf[3] << 32U));
 		}
@@ -374,6 +490,45 @@ static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
 		 (uint64_t)buf[1] | ((uint64_t)buf[2] << 32U));
 }
 
+/**
+ * eemi_api_handler() - Prepare EEMI payload and perform IPI transaction.
+ * @api_id: identifier for the API being called.
+ * @pm_arg: pointer to the argument data for the API call.
+ * @handle: Pointer to caller's context structure.
+ * @security_flag: SECURE_FLAG or NON_SECURE_FLAG.
+ *
+ * EEMI - Embedded Energy Management Interface is AMD-Xilinx proprietary
+ * protocol to allow communication between power management controller and
+ * different processing clusters.
+ *
+ * This handler prepares EEMI protocol payload received from kernel and performs
+ * IPI transaction.
+ *
+ * Return: If EEMI API found then, uintptr_t type address, else 0
+ */
+static uintptr_t eemi_api_handler(uint32_t api_id, const uint32_t *pm_arg,
+				  void *handle, uint32_t security_flag)
+{
+	enum pm_ret_status ret;
+	uint32_t buf[RET_PAYLOAD_ARG_CNT] = {0U};
+	uint32_t payload[PAYLOAD_ARG_CNT] = {0U};
+	uint32_t module_id;
+
+	module_id = (api_id & MODULE_ID_MASK) >> 8U;
+
+	PM_PACK_PAYLOAD7(payload, module_id, security_flag, api_id,
+			 pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
+			 pm_arg[4], pm_arg[5]);
+
+	ret = pm_ipi_send_sync(primary_proc, payload, (uint32_t *)buf,
+			       RET_PAYLOAD_ARG_CNT);
+
+	SMC_RET4(handle, (uint64_t)ret | ((uint64_t)buf[0] << 32U),
+		 (uint64_t)buf[1] | ((uint64_t)buf[2] << 32U),
+		 (uint64_t)buf[3] | ((uint64_t)buf[4] << 32U),
+		 (uint64_t)buf[5]);
+}
+
 /**
  * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2.
  * @smc_fid: Function Identifier.
@@ -398,11 +553,13 @@ static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
 {
+	(void)cookie;
 	uintptr_t ret;
 	uint32_t pm_arg[PAYLOAD_ARG_CNT] = {0};
 	uint32_t security_flag = NON_SECURE_FLAG;
 	uint32_t api_id;
 	bool status = false, status_tmp = false;
+	const uint64_t x[4] = {x1, x2, x3, x4};
 
 	/* Handle case where PM wasn't initialized properly */
 	if (pm_up == false) {
@@ -420,6 +577,14 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		security_flag = SECURE_FLAG;
 	}
 
+	if ((smc_fid & FUNCID_NUM_MASK) == PASS_THROUGH_FW_CMD_ID) {
+		api_id = lower_32_bits(x[0]);
+
+		EXTRACT_ARGS(pm_arg, x);
+
+		return eemi_api_handler(api_id, pm_arg, handle, security_flag);
+	}
+
 	pm_arg[0] = (uint32_t)x1;
 	pm_arg[1] = (uint32_t)(x1 >> 32U);
 	pm_arg[2] = (uint32_t)x2;
diff --git a/plat/xilinx/common/versal.c b/plat/xilinx/common/versal.c
index 3ea022cf..b37dc76c 100644
--- a/plat/xilinx/common/versal.c
+++ b/plat/xilinx/common/versal.c
@@ -7,6 +7,7 @@
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <lib/smccc.h>
+#include <plat/common/platform.h>
 #include <services/arm_arch_svc.h>
 
 #include <plat_private.h>
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index aba190de..4236d8a9 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -1,12 +1,11 @@
 /*
  * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <common/debug.h>
-#include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
@@ -18,6 +17,7 @@
 #include <versal_def.h>
 
 uint32_t platform_id, platform_version;
+uint32_t cpu_clock;
 
 /*
  * Table of regions to map using the MMU.
@@ -38,24 +38,10 @@ const mmap_region_t *plat_get_mmap(void)
 	return plat_versal_mmap;
 }
 
-static void versal_print_platform_name(void)
-{
-	NOTICE("TF-A running on %s\n", PLATFORM_NAME);
-}
-
 void versal_config_setup(void)
 {
 	/* Configure IPI data for versal */
 	versal_ipi_config_table_init();
-
-	versal_print_platform_name();
-
-	generic_delay_timer_init();
-}
-
-uint32_t plat_get_syscnt_freq2(void)
-{
-	return VERSAL_CPU_CLOCK;
 }
 
 void board_detection(void)
@@ -72,9 +58,54 @@ void board_detection(void)
 
 	platform_id = FIELD_GET(PLATFORM_MASK, plat_info[1]);
 	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, plat_info[1]);
+
+	if (platform_id == VERSAL_COSIM) {
+		platform_id = VERSAL_QEMU;
+	}
+}
+
+const char *board_name_decode(void)
+{
+	const char *platform;
+
+	switch (platform_id) {
+	case VERSAL_SPP:
+		platform = "IPP";
+		break;
+	case VERSAL_EMU:
+		platform = "EMU";
+		break;
+	case VERSAL_QEMU:
+		platform = "QEMU";
+		break;
+	case VERSAL_SILICON:
+		platform = "SILICON";
+		break;
+	default:
+		platform = "unknown";
+	}
+
+	return platform;
 }
 
 uint32_t get_uart_clk(void)
 {
-	return UART_CLOCK;
+	uint32_t uart_clock;
+
+	switch (platform_id) {
+	case VERSAL_SPP:
+		uart_clock = 25000000;
+		break;
+	case VERSAL_EMU:
+		uart_clock = 212000;
+		break;
+	case VERSAL_QEMU:
+	case VERSAL_SILICON:
+		uart_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+
+	return uart_clock;
 }
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index cd105c61..819a55b7 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,11 +12,13 @@
 #include <bl31/bl31.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <plat_arm.h>
 #include <plat_console.h>
+#include <plat_clkfunc.h>
 
 #include <plat_fdt.h>
 #include <plat_private.h>
@@ -67,18 +69,14 @@ static inline void bl31_set_default_config(void)
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
+	(void)arg0;
+	(void)arg1;
+	(void)arg2;
+	(void)arg3;
 	uint64_t tfa_handoff_addr;
 	uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE;
 	enum pm_ret_status ret_status;
-	uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
-
-	setup_console();
-
-	/* Initialize the platform config for future decision making */
-	versal_config_setup();
-
-	/* Get platform related information */
-	board_detection();
+	const uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
 
 	/*
 	 * Do initial security configuration to allow DRAM/device access. On
@@ -86,6 +84,32 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	 * other platforms might have more programmable security devices
 	 * present.
 	 */
+	versal_config_setup();
+
+	/* Initialize the platform config for future decision making */
+	board_detection();
+
+	switch (platform_id) {
+	case VERSAL_SPP:
+		cpu_clock = 2720000;
+		break;
+	case VERSAL_EMU:
+		cpu_clock = 212000;
+		break;
+	case VERSAL_QEMU:
+	case VERSAL_SILICON:
+		cpu_clock = 100000000;
+		break;
+	default:
+		panic();
+	}
+	set_cnt_freq();
+
+	generic_delay_timer_init();
+
+	setup_console();
+
+	NOTICE("TF-A running on %s %d\n", board_name_decode(), platform_version);
 
 	/* Populate common information for BL32 and BL33 */
 	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
@@ -107,7 +131,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	enum xbl_handoff ret = xbl_handover(&bl32_image_ep_info,
 						  &bl33_image_ep_info,
 						  tfa_handoff_addr);
-	if (ret == XBL_HANDOFF_NO_STRUCT || ret == XBL_HANDOFF_INVAL_STRUCT) {
+	if ((ret == XBL_HANDOFF_NO_STRUCT) || (ret == XBL_HANDOFF_INVAL_STRUCT)) {
 		bl31_set_default_config();
 	} else if (ret == XBL_HANDOFF_TOO_MANY_PARTS) {
 		ERROR("BL31: Error too many partitions %u\n", ret);
@@ -115,19 +139,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		panic();
 	} else {
 		INFO("BL31: PLM to TF-A handover success %u\n", ret);
-
-		/*
-		 * The BL32 load address is indicated as 0x0 in the handoff
-		 * parameters, which is different from the default/user-provided
-		 * load address of 0x60000000 but the flags are correctly
-		 * configured. Consequently, in this scenario, set the PC
-		 * to the requested BL32_BASE address.
-		 */
-
-		/* TODO: Remove the following check once this is fixed from PLM */
-		if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
-			bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
-		}
 	}
 
 	NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
@@ -142,7 +153,7 @@ int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
 	uint32_t i;
 
 	/* Validate 'handler' and 'id' parameters */
-	if (handler == NULL || index >= MAX_INTR_EL3) {
+	if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
 		return -EINVAL;
 	}
 
@@ -164,6 +175,7 @@ int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
 static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
 					  void *handle, void *cookie)
 {
+	(void)id;
 	uint32_t intr_id;
 	uint32_t i;
 	interrupt_type_handler_t handler = NULL;
@@ -203,8 +215,6 @@ void bl31_plat_runtime_setup(void)
 	if (rc != 0) {
 		panic();
 	}
-
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
diff --git a/plat/xilinx/versal/include/plat_macros.S b/plat/xilinx/versal/include/plat_macros.S
index 41193a51..38f47f66 100644
--- a/plat/xilinx/versal/include/plat_macros.S
+++ b/plat/xilinx/versal/include/plat_macros.S
@@ -103,8 +103,8 @@ exit_print_gic_regs:
 	 * ---------------------------------------------
 	 */
 	.macro plat_crash_print_regs
-	mov_imm	x17, PLAT_GICD_BASE_VALUE
-	mov_imm	x16, PLAT_GICR_BASE_VALUE
+	mov_imm	x17, PLAT_ARM_GICD_BASE
+	mov_imm	x16, PLAT_ARM_GICR_BASE
 	versal_print_gic_regs
 	.endm
 
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index a4210cd1..658dc9eb 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,9 +22,11 @@ void versal_config_setup(void);
 
 const mmap_region_t *plat_get_mmap(void);
 
-extern uint32_t platform_id, platform_version;
+extern uint32_t cpu_clock, platform_id, platform_version;
 
 void board_detection(void);
+const char *board_name_decode(void);
+
 void plat_versal_gic_driver_init(void);
 void plat_versal_gic_init(void);
 void plat_versal_gic_cpuif_enable(void);
@@ -32,6 +34,8 @@ void plat_versal_gic_cpuif_disable(void);
 void plat_versal_gic_pcpu_init(void);
 void plat_versal_gic_save(void);
 void plat_versal_gic_resume(void);
+void plat_versal_gic_redistif_on(void);
+void plat_versal_gic_redistif_off(void);
 
 uint32_t versal_calc_core_pos(u_register_t mpidr);
 /*
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 286a706c..8cf8de0d 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -9,6 +9,7 @@
 #define PLATFORM_DEF_H
 
 #include <arch.h>
+#include <plat_common.h>
 #include "versal_def.h"
 
 /*******************************************************************************
@@ -74,8 +75,17 @@
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 32)
+
+#if (BL31_BASE >= (1ULL << 32U))
+/* Address range in High DDR and HBM memory range */
+#define PLAT_ADDR_SPACE_SHIFT		U(42)
+#else
+/* Address range in OCM and Low DDR memory range */
+#define PLAT_ADDR_SPACE_SHIFT		U(32)
+#endif
+
+#define PLAT_PHY_ADDR_SPACE_SIZE        (1ull << PLAT_ADDR_SPACE_SHIFT)
+#define PLAT_VIRT_ADDR_SPACE_SIZE       (1ull << PLAT_ADDR_SPACE_SHIFT)
 
 #define XILINX_OF_BOARD_DTB_MAX_SIZE	U(0x200000)
 
@@ -103,8 +113,8 @@
 #define CACHE_WRITEBACK_SHIFT	6
 #define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
 
-#define PLAT_GICD_BASE_VALUE	U(0xF9000000)
-#define PLAT_GICR_BASE_VALUE	U(0xF9080000)
+#define PLAT_ARM_GICD_BASE	U(0xF9000000)
+#define PLAT_ARM_GICR_BASE	U(0xF9080000)
 
 /*
  * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
@@ -122,6 +132,8 @@
 #define PLAT_VERSAL_G0_IRQ_PROPS(grp) \
 	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(CPU_PWR_DOWN_REQ_INTR, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE)
 
 #define IRQ_MAX		142U
 
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 92c0ba6c..3a1c127f 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,20 +18,30 @@
 /* number of interrupt handlers. increase as required */
 #define MAX_INTR_EL3			2
 /* List all consoles */
+#define VERSAL_CONSOLE_ID_none		0
 #define VERSAL_CONSOLE_ID_pl011	1
 #define VERSAL_CONSOLE_ID_pl011_0	1
 #define VERSAL_CONSOLE_ID_pl011_1	2
 #define VERSAL_CONSOLE_ID_dcc		3
+#define VERSAL_CONSOLE_ID_dtb		4
 
 #define CONSOLE_IS(con)	(VERSAL_CONSOLE_ID_ ## con == VERSAL_CONSOLE)
 
-/* List all supported platforms */
-#define VERSAL_PLATFORM_ID_versal_virt	1
-#define VERSAL_PLATFORM_ID_spp_itr6	2
-#define VERSAL_PLATFORM_ID_emu_itr6	3
-#define VERSAL_PLATFORM_ID_silicon	4
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011	1
+#define RT_CONSOLE_ID_pl011_0	1
+#define RT_CONSOLE_ID_pl011_1	2
+#define RT_CONSOLE_ID_dcc	3
+#define RT_CONSOLE_ID_dtb	4
 
-#define VERSAL_PLATFORM_IS(con)	(VERSAL_PLATFORM_ID_ ## con == VERSAL_PLATFORM)
+#define RT_CONSOLE_IS(con)	(RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
+/* List of platforms */
+#define VERSAL_SILICON              U(0)
+#define VERSAL_SPP                  U(1)
+#define VERSAL_EMU                  U(2)
+#define VERSAL_QEMU                 U(3)
+#define VERSAL_COSIM                U(7)
 
 /* Firmware Image Package */
 #define VERSAL_PRIMARY_CPU	0
@@ -64,38 +74,41 @@
 #define VERSAL_UART0_BASE		0xFF000000
 #define VERSAL_UART1_BASE		0xFF010000
 
-#if CONSOLE_IS(pl011) || CONSOLE_IS(dcc)
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
 # define UART_BASE	VERSAL_UART0_BASE
+# define UART_TYPE	CONSOLE_PL011
 #elif CONSOLE_IS(pl011_1)
 # define UART_BASE	VERSAL_UART1_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
 #else
 # error "invalid VERSAL_CONSOLE"
 #endif
 
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE VERSAL_UART0_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE VERSAL_UART1_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
 /*******************************************************************************
  * Platform related constants
  ******************************************************************************/
-#if VERSAL_PLATFORM_IS(versal_virt)
-# define PLATFORM_NAME		"Versal Virt"
-# define UART_CLOCK	25000000
-# define UART_BAUDRATE	115200
-# define VERSAL_CPU_CLOCK	2720000
-#elif VERSAL_PLATFORM_IS(silicon)
-# define PLATFORM_NAME		"Versal Silicon"
-# define UART_CLOCK	100000000
-# define UART_BAUDRATE	115200
-# define VERSAL_CPU_CLOCK	100000000
-#elif VERSAL_PLATFORM_IS(spp_itr6)
-# define PLATFORM_NAME		"SPP ITR6"
-# define UART_CLOCK	25000000
-# define UART_BAUDRATE	115200
-# define VERSAL_CPU_CLOCK	2720000
-#elif VERSAL_PLATFORM_IS(emu_itr6)
-# define PLATFORM_NAME		"EMU ITR6"
-# define UART_CLOCK	212000
-# define UART_BAUDRATE	9600
-# define VERSAL_CPU_CLOCK	212000
-#endif
+#define UART_BAUDRATE  115200
 
 /* Access control register defines */
 #define ACTLR_EL3_L2ACTLR_BIT	(1 << 6)
@@ -111,6 +124,10 @@
 #define CRF_RST_APU_ACPU_RESET		(1 << 0)
 #define CRF_RST_APU_ACPU_PWRON_RESET	(1 << 10)
 
+/* IOU SCNTRS */
+#define IOU_SCNTRS_BASE	U(0xFF140000)
+#define IOU_SCNTRS_BASE_FREQ_OFFSET	U(0x20)
+
 /* APU registers and bitfields */
 #define FPD_APU_BASE		0xFD5C0000U
 #define FPD_APU_CONFIG_0	(FPD_APU_BASE + 0x20U)
diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c
index 56d98f79..3fc6dbd3 100644
--- a/plat/xilinx/versal/plat_psci.c
+++ b/plat/xilinx/versal/plat_psci.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,10 +14,13 @@
 #include <plat/common/platform.h>
 #include <plat_arm.h>
 
+#include "drivers/delay_timer.h"
 #include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include <pm_common.h>
+#include "pm_ipi.h"
+#include "pm_svc_main.h"
 
 static uintptr_t versal_sec_entry;
 
@@ -33,6 +36,9 @@ static int32_t versal_pwr_domain_on(u_register_t mpidr)
 	}
 
 	proc = pm_get_proc((uint32_t)cpu_id);
+	if (proc == NULL) {
+		return PSCI_E_INTERN_FAIL;
+	}
 
 	/* Send request to PMC to wake up selected ACPU core */
 	(void)pm_req_wakeup(proc->node_id, (versal_sec_entry & 0xFFFFFFFFU) | 0x1U,
@@ -56,6 +62,10 @@ static void versal_pwr_domain_suspend(const psci_power_state_t *target_state)
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
@@ -67,7 +77,7 @@ static void versal_pwr_domain_suspend(const psci_power_state_t *target_state)
 		plat_versal_gic_save();
 	}
 
-	state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+	state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
 		PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
 
 	/* Send request to PMC to suspend this core */
@@ -93,6 +103,10 @@ static void versal_pwr_domain_suspend_finish(
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
@@ -112,7 +126,7 @@ static void versal_pwr_domain_suspend_finish(
 	plat_versal_gic_cpuif_enable();
 }
 
-void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
+static void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	/* Enable the gic cpu interface */
 	plat_versal_gic_pcpu_init();
@@ -132,7 +146,7 @@ static void __dead2 versal_system_off(void)
 	(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN,
 				 pm_get_shutdown_scope(), SECURE_FLAG);
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -145,11 +159,33 @@ static void __dead2 versal_system_off(void)
  */
 static void __dead2 versal_system_reset(void)
 {
-	/* Send the system reset request to the PMC */
-	(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
-				 pm_get_shutdown_scope(), SECURE_FLAG);
+	uint32_t ret, timeout = 10000U;
 
-	while (1) {
+	request_cpu_pwrdwn();
+
+	/*
+	 * Send the system reset request to the firmware if power down request
+	 * is not received from firmware.
+	 */
+	if (!pwrdwn_req_received) {
+		(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
+					 pm_get_shutdown_scope(), SECURE_FLAG);
+
+		/*
+		 * Wait for system shutdown request completed and idle callback
+		 * not received.
+		 */
+		do {
+			ret = ipi_mb_enquire_status(primary_proc->ipi->local_ipi_id,
+						    primary_proc->ipi->remote_ipi_id);
+			udelay(100);
+			timeout--;
+		} while ((ret != IPI_MB_STATUS_RECV_PENDING) && (timeout > 0U));
+	}
+
+	(void)psci_cpu_off();
+
+	while (true) {
 		wfi();
 	}
 }
@@ -161,9 +197,14 @@ static void __dead2 versal_system_reset(void)
  */
 static void versal_pwr_domain_off(const psci_power_state_t *target_state)
 {
+	uint32_t ret, fw_api_version, version_type[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0U; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
@@ -180,8 +221,17 @@ static void versal_pwr_domain_off(const psci_power_state_t *target_state)
 	 * invoking CPU_on function, during which resume address will
 	 * be set.
 	 */
-	(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
-			      SECURE_FLAG);
+	ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version_type[0], SECURE_FLAG);
+	if (ret == PM_RET_SUCCESS) {
+		fw_api_version = version_type[0] & 0xFFFFU;
+		if (fw_api_version >= 3U) {
+			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
+					      SECURE_FLAG);
+		} else {
+			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
+					      SECURE_FLAG);
+		}
+	}
 }
 
 /**
@@ -200,7 +250,7 @@ static int32_t versal_validate_power_state(uint32_t power_state,
 
 	uint32_t pstate = psci_get_pstate_type(power_state);
 
-	assert(req_state);
+	assert(req_state != NULL);
 
 	/* Sanity check the requested state */
 	if (pstate == PSTATE_TYPE_STANDBY) {
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 7c53daad..7c15be02 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -1,5 +1,5 @@
 # Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
-# Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -11,6 +11,8 @@ override RESET_TO_BL31 := 1
 PL011_GENERIC_UART := 1
 IPI_CRC_CHECK := 0
 HARDEN_SLS_ALL := 0
+CPU_PWRDWN_SGI ?= 6
+$(eval $(call add_define_val,CPU_PWR_DOWN_REQ_INTR,ARM_IRQ_SEC_SGI_${CPU_PWRDWN_SGI}))
 
 # A72 Erratum for SoC
 ERRATA_A72_859971 := 1
@@ -20,7 +22,7 @@ ifdef VERSAL_ATF_MEM_BASE
     $(eval $(call add_define,VERSAL_ATF_MEM_BASE))
 
     ifndef VERSAL_ATF_MEM_SIZE
-        $(error "VERSAL_ATF_BASE defined without VERSAL_ATF_SIZE")
+        $(error "VERSAL_ATF_MEM_BASE defined without VERSAL_ATF_MEM_SIZE")
     endif
     $(eval $(call add_define,VERSAL_ATF_MEM_SIZE))
 
@@ -33,7 +35,7 @@ ifdef VERSAL_BL32_MEM_BASE
     $(eval $(call add_define,VERSAL_BL32_MEM_BASE))
 
     ifndef VERSAL_BL32_MEM_SIZE
-        $(error "VERSAL_BL32_BASE defined without VERSAL_BL32_SIZE")
+        $(error "VERSAL_BL32_MEM_BASE defined without VERSAL_BL32_MEM_SIZE")
     endif
     $(eval $(call add_define,VERSAL_BL32_MEM_SIZE))
 endif
@@ -42,8 +44,9 @@ ifdef IPI_CRC_CHECK
     $(eval $(call add_define,IPI_CRC_CHECK))
 endif
 
-VERSAL_PLATFORM ?= silicon
-$(eval $(call add_define_val,VERSAL_PLATFORM,VERSAL_PLATFORM_ID_${VERSAL_PLATFORM}))
+ifdef VERSAL_PLATFORM
+    $(warning "VERSAL_PLATFORM has been deprecated")
+endif
 
 ifdef XILINX_OF_BOARD_DTB_ADDR
 $(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
@@ -82,13 +85,27 @@ PLAT_BL_COMMON_SOURCES	:= 	drivers/arm/dcc/dcc_console.c			\
 				${XLAT_TABLES_LIB_SRCS}
 
 VERSAL_CONSOLE	?=	pl011
-ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc))
+ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
 else
   $(error "Please define VERSAL_CONSOLE")
 endif
 
 $(eval $(call add_define_val,VERSAL_CONSOLE,VERSAL_CONSOLE_ID_${VERSAL_CONSOLE}))
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
 				lib/cpus/aarch64/cortex_a72.S			\
 				common/fdt_wrappers.c                           \
@@ -96,6 +113,7 @@ BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
 				plat/xilinx/common/ipi.c			\
 				plat/xilinx/common/plat_fdt.c			\
 				plat/xilinx/common/plat_console.c               \
+				plat/xilinx/common/plat_clkfunc.c               \
 				plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
 				plat/xilinx/common/pm_service/pm_ipi.c		\
@@ -116,3 +134,9 @@ BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
 ifeq ($(HARDEN_SLS_ALL), 1)
 TF_CFLAGS_aarch64      +=      -mharden-sls=all
 endif
+
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+# enable the cpu macros for errata abi interface
+CORTEX_A72_H_INC	:= 1
+$(eval $(call add_define, CORTEX_A72_H_INC))
+endif
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index ccbfe770..3e441538 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -155,6 +155,9 @@ enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq)
 	case 74:
 		dev_idx = XPM_NODEIDX_DEV_USB_0;
 		break;
+	case 122:
+		dev_idx = XPM_NODEIDX_DEV_GPIO_PMC;
+		break;
 	case 126:
 	case 127:
 		dev_idx = XPM_NODEIDX_DEV_SDIO_0;
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index b30254d5..3027946b 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,13 +17,12 @@
 #include "pm_svc_main.h"
 
 /* SMC function IDs for SiP Service queries */
-#define VERSAL_SIP_SVC_CALL_COUNT	U(0x8200ff00)
 #define VERSAL_SIP_SVC_UID		U(0x8200ff01)
 #define VERSAL_SIP_SVC_VERSION		U(0x8200ff03)
 
 /* SiP Service Calls version numbers */
 #define SIP_SVC_VERSION_MAJOR	U(0)
-#define SIP_SVC_VERSION_MINOR	U(1)
+#define SIP_SVC_VERSION_MINOR	U(2)
 
 /* These macros are used to identify PM calls from the SMC function ID */
 #define SIP_FID_MASK	GENMASK(23, 16)
@@ -69,19 +68,19 @@ static int32_t sip_svc_setup(void)
  *
  * Return: Unused.
  */
-uintptr_t sip_svc_smc_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)
+static uintptr_t sip_svc_smc_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)
 {
 	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
 		smc_fid, x1, x2, x3, x4);
 
-	if (smc_fid & SIP_FID_MASK) {
+	if ((smc_fid & SIP_FID_MASK) != 0U) {
 		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
@@ -100,10 +99,6 @@ uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
 
 	/* Let PM SMC handler deal with PM-related requests */
 	switch (smc_fid) {
-	case VERSAL_SIP_SVC_CALL_COUNT:
-		/* PM functions + default functions */
-		SMC_RET1(handle, 2);
-
 	case VERSAL_SIP_SVC_UID:
 		SMC_UUID_RET(handle, versal_sip_uuid);
 
diff --git a/plat/xilinx/versal/versal_gicv3.c b/plat/xilinx/versal/versal_gicv3.c
index 197d047f..1750d351 100644
--- a/plat/xilinx/versal/versal_gicv3.c
+++ b/plat/xilinx/versal/versal_gicv3.c
@@ -62,8 +62,8 @@ static uint32_t versal_gicv3_mpidr_hash(u_register_t mpidr)
 }
 
 static const gicv3_driver_data_t versal_gic_data __unused = {
-	.gicd_base = PLAT_GICD_BASE_VALUE,
-	.gicr_base = PLAT_GICR_BASE_VALUE,
+	.gicd_base = PLAT_ARM_GICD_BASE,
+	.gicr_base = PLAT_ARM_GICR_BASE,
 	.interrupt_props = versal_interrupt_props,
 	.interrupt_props_num = ARRAY_SIZE(versal_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c
index 69c5c87d..0dd01946 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_common.c
+++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c
@@ -60,11 +60,11 @@ char *board_name_decode(void)
 
 void board_detection(void)
 {
-	uint32_t version;
+	uint32_t version_type;
 
-	version = mmio_read_32(PMC_TAP_VERSION);
-	platform_id = FIELD_GET(PLATFORM_MASK, version);
-	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version);
+	version_type = mmio_read_32(PMC_TAP_VERSION);
+	platform_id = FIELD_GET(PLATFORM_MASK, version_type);
+	platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version_type);
 
 	if (platform_id == VERSAL_NET_QEMU_COSIM) {
 		platform_id = VERSAL_NET_QEMU;
@@ -113,12 +113,22 @@ uint32_t get_uart_clk(void)
 }
 
 void versal_net_config_setup(void)
+{
+	generic_delay_timer_init();
+
+#if (TFA_NO_PM == 0)
+	/* Configure IPI data for versal_net */
+	versal_net_ipi_config_table_init();
+#endif
+}
+
+void syscnt_freq_config_setup(void)
 {
 	uint32_t val;
 	uintptr_t crl_base, iou_scntrs_base, psx_base;
 
 	crl_base = VERSAL_NET_CRL;
-	iou_scntrs_base = VERSAL_NET_IOU_SCNTRS;
+	iou_scntrs_base = IOU_SCNTRS_BASE;
 	psx_base = PSX_CRF;
 
 	/* Reset for system timestamp generator in FPX */
@@ -133,20 +143,9 @@ void versal_net_config_setup(void)
 	mmio_write_32(crl_base + VERSAL_NET_CRL_RST_TIMESTAMP_OFFSET, 0);
 
 	/* Program freq register in System counter and enable system counter. */
-	mmio_write_32(iou_scntrs_base + VERSAL_NET_IOU_SCNTRS_BASE_FREQ_OFFSET,
+	mmio_write_32(iou_scntrs_base + IOU_SCNTRS_BASE_FREQ_OFFSET,
 		      cpu_clock);
-	mmio_write_32(iou_scntrs_base + VERSAL_NET_IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET,
-		      VERSAL_NET_IOU_SCNTRS_CONTROL_EN);
-
-	generic_delay_timer_init();
-
-#if (TFA_NO_PM == 0)
-	/* Configure IPI data for versal_net */
-	versal_net_ipi_config_table_init();
-#endif
+	mmio_write_32(iou_scntrs_base + IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET,
+		      IOU_SCNTRS_CONTROL_EN);
 }
 
-uint32_t plat_get_syscnt_freq2(void)
-{
-	return cpu_clock;
-}
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
index dab87179..1ae879f3 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
+++ b/plat/xilinx/versal_net/aarch64/versal_net_helpers.S
@@ -12,6 +12,7 @@
 
 #include <platform_def.h>
 
+	.globl	plat_arm_calc_core_pos
 	.globl	plat_secondary_cold_boot_setup
 	.globl	plat_is_my_cpu_primary
 	.globl	platform_mem_init
@@ -58,6 +59,16 @@ func plat_my_core_pos
 	b	plat_core_pos_by_mpidr
 endfunc plat_my_core_pos
 
+	 /* -----------------------------------------------------
+	  * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+	  * This function uses the plat_core_pos_by_mpidr()
+	  * definition to get the index of the calling CPU.
+	  * -----------------------------------------------------
+	  */
+func plat_arm_calc_core_pos
+	b	plat_core_pos_by_mpidr
+endfunc plat_arm_calc_core_pos
+
 	/* ---------------------------------------------------------------------
 	 * We don't need to carry out any memory initialization on Versal NET
 	 * platform. The Secure RAM is accessible straight away.
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 56ef27b1..cf2368a0 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
  * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  *
@@ -17,6 +17,7 @@
 #include <plat/common/platform.h>
 #include <plat_arm.h>
 #include <plat_console.h>
+#include <plat_clkfunc.h>
 
 #include <plat_fdt.h>
 #include <plat_private.h>
@@ -58,6 +59,20 @@ static inline void bl31_set_default_config(void)
 					DISABLE_ALL_EXCEPTIONS);
 }
 
+/* Define read and write function for clusterbusqos register */
+DEFINE_RENAME_SYSREG_RW_FUNCS(cluster_bus_qos, S3_0_C15_C4_4)
+
+static void versal_net_setup_qos(void)
+{
+	int ret;
+
+	ret = read_cluster_bus_qos();
+	INFO("BL31: default cluster bus qos: 0x%x\n", ret);
+	write_cluster_bus_qos(0);
+	ret = read_cluster_bus_qos();
+	INFO("BL31: cluster bus qos written: 0x%x\n", ret);
+}
+
 /*
  * Perform any BL31 specific platform actions. Here is an opportunity to copy
  * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
@@ -67,6 +82,11 @@ static inline void bl31_set_default_config(void)
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
+	(void)arg0;
+	(void)arg1;
+	(void)arg2;
+	(void)arg3;
+
 #if !(TFA_NO_PM)
 	uint64_t tfa_handoff_addr, buff[HANDOFF_PARAMS_MAX_SIZE] = {0};
 	uint32_t payload[PAYLOAD_ARG_CNT], max_size = HANDOFF_PARAMS_MAX_SIZE;
@@ -93,11 +113,17 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 		panic();
 	}
 
+	syscnt_freq_config_setup();
+
+	set_cnt_freq();
+
 	setup_console();
 
 	NOTICE("TF-A running on %s %d.%d\n", board_name_decode(),
 	       platform_version / 10U, platform_version % 10U);
 
+	versal_net_setup_qos();
+
 	/* Initialize the platform config for future decision making */
 	versal_net_config_setup();
 
@@ -132,18 +158,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 
 		INFO("BL31: PLM to TF-A handover success\n");
 
-		/*
-		 * The BL32 load address is indicated as 0x0 in the handoff
-		 * parameters, which is different from the default/user-provided
-		 * load address of 0x60000000 but the flags are correctly
-		 * configured. Consequently, in this scenario, set the PC
-		 * to the requested BL32_BASE address.
-		 */
-
-		/* TODO: Remove the following check once this is fixed from PLM */
-		if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
-			bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
-		}
 	} else {
 		INFO("BL31: setting up default configs\n");
 
@@ -165,7 +179,7 @@ int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
 	uint32_t i;
 
 	/* Validate 'handler' and 'id' parameters */
-	if (handler == NULL || index >= MAX_INTR_EL3) {
+	if ((handler == NULL) || (index >= MAX_INTR_EL3)) {
 		return -EINVAL;
 	}
 
@@ -200,7 +214,7 @@ static uint64_t rdo_el3_interrupt_handler(uint32_t id, uint32_t flags,
 	}
 
 	if (handler != NULL) {
-		handler(intr_id, flags, handle, cookie);
+		(void)handler(intr_id, flags, handle, cookie);
 	}
 
 	return 0;
@@ -211,8 +225,8 @@ void bl31_platform_setup(void)
 	prepare_dtb();
 
 	/* Initialize the gic cpu and distributor interfaces */
-	plat_versal_net_gic_driver_init();
-	plat_versal_net_gic_init();
+	plat_arm_gic_driver_init();
+	plat_arm_gic_init();
 }
 
 void bl31_plat_runtime_setup(void)
@@ -226,8 +240,6 @@ void bl31_plat_runtime_setup(void)
 	if (rc != 0) {
 		panic();
 	}
-
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
diff --git a/plat/xilinx/versal_net/include/plat_ipi.h b/plat/xilinx/versal_net/include/plat_ipi.h
index 9f9947e3..e0fe723b 100644
--- a/plat/xilinx/versal_net/include/plat_ipi.h
+++ b/plat/xilinx/versal_net/include/plat_ipi.h
@@ -24,7 +24,15 @@
 #define IPI_ID_3	5U
 #define IPI_ID_4	6U
 #define IPI_ID_5	7U
-#define IPI_ID_MAX	8U
+#define IPI_ID_PMC_NOBUF	8U
+#define IPI_ID_6_NOBUF_95	9U
+#define IPI_ID_1_NOBUF	10U
+#define IPI_ID_2_NOBUF	11U
+#define IPI_ID_3_NOBUF	12U
+#define IPI_ID_4_NOBUF	13U
+#define IPI_ID_5_NOBUF	14U
+#define IPI_ID_6_NOBUF_101	15U
+#define IPI_ID_MAX	16U
 
 /*********************************************************************
  * IPI message buffers
@@ -68,5 +76,21 @@ void versal_net_ipi_config_table_init(void);
 #define IPI4_TRIG_BIT		(1 << 6)
 #define IPI5_REG_BASE		(0xEB380000U)
 #define IPI5_TRIG_BIT		(1 << 7)
+#define PMC_NOBUF_REG_BASE	(0xEB390000U)
+#define PMC_NOBUF_TRIG_BIT	(1 << 8)
+#define IPI6_NOBUF_95_REG_BASE	(0xEB3A0000U)
+#define IPI6_NOBUF_95_TRIG_BIT	(1 << 9)
+#define IPI1_NOBUF_REG_BASE	(0xEB3B0000U)
+#define IPI1_NOBUF_TRIG_BIT	(1 << 10)
+#define IPI2_NOBUF_REG_BASE	(0xEB3B1000U)
+#define IPI2_NOBUF_TRIG_BIT	(1 << 11)
+#define IPI3_NOBUF_REG_BASE	(0xEB3B2000U)
+#define IPI3_NOBUF_TRIG_BIT	(1 << 12)
+#define IPI4_NOBUF_REG_BASE	(0xEB3B3000U)
+#define IPI4_NOBUF_TRIG_BIT	(1 << 13)
+#define IPI5_NOBUF_REG_BASE	(0xEB3B4000U)
+#define IPI5_NOBUF_TRIG_BIT	(1 << 14)
+#define IPI6_NOBUF_101_REG_BASE	(0xEB3B5000U)
+#define IPI6_NOBUF_101_TRIG_BIT	(1 << 15)
 
 #endif /* PLAT_IPI_H */
diff --git a/plat/xilinx/versal_net/include/plat_macros.S b/plat/xilinx/versal_net/include/plat_macros.S
index db7e42b3..57f8336b 100644
--- a/plat/xilinx/versal_net/include/plat_macros.S
+++ b/plat/xilinx/versal_net/include/plat_macros.S
@@ -109,8 +109,8 @@ exit_print_gic_regs:
 	 * Uncomment it when versions are stable
 	 */
 	/*
-	mov_imm	x17, PLAT_GICD_BASE_VALUE
-	mov_imm	x16, PLAT_GICR_BASE_VALUE
+	mov_imm	x17, PLAT_ARM_GICD_BASE
+	mov_imm	x16, PLAT_ARM_GICR_BASE
 	versal_net_print_gic_regs
 	*/
 	.endm
diff --git a/plat/xilinx/versal_net/include/plat_private.h b/plat/xilinx/versal_net/include/plat_private.h
index 9cd86361..0b82ca73 100644
--- a/plat/xilinx/versal_net/include/plat_private.h
+++ b/plat/xilinx/versal_net/include/plat_private.h
@@ -18,6 +18,7 @@ typedef struct versal_intr_info_type_el3 {
 } versal_intr_info_type_el3_t;
 
 void versal_net_config_setup(void);
+void syscnt_freq_config_setup(void);
 uint32_t get_uart_clk(void);
 
 const mmap_region_t *plat_get_mmap(void);
diff --git a/plat/xilinx/versal_net/include/platform_def.h b/plat/xilinx/versal_net/include/platform_def.h
index 872b6eeb..8cb7deb1 100644
--- a/plat/xilinx/versal_net/include/platform_def.h
+++ b/plat/xilinx/versal_net/include/platform_def.h
@@ -10,6 +10,7 @@
 #define PLATFORM_DEF_H
 
 #include <arch.h>
+#include <plat_common.h>
 #include "versal_net_def.h"
 
 /*******************************************************************************
@@ -107,8 +108,8 @@
 #define CACHE_WRITEBACK_SHIFT	U(6)
 #define CACHE_WRITEBACK_GRANULE	(1 << CACHE_WRITEBACK_SHIFT)
 
-#define PLAT_GICD_BASE_VALUE	U(0xE2000000)
-#define PLAT_GICR_BASE_VALUE	U(0xE2060000)
+#define PLAT_ARM_GICD_BASE	U(0xE2000000)
+#define PLAT_ARM_GICR_BASE	U(0xE2060000)
 
 /*
  * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
@@ -118,13 +119,15 @@
 #define PLAT_VERSAL_NET_IPI_IRQ	89
 #define PLAT_VERSAL_IPI_IRQ	PLAT_VERSAL_NET_IPI_IRQ
 
-#define PLAT_VERSAL_NET_G1S_IRQ_PROPS(grp) \
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
 	INTR_PROP_DESC(VERSAL_NET_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL)
 
-#define PLAT_VERSAL_NET_G0_IRQ_PROPS(grp) \
+#define PLAT_ARM_G0_IRQ_PROPS(grp) \
 	INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(CPU_PWR_DOWN_REQ_INTR, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE)
 
 #define IRQ_MAX		200U
 
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index dd20faa4..5caf3768 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -15,13 +15,24 @@
 #define MAX_INTR_EL3			2
 
 /* List all consoles */
+#define VERSAL_NET_CONSOLE_ID_none	U(0)
 #define VERSAL_NET_CONSOLE_ID_pl011	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_0	U(1)
 #define VERSAL_NET_CONSOLE_ID_pl011_1	U(2)
 #define VERSAL_NET_CONSOLE_ID_dcc	U(3)
+#define VERSAL_NET_CONSOLE_ID_dtb	U(4)
 
 #define CONSOLE_IS(con)	(VERSAL_NET_CONSOLE_ID_ ## con == VERSAL_NET_CONSOLE)
 
+/* Runtime console */
+#define RT_CONSOLE_ID_pl011    1
+#define RT_CONSOLE_ID_pl011_0  1
+#define RT_CONSOLE_ID_pl011_1  2
+#define RT_CONSOLE_ID_dcc      3
+#define RT_CONSOLE_ID_dtb      4
+
+#define RT_CONSOLE_IS(con)     (RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
 /* List all platforms */
 #define VERSAL_NET_SILICON		U(0)
 #define VERSAL_NET_SPP			U(1)
@@ -111,11 +122,11 @@
 #define VERSAL_NET_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT	(1U << 25U)
 
 /* IOU SCNTRS */
-#define VERSAL_NET_IOU_SCNTRS					U(0xEC920000)
-#define VERSAL_NET_IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET	U(0)
-#define VERSAL_NET_IOU_SCNTRS_BASE_FREQ_OFFSET			U(0x20)
+#define IOU_SCNTRS_BASE	U(0xEC920000)
+#define IOU_SCNTRS_COUNTER_CONTROL_REG_OFFSET	U(0)
+#define IOU_SCNTRS_BASE_FREQ_OFFSET	U(0x20)
 
-#define VERSAL_NET_IOU_SCNTRS_CONTROL_EN	U(1)
+#define IOU_SCNTRS_CONTROL_EN	U(1)
 
 #define APU_CLUSTER0		U(0xECC00000)
 #define APU_RVBAR_L_0		U(0x40)
@@ -138,11 +149,35 @@
 
 #define UART_BAUDRATE	115200
 
-#if CONSOLE_IS(pl011_1)
-#define UART_BASE		VERSAL_NET_UART1_BASE
+#if CONSOLE_IS(pl011) || CONSOLE_IS(dtb)
+#define UART_BASE		VERSAL_NET_UART0_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(pl011_1)
+#define UART_BASE            VERSAL_NET_UART1_BASE
+# define UART_TYPE	CONSOLE_PL011
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
+#else
+# error "invalid VERSAL_NET_CONSOLE"
+#endif
+
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(pl011) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE VERSAL_NET_UART0_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(pl011_1)
+# define RT_UART_BASE VERSAL_NET_UART1_BASE
+# define RT_UART_TYPE	CONSOLE_PL011
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
 #else
-/* Default console is UART0 */
-#define UART_BASE            VERSAL_NET_UART0_BASE
+# error "invalid CONSOLE_RUNTIME"
+#endif
 #endif
 
 /* Processor core device IDs */
diff --git a/plat/xilinx/versal_net/plat_psci.c b/plat/xilinx/versal_net/plat_psci.c
index 6e556cdf..fcb32b97 100644
--- a/plat/xilinx/versal_net/plat_psci.c
+++ b/plat/xilinx/versal_net/plat_psci.c
@@ -108,8 +108,8 @@ static void zynqmp_pwr_domain_suspend(const psci_power_state_t *target_state)
 
 static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-	plat_versal_net_gic_pcpu_init();
-	plat_versal_net_gic_cpuif_enable();
+	plat_arm_gic_pcpu_init();
+	plat_arm_gic_cpuif_enable();
 }
 
 static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
diff --git a/plat/xilinx/versal_net/plat_psci_pm.c b/plat/xilinx/versal_net/plat_psci_pm.c
index 87e25bcd..1c32879b 100644
--- a/plat/xilinx/versal_net/plat_psci_pm.c
+++ b/plat/xilinx/versal_net/plat_psci_pm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,10 +14,12 @@
 #include <plat/common/platform.h>
 #include <plat_arm.h>
 
+#include <drivers/delay_timer.h>
 #include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include <pm_common.h>
+#include "pm_ipi.h"
 #include "pm_svc_main.h"
 #include "versal_net_def.h"
 
@@ -36,11 +38,11 @@ static int32_t versal_net_pwr_domain_on(u_register_t mpidr)
 	}
 
 	proc = pm_get_proc(cpu_id);
-	if (!proc) {
+	if (proc == NULL) {
 		return PSCI_E_INTERN_FAIL;
 	}
 
-	pm_req_wakeup(proc->node_id, (versal_net_sec_entry & 0xFFFFFFFFU) | 0x1U,
+	(void)pm_req_wakeup(proc->node_id, (versal_net_sec_entry & 0xFFFFFFFFU) | 0x1U,
 		      versal_net_sec_entry >> 32, 0, 0);
 
 	/* Clear power down request */
@@ -57,16 +59,21 @@ static int32_t versal_net_pwr_domain_on(u_register_t mpidr)
  */
 static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
 {
+	uint32_t ret, fw_api_version, version_type[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 	}
 
 	/* Prevent interrupts from spuriously waking up this cpu */
-	plat_versal_net_gic_cpuif_disable();
+	plat_arm_gic_cpuif_disable();
 
 	/*
 	 * Send request to PMC to power down the appropriate APU CPU
@@ -76,8 +83,17 @@ static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
 	 * invoking CPU_on function, during which resume address will
 	 * be set.
 	 */
-	pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
-			SECURE_FLAG);
+	ret = pm_feature_check((uint32_t)PM_SELF_SUSPEND, &version_type[0], SECURE_FLAG);
+	if (ret == PM_RET_SUCCESS) {
+		fw_api_version = version_type[0] & 0xFFFFU;
+		if (fw_api_version >= 3U) {
+			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0,
+					      SECURE_FLAG);
+		} else {
+			(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0,
+					      SECURE_FLAG);
+		}
+	}
 }
 
 /**
@@ -88,11 +104,33 @@ static void versal_net_pwr_domain_off(const psci_power_state_t *target_state)
  */
 static void __dead2 versal_net_system_reset(void)
 {
-	/* Send the system reset request to the PMC */
-	pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
-			  pm_get_shutdown_scope(), SECURE_FLAG);
+	uint32_t ret, timeout = 10000U;
+
+	request_cpu_pwrdwn();
 
-	while (1) {
+	/*
+	 * Send the system reset request to the firmware if power down request
+	 * is not received from firmware.
+	 */
+	if (!pwrdwn_req_received) {
+		(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET,
+					 pm_get_shutdown_scope(), SECURE_FLAG);
+
+		/*
+		 * Wait for system shutdown request completed and idle callback
+		 * not received.
+		 */
+		do {
+			ret = ipi_mb_enquire_status(primary_proc->ipi->local_ipi_id,
+						    primary_proc->ipi->remote_ipi_id);
+			udelay(100);
+			timeout--;
+		} while ((ret != IPI_MB_STATUS_RECV_PENDING) && (timeout > 0U));
+	}
+
+	(void)psci_cpu_off();
+
+	while (true) {
 		wfi();
 	}
 }
@@ -109,22 +147,26 @@ static void versal_net_pwr_domain_suspend(const psci_power_state_t *target_state
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 	}
 
-	plat_versal_net_gic_cpuif_disable();
+	plat_arm_gic_cpuif_disable();
 
 	if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
-		plat_versal_net_gic_save();
+		plat_arm_gic_save();
 	}
 
-	state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+	state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
 		PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
 
 	/* Send request to PMC to suspend this core */
-	pm_self_suspend(proc->node_id, MAX_LATENCY, state, versal_net_sec_entry,
+	(void)pm_self_suspend(proc->node_id, MAX_LATENCY, state, versal_net_sec_entry,
 			SECURE_FLAG);
 
 	/* TODO: disable coherency */
@@ -135,10 +177,10 @@ static void versal_net_pwr_domain_on_finish(const psci_power_state_t *target_sta
 	(void)target_state;
 
 	/* Enable the gic cpu interface */
-	plat_versal_net_gic_pcpu_init();
+	plat_arm_gic_pcpu_init();
 
 	/* Program the gic per-cpu distributor or re-distributor interface */
-	plat_versal_net_gic_cpuif_enable();
+	plat_arm_gic_cpuif_enable();
 }
 
 /**
@@ -152,6 +194,10 @@ static void versal_net_pwr_domain_suspend_finish(const psci_power_state_t *targe
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
@@ -163,10 +209,10 @@ static void versal_net_pwr_domain_suspend_finish(const psci_power_state_t *targe
 
 	/* APU was turned off, so restore GIC context */
 	if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
-		plat_versal_net_gic_resume();
+		plat_arm_gic_resume();
 	}
 
-	plat_versal_net_gic_cpuif_enable();
+	plat_arm_gic_cpuif_enable();
 }
 
 /**
@@ -177,10 +223,10 @@ static void versal_net_pwr_domain_suspend_finish(const psci_power_state_t *targe
 static void __dead2 versal_net_system_off(void)
 {
 	/* Send the power down request to the PMC */
-	pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN,
+	(void)pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN,
 			  pm_get_shutdown_scope(), SECURE_FLAG);
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -201,7 +247,7 @@ static int32_t versal_net_validate_power_state(unsigned int power_state,
 
 	int32_t pstate = psci_get_pstate_type(power_state);
 
-	assert(req_state);
+	assert(req_state != NULL);
 
 	/* Sanity check the requested state */
 	if (pstate == PSTATE_TYPE_STANDBY) {
@@ -211,7 +257,7 @@ static int32_t versal_net_validate_power_state(unsigned int power_state,
 	}
 
 	/* We expect the 'state id' to be zero */
-	if (psci_get_pstate_id(power_state)) {
+	if (psci_get_pstate_id(power_state) != 0U) {
 		return PSCI_E_INVALID_PARAMS;
 	}
 
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index f2991890..9534118b 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -21,6 +21,8 @@ IPI_CRC_CHECK := 0
 GIC_ENABLE_V4_EXTN :=  0
 GICV3_SUPPORT_GIC600 := 1
 TFA_NO_PM := 0
+CPU_PWRDWN_SGI ?= 6
+$(eval $(call add_define_val,CPU_PWR_DOWN_REQ_INTR,ARM_IRQ_SEC_SGI_${CPU_PWRDWN_SGI}))
 
 override CTX_INCLUDE_AARCH32_REGS    := 0
 
@@ -32,7 +34,7 @@ ifdef VERSAL_NET_ATF_MEM_BASE
     $(eval $(call add_define,VERSAL_NET_ATF_MEM_BASE))
 
     ifndef VERSAL_NET_ATF_MEM_SIZE
-        $(error "VERSAL_NET_ATF_BASE defined without VERSAL_NET_ATF_SIZE")
+        $(error "VERSAL_NET_ATF_MEM_BASE defined without VERSAL_NET_ATF_MEM_SIZE")
     endif
     $(eval $(call add_define,VERSAL_NET_ATF_MEM_SIZE))
 
@@ -45,7 +47,7 @@ ifdef VERSAL_NET_BL32_MEM_BASE
     $(eval $(call add_define,VERSAL_NET_BL32_MEM_BASE))
 
     ifndef VERSAL_NET_BL32_MEM_SIZE
-        $(error "VERSAL_NET_BL32_BASE defined without VERSAL_NET_BL32_SIZE")
+        $(error "VERSAL_NET_BL32_MEM_BASE defined without VERSAL_NET_BL32_MEM_SIZE")
     endif
     $(eval $(call add_define,VERSAL_NET_BL32_MEM_SIZE))
 endif
@@ -58,7 +60,7 @@ USE_COHERENT_MEM := 0
 HW_ASSISTED_COHERENCY := 1
 
 VERSAL_NET_CONSOLE	?=	pl011
-ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc))
+ifeq (${VERSAL_NET_CONSOLE}, $(filter ${VERSAL_NET_CONSOLE},pl011 pl011_0 pl011_1 dcc dtb none))
 else
   $(error Please define VERSAL_NET_CONSOLE)
 endif
@@ -69,6 +71,20 @@ ifdef XILINX_OF_BOARD_DTB_ADDR
 $(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
 endif
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= pl011
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},pl011 pl011_0 pl011_1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 # enable assert() for release/debug builds
 ENABLE_ASSERTIONS := 1
 
@@ -93,7 +109,9 @@ PLAT_BL_COMMON_SOURCES	:=	\
 				plat/arm/common/arm_common.c			\
 				plat/common/plat_gicv3.c			\
 				${PLAT_PATH}/aarch64/versal_net_helpers.S	\
-				${PLAT_PATH}/aarch64/versal_net_common.c
+				${PLAT_PATH}/aarch64/versal_net_common.c	\
+				${PLAT_PATH}/plat_topology.c                    \
+				${XLAT_TABLES_LIB_SRCS}
 
 BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
 				lib/cpus/aarch64/cortex_a78_ae.S		\
@@ -112,14 +130,14 @@ endif
 BL31_SOURCES		+=	plat/xilinx/common/plat_fdt.c			\
 				plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/common/plat_console.c		\
+				plat/xilinx/common/plat_clkfunc.c		\
 				plat/xilinx/common/ipi.c			\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
 				plat/xilinx/common/versal.c			\
 				${PLAT_PATH}/bl31_versal_net_setup.c		\
-				${PLAT_PATH}/plat_topology.c			\
 				common/fdt_fixup.c				\
 				common/fdt_wrappers.c				\
+				plat/arm/common/arm_gicv3.c 			\
 				${LIBFDT_SRCS}					\
 				${PLAT_PATH}/sip_svc_setup.c			\
-				${PLAT_PATH}/versal_net_gicv3.c			\
 				${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/xilinx/versal_net/sip_svc_setup.c b/plat/xilinx/versal_net/sip_svc_setup.c
index 0c27dec5..bf06e2c6 100644
--- a/plat/xilinx/versal_net/sip_svc_setup.c
+++ b/plat/xilinx/versal_net/sip_svc_setup.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,13 +20,12 @@
 #include "pm_svc_main.h"
 
 /* SMC function IDs for SiP Service queries */
-#define VERSAL_NET_SIP_SVC_CALL_COUNT	(0x8200ff00U)
 #define VERSAL_NET_SIP_SVC_UID		(0x8200ff01U)
 #define VERSAL_NET_SIP_SVC_VERSION	(0x8200ff03U)
 
 /* SiP Service Calls version numbers */
 #define SIP_SVC_VERSION_MAJOR		(0U)
-#define SIP_SVC_VERSION_MINOR		(1U)
+#define SIP_SVC_VERSION_MINOR		(2U)
 
 /* These macros are used to identify PM calls from the SMC function ID */
 #define SIP_FID_MASK	GENMASK(23, 16)
@@ -70,7 +69,7 @@ static uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
 	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
 		smc_fid, x1, x2, x3, x4);
 
-	if (smc_fid & SIP_FID_MASK) {
+	if ((smc_fid & SIP_FID_MASK) != 0U) {
 		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
@@ -88,10 +87,6 @@ static uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
 
 	/* Let PM SMC handler deal with PM-related requests */
 	switch (smc_fid) {
-	case VERSAL_NET_SIP_SVC_CALL_COUNT:
-		/* PM functions + default functions */
-		SMC_RET1(handle, 2);
-
 	case VERSAL_NET_SIP_SVC_UID:
 		SMC_UUID_RET(handle, versal_net_sip_uuid);
 
diff --git a/plat/xilinx/versal_net/tsp/tsp-versal_net.mk b/plat/xilinx/versal_net/tsp/tsp-versal_net.mk
index 87638ab4..ab7871c0 100644
--- a/plat/xilinx/versal_net/tsp/tsp-versal_net.mk
+++ b/plat/xilinx/versal_net/tsp/tsp-versal_net.mk
@@ -8,6 +8,3 @@
 PLAT_XILINX_COMMON := plat/xilinx/common/
 
 include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
-
-BL32_SOURCES		+=	plat/xilinx/versal_net/plat_topology.c		\
-				${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/xilinx/versal_net/versal_net_ipi.c b/plat/xilinx/versal_net/versal_net_ipi.c
index e8d8fb76..7c38921c 100644
--- a/plat/xilinx/versal_net/versal_net_ipi.c
+++ b/plat/xilinx/versal_net/versal_net_ipi.c
@@ -63,6 +63,62 @@ static const struct ipi_config versal_net_ipi_table[IPI_ID_MAX] = {
 		.ipi_reg_base = IPI5_REG_BASE,
 		.secure_only = 0,
 	},
+
+	/* PMC_NOBUF IPI */
+	[IPI_ID_PMC_NOBUF] = {
+		.ipi_bit_mask = PMC_NOBUF_TRIG_BIT,
+		.ipi_reg_base = PMC_NOBUF_REG_BASE,
+		.secure_only = IPI_SECURE_MASK,
+	},
+
+	/* IPI6 IPI */
+	[IPI_ID_6_NOBUF_95] = {
+		.ipi_bit_mask = IPI6_NOBUF_95_TRIG_BIT,
+		.ipi_reg_base = IPI6_NOBUF_95_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI1 NO BUF IPI */
+	[IPI_ID_1_NOBUF] = {
+		.ipi_bit_mask = IPI1_NOBUF_TRIG_BIT,
+		.ipi_reg_base = IPI1_NOBUF_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI2 NO BUF IPI */
+	[IPI_ID_2_NOBUF] = {
+		.ipi_bit_mask = IPI2_NOBUF_TRIG_BIT,
+		.ipi_reg_base = IPI2_NOBUF_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI3 NO BUF IPI */
+	[IPI_ID_3_NOBUF] = {
+		.ipi_bit_mask = IPI3_NOBUF_TRIG_BIT,
+		.ipi_reg_base = IPI3_NOBUF_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI4 NO BUF IPI */
+	[IPI_ID_4_NOBUF] = {
+		.ipi_bit_mask = IPI4_NOBUF_TRIG_BIT,
+		.ipi_reg_base = IPI4_NOBUF_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI5 NO BUF IPI */
+	[IPI_ID_5_NOBUF] = {
+		.ipi_bit_mask = IPI5_NOBUF_TRIG_BIT,
+		.ipi_reg_base = IPI5_NOBUF_REG_BASE,
+		.secure_only = 0,
+	},
+
+	/* IPI6 NO BUF IPI */
+	[IPI_ID_6_NOBUF_101] = {
+		.ipi_bit_mask = IPI6_NOBUF_101_TRIG_BIT,
+		.ipi_reg_base = IPI6_NOBUF_101_REG_BASE,
+		.secure_only = 0,
+	},
 };
 
 /* versal_net_ipi_config_table_init() - Initialize versal_net IPI configuration
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index dba1734c..0e698f73 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,8 +12,9 @@
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/smccc.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
+#include <plat_arm.h>
 #include <services/arm_arch_svc.h>
 
 #include <plat_ipi.h>
@@ -28,9 +29,9 @@
  * configure_mmu_elx() will give the available subset of that,
  */
 const mmap_region_t plat_zynqmp_mmap[] = {
-	{ DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
-	{ DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
-	{ CRF_APB_BASE, CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
+	MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	{0}
 };
 
@@ -244,8 +245,8 @@ static char *zynqmp_get_silicon_idcode_name(void)
 	ver = chipid[1] >> ZYNQMP_EFUSE_IPDISABLE_SHIFT;
 
 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
-		if (zynqmp_devices[i].id == id &&
-		    zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK)) {
+		if ((zynqmp_devices[i].id == id) &&
+		    (zynqmp_devices[i].ver == (ver & ZYNQMP_CSU_VERSION_MASK))) {
 			break;
 		}
 	}
@@ -299,8 +300,8 @@ static char *zynqmp_print_silicon_idcode(void)
 	tmp = id;
 	tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK |
 	       ZYNQMP_CSU_IDCODE_FAMILY_MASK;
-	maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
-		 ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
+	maskid = (ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT) |
+		 (ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT);
 	if (tmp != maskid) {
 		ERROR("Incorrect IDCODE 0x%x, maskid 0x%x\n", id, maskid);
 		return "UNKN";
@@ -348,7 +349,7 @@ static void zynqmp_print_platform_name(void)
 {
 	uint32_t ver = zynqmp_get_silicon_ver();
 	uint32_t rtl = zynqmp_get_rtl_ver();
-	char *label = "Unknown";
+	const char *label = "Unknown";
 
 	switch (ver) {
 	case ZYNQMP_CSU_VERSION_QEMU:
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index baf67170..ede3a21f 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <common/fdt_fixup.h>
 #include <common/fdt_wrappers.h>
 #include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 #include <libfdt.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
@@ -71,6 +72,10 @@ static inline void bl31_set_default_config(void)
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
+	(void)arg0;
+	(void)arg1;
+	(void)arg2;
+	(void)arg3;
 	uint64_t tfa_handoff_addr;
 
 	setup_console();
@@ -190,8 +195,6 @@ void bl31_plat_runtime_setup(void)
 #endif
 
 	custom_runtime_setup();
-
-	console_switch_state(CONSOLE_FLAG_RUNTIME);
 }
 
 /*
@@ -222,5 +225,5 @@ void bl31_plat_arch_setup(void)
 	custom_mmap_add();
 
 	setup_page_tables(bl_regions, plat_get_mmap());
-	enable_mmu_el3(0);
+	enable_mmu(0);
 }
diff --git a/plat/xilinx/zynqmp/custom_sip_svc.c b/plat/xilinx/zynqmp/custom_sip_svc.c
index b9664afa..c39e4bef 100644
--- a/plat/xilinx/zynqmp/custom_sip_svc.c
+++ b/plat/xilinx/zynqmp/custom_sip_svc.c
@@ -8,10 +8,18 @@
 #include <common/debug.h>
 #include <smccc_helpers.h>
 
+#include <custom_svc.h>
+
 uint64_t custom_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 			    uint64_t x3, uint64_t x4, void *cookie,
 			    void *handle, uint64_t flags)
 {
+	(void)x1;
+	(void)x2;
+	(void)x3;
+	(void)x4;
+	(void)cookie;
+	(void)flags;
 	WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
 	SMC_RET1(handle, SMC_UNK);
 }
diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h
index afa102d8..1b41b7cd 100644
--- a/plat/xilinx/zynqmp/include/plat_private.h
+++ b/plat/xilinx/zynqmp/include/plat_private.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,7 +13,7 @@
 #include <bl31/interrupt_mgmt.h>
 #include <common/bl_common.h>
 #include <drivers/cadence/cdns_uart.h>
-#include <lib/xlat_tables/xlat_tables.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
 
 void zynqmp_config_setup(void);
 
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index d715ce2f..68485cf4 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -10,13 +10,24 @@
 #include <plat/arm/common/smccc_def.h>
 #include <plat/common/common_def.h>
 
+#define ZYNQMP_CONSOLE_ID_none		0
 #define ZYNQMP_CONSOLE_ID_cadence	1
 #define ZYNQMP_CONSOLE_ID_cadence0	1
 #define ZYNQMP_CONSOLE_ID_cadence1	2
 #define ZYNQMP_CONSOLE_ID_dcc		3
+#define ZYNQMP_CONSOLE_ID_dtb		4
 
 #define CONSOLE_IS(con)	(ZYNQMP_CONSOLE_ID_ ## con == ZYNQMP_CONSOLE)
 
+/* Runtime console */
+#define RT_CONSOLE_ID_cadence	1
+#define RT_CONSOLE_ID_cadence0	1
+#define RT_CONSOLE_ID_cadence1	2
+#define RT_CONSOLE_ID_dcc	3
+#define RT_CONSOLE_ID_dtb	4
+
+#define RT_CONSOLE_IS(con)	(RT_CONSOLE_ID_ ## con == CONSOLE_RUNTIME)
+
 /* Default counter frequency */
 #define ZYNQMP_DEFAULT_COUNTER_FREQ	0U
 
@@ -144,14 +155,38 @@
 #define ZYNQMP_UART0_BASE		U(0xFF000000)
 #define ZYNQMP_UART1_BASE		U(0xFF010000)
 
-#if CONSOLE_IS(cadence) || CONSOLE_IS(dcc)
+/* Boot console */
+#if CONSOLE_IS(cadence) || CONSOLE_IS(dtb)
 # define UART_BASE	ZYNQMP_UART0_BASE
+# define UART_TYPE	CONSOLE_CDNS
 #elif CONSOLE_IS(cadence1)
 # define UART_BASE	ZYNQMP_UART1_BASE
+# define UART_TYPE	CONSOLE_CDNS
+#elif CONSOLE_IS(dcc)
+# define UART_BASE	0x0
+# define UART_TYPE	CONSOLE_DCC
+#elif CONSOLE_IS(none)
+# define UART_TYPE	CONSOLE_NONE
 #else
 # error "invalid ZYNQMP_CONSOLE"
 #endif
 
+/* Runtime console */
+#if defined(CONSOLE_RUNTIME)
+#if RT_CONSOLE_IS(cadence) || RT_CONSOLE_IS(dtb)
+# define RT_UART_BASE	ZYNQMP_UART0_BASE
+# define RT_UART_TYPE	CONSOLE_CDNS
+#elif RT_CONSOLE_IS(cadence1)
+# define RT_UART_BASE	ZYNQMP_UART1_BASE
+# define RT_UART_TYPE	CONSOLE_CDNS
+#elif RT_CONSOLE_IS(dcc)
+# define RT_UART_BASE	0x0
+# define RT_UART_TYPE	CONSOLE_DCC
+#else
+# error "invalid CONSOLE_RUNTIME"
+#endif
+#endif
+
 /* Must be non zero */
 #define UART_BAUDRATE		115200
 
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index c6c6c4ba..58db2e4c 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -42,7 +42,11 @@ static int32_t zynqmp_pwr_domain_on(u_register_t mpidr)
 	if (cpu_id == -1) {
 		return PSCI_E_INTERN_FAIL;
 	}
+
 	proc = pm_get_proc(cpu_id);
+	if (proc == NULL) {
+		return PSCI_E_INTERN_FAIL;
+	}
 
 	/* Check the APU proc status before wakeup */
 	ret = pm_get_node_status(proc->node_id, buff);
@@ -54,7 +58,7 @@ static int32_t zynqmp_pwr_domain_on(u_register_t mpidr)
 	pm_client_wakeup(proc);
 
 	/* Send request to PMU to wake up selected APU CPU core */
-	pm_req_wakeup(proc->node_id, 1, zynqmp_sec_entry, REQ_ACK_BLOCKING);
+	(void)pm_req_wakeup(proc->node_id, 1, zynqmp_sec_entry, REQ_ACK_BLOCKING);
 
 	return PSCI_E_SUCCESS;
 }
@@ -64,6 +68,10 @@ static void zynqmp_pwr_domain_off(const psci_power_state_t *target_state)
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
@@ -80,7 +88,7 @@ static void zynqmp_pwr_domain_off(const psci_power_state_t *target_state)
 	 * invoking CPU_on function, during which resume address will
 	 * be set.
 	 */
-	pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0);
+	(void)pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0);
 }
 
 static void zynqmp_pwr_domain_suspend(const psci_power_state_t *target_state)
@@ -89,15 +97,19 @@ static void zynqmp_pwr_domain_suspend(const psci_power_state_t *target_state)
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
 
-	state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
+	state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ?
 		PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
 
 	/* Send request to PMU to suspend this core */
-	pm_self_suspend(proc->node_id, MAX_LATENCY, state, zynqmp_sec_entry);
+	(void)pm_self_suspend(proc->node_id, MAX_LATENCY, state, zynqmp_sec_entry);
 
 	/* APU is to be turned off */
 	if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
@@ -121,6 +133,10 @@ static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_st
 	uint32_t cpu_id = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpu_id);
 
+	if (proc == NULL) {
+		return;
+	}
+
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) {
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
@@ -150,10 +166,10 @@ static void __dead2 zynqmp_system_off(void)
 	plat_arm_interconnect_exit_coherency();
 
 	/* Send the power down request to the PMU */
-	pm_system_shutdown(PMF_SHUTDOWN_TYPE_SHUTDOWN,
+	(void)pm_system_shutdown((uint32_t)PMF_SHUTDOWN_TYPE_SHUTDOWN,
 			   pm_get_shutdown_scope());
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -164,10 +180,10 @@ static void __dead2 zynqmp_system_reset(void)
 	plat_arm_interconnect_exit_coherency();
 
 	/* Send the system reset request to the PMU */
-	pm_system_shutdown(PMF_SHUTDOWN_TYPE_RESET,
+	(void)pm_system_shutdown((uint32_t)PMF_SHUTDOWN_TYPE_RESET,
 			   pm_get_shutdown_scope());
 
-	while (1) {
+	while (true) {
 		wfi();
 	}
 }
@@ -188,7 +204,7 @@ static int32_t zynqmp_validate_power_state(uint32_t power_state,
 		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
 	}
 	/* We expect the 'state id' to be zero */
-	if (psci_get_pstate_id(power_state)) {
+	if (psci_get_pstate_id(power_state) != 0U) {
 		return PSCI_E_INVALID_PARAMS;
 	}
 
diff --git a/plat/xilinx/zynqmp/plat_topology.c b/plat/xilinx/zynqmp/plat_topology.c
index 25966508..3755513c 100644
--- a/plat/xilinx/zynqmp/plat_topology.c
+++ b/plat/xilinx/zynqmp/plat_topology.c
@@ -5,6 +5,8 @@
  */
 #include <stdint.h>
 
+#include <plat/common/platform.h>
+
 static const uint8_t plat_power_domain_tree_desc[] = {1, 4};
 
 const uint8_t *plat_get_power_domain_tree_desc(void)
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index e3a979ea..65faa2fc 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -10,7 +10,7 @@
 
 int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
-	if (mpidr & MPIDR_CLUSTER_MASK) {
+	if ((mpidr & MPIDR_CLUSTER_MASK) != 0U) {
 		return -1;
 	}
 
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index e266615f..5a866582 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -2,7 +2,7 @@
 # Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
 # Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved.
 # Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
-# Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -16,11 +16,12 @@ ZYNQMP_WDT_RESTART := 0
 IPI_CRC_CHECK := 0
 override RESET_TO_BL31 := 1
 override WARMBOOT_ENABLE_DCACHE_EARLY := 1
+ENABLE_LTO := 1
 
 EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
 
 # pncd SPD requires secure SGI to be handled at EL1
-ifeq (${SPD}, $(filter ${SPD},pncd tspd))
+ifeq (${SPD}, $(filter ${SPD},pncd tspd opteed))
 ifeq (${ZYNQMP_WDT_RESTART},1)
 $(error "Error: ZYNQMP_WDT_RESTART and SPD=pncd are incompatible")
 endif
@@ -34,15 +35,11 @@ ENABLE_SVE_FOR_NS	:= 0
 
 WORKAROUND_CVE_2017_5715	:=	0
 
-ARM_XLAT_TABLES_LIB_V1		:=	1
-$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
-$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
-
 ifdef ZYNQMP_ATF_MEM_BASE
     $(eval $(call add_define,ZYNQMP_ATF_MEM_BASE))
 
     ifndef ZYNQMP_ATF_MEM_SIZE
-        $(error "ZYNQMP_ATF_BASE defined without ZYNQMP_ATF_SIZE")
+        $(error "ZYNQMP_ATF_MEM_BASE defined without ZYNQMP_ATF_MEM_SIZE")
     endif
     $(eval $(call add_define,ZYNQMP_ATF_MEM_SIZE))
 
@@ -59,7 +56,7 @@ ifdef ZYNQMP_BL32_MEM_BASE
     $(eval $(call add_define,ZYNQMP_BL32_MEM_BASE))
 
     ifndef ZYNQMP_BL32_MEM_SIZE
-        $(error "ZYNQMP_BL32_BASE defined without ZYNQMP_BL32_SIZE")
+        $(error "ZYNQMP_BL32_MEM_BASE defined without ZYNQMP_BL32_MEM_SIZE")
     endif
     $(eval $(call add_define,ZYNQMP_BL32_MEM_SIZE))
 endif
@@ -95,10 +92,9 @@ PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
 include lib/libfdt/libfdt.mk
 # Include GICv2 driver files
 include drivers/arm/gic/v2/gicv2.mk
+include lib/xlat_tables_v2/xlat_tables.mk
 
-PLAT_BL_COMMON_SOURCES	:=	lib/xlat_tables/xlat_tables_common.c		\
-				lib/xlat_tables/aarch64/xlat_tables.c		\
-				drivers/arm/dcc/dcc_console.c			\
+PLAT_BL_COMMON_SOURCES	:=	drivers/arm/dcc/dcc_console.c			\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
 				${GICV2_SOURCES}				\
@@ -111,15 +107,30 @@ PLAT_BL_COMMON_SOURCES	:=	lib/xlat_tables/xlat_tables_common.c		\
 				plat/xilinx/zynqmp/zynqmp_ipi.c			\
 				plat/common/aarch64/crash_console_helpers.S	\
 				plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S	\
-				plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+				plat/xilinx/zynqmp/aarch64/zynqmp_common.c	\
+				${XLAT_TABLES_LIB_SRCS}
 
 ZYNQMP_CONSOLE	?=	cadence
-ifeq (${ZYNQMP_CONSOLE}, $(filter ${ZYNQMP_CONSOLE},cadence cadence0 cadence1 dcc))
+ifeq (${ZYNQMP_CONSOLE}, $(filter ${ZYNQMP_CONSOLE},cadence cadence0 cadence1 dcc dtb none))
 else
   $(error "Please define ZYNQMP_CONSOLE")
 endif
 $(eval $(call add_define_val,ZYNQMP_CONSOLE,ZYNQMP_CONSOLE_ID_${ZYNQMP_CONSOLE}))
 
+# Runtime console in default console in DEBUG build
+ifeq ($(DEBUG), 1)
+CONSOLE_RUNTIME ?= cadence
+endif
+
+# Runtime console
+ifdef CONSOLE_RUNTIME
+ifeq (${CONSOLE_RUNTIME}, $(filter ${CONSOLE_RUNTIME},cadence cadence0 cadence1 dcc dtb))
+$(eval $(call add_define_val,CONSOLE_RUNTIME,RT_CONSOLE_ID_${CONSOLE_RUNTIME}))
+else
+$(error "Please define CONSOLE_RUNTIME")
+endif
+endif
+
 # Build PM code as a Library
 include plat/xilinx/zynqmp/libpm.mk
 
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 9682e590..91adb07b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -1226,7 +1226,7 @@ static struct pm_clock clocks[] = {
 		.control_reg = CRF_APB_ACPU_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_ACPU | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_NA_PARENT
 		}),
 		.nodes = &acpu_full_nodes,
@@ -2117,7 +2117,7 @@ static struct pm_clock clocks[] = {
 		.control_reg = CRF_APB_ACPU_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_ACPU | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_NA_PARENT
 		}),
 		.nodes = &acpu_half_nodes,
@@ -2140,7 +2140,7 @@ static struct pm_clock clocks[] = {
 		.control_reg = CRF_APB_GPU_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_GPU_REF | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_NA_PARENT
 		}),
 		.nodes = &gpu_pp0_nodes,
@@ -2151,7 +2151,7 @@ static struct pm_clock clocks[] = {
 		.control_reg = CRF_APB_GPU_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_GPU_REF | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_NA_PARENT
 		}),
 		.nodes = &gpu_pp1_nodes,
@@ -2176,7 +2176,7 @@ static struct pm_clock clocks[] = {
 		.control_reg = CRL_APB_CPU_R5_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			(CLK_CPU_R5 | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
 			CLK_DUMMY_PARENT,
 			CLK_NA_PARENT
 		}),
@@ -2456,14 +2456,14 @@ enum pm_ret_status pm_api_clock_get_num_clocks(uint32_t *nclocks)
 void pm_api_clock_get_name(uint32_t clock_id, char *name)
 {
 	if (clock_id == CLK_MAX) {
-		memcpy(name, END_OF_CLK, sizeof(END_OF_CLK) > CLK_NAME_LEN ?
-					 CLK_NAME_LEN : sizeof(END_OF_CLK));
+		(void)memcpy(name, END_OF_CLK, ((sizeof(END_OF_CLK) > CLK_NAME_LEN) ?
+					 CLK_NAME_LEN : sizeof(END_OF_CLK)));
 	} else if ((clock_id > CLK_MAX) || (!pm_clock_valid(clock_id))) {
-		memset(name, 0, CLK_NAME_LEN);
+		(void)memset(name, 0, CLK_NAME_LEN);
 	} else if (clock_id < CLK_MAX_OUTPUT_CLK) {
-		memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
+		(void)memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
 	} else {
-		memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
+		(void)memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
 		       CLK_NAME_LEN);
 	}
 }
@@ -2486,7 +2486,7 @@ enum pm_ret_status pm_api_clock_get_topology(uint32_t clock_id,
 					     uint32_t index,
 					     uint32_t *topology)
 {
-	struct pm_clock_node *clock_nodes;
+	const struct pm_clock_node *clock_nodes;
 	uint8_t num_nodes;
 	uint32_t i;
 	uint16_t typeflags;
@@ -2499,7 +2499,7 @@ enum pm_ret_status pm_api_clock_get_topology(uint32_t clock_id,
 		return PM_RET_ERROR_NOTSUPPORTED;
 	}
 
-	memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
+	(void)memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
 	clock_nodes = *clocks[clock_id].nodes;
 	num_nodes = clocks[clock_id].num_nodes;
 
@@ -2543,7 +2543,7 @@ enum pm_ret_status pm_api_clock_get_fixedfactor_params(uint32_t clock_id,
 						       uint32_t *mul,
 						       uint32_t *div)
 {
-	struct pm_clock_node *clock_nodes;
+	const struct pm_clock_node *clock_nodes;
 	uint8_t num_nodes;
 	uint32_t type, i;
 
@@ -2598,7 +2598,7 @@ enum pm_ret_status pm_api_clock_get_parents(uint32_t clock_id,
 					    uint32_t *parents)
 {
 	uint32_t i;
-	int32_t *clk_parents;
+	const int32_t *clk_parents;
 
 	if (!pm_clock_valid(clock_id)) {
 		return PM_RET_ERROR_ARGS;
@@ -2613,7 +2613,7 @@ enum pm_ret_status pm_api_clock_get_parents(uint32_t clock_id,
 		return PM_RET_ERROR_ARGS;
 	}
 
-	memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
+	(void)memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
 
 	/* Skip parent till index */
 	for (i = 0; i < index; i++) {
@@ -2675,7 +2675,7 @@ enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id,
 						uint32_t *max_div)
 {
 	uint32_t i;
-	struct pm_clock_node *nodes;
+	const struct pm_clock_node *nodes;
 
 	if (clock_id >= CLK_MAX_OUTPUT_CLK) {
 		return PM_RET_ERROR_ARGS;
@@ -2684,8 +2684,8 @@ enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id,
 	nodes = *clocks[clock_id].nodes;
 	for (i = 0; i < clocks[clock_id].num_nodes; i++) {
 		if (nodes[i].type == div_type) {
-			if (CLK_DIVIDER_POWER_OF_TWO &
-					nodes[i].typeflags) {
+			if ((CLK_DIVIDER_POWER_OF_TWO &
+					nodes[i].typeflags) != 0U) {
 				*max_div = (1U << (BIT(nodes[i].width) - 1U));
 			} else {
 				*max_div = BIT(nodes[i].width) - 1U;
@@ -2789,9 +2789,9 @@ struct pm_pll *pm_clock_get_pll(enum clock_id clock_id)
 enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
 					    enum pm_node_id *node_id)
 {
-	struct pm_pll *pll = pm_clock_get_pll(clock_id);
+	const struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if (pll) {
+	if (pll != NULL) {
 		*node_id = pll->nid;
 		return PM_RET_SUCCESS;
 	}
@@ -2812,10 +2812,10 @@ struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id)
 	uint32_t i;
 
 	for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
-		if (pm_plls[i].pre_src == clock_id ||
-		    pm_plls[i].post_src == clock_id ||
-		    pm_plls[i].div2 == clock_id ||
-		    pm_plls[i].bypass == clock_id) {
+		if ((pm_plls[i].pre_src == clock_id) ||
+		    (pm_plls[i].post_src == clock_id) ||
+		    (pm_plls[i].div2 == clock_id) ||
+		    (pm_plls[i].bypass == clock_id)) {
 			return &pm_plls[i];
 		}
 	}
@@ -2883,7 +2883,7 @@ enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
 	enum pm_ret_status status;
 	enum pm_pll_mode mode;
 
-	if ((pll == NULL) || !state) {
+	if ((pll == NULL) || (state == NULL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -2990,7 +2990,7 @@ enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
 {
 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if ((pll == NULL) || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)) {
+	if ((pll == NULL) || ((mode != PLL_FRAC_MODE) && (mode != PLL_INT_MODE))) {
 		return PM_RET_ERROR_ARGS;
 	}
 	pll->mode = mode;
@@ -3011,9 +3011,9 @@ enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
 enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
 					 uint32_t *mode)
 {
-	struct pm_pll *pll = pm_clock_get_pll(clock_id);
+	const struct pm_pll *pll = pm_clock_get_pll(clock_id);
 
-	if ((pll == NULL) || !mode) {
+	if ((pll == NULL) || (mode == NULL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 	*mode = pll->mode;
@@ -3052,7 +3052,7 @@ enum pm_ret_status pm_clock_id_is_valid(uint32_t clock_id)
 uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id)
 {
 	uint32_t i;
-	struct pm_clock_node *nodes;
+	const struct pm_clock_node *nodes;
 
 	if (clock_id >= CLK_MAX_OUTPUT_CLK) {
 		return 0;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index dd214996..0dbfa57d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -62,7 +62,7 @@ static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
 {
 	uint32_t val;
 
-	if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) {
+	if ((mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) != 0U) {
 		return PM_RET_ERROR_ACCESS;
 	}
 
@@ -165,8 +165,8 @@ static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
 static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
 						       uint32_t value)
 {
-	if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
-	     value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX) {
+	if ((((value != PM_TAPDELAY_BYPASS_ENABLE) &&
+	     (value != PM_TAPDELAY_BYPASS_DISABLE)) || (type >= PM_TAPDELAY_MAX))) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -481,7 +481,7 @@ static enum pm_ret_status pm_ioctl_afi(uint32_t index,
 					      uint32_t value)
 {
 	uint32_t mask;
-	uint32_t regarr[] = {0xFD360000U,
+	const uint32_t regarr[] = {0xFD360000U,
 				0xFD360014U,
 				0xFD370000U,
 				0xFD370014U,
@@ -682,7 +682,7 @@ enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
  */
 enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask)
 {
-	uint8_t supported_ids[] = {
+	const uint8_t supported_ids[] = {
 		IOCTL_GET_RPU_OPER_MODE,
 		IOCTL_SET_RPU_OPER_MODE,
 		IOCTL_RPU_BOOT_ADDR_CONFIG,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
index 2d8c23b4..1477e25d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -2012,9 +2012,9 @@ enum pm_ret_status pm_api_pinctrl_get_num_func_groups(uint32_t fid,
 void pm_api_pinctrl_get_function_name(uint32_t fid, char *name)
 {
 	if (fid >= MAX_FUNCTION) {
-		memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
+		(void)memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
 	} else {
-		memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
+		(void)memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
 	}
 }
 
@@ -2049,7 +2049,7 @@ enum pm_ret_status pm_api_pinctrl_get_function_groups(uint32_t fid,
 		return PM_RET_ERROR_ARGS;
 	}
 
-	memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
+	(void)memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
 
 	grps = pinctrl_functions[fid].group_base;
 	end_of_grp_offset = grps + pinctrl_functions[fid].group_size;
@@ -2088,13 +2088,13 @@ enum pm_ret_status pm_api_pinctrl_get_pin_groups(uint32_t pin,
 						 uint16_t *groups)
 {
 	uint32_t i;
-	uint16_t *grps;
+	const uint16_t *grps;
 
 	if (pin >= MAX_PIN) {
 		return PM_RET_ERROR_ARGS;
 	}
 
-	memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
+	(void)memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
 
 	grps = *zynqmp_pin_groups[pin].groups;
 	if (grps == NULL) {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 4afa01d6..a5172575 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -204,7 +204,7 @@ static void pm_client_set_wakeup_sources(void)
 			continue;
 		}
 
-		while (reg) {
+		while (reg != 0U) {
 			enum pm_node_id node;
 			uint32_t idx, ret, irq, lowest_set = reg & (-reg);
 
@@ -218,7 +218,7 @@ static void pm_client_set_wakeup_sources(void)
 			node = irq_to_pm_node(irq);
 			reg &= ~lowest_set;
 
-			if (node > NODE_UNKNOWN && node < NODE_MAX) {
+			if ((node > NODE_UNKNOWN) && (node < NODE_MAX)) {
 				if (pm_wakeup_nodes_set[node] == 0U) {
 					ret = pm_set_wakeup_source(NODE_APU, node, 1U);
 					pm_wakeup_nodes_set[node] = (ret == PM_RET_SUCCESS) ? 1U : 0U;
@@ -244,23 +244,6 @@ const struct pm_proc *pm_get_proc(uint32_t cpuid)
 	return NULL;
 }
 
-/**
- * pm_get_proc_by_node() - returns pointer to the proc structure.
- * @nid: node id of the processor.
- *
- * Return: pointer to a proc structure if proc is found, otherwise NULL.
- *
- */
-const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid)
-{
-	for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
-		if (nid == pm_procs_all[i].node_id) {
-			return &pm_procs_all[i];
-		}
-	}
-	return NULL;
-}
-
 /**
  * pm_get_cpuid() - get the local cpu ID for a global node ID.
  * @nid: node id of the processor.
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index 6b42055d..719ab6f8 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -268,10 +268,16 @@ enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
 				   uint32_t state,
 				   uintptr_t address)
 {
+	(void)nid;
 	uint32_t payload[PAYLOAD_ARG_CNT];
 	uint32_t cpuid = plat_my_core_pos();
 	const struct pm_proc *proc = pm_get_proc(cpuid);
 
+	if (proc == NULL) {
+		WARN("Failed to get proc %d\n", cpuid);
+		return PM_RET_ERROR_INTERNAL;
+	}
+
 	/*
 	 * Do client specific suspend operations
 	 * (e.g. set powerdown request bit)
@@ -763,7 +769,7 @@ static enum pm_ret_status fw_api_version(uint32_t id, uint32_t *version,
 enum pm_ret_status check_api_dependency(uint8_t id)
 {
 	uint8_t i;
-	uint32_t version;
+	uint32_t version_type;
 	int ret;
 
 	for (i = 0U; i < ARRAY_SIZE(api_dep_table); i++) {
@@ -773,13 +779,13 @@ enum pm_ret_status check_api_dependency(uint8_t id)
 			}
 
 			ret = fw_api_version(api_dep_table[i].api_id,
-					     &version, 1);
+					     &version_type, 1);
 			if (ret != PM_RET_SUCCESS) {
 				return ret;
 			}
 
 			/* Check if fw version matches TF-A expected version */
-			if (version != tfa_expected_ver_id[api_dep_table[i].api_id]) {
+			if (version_type != tfa_expected_ver_id[api_dep_table[i].api_id]) {
 				return PM_RET_ERROR_NOTSUPPORTED;
 			}
 		}
@@ -914,7 +920,7 @@ static enum pm_ret_status feature_check_partial(uint32_t api_id,
 enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *version,
 				    uint32_t *bit_mask, uint8_t len)
 {
-	uint32_t ret_payload[PAYLOAD_ARG_CNT] = {0U};
+	uint32_t ret_payload[RET_PAYLOAD_ARG_CNT] = {0U};
 	uint32_t status;
 
 	/* Get API version implemented in TF-A */
@@ -1109,7 +1115,7 @@ static enum pm_ret_status pm_clock_gate(uint32_t clock_id,
 		return status;
 	}
 
-	if (enable) {
+	if (enable != 0U) {
 		api_id = PM_CLOCK_ENABLE;
 	} else {
 		api_id = PM_CLOCK_DISABLE;
@@ -1144,7 +1150,7 @@ enum pm_ret_status pm_clock_enable(uint32_t clock_id)
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_enable(pll);
 	}
 
@@ -1169,7 +1175,7 @@ enum pm_ret_status pm_clock_disable(uint32_t clock_id)
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_disable(pll);
 	}
 
@@ -1197,9 +1203,9 @@ enum pm_ret_status pm_clock_getstate(uint32_t clock_id,
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll(clock_id);
-	if (pll)
+	if (pll != NULL) {
 		return pm_clock_pll_get_state(pll, state);
-
+	}
 	/* Check if clock ID is a valid on-chip clock */
 	status = pm_clock_id_is_valid(clock_id);
 	if (status != PM_RET_SUCCESS) {
@@ -1291,7 +1297,7 @@ enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
 		return status;
 	}
 
-	if (pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) {
+	if ((pm_clock_has_div(clock_id, PM_CLOCK_DIV0_ID)) != 0U) {
 		/* Send request to the PMU to get div0 */
 		PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
 				 PM_CLOCK_DIV0_ID);
@@ -1302,7 +1308,7 @@ enum pm_ret_status pm_clock_getdivider(uint32_t clock_id,
 		*divider = val;
 	}
 
-	if (pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) {
+	if ((pm_clock_has_div(clock_id, PM_CLOCK_DIV1_ID)) != 0U) {
 		/* Send request to the PMU to get div1 */
 		PM_PACK_PAYLOAD3(payload, PM_CLOCK_GETDIVIDER, clock_id,
 				 PM_CLOCK_DIV1_ID);
@@ -1335,7 +1341,7 @@ enum pm_ret_status pm_clock_setparent(uint32_t clock_id,
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll_by_related_clk(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_set_parent(pll, clock_id, parent_index);
 	}
 
@@ -1370,7 +1376,7 @@ enum pm_ret_status pm_clock_getparent(uint32_t clock_id,
 
 	/* First try to handle it as a PLL */
 	pll = pm_clock_get_pll_by_related_clk(clock_id);
-	if (pll) {
+	if (pll != NULL) {
 		return pm_clock_pll_get_parent(pll, clock_id, parent_index);
 	}
 
@@ -1509,6 +1515,7 @@ static enum pm_ret_status pm_pinctrl_get_pin_groups(uint32_t pin_id,
 void pm_query_data(enum pm_query_ids qid, uint32_t arg1, uint32_t arg2,
 		   uint32_t arg3, uint32_t *data)
 {
+	(void)arg3;
 	switch (qid) {
 	case PM_QID_CLOCK_GET_NAME:
 		pm_clock_get_name(arg1, (char *)data);
@@ -1650,7 +1657,7 @@ enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	/* Check if given node ID is a PLL node */
-	if (nid < NODE_APLL || nid > NODE_IOPLL) {
+	if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -1681,7 +1688,7 @@ enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	/* Check if given node ID is a PLL node */
-	if (nid < NODE_APLL || nid > NODE_IOPLL) {
+	if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -1714,7 +1721,7 @@ enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	/* Check if given node ID is a PLL node */
-	if (nid < NODE_APLL || nid > NODE_IOPLL) {
+	if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 
@@ -1742,7 +1749,7 @@ enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode)
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	/* Check if given node ID is a PLL node */
-	if (nid < NODE_APLL || nid > NODE_IOPLL) {
+	if ((nid < NODE_APLL) || (nid > NODE_IOPLL)) {
 		return PM_RET_ERROR_ARGS;
 	}
 
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
index 5a6a9f8c..738699ea 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_svc_main.c
@@ -22,6 +22,7 @@
 #include <plat_private.h>
 #include "pm_client.h"
 #include "pm_ipi.h"
+#include "pm_svc_main.h"
 #include "zynqmp_pm_api_sys.h"
 #include "zynqmp_pm_defs.h"
 
@@ -281,11 +282,14 @@ int32_t pm_setup(void)
 uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 			uint64_t x4, const void *cookie, void *handle, uint64_t flags)
 {
+	(void)x4;
+	(void)cookie;
+	(void)flags;
 	enum pm_ret_status ret;
 	uint32_t payload[PAYLOAD_ARG_CNT];
 
 	uint32_t pm_arg[5];
-	uint32_t result[PAYLOAD_ARG_CNT] = {0};
+	uint32_t result[RET_PAYLOAD_ARG_CNT] = {0};
 	uint32_t api_id;
 
 	/* Handle case where PM wasn't initialized properly */
@@ -371,7 +375,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		uint32_t value = 0U;
 
 		ret = pm_fpga_get_status(&value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
 	}
 
 	case PM_SECURE_RSA_AES:
@@ -386,15 +390,15 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		}
 
 		SMC_RET2(handle,
-			 (uint64_t)result[0] | ((uint64_t)result[1] << 32),
-			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
+			 ((uint64_t)result[0] | ((uint64_t)result[1] << 32)),
+			 ((uint64_t)result[2] | ((uint64_t)result[3] << 32)));
 	case PM_IOCTL:
 	{
 		uint32_t value = 0U;
 
 		ret = pm_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
 			       pm_arg[3], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
 	}
 
 	case PM_QUERY_DATA:
@@ -403,8 +407,8 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 
 		pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
 			      pm_arg[3], data);
-		SMC_RET2(handle, (uint64_t)data[0]  | ((uint64_t)data[1] << 32),
-			 (uint64_t)data[2] | ((uint64_t)data[3] << 32));
+		SMC_RET2(handle, ((uint64_t)data[0]  | ((uint64_t)data[1] << 32)),
+			 ((uint64_t)data[2] | ((uint64_t)data[3] << 32)));
 	}
 
 	case PM_CLOCK_ENABLE:
@@ -420,7 +424,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		uint32_t value = 0U;
 
 		ret = pm_clock_getstate(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
 	}
 
 	case PM_CLOCK_SETDIVIDER:
@@ -432,7 +436,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		uint32_t value = 0U;
 
 		ret = pm_clock_getdivider(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32)));
 	}
 
 	case PM_CLOCK_SETPARENT:
@@ -444,7 +448,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		uint32_t value = 0U;
 
 		ret = pm_clock_getparent(pm_arg[0], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
 	}
 
 	case PM_GET_TRUSTZONE_VERSION:
@@ -469,7 +473,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 	{
 		ret = pm_secure_image(pm_arg[0], pm_arg[1], pm_arg[2],
 				      pm_arg[3], &result[0]);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
+		SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)result[0] << 32U)),
 			 result[1]);
 	}
 
@@ -479,7 +483,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 
 		ret = pm_fpga_read(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3],
 				   &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
 	}
 
 	case PM_SECURE_AES:
@@ -487,7 +491,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		uint32_t value = 0U;
 
 		ret = pm_aes_engine(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
 	}
 
 	case PM_PLL_SET_PARAMETER:
@@ -499,7 +503,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		uint32_t value = 0U;
 
 		ret = pm_pll_get_parameter(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32U));
+		SMC_RET1(handle, ((uint64_t)ret | ((uint64_t)value << 32U)));
 	}
 
 	case PM_PLL_SET_MODE:
@@ -511,7 +515,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		uint32_t mode = 0U;
 
 		ret = pm_pll_get_mode(pm_arg[0], &mode);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32U));
+		SMC_RET1(handle, ((uint64_t)ret | ((uint64_t)mode << 32U)));
 	}
 
 	case PM_REGISTER_ACCESS:
@@ -520,7 +524,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 
 		ret = pm_register_access(pm_arg[0], pm_arg[1], pm_arg[2],
 					 pm_arg[3], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, ((uint64_t)ret | (((uint64_t)value) << 32U)));
 	}
 
 	case PM_EFUSE_ACCESS:
@@ -535,7 +539,7 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		}
 #endif
 		ret = pm_efuse_access(pm_arg[0], pm_arg[1], &value);
-		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
+		SMC_RET1(handle, (uint64_t)ret | (((uint64_t)value) << 32U));
 	}
 
 	case PM_FPGA_GET_VERSION:
@@ -546,19 +550,19 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		PM_PACK_PAYLOAD5(payload, smc_fid & FUNCID_NUM_MASK,
 				 pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
 		ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, 3U);
-		SMC_RET2(handle, (uint64_t)ret | (uint64_t)ret_payload[0] << 32U,
-			 (uint64_t)ret_payload[1] | (uint64_t)ret_payload[2] << 32U);
+		SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)ret_payload[0] << 32U)),
+			 ((uint64_t)ret_payload[1] | ((uint64_t)ret_payload[2] << 32U)));
 	}
 
 	case PM_FEATURE_CHECK:
 	{
-		uint32_t version = 0;
+		uint32_t version_type = 0;
 		uint32_t bit_mask[2] = {0};
 
-		ret = pm_feature_check(pm_arg[0], &version, bit_mask,
+		ret = pm_feature_check(pm_arg[0], &version_type, bit_mask,
 				       ARRAY_SIZE(bit_mask));
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)version << 32U),
-			 (uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32U));
+		SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)version_type << 32U)),
+			 ((uint64_t)bit_mask[0] | ((uint64_t)bit_mask[1] << 32U)));
 	}
 
 	default:
@@ -566,8 +570,8 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
 		PM_PACK_PAYLOAD6(payload, api_id, pm_arg[0], pm_arg[1],
 				 pm_arg[2], pm_arg[3], pm_arg[4]);
 		ret = pm_ipi_send_sync(primary_proc, payload, result,
-				       PAYLOAD_ARG_CNT);
-		SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32U),
-			 (uint64_t)result[1] | ((uint64_t)result[2] << 32U));
+				       RET_PAYLOAD_ARG_CNT);
+		SMC_RET2(handle, ((uint64_t)ret | ((uint64_t)result[0] << 32U)),
+			 ((uint64_t)result[1] | ((uint64_t)result[2] << 32U)));
 	}
 }
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 6a8555ee..1baefb3c 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -18,7 +18,6 @@
 #include "zynqmp_pm_svc_main.h"
 
 /* SMC function IDs for SiP Service queries */
-#define ZYNQMP_SIP_SVC_CALL_COUNT	U(0x8200ff00)
 #define ZYNQMP_SIP_SVC_UID		U(0x8200ff01)
 #define ZYNQMP_SIP_SVC_VERSION		U(0x8200ff03)
 
@@ -82,7 +81,7 @@ static uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
 	VERBOSE("SMCID: 0x%08x, x1: 0x%016" PRIx64 ", x2: 0x%016" PRIx64 ", x3: 0x%016" PRIx64 ", x4: 0x%016" PRIx64 "\n",
 		smc_fid, x1, x2, x3, x4);
 
-	if (smc_fid & SIP_FID_MASK) {
+	if ((smc_fid & (uint32_t)SIP_FID_MASK) != 0U) {
 		WARN("SMC out of SiP assinged range: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
@@ -100,10 +99,6 @@ static uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
 	}
 
 	switch (smc_fid) {
-	case ZYNQMP_SIP_SVC_CALL_COUNT:
-		/* PM functions + default functions */
-		SMC_RET1(handle, PM_API_MAX + 2);
-
 	case ZYNQMP_SIP_SVC_UID:
 		SMC_UUID_RET(handle, zynqmp_sip_uuid);
 
diff --git a/poetry.lock b/poetry.lock
index 08b2b374..9a907044 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
 
 [[package]]
 name = "alabaster"
@@ -13,163 +13,201 @@ files = [
 
 [[package]]
 name = "anytree"
-version = "2.8.0"
-description = "Powerful and Lightweight Python Tree Data Structure.."
+version = "2.12.1"
+description = "Powerful and Lightweight Python Tree Data Structure with various plugins"
 optional = false
-python-versions = "*"
+python-versions = ">=3.7.2,<4"
 files = [
-    {file = "anytree-2.8.0-py2.py3-none-any.whl", hash = "sha256:14c55ac77492b11532395049a03b773d14c7e30b22aa012e337b1e983de31521"},
-    {file = "anytree-2.8.0.tar.gz", hash = "sha256:3f0f93f355a91bc3e6245319bf4c1d50e3416cc7a35cc1133c1ff38306bbccab"},
+    {file = "anytree-2.12.1-py3-none-any.whl", hash = "sha256:5ea9e61caf96db1e5b3d0a914378d2cd83c269dfce1fb8242ce96589fa3382f0"},
+    {file = "anytree-2.12.1.tar.gz", hash = "sha256:244def434ccf31b668ed282954e5d315b4e066c4940b94aff4a7962d85947830"},
 ]
 
 [package.dependencies]
-six = ">=1.9.0"
-
-[package.extras]
-dev = ["check-manifest"]
-test = ["coverage"]
+six = "*"
 
 [[package]]
 name = "babel"
-version = "2.12.1"
+version = "2.16.0"
 description = "Internationalization utilities"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
-    {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
+    {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"},
+    {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"},
 ]
 
 [package.dependencies]
 pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""}
 
+[package.extras]
+dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"]
+
 [[package]]
 name = "build"
-version = "0.10.0"
+version = "1.2.2"
 description = "A simple, correct Python build frontend"
 optional = false
-python-versions = ">= 3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "build-0.10.0-py3-none-any.whl", hash = "sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171"},
-    {file = "build-0.10.0.tar.gz", hash = "sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269"},
+    {file = "build-1.2.2-py3-none-any.whl", hash = "sha256:277ccc71619d98afdd841a0e96ac9fe1593b823af481d3b0cea748e8894e0613"},
+    {file = "build-1.2.2.tar.gz", hash = "sha256:119b2fb462adef986483438377a13b2f42064a2a3a4161f24a0cca698a07ac8c"},
 ]
 
 [package.dependencies]
 colorama = {version = "*", markers = "os_name == \"nt\""}
-packaging = ">=19.0"
+importlib-metadata = {version = ">=4.6", markers = "python_full_version < \"3.10.2\""}
+packaging = ">=19.1"
 pyproject_hooks = "*"
 tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
 
 [package.extras]
-docs = ["furo (>=2021.08.31)", "sphinx (>=4.0,<5.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)"]
-test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "toml (>=0.10.0)", "wheel (>=0.36.0)"]
-typing = ["importlib-metadata (>=5.1)", "mypy (==0.991)", "tomli", "typing-extensions (>=3.7.4.3)"]
+docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"]
+test = ["build[uv,virtualenv]", "filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"]
+typing = ["build[uv]", "importlib-metadata (>=5.1)", "mypy (>=1.9.0,<1.10.0)", "tomli", "typing-extensions (>=3.7.4.3)"]
+uv = ["uv (>=0.1.18)"]
 virtualenv = ["virtualenv (>=20.0.35)"]
 
+[[package]]
+name = "cachetools"
+version = "5.5.0"
+description = "Extensible memoizing collections and decorators"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"},
+    {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"},
+]
+
 [[package]]
 name = "certifi"
-version = "2023.7.22"
+version = "2024.8.30"
 description = "Python package for providing Mozilla's CA Bundle."
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"},
-    {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"},
+    {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
+    {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
+]
+
+[[package]]
+name = "chardet"
+version = "5.2.0"
+description = "Universal encoding detector for Python 3"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
+    {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
 ]
 
 [[package]]
 name = "charset-normalizer"
-version = "3.1.0"
+version = "3.3.2"
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 optional = false
 python-versions = ">=3.7.0"
 files = [
-    {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
-    {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
-    {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
-    {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
-    {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
-    {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
-    {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
+    {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
+    {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
 ]
 
 [[package]]
 name = "click"
-version = "8.1.3"
+version = "8.1.7"
 description = "Composable command line interface toolkit"
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
-    {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
+    {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
+    {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
 ]
 
 [package.dependencies]
@@ -186,6 +224,51 @@ files = [
     {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
 ]
 
+[[package]]
+name = "commonmark"
+version = "0.9.1"
+description = "Python parser for the CommonMark Markdown spec"
+optional = false
+python-versions = "*"
+files = [
+    {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
+    {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
+]
+
+[package.extras]
+test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"]
+
+[[package]]
+name = "cot-dt2c"
+version = "0.1.0"
+description = "CoT-dt2c Tool is a python script to convert CoT DT file into corresponding C file"
+optional = false
+python-versions = "^3.8"
+files = []
+develop = true
+
+[package.dependencies]
+click = "^8.1.7"
+igraph = "^0.11.6"
+plotly = "^5.23.0"
+pydevicetree = "0.0.13"
+pyparsing = "^3.1.2"
+
+[package.source]
+type = "directory"
+url = "tools/cot_dt2c"
+
+[[package]]
+name = "distlib"
+version = "0.3.8"
+description = "Distribution utilities"
+optional = false
+python-versions = "*"
+files = [
+    {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
+    {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
+]
+
 [[package]]
 name = "docutils"
 version = "0.18.1"
@@ -197,17 +280,93 @@ files = [
     {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
 ]
 
+[[package]]
+name = "filelock"
+version = "3.16.0"
+description = "A platform independent file lock."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "filelock-3.16.0-py3-none-any.whl", hash = "sha256:f6ed4c963184f4c84dd5557ce8fece759a3724b37b80c6c4f20a2f63a4dc6609"},
+    {file = "filelock-3.16.0.tar.gz", hash = "sha256:81de9eb8453c769b63369f87f11131a7ab04e367f8d97ad39dc230daa07e3bec"},
+]
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.1.1)", "pytest (>=8.3.2)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.3)"]
+typing = ["typing-extensions (>=4.12.2)"]
+
 [[package]]
 name = "idna"
-version = "3.4"
+version = "3.8"
 description = "Internationalized Domain Names in Applications (IDNA)"
 optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
 files = [
-    {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
-    {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+    {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"},
+    {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"},
 ]
 
+[[package]]
+name = "igraph"
+version = "0.11.6"
+description = "High performance graph data structures and algorithms"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "igraph-0.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3f8b837181e8e87676be3873ce87cc92cc234efd58a2da2f6b4e050db150fcf4"},
+    {file = "igraph-0.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:245c4b7d7657849eff80416f5df4525c8fc44c74a981ee4d44f0ef2612c3bada"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdb7be3d165073c0136295c0808e9edc57ba096cdb26e94086abb04561f7a292"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58974e20df2986a1ae52a16e51ecb387cc0cbeb41c5c0ddff4d373a1bbf1d9c5"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bef14de5e8ab70724a43808b1ed14aaa6fe1002f87e592289027a3827a8f44a"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:86c1e98de2e32d074df8510bf18abfa1f4c5fda4cb28a009985a5d746b0c0125"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ebc5b3d702158abeb2e4d2414374586a2b932e1a07e48352b470600e1733d528"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0efe6d0fb22d3987a800eb3857ed04df9eb4c5dddd0998be05232cb646f1c337"},
+    {file = "igraph-0.11.6-cp38-cp38-win32.whl", hash = "sha256:f4e68b27497b1c8ada2fb2bc35ef3fa7b0d72e84306b3d648d3de240fc618c32"},
+    {file = "igraph-0.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:5665b33dfbfca5f54ce9b4fea6b97903bd0e99fb1b02acf5e57e600bdfa5a355"},
+    {file = "igraph-0.11.6-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8aabef03d787b519d1075dfc0da4a1109fb113b941334883e3e7947ac30a459e"},
+    {file = "igraph-0.11.6-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1f2cc4a518d99cdf6cae514f85e93e56852bc8c325b3abb96037d1d690b5975f"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e859238be52ab8ccc614d18f9362942bc88ce543afc12548f81ae99b10801d"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d61fbe5e85eb4ae9efe08c461f9bdeedb02a2b5739fbc223d324a71f40a28be2"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6620ba39df29fd42151becf82309b54e57148233c9c3ef890eed62e25eed8a5"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59666589bb3d07f310cda2c5106a8adeeb77c2ef27fecf1c6438b6091f4ca69d"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:8750b6d6caebf199cf7dc41c931f58e330153779707391e30f0a29f02666fb6e"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:967d6f2c30fe94317da15e459374d0fb8ca3e56020412f201ecd07dd5b5352f2"},
+    {file = "igraph-0.11.6-cp39-abi3-win32.whl", hash = "sha256:9744f95a67319eb6cb487ceabf30f5d7940de34bada51f0ba63adbd23e0f94ad"},
+    {file = "igraph-0.11.6-cp39-abi3-win_amd64.whl", hash = "sha256:b80e69eb11faa9c57330a9ffebdde5808966efe1c1f638d4d4827ea04df7aca8"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0329c16092e2ea7930d5f8368666ce7cb704900cc0ea04e4afe9ea1dd46e44af"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:21752313f449bd8688e5688e95ea7231cea5e9199c7162535029be0d9af848ac"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea25e136c6c4161f53ff58868b23ff6c845193050ab0e502236d68e5d4174e32"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac84433a03aef15e4b810010b08882b09854a3669450ccf31e392dbe295d2a66"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac697a44e3573169fa2b28c9c37dcf9cf01e0f558b845dd7123860d4c7c8fb89"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bdeae8bf35316eb1fb27bf667dcf5ecf5fcfb0b8f51831bc1b00c39c09c2d73b"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ad7e4aa442935de72554b96733bf6d7f09eac5cee97988a2562bdd3ca173cfa3"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d2818780358a686178866d01568b9df1f29678581734ad7a78882bab54df004"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2352276a20d979f1dea360af4202bb9f0c9a7d2c77f51815c0e625165e82013d"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:687fdab543b507d622fa3043f4227e5b26dc61dcf8ff8c0919fccddcc655f8b8"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f7f8214cd48c9a4d97f7346a4152ba2d4ac95fb5ee0df4ecf224fce4ba3d14"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2b9cc69ede53f76ffae03b066609aa90184dd68ef15da8c104a97cebb9210838"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:591e1e447c3f0092daf7613a3eaedab83f9a0b0adbaf7702724c5117ded038a5"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ca558eb331bc687bc33e5cd23717e22676e9412f8cda3a31d30c996a0487610d"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf43c30e08debb087c9e3da69aa5cf1b6732968da34d55a614e3421b9a452146"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d38e8d7db72b187d9d2211d0d06b3271fa9f32b04d49d789e2859b5480db0d0"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a318b059051ff78144a1c3cb880f4d933c812bcdb3d833a49cd7168d0427672"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2c54027add809b3c5b6685b8deca4ea4763fd000b9ea45c7ee46b7c9d61ff15e"},
+    {file = "igraph-0.11.6.tar.gz", hash = "sha256:837f233256c3319f2a35a6a80d94eafe47b43791ef4c6f9e9871061341ac8e28"},
+]
+
+[package.dependencies]
+texttable = ">=1.6.2"
+
+[package.extras]
+cairo = ["cairocffi (>=1.2.0)"]
+doc = ["Sphinx (>=7.0.0)", "pydoctor (>=23.4.0)", "sphinx-gallery (>=0.14.0)", "sphinx-rtd-theme (>=1.3.0)"]
+matplotlib = ["matplotlib (>=3.6.0)"]
+plotly = ["plotly (>=5.3.0)"]
+plotting = ["cairocffi (>=1.2.0)"]
+test = ["Pillow (>=9)", "cairocffi (>=1.2.0)", "matplotlib (>=3.6.0)", "networkx (>=2.5)", "numpy (>=1.19.0)", "pandas (>=1.1.0)", "plotly (>=5.3.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "scipy (>=1.5.0)"]
+test-musl = ["cairocffi (>=1.2.0)", "networkx (>=2.5)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)"]
+
 [[package]]
 name = "imagesize"
 version = "1.4.1"
@@ -221,32 +380,32 @@ files = [
 
 [[package]]
 name = "importlib-metadata"
-version = "6.6.0"
+version = "8.4.0"
 description = "Read metadata from Python packages"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"},
-    {file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"},
+    {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"},
+    {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"},
 ]
 
 [package.dependencies]
 zipp = ">=0.5"
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
 perf = ["ipython"]
-testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
+test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"]
 
 [[package]]
 name = "jinja2"
-version = "3.1.2"
+version = "3.1.4"
 description = "A very fast and expressive template engine."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
-    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
+    {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
+    {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
 ]
 
 [package.dependencies]
@@ -281,61 +440,71 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
 
 [[package]]
 name = "markupsafe"
-version = "2.1.2"
+version = "2.1.5"
 description = "Safely add untrusted strings to HTML/XML markup."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"},
-    {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"},
-    {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"},
-    {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"},
-    {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"},
-    {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"},
-    {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
+    {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
 ]
 
 [[package]]
@@ -396,35 +565,35 @@ testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov",
 
 [[package]]
 name = "packaging"
-version = "23.1"
+version = "24.1"
 description = "Core utilities for Python packages"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
-    {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
+    {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
+    {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
 ]
 
 [[package]]
 name = "pip"
-version = "23.1.2"
+version = "24.2"
 description = "The PyPA recommended tool for installing Python packages."
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "pip-23.1.2-py3-none-any.whl", hash = "sha256:3ef6ac33239e4027d9a5598a381b9d30880a1477e50039db2eac6e8a8f6d1b18"},
-    {file = "pip-23.1.2.tar.gz", hash = "sha256:0e7c86f486935893c708287b30bd050a36ac827ec7fe5e43fe7cb198dd835fba"},
+    {file = "pip-24.2-py3-none-any.whl", hash = "sha256:2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2"},
+    {file = "pip-24.2.tar.gz", hash = "sha256:5b5e490b5e9cb275c879595064adce9ebd31b854e3e803740b72f9ccf34a45b8"},
 ]
 
 [[package]]
 name = "pip-tools"
-version = "6.13.0"
+version = "6.14.0"
 description = "pip-tools keeps your pinned dependencies fresh."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pip-tools-6.13.0.tar.gz", hash = "sha256:61d46bd2eb8016ed4a924e196e6e5b0a268cd3babd79e593048720db23522bb1"},
-    {file = "pip_tools-6.13.0-py3-none-any.whl", hash = "sha256:50943f151d87e752abddec8158622c34ad7f292e193836e90e30d87da60b19d9"},
+    {file = "pip-tools-6.14.0.tar.gz", hash = "sha256:06366be0e08d86b416407333e998b4d305d5bd925151b08942ed149380ba3e47"},
+    {file = "pip_tools-6.14.0-py3-none-any.whl", hash = "sha256:c5ad042cd27c0b343b10db1db7f77a7d087beafbec59ae6df1bba4d3368dfe8c"},
 ]
 
 [package.dependencies]
@@ -432,28 +601,89 @@ build = "*"
 click = ">=8"
 pip = ">=22.2"
 setuptools = "*"
+tomli = {version = "*", markers = "python_version < \"3.11\""}
 wheel = "*"
 
 [package.extras]
-coverage = ["pytest-cov"]
-testing = ["flit-core (>=2,<4)", "poetry-core (>=1.0.0)", "pytest (>=7.2.0)", "pytest-rerunfailures", "pytest-xdist"]
+coverage = ["covdefaults", "pytest-cov"]
+testing = ["flit-core (>=2,<4)", "poetry-core (>=1.0.0)", "pytest (>=7.2.0)", "pytest-rerunfailures", "pytest-xdist", "tomli-w"]
+
+[[package]]
+name = "platformdirs"
+version = "4.3.2"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "platformdirs-4.3.2-py3-none-any.whl", hash = "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617"},
+    {file = "platformdirs-4.3.2.tar.gz", hash = "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c"},
+]
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"]
+type = ["mypy (>=1.11.2)"]
+
+[[package]]
+name = "plotly"
+version = "5.24.0"
+description = "An open-source, interactive data visualization library for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "plotly-5.24.0-py3-none-any.whl", hash = "sha256:0e54efe52c8cef899f7daa41be9ed97dfb6be622613a2a8f56a86a0634b2b67e"},
+    {file = "plotly-5.24.0.tar.gz", hash = "sha256:eae9f4f54448682442c92c1e97148e3ad0c52f0cf86306e1b76daba24add554a"},
+]
+
+[package.dependencies]
+packaging = "*"
+tenacity = ">=6.2.0"
+
+[[package]]
+name = "pluggy"
+version = "1.5.0"
+description = "plugin and hook calling mechanisms for python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
+    {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
+]
+
+[package.extras]
+dev = ["pre-commit", "tox"]
+testing = ["pytest", "pytest-benchmark"]
 
 [[package]]
 name = "prettytable"
-version = "3.7.0"
+version = "3.11.0"
 description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "prettytable-3.7.0-py3-none-any.whl", hash = "sha256:f4aaf2ed6e6062a82fd2e6e5289bbbe705ec2788fe401a3a1f62a1cea55526d2"},
-    {file = "prettytable-3.7.0.tar.gz", hash = "sha256:ef8334ee40b7ec721651fc4d37ecc7bb2ef55fde5098d994438f0dfdaa385c0c"},
+    {file = "prettytable-3.11.0-py3-none-any.whl", hash = "sha256:aa17083feb6c71da11a68b2c213b04675c4af4ce9c541762632ca3f2cb3546dd"},
+    {file = "prettytable-3.11.0.tar.gz", hash = "sha256:7e23ca1e68bbfd06ba8de98bf553bf3493264c96d5e8a615c0471025deeba722"},
 ]
 
 [package.dependencies]
 wcwidth = "*"
 
 [package.extras]
-tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"]
+tests = ["pytest", "pytest-cov", "pytest-lazy-fixtures"]
+
+[[package]]
+name = "pydevicetree"
+version = "0.0.13"
+description = "A library for parsing Devicetree Source v1"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "pydevicetree-0.0.13-py3-none-any.whl", hash = "sha256:d61c695cec925b90a8b5740053f4b604e51154a9b36e62a2f12ed9ceaf2f8c38"},
+    {file = "pydevicetree-0.0.13.tar.gz", hash = "sha256:5700c05df89bad8fd729c11aa6f764a3323bcb3796f13b32481ae34445cfc1b7"},
+]
+
+[package.dependencies]
+pyparsing = "*"
 
 [[package]]
 name = "pyelftools"
@@ -468,101 +698,144 @@ files = [
 
 [[package]]
 name = "pygments"
-version = "2.15.1"
+version = "2.18.0"
 description = "Pygments is a syntax highlighting package written in Python."
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
+files = [
+    {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
+    {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
+]
+
+[package.extras]
+windows-terminal = ["colorama (>=0.4.6)"]
+
+[[package]]
+name = "pyparsing"
+version = "3.1.4"
+description = "pyparsing module - Classes and methods to define and execute parsing grammars"
+optional = false
+python-versions = ">=3.6.8"
+files = [
+    {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"},
+    {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"},
+]
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
+
+[[package]]
+name = "pyproject-api"
+version = "1.7.1"
+description = "API to interact with the python pyproject.toml based projects"
+optional = false
+python-versions = ">=3.8"
 files = [
-    {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"},
-    {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"},
+    {file = "pyproject_api-1.7.1-py3-none-any.whl", hash = "sha256:2dc1654062c2b27733d8fd4cdda672b22fe8741ef1dde8e3a998a9547b071eeb"},
+    {file = "pyproject_api-1.7.1.tar.gz", hash = "sha256:7ebc6cd10710f89f4cf2a2731710a98abce37ebff19427116ff2174c9236a827"},
 ]
 
+[package.dependencies]
+packaging = ">=24.1"
+tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
+
 [package.extras]
-plugins = ["importlib-metadata"]
+docs = ["furo (>=2024.5.6)", "sphinx-autodoc-typehints (>=2.2.1)"]
+testing = ["covdefaults (>=2.3)", "pytest (>=8.2.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "setuptools (>=70.1)"]
 
 [[package]]
 name = "pyproject-hooks"
-version = "1.0.0"
+version = "1.1.0"
 description = "Wrappers to call pyproject.toml-based build backend hooks."
 optional = false
 python-versions = ">=3.7"
 files = [
-    {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"},
-    {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"},
+    {file = "pyproject_hooks-1.1.0-py3-none-any.whl", hash = "sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2"},
+    {file = "pyproject_hooks-1.1.0.tar.gz", hash = "sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965"},
 ]
 
-[package.dependencies]
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-
 [[package]]
 name = "pytz"
-version = "2023.3"
+version = "2024.1"
 description = "World timezone definitions, modern and historical"
 optional = false
 python-versions = "*"
 files = [
-    {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"},
-    {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"},
+    {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
+    {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
 ]
 
 [[package]]
 name = "pyyaml"
-version = "6.0"
+version = "6.0.2"
 description = "YAML parser and emitter for Python"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
 files = [
-    {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
-    {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
-    {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
-    {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
-    {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"},
-    {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"},
-    {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"},
-    {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"},
-    {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"},
-    {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"},
-    {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"},
-    {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
-    {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
-    {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
-    {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
-    {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
-    {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
-    {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
-    {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
-    {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
-    {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
-    {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
-    {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
-    {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
-    {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
+    {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
+    {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
+    {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
+    {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
+    {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
+    {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
+    {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
+    {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
+    {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
+    {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
+    {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
+    {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
+    {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
+    {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
+    {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
+    {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
+    {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
+    {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
+    {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
+    {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
+    {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
+    {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
+    {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
+    {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
+    {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
+    {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
+    {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
+    {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
+    {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
+    {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
+    {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
+    {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
+    {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
+    {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
+    {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
 ]
 
 [[package]]
 name = "requests"
-version = "2.31.0"
+version = "2.32.3"
 description = "Python HTTP for Humans."
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
-    {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
+    {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
+    {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
 ]
 
 [package.dependencies]
@@ -575,21 +848,55 @@ urllib3 = ">=1.21.1,<3"
 socks = ["PySocks (>=1.5.6,!=1.5.7)"]
 use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
 
+[[package]]
+name = "rich"
+version = "10.16.2"
+description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
+optional = false
+python-versions = ">=3.6.2,<4.0.0"
+files = [
+    {file = "rich-10.16.2-py3-none-any.whl", hash = "sha256:c59d73bd804c90f747c8d7b1d023b88f2a9ac2454224a4aeaf959b21eeb42d03"},
+    {file = "rich-10.16.2.tar.gz", hash = "sha256:720974689960e06c2efdb54327f8bf0cdbdf4eae4ad73b6c94213cad405c371b"},
+]
+
+[package.dependencies]
+colorama = ">=0.4.0,<0.5.0"
+commonmark = ">=0.9.0,<0.10.0"
+pygments = ">=2.6.0,<3.0.0"
+
+[package.extras]
+jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
+
 [[package]]
 name = "setuptools"
-version = "67.7.2"
+version = "74.1.2"
 description = "Easily download, build, install, upgrade, and uninstall Python packages"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"},
-    {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"},
+    {file = "setuptools-74.1.2-py3-none-any.whl", hash = "sha256:5f4c08aa4d3ebcb57a50c33b1b07e94315d7fc7230f7115e47fc99776c8ce308"},
+    {file = "setuptools-74.1.2.tar.gz", hash = "sha256:95b40ed940a1c67eb70fc099094bd6e99c6ee7c23aa2306f4d2697ba7916f9c6"},
 ]
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
-testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
-testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
+core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+cover = ["pytest-cov"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
+enabler = ["pytest-enabler (>=2.2)"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
+type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
+
+[[package]]
+name = "shellingham"
+version = "1.5.4"
+description = "Tool to Detect Surrounding Shell"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
+    {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
+]
 
 [[package]]
 name = "six"
@@ -650,19 +957,19 @@ test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"]
 
 [[package]]
 name = "sphinx-rtd-theme"
-version = "1.2.0"
+version = "1.3.0"
 description = "Read the Docs theme for Sphinx"
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
 files = [
-    {file = "sphinx_rtd_theme-1.2.0-py2.py3-none-any.whl", hash = "sha256:f823f7e71890abe0ac6aaa6013361ea2696fc8d3e1fa798f463e82bdb77eeff2"},
-    {file = "sphinx_rtd_theme-1.2.0.tar.gz", hash = "sha256:a0d8bd1a2ed52e0b338cbe19c4b2eef3c5e7a048769753dac6a9f059c7b641b8"},
+    {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"},
+    {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"},
 ]
 
 [package.dependencies]
 docutils = "<0.19"
-sphinx = ">=1.6,<7"
-sphinxcontrib-jquery = {version = ">=2.0.0,<3.0.0 || >3.0.0", markers = "python_version > \"3\""}
+sphinx = ">=1.6,<8"
+sphinxcontrib-jquery = ">=4,<5"
 
 [package.extras]
 dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"]
@@ -803,6 +1110,53 @@ Sphinx = ">=1.6.3"
 [package.extras]
 cairosvg = ["cairosvg (>=1.0)"]
 
+[[package]]
+name = "tenacity"
+version = "9.0.0"
+description = "Retry code until it succeeds"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"},
+    {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"},
+]
+
+[package.extras]
+doc = ["reno", "sphinx"]
+test = ["pytest", "tornado (>=4.5)", "typeguard"]
+
+[[package]]
+name = "texttable"
+version = "1.7.0"
+description = "module to create simple ASCII tables"
+optional = false
+python-versions = "*"
+files = [
+    {file = "texttable-1.7.0-py2.py3-none-any.whl", hash = "sha256:72227d592c82b3d7f672731ae73e4d1f88cd8e2ef5b075a7a7f01a23a3743917"},
+    {file = "texttable-1.7.0.tar.gz", hash = "sha256:2d2068fb55115807d3ac77a4ca68fa48803e84ebb0ee2340f858107a36522638"},
+]
+
+[[package]]
+name = "tlc"
+version = "0.9.0"
+description = "Transfer List Compiler (TLC) is a Python-based CLI for efficiently handling transfer lists."
+optional = false
+python-versions = "^3.8"
+files = []
+develop = true
+
+[package.dependencies]
+click = "^8.1.7"
+jinja2 = "^3.1.4"
+pyyaml = "^6.0.1"
+rich = "^10.14.0"
+tox = "^4.18.0"
+typer = {version = "^0.4.0", extras = ["all"]}
+
+[package.source]
+type = "directory"
+url = "tools/tlc"
+
 [[package]]
 name = "tomli"
 version = "2.0.1"
@@ -814,75 +1168,148 @@ files = [
     {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
 ]
 
+[[package]]
+name = "tox"
+version = "4.18.1"
+description = "tox is a generic virtualenv management and test command line tool"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tox-4.18.1-py3-none-any.whl", hash = "sha256:35d472032ee1f73fe20c3e0e73d7073a4e85075c86ff02c576f9fc7c6a15a578"},
+    {file = "tox-4.18.1.tar.gz", hash = "sha256:3c0c96bc3a568a5c7e66387a4cfcf8c875b52e09f4d47c9f7a277ec82f1a0b11"},
+]
+
+[package.dependencies]
+cachetools = ">=5.5"
+chardet = ">=5.2"
+colorama = ">=0.4.6"
+filelock = ">=3.15.4"
+packaging = ">=24.1"
+platformdirs = ">=4.2.2"
+pluggy = ">=1.5"
+pyproject-api = ">=1.7.1"
+tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
+virtualenv = ">=20.26.3"
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-argparse-cli (>=1.17)", "sphinx-autodoc-typehints (>=2.4)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=24.8)"]
+testing = ["build[virtualenv] (>=1.2.2)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.2)", "devpi-process (>=1)", "diff-cover (>=9.1.1)", "distlib (>=0.3.8)", "flaky (>=3.8.1)", "hatch-vcs (>=0.4)", "hatchling (>=1.25)", "psutil (>=6)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-xdist (>=3.6.1)", "re-assert (>=1.1)", "setuptools (>=74.1.2)", "time-machine (>=2.15)", "wheel (>=0.44)"]
+
+[[package]]
+name = "typer"
+version = "0.4.2"
+description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "typer-0.4.2-py3-none-any.whl", hash = "sha256:023bae00d1baf358a6cc7cea45851639360bb716de687b42b0a4641cd99173f1"},
+    {file = "typer-0.4.2.tar.gz", hash = "sha256:b8261c6c0152dd73478b5ba96ba677e5d6948c715c310f7c91079f311f62ec03"},
+]
+
+[package.dependencies]
+click = ">=7.1.1,<9.0.0"
+colorama = {version = ">=0.4.3,<0.5.0", optional = true, markers = "extra == \"all\""}
+shellingham = {version = ">=1.3.0,<2.0.0", optional = true, markers = "extra == \"all\""}
+
+[package.extras]
+all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"]
+dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"]
+doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)"]
+test = ["black (>=22.3.0,<23.0.0)", "coverage (>=5.2,<6.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
+
 [[package]]
 name = "typing-extensions"
-version = "4.5.0"
-description = "Backported and Experimental Type Hints for Python 3.7+"
+version = "4.12.2"
+description = "Backported and Experimental Type Hints for Python 3.8+"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"},
-    {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"},
+    {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
+    {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
 ]
 
 [[package]]
 name = "urllib3"
-version = "2.0.2"
+version = "2.2.2"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"},
-    {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"},
+    {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
+    {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
 ]
 
 [package.extras]
 brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
-secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
+h2 = ["h2 (>=4,<5)"]
 socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
 zstd = ["zstandard (>=0.18.0)"]
 
+[[package]]
+name = "virtualenv"
+version = "20.26.4"
+description = "Virtual Python Environment builder"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "virtualenv-20.26.4-py3-none-any.whl", hash = "sha256:48f2695d9809277003f30776d155615ffc11328e6a0a8c1f0ec80188d7874a55"},
+    {file = "virtualenv-20.26.4.tar.gz", hash = "sha256:c17f4e0f3e6036e9f26700446f85c76ab11df65ff6d8a9cbfad9f71aabfcf23c"},
+]
+
+[package.dependencies]
+distlib = ">=0.3.7,<1"
+filelock = ">=3.12.2,<4"
+platformdirs = ">=3.9.1,<5"
+
+[package.extras]
+docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
+test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
+
 [[package]]
 name = "wcwidth"
-version = "0.2.6"
+version = "0.2.13"
 description = "Measures the displayed width of unicode strings in a terminal"
 optional = false
 python-versions = "*"
 files = [
-    {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"},
-    {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"},
+    {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
+    {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
 ]
 
 [[package]]
 name = "wheel"
-version = "0.40.0"
+version = "0.44.0"
 description = "A built-package format for Python"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "wheel-0.40.0-py3-none-any.whl", hash = "sha256:d236b20e7cb522daf2390fa84c55eea81c5c30190f90f29ae2ca1ad8355bf247"},
-    {file = "wheel-0.40.0.tar.gz", hash = "sha256:cd1196f3faee2b31968d626e1731c94f99cbdb67cf5a46e4f5656cbee7738873"},
+    {file = "wheel-0.44.0-py3-none-any.whl", hash = "sha256:2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f"},
+    {file = "wheel-0.44.0.tar.gz", hash = "sha256:a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49"},
 ]
 
 [package.extras]
-test = ["pytest (>=6.0.0)"]
+test = ["pytest (>=6.0.0)", "setuptools (>=65)"]
 
 [[package]]
 name = "zipp"
-version = "3.15.0"
+version = "3.20.1"
 description = "Backport of pathlib-compatible object wrapper for zip files"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
 files = [
-    {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"},
-    {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"},
+    {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"},
+    {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"},
 ]
 
 [package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
+cover = ["pytest-cov"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+enabler = ["pytest-enabler (>=2.2)"]
+test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
+type = ["pytest-mypy"]
 
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.8"
-content-hash = "62d9ce9ca1c9f4669c7b40724acfc93968cde31c0460d1d7515d289739dc9464"
+content-hash = "6a6d2fe9390a4d7d1ecf808d5f303f2dc1eeb44736827b706a858046f3eea1db"
diff --git a/pyproject.toml b/pyproject.toml
index 0fe23838..62878b41 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "trusted-firmware-a"
-version = "2.10.0"
+version = "2.12.0"
 description = "Trusted Firmware-A (TF-A) Python dependencies."
 authors = ["Arm Ltd."]
 license = "BSD-3-Clause"
@@ -14,8 +14,13 @@ memory = "memory.memmap:main"
 
 [tool.poetry.dependencies]
 python = "^3.8"
+cot-dt2c = {path = "tools/cot_dt2c", develop = true}
+tlc = {path = "tools/tlc", develop = true}
 
-[tool.poetry.group.doc.dependencies]
+[tool.poetry.group.docs]
+optional = true
+
+[tool.poetry.group.docs.dependencies]
 sphinx = "^5.3.0"
 myst-parser = "^0.18.1"
 sphinxcontrib-plantuml = "^0.24.1"
diff --git a/readme.rst b/readme.rst
index 148d477a..171b32bf 100644
--- a/readme.rst
+++ b/readme.rst
@@ -39,7 +39,7 @@ that is available through `trustedfirmware.org`_.
 .. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php
 .. _Power State Coordination Interface (PSCI): PSCI_
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
-.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT): https://developer.arm.com/docs/den0006/latest
 .. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
 .. _System Control and Management Interface (SCMI): SCMI_
 .. _SCMI: http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 57d211ed..54561646 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -54,7 +54,7 @@ static int32_t smccc_arch_features(u_register_t arg1)
 		 * If architectural SSBS is available on this PE, no firmware
 		 * mitigation via SMCCC_ARCH_WORKAROUND_2 is required.
 		 */
-		if (ssbs != SSBS_UNAVAILABLE)
+		if (ssbs != SSBS_NOT_IMPLEMENTED)
 			return 1;
 
 		/*
diff --git a/services/el3/ven_el3_svc.c b/services/el3/ven_el3_svc.c
new file mode 100644
index 00000000..32a3dc27
--- /dev/null
+++ b/services/el3/ven_el3_svc.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/debugfs.h>
+#include <lib/pmf/pmf.h>
+#include <services/ven_el3_svc.h>
+#include <tools_share/uuid.h>
+
+/* vendor-specific EL3 UUID */
+DEFINE_SVC_UUID2(ven_el3_svc_uid,
+	0xb6011dca, 0x57c4, 0x407e, 0x83, 0xf0,
+	0xa7, 0xed, 0xda, 0xf0, 0xdf, 0x6c);
+
+static int ven_el3_svc_setup(void)
+{
+#if USE_DEBUGFS
+	if (debugfs_smc_setup() != 0) {
+		return 1;
+	}
+#endif /* USE_DEBUGFS */
+
+#if ENABLE_PMF
+	if (pmf_setup() != 0) {
+		return 1;
+	}
+#endif /* ENABLE_PMF */
+
+	return 0;
+}
+
+/*
+ * This function handles Arm defined vendor-specific EL3 Service Calls.
+ */
+static uintptr_t ven_el3_svc_handler(unsigned int 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)
+{
+#if USE_DEBUGFS
+	/*
+	 * Dispatch debugfs calls to debugfs SMC handler and return its
+	 * return value.
+	 */
+	if (is_debugfs_fid(smc_fid)) {
+		return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+			handle, flags);
+	}
+#endif /* USE_DEBUGFS */
+
+#if ENABLE_PMF
+
+	/*
+	 * Dispatch PMF calls to PMF SMC handler and return its return
+	 * value
+	 */
+	if (is_pmf_fid(smc_fid)) {
+		return pmf_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+				handle, flags);
+	}
+
+#endif /* ENABLE_PMF */
+
+	switch (smc_fid) {
+	case VEN_EL3_SVC_UID:
+		/* Return UID to the caller */
+		SMC_UUID_RET(handle, ven_el3_svc_uid);
+		break;
+	case VEN_EL3_SVC_VERSION:
+		SMC_RET2(handle, VEN_EL3_SVC_VERSION_MAJOR, VEN_EL3_SVC_VERSION_MINOR);
+		break;
+	default:
+		WARN("Unimplemented vendor-specific EL3 Service call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+		break;
+	}
+}
+
+/* Define a runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+	ven_el3_svc,
+	OEN_VEN_EL3_START,
+	OEN_VEN_EL3_END,
+	SMC_TYPE_FAST,
+	ven_el3_svc_setup,
+	ven_el3_svc_handler
+);
diff --git a/services/oem/chromeos/widevine_smc_handlers.c b/services/oem/chromeos/widevine_smc_handlers.c
new file mode 100644
index 00000000..83c6ccc9
--- /dev/null
+++ b/services/oem/chromeos/widevine_smc_handlers.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2024, The ChromiumOS Authors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/psci/psci.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/oem/chromeos/widevine_smc_handlers.h>
+#include <tools_share/uuid.h>
+
+#define CROS_OEM_TPM_AUTH_PK_MAX_LEN 128
+#define CROS_OEM_HUK_LEN 32
+#define CROS_OEM_ROT_LEN 32
+
+static uint8_t cros_oem_tpm_auth_pk_buffer[CROS_OEM_TPM_AUTH_PK_MAX_LEN];
+static uint8_t cros_oem_huk_buffer[CROS_OEM_HUK_LEN];
+static uint8_t cros_oem_rot_len_buffer[CROS_OEM_ROT_LEN];
+
+struct cros_oem_data cros_oem_tpm_auth_pk = {
+	.buffer = cros_oem_tpm_auth_pk_buffer,
+	.max_length = sizeof(cros_oem_tpm_auth_pk_buffer),
+};
+
+struct cros_oem_data cros_oem_huk = {
+	.buffer = cros_oem_huk_buffer,
+	.max_length = sizeof(cros_oem_huk_buffer),
+};
+
+struct cros_oem_data cros_oem_rot = {
+	.buffer = cros_oem_rot_len_buffer,
+	.max_length = sizeof(cros_oem_rot_len_buffer),
+};
+
+static uintptr_t cros_write_data(struct cros_oem_data *data,
+				 u_register_t length, u_register_t address,
+				 void *handle)
+{
+	uintptr_t aligned_address;
+	uintptr_t aligned_size;
+	int32_t rc;
+
+	if (data->length) {
+		SMC_RET1(handle, PSCI_E_ALREADY_ON);
+	}
+
+	if (length > data->max_length) {
+		SMC_RET1(handle, PSCI_E_INVALID_PARAMS);
+	}
+
+	aligned_address = page_align(address, DOWN);
+	aligned_size = page_align(length + (address - aligned_address), UP);
+
+	/*
+	 * We do not validate the passed in address because we are trusting the
+	 * non-secure world at this point still.
+	 */
+	rc = mmap_add_dynamic_region(aligned_address, aligned_address,
+				     aligned_size, MT_MEMORY | MT_RO | MT_NS);
+	if (rc != 0) {
+		SMC_RET1(handle, PSCI_E_INVALID_ADDRESS);
+	}
+
+	memcpy(data->buffer, (void *)address, length);
+	data->length = length;
+
+	mmap_remove_dynamic_region(aligned_address, aligned_size);
+	SMC_RET1(handle, SMC_OK);
+}
+
+/* Handler for servicing specific SMC calls. */
+static uintptr_t cros_oem_svc_smc_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 CROS_OEM_SMC_DRM_SET_TPM_AUTH_PUB_FUNC_ID:
+		return cros_write_data(&cros_oem_tpm_auth_pk, x1, x2, handle);
+	case CROS_OEM_SMC_DRM_SET_HARDWARE_UNIQUE_KEY_FUNC_ID:
+		return cros_write_data(&cros_oem_huk, x1, x2, handle);
+	case CROS_OEM_SMC_DRM_SET_ROOT_OF_TRUST_FUNC_ID:
+		return cros_write_data(&cros_oem_rot, x1, x2, handle);
+	default:
+		WARN("Unimplemented OEM Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
+
+/* Register OEM Service Calls as runtime service */
+DECLARE_RT_SVC(cros_oem_svc_smc_handler, OEN_OEM_START, OEN_OEM_END,
+	       SMC_TYPE_FAST, NULL, cros_oem_svc_smc_handler);
diff --git a/services/spd/opteed/opteed.mk b/services/spd/opteed/opteed.mk
index f394744e..289b3e77 100644
--- a/services/spd/opteed/opteed.mk
+++ b/services/spd/opteed/opteed.mk
@@ -33,3 +33,11 @@ $(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
 $(eval $(call add_define,OPTEE_ALLOW_SMC_LOAD))
 include lib/libfdt/libfdt.mk
 endif
+
+CROS_WIDEVINE_SMC		:=	0
+ifeq ($(CROS_WIDEVINE_SMC),1)
+ifeq ($(OPTEE_ALLOW_SMC_LOAD),0)
+$(error When CROS_WIDEVINE_SMC=1, OPTEE_ALLOW_SMC_LOAD must also be 1)
+endif
+$(eval $(call add_define,CROS_WIDEVINE_SMC))
+endif
diff --git a/services/spd/opteed/opteed_common.c b/services/spd/opteed/opteed_common.c
index 9aa19c5b..8a769fb0 100644
--- a/services/spd/opteed/opteed_common.c
+++ b/services/spd/opteed/opteed_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,9 +20,9 @@
  * initialize OPTEE context and entry point info for OPTEE.
  ******************************************************************************/
 void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
-				uint32_t rw, uint64_t pc,
-				uint64_t pageable_part, uint64_t mem_limit,
-				uint64_t dt_addr, optee_context_t *optee_ctx)
+				uint32_t rw, uint64_t pc, uint64_t arg0,
+				uint64_t arg1, uint64_t arg2, uint64_t arg3,
+				optee_context_t *optee_ctx)
 {
 	uint32_t ep_attr;
 
@@ -54,9 +54,10 @@ void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
 							DAIF_IRQ_BIT |
 							DAIF_ABT_BIT);
 	zeromem(&optee_entry_point->args, sizeof(optee_entry_point->args));
-	optee_entry_point->args.arg0 = pageable_part;
-	optee_entry_point->args.arg1 = mem_limit;
-	optee_entry_point->args.arg2 = dt_addr;
+	optee_entry_point->args.arg0 = arg0;
+	optee_entry_point->args.arg1 = arg1;
+	optee_entry_point->args.arg2 = arg2;
+	optee_entry_point->args.arg3 = arg3;
 }
 
 /*******************************************************************************
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 4d055db1..9e838484 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,16 +27,22 @@
 #include <lib/coreboot.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/optee_utils.h>
+#include <lib/transfer_list.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #if OPTEE_ALLOW_SMC_LOAD
 #include <libfdt.h>
 #endif  /* OPTEE_ALLOW_SMC_LOAD */
 #include <plat/common/platform.h>
+#include <services/oem/chromeos/widevine_smc_handlers.h>
 #include <tools_share/uuid.h>
 
 #include "opteed_private.h"
 #include "teesmc_opteed.h"
 
+#if OPTEE_ALLOW_SMC_LOAD
+static struct transfer_list_header *bl31_tl;
+#endif
+
 /*******************************************************************************
  * Address of the entrypoint vector table in OPTEE. It is
  * initialised once on the primary core after a cold boot.
@@ -56,7 +62,7 @@ DEFINE_SVC_UUID2(optee_image_load_uuid,
 	0xb1eafba3, 0x5d31, 0x4612, 0xb9, 0x06,
 	0xc4, 0xc7, 0xa4, 0xbe, 0x3c, 0xc0);
 
-#define OPTEED_FDT_SIZE 256
+#define OPTEED_FDT_SIZE 1024
 static uint8_t fdt_buf[OPTEED_FDT_SIZE] __aligned(CACHE_WRITEBACK_GRANULE);
 
 #else
@@ -81,6 +87,13 @@ static uint64_t opteed_sel1_interrupt_handler(uint32_t id,
 	uint32_t linear_id;
 	optee_context_t *optee_ctx;
 
+#if OPTEE_ALLOW_SMC_LOAD
+	if (optee_vector_table == NULL) {
+		/* OPTEE is not loaded yet, ignore this interrupt */
+		SMC_RET0(handle);
+	}
+#endif
+
 	/* Check the security state when the exception was generated */
 	assert(get_interrupt_src_ss(flags) == NON_SECURE);
 
@@ -109,6 +122,24 @@ static uint64_t opteed_sel1_interrupt_handler(uint32_t id,
 	SMC_RET1(&optee_ctx->cpu_ctx, read_elr_el3());
 }
 
+/*
+ * Registers an interrupt handler for S-EL1 interrupts when generated during
+ * code executing in the non-secure state. Panics if it fails to do so.
+ */
+static void register_opteed_interrupt_handler(void)
+{
+	u_register_t flags;
+	uint64_t rc;
+
+	flags = 0;
+	set_interrupt_rm_flag(flags, NON_SECURE);
+	rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+			opteed_sel1_interrupt_handler,
+			flags);
+	if (rc)
+		panic();
+}
+
 /*******************************************************************************
  * OPTEE Dispatcher setup. The OPTEED finds out the OPTEE entrypoint and type
  * (aarch32/aarch64) if not already known and initialises the context for entry
@@ -119,13 +150,22 @@ static int32_t opteed_setup(void)
 #if OPTEE_ALLOW_SMC_LOAD
 	opteed_allow_load = true;
 	INFO("Delaying OP-TEE setup until we receive an SMC call to load it\n");
+	/*
+	 * We must register the interrupt handler now so that the interrupt
+	 * priorities are not changed after starting the linux kernel.
+	 */
+	register_opteed_interrupt_handler();
 	return 0;
 #else
 	entry_point_info_t *optee_ep_info;
 	uint32_t linear_id;
-	uint64_t opteed_pageable_part;
-	uint64_t opteed_mem_limit;
-	uint64_t dt_addr;
+	uint64_t arg0;
+	uint64_t arg1;
+	uint64_t arg2;
+	uint64_t arg3;
+	struct transfer_list_header *tl = NULL;
+	struct transfer_list_entry *te = NULL;
+	void *dt = NULL;
 
 	linear_id = plat_my_core_pos();
 
@@ -150,17 +190,39 @@ static int32_t opteed_setup(void)
 	if (!optee_ep_info->pc)
 		return 1;
 
-	opteed_rw = optee_ep_info->args.arg0;
-	opteed_pageable_part = optee_ep_info->args.arg1;
-	opteed_mem_limit = optee_ep_info->args.arg2;
-	dt_addr = optee_ep_info->args.arg3;
-
-	opteed_init_optee_ep_state(optee_ep_info,
-				opteed_rw,
-				optee_ep_info->pc,
-				opteed_pageable_part,
-				opteed_mem_limit,
-				dt_addr,
+	if (TRANSFER_LIST &&
+		optee_ep_info->args.arg1 == (TRANSFER_LIST_SIGNATURE |
+					REGISTER_CONVENTION_VERSION_MASK)) {
+		tl = (void *)optee_ep_info->args.arg3;
+		if (transfer_list_check_header(tl) == TL_OPS_NON) {
+			return 1;
+		}
+
+		opteed_rw = GET_RW(optee_ep_info->spsr);
+		te = transfer_list_find(tl, TL_TAG_FDT);
+		dt = transfer_list_entry_data(te);
+
+		if (opteed_rw == OPTEE_AARCH64) {
+			arg0 = (uint64_t)dt;
+			arg2 = 0;
+		} else {
+			arg2 = (uint64_t)dt;
+			arg0 = 0;
+		}
+
+		arg1 = optee_ep_info->args.arg1;
+		arg3 = optee_ep_info->args.arg3;
+	} else {
+		/* Default handoff arguments */
+		opteed_rw = optee_ep_info->args.arg0;
+		arg0 = optee_ep_info->args.arg1; /* opteed_pageable_part */
+		arg1 = optee_ep_info->args.arg2; /* opteed_mem_limit */
+		arg2 = optee_ep_info->args.arg3; /* dt_addr */
+		arg3 = 0;
+	}
+
+	opteed_init_optee_ep_state(optee_ep_info, opteed_rw, optee_ep_info->pc,
+				arg0, arg1, arg2, arg3,
 				&opteed_sp_context[linear_id]);
 
 	/*
@@ -268,6 +330,62 @@ static int add_coreboot_node(void *fdt)
 }
 #endif /* COREBOOT */
 
+#if CROS_WIDEVINE_SMC
+/*
+ * Adds a options/widevine node with the widevine table information to a device
+ * tree. Returns zero on success or if there is no widevine table information;
+ * failure code otherwise.
+ */
+static int add_options_widevine_node(void *fdt)
+{
+	int ret;
+
+	ret = fdt_begin_node(fdt, "options");
+	if (ret)
+		return ret;
+
+	ret = fdt_begin_node(fdt, "op-tee");
+	if (ret)
+		return ret;
+
+	ret = fdt_begin_node(fdt, "widevine");
+	if (ret)
+		return ret;
+
+	if (cros_oem_tpm_auth_pk.length) {
+		ret = fdt_property(fdt, "tcg,tpm-auth-public-key",
+				   cros_oem_tpm_auth_pk.buffer,
+				   cros_oem_tpm_auth_pk.length);
+		if (ret)
+			return ret;
+	}
+
+	if (cros_oem_huk.length) {
+		ret = fdt_property(fdt, "op-tee,hardware-unique-key",
+				   cros_oem_huk.buffer, cros_oem_huk.length);
+		if (ret)
+			return ret;
+	}
+
+	if (cros_oem_rot.length) {
+		ret = fdt_property(fdt, "google,widevine-root-of-trust-ecc-p256",
+				   cros_oem_rot.buffer, cros_oem_rot.length);
+		if (ret)
+			return ret;
+	}
+
+	ret = fdt_end_node(fdt);
+	if (ret)
+		return ret;
+
+	ret = fdt_end_node(fdt);
+	if (ret)
+		return ret;
+
+	return fdt_end_node(fdt);
+}
+#endif /* CROS_WIDEVINE_SMC */
+
 /*
  * Creates a device tree for passing into OP-TEE. Currently is populated with
  * the coreboot table address.
@@ -295,6 +413,12 @@ static int create_opteed_dt(void)
 		return ret;
 #endif /* COREBOOT */
 
+#if CROS_WIDEVINE_SMC
+	ret = add_options_widevine_node(fdt_buf);
+	if (ret)
+		return ret;
+#endif /* CROS_WIDEVINE_SMC */
+
 	ret = fdt_end_node(fdt_buf);
 	if (ret)
 		return ret;
@@ -302,6 +426,26 @@ static int create_opteed_dt(void)
 	return fdt_finish(fdt_buf);
 }
 
+static int32_t create_smc_tl(const void *fdt, uint32_t fdt_sz)
+{
+#if TRANSFER_LIST
+	bl31_tl = transfer_list_init((void *)(uintptr_t)FW_HANDOFF_BASE,
+				FW_HANDOFF_SIZE);
+	if (!bl31_tl) {
+		ERROR("Failed to initialize Transfer List at 0x%lx\n",
+		(unsigned long)FW_HANDOFF_BASE);
+		return -1;
+	}
+
+	if (!transfer_list_add(bl31_tl, TL_TAG_FDT, fdt_sz, fdt)) {
+		return -1;
+	}
+	return 0;
+#else
+	return -1;
+#endif
+}
+
 /*******************************************************************************
  * This function is responsible for handling the SMC that loads the OP-TEE
  * binary image via a non-secure SMC call. It takes the size and physical
@@ -326,6 +470,10 @@ static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa)
 	entry_point_info_t optee_ep_info;
 	uint32_t linear_id = plat_my_core_pos();
 	uint64_t dt_addr = 0;
+	uint64_t arg0 = 0;
+	uint64_t arg1 = 0;
+	uint64_t arg2 = 0;
+	uint64_t arg3 = 0;
 
 	mapped_data_pa = page_align(data_pa, DOWN);
 	mapped_data_va = mapped_data_pa;
@@ -394,12 +542,37 @@ static int32_t opteed_handle_smc_load(uint64_t data_size, uint32_t data_pa)
 	dt_addr = (uint64_t)fdt_buf;
 	flush_dcache_range(dt_addr, OPTEED_FDT_SIZE);
 
+	if (TRANSFER_LIST &&
+	    !create_smc_tl((void *)dt_addr, OPTEED_FDT_SIZE)) {
+		struct transfer_list_entry *te = NULL;
+		void *dt = NULL;
+
+		te = transfer_list_find(bl31_tl, TL_TAG_FDT);
+		dt = transfer_list_entry_data(te);
+
+		if (opteed_rw == OPTEE_AARCH64) {
+			arg0 = (uint64_t)dt;
+			arg1 = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
+			arg2 = 0;
+		} else {
+			arg0 = 0;
+			arg1 = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+			arg2 = (uint64_t)dt;
+		}
+
+		arg3 = (uint64_t)bl31_tl;
+	} else {
+		/* Default handoff arguments */
+		arg2 = dt_addr;
+	}
+
 	opteed_init_optee_ep_state(&optee_ep_info,
 				   opteed_rw,
 				   image_pa,
-				   0,
-				   0,
-				   dt_addr,
+				   arg0,
+				   arg1,
+				   arg2,
+				   arg3,
 				   &opteed_sp_context[linear_id]);
 	if (opteed_init_with_entry_point(&optee_ep_info) == 0) {
 		rc = -EFAULT;
@@ -433,7 +606,6 @@ static uintptr_t opteed_smc_handler(uint32_t smc_fid,
 	cpu_context_t *ns_cpu_context;
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
-	uint64_t rc;
 
 	/*
 	 * Determine which security state this SMC originated from
@@ -567,18 +739,9 @@ static uintptr_t opteed_smc_handler(uint32_t smc_fid,
 			 */
 			psci_register_spd_pm_hook(&opteed_pm);
 
-			/*
-			 * Register an interrupt handler for S-EL1 interrupts
-			 * when generated during code executing in the
-			 * non-secure state.
-			 */
-			flags = 0;
-			set_interrupt_rm_flag(flags, NON_SECURE);
-			rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
-						opteed_sel1_interrupt_handler,
-						flags);
-			if (rc)
-				panic();
+#if !OPTEE_ALLOW_SMC_LOAD
+			register_opteed_interrupt_handler();
+#endif
 		}
 
 		/*
diff --git a/services/spd/opteed/opteed_pm.c b/services/spd/opteed/opteed_pm.c
index fa724a11..c949823e 100644
--- a/services/spd/opteed/opteed_pm.c
+++ b/services/spd/opteed/opteed_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -113,7 +113,7 @@ void opteed_cpu_on_finish_handler(u_register_t unused)
 
 	opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
 				(uint64_t)&optee_vector_table->cpu_on_entry,
-				0, 0, 0, optee_ctx);
+				0, 0, 0, 0, optee_ctx);
 
 	/* Initialise this cpu's secure context */
 	cm_init_my_context(&optee_on_entrypoint);
diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h
index c8fbc221..c484516d 100644
--- a/services/spd/opteed/opteed_private.h
+++ b/services/spd/opteed/opteed_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -148,11 +148,8 @@ void __dead2 opteed_exit_sp(uint64_t c_rt_ctx, uint64_t ret);
 uint64_t opteed_synchronous_sp_entry(optee_context_t *optee_ctx);
 void __dead2 opteed_synchronous_sp_exit(optee_context_t *optee_ctx, uint64_t ret);
 void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
-				uint32_t rw,
-				uint64_t pc,
-				uint64_t pageable_part,
-				uint64_t mem_limit,
-				uint64_t dt_addr,
+				uint32_t rw, uint64_t pc, uint64_t arg0,
+				uint64_t arg1, uint64_t arg2, uint64_t arg3,
 				optee_context_t *optee_ctx);
 void opteed_cpu_on_finish_handler(u_register_t unused);
 
diff --git a/services/spd/pncd/pncd_common.c b/services/spd/pncd/pncd_common.c
index 6fdb6293..8e89491c 100644
--- a/services/spd/pncd/pncd_common.c
+++ b/services/spd/pncd/pncd_common.c
@@ -67,8 +67,9 @@ uint64_t pncd_synchronous_sp_entry(pnc_context_t *pnc_ctx)
 	/* Apply the Secure EL1 system register context and switch to it */
 	assert(cm_get_context(SECURE) == &pnc_ctx->cpu_ctx);
 	cm_el1_sysregs_context_restore(SECURE);
+
 #if CTX_INCLUDE_FPREGS
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
+	simd_ctx_restore(SECURE);
 #endif
 	cm_set_next_eret_context(SECURE);
 
@@ -90,8 +91,9 @@ void pncd_synchronous_sp_exit(pnc_context_t *pnc_ctx, uint64_t ret)
 	/* Save the Secure EL1 system register context */
 	assert(cm_get_context(SECURE) == &pnc_ctx->cpu_ctx);
 	cm_el1_sysregs_context_save(SECURE);
+
 #if CTX_INCLUDE_FPREGS
-	fpregs_context_save(get_fpregs_ctx(cm_get_context(SECURE)));
+	simd_ctx_save(SECURE, false);
 #endif
 
 	assert(pnc_ctx->c_rt_ctx != 0);
diff --git a/services/spd/pncd/pncd_main.c b/services/spd/pncd/pncd_main.c
index 99c4aa1b..cc1c1f28 100644
--- a/services/spd/pncd/pncd_main.c
+++ b/services/spd/pncd/pncd_main.c
@@ -55,8 +55,9 @@ static void context_save(unsigned long security_state)
 	assert(sec_state_is_valid(security_state));
 
 	cm_el1_sysregs_context_save((uint32_t) security_state);
+
 #if CTX_INCLUDE_FPREGS
-	fpregs_context_save(get_fpregs_ctx(cm_get_context(security_state)));
+	simd_ctx_save((uint32_t)security_state, false);
 #endif
 }
 
@@ -72,8 +73,9 @@ static void *context_restore(unsigned long security_state)
 
 	/* Restore state */
 	cm_el1_sysregs_context_restore((uint32_t) security_state);
+
 #if CTX_INCLUDE_FPREGS
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(security_state)));
+	simd_ctx_restore((uint32_t)security_state);
 #endif
 
 	cm_set_next_eret_context((uint32_t) security_state);
diff --git a/services/spd/tlkd/tlkd.mk b/services/spd/tlkd/tlkd.mk
index 56de0a64..fc8840d6 100644
--- a/services/spd/tlkd/tlkd.mk
+++ b/services/spd/tlkd/tlkd.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,9 @@ ifeq (${ERROR_DEPRECATED},0)
 SPD_INCLUDES		:=	-Iinclude/bl32/payloads
 endif
 
+ifeq (${ENABLE_FEAT_D128}, 0)
 SPD_SOURCES		:=	services/spd/tlkd/tlkd_common.c		\
 				services/spd/tlkd/tlkd_helpers.S	\
 				services/spd/tlkd/tlkd_main.c		\
 				services/spd/tlkd/tlkd_pm.c
+endif
\ No newline at end of file
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index 7daebcdd..aae2d9a0 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -118,8 +118,10 @@ static struct smc_args trusty_context_switch(uint32_t security_state, uint64_t r
 	 * when it's needed the PSCI caller has preserved FP context before
 	 * going here.
 	 */
-	if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME)
-		fpregs_context_save(get_fpregs_ctx(cm_get_context(security_state)));
+	if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME) {
+		simd_ctx_save(security_state, false);
+	}
+
 	cm_el1_sysregs_context_save(security_state);
 
 	ctx->saved_security_state = security_state;
@@ -128,8 +130,9 @@ static struct smc_args trusty_context_switch(uint32_t security_state, uint64_t r
 	assert(ctx->saved_security_state == ((security_state == 0U) ? 1U : 0U));
 
 	cm_el1_sysregs_context_restore(security_state);
-	if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME)
-		fpregs_context_restore(get_fpregs_ctx(cm_get_context(security_state)));
+	if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME) {
+		simd_ctx_restore(security_state);
+	}
 
 	cm_set_next_eret_context(security_state);
 
@@ -160,9 +163,9 @@ static uint64_t trusty_fiq_handler(uint32_t id,
 	(void)memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
 	ctx->fiq_pc = SMC_GET_EL3(handle, CTX_ELR_EL3);
 	ctx->fiq_cpsr = SMC_GET_EL3(handle, CTX_SPSR_EL3);
-	ctx->fiq_sp_el1 = read_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1);
+	ctx->fiq_sp_el1 = read_el1_ctx_common(get_el1_sysregs_ctx(handle), sp_el1);
 
-	write_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp);
+	write_el1_ctx_common(get_el1_sysregs_ctx(handle), sp_el1, ctx->fiq_handler_sp);
 	cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, (uint32_t)ctx->fiq_handler_cpsr);
 
 	SMC_RET0(handle);
@@ -221,7 +224,7 @@ static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t
 	 */
 	(void)memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
 	ctx->fiq_handler_active = 0;
-	write_ctx_reg(get_el1_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1);
+	write_el1_ctx_common(get_el1_sysregs_ctx(handle), sp_el1, ctx->fiq_sp_el1);
 	cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, (uint32_t)ctx->fiq_cpsr);
 
 	SMC_RET0(handle);
@@ -320,7 +323,7 @@ static int32_t trusty_init(void)
 	ep_info = bl31_plat_get_next_image_ep_info(SECURE);
 	assert(ep_info != NULL);
 
-	fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
+	simd_ctx_save(NON_SECURE, false);
 	cm_el1_sysregs_context_save(NON_SECURE);
 
 	cm_set_context(&ctx->cpu_ctx, SECURE);
@@ -337,7 +340,7 @@ static int32_t trusty_init(void)
 	}
 
 	cm_el1_sysregs_context_restore(SECURE);
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
+	simd_ctx_restore(SECURE);
 	cm_set_next_eret_context(SECURE);
 
 	ctx->saved_security_state = ~0U; /* initial saved state is invalid */
@@ -346,7 +349,7 @@ static int32_t trusty_init(void)
 	(void)trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
 
 	cm_el1_sysregs_context_restore(NON_SECURE);
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
+	simd_ctx_restore(NON_SECURE);
 	cm_set_next_eret_context(NON_SECURE);
 
 	return 1;
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index 6cb4992a..8ff71cc8 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -575,6 +575,11 @@ static uintptr_t tspd_smc_handler(uint32_t smc_fid,
 		 * of the DIT PSTATE bit.
 		 */
 	case TSP_YIELD_FID(TSP_CHECK_DIT):
+		/*
+		 * Request from non-secure client to modify the EL1
+		 * context registers.
+		 */
+	case TSP_YIELD_FID(TSP_MODIFY_EL1_CTX):
 		if (ns) {
 			/*
 			 * This is a fresh request from the non-secure client.
diff --git a/services/std_svc/drtm/drtm_main.c b/services/std_svc/drtm/drtm_main.c
index 3acf6838..8d27e96d 100644
--- a/services/std_svc/drtm/drtm_main.c
+++ b/services/std_svc/drtm/drtm_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -211,7 +211,7 @@ static enum drtm_retc drtm_dl_check_cores(void)
 	running_on_single_core = psci_is_last_on_cpu_safe();
 	if (!running_on_single_core) {
 		ERROR("DRTM: invalid launch due to non-boot PE not being turned off\n");
-		return DENIED;
+		return SECONDARY_PE_NOT_OFF;
 	}
 
 	return SUCCESS;
@@ -463,7 +463,7 @@ static enum drtm_retc drtm_dl_check_args(uint64_t x1,
 	 * is required to avoid / defend against racing with cache evictions
 	 */
 	va_mapping_size = ALIGNED_UP((dlme_end - dlme_start), DRTM_PAGE_SIZE);
-	rc = mmap_add_dynamic_region_alloc_va(dlme_img_start, &va_mapping, va_mapping_size,
+	rc = mmap_add_dynamic_region_alloc_va(dlme_start, &va_mapping, va_mapping_size,
 					      MT_MEMORY | MT_NS | MT_RO |
 					      MT_SHAREABILITY_ISH);
 	if (rc != 0) {
@@ -512,10 +512,10 @@ static void drtm_dl_reset_dlme_el_state(enum drtm_dlme_el dlme_el)
 	sctlr &= ~(/* Disable DLME's EL MMU, since the existing page-tables are untrusted. */
 		   SCTLR_M_BIT
 		   | SCTLR_EE_BIT               /* Little-endian data accesses. */
+		   | SCTLR_C_BIT		/* disable data caching */
+		   | SCTLR_I_BIT		/* disable instruction caching */
 		  );
 
-	sctlr |= SCTLR_C_BIT | SCTLR_I_BIT; /* Allow instruction and data caching. */
-
 	switch (dlme_el) {
 	case DLME_AT_EL1:
 		write_sctlr_el1(sctlr);
@@ -655,10 +655,14 @@ static uint64_t drtm_dynamic_launch(uint64_t x1, void *handle)
 	drtm_dl_reset_dlme_el_state(dlme_el);
 	drtm_dl_reset_dlme_context(dlme_el);
 
+	/*
+	 * Setting the Generic Timer frequency is required before launching
+	 * DLME and is already done for running CPU during PSCI setup.
+	 */
 	drtm_dl_prepare_eret_to_dlme(&args, dlme_el);
 
 	/*
-	 * As per DRTM beta0 spec table #28 invalidate the instruction cache
+	 * As per DRTM 1.0 spec table #30 invalidate the instruction cache
 	 * before jumping to the DLME. This is required to defend against
 	 * potentially-malicious cache contents.
 	 */
@@ -808,12 +812,12 @@ uint64_t drtm_smc_handler(uint32_t smc_fid,
 
 	case ARM_DRTM_SVC_GET_ERROR:
 		INFO("DRTM service handler: get error\n");
-		drtm_get_error(handle);
+		return drtm_get_error(handle);
 		break;	/* not reached */
 
 	case ARM_DRTM_SVC_SET_ERROR:
 		INFO("DRTM service handler: set error\n");
-		drtm_set_error(x1, handle);
+		return drtm_set_error(x1, handle);
 		break;	/* not reached */
 
 	case ARM_DRTM_SVC_SET_TCB_HASH:
diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h
index 60051632..a7d053f1 100644
--- a/services/std_svc/drtm/drtm_main.h
+++ b/services/std_svc/drtm/drtm_main.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -55,6 +55,12 @@ enum drtm_retc {
 	NOT_FOUND = -4,
 	INTERNAL_ERROR = -5,
 	MEM_PROTECT_INVALID = -6,
+	COPROCESSOR_ERROR = -7,
+	OUT_OF_RESOURCE = -8,
+	INVALID_DATA = -9,
+	SECONDARY_PE_NOT_OFF = -10,
+	ALREADY_CLOSED = -11,
+	TPM_ERROR = -12
 };
 
 typedef struct {
@@ -89,6 +95,7 @@ struct __packed dlme_data_header_v1 {
 	uint64_t dlme_addr_map_size;
 	uint64_t dlme_tpm_log_size;
 	uint64_t dlme_tcb_hashes_table_size;
+	uint64_t dlme_acpi_tables_region_size;
 	uint64_t dlme_impdef_region_size;
 } __aligned(__alignof(uint16_t /* First member's type, `uint16_t version'. */));
 
diff --git a/services/std_svc/drtm/drtm_remediation.c b/services/std_svc/drtm/drtm_remediation.c
index 696b4ea6..81d27ec2 100644
--- a/services/std_svc/drtm/drtm_remediation.c
+++ b/services/std_svc/drtm/drtm_remediation.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024 Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier:    BSD-3-Clause
  *
@@ -21,7 +21,7 @@ uint64_t drtm_set_error(uint64_t x1, void *ctx)
 	rc = plat_set_drtm_error(x1);
 
 	if (rc != 0) {
-		SMC_RET1(ctx, INTERNAL_ERROR);
+		SMC_RET1(ctx, NOT_FOUND);
 	}
 
 	SMC_RET1(ctx, SUCCESS);
@@ -35,7 +35,7 @@ uint64_t drtm_get_error(void *ctx)
 	rc = plat_get_drtm_error(&error_code);
 
 	if (rc != 0) {
-		SMC_RET1(ctx, INTERNAL_ERROR);
+		SMC_RET1(ctx, NOT_FOUND);
 	}
 
 	SMC_RET2(ctx, SUCCESS, error_code);
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
index e24a6217..d6884319 100644
--- a/services/std_svc/errata_abi/cpu_errata_info.h
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,46 +8,29 @@
 #define ERRATA_CPUSPEC_H
 
 #include <stdint.h>
+#include <arch.h>
 #include <arch_helpers.h>
 
 #if __aarch64__
-#include <cortex_a35.h>
-#include <cortex_a510.h>
-#include <cortex_a53.h>
-#include <cortex_a57.h>
-#include <cortex_a55.h>
 #include <cortex_a710.h>
-#include <cortex_a72.h>
-#include <cortex_a73.h>
-#include <cortex_a75.h>
-#include <cortex_a76.h>
-#include <cortex_a77.h>
 #include <cortex_a78.h>
 #include <cortex_a78_ae.h>
 #include <cortex_a78c.h>
-#include <cortex_a715.h>
-#include <cortex_x1.h>
 #include <cortex_x2.h>
 #include <cortex_x3.h>
-#include <neoverse_n1.h>
+#include <cortex_x4.h>
 #include <neoverse_n2.h>
 #include <neoverse_v1.h>
 #include <neoverse_v2.h>
-#else
-#include <cortex_a15.h>
-#include <cortex_a17.h>
-#include <cortex_a57.h>
-#include <cortex_a9.h>
 #endif
 
-#define MAX_ERRATA_ENTRIES	32
+/* Max number of platform based errata with no workaround in EL3 */
+#define MAX_PLAT_CPU_ERRATA_ENTRIES	2
 
-#define ERRATA_LIST_END		(MAX_ERRATA_ENTRIES - 1)
+#define ERRATA_LIST_END		(MAX_PLAT_CPU_ERRATA_ENTRIES - 1)
 
 /* Default values for unused memory in the array */
-#define UNDEF_ERRATA		{UINT_MAX, UCHAR_MAX, UCHAR_MAX, false, false}
-
-#define EXTRACT_PARTNUM(x)	((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+#define UNDEF_ERRATA		{UINT_MAX, UCHAR_MAX, UCHAR_MAX}
 
 #define RXPX_RANGE(x, y, z)	(((x >= y) && (x <= z)) ? true : false)
 
@@ -58,15 +41,11 @@ struct em_cpu{
 	unsigned int em_errata_id;
 	unsigned char em_rxpx_lo;	/* lowest revision of errata applicable for the cpu */
 	unsigned char em_rxpx_hi;	/* highest revision of errata applicable for the cpu */
-	bool errata_enabled;		/* indicate if errata enabled */
-	/* flag to indicate if errata query is based out of non-arm interconnect */
-	bool non_arm_interconnect;
 };
 
 struct em_cpu_list{
-	/* field to hold cpu specific part number defined in midr reg */
-	unsigned long cpu_partnumber;
-	struct   em_cpu cpu_errata_list[MAX_ERRATA_ENTRIES];
+	unsigned long cpu_midr;	/* cpu specific part number is bit[15:4] of midr value */
+	struct   em_cpu cpu_errata_list[MAX_PLAT_CPU_ERRATA_ENTRIES];
 };
 
 int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag);
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index 0b263e5f..0d0ecc3d 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -1,11 +1,13 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 #include "cpu_errata_info.h"
+#include <lib/cpus/cpu_ops.h>
+#include <lib/cpus/errata.h>
 #include <lib/smccc.h>
 #include <lib/utils_def.h>
 #include <services/errata_abi_svc.h>
@@ -17,516 +19,192 @@
  */
 struct em_cpu_list *cpu_ptr;
 
-extern uint8_t cpu_get_rev_var(void);
-
 /* Structure array that holds CPU specific errata information */
 struct em_cpu_list cpu_list[] = {
-#if CORTEX_A9_H_INC
-{
-	.cpu_partnumber = CORTEX_A9_MIDR,
-	.cpu_errata_list = {
-		[0] = {794073, 0x00, 0xFF, ERRATA_A9_794073},
-		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A9_H_INC */
-
-#if CORTEX_A15_H_INC
-{
-	.cpu_partnumber = CORTEX_A15_MIDR,
-	.cpu_errata_list = {
-		[0] = {816470, 0x30, 0xFF, ERRATA_A15_816470},
-		[1] = {827671, 0x30, 0xFF, ERRATA_A15_827671},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A15_H_INC */
-
-#if CORTEX_A17_H_INC
-{
-	.cpu_partnumber = CORTEX_A17_MIDR,
-	.cpu_errata_list = {
-		[0] = {852421, 0x00, 0x12, ERRATA_A17_852421},
-		[1] = {852423, 0x00, 0x12, ERRATA_A17_852423},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A17_H_INC */
-
-#if CORTEX_A35_H_INC
-{
-	.cpu_partnumber = CORTEX_A35_MIDR,
-	.cpu_errata_list = {
-		[0] = {855472, 0x00, 0x00, ERRATA_A35_855472},
-		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A35_H_INC */
-
-#if CORTEX_A53_H_INC
-{
-	.cpu_partnumber = CORTEX_A53_MIDR,
-	.cpu_errata_list = {
-		[0] = {819472, 0x00, 0x01, ERRATA_A53_819472},
-		[1] = {824069, 0x00, 0x02, ERRATA_A53_824069},
-		[2] = {826319, 0x00, 0x02, ERRATA_A53_826319},
-		[3] = {827319, 0x00, 0x02, ERRATA_A53_827319},
-		[4] = {835769, 0x00, 0x04, ERRATA_A53_835769},
-		[5] = {836870, 0x00, 0x03, ERRATA_A53_836870},
-		[6] = {843419, 0x00, 0x04, ERRATA_A53_843419},
-		[7] = {855873, 0x03, 0xFF, ERRATA_A53_855873},
-		[8] = {1530924, 0x00, 0xFF, ERRATA_A53_1530924},
-		[9 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A53_H_INC */
-
-#if CORTEX_A55_H_INC
-{
-	.cpu_partnumber = CORTEX_A55_MIDR,
-	.cpu_errata_list = {
-		[0] = {768277, 0x00, 0x00, ERRATA_A55_768277},
-		[1] = {778703, 0x00, 0x00, ERRATA_A55_778703},
-		[2] = {798797, 0x00, 0x00, ERRATA_A55_798797},
-		[3] = {846532, 0x00, 0x01, ERRATA_A55_846532},
-		[4] = {903758, 0x00, 0x01, ERRATA_A55_903758},
-		[5] = {1221012, 0x00, 0x10, ERRATA_A55_1221012},
-		[6] = {1530923, 0x00, 0xFF, ERRATA_A55_1530923},
-		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A55_H_INC */
-
-#if CORTEX_A57_H_INC
-{
-	.cpu_partnumber = CORTEX_A57_MIDR,
-	.cpu_errata_list = {
-		[0] = {806969, 0x00, 0x00, ERRATA_A57_806969},
-		[1] = {813419, 0x00, 0x00, ERRATA_A57_813419},
-		[2] = {813420, 0x00, 0x00, ERRATA_A57_813420},
-		[3] = {814670, 0x00, 0x00, ERRATA_A57_814670},
-		[4] = {817169, 0x00, 0x01, ERRATA_A57_817169},
-		[5] = {826974, 0x00, 0x11, ERRATA_A57_826974},
-		[6] = {826977, 0x00, 0x11, ERRATA_A57_826977},
-		[7] = {828024, 0x00, 0x11, ERRATA_A57_828024},
-		[8] = {829520, 0x00, 0x12, ERRATA_A57_829520},
-		[9] = {833471, 0x00, 0x12, ERRATA_A57_833471},
-		[10] = {859972, 0x00, 0x13, ERRATA_A57_859972},
-		[11] = {1319537, 0x00, 0xFF, ERRATA_A57_1319537},
-		[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A57_H_INC */
-
-#if CORTEX_A72_H_INC
-{
-	.cpu_partnumber = CORTEX_A72_MIDR,
-	.cpu_errata_list = {
-		[0] = {859971, 0x00, 0x03, ERRATA_A72_859971},
-		[1] = {1319367, 0x00, 0xFF, ERRATA_A72_1319367},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A72_H_INC */
-
-#if CORTEX_A73_H_INC
-{
-	.cpu_partnumber = CORTEX_A73_MIDR,
-	.cpu_errata_list = {
-		[0] = {852427, 0x00, 0x00, ERRATA_A73_852427},
-		[1] = {855423, 0x00, 0x01, ERRATA_A73_855423},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A73_H_INC */
-
-#if CORTEX_A75_H_INC
-{
-	.cpu_partnumber = CORTEX_A75_MIDR,
-	.cpu_errata_list = {
-		[0] = {764081, 0x00, 0x00, ERRATA_A75_764081},
-		[1] = {790748, 0x00, 0x00, ERRATA_A75_790748},
-		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A75_H_INC */
-
-#if CORTEX_A76_H_INC
-{
-	.cpu_partnumber = CORTEX_A76_MIDR,
-	.cpu_errata_list = {
-		[0] = {1073348, 0x00, 0x10, ERRATA_A76_1073348},
-		[1] = {1130799, 0x00, 0x20, ERRATA_A76_1130799},
-		[2] = {1165522, 0x00, 0xFF, ERRATA_A76_1165522},
-		[3] = {1220197, 0x00, 0x20, ERRATA_A76_1220197},
-		[4] = {1257314, 0x00, 0x30, ERRATA_A76_1257314},
-		[5] = {1262606, 0x00, 0x30, ERRATA_A76_1262606},
-		[6] = {1262888, 0x00, 0x30, ERRATA_A76_1262888},
-		[7] = {1275112, 0x00, 0x30, ERRATA_A76_1275112},
-		[8] = {1286807, 0x00, 0x30, ERRATA_A76_1286807},
-		[9] = {1791580, 0x00, 0x40, ERRATA_A76_1791580},
-		[10] = {1868343, 0x00, 0x40, ERRATA_A76_1868343},
-		[11] = {1946160, 0x30, 0x41, ERRATA_A76_1946160},
-		[12] = {2743102, 0x00, 0x41, ERRATA_A76_2743102},
-		[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A76_H_INC */
-
-#if CORTEX_A77_H_INC
-{
-	.cpu_partnumber = CORTEX_A77_MIDR,
-	.cpu_errata_list = {
-		[0] = {1508412, 0x00, 0x10, ERRATA_A77_1508412},
-		[1] = {1791578, 0x00, 0x11, ERRATA_A77_1791578},
-		[2] = {1800714, 0x00, 0x11, ERRATA_A77_1800714},
-		[3] = {1925769, 0x00, 0x11, ERRATA_A77_1925769},
-		[4] = {1946167, 0x00, 0x11, ERRATA_A77_1946167},
-		[5] = {2356587, 0x00, 0x11, ERRATA_A77_2356587},
-		[6] = {2743100, 0x00, 0x11, ERRATA_A77_2743100},
-		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A77_H_INC */
-
 #if CORTEX_A78_H_INC
 {
-	.cpu_partnumber = CORTEX_A78_MIDR,
+	.cpu_midr = CORTEX_A78_MIDR,
 	.cpu_errata_list = {
-		[0] = {1688305, 0x00, 0x10, ERRATA_A78_1688305},
-		[1] = {1821534, 0x00, 0x10, ERRATA_A78_1821534},
-		[2] = {1941498, 0x00, 0x11, ERRATA_A78_1941498},
-		[3] = {1951500, 0x10, 0x11, ERRATA_A78_1951500},
-		[4] = {1952683, 0x00, 0x00, ERRATA_A78_1952683},
-		[5] = {2132060, 0x00, 0x12, ERRATA_A78_2132060},
-		[6] = {2242635, 0x10, 0x12, ERRATA_A78_2242635},
-		[7] = {2376745, 0x00, 0x12, ERRATA_A78_2376745},
-		[8] = {2395406, 0x00, 0x12, ERRATA_A78_2395406},
-		[9] = {2712571, 0x00, 0x12, ERRATA_A78_2712571, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[10] = {2742426, 0x00, 0x12, ERRATA_A78_2742426},
-		[11] = {2772019, 0x00, 0x12, ERRATA_A78_2772019},
-		[12] = {2779479, 0x00, 0x12, ERRATA_A78_2779479},
-		[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2712571, 0x00, 0x12},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A78_H_INC */
 
 #if CORTEX_A78_AE_H_INC
 {
-	.cpu_partnumber = CORTEX_A78_AE_MIDR,
+	.cpu_midr = CORTEX_A78_AE_MIDR,
 	.cpu_errata_list = {
-		[0] = {1941500, 0x00, 0x01, ERRATA_A78_AE_1941500},
-		[1] = {1951502, 0x00, 0x01, ERRATA_A78_AE_1951502},
-		[2] = {2376748, 0x00, 0x02, ERRATA_A78_AE_2376748},
-		[3] = {2395408, 0x00, 0x01, ERRATA_A78_AE_2395408},
-		[4] = {2712574, 0x00, 0x02, ERRATA_A78_AE_2712574, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[5 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2712574, 0x00, 0x02},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A78_AE_H_INC */
 
 #if CORTEX_A78C_H_INC
 {
-	.cpu_partnumber = CORTEX_A78C_MIDR,
+	.cpu_midr = CORTEX_A78C_MIDR,
 	.cpu_errata_list = {
-		[0] = {1827430, 0x00, 0x00, ERRATA_A78C_1827430},
-		[1] = {1827440, 0x00, 0x00, ERRATA_A78C_1827440},
-		[2] = {2132064, 0x01, 0x02, ERRATA_A78C_2132064},
-		[3] = {2242638, 0x01, 0x02, ERRATA_A78C_2242638},
-		[4] = {2376749, 0x01, 0x02, ERRATA_A78C_2376749},
-		[5] = {2395411, 0x01, 0x02, ERRATA_A78C_2395411},
-		[6] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[7] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121},
-		[8] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484},
-		[9 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2712575, 0x01, 0x02},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A78C_H_INC */
 
-#if CORTEX_X1_H_INC
-{
-	.cpu_partnumber = CORTEX_X1_MIDR,
-	.cpu_errata_list = {
-		[0] = {1688305, 0x00, 0x10, ERRATA_X1_1688305},
-		[1] = {1821534, 0x00, 0x10, ERRATA_X1_1821534},
-		[2] = {1827429, 0x00, 0x10, ERRATA_X1_1827429},
-		[3 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_X1_H_INC */
-
-#if NEOVERSE_N1_H_INC
-{
-	.cpu_partnumber = NEOVERSE_N1_MIDR,
-	.cpu_errata_list = {
-		[0] = {1043202, 0x00, 0x10, ERRATA_N1_1043202},
-		[1] = {1073348, 0x00, 0x10, ERRATA_N1_1073348},
-		[2] = {1130799, 0x00, 0x20, ERRATA_N1_1130799},
-		[3] = {1165347, 0x00, 0x20, ERRATA_N1_1165347},
-		[4] = {1207823, 0x00, 0x20, ERRATA_N1_1207823},
-		[5] = {1220197, 0x00, 0x20, ERRATA_N1_1220197},
-		[6] = {1257314, 0x00, 0x30, ERRATA_N1_1257314},
-		[7] = {1262606, 0x00, 0x30, ERRATA_N1_1262606},
-		[8] = {1262888, 0x00, 0x30, ERRATA_N1_1262888},
-		[9] = {1275112, 0x00, 0x30, ERRATA_N1_1275112},
-		[10] = {1315703, 0x00, 0x30, ERRATA_N1_1315703},
-		[11] = {1542419, 0x30, 0x40, ERRATA_N1_1542419},
-		[12] = {1868343, 0x00, 0x40, ERRATA_N1_1868343},
-		[13] = {1946160, 0x30, 0x41, ERRATA_N1_1946160},
-		[14] = {2743102, 0x00, 0x41, ERRATA_N1_2743102},
-		[15 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* NEOVERSE_N1_H_INC */
-
 #if NEOVERSE_V1_H_INC
 {
-	.cpu_partnumber = NEOVERSE_V1_MIDR,
+	.cpu_midr = NEOVERSE_V1_MIDR,
 	.cpu_errata_list = {
-		[0] = {1618635, 0x00, 0x00, ERRATA_V1_1618635},
-		[1] = {1774420, 0x00, 0x10, ERRATA_V1_1774420},
-		[2] = {1791573, 0x00, 0x10, ERRATA_V1_1791573},
-		[3] = {1852267, 0x00, 0x10, ERRATA_V1_1852267},
-		[4] = {1925756, 0x00, 0x11, ERRATA_V1_1925756},
-		[5] = {1940577, 0x10, 0x11, ERRATA_V1_1940577},
-		[6] = {1966096, 0x10, 0x11, ERRATA_V1_1966096},
-		[7] = {2108267, 0x00, 0x12, ERRATA_V1_2108267},
-		[8] = {2139242, 0x00, 0x11, ERRATA_V1_2139242},
-		[9] = {2216392, 0x10, 0x11, ERRATA_V1_2216392},
-		[10] = {2294912, 0x00, 0x12, ERRATA_V1_2294912},
-		[11] = {2372203, 0x00, 0x11, ERRATA_V1_2372203},
-		[12] = {2701953, 0x00, 0x11, ERRATA_V1_2701953, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[13] = {2743093, 0x00, 0x12, ERRATA_V1_2743093},
-		[14] = {2743233, 0x00, 0x12, ERRATA_V1_2743233},
-		[15] = {2779461, 0x00, 0x12, ERRATA_V1_2779461},
-		[16 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2701953, 0x00, 0x11},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_V1_H_INC */
 
 #if CORTEX_A710_H_INC
 {
-	.cpu_partnumber = CORTEX_A710_MIDR,
+	.cpu_midr = CORTEX_A710_MIDR,
 	.cpu_errata_list = {
-		[0] = {1987031, 0x00, 0x20, ERRATA_A710_1987031},
-		[1] = {2008768, 0x00, 0x20, ERRATA_A710_2008768},
-		[2] = {2017096, 0x00, 0x20, ERRATA_A710_2017096},
-		[3] = {2055002, 0x10, 0x20, ERRATA_A710_2055002},
-		[4] = {2058056, 0x00, 0x21, ERRATA_A710_2058056},
-		[5] = {2081180, 0x00, 0x20, ERRATA_A710_2081180},
-		[6] = {2083908, 0x20, 0x20, ERRATA_A710_2083908},
-		[7] = {2136059, 0x00, 0x20, ERRATA_A710_2136059},
-		[8] = {2147715, 0x20, 0x20, ERRATA_A710_2147715},
-		[9] = {2216384, 0x00, 0x20, ERRATA_A710_2216384},
-		[10] = {2267065, 0x00, 0x20, ERRATA_A710_2267065},
-		[11] = {2282622, 0x00, 0x21, ERRATA_A710_2282622},
-		[12] = {2291219, 0x00, 0x20, ERRATA_A710_2291219},
-		[13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105},
-		[14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[15] = {2742423, 0x00, 0x21, ERRATA_A710_2742423},
-		[16] = {2768515, 0x00, 0x21, ERRATA_A710_2768515},
-		[17 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2701952, 0x00, 0x21},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A710_H_INC */
 
 #if NEOVERSE_N2_H_INC
 {
-	.cpu_partnumber = NEOVERSE_N2_MIDR,
+	.cpu_midr = NEOVERSE_N2_MIDR,
 	.cpu_errata_list = {
-		[0] = {2002655, 0x00, 0x00, ERRATA_N2_2002655},
-		[1] = {2009478, 0x00, 0x00, ERRATA_N2_2009478},
-		[2] = {2025414, 0x00, 0x00, ERRATA_N2_2025414},
-		[3] = {2067956, 0x00, 0x00, ERRATA_N2_2067956},
-		[4] = {2138953, 0x00, 0x03, ERRATA_N2_2138953},
-		[5] = {2138956, 0x00, 0x00, ERRATA_N2_2138956},
-		[6] = {2138958, 0x00, 0x00, ERRATA_N2_2138958},
-		[7] = {2189731, 0x00, 0x00, ERRATA_N2_2189731},
-		[8] = {2242400, 0x00, 0x00, ERRATA_N2_2242400},
-		[9] = {2242415, 0x00, 0x00, ERRATA_N2_2242415},
-		[10] = {2280757, 0x00, 0x00, ERRATA_N2_2280757},
-		[11] = {2326639, 0x00, 0x00, ERRATA_N2_2326639},
-		[12] = {2340933, 0x00, 0x00, ERRATA_N2_2340933},
-		[13] = {2346952, 0x00, 0x02, ERRATA_N2_2346952},
-		[14] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
-		[15] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
-		[16] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[17] = {2743014, 0x00, 0x02, ERRATA_N2_2743014},
-		[18] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
-		[19] = {2779511, 0x00, 0x02, ERRATA_N2_2779511},
-		[20 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2728475, 0x00, 0x02},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_N2_H_INC */
 
 #if CORTEX_X2_H_INC
 {
-	.cpu_partnumber = CORTEX_X2_MIDR,
+	.cpu_midr = CORTEX_X2_MIDR,
 	.cpu_errata_list = {
-		[0] = {2002765, 0x00, 0x20, ERRATA_X2_2002765},
-		[1] = {2017096, 0x00, 0x20, ERRATA_X2_2017096},
-		[2] = {2058056, 0x00, 0x21, ERRATA_X2_2058056},
-		[3] = {2081180, 0x00, 0x20, ERRATA_X2_2081180},
-		[4] = {2083908, 0x20, 0x20, ERRATA_X2_2083908},
-		[5] = {2147715, 0x20, 0x20, ERRATA_X2_2147715},
-		[6] = {2216384, 0x00, 0x20, ERRATA_X2_2216384},
-		[7] = {2282622, 0x00, 0x21, ERRATA_X2_2282622},
-		[8] = {2371105, 0x00, 0x20, ERRATA_X2_2371105},
-		[9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[10] = {2742423, 0x00, 0x21, ERRATA_X2_2742423},
-		[11] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
-		[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2701952, 0x00, 0x21},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_X2_H_INC */
 
-#if CORTEX_A510_H_INC
-{
-	.cpu_partnumber = CORTEX_A510_MIDR,
-	.cpu_errata_list = {
-		[0] = {1922240, 0x00, 0x00, ERRATA_A510_1922240},
-		[1] = {2041909, 0x02, 0x02, ERRATA_A510_2041909},
-		[2] = {2042739, 0x00, 0x02, ERRATA_A510_2042739},
-		[3] = {2080326, 0x02, 0x02, ERRATA_A510_2080326},
-		[4] = {2172148, 0x00, 0x10, ERRATA_A510_2172148},
-		[5] = {2218950, 0x00, 0x10, ERRATA_A510_2218950},
-		[6] = {2250311, 0x00, 0x10, ERRATA_A510_2250311},
-		[7] = {2288014, 0x00, 0x10, ERRATA_A510_2288014},
-		[8] = {2347730, 0x00, 0x11, ERRATA_A510_2347730},
-		[9] = {2371937, 0x00, 0x11, ERRATA_A510_2371937},
-		[10] = {2666669, 0x00, 0x11, ERRATA_A510_2666669},
-		[11] = {2684597, 0x00, 0x12, ERRATA_A510_2684597},
-		[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
-	}
-},
-#endif /* CORTEX_A510_H_INC */
-
 #if NEOVERSE_V2_H_INC
 {
-	.cpu_partnumber = NEOVERSE_V2_MIDR,
+	.cpu_midr = NEOVERSE_V2_MIDR,
 	.cpu_errata_list = {
-		[0] = {2331132, 0x00, 0x02, ERRATA_V2_2331132},
-		[1] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \
-			ERRATA_NON_ARM_INTERCONNECT},
-		[2] = {2719105, 0x00, 0x01, ERRATA_V2_2719105},
-		[3] = {2743011, 0x00, 0x01, ERRATA_V2_2743011},
-		[4] = {2779510, 0x00, 0x01, ERRATA_V2_2779510},
-		[5] = {2801372, 0x00, 0x01, ERRATA_V2_2801372},
-		[6 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2719103, 0x00, 0x01},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_V2_H_INC */
 
-#if CORTEX_A715_H_INC
+#if CORTEX_X3_H_INC
 {
-	.cpu_partnumber = CORTEX_A715_MIDR,
+	.cpu_midr = CORTEX_X3_MIDR,
 	.cpu_errata_list = {
-		[0] = {2701951, 0x00, 0x11, ERRATA_A715_2701951, \
-			ERRATA_NON_ARM_INTERCONNECT},
+		[0] = {2701951, 0x00, 0x11},
 		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
-#endif /* CORTEX_A715_H_INC */
+#endif /* CORTEX_X3_H_INC */
 
-#if CORTEX_X3_H_INC
+#if CORTEX_X4_H_INC
 {
-	.cpu_partnumber = CORTEX_X3_MIDR,
+	.cpu_midr = CORTEX_X4_MIDR,
 	.cpu_errata_list = {
-		[0] = {2070301, 0x00, 0x12, ERRATA_X3_2070301},
-		[1] = {2313909, 0x00, 0x10, ERRATA_X3_2313909},
-		[2] = {2615812, 0x00, 0x11, ERRATA_X3_2615812},
-		[3] = {2742421, 0x00, 0x11, ERRATA_X3_2742421},
-		[4 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {2701112, 0x00, 0x00},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
-#endif /* CORTEX_X3_H_INC */
-};
-
-/*
- * Function to do binary search and check for the specific errata ID
- * in the array of structures specific to the cpu identified.
- */
-int32_t binary_search(struct em_cpu_list *ptr, uint32_t erratum_id, uint8_t rxpx_val)
-{
-	int low_index = 0U, mid_index = 0U;
+#endif /* CORTEX_X4_H_INC */
 
-	int high_index = MAX_ERRATA_ENTRIES - 1;
+};
 
-	assert(ptr != NULL);
+#if ERRATA_NON_ARM_INTERCONNECT
 
-	/*
-	 * Pointer to the errata list of the cpu that matches
-	 * extracted partnumber in the cpu list
-	 */
-	struct em_cpu *erratum_ptr = NULL;
+/* Check if the errata is enabled for non-arm interconnect */
+static int32_t non_arm_interconnect_errata(uint32_t errata_id, long rev_var)
+{
+	int32_t ret_val = EM_UNKNOWN_ERRATUM;
 
-	while (low_index <= high_index) {
-		mid_index = (low_index + high_index) / 2;
+	/* Determine the number of cpu listed in the cpu list */
+	uint8_t size_cpulist = ARRAY_SIZE(cpu_list);
 
-		erratum_ptr = &ptr->cpu_errata_list[mid_index];
-		assert(erratum_ptr != NULL);
+	/* Read the midr reg to extract cpu, revision and variant info */
+	uint32_t midr_val = read_midr();
 
-		if (erratum_id < erratum_ptr->em_errata_id) {
-			high_index = mid_index - 1;
-		} else if (erratum_id > erratum_ptr->em_errata_id) {
-			low_index = mid_index + 1;
-		} else if (erratum_id == erratum_ptr->em_errata_id) {
-			if (RXPX_RANGE(rxpx_val, erratum_ptr->em_rxpx_lo, \
-				erratum_ptr->em_rxpx_hi)) {
-				if ((erratum_ptr->errata_enabled) && \
-				(!(erratum_ptr->non_arm_interconnect))) {
-					return EM_HIGHER_EL_MITIGATION;
+	for (uint8_t i = 0U; i < size_cpulist; i++) {
+		cpu_ptr = &cpu_list[i];
+		/*
+		 * If the cpu partnumber in the cpu list, matches the midr
+		 * part number, check to see if the errata ID matches
+		 */
+		if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(cpu_ptr->cpu_midr)) {
+
+			struct em_cpu *ptr = NULL;
+
+			for (int j = 0; j < MAX_PLAT_CPU_ERRATA_ENTRIES; j++) {
+				ptr = &cpu_ptr->cpu_errata_list[j];
+				assert(ptr != NULL);
+				if (errata_id == ptr->em_errata_id) {
+					if (RXPX_RANGE(rev_var, ptr->em_rxpx_lo, ptr->em_rxpx_hi)) {
+						ret_val = EM_AFFECTED;
+						break;
+					}
+					ret_val = EM_NOT_AFFECTED;
+					break;
 				}
-				return EM_AFFECTED;
 			}
-			return EM_NOT_AFFECTED;
+			break;
 		}
 	}
-	/* no matching errata ID */
-	return EM_UNKNOWN_ERRATUM;
+	return ret_val;
 }
+#endif
 
 /* Function to check if the errata exists for the specific CPU and rxpx */
 int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag)
 {
-	/*
-	 * Read MIDR value and extract the revision, variant and partnumber
-	 */
-	static uint32_t midr_val, cpu_partnum;
-	static uint8_t  cpu_rxpx_val;
-	int32_t ret_val = EM_UNKNOWN_ERRATUM;
+	int32_t ret_val;
+	struct cpu_ops *cpu_ops;
+	struct erratum_entry *entry, *end;
+	long rev_var;
+
+	ret_val = EM_UNKNOWN_ERRATUM;
+	rev_var = cpu_get_rev_var();
+
+#if ERRATA_NON_ARM_INTERCONNECT
+	ret_val = non_arm_interconnect_errata(errata_id, rev_var);
+	if (ret_val != EM_UNKNOWN_ERRATUM) {
+		return ret_val;
+	}
+#endif
 
-	/* Determine the number of cpu listed in the cpu list */
-	uint8_t size_cpulist = ARRAY_SIZE(cpu_list);
+	cpu_ops = get_cpu_ops_ptr();
+	assert(cpu_ops != NULL);
 
-	/* Read the midr reg to extract cpu, revision and variant info */
-	midr_val = read_midr();
+	entry = cpu_ops->errata_list_start;
+	assert(entry != NULL);
 
-	/* Extract revision and variant from the MIDR register */
-	cpu_rxpx_val = cpu_get_rev_var();
+	end = cpu_ops->errata_list_end;
+	assert(end != NULL);
 
-	/* Extract the cpu partnumber and check if the cpu is in the cpu list */
-	cpu_partnum = EXTRACT_PARTNUM(midr_val);
+	end--; /* point to the last erratum entry of the queried cpu */
 
-	for (uint8_t i = 0; i < size_cpulist; i++) {
-		cpu_ptr = &cpu_list[i];
-		uint16_t partnum_extracted = EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber);
-
-		if (partnum_extracted == cpu_partnum) {
-			/*
-			 * If the midr value is in the cpu list, binary search
-			 * for the errata ID and specific revision in the list.
-			 */
-			ret_val = binary_search(cpu_ptr, errata_id, cpu_rxpx_val);
-			break;
+	while ((entry <= end) && (ret_val == EM_UNKNOWN_ERRATUM)) {
+		if (entry->id == errata_id) {
+			if (entry->check_func(rev_var)) {
+				if (entry->chosen)
+					return EM_HIGHER_EL_MITIGATION;
+				else
+					return EM_AFFECTED;
+			}
+			return EM_NOT_AFFECTED;
 		}
+		entry += 1;
 	}
 	return ret_val;
 }
diff --git a/services/std_svc/rmmd/rmmd.mk b/services/std_svc/rmmd/rmmd.mk
index bcf54e1b..eae5031f 100644
--- a/services/std_svc/rmmd/rmmd.mk
+++ b/services/std_svc/rmmd/rmmd.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,10 @@ ifneq (${ARCH},aarch64)
         $(error "Error: RMMD is only supported on aarch64.")
 endif
 
-include services/std_svc/rmmd/trp/trp.mk
+# Include TRP makefile only if RMM is not defined.
+ifeq ($(RMM),)
+        include services/std_svc/rmmd/trp/trp.mk
+endif
 
 RMMD_SOURCES	+=	$(addprefix services/std_svc/rmmd/,	\
 			${ARCH}/rmmd_helpers.S			\
diff --git a/services/std_svc/rmmd/rmmd_attest.c b/services/std_svc/rmmd/rmmd_attest.c
index 25adf502..7d4ea701 100644
--- a/services/std_svc/rmmd/rmmd_attest.c
+++ b/services/std_svc/rmmd/rmmd_attest.c
@@ -1,8 +1,10 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include <errno.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -11,7 +13,8 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include "rmmd_private.h"
-#include <services/rmmd_svc.h>
+#include <services/rmm_el3_token_sign.h>
+#include <smccc_helpers.h>
 
 static spinlock_t lock;
 
@@ -85,7 +88,8 @@ static int validate_buffer_params(uint64_t buf_pa, uint64_t buf_len)
 }
 
 int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
-				   uint64_t c_size)
+				   uint64_t c_size,
+				   uint64_t *remaining_len)
 {
 	int err;
 	uint8_t temp_buf[SHA512_DIGEST_SIZE];
@@ -110,9 +114,19 @@ int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
 
 	/* Get the platform token. */
 	err = plat_rmmd_get_cca_attest_token((uintptr_t)buf_pa,
-		buf_size, (uintptr_t)temp_buf, c_size);
+		buf_size, (uintptr_t)temp_buf, c_size, remaining_len);
 
-	if (err != 0) {
+	switch (err) {
+	case 0:
+		err = E_RMM_OK;
+		break;
+	case -EAGAIN:
+		err = E_RMM_AGAIN;
+		break;
+	case -EINVAL:
+		err = E_RMM_INVAL;
+		break;
+	default:
 		ERROR("Failed to get platform token: %d.\n", err);
 		err = E_RMM_UNK;
 	}
@@ -144,10 +158,110 @@ int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
 						 (unsigned int)ecc_curve);
 	if (err != 0) {
 		ERROR("Failed to get attestation key: %d.\n", err);
-		err =  E_RMM_UNK;
+		err = E_RMM_UNK;
 	}
 
 	spin_unlock(&lock);
 
 	return err;
 }
+
+static int rmmd_el3_token_sign_push_req(uint64_t buf_pa, uint64_t buf_size)
+{
+	int err;
+
+	err = validate_buffer_params(buf_pa, buf_size);
+	if (err != 0) {
+		return err;
+	}
+
+	if (buf_size < sizeof(struct el3_token_sign_request)) {
+		return E_RMM_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Call platform port to handle attestation toekn signing request. */
+	err = plat_rmmd_el3_token_sign_push_req((struct el3_token_sign_request *)buf_pa);
+
+	spin_unlock(&lock);
+
+	return err;
+}
+
+static int rmmd_el3_token_sign_pull_resp(uint64_t buf_pa, uint64_t buf_size)
+{
+	int err;
+
+	err = validate_buffer_params(buf_pa, buf_size);
+	if (err != 0) {
+		return err;
+	}
+
+
+	if (buf_size < sizeof(struct el3_token_sign_response)) {
+		return E_RMM_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Pull attestation signing response from HES. */
+	err = plat_rmmd_el3_token_sign_pull_resp(
+			(struct el3_token_sign_response *)buf_pa);
+
+	spin_unlock(&lock);
+
+	return err;
+}
+
+static int rmmd_attest_get_attest_pub_key(uint64_t buf_pa, uint64_t *buf_size,
+				   uint64_t ecc_curve)
+{
+	int err;
+
+	err = validate_buffer_params(buf_pa, *buf_size);
+	if (err != 0) {
+		return err;
+	}
+
+	if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+		ERROR("Invalid ECC curve specified\n");
+		return E_RMM_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Get the Realm attestation public key from platform port. */
+	err = plat_rmmd_el3_token_sign_get_rak_pub(
+		(uintptr_t)buf_pa, buf_size, (unsigned int)ecc_curve);
+
+	spin_unlock(&lock);
+	if (err != 0) {
+		ERROR("Failed to get attestation public key from HES: %d.\n",
+		      err);
+		err = E_RMM_UNK;
+	}
+
+
+	return err;
+}
+
+uint64_t rmmd_el3_token_sign(void *handle, uint64_t opcode, uint64_t x2,
+				    uint64_t x3, uint64_t x4)
+{
+	int ret;
+
+	switch (opcode) {
+	case RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP:
+		ret = rmmd_el3_token_sign_push_req(x2, x3);
+		SMC_RET1(handle, ret);
+	case RMM_EL3_TOKEN_SIGN_PULL_RESP_OP:
+		ret = rmmd_el3_token_sign_pull_resp(x2, x3);
+		SMC_RET1(handle, ret);
+	case RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP:
+		ret = rmmd_attest_get_attest_pub_key(x2, &x3, x4);
+		SMC_RET2(handle, ret, x3);
+	default:
+		SMC_RET1(handle, SMC_UNK);
+	}
+}
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 8b78b135..d063ea34 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -70,7 +70,6 @@ uint64_t rmmd_rmm_sync_entry(rmmd_rmm_context_t *rmm_ctx)
 	cm_set_context(&(rmm_ctx->cpu_ctx), REALM);
 
 	/* Restore the realm context assigned above */
-	cm_el1_sysregs_context_restore(REALM);
 	cm_el2_sysregs_context_restore(REALM);
 	cm_set_next_eret_context(REALM);
 
@@ -78,12 +77,10 @@ uint64_t rmmd_rmm_sync_entry(rmmd_rmm_context_t *rmm_ctx)
 	rc = rmmd_rmm_enter(&rmm_ctx->c_rt_ctx);
 
 	/*
-	 * Save realm context. EL1 and EL2 Non-secure
-	 * contexts will be restored before exiting to
-	 * Non-secure world, therefore there is no need
-	 * to clear EL1 and EL2 context registers.
+	 * Save realm context. EL2 Non-secure context will be restored
+	 * before exiting Non-secure world, therefore there is no need
+	 * to clear EL2 context registers.
 	 */
-	cm_el1_sysregs_context_save(REALM);
 	cm_el2_sysregs_context_save(REALM);
 
 	return rc;
@@ -112,8 +109,8 @@ __dead2 void rmmd_rmm_sync_exit(uint64_t rc)
 
 static void rmm_el2_context_init(el2_sysregs_t *regs)
 {
-	regs->ctx_regs[CTX_SPSR_EL2 >> 3] = REALM_SPSR_EL2;
-	regs->ctx_regs[CTX_SCTLR_EL2 >> 3] = SCTLR_EL2_RES1;
+	write_el2_ctx_common(regs, spsr_el2, REALM_SPSR_EL2);
+	write_el2_ctx_common(regs, sctlr_el2, SCTLR_EL2_RES1);
 }
 
 /*******************************************************************************
@@ -134,6 +131,8 @@ static void manage_extensions_realm(cpu_context_t *ctx)
 
 static void manage_extensions_realm_per_world(void)
 {
+	cm_el3_arch_init_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+
 	if (is_feat_sve_supported()) {
 	/*
 	 * Enable SVE and FPU in realm context when it is enabled for NS.
@@ -203,19 +202,23 @@ int rmmd_setup(void)
 	int rc;
 
 	/* Make sure RME is supported. */
-	assert(get_armv9_2_feat_rme_support() != 0U);
+	if (is_feat_rme_present() == 0U) {
+		/* Mark the RMM boot as failed for all the CPUs */
+		rmm_boot_failed = true;
+		return -ENOTSUP;
+	}
 
 	rmm_ep_info = bl31_plat_get_next_image_ep_info(REALM);
-	if (rmm_ep_info == NULL) {
+	if ((rmm_ep_info == NULL) || (rmm_ep_info->pc == 0)) {
 		WARN("No RMM image provided by BL2 boot loader, Booting "
 		     "device without RMM initialization. SMCs destined for "
 		     "RMM will return SMC_UNK\n");
+
+		/* Mark the boot as failed for all the CPUs */
+		rmm_boot_failed = true;
 		return -ENOENT;
 	}
 
-	/* Under no circumstances will this parameter be 0 */
-	assert(rmm_ep_info->pc == RMM_BASE);
-
 	/* Initialise an entrypoint to set up the CPU context */
 	ep_attr = EP_REALM;
 	if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0U) {
@@ -233,11 +236,15 @@ int rmmd_setup(void)
 	assert((shared_buf_size == SZ_4K) &&
 					((void *)shared_buf_base != NULL));
 
-	/* Load the boot manifest at the beginning of the shared area */
+	/* Zero out and load the boot manifest at the beginning of the share area */
 	manifest = (struct rmm_manifest *)shared_buf_base;
+	(void)memset((void *)manifest, 0, sizeof(struct rmm_manifest));
+
 	rc = plat_rmmd_load_manifest(manifest);
 	if (rc != 0) {
 		ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
+		/* Mark the boot as failed for all the CPUs */
+		rmm_boot_failed = true;
 		return rc;
 	}
 	flush_dcache_range((uintptr_t)shared_buf_base, shared_buf_size);
@@ -277,11 +284,9 @@ static uint64_t	rmmd_smc_forward(uint32_t src_sec_state,
 	cpu_context_t *ctx = cm_get_context(dst_sec_state);
 
 	/* Save incoming security state */
-	cm_el1_sysregs_context_save(src_sec_state);
 	cm_el2_sysregs_context_save(src_sec_state);
 
 	/* Restore outgoing security state */
-	cm_el1_sysregs_context_restore(dst_sec_state);
 	cm_el2_sysregs_context_restore(dst_sec_state);
 	cm_set_next_eret_context(dst_sec_state);
 
@@ -436,6 +441,21 @@ static int gpt_to_gts_error(int error, uint32_t smc_fid, uint64_t address)
 	return ret;
 }
 
+static int rmm_el3_ifc_get_feat_register(uint64_t feat_reg_idx,
+					 uint64_t *feat_reg)
+{
+	if (feat_reg_idx != RMM_EL3_FEAT_REG_0_IDX) {
+		ERROR("RMMD: Failed to get feature register %ld\n", feat_reg_idx);
+		return E_RMM_INVAL;
+	}
+
+	*feat_reg = 0UL;
+#if RMMD_ENABLE_EL3_TOKEN_SIGN
+	*feat_reg |= RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK;
+#endif
+	return E_RMM_OK;
+}
+
 /*******************************************************************************
  * This function handles RMM-EL3 interface SMCs
  ******************************************************************************/
@@ -443,6 +463,7 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 				uint64_t x3, uint64_t x4, void *cookie,
 				void *handle, uint64_t flags)
 {
+	uint64_t remaining_len = 0UL;
 	uint32_t src_sec_state;
 	int ret;
 
@@ -468,12 +489,18 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 		ret = gpt_undelegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
 		SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
 	case RMM_ATTEST_GET_PLAT_TOKEN:
-		ret = rmmd_attest_get_platform_token(x1, &x2, x3);
-		SMC_RET2(handle, ret, x2);
+		ret = rmmd_attest_get_platform_token(x1, &x2, x3, &remaining_len);
+		SMC_RET3(handle, ret, x2, remaining_len);
 	case RMM_ATTEST_GET_REALM_KEY:
 		ret = rmmd_attest_get_signing_key(x1, &x2, x3);
 		SMC_RET2(handle, ret, x2);
-
+	case RMM_EL3_FEATURES:
+		ret = rmm_el3_ifc_get_feat_register(x1, &x2);
+		SMC_RET2(handle, ret, x2);
+#if RMMD_ENABLE_EL3_TOKEN_SIGN
+	case RMM_EL3_TOKEN_SIGN:
+		return rmmd_el3_token_sign(handle, x1, x2, x3, x4);
+#endif
 	case RMM_BOOT_COMPLETE:
 		VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
 		rmmd_rmm_sync_exit(x1);
diff --git a/services/std_svc/rmmd/rmmd_private.h b/services/std_svc/rmmd/rmmd_private.h
index 4954a435..0ce104d0 100644
--- a/services/std_svc/rmmd/rmmd_private.h
+++ b/services/std_svc/rmmd/rmmd_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -47,9 +47,12 @@ __dead2 void rmmd_rmm_sync_exit(uint64_t rc);
 
 /* Functions implementing attestation utilities for RMM */
 int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
-				   uint64_t c_size);
+				   uint64_t c_size,
+				   uint64_t *remaining_len);
 int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
 				uint64_t ecc_curve);
+uint64_t rmmd_el3_token_sign(void *handle, uint64_t x1, uint64_t x2,
+				    uint64_t x3, uint64_t x4);
 
 /* Assembly helpers */
 uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);
diff --git a/services/std_svc/rmmd/trp/trp.mk b/services/std_svc/rmmd/trp/trp.mk
index b7bd3176..bb963431 100644
--- a/services/std_svc/rmmd/trp/trp.mk
+++ b/services/std_svc/rmmd/trp/trp.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2023 Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -10,9 +10,9 @@ RMM_SOURCES		+=	services/std_svc/rmmd/trp/trp_entry.S \
 
 RMM_DEFAULT_LINKER_SCRIPT_SOURCE := services/std_svc/rmmd/trp/linker.ld.S
 
-ifneq ($(findstring gcc,$(notdir $(LD))),)
+ifeq ($($(ARCH)-ld-id),gnu-gcc)
         RMM_LDFLAGS	+=	-Wl,--sort-section=alignment
-else ifneq ($(findstring ld,$(notdir $(LD))),)
+else ifneq ($(filter llvm-lld gnu-ld,$($(ARCH)-ld-id)),)
         RMM_LDFLAGS	+=	--sort-section=alignment
 endif
 
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 33f2fb08..b75483cb 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/build_message.h>
 #include <common/debug.h>
 #include <plat/common/platform.h>
 #include <services/rmm_core_manifest.h>
@@ -86,7 +87,7 @@ int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,
 /* Main function for TRP */
 void trp_main(void)
 {
-	NOTICE("TRP: %s\n", version_string);
+	NOTICE("TRP: %s\n", build_version_string);
 	NOTICE("TRP: %s\n", build_message);
 	NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
 		TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 3bdf4a2b..c58adba5 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <arch_features.h>
 #include <bl31/ehf.h>
 #include <bl31/interrupt_mgmt.h>
+#include <bl31/sync_handle.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -237,9 +238,7 @@ static cpu_context_t *restore_and_resume_ns_context(void)
 /*
  * Prepare for ERET:
  * - Set the ELR to the registered handler address
- * - Set the SPSR register as described in the SDEI documentation and
- *   the AArch64.TakeException() pseudocode function in
- *   ARM DDI 0487F.c page J1-7635
+ * - Set the SPSR register by calling the common create_spsr() function
  */
 
 static void sdei_set_elr_spsr(sdei_entry_t *se, sdei_dispatch_context_t *disp_ctx)
@@ -250,57 +249,7 @@ static void sdei_set_elr_spsr(sdei_entry_t *se, sdei_dispatch_context_t *disp_ct
 
 	u_register_t interrupted_pstate = disp_ctx->spsr_el3;
 
-	/* Check the SPAN bit in the client el SCTLR */
-	u_register_t client_el_sctlr;
-
-	if (client_el == MODE_EL2) {
-		client_el_sctlr = read_sctlr_el2();
-	} else {
-		client_el_sctlr = read_sctlr_el1();
-	}
-
-	/*
-	 * Check whether to force the PAN bit or use the value in the
-	 * interrupted EL according to the check described in
-	 * TakeException. Since the client can only be Non-Secure
-	 * EL2 or El1 some of the conditions in ElIsInHost() we know
-	 * will always be True.
-	 * When the client_el is EL2 we know that there will be a SPAN
-	 * bit in SCTLR_EL2 as we have already checked for the condition
-	 * HCR_EL2.E2H = 1 and HCR_EL2.TGE = 1
-	 */
-	u_register_t hcr_el2 = read_hcr();
-	bool el_is_in_host = (read_feat_vhe_id_field() != 0U) &&
-			     (hcr_el2 & HCR_TGE_BIT) &&
-			     (hcr_el2 & HCR_E2H_BIT);
-
-	if (is_feat_pan_supported() &&
-	    ((client_el == MODE_EL1) ||
-		(client_el == MODE_EL2 && el_is_in_host)) &&
-	    ((client_el_sctlr & SCTLR_SPAN_BIT) == 0U)) {
-		sdei_spsr |=  SPSR_PAN_BIT;
-	} else {
-		sdei_spsr |= (interrupted_pstate & SPSR_PAN_BIT);
-	}
-
-	/* If SSBS is implemented, take the value from the client el SCTLR */
-	u_register_t ssbs_enabled = (read_id_aa64pfr1_el1()
-					>> ID_AA64PFR1_EL1_SSBS_SHIFT)
-					& ID_AA64PFR1_EL1_SSBS_MASK;
-	if (ssbs_enabled != SSBS_UNAVAILABLE) {
-		u_register_t  ssbs_bit = ((client_el_sctlr & SCTLR_DSSBS_BIT)
-						>> SCTLR_DSSBS_SHIFT)
-						<< SPSR_SSBS_SHIFT_AARCH64;
-		sdei_spsr |= ssbs_bit;
-	}
-
-	/* If MTE is implemented in the client el set the TCO bit */
-	if (get_armv8_5_mte_support() >= MTE_IMPLEMENTED_ELX) {
-		sdei_spsr |= SPSR_TCO_BIT_AARCH64;
-	}
-
-	/* Take the DIT field from the pstate of the interrupted el */
-	sdei_spsr |= (interrupted_pstate & SPSR_DIT_BIT);
+	sdei_spsr = create_spsr(interrupted_pstate, client_el);
 
 	cm_set_elr_spsr_el3(NON_SECURE, (uintptr_t) se->ep, sdei_spsr);
 }
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index 59a1673d..01cc1315 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -744,7 +744,9 @@ static int sdei_interrupt_bind(unsigned int intr_num)
 			return SDEI_ENOMEM;
 
 		/* The returned mapping must be dynamic */
-		assert(is_map_dynamic(map));
+		if (!is_map_dynamic(map)) {
+			return SDEI_ENOMEM;
+		}
 
 		/*
 		 * We cannot assert for bound maps here, as we might be racing
diff --git a/services/std_svc/spm/el3_spmc/spmc.h b/services/std_svc/spm/el3_spmc/spmc.h
index 48644ac7..e093a82b 100644
--- a/services/std_svc/spm/el3_spmc/spmc.h
+++ b/services/std_svc/spm/el3_spmc/spmc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -168,6 +168,12 @@ struct secure_partition_desc {
 	/* Mailbox tracking. */
 	struct mailbox mailbox;
 
+	/* Lock to protect the runtime state of a S-EL0 SP execution context. */
+	spinlock_t rt_state_lock;
+
+	/* Pointer to translation table context of a S-EL0 SP. */
+	xlat_ctx_t *xlat_ctx_handle;
+
 	/* Secondary entrypoint. Only valid for a S-EL1 SP. */
 	uintptr_t secondary_ep;
 
@@ -224,6 +230,10 @@ void spmc_el1_sp_setup(struct secure_partition_desc *sp,
 		       entry_point_info_t *ep_info);
 void spmc_sp_common_ep_commit(struct secure_partition_desc *sp,
 			      entry_point_info_t *ep_info);
+void spmc_el0_sp_spsr_setup(entry_point_info_t *ep_info);
+void spmc_el0_sp_setup(struct secure_partition_desc *sp,
+		       int32_t boot_info_reg,
+		       void *sp_manifest);
 
 /*
  * Helper function to perform a synchronous entry into a SP.
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index ada6f455..c6ec30c3 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
 #include <errno.h>
+#include <stdio.h>
 
 #include <arch_helpers.h>
 #include <bl31/bl31.h>
@@ -30,6 +31,17 @@
 
 #include <platform_def.h>
 
+/* FFA_MEM_PERM_* helpers */
+#define FFA_MEM_PERM_MASK		U(7)
+#define FFA_MEM_PERM_DATA_MASK		U(3)
+#define FFA_MEM_PERM_DATA_SHIFT		U(0)
+#define FFA_MEM_PERM_DATA_NA		U(0)
+#define FFA_MEM_PERM_DATA_RW		U(1)
+#define FFA_MEM_PERM_DATA_RES		U(2)
+#define FFA_MEM_PERM_DATA_RO		U(3)
+#define FFA_MEM_PERM_INST_EXEC          (U(0) << 2)
+#define FFA_MEM_PERM_INST_NON_EXEC      (U(1) << 2)
+
 /* Declare the maximum number of SPs and El3 LPs. */
 #define MAX_SP_LP_PARTITIONS SECURE_PARTITION_COUNT + MAX_EL3_LP_DESCS_COUNT
 
@@ -222,7 +234,7 @@ static uint64_t spmc_smc_return(uint32_t smc_fid,
 	/* If we originated in the normal world then switch contexts. */
 	else if (!secure_origin && ffa_is_secure_world_id(dst_id)) {
 		return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2,
-					     x3, x4, handle);
+					     x3, x4, handle, flags);
 	} else {
 		/* Unknown State. */
 		panic();
@@ -390,6 +402,11 @@ static uint64_t direct_req_smc_handler(uint32_t smc_fid,
 					     FFA_ERROR_INVALID_PARAMETER);
 	}
 
+	/* Protect the runtime state of a UP S-EL0 SP with a lock. */
+	if (sp->runtime_el == S_EL0) {
+		spin_lock(&sp->rt_state_lock);
+	}
+
 	/*
 	 * Check that the target execution context is in a waiting state before
 	 * forwarding the direct request to it.
@@ -398,6 +415,11 @@ static uint64_t direct_req_smc_handler(uint32_t smc_fid,
 	if (sp->ec[idx].rt_state != RT_STATE_WAITING) {
 		VERBOSE("SP context on core%u is not waiting (%u).\n",
 			idx, sp->ec[idx].rt_model);
+
+		if (sp->runtime_el == S_EL0) {
+			spin_unlock(&sp->rt_state_lock);
+		}
+
 		return spmc_ffa_error_return(handle, FFA_ERROR_BUSY);
 	}
 
@@ -408,6 +430,11 @@ static uint64_t direct_req_smc_handler(uint32_t smc_fid,
 	sp->ec[idx].rt_state = RT_STATE_RUNNING;
 	sp->ec[idx].rt_model = RT_MODEL_DIR_REQ;
 	sp->ec[idx].dir_req_origin_id = src_id;
+
+	if (sp->runtime_el == S_EL0) {
+		spin_unlock(&sp->rt_state_lock);
+	}
+
 	return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
 			       handle, cookie, flags, dst_id);
 }
@@ -462,6 +489,10 @@ static uint64_t direct_resp_smc_handler(uint32_t smc_fid,
 					     FFA_ERROR_INVALID_PARAMETER);
 	}
 
+	if (sp->runtime_el == S_EL0) {
+		spin_lock(&sp->rt_state_lock);
+	}
+
 	/* Sanity check state is being tracked correctly in the SPMC. */
 	idx = get_ec_index(sp);
 	assert(sp->ec[idx].rt_state == RT_STATE_RUNNING);
@@ -470,12 +501,18 @@ static uint64_t direct_resp_smc_handler(uint32_t smc_fid,
 	if (sp->ec[idx].rt_model != RT_MODEL_DIR_REQ) {
 		VERBOSE("SP context on core%u not handling direct req (%u).\n",
 			idx, sp->ec[idx].rt_model);
+		if (sp->runtime_el == S_EL0) {
+			spin_unlock(&sp->rt_state_lock);
+		}
 		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
 	}
 
 	if (sp->ec[idx].dir_req_origin_id != dst_id) {
 		WARN("Invalid direct resp partition ID 0x%x != 0x%x on core%u.\n",
 		     dst_id, sp->ec[idx].dir_req_origin_id, idx);
+		if (sp->runtime_el == S_EL0) {
+			spin_unlock(&sp->rt_state_lock);
+		}
 		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
 	}
 
@@ -485,6 +522,10 @@ static uint64_t direct_resp_smc_handler(uint32_t smc_fid,
 	/* Clear the ongoing direct request ID. */
 	sp->ec[idx].dir_req_origin_id = INV_SP_ID;
 
+	if (sp->runtime_el == S_EL0) {
+		spin_unlock(&sp->rt_state_lock);
+	}
+
 	/*
 	 * If the receiver is not the SPMC then forward the response to the
 	 * Normal world.
@@ -536,9 +577,15 @@ static uint64_t msg_wait_handler(uint32_t smc_fid,
 	 * Get the execution context of the SP that invoked FFA_MSG_WAIT.
 	 */
 	idx = get_ec_index(sp);
+	if (sp->runtime_el == S_EL0) {
+		spin_lock(&sp->rt_state_lock);
+	}
 
 	/* Ensure SP execution context was in the right runtime model. */
 	if (sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) {
+		if (sp->runtime_el == S_EL0) {
+			spin_unlock(&sp->rt_state_lock);
+		}
 		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
 	}
 
@@ -550,6 +597,9 @@ static uint64_t msg_wait_handler(uint32_t smc_fid,
 	 * state is updated after the exit.
 	 */
 	if (sp->ec[idx].rt_model == RT_MODEL_INIT) {
+		if (sp->runtime_el == S_EL0) {
+			spin_unlock(&sp->rt_state_lock);
+		}
 		spmc_sp_synchronous_exit(&sp->ec[idx], x4);
 		/* Should not get here */
 		panic();
@@ -567,9 +617,19 @@ static uint64_t msg_wait_handler(uint32_t smc_fid,
 		cm_el1_sysregs_context_save(secure_state_in);
 		cm_el1_sysregs_context_restore(secure_state_out);
 		cm_set_next_eret_context(secure_state_out);
+
+		if (sp->runtime_el == S_EL0) {
+			spin_unlock(&sp->rt_state_lock);
+		}
+
 		SMC_RET0(cm_get_context(secure_state_out));
 	}
 
+	/* Protect the runtime state of a S-EL0 SP with a lock. */
+	if (sp->runtime_el == S_EL0) {
+		spin_unlock(&sp->rt_state_lock);
+	}
+
 	/* Forward the response to the Normal world. */
 	return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4,
 			       handle, cookie, flags, FFA_NWD_ID);
@@ -1231,6 +1291,8 @@ static uint64_t ffa_features_handler(uint32_t smc_fid,
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
 	case FFA_MEM_RELINQUISH:
 	case FFA_MSG_WAIT:
+	case FFA_CONSOLE_LOG_SMC32:
+	case FFA_CONSOLE_LOG_SMC64:
 
 		if (!secure_origin) {
 			return spmc_ffa_error_return(handle,
@@ -1343,14 +1405,21 @@ static uint64_t ffa_run_handler(uint32_t smc_fid,
 	}
 
 	idx = get_ec_index(sp);
+
 	if (idx != vcpu_id) {
 		ERROR("Cannot run vcpu %d != %d.\n", idx, vcpu_id);
 		return spmc_ffa_error_return(handle,
 					     FFA_ERROR_INVALID_PARAMETER);
 	}
+	if (sp->runtime_el == S_EL0) {
+		spin_lock(&sp->rt_state_lock);
+	}
 	rt_state = &((sp->ec[idx]).rt_state);
 	rt_model = &((sp->ec[idx]).rt_model);
 	if (*rt_state == RT_STATE_RUNNING) {
+		if (sp->runtime_el == S_EL0) {
+			spin_unlock(&sp->rt_state_lock);
+		}
 		ERROR("Partition (0x%x) is already running.\n", target_id);
 		return spmc_ffa_error_return(handle, FFA_ERROR_BUSY);
 	}
@@ -1377,6 +1446,10 @@ static uint64_t ffa_run_handler(uint32_t smc_fid,
 	 */
 	*rt_state = RT_STATE_RUNNING;
 
+	if (sp->runtime_el == S_EL0) {
+		spin_unlock(&sp->rt_state_lock);
+	}
+
 	return spmc_smc_return(smc_fid, secure_origin, x1, 0, 0, 0,
 			       handle, cookie, flags, target_id);
 }
@@ -1406,6 +1479,58 @@ static uint64_t rx_release_handler(uint32_t smc_fid,
 	SMC_RET1(handle, FFA_SUCCESS_SMC32);
 }
 
+static uint64_t spmc_ffa_console_log(uint32_t smc_fid,
+				     bool secure_origin,
+				     uint64_t x1,
+				     uint64_t x2,
+				     uint64_t x3,
+				     uint64_t x4,
+				     void *cookie,
+				     void *handle,
+				     uint64_t flags)
+{
+	/* Maximum number of characters is 48: 6 registers of 8 bytes each. */
+	char chars[48] = {0};
+	size_t chars_max;
+	size_t chars_count = x1;
+
+	/* Does not support request from Nwd. */
+	if (!secure_origin) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+	}
+
+	assert(smc_fid == FFA_CONSOLE_LOG_SMC32 || smc_fid == FFA_CONSOLE_LOG_SMC64);
+	if (smc_fid == FFA_CONSOLE_LOG_SMC32) {
+		uint32_t *registers = (uint32_t *)chars;
+		registers[0] = (uint32_t)x2;
+		registers[1] = (uint32_t)x3;
+		registers[2] = (uint32_t)x4;
+		registers[3] = (uint32_t)SMC_GET_GP(handle, CTX_GPREG_X5);
+		registers[4] = (uint32_t)SMC_GET_GP(handle, CTX_GPREG_X6);
+		registers[5] = (uint32_t)SMC_GET_GP(handle, CTX_GPREG_X7);
+		chars_max = 6 * sizeof(uint32_t);
+	} else {
+		uint64_t *registers = (uint64_t *)chars;
+		registers[0] = x2;
+		registers[1] = x3;
+		registers[2] = x4;
+		registers[3] = SMC_GET_GP(handle, CTX_GPREG_X5);
+		registers[4] = SMC_GET_GP(handle, CTX_GPREG_X6);
+		registers[5] = SMC_GET_GP(handle, CTX_GPREG_X7);
+		chars_max = 6 * sizeof(uint64_t);
+	}
+
+	if ((chars_count == 0) || (chars_count > chars_max)) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	for (size_t i = 0; (i < chars_count) && (chars[i] != '\0'); i++) {
+		putchar(chars[i]);
+	}
+
+	SMC_RET1(handle, FFA_SUCCESS_SMC32);
+}
+
 /*
  * Perform initial validation on the provided secondary entry point.
  * For now ensure it does not lie within the BL31 Image or the SP's
@@ -1504,6 +1629,223 @@ static uint64_t ffa_sec_ep_register_handler(uint32_t smc_fid,
 	SMC_RET1(handle, FFA_SUCCESS_SMC32);
 }
 
+/*******************************************************************************
+ * Permissions are encoded using a different format in the FFA_MEM_PERM_* ABIs
+ * than in the Trusted Firmware, where the mmap_attr_t enum type is used. This
+ * function converts a permission value from the FF-A format to the mmap_attr_t
+ * format by setting MT_RW/MT_RO, MT_USER/MT_PRIVILEGED and
+ * MT_EXECUTE/MT_EXECUTE_NEVER. The other fields are left as 0 because they are
+ * ignored by the function xlat_change_mem_attributes_ctx().
+ ******************************************************************************/
+static unsigned int ffa_perm_to_mmap_perm(unsigned int perms)
+{
+	unsigned int tf_attr = 0U;
+	unsigned int access;
+
+	/* Deal with data access permissions first. */
+	access = (perms & FFA_MEM_PERM_DATA_MASK) >> FFA_MEM_PERM_DATA_SHIFT;
+
+	switch (access) {
+	case FFA_MEM_PERM_DATA_RW:
+		/* Return 0 if the execute is set with RW. */
+		if ((perms & FFA_MEM_PERM_INST_NON_EXEC) != 0) {
+			tf_attr |= MT_RW | MT_USER | MT_EXECUTE_NEVER;
+		}
+		break;
+
+	case FFA_MEM_PERM_DATA_RO:
+		tf_attr |= MT_RO | MT_USER;
+		/* Deal with the instruction access permissions next. */
+		if ((perms & FFA_MEM_PERM_INST_NON_EXEC) == 0) {
+			tf_attr |= MT_EXECUTE;
+		} else {
+			tf_attr |= MT_EXECUTE_NEVER;
+		}
+		break;
+
+	case FFA_MEM_PERM_DATA_NA:
+	default:
+		return tf_attr;
+	}
+
+	return tf_attr;
+}
+
+/*******************************************************************************
+ * Handler to set the permissions of a set of contiguous pages of a S-EL0 SP
+ ******************************************************************************/
+static uint64_t ffa_mem_perm_set_handler(uint32_t smc_fid,
+					 bool secure_origin,
+					 uint64_t x1,
+					 uint64_t x2,
+					 uint64_t x3,
+					 uint64_t x4,
+					 void *cookie,
+					 void *handle,
+					 uint64_t flags)
+{
+	struct secure_partition_desc *sp;
+	unsigned int idx;
+	uintptr_t base_va = (uintptr_t) x1;
+	size_t size = (size_t)(x2 * PAGE_SIZE);
+	uint32_t tf_attr;
+	int ret;
+
+	/* This request cannot originate from the Normal world. */
+	if (!secure_origin) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+	}
+
+	if (size == 0) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Get the context of the current SP. */
+	sp = spmc_get_current_sp_ctx();
+	if (sp == NULL) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* A S-EL1 SP has no business invoking this ABI. */
+	if (sp->runtime_el == S_EL1) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
+	if ((x3 & ~((uint64_t)FFA_MEM_PERM_MASK)) != 0) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Get the execution context of the calling SP. */
+	idx = get_ec_index(sp);
+
+	/*
+	 * Ensure that the S-EL0 SP is initialising itself. We do not need to
+	 * synchronise this operation through a spinlock since a S-EL0 SP is UP
+	 * and can only be initialising on this cpu.
+	 */
+	if (sp->ec[idx].rt_model != RT_MODEL_INIT) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
+	VERBOSE("Setting memory permissions:\n");
+	VERBOSE("  Start address  : 0x%lx\n", base_va);
+	VERBOSE("  Number of pages: %lu (%zu bytes)\n", x2, size);
+	VERBOSE("  Attributes     : 0x%x\n", (uint32_t)x3);
+
+	/* Convert inbound permissions to TF-A permission attributes */
+	tf_attr = ffa_perm_to_mmap_perm((unsigned int)x3);
+	if (tf_attr == 0U) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Request the change in permissions */
+	ret = xlat_change_mem_attributes_ctx(sp->xlat_ctx_handle,
+					     base_va, size, tf_attr);
+	if (ret != 0) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	SMC_RET1(handle, FFA_SUCCESS_SMC32);
+}
+
+/*******************************************************************************
+ * Permissions are encoded using a different format in the FFA_MEM_PERM_* ABIs
+ * than in the Trusted Firmware, where the mmap_attr_t enum type is used. This
+ * function converts a permission value from the mmap_attr_t format to the FF-A
+ * format.
+ ******************************************************************************/
+static unsigned int mmap_perm_to_ffa_perm(unsigned int attr)
+{
+	unsigned int perms = 0U;
+	unsigned int data_access;
+
+	if ((attr & MT_USER) == 0) {
+		/* No access from EL0. */
+		data_access = FFA_MEM_PERM_DATA_NA;
+	} else {
+		if ((attr & MT_RW) != 0) {
+			data_access = FFA_MEM_PERM_DATA_RW;
+		} else {
+			data_access = FFA_MEM_PERM_DATA_RO;
+		}
+	}
+
+	perms |= (data_access & FFA_MEM_PERM_DATA_MASK)
+		<< FFA_MEM_PERM_DATA_SHIFT;
+
+	if ((attr & MT_EXECUTE_NEVER) != 0U) {
+		perms |= FFA_MEM_PERM_INST_NON_EXEC;
+	}
+
+	return perms;
+}
+
+/*******************************************************************************
+ * Handler to get the permissions of a set of contiguous pages of a S-EL0 SP
+ ******************************************************************************/
+static uint64_t ffa_mem_perm_get_handler(uint32_t smc_fid,
+					 bool secure_origin,
+					 uint64_t x1,
+					 uint64_t x2,
+					 uint64_t x3,
+					 uint64_t x4,
+					 void *cookie,
+					 void *handle,
+					 uint64_t flags)
+{
+	struct secure_partition_desc *sp;
+	unsigned int idx;
+	uintptr_t base_va = (uintptr_t)x1;
+	uint32_t tf_attr = 0;
+	int ret;
+
+	/* This request cannot originate from the Normal world. */
+	if (!secure_origin) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+	}
+
+	/* Get the context of the current SP. */
+	sp = spmc_get_current_sp_ctx();
+	if (sp == NULL) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* A S-EL1 SP has no business invoking this ABI. */
+	if (sp->runtime_el == S_EL1) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
+	/* Get the execution context of the calling SP. */
+	idx = get_ec_index(sp);
+
+	/*
+	 * Ensure that the S-EL0 SP is initialising itself. We do not need to
+	 * synchronise this operation through a spinlock since a S-EL0 SP is UP
+	 * and can only be initialising on this cpu.
+	 */
+	if (sp->ec[idx].rt_model != RT_MODEL_INIT) {
+		return spmc_ffa_error_return(handle, FFA_ERROR_DENIED);
+	}
+
+	/* Request the permissions */
+	ret = xlat_get_mem_attributes_ctx(sp->xlat_ctx_handle, base_va, &tf_attr);
+	if (ret != 0) {
+		return spmc_ffa_error_return(handle,
+					     FFA_ERROR_INVALID_PARAMETER);
+	}
+
+	/* Convert TF-A permission to FF-A permissions attributes. */
+	x2 = mmap_perm_to_ffa_perm(tf_attr);
+
+	SMC_RET3(handle, FFA_SUCCESS_SMC32, 0, x2);
+}
+
 /*******************************************************************************
  * This function will parse the Secure Partition Manifest. From manifest, it
  * will fetch details for preparing Secure partition image context and secure
@@ -1588,7 +1930,7 @@ static int sp_manifest_parse(void *sp_manifest, int offset,
 	 * since this is currently a hardcoded value for S-EL1 partitions
 	 * we don't need to save it here, just validate.
 	 */
-	if (config_32 != PLATFORM_CORE_COUNT) {
+	if ((sp->runtime_el == S_EL1) && (config_32 != PLATFORM_CORE_COUNT)) {
 		ERROR("SP Execution Context Count (%u) must be %u.\n",
 			config_32, PLATFORM_CORE_COUNT);
 		return -EINVAL;
@@ -1615,6 +1957,11 @@ static int sp_manifest_parse(void *sp_manifest, int offset,
 	if (ret != 0) {
 		WARN("Missing Power Management Messages entry.\n");
 	} else {
+		if ((sp->runtime_el == S_EL0) && (config_32 != 0)) {
+			ERROR("Power messages not supported for S-EL0 SP\n");
+			return -EINVAL;
+		}
+
 		/*
 		 * Ensure only the currently supported power messages have
 		 * been requested.
@@ -1704,7 +2051,8 @@ static int find_and_prepare_sp_context(void)
 	 * the manifest as boot information later.
 	 */
 	next_image_ep_info->args.arg1 = fdt_totalsize(sp_manifest);
-	INFO("Manifest size = %lu bytes.\n", next_image_ep_info->args.arg1);
+	INFO("Manifest adr = %lx , size = %lu bytes\n", manifest_base,
+	     next_image_ep_info->args.arg1);
 
 	/*
 	 * Select an SP descriptor for initialising the partition's execution
@@ -1712,6 +2060,11 @@ static int find_and_prepare_sp_context(void)
 	 */
 	sp = spmc_get_current_sp_ctx();
 
+#if SPMC_AT_EL3_SEL0_SP
+	/* Assign translation tables context. */
+	sp_desc->xlat_ctx_handle = spm_get_sp_xlat_context();
+
+#endif /* SPMC_AT_EL3_SEL0_SP */
 	/* Initialize entry point information for the SP */
 	SET_PARAM_HEAD(next_image_ep_info, PARAM_EP, VERSION_1,
 		       SECURE | EP_ST_ENABLE);
@@ -1725,7 +2078,7 @@ static int find_and_prepare_sp_context(void)
 	}
 
 	/* Check that the runtime EL in the manifest was correct. */
-	if (sp->runtime_el != S_EL1) {
+	if (sp->runtime_el != S_EL0 && sp->runtime_el != S_EL1) {
 		ERROR("Unexpected runtime EL: %d\n", sp->runtime_el);
 		return -EINVAL;
 	}
@@ -1734,11 +2087,29 @@ static int find_and_prepare_sp_context(void)
 	spmc_sp_common_setup(sp, next_image_ep_info, boot_info_reg);
 
 	/* Perform any initialisation specific to S-EL1 SPs. */
-	spmc_el1_sp_setup(sp, next_image_ep_info);
+	if (sp->runtime_el == S_EL1) {
+		spmc_el1_sp_setup(sp, next_image_ep_info);
+	}
+
+#if SPMC_AT_EL3_SEL0_SP
+	/* Setup spsr in endpoint info for common context management routine. */
+	if (sp->runtime_el == S_EL0) {
+		spmc_el0_sp_spsr_setup(next_image_ep_info);
+	}
+#endif /* SPMC_AT_EL3_SEL0_SP */
 
 	/* Initialize the SP context with the required ep info. */
 	spmc_sp_common_ep_commit(sp, next_image_ep_info);
 
+#if SPMC_AT_EL3_SEL0_SP
+	/*
+	 * Perform any initialisation specific to S-EL0 not set by common
+	 * context management routine.
+	 */
+	if (sp->runtime_el == S_EL0) {
+		spmc_el0_sp_setup(sp, boot_info_reg, sp_manifest);
+	}
+#endif /* SPMC_AT_EL3_SEL0_SP */
 	return 0;
 }
 
@@ -2049,7 +2420,19 @@ uint64_t spmc_smc_handler(uint32_t smc_fid,
 
 	case FFA_MEM_RECLAIM:
 		return spmc_ffa_mem_reclaim(smc_fid, secure_origin, x1, x2, x3,
-					    x4, cookie, handle, flags);
+						x4, cookie, handle, flags);
+	case FFA_CONSOLE_LOG_SMC32:
+	case FFA_CONSOLE_LOG_SMC64:
+		return spmc_ffa_console_log(smc_fid, secure_origin, x1, x2, x3,
+						x4, cookie, handle, flags);
+
+	case FFA_MEM_PERM_GET:
+		return ffa_mem_perm_get_handler(smc_fid, secure_origin, x1, x2,
+						x3, x4, cookie, handle, flags);
+
+	case FFA_MEM_PERM_SET:
+		return ffa_mem_perm_set_handler(smc_fid, secure_origin, x1, x2,
+						x3, x4, cookie, handle, flags);
 
 	default:
 		WARN("Unsupported FF-A call 0x%08x.\n", smc_fid);
@@ -2104,9 +2487,11 @@ static uint64_t spmc_sp_interrupt_handler(uint32_t id,
 	/*
 	 * Forward the interrupt to the S-EL1 SP. The interrupt ID is not
 	 * populated as the SP can determine this by itself.
+	 * The flags field is forced to 0 mainly to pass the SVE hint bit
+	 * cleared for consumption by the lower EL.
 	 */
 	return spmd_smc_switch_state(FFA_INTERRUPT, false,
 				     FFA_PARAM_MBZ, FFA_PARAM_MBZ,
 				     FFA_PARAM_MBZ, FFA_PARAM_MBZ,
-				     handle);
+				     handle, 0ULL);
 }
diff --git a/services/std_svc/spm/el3_spmc/spmc_pm.c b/services/std_svc/spm/el3_spmc/spmc_pm.c
index c7e864f3..517d6d5e 100644
--- a/services/std_svc/spm/el3_spmc/spmc_pm.c
+++ b/services/std_svc/spm/el3_spmc/spmc_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,7 +36,7 @@ static void spmc_build_pm_message(gp_regs_t *gpregs,
 }
 
 /*******************************************************************************
- * This CPU has been turned on. Enter the SP to initialise S-EL1.
+ * This CPU has been turned on. Enter the SP to initialise S-EL0 or S-EL1.
  ******************************************************************************/
 static void spmc_cpu_on_finish_handler(u_register_t unused)
 {
@@ -49,6 +49,19 @@ static void spmc_cpu_on_finish_handler(u_register_t unused)
 	/* Sanity check for a NULL pointer dereference. */
 	assert(sp != NULL);
 
+	/* Obtain a reference to the SP execution context */
+	ec = &sp->ec[get_ec_index(sp)];
+
+	/*
+	 * In case of a S-EL0 SP, only initialise the context data structure for
+	 * the secure world on this cpu and return.
+	 */
+	if (sp->runtime_el == S_EL0) {
+		/* Assign the context of the SP to this CPU */
+		cm_set_context(&(ec->cpu_ctx), SECURE);
+		return;
+	}
+
 	/* Initialize entry point information for the SP. */
 	SET_PARAM_HEAD(&sec_ec_ep_info, PARAM_EP, VERSION_1,
 		       SECURE | EP_ST_ENABLE);
diff --git a/services/std_svc/spm/el3_spmc/spmc_setup.c b/services/std_svc/spm/el3_spmc/spmc_setup.c
index 6de25f64..f7357f1f 100644
--- a/services/std_svc/spm/el3_spmc/spmc_setup.c
+++ b/services/std_svc/spm/el3_spmc/spmc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,6 +20,7 @@
 #include <plat/common/platform.h>
 #include <services/ffa_svc.h>
 #include "spm_common.h"
+#include "spm_shim_private.h"
 #include "spmc.h"
 #include <tools_share/firmware_image_package.h>
 
@@ -30,6 +31,26 @@
  */
 static uint8_t ffa_boot_info_mem[PAGE_SIZE] __aligned(PAGE_SIZE);
 
+/*
+ * We need to choose one execution context from all those available for a S-EL0
+ * SP. This execution context will be used subsequently irrespective of which
+ * physical CPU the SP runs on.
+ */
+#define SEL0_SP_EC_INDEX 0
+#define SP_MEM_READ 0x1
+#define SP_MEM_WRITE 0x2
+#define SP_MEM_EXECUTE 0x4
+#define SP_MEM_NON_SECURE 0x8
+#define SP_MEM_READ_ONLY SP_MEM_READ
+#define SP_MEM_READ_WRITE (SP_MEM_READ | SP_MEM_WRITE)
+
+/* Type of the memory region in SP's manifest. */
+enum sp_memory_region_type {
+	SP_MEM_REGION_DEVICE,
+	SP_MEM_REGION_MEMORY,
+	SP_MEM_REGION_NOT_SPECIFIED
+};
+
 /*
  * This function creates a initialization descriptor in the memory reserved
  * for passing boot information to an SP. It then copies the partition manifest
@@ -143,14 +164,310 @@ static void spmc_create_boot_info(entry_point_info_t *ep_info,
 }
 
 /*
- * We are assuming that the index of the execution
- * context used is the linear index of the current physical cpu.
+ * S-EL1 partitions can be assigned with multiple execution contexts, each
+ * pinned to the physical CPU. Each execution context index corresponds to the
+ * respective liner core position.
+ * S-EL0 partitions execute in a single execution context (index 0).
  */
 unsigned int get_ec_index(struct secure_partition_desc *sp)
 {
-	return plat_my_core_pos();
+	return (sp->runtime_el == S_EL0) ?
+		SEL0_SP_EC_INDEX : plat_my_core_pos();
+}
+
+#if SPMC_AT_EL3_SEL0_SP
+/* Setup spsr in entry point info for common context management code to use. */
+void spmc_el0_sp_spsr_setup(entry_point_info_t *ep_info)
+{
+	/* Setup Secure Partition SPSR for S-EL0 SP. */
+	ep_info->spsr = SPSR_64(MODE_EL0, MODE_SP_EL0, DISABLE_ALL_EXCEPTIONS);
+}
+
+static void read_optional_string(void *manifest, int32_t offset,
+				 char *property, char *out, size_t len)
+{
+	const fdt32_t *prop;
+	int lenp;
+
+	prop = fdt_getprop(manifest, offset, property, &lenp);
+	if (prop == NULL) {
+		out[0] = '\0';
+	} else {
+		memcpy(out, prop, MIN(lenp, (int)len));
+	}
+}
+
+/*******************************************************************************
+ * This function will parse the Secure Partition Manifest for fetching secure
+ * partition specific memory/device region details. It will find base address,
+ * size, memory attributes for each region and then add the respective region
+ * into secure parition's translation context.
+ ******************************************************************************/
+static void populate_sp_regions(struct secure_partition_desc *sp,
+				void *sp_manifest, int node,
+				enum sp_memory_region_type type)
+{
+	uintptr_t base_address;
+	uint32_t mem_attr, mem_region, size;
+	struct mmap_region sp_mem_regions = {0};
+	int32_t offset, ret;
+	char *compatibility[SP_MEM_REGION_NOT_SPECIFIED] = {
+		"arm,ffa-manifest-device-regions",
+		"arm,ffa-manifest-memory-regions"
+	};
+	char description[10];
+	char *property;
+	char *region[SP_MEM_REGION_NOT_SPECIFIED] = {
+		"device regions",
+		"memory regions"
+	};
+
+	if (type >= SP_MEM_REGION_NOT_SPECIFIED) {
+		WARN("Invalid region type\n");
+		return;
+	}
+
+	INFO("Mapping SP's %s\n", region[type]);
+
+	if (fdt_node_check_compatible(sp_manifest, node,
+				      compatibility[type]) != 0) {
+		WARN("Incompatible region node in manifest\n");
+		return;
+	}
+
+	for (offset = fdt_first_subnode(sp_manifest, node), mem_region = 0;
+	     offset >= 0;
+	     offset = fdt_next_subnode(sp_manifest, offset), mem_region++) {
+		read_optional_string(sp_manifest, offset, "description",
+				     description, sizeof(description));
+
+		INFO("Mapping: region: %d, %s\n", mem_region, description);
+
+		property = "base-address";
+		ret = fdt_read_uint64(sp_manifest, offset, property,
+					&base_address);
+		if (ret < 0) {
+			WARN("Missing:%s for %s.\n", property, description);
+			continue;
+		}
+
+		property = "pages-count";
+		ret = fdt_read_uint32(sp_manifest, offset, property, &size);
+		if (ret < 0) {
+			WARN("Missing: %s for %s.\n", property, description);
+			continue;
+		}
+		size *= PAGE_SIZE;
+
+		property = "attributes";
+		ret = fdt_read_uint32(sp_manifest, offset, property, &mem_attr);
+		if (ret < 0) {
+			WARN("Missing: %s for %s.\n", property, description);
+			continue;
+		}
+
+		sp_mem_regions.attr = MT_USER;
+		if (type == SP_MEM_REGION_DEVICE) {
+			sp_mem_regions.attr |= MT_EXECUTE_NEVER;
+		} else {
+			sp_mem_regions.attr |= MT_MEMORY;
+			if ((mem_attr & SP_MEM_EXECUTE) == SP_MEM_EXECUTE) {
+				sp_mem_regions.attr &= ~MT_EXECUTE_NEVER;
+			} else {
+				sp_mem_regions.attr |= MT_EXECUTE_NEVER;
+			}
+		}
+
+		if ((mem_attr & SP_MEM_READ_WRITE) == SP_MEM_READ_WRITE) {
+			sp_mem_regions.attr |= MT_RW;
+		}
+
+		if ((mem_attr & SP_MEM_NON_SECURE) == SP_MEM_NON_SECURE) {
+			sp_mem_regions.attr |= MT_NS;
+		} else {
+			sp_mem_regions.attr |= MT_SECURE;
+		}
+
+		sp_mem_regions.base_pa = base_address;
+		sp_mem_regions.base_va = base_address;
+		sp_mem_regions.size = size;
+
+		INFO("Adding PA: 0x%llx VA: 0x%lx Size: 0x%lx attr:0x%x\n",
+		     sp_mem_regions.base_pa,
+		     sp_mem_regions.base_va,
+		     sp_mem_regions.size,
+		     sp_mem_regions.attr);
+
+		if (type == SP_MEM_REGION_DEVICE) {
+			sp_mem_regions.granularity = XLAT_BLOCK_SIZE(1);
+		} else {
+			sp_mem_regions.granularity = XLAT_BLOCK_SIZE(3);
+		}
+		mmap_add_region_ctx(sp->xlat_ctx_handle, &sp_mem_regions);
+	}
+}
+
+static void spmc_el0_sp_setup_mmu(struct secure_partition_desc *sp,
+				  cpu_context_t *ctx)
+{
+	xlat_ctx_t *xlat_ctx;
+	uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
+
+	xlat_ctx = sp->xlat_ctx_handle;
+	init_xlat_tables_ctx(sp->xlat_ctx_handle);
+	setup_mmu_cfg((uint64_t *)&mmu_cfg_params, 0, xlat_ctx->base_table,
+		      xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
+		      EL1_EL0_REGIME);
+
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), mair_el1,
+		      mmu_cfg_params[MMU_CFG_MAIR]);
+
+	write_ctx_tcr_el1_reg_errata(ctx, mmu_cfg_params[MMU_CFG_TCR]);
+
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), ttbr0_el1,
+		      mmu_cfg_params[MMU_CFG_TTBR0]);
+}
+
+static void spmc_el0_sp_setup_sctlr_el1(cpu_context_t *ctx)
+{
+	u_register_t sctlr_el1_val;
+
+	/* Setup SCTLR_EL1 */
+	sctlr_el1_val = read_ctx_sctlr_el1_reg_errata(ctx);
+
+	sctlr_el1_val |=
+		/*SCTLR_EL1_RES1 |*/
+		/* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */
+		SCTLR_UCI_BIT |
+		/* RW regions at xlat regime EL1&0 are forced to be XN. */
+		SCTLR_WXN_BIT |
+		/* Don't trap to EL1 execution of WFI or WFE at EL0. */
+		SCTLR_NTWI_BIT | SCTLR_NTWE_BIT |
+		/* Don't trap to EL1 accesses to CTR_EL0 from EL0. */
+		SCTLR_UCT_BIT |
+		/* Don't trap to EL1 execution of DZ ZVA at EL0. */
+		SCTLR_DZE_BIT |
+		/* Enable SP Alignment check for EL0 */
+		SCTLR_SA0_BIT |
+		/* Don't change PSTATE.PAN on taking an exception to EL1 */
+		SCTLR_SPAN_BIT |
+		/* Allow cacheable data and instr. accesses to normal memory. */
+		SCTLR_C_BIT | SCTLR_I_BIT |
+		/* Enable MMU. */
+		SCTLR_M_BIT;
+
+	sctlr_el1_val &= ~(
+		/* Explicit data accesses at EL0 are little-endian. */
+		SCTLR_E0E_BIT |
+		/*
+		 * Alignment fault checking disabled when at EL1 and EL0 as
+		 * the UEFI spec permits unaligned accesses.
+		 */
+		SCTLR_A_BIT |
+		/* Accesses to DAIF from EL0 are trapped to EL1. */
+		SCTLR_UMA_BIT
+	);
+
+	/* Store the initialised SCTLR_EL1 value in the cpu_context */
+	write_ctx_sctlr_el1_reg_errata(ctx, sctlr_el1_val);
 }
 
+static void spmc_el0_sp_setup_system_registers(struct secure_partition_desc *sp,
+					       cpu_context_t *ctx)
+{
+
+	spmc_el0_sp_setup_mmu(sp, ctx);
+
+	spmc_el0_sp_setup_sctlr_el1(ctx);
+
+	/* Setup other system registers. */
+
+	/* Shim Exception Vector Base Address */
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), vbar_el1,
+			SPM_SHIM_EXCEPTIONS_PTR);
+#if NS_TIMER_SWITCH
+	write_el1_ctx_arch_timer(get_el1_sysregs_ctx(ctx), cntkctl_el1,
+		      EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT);
+#endif
+
+	/*
+	 * FPEN: Allow the Secure Partition to access FP/SIMD registers.
+	 * Note that SPM will not do any saving/restoring of these registers on
+	 * behalf of the SP. This falls under the SP's responsibility.
+	 * TTA: Enable access to trace registers.
+	 * ZEN (v8.2): Trap SVE instructions and access to SVE registers.
+	 */
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cpacr_el1,
+			CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
+}
+
+/* Setup context of an EL0 Secure Partition.  */
+void spmc_el0_sp_setup(struct secure_partition_desc *sp,
+		       int32_t boot_info_reg,
+		       void *sp_manifest)
+{
+	mmap_region_t sel1_exception_vectors =
+		MAP_REGION_FLAT(SPM_SHIM_EXCEPTIONS_START,
+				SPM_SHIM_EXCEPTIONS_SIZE,
+				MT_CODE | MT_SECURE | MT_PRIVILEGED);
+	cpu_context_t *ctx;
+	int node;
+	int offset = 0;
+
+	ctx = &sp->ec[SEL0_SP_EC_INDEX].cpu_ctx;
+
+	sp->xlat_ctx_handle->xlat_regime = EL1_EL0_REGIME;
+
+	/* This region contains the exception vectors used at S-EL1. */
+	mmap_add_region_ctx(sp->xlat_ctx_handle,
+			    &sel1_exception_vectors);
+
+	/*
+	 * If the SP manifest specified the register to pass the address of the
+	 * boot information, then map the memory region to pass boot
+	 * information.
+	 */
+	if (boot_info_reg >= 0) {
+		mmap_region_t ffa_boot_info_region = MAP_REGION_FLAT(
+			(uintptr_t) ffa_boot_info_mem,
+			PAGE_SIZE,
+			MT_RO_DATA | MT_SECURE | MT_USER);
+		mmap_add_region_ctx(sp->xlat_ctx_handle, &ffa_boot_info_region);
+	}
+
+	/*
+	 * Parse the manifest for any device regions that the SP wants to be
+	 * mapped in its translation regime.
+	 */
+	node = fdt_subnode_offset_namelen(sp_manifest, offset,
+					  "device-regions",
+					  sizeof("device-regions") - 1);
+	if (node < 0) {
+		WARN("Not found device-region configuration for SP.\n");
+	} else {
+		populate_sp_regions(sp, sp_manifest, node,
+				    SP_MEM_REGION_DEVICE);
+	}
+
+	/*
+	 * Parse the manifest for any memory regions that the SP wants to be
+	 * mapped in its translation regime.
+	 */
+	node = fdt_subnode_offset_namelen(sp_manifest, offset,
+					  "memory-regions",
+					  sizeof("memory-regions") - 1);
+	if (node < 0) {
+		WARN("Not found memory-region configuration for SP.\n");
+	} else {
+		populate_sp_regions(sp, sp_manifest, node,
+				    SP_MEM_REGION_MEMORY);
+	}
+
+	spmc_el0_sp_setup_system_registers(sp, ctx);
+
+}
+#endif /* SPMC_AT_EL3_SEL0_SP */
+
 /* S-EL1 partition specific initialisation. */
 void spmc_el1_sp_setup(struct secure_partition_desc *sp,
 		       entry_point_info_t *ep_info)
@@ -211,12 +528,6 @@ void spmc_sp_common_setup(struct secure_partition_desc *sp,
 		sp->sp_id = sp_id;
 	}
 
-	/*
-	 * We currently only support S-EL1 partitions so ensure this is the
-	 * case.
-	 */
-	assert(sp->runtime_el == S_EL1);
-
 	/* Check if the SP wants to use the FF-A boot protocol. */
 	if (boot_info_reg >= 0) {
 		/*
diff --git a/services/std_svc/spm/spm_mm/spm_mm_main.c b/services/std_svc/spm/spm_mm/spm_mm_main.c
index 1ff7bb77..34e2c00f 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_main.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,7 @@
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/el3_runtime/simd_ctx.h>
 #include <lib/smccc.h>
 #include <lib/spinlock.h>
 #include <lib/utils.h>
@@ -190,13 +191,13 @@ uint64_t spm_mm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3)
 	uint64_t rc;
 	sp_context_t *sp_ptr = &sp_ctx;
 
-#if CTX_INCLUDE_FPREGS
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
 	/*
-	 * SP runs to completion, no need to restore FP registers of secure context.
-	 * Save FP registers only for non secure context.
+	 * SP runs to completion, no need to restore FP/SVE registers of secure context.
+	 * Save FP/SVE registers only for non secure context.
 	 */
-	fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
-#endif
+	simd_ctx_save(NON_SECURE, false);
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
 
 	/* Wait until the Secure Partition is idle and set it to busy. */
 	sp_state_wait_switch(sp_ptr, SP_STATE_IDLE, SP_STATE_BUSY);
@@ -216,13 +217,13 @@ uint64_t spm_mm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3)
 	assert(sp_ptr->state == SP_STATE_BUSY);
 	sp_state_set(sp_ptr, SP_STATE_IDLE);
 
-#if CTX_INCLUDE_FPREGS
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
 	/*
-	 * SP runs to completion, no need to save FP registers of secure context.
-	 * Restore only non secure world FP registers.
+	 * SP runs to completion, no need to save FP/SVE registers of secure context.
+	 * Restore only non secure world FP/SVE registers.
 	 */
-	fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
-#endif
+	simd_ctx_restore(NON_SECURE);
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
 
 	return rc;
 }
diff --git a/services/std_svc/spm/spm_mm/spm_mm_setup.c b/services/std_svc/spm/spm_mm/spm_mm_setup.c
index 4e65c9cb..de054597 100644
--- a/services/std_svc/spm/spm_mm/spm_mm_setup.c
+++ b/services/std_svc/spm/spm_mm/spm_mm_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -27,7 +27,7 @@
 void spm_sp_setup(sp_context_t *sp_ctx)
 {
 	cpu_context_t *ctx = &(sp_ctx->cpu_ctx);
-
+	u_register_t sctlr_el1_val;
 	/* Pointer to the MP information from the platform port. */
 	const spm_mm_boot_info_t *sp_boot_info =
 			plat_get_secure_partition_boot_info(NULL);
@@ -122,19 +122,17 @@ void spm_sp_setup(sp_context_t *sp_ctx)
 		      xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
 		      EL1_EL0_REGIME);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_MAIR_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), mair_el1,
 		      mmu_cfg_params[MMU_CFG_MAIR]);
+	write_ctx_tcr_el1_reg_errata(ctx, mmu_cfg_params[MMU_CFG_TCR]);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TCR_EL1,
-		      mmu_cfg_params[MMU_CFG_TCR]);
-
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_TTBR0_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), ttbr0_el1,
 		      mmu_cfg_params[MMU_CFG_TTBR0]);
 
 	/* Setup SCTLR_EL1 */
-	u_register_t sctlr_el1 = read_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1);
+	sctlr_el1_val = read_ctx_sctlr_el1_reg_errata(ctx);
 
-	sctlr_el1 |=
+	sctlr_el1_val |=
 		/*SCTLR_EL1_RES1 |*/
 		/* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */
 		SCTLR_UCI_BIT							|
@@ -156,7 +154,7 @@ void spm_sp_setup(sp_context_t *sp_ctx)
 		SCTLR_M_BIT
 	;
 
-	sctlr_el1 &= ~(
+	sctlr_el1_val &= ~(
 		/* Explicit data accesses at EL0 are little-endian. */
 		SCTLR_E0E_BIT							|
 		/*
@@ -168,7 +166,8 @@ void spm_sp_setup(sp_context_t *sp_ctx)
 		SCTLR_UMA_BIT
 	);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
+	/* Store the initialised SCTLR_EL1 value in the cpu_context */
+	write_ctx_sctlr_el1_reg_errata(ctx, sctlr_el1_val);
 
 	/*
 	 * Setup other system registers
@@ -176,10 +175,10 @@ void spm_sp_setup(sp_context_t *sp_ctx)
 	 */
 
 	/* Shim Exception Vector Base Address */
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_VBAR_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), vbar_el1,
 			SPM_SHIM_EXCEPTIONS_PTR);
 
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CNTKCTL_EL1,
+	write_el1_ctx_arch_timer(get_el1_sysregs_ctx(ctx), cntkctl_el1,
 		      EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT);
 
 	/*
@@ -189,7 +188,7 @@ void spm_sp_setup(sp_context_t *sp_ctx)
 	 * TTA: Enable access to trace registers.
 	 * ZEN (v8.2): Trap SVE instructions and access to SVE registers.
 	 */
-	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_CPACR_EL1,
+	write_el1_ctx_common(get_el1_sysregs_ctx(ctx), cpacr_el1,
 			CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
 
 	/*
diff --git a/services/std_svc/spmd/spmd_logical_sp.c b/services/std_svc/spmd/spmd_logical_sp.c
index d992187d..64d506e7 100644
--- a/services/std_svc/spmd/spmd_logical_sp.c
+++ b/services/std_svc/spmd/spmd_logical_sp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -528,9 +528,10 @@ bool spmd_el3_invoke_partition_info_get(
 	}
 
 	/* Save the non-secure context before entering SPMC */
-	cm_el1_sysregs_context_save(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_save(NON_SECURE);
+#else
+	cm_el1_sysregs_context_save(NON_SECURE);
 #endif
 
 	spmd_build_ffa_info_get_regs(ctx, target_uuid, start_index, tag);
@@ -548,9 +549,10 @@ bool spmd_el3_invoke_partition_info_get(
 
 	assert(is_ffa_error(retval) || is_ffa_success(retval));
 
-	cm_el1_sysregs_context_restore(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_restore(NON_SECURE);
+#else
+	cm_el1_sysregs_context_restore(NON_SECURE);
 #endif
 	cm_set_next_eret_context(NON_SECURE);
 	return true;
@@ -667,9 +669,10 @@ bool spmd_el3_ffa_msg_direct_req(uint64_t x1,
 	}
 
 	/* Save the non-secure context before entering SPMC */
-	cm_el1_sysregs_context_save(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_save(NON_SECURE);
+#else
+	cm_el1_sysregs_context_save(NON_SECURE);
 #endif
 
 	/*
@@ -707,9 +710,10 @@ bool spmd_el3_ffa_msg_direct_req(uint64_t x1,
 				ffa_endpoint_destination(x1)));
 	}
 
-	cm_el1_sysregs_context_restore(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_restore(NON_SECURE);
+#else
+	cm_el1_sysregs_context_restore(NON_SECURE);
 #endif
 	cm_set_next_eret_context(NON_SECURE);
 
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 066571e9..3953b245 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -51,27 +51,12 @@ static spmc_manifest_attribute_t spmc_attrs;
  ******************************************************************************/
 static entry_point_info_t *spmc_ep_info;
 
-/*******************************************************************************
- * SPM Core context on CPU based on mpidr.
- ******************************************************************************/
-spmd_spm_core_context_t *spmd_get_context_by_mpidr(uint64_t mpidr)
-{
-	int core_idx = plat_core_pos_by_mpidr(mpidr);
-
-	if (core_idx < 0) {
-		ERROR("Invalid mpidr: %" PRIx64 ", returned ID: %d\n", mpidr, core_idx);
-		panic();
-	}
-
-	return &spm_core_context[core_idx];
-}
-
 /*******************************************************************************
  * SPM Core context on current CPU get helper.
  ******************************************************************************/
 spmd_spm_core_context_t *spmd_get_context(void)
 {
-	return spmd_get_context_by_mpidr(read_mpidr());
+	return &spm_core_context[plat_my_core_pos()];
 }
 
 /*******************************************************************************
@@ -217,7 +202,6 @@ static uint64_t spmd_secure_interrupt_handler(uint32_t id,
 {
 	spmd_spm_core_context_t *ctx = spmd_get_context();
 	gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
-	unsigned int linear_id = plat_my_core_pos();
 	int64_t rc;
 
 	/* Sanity check the security state when the exception was generated */
@@ -227,9 +211,18 @@ static uint64_t spmd_secure_interrupt_handler(uint32_t id,
 	assert(handle == cm_get_context(NON_SECURE));
 
 	/* Save the non-secure context before entering SPMC */
-	cm_el1_sysregs_context_save(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_save(NON_SECURE);
+#else
+	cm_el1_sysregs_context_save(NON_SECURE);
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	/*
+	 * The hint bit denoting absence of SVE live state is effectively false
+	 * in this scenario where execution was trapped to EL3 due to FIQ.
+	 */
+	simd_ctx_save(NON_SECURE, false);
+#endif
 #endif
 
 	/* Convey the event to the SPMC through the FFA_INTERRUPT interface. */
@@ -245,16 +238,28 @@ static uint64_t spmd_secure_interrupt_handler(uint32_t id,
 	/* Mark current core as handling a secure interrupt. */
 	ctx->secure_interrupt_ongoing = true;
 
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	simd_ctx_restore(SECURE);
+#endif
 	rc = spmd_spm_core_sync_entry(ctx);
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	simd_ctx_save(SECURE, false);
+#endif
 	if (rc != 0ULL) {
-		ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, linear_id);
+		ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, plat_my_core_pos());
 	}
 
 	ctx->secure_interrupt_ongoing = false;
 
-	cm_el1_sysregs_context_restore(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_restore(NON_SECURE);
+#else
+	cm_el1_sysregs_context_restore(NON_SECURE);
+
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	simd_ctx_restore(NON_SECURE);
+#endif
 #endif
 	cm_set_next_eret_context(NON_SECURE);
 
@@ -593,14 +598,17 @@ static int spmd_spmc_init(void *pm_addr)
 	 */
 #if (EL3_EXCEPTION_HANDLING == 0)
 	/*
-	 * Register an interrupt handler routing Group0 interrupts to SPMD
-	 * while the NWd is running.
+	 * If EL3 interrupts are supported by the platform, register an
+	 * interrupt handler routing Group0 interrupts to SPMD while the NWd is
+	 * running.
 	 */
-	rc = register_interrupt_type_handler(INTR_TYPE_EL3,
-					     spmd_group0_interrupt_handler_nwd,
-					     flags);
-	if (rc != 0) {
-		panic();
+	if (plat_ic_has_interrupt_type(INTR_TYPE_EL3)) {
+		rc = register_interrupt_type_handler(INTR_TYPE_EL3,
+						     spmd_group0_interrupt_handler_nwd,
+						     flags);
+		if (rc != 0) {
+			panic();
+		}
 	}
 #endif
 
@@ -667,32 +675,46 @@ uint64_t spmd_smc_switch_state(uint32_t smc_fid,
 			       uint64_t x2,
 			       uint64_t x3,
 			       uint64_t x4,
-			       void *handle)
+			       void *handle,
+			       uint64_t flags)
 {
 	unsigned int secure_state_in = (secure_origin) ? SECURE : NON_SECURE;
 	unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
+	void *ctx_out;
 
-	/* Save incoming security state */
 #if SPMD_SPM_AT_SEL2
-	if (secure_state_in == NON_SECURE) {
-		cm_el1_sysregs_context_save(secure_state_in);
+	if ((secure_state_out == SECURE) && (is_sve_hint_set(flags) == true)) {
+		/*
+		 * Set the SVE hint bit in x0 and pass to the lower secure EL,
+		 * if it was set by the caller.
+		 */
+		smc_fid |= (FUNCID_SVE_HINT_MASK << FUNCID_SVE_HINT_SHIFT);
 	}
+#endif
+
+	/* Save incoming security state */
+#if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_save(secure_state_in);
 #else
 	cm_el1_sysregs_context_save(secure_state_in);
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	/* Forward the hint bit denoting the absence of SVE live state. */
+	simd_ctx_save(secure_state_in, (!secure_origin && (is_sve_hint_set(flags) == true)));
+#endif
 #endif
 
 	/* Restore outgoing security state */
 #if SPMD_SPM_AT_SEL2
-	if (secure_state_out == NON_SECURE) {
-		cm_el1_sysregs_context_restore(secure_state_out);
-	}
 	cm_el2_sysregs_context_restore(secure_state_out);
 #else
 	cm_el1_sysregs_context_restore(secure_state_out);
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+	simd_ctx_restore(secure_state_out);
+#endif
 #endif
 	cm_set_next_eret_context(secure_state_out);
 
+	ctx_out = cm_get_context(secure_state_out);
 #if SPMD_SPM_AT_SEL2
 	/*
 	 * If SPMC is at SEL2, save additional registers x8-x17, which may
@@ -705,7 +727,7 @@ uint64_t spmd_smc_switch_state(uint32_t smc_fid,
 	 * preserved, so the SPMD passes through these registers and expects the
 	 * SPMC to save and restore (potentially also modify) them.
 	 */
-	SMC_RET18(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4,
+	SMC_RET18(ctx_out, smc_fid, x1, x2, x3, x4,
 			SMC_GET_GP(handle, CTX_GPREG_X5),
 			SMC_GET_GP(handle, CTX_GPREG_X6),
 			SMC_GET_GP(handle, CTX_GPREG_X7),
@@ -722,7 +744,7 @@ uint64_t spmd_smc_switch_state(uint32_t smc_fid,
 			);
 
 #else
-	SMC_RET8(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4,
+	SMC_RET8(ctx_out, smc_fid, x1, x2, x3, x4,
 			SMC_GET_GP(handle, CTX_GPREG_X5),
 			SMC_GET_GP(handle, CTX_GPREG_X6),
 			SMC_GET_GP(handle, CTX_GPREG_X7));
@@ -746,8 +768,9 @@ static uint64_t spmd_smc_forward(uint32_t smc_fid,
 		return spmc_smc_handler(smc_fid, secure_origin, x1, x2, x3, x4,
 					cookie, handle, flags);
 	}
+
 	return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, x3, x4,
-				     handle);
+				     handle, flags);
 
 }
 
@@ -786,19 +809,6 @@ static bool spmd_is_spmc_message(unsigned int ep)
 		&& (ffa_endpoint_source(ep) == spmc_attrs.spmc_id));
 }
 
-/******************************************************************************
- * spmd_handle_spmc_message
- *****************************************************************************/
-static int spmd_handle_spmc_message(unsigned long long msg,
-		unsigned long long parm1, unsigned long long parm2,
-		unsigned long long parm3, unsigned long long parm4)
-{
-	VERBOSE("%s %llx %llx %llx %llx %llx\n", __func__,
-		msg, parm1, parm2, parm3, parm4);
-
-	return -EINVAL;
-}
-
 /*******************************************************************************
  * This function forwards FF-A SMCs to either the main SPMD handler or the
  * SPMC at EL3, depending on the origin security state, if enabled.
@@ -841,10 +851,9 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
 			  void *handle,
 			  uint64_t flags)
 {
-	unsigned int linear_id = plat_my_core_pos();
 	spmd_spm_core_context_t *ctx = spmd_get_context();
 	bool secure_origin;
-	int32_t ret;
+	int ret;
 	uint32_t input_version;
 
 	/* Determine which security state this SMC originated from */
@@ -852,7 +861,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
 
 	VERBOSE("SPM(%u): 0x%x 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64
 		" 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 "\n",
-		    linear_id, smc_fid, x1, x2, x3, x4,
+		    plat_my_core_pos(), smc_fid, x1, x2, x3, x4,
 		    SMC_GET_GP(handle, CTX_GPREG_X5),
 		    SMC_GET_GP(handle, CTX_GPREG_X6),
 		    SMC_GET_GP(handle, CTX_GPREG_X7));
@@ -936,9 +945,10 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
 				break;
 			}
 			/* Save non-secure system registers context */
-			cm_el1_sysregs_context_save(NON_SECURE);
 #if SPMD_SPM_AT_SEL2
 			cm_el2_sysregs_context_save(NON_SECURE);
+#else
+			cm_el1_sysregs_context_save(NON_SECURE);
 #endif
 
 			/*
@@ -1100,6 +1110,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
 
 	case FFA_MSG_SEND_DIRECT_REQ_SMC32:
 	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
+	case FFA_MSG_SEND_DIRECT_REQ2_SMC64:
 		/*
 		 * Regardless of secure_origin, SPMD logical partitions cannot
 		 * handle direct messages. They can only initiate direct
@@ -1133,16 +1144,8 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
 			}
 		}
 		if (secure_origin && spmd_is_spmc_message(x1)) {
-			ret = spmd_handle_spmc_message(x3, x4,
-				SMC_GET_GP(handle, CTX_GPREG_X5),
-				SMC_GET_GP(handle, CTX_GPREG_X6),
-				SMC_GET_GP(handle, CTX_GPREG_X7));
-
-			SMC_RET8(handle, FFA_SUCCESS_SMC32,
-				FFA_TARGET_INFO_MBZ, ret,
-				FFA_PARAM_MBZ, FFA_PARAM_MBZ,
-				FFA_PARAM_MBZ, FFA_PARAM_MBZ,
-				FFA_PARAM_MBZ);
+				return spmd_ffa_error_return(handle,
+						FFA_ERROR_DENIED);
 		} else {
 			/* Forward direct message to the other world */
 			return spmd_smc_forward(smc_fid, secure_origin,
@@ -1153,6 +1156,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
 
 	case FFA_MSG_SEND_DIRECT_RESP_SMC32:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
+	case FFA_MSG_SEND_DIRECT_RESP2_SMC64:
 		if (secure_origin && (spmd_is_spmc_message(x1) ||
 		    is_spmd_logical_sp_dir_req_in_progress(ctx))) {
 			spmd_spm_core_sync_exit(0ULL);
@@ -1163,7 +1167,6 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
 						handle, flags);
 		}
 		break; /* Not reached */
-
 	case FFA_RX_RELEASE:
 	case FFA_RXTX_MAP_SMC32:
 	case FFA_RXTX_MAP_SMC64:
@@ -1279,6 +1282,12 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
 					handle, flags);
 		break; /* Not reached */
 #endif
+	case FFA_CONSOLE_LOG_SMC32:
+	case FFA_CONSOLE_LOG_SMC64:
+		/* This interface must not be forwarded to other worlds. */
+		return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
+		break; /* not reached */
+
 	case FFA_EL3_INTR_HANDLE:
 		if (secure_origin) {
 			return spmd_handle_group0_intr_swd(handle);
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index e782d09d..5cfe5f9d 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -66,7 +66,7 @@ static int32_t std_svc_setup(void)
 
 #if ENABLE_RME
 	if (rmmd_setup() != 0) {
-		ret = 1;
+		WARN("RMMD setup failed. Continuing boot.\n");
 	}
 #endif
 
diff --git a/tools/amlogic/Makefile b/tools/amlogic/Makefile
index 1a1d1f81..7bfee7d7 100644
--- a/tools/amlogic/Makefile
+++ b/tools/amlogic/Makefile
@@ -4,13 +4,15 @@
 # SPDX-License-Identifier:     BSD-3-Clause
 # https://spdx.org/licenses
 #
+
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
+include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 PROJECT := doimage${BIN_EXT}
 OBJECTS := doimage.o
-V := 0
 
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
 
@@ -20,28 +22,20 @@ else
   HOSTCCFLAGS += -O2
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
-HOSTCC := gcc
-
 .PHONY: all clean distclean
 
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}${HOSTCC} ${OBJECTS} -o $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}${HOSTCC} -c ${HOSTCCFLAGS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index b911d19d..ce12a660 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -1,11 +1,10 @@
 #
-# Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 PLAT		:= none
-V		?= 0
 DEBUG		:= 0
 CRTTOOL		?= cert_create${BIN_EXT}
 BINARY		:= $(notdir ${CRTTOOL})
@@ -14,7 +13,10 @@ COT		:= tbbr
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
+include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
+include ${MAKE_HELPERS_DIRECTORY}utilities.mk
 
 ifneq (${PLAT},none)
 TF_PLATFORM_ROOT	:=	../../plat/
@@ -57,13 +59,7 @@ else
   HOSTCCFLAGS += -O2 -DLOG_LEVEL=20
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
-HOSTCCFLAGS += ${DEFINES}
+HOSTCCFLAGS += ${DEFINES} -DPLAT_MSG=$(call escape-shell,"$(PLAT_MSG)")
 # USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
 # computed value.
 HOSTCCFLAGS += -DUSING_OPENSSL3=$(USING_OPENSSL3)
@@ -81,31 +77,25 @@ INC_DIR += -I ./include -I ${PLAT_INCLUDE} -I ${OPENSSL_DIR}/include
 LIB_DIR := -L ${OPENSSL_DIR}/lib -L ${OPENSSL_DIR}
 LIB := -lssl -lcrypto
 
-HOSTCC ?= gcc
-
 .PHONY: all clean realclean --openssl
 
 all: --openssl ${BINARY}
 
 ${BINARY}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
-                const char platform_msg[] = "${PLAT_MSG}";' | \
-                ${HOSTCC} -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
-	${Q}${HOSTCC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
 
 %.o: %.c
-	@echo "  HOSTCC  $<"
-	${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
 --openssl:
 ifeq ($(DEBUG),1)
-	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+	$(s)echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
 
 clean:
-	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
+	$(call SHELL_DELETE_ALL,${OBJECTS})
 
 realclean: clean
 	$(call SHELL_DELETE,${BINARY})
-
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index e0ecdaed..f7adfab2 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -65,35 +65,35 @@ typedef struct key_s {
 	const char *desc;	/* Key description (debug purposes) */
 	char *fn;		/* Filename to load/store the key */
 	EVP_PKEY *key;		/* Key container */
-} key_t;
+} cert_key_t;
 
 /* Exported API */
 int key_init(void);
-key_t *key_get_by_opt(const char *opt);
+cert_key_t *key_get_by_opt(const char *opt);
 #if !USING_OPENSSL3
-int key_new(key_t *key);
+int key_new(cert_key_t *key);
 #endif
-int key_create(key_t *key, int type, int key_bits);
-unsigned int key_load(key_t *key);
-int key_store(key_t *key);
+int key_create(cert_key_t *key, int type, int key_bits);
+unsigned int key_load(cert_key_t *key);
+int key_store(cert_key_t *key);
 void key_cleanup(void);
 
 /* Macro to register the keys used in the CoT */
 #define REGISTER_KEYS(_keys) \
-	key_t *def_keys = &_keys[0]; \
+	cert_key_t *def_keys = &_keys[0]; \
 	const unsigned int num_def_keys = sizeof(_keys)/sizeof(_keys[0])
 
 /* Macro to register the platform defined keys used in the CoT */
 #define PLAT_REGISTER_KEYS(_pdef_keys) \
-	key_t *pdef_keys = &_pdef_keys[0]; \
+	cert_key_t *pdef_keys = &_pdef_keys[0]; \
 	const unsigned int num_pdef_keys = sizeof(_pdef_keys)/sizeof(_pdef_keys[0])
 
 /* Exported variables */
-extern key_t *def_keys;
+extern cert_key_t *def_keys;
 extern const unsigned int num_def_keys;
-extern key_t *pdef_keys;
+extern cert_key_t *pdef_keys;
 extern const unsigned int num_pdef_keys;
 
-extern key_t *keys;
+extern cert_key_t *keys;
 extern unsigned int num_keys;
 #endif /* KEY_H */
diff --git a/tools/cert_create/src/cca/cot.c b/tools/cert_create/src/cca/cot.c
index 372d9087..658b81c2 100644
--- a/tools/cert_create/src/cca/cot.c
+++ b/tools/cert_create/src/cca/cot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -410,7 +410,7 @@ static ext_t cot_ext[] = {
 REGISTER_EXTENSIONS(cot_ext);
 
 /* Keys used to establish the chain of trust. */
-static key_t cot_keys[] = {
+static cert_key_t cot_keys[] = {
 	[ROT_KEY] = {
 		.id = ROT_KEY,
 		.opt = "rot-key",
diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c
index 2513213a..4a36ee8f 100644
--- a/tools/cert_create/src/cert.c
+++ b/tools/cert_create/src/cert.c
@@ -22,7 +22,6 @@
 #include "sha.h"
 
 #define SERIAL_RAND_BITS	64
-#define RSA_SALT_LEN		32
 
 cert_t *certs;
 unsigned int num_certs;
@@ -152,7 +151,7 @@ int cert_new(
 			goto END;
 		}
 
-		if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, RSA_SALT_LEN)) {
+		if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, EVP_MD_size(get_digest(md_alg)))) {
 			ERR_print_errors_fp(stdout);
 			goto END;
 		}
diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c
index 81a7d75d..d2c15bf9 100644
--- a/tools/cert_create/src/dualroot/cot.c
+++ b/tools/cert_create/src/dualroot/cot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -536,7 +536,7 @@ REGISTER_EXTENSIONS(cot_ext);
 
 
 /* Keys used to establish the chain of trust. */
-static key_t cot_keys[] = {
+static cert_key_t cot_keys[] = {
 	[ROT_KEY] = {
 		.id = ROT_KEY,
 		.opt = "rot-key",
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 04214aac..190c0963 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,14 +26,14 @@
 
 #define MAX_FILENAME_LEN		1024
 
-key_t *keys;
+cert_key_t *keys;
 unsigned int num_keys;
 
 #if !USING_OPENSSL3
 /*
  * Create a new key container
  */
-int key_new(key_t *key)
+int key_new(cert_key_t *key)
 {
 	/* Create key pair container */
 	key->key = EVP_PKEY_new();
@@ -45,7 +45,7 @@ int key_new(key_t *key)
 }
 #endif
 
-static int key_create_rsa(key_t *key, int key_bits)
+static int key_create_rsa(cert_key_t *key, int key_bits)
 {
 #if USING_OPENSSL3
 	EVP_PKEY *rsa = EVP_RSA_gen(key_bits);
@@ -99,7 +99,7 @@ err2:
 
 #ifndef OPENSSL_NO_EC
 #if USING_OPENSSL3
-static int key_create_ecdsa(key_t *key, int key_bits, const char *curve)
+static int key_create_ecdsa(cert_key_t *key, int key_bits, const char *curve)
 {
 	EVP_PKEY *ec = EVP_EC_gen(curve);
 	if (ec == NULL) {
@@ -111,7 +111,7 @@ static int key_create_ecdsa(key_t *key, int key_bits, const char *curve)
 	return 1;
 }
 
-static int key_create_ecdsa_nist(key_t *key, int key_bits)
+static int key_create_ecdsa_nist(cert_key_t *key, int key_bits)
 {
 	if (key_bits == 384) {
 		return key_create_ecdsa(key, key_bits, "secp384r1");
@@ -121,17 +121,17 @@ static int key_create_ecdsa_nist(key_t *key, int key_bits)
 	}
 }
 
-static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
+static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits)
 {
 	return key_create_ecdsa(key, key_bits, "brainpoolP256r1");
 }
 
-static int key_create_ecdsa_brainpool_t(key_t *key, int key_bits)
+static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits)
 {
 	return key_create_ecdsa(key, key_bits, "brainpoolP256t1");
 }
 #else
-static int key_create_ecdsa(key_t *key, int key_bits, const int curve_id)
+static int key_create_ecdsa(cert_key_t *key, int key_bits, const int curve_id)
 {
 	EC_KEY *ec;
 
@@ -158,7 +158,7 @@ err:
 	return 0;
 }
 
-static int key_create_ecdsa_nist(key_t *key, int key_bits)
+static int key_create_ecdsa_nist(cert_key_t *key, int key_bits)
 {
 	if (key_bits == 384) {
 		return key_create_ecdsa(key, key_bits, NID_secp384r1);
@@ -168,29 +168,33 @@ static int key_create_ecdsa_nist(key_t *key, int key_bits)
 	}
 }
 
-static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits)
 {
 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256r1);
 }
 
-static int key_create_ecdsa_brainpool_t(key_t *key, int key_bits)
+static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits)
 {
 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1);
 }
+#endif
 #endif /* USING_OPENSSL3 */
 #endif /* OPENSSL_NO_EC */
 
-typedef int (*key_create_fn_t)(key_t *key, int key_bits);
+typedef int (*key_create_fn_t)(cert_key_t *key, int key_bits);
 static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
 	[KEY_ALG_RSA] = key_create_rsa,
 #ifndef OPENSSL_NO_EC
 	[KEY_ALG_ECDSA_NIST] = key_create_ecdsa_nist,
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	[KEY_ALG_ECDSA_BRAINPOOL_R] = key_create_ecdsa_brainpool_r,
 	[KEY_ALG_ECDSA_BRAINPOOL_T] = key_create_ecdsa_brainpool_t,
+#endif
 #endif /* OPENSSL_NO_EC */
 };
 
-int key_create(key_t *key, int type, int key_bits)
+int key_create(cert_key_t *key, int type, int key_bits)
 {
 	if (type >= KEY_ALG_MAX_NUM) {
 		printf("Invalid key type\n");
@@ -239,7 +243,7 @@ err:
 
 }
 
-unsigned int key_load(key_t *key)
+unsigned int key_load(cert_key_t *key)
 {
 	if (key->fn == NULL) {
 		VERBOSE("Key not specified\n");
@@ -269,7 +273,7 @@ unsigned int key_load(key_t *key)
 	return KEY_ERR_NONE;
 }
 
-int key_store(key_t *key)
+int key_store(cert_key_t *key)
 {
 	FILE *fp;
 
@@ -297,7 +301,7 @@ int key_store(key_t *key)
 int key_init(void)
 {
 	cmd_opt_t cmd_opt;
-	key_t *key;
+	cert_key_t *key;
 	unsigned int i;
 
 	keys = malloc((num_def_keys * sizeof(def_keys[0]))
@@ -337,9 +341,9 @@ int key_init(void)
 	return 0;
 }
 
-key_t *key_get_by_opt(const char *opt)
+cert_key_t *key_get_by_opt(const char *opt)
 {
-	key_t *key;
+	cert_key_t *key;
 	unsigned int i;
 
 	/* Sequential search. This is not a performance concern since the number
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index f10a768b..aa21206c 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -1,9 +1,11 @@
 /*
- * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#define _POSIX_C_SOURCE 200809L
+
 #include <assert.h>
 #include <ctype.h>
 #include <getopt.h>
@@ -66,27 +68,17 @@ static int new_keys;
 static int save_keys;
 static int print_cert;
 
-/* Info messages created in the Makefile */
-extern const char build_msg[];
-extern const char platform_msg[];
-
-
-static char *strdup(const char *str)
-{
-	int n = strlen(str) + 1;
-	char *dup = malloc(n);
-	if (dup) {
-		strcpy(dup, str);
-	}
-	return dup;
-}
+static const char build_msg[] = "Built : " __TIME__ ", " __DATE__;
+static const char platform_msg[] = PLAT_MSG;
 
 static const char *key_algs_str[] = {
 	[KEY_ALG_RSA] = "rsa",
 #ifndef OPENSSL_NO_EC
 	[KEY_ALG_ECDSA_NIST] = "ecdsa",
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	[KEY_ALG_ECDSA_BRAINPOOL_R] = "ecdsa-brainpool-regular",
 	[KEY_ALG_ECDSA_BRAINPOOL_T] = "ecdsa-brainpool-twisted",
+#endif
 #endif /* OPENSSL_NO_EC */
 };
 
@@ -178,7 +170,7 @@ static void check_cmd_params(void)
 {
 	cert_t *cert;
 	ext_t *ext;
-	key_t *key;
+	cert_key_t *key;
 	int i, j;
 	bool valid_size;
 
@@ -269,8 +261,12 @@ static const cmd_opt_t common_cmd_opt[] = {
 	},
 	{
 		{ "key-alg", required_argument, NULL, 'a' },
-		"Key algorithm: 'rsa' (default)- RSAPSS scheme as per PKCS#1 v2.1, " \
+		"Key algorithm: 'rsa' (default)- RSAPSS scheme as per PKCS#1 v2.1, "
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 		"'ecdsa', 'ecdsa-brainpool-regular', 'ecdsa-brainpool-twisted'"
+#else
+		"'ecdsa'"
+#endif
 	},
 	{
 		{ "key-size", required_argument, NULL, 'b' },
@@ -299,7 +295,7 @@ int main(int argc, char *argv[])
 	STACK_OF(X509_EXTENSION) * sk;
 	X509_EXTENSION *cert_ext = NULL;
 	ext_t *ext;
-	key_t *key;
+	cert_key_t *key;
 	cert_t *cert;
 	FILE *file;
 	int i, j, ext_nid, nvctr;
diff --git a/tools/cert_create/src/tbbr/tbb_key.c b/tools/cert_create/src/tbbr/tbb_key.c
index 5b84b6e9..3d99067f 100644
--- a/tools/cert_create/src/tbbr/tbb_key.c
+++ b/tools/cert_create/src/tbbr/tbb_key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
  *
  * The order of the keys must follow the enumeration specified in tbb_key.h
  */
-static key_t tbb_keys[] = {
+static cert_key_t tbb_keys[] = {
 	[ROT_KEY] = {
 		.id = ROT_KEY,
 		.opt = "rot-key",
diff --git a/tools/conventional-changelog-tf-a/package.json b/tools/conventional-changelog-tf-a/package.json
index d0efab8f..9975ea32 100644
--- a/tools/conventional-changelog-tf-a/package.json
+++ b/tools/conventional-changelog-tf-a/package.json
@@ -1,6 +1,6 @@
 {
   "name": "conventional-changelog-tf-a",
-  "version": "2.10.0",
+  "version": "2.12.0",
   "license": "BSD-3-Clause",
   "private": true,
   "main": "index.js",
diff --git a/tools/cot_dt2c/.gitignore b/tools/cot_dt2c/.gitignore
new file mode 100644
index 00000000..ad4a1f17
--- /dev/null
+++ b/tools/cot_dt2c/.gitignore
@@ -0,0 +1,176 @@
+# Created by https://www.toptal.com/developers/gitignore/api/python
+# Edit at https://www.toptal.com/developers/gitignore?templates=python
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+#   in version control.
+#   https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+### Python Patch ###
+# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
+poetry.toml
+
+# ruff
+.ruff_cache/
+
+# LSP config files
+pyrightconfig.json
+
+# End of https://www.toptal.com/developers/gitignore/api/python
diff --git a/tools/cot_dt2c/cot_dt2c/__init__.py b/tools/cot_dt2c/cot_dt2c/__init__.py
new file mode 100644
index 00000000..621c55a1
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/__init__.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import sys
+
+if sys.version_info >= (3, 8):
+    from importlib import metadata as importlib_metadata
+else:
+    import importlib_metadata
+
+
+def get_version() -> str:
+    try:
+        return importlib_metadata.version(__name__)
+    except importlib_metadata.PackageNotFoundError:  # pragma: no cover
+        return "unknown"
+
+
+version: str = get_version()
diff --git a/tools/cot_dt2c/cot_dt2c/__main__.py b/tools/cot_dt2c/cot_dt2c/__main__.py
new file mode 100644
index 00000000..5aa4a92f
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/__main__.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+from cot_dt2c.cli import cli
+if __name__ == "__main__":
+    cli()
diff --git a/tools/cot_dt2c/cot_dt2c/cli.py b/tools/cot_dt2c/cot_dt2c/cli.py
new file mode 100644
index 00000000..d338430c
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/cli.py
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+from pathlib import Path
+from cot_dt2c.cot_dt2c import generateMain
+from cot_dt2c.cot_dt2c import validateMain
+from cot_dt2c.cot_dt2c import visualizeMain
+from cot_dt2c.dt_validator import dtValidatorMain
+
+import click
+
+@click.group()
+@click.version_option()
+def cli():
+    pass
+
+@cli.command()
+@click.argument("inputfile", type=click.Path(dir_okay=True))
+@click.argument("outputfile", type=click.Path(dir_okay=True))
+def convert_to_c(inputfile, outputfile):
+    generateMain(inputfile, outputfile)
+
+@cli.command()
+@click.argument("inputfile", type=click.Path(dir_okay=True))
+def validate_cot(inputfile):
+    validateMain(inputfile)
+
+@cli.command()
+@click.argument("inputfile", type=click.Path(dir_okay=True))
+def visualize_cot(inputfile):
+    visualizeMain(inputfile)
+
+@cli.command()
+@click.argument("inputfiledir", type=click.Path(dir_okay=True))
+def validate_dt(inputfiledir):
+    dtValidatorMain(inputfiledir)
diff --git a/tools/cot_dt2c/cot_dt2c/cot_dt2c.py b/tools/cot_dt2c/cot_dt2c/cot_dt2c.py
new file mode 100644
index 00000000..4056aac9
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/cot_dt2c.py
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import sys
+from cot_dt2c.cot_parser import COT
+
+def generateMain(input, output=None):
+    cot = COT(input, output)
+    cot.generate_c_file()
+
+def validateMain(input):
+    cot = COT(input)
+    if not cot.validate_nodes():
+        print("not a valid CoT DT file")
+
+def visualizeMain(input):
+    cot = COT(input)
+    cot.tree_visualization()
+
+if __name__=="__main__":
+    if (len(sys.argv) < 2):
+        print("usage: python3 " + sys.argv[0] + " [dtsi file path] [optional output c file path]")
+        exit()
+    if len(sys.argv) == 3:
+        generateMain(sys.argv[1], sys.argv[2])
+    if len(sys.argv) == 2:
+        validateMain(sys.argv[1])
diff --git a/tools/cot_dt2c/cot_dt2c/cot_parser.py b/tools/cot_dt2c/cot_dt2c/cot_parser.py
new file mode 100644
index 00000000..39e51db3
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/cot_parser.py
@@ -0,0 +1,673 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import sys
+import re
+from pydevicetree.ast import CellArray, LabelReference
+from pydevicetree import Devicetree, Property, Node
+from pathlib import Path
+from typing import List, Optional
+
+class COT:
+    def __init__(self, inputfile: str, outputfile=None):
+        try:
+            self.tree = Devicetree.parseFile(inputfile)
+        except:
+            print("not a valid CoT DT file")
+            exit(1)
+
+        self.output = outputfile
+        self.input = inputfile
+        self.has_root = False
+
+        # edge cases
+        certs = self.get_all_certificates()
+        for c in certs:
+            if self.if_root(c):
+                if not c.get_fields("signing-key"):
+                    c.properties.append(Property("signing-key", CellArray([LabelReference("subject_pk")])))
+
+    def print_cert_info(self, node:Node):
+        img_id = node.get_field("image-id").values[0].replace('"', "")
+        sign_key = self.get_sign_key(node)
+        nv = self.get_nv_ctr(node)
+
+        info = "<b>name:</b> {}<br><b>image-id:</b> {}<br>{}{}{}"\
+                .format(node.name, img_id, "<b>root-certificate</b><br>" if self.if_root(node) else "", \
+                     "<b>signing-key:</b> " + self.extract_label(sign_key) + "<br>" if sign_key else "", \
+                     "<b>nv counter:</b> " + self.extract_label(nv) + "<br>" if nv else "")
+        return info
+
+    def print_data_info(self, node:Node):
+        oid = node.get_field("oid")
+        info = "<b>name:</b> {}<br><b>oid:</b> {}<br>" \
+                .format(node.name, oid)
+
+        return info
+
+    def print_img_info(self, node:Node):
+        hash = self.extract_label(node.get_fields("hash"))
+        img_id = node.get_field("image-id").values[0].replace('"', "")
+        info = "<b>name:</b> {}<br><b>image-id:</b> {}<br><b>hash:</b> {}"\
+                .format(node.name, img_id, hash)
+
+        return info
+
+    def tree_width(self, parent_set, root):
+        ans = 1
+        stack = [root]
+
+        while stack:
+            tmp_stack = []
+            while stack:
+                cur_node = stack.pop()
+                child = parent_set[cur_node]
+                for c in child:
+                    tmp_stack.append(c)
+
+            stack = tmp_stack.copy()
+            ans = max(ans, len(tmp_stack))
+
+        return ans
+
+    def resolve_lay(self, parent_set, lay, name_idx, root, bounds, break_name):
+        child = parent_set[root]
+
+        if len(child) == 0:
+            return
+
+        width = []
+        total_width = 0
+        for c in child:
+            w = self.tree_width(parent_set, c)
+            width.append(w)
+            total_width += w
+
+        allow_width = bounds[1] - bounds[0]
+        interval = allow_width / total_width
+        start = bounds[0]
+        for i, c in enumerate(child):
+            end = start + interval * width[i]
+            new_bounds = [start, end]
+            lay[name_idx[c]][0] = start + (end - start) / 2
+            if end - start < 0.28:
+                break_name.add(c)
+            start = end
+            self.resolve_lay(parent_set, lay, name_idx, c, new_bounds, break_name)
+
+    def tree_visualization(self):
+        import igraph
+        from igraph import Graph, EdgeSeq
+        import collections
+
+        cert = self.get_certificates()
+        pk = self.get_rot_keys()
+        nv = self.get_nv_counters()
+        image = self.get_images()
+
+        certs = cert.children
+        if pk:
+            pks = pk.children
+        else:
+            pks = []
+        nvs = nv.children
+        images = image.children
+
+        root_name = "CoT"
+
+        G = Graph()
+        detail = []
+        lay = []
+        name_idx = {}
+        parent_set = collections.defaultdict(list)
+
+        G.add_vertex(root_name)
+        detail.append("CoT Root")
+        name_idx[root_name] = len(lay)
+        lay.append([0,0])
+
+        G.add_vertex(cert.name)
+        G.add_edge(root_name, cert.name)
+        detail.append("All Certificates")
+        name_idx[cert.name] = len(lay)
+        lay.append([0, 1])
+        parent_set[root_name].append(cert.name)
+
+        if pk:
+            G.add_vertex(pk.name)
+            detail.append("All Public Trusted Key")
+            G.add_edge(root_name, pk.name)
+            name_idx[pk.name] = len(lay)
+            lay.append([-2.0, 1])
+            parent_set[root_name].append(pk.name)
+
+        G.add_vertex(nv.name)
+        detail.append("All NV Counters")
+        G.add_edge(root_name, nv.name)
+        name_idx[nv.name] = len(lay)
+        lay.append([2.0, 1])
+        parent_set[root_name].append(nv.name)
+
+        if pks:
+            for i, p in enumerate(pks):
+                G.add_vertex(p.name)
+                detail.append(self.print_data_info(p))
+                G.add_edge(pk.name, p.name)
+                name_idx[p.name] = len(lay)
+                parent_set[pk.name].append(p.name)
+                lay.append([0, lay[name_idx[pk.name]][1] + 1])
+
+        for c in certs:
+            G.add_vertex(c.name)
+            detail.append(self.print_cert_info(c))
+            name_idx[c.name] = len(lay)
+            if self.if_root(c):
+                G.add_edge(cert.name, c.name)
+                parent_set[cert.name].append(c.name)
+                lay.append([0, 2])
+            else:
+                parent = self.extract_label(c.get_fields("parent"))
+                G.add_edge(parent, c.name)
+                parent_set[parent].append(c.name)
+                lay.append([0, lay[name_idx[parent]][1] + 1])
+
+        for idx, i in enumerate(images):
+            G.add_vertex(i.name)
+            detail.append(self.print_img_info(i))
+            parent = self.extract_label(i.get_fields("parent"))
+            G.add_edge(parent, i.name)
+            parent_set[parent].append(i.name)
+            name_idx[i.name] = len(lay)
+            lay.append([0, lay[name_idx[parent]][1] + 1])
+
+        for i, n in enumerate(nvs):
+            G.add_vertex(n.name)
+            detail.append(self.print_data_info(n))
+            G.add_edge(nv.name, n.name)
+            name_idx[n.name] = len(lay)
+            parent_set[nv.name].append(n.name)
+            lay.append([0, lay[name_idx[nv.name]][1] + 1])
+
+        break_name = set()
+        self.resolve_lay(parent_set, lay, name_idx, root_name, [-3, 3], break_name)
+        #lay = G.layout('rt')
+
+        numVertex = len(G.get_vertex_dataframe())
+        vertices = G.get_vertex_dataframe()
+        v_label = []
+
+        for i in vertices['name']:
+            if i in break_name and len(i) > 10:
+                middle = len(i) // 2
+                v_label.append(i[:middle] + "<br>" + i[middle:])
+            else:
+                v_label.append(i)
+
+        position = {k: lay[k] for k in range(numVertex)}
+        Y = [lay[k][1] for k in range(numVertex)]
+        M = max(Y)
+
+        es = EdgeSeq(G) # sequence of edges
+        E = [e.tuple for e in G.es] # list of edges
+
+        L = len(position)
+        Xn = [position[k][0] for k in range(L)]
+        Yn = [2*M-position[k][1] for k in range(L)]
+        Xe = []
+        Ye = []
+        for edge in E:
+            Xe += [position[edge[0]][0], position[edge[1]][0], None]
+            Ye += [2*M-position[edge[0]][1], 2*M-position[edge[1]][1], None]
+
+        labels = v_label
+
+        import plotly.graph_objects as go
+        fig = go.Figure()
+        fig.add_trace(go.Scatter(x = Xe,
+                        y = Ye,
+                        mode = 'lines',
+                        line = dict(color='rgb(210,210,210)', width=2),
+                        hoverinfo = 'none'
+                        ))
+        fig.add_trace(go.Scatter(x = Xn,
+                        y = Yn,
+                        mode = 'markers',
+                        name = 'detail',
+                        marker = dict(symbol = 'circle-dot',
+                                        size = 50,
+                                        color = 'rgba(135, 206, 250, 0.8)',    #'#DB4551',
+                                        line = dict(color='MediumPurple', width=3)
+                                        ),
+                        text=detail,
+                        hoverinfo='text',
+                        hovertemplate =
+                            '<b>Detail</b><br>'
+                            '%{text}',
+                        opacity=0.8
+                        ))
+
+        def make_annotations(pos, text, font_size=10, font_color='rgb(0,0,0)'):
+            L = len(pos)
+            if len(text) != L:
+                raise ValueError('The lists pos and text must have the same len')
+            annotations = []
+            for k in range(L):
+                annotations.append(
+                    dict(
+                        text = labels[k],
+                        x = pos[k][0], y = 2*M-position[k][1],
+                        xref = 'x1', yref = 'y1',
+                        font = dict(color = font_color, size = font_size),
+                        showarrow = False)
+                )
+            return annotations
+
+        axis = dict(showline=False, # hide axis line, grid, ticklabels and  title
+            zeroline=False,
+            showgrid=False,
+            showticklabels=False,
+            )
+
+        fig.update_layout(title= 'CoT Device Tree',
+                    annotations=make_annotations(position, v_label),
+                    font_size=12,
+                    showlegend=False,
+                    xaxis=axis,
+                    yaxis=axis,
+                    margin=dict(l=40, r=40, b=85, t=100),
+                    hovermode='closest',
+                    plot_bgcolor='rgb(248,248,248)'
+                    )
+
+        fig.show()
+
+        return
+
+    def if_root(self, node:Node) -> bool:
+        for p in node.properties:
+            if p.name == "root-certificate":
+                return True
+        return False
+
+    def get_sign_key(self, node:Node):
+        for p in node.properties:
+            if p.name == "signing-key":
+                return p.values
+
+        return None
+
+    def get_nv_ctr(self, node:Node):
+        for nv in node.properties:
+            if nv.name == "antirollback-counter":
+                return nv.values
+
+        return None
+
+    def extract_label(self, label) -> str:
+        if not label:
+            return label
+        return label[0].label.name
+
+    def get_auth_data(self, node:Node):
+        return node.children
+
+    def format_auth_data_val(self, node:Node, cert:Node):
+        type_desc = node.name
+        ptr = type_desc + "_buf"
+        len = "HASH_DER_LEN"
+        if re.search("_pk$", type_desc):
+            len = "PK_DER_LEN"
+
+        # edge case
+        if not self.if_root(cert) and "key_cert" in cert.name:
+            if "content_pk" in ptr:
+                ptr = "content_pk_buf"
+
+        return type_desc, ptr, len
+
+    def get_node(self, nodes: List[Node], name: str) -> Node:
+        for i in nodes:
+            if i.name == name:
+                return i
+
+    def get_certificates(self) -> Node:
+        children = self.tree.children
+        for i in children:
+            if i.name == "cot":
+                return self.get_node(i.children, "manifests")
+
+    def get_images(self)-> Node:
+        children = self.tree.children
+        for i in children:
+            if i.name == "cot":
+                return self.get_node(i.children, "images")
+
+    def get_nv_counters(self) -> Node:
+        children = self.tree.children
+        return self.get_node(children, "non_volatile_counters")
+
+    def get_rot_keys(self) -> Node:
+        children = self.tree.children
+        return self.get_node(children, "rot_keys")
+
+    def get_all_certificates(self) -> Node:
+        cert = self.get_certificates()
+        return cert.children
+
+    def get_all_images(self) -> Node:
+        image = self.get_images()
+        return image.children
+
+    def get_all_nv_counters(self) -> Node:
+        nv = self.get_nv_counters()
+        return nv.children
+
+    def get_all_pks(self) -> Node:
+        pk = self.get_rot_keys()
+        if not pk:
+            return []
+        return pk.children
+
+    def validate_cert(self, node:Node) -> bool:
+        valid = True
+        if not node.has_field("image-id"):
+            print("{} missing mandatory attribute image-id".format(node.name))
+            valid = False
+
+        if not node.has_field("root-certificate"):
+            if not node.has_field("parent"):
+                print("{} missing mandatory attribute parent".format(node.name))
+                valid = False
+            else:
+                # check if refer to non existing parent
+                certs = self.get_all_certificates()
+                found = False
+                for c in certs:
+                    if c.name == self.extract_label(node.get_fields("parent")):
+                        found = True
+
+                if not found:
+                    print("{} refer to non existing parent".format(node.name))
+                    valid = False
+
+        else:
+            self.has_root = True
+
+        child = node.children
+        if child:
+            for c in child:
+                if not c.has_field("oid"):
+                    print("{} missing mandatory attribute oid".format(c.name))
+                    valid = False
+
+        return valid
+
+    def validate_img(self, node:Node) -> bool:
+        valid = True
+        if not node.has_field("image-id"):
+            print("{} missing mandatory attribute image-id".format(node.name))
+            valid = False
+
+        if not node.has_field("parent"):
+            print("{} missing mandatory attribute parent".format(node.name))
+            valid = False
+
+        if not node.has_field("hash"):
+            print("{} missing mandatory attribute hash".format(node.name))
+            valid = False
+
+        # check if refer to non existing parent
+        certs = self.get_all_certificates()
+        found = False
+        for c in certs:
+            if c.name == self.extract_label(node.get_fields("parent")):
+                found = True
+
+        if not found:
+            print("{} refer to non existing parent".format(node.name))
+            valid = False
+
+        return valid
+
+    def validate_nodes(self) -> bool:
+        valid = True
+
+        certs = self.get_all_certificates()
+        images = self.get_all_images()
+
+        for n in certs:
+            node_valid = self.validate_cert(n)
+            valid = valid and node_valid
+
+        for i in images:
+            node_valid = self.validate_img(i)
+            valid = valid and node_valid
+
+        if not self.has_root:
+            print("missing root certificate")
+
+        return valid
+
+    def include_to_c(self, f):
+        f.write("#include <stddef.h>\n")
+        f.write("#include <mbedtls/version.h>\n")
+        f.write("#include <common/tbbr/cot_def.h>\n")
+        f.write("#include <drivers/auth/auth_mod.h>\n")
+        f.write("#include <platform_def.h>\n\n")
+        return
+
+    def generate_header(self, output):
+        self.include_to_c(output)
+
+    def all_cert_to_c(self, f):
+        certs = self.get_all_certificates()
+        for c in certs:
+            self.cert_to_c(c, f)
+
+        f.write("\n")
+
+    def cert_to_c(self, node: Node, f):
+        node_image_id: int = node.get_field("image-id")
+
+        f.write(f"static const auth_img_desc_t {node.name} = {{\n")
+        f.write(f"\t.img_id = {node_image_id},\n")
+        f.write("\t.img_type = IMG_CERT,\n")
+
+        if not self.if_root(node):
+            node_parent: Node = node.get_field("parent")
+
+            f.write(f"\t.parent = &{node_parent.label.name},\n")
+        else:
+            f.write("\t.parent = NULL,\n")
+
+        sign = self.get_sign_key(node)
+        nv_ctr = self.get_nv_ctr(node)
+
+        if sign or nv_ctr:
+            f.write("\t.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {\n")
+
+        if sign:
+            f.write("\t\t[0] = {\n")
+            f.write("\t\t\t.type = AUTH_METHOD_SIG,\n")
+            f.write("\t\t\t.param.sig = {\n")
+
+            f.write("\t\t\t\t.pk = &{},\n".format(self.extract_label(sign)))
+            f.write("\t\t\t\t.sig = &sig,\n")
+            f.write("\t\t\t\t.alg = &sig_alg,\n")
+            f.write("\t\t\t\t.data = &raw_data\n")
+            f.write("\t\t\t}\n")
+            f.write("\t\t}}{}\n".format("," if nv_ctr else ""))
+
+        if nv_ctr:
+            f.write("\t\t[1] = {\n")
+            f.write("\t\t\t.type = AUTH_METHOD_NV_CTR,\n")
+            f.write("\t\t\t.param.nv_ctr = {\n")
+
+            f.write("\t\t\t\t.cert_nv_ctr = &{},\n".format(self.extract_label(nv_ctr)))
+            f.write("\t\t\t\t.plat_nv_ctr = &{}\n".format(self.extract_label(nv_ctr)))
+
+            f.write("\t\t\t}\n")
+            f.write("\t\t}\n")
+
+        f.write("\t},\n")
+
+        auth_data = self.get_auth_data(node)
+        if auth_data:
+            f.write("\t.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {\n")
+
+            for i, d in enumerate(auth_data):
+                type_desc, ptr, data_len = self.format_auth_data_val(d, node)
+
+                f.write("\t\t[{}] = {{\n".format(i))
+                f.write("\t\t\t.type_desc = &{},\n".format(type_desc))
+                f.write("\t\t\t.data = {\n")
+
+                f.write("\t\t\t\t.ptr = (void *){},\n".format(ptr))
+
+                f.write("\t\t\t\t.len = (unsigned int){}\n".format(data_len))
+                f.write("\t\t\t}\n")
+
+                f.write("\t\t}}{}\n".format("," if i != len(auth_data) - 1 else ""))
+
+            f.write("\t}\n")
+
+        f.write("};\n\n")
+
+        return
+
+
+    def img_to_c(self, node:Node, f):
+        node_image_id: int = node.get_field("image-id")
+        node_parent: Node = node.get_field("parent")
+        node_hash: Node = node.get_field("hash")
+
+        f.write(f"static const auth_img_desc_t {node.name} = {{\n")
+        f.write(f"\t.img_id = {node_image_id},\n")
+        f.write("\t.img_type = IMG_RAW,\n")
+        f.write(f"\t.parent = &{node_parent.label.name},\n")
+        f.write("\t.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {\n")
+
+        f.write("\t\t[0] = {\n")
+        f.write("\t\t\t.type = AUTH_METHOD_HASH,\n")
+        f.write("\t\t\t.param.hash = {\n")
+        f.write("\t\t\t\t.data = &raw_data,\n")
+        f.write(f"\t\t\t\t.hash = &{node_hash.label.name}\n")
+        f.write("\t\t\t}\n")
+
+        f.write("\t\t}\n")
+        f.write("\t}\n")
+        f.write("};\n\n")
+
+        return
+
+    def all_img_to_c(self, f):
+        images = self.get_all_images()
+        for i in images:
+            self.img_to_c(i, f)
+
+        f.write("\n")
+
+    def nv_to_c(self, f):
+        nv_ctr = self.get_all_nv_counters()
+
+        for nv in nv_ctr:
+            nv_oid: str = nv.get_field("oid")
+
+            f.write(f"static auth_param_type_desc_t {nv.name} = "\
+                    f"AUTH_PARAM_TYPE_DESC(AUTH_PARAM_NV_CTR, \"{nv_oid}\");\n")
+
+        f.write("\n")
+
+        return
+
+    def pk_to_c(self, f):
+        pks = self.get_all_pks()
+
+        for p in pks:
+            pk_oid: str = p.get_field("oid")
+
+            f.write(f"static auth_param_type_desc_t {p.name} = "\
+                    f"AUTH_PARAM_TYPE_DESC(AUTH_PARAM_PUB_KEY, \"{pk_oid}\");\n")
+
+        f.write("\n")
+        return
+
+    def buf_to_c(self, f):
+        certs = self.get_all_certificates()
+
+        buffers = set()
+
+        for c in certs:
+            auth_data = self.get_auth_data(c)
+
+            for a in auth_data:
+                type_desc, ptr, data_len = self.format_auth_data_val(a, c)
+
+                if not ptr in buffers:
+                    f.write(f"static unsigned char {ptr}[{data_len}];\n")
+                    buffers.add(ptr)
+
+        f.write("\n")
+
+    def param_to_c(self, f):
+        f.write("static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(AUTH_PARAM_PUB_KEY, 0);\n")
+        f.write("static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(AUTH_PARAM_SIG, 0);\n")
+        f.write("static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(AUTH_PARAM_SIG_ALG, 0);\n")
+        f.write("static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(AUTH_PARAM_RAW_DATA, 0);\n")
+        f.write("\n")
+
+        certs = self.get_all_certificates()
+        for c in certs:
+            hash = c.children
+            for h in hash:
+                name = h.name
+                oid = h.get_field("oid")
+
+                if re.search("_pk$", name):
+                    ty = "AUTH_PARAM_PUB_KEY"
+                elif re.search("_hash$", name):
+                    ty = "AUTH_PARAM_HASH"
+
+                f.write(f"static auth_param_type_desc_t {name} = "\
+                    f"AUTH_PARAM_TYPE_DESC({ty}, \"{oid}\");\n")
+
+        f.write("\n")
+
+    def cot_to_c(self, f):
+        certs = self.get_all_certificates()
+        images = self.get_all_images()
+
+        f.write("static const auth_img_desc_t * const cot_desc[] = {\n")
+
+        for i, c in enumerate(certs):
+            c_image_id: int = c.get_field("image-id")
+
+            f.write(f"\t[{c_image_id}]	=	&{c.name},\n")
+
+        for i, c in enumerate(images):
+            c_image_id: int = c.get_field("image-id")
+
+            f.write(f"\t[{c_image_id}]	=	&{c.name},\n")
+
+        f.write("};\n\n")
+        f.write("REGISTER_COT(cot_desc);\n")
+        return
+
+    def generate_c_file(self):
+        filename = Path(self.output)
+        filename.parent.mkdir(exist_ok=True, parents=True)
+
+        with open(self.output, 'w+') as output:
+            self.generate_header(output)
+            self.buf_to_c(output)
+            self.param_to_c(output)
+            self.nv_to_c(output)
+            self.pk_to_c(output)
+            self.all_cert_to_c(output)
+            self.all_img_to_c(output)
+            self.cot_to_c(output)
+
+        return
diff --git a/tools/cot_dt2c/cot_dt2c/dt_validator.py b/tools/cot_dt2c/cot_dt2c/dt_validator.py
new file mode 100644
index 00000000..ade037ca
--- /dev/null
+++ b/tools/cot_dt2c/cot_dt2c/dt_validator.py
@@ -0,0 +1,130 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import sys
+from os import path, walk, mkdir
+import subprocess
+from pydevicetree import Devicetree
+
+class bcolors:
+    HEADER = '\033[95m'
+    OKBLUE = '\033[94m'
+    OKCYAN = '\033[96m'
+    OKGREEN = '\033[92m'
+    WARNING = '\033[93m'
+    FAIL = '\033[91m'
+    ENDC = '\033[0m'
+    BOLD = '\033[1m'
+    UNDERLINE = '\033[4m'
+
+class DTTree:
+    def __init__(self, input):
+        self.input = input
+        self.test_dir = "./tmp"
+        self.logging_file = self.test_dir + "/result.log"
+
+    def dtValidate(self):
+        subprocess.run(["rm", "-rf", self.test_dir])
+
+        if not path.exists(self.test_dir):
+            mkdir(self.test_dir)
+
+        if path.isfile(self.input):
+            self.dtValidateFile(self.input, printInfo=True)
+            return
+
+        if path.isdir(self.input):
+            self.dtValidateFiles()
+            return
+
+    def dtValidateFile(self, input, printInfo=False):
+        valid, tree = self.dtParseFile(input, printInfo)
+
+        if not valid:
+            return False
+
+        if input.rfind("/") != -1:
+            filename = self.test_dir + input[input.rfind("/"):]
+        else:
+            filename = self.test_dir + "/" + input
+
+        f = open(filename, "w+")
+        if "/dts-v1/;" not in str(tree):
+            f.write("/dts-v1/;\n\n")
+        f.write(str(tree))
+        f.close()
+
+        if str(tree) == "":
+            return valid
+
+        return valid
+
+    def dtParseFile(self, input, printInfo=False):
+        with open(input, 'r') as f:
+            contents = f.read()
+
+        pos = contents.find("/ {")
+        if pos != -1:
+            contents = contents[pos:]
+
+        try:
+            tree = Devicetree.parseStr(contents)
+            if printInfo:
+                print(bcolors.OKGREEN + "{} parse tree successfully".format(input) + bcolors.ENDC)
+        except Exception as e:
+            if printInfo:
+                print(bcolors.FAIL + "{} parse tree failed:\t{}".format(input, str(e)) + bcolors.ENDC)
+            else:
+                f = open(self.logging_file, "a")
+                f.write("=====================================================================================\n")
+                f.write("{} result:\n".format(input))
+                f.write("{} INVALID:\t{}\n".format(input, str(e)))
+                f.close()
+            return False, None
+
+        return True, tree
+
+    def dtValidateFiles(self):
+        f = []
+        for (dirpath, dirnames, filenames) in walk(self.input):
+            f.extend(filenames)
+
+        allFile = len(f)
+        dtsiFile = 0
+        validFile = 0
+        invalidFile = 0
+
+        for i in f:
+            if (".dtsi" in i or ".dts" in i) and "cot" not in i and "fw-config" not in i:
+                dtsiFile += 1
+                valid = True
+
+                if self.input[-1] == "/":
+                    valid = self.dtValidateFile(self.input + i)
+                else:
+                    valid = self.dtValidateFile(self.input + "/" + i)
+
+                if valid:
+                    validFile += 1
+                else:
+                    invalidFile += 1
+
+        print("=====================================================")
+        print("Total File: " + str(allFile))
+        print("Total DT File: " + str(dtsiFile))
+        print("Total Valid File: " + str(validFile))
+        print("Total Invalid File: " + str(invalidFile))
+
+def dtValidatorMain(input):
+    dt = DTTree(input)
+    dt.dtValidate()
+
+if __name__=="__main__":
+    if (len(sys.argv) < 2):
+        print("usage: python3 " + sys.argv[0] + " [dtsi file path] or [dtsi folder path]")
+        exit()
+    if len(sys.argv) == 2:
+        dtValidatorMain(sys.argv[1])
diff --git a/tools/cot_dt2c/poetry.lock b/tools/cot_dt2c/poetry.lock
new file mode 100644
index 00000000..df58d54c
--- /dev/null
+++ b/tools/cot_dt2c/poetry.lock
@@ -0,0 +1,334 @@
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+
+[[package]]
+name = "atomicwrites"
+version = "1.4.1"
+description = "Atomic file writes."
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+    {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"},
+]
+
+[[package]]
+name = "attrs"
+version = "24.2.0"
+description = "Classes Without Boilerplate"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"},
+    {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"},
+]
+
+[package.extras]
+benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
+tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
+
+[[package]]
+name = "click"
+version = "8.1.7"
+description = "Composable command line interface toolkit"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
+    {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "igraph"
+version = "0.11.6"
+description = "High performance graph data structures and algorithms"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "igraph-0.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3f8b837181e8e87676be3873ce87cc92cc234efd58a2da2f6b4e050db150fcf4"},
+    {file = "igraph-0.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:245c4b7d7657849eff80416f5df4525c8fc44c74a981ee4d44f0ef2612c3bada"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdb7be3d165073c0136295c0808e9edc57ba096cdb26e94086abb04561f7a292"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58974e20df2986a1ae52a16e51ecb387cc0cbeb41c5c0ddff4d373a1bbf1d9c5"},
+    {file = "igraph-0.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bef14de5e8ab70724a43808b1ed14aaa6fe1002f87e592289027a3827a8f44a"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:86c1e98de2e32d074df8510bf18abfa1f4c5fda4cb28a009985a5d746b0c0125"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ebc5b3d702158abeb2e4d2414374586a2b932e1a07e48352b470600e1733d528"},
+    {file = "igraph-0.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0efe6d0fb22d3987a800eb3857ed04df9eb4c5dddd0998be05232cb646f1c337"},
+    {file = "igraph-0.11.6-cp38-cp38-win32.whl", hash = "sha256:f4e68b27497b1c8ada2fb2bc35ef3fa7b0d72e84306b3d648d3de240fc618c32"},
+    {file = "igraph-0.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:5665b33dfbfca5f54ce9b4fea6b97903bd0e99fb1b02acf5e57e600bdfa5a355"},
+    {file = "igraph-0.11.6-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8aabef03d787b519d1075dfc0da4a1109fb113b941334883e3e7947ac30a459e"},
+    {file = "igraph-0.11.6-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1f2cc4a518d99cdf6cae514f85e93e56852bc8c325b3abb96037d1d690b5975f"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e859238be52ab8ccc614d18f9362942bc88ce543afc12548f81ae99b10801d"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d61fbe5e85eb4ae9efe08c461f9bdeedb02a2b5739fbc223d324a71f40a28be2"},
+    {file = "igraph-0.11.6-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6620ba39df29fd42151becf82309b54e57148233c9c3ef890eed62e25eed8a5"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59666589bb3d07f310cda2c5106a8adeeb77c2ef27fecf1c6438b6091f4ca69d"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:8750b6d6caebf199cf7dc41c931f58e330153779707391e30f0a29f02666fb6e"},
+    {file = "igraph-0.11.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:967d6f2c30fe94317da15e459374d0fb8ca3e56020412f201ecd07dd5b5352f2"},
+    {file = "igraph-0.11.6-cp39-abi3-win32.whl", hash = "sha256:9744f95a67319eb6cb487ceabf30f5d7940de34bada51f0ba63adbd23e0f94ad"},
+    {file = "igraph-0.11.6-cp39-abi3-win_amd64.whl", hash = "sha256:b80e69eb11faa9c57330a9ffebdde5808966efe1c1f638d4d4827ea04df7aca8"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0329c16092e2ea7930d5f8368666ce7cb704900cc0ea04e4afe9ea1dd46e44af"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:21752313f449bd8688e5688e95ea7231cea5e9199c7162535029be0d9af848ac"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea25e136c6c4161f53ff58868b23ff6c845193050ab0e502236d68e5d4174e32"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac84433a03aef15e4b810010b08882b09854a3669450ccf31e392dbe295d2a66"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac697a44e3573169fa2b28c9c37dcf9cf01e0f558b845dd7123860d4c7c8fb89"},
+    {file = "igraph-0.11.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bdeae8bf35316eb1fb27bf667dcf5ecf5fcfb0b8f51831bc1b00c39c09c2d73b"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ad7e4aa442935de72554b96733bf6d7f09eac5cee97988a2562bdd3ca173cfa3"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d2818780358a686178866d01568b9df1f29678581734ad7a78882bab54df004"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2352276a20d979f1dea360af4202bb9f0c9a7d2c77f51815c0e625165e82013d"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:687fdab543b507d622fa3043f4227e5b26dc61dcf8ff8c0919fccddcc655f8b8"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f7f8214cd48c9a4d97f7346a4152ba2d4ac95fb5ee0df4ecf224fce4ba3d14"},
+    {file = "igraph-0.11.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2b9cc69ede53f76ffae03b066609aa90184dd68ef15da8c104a97cebb9210838"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:591e1e447c3f0092daf7613a3eaedab83f9a0b0adbaf7702724c5117ded038a5"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ca558eb331bc687bc33e5cd23717e22676e9412f8cda3a31d30c996a0487610d"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf43c30e08debb087c9e3da69aa5cf1b6732968da34d55a614e3421b9a452146"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d38e8d7db72b187d9d2211d0d06b3271fa9f32b04d49d789e2859b5480db0d0"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a318b059051ff78144a1c3cb880f4d933c812bcdb3d833a49cd7168d0427672"},
+    {file = "igraph-0.11.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2c54027add809b3c5b6685b8deca4ea4763fd000b9ea45c7ee46b7c9d61ff15e"},
+    {file = "igraph-0.11.6.tar.gz", hash = "sha256:837f233256c3319f2a35a6a80d94eafe47b43791ef4c6f9e9871061341ac8e28"},
+]
+
+[package.dependencies]
+texttable = ">=1.6.2"
+
+[package.extras]
+cairo = ["cairocffi (>=1.2.0)"]
+doc = ["Sphinx (>=7.0.0)", "pydoctor (>=23.4.0)", "sphinx-gallery (>=0.14.0)", "sphinx-rtd-theme (>=1.3.0)"]
+matplotlib = ["matplotlib (>=3.6.0)"]
+plotly = ["plotly (>=5.3.0)"]
+plotting = ["cairocffi (>=1.2.0)"]
+test = ["Pillow (>=9)", "cairocffi (>=1.2.0)", "matplotlib (>=3.6.0)", "networkx (>=2.5)", "numpy (>=1.19.0)", "pandas (>=1.1.0)", "plotly (>=5.3.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "scipy (>=1.5.0)"]
+test-musl = ["cairocffi (>=1.2.0)", "networkx (>=2.5)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)"]
+
+[[package]]
+name = "iniconfig"
+version = "2.0.0"
+description = "brain-dead simple config-ini parsing"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
+    {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
+]
+
+[[package]]
+name = "mypy"
+version = "0.910"
+description = "Optional static typing for Python"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"},
+    {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"},
+    {file = "mypy-0.910-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9"},
+    {file = "mypy-0.910-cp35-cp35m-win_amd64.whl", hash = "sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e"},
+    {file = "mypy-0.910-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921"},
+    {file = "mypy-0.910-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6"},
+    {file = "mypy-0.910-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212"},
+    {file = "mypy-0.910-cp36-cp36m-win_amd64.whl", hash = "sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885"},
+    {file = "mypy-0.910-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0"},
+    {file = "mypy-0.910-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de"},
+    {file = "mypy-0.910-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703"},
+    {file = "mypy-0.910-cp37-cp37m-win_amd64.whl", hash = "sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a"},
+    {file = "mypy-0.910-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504"},
+    {file = "mypy-0.910-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9"},
+    {file = "mypy-0.910-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072"},
+    {file = "mypy-0.910-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811"},
+    {file = "mypy-0.910-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e"},
+    {file = "mypy-0.910-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b"},
+    {file = "mypy-0.910-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2"},
+    {file = "mypy-0.910-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97"},
+    {file = "mypy-0.910-cp39-cp39-win_amd64.whl", hash = "sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8"},
+    {file = "mypy-0.910-py3-none-any.whl", hash = "sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"},
+    {file = "mypy-0.910.tar.gz", hash = "sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150"},
+]
+
+[package.dependencies]
+mypy-extensions = ">=0.4.3,<0.5.0"
+toml = "*"
+typing-extensions = ">=3.7.4"
+
+[package.extras]
+dmypy = ["psutil (>=4.0)"]
+python2 = ["typed-ast (>=1.4.0,<1.5.0)"]
+
+[[package]]
+name = "mypy-extensions"
+version = "0.4.4"
+description = "Experimental type system extensions for programs checked with the mypy typechecker."
+optional = false
+python-versions = ">=2.7"
+files = [
+    {file = "mypy_extensions-0.4.4.tar.gz", hash = "sha256:c8b707883a96efe9b4bb3aaf0dcc07e7e217d7d8368eec4db4049ee9e142f4fd"},
+]
+
+[[package]]
+name = "packaging"
+version = "24.1"
+description = "Core utilities for Python packages"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
+    {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
+]
+
+[[package]]
+name = "plotly"
+version = "5.23.0"
+description = "An open-source, interactive data visualization library for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "plotly-5.23.0-py3-none-any.whl", hash = "sha256:76cbe78f75eddc10c56f5a4ee3e7ccaade7c0a57465546f02098c0caed6c2d1a"},
+    {file = "plotly-5.23.0.tar.gz", hash = "sha256:89e57d003a116303a34de6700862391367dd564222ab71f8531df70279fc0193"},
+]
+
+[package.dependencies]
+packaging = "*"
+tenacity = ">=6.2.0"
+
+[[package]]
+name = "pluggy"
+version = "1.5.0"
+description = "plugin and hook calling mechanisms for python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
+    {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
+]
+
+[package.extras]
+dev = ["pre-commit", "tox"]
+testing = ["pytest", "pytest-benchmark"]
+
+[[package]]
+name = "py"
+version = "1.11.0"
+description = "library with cross-python path, ini-parsing, io, code, log facilities"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+    {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
+    {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
+]
+
+[[package]]
+name = "pydevicetree"
+version = "0.0.13"
+description = "A library for parsing Devicetree Source v1"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "pydevicetree-0.0.13-py3-none-any.whl", hash = "sha256:d61c695cec925b90a8b5740053f4b604e51154a9b36e62a2f12ed9ceaf2f8c38"},
+    {file = "pydevicetree-0.0.13.tar.gz", hash = "sha256:5700c05df89bad8fd729c11aa6f764a3323bcb3796f13b32481ae34445cfc1b7"},
+]
+
+[package.dependencies]
+pyparsing = "*"
+
+[[package]]
+name = "pyparsing"
+version = "3.1.2"
+description = "pyparsing module - Classes and methods to define and execute parsing grammars"
+optional = false
+python-versions = ">=3.6.8"
+files = [
+    {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"},
+    {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"},
+]
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
+
+[[package]]
+name = "pytest"
+version = "6.2.5"
+description = "pytest: simple powerful testing with Python"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
+    {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
+]
+
+[package.dependencies]
+atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
+attrs = ">=19.2.0"
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+iniconfig = "*"
+packaging = "*"
+pluggy = ">=0.12,<2.0"
+py = ">=1.8.2"
+toml = "*"
+
+[package.extras]
+testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
+
+[[package]]
+name = "tenacity"
+version = "9.0.0"
+description = "Retry code until it succeeds"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"},
+    {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"},
+]
+
+[package.extras]
+doc = ["reno", "sphinx"]
+test = ["pytest", "tornado (>=4.5)", "typeguard"]
+
+[[package]]
+name = "texttable"
+version = "1.7.0"
+description = "module to create simple ASCII tables"
+optional = false
+python-versions = "*"
+files = [
+    {file = "texttable-1.7.0-py2.py3-none-any.whl", hash = "sha256:72227d592c82b3d7f672731ae73e4d1f88cd8e2ef5b075a7a7f01a23a3743917"},
+    {file = "texttable-1.7.0.tar.gz", hash = "sha256:2d2068fb55115807d3ac77a4ca68fa48803e84ebb0ee2340f858107a36522638"},
+]
+
+[[package]]
+name = "toml"
+version = "0.10.2"
+description = "Python Library for Tom's Obvious, Minimal Language"
+optional = false
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
+    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.12.2"
+description = "Backported and Experimental Type Hints for Python 3.8+"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
+    {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
+]
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.8"
+content-hash = "afa5cb49be96467a848bab753a630c6f5ec42d6750d67d29920c3e3971774e36"
diff --git a/tools/cot_dt2c/pyproject.toml b/tools/cot_dt2c/pyproject.toml
new file mode 100644
index 00000000..73251d7e
--- /dev/null
+++ b/tools/cot_dt2c/pyproject.toml
@@ -0,0 +1,63 @@
+# Poetry pyproject.toml: https://python-poetry.org/docs/pyproject/
+[build-system]
+requires = ["poetry_core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"
+
+[tool.poetry]
+name = "cot_dt2c"
+version = "0.1.0"
+description = "CoT-dt2c Tool is a python script to convert CoT DT file into corresponding C file"
+authors = ["Arm Ltd <tf-a@lists.trustedfirmware.org>"]
+license = "BSD-3"
+repository = "https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/"
+homepage = "https://trustedfirmware-a.readthedocs.io/en/latest/index.html"
+
+# Pypi classifiers: https://pypi.org/classifiers/
+classifiers = [
+  "Development Status :: 3 - Alpha",
+  "Intended Audience :: Developers",
+  "Operating System :: OS Independent",
+  "Topic :: Software Development :: Libraries :: Python Modules",
+  "License :: OSI Approved :: BSD License",
+  "Programming Language :: Python :: 3",
+  "Programming Language :: Python :: 3.8",
+  "Programming Language :: Python :: 3.9",
+]
+
+
+[tool.poetry.dependencies]
+python = "^3.8"
+click = "^8.1.7"
+plotly = "^5.23.0"
+pydevicetree = "0.0.13"
+igraph = "^0.11.6"
+pyparsing = "^3.1.2"
+
+[tool.poetry.group.dev]
+optional = true
+
+[tool.poetry.group.dev.dependencies]
+mypy = "^0.910"
+pytest = "^6.2.5"
+
+[tool.mypy]
+# https://mypy.readthedocs.io/en/latest/config_file.html#using-a-pyproject-toml-file
+python_version = "3.8"
+pretty = true
+show_traceback = true
+color_output = true
+
+[[tool.mypy.overrides]]
+module = ["igraph", "pydevicetree", "pydevicetree.ast", "plotly", "plotly.graph_objects"]
+ignore_missing_imports = true
+
+[tool.coverage.run]
+source = ["tests"]
+
+[tool.coverage.paths]
+source = "cot_dt2c"
+
+[tool.poetry.scripts]
+# Entry points for the package https://python-poetry.org/docs/pyproject/#scripts
+# "cot-dt2c" = "cot_dt2c.__main__:cli"
+"cot-dt2c" = "cot_dt2c.__main__:cli"
diff --git a/tools/cot_dt2c/tests/test.dtsi b/tools/cot_dt2c/tests/test.dtsi
new file mode 100644
index 00000000..ee744e66
--- /dev/null
+++ b/tools/cot_dt2c/tests/test.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a valid CoT DT file
+ *
+ */
+
+#include <example/example.h>
+#include <example/example/example.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+#if defined(test)
+		example_cert: example_cert {
+			root-certificate;
+			image-id =<EXAMPLE_ID>;
+			antirollback-counter = <&example_ctr>;
+
+			example_hash: example_hash
+			{
+				oid = EXAMPLE_HASH_ID;
+			};
+		};
+#endif
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		example {
+			image-id = <EXAMPLE_ID>;
+			parent = <&example_cert>;
+			hash = <&example_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	example_ctr: example_ctr {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = CCA_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys {
+	example_pk: example_pk {
+		oid = EXAMPLE_PK_OID;
+	};
+};
diff --git a/tools/cot_dt2c/tests/test2.dtsi b/tools/cot_dt2c/tests/test2.dtsi
new file mode 100644
index 00000000..c4dbf833
--- /dev/null
+++ b/tools/cot_dt2c/tests/test2.dtsi
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a valid CoT DT file
+ *
+ */
+
+#if test
+#include <example/example.h>
+#include <example/example/example.h>
+#endif
+
+cot
+{
+	manifests
+	{
+		compatible = "arm, cert-descs";
+#if defined (test)
+		example_cert: example_cert
+		{
+			root-certificate;
+			image-id =<EXAMPLE_ID>;
+			antirollback-counter = <&example_ctr>;
+
+			example_hash: example_hash
+			{
+				oid = EXAMPLE_HASH_ID;
+			};
+
+		};
+#endif
+	};
+
+	images
+	{
+		compatible = "arm, img-descs";
+
+		example
+		{
+			image-id = <EXAMPLE_ID>;
+			parent = <&example_cert>;
+			hash = <&example_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters
+{
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	example_ctr: example_ctr
+	{
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = CCA_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys
+{
+	example_pk: example_pk
+	{
+		oid = EXAMPLE_PK_OID;
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_bracket.dtsi b/tools/cot_dt2c/tests/test_invalid_bracket.dtsi
new file mode 100644
index 00000000..9752ecfa
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_bracket.dtsi
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there is
+ * unmatching bracket
+ *
+ */
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		example_cert: example_cert {
+			root-certificate;
+			image-id =<2>;
+			antirollback-counter = <&example_ctr>;
+
+			example_hash: example_hash
+			{
+				oid = "1.3.6.1.4.1.4128.2100.101";
+			};
+
+		};
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		example {
+			image-id = <2>;
+			parent = <&example_cert>;
+			hash = <&example_hash>;
+		};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	example_ctr: example_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.3";
+	};
+};
+
+rot_keys {
+	example_pk: example_pk {
+		oid = "1.3.6.1.4.1.4128.2100.101";
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_missing_attribute.dtsi b/tools/cot_dt2c/tests/test_invalid_missing_attribute.dtsi
new file mode 100644
index 00000000..e35ab737
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_missing_attribute.dtsi
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there
+ * are image/certificate that missing mandantory attributes
+ *
+ */
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		cca_content_cert: cca_content_cert {
+			root-certificate;
+			antirollback-counter = <&cca_nv_ctr>;
+
+			hw_config_hash: hw_config_hash {
+			};
+
+			soc_fw_config_hash: soc_fw_config_hash {
+				oid = "1.3.6.1.4.1.4128.2100.604";
+			};
+		};
+
+		plat_key_cert: plat_key_cert {
+			root-certificate;
+			image-id = <38>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			plat_pk: plat_pk {
+				oid = "1.3.6.1.4.1.4128.2100.1105";
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			image-id = <15>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = "1.3.6.1.4.1.4128.2100.1201";
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid =  "1.3.6.1.4.1.4128.2100.1202";
+			};
+		};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <23>;
+			hash = <&hw_config_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <25>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <5>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <27>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_fw_config_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	cca_nv_ctr: cca_nv_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.3";
+	};
+
+	trusted_nv_ctr: trusted_nv_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.1";
+	};
+
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
+		id  = <1>;
+		oid = "1.3.6.1.4.1.4128.2100.2";
+	};
+};
+
+rot_keys {
+	swd_rot_pk: swd_rot_pk {
+		oid = "1.3.6.1.4.1.4128.2100.1103";
+	};
+	prot_pk: prot_pk {
+		oid = "1.3.6.1.4.1.4128.2100.1102";
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_missing_ctr.dtsi b/tools/cot_dt2c/tests/test_invalid_missing_ctr.dtsi
new file mode 100644
index 00000000..c572b1af
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_missing_ctr.dtsi
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there
+ * are image/certificate that missing definition of
+ * nv counters
+ *
+ */
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		example_cert: example_cert {
+			root-certificate;
+			image-id =<2>;
+			signing-key = <&swd_rot_pk>;
+			antirollback-counter = <&example_ctr>;
+
+			example_hash: example_hash
+			{
+				oid = "1.3.6.1.4.1.4128.2100.104";
+			};
+
+		};
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		example {
+			image-id = <2>;
+			parent = <&example_cert>;
+			hash = <&example_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+};
+
+rot_keys {
+	example_pk: example_pk {
+		oid = "1.3.6.1.4.1.4128.2100.104";
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_missing_root.dtsi b/tools/cot_dt2c/tests/test_invalid_missing_root.dtsi
new file mode 100644
index 00000000..465a4c6b
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_missing_root.dtsi
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there
+ * are image/certificate that missing root certificate
+ *
+ */
+
+#include <tools_share/cca_oid.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <common/nv_cntr_ids.h>
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		core_swd_key_cert: core_swd_key_cert {
+			image-id = <CORE_SWD_KEY_CERT_ID>;
+			signing-key = <&swd_rot_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			core_swd_pk: core_swd_pk {
+				oid = CORE_SWD_PK_OID;
+			};
+		};
+
+		trusted_os_fw_content_cert: trusted_os_fw_content_cert {
+			image-id = <TRUSTED_OS_FW_CONTENT_CERT_ID>;
+			parent = <&core_swd_key_cert>;
+			signing-key = <&core_swd_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			tos_fw_hash: tos_fw_hash {
+				oid = TRUSTED_OS_FW_HASH_OID;
+			};
+			tos_fw_config_hash: tos_fw_config_hash {
+				oid = TRUSTED_OS_FW_CONFIG_HASH_OID;
+			};
+		};
+
+		plat_key_cert: plat_key_cert {
+			image-id = <PLAT_KEY_CERT_ID>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			plat_pk: plat_pk {
+				oid = PLAT_PK_OID;
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			parent = <&plat_key_cert>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID;
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid = NON_TRUSTED_FW_CONFIG_HASH_OID;
+			};
+		};
+
+#if defined(SPD_spmd)
+		sip_sp_content_cert: sip_sp_content_cert {
+			image-id = <SIP_SP_CONTENT_CERT_ID>;
+			parent = <&core_swd_key_cert>;
+			signing-key = <&core_swd_pk>;
+			antirollback-counter = <&trusted_nv_ctr>;
+
+			sp_pkg1_hash: sp_pkg1_hash {
+				oid = SP_PKG1_HASH_OID;
+			};
+			sp_pkg2_hash: sp_pkg2_hash {
+				oid = SP_PKG2_HASH_OID;
+			};
+			sp_pkg3_hash: sp_pkg3_hash {
+				oid = SP_PKG3_HASH_OID;
+			};
+			sp_pkg4_hash: sp_pkg4_hash {
+				oid = SP_PKG4_HASH_OID;
+			};
+		};
+
+		plat_sp_content_cert: plat_sp_content_cert {
+			image-id = <PLAT_SP_CONTENT_CERT_ID>;
+			parent = <&plat_key_cert>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			sp_pkg5_hash: sp_pkg5_hash {
+				oid = SP_PKG5_HASH_OID;
+			};
+			sp_pkg6_hash: sp_pkg6_hash {
+				oid = SP_PKG6_HASH_OID;
+			};
+			sp_pkg7_hash: sp_pkg7_hash {
+				oid = SP_PKG7_HASH_OID;
+			};
+			sp_pkg8_hash: sp_pkg8_hash {
+				oid = SP_PKG8_HASH_OID;
+			};
+		};
+#endif
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <HW_CONFIG_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		bl31_image {
+			image-id = <BL31_IMAGE_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <SOC_FW_CONFIG_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		rmm_image {
+			image-id = <RMM_IMAGE_ID>;
+			parent = <&cca_content_cert>;
+			hash = <&rmm_hash>;
+		};
+
+		bl32_image {
+			image-id = <BL32_IMAGE_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_hash>;
+		};
+
+		tos_fw_config {
+			image-id = <TOS_FW_CONFIG_ID>;
+			parent = <&trusted_os_fw_content_cert>;
+			hash = <&tos_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <BL33_IMAGE_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <NT_FW_CONFIG_ID>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_fw_config_hash>;
+		};
+
+#if defined(SPD_spmd)
+		sp_pkg1 {
+			image-id = <SP_PKG1_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg1_hash>;
+		};
+
+		sp_pkg2 {
+			image-id = <SP_PKG2_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg2_hash>;
+		};
+
+		sp_pkg3 {
+			image-id = <SP_PKG3_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg3_hash>;
+		};
+
+		sp_pkg4 {
+			image-id = <SP_PKG4_ID>;
+			parent = <&sip_sp_content_cert>;
+			hash = <&sp_pkg4_hash>;
+		};
+
+		sp_pkg5 {
+			image-id = <SP_PKG5_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg5_hash>;
+		};
+
+		sp_pkg6 {
+			image-id = <SP_PKG6_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg6_hash>;
+		};
+
+		sp_pkg7 {
+			image-id = <SP_PKG7_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg7_hash>;
+		};
+
+		sp_pkg8 {
+			image-id = <SP_PKG8_ID>;
+			parent = <&plat_sp_content_cert>;
+			hash = <&sp_pkg8_hash>;
+		};
+#endif
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	cca_nv_ctr: cca_nv_ctr {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = CCA_FW_NVCOUNTER_OID;
+	};
+
+	trusted_nv_ctr: trusted_nv_ctr {
+		id  = <TRUSTED_NV_CTR_ID>;
+		oid = TRUSTED_FW_NVCOUNTER_OID;
+	};
+
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
+		id  = <NON_TRUSTED_NV_CTR_ID>;
+		oid = NON_TRUSTED_FW_NVCOUNTER_OID;
+	};
+};
+
+rot_keys {
+	swd_rot_pk: swd_rot_pk {
+		oid = SWD_ROT_PK_OID;
+	};
+	prot_pk: prot_pk {
+		oid = PROT_PK_OID;
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_invalid_undefined_parent.dtsi b/tools/cot_dt2c/tests/test_invalid_undefined_parent.dtsi
new file mode 100644
index 00000000..b6056caf
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_invalid_undefined_parent.dtsi
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file provide a malformed CoT DT file that there
+ * are image/certificate that points to invalid parent
+ *
+ */
+
+cot {
+	manifests {
+		compatible = "arm, cert-descs";
+
+		cca_content_cert: cca_content_cert {
+			root-certificate;
+			image-id =<36>;
+			antirollback-counter = <&cca_nv_ctr>;
+
+			hw_config_hash: hw_config_hash {
+				oid = "1.3.6.1.4.1.4128.2100.203";
+			};
+			soc_fw_config_hash: soc_fw_config_hash {
+				oid = "1.3.6.1.4.1.4128.2100.604";
+			};
+		};
+
+		plat_key_cert: plat_key_cert {
+			root-certificate;
+			image-id = <38>;
+			signing-key = <&prot_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			plat_pk: plat_pk {
+				oid =  "1.3.6.1.4.1.4128.2100.1105";
+			};
+		};
+
+		non_trusted_fw_content_cert: non_trusted_fw_content_cert {
+			image-id = <NON_TRUSTED_FW_CONTENT_CERT_ID>;
+			parent = <&wrong_parent>;
+			signing-key = <&plat_pk>;
+			antirollback-counter = <&non_trusted_nv_ctr>;
+
+			nt_world_bl_hash: nt_world_bl_hash {
+				oid = "1.3.6.1.4.1.4128.2100.1201";
+			};
+			nt_fw_config_hash: nt_fw_config_hash {
+				oid = "1.3.6.1.4.1.4128.2100.1202";
+			};
+		};
+
+	};
+
+	images {
+		compatible = "arm, img-descs";
+
+		hw_config {
+			image-id = <23>;
+			parent = <&cca_content_cert>;
+			hash = <&hw_config_hash>;
+		};
+
+		soc_fw_config {
+			image-id = <25>;
+			parent = <&cca_content_cert>;
+			hash = <&soc_fw_config_hash>;
+		};
+
+		bl33_image {
+			image-id = <5>;
+			parent = <&non_trusted_fw_content_cert>;
+			hash = <&nt_world_bl_hash>;
+		};
+
+		nt_fw_config {
+			image-id = <27>;
+			hash = <&nt_fw_config_hash>;
+		};
+	};
+};
+
+non_volatile_counters: non_volatile_counters {
+	compatible = "arm, non-volatile-counter";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	cca_nv_ctr: cca_nv_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.3";
+	};
+
+	trusted_nv_ctr: trusted_nv_ctr {
+		id  = <0>;
+		oid = "1.3.6.1.4.1.4128.2100.1";
+	};
+
+	non_trusted_nv_ctr: non_trusted_nv_ctr {
+		id  = <1>;
+		oid = "1.3.6.1.4.1.4128.2100.2";
+	};
+};
+
+rot_keys {
+	swd_rot_pk: swd_rot_pk {
+		oid = "1.3.6.1.4.1.4128.2100.1103";
+	};
+
+	prot_pk: prot_pk {
+		oid = "1.3.6.1.4.1.4128.2100.1102";
+	};
+};
diff --git a/tools/cot_dt2c/tests/test_util.py b/tools/cot_dt2c/tests/test_util.py
new file mode 100644
index 00000000..b8e44d47
--- /dev/null
+++ b/tools/cot_dt2c/tests/test_util.py
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import os
+import sys
+
+from cot_dt2c.cli import *
+from click.testing import CliRunner
+
+def get_script_path():
+    return os.path.dirname(os.path.realpath(sys.argv[0]))
+
+def test_convert():
+    runner = CliRunner()
+    test_file = get_script_path() + "/test.dtsi"
+    test_output = get_script_path() + "/test.c"
+
+    result = runner.invoke(convert_to_c, [test_file, test_output])
+    try:
+        assert result.output == ""
+    except:
+        print("test convert fail")
+
+    try:
+        os.remove(test_output)
+    except OSError:
+        pass
+
+if __name__=="__main__":
+    test_convert()
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index 924e5feb..50b0fa2f 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -1,21 +1,22 @@
 #
+# Copyright (c) 2024, Arm Limited. All rights reserved.
 # Copyright (c) 2019-2022, Linaro Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-V		?= 0
 BUILD_INFO	?= 1
 DEBUG		:= 0
 ENCTOOL		?= encrypt_fw${BIN_EXT}
 BINARY		:= $(notdir ${ENCTOOL})
 OPENSSL_DIR	:= /usr
 
-
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
+include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 OBJECTS := src/encrypt.o \
            src/cmd_opt.o \
@@ -36,11 +37,6 @@ else
   HOSTCCFLAGS += -O2 -DLOG_LEVEL=10
 endif
 endif
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
 
 HOSTCCFLAGS += ${DEFINES}
 # USING_OPENSSL3 flag will be added to the HOSTCCFLAGS variable with the proper
@@ -61,29 +57,25 @@ INC_DIR := -I ./include -I ../../include/tools_share -I ${OPENSSL_DIR}/include
 LIB_DIR := -L ${OPENSSL_DIR}/lib -L ${OPENSSL_DIR}
 LIB := -lssl -lcrypto
 
-HOSTCC ?= gcc
-
 .PHONY: all clean realclean --openssl
 
 all: --openssl ${BINARY}
 
 ${BINARY}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__;' | \
-                ${HOSTCC} -c ${HOSTCCFLAGS} -xc - -o src/build_msg.o
-	${Q}${HOSTCC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
 
 %.o: %.c
-	@echo "  HOSTCC  $<"
-	${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INC_DIR} $< -o $@
 
 --openssl:
 ifeq ($(DEBUG),1)
-	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+	$(s)echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
 
 clean:
-	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
+	$(call SHELL_DELETE_ALL,${OBJECTS})
 
 realclean: clean
 	$(call SHELL_DELETE,${BINARY})
diff --git a/tools/encrypt_fw/src/main.c b/tools/encrypt_fw/src/main.c
index 39b7af76..6e43e73a 100644
--- a/tools/encrypt_fw/src/main.c
+++ b/tools/encrypt_fw/src/main.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2019, Linaro Limited. All rights reserved.
  * Author: Sumit Garg <sumit.garg@linaro.org>
  *
@@ -25,8 +26,7 @@
 
 /* Global options */
 
-/* Info messages created in the Makefile */
-extern const char build_msg[];
+static const char build_msg[] = "Built : " __TIME__ ", " __DATE__;
 
 static char *key_algs_str[] = {
 	[KEY_ALG_GCM] = "gcm",
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index fda7c779..54dee87e 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,12 +7,13 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
 include ${MAKE_HELPERS_DIRECTORY}defaults.mk
+include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 FIPTOOL ?= fiptool${BIN_EXT}
 PROJECT := $(notdir ${FIPTOOL})
 OBJECTS := fiptool.o tbbr_config.o
-V ?= 0
 STATIC ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
@@ -52,14 +53,6 @@ endif # STATIC
 
 HOSTCCFLAGS += ${DEFINES}
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
-HOSTCC ?= gcc
-
 ifneq (${PLAT},)
 TF_PLATFORM_ROOT	:=	../../plat/
 include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
@@ -80,22 +73,22 @@ DEPS := $(patsubst %.o,%.d,$(OBJECTS))
 all: --openssl ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}${HOSTCC} ${OBJECTS} -o $@ $(LDOPTS)
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@ $(LDOPTS)
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} -MD -MP $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} -MD -MP $< -o $@
 
 -include $(DEPS)
 
 --openssl:
 ifeq ($(STATIC),0)
 ifeq ($(DEBUG),1)
-	@echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
+	$(s)echo "Selected OpenSSL version: ${OPENSSL_CURRENT_VER}"
 endif
 endif # STATIC
 
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 6c566ef0..27119a1a 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -1,12 +1,13 @@
 /*
- * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef _MSC_VER
+#ifdef __linux__
 #include <sys/mount.h>
 #endif
+
 #include <sys/types.h>
 #include <sys/stat.h>
 
diff --git a/plat/arm/board/juno/fip/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/arm/board/juno/plat_def_uuid_config.c
similarity index 100%
rename from plat/arm/board/juno/fip/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/arm/board/juno/plat_def_uuid_config.c
diff --git a/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
index fef2116e..5549b0d3 100644
--- a/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/arm/board/juno/plat_fiptool.mk
@@ -11,6 +11,6 @@ HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
 ifeq (${ETHOSN_NPU_TZMP1},1)
 HOSTCCFLAGS += -DETHOSN_NPU_TZMP1
 endif
-INCLUDE_PATHS += -I./ -I${PLAT_DIR}fip -I../../include/
-OBJECTS += ${PLAT_DIR}fip/plat_def_uuid_config.o
+INCLUDE_PATHS += -I./ -I../../plat/arm/board/juno/fip -I../../include
+OBJECTS += plat_fiptool/arm/board/juno/plat_def_uuid_config.o
 endif
diff --git a/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
index 903310b2..792593f3 100644
--- a/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
+++ b/tools/fiptool/plat_fiptool/arm/board/tc/plat_def_uuid_config.c
@@ -13,44 +13,44 @@
 
 toc_entry_t plat_def_toc_entries[] = {
 	{
-		.name = "RSS Firmware BL1_2 image",
-		.uuid = UUID_RSS_FIRMWARE_BL1_2,
-		.cmdline_name = "rss-bl1_2"
+		.name = "RSE Firmware BL1_2 image",
+		.uuid = UUID_RSE_FIRMWARE_BL1_2,
+		.cmdline_name = "rse-bl1_2"
 	},
 	{
-		.name = "RSS Firmware BL2 image",
-		.uuid = UUID_RSS_FIRMWARE_BL2,
-		.cmdline_name = "rss-bl2"
+		.name = "RSE Firmware BL2 image",
+		.uuid = UUID_RSE_FIRMWARE_BL2,
+		.cmdline_name = "rse-bl2"
 	},
 	{
-		.name = "RSS Firmware SCP BL1 image",
-		.uuid = UUID_RSS_FIRMWARE_SCP_BL1,
-		.cmdline_name = "rss-scp-bl1"
+		.name = "RSE Firmware SCP BL1 image",
+		.uuid = UUID_RSE_FIRMWARE_SCP_BL1,
+		.cmdline_name = "rse-scp-bl1"
 	},
 	{
-		.name = "RSS Firmware AP BL1 image",
-		.uuid = UUID_RSS_FIRMWARE_AP_BL1,
-		.cmdline_name = "rss-ap-bl1"
+		.name = "RSE Firmware AP BL1 image",
+		.uuid = UUID_RSE_FIRMWARE_AP_BL1,
+		.cmdline_name = "rse-ap-bl1"
 	},
 	{
-		.name = "RSS Firmware non-secure image",
-		.uuid = UUID_RSS_FIRMWARE_NS,
-		.cmdline_name = "rss-ns"
+		.name = "RSE Firmware non-secure image",
+		.uuid = UUID_RSE_FIRMWARE_NS,
+		.cmdline_name = "rse-ns"
 	},
 	{
-		.name = "RSS Firmware secure image",
-		.uuid = UUID_RSS_FIRMWARE_S,
-		.cmdline_name = "rss-s"
+		.name = "RSE Firmware secure image",
+		.uuid = UUID_RSE_FIRMWARE_S,
+		.cmdline_name = "rse-s"
 	},
 	{
-		.name = "RSS Firmware non-secure SIC tables",
-		.uuid = UUID_RSS_SIC_TABLES_NS,
-		.cmdline_name = "rss-sic-tables-ns"
+		.name = "RSE Firmware non-secure SIC tables",
+		.uuid = UUID_RSE_SIC_TABLES_NS,
+		.cmdline_name = "rse-sic-tables-ns"
 	},
 	{
-		.name = "RSS Firmware secure SIC tables",
-		.uuid = UUID_RSS_SIC_TABLES_S,
-		.cmdline_name = "rss-sic-tables-s"
+		.name = "RSE Firmware secure SIC tables",
+		.uuid = UUID_RSE_SIC_TABLES_S,
+		.cmdline_name = "rse-sic-tables-s"
 	},
 
 	{
diff --git a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c b/tools/fiptool/plat_fiptool/st/plat_def_uuid_config.c
similarity index 71%
rename from tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
rename to tools/fiptool/plat_fiptool/st/plat_def_uuid_config.c
index 4df41446..8d3329fc 100644
--- a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_def_uuid_config.c
+++ b/tools/fiptool/plat_fiptool/st/plat_def_uuid_config.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2024, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,11 @@
 #include "tbbr_config.h"
 
 toc_entry_t plat_def_toc_entries[] = {
+	{
+		.name = "DDR_FW",
+		.uuid = UUID_DDR_FW,
+		.cmdline_name = "ddr-fw"
+	},
 	{
 		.name = "STM32MP CONFIG CERT",
 		.uuid = UUID_STM32MP_CONFIG_CERT,
diff --git a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk b/tools/fiptool/plat_fiptool/st/plat_fiptool.mk
similarity index 60%
rename from tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
rename to tools/fiptool/plat_fiptool/st/plat_fiptool.mk
index 1ba47c1f..494715cc 100644
--- a/tools/fiptool/plat_fiptool/st/stm32mp1/plat_fiptool.mk
+++ b/tools/fiptool/plat_fiptool/st/plat_fiptool.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
+# Copyright (c) 2021-2024, STMicroelectronics - All Rights Reserved
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,15 +9,15 @@
 # in the plat_def_toc_entries[].
 PLAT_DEF_UUID_FILE_NAME	:= plat_def_uuid_config
 
-INCLUDE_PATHS		+= -I${PLAT_DIR}/include -I./
+INCLUDE_PATHS		+= -I../../plat/st/common/include -I./
 
 PLAT_DEF_UUID		:= yes
 
 ifeq (${PLAT_DEF_UUID},yes)
 HOSTCCFLAGS += -DPLAT_DEF_FIP_UUID
 
-${PLAT_DEF_UUID_FILE_NAME}.o: plat_fiptool/st/stm32mp1/${PLAT_DEF_UUID_FILE_NAME}.c
-	${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
+${PLAT_DEF_UUID_FILE_NAME}.o: plat_fiptool/st/${PLAT_DEF_UUID_FILE_NAME}.c
+	$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 PLAT_OBJECTS += ${PLAT_DEF_UUID_FILE_NAME}.o
 endif
diff --git a/tools/marvell/doimage/Makefile b/tools/marvell/doimage/Makefile
index 9f0d89d3..a4f7a1d8 100644
--- a/tools/marvell/doimage/Makefile
+++ b/tools/marvell/doimage/Makefile
@@ -4,6 +4,9 @@
 # SPDX-License-Identifier:     BSD-3-Clause
 # https://spdx.org/licenses
 
+include ../../../make_helpers/common.mk
+include ../../../make_helpers/toolchain.mk
+
 PROJECT = doimage
 OBJECTS = doimage.o
 
@@ -25,7 +28,6 @@ HOSTCCFLAGS += ${DOIMAGE_CC_FLAGS}
 # could get pulled in from firmware tree.
 INCLUDE_PATHS = -I.
 
-HOSTCC ?= gcc
 RM := rm -rf
 
 .PHONY: all clean
@@ -33,16 +35,16 @@ RM := rm -rf
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}${HOSTCC} ${OBJECTS} ${DOIMAGE_LD_FLAGS} -o $@
-	@echo
-	@echo "Built $@ successfully"
-	@echo
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} ${DOIMAGE_LD_FLAGS} -o $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}${HOSTCC} -c ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
-	${Q}${RM} ${PROJECT}
-	${Q}${RM} ${OBJECTS}
+	$(q)${RM} ${PROJECT}
+	$(q)${RM} ${OBJECTS}
diff --git a/tools/marvell/doimage/doimage.c b/tools/marvell/doimage/doimage.c
index 513f33f3..1f0985c4 100644
--- a/tools/marvell/doimage/doimage.c
+++ b/tools/marvell/doimage/doimage.c
@@ -18,6 +18,7 @@
 #include <libconfig.h>	/* for parsing config file */
 
 /* mbedTLS stuff */
+#include <mbedtls/version.h>
 #if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ENTROPY_C) && \
 	defined(MBEDTLS_SHA256_C) && \
 	defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_FS_IO) && \
@@ -28,7 +29,6 @@
 #include <mbedtls/md.h>
 #include <mbedtls/pk.h>
 #include <mbedtls/sha256.h>
-#include <mbedtls/version.h>
 #include <mbedtls/x509.h>
 #else
 #error "Bad mbedTLS configuration!"
diff --git a/tools/memory/memory/mapparser.py b/tools/memory/memory/mapparser.py
index b1a4b4c5..ce4cc311 100644
--- a/tools/memory/memory/mapparser.py
+++ b/tools/memory/memory/mapparser.py
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -57,7 +57,7 @@ class TfaMapParser:
 
             if "start" and "length" and "end" in memory_layout[region]:
                 memory_layout[region]["limit"] = (
-                    memory_layout[region]["end"]
+                    memory_layout[region]["start"]
                     + memory_layout[region]["length"]
                 )
                 memory_layout[region]["free"] = (
diff --git a/tools/memory/memory/memmap.py b/tools/memory/memory/memmap.py
index 99149b54..34f5069c 100755
--- a/tools/memory/memory/memmap.py
+++ b/tools/memory/memory/memmap.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 
 #
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -99,7 +99,7 @@ def main(
 
     if symbols:
         expr = (
-            r"(.*)(TEXT|BSS|RODATA|STACKS|_OPS|PMF|XLAT|GOT|FCONF"
+            r"(.*)(TEXT|BSS|RO|RODATA|STACKS|_OPS|PMF|XLAT|GOT|FCONF|RELA"
             r"|R.M)(.*)(START|UNALIGNED|END)__$"
         )
         printer.print_symbol_table(
diff --git a/tools/nxp/cert_create_helper/src/pdef_tbb_key.c b/tools/nxp/cert_create_helper/src/pdef_tbb_key.c
index cf2ebda3..cd48866c 100644
--- a/tools/nxp/cert_create_helper/src/pdef_tbb_key.c
+++ b/tools/nxp/cert_create_helper/src/pdef_tbb_key.c
@@ -6,7 +6,7 @@
 
 #include <pdef_tbb_key.h>
 
-static key_t pdef_tbb_keys[] = {
+static cert_key_t pdef_tbb_keys[] = {
 	[DDR_FW_CONTENT_KEY - DDR_FW_CONTENT_KEY] = {
 		.id = DDR_FW_CONTENT_KEY,
 		.opt = "ddr-fw-key",
diff --git a/tools/nxp/create_pbl/Makefile b/tools/nxp/create_pbl/Makefile
index f971a746..22aa921d 100644
--- a/tools/nxp/create_pbl/Makefile
+++ b/tools/nxp/create_pbl/Makefile
@@ -7,12 +7,13 @@
 MAKE_HELPERS_DIRECTORY := ../../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
+include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 PROJECT_1 := create_pbl${BIN_EXT}
 OBJECTS_1 := create_pbl.o
 PROJECT_2 := byte_swap${BIN_EXT}
 OBJECTS_2 := byte_swap.o
-V ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
 CFLAGS := -Wall -Werror -pedantic -std=c99
@@ -23,38 +24,29 @@ else
 endif
 LDLIBS :=
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 INCLUDE_PATHS :=
 
-HOSTCC ?= gcc
-CC = gcc
-
 .PHONY: all clean distclean
 
 all: create_pbl byte_swap
 
 ${PROJECT_1}: ${OBJECTS_1} Makefile
-	@echo "  LD      $@"
-	${Q}${HOSTCC} ${OBJECTS_1} -o $@ ${LDLIBS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  LD      $@"
+	$(q)$(host-cc) ${OBJECTS_1} -o $@ ${LDLIBS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 ${PROJECT_2}: ${OBJECTS_2} Makefile
-	@echo "  LD      $@"
-	${Q}${HOSTCC} ${OBJECTS_2} -o $@ ${LDLIBS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  LD      $@"
+	$(q)$(host-cc) ${OBJECTS_2} -o $@ ${LDLIBS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c %.h Makefile
-	@echo "  CC      $<"
-	${Q}${HOSTCC} -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
+	$(s)echo "  CC      $<"
+	$(q)$(host-cc) -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT_1} ${OBJECTS_1})
diff --git a/tools/nxp/create_pbl/pbl_ch2.mk b/tools/nxp/create_pbl/pbl_ch2.mk
index e6f1d8b9..bf05a12d 100644
--- a/tools/nxp/create_pbl/pbl_ch2.mk
+++ b/tools/nxp/create_pbl/pbl_ch2.mk
@@ -15,12 +15,12 @@ pbl:	${BUILD_PLAT}/bl2.bin
 ifeq ($(SECURE_BOOT),yes)
 pbl: ${BUILD_PLAT}/bl2.bin
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
 	# Generate header for bl2.bin
-	$(Q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
+	$(q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
 	# Compile create_pbl tool
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
 	# Add bl2.bin to RCW
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE}\
 			-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl ;\
@@ -31,7 +31,7 @@ else
 # Swapping of RCW is required for QSPi Chassis 2 devices
 ifeq (${BOOT_MODE}, qspi)
 ifeq ($(SWAP),1)
-	${Q}echo "Byteswapping RCW for QSPI"
+	$(s)echo "Byteswapping RCW for QSPI"
 	${BYTE_SWAP} ${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl;
 endif # SWAP
 endif # BOOT_MODE
@@ -39,22 +39,19 @@ endif # BOOT_MODE
 endif
 else  # NON SECURE_BOOT
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
 	# -a option appends the image for Chassis 3 devices in case of non secure boot
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE} \
 	-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl ;
 # Swapping of RCW is required for QSPi Chassis 2 devices
 ifeq (${BOOT_MODE}, qspi)
 ifeq ($(SWAP),1)
-	${Q}echo "Byteswapping RCW for QSPI"
+	$(s)echo "Byteswapping RCW for QSPI"
 	${BYTE_SWAP} ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl;
 endif # SWAP
 endif # BOOT_MODE
 	cd ${CREATE_PBL_TOOL_PATH}; ${MAKE} clean ; cd -;
 endif
 endif # SECURE_BOOT
-
-
-
diff --git a/tools/nxp/create_pbl/pbl_ch3.mk b/tools/nxp/create_pbl/pbl_ch3.mk
index 92834741..15129e40 100644
--- a/tools/nxp/create_pbl/pbl_ch3.mk
+++ b/tools/nxp/create_pbl/pbl_ch3.mk
@@ -21,13 +21,13 @@ pbl:	${BUILD_PLAT}/bl2.bin
 ifeq ($(SECURE_BOOT),yes)
 pbl: ${BUILD_PLAT}/bl2.bin
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
 	# Generate header for bl2.bin
-	$(Q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
+	$(q)$(CST_DIR)/create_hdr_isbc --in ${BUILD_PLAT}/bl2.bin --out ${BUILD_PLAT}/hdr_bl2 ${BL2_INPUT_FILE}
 
 	# Compile create_pbl tool
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};\
 
 	# Add Block Copy command for bl2.bin to RCW
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE}\
@@ -39,14 +39,14 @@ else
 			-o ${BUILD_PLAT}/rcw_sec.pbl
 
 	# Sign and add "Load Security Header command to PBI commands
-	$(Q)$(CST_DIR)/create_hdr_pbi --out ${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl --in ${BUILD_PLAT}/rcw_sec.pbl ${PBI_INPUT_FILE}
+	$(q)$(CST_DIR)/create_hdr_pbi --out ${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl --in ${BUILD_PLAT}/rcw_sec.pbl ${PBI_INPUT_FILE}
 
 	# Append the bl2_hdr to the RCW image
-	@echo "${bl2_hdr_loc}"
+	$(s)echo "${bl2_hdr_loc}"
 	dd if=${BUILD_PLAT}/hdr_bl2 of=${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl bs=1K seek=${bl2_hdr_loc}
 
 	# Append the bl2.bin to the RCW image
-	@echo "${bl2_loc}"
+	$(s)echo "${bl2_loc}"
 	dd if=${BUILD_PLAT}/bl2.bin of=${BUILD_PLAT}/bl2_${BOOT_MODE}_sec.pbl bs=1K seek=${bl2_loc}
 
 	rm ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl
@@ -54,16 +54,16 @@ else
 endif
 else  #SECURE_BOOT
 ifeq ($(RCW),"")
-	${Q}echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
+	$(s)echo "Platform ${PLAT} requires rcw file. Please set RCW to point to the right RCW file for boot mode ${BOOT_MODE}"
 else
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
+	$(q)${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${CREATE_PBL_TOOL_PATH};
 
 	# Add Block Copy command and populate boot loc ptrfor bl2.bin to RCW
 	${CREATE_PBL} -r ${RCW} -i ${BUILD_PLAT}/bl2.bin -b ${BOOT_MODE} -c ${SOC_NUM} -d ${BL2_BASE} -e ${BL2_BASE} \
 	-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl -f ${BL2_SRC_OFFSET};
 
 	# Append the bl2.bin to the RCW image
-	@echo "bl2_loc is ${bl2_loc} KB"
+	$(s)echo "bl2_loc is ${bl2_loc} KB"
 	dd if=${BUILD_PLAT}/bl2.bin of=${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl bs=1K seek=${bl2_loc}
 
 	cd ${CREATE_PBL_TOOL_PATH}; ${MAKE} clean ; cd -;
diff --git a/tools/renesas/rcar_layout_create/makefile b/tools/renesas/rcar_layout_create/makefile
index d5857549..7a64b190 100644
--- a/tools/renesas/rcar_layout_create/makefile
+++ b/tools/renesas/rcar_layout_create/makefile
@@ -1,9 +1,16 @@
 #
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+toolchains := aarch64
+
+include ../../../make_helpers/build-rules.mk
+include ../../../make_helpers/common.mk
+include ../../../make_helpers/toolchain.mk
+
 ###################################################
 # makefile
 ###################################################
@@ -67,16 +74,9 @@ $(eval $(call add_define,RCAR_VMA_ADJUST_ADDR))
 ###################################################
 
 #c compiler
-CC = $(CROSS_COMPILE)gcc
 CFLAGS += ${DEFINES}
 CFLAGS += -I../../include/lib/stdlib
 
-#Linker
-LD = $(CROSS_COMPILE)ld
-
-#objcopy
-objcopy = $(CROSS_COMPILE)objcopy
-
 #clean
 CL = rm -f
 
@@ -87,34 +87,38 @@ CL = rm -f
 # command
 
 .PHONY: all
-all: $(OUTPUT_FILE_SA0) $(OUTPUT_FILE_SA6)
+
+all: $(FILE_NAME_SA0).srec $(FILE_NAME_SA0).bin
+all: $(FILE_NAME_SA6).srec $(FILE_NAME_SA6).bin
+
 ###################################################
 # Linker
 ###################################################
-$(OUTPUT_FILE_SA0) : $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0)
-	$(LD) $(OBJ_FILE_SA0)		 	\
-	-T $(MEMORY_DEF_SA0)			\
-	-o $(OUTPUT_FILE_SA0)			\
-	-Map $(FILE_NAME_SA0).map 		\
 
-	$(objcopy) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
-	$(objcopy) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
+$(FILE_NAME_SA0).srec: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
+
+$(FILE_NAME_SA0).bin: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
+
+$(OUTPUT_FILE_SA0): $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0) | $$(@D)/
+	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
+
+$(FILE_NAME_SA6).srec: $(OUTPUT_FILE_SA6) | $$(@D)/
+	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
 
-$(OUTPUT_FILE_SA6) : $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6)
-	$(LD) $(OBJ_FILE_SA6)		 	\
-	-T $(MEMORY_DEF_SA6)			\
-	-o $(OUTPUT_FILE_SA6)			\
-	-Map $(FILE_NAME_SA6).map 		\
+$(FILE_NAME_SA6).bin: $(OUTPUT_FILE_SA6) | $$(@D)/
+	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin
 
-	$(objcopy) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
-	$(objcopy) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin
+$(OUTPUT_FILE_SA6): $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6) | $$(@D)/
+	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib -T $(MEMORY_DEF_SA6) -o $(OUTPUT_FILE_SA6) -Wl,-Map $(FILE_NAME_SA6).map
 
 ###################################################
 # Compile
 ###################################################
 
-%.o:../%.c
-	$(CC) -c -I $< -o $@
+%.o: %.c | $$(@D)/
+	$(aarch64-cc) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
 
 .PHONY: clean
 clean:
diff --git a/tools/renesas/rcar_layout_create/sa6.c b/tools/renesas/rcar_layout_create/sa6.c
index 8fafdade..58881f97 100644
--- a/tools/renesas/rcar_layout_create/sa6.c
+++ b/tools/renesas/rcar_layout_create/sa6.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -91,7 +91,7 @@
 #define RCAR_BL31DST_ADDRESS		(0x44000000U)
 #define RCAR_BL31DST_ADDRESSH		(0x00000000U)
 /* Destination size for BL31 */
-#define RCAR_BL31DST_SIZE		(0x00004000U)
+#define RCAR_BL31DST_SIZE		(0x0000F800U)
 /* Destination address for BL32 */
 #define RCAR_BL32DST_ADDRESS		(0x44100000U)
 #define RCAR_BL32DST_ADDRESSH		(0x00000000U)
diff --git a/tools/renesas/rzg_layout_create/makefile b/tools/renesas/rzg_layout_create/makefile
index 2d438b92..936420db 100644
--- a/tools/renesas/rzg_layout_create/makefile
+++ b/tools/renesas/rzg_layout_create/makefile
@@ -1,9 +1,16 @@
 #
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 # Copyright (c) 2020, Renesas Electronics Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+toolchains := aarch64
+
+include ../../../make_helpers/build-rules.mk
+include ../../../make_helpers/common.mk
+include ../../../make_helpers/toolchain.mk
+
 ###################################################
 # makefile
 ###################################################
@@ -62,18 +69,11 @@ $(eval $(call add_define,RCAR_VMA_ADJUST_ADDR))
 ###################################################
 
 #c compiler
-CC = $(CROSS_COMPILE)gcc
 CFLAGS += ${DEFINES}
 CFLAGS += -nostdinc \
 	  -I../../../include/lib/libc \
 	  -I../../../include/lib/libc/aarch64
 
-#Linker
-LD = $(CROSS_COMPILE)ld
-
-#objcopy
-objcopy = $(CROSS_COMPILE)objcopy
-
 #clean
 CL = rm -f
 
@@ -84,34 +84,38 @@ CL = rm -f
 # command
 
 .PHONY: all
-all: $(OUTPUT_FILE_SA0) $(OUTPUT_FILE_SA6)
+
+all: $(FILE_NAME_SA0).srec $(FILE_NAME_SA0).bin
+all: $(FILE_NAME_SA6).srec $(FILE_NAME_SA6).bin
+
 ###################################################
 # Linker
 ###################################################
-$(OUTPUT_FILE_SA0) : $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0)
-	$(LD) $(OBJ_FILE_SA0)		 	\
-	-T $(MEMORY_DEF_SA0)			\
-	-o $(OUTPUT_FILE_SA0)			\
-	-Map $(FILE_NAME_SA0).map 		\
 
-	$(objcopy) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
-	$(objcopy) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
+$(FILE_NAME_SA0).srec: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).srec
+
+$(FILE_NAME_SA0).bin: $(OUTPUT_FILE_SA0) | $$(@D)/
+	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA0) $(FILE_NAME_SA0).bin
+
+$(OUTPUT_FILE_SA0): $(MEMORY_DEF_SA0) $(OBJ_FILE_SA0) | $$(@D)/
+	$(aarch64-ld) $(OBJ_FILE_SA0) -nostdlib -T $(MEMORY_DEF_SA0) -o $(OUTPUT_FILE_SA0) -Wl,-Map $(FILE_NAME_SA0).map
+
+$(FILE_NAME_SA6).srec: $(OUTPUT_FILE_SA6) | $$(@D)/
+	$(aarch64-oc) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
 
-$(OUTPUT_FILE_SA6) : $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6)
-	$(LD) $(OBJ_FILE_SA6)		 	\
-	-T $(MEMORY_DEF_SA6)			\
-	-o $(OUTPUT_FILE_SA6)			\
-	-Map $(FILE_NAME_SA6).map 		\
+$(FILE_NAME_SA6).bin: $(OUTPUT_FILE_SA6) | $$(@D)/
+	$(aarch64-oc) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3 $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin
 
-	$(objcopy) -O srec --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).srec
-	$(objcopy) -O binary --adjust-vma=$(RCAR_VMA_ADJUST_ADDR) --srec-forceS3  $(OUTPUT_FILE_SA6) $(FILE_NAME_SA6).bin
+$(OUTPUT_FILE_SA6): $(MEMORY_DEF_SA6) $(OBJ_FILE_SA6) | $$(@D)/
+	$(aarch64-ld) $(OBJ_FILE_SA6) -nostdlib -T $(MEMORY_DEF_SA6) -o $(OUTPUT_FILE_SA6) -Wl,-Map $(FILE_NAME_SA6).map
 
 ###################################################
 # Compile
 ###################################################
 
-%.o:../%.c
-	$(CC) -c -I $< -o $@
+%.o: %.c | $$(@D)/
+	$(aarch64-cc) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
 
 .PHONY: clean
 clean:
diff --git a/tools/sptool/Makefile b/tools/sptool/Makefile
index 1fa85fb2..0da5c09c 100644
--- a/tools/sptool/Makefile
+++ b/tools/sptool/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,11 +7,12 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
+include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 SPTOOL  ?= sptool${BIN_EXT}
 PROJECT := $(notdir ${SPTOOL})
 OBJECTS := sptool.o
-V ?= 0
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99
@@ -21,30 +22,22 @@ else
   HOSTCCFLAGS += -O2
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
 INCLUDE_PATHS := -I../../include/tools_share
 
-HOSTCC ?= gcc
-
 .PHONY: all clean distclean
 
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}${HOSTCC} ${OBJECTS} -o $@ ${LDLIBS}
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@ ${LDLIBS}
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}${HOSTCC} -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${CPPFLAGS} ${HOSTCCFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index c69e0a73..1edb77d0 100644
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -1,5 +1,5 @@
 #!/usr/bin/python3
-# Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -136,7 +136,10 @@ def get_load_address(sp_layout, sp, args :dict):
     ''' Helper to fetch load-address from pm file listed in sp_layout.json'''
     with open(get_sp_manifest_full_path(sp_layout[sp], args), "r") as pm_f:
         load_address_lines = [l for l in pm_f if 'load-address' in l]
-    assert(len(load_address_lines) == 1)
+
+    if len(load_address_lines) != 1:
+        return None
+
     load_address_parsed = re.search("(0x[0-9a-f]+)", load_address_lines[0])
     return load_address_parsed.group(0)
 
@@ -240,7 +243,8 @@ def gen_fconf_fragment(sp_layout, sp, args: dict):
         else:
             load_address = get_load_address(sp_layout, sp, args)
 
-        f.write(
+        if load_address is not None:
+            f.write(
 f'''\
 {sp} {{
     uuid = "{uuid}";
@@ -249,6 +253,9 @@ f'''\
 }};
 
 ''')
+        else:
+            print("Warning: No load-address was found in the SP manifest.")
+
     return args
 
 def init_sp_actions(sys):
diff --git a/tools/stm32image/Makefile b/tools/stm32image/Makefile
index 9c9b7b5f..453daaeb 100644
--- a/tools/stm32image/Makefile
+++ b/tools/stm32image/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,10 +7,11 @@
 MAKE_HELPERS_DIRECTORY := ../../make_helpers/
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+include ${MAKE_HELPERS_DIRECTORY}common.mk
+include ${MAKE_HELPERS_DIRECTORY}toolchain.mk
 
 PROJECT := stm32image${BIN_EXT}
 OBJECTS := stm32image.o
-V := 0
 
 HOSTCCFLAGS := -Wall -Werror -pedantic -std=c99 -D_GNU_SOURCE
 
@@ -20,28 +21,20 @@ else
   HOSTCCFLAGS += -O2
 endif
 
-ifeq (${V},0)
-  Q := @
-else
-  Q :=
-endif
-
-HOSTCC := gcc
-
 .PHONY: all clean distclean
 
 all: ${PROJECT}
 
 ${PROJECT}: ${OBJECTS} Makefile
-	@echo "  HOSTLD  $@"
-	${Q}${HOSTCC} ${OBJECTS} -o $@
-	@${ECHO_BLANK_LINE}
-	@echo "Built $@ successfully"
-	@${ECHO_BLANK_LINE}
+	$(s)echo "  HOSTLD  $@"
+	$(q)$(host-cc) ${OBJECTS} -o $@
+	$(s)echo
+	$(s)echo "Built $@ successfully"
+	$(s)echo
 
 %.o: %.c Makefile
-	@echo "  HOSTCC  $<"
-	${Q}${HOSTCC} -c ${HOSTCCFLAGS} $< -o $@
+	$(s)echo "  HOSTCC  $<"
+	$(q)$(host-cc) -c ${HOSTCCFLAGS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
diff --git a/tools/tlc/.gitignore b/tools/tlc/.gitignore
new file mode 100644
index 00000000..ad4a1f17
--- /dev/null
+++ b/tools/tlc/.gitignore
@@ -0,0 +1,176 @@
+# Created by https://www.toptal.com/developers/gitignore/api/python
+# Edit at https://www.toptal.com/developers/gitignore?templates=python
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+#   in version control.
+#   https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+### Python Patch ###
+# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
+poetry.toml
+
+# ruff
+.ruff_cache/
+
+# LSP config files
+pyrightconfig.json
+
+# End of https://www.toptal.com/developers/gitignore/api/python
diff --git a/tools/tlc/assets/images/coverage.svg b/tools/tlc/assets/images/coverage.svg
new file mode 100644
index 00000000..b6c4e361
--- /dev/null
+++ b/tools/tlc/assets/images/coverage.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="99" height="20">
+    <linearGradient id="b" x2="0" y2="100%">
+        <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
+        <stop offset="1" stop-opacity=".1"/>
+    </linearGradient>
+    <mask id="a">
+        <rect width="99" height="20" rx="3" fill="#fff"/>
+    </mask>
+    <g mask="url(#a)">
+        <path fill="#555" d="M0 0h63v20H0z"/>
+        <path fill="#4c1" d="M63 0h36v20H63z"/>
+        <path fill="url(#b)" d="M0 0h99v20H0z"/>
+    </g>
+    <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
+        <text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
+        <text x="31.5" y="14">coverage</text>
+        <text x="80" y="15" fill="#010101" fill-opacity=".3">95%</text>
+        <text x="80" y="14">95%</text>
+    </g>
+</svg>
diff --git a/tools/tlc/poetry.lock b/tools/tlc/poetry.lock
new file mode 100644
index 00000000..decec598
--- /dev/null
+++ b/tools/tlc/poetry.lock
@@ -0,0 +1,1434 @@
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+
+[[package]]
+name = "astroid"
+version = "2.15.8"
+description = "An abstract syntax tree for Python with inference support."
+optional = false
+python-versions = ">=3.7.2"
+files = [
+    {file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"},
+    {file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"},
+]
+
+[package.dependencies]
+lazy-object-proxy = ">=1.4.0"
+typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""}
+wrapt = [
+    {version = ">=1.11,<2", markers = "python_version < \"3.11\""},
+    {version = ">=1.14,<2", markers = "python_version >= \"3.11\""},
+]
+
+[[package]]
+name = "bandit"
+version = "1.7.9"
+description = "Security oriented static analyser for python code."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "bandit-1.7.9-py3-none-any.whl", hash = "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec"},
+    {file = "bandit-1.7.9.tar.gz", hash = "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61"},
+]
+
+[package.dependencies]
+colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""}
+PyYAML = ">=5.3.1"
+rich = "*"
+stevedore = ">=1.20.0"
+
+[package.extras]
+baseline = ["GitPython (>=3.1.30)"]
+sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"]
+test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"]
+toml = ["tomli (>=1.1.0)"]
+yaml = ["PyYAML"]
+
+[[package]]
+name = "black"
+version = "24.8.0"
+description = "The uncompromising code formatter."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "black-24.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6"},
+    {file = "black-24.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb"},
+    {file = "black-24.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42"},
+    {file = "black-24.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a"},
+    {file = "black-24.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"},
+    {file = "black-24.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af"},
+    {file = "black-24.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4"},
+    {file = "black-24.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af"},
+    {file = "black-24.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368"},
+    {file = "black-24.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed"},
+    {file = "black-24.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018"},
+    {file = "black-24.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2"},
+    {file = "black-24.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd"},
+    {file = "black-24.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2"},
+    {file = "black-24.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e"},
+    {file = "black-24.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920"},
+    {file = "black-24.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c"},
+    {file = "black-24.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e"},
+    {file = "black-24.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47"},
+    {file = "black-24.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb"},
+    {file = "black-24.8.0-py3-none-any.whl", hash = "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed"},
+    {file = "black-24.8.0.tar.gz", hash = "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f"},
+]
+
+[package.dependencies]
+click = ">=8.0.0"
+mypy-extensions = ">=0.4.3"
+packaging = ">=22.0"
+pathspec = ">=0.9.0"
+platformdirs = ">=2"
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
+
+[package.extras]
+colorama = ["colorama (>=0.4.3)"]
+d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
+jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
+uvloop = ["uvloop (>=0.15.2)"]
+
+[[package]]
+name = "cachetools"
+version = "5.5.0"
+description = "Extensible memoizing collections and decorators"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"},
+    {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"},
+]
+
+[[package]]
+name = "certifi"
+version = "2024.8.30"
+description = "Python package for providing Mozilla's CA Bundle."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
+    {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
+]
+
+[[package]]
+name = "cfgv"
+version = "3.4.0"
+description = "Validate configuration and produce human readable error messages."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
+    {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
+]
+
+[[package]]
+name = "chardet"
+version = "5.2.0"
+description = "Universal encoding detector for Python 3"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
+    {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
+]
+
+[[package]]
+name = "charset-normalizer"
+version = "3.3.2"
+description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+optional = false
+python-versions = ">=3.7.0"
+files = [
+    {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
+    {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
+    {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
+    {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
+    {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
+    {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
+    {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
+    {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
+]
+
+[[package]]
+name = "click"
+version = "8.1.7"
+description = "Composable command line interface toolkit"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
+    {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "commonmark"
+version = "0.9.1"
+description = "Python parser for the CommonMark Markdown spec"
+optional = false
+python-versions = "*"
+files = [
+    {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
+    {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
+]
+
+[package.extras]
+test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"]
+
+[[package]]
+name = "coverage"
+version = "6.5.0"
+description = "Code coverage measurement for Python"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"},
+    {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"},
+    {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"},
+    {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"},
+    {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"},
+    {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"},
+    {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"},
+    {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"},
+    {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"},
+    {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"},
+    {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"},
+    {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"},
+    {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"},
+    {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"},
+    {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"},
+    {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"},
+    {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"},
+    {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"},
+    {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"},
+    {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"},
+    {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"},
+    {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"},
+    {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"},
+    {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"},
+    {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"},
+    {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"},
+    {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"},
+    {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"},
+    {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"},
+    {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"},
+    {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"},
+    {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"},
+    {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"},
+    {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"},
+    {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"},
+    {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"},
+    {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"},
+    {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"},
+    {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"},
+    {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"},
+    {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"},
+    {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"},
+    {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"},
+    {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"},
+    {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"},
+    {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"},
+    {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"},
+    {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"},
+    {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"},
+    {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"},
+]
+
+[package.dependencies]
+tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
+
+[package.extras]
+toml = ["tomli"]
+
+[[package]]
+name = "coverage-badge"
+version = "1.1.2"
+description = "Generate coverage badges for Coverage.py."
+optional = false
+python-versions = "*"
+files = [
+    {file = "coverage_badge-1.1.2-py2.py3-none-any.whl", hash = "sha256:d8413ce51c91043a1692b943616b450868cbeeb0ea6a0c54a32f8318c9c96ff7"},
+    {file = "coverage_badge-1.1.2.tar.gz", hash = "sha256:fe7ed58a3b72dad85a553b64a99e963dea3847dcd0b8ddd2b38a00333618642c"},
+]
+
+[package.dependencies]
+coverage = "*"
+setuptools = "*"
+
+[[package]]
+name = "darglint"
+version = "1.8.1"
+description = "A utility for ensuring Google-style docstrings stay up to date with the source code."
+optional = false
+python-versions = ">=3.6,<4.0"
+files = [
+    {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"},
+    {file = "darglint-1.8.1.tar.gz", hash = "sha256:080d5106df149b199822e7ee7deb9c012b49891538f14a11be681044f0bb20da"},
+]
+
+[[package]]
+name = "dill"
+version = "0.3.8"
+description = "serialize all of Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"},
+    {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"},
+]
+
+[package.extras]
+graph = ["objgraph (>=1.7.2)"]
+profile = ["gprof2dot (>=2022.7.29)"]
+
+[[package]]
+name = "distlib"
+version = "0.3.8"
+description = "Distribution utilities"
+optional = false
+python-versions = "*"
+files = [
+    {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
+    {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
+]
+
+[[package]]
+name = "dparse"
+version = "0.6.3"
+description = "A parser for Python dependency files"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "dparse-0.6.3-py3-none-any.whl", hash = "sha256:0d8fe18714056ca632d98b24fbfc4e9791d4e47065285ab486182288813a5318"},
+    {file = "dparse-0.6.3.tar.gz", hash = "sha256:27bb8b4bcaefec3997697ba3f6e06b2447200ba273c0b085c3d012a04571b528"},
+]
+
+[package.dependencies]
+packaging = "*"
+tomli = {version = "*", markers = "python_version < \"3.11\""}
+
+[package.extras]
+conda = ["pyyaml"]
+pipenv = ["pipenv (<=2022.12.19)"]
+
+[[package]]
+name = "exceptiongroup"
+version = "1.2.2"
+description = "Backport of PEP 654 (exception groups)"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
+    {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
+]
+
+[package.extras]
+test = ["pytest (>=6)"]
+
+[[package]]
+name = "filelock"
+version = "3.16.1"
+description = "A platform independent file lock."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
+    {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
+]
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
+typing = ["typing-extensions (>=4.12.2)"]
+
+[[package]]
+name = "identify"
+version = "2.6.1"
+description = "File identification library for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"},
+    {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"},
+]
+
+[package.extras]
+license = ["ukkonen"]
+
+[[package]]
+name = "idna"
+version = "3.10"
+description = "Internationalized Domain Names in Applications (IDNA)"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
+    {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
+]
+
+[package.extras]
+all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
+
+[[package]]
+name = "iniconfig"
+version = "2.0.0"
+description = "brain-dead simple config-ini parsing"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
+    {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
+]
+
+[[package]]
+name = "isort"
+version = "5.13.2"
+description = "A Python utility / library to sort Python imports."
+optional = false
+python-versions = ">=3.8.0"
+files = [
+    {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"},
+    {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"},
+]
+
+[package.dependencies]
+colorama = {version = ">=0.4.6", optional = true, markers = "extra == \"colors\""}
+
+[package.extras]
+colors = ["colorama (>=0.4.6)"]
+
+[[package]]
+name = "jinja2"
+version = "3.1.4"
+description = "A very fast and expressive template engine."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
+    {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
+]
+
+[package.dependencies]
+MarkupSafe = ">=2.0"
+
+[package.extras]
+i18n = ["Babel (>=2.7)"]
+
+[[package]]
+name = "lazy-object-proxy"
+version = "1.10.0"
+description = "A fast and thorough lazy object proxy."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"},
+    {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"},
+    {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"},
+    {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"},
+    {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"},
+    {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"},
+    {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"},
+]
+
+[[package]]
+name = "markupsafe"
+version = "2.1.5"
+description = "Safely add untrusted strings to HTML/XML markup."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
+    {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
+    {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
+    {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
+    {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
+    {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
+    {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
+    {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
+]
+
+[[package]]
+name = "mccabe"
+version = "0.7.0"
+description = "McCabe checker, plugin for flake8"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
+    {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
+]
+
+[[package]]
+name = "mypy"
+version = "0.910"
+description = "Optional static typing for Python"
+optional = false
+python-versions = ">=3.5"
+files = [
+    {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"},
+    {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"},
+    {file = "mypy-0.910-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9"},
+    {file = "mypy-0.910-cp35-cp35m-win_amd64.whl", hash = "sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e"},
+    {file = "mypy-0.910-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921"},
+    {file = "mypy-0.910-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6"},
+    {file = "mypy-0.910-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212"},
+    {file = "mypy-0.910-cp36-cp36m-win_amd64.whl", hash = "sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885"},
+    {file = "mypy-0.910-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0"},
+    {file = "mypy-0.910-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de"},
+    {file = "mypy-0.910-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703"},
+    {file = "mypy-0.910-cp37-cp37m-win_amd64.whl", hash = "sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a"},
+    {file = "mypy-0.910-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504"},
+    {file = "mypy-0.910-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9"},
+    {file = "mypy-0.910-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072"},
+    {file = "mypy-0.910-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811"},
+    {file = "mypy-0.910-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e"},
+    {file = "mypy-0.910-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b"},
+    {file = "mypy-0.910-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2"},
+    {file = "mypy-0.910-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97"},
+    {file = "mypy-0.910-cp39-cp39-win_amd64.whl", hash = "sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8"},
+    {file = "mypy-0.910-py3-none-any.whl", hash = "sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"},
+    {file = "mypy-0.910.tar.gz", hash = "sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150"},
+]
+
+[package.dependencies]
+mypy-extensions = ">=0.4.3,<0.5.0"
+toml = "*"
+typing-extensions = ">=3.7.4"
+
+[package.extras]
+dmypy = ["psutil (>=4.0)"]
+python2 = ["typed-ast (>=1.4.0,<1.5.0)"]
+
+[[package]]
+name = "mypy-extensions"
+version = "0.4.4"
+description = "Experimental type system extensions for programs checked with the mypy typechecker."
+optional = false
+python-versions = ">=2.7"
+files = [
+    {file = "mypy_extensions-0.4.4.tar.gz", hash = "sha256:c8b707883a96efe9b4bb3aaf0dcc07e7e217d7d8368eec4db4049ee9e142f4fd"},
+]
+
+[[package]]
+name = "nodeenv"
+version = "1.9.1"
+description = "Node.js virtual environment builder"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+    {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"},
+    {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"},
+]
+
+[[package]]
+name = "packaging"
+version = "24.1"
+description = "Core utilities for Python packages"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
+    {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
+]
+
+[[package]]
+name = "pathspec"
+version = "0.12.1"
+description = "Utility library for gitignore style pattern matching of file paths."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
+    {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
+]
+
+[[package]]
+name = "pbr"
+version = "6.1.0"
+description = "Python Build Reasonableness"
+optional = false
+python-versions = ">=2.6"
+files = [
+    {file = "pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"},
+    {file = "pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24"},
+]
+
+[[package]]
+name = "platformdirs"
+version = "4.3.6"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
+    {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
+]
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"]
+type = ["mypy (>=1.11.2)"]
+
+[[package]]
+name = "pluggy"
+version = "1.5.0"
+description = "plugin and hook calling mechanisms for python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
+    {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
+]
+
+[package.extras]
+dev = ["pre-commit", "tox"]
+testing = ["pytest", "pytest-benchmark"]
+
+[[package]]
+name = "pre-commit"
+version = "2.21.0"
+description = "A framework for managing and maintaining multi-language pre-commit hooks."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"},
+    {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"},
+]
+
+[package.dependencies]
+cfgv = ">=2.0.0"
+identify = ">=1.0.0"
+nodeenv = ">=0.11.1"
+pyyaml = ">=5.1"
+virtualenv = ">=20.10.0"
+
+[[package]]
+name = "pydocstyle"
+version = "6.3.0"
+description = "Python docstring style checker"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"},
+    {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"},
+]
+
+[package.dependencies]
+snowballstemmer = ">=2.2.0"
+
+[package.extras]
+toml = ["tomli (>=1.2.3)"]
+
+[[package]]
+name = "pygments"
+version = "2.18.0"
+description = "Pygments is a syntax highlighting package written in Python."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
+    {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
+]
+
+[package.extras]
+windows-terminal = ["colorama (>=0.4.6)"]
+
+[[package]]
+name = "pylint"
+version = "2.17.7"
+description = "python code static checker"
+optional = false
+python-versions = ">=3.7.2"
+files = [
+    {file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"},
+    {file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"},
+]
+
+[package.dependencies]
+astroid = ">=2.15.8,<=2.17.0-dev0"
+colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
+dill = [
+    {version = ">=0.2", markers = "python_version < \"3.11\""},
+    {version = ">=0.3.6", markers = "python_version >= \"3.11\""},
+]
+isort = ">=4.2.5,<6"
+mccabe = ">=0.6,<0.8"
+platformdirs = ">=2.2.0"
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+tomlkit = ">=0.10.1"
+typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""}
+
+[package.extras]
+spelling = ["pyenchant (>=3.2,<4.0)"]
+testutils = ["gitpython (>3)"]
+
+[[package]]
+name = "pyproject-api"
+version = "1.8.0"
+description = "API to interact with the python pyproject.toml based projects"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pyproject_api-1.8.0-py3-none-any.whl", hash = "sha256:3d7d347a047afe796fd5d1885b1e391ba29be7169bd2f102fcd378f04273d228"},
+    {file = "pyproject_api-1.8.0.tar.gz", hash = "sha256:77b8049f2feb5d33eefcc21b57f1e279636277a8ac8ad6b5871037b243778496"},
+]
+
+[package.dependencies]
+packaging = ">=24.1"
+tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx-autodoc-typehints (>=2.4.1)"]
+testing = ["covdefaults (>=2.3)", "pytest (>=8.3.3)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "setuptools (>=75.1)"]
+
+[[package]]
+name = "pytest"
+version = "8.3.3"
+description = "pytest: simple powerful testing with Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"},
+    {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
+iniconfig = "*"
+packaging = "*"
+pluggy = ">=1.5,<2"
+tomli = {version = ">=1", markers = "python_version < \"3.11\""}
+
+[package.extras]
+dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
+
+[[package]]
+name = "pytest-cov"
+version = "5.0.0"
+description = "Pytest plugin for measuring coverage."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"},
+    {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"},
+]
+
+[package.dependencies]
+coverage = {version = ">=5.2.1", extras = ["toml"]}
+pytest = ">=4.6"
+
+[package.extras]
+testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"]
+
+[[package]]
+name = "pytest-html"
+version = "4.1.1"
+description = "pytest plugin for generating HTML reports"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pytest_html-4.1.1-py3-none-any.whl", hash = "sha256:c8152cea03bd4e9bee6d525573b67bbc6622967b72b9628dda0ea3e2a0b5dd71"},
+    {file = "pytest_html-4.1.1.tar.gz", hash = "sha256:70a01e8ae5800f4a074b56a4cb1025c8f4f9b038bba5fe31e3c98eb996686f07"},
+]
+
+[package.dependencies]
+jinja2 = ">=3.0.0"
+pytest = ">=7.0.0"
+pytest-metadata = ">=2.0.0"
+
+[package.extras]
+docs = ["pip-tools (>=6.13.0)"]
+test = ["assertpy (>=1.1)", "beautifulsoup4 (>=4.11.1)", "black (>=22.1.0)", "flake8 (>=4.0.1)", "pre-commit (>=2.17.0)", "pytest-mock (>=3.7.0)", "pytest-rerunfailures (>=11.1.2)", "pytest-xdist (>=2.4.0)", "selenium (>=4.3.0)", "tox (>=3.24.5)"]
+
+[[package]]
+name = "pytest-metadata"
+version = "3.1.1"
+description = "pytest plugin for test session metadata"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "pytest_metadata-3.1.1-py3-none-any.whl", hash = "sha256:c8e0844db684ee1c798cfa38908d20d67d0463ecb6137c72e91f418558dd5f4b"},
+    {file = "pytest_metadata-3.1.1.tar.gz", hash = "sha256:d2a29b0355fbc03f168aa96d41ff88b1a3b44a3b02acbe491801c98a048017c8"},
+]
+
+[package.dependencies]
+pytest = ">=7.0.0"
+
+[package.extras]
+test = ["black (>=22.1.0)", "flake8 (>=4.0.1)", "pre-commit (>=2.17.0)", "tox (>=3.24.5)"]
+
+[[package]]
+name = "pyupgrade"
+version = "2.38.4"
+description = "A tool to automatically upgrade syntax for newer versions."
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "pyupgrade-2.38.4-py2.py3-none-any.whl", hash = "sha256:944ff993c396ddc2b9012eb3de4cda138eb4c149b22c6c560d4c8bfd0e180982"},
+    {file = "pyupgrade-2.38.4.tar.gz", hash = "sha256:1eb43a49f416752929741ba4d706bf3f33593d3cac9bdc217fc1ef55c047c1f4"},
+]
+
+[package.dependencies]
+tokenize-rt = "<5"
+
+[[package]]
+name = "pyyaml"
+version = "6.0.2"
+description = "YAML parser and emitter for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
+    {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
+    {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
+    {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
+    {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
+    {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
+    {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
+    {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
+    {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
+    {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
+    {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
+    {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
+    {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
+    {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
+    {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
+    {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
+    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
+    {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
+    {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
+    {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
+    {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
+    {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
+    {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
+    {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
+    {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
+    {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
+    {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
+    {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
+    {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
+    {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
+    {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
+    {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
+    {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
+    {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
+    {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
+    {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
+    {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
+    {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
+    {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
+    {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
+    {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
+]
+
+[[package]]
+name = "requests"
+version = "2.32.3"
+description = "Python HTTP for Humans."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
+    {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
+]
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+charset-normalizer = ">=2,<4"
+idna = ">=2.5,<4"
+urllib3 = ">=1.21.1,<3"
+
+[package.extras]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+
+[[package]]
+name = "rich"
+version = "10.16.2"
+description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
+optional = false
+python-versions = ">=3.6.2,<4.0.0"
+files = [
+    {file = "rich-10.16.2-py3-none-any.whl", hash = "sha256:c59d73bd804c90f747c8d7b1d023b88f2a9ac2454224a4aeaf959b21eeb42d03"},
+    {file = "rich-10.16.2.tar.gz", hash = "sha256:720974689960e06c2efdb54327f8bf0cdbdf4eae4ad73b6c94213cad405c371b"},
+]
+
+[package.dependencies]
+colorama = ">=0.4.0,<0.5.0"
+commonmark = ">=0.9.0,<0.10.0"
+pygments = ">=2.6.0,<3.0.0"
+
+[package.extras]
+jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
+
+[[package]]
+name = "ruamel-yaml"
+version = "0.18.6"
+description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"},
+    {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"},
+]
+
+[package.dependencies]
+"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""}
+
+[package.extras]
+docs = ["mercurial (>5.7)", "ryd"]
+jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
+
+[[package]]
+name = "ruamel-yaml-clib"
+version = "0.2.8"
+description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"},
+    {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"},
+    {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"},
+    {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"},
+    {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"},
+    {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"},
+    {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"},
+    {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"},
+]
+
+[[package]]
+name = "safety"
+version = "2.3.4"
+description = "Checks installed dependencies for known vulnerabilities and licenses."
+optional = false
+python-versions = "*"
+files = [
+    {file = "safety-2.3.4-py3-none-any.whl", hash = "sha256:6224dcd9b20986a2b2c5e7acfdfba6bca42bb11b2783b24ed04f32317e5167ea"},
+    {file = "safety-2.3.4.tar.gz", hash = "sha256:b9e74e794e82f54d11f4091c5d820c4d2d81de9f953bf0b4f33ac8bc402ae72c"},
+]
+
+[package.dependencies]
+Click = ">=8.0.2"
+dparse = ">=0.6.2"
+packaging = ">=21.0"
+requests = "*"
+"ruamel.yaml" = ">=0.17.21"
+setuptools = ">=19.3"
+
+[package.extras]
+github = ["jinja2 (>=3.1.0)", "pygithub (>=1.43.3)"]
+gitlab = ["python-gitlab (>=1.3.0)"]
+
+[[package]]
+name = "setuptools"
+version = "75.1.0"
+description = "Easily download, build, install, upgrade, and uninstall Python packages"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"},
+    {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"},
+]
+
+[package.extras]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
+core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+cover = ["pytest-cov"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
+enabler = ["pytest-enabler (>=2.2)"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
+type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
+
+[[package]]
+name = "shellingham"
+version = "1.5.4"
+description = "Tool to Detect Surrounding Shell"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
+    {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
+]
+
+[[package]]
+name = "snowballstemmer"
+version = "2.2.0"
+description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
+optional = false
+python-versions = "*"
+files = [
+    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
+    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
+]
+
+[[package]]
+name = "stevedore"
+version = "5.3.0"
+description = "Manage dynamic plugins for Python applications"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "stevedore-5.3.0-py3-none-any.whl", hash = "sha256:1efd34ca08f474dad08d9b19e934a22c68bb6fe416926479ba29e5013bcc8f78"},
+    {file = "stevedore-5.3.0.tar.gz", hash = "sha256:9a64265f4060312828151c204efbe9b7a9852a0d9228756344dbc7e4023e375a"},
+]
+
+[package.dependencies]
+pbr = ">=2.0.0"
+
+[[package]]
+name = "tokenize-rt"
+version = "4.2.1"
+description = "A wrapper around the stdlib `tokenize` which roundtrips."
+optional = false
+python-versions = ">=3.6.1"
+files = [
+    {file = "tokenize_rt-4.2.1-py2.py3-none-any.whl", hash = "sha256:08a27fa032a81cf45e8858d0ac706004fcd523e8463415ddf1442be38e204ea8"},
+    {file = "tokenize_rt-4.2.1.tar.gz", hash = "sha256:0d4f69026fed520f8a1e0103aa36c406ef4661417f20ca643f913e33531b3b94"},
+]
+
+[[package]]
+name = "toml"
+version = "0.10.2"
+description = "Python Library for Tom's Obvious, Minimal Language"
+optional = false
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
+    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
+]
+
+[[package]]
+name = "tomli"
+version = "2.0.1"
+description = "A lil' TOML parser"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
+    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+]
+
+[[package]]
+name = "tomlkit"
+version = "0.13.2"
+description = "Style preserving TOML library"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"},
+    {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"},
+]
+
+[[package]]
+name = "tox"
+version = "4.20.0"
+description = "tox is a generic virtualenv management and test command line tool"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "tox-4.20.0-py3-none-any.whl", hash = "sha256:21a8005e3d3fe5658a8e36b8ca3ed13a4230429063c5cc2a2fdac6ee5aa0de34"},
+    {file = "tox-4.20.0.tar.gz", hash = "sha256:5b78a49b6eaaeab3ae4186415e7c97d524f762ae967c63562687c3e5f0ec23d5"},
+]
+
+[package.dependencies]
+cachetools = ">=5.5"
+chardet = ">=5.2"
+colorama = ">=0.4.6"
+filelock = ">=3.15.4"
+packaging = ">=24.1"
+platformdirs = ">=4.2.2"
+pluggy = ">=1.5"
+pyproject-api = ">=1.7.1"
+tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
+virtualenv = ">=20.26.3"
+
+[package.extras]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-argparse-cli (>=1.17)", "sphinx-autodoc-typehints (>=2.4)", "sphinx-copybutton (>=0.5.2)", "sphinx-inline-tabs (>=2023.4.21)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=24.8)"]
+testing = ["build[virtualenv] (>=1.2.2)", "covdefaults (>=2.3)", "detect-test-pollution (>=1.2)", "devpi-process (>=1)", "diff-cover (>=9.1.1)", "distlib (>=0.3.8)", "flaky (>=3.8.1)", "hatch-vcs (>=0.4)", "hatchling (>=1.25)", "psutil (>=6)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-xdist (>=3.6.1)", "re-assert (>=1.1)", "setuptools (>=74.1.2)", "time-machine (>=2.15)", "wheel (>=0.44)"]
+
+[[package]]
+name = "typer"
+version = "0.4.2"
+description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "typer-0.4.2-py3-none-any.whl", hash = "sha256:023bae00d1baf358a6cc7cea45851639360bb716de687b42b0a4641cd99173f1"},
+    {file = "typer-0.4.2.tar.gz", hash = "sha256:b8261c6c0152dd73478b5ba96ba677e5d6948c715c310f7c91079f311f62ec03"},
+]
+
+[package.dependencies]
+click = ">=7.1.1,<9.0.0"
+colorama = {version = ">=0.4.3,<0.5.0", optional = true, markers = "extra == \"all\""}
+shellingham = {version = ">=1.3.0,<2.0.0", optional = true, markers = "extra == \"all\""}
+
+[package.extras]
+all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"]
+dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"]
+doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)"]
+test = ["black (>=22.3.0,<23.0.0)", "coverage (>=5.2,<6.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
+
+[[package]]
+name = "typing-extensions"
+version = "4.12.2"
+description = "Backported and Experimental Type Hints for Python 3.8+"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
+    {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
+]
+
+[[package]]
+name = "urllib3"
+version = "2.2.3"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
+    {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
+]
+
+[package.extras]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+h2 = ["h2 (>=4,<5)"]
+socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
+zstd = ["zstandard (>=0.18.0)"]
+
+[[package]]
+name = "virtualenv"
+version = "20.26.5"
+description = "Virtual Python Environment builder"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "virtualenv-20.26.5-py3-none-any.whl", hash = "sha256:4f3ac17b81fba3ce3bd6f4ead2749a72da5929c01774948e243db9ba41df4ff6"},
+    {file = "virtualenv-20.26.5.tar.gz", hash = "sha256:ce489cac131aa58f4b25e321d6d186171f78e6cb13fafbf32a840cee67733ff4"},
+]
+
+[package.dependencies]
+distlib = ">=0.3.7,<1"
+filelock = ">=3.12.2,<4"
+platformdirs = ">=3.9.1,<5"
+
+[package.extras]
+docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
+test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
+
+[[package]]
+name = "wrapt"
+version = "1.16.0"
+description = "Module for decorators, wrappers and monkey patching."
+optional = false
+python-versions = ">=3.6"
+files = [
+    {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"},
+    {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"},
+    {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"},
+    {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"},
+    {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"},
+    {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"},
+    {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"},
+    {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"},
+    {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"},
+    {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"},
+    {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"},
+    {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"},
+    {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"},
+    {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"},
+    {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"},
+    {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"},
+    {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"},
+    {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"},
+    {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"},
+    {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"},
+    {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"},
+    {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"},
+    {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"},
+    {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"},
+    {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"},
+    {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"},
+    {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"},
+    {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"},
+    {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"},
+    {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"},
+    {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"},
+    {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"},
+    {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"},
+    {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"},
+    {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"},
+    {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"},
+    {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"},
+    {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"},
+    {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"},
+    {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"},
+    {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"},
+    {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"},
+    {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"},
+    {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"},
+    {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"},
+    {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"},
+    {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"},
+    {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"},
+    {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"},
+    {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"},
+    {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"},
+    {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"},
+    {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"},
+    {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"},
+    {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"},
+    {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"},
+    {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"},
+    {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"},
+    {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"},
+    {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"},
+    {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"},
+    {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"},
+    {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"},
+    {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"},
+    {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"},
+    {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"},
+    {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"},
+    {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"},
+    {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"},
+    {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"},
+]
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.8"
+content-hash = "aac9123f3fa544b8c3e9b085f41f5a1c6c4ed2d59ce3236dcda6ea2aef5a694c"
diff --git a/tools/tlc/pyproject.toml b/tools/tlc/pyproject.toml
new file mode 100644
index 00000000..b6062384
--- /dev/null
+++ b/tools/tlc/pyproject.toml
@@ -0,0 +1,151 @@
+# Poetry pyproject.toml: https://python-poetry.org/docs/pyproject/
+[build-system]
+requires = ["poetry_core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"
+
+[tool.poetry]
+name = "tlc"
+version = "0.9.0"
+description = "Transfer List Compiler (TLC) is a Python-based CLI for efficiently handling transfer lists."
+authors = ["Arm Ltd <tf-a@lists.trustedfirmware.org>"]
+license = "BSD-3"
+repository = "https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/"
+homepage = "https://trustedfirmware-a.readthedocs.io/en/latest/index.html"
+
+# Keywords description https://python-poetry.org/docs/pyproject/#keywords
+keywords = []  #! Update me
+
+# Pypi classifiers: https://pypi.org/classifiers/
+classifiers = [
+  "Development Status :: 3 - Alpha",
+  "Intended Audience :: Developers",
+  "Operating System :: OS Independent",
+  "Topic :: Software Development :: Libraries :: Python Modules",
+  "License :: OSI Approved :: BSD License",
+  "Programming Language :: Python :: 3",
+  "Programming Language :: Python :: 3.8",
+  "Programming Language :: Python :: 3.9",
+]
+
+[tool.poetry.scripts]
+# Entry points for the package https://python-poetry.org/docs/pyproject/#scripts
+"tlc" = "tlc.__main__:cli"
+
+[tool.poetry.dependencies]
+python = "^3.8"
+
+typer = {extras = ["all"], version = "^0.4.0"}
+rich = "^10.14.0"
+click = "^8.1.7"
+pyyaml = "^6.0.1"
+tox = "^4.18.0"
+jinja2 = "^3.1.4"
+
+[tool.poetry.group.dev]
+optional = true
+
+[tool.poetry.group.dev.dependencies]
+bandit = "^1.7.1"
+tox = "^4.18.0"
+darglint = "^1.8.1"
+black = "^24.4.2"
+isort = {extras = ["colors"], version = "^5.10.1"}
+mypy = "^0.910"
+mypy-extensions = "^0.4.3"
+pre-commit = "^2.15.0"
+pydocstyle = "^6.1.1"
+pylint = "^2.11.1"
+pytest = "^8.0.0"
+pyupgrade = "^2.29.1"
+safety = "^2.2.0"
+coverage = "^6.1.2"
+coverage-badge = "^1.1.0"
+pytest-html = "^4.1.1"
+pytest-cov = "5.0.0"
+
+[tool.black]
+# https://github.com/psf/black
+target-version = ["py38"]
+line-length = 88
+color = true
+
+exclude = '''
+/(
+    \.git
+    | \.hg
+    | \.mypy_cache
+    | \.tox
+    | \.venv
+    | _build
+    | buck-out
+    | build
+    | dist
+    | env
+    | venv
+)/
+'''
+
+[tool.isort]
+# https://github.com/timothycrosley/isort/
+py_version = 38
+line_length = 88
+
+known_typing = ["typing", "types", "typing_extensions", "mypy", "mypy_extensions"]
+sections = ["FUTURE", "TYPING", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
+include_trailing_comma = true
+profile = "black"
+multi_line_output = 3
+indent = 4
+color_output = true
+
+[tool.mypy]
+# https://mypy.readthedocs.io/en/latest/config_file.html#using-a-pyproject-toml-file
+python_version = 3.8
+pretty = true
+show_traceback = true
+color_output = true
+
+allow_redefinition = false
+check_untyped_defs = true
+disallow_any_generics = true
+disallow_incomplete_defs = true
+ignore_missing_imports = true
+implicit_reexport = false
+no_implicit_optional = true
+show_column_numbers = true
+show_error_codes = true
+show_error_context = true
+strict_equality = true
+strict_optional = true
+warn_no_return = true
+warn_redundant_casts = true
+warn_return_any = true
+warn_unreachable = true
+warn_unused_configs = true
+warn_unused_ignores = true
+
+
+[tool.pytest.ini_options]
+# https://docs.pytest.org/en/6.2.x/customize.html#pyproject-toml
+# Directories that are not visited by pytest collector:
+norecursedirs =["hooks", "*.egg", ".eggs", "dist", "build", "docs", ".tox", ".git", "__pycache__"]
+doctest_optionflags = ["NUMBER", "NORMALIZE_WHITESPACE", "IGNORE_EXCEPTION_DETAIL"]
+
+# Extra options:
+addopts = [
+  "--strict-markers",
+  "--tb=short",
+  "--doctest-modules",
+  "--doctest-continue-on-failure",
+]
+
+[tool.coverage.run]
+source = ["tests"]
+branch = true
+
+[tool.coverage.paths]
+source = ["tlc"]
+
+[tool.coverage.report]
+fail_under = 50
+show_missing = true
diff --git a/tools/tlc/setup.cfg b/tools/tlc/setup.cfg
new file mode 100644
index 00000000..3c46a08c
--- /dev/null
+++ b/tools/tlc/setup.cfg
@@ -0,0 +1,4 @@
+[darglint]
+# https://github.com/terrencepreilly/darglint
+strictness = long
+docstring_style = google
diff --git a/tools/tlc/tests/conftest.py b/tools/tlc/tests/conftest.py
new file mode 100644
index 00000000..b8f88b50
--- /dev/null
+++ b/tools/tlc/tests/conftest.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+""" Common configurations and fixtures for test environment."""
+
+import pytest
+import yaml
+from click.testing import CliRunner
+
+from tlc.cli import cli
+
+
+@pytest.fixture
+def tmptlstr(tmpdir):
+    return tmpdir.join("tl.bin").strpath
+
+
+@pytest.fixture
+def tmpyamlconfig(tmpdir):
+    return tmpdir.join("config.yaml").strpath
+
+
+@pytest.fixture
+def tmpfdt(tmpdir):
+    fdt = tmpdir.join("fdt.dtb")
+    fdt.write_binary(b"\x00" * 100)
+    return fdt
+
+
+@pytest.fixture(params=[1, 2, 3, 4, 5, 0x100, 0x101, 0x102, 0x104])
+def non_empty_tag_id(request):
+    return request.param
+
+
+@pytest.fixture
+def tmpyamlconfig_blob_file(tmpdir, tmpfdt, non_empty_tag_id):
+    config_path = tmpdir.join("config.yaml")
+
+    config = {
+        "has_checksum": True,
+        "max_size": 0x1000,
+        "entries": [
+            {
+                "tag_id": non_empty_tag_id,
+                "blob_file_path": tmpfdt.strpath,
+            },
+        ],
+    }
+
+    with open(config_path, "w") as f:
+        yaml.safe_dump(config, f)
+
+    return config_path
+
+
+@pytest.fixture
+def tlcrunner(tmptlstr):
+    runner = CliRunner()
+    with runner.isolated_filesystem():
+        runner.invoke(cli, ["create", tmptlstr])
+    return runner
+
+
+@pytest.fixture
+def tlc_entries(tmpfdt):
+    return [(0, "/dev/null"), (1, tmpfdt.strpath), (0x102, tmpfdt.strpath)]
diff --git a/tools/tlc/tests/test_cli.py b/tools/tlc/tests/test_cli.py
new file mode 100644
index 00000000..a5ef30ee
--- /dev/null
+++ b/tools/tlc/tests/test_cli.py
@@ -0,0 +1,476 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Contains unit tests for the CLI functionality."""
+
+from math import ceil, log2
+from pathlib import Path
+from re import findall, search
+from unittest import mock
+
+import pytest
+import yaml
+from click.testing import CliRunner
+
+from tlc.cli import cli
+from tlc.te import TransferEntry
+from tlc.tl import TransferList
+
+
+def test_create_empty_tl(tmpdir):
+    runner = CliRunner()
+    test_file = tmpdir.join("tl.bin")
+
+    result = runner.invoke(cli, ["create", test_file.strpath])
+    assert result.exit_code == 0
+    assert TransferList.fromfile(test_file) is not None
+
+
+def test_create_with_fdt(tmpdir):
+    runner = CliRunner()
+    fdt = tmpdir.join("fdt.dtb")
+    fdt.write_binary(b"\x00" * 100)
+
+    result = runner.invoke(
+        cli,
+        [
+            "create",
+            "--fdt",
+            fdt.strpath,
+            "--size",
+            "1000",
+            tmpdir.join("tl.bin").strpath,
+        ],
+    )
+    assert result.exit_code == 0
+
+
+def test_add_single_entry(tlcrunner, tmptlstr):
+    tlcrunner.invoke(cli, ["add", "--entry", "0", "/dev/null", tmptlstr])
+
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == 1
+    assert tl.entries[0].id == 0
+
+
+def test_add_multiple_entries(tlcrunner, tlc_entries, tmptlstr):
+    for id, path in tlc_entries:
+        tlcrunner.invoke(cli, ["add", "--entry", id, path, tmptlstr])
+
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == len(tlc_entries)
+
+
+def test_info(tlcrunner, tmptlstr, tmpfdt):
+    tlcrunner.invoke(cli, ["add", "--entry", "0", "/dev/null", tmptlstr])
+    tlcrunner.invoke(cli, ["add", "--fdt", tmpfdt.strpath, tmptlstr])
+
+    result = tlcrunner.invoke(cli, ["info", tmptlstr])
+    assert result.exit_code == 0
+    assert "signature" in result.stdout
+    assert "id" in result.stdout
+
+    result = tlcrunner.invoke(cli, ["info", "--header", tmptlstr])
+    assert result.exit_code == 0
+    assert "signature" in result.stdout
+    assert "id" not in result.stdout
+
+    result = tlcrunner.invoke(cli, ["info", "--entries", tmptlstr])
+    assert result.exit_code == 0
+    assert "signature" not in result.stdout
+    assert "id" in result.stdout
+
+
+def test_raises_max_size_error(tmptlstr, tmpfdt):
+    tmpfdt.write_binary(bytes(6000))
+
+    runner = CliRunner()
+    result = runner.invoke(cli, ["create", "--fdt", tmpfdt, tmptlstr])
+
+    assert result.exception
+    assert isinstance(result.exception, MemoryError)
+    assert "TL max size exceeded, consider increasing with the option -s" in str(
+        result.exception
+    )
+    assert "TL size has exceeded the maximum allocation" in str(
+        result.exception.__cause__
+    )
+
+
+def test_info_get_fdt_offset(tmptlstr, tmpfdt):
+    runner = CliRunner()
+    with runner.isolated_filesystem():
+        runner.invoke(cli, ["create", "--size", "1000", tmptlstr])
+        runner.invoke(cli, ["add", "--entry", "1", tmpfdt.strpath, tmptlstr])
+        result = runner.invoke(cli, ["info", "--fdt-offset", tmptlstr])
+
+    assert result.exit_code == 0
+    assert result.output.strip("\n").isdigit()
+
+
+def test_remove_tag(tlcrunner, tmptlstr):
+    tlcrunner.invoke(cli, ["add", "--entry", "0", "/dev/null", tmptlstr])
+    result = tlcrunner.invoke(cli, ["info", tmptlstr])
+
+    assert result.exit_code == 0
+    assert "signature" in result.stdout
+
+    tlcrunner.invoke(cli, ["remove", "--tags", "0", tmptlstr])
+    tl = TransferList.fromfile(tmptlstr)
+
+    assert result.exit_code == 0
+    assert len(tl.entries) == 0
+
+
+def test_unpack_tl(tlcrunner, tmptlstr, tmpfdt, tmpdir):
+    with tlcrunner.isolated_filesystem(temp_dir=tmpdir):
+        tlcrunner.invoke(cli, ["add", "--entry", 1, tmpfdt.strpath, tmptlstr])
+        tlcrunner.invoke(cli, ["unpack", tmptlstr])
+        assert Path("te_0_1.bin").exists()
+
+
+def test_unpack_multiple_tes(tlcrunner, tlc_entries, tmptlstr, tmpdir):
+    with tlcrunner.isolated_filesystem(temp_dir=tmpdir):
+        for id, path in tlc_entries:
+            tlcrunner.invoke(cli, ["add", "--entry", id, path, tmptlstr])
+
+    assert all(
+        filter(
+            lambda te: (Path(tmpdir.strpath) / f"te_{te[0]}.bin").exists(), tlc_entries
+        )
+    )
+
+
+def test_unpack_into_dir(tlcrunner, tmpdir, tmptlstr, tmpfdt):
+    tlcrunner.invoke(cli, ["add", "--entry", 1, tmpfdt.strpath, tmptlstr])
+    tlcrunner.invoke(cli, ["unpack", "-C", tmpdir.strpath, tmptlstr])
+
+    assert (Path(tmpdir.strpath) / "te_0_1.bin").exists()
+
+
+def test_unpack_into_dir_with_conflicting_tags(tlcrunner, tmpdir, tmptlstr, tmpfdt):
+    tlcrunner.invoke(cli, ["add", "--entry", 1, tmpfdt.strpath, tmptlstr])
+    tlcrunner.invoke(cli, ["add", "--entry", 1, tmpfdt.strpath, tmptlstr])
+    tlcrunner.invoke(cli, ["unpack", "-C", tmpdir.strpath, tmptlstr])
+
+    assert (Path(tmpdir.strpath) / "te_0_1.bin").exists()
+    assert (Path(tmpdir.strpath) / "te_1_1.bin").exists()
+
+
+def test_validate_invalid_signature(tmptlstr, tlcrunner, monkeypatch):
+    tl = TransferList()
+    tl.signature = 0xDEADBEEF
+
+    mock_open = lambda tmptlstr, mode: mock.mock_open(read_data=tl.header_to_bytes())()
+    monkeypatch.setattr("builtins.open", mock_open)
+
+    result = tlcrunner.invoke(cli, ["validate", tmptlstr])
+    assert result.exit_code != 0
+
+
+def test_validate_misaligned_entries(tmptlstr, tlcrunner, monkeypatch):
+    """Base address of a TE must be 8-byte aligned."""
+    mock_open = lambda tmptlstr, mode: mock.mock_open(
+        read_data=TransferList().header_to_bytes()
+        + bytes(5)
+        + TransferEntry(0, 0, bytes(0)).header_to_bytes
+    )()
+    monkeypatch.setattr("builtins.open", mock_open)
+
+    result = tlcrunner.invoke(cli, ["validate", tmptlstr])
+
+    assert result.exit_code == 1
+
+
+@pytest.mark.parametrize(
+    "version", [0, TransferList.version, TransferList.version + 1, 1 << 8]
+)
+def test_validate_unsupported_version(version, tmptlstr, tlcrunner, monkeypatch):
+    tl = TransferList()
+    tl.version = version
+
+    mock_open = lambda tmptlstr, mode: mock.mock_open(read_data=tl.header_to_bytes())()
+    monkeypatch.setattr("builtins.open", mock_open)
+
+    result = tlcrunner.invoke(cli, ["validate", tmptlstr])
+
+    if version >= TransferList.version and version <= 0xFF:
+        assert result.exit_code == 0
+    else:
+        assert result.exit_code == 1
+
+
+def test_create_entry_from_yaml_and_blob_file(
+    tlcrunner, tmpyamlconfig_blob_file, tmptlstr, non_empty_tag_id
+):
+    tlcrunner.invoke(
+        cli,
+        [
+            "create",
+            "--from-yaml",
+            tmpyamlconfig_blob_file.strpath,
+            tmptlstr,
+        ],
+    )
+
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == 1
+    assert tl.entries[0].id == non_empty_tag_id
+
+
+@pytest.mark.parametrize(
+    "entry",
+    [
+        {"tag_id": 0},
+        {
+            "tag_id": 0x104,
+            "addr": 0x0400100000000010,
+            "size": 0x0003300000000000,
+        },
+        {
+            "tag_id": 0x100,
+            "pp_addr": 100,
+        },
+        {
+            "tag_id": "optee_pageable_part",
+            "pp_addr": 100,
+        },
+    ],
+)
+def test_create_from_yaml_check_sum_bytes(tlcrunner, tmpyamlconfig, tmptlstr, entry):
+    """Test creating a TL from a yaml file, but only check that the sum of the
+    data in the yaml file matches the sum of the data in the TL. This means
+    you don't have to type the exact sequence of expected bytes. All the data
+    in the yaml file must be integers (except for the tag IDs, which can be
+    strings).
+    """
+    # create yaml config file
+    config = {
+        "has_checksum": True,
+        "max_size": 0x1000,
+        "entries": [entry],
+    }
+    with open(tmpyamlconfig, "w") as f:
+        yaml.safe_dump(config, f)
+
+    # invoke TLC
+    tlcrunner.invoke(
+        cli,
+        [
+            "create",
+            "--from-yaml",
+            tmpyamlconfig,
+            tmptlstr,
+        ],
+    )
+
+    # open created TL, and check
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == 1
+
+    # Check that the sum of all the data in the transfer entry in the yaml file
+    # is the same as the sum of all the data in the transfer list. Don't count
+    # the tag id or the TE headers.
+
+    # every item in the entry dict must be an integer
+    yaml_total = 0
+    for key, data in iter_nested_dict(entry):
+        if key != "tag_id":
+            num_bytes = ceil(log2(data + 1) / 8)
+            yaml_total += sum(data.to_bytes(num_bytes, "little"))
+
+    tl_total = sum(tl.entries[0].data)
+
+    assert tl_total == yaml_total
+
+
+@pytest.mark.parametrize(
+    "entry,expected",
+    [
+        (
+            {
+                "tag_id": 0x102,
+                "ep_info": {
+                    "h": {
+                        "type": 0x01,
+                        "version": 0x02,
+                        "attr": 8,
+                    },
+                    "pc": 67239936,
+                    "spsr": 965,
+                    "args": [67112976, 67112960, 0, 0, 0, 0, 0, 0],
+                },
+            },
+            (
+                "0x00580201 0x00000008 0x04020000 0x00000000 "
+                "0x000003C5 0x00000000 0x04001010 0x00000000 "
+                "0x04001000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000"
+            ),
+        ),
+        (
+            {
+                "tag_id": 0x102,
+                "ep_info": {
+                    "h": {
+                        "type": 0x01,
+                        "version": 0x02,
+                        "attr": "EP_NON_SECURE | EP_ST_ENABLE",
+                    },
+                    "pc": 67239936,
+                    "spsr": 965,
+                    "args": [67112976, 67112960, 0, 0, 0, 0, 0, 0],
+                },
+            },
+            (
+                "0x00580201 0x00000005 0x04020000 0x00000000 "
+                "0x000003C5 0x00000000 0x04001010 0x00000000 "
+                "0x04001000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000 0x00000000 0x00000000 "
+                "0x00000000 0x00000000"
+            ),
+        ),
+    ],
+)
+def test_create_from_yaml_check_exact_data(
+    tlcrunner, tmpyamlconfig, tmptlstr, entry, expected
+):
+    """Test creating a TL from a yaml file, checking the exact sequence of
+    bytes. This is useful for checking that the alignment is correct. You can
+    get the expected sequence of bytes by copying it from the ArmDS debugger.
+    """
+    # create yaml config file
+    config = {
+        "has_checksum": True,
+        "max_size": 0x1000,
+        "entries": [entry],
+    }
+    with open(tmpyamlconfig, "w") as f:
+        yaml.safe_dump(config, f)
+
+    # invoke TLC
+    tlcrunner.invoke(
+        cli,
+        [
+            "create",
+            "--from-yaml",
+            tmpyamlconfig,
+            tmptlstr,
+        ],
+    )
+
+    # open TL and check
+    tl = TransferList.fromfile(tmptlstr)
+    assert tl is not None
+    assert len(tl.entries) == 1
+
+    # check expected and actual data
+    actual = tl.entries[0].data
+    actual = bytes_to_hex(actual)
+
+    assert actual == expected
+
+
+@pytest.mark.parametrize("option", ["-O", "--output"])
+def test_gen_tl_header_with_output_name(tlcrunner, tmptlstr, option, filename="test.h"):
+    with tlcrunner.isolated_filesystem():
+        result = tlcrunner.invoke(
+            cli,
+            [
+                "gen-header",
+                option,
+                filename,
+                tmptlstr,
+            ],
+        )
+
+        assert result.exit_code == 0
+        assert Path(filename).exists()
+
+
+def test_gen_tl_with_fdt_header(tmptlstr, tmpfdt):
+    tlcrunner = CliRunner()
+
+    with tlcrunner.isolated_filesystem():
+        tlcrunner.invoke(cli, ["create", "--size", 1000, "--fdt", tmpfdt, tmptlstr])
+
+        result = tlcrunner.invoke(
+            cli,
+            [
+                "gen-header",
+                tmptlstr,
+            ],
+        )
+
+        assert result.exit_code == 0
+        assert Path("header.h").exists()
+
+        with open("header.h", "r") as f:
+            dtb_match = search(r"DTB_OFFSET\s+(\d+)", "".join(f.readlines()))
+            assert dtb_match and dtb_match[1].isnumeric()
+
+
+def test_gen_empty_tl_c_header(tlcrunner, tmptlstr):
+    with tlcrunner.isolated_filesystem():
+        result = tlcrunner.invoke(
+            cli,
+            [
+                "gen-header",
+                tmptlstr,
+            ],
+        )
+
+        assert result.exit_code == 0
+        assert Path("header.h").exists()
+
+        with open("header.h", "r") as f:
+            lines = "".join(f.readlines())
+
+            assert TransferList.hdr_size == int(
+                findall(r"SIZE\s+(0x[0-9a-fA-F]+|\d+)", lines)[0], 16
+            )
+            assert TransferList.version == int(
+                findall(r"VERSION.+(0x[0-9a-fA-F]+|\d+)", lines)[0]
+            )
+
+
+def bytes_to_hex(data: bytes) -> str:
+    """Convert bytes to a hex string in the same format as the debugger in
+    ArmDS
+
+    You can copy data from the debugger in Arm Development Studio and put it
+    into a unit test. You can then run this function on the output from tlc,
+    and compare it to the data you copied.
+
+    The format is groups of 4 bytes with 0x prefixes separated by spaces.
+    Little endian is used.
+    """
+    words_hex = []
+    for i in range(0, len(data), 4):
+        word = data[i : i + 4]
+        word_int = int.from_bytes(word, "little")
+        word_hex = "0x" + f"{word_int:0>8x}".upper()
+        words_hex.append(word_hex)
+
+    return " ".join(words_hex)
+
+
+def iter_nested_dict(dictionary: dict):
+    for key, value in dictionary.items():
+        if isinstance(value, dict):
+            yield from iter_nested_dict(value)
+        else:
+            yield key, value
diff --git a/tools/tlc/tests/test_transfer_list.py b/tools/tlc/tests/test_transfer_list.py
new file mode 100644
index 00000000..e8c430e5
--- /dev/null
+++ b/tools/tlc/tests/test_transfer_list.py
@@ -0,0 +1,234 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Contains unit tests for the types TransferEntry and TransferList."""
+
+import math
+
+import pytest
+
+from tlc.te import TransferEntry
+from tlc.tl import TransferList
+
+large_data = 0xDEADBEEF.to_bytes(4, "big")
+small_data = 0x1234.to_bytes(3, "big")
+test_entries = [
+    (0, b""),
+    (1, small_data),
+    (1, large_data),
+    (0xFFFFFF, small_data),
+    (0xFFFFFF, large_data),
+]
+
+
+@pytest.mark.parametrize(
+    "size,csum",
+    [
+        (-1, None),
+        (0x18, 0x9E),
+        (0x1000, 0xA6),
+        (0x2000, 0x96),
+        (0x4000, 0x76),
+    ],
+)
+def test_make_transfer_list(size, csum):
+    if size < 8:
+        with pytest.raises(AssertionError):
+            tl = TransferList(size)
+    else:
+        tl = TransferList(size)
+
+        assert tl.signature == 0x4A0FB10B
+        assert not tl.entries
+        assert tl.sum_of_bytes() == 0
+        assert tl.checksum == csum
+
+
+@pytest.mark.parametrize(("tag_id", "data"), test_entries)
+def test_add_transfer_entry(tag_id, data):
+    tl = TransferList(0x1000)
+    te = TransferEntry(tag_id, len(data), data)
+
+    tl.add_transfer_entry(tag_id, data)
+
+    assert te in tl.entries
+    assert tl.size == TransferList.hdr_size + te.size
+
+
+@pytest.mark.parametrize(
+    ("tag_id", "data"),
+    [
+        (-1, None),  # tag out of range
+        (1, None),  # no data provided
+        (1, bytes(8000)),  # very large data > total size
+        (0x100000, b"0dd0edfe"),  # tag out of range
+    ],
+)
+def test_add_out_of_range_transfer_entry(tag_id, data):
+    tl = TransferList()
+
+    with pytest.raises(Exception):
+        tl.add_transfer_entry(tag_id, data)
+
+
+@pytest.mark.parametrize(("tag_id", "data"), test_entries)
+def test_calculate_te_sum_of_bytes(tag_id, data):
+    te = TransferEntry(tag_id, len(data), data)
+    csum = (
+        sum(data)
+        + sum(len(data).to_bytes(4, "big"))
+        + te.hdr_size
+        + sum(tag_id.to_bytes(4, "big"))
+    ) % 256
+    assert te.sum_of_bytes == csum
+
+
+@pytest.mark.parametrize(("tag_id", "data"), test_entries)
+def test_calculate_tl_checksum(tag_id, data):
+    tl = TransferList(0x1000)
+
+    tl.add_transfer_entry(tag_id, data)
+    assert tl.sum_of_bytes() == 0
+
+
+def test_empty_transfer_list_blob(tmpdir):
+    """Check that we can correctly create a transfer list header."""
+    test_file = tmpdir.join("test_tl_blob.bin")
+    tl = TransferList()
+    tl.write_to_file(test_file)
+
+    with open(test_file, "rb") as f:
+        assert f.read(tl.hdr_size) == tl.header_to_bytes()
+
+
+@pytest.mark.parametrize(("tag_id", "data"), test_entries)
+def test_single_te_transfer_list(tag_id, data, tmpdir):
+    """Check that we can create a complete TL with a single TE."""
+    test_file = tmpdir.join("test_tl_blob.bin")
+    tl = TransferList(0x1000)
+
+    tl.add_transfer_entry(tag_id, data)
+    tl.write_to_file(test_file)
+
+    te = tl.entries[0]
+
+    with open(test_file, "rb") as f:
+        assert f.read(tl.hdr_size) == tl.header_to_bytes()
+        assert int.from_bytes(f.read(3), "little") == te.id
+        assert int.from_bytes(f.read(1), "little") == te.hdr_size
+        assert int.from_bytes(f.read(4), "little") == te.data_size
+        assert f.read(te.data_size) == te.data
+
+
+def test_multiple_te_transfer_list(tmpdir):
+    """Check that we can create a TL with multiple TE's."""
+    test_file = tmpdir.join("test_tl_blob.bin")
+    tl = TransferList(0x1000)
+
+    for tag_id, data in test_entries:
+        tl.add_transfer_entry(tag_id, data)
+
+    tl.write_to_file(test_file)
+
+    with open(test_file, "rb") as f:
+        assert f.read(tl.hdr_size) == tl.header_to_bytes()
+        # Ensure that TE's have the correct alignment
+        for tag_id, data in test_entries:
+            f.seek(int(math.ceil(f.tell() / 2**tl.alignment) * 2**tl.alignment))
+            print(f.tell())
+            assert int.from_bytes(f.read(3), "little") == tag_id
+            assert int.from_bytes(f.read(1), "little") == TransferEntry.hdr_size
+            # Make sure the data in the TE matches the data in the original case
+            data_size = int.from_bytes(f.read(4), "little")
+            assert f.read(data_size) == data
+
+
+def test_read_empty_transfer_list_from_file(tmpdir):
+    test_file = tmpdir.join("test_tl_blob.bin")
+    original_tl = TransferList(0x1000)
+    original_tl.write_to_file(test_file)
+
+    # Read the contents of the file we just wrote
+    tl = TransferList.fromfile(test_file)
+    assert tl.header_to_bytes() == original_tl.header_to_bytes()
+    assert tl.sum_of_bytes() == 0
+
+
+def test_read_single_transfer_list_from_file(tmpdir):
+    test_file = tmpdir.join("test_tl_blob.bin")
+    original_tl = TransferList(0x1000)
+
+    original_tl.add_transfer_entry(test_entries[0][0], test_entries[0][1])
+    original_tl.write_to_file(test_file)
+
+    # Read the contents of the file we just wrote
+    tl = TransferList.fromfile(test_file)
+    assert tl.entries
+
+    te = tl.entries[0]
+    assert te.id == test_entries[0][0]
+    assert te.data == test_entries[0][1]
+    assert tl.sum_of_bytes() == 0
+
+
+def test_read_multiple_transfer_list_from_file(tmpdir):
+    test_file = tmpdir.join("test_tl_blob.bin")
+    original_tl = TransferList(0x1000)
+
+    for tag_id, data in test_entries:
+        original_tl.add_transfer_entry(tag_id, data)
+
+    original_tl.write_to_file(test_file)
+
+    # Read the contents of the file we just wrote
+    tl = TransferList.fromfile(test_file)
+
+    # The TE we derive from the file might have a an associated offset, compare
+    # the TE's based on the header in bytes, which doesn't account for this.
+    for te0, te1 in zip(tl.entries, original_tl.entries):
+        assert te0.header_to_bytes() == te1.header_to_bytes()
+
+    assert tl.sum_of_bytes() == 0
+
+
+@pytest.mark.parametrize("tag", [tag for tag, _ in test_entries])
+def test_remove_tag_from_file(tag):
+    tl = TransferList(0x1000)
+
+    for tag_id, data in test_entries:
+        tl.add_transfer_entry(tag_id, data)
+
+    removed_entries = list(filter(lambda te: te.id == tag, tl.entries))
+    original_size = tl.size
+    tl.remove_tag(tag)
+
+    assert not any(tag == te.id for te in tl.entries)
+    assert tl.size == original_size - sum(map(lambda te: te.size, removed_entries))
+
+
+def test_get_fdt_offset(tmpdir):
+    tl = TransferList(0x1000)
+    tl.add_transfer_entry(1, 0xEDFE0DD0.to_bytes(4, "big"))
+    f = tmpdir.join("blob.bin")
+
+    tl.write_to_file(f)
+
+    blob_tl = TransferList.fromfile(f)
+
+    assert blob_tl.hdr_size + TransferEntry.hdr_size == blob_tl.get_entry_data_offset(1)
+
+
+def test_get_missing_fdt_offset(tmpdir):
+    tl = TransferList(0x1000)
+    f = tmpdir.join("blob.bin")
+
+    tl.write_to_file(f)
+    blob_tl = TransferList.fromfile(f)
+
+    with pytest.raises(ValueError):
+        blob_tl.get_entry_data_offset(1)
diff --git a/tools/tlc/tlc/__init__.py b/tools/tlc/tlc/__init__.py
new file mode 100644
index 00000000..82f5f5bf
--- /dev/null
+++ b/tools/tlc/tlc/__init__.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Transfer List Compiler (TLC) is a Python-based CLI for efficiently handling transfer lists."""
+
+import sys
+
+if sys.version_info >= (3, 8):
+    from importlib import metadata as importlib_metadata
+else:
+    import importlib_metadata
+
+
+def get_version() -> str:
+    try:
+        return importlib_metadata.version(__name__)
+    except importlib_metadata.PackageNotFoundError:  # pragma: no cover
+        return "unknown"
+
+
+version: str = get_version()
diff --git a/tools/tlc/tlc/__main__.py b/tools/tlc/tlc/__main__.py
new file mode 100644
index 00000000..03ffa0e7
--- /dev/null
+++ b/tools/tlc/tlc/__main__.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+from tlc.cli import cli
+
+if __name__ == "__main__":
+    cli()
diff --git a/tools/tlc/tlc/cli.py b/tools/tlc/tlc/cli.py
new file mode 100644
index 00000000..3d609380
--- /dev/null
+++ b/tools/tlc/tlc/cli.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python3
+# type: ignore[attr-defined]
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Module defining the Transfer List Compiler (TLC) command line interface."""
+
+from pathlib import Path
+
+import click
+import jinja2
+import yaml
+
+from tlc.tl import *
+
+
+@click.group()
+@click.version_option()
+def cli():
+    pass
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(dir_okay=False))
+@click.option(
+    "-s", "--size", default=0x1000, type=int, help="Maximum size of the Transfer List"
+)
+@click.option(
+    "--fdt",
+    type=click.Path(exists=True),
+    help="Path to flattened device tree (FDT).",
+)
+@click.option(
+    "--entry",
+    type=(int, click.Path(exists=True)),
+    multiple=True,
+    help="A tag ID and the corresponding path to a binary blob in the form <id> <path-to-blob>.",
+)
+@click.option(
+    "--flags",
+    default=TRANSFER_LIST_ENABLE_CHECKSUM,
+    show_default=True,
+    help="Settings for the TL's properties.",
+)
+@click.option(
+    "--from-yaml",
+    type=click.Path(exists=True),
+    help="Create the transfer list from a YAML config file.",
+)
+def create(filename, size, fdt, entry, flags, from_yaml):
+    """Create a new Transfer List."""
+    try:
+        if from_yaml:
+            with open(from_yaml, "r") as f:
+                config = yaml.safe_load(f)
+
+            tl = TransferList.from_dict(config)
+        else:
+            tl = TransferList(size)
+
+            entry = (*entry, (1, fdt)) if fdt else entry
+
+            for id, path in entry:
+                tl.add_transfer_entry_from_file(id, path)
+    except MemoryError as mem_excp:
+        raise MemoryError(
+            "TL max size exceeded, consider increasing with the option -s"
+        ) from mem_excp
+
+    tl.write_to_file(filename)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+    "--fdt-offset",
+    is_flag=True,
+    help="Returns the offset of FDT in the TL if it is present.",
+)
+@click.option(
+    "--header",
+    is_flag=True,
+    help="Print the Transfer List header.",
+)
+@click.option(
+    "--entries",
+    is_flag=True,
+    help="Print the Transfer List entries.",
+)
+def info(filename, fdt_offset, header, entries):
+    """Print the contents of an existing Transfer List.
+
+    This command allows you to extract the data stored in a binary blob
+    representing a transfer list (TL). The transfer list must comply with the
+    version of the firmware handoff specification supported by this tool.
+    """
+    tl = TransferList.fromfile(filename)
+
+    if fdt_offset:
+        return print(tl.get_entry_data_offset(1))
+
+    if header and entries or not (header or entries):
+        print(tl, sep="")
+        if tl.entries:
+            print("----", tl.get_transfer_entries_str(), sep="\n")
+    elif entries:
+        print(tl.get_transfer_entries_str())
+    elif header:
+        print(tl)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+    "--tags",
+    type=int,
+    multiple=True,
+    help="Tags to be removed from TL.",
+)
+def remove(filename, tags):
+    """Remove Transfer Entries with given tags.
+
+    Remove Transfer Entries with given tags from a Transfer List."""
+    tl = TransferList.fromfile(filename)
+
+    for tag in tags:
+        tl.remove_tag(tag)
+    tl.write_to_file(filename)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+    "--entry",
+    type=(int, click.Path(exists=True)),
+    multiple=True,
+    help="A tag ID and the corresponding path to a binary blob in the form <id> <path-to-blob>.",
+)
+def add(filename, entry):
+    """Update an existing Transfer List with given images."""
+    tl = TransferList.fromfile(filename)
+
+    for id, path in entry:
+        tl.add_transfer_entry_from_file(id, path)
+
+    tl.write_to_file(filename)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+    "-C", type=click.Path(exists=True), help="Output directory for extracted images."
+)
+def unpack(filename, c):
+    """Unpack images from a Transfer List."""
+    tl = TransferList.fromfile(filename)
+    pwd = Path(".") if not c else Path(c)
+
+    for i, te in enumerate(tl.entries):
+        with open(pwd / f"te_{i}_{te.id}.bin", "wb") as f:
+            f.write(te.data)
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+@click.option(
+    "--output",
+    "-O",
+    type=click.Path(exists=False),
+    help="Output filename for the header",
+    default=Path("header.h"),
+)
+def gen_header(filename, output):
+    """Generate a header with common definitions."""
+    tl = TransferList.fromfile(filename)
+    tmp_keys = tl.__dict__
+    tmp_keys["header_guard"] = Path(output).name.replace(".", "_").upper()
+
+    dtb_te = tl.get_entry(1)
+
+    if dtb_te:
+        tmp_keys["dtb_offset"] = dtb_te.offset + dtb_te.hdr_size
+
+    env = jinja2.Environment(
+        loader=jinja2.PackageLoader("tlc", "templates"),
+    )
+    template = env.get_template("header.h.j2")
+    with open(output, "w") as f:
+        f.write(template.render(tmp_keys))
+
+
+@cli.command()
+@click.argument("filename", type=click.Path(exists=True, dir_okay=False))
+def validate(filename):
+    """Validate the contents of an existing Transfer List."""
+    TransferList.fromfile(filename)
+    print("Valid TL!")
diff --git a/tools/tlc/tlc/te.py b/tools/tlc/tlc/te.py
new file mode 100644
index 00000000..cf7aa67c
--- /dev/null
+++ b/tools/tlc/tlc/te.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Module containing definitions pertaining to the 'Transfer Entry' (TE) type."""
+
+from typing import ClassVar
+
+import struct
+from dataclasses import dataclass
+
+
+@dataclass
+class TransferEntry:
+    """Class representing a Transfer Entry."""
+
+    id: int
+    data_size: int
+    data: bytes
+    hdr_size: int = 8
+    offset: int = 0
+    # Header encoding, with little-endian byte order.
+    encoding: ClassVar[str] = "<BI"
+
+    def __post_init__(self):
+        if self.id < 0 or self.id > 0xFFFFFF:
+            raise ValueError(
+                f"Out of bounds tag ID: {self.id:x}.\n"
+                f"Valid range is from 0 to 0xFFFFFF. Please ensure the tag ID is within this range."
+            )
+
+    def __str__(self) -> str:
+        return "\n".join(
+            [
+                f"{k:<10} {hex(v)}"
+                for k, v in vars(self).items()
+                if not isinstance(v, bytes)
+            ]
+        )
+
+    @property
+    def size(self) -> int:
+        return self.hdr_size + len(self.data)
+
+    @property
+    def sum_of_bytes(self) -> int:
+        return (sum(self.header_to_bytes()) + sum(self.data)) % 256
+
+    def header_to_bytes(self) -> bytes:
+        return self.id.to_bytes(3, "little") + struct.pack(
+            self.encoding, self.hdr_size, self.data_size
+        )
diff --git a/tools/tlc/tlc/templates/header.h.j2 b/tools/tlc/tlc/templates/header.h.j2
new file mode 100644
index 00000000..87707cec
--- /dev/null
+++ b/tools/tlc/tlc/templates/header.h.j2
@@ -0,0 +1,16 @@
+/*
+ * Auto-generated by TLC, this file includes declarations and macros
+ * derived from a Transfer List input.
+ */
+
+#ifndef {{ header_guard }}
+#define {{ header_guard }}
+
+{% if dtb_offset -%}
+#define TRANSFER_LIST_DTB_OFFSET	{{ "0x%x" % dtb_offset }}
+{%- endif %}
+#define TRANSFER_LIST_CONVENTION_VERSION	{{ version }}
+#define TRANSFER_LIST_HEADER_SIZE	{{ "0x%x" % hdr_size }}
+#define TRANSFER_LIST_SIZE		{{ "0x%x" % size }}
+
+#endif /* {{ header_guard }} */
diff --git a/tools/tlc/tlc/tl.py b/tools/tlc/tlc/tl.py
new file mode 100644
index 00000000..98d2205b
--- /dev/null
+++ b/tools/tlc/tlc/tl.py
@@ -0,0 +1,363 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+"""Module containing definitions pertaining to the 'Transfer List' (TL) type."""
+
+from typing import Any, Dict, List, Optional
+
+import math
+import struct
+from dataclasses import dataclass
+from functools import reduce
+from pathlib import Path
+
+from tlc.te import TransferEntry
+
+TRANSFER_LIST_ENABLE_CHECKSUM = 0b1
+
+# Description of each TE type. For each TE, there is a tag ID, a format (to be
+# used in struct.pack to encode the TE), and a list of field names that can
+# appear in the yaml file for that TE. Some fields are missing, if that TE has
+# to be processed differently, or if it can only be added with a blob file.
+transfer_entry_formats: Dict[int, Any] = {
+    0: {
+        "tag_name": "empty",
+        "format": "4x",
+        "fields": [],
+    },
+    1: {
+        "tag_name": "fdt",
+    },
+    2: {
+        "tag_name": "hob_block",
+    },
+    3: {
+        "tag_name": "hob_list",
+    },
+    4: {
+        "tag_name": "acpi_table_aggregate",
+    },
+    5: {
+        "tag_name": "tpm_event_log_table",
+        "fields": ["event_log", "flags"],
+    },
+    6: {
+        "tag_name": "tpm_crb_base_address_table",
+        "format": "QI",
+        "fields": ["crb_base_address", "crb_size"],
+    },
+    0x100: {
+        "tag_name": "optee_pageable_part",
+        "format": "Q",
+        "fields": ["pp_addr"],
+    },
+    0x101: {
+        "tag_name": "dt_spmc_manifest",
+    },
+    0x102: {
+        "tag_name": "exec_ep_info",
+        "format": "2BHIQI4x8Q",
+        "fields": ["ep_info"],
+    },
+    0x104: {
+        "tag_name": "sram_layout",
+        "format": "2Q",
+        "fields": ["addr", "size"],
+    },
+}
+tag_name_to_tag_id = {
+    te["tag_name"]: tag_id for tag_id, te in transfer_entry_formats.items()
+}
+
+
+class TransferList:
+    """Class representing a Transfer List based on version 1.0 of the Firmware Handoff specification."""
+
+    # Header encoding, with little-endian byte order.
+    encoding = "<I4B4I"
+    hdr_size = 0x18
+    signature = 0x4A0FB10B
+    version = 1
+
+    def __init__(
+        self, max_size: int = hdr_size, flags: int = TRANSFER_LIST_ENABLE_CHECKSUM
+    ) -> None:
+        assert max_size >= self.hdr_size
+        self.checksum: int = 0
+        self.alignment: int = 3
+        self.size = self.hdr_size
+        self.total_size = max_size
+        self.flags = flags
+        self.entries: List[TransferEntry] = []
+        self.update_checksum()
+
+    def __str__(self) -> str:
+        return "\n".join(
+            [
+                f"{k:<10} {hex(v)}"
+                for k, v in vars(self).items()
+                if not isinstance(v, list)
+            ]
+        )
+
+    def get_transfer_entries_str(self):
+        return "\n----\n".join([str(te) for _, te in enumerate(self.entries)])
+
+    @classmethod
+    def fromfile(cls, filepath: Path) -> "TransferList":
+        tl = cls()
+
+        with open(filepath, "rb") as f:
+            (
+                tl.signature,
+                tl.checksum,
+                tl.version,
+                tl.hdr_size,
+                tl.alignment,
+                used_size,
+                tl.total_size,
+                tl.flags,
+                _,
+            ) = struct.unpack(
+                cls.encoding,
+                f.read(tl.hdr_size),
+            )
+
+            if tl.signature != TransferList.signature:
+                raise ValueError(f"Invalid TL signature 0x{tl.signature:x}!")
+            elif tl.version == 0 or tl.version > 0xFF:
+                raise ValueError(f"Invalid TL version 0x{tl.version:x}!")
+            else:
+                while tl.size < used_size:
+                    # We add an extra padding byte into the header so we can extract
+                    # the 3-byte wide ID as a 4-byte uint, shift out this padding
+                    # once we have the id.
+                    te_base = f.tell()
+                    (id, hdr_size, data_size) = struct.unpack(
+                        TransferEntry.encoding[0] + "I" + TransferEntry.encoding[1:],
+                        b"\x00" + f.read(TransferEntry.hdr_size),
+                    )
+
+                    id >>= 8
+
+                    te = tl.add_transfer_entry(id, f.read(data_size))
+                    te.offset = te_base
+                    f.seek(align(te_base + hdr_size + data_size, 2**tl.alignment))
+
+        return tl
+
+    @classmethod
+    def from_dict(cls, config: Dict[str, Any]) -> "TransferList":
+        """Create a TL from data in a dictionary
+
+        The dictionary should have the same format as the yaml config files.
+        See the readme for more detail.
+
+        :param config: Dictionary containing the data described above.
+        """
+        # get settings from config and set defaults
+        max_size = config.get("max_size", 0x1000)
+        has_checksum = config.get("has_checksum", True)
+
+        flags = TRANSFER_LIST_ENABLE_CHECKSUM if has_checksum else 0
+
+        tl = cls(max_size, flags)
+
+        for entry in config["entries"]:
+            tl.add_transfer_entry_from_dict(entry)
+
+        return tl
+
+    def header_to_bytes(self) -> bytes:
+        return struct.pack(
+            self.encoding,
+            self.signature,
+            self.checksum,
+            self.version,
+            self.hdr_size,
+            self.alignment,
+            self.size,
+            self.total_size,
+            self.flags,
+            0,
+        )
+
+    def update_checksum(self) -> None:
+        """Calculates the checksum based on the sum of bytes."""
+        self.checksum = 256 - ((self.sum_of_bytes() - self.checksum) % 256)
+
+    def sum_of_bytes(self) -> int:
+        """Sum of all bytes between the base address and the end of that last TE (modulo 0xff)."""
+        return (
+            sum(self.header_to_bytes()) + sum(te.sum_of_bytes for te in self.entries)
+        ) % 256
+
+    def get_entry(self, tag_id: int) -> Optional[TransferEntry]:
+        for te in self.entries:
+            if te.id == tag_id:
+                return te
+
+        return None
+
+    def get_entry_data_offset(self, tag_id: int) -> int:
+        """Returns offset of data of a TE from the base of the TL."""
+        te = self.get_entry(tag_id)
+
+        if not te:
+            raise ValueError(f"Tag {tag_id} not found in TL!")
+
+        return te.offset + te.hdr_size
+
+    def add_transfer_entry(self, tag_id: int, data: bytes) -> TransferEntry:
+        """Appends a TransferEntry into the internal list of TE's."""
+        if not (self.total_size >= self.size + TransferEntry.hdr_size + len(data)):
+            raise MemoryError(
+                f"TL size has exceeded the maximum allocation {self.total_size}."
+            )
+        else:
+            te = TransferEntry(tag_id, len(data), data)
+            self.entries.append(te)
+            self.size += te.size
+            self.update_checksum()
+            return te
+
+    def add_transfer_entry_from_struct_format(
+        self, tag_id: int, struct_format: str, *args: Any
+    ) -> TransferEntry:
+        struct_format = "<" + struct_format
+        data = struct.pack(struct_format, *args)
+        return self.add_transfer_entry(tag_id, data)
+
+    def add_entry_point_info_transfer_entry(
+        self, entry: Dict[str, Any]
+    ) -> TransferEntry:
+        """Add entry_point_info transfer entry
+
+        :param entry: Dictionary of the transfer entry, in the same format as
+        the YAML file.
+        """
+        ep_info = entry["ep_info"]
+        header = ep_info["h"]
+
+        # size of the entry_point_info struct
+        entry_point_size = 88
+
+        attr = header["attr"]
+        if type(attr) is str:
+            # convert string of flags names to an integer
+
+            # bit number  | 0                     | 1                    |
+            # ------------|-----------------------|----------------------|
+            # 0           | secure                | non-secure           |
+            # 1           | little endian         | big-endian           |
+            # 2           | disable secure timer  | enable secure timer  |
+            # 3           | executable            | non-executable       |
+            # 4           | first exe             | not first exe        |
+            #
+            # Bit 5 and bit 0 are used to determine the security state.
+
+            flag_names = {
+                "EP_SECURE": 0x0,
+                "EP_NON_SECURE": 0x1,
+                "EP_REALM": 0x21,
+                "EP_EE_LITTLE": 0x0,
+                "EP_EE_BIG": 0x2,
+                "EP_ST_DISABLE": 0x0,
+                "EP_ST_ENABLE": 0x4,
+                "EP_NON_EXECUTABLE": 0x0,
+                "EP_EXECUTABLE": 0x8,
+                "EP_FIRST_EXE": 0x10,
+            }
+
+            # create list of integer flags, then bitwise-or them together
+            flags = [flag_names[f.strip()] for f in attr.split("|")]
+            attr = reduce(lambda x, y: x | y, flags)
+
+        return self.add_transfer_entry_from_struct_format(
+            0x102,
+            transfer_entry_formats[0x102]["format"],
+            header["type"],
+            header["version"],
+            entry_point_size,
+            attr,
+            ep_info["pc"],
+            ep_info["spsr"],
+            *ep_info["args"],
+        )
+
+    def add_transfer_entry_from_dict(
+        self,
+        entry: Dict[str, Any],
+    ) -> TransferEntry:
+        """Add a transfer entry from data in a dictionary
+
+        The dictionary should have the same format as the entries in the yaml
+        config files. See the readme for more detail.
+
+        :param entry: Dictionary containing the data described above.
+        """
+        # Tag_id is either a tag name or a tag id. Use it to get the TE format.
+        tag_id = entry["tag_id"]
+        if tag_id in tag_name_to_tag_id:
+            tag_id = tag_name_to_tag_id[tag_id]
+        te_format = transfer_entry_formats[tag_id]
+        tag_name = te_format["tag_name"]
+
+        if "blob_file_path" in entry:
+            return self.add_transfer_entry_from_file(tag_id, entry["blob_file_path"])
+        elif tag_name == "tpm_event_log_table":
+            with open(entry["event_log"], "rb") as f:
+                event_log_data = f.read()
+
+            flags_bytes = entry["flags"].to_bytes(4, "little")
+            data = flags_bytes + event_log_data
+
+            return self.add_transfer_entry(tag_id, data)
+        elif tag_name == "exec_ep_info":
+            return self.add_entry_point_info_transfer_entry(entry)
+        elif "format" in te_format and "fields" in te_format:
+            fields = [entry[field] for field in te_format["fields"]]
+            return self.add_transfer_entry_from_struct_format(
+                tag_id, te_format["format"], *fields
+            )
+        else:
+            raise ValueError(f"Invalid transfer entry {entry}.")
+
+    def add_transfer_entry_from_file(self, tag_id: int, path: Path) -> TransferEntry:
+        with open(path, "rb") as f:
+            return self.add_transfer_entry(tag_id, f.read())
+
+    def write_to_file(self, file: Path) -> None:
+        """Write the contents of the TL to a file."""
+        with open(file, "wb") as f:
+            f.write(self.header_to_bytes())
+            for te in self.entries:
+                assert f.tell() + te.hdr_size + te.data_size < self.total_size
+                te_base = f.tell()
+                f.write(te.header_to_bytes())
+                f.write(te.data)
+                # Ensure the next TE has the correct alignment
+                f.write(
+                    bytes(
+                        (
+                            align(
+                                te_base + te.hdr_size + te.data_size, 2**self.alignment
+                            )
+                            - f.tell()
+                        )
+                    )
+                )
+
+    def remove_tag(self, tag: int) -> None:
+        self.entries = list(filter(lambda te: te.id != tag, self.entries))
+        self.size = self.hdr_size + sum(map(lambda te: te.size, self.entries))
+        self.update_checksum()
+
+
+def align(n, alignment):
+    return int(math.ceil(n / alignment) * alignment)
diff --git a/tools/tlc/tox.ini b/tools/tlc/tox.ini
new file mode 100644
index 00000000..4fd141f1
--- /dev/null
+++ b/tools/tlc/tox.ini
@@ -0,0 +1,26 @@
+[tox]
+envlist = py38, py39, py310, py311, py312, lint
+
+[testenv]
+allowlist_externals = poetry
+commands =
+    poetry install -v --with dev
+    poetry run pytest
+
+[testenv:format]
+description = Run linters and type checks
+skip_install = true
+allowlist_externals = poetry
+commands =
+    poetry run black .
+    poetry run isort .
+
+[testenv:lint]
+description = Run linters and type checks
+skip_install = true
+allowlist_externals = poetry
+commands =
+    poetry run black --check .
+    poetry run isort --check-only .
+    poetry run mypy .
+    poetry run darglint tlc tests
-- 
GitLab


From c32f2d4753e527e9ffedddf27ce6036e4b5c84c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dylan=20A=C3=AFssi?= <dylan.aissi@collabora.com>
Date: Mon, 10 Mar 2025 17:48:02 +0100
Subject: [PATCH 2/3] Release arm-trusted-firmware version
 2.12.0+dfsg-2+apertis1
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Dylan Aïssi <dylan.aissi@collabora.com>
---
 debian/changelog | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 255734c0..bb8ca1e8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+arm-trusted-firmware (2.12.0+dfsg-2+apertis1) apertis; urgency=medium
+
+  * Sync from debian/trixie.
+  * Remaining Apertis specific changes:
+    - Add build profile for QEMU.
+    - Build for the ls1028ardb platform.
+
+ -- Dylan Aïssi <dylan.aissi@collabora.com>  Mon, 10 Mar 2025 17:44:24 +0100
+
 arm-trusted-firmware (2.12.0+dfsg-2) unstable; urgency=medium
 
   [ Martyn Welch ]
-- 
GitLab


From 2635af89375f81a8d9e09eb43762590fd55aa2f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dylan=20A=C3=AFssi?= <dylan.aissi@collabora.com>
Date: Mon, 10 Mar 2025 16:49:15 +0000
Subject: [PATCH 3/3] Refresh the automatically detected licensing information
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Dylan Aïssi <dylan.aissi@collabora.com>
---
 debian/apertis/copyright | 2910 +++++++++++++++++++++++---------------
 1 file changed, 1766 insertions(+), 1144 deletions(-)

diff --git a/debian/apertis/copyright b/debian/apertis/copyright
index 0329b806..52f028b2 100644
--- a/debian/apertis/copyright
+++ b/debian/apertis/copyright
@@ -1,90 +1,149 @@
 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 
 Files: *
-Copyright: no-info-found
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-Clause
 
-Files: docs/* docs/components/* docs/design/* docs/design_documents/* docs/plat/nxp/* docs/plat/st/* fdts/* include/dt-bindings/pinctrl/* include/lib/libfdt/* lib/libfdt/*
+Files: docs/about/* docs/components/* docs/design/* docs/design_documents/* docs/getting_started/* docs/perf/* docs/plat/arm/* docs/plat/st/* docs/process/* docs/threat_model/* docs/tools/* fdts/* include/lib/libfdt/* lib/libfdt/*
 Copyright:
  1989 Regents of the University of California.
- 1998 Softweyr LLC.  All rights reserved.
+ 1998 Softweyr LLC.
  2001 David E. O'Brien
  2005 MontaVista Software, Inc.
  2005 Nokia Corporation
  2011 The FreeBSD Foundation
  2012-2021 Roberto E. Vargas Caballero
- 2013-2023 ARM Limited and Contributors. All rights reserved.
- 2013-2023 Arm Limited and Contributors. All rights reserved.
- 2014-2023 Arm Limited. All rights reserved.
- 2014-2016 Freescale Semiconductor, Inc.
- 2014 Linaro Limited. All rights reserved.
- 2014-2023 STMicroelectronics - All Rights Reserved
+ 2013-2024 ARM Limited and Contributors.
+ 2013-2024 Arm Limited and Contributors.
+ 2014 Linaro Limited.
  2014 STMicroelectronics International N.V.
+ 2014-2016 Freescale Semiconductor, Inc.
+ 2014-2023 Arm Limited.
+ 2014-2023 STMicroelectronics
  2015-2021 Broadcom
- 2015-2023 NVIDIA Corporation. All rights reserved.
- 2015-2023 Renesas Electronics Corporation.
- 2015-2023 Renesas Electronics Corporation. All rights
- 2015-2023 Renesas Electronics Corporation. All rights reserved.
- 2016-2020 Marvell International Ltd.
- 2016-2022 Linaro Limited. All rights reserved.
+ 2015-2022 Xilinx Inc.
+ 2015-2023 NVIDIA Corporation.
+ 2015-2024 Arm Limited.
+ 2015-2024 Renesas Electronics Corporation
+ 2015-2024 STMicroelectronics
  2016-2021 Marvell International Ltd.
+ 2016-2022 Linaro Limited.
  2016-2023 NXP
- 2017-2020 Arm Limited and Contributors. All rights reserved.
- 2017-2023 NVIDIA CORPORATION. All rights reserved.
+ 2016-2024 ARM Limited and Contributors.
+ 2016-2024 STMicroelectronics
+ 2017-2020 Arm Limited and Contributors.
  2017-2022 NXP Semiconductors
+ 2017-2022 Xilinx, Inc.
+ 2017-2023 NVIDIA CORPORATION.
  2017-2023 Nuvoton Ltd.
  2017-2023 Nuvoton Technology Corp.
- 2017-2022 Xilinx, Inc. All rights reserved.
  2018 Andre Przywara <osp@andrep.de>
- 2018-2020 Arm Limited and Contributors.
  2018 Icenowy Zheng <icenowy@aosc.io>
  2018-2019 Linaro
- 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
- 2018-2021 The Linux Foundation. All rights reserved.
- 2019-2023 STMicroelectronics - All Rights Reserved
- 2019-2020 Broadcom.
+ 2018-2020 Arm Limited and Contributors.
+ 2018-2021 The Linux Foundation.
+ 2018-2022 Xilinx Inc.
+ 2018-2024 Arm Limited and Contributors.
+ 2018-2024 Arm Limited.
+ 2018-2024 Marvell International Ltd.
+ 2018-2024 STMicroelectronics
+ 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
  2019 Carlo Caione <ccaione@baylibre.com>
- 2019-2023 Intel Corporation. All rights reserved.
- 2019-2022 Linaro Limited
- 2019-2020 Linaro Limited and Contributors.
- 2019-2023 Linaro Limited and Contributors. All rights reserved.
- 2019-2023 MediaTek Inc. All rights reserved.
- 2019-2022 NXP. All rights reserved.
  2019 Remi Pommarel <repk@triplefau.lt>
  2019 Repk repk@triplefau.lt
- 2019-2022 Socionext Inc. All rights reserved.
  2019 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
- 2020-2022 ARM Limited and Contributors. All rights reserved.
- 2020-2023 Google LLC. All rights reserved.
+ 2019-2020 Broadcom.
+ 2019-2020 Linaro Limited and Contributors.
+ 2019-2021 2024 NXP
+ 2019-2022 Linaro Limited
+ 2019-2022 Linaro Limited.
+ 2019-2022 NXP.
+ 2019-2022 Socionext Inc.
+ 2019-2023 Intel Corporation.
+ 2019-2023 Linaro Limited and Contributors.
+ 2019-2023 MediaTek Inc.
+ 2019-2023 STMicroelectronics
+ 2019-2024 Arm Limited and Contributors.
+ 2019-2024 NXP
+ 2019-2024 STMicroelectronics
  2020 Marek Behun, CZ.NIC
- 2020 Marvell Technology Group Ltd. All rights reserved.
- 2020 MediaTek Inc. All rights reserved.
+ 2020 Marvell Technology Group Ltd.
+ 2020 MediaTek Inc.
  2020 NXP.
  2020 Nuvia Inc
  2020-2021 Sartura Ltd.
  2020-2021 Siemens AG
- 2021 Xilinx Inc.
+ 2020-2023 Google LLC
+ 2020-2024 Arm Limited and Contributors.
+ 2020-2024 Arm Limited.
+ 2020-2024 MediaTek Inc.
+ 2020-2024 NXP
  2021 Arm
  2021 Arm Limited
  2021 Globalscale technologies, Inc.
  2021 Marek Behun <marek.behun@nic.cz>
- 2021-2022 ProvenRun S.A.S. All rights reserved.
  2021 Semihalf.
  2021 Sipeed
+ 2021 Xilinx Inc.
+ 2021-2022 ProvenRun S.A.S.
+ 2021-2022 Xilinx Inc.
+ 2021-2023 Renesas Electronics Corporation.
  2021-2023 Stephan Gerhold <stephan@gerhold.net>
- 2022-2023 Advanced Micro Devices, Inc. All rights reserved.
- 2022-2023 Arm Ltd. All rights reserved.
- 2022 Fujitsu Limited and Contributors. All rights reserved.
+ 2021-2024 ARM Limited and Contributors.
+ 2021-2024 ARM Limited.
+ 2021-2024 Arm Limited and Contributors.
+ 2021-2024 Arm Limited.
+ 2021-2024 MediaTek Inc.
+ 2021-2024 NXP
+ 2021-2024 STMicroelectronics
+ 2022 Advanced Micro Devices Inc.
+ 2022 Arm Limited and Contributors.
+ 2022 Fujitsu Limited and Contributors.
  2022 Leica Geosystems AG
  2022 Linaro
- 2022-2023 Linaro.
- 2022 Mediatek Inc. All rights reserved.
- 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ 2022 Mediatek Inc.
+ 2022 Qualcomm Innovation Center, Inc.
  2022 The Hafnium Authors.
- 2023 Advanced Micro Devices. All rights reserved.
- 2023 Arm Limited. All rights reserved
+ 2022 Xilinx Inc.
+ 2022-2023 Advanced Micro Devices, Inc.
+ 2022-2023 Arm Ltd.
+ 2022-2023 Linaro.
+ 2022-2024 ARM Limited and Contributors.
+ 2022-2024 Advanced Micro Devices Inc.
+ 2022-2024 Arm Limited and Contributors.
+ 2022-2024 Arm Limited.
+ 2022-2024 Arm Ltd.
+ 2022-2024 MediaTek Inc.
+ 2022-2024 STMicroelectronics
+ 2023 ARM Limited and Contributors.
+ 2023 Advanced Micro Devices.
+ 2023 Arm Limited.
  2023 Aspeed Technology Inc.
- 2023 Pengutronix. All rights reserved.
+ 2023 MediaTek Inc.
+ 2023 Pengutronix.
+ 2023-2024 Advanced Micro Devices Inc.
+ 2023-2024 Arm Limited and Contributors.
+ 2023-2024 Arm Limited.
+ 2023-2024 Arm Ltd.
+ 2023-2024 Linaro Limited and Contributors.
+ 2023-2024 NXP
+ 2023-2024 STMicroelectronics
+ 2024 ARM Limited and Contributors.
+ 2024 ARM Limited.
+ 2024 Altera Corporation.
+ 2024 Arm Limited and Contributors.
+ 2024 Arm Limited.
+ 2024 Arm Ltd.
+ 2024 Intel Corporation.
+ 2024 Linaro Limited and Contributors.
+ 2024 Mario Bălănică <mariobalanica02@gmail.com>
+ 2024 Mediatek Inc.
+ 2024 NVIDIA Corporation.
+ 2024 NXP
+ 2024 Pengutronix Inc.
+ 2024 Rockchip Inc.
+ 2024 STMicroelectronics
+ 2024 The ChromiumOS Authors.
 License: BSD-3-Clause
 
 Files: lib/zlib/*
@@ -94,264 +153,280 @@ Copyright:
 License: Zlib
 
 Files: .checkpatch.conf
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: .commitlintrc.js
- .readthedocs.yaml
- .versionrc.js
+ .cz-adapter.cjs
+ .versionrc.cjs
  changelog.yaml
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: .editorconfig
  Makefile
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: .husky/*
+Files: .husky/commit-msg.gerrit
 Copyright: 2009, The Android Open Source Project
 License: Apache-2.0
 
+Files: .readthedocs.yaml
+Copyright: 2023, 2024, Arm Limited.
+License: BSD-3-clause
+
 Files: bl1/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: bl1/aarch32/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: bl1/aarch64/bl1_arch_setup.c
+ bl1/aarch64/bl1_exceptions.S
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: bl1/aarch64/bl1_context_mgmt.c
- bl1/aarch64/bl1_entrypoint.S
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: bl1/bl1_fwu.c
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: bl1/bl1.ld.S
- bl1/bl1.mk
- bl1/bl1_main.c
- bl1/bl1_private.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: bl1/tbbr/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl2/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl2/aarch32/bl2_el3_entrypoint.S
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl2/aarch32/bl2_run_next_image.S
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: bl2/aarch64/bl2_el3_entrypoint.S
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl2/aarch64/bl2_rme_entrypoint.S
  bl2/aarch64/bl2_run_next_image.S
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: bl2/bl2.ld.S
  bl2/bl2.mk
  bl2/bl2_el3.ld.S
  bl2/bl2_main.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl2u/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: bl2u/aarch32/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: bl2u/bl2u.ld.S
- bl2u/bl2u.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: bl2u/aarch64/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl31/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl31/aarch64/bl31_entrypoint.S
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl31/aarch64/ea_delegate.S
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl31/bl31_traps.c
-Copyright: 2023, NVIDIA Corporation.
- 2019, 2022, ARM Limited.
+Copyright: 2021-2024, NVIDIA Corporation.
+ 2019-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: bl32/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: bl32/sp_min/sp_min_private.h
- bl32/sp_min/wa_cve_2017_5715_bpiall.S
+Files: bl32/sp_min/wa_cve_2017_5715_bpiall.S
  bl32/sp_min/wa_cve_2017_5715_icache_inv.S
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: bl32/tsp/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Files: bl32/tsp/aarch64/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: bl32/tsp/ffa_helpers.c
  bl32/tsp/ffa_helpers.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: bl32/tsp/tsp.ld.S
- bl32/tsp/tsp.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: bl32/tsp/tsp_interrupt.c
+ bl32/tsp/tsp_private.h
+ bl32/tsp/tsp_timer.c
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: common/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: common/aarch64/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: common/aarch64/debug.S
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: common/aarch64/early_exceptions.S
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: common/bl_common.c
+ common/fdt_wrappers.c
  common/feat_detect.c
  common/tf_log.c
  common/uuid.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: common/fdt_wrappers.mk
  common/tf_crc32.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: debian/*
-Copyright: 
-  1989 Regents of the University of California.
-  1998 Softweyr LLC.  All rights reserved.
-  2001 David E. O'Brien
-  2005 MontaVista Software, Inc.
-  2005 Nokia Corporation
-  2011 The FreeBSD Foundation
-  2012-2021 Roberto E. Vargas Caballero
-  2013-2023 ARM Limited and Contributors. All rights reserved.
-  2013-2023 Arm Limited and Contributors. All rights reserved.
-  2014-2023 Arm Limited. All rights reserved.
-  2014-2016 Freescale Semiconductor, Inc.
-  2014 Linaro Limited. All rights reserved.
-  2014-2023 STMicroelectronics - All Rights Reserved
-  2014 STMicroelectronics International N.V.
-  2015-2021 Broadcom
-  2015-2023 NVIDIA Corporation. All rights reserved.
-  2015-2023 Renesas Electronics Corporation.
-  2015-2023 Renesas Electronics Corporation. All rights
-  2015-2023 Renesas Electronics Corporation. All rights reserved.
-  2016-2020 Marvell International Ltd.
-  2016-2022 Linaro Limited. All rights reserved.
-  2016-2021 Marvell International Ltd.
-  2016-2023 NXP
-  2017-2020 Arm Limited and Contributors. All rights reserved.
-  2017-2023 NVIDIA CORPORATION. All rights reserved.
-  2017-2022 NXP Semiconductors
-  2017-2023 Nuvoton Ltd.
-  2017-2023 Nuvoton Technology Corp.
-  2017-2022 Xilinx, Inc. All rights reserved.
-  2018 Andre Przywara <osp@andrep.de>
-  2018-2020 Arm Limited and Contributors.
-  2018 Icenowy Zheng <icenowy@aosc.io>
-  2018-2019 Linaro
-  2018-2022 Texas Instruments Incorporated - https://www.ti.com/
-  2018-2021 The Linux Foundation. All rights reserved.
-  2019-2023 STMicroelectronics - All Rights Reserved
-  2019-2020 Broadcom.
-  2019 Carlo Caione <ccaione@baylibre.com>
-  2019-2023 Intel Corporation. All rights reserved.
-  2019-2022 Linaro Limited
-  2019-2020 Linaro Limited and Contributors.
-  2019-2023 Linaro Limited and Contributors. All rights reserved.
-  2019-2023 MediaTek Inc. All rights reserved.
-  2019-2022 NXP. All rights reserved.
-  2019 Remi Pommarel <repk@triplefau.lt>
-  2019 Repk repk@triplefau.lt
-  2019-2022 Socionext Inc. All rights reserved.
-  2019 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
-  2020-2022 ARM Limited and Contributors. All rights reserved.
-  2020-2023 Google LLC. All rights reserved.
-  2020 Marek Behun, CZ.NIC
-  2020 Marvell Technology Group Ltd. All rights reserved.
-  2020 MediaTek Inc. All rights reserved.
-  2020 NXP.
-  2020 Nuvia Inc
-  2020-2021 Sartura Ltd.
-  2020-2021 Siemens AG
-  2021 Xilinx Inc.
-  2021 Arm
-  2021 Arm Limited
-  2021 Globalscale technologies, Inc.
-  2021 Marek Behun <marek.behun@nic.cz>
-  2021-2022 ProvenRun S.A.S. All rights reserved.
-  2021 Semihalf.
-  2021 Sipeed
-  2021-2023 Stephan Gerhold <stephan@gerhold.net>
-  2022-2023 Advanced Micro Devices, Inc. All rights reserved.
-  2022-2023 Arm Ltd. All rights reserved.
-  2022 Fujitsu Limited and Contributors. All rights reserved.
-  2022 Leica Geosystems AG
-  2022 Linaro
-  2022-2023 Linaro.
-  2022 Mediatek Inc. All rights reserved.
-  2022 Qualcomm Innovation Center, Inc. All rights reserved.
-  2022 The Hafnium Authors.
-  2023 Advanced Micro Devices. All rights reserved.
-  2023 Arm Limited. All rights reserved
-  2023 Aspeed Technology Inc.
-  2023 Pengutronix. All rights reserved.
+Copyright: 2024, The ChromiumOS Authors.
+ 2024, Rockchip Inc.
+ 2024, Pengutronix Inc.
+ 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ 2024, Linaro Limited and Contributors.
+ 2024, Arm Limited and Contributors.
+ 2024, Altera Corporation.
+ 2024, ARM Limited and Contributors.
+ 2023, Pengutronix.
+ 2023, Aspeed Technology Inc.
+ 2023, Advanced Micro Devices.
+ 2022-2024, Arm Ltd.
+ 2022-2024, Advanced Micro Devices Inc.
+ 2022, The Hafnium Authors.
+ 2022, Qualcomm Innovation Center, Inc.
+ 2022, Leica Geosystems AG
+ 2022, Fujitsu Limited and Contributors.
+ 2022, 2024, Mediatek Inc.
+ 2022, 2023, Linaro.
+ 2022, 2023, Advanced Micro Devices, Inc.
+ 2021-2024, ARM Limited.
+ 2021-2023, Stephan Gerhold <stephan@gerhold.net>
+ 2021-2023, Renesas Electronics Corporation.
+ 2021, Sipeed
+ 2021, Semihalf.
+ 2021, Marek Behun <marek.behun@nic.cz>
+ 2021, Globalscale technologies, Inc.
+ 2021, Arm Limited
+ 2021, Arm
+ 2021, 2022, ProvenRun S.A.S.
+ 2020-2023, Google LLC
+ 2020, Nuvia Inc
+ 2020, Marvell Technology Group Ltd.
+ 2020, Marek Behun, CZ.NIC
+ 2020, 2021, Siemens AG
+ 2020, 2021, Sartura Ltd.
+ 2019-2024, MediaTek Inc.
+ 2019-2024, Intel Corporation.
+ 2019-2022, Socionext Inc.
+ 2019-2022, NXP.
+ 2019-2022, Linaro Limited
+ 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ 2019, Repk repk@triplefau.lt
+ 2019, Remi Pommarel <repk@triplefau.lt>
+ 2019, Carlo Caione <ccaione@baylibre.com>
+ 2019, 2020, Broadcom.
+ 2018-2024, Texas Instruments Incorporated - https://www.ti.com
+ 2018-2021, The Linux Foundation.
+ 2018, Icenowy Zheng <icenowy@aosc.io>
+ 2018, Andre Przywara <osp@andrep.de>
+ 2018, 2019, 2022, Linaro
+ 2017-2023, Nuvoton Technology Corp.
+ 2017-2023, Nuvoton Ltd.
+ 2017-2023, NVIDIA CORPORATION.
+ 2017-2022, Xilinx, Inc.
+ 2017-2022, NXP Semiconductors
+ 2016-2024, NXP
+ 2016-2024, Marvell International Ltd.
+ 2015-2024, Renesas Electronics Corporation
+ 2015-2024, NVIDIA Corporation.
+ 2015-2022, Xilinx Inc.
+ 2015-2021, Broadcom
+ 2014-2024, STMicroelectronics
+ 2014-2024, Arm Limited.
+ 2014-2016, Freescale Semiconductor, Inc.
+ 2014, STMicroelectronics International N.V.
+ 2014, 2016-2022, Linaro Limited.
+ 2012-2021, Roberto E. Vargas Caballero
+ 2011, The FreeBSD Foundation
+ 2005, Nokia Corporation
+ 2005, MontaVista Software, Inc.
+ 2001, David E. O'Brien
+ 1998, Softweyr LLC.
+ 1989, Regents of the University of California.
 License: BSD-3-Clause
 
+Files: docs/*
+Copyright: no-info-found
+License: Apache-2.0 or BSD-2-clause or BSD-3-clause or Expat or NCSA or Zlib
+
 Files: docs/Makefile
-Copyright: 2015-2023, ARM Limited.
+ docs/conf.py
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: docs/_static/*
-Copyright: 2015-2023, Arm Limited.
-License: BSD-3-clause
-
-Files: docs/conf.py
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: docs/design/trusted-board-boot-build.rst
 Copyright: 2019-2022, Arm Limited.
 License: Apache-2.0
 
-Files: docs/license.rst
-Copyright: no-info-found
-License: BSD-2-clause and/or BSD-3-clause and/or Expat and/or NCSA and/or Zlib
-
 Files: docs/process/contributing.rst
-Copyright: 2015-2023, Arm Limited.
-License: BSD-3-clause
-
-Files: docs/resources/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: docs/resources/diagrams/plantuml/*
-Copyright: 2015-2023, Arm Limited.
+Files: docs/resources/diagrams/Makefile
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: docs/resources/diagrams/plantuml/bl2-loading-sp.puml
  docs/resources/diagrams/plantuml/fip-secure-partitions.puml
  docs/resources/diagrams/plantuml/sdei_explicit_dispatch.puml
  docs/resources/diagrams/plantuml/sdei_general.puml
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: docs/resources/diagrams/plantuml/el3_spm_dfd.puml
+ docs/resources/diagrams/plantuml/spm_dfd.puml
+ docs/resources/diagrams/plantuml/tfa_arm_cca_dfd.puml
+ docs/resources/diagrams/plantuml/tfa_dfd.puml
+ docs/resources/diagrams/plantuml/tfa_rse_dfd.puml
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2015-2024, Renesas Electronics Corporation.
+License: BSD-3-clause
+
+Files: drivers/allwinner/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/amlogic/*
@@ -359,107 +434,133 @@ Copyright: 2019, Remi Pommarel <repk@triplefau.lt>
 License: BSD-3-clause
 
 Files: drivers/amlogic/console/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: drivers/arm/css/scp/css_pm_scmi.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: drivers/arm/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/arm/css/dsu/*
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: drivers/arm/css/scmi/scmi_common.c
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/arm/css/scp/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/arm/css/scp/css_bom_bootloader.c
+ drivers/arm/css/scp/css_pm_scpi.c
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/arm/css/sds/sds.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/arm/dcc/*
-Copyright: 2015-2021, Xilinx Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
+ 2015-2022, Xilinx Inc.
 License: BSD-3-clause
 
 Files: drivers/arm/ethosn/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/arm/fvp/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/arm/gic/v2/gicv2.mk
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/arm/gic/v2/gicv2_main.c
 Copyright: 2021, 2022, ProvenRun S.A.S.
- 2015-2023, Arm Limited and Contributors.
+ 2015-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/arm/gic/v3/*
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: drivers/arm/gic/v3/arm_gicv3_common.c
- drivers/arm/gic/v3/gicdv3_helpers.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/arm/gic/v3/gic600_multichip.c
-Copyright: 2021-2023, NVIDIA Corporation.
- 2019-2023, Arm Limited.
+Copyright: 2021-2024, NVIDIA Corporation.
+ 2019-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/arm/gic/v3/gic600_multichip_private.h
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: drivers/arm/gic/v3/gic600ae_fmu.c
  drivers/arm/gic/v3/gic600ae_fmu_helpers.c
-Copyright: 2017-2022, NVIDIA Corporation.
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
 License: BSD-3-clause
 
-Files: drivers/arm/gic/v3/gicrv3_helpers.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: drivers/arm/gic/v3/gicdv3_helpers.c
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/arm/gic/v3/gicv3_private.h
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/arm/mhu/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/arm/mhu/mhu_v2_x.c
+ drivers/arm/mhu/mhu_v2_x.h
+ drivers/arm/mhu/mhu_wrapper_v2_x.c
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: drivers/arm/rss/*
-Copyright: 2015-2023, Arm Limited.
+Files: drivers/arm/rse/*
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/arm/sbsa/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/arm/scu/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/auth/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/auth/cca/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/auth/dualroot/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/auth/img_parser_mod.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/auth/mbedtls/mbedtls_common.mk
- drivers/auth/mbedtls/mbedtls_psa_crypto.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: drivers/auth/mbedtls/mbedtls_psa_crypto.c
+Copyright: 2023, 2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/auth/mbedtls/mbedtls_x509.mk
  drivers/auth/mbedtls/mbedtls_x509_parser.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/brcm/*
@@ -467,40 +568,77 @@ Copyright: 2015-2021, Broadcom
 License: BSD-3-clause
 
 Files: drivers/cadence/*
-Copyright: 2019-2023, Intel Corporation.
+Copyright: 2019-2024, Intel Corporation.
+License: BSD-3-clause
+
+Files: drivers/cadence/emmc/*
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
 Files: drivers/cadence/uart/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/cfi/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/clk/*
-Copyright: 2014-2023, STMicroelectronics
+Copyright: 2014-2024, STMicroelectronics
+License: BSD-3-clause
+
+Files: drivers/console/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/coreboot/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/delay_timer/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/delay_timer/generic_delay_timer.c
-Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+Copyright: 2020-2023, NVIDIA Corporation.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/fwu/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: drivers/gpio/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/imx/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/imx/uart/*
 Copyright: Linaro 2018, Limited and Contributors.
 License: BSD-3-clause
 
+Files: drivers/intel/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/io/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
 Files: drivers/io/io_encrypted.c
 Copyright: 2019, 2020, Linaro Limited.
 License: BSD-3-clause
 
 Files: drivers/marvell/*
-Copyright: 2016-2021, Marvell International Ltd.
+Copyright: 2016-2024, Marvell International Ltd.
 License: BSD-3-clause
 
 Files: drivers/measured_boot/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: drivers/mentor/*
@@ -508,12 +646,16 @@ Copyright: 2018, Marvell International Ltd.
  2018, Icenowy Zheng <icenowy@aosc.io>
 License: BSD-3-clause
 
+Files: drivers/mmc/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
 Files: drivers/mtd/*
-Copyright: 2014-2023, STMicroelectronics
+Copyright: 2014-2024, STMicroelectronics
 License: BSD-3-clause
 
 Files: drivers/nxp/*
-Copyright: 2016-2023, NXP
+Copyright: 2016-2024, NXP
 License: BSD-3-clause
 
 Files: drivers/nxp/auth/csf_hdr_parser/cot.c
@@ -534,19 +676,19 @@ Copyright: 2020, NXP
 License: BSD-3-clause
 
 Files: drivers/nxp/console/16550_console.S
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: drivers/partition/partition.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: drivers/partition/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: drivers/rambus/*
-Copyright: 2020, Marvell Technology Group Ltd.
+Files: drivers/partition/gpt.c
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: drivers/renesas/*
-Copyright: 2015-2023, Renesas Electronics Corporation.
+Files: drivers/rambus/*
+Copyright: 2020, Marvell Technology Group Ltd.
 License: BSD-3-clause
 
 Files: drivers/renesas/common/auth/*
@@ -559,11 +701,11 @@ License: BSD-3-clause
 
 Files: drivers/renesas/common/ddr/ddr_a/boot_init_dram_regdef.h
  drivers/renesas/common/ddr/ddr_a/ddr_init_v3m.c
-Copyright: 2015-2019, Renesas Electronics Corporation
+Copyright: 2015-2024, Renesas Electronics Corporation
 License: BSD-3-clause
 
 Files: drivers/renesas/common/ddr_regs.h
-Copyright: 2015-2019, Renesas Electronics Corporation
+Copyright: 2015-2024, Renesas Electronics Corporation
 License: BSD-3-clause
 
 Files: drivers/renesas/common/emmc/emmc_interrupt.c
@@ -575,76 +717,101 @@ Copyright: 2015-2023, Renesas Electronics Corporation. All rights
 License: BSD-3-clause
 
 Files: drivers/renesas/rcar/pfc/V3M/*
-Copyright: 2015-2019, Renesas Electronics Corporation
+Copyright: 2015-2024, Renesas Electronics Corporation
 License: BSD-3-clause
 
 Files: drivers/renesas/rcar/qos/D3/qos_init_d3.h
-Copyright: 2015-2019, Renesas Electronics Corporation
+Copyright: 2015-2024, Renesas Electronics Corporation
 License: BSD-3-clause
 
 Files: drivers/renesas/rcar/qos/V3M/*
-Copyright: 2015-2019, Renesas Electronics Corporation
+Copyright: 2015-2024, Renesas Electronics Corporation
 License: BSD-3-clause
 
 Files: drivers/rpi3/*
-Copyright: 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/rpi3/gpio/*
+Copyright: 2024, Arm Limited.
+ 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
  2019, Linaro Limited
 License: BSD-3-clause
 
 Files: drivers/rpi3/mailbox/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: drivers/rpi3/rng/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Files: drivers/rpi3/sdhost/*
+Copyright: 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ 2019, Linaro Limited
 License: BSD-3-clause
 
 Files: drivers/scmi-msg/*
 Copyright: 2019-2022, Linaro Limited
- 2015-2022, Arm Limited and Contributors.
+ 2015-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/scmi-msg/power_domain.h
-Copyright: 2016-2023, NXP
+ drivers/scmi-msg/sensor.c
+Copyright: 2016-2024, NXP
+License: BSD-3-clause
+
+Files: drivers/scmi-msg/sensor.h
+Copyright: 2023, 2024, NXP
 License: BSD-3-clause
 
 Files: drivers/st/*
-Copyright: 2014-2023, STMicroelectronics
+Copyright: 2014-2024, STMicroelectronics
 License: BSD-3-clause
 
 Files: drivers/st/clk/*
-Copyright: 2017-2023, STMicroelectronics
+Copyright: 2017-2024, STMicroelectronics
 License: GPL-2
 
 Files: drivers/st/clk/stm32mp_clkfunc.c
-Copyright: 2014-2023, STMicroelectronics
+Copyright: 2014-2024, STMicroelectronics
 License: BSD-3-clause
 
 Files: drivers/st/ddr/stm32mp1_ddr.c
  drivers/st/ddr/stm32mp1_ram.c
-Copyright: 2017-2023, STMicroelectronics
+ drivers/st/ddr/stm32mp2_ram.c
+Copyright: 2017-2024, STMicroelectronics
 License: GPL-2
 
 Files: drivers/st/fmc/*
-Copyright: 2017-2023, STMicroelectronics
+Copyright: 2017-2024, STMicroelectronics
 License: GPL-2
 
 Files: drivers/st/spi/*
-Copyright: 2017-2023, STMicroelectronics
+Copyright: 2017-2024, STMicroelectronics
 License: GPL-2
 
 Files: drivers/st/uart/aarch32/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/synopsys/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/ti/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: drivers/ufs/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: drivers/usb/*
-Copyright: 2014-2023, STMicroelectronics
+Copyright: 2014-2024, STMicroelectronics
 License: BSD-3-clause
 
 Files: fdts/a5ds.dts
  fdts/corstone700.dtsi
  fdts/corstone700_fpga.dts
  fdts/corstone700_fvp.dts
+ fdts/dualroot_cot_descriptors.dtsi
  fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
  fdts/fvp-ve-Cortex-A5x1.dts
  fdts/fvp-ve-Cortex-A7x1.dts
@@ -654,13 +821,21 @@ Files: fdts/a5ds.dts
  fdts/morello-fvp.dts
  fdts/morello-soc.dts
  fdts/morello.dtsi
- fdts/tc.dts
-Copyright: 2015-2023, Arm Limited.
+ fdts/rd1ae.dts
+ fdts/tbbr_cot_descriptors.dtsi
+ fdts/tc-base.dtsi
+ fdts/tc2.dts
+ fdts/tc3-4-base.dtsi
+ fdts/tc3.dts
+ fdts/tc4.dts
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: fdts/cot_descriptors.dtsi
- fdts/stm32mp1-cot-descriptors.dtsi
-Copyright: 2015-2023, ARM Limited.
+Files: fdts/cca_cot_descriptors.dtsi
+ fdts/tc-common.dtsi
+ fdts/tc-fpga.dtsi
+ fdts/tc-fvp.dtsi
+Copyright: 2023, 2024, Arm Limited.
 License: BSD-3-clause
 
 Files: fdts/fvp-base-gicv2-psci.dts
@@ -673,7 +848,7 @@ Files: fdts/fvp-base-gicv2-psci.dts
  fdts/fvp-foundation-gicv2-psci.dts
  fdts/fvp-foundation-gicv3-psci.dts
  fdts/fvp-foundation-motherboard.dtsi
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: fdts/fvp-base-psci-common.dtsi
@@ -682,7 +857,11 @@ License: GPL-2
 
 Files: fdts/fvp-defs-dynamiq.dtsi
  fdts/fvp-defs.dtsi
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: fdts/stm32mp1-cot-descriptors.dtsi
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: fdts/stm32mp13-ddr.dtsi
@@ -690,7 +869,10 @@ Files: fdts/stm32mp13-ddr.dtsi
  fdts/stm32mp15-ddr.dtsi
  fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi
  fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
-Copyright: 2017-2023, STMicroelectronics
+ fdts/stm32mp25-ddr.dtsi
+ fdts/stm32mp25-ddr4-2x16Gbits-2x16bits-1200MHz.dtsi
+ fdts/stm32mp25-ddr4-2x8Gbits-2x16bits-1200MHz.dtsi
+Copyright: 2017-2024, STMicroelectronics
 License: GPL-2
 
 Files: fdts/stm32mp15-ddr3-dhsom-2x4Gb-1066-binG.dtsi
@@ -699,7 +881,9 @@ License: GPL-2
 
 Files: fdts/stm32mp157a-dhcor-avenger96.dts
  fdts/stm32mp15xx-dhcor-avenger96.dtsi
-Copyright: Linaro Ltd 2019, - / 2022, DH electronics GmbH / 2020, Marek Vasut <marex@denx.de>
+Copyright: 2022, DH electronics GmbH
+ 2020, Marek Vasut <marex@denx.de>
+ 2019, Linaro Ltd
 License: GPL-2
 
 Files: fdts/stm32mp157c-dhcom-pdk2-fw-config.dts
@@ -713,44 +897,67 @@ Copyright: 2022, DH electronics GmbH
 License: GPL-2
 
 Files: fdts/stm32mp15xx-dhcom-som.dtsi
-Copyright: 2023, STMicroelectronics
+Copyright: 2023, 2024, STMicroelectronics
  2022, DH electronics GmbH
  2019, 2020, Marek Vasut <marex@denx.de>
 License: GPL-2
 
 Files: fdts/stm32mp15xx-dhcor-som.dtsi
-Copyright: Linaro Ltd 2019, - / 2023, STMicroelectronics - / 2022, DH electronics GmbH / 2020, Marek Vasut <marex@denx.de>
+Copyright: 2023, 2024, STMicroelectronics
+ 2022, DH electronics GmbH
+ 2020, Marek Vasut <marex@denx.de>
+ 2019, Linaro Ltd
 License: GPL-2
 
 Files: include/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/arch/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/arch/aarch32/arch.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/arch/aarch32/arch_features.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/arch/aarch32/arch_helpers.h
 Copyright: 2021, 2022, ProvenRun S.A.S.
- 2016-2022, ARM Limited and Contributors.
+ 2016-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/arch/aarch64/arch.h
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/arch/aarch64/arch_features.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/arch/aarch64/arch_helpers.h
  include/arch/aarch64/el3_common_macros.S
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/bl1/tbbr/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/bl2/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/bl2u/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/bl31/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/bl31/sync_handle.h
@@ -760,28 +967,59 @@ License: BSD-3-clause
 
 Files: include/bl32/payloads/*
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/bl32/pnc/*
 Copyright: 2021, 2022, ProvenRun S.A.S.
 License: BSD-3-clause
 
-Files: include/common/debug.h
+Files: include/bl32/sp_min/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/bl32/tsp/platform_tsp.h
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/common/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/common/bl_common.h
+ include/common/debug.h
  include/common/ep_info.h
  include/common/fdt_wrappers.h
  include/common/feat_detect.h
+ include/common/par.h
  include/common/uuid.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: include/common/nv_cntr_ids.h
+Files: include/common/build_message.h
+ include/common/nv_cntr_ids.h
  include/common/tf_crc32.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: include/common/tbbr/cot_def.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: include/common/sha_common_macros.h
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
+License: BSD-3-clause
+
+Files: include/common/tbbr/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/common/tbbr/tbbr_img_def.h
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/drivers/*
+Copyright: 2016-2024, NXP
+License: BSD-3-clause
+
+Files: include/drivers/allwinner/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/amlogic/*
@@ -789,11 +1027,26 @@ Copyright: 2019, Remi Pommarel <repk@triplefau.lt>
 License: BSD-3-clause
 
 Files: include/drivers/amlogic/meson_console.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/drivers/arm/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/drivers/arm/css/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/drivers/arm/css/css_mhu.h
+ include/drivers/arm/css/css_scp.h
+ include/drivers/arm/css/css_scpi.h
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/arm/dcc.h
-Copyright: 2015-2021, Xilinx Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
+ 2015-2022, Xilinx Inc.
 License: BSD-3-clause
 
 Files: include/drivers/arm/ethosn.h
@@ -801,10 +1054,10 @@ Files: include/drivers/arm/ethosn.h
  include/drivers/arm/ethosn_fip.h
  include/drivers/arm/ethosn_oid.h
  include/drivers/arm/mhu.h
- include/drivers/arm/rss_comms.h
+ include/drivers/arm/rse_comms.h
  include/drivers/arm/sbsa.h
  include/drivers/arm/scu.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/drivers/arm/gic600_multichip.h
@@ -813,32 +1066,37 @@ Copyright: 2023, NVIDIA Corporation.
 License: BSD-3-clause
 
 Files: include/drivers/arm/gic600ae_fmu.h
-Copyright: 2017-2022, NVIDIA Corporation.
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
 License: BSD-3-clause
 
 Files: include/drivers/arm/gicv2.h
 Copyright: 2021, 2022, ProvenRun S.A.S.
- 2015-2023, Arm Limited and Contributors.
+ 2015-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/arm/gicv3.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/drivers/auth/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/auth/crypto_mod.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+ include/drivers/auth/tbbr_cot_common.h
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/auth/mbedtls/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2022-2024, Arm Ltd.
 License: BSD-3-clause
 
 Files: include/drivers/auth/mbedtls/mbedtls_common.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: include/drivers/auth/mbedtls/psa_mbedtls_config.h
-Copyright: 2022, 2023, Arm Ltd.
+Files: include/drivers/auth/mbedtls/mbedtls_config-3.h
+Copyright: 2023, 2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/drivers/brcm/*
@@ -846,16 +1104,21 @@ Copyright: 2015-2021, Broadcom
 License: BSD-3-clause
 
 Files: include/drivers/cadence/*
-Copyright: 2019-2023, Intel Corporation.
+Copyright: 2019-2024, Intel Corporation.
 License: BSD-3-clause
 
 Files: include/drivers/cadence/cdns_sdmmc.h
-Copyright: 2019-2023, ARM Limited and Contributors.
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
  2019-2023, Intel Corporation.
 License: BSD-3-clause
 
 Files: include/drivers/cadence/cdns_uart.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/drivers/cfi/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/clk.h
@@ -865,16 +1128,35 @@ Files: include/drivers/clk.h
  include/drivers/spi_nand.h
  include/drivers/spi_nor.h
  include/drivers/usb_device.h
-Copyright: 2014-2023, STMicroelectronics
+Copyright: 2014-2024, STMicroelectronics
+License: BSD-3-clause
+
+Files: include/drivers/console.h
+ include/drivers/console_assertions.h
+ include/drivers/dw_ufs.h
+ include/drivers/generic_delay_timer.h
+ include/drivers/gpio.h
+ include/drivers/mmc.h
+ include/drivers/ufs.h
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/drivers/coreboot/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/delay_timer.h
-Copyright: 2019, Linaro Limited
- 2015-2019, ARM Limited and Contributors.
+ include/drivers/scmi-msg.h
+Copyright: 2019-2022, Linaro Limited
+ 2015-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/fwu/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: include/drivers/io/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/io/io_encrypted.h
@@ -882,11 +1164,11 @@ Copyright: 2019, 2020, Linaro Limited.
 License: BSD-3-clause
 
 Files: include/drivers/marvell/*
-Copyright: 2016-2021, Marvell International Ltd.
+Copyright: 2016-2024, Marvell International Ltd.
 License: BSD-3-clause
 
 Files: include/drivers/measured_boot/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/drivers/mentor/*
@@ -899,21 +1181,17 @@ Copyright: 2017-2023, Nuvoton Ltd.
 License: BSD-3-clause
 
 Files: include/drivers/nuvoton/npcm845x/npcm845x_lpuart.h
-Copyright: 2017-2023, Nuvoton Ltd.
+Copyright: 2022, 2023, Nuvoton Ltd.
  2015-2023, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: include/drivers/nxp/*
-Copyright: 2016-2023, NXP
-License: BSD-3-clause
-
 Files: include/drivers/nxp/sd/*
 Copyright: 2017-2021, NXP
  2014-2016, Freescale Semiconductor, Inc.
 License: BSD-3-clause
 
 Files: include/drivers/partition/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/partition/efi.h
@@ -922,7 +1200,7 @@ Copyright: 2022, STMicroelectronics
 License: BSD-3-clause
 
 Files: include/drivers/partition/mbr.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/rambus/*
@@ -930,70 +1208,80 @@ Copyright: 2020, Marvell Technology Group Ltd.
 License: BSD-3-clause
 
 Files: include/drivers/renesas/*
-Copyright: 2015-2023, Renesas Electronics Corporation.
+Copyright: 2015-2024, Renesas Electronics Corporation.
 License: BSD-3-clause
 
 Files: include/drivers/rpi3/*
-Copyright: 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
- 2019, Linaro Limited
-License: BSD-3-clause
-
-Files: include/drivers/rpi3/mailbox/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: include/drivers/rpi3/rng/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: include/drivers/rpi3/gpio/*
+Copyright: 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ 2019, Linaro Limited
 License: BSD-3-clause
 
-Files: include/drivers/scmi-msg.h
-Copyright: 2019-2022, Linaro Limited
- 2015-2022, Arm Limited and Contributors.
+Files: include/drivers/rpi3/sdhost/*
+Copyright: 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ 2019, Linaro Limited
 License: BSD-3-clause
 
 Files: include/drivers/scmi.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/st/*
-Copyright: 2014-2023, STMicroelectronics
+Copyright: 2014-2024, STMicroelectronics
 License: BSD-3-clause
 
 Files: include/drivers/st/stm32_console.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/drivers/st/stm32_fmc2_nand.h
  include/drivers/st/stm32_qspi.h
  include/drivers/st/stm32mp1_ddr.h
  include/drivers/st/stm32mp1_ddr_regs.h
+ include/drivers/st/stm32mp2_ddr.h
+ include/drivers/st/stm32mp2_ddr_regs.h
  include/drivers/st/stm32mp_ddr.h
  include/drivers/st/stm32mp_ddrctrl_regs.h
-Copyright: 2017-2023, STMicroelectronics
+Copyright: 2017-2024, STMicroelectronics
 License: GPL-2
 
+Files: include/drivers/synopsys/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/drivers/ti/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
 Files: include/dt-bindings/*
-Copyright: 2017-2023, STMicroelectronics
+Copyright: 2017-2024, STMicroelectronics
 License: GPL-2
 
 Files: include/dt-bindings/interrupt-controller/*
 Copyright: 2019-2021, Arm Limited and Contributors.
 License: Expat
 
+Files: include/export/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
 Files: include/export/common/ep_info_exp.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/export/lib/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: include/lib/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: include/lib/cpus/*
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: include/lib/cpus/aarch64/*
-Copyright: 2015-2023, Arm Limited.
+Files: include/lib/cpus/aarch32/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/lib/cpus/aarch64/a64fx.h
@@ -1016,60 +1304,73 @@ Files: include/lib/cpus/aarch64/aem_generic.h
  include/lib/cpus/aarch64/neoverse_e1.h
  include/lib/cpus/aarch64/neoverse_n1.h
  include/lib/cpus/aarch64/qemu_max.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/lib/cpus/aarch64/cortex_a57.h
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/lib/cpus/aarch64/cortex_a78_ae.h
-Copyright: 2021-2023, NVIDIA Corporation.
- 2019-2023, Arm Limited.
+Copyright: 2021-2024, NVIDIA Corporation.
+ 2019-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/lib/cpus/aarch64/cortex_x1.h
 Copyright: 2020, 2022, 2023, Google LLC.
 License: BSD-3-clause
 
+Files: include/lib/cpus/cpu_ops.h
+Copyright: 2023, 2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/lib/cpus/errata.h
+ include/lib/cpus/wa_cve_2017_5715.h
+ include/lib/cpus/wa_cve_2018_3639.h
+ include/lib/cpus/wa_cve_2022_23960.h
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
 Files: include/lib/debugfs.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: include/lib/dice/*
+Copyright: 2020, Google LLC
+License: Apache-2.0
+
+Files: include/lib/el3_runtime/simd_ctx.h
+Copyright: 2024, Arm Limited and Contributors.
+ 2022, Google LLC.
 License: BSD-3-clause
 
 Files: include/lib/extensions/brbe.h
+ include/lib/extensions/fgt2.h
  include/lib/extensions/pmuv3.h
  include/lib/extensions/sys_reg_trace.h
+ include/lib/extensions/tcr2.h
  include/lib/extensions/trbe.h
  include/lib/extensions/trf.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/lib/extensions/ras.h
  include/lib/extensions/ras_arch.h
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/lib/fconf/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/lib/gpt_rme/*
-Copyright: 2015-2023, Arm Limited.
-License: BSD-3-clause
-
-Files: include/lib/libc/*
-Copyright: 2018, 2019, Arm Limited and Contributors.
- 2012-2021, Roberto E. Vargas Caballero
-License: BSD-3-clause
-
-Files: include/lib/libc/aarch32/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/lib/libc/aarch32/endian_.h
-Copyright: 2001, David E. OBrien
+Copyright: 2001, David E. O'Brien
 License: BSD-3-clause
 
 Files: include/lib/libc/aarch32/float.h
@@ -1082,12 +1383,8 @@ Copyright: 2020, Broadcom
  2020, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: include/lib/libc/aarch64/*
-Copyright: 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
 Files: include/lib/libc/aarch64/endian_.h
-Copyright: 2001, David E. OBrien
+Copyright: 2001, David E. O'Brien
 License: BSD-3-clause
 
 Files: include/lib/libc/aarch64/float.h
@@ -1104,16 +1401,9 @@ Files: include/lib/libc/arm_acle.h
 Copyright: 2021, Arm Limited
 License: BSD-3-clause
 
-Files: include/lib/libc/assert.h
- include/lib/libc/cdefs.h
- include/lib/libc/setjmp.h
- include/lib/libc/stdbool.h
-Copyright: 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
 Files: include/lib/libc/endian.h
 Copyright: 2002, Thomas Moestl <tmm@FreeBSD.org>
-License: BSD-2-Clause-FreeBSD and/or BSD-2-clause
+License: BSD-2-Clause-FreeBSD or BSD-2-clause
 
 Files: include/lib/libc/errno.h
 Copyright: UNIX System Laboratories, Inc.
@@ -1125,6 +1415,17 @@ Copyright: 2020, Broadcom
  2020, Arm Limited and Contributors.
 License: BSD-3-clause
 
+Files: include/lib/libc/limits.h
+ include/lib/libc/stdarg.h
+ include/lib/libc/stddef.h
+ include/lib/libc/stdint.h
+ include/lib/libc/stdio.h
+ include/lib/libc/stdlib.h
+ include/lib/libc/time.h
+Copyright: 2018, 2019, Arm Limited and Contributors.
+ 2012-2021, Roberto E. Vargas Caballero
+License: BSD-3-clause
+
 Files: include/lib/libc/string.h
 Copyright: 2023, Intel Corporation.
  2018-2020, Arm Limited and Contributors.
@@ -1136,29 +1437,41 @@ Copyright: 1988-1991, 1993, The Regents of the University of California.
 License: BSD-3-clause
 
 Files: include/lib/mpmm/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/lib/pmf/aarch32/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/lib/psa/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: include/lib/psa/cca_attestation.h
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/lib/psci/psci.h
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/lib/transfer_list.h
-Copyright: 2019-2023, Linaro Limited and Contributors.
+Copyright: 2019-2024, Linaro Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/lib/utils_def.h
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: include/plat/*
+Copyright: 2016-2024, Marvell International Ltd.
+License: BSD-3-clause
+
+Files: include/plat/arm/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/plat/arm/common/arm_def.h
@@ -1167,45 +1480,41 @@ Files: include/plat/arm/common/arm_def.h
  include/plat/arm/common/arm_sip_svc.h
  include/plat/arm/common/fconf_arm_sp_getter.h
  include/plat/arm/common/plat_arm.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/plat/arm/common/arm_fconf_getter.h
  include/plat/arm/common/arm_fconf_io_storage.h
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: include/plat/arm/common/fconf_ethosn_getter.h
  include/plat/arm/common/fconf_nv_cntr_getter.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/plat/arm/css/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/plat/arm/css/common/aarch64/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/plat/brcm/*
 Copyright: 2015-2021, Broadcom
 License: BSD-3-clause
 
-Files: include/plat/common/plat_drtm.h
-Copyright: 2015-2023, Arm Limited.
-License: BSD-3-clause
-
-Files: include/plat/common/plat_trng.h
-Copyright: 2015-2023, ARM Limited.
+Files: include/plat/common/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: include/plat/common/platform.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: include/plat/common/plat_drtm.h
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: include/plat/marvell/*
-Copyright: 2016-2021, Marvell International Ltd.
+Files: include/plat/common/plat_trng.h
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: include/plat/nuvoton/*
@@ -1218,33 +1527,46 @@ Copyright: 2017-2023, Nuvoton Ltd.
  2015-2023, ARM Limited and Contributors.
 License: BSD-3-clause
 
+Files: include/services/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
 Files: include/services/drtm_svc.h
  include/services/errata_abi_svc.h
  include/services/ffa_svc.h
  include/services/rmm_core_manifest.h
  include/services/spm_core_manifest.h
-Copyright: 2015-2023, Arm Limited.
+ include/services/ven_el3_svc.h
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: include/services/oem/*
+Copyright: 2024, The ChromiumOS Authors.
+License: BSD-3-clause
+
+Files: include/services/rmm_el3_token_sign.h
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
 License: BSD-3-clause
 
 Files: include/services/rmmd_svc.h
  include/services/sdei.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/services/trng_svc.h
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: include/services/trp/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/services/trp/trp_helpers.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/tools_share/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: include/tools_share/firmware_encrypted.h
@@ -1252,11 +1574,11 @@ Copyright: 2019, 2020, Linaro Limited.
 License: BSD-3-clause
 
 Files: include/tools_share/firmware_image_package.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/tools_share/tbbr_oid.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: include/tools_share/uuid.h
@@ -1264,23 +1586,27 @@ Copyright: 2002, Marcel Moolenaar
 License: BSD-2-clause
 
 Files: lib/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/compiler-rt/*
 Copyright: 2009-2016, the contributors listed in CREDITS.TXT
-License: Expat and/or NCSA
+License: Expat or NCSA
 
 Files: lib/compiler-rt/builtins/*
 Copyright: no-info-found
 License: Apache-2.0
 
 Files: lib/compiler-rt/compiler-rt.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: lib/cpus/*
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: lib/cpus/aarch64/*
-Copyright: 2015-2023, Arm Limited.
+Files: lib/cpus/aarch32/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/cpus/aarch64/a64fx.S
@@ -1307,18 +1633,18 @@ Files: lib/cpus/aarch64/aem_generic.S
  lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S
  lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
  lib/cpus/aarch64/wa_cve_2022_23960_bhb.S
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/cpus/aarch64/cortex_a57.S
  lib/cpus/aarch64/denver.S
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/cpus/aarch64/cortex_a78_ae.S
-Copyright: 2021-2023, NVIDIA Corporation.
- 2019-2023, Arm Limited.
+Copyright: 2021-2024, NVIDIA Corporation.
+ 2019-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: lib/cpus/aarch64/cortex_x1.S
@@ -1326,80 +1652,94 @@ Copyright: 2020, 2022, 2023, Google LLC.
 License: BSD-3-clause
 
 Files: lib/cpus/aarch64/cpuamu.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/cpus/cpu-ops.mk
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: lib/cpus/errata_common.c
+ lib/cpus/errata_report.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/debugfs/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: lib/debugfs/debugfs.mk
  lib/debugfs/debugfs_smc.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/el3_runtime/aarch64/context_mgmt.c
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: lib/extensions/amu/amu.mk
-Copyright: 2015-2023, Arm Limited.
+Files: lib/el3_runtime/simd_ctx.c
+Copyright: 2024, Arm Limited and Contributors.
+ 2022, Google LLC.
+License: BSD-3-clause
+
+Files: lib/extensions/*
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: lib/extensions/brbe/*
-Copyright: 2015-2023, Arm Limited.
+Files: lib/extensions/amu/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: lib/extensions/pauth/*
-Copyright: 2015-2023, Arm Limited.
+Files: lib/extensions/amu/amu.mk
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: lib/extensions/mpam/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: lib/extensions/pmuv3/*
-Copyright: 2015-2023, Arm Limited.
+Files: lib/extensions/ras/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/extensions/ras/ras_common.c
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: lib/extensions/sys_reg_trace/*
-Copyright: 2015-2023, Arm Limited.
+Files: lib/extensions/sme/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: lib/extensions/trbe/*
-Copyright: 2015-2023, Arm Limited.
+Files: lib/extensions/spe/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: lib/extensions/trf/*
-Copyright: 2015-2023, Arm Limited.
+Files: lib/extensions/sve/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/fconf/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: lib/gpt_rme/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: lib/libc/aarch32/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: lib/libc/aarch64/memset.S
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: lib/libc/libc_asm.mk
  lib/libc/memrchr.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: lib/libc/memcpy_s.c
@@ -1421,12 +1761,12 @@ License: ISC
 
 Files: lib/libc/strnlen.c
 Copyright: 2009, David Schultz <das@FreeBSD.org>
-License: BSD-2-Clause-FreeBSD and/or BSD-2-clause
+License: BSD-2-Clause-FreeBSD or BSD-2-clause
 
 Files: lib/libc/strtok.c
 Copyright: 1998, Softweyr LLC.
  1988, 1993, The Regents of the University of California.
-License: BSD-3-clause and/or BSD-3-clause
+License: BSD-3-clause
 
 Files: lib/libc/strtol.c
  lib/libc/strtoll.c
@@ -1437,65 +1777,69 @@ Copyright: 2011, The FreeBSD Foundation
 License: BSD-3-clause
 
 Files: lib/libfdt/libfdt.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/locks/bakery/bakery_lock_normal.c
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/mpmm/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: lib/psa/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: lib/psa/cca_attestation.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/psci/psci_off.c
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/psci/psci_suspend.c
  lib/psci/psci_system_off.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: lib/romlib/romlib_generator.py
-Copyright: 2015-2023, Arm Limited.
+Files: lib/romlib/*
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: lib/romlib/templates/*
-Copyright: 2015-2023, Arm Limited.
+Files: lib/romlib/Makefile
+ lib/romlib/gen_combined_bl1_romlib.sh
+ lib/romlib/init.s
+ lib/romlib/jmptbl.i
+ lib/romlib/romlib.ld.S
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/transfer_list/transfer_list.c
-Copyright: 2019-2023, Linaro Limited and Contributors.
+Copyright: 2019-2024, Linaro Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/xlat_mpu/ro_xlat_mpu.mk
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: lib/xlat_tables/aarch32/*
+Files: lib/xlat_tables/aarch32/nonlpae_tables.c
 Copyright: 2016, 2017, Linaro Limited.
  2014-2020, Arm Limited.
  2014, STMicroelectronics International N.V.
 License: BSD-3-clause
 
-Files: lib/xlat_tables/aarch32/xlat_tables.c
-Copyright: 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
 Files: lib/xlat_tables_v2/ro_xlat_tables.mk
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: lib/zlib/tf_gunzip.c
  lib/zlib/zlib.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: lib/zlib/zlib.h
@@ -1504,25 +1848,34 @@ License: Zlib
 
 Files: licenses/*
 Copyright: no-info-found
+License: Apache-2.0 or Expat
+
+Files: licenses/LICENSE-APACHE-2.0.txt
+Copyright: no-info-found
+License: Apache-2.0
+
+Files: licenses/LICENSE.MIT
+Copyright: no-info-found
 License: Expat
 
 Files: make_helpers/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: make_helpers/arch_features.mk
  make_helpers/defaults.mk
- make_helpers/march.mk
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: make_helpers/build_macros.mk
- make_helpers/windows.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: make_helpers/armv7-a-cpus.mk
+ make_helpers/cygwin.mk
+ make_helpers/msys.mk
+ make_helpers/plat_helpers.mk
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: make_helpers/tbbr/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: make_helpers/march.mk
+Copyright: 2023, 2024, Arm Limited.
 License: BSD-3-clause
 
 Files: package-lock.json
@@ -1530,7 +1883,7 @@ Copyright: no-info-found
 License: BSD-3-clause
 
 Files: plat/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/allwinner/common/arisc_off.S
@@ -1545,8 +1898,12 @@ Files: plat/allwinner/common/include/sunxi_cpucfg_ncat2.h
 Copyright: 2021, Sipeed
 License: BSD-3-clause
 
+Files: plat/allwinner/common/sunxi_bl31_setup.c
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
 Files: plat/allwinner/common/sunxi_prepare_dtb.c
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/allwinner/sun50i_a64/sunxi_power.c
@@ -1560,7 +1917,8 @@ Copyright: 2018, Icenowy Zheng <icenowy@aosc.io>
 License: BSD-3-clause
 
 Files: plat/allwinner/sun50i_h616/platform.mk
-Copyright: 2015-2023, ARM Limited.
+ plat/allwinner/sun50i_h616/sunxi_h616_dtb.c
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/allwinner/sun50i_h616/sunxi_power.c
@@ -1573,317 +1931,375 @@ Copyright: 2021, Sipeed
 License: BSD-3-clause
 
 Files: plat/allwinner/sun50i_r329/include/sunxi_mmap.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/allwinner/sun50i_r329/sunxi_idle_states.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/amd/*
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
+ 2017-2022, Xilinx, Inc.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/amlogic/axg/include/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/amlogic/axg/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/amlogic/common/aml_console.c
 Copyright: 2019, Carlo Caione <ccaione@baylibre.com>
 License: BSD-3-clause
 
-Files: plat/arm/board/a5ds/*
-Copyright: 2015-2023, Arm Limited.
+Files: plat/amlogic/g12a/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/a5ds/sp_min/*
-Copyright: 2015-2023, ARM Limited.
+Files: plat/amlogic/gxbb/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/arm_fpga/build_axf.ld.S
- plat/arm/board/arm_fpga/platform.mk
-Copyright: 2015-2023, Arm Limited.
+Files: plat/amlogic/gxl/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/arm_fpga/kernel_trampoline.S
- plat/arm/board/arm_fpga/rom_trampoline.S
-Copyright: 2015-2023, ARM Limited.
+Files: plat/arm/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/common/*
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/a5ds/*
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/a5ds/sp_min/*
+Copyright: 2015-2024, ARM Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/arm_fpga/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/arm/board/arm_fpga/build_axf.ld.S
+ plat/arm/board/arm_fpga/platform.mk
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/arm_fpga/kernel_trampoline.S
+ plat/arm/board/arm_fpga/rom_trampoline.S
+Copyright: 2015-2024, ARM Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/automotive_rd/*
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/automotive_rd/platform/rd1ae/rd1ae_tbb.c
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/common/aarch32/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/common/aarch64/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/common/board_arm_trusted_boot.c
- plat/arm/board/common/board_common.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: plat/arm/board/common/protpk/arm_dev_protpk.S
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/common/rotpk/arm_dev_rotpk.S
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p256_rotpk.S
+ plat/arm/board/common/rotpk/arm_full_dev_ecdsa_p384_rotpk.S
+ plat/arm/board/common/rotpk/arm_full_dev_rsa_rotpk.S
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: plat/arm/board/corstone1000/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: plat/arm/board/common/swd_rotpk/arm_dev_swd_rotpk.S
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/corstone1000/common/corstone1000_bl2_mem_params_desc.c
  plat/arm/board/corstone1000/common/corstone1000_stack_protector.c
  plat/arm/board/corstone1000/common/corstone1000_topology.c
  plat/arm/board/corstone1000/common/corstone1000_trusted_boot.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/corstone1000/common/fdts/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/corstone1000/include/*
-Copyright: 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/arm/board/corstone700/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/corstone700/common/corstone700_stack_protector.c
  plat/arm/board/corstone700/common/corstone700_topology.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/corstone700/common/drivers/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: plat/arm/board/fvp/aarch64/fvp_ea.c
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/fvp/*
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: plat/arm/board/fvp/fconf/*
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/fvp/aarch32/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/fvp/fdts/*
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/fvp/aarch64/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/arm/board/fvp/aarch64/fvp_ea.c
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/fvp/aarch64/fvp_lsp_ras_sp.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/fvp/fdts/event_log.dtsi
- plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts
  plat/arm/board/fvp/fdts/fvp_soc_fw_config.dts
  plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/fvp/fvp_bl1_measured_boot.c
- plat/arm/board/fvp/fvp_bl2_measured_boot.c
- plat/arm/board/fvp/fvp_common_measured_boot.c
- plat/arm/board/fvp/fvp_drtm_addr.c
- plat/arm/board/fvp/fvp_drtm_dma_prot.c
- plat/arm/board/fvp/fvp_drtm_err.c
- plat/arm/board/fvp/fvp_drtm_measurement.c
- plat/arm/board/fvp/fvp_drtm_stub.c
- plat/arm/board/fvp/fvp_err.c
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/fvp/fvp_bl1_setup.c
+ plat/arm/board/fvp/fvp_bl2_el3_setup.c
+ plat/arm/board/fvp/fvp_bl2u_setup.c
+ plat/arm/board/fvp/fvp_console.c
+ plat/arm/board/fvp/fvp_cpu_pwr.c
+ plat/arm/board/fvp/fvp_def.h
+ plat/arm/board/fvp/fvp_el3_spmc_logical_sp.c
+ plat/arm/board/fvp/fvp_gicv3.c
+ plat/arm/board/fvp/fvp_io_storage.c
+ plat/arm/board/fvp/fvp_private.h
+ plat/arm/board/fvp/fvp_spmd_logical_sp.c
+ plat/arm/board/fvp/fvp_stack_protector.c
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/fvp/fvp_bl2_setup.c
  plat/arm/board/fvp/fvp_bl31_setup.c
  plat/arm/board/fvp/fvp_common.c
- plat/arm/board/fvp/fvp_cpu_errata.mk
  plat/arm/board/fvp/fvp_el3_spmc.c
- plat/arm/board/fvp/fvp_plat_attest_token.c
+ plat/arm/board/fvp/fvp_pm.c
  plat/arm/board/fvp/fvp_realm_attest_key.c
  plat/arm/board/fvp/fvp_security.c
  plat/arm/board/fvp/fvp_spmd.c
+ plat/arm/board/fvp/fvp_topology.c
  plat/arm/board/fvp/fvp_trusted_boot.c
  plat/arm/board/fvp/jmptbl.i
  plat/arm/board/fvp/platform.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/fvp/fvp_sync_traps.c
-Copyright: 2015-2023, ARM Limited.
+Files: plat/arm/board/fvp/fvp_cpu_errata.mk
+Copyright: 2023, 2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/fvp/include/*
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/fvp/fvp_el3_token_sign.c
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
 License: BSD-3-clause
 
-Files: plat/arm/board/fvp/include/plat.ld.S
+Files: plat/arm/board/fvp/fvp_plat_attest_token.c
+Copyright: 2024, Linaro Limited and Contributors.
+ 2022-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/arm/board/fvp/fvp_sync_traps.c
+Copyright: 2015-2024, ARM Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/fvp/include/fvp_pas_def.h
+ plat/arm/board/fvp/include/plat.ld.S
  plat/arm/board/fvp/include/plat_macros.S
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/fvp/include/platform_def.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/fvp/sp_min/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/arm/board/fvp/tsp/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/fvp/trp/*
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/fvp_r/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/arm/board/fvp_r/fvp_r_bl1_main.c
+ plat/arm/board/fvp_r/fvp_r_bl1_setup.c
+ plat/arm/board/fvp_r/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/fvp_r/fvp_r_err.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/fvp_r/include/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/arm/board/fvp_r/include/fvp_r_arch_helpers.h
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/fvp_ve/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/juno/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/juno/cert_create_tbbr.mk
  plat/arm/board/juno/juno_ethosn_tzmp1_def.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/juno/certificate/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/juno/fdts/*
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/juno/fdts/juno_tb_fw_config.dts
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/juno/fip/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/board/juno/include/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/arm/board/juno/include/plat_macros.S
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/juno/include/plat_tbbr_img_def.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: plat/arm/board/juno/juno_bl31_setup.c
+Files: plat/arm/board/juno/juno_bl1_setup.c
+ plat/arm/board/juno/juno_bl31_setup.c
+ plat/arm/board/juno/juno_common.c
  plat/arm/board/juno/juno_tbbr_cot_bl2.c
  plat/arm/board/juno/platform.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/juno/juno_trusted_boot.c
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/morello/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/n1sdp/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/n1sdp/aarch64/*
-Copyright: 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/arm/board/n1sdp/include/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/n1sdp/include/platform_def.h
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/n1sdp/include/plat_macros.S
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/n1sdp/n1sdp_interconnect.c
  plat/arm/board/n1sdp/n1sdp_security.c
  plat/arm/board/n1sdp/n1sdp_topology.c
-Copyright: 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/arm/board/rde1edge/*
-Copyright: 2015-2023, Arm Limited.
-License: BSD-3-clause
-
-Files: plat/arm/board/rde1edge/fdts/*
-Copyright: 2015-2023, ARM Limited.
-License: BSD-3-clause
-
-Files: plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts
-Copyright: 2015-2023, Arm Limited.
-License: BSD-3-clause
-
-Files: plat/arm/board/rde1edge/rde1edge_topology.c
-Copyright: 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/arm/board/rdn1edge/rdn1edge_err.c
- plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c
-Copyright: 2015-2023, Arm Limited.
-License: BSD-3-clause
-
-Files: plat/arm/board/rdn2/platform.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/board/rdn2/rdn2_trusted_boot.c
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/neoverse_rd/common/nrd_bl1_setup.c
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: plat/arm/board/rdv1/rdv1_trusted_boot.c
-Copyright: 2015-2023, Arm Limited.
-License: BSD-3-clause
-
-Files: plat/arm/board/rdv1mc/rdv1mc_trusted_boot.c
-Copyright: 2015-2023, Arm Limited.
-License: BSD-3-clause
-
-Files: plat/arm/board/sgi575/sgi575_err.c
- plat/arm/board/sgi575/sgi575_trusted_boot.c
-Copyright: 2015-2023, Arm Limited.
+Files: plat/arm/board/neoverse_rd/platform/rdv3/rdv3_mhuv3.c
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/tc/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/tc/include/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/tc/include/platform_def.h
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/tc/include/tc_plat.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/tc/plat_tc_mbedtls_config.h
  plat/arm/board/tc/region_defs.h
- plat/arm/board/tc/rss_ap_test_stubs.c
- plat/arm/board/tc/rss_ap_tests.c
- plat/arm/board/tc/rss_ap_testsuites.c
- plat/arm/board/tc/rss_ap_testsuites.h
-Copyright: 2022, 2023, Arm Ltd.
+ plat/arm/board/tc/rse_ap_test_stubs.c
+ plat/arm/board/tc/rse_ap_tests.c
+ plat/arm/board/tc/rse_ap_testsuites.c
+ plat/arm/board/tc/rse_ap_testsuites.h
+Copyright: 2022-2024, Arm Ltd.
 License: BSD-3-clause
 
 Files: plat/arm/board/tc/tc_bl2_setup.c
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/arm/board/tc/tc_bl31_setup.c
  plat/arm/board/tc/tc_plat.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+ plat/arm/board/tc/tc_topology.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/board/tc/tc_err.c
  plat/arm/board/tc/tc_interconnect.c
- plat/arm/board/tc/tc_topology.c
+ plat/arm/board/tc/tc_trng.c
  plat/arm/board/tc/tc_trusted_boot.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/arm/common/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/common/aarch64/arm_pauth.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/common/arm_bl1_setup.c
@@ -1892,69 +2308,79 @@ Files: plat/arm/common/arm_bl1_setup.c
  plat/arm/common/arm_common.mk
  plat/arm/common/arm_dyn_cfg.c
  plat/arm/common/arm_dyn_cfg_helpers.c
+ plat/arm/common/arm_image_load.c
+ plat/arm/common/arm_pm.c
  plat/arm/common/arm_sip_svc.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+ plat/arm/common/arm_transfer_list.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/common/arm_io_storage.c
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/arm/common/fconf/arm_fconf_io.c
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/arm/common/fconf/fconf_ethosn_getter.c
  plat/arm/common/fconf/fconf_nv_cntr_getter.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/common/plat_arm_mbedtls_config.h
+ plat/arm/common/plat_arm_psa_mbedtls_config.h
+Copyright: 2022-2024, Arm Ltd.
 License: BSD-3-clause
 
 Files: plat/arm/common/plat_arm_sip_svc.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2023, 2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/arm/common/trp/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/common/trp/arm_trp_setup.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
+License: BSD-3-clause
+
+Files: plat/arm/css/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/arm/css/common/css_bl2_setup.c
  plat/arm/css/common/css_common.mk
  plat/arm/css/common/css_pm.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/arm/css/sgi/include/sgi_base_platform_def.h
-Copyright: 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/arm/css/sgi/sgi-common.mk
- plat/arm/css/sgi/sgi_bl31_setup.c
- plat/arm/css/sgi/sgi_plat.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: plat/arm/soc/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/aspeed/*
 Copyright: 2023, Aspeed Technology Inc.
 License: BSD-3-clause
 
-Files: plat/brcm/board/*
+Files: plat/brcm/*
 Copyright: 2015-2021, Broadcom
 License: BSD-3-clause
 
 Files: plat/brcm/board/common/bcm_console.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/brcm/board/common/bcm_elog_ddr.c
 Copyright: 2019, 2020, Broadcom.
 License: BSD-3-clause
 
+Files: plat/brcm/common/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
 Files: plat/common/aarch64/plat_common.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/common/aarch64/plat_ehf.c
@@ -1963,22 +2389,23 @@ Copyright: 2020, Broadcom
 License: BSD-3-clause
 
 Files: plat/common/plat_bl1_common.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+ plat/common/plat_bl_common.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/common/plat_gicv2.c
  plat/common/plat_gicv3.c
 Copyright: 2021, 2022, ProvenRun S.A.S.
- 2015-2023, Arm Limited and Contributors.
+ 2015-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/common/plat_psci_common.c
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/common/plat_spmd_manifest.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/common/ubsan.c
@@ -1986,13 +2413,31 @@ Copyright: 2019, ARM Limited.
  2016, Linaro Limited
 License: BSD-2-clause
 
+Files: plat/hisilicon/hikey/hikey_bl31_setup.c
+ plat/hisilicon/hikey/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
 Files: plat/hisilicon/hikey960/hikey960_bl31_setup.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+ plat/hisilicon/hikey960/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/hisilicon/poplar/bl31_plat_setup.c
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/imx/common/imx_bl31_common.c
+Copyright: 2023, 2024, NXP
+License: BSD-3-clause
+
+Files: plat/imx/common/imx_common.c
+Copyright: 2024, Pengutronix, Inc.
 License: BSD-3-clause
 
 Files: plat/imx/common/imx_ehf.c
  plat/imx/common/imx_sip_handler.c
-Copyright: 2016-2023, NXP
+Copyright: 2016-2024, NXP
 License: BSD-3-clause
 
 Files: plat/imx/common/imx_sdei.c
@@ -2000,6 +2445,14 @@ Copyright: 2020, NXP
  2015-2023, ARM Limited and Contributors.
 License: BSD-3-clause
 
+Files: plat/imx/common/include/imx_plat_common.h
+Copyright: 2023, 2024, NXP
+License: BSD-3-clause
+
+Files: plat/imx/common/include/plat_common.h
+Copyright: 2024, Pengutronix, Inc.
+License: BSD-3-clause
+
 Files: plat/imx/common/include/sci/svc/misc/*
 Copyright: 2017-2021, NXP
  2014-2016, Freescale Semiconductor, Inc.
@@ -2021,7 +2474,7 @@ Copyright: 2017-2021, NXP
 License: BSD-3-clause
 
 Files: plat/imx/imx7/common/imx7.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx7/common/imx7_helpers.S
@@ -2029,18 +2482,18 @@ Copyright: Linaro 2018-2019, Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/*
-Copyright: 2016-2023, NXP
+Copyright: 2016-2024, NXP
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/gpc_common.c
  plat/imx/imx8m/imx8m_image_load.c
  plat/imx/imx8m/imx8m_psci_common.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8m_caam.c
  plat/imx/imx8m/imx_rdc.c
-Copyright: 2019-2022, NXP.
+Copyright: 2019-2024, NXP.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8m_ccm.c
@@ -2053,12 +2506,12 @@ Copyright: 2022, Linaro.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8m_measured_boot.c
-Copyright: 2022, Linaro.
- 2022, 2023, Arm Limited.
+Copyright: 2022-2024, Arm Limited.
+ 2022, 2023, Linaro.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8mm/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c
@@ -2066,35 +2519,43 @@ Copyright: 2021, Arm
  2017-2021, NXP
 License: BSD-3-clause
 
-Files: plat/imx/imx8m/imx8mm/include/gpc_reg.h
- plat/imx/imx8m/imx8mm/include/imx_sec_def.h
-Copyright: 2016-2023, NXP
+Files: plat/imx/imx8m/imx8mm/include/*
+Copyright: 2016-2024, NXP
+License: BSD-3-clause
+
+Files: plat/imx/imx8m/imx8mm/include/imx8mm_private.h
+ plat/imx/imx8m/imx8mm/include/platform_def.h
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/imx/imx8m/imx8mm/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c
  plat/imx/imx8m/imx8mp/imx8mp_rotpk.S
  plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8mp/include/imx8mp_private.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8mq/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8mq/include/*
-Copyright: 2016-2023, NXP
+Copyright: 2016-2024, NXP
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx8mq/include/platform_def.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx_aipstz.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/imx_hab.c
@@ -2105,12 +2566,12 @@ License: BSD-3-clause
 Files: plat/imx/imx8m/include/gpc.h
  plat/imx/imx8m/include/imx8m_psci.h
  plat/imx/imx8m/include/imx_aipstz.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/include/imx8m_caam.h
  plat/imx/imx8m/include/imx_rdc.h
-Copyright: 2019-2022, NXP.
+Copyright: 2019-2024, NXP.
 License: BSD-3-clause
 
 Files: plat/imx/imx8m/include/imx8m_ccm.h
@@ -2121,111 +2582,207 @@ Files: plat/imx/imx8m/include/imx8m_measured_boot.h
 Copyright: 2022, Linaro
 License: BSD-3-clause
 
+Files: plat/imx/imx8ulp/*
+Copyright: 2016-2024, NXP
+License: BSD-3-clause
+
+Files: plat/imx/imx8ulp/imx8ulp_caam.c
+Copyright: 2019-2024, NXP.
+License: BSD-3-clause
+
+Files: plat/imx/imx8ulp/include/imx8ulp_caam.h
+Copyright: 2019-2024, NXP.
+License: BSD-3-clause
+
+Files: plat/imx/imx8ulp/include/scmi_sensor.h
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
 Files: plat/imx/imx93/*
-Copyright: 2016-2023, NXP
+Copyright: 2016-2024, NXP
 License: BSD-3-clause
 
 Files: plat/intel/*
-Copyright: 2019-2023, Intel Corporation.
+Copyright: 2019-2024, Intel Corporation.
 License: BSD-3-clause
 
 Files: plat/intel/soc/agilex/bl2_plat_setup.c
  plat/intel/soc/agilex/bl31_plat_setup.c
-Copyright: 2019-2023, Intel Corporation.
- 2019-2023, ARM Limited and Contributors.
+ plat/intel/soc/agilex/platform.mk
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
-Files: plat/intel/soc/agilex/include/socfpga_plat_def.h
-Copyright: 2019-2023, Intel Corporation.
- 2019-2023, ARM Limited and Contributors.
+Files: plat/intel/soc/agilex/include/agilex_memory_controller.h
+ plat/intel/soc/agilex/include/agilex_system_manager.h
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
-Files: plat/intel/soc/agilex/platform.mk
-Copyright: 2019-2023, ARM Limited and Contributors.
+Files: plat/intel/soc/agilex/include/socfpga_plat_def.h
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
  2019-2023, Intel Corporation.
 License: BSD-3-clause
 
 Files: plat/intel/soc/agilex5/*
-Copyright: 2019-2023, Intel Corporation.
- 2019-2023, ARM Limited and Contributors.
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
-Files: plat/intel/soc/agilex5/include/*
-Copyright: 2019-2023, Intel Corporation.
+Files: plat/intel/soc/agilex5/bl2_plat_setup.c
+ plat/intel/soc/agilex5/bl31_plat_setup.c
+ plat/intel/soc/agilex5/platform.mk
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
+ 2019-2023, Intel Corporation.
+License: BSD-3-clause
+
+Files: plat/intel/soc/agilex5/include/agilex5_memory_controller.h
+ plat/intel/soc/agilex5/include/agilex5_mmc.h
+Copyright: 2019-2024, Intel Corporation.
 License: BSD-3-clause
 
 Files: plat/intel/soc/agilex5/include/socfpga_plat_def.h
-Copyright: 2019-2023, Intel Corporation.
- 2019-2023, ARM Limited and Contributors.
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
-Files: plat/intel/soc/agilex5/soc/*
-Copyright: 2019-2023, Intel Corporation.
+Files: plat/intel/soc/agilex5/soc/agilex5_memory_controller.c
+ plat/intel/soc/agilex5/soc/agilex5_mmc.c
+Copyright: 2019-2024, Intel Corporation.
 License: BSD-3-clause
 
-Files: plat/intel/soc/common/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Files: plat/intel/soc/common/aarch64/*
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
-Files: plat/intel/soc/common/drivers/*
-Copyright: 2019-2023, Intel Corporation.
+Files: plat/intel/soc/common/aarch64/platform_common.c
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/intel/soc/common/bl2_plat_mem_params_desc.c
+ plat/intel/soc/common/socfpga_topology.c
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/intel/soc/common/drivers/ccu/*
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
 Files: plat/intel/soc/common/drivers/qspi/*
-Copyright: 2019-2023, Intel Corporation.
- 2019-2023, ARM Limited and Contributors.
+Copyright: 2019-2022, Intel Corporation.
+ 2019-2022, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/intel/soc/common/include/*
-Copyright: 2019-2023, Intel Corporation.
+Files: plat/intel/soc/common/drivers/sdmmc/*
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
 Files: plat/intel/soc/common/include/platform_def.h
-Copyright: 2019-2023, Intel Corporation.
- 2019-2023, ARM Limited and Contributors.
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
-Files: plat/intel/soc/common/sip/socfpga_sip_fcs.c
-Copyright: 2019-2023, Intel Corporation.
+Files: plat/intel/soc/common/include/socfpga_handoff.h
+ plat/intel/soc/common/include/socfpga_mailbox.h
+ plat/intel/soc/common/include/socfpga_private.h
+ plat/intel/soc/common/include/socfpga_sip_svc.h
+ plat/intel/soc/common/include/socfpga_system_manager.h
+ plat/intel/soc/common/include/socfpga_vab.h
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
+License: BSD-3-clause
+
+Files: plat/intel/soc/common/lib/*
+Copyright: 2024, Altera Corporation.
+License: BSD-3-clause
+
+Files: plat/intel/soc/common/sip/*
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
+License: BSD-3-clause
+
+Files: plat/intel/soc/common/sip/socfpga_sip_ecc.c
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/intel/soc/common/soc/*
-Copyright: 2019-2023, Intel Corporation.
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
+License: BSD-3-clause
+
+Files: plat/intel/soc/common/soc/socfpga_emac.c
+ plat/intel/soc/common/soc/socfpga_firewall.c
+Copyright: 2019-2024, Intel Corporation.
+License: BSD-3-clause
+
+Files: plat/intel/soc/common/socfpga_delay_timer.c
+ plat/intel/soc/common/socfpga_image_load.c
+Copyright: 2024, Altera Corporation.
+ 2019-2023, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/intel/soc/common/socfpga_psci.c
+ plat/intel/soc/common/socfpga_sip_svc.c
  plat/intel/soc/common/socfpga_storage.c
  plat/intel/soc/common/socfpga_vab.c
-Copyright: 2019-2023, Intel Corporation.
- 2019-2023, ARM Limited and Contributors.
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
+ 2019-2023, Intel Corporation.
+License: BSD-3-clause
+
+Files: plat/intel/soc/n5x/*
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
-Files: plat/intel/soc/common/socfpga_sip_svc_v2.c
-Copyright: 2019-2023, Intel Corporation.
+Files: plat/intel/soc/n5x/bl31_plat_setup.c
+Copyright: 2019-2024, Intel Corporation.
 License: BSD-3-clause
 
 Files: plat/intel/soc/n5x/include/socfpga_plat_def.h
-Copyright: 2019-2023, Intel Corporation.
- 2019-2023, ARM Limited and Contributors.
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
+ 2019-2023, Intel Corporation.
+License: BSD-3-clause
+
+Files: plat/intel/soc/n5x/soc/*
+Copyright: 2019-2024, Intel Corporation.
 License: BSD-3-clause
 
 Files: plat/intel/soc/stratix10/bl2_plat_setup.c
  plat/intel/soc/stratix10/bl31_plat_setup.c
-Copyright: 2019-2023, Intel Corporation.
- 2019-2023, ARM Limited and Contributors.
+Copyright: 2019-2022, Intel Corporation.
+ 2019-2022, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/intel/soc/stratix10/include/s10_memory_controller.h
+ plat/intel/soc/stratix10/include/s10_system_manager.h
+Copyright: 2024, Altera Corporation.
+ 2019-2023, Intel Corporation.
 License: BSD-3-clause
 
 Files: plat/intel/soc/stratix10/include/socfpga_plat_def.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2024, Altera Corporation.
+ 2019-2023, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/intel/soc/stratix10/platform.mk
-Copyright: 2019-2023, ARM Limited and Contributors.
+Copyright: 2024, Altera Corporation.
+ 2019-2024, ARM Limited and Contributors.
  2019-2023, Intel Corporation.
 License: BSD-3-clause
 
 Files: plat/marvell/*
-Copyright: 2016-2021, Marvell International Ltd.
+Copyright: 2016-2024, Marvell International Ltd.
 License: BSD-3-clause
 
 Files: plat/marvell/armada/a3k/common/a3700_ea.c
@@ -2240,12 +2797,17 @@ Files: plat/marvell/armada/a3k/common/plat_cci.c
 Copyright: 2021, Marek Behun <marek.behun@nic.cz>
 License: BSD-3-clause
 
-Files: plat/marvell/armada/a8k/a70x0_mochabin/board/*
+Files: plat/marvell/armada/a8k/a70x0_mochabin/*
 Copyright: 2021, Sartura Ltd.
  2021, Marvell International Ltd.
  2021, Globalscale technologies, Inc.
 License: BSD-3-clause
 
+Files: plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h
+ plat/marvell/armada/a8k/a70x0_mochabin/platform.mk
+Copyright: 2016-2024, Marvell International Ltd.
+License: BSD-3-clause
+
 Files: plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c
 Copyright: 2020, Sartura Ltd.
 License: BSD-3-clause
@@ -2256,89 +2818,85 @@ Copyright: 2020, ARM Limited.
 License: BSD-3-clause
 
 Files: plat/marvell/armada/common/aarch64/marvell_bl2_mem_params_desc.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/marvell/armada/common/aarch64/marvell_common.c
-Copyright: 2016-2021, Marvell International Ltd.
+Copyright: 2016-2024, Marvell International Ltd.
 License: BSD-3-clause
 
 Files: plat/marvell/armada/common/marvell_console.c
  plat/marvell/armada/common/marvell_image_load.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/marvell/octeontx/*
+Files: plat/marvell/octeontx/otx2/t91/t9130_cex7_eval/*
 Copyright: 2021, Semihalf.
  2018, Marvell International Ltd.
 License: BSD-3-clause
 
-Files: plat/marvell/octeontx/otx2/t91/t9130/*
-Copyright: 2016-2021, Marvell International Ltd.
-License: BSD-3-clause
-
 Files: plat/mediatek/*
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/common/mtk_plat_common.c
  plat/mediatek/common/mtk_plat_common.h
  plat/mediatek/common/mtk_sip_svc.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/drivers/audio/mt8188/audio_domain.c
-Copyright: 2022, Mediatek Inc.
+Copyright: 2022, 2024, Mediatek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/drivers/emi_mpu/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/drivers/emi_mpu/rules.mk
-Copyright: 2019-2023, MediaTek Inc.
-License: BSD-3-clause
-
-Files: plat/mediatek/drivers/uart/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
-Files: plat/mediatek/drivers/uart/uart.c
- plat/mediatek/drivers/uart/uart.h
-Copyright: 2019-2023, MediaTek Inc.
+Files: plat/mediatek/drivers/uart/8250_console.S
+ plat/mediatek/drivers/uart/uart8250.h
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/helpers/*
-Copyright: 2022, Mediatek Inc.
+Copyright: 2022, 2024, Mediatek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/helpers/rules.mk
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/include/armv8_2/*
-Copyright: 2022, Mediatek Inc.
+Copyright: 2022, 2024, Mediatek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/include/mtk_sip_svc.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/mediatek/include/plat_helpers.h
+Copyright: 2022, 2024, Mediatek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/lib/pm/*
-Copyright: 2022, Mediatek Inc.
+Copyright: 2022, 2024, Mediatek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/lib/pm/armv8_2/rules.mk
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/lib/pm/mtk_pm.c
  plat/mediatek/lib/pm/rules.mk
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8173/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8173/drivers/wdt/*
@@ -2346,7 +2904,7 @@ Copyright: 2020, 2022, 2023, Google LLC.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8183/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8183/bl31_plat_setup.c
@@ -2354,43 +2912,43 @@ Files: plat/mediatek/mt8183/bl31_plat_setup.c
  plat/mediatek/mt8183/plat_mt_gic.c
  plat/mediatek/mt8183/plat_pm.c
  plat/mediatek/mt8183/platform.mk
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8183/drivers/gpio/*
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8183/drivers/pmic/*
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8183/drivers/rtc/*
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8183/drivers/spm/spm.h
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8183/drivers/spmc/*
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8183/drivers/timer/*
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8183/include/plat_dcm.h
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8186/aarch64/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8186/drivers/emi_mpu/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8186/drivers/spm/mt_spm_extern.c
@@ -2398,86 +2956,83 @@ Files: plat/mediatek/mt8186/drivers/spm/mt_spm_extern.c
 Copyright: since 2022, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/mediatek/mt8186/include/plat_helpers.h
- plat/mediatek/mt8186/include/plat_macros.S
+Files: plat/mediatek/mt8186/include/plat_macros.S
  plat/mediatek/mt8186/include/plat_private.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8186/include/platform_def.h
-Copyright: 2021, 2022, MediaTek Inc.
- 2021, 2022, ARM Limited and Contributors.
+Copyright: 2021-2024, MediaTek Inc.
+ 2021-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8186/plat_topology.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8188/include/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8188/include/spm_reg.h
-Copyright: 2022, Mediatek Inc.
+Copyright: 2022, 2024, Mediatek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8192/aarch64/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8192/drivers/devapc/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8192/drivers/emi_mpu/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/mediatek/mt8192/include/plat_helpers.h
- plat/mediatek/mt8192/include/plat_macros.S
+Files: plat/mediatek/mt8192/include/plat_macros.S
  plat/mediatek/mt8192/include/plat_private.h
  plat/mediatek/mt8192/include/platform_def.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8192/plat_topology.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8195/aarch64/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8195/drivers/apusys/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8195/drivers/apusys/mtk_apusys.c
  plat/mediatek/mt8195/drivers/apusys/mtk_apusys.h
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8195/drivers/emi_mpu/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/mediatek/mt8195/include/plat_helpers.h
- plat/mediatek/mt8195/include/plat_macros.S
+Files: plat/mediatek/mt8195/include/plat_macros.S
  plat/mediatek/mt8195/include/plat_private.h
  plat/mediatek/mt8195/include/platform_def.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/mt8195/plat_topology.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/mediatek/topology/*
-Copyright: 2022, Mediatek Inc.
+Copyright: 2022, 2024, Mediatek Inc.
 License: BSD-3-clause
 
 Files: plat/mediatek/topology/rules.mk
-Copyright: 2019-2023, MediaTek Inc.
+Copyright: 2019-2024, MediaTek Inc.
 License: BSD-3-clause
 
 Files: plat/nuvoton/*
@@ -2492,18 +3047,19 @@ License: BSD-3-clause
 
 Files: plat/nvidia/*
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/nvidia/tegra/common/tegra_fiq_glue.c
+Copyright: 2020-2023, NVIDIA Corporation.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/common/tegra_gicv3.c
  plat/nvidia/tegra/common/tegra_io_storage.c
  plat/nvidia/tegra/common/tegra_sdei.c
  plat/nvidia/tegra/common/tegra_stack_protector.c
-Copyright: 2017-2022, NVIDIA Corporation.
-License: BSD-3-clause
-
-Files: plat/nvidia/tegra/drivers/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/drivers/bpmp_ipc/*
@@ -2511,28 +3067,7 @@ Copyright: 2017-2023, NVIDIA CORPORATION.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/drivers/bpmp_ipc/ivc.h
-Copyright: 2017-2022, NVIDIA Corporation.
-License: BSD-3-clause
-
-Files: plat/nvidia/tegra/drivers/memctrl/*
-Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/nvidia/tegra/drivers/smmu/*
-Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/nvidia/tegra/drivers/spe/*
-Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/nvidia/tegra/include/drivers/bpmp.h
- plat/nvidia/tegra/include/drivers/mce.h
- plat/nvidia/tegra/include/drivers/memctrl_v1.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -2542,12 +3077,12 @@ Copyright: 2017-2020, NVIDIA CORPORATION.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/include/drivers/spe.h
-Copyright: 2017-2022, NVIDIA Corporation.
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/include/lib/*
 Copyright: 2020-2023, NVIDIA Corporation.
- 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/include/t186/*
@@ -2556,7 +3091,7 @@ License: BSD-3-clause
 
 Files: plat/nvidia/tegra/include/t186/tegra_def.h
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/include/t194/*
@@ -2564,45 +3099,43 @@ Copyright: 2017-2023, NVIDIA CORPORATION.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/include/t194/tegra194_ras_private.h
-Copyright: 2017-2022, NVIDIA Corporation.
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/lib/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/nvidia/tegra/scat/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Files: plat/nvidia/tegra/platform.mk
+Copyright: 2020-2023, NVIDIA Corporation.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/nvidia/tegra/soc/t186/drivers/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Files: plat/nvidia/tegra/soc/*
+Copyright: 2017-2023, NVIDIA CORPORATION.
 License: BSD-3-clause
 
-Files: plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
+Files: plat/nvidia/tegra/soc/t186/*
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/soc/t186/drivers/se/*
-Copyright: 2017-2022, NVIDIA Corporation.
-License: BSD-3-clause
-
-Files: plat/nvidia/tegra/soc/t186/plat_sip_calls.c
-Copyright: 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/nvidia/tegra/soc/t194/*
-Copyright: 2017-2023, NVIDIA CORPORATION.
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/soc/t194/drivers/se/*
-Copyright: 2020, ARM Limited and Contributors.
- 2019, 2020, NVIDIA CORPORATION.
+Copyright: 2017-2020, NVIDIA CORPORATION.
+ 2015-2020, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/soc/t194/plat_ras.c
-Copyright: 2017-2022, NVIDIA Corporation.
+Copyright: 2017-2022, 2024, NVIDIA Corporation.
+License: BSD-3-clause
+
+Files: plat/nvidia/tegra/soc/t210/*
+Copyright: 2015-2023, NVIDIA Corporation.
+ 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/nvidia/tegra/soc/t210/drivers/*
@@ -2610,26 +3143,22 @@ Copyright: 2017-2020, NVIDIA CORPORATION.
  2015-2020, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/nvidia/tegra/soc/t210/plat_secondary.c
-Copyright: 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
 Files: plat/nxp/*
-Copyright: 2016-2023, NXP
+Copyright: 2016-2024, NXP
 License: BSD-3-clause
 
 Files: plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk
-Copyright: 2023, Arm Limited.
+Copyright: 2023, 2024, Arm Limited.
  2018-2020, NXP
 License: BSD-3-clause
 
 Files: plat/nxp/common/fip_handler/fuse_fip/fuse.mk
-Copyright: 2023, Arm Limited.
+Copyright: 2023, 2024, Arm Limited.
  2018-2020, NXP
 License: BSD-3-clause
 
 Files: plat/nxp/common/plat_make_helper/plat_build_macros.mk
-Copyright: 2019-2022, NXP.
+Copyright: 2019-2024, NXP.
 License: BSD-3-clause
 
 Files: plat/nxp/soc-ls1043a/include/ns_access.h
@@ -2645,36 +3174,53 @@ License: BSD-3-clause
 Files: plat/qemu/common/common.mk
  plat/qemu/common/qemu_gicv3.c
  plat/qemu/common/qemu_spm.c
-Copyright: 2019-2023, Linaro Limited and Contributors.
+Copyright: 2019-2024, Linaro Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/qemu/common/qemu_bl2_setup.c
+Files: plat/qemu/common/qemu_bl2_mem_params_desc.c
+ plat/qemu/common/qemu_bl2_setup.c
+ plat/qemu/common/qemu_bl31_setup.c
  plat/qemu/common/qemu_common.c
  plat/qemu/common/qemu_image_load.c
+ plat/qemu/common/qemu_io_storage.c
  plat/qemu/common/qemu_private.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+ plat/qemu/common/qemu_realm_attest_key.c
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/qemu/common/qemu_plat_attest_token.c
+Copyright: 2024, Linaro Limited and Contributors.
+ 2022-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/qemu/common/trp/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/qemu/common/trp/qemu_trp_setup.c
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/qemu/qemu/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/qemu/qemu/qemu_bl1_measured_boot.c
-Copyright: 2022, Linaro.
- 2022, 2023, Arm Limited.
+ plat/qemu/qemu/qemu_measured_boot.c
+Copyright: 2022-2024, Arm Limited.
+ 2022, 2023, Linaro.
 License: BSD-3-clause
 
 Files: plat/qemu/qemu/qemu_helpers.c
 Copyright: 2022, Linaro.
 License: BSD-3-clause
 
-Files: plat/qemu/qemu/qemu_measured_boot.c
-Copyright: 2022, Arm Limited.
- 2022, 2023, Linaro.
+Files: plat/qemu/qemu/trp/*
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: plat/qemu/qemu_sbsa/*
-Copyright: 2019-2023, Linaro Limited and Contributors.
+Copyright: 2019-2024, Linaro Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/qemu/qemu_sbsa/sbsa_pm.c
@@ -2696,20 +3242,19 @@ Copyright: 2018-2021, The Linux Foundation.
  2013-2018, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/qti/common/inc/qti_cpu.h
- plat/qti/common/inc/qti_interrupt_svc.h
- plat/qti/common/inc/qti_rng.h
-Copyright: 2018-2021, The Linux Foundation.
-License: BSD-3-clause
-
 Files: plat/qti/common/inc/spmi_arb.h
 Copyright: 2020, 2022, 2023, Google LLC.
 License: BSD-3-clause
 
-Files: plat/qti/common/src/aarch64/qti_kryo6_gold.S
- plat/qti/common/src/aarch64/qti_kryo6_silver.S
+Files: plat/qti/common/src/aarch64/*
 Copyright: 2018-2021, The Linux Foundation.
- 2015-2018, Arm Limited and Contributors.
+ 2015-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/qti/common/src/aarch64/qti_helpers.S
+ plat/qti/common/src/aarch64/qti_uart_console.S
+Copyright: 2018-2021, The Linux Foundation.
+ 2013-2018, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/qti/common/src/pm_ps_hold.c
@@ -2717,16 +3262,6 @@ Files: plat/qti/common/src/pm_ps_hold.c
 Copyright: 2020, 2022, 2023, Google LLC.
 License: BSD-3-clause
 
-Files: plat/qti/common/src/qti_pm.c
-Copyright: 2018, ARM Limited and Contributors.
- 2018, 2020, The Linux Foundation.
-License: BSD-3-clause
-
-Files: plat/qti/common/src/qti_rng.c
- plat/qti/common/src/qti_stack_protector.c
-Copyright: 2018-2021, The Linux Foundation.
-License: BSD-3-clause
-
 Files: plat/qti/msm8916/aarch32/uartdm_console.S
 Copyright: 2021-2023, Stephan Gerhold <stephan@gerhold.net>
  2015-2021, ARM Limited and Contributors.
@@ -2738,7 +3273,7 @@ Copyright: 2021-2023, Stephan Gerhold <stephan@gerhold.net>
 License: BSD-3-clause
 
 Files: plat/qti/msm8916/include/plat_macros.S
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/qti/msm8916/msm8916_topology.c
@@ -2774,7 +3309,7 @@ License: BSD-3-clause
 
 Files: plat/qti/sc7280/inc/platform_def.h
 Copyright: 2018-2021, The Linux Foundation.
- 2015-2018, Arm Limited and Contributors.
+ 2015-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/qti/sc7280/inc/qti_map_chipinfo.h
@@ -2783,43 +3318,105 @@ License: BSD-3-clause
 
 Files: plat/qti/sc7280/platform.mk
 Copyright: 2018-2021, The Linux Foundation.
- 2015-2018, Arm Limited and Contributors.
+ 2015-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/renesas/*
-Copyright: 2015-2023, Renesas Electronics Corporation.
+Copyright: 2015-2024, Renesas Electronics Corporation.
 License: BSD-3-clause
 
 Files: plat/renesas/common/aarch64/*
-Copyright: 2015-2021, Renesas Electronics Corporation.
- 2013-2023, Arm Limited and Contributors.
+Copyright: 2015-2023, Renesas Electronics Corporation.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/renesas/common/aarch64/platform_common.c
-Copyright: 2015-2020, Renesas Electronics Corporation.
+Copyright: 2015-2023, Renesas Electronics Corporation.
  2013, 2014, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/renesas/common/bl2_plat_mem_params_desc.c
  plat/renesas/common/plat_image_load.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/renesas/common/bl31_plat_setup.c
-Copyright: 2015-2020, Renesas Electronics Corporation.
+Copyright: 2015-2023, Renesas Electronics Corporation.
  2013, 2014, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/renesas/common/include/plat.ld.S
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/rockchip/common/include/plat_pm_helpers.h
+Copyright: 2024, Rockchip, Inc.
+License: BSD-3-clause
+
+Files: plat/rockchip/common/plat_pm_helpers.c
+Copyright: 2024, Rockchip, Inc.
+License: BSD-3-clause
+
+Files: plat/rockchip/common/scmi/*
+Copyright: 2024, Rockchip, Inc.
 License: BSD-3-clause
 
 Files: plat/rockchip/rk3288/platform.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/rockchip/rk3399/drivers/m0/Makefile
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/rockchip/rk3588/*
+Copyright: 2024, Rockchip, Inc.
+License: BSD-3-clause
+
+Files: plat/rpi/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/rpi/common/rpi3_console_dual.c
+ plat/rpi/common/rpi3_console_pl011.c
+ plat/rpi/common/rpi_pci_svc.c
+Copyright: no-info-found
+License: BSD-3-clause
+
+Files: plat/rpi/common/rpi3_image_load.c
+ plat/rpi/common/rpi3_io_storage.c
+ plat/rpi/common/rpi3_rotpk.S
+ plat/rpi/common/rpi3_stack_protector.c
+ plat/rpi/common/rpi3_trusted_boot.c
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/rpi/rpi3/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/rpi/rpi3/include/*
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/rpi/rpi3/platform.mk
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/rpi/rpi4/include/plat.ld.S
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/rpi/rpi5/*
+Copyright: no-info-found
+License: BSD-3-clause
+
+Files: plat/rpi/rpi5/include/plat.ld.S
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/socionext/synquacer/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/socionext/synquacer/sq_bl2_setup.c
@@ -2830,18 +3427,24 @@ Files: plat/socionext/synquacer/sq_bl2_setup.c
 Copyright: 2019, 2020, 2022, Socionext Inc.
 License: BSD-3-clause
 
+Files: plat/socionext/uniphier/platform.mk
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
 Files: plat/socionext/uniphier/uniphier_console_setup.c
 Copyright: 2019, 2020, 2022, Socionext Inc.
 License: BSD-3-clause
 
 Files: plat/st/*
-Copyright: 2014-2023, STMicroelectronics
+Copyright: 2014-2024, STMicroelectronics
 License: BSD-3-clause
 
 Files: plat/st/common/bl2_io_storage.c
  plat/st/common/plat_image_load.c
+ plat/st/common/stm32mp_common.c
  plat/st/common/stm32mp_dt.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+ plat/st/common/stm32mp_gic.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/st/common/include/stm32mp_dt.h
@@ -2854,116 +3457,91 @@ Copyright: 2022, STMicroelectronics
  2021, Linaro Limited
 License: BSD-3-clause
 
-Files: plat/st/common/stm32mp_common.c
- plat/st/common/stm32mp_gic.c
-Copyright: 2013-2023, ARM Limited and Contributors.
-License: BSD-3-clause
-
 Files: plat/st/stm32mp1/bl2_plat_setup.c
- plat/st/stm32mp1/plat_bl2_mem_params_desc.c
- plat/st/stm32mp1/stm32mp1.S
- plat/st/stm32mp1/stm32mp1.ld.S
- plat/st/stm32mp1/stm32mp1_helper.S
+ plat/st/stm32mp1/platform.mk
+ plat/st/stm32mp1/stm32mp1_def.h
+ plat/st/stm32mp1/stm32mp1_pm.c
  plat/st/stm32mp1/stm32mp1_private.c
- plat/st/stm32mp1/stm32mp1_stack_protector.c
- plat/st/stm32mp1/stm32mp1_tbb_cert.c
- plat/st/stm32mp1/stm32mp1_topology.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/st/stm32mp1/include/platform_def.h
- plat/st/stm32mp1/include/stm32mp1_private.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: plat/st/stm32mp1/include/stm32mp1_private.h
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/st/stm32mp1/include/tbbr/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/st/stm32mp1/platform.mk
- plat/st/stm32mp1/stm32mp1_def.h
- plat/st/stm32mp1/stm32mp1_pm.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: plat/st/stm32mp1/plat_bl2_mem_params_desc.c
+ plat/st/stm32mp1/stm32mp1.S
+ plat/st/stm32mp1/stm32mp1.ld.S
+ plat/st/stm32mp1/stm32mp1_helper.S
+ plat/st/stm32mp1/stm32mp1_stack_protector.c
+ plat/st/stm32mp1/stm32mp1_tbb_cert.c
+ plat/st/stm32mp1/stm32mp1_topology.c
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/st/stm32mp1/sp_min/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/ti/k3/common/drivers/*
-Copyright: 2018, Texas Instruments Incorporated - http://www.ti.com
-License: BSD-3-clause
-
-Files: plat/ti/k3/common/drivers/ti_sci/*
-Copyright: 2018-2022, Texas Instruments Incorporated - https://www.ti.com
+Copyright: 2018-2024, Texas Instruments Incorporated - https://www.ti.com
 License: BSD-3-clause
 
-Files: plat/xilinx/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
- 2013-2022, Arm Limited and Contributors.
+Files: plat/ti/k3/common/drivers/sec_proxy/*
+Copyright: 2018, Texas Instruments Incorporated - http://www.ti.com
 License: BSD-3-clause
 
-Files: plat/xilinx/common/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Files: plat/ti/k3/common/k3_bl31_setup.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/xilinx/common/include/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
- 2019-2022, Xilinx, Inc.
+Files: plat/xilinx/*
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/xilinx/common/include/ipi.h
 Copyright: 2018, 2019, Xilinx, Inc.
 License: BSD-3-clause
 
-Files: plat/xilinx/common/include/plat_common.h
- plat/xilinx/common/include/plat_console.h
- plat/xilinx/common/include/plat_fdt.h
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
-License: BSD-3-clause
-
-Files: plat/xilinx/common/include/plat_startup.h
- plat/xilinx/common/include/pm_common.h
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
- 2013-2022, Arm Limited and Contributors.
+Files: plat/xilinx/common/include/pm_api_sys.h
+ plat/xilinx/common/include/pm_defs.h
+ plat/xilinx/common/include/pm_node.h
+ plat/xilinx/common/include/pm_svc_main.h
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
+ 2019-2022, Xilinx, Inc.
 License: BSD-3-clause
 
 Files: plat/xilinx/common/include/pm_client.h
  plat/xilinx/common/include/pm_ipi.h
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2017-2022, Xilinx, Inc.
- 2013-2022, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/xilinx/common/ipi.c
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2017-2022, Xilinx, Inc.
- 2013-2022, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/common/ipi_mailbox_service/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
- 2013-2022, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h
-Copyright: 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/common/plat_startup.c
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
- 2013-2022, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/xilinx/common/pm_service/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2019-2022, Xilinx, Inc.
 License: BSD-3-clause
 
 Files: plat/xilinx/common/pm_service/pm_ipi.c
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2017-2022, Xilinx, Inc.
- 2013-2022, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/xilinx/common/tsp/*
@@ -2972,21 +3550,17 @@ Copyright: 2023, Advanced Micro Devices.
 License: BSD-3-clause
 
 Files: plat/xilinx/common/tsp/tsp.mk
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
-License: BSD-3-clause
-
-Files: plat/xilinx/versal/aarch64/versal_helpers.S
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
 License: BSD-3-clause
 
 Files: plat/xilinx/versal/bl31_versal_setup.c
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2017-2022, Xilinx, Inc.
- 2013-2022, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/xilinx/versal/include/plat_ipi.h
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2019-2022, Xilinx, Inc.
 License: BSD-3-clause
 
@@ -2996,121 +3570,41 @@ License: BSD-3-clause
 
 Files: plat/xilinx/versal/include/plat_private.h
  plat/xilinx/versal/include/versal_def.h
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2017-2022, Xilinx, Inc.
- 2013-2022, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/versal/plat_topology.c
- plat/xilinx/versal/plat_versal.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/xilinx/versal/pm_service/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2019-2022, Xilinx, Inc.
 License: BSD-3-clause
 
-Files: plat/xilinx/versal/tsp/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
-License: BSD-3-clause
-
 Files: plat/xilinx/versal/versal_ipi.c
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2019-2022, Xilinx, Inc.
 License: BSD-3-clause
 
 Files: plat/xilinx/versal_net/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
- 2017-2022, Xilinx, Inc.
- 2013-2022, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/versal_net/aarch64/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
- 2021, 2022, Arm Limited and Contributors.
- 2018-2022, Xilinx, Inc.
-License: BSD-3-clause
-
-Files: plat/xilinx/versal_net/aarch64/versal_net_helpers.S
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2017-2022, Xilinx, Inc.
- 2013-2022, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/versal_net/include/plat_ipi.h
- plat/xilinx/versal_net/include/plat_pm_common.h
-Copyright: 2022, Xilinx, Inc.
- 2022, 2023, Advanced Micro Devices, Inc.
-License: BSD-3-clause
-
-Files: plat/xilinx/versal_net/include/versal_net_def.h
-Copyright: 2022, Arm Limited and Contributors.
- 2022, 2023, Advanced Micro Devices, Inc.
- 2021, 2022, Xilinx, Inc.
-License: BSD-3-clause
-
-Files: plat/xilinx/versal_net/plat_psci_pm.c
- plat/xilinx/versal_net/versal_net_ipi.c
-Copyright: 2022, Xilinx, Inc.
- 2022, 2023, Advanced Micro Devices, Inc.
-License: BSD-3-clause
-
-Files: plat/xilinx/versal_net/pm_service/*
-Copyright: 2022, Xilinx, Inc.
- 2022, 2023, Advanced Micro Devices, Inc.
-License: BSD-3-clause
-
-Files: plat/xilinx/versal_net/tsp/*
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
-License: BSD-3-clause
-
-Files: plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
-Copyright: 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/zynqmp/custom_sip_svc.c
- plat/xilinx/zynqmp/libpm.mk
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
-License: BSD-3-clause
-
-Files: plat/xilinx/zynqmp/include/custom_svc.h
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/xilinx/zynqmp/include/plat_ipi.h
  plat/xilinx/zynqmp/include/platform_def.h
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2017-2022, Xilinx, Inc.
- 2013-2022, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/zynqmp/include/plat_macros.S
- plat/xilinx/zynqmp/include/zynqmp_def.h
-Copyright: 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/zynqmp/plat_topology.c
- plat/xilinx/zynqmp/plat_zynqmp.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: plat/xilinx/zynqmp/platform.mk
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2021, 2022, ProvenRun S.A.S.
  2018-2022, Xilinx, Inc.
  2013-2021, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: plat/xilinx/zynqmp/pm_service/pm_api_clock.h
- plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
-Copyright: 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
-Files: plat/xilinx/zynqmp/tsp/*
-Copyright: 2013-2023, Arm Limited and Contributors.
-License: BSD-3-clause
-
 Files: plat/xilinx/zynqmp/zynqmp_ehf.c
  plat/xilinx/zynqmp/zynqmp_sdei.c
 Copyright: 2020, 2021, Siemens AG
@@ -3118,22 +3612,40 @@ Copyright: 2020, 2021, Siemens AG
 License: BSD-3-clause
 
 Files: plat/xilinx/zynqmp/zynqmp_ipi.c
-Copyright: 2022, 2023, Advanced Micro Devices, Inc.
+Copyright: 2022-2024, Advanced Micro Devices, Inc.
  2017-2022, Xilinx, Inc.
- 2013-2022, Arm Limited and Contributors.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: services/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: services/arm_arch_svc/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: services/el3/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: services/oem/*
+Copyright: 2024, The ChromiumOS Authors.
+License: BSD-3-clause
+
+Files: services/spd/opteed/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: services/spd/opteed/opteed.mk
+ services/spd/opteed/opteed_helpers.S
+ services/spd/opteed/teesmc_opteed_macros.h
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: services/spd/opteed/teesmc_opteed.h
 Copyright: 2014-2023, ARM Limited and Contributors.
- 2014, Linaro Limited.
+ 2014, 2019, Linaro Limited.
 License: BSD-3-clause
 
 Files: services/spd/pncd/*
@@ -3142,72 +3654,96 @@ License: BSD-3-clause
 
 Files: services/spd/pncd/pncd_private.h
 Copyright: 2021, 2022, ProvenRun S.A.S.
- 2016-2022, ARM Limited and Contributors.
+ 2016-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: services/spd/tlkd/tlkd_main.c
  services/spd/tlkd/tlkd_pm.c
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: services/spd/trusty/smcall.h
- services/spd/trusty/trusty.c
 Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+ 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: services/spd/trusty/trusty.c
+Copyright: 2020-2023, NVIDIA Corporation.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: services/std_svc/drtm/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: services/std_svc/errata_abi/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2023, 2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: services/std_svc/rmmd/rmmd_attest.c
-Copyright: 2015-2023, Arm Limited.
+Files: services/std_svc/rmmd/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: services/std_svc/rmmd/aarch64/*
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: services/std_svc/rmmd/rmmd_initial_context.h
- services/std_svc/rmmd/rmmd_main.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: services/std_svc/rmmd/rmmd.mk
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
-Files: services/std_svc/rmmd/trp/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: services/std_svc/rmmd/rmmd_attest.c
+Copyright: 2021-2024, NVIDIA Corporation.
+ 2019-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: services/std_svc/rmmd/trp/trp_entry.S
  services/std_svc/rmmd/trp/trp_helpers.c
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: services/std_svc/sdei/sdei_event.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+ services/std_svc/sdei/sdei_intr_mgmt.c
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: services/std_svc/spm/el3_spmc/spmc_setup.c
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: services/std_svc/spm/spm_mm/spm_mm_main.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: services/std_svc/spm/spm_mm/spm_mm_setup.c
-Copyright: 2015-2023, NVIDIA Corporation.
- 2013-2023, ARM Limited and Contributors.
+Copyright: 2020-2023, NVIDIA Corporation.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: services/std_svc/spmd/spmd_logical_sp.c
- services/std_svc/spmd/spmd_main.c
- services/std_svc/spmd/spmd_private.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Files: services/std_svc/spmd/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
+Files: services/std_svc/spmd/aarch64/*
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: services/std_svc/spmd/spmd.mk
+ services/std_svc/spmd/spmd_pm.c
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: services/std_svc/std_svc_setup.c
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: services/std_svc/trng/trng_entropy_pool.c
-Copyright: 2015-2023, ARM Limited.
+Copyright: 2015-2024, ARM Limited.
 License: BSD-3-clause
 
 Files: tools/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: tools/amlogic/*
@@ -3215,94 +3751,118 @@ Copyright: 2019, Remi Pommarel <repk@triplefau.lt>
 License: BSD-3-clause
 
 Files: tools/cert_create/*
-Copyright: 2014-2023, Arm Limited and Contributors.
-License: BSD-3-clause and/or OpenSSL
-
-Files: tools/cert_create/include/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
+Files: tools/cert_create/Makefile
+Copyright: 2014-2024, Arm Limited and Contributors.
+License: BSD-3-clause or OpenSSL
+
 Files: tools/cert_create/include/cca/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: tools/cert_create/include/dualroot/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: tools/cert_create/include/ext.h
  tools/cert_create/include/key.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: tools/cert_create/src/*
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: tools/cert_create/src/cca/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: tools/cert_create/src/cmd_opt.c
  tools/cert_create/src/ext.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: tools/cert_create/src/dualroot/*
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: tools/cert_create/src/tbbr/*
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: tools/cert_create/src/tbbr/tbb_key.c
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: tools/cert_create/src/tbbr/tbbr.mk
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
 Files: tools/conventional-changelog-tf-a/*
 Copyright: no-info-found
-License: BSD-3-clause
+License: BSD-3-Clause
 
 Files: tools/conventional-changelog-tf-a/index.js
-Copyright: 2015-2023, Arm Limited.
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: tools/encrypt_fw/*
-Copyright: 2019-2022, Linaro Limited.
-License: BSD-3-clause and/or OpenSSL
+Files: tools/cot_dt2c/cot_dt2c/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
 
-Files: tools/encrypt_fw/include/*
-Copyright: 2019, Linaro Limited.
- 2015, ARM Limited and Contributors.
+Files: tools/cot_dt2c/cot_dt2c/__init__.py
+ tools/cot_dt2c/cot_dt2c/__main__.py
+Copyright: 2015-2024, Arm Limited.
 License: BSD-3-clause
 
-Files: tools/encrypt_fw/include/debug.h
-Copyright: 2013-2023, ARM Limited and Contributors.
+Files: tools/cot_dt2c/tests/test_util.py
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: tools/encrypt_fw/include/encrypt.h
+Files: tools/encrypt_fw/*
 Copyright: 2019, 2020, Linaro Limited.
 License: BSD-3-clause
 
-Files: tools/encrypt_fw/src/*
-Copyright: 2019, 2020, Linaro Limited.
+Files: tools/encrypt_fw/Makefile
+Copyright: 2024, Arm Limited.
+ 2019-2022, Linaro Limited.
+License: BSD-3-clause or OpenSSL
+
+Files: tools/encrypt_fw/include/cmd_opt.h
+Copyright: 2014-2023, ARM Limited and Contributors.
+ 2014, 2019, Linaro Limited.
+License: BSD-3-clause
+
+Files: tools/encrypt_fw/include/debug.h
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: tools/encrypt_fw/src/cmd_opt.c
-Copyright: 2013-2023, ARM Limited and Contributors.
+Copyright: 2013-2024, ARM Limited and Contributors.
+License: BSD-3-clause
+
+Files: tools/encrypt_fw/src/main.c
+Copyright: 2024, Arm Limited and Contributors.
+ 2019, Linaro Limited.
 License: BSD-3-clause
 
 Files: tools/fiptool/Makefile
-Copyright: 2014-2023, Arm Limited and Contributors.
-License: BSD-3-clause and/or OpenSSL
+Copyright: 2014-2024, Arm Limited and Contributors.
+License: BSD-3-clause or OpenSSL
 
-Files: tools/fiptool/Makefile.msvc
-Copyright: 2015-2023, Arm Limited.
+Files: tools/fiptool/fiptool.c
+ tools/fiptool/win_posix.c
+ tools/fiptool/win_posix.h
+Copyright: 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: tools/fiptool/plat_fiptool/*
-Copyright: 2015-2023, Arm Limited.
+Files: tools/fiptool/fiptool.h
+ tools/fiptool/fiptool_platform.h
+ tools/fiptool/tbbr_config.c
+ tools/fiptool/tbbr_config.h
+Copyright: 2013-2024, ARM Limited and Contributors.
 License: BSD-3-clause
 
 Files: tools/fiptool/plat_fiptool/arm/board/tc/plat_fiptool.mk
@@ -3311,41 +3871,40 @@ Copyright: 2022, 2023, Arm Limited.
 License: BSD-3-clause
 
 Files: tools/fiptool/plat_fiptool/nxp/*
-Copyright: 2022, 2023, Arm Limited.
- 2021, NXP.
+Copyright: 2016-2024, NXP
 License: BSD-3-clause
 
-Files: tools/fiptool/plat_fiptool/nxp/plat_def_uuid_config.c
-Copyright: 2016-2023, NXP
+Files: tools/fiptool/plat_fiptool/nxp/plat_fiptool.mk
+Copyright: 2022, 2023, Arm Limited.
+ 2021, NXP.
 License: BSD-3-clause
 
 Files: tools/fiptool/plat_fiptool/st/*
-Copyright: 2014-2023, STMicroelectronics
-License: BSD-3-clause
-
-Files: tools/fiptool/win_posix.c
- tools/fiptool/win_posix.h
-Copyright: 2013-2023, Arm Limited and Contributors.
+Copyright: 2014-2024, STMicroelectronics
 License: BSD-3-clause
 
-Files: tools/marvell/*
-Copyright: 2016-2021, Marvell International Ltd.
-License: BSD-3-clause
-
-Files: tools/memory/*
-Copyright: 2015-2023, Arm Limited.
+Files: tools/marvell/doimage/Makefile
+ tools/marvell/doimage/doimage.c
+ tools/marvell/doimage/doimage.mk
+Copyright: 2016-2024, Marvell International Ltd.
 License: BSD-3-clause
 
 Files: tools/nxp/*
-Copyright: 2016-2023, NXP
+Copyright: 2016-2024, NXP
 License: BSD-3-clause
 
 Files: tools/renesas/*
+Copyright: 2015-2024, Renesas Electronics Corporation.
+License: BSD-3-clause
+
+Files: tools/renesas/rcar_layout_create/makefile
 Copyright: 2015-2023, Renesas Electronics Corporation.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
-Files: tools/sptool/*
-Copyright: 2015-2023, Arm Limited.
+Files: tools/renesas/rzg_layout_create/makefile
+Copyright: 2015-2023, Renesas Electronics Corporation.
+ 2013-2024, Arm Limited and Contributors.
 License: BSD-3-clause
 
 Files: tools/sptool/sptool.py
@@ -3353,99 +3912,162 @@ Copyright: 2022, The Hafnium Authors.
  2022, Arm Limited.
 License: BSD-3-clause
 
+Files: tools/stm32image/*
+Copyright: 2013-2024, Arm Limited and Contributors.
+License: BSD-3-clause
+
 Files: tools/stm32image/stm32image.c
-Copyright: 2014-2023, STMicroelectronics
+Copyright: 2014-2024, STMicroelectronics
 License: BSD-3-clause
 
-Files: .husky/pre-commit.copyright dco.txt docs/about/release-information.rst docs/change-log.md docs/components/activity-monitors.rst docs/components/cot-binding.rst docs/components/romlib-design.rst docs/design/alt-boot-flows.rst docs/design/index.rst docs/design_documents/drtm_poc.rst docs/design_documents/measured_boot.rst docs/design_documents/measured_boot_poc.rst docs/design_documents/rss.rst docs/getting_started/psci-lib-integration-guide.rst docs/getting_started/rt-svc-writers-guide.rst docs/index.rst docs/perf/performance-monitoring-unit.rst docs/perf/psci-performance-juno.rst docs/plat/stm32mp1.rst docs/porting-guide.rst docs/process/code-review-guidelines.rst docs/process/coding-guidelines.rst docs/process/commit-style.rst docs/process/platform-ports-policy.rst docs/resources/diagrams/PSA-FWU.dia docs/resources/diagrams/int_handling.dia docs/resources/diagrams/measured_boot_design.dia docs/resources/diagrams/reset_code_flow.dia docs/resources/diagrams/rmm_cold_boot_generic.dia docs/resources/diagrams/romlib_design.dia docs/resources/diagrams/romlib_wrapper.dia docs/resources/diagrams/xlat_align.dia docs/threat_model/index.rst plat/arm/board/common/rotpk/arm_rotpk_rsa.der readme.rst
+Files: .husky/pre-commit.copyright dco.txt docs/about/maintainers.rst docs/about/release-information.rst docs/change-log.md docs/components/activity-monitors.rst docs/components/cot-binding.rst docs/components/romlib-design.rst docs/design/alt-boot-flows.rst docs/design/index.rst docs/design_documents/drtm_poc.rst docs/design_documents/measured_boot.rst docs/design_documents/measured_boot_poc.rst docs/design_documents/rse.rst docs/getting_started/psci-lib-integration-guide.rst docs/getting_started/rt-svc-writers-guide.rst docs/index.rst docs/perf/performance-monitoring-unit.rst docs/perf/psci-performance-juno.rst docs/plat/index.rst docs/plat/nxp/index.rst docs/plat/stm32mp1.rst docs/porting-guide.rst docs/process/code-review-guidelines.rst docs/process/coding-guidelines.rst docs/process/commit-style.rst docs/process/platform-ports-policy.rst docs/resources/diagrams/PSA-FWU.dia docs/resources/diagrams/int_handling.dia docs/resources/diagrams/measured_boot_design.dia docs/resources/diagrams/reset_code_flow.dia docs/resources/diagrams/rmm_cold_boot_generic.dia docs/resources/diagrams/romlib_design.dia docs/resources/diagrams/romlib_wrapper.dia docs/resources/diagrams/xlat_align.dia docs/threat_model/firmware_threat_model/index.rst docs/threat_model/index.rst plat/arm/board/common/rotpk/arm_rotpk_rsa.der
 Copyright:
  1989 Regents of the University of California.
- 1998 Softweyr LLC.  All rights reserved.
+ 1998 Softweyr LLC.
  2001 David E. O'Brien
  2005 MontaVista Software, Inc.
  2005 Nokia Corporation
  2011 The FreeBSD Foundation
  2012-2021 Roberto E. Vargas Caballero
- 2013-2023 ARM Limited and Contributors. All rights reserved.
- 2013-2023 Arm Limited and Contributors. All rights reserved.
- 2014-2023 Arm Limited. All rights reserved.
- 2014-2016 Freescale Semiconductor, Inc.
- 2014 Linaro Limited. All rights reserved.
- 2014-2023 STMicroelectronics - All Rights Reserved
+ 2013-2024 ARM Limited and Contributors.
+ 2013-2024 Arm Limited and Contributors.
+ 2014 Linaro Limited.
  2014 STMicroelectronics International N.V.
+ 2014-2016 Freescale Semiconductor, Inc.
+ 2014-2023 Arm Limited.
+ 2014-2023 STMicroelectronics
  2015-2021 Broadcom
- 2015-2023 NVIDIA Corporation. All rights reserved.
- 2015-2023 Renesas Electronics Corporation.
- 2015-2023 Renesas Electronics Corporation. All rights
- 2015-2023 Renesas Electronics Corporation. All rights reserved.
- 2016-2020 Marvell International Ltd.
- 2016-2022 Linaro Limited. All rights reserved.
+ 2015-2022 Xilinx Inc.
+ 2015-2023 NVIDIA Corporation.
+ 2015-2024 Arm Limited.
+ 2015-2024 Renesas Electronics Corporation
+ 2015-2024 STMicroelectronics
  2016-2021 Marvell International Ltd.
+ 2016-2022 Linaro Limited.
  2016-2023 NXP
- 2017-2020 Arm Limited and Contributors. All rights reserved.
- 2017-2023 NVIDIA CORPORATION. All rights reserved.
+ 2016-2024 ARM Limited and Contributors.
+ 2016-2024 STMicroelectronics
+ 2017-2020 Arm Limited and Contributors.
  2017-2022 NXP Semiconductors
+ 2017-2022 Xilinx, Inc.
+ 2017-2023 NVIDIA CORPORATION.
  2017-2023 Nuvoton Ltd.
  2017-2023 Nuvoton Technology Corp.
- 2017-2022 Xilinx, Inc. All rights reserved.
  2018 Andre Przywara <osp@andrep.de>
- 2018-2020 Arm Limited and Contributors.
  2018 Icenowy Zheng <icenowy@aosc.io>
  2018-2019 Linaro
- 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
- 2018-2021 The Linux Foundation. All rights reserved.
- 2019-2023 STMicroelectronics - All Rights Reserved
- 2019-2020 Broadcom.
+ 2018-2020 Arm Limited and Contributors.
+ 2018-2021 The Linux Foundation.
+ 2018-2022 Xilinx Inc.
+ 2018-2024 Arm Limited and Contributors.
+ 2018-2024 Arm Limited.
+ 2018-2024 Marvell International Ltd.
+ 2018-2024 STMicroelectronics
+ 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
  2019 Carlo Caione <ccaione@baylibre.com>
- 2019-2023 Intel Corporation. All rights reserved.
- 2019-2022 Linaro Limited
- 2019-2020 Linaro Limited and Contributors.
- 2019-2023 Linaro Limited and Contributors. All rights reserved.
- 2019-2023 MediaTek Inc. All rights reserved.
- 2019-2022 NXP. All rights reserved.
  2019 Remi Pommarel <repk@triplefau.lt>
  2019 Repk repk@triplefau.lt
- 2019-2022 Socionext Inc. All rights reserved.
  2019 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
- 2020-2022 ARM Limited and Contributors. All rights reserved.
- 2020-2023 Google LLC. All rights reserved.
+ 2019-2020 Broadcom.
+ 2019-2020 Linaro Limited and Contributors.
+ 2019-2021 2024 NXP
+ 2019-2022 Linaro Limited
+ 2019-2022 Linaro Limited.
+ 2019-2022 NXP.
+ 2019-2022 Socionext Inc.
+ 2019-2023 Intel Corporation.
+ 2019-2023 Linaro Limited and Contributors.
+ 2019-2023 MediaTek Inc.
+ 2019-2023 STMicroelectronics
+ 2019-2024 Arm Limited and Contributors.
+ 2019-2024 NXP
+ 2019-2024 STMicroelectronics
  2020 Marek Behun, CZ.NIC
- 2020 Marvell Technology Group Ltd. All rights reserved.
- 2020 MediaTek Inc. All rights reserved.
+ 2020 Marvell Technology Group Ltd.
+ 2020 MediaTek Inc.
  2020 NXP.
  2020 Nuvia Inc
  2020-2021 Sartura Ltd.
  2020-2021 Siemens AG
- 2021 Xilinx Inc.
+ 2020-2023 Google LLC
+ 2020-2024 Arm Limited and Contributors.
+ 2020-2024 Arm Limited.
+ 2020-2024 MediaTek Inc.
+ 2020-2024 NXP
  2021 Arm
  2021 Arm Limited
  2021 Globalscale technologies, Inc.
  2021 Marek Behun <marek.behun@nic.cz>
- 2021-2022 ProvenRun S.A.S. All rights reserved.
  2021 Semihalf.
  2021 Sipeed
+ 2021 Xilinx Inc.
+ 2021-2022 ProvenRun S.A.S.
+ 2021-2022 Xilinx Inc.
+ 2021-2023 Renesas Electronics Corporation.
  2021-2023 Stephan Gerhold <stephan@gerhold.net>
- 2022-2023 Advanced Micro Devices, Inc. All rights reserved.
- 2022-2023 Arm Ltd. All rights reserved.
- 2022 Fujitsu Limited and Contributors. All rights reserved.
+ 2021-2024 ARM Limited and Contributors.
+ 2021-2024 ARM Limited.
+ 2021-2024 Arm Limited and Contributors.
+ 2021-2024 Arm Limited.
+ 2021-2024 MediaTek Inc.
+ 2021-2024 NXP
+ 2021-2024 STMicroelectronics
+ 2022 Advanced Micro Devices Inc.
+ 2022 Arm Limited and Contributors.
+ 2022 Fujitsu Limited and Contributors.
  2022 Leica Geosystems AG
  2022 Linaro
- 2022-2023 Linaro.
- 2022 Mediatek Inc. All rights reserved.
- 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ 2022 Mediatek Inc.
+ 2022 Qualcomm Innovation Center, Inc.
  2022 The Hafnium Authors.
- 2023 Advanced Micro Devices. All rights reserved.
- 2023 Arm Limited. All rights reserved
+ 2022 Xilinx Inc.
+ 2022-2023 Advanced Micro Devices, Inc.
+ 2022-2023 Arm Ltd.
+ 2022-2023 Linaro.
+ 2022-2024 ARM Limited and Contributors.
+ 2022-2024 Advanced Micro Devices Inc.
+ 2022-2024 Arm Limited and Contributors.
+ 2022-2024 Arm Limited.
+ 2022-2024 Arm Ltd.
+ 2022-2024 MediaTek Inc.
+ 2022-2024 STMicroelectronics
+ 2023 ARM Limited and Contributors.
+ 2023 Advanced Micro Devices.
+ 2023 Arm Limited.
  2023 Aspeed Technology Inc.
- 2023 Pengutronix. All rights reserved.
+ 2023 MediaTek Inc.
+ 2023 Pengutronix.
+ 2023-2024 Advanced Micro Devices Inc.
+ 2023-2024 Arm Limited and Contributors.
+ 2023-2024 Arm Limited.
+ 2023-2024 Arm Ltd.
+ 2023-2024 Linaro Limited and Contributors.
+ 2023-2024 NXP
+ 2023-2024 STMicroelectronics
+ 2024 ARM Limited and Contributors.
+ 2024 ARM Limited.
+ 2024 Altera Corporation.
+ 2024 Arm Limited and Contributors.
+ 2024 Arm Limited.
+ 2024 Arm Ltd.
+ 2024 Intel Corporation.
+ 2024 Linaro Limited and Contributors.
+ 2024 Mario Bălănică <mariobalanica02@gmail.com>
+ 2024 Mediatek Inc.
+ 2024 NVIDIA Corporation.
+ 2024 NXP
+ 2024 Pengutronix Inc.
+ 2024 Rockchip Inc.
+ 2024 STMicroelectronics
+ 2024 The ChromiumOS Authors.
 License: BSD-3-Clause
 
 Files: fdts/arm_fpga.dts fdts/n1sdp-multi-chip.dts fdts/n1sdp-single-chip.dts fdts/n1sdp.dtsi
 Copyright:
- 2017-2021 ARM Limited and Contributors. All rights reserved.
+ 2017-2021 ARM Limited and Contributors.
  2018-2022 STMicroelectronics
  2019-2022 Arm Limited.
- 2020 Arm Limited. All rights reserved.
+ 2020 Arm Limited.
 License: GPL-2.0 or BSD-3-Clause
 
 Files: fdts/rtsm_ve-motherboard.dtsi
@@ -3456,17 +4078,17 @@ License: GPL-2.0 OR MIT
 Files: fdts/stm32mp151a-prtt1a-fw-config.dts fdts/stm32mp151a-prtt1a.dts fdts/stm32mp157a-avenger96.dts fdts/stm32mp157c-lxa-mc1.dts fdts/stm32mp157c-odyssey-som.dtsi fdts/stm32mp157c-odyssey.dts fdts/stm32mp15xx-osd32.dtsi
 Copyright:
  2017-2022 STMicroelectronics
- 2017-2023 STMicroelectronics - All Rights Reserved
+ 2017-2023 STMicroelectronics
  2019 Arrow Electronics
  2019 Linaro Ltd
  2019-2020 Marek Vasut <marex@denx.de>
- 2019 STMicroelectronics. All Rights Reserved.
+ 2019 STMicroelectronics.
  2020 Ahmad Fatoum, Pengutronix
- 2020 DH electronics - All Rights Reserved
+ 2020 DH electronics
  2021 Grzegorz Szymaszek.
  2022 DH electronics GmbH
  2023 Oleksij Rempel <kernel@pengutronix.de>, Pengutronix
- 2023 Protonic Holland - All Rights Reserved
+ 2023 Protonic Holland
 License: GPL-2.0+ OR BSD-3-Clause
 
 Files: fdts/stm32mp15xx-dhcor-io1v8.dtsi
@@ -3474,7 +4096,7 @@ Copyright:
  2019 Linaro Ltd
  2020 Marek Vasut <marex@denx.de>
  2022 DH electronics GmbH
- 2023 STMicroelectronics - All Rights Reserved
+ 2023 STMicroelectronics
 License: GPL-2.0 OR BSD-3-Clause
 
 Files: include/lib/libfdt/libfdt.h lib/libfdt/fdt_addresses.c lib/libfdt/fdt_overlay.c
-- 
GitLab