summaryrefslogtreecommitdiffstats
path: root/plat/nxp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 17:43:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 17:43:51 +0000
commitbe58c81aff4cd4c0ccf43dbd7998da4a6a08c03b (patch)
tree779c248fb61c83f65d1f0dc867f2053d76b4e03a /plat/nxp
parentInitial commit. (diff)
downloadarm-trusted-firmware-upstream.tar.xz
arm-trusted-firmware-upstream.zip
Adding upstream version 2.10.0+dfsg.upstream/2.10.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plat/nxp')
-rw-r--r--plat/nxp/common/aarch64/bl31_data.S558
-rw-r--r--plat/nxp/common/aarch64/ls_helpers.S220
-rw-r--r--plat/nxp/common/fip_handler/common/plat_def_fip_uuid.h51
-rw-r--r--plat/nxp/common/fip_handler/common/plat_tbbr_img_def.h53
-rw-r--r--plat/nxp/common/fip_handler/common/platform_oid.h16
-rw-r--r--plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk37
-rw-r--r--plat/nxp/common/fip_handler/ddr_fip/ddr_io_storage.c232
-rw-r--r--plat/nxp/common/fip_handler/ddr_fip/ddr_io_storage.h26
-rw-r--r--plat/nxp/common/fip_handler/fuse_fip/fuse.mk99
-rw-r--r--plat/nxp/common/fip_handler/fuse_fip/fuse_io.h27
-rw-r--r--plat/nxp/common/fip_handler/fuse_fip/fuse_io_storage.c223
-rw-r--r--plat/nxp/common/img_loadr/img_loadr.mk21
-rw-r--r--plat/nxp/common/img_loadr/load_img.c83
-rw-r--r--plat/nxp/common/img_loadr/load_img.h14
-rw-r--r--plat/nxp/common/include/default/ch_2/soc_default_base_addr.h70
-rw-r--r--plat/nxp/common/include/default/ch_2/soc_default_helper_macros.h83
-rw-r--r--plat/nxp/common/include/default/ch_3/soc_default_base_addr.h100
-rw-r--r--plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h98
-rw-r--r--plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h88
-rw-r--r--plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h87
-rw-r--r--plat/nxp/common/include/default/plat_default_def.h172
-rw-r--r--plat/nxp/common/nv_storage/nv_storage.mk29
-rw-r--r--plat/nxp/common/nv_storage/plat_nv_storage.c121
-rw-r--r--plat/nxp/common/nv_storage/plat_nv_storage.h40
-rw-r--r--plat/nxp/common/ocram/aarch64/ocram.S71
-rw-r--r--plat/nxp/common/ocram/ocram.h13
-rw-r--r--plat/nxp/common/ocram/ocram.mk14
-rw-r--r--plat/nxp/common/plat_make_helper/plat_build_macros.mk11
-rw-r--r--plat/nxp/common/plat_make_helper/plat_common_def.mk103
-rw-r--r--plat/nxp/common/plat_make_helper/soc_common_def.mk117
-rw-r--r--plat/nxp/common/psci/aarch64/psci_utils.S1155
-rw-r--r--plat/nxp/common/psci/include/plat_psci.h145
-rw-r--r--plat/nxp/common/psci/plat_psci.c475
-rw-r--r--plat/nxp/common/psci/psci.mk35
-rw-r--r--plat/nxp/common/setup/aarch64/ls_bl2_mem_params_desc.c103
-rw-r--r--plat/nxp/common/setup/common.mk105
-rw-r--r--plat/nxp/common/setup/core.mk22
-rw-r--r--plat/nxp/common/setup/include/bl31_data.h61
-rw-r--r--plat/nxp/common/setup/include/ls_interrupt_mgmt.h23
-rw-r--r--plat/nxp/common/setup/include/mmu_def.h34
-rw-r--r--plat/nxp/common/setup/include/plat_common.h152
-rw-r--r--plat/nxp/common/setup/include/plat_macros.S22
-rw-r--r--plat/nxp/common/setup/ls_bl2_el3_setup.c303
-rw-r--r--plat/nxp/common/setup/ls_bl31_setup.c212
-rw-r--r--plat/nxp/common/setup/ls_common.c277
-rw-r--r--plat/nxp/common/setup/ls_err.c55
-rw-r--r--plat/nxp/common/setup/ls_image_load.c33
-rw-r--r--plat/nxp/common/setup/ls_interrupt_mgmt.c66
-rw-r--r--plat/nxp/common/setup/ls_io_storage.c556
-rw-r--r--plat/nxp/common/setup/ls_stack_protector.c22
-rw-r--r--plat/nxp/common/sip_svc/aarch64/sipsvc.S152
-rw-r--r--plat/nxp/common/sip_svc/include/sipsvc.h80
-rw-r--r--plat/nxp/common/sip_svc/sip_svc.c194
-rw-r--r--plat/nxp/common/sip_svc/sipsvc.mk35
-rw-r--r--plat/nxp/common/soc_errata/errata.c59
-rw-r--r--plat/nxp/common/soc_errata/errata.h15
-rw-r--r--plat/nxp/common/soc_errata/errata.mk26
-rw-r--r--plat/nxp/common/soc_errata/errata_a008850.c42
-rw-r--r--plat/nxp/common/soc_errata/errata_a009660.c14
-rw-r--r--plat/nxp/common/soc_errata/errata_a010539.c26
-rw-r--r--plat/nxp/common/soc_errata/errata_a050426.c201
-rw-r--r--plat/nxp/common/soc_errata/errata_list.h28
-rw-r--r--plat/nxp/common/tbbr/csf_tbbr.c81
-rw-r--r--plat/nxp/common/tbbr/nxp_rotpk.S21
-rw-r--r--plat/nxp/common/tbbr/tbbr.mk162
-rw-r--r--plat/nxp/common/tbbr/x509_tbbr.c105
-rw-r--r--plat/nxp/common/warm_reset/plat_warm_reset.c121
-rw-r--r--plat/nxp/common/warm_reset/plat_warm_rst.h28
-rw-r--r--plat/nxp/common/warm_reset/warm_reset.mk20
-rw-r--r--plat/nxp/soc-ls1028a/aarch64/ls1028a.S1387
-rw-r--r--plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S70
-rw-r--r--plat/nxp/soc-ls1028a/include/soc.h149
-rw-r--r--plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c185
-rw-r--r--plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h76
-rw-r--r--plat/nxp/soc-ls1028a/ls1028ardb/platform.c28
-rw-r--r--plat/nxp/soc-ls1028a/ls1028ardb/platform.mk33
-rw-r--r--plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h13
-rw-r--r--plat/nxp/soc-ls1028a/ls1028ardb/policy.h16
-rw-r--r--plat/nxp/soc-ls1028a/soc.c432
-rw-r--r--plat/nxp/soc-ls1028a/soc.def97
-rw-r--r--plat/nxp/soc-ls1028a/soc.mk113
-rw-r--r--plat/nxp/soc-ls1043a/aarch64/ls1043a.S1637
-rw-r--r--plat/nxp/soc-ls1043a/aarch64/ls1043a_helpers.S70
-rw-r--r--plat/nxp/soc-ls1043a/include/ns_access.h175
-rw-r--r--plat/nxp/soc-ls1043a/include/soc.h234
-rw-r--r--plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c163
-rw-r--r--plat/nxp/soc-ls1043a/ls1043ardb/plat_def.h79
-rw-r--r--plat/nxp/soc-ls1043a/ls1043ardb/platform.c28
-rw-r--r--plat/nxp/soc-ls1043a/ls1043ardb/platform.mk40
-rw-r--r--plat/nxp/soc-ls1043a/ls1043ardb/platform_def.h13
-rw-r--r--plat/nxp/soc-ls1043a/ls1043ardb/policy.h16
-rw-r--r--plat/nxp/soc-ls1043a/soc.c439
-rw-r--r--plat/nxp/soc-ls1043a/soc.def107
-rw-r--r--plat/nxp/soc-ls1043a/soc.mk114
-rw-r--r--plat/nxp/soc-ls1046a/aarch64/ls1046a.S937
-rw-r--r--plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S92
-rw-r--r--plat/nxp/soc-ls1046a/include/ns_access.h174
-rw-r--r--plat/nxp/soc-ls1046a/include/soc.h125
-rw-r--r--plat/nxp/soc-ls1046a/ls1046afrwy/ddr_init.c177
-rw-r--r--plat/nxp/soc-ls1046a/ls1046afrwy/plat_def.h79
-rw-r--r--plat/nxp/soc-ls1046a/ls1046afrwy/platform.c28
-rw-r--r--plat/nxp/soc-ls1046a/ls1046afrwy/platform.mk39
-rw-r--r--plat/nxp/soc-ls1046a/ls1046afrwy/platform_def.h13
-rw-r--r--plat/nxp/soc-ls1046a/ls1046afrwy/policy.h16
-rw-r--r--plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c91
-rw-r--r--plat/nxp/soc-ls1046a/ls1046aqds/plat_def.h79
-rw-r--r--plat/nxp/soc-ls1046a/ls1046aqds/platform.c28
-rw-r--r--plat/nxp/soc-ls1046a/ls1046aqds/platform.mk39
-rw-r--r--plat/nxp/soc-ls1046a/ls1046aqds/platform_def.h13
-rw-r--r--plat/nxp/soc-ls1046a/ls1046aqds/policy.h16
-rw-r--r--plat/nxp/soc-ls1046a/ls1046ardb/ddr_init.c267
-rw-r--r--plat/nxp/soc-ls1046a/ls1046ardb/plat_def.h79
-rw-r--r--plat/nxp/soc-ls1046a/ls1046ardb/platform.c28
-rw-r--r--plat/nxp/soc-ls1046a/ls1046ardb/platform.mk38
-rw-r--r--plat/nxp/soc-ls1046a/ls1046ardb/platform_def.h13
-rw-r--r--plat/nxp/soc-ls1046a/ls1046ardb/policy.h16
-rw-r--r--plat/nxp/soc-ls1046a/soc.c399
-rw-r--r--plat/nxp/soc-ls1046a/soc.def107
-rw-r--r--plat/nxp/soc-ls1046a/soc.mk114
-rw-r--r--plat/nxp/soc-ls1088a/aarch64/ls1088a.S1817
-rw-r--r--plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S69
-rw-r--r--plat/nxp/soc-ls1088a/include/soc.h229
-rw-r--r--plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c82
-rw-r--r--plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h81
-rw-r--r--plat/nxp/soc-ls1088a/ls1088aqds/platform.c28
-rw-r--r--plat/nxp/soc-ls1088a/ls1088aqds/platform.mk31
-rw-r--r--plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h13
-rw-r--r--plat/nxp/soc-ls1088a/ls1088aqds/policy.h16
-rw-r--r--plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c84
-rw-r--r--plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h80
-rw-r--r--plat/nxp/soc-ls1088a/ls1088ardb/platform.c28
-rw-r--r--plat/nxp/soc-ls1088a/ls1088ardb/platform.mk30
-rw-r--r--plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h13
-rw-r--r--plat/nxp/soc-ls1088a/ls1088ardb/policy.h15
-rw-r--r--plat/nxp/soc-ls1088a/soc.c401
-rw-r--r--plat/nxp/soc-ls1088a/soc.def86
-rw-r--r--plat/nxp/soc-ls1088a/soc.mk110
-rw-r--r--plat/nxp/soc-lx2160a/aarch64/lx2160a.S1816
-rw-r--r--plat/nxp/soc-lx2160a/aarch64/lx2160a_helpers.S77
-rw-r--r--plat/nxp/soc-lx2160a/aarch64/lx2160a_warm_rst.S229
-rw-r--r--plat/nxp/soc-lx2160a/ddr_fip.mk97
-rw-r--r--plat/nxp/soc-lx2160a/ddr_sb.mk43
-rw-r--r--plat/nxp/soc-lx2160a/ddr_tbbr.mk95
-rw-r--r--plat/nxp/soc-lx2160a/include/soc.h164
-rw-r--r--plat/nxp/soc-lx2160a/lx2160aqds/ddr_init.c355
-rw-r--r--plat/nxp/soc-lx2160a/lx2160aqds/plat_def.h105
-rw-r--r--plat/nxp/soc-lx2160a/lx2160aqds/platform.c29
-rw-r--r--plat/nxp/soc-lx2160a/lx2160aqds/platform.mk51
-rw-r--r--plat/nxp/soc-lx2160a/lx2160aqds/platform_def.h14
-rw-r--r--plat/nxp/soc-lx2160a/lx2160aqds/policy.h38
-rw-r--r--plat/nxp/soc-lx2160a/lx2160ardb/ddr_init.c212
-rw-r--r--plat/nxp/soc-lx2160a/lx2160ardb/plat_def.h105
-rw-r--r--plat/nxp/soc-lx2160a/lx2160ardb/platform.c29
-rw-r--r--plat/nxp/soc-lx2160a/lx2160ardb/platform.mk51
-rw-r--r--plat/nxp/soc-lx2160a/lx2160ardb/platform_def.h14
-rw-r--r--plat/nxp/soc-lx2160a/lx2160ardb/policy.h38
-rw-r--r--plat/nxp/soc-lx2160a/lx2162aqds/ddr_init.c354
-rw-r--r--plat/nxp/soc-lx2160a/lx2162aqds/plat_def.h105
-rw-r--r--plat/nxp/soc-lx2160a/lx2162aqds/platform.c29
-rw-r--r--plat/nxp/soc-lx2160a/lx2162aqds/platform.mk52
-rw-r--r--plat/nxp/soc-lx2160a/lx2162aqds/platform_def.h14
-rw-r--r--plat/nxp/soc-lx2160a/lx2162aqds/policy.h38
-rw-r--r--plat/nxp/soc-lx2160a/soc.c542
-rw-r--r--plat/nxp/soc-lx2160a/soc.def119
-rw-r--r--plat/nxp/soc-lx2160a/soc.mk174
165 files changed, 25066 insertions, 0 deletions
diff --git a/plat/nxp/common/aarch64/bl31_data.S b/plat/nxp/common/aarch64/bl31_data.S
new file mode 100644
index 0000000..cc91540
--- /dev/null
+++ b/plat/nxp/common/aarch64/bl31_data.S
@@ -0,0 +1,558 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <asm_macros.S>
+
+#include "bl31_data.h"
+#include "plat_psci.h"
+#include "platform_def.h"
+
+.global _getCoreData
+.global _setCoreData
+.global _getCoreState
+.global _setCoreState
+.global _init_global_data
+.global _get_global_data
+.global _set_global_data
+.global _initialize_psci
+.global _init_task_flags
+.global _set_task1_start
+.global _set_task1_done
+
+
+/* Function returns the specified data field value from the specified cpu
+ * core data area
+ * in: x0 = core mask lsb
+ * x1 = data field name/offset
+ * out: x0 = data value
+ * uses x0, x1, x2, [x13, x14, x15]
+ */
+func _getCoreData
+
+ /* generate a 0-based core number from the input mask */
+ clz x2, x0
+ mov x0, #63
+ sub x0, x0, x2
+
+ /* x0 = core number (0-based) */
+ /* x1 = field offset */
+
+ /* determine if this is bootcore or secondary core */
+ cbnz x0, 1f
+
+ /* get base address for bootcore data */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, x1
+ b 2f
+
+1: /* get base address for secondary core data */
+
+ /* x0 = core number (0-based) */
+ /* x1 = field offset */
+
+ /* generate number of regions to offset */
+ mov x2, #SEC_REGION_SIZE
+ mul x2, x2, x0
+
+ /* x1 = field offset */
+ /* x2 = region offset */
+
+ /* generate the total offset to data element */
+ sub x1, x2, x1
+
+ /* x1 = total offset to data element */
+
+ /* get the base address */
+ ldr x2, =SECONDARY_TOP
+
+ /* apply offset to base addr */
+ sub x2, x2, x1
+2:
+ /* x2 = data element address */
+
+ dc ivac, x2
+ dsb sy
+ isb
+ /* read data */
+ ldr x0, [x2]
+
+ ret
+endfunc _getCoreData
+
+
+/* Function returns the SoC-specific state of the specified cpu
+ * in: x0 = core mask lsb
+ * out: x0 = data value
+ * uses x0, x1, x2, [x13, x14, x15]
+ */
+func _getCoreState
+
+ mov x1, #CORE_STATE_DATA
+
+ /* generate a 0-based core number from the input mask */
+ clz x2, x0
+ mov x0, #63
+ sub x0, x0, x2
+
+ /* x0 = core number (0-based) */
+ /* x1 = field offset */
+
+ /* determine if this is bootcore or secondary core */
+ cbnz x0, 1f
+
+ /* get base address for bootcore data */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, x1
+ b 2f
+
+1: /* get base address for secondary core data */
+
+ /* x0 = core number (0-based) */
+ /* x1 = field offset */
+
+ /* generate number of regions to offset */
+ mov x2, #SEC_REGION_SIZE
+ mul x2, x2, x0
+
+ /* x1 = field offset */
+ /* x2 = region offset */
+
+ /* generate the total offset to data element */
+ sub x1, x2, x1
+
+ /* x1 = total offset to data element */
+
+ /* get the base address */
+ ldr x2, =SECONDARY_TOP
+
+ /* apply offset to base addr */
+ sub x2, x2, x1
+2:
+ /* x2 = data element address */
+
+ dc ivac, x2
+ dsb sy
+ isb
+
+ /* read data */
+ ldr x0, [x2]
+
+ ret
+endfunc _getCoreState
+
+
+/* Function writes the specified data value into the specified cpu
+ * core data area
+ * in: x0 = core mask lsb
+ * x1 = data field offset
+ * x2 = data value to write/store
+ * out: none
+ * uses x0, x1, x2, x3, [x13, x14, x15]
+ */
+func _setCoreData
+ /* x0 = core mask */
+ /* x1 = field offset */
+ /* x2 = data value */
+
+ clz x3, x0
+ mov x0, #63
+ sub x0, x0, x3
+
+ /* x0 = core number (0-based) */
+ /* x1 = field offset */
+ /* x2 = data value */
+
+ /* determine if this is bootcore or secondary core */
+ cbnz x0, 1f
+
+ /* get base address for bootcore data */
+ ldr x3, =BC_PSCI_BASE
+ add x3, x3, x1
+ b 2f
+
+1: /* get base address for secondary core data */
+
+ /* x0 = core number (0-based) */
+ /* x1 = field offset */
+ /* x2 = data value */
+
+ /* generate number of regions to offset */
+ mov x3, #SEC_REGION_SIZE
+ mul x3, x3, x0
+
+ /* x1 = field offset */
+ /* x2 = data value */
+ /* x3 = region offset */
+
+ /* generate the total offset to data element */
+ sub x1, x3, x1
+
+ /* x1 = total offset to data element */
+ /* x2 = data value */
+
+ ldr x3, =SECONDARY_TOP
+
+ /* apply offset to base addr */
+ sub x3, x3, x1
+
+2:
+ /* x2 = data value */
+ /* x3 = data element address */
+
+ str x2, [x3]
+
+ dc cvac, x3
+ dsb sy
+ isb
+ ret
+endfunc _setCoreData
+
+
+/* Function stores the specified core state
+ * in: x0 = core mask lsb
+ * x1 = data value to write/store
+ * out: none
+ * uses x0, x1, x2, x3, [x13, x14, x15]
+ */
+func _setCoreState
+ mov x2, #CORE_STATE_DATA
+
+ clz x3, x0
+ mov x0, #63
+ sub x0, x0, x3
+
+ /* x0 = core number (0-based) */
+ /* x1 = data value */
+ /* x2 = field offset */
+
+ /* determine if this is bootcore or secondary core */
+ cbnz x0, 1f
+
+ /* get base address for bootcore data */
+ ldr x3, =BC_PSCI_BASE
+ add x3, x3, x2
+ b 2f
+
+1: /* get base address for secondary core data */
+
+ /* x0 = core number (0-based) */
+ /* x1 = data value */
+ /* x2 = field offset */
+
+ /* generate number of regions to offset */
+ mov x3, #SEC_REGION_SIZE
+ mul x3, x3, x0
+
+ /* x1 = data value */
+ /* x2 = field offset */
+ /* x3 = region offset */
+
+ /* generate the total offset to data element */
+ sub x2, x3, x2
+
+ /* x1 = data value */
+ /* x2 = total offset to data element */
+
+ ldr x3, =SECONDARY_TOP
+
+ /* apply offset to base addr */
+ sub x3, x3, x2
+
+2:
+ /* x1 = data value */
+ /* x3 = data element address */
+
+ str x1, [x3]
+
+ dc civac, x3
+ dsb sy
+ isb
+ ret
+endfunc _setCoreState
+
+
+/* Function sets the task1 start
+ * in: w0 = value to set flag to
+ * out: none
+ * uses x0, x1
+ */
+func _set_task1_start
+
+ ldr x1, =SMC_TASK1_BASE
+
+ add x1, x1, #TSK_START_OFFSET
+ str w0, [x1]
+ dc cvac, x1
+ dsb sy
+ isb
+ ret
+endfunc _set_task1_start
+
+
+/* Function sets the state of the task 1 done flag
+ * in: w0 = value to set flag to
+ * out: none
+ * uses x0, x1
+ */
+func _set_task1_done
+
+ ldr x1, =SMC_TASK1_BASE
+
+ add x1, x1, #TSK_DONE_OFFSET
+ str w0, [x1]
+ dc cvac, x1
+ dsb sy
+ isb
+ ret
+endfunc _set_task1_done
+
+
+/* Function initializes the smc global data entries
+ * Note: the constant LAST_SMC_GLBL_OFFSET must reference the last entry in the
+ * smc global region
+ * in: none
+ * out: none
+ * uses x0, x1, x2
+ */
+func _init_global_data
+
+ ldr x1, =SMC_GLBL_BASE
+
+ /* x1 = SMC_GLBL_BASE */
+
+ mov x2, #LAST_SMC_GLBL_OFFSET
+ add x2, x2, x1
+1:
+ str xzr, [x1]
+ dc cvac, x1
+ cmp x2, x1
+ add x1, x1, #8
+ b.hi 1b
+
+ dsb sy
+ isb
+ ret
+endfunc _init_global_data
+
+
+/* Function gets the value of the specified global data element
+ * in: x0 = offset of data element
+ * out: x0 = requested data element
+ * uses x0, x1
+ */
+func _get_global_data
+
+ ldr x1, =SMC_GLBL_BASE
+ add x1, x1, x0
+ dc ivac, x1
+ isb
+
+ ldr x0, [x1]
+ ret
+endfunc _get_global_data
+
+
+/* Function sets the value of the specified global data element
+ * in: x0 = offset of data element
+ * x1 = value to write
+ * out: none
+ * uses x0, x1, x2
+ */
+func _set_global_data
+
+ ldr x2, =SMC_GLBL_BASE
+ add x0, x0, x2
+ str x1, [x0]
+ dc cvac, x0
+
+ dsb sy
+ isb
+ ret
+endfunc _set_global_data
+
+
+/* Function initializes the core data areas
+ * only executed by the boot core
+ * in: none
+ * out: none
+ * uses: x0, x1, x2, x3, x4, x5, x6, x7, [x13, x14, x15]
+ */
+func _initialize_psci
+ mov x7, x30
+
+ /* initialize the bootcore psci data */
+ ldr x5, =BC_PSCI_BASE
+ mov x6, #CORE_RELEASED
+
+ str x6, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5], #8
+ dc cvac, x5
+ str xzr, [x5]
+ dc cvac, x5
+ dsb sy
+ isb
+
+ /* see if we have any secondary cores */
+ mov x4, #PLATFORM_CORE_COUNT
+ sub x4, x4, #1
+ cbz x4, 3f
+
+ /* initialize the secondary core's psci data */
+ ldr x5, =SECONDARY_TOP
+ /* core mask lsb for core 1 */
+ mov x3, #2
+ sub x5, x5, #SEC_REGION_SIZE
+
+ /* x3 = core1 mask lsb */
+ /* x4 = number of secondary cores */
+ /* x5 = core1 psci data base address */
+2:
+ /* set core state in x6 */
+ mov x0, x3
+ mov x6, #CORE_IN_RESET
+ bl _soc_ck_disabled
+ cbz x0, 1f
+ mov x6, #CORE_DISABLED
+1:
+ add x2, x5, #CORE_STATE_DATA
+ str x6, [x2]
+ dc cvac, x2
+ add x2, x5, #SPSR_EL3_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #CNTXT_ID_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #START_ADDR_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #LINK_REG_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #GICC_CTLR_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #ABORT_FLAG_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #SCTLR_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #CPUECTLR_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #AUX_01_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #AUX_02_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #AUX_03_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #AUX_04_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #AUX_05_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #SCR_EL3_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ add x2, x5, #HCR_EL2_DATA
+ str xzr, [x2]
+ dc cvac, x2
+ dsb sy
+ isb
+
+ sub x4, x4, #1
+ cbz x4, 3f
+
+ /* generate next core mask */
+ lsl x3, x3, #1
+
+ /* decrement base address to next data area */
+ sub x5, x5, #SEC_REGION_SIZE
+ b 2b
+3:
+ mov x30, x7
+ ret
+endfunc _initialize_psci
+
+
+/* Function initializes the soc init task flags
+ * in: none
+ * out: none
+ * uses x0, x1, [x13, x14, x15]
+ */
+func _init_task_flags
+
+ /* get the base address of the first task structure */
+ ldr x0, =SMC_TASK1_BASE
+
+ /* x0 = task1 base address */
+
+ str wzr, [x0, #TSK_START_OFFSET]
+ str wzr, [x0, #TSK_DONE_OFFSET]
+ str wzr, [x0, #TSK_CORE_OFFSET]
+ dc cvac, x0
+
+ /* move to task2 structure */
+ add x0, x0, #SMC_TASK_OFFSET
+
+ str wzr, [x0, #TSK_START_OFFSET]
+ str wzr, [x0, #TSK_DONE_OFFSET]
+ str wzr, [x0, #TSK_CORE_OFFSET]
+ dc cvac, x0
+
+ /* move to task3 structure */
+ add x0, x0, #SMC_TASK_OFFSET
+
+ str wzr, [x0, #TSK_START_OFFSET]
+ str wzr, [x0, #TSK_DONE_OFFSET]
+ str wzr, [x0, #TSK_CORE_OFFSET]
+ dc cvac, x0
+
+ /* move to task4 structure */
+ add x0, x0, #SMC_TASK_OFFSET
+
+ str wzr, [x0, #TSK_START_OFFSET]
+ str wzr, [x0, #TSK_DONE_OFFSET]
+ str wzr, [x0, #TSK_CORE_OFFSET]
+ dc cvac, x0
+
+ dsb sy
+ isb
+ ret
+endfunc _init_task_flags
diff --git a/plat/nxp/common/aarch64/ls_helpers.S b/plat/nxp/common/aarch64/ls_helpers.S
new file mode 100644
index 0000000..311dce1
--- /dev/null
+++ b/plat/nxp/common/aarch64/ls_helpers.S
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <asm_macros.S>
+#include <cortex_a53.h>
+#include <drivers/console.h>
+#include <lib/cpus/aarch64/cortex_a72.h>
+
+#include <platform_def.h>
+
+
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+ .globl plat_core_pos
+ .globl plat_my_core_pos
+ .globl plat_core_mask
+ .globl plat_my_core_mask
+ .globl plat_core_pos_by_mpidr
+ .globl _disable_ldstr_pfetch_A53
+ .globl _disable_ldstr_pfetch_A72
+ .global _set_smmu_pagesz_64
+
+ /* int plat_crash_console_init(void)
+ * Function to initialize the crash console
+ * without a C Runtime to print crash report.
+ * Clobber list : x0 - x4
+ */
+
+ /* int plat_crash_console_init(void)
+ * Use normal console by default. Switch it to crash
+ * mode so serial consoles become active again.
+ * NOTE: This default implementation will only work for
+ * crashes that occur after a normal console (marked
+ * valid for the crash state) has been registered with
+ * the console framework. To debug crashes that occur
+ * earlier, the platform has to override these functions
+ * with an implementation that initializes a console
+ * driver with hardcoded parameters. See
+ * docs/porting-guide.rst for more information.
+ */
+func plat_crash_console_init
+ mov x3, x30
+ mov x0, #CONSOLE_FLAG_CRASH
+ bl console_switch_state
+ mov x0, #1
+ ret x3
+endfunc plat_crash_console_init
+
+ /* void plat_crash_console_putc(int character)
+ * Output through the normal console by default.
+ */
+func plat_crash_console_putc
+ b console_putc
+endfunc plat_crash_console_putc
+
+ /* void plat_crash_console_flush(void)
+ * Flush normal console by default.
+ */
+func plat_crash_console_flush
+ b console_flush
+endfunc plat_crash_console_flush
+
+/* 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.
+ */
+func plat_core_pos_by_mpidr
+
+ b plat_core_pos
+
+endfunc plat_core_pos_by_mpidr
+
+#if (SYMMETRICAL_CLUSTERS)
+/* unsigned int plat_my_core_mask(void)
+ * generate a mask bit for this core
+ */
+func plat_my_core_mask
+ mrs x0, MPIDR_EL1
+ b plat_core_mask
+endfunc plat_my_core_mask
+
+/* unsigned int plat_core_mask(u_register_t mpidr)
+ * generate a lsb-based mask bit for the core specified by mpidr in x0.
+ *
+ * SoC core = ((cluster * cpu_per_cluster) + core)
+ * mask = (1 << SoC core)
+ */
+func plat_core_mask
+ mov w1, wzr
+ mov w2, wzr
+
+ /* extract cluster */
+ bfxil w1, w0, #8, #8
+ /* extract cpu # */
+ bfxil w2, w0, #0, #8
+
+ mov w0, wzr
+
+ /* error checking */
+ cmp w1, #NUMBER_OF_CLUSTERS
+ b.ge 1f
+ cmp w2, #CORES_PER_CLUSTER
+ b.ge 1f
+
+ mov w0, #CORES_PER_CLUSTER
+ mul w1, w1, w0
+ add w1, w1, w2
+ mov w2, #0x1
+ lsl w0, w2, w1
+1:
+ ret
+endfunc plat_core_mask
+
+/*
+ * unsigned int plat_my_core_pos(void)
+ * generate a linear core number for this core
+ */
+func plat_my_core_pos
+ mrs x0, MPIDR_EL1
+ b plat_core_pos
+endfunc plat_my_core_pos
+
+/*
+ * unsigned int plat_core_pos(u_register_t mpidr)
+ * Generate a linear core number for the core specified by mpidr.
+ *
+ * SoC core = ((cluster * cpu_per_cluster) + core)
+ * Returns -1 if mpidr invalid
+ */
+func plat_core_pos
+ mov w1, wzr
+ mov w2, wzr
+ bfxil w1, w0, #8, #8 /* extract cluster */
+ bfxil w2, w0, #0, #8 /* extract cpu # */
+
+ mov w0, #-1
+
+ /* error checking */
+ cmp w1, #NUMBER_OF_CLUSTERS
+ b.ge 1f
+ cmp w2, #CORES_PER_CLUSTER
+ b.ge 1f
+
+ mov w0, #CORES_PER_CLUSTER
+ mul w1, w1, w0
+ add w0, w1, w2
+1:
+ ret
+endfunc plat_core_pos
+
+#endif
+
+/* this function disables the load-store prefetch of the calling core
+ * Note: this function is for A53 cores ONLY
+ * in: none
+ * out: none
+ * uses x0
+ */
+func _disable_ldstr_pfetch_A53
+ mrs x0, CORTEX_A53_CPUACTLR_EL1
+ tst x0, #CORTEX_A53_CPUACTLR_EL1_L1PCTL
+ b.ne 1f
+ b 2f
+
+.align 6
+1:
+ dsb sy
+ isb
+ bic x0, x0, #CORTEX_A53_CPUACTLR_EL1_L1PCTL
+ msr CORTEX_A53_CPUACTLR_EL1, x0
+ isb
+
+2:
+ ret
+endfunc _disable_ldstr_pfetch_A53
+
+
+/* this function disables the load-store prefetch of the calling core
+ * Note: this function is for A72 cores ONLY
+ * in: none
+ * out: none
+ * uses x0
+ */
+func _disable_ldstr_pfetch_A72
+
+ mrs x0, CORTEX_A72_CPUACTLR_EL1
+ tst x0, #CORTEX_A72_CPUACTLR_EL1_DISABLE_L1_DCACHE_HW_PFTCH
+ b.eq 1f
+ b 2f
+
+.align 6
+1:
+ dsb sy
+ isb
+ orr x0, x0, #CORTEX_A72_CPUACTLR_EL1_DISABLE_L1_DCACHE_HW_PFTCH
+ msr CORTEX_A72_CPUACTLR_EL1, x0
+ isb
+
+2:
+ ret
+endfunc _disable_ldstr_pfetch_A72
+
+/*
+ * Function sets the SACR pagesize to 64k
+ */
+func _set_smmu_pagesz_64
+
+ ldr x1, =NXP_SMMU_ADDR
+ ldr w0, [x1, #0x10]
+ orr w0, w0, #1 << 16 /* setting to 64K page */
+ str w0, [x1, #0x10]
+
+ ret
+endfunc _set_smmu_pagesz_64
diff --git a/plat/nxp/common/fip_handler/common/plat_def_fip_uuid.h b/plat/nxp/common/fip_handler/common/plat_def_fip_uuid.h
new file mode 100644
index 0000000..65aef14
--- /dev/null
+++ b/plat/nxp/common/fip_handler/common/plat_def_fip_uuid.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_DEF_FIP_UUID_H
+#define PLAT_DEF_FIP_UUID_H
+
+/* PHy images configs */
+#define UUID_DDR_IMEM_UDIMM_1D \
+ {{0x5b, 0xdb, 0xe3, 0x83}, {0xd1, 0x9f}, {0xc7, 0x06}, 0xd4, 0x91, {0x76, 0x4f, 0x9d, 0x23, 0x2d, 0x2d} }
+
+#define UUID_DDR_IMEM_UDIMM_2D \
+ {{0xfa, 0x0e, 0xeb, 0x21}, {0xe0, 0x7f}, {0x8e, 0x65}, 0x95, 0xd8, {0x2b, 0x94, 0xf6, 0xb8, 0x28, 0x0a} }
+
+#define UUID_DDR_DMEM_UDIMM_1D \
+ {{0xba, 0xbb, 0xfd, 0x7e}, {0x5b, 0xf0}, {0xeb, 0xb8}, 0xeb, 0x71, {0xb1, 0x85, 0x07, 0xdd, 0xe1, 0x32} }
+
+#define UUID_DDR_DMEM_UDIMM_2D \
+ {{0xb6, 0x99, 0x61, 0xda}, {0xf9, 0x92}, {0x4b, 0x9e}, 0x0c, 0x49, {0x74, 0xa5, 0xe0, 0x5c, 0xbe, 0xc3} }
+
+#define UUID_DDR_IMEM_RDIMM_1D \
+ {{0x42, 0x33, 0x66, 0x52}, {0xd8, 0x94}, {0x4d, 0xc1}, 0x91, 0xcc, {0x26, 0x8f, 0x7a, 0x67, 0xf1, 0xa2} }
+
+#define UUID_DDR_IMEM_RDIMM_2D \
+ {{0x2e, 0x95, 0x73, 0xba}, {0xb5, 0xca}, {0x7c, 0xc7}, 0xef, 0xc9, {0x5e, 0xb0, 0x42, 0xec, 0x08, 0x7a} }
+
+#define UUID_DDR_DMEM_RDIMM_1D \
+ {{0x1c, 0x51, 0x17, 0xed}, {0x30, 0x0d}, {0xae, 0xba}, 0x87, 0x03, {0x1f, 0x37, 0x85, 0xec, 0xe1, 0x44} }
+
+#define UUID_DDR_DMEM_RDIMM_2D \
+ {{0xe9, 0x0a, 0x90, 0x78}, {0x11, 0xd6}, {0x8b, 0xba}, 0x24, 0x35, {0xec, 0x10, 0x75, 0x4f, 0x56, 0xa5} }
+
+#define UUID_DDR_FW_KEY_CERT \
+ {{0xac, 0x4b, 0xb8, 0x9c}, {0x8f, 0xb9}, {0x11, 0xea}, 0xbc, 0x55, {0x02, 0x42, 0xac, 0x12, 0x00, 0x03} }
+
+#define UUID_DDR_UDIMM_FW_CONTENT_CERT \
+ {{0x2c, 0x7f, 0x52, 0x54}, {0x70, 0x92}, {0x48, 0x40}, 0x8c, 0x34, {0x87, 0x4b, 0xbf, 0xbd, 0x9d, 0x89} }
+
+#define UUID_DDR_RDIMM_FW_CONTENT_CERT \
+ {{0x94, 0xc3, 0x63, 0x30}, {0x7c, 0xf7}, {0x4f, 0x1d}, 0xaa, 0xcd, {0xb5, 0x80, 0xb2, 0xc2, 0x40, 0xa5} }
+
+#define UUID_FUSE_PROV \
+ {{0xec, 0x45, 0x90, 0x42}, {0x30, 0x0d}, {0xae, 0xba}, 0x87, 0x03, {0x1f, 0x37, 0x85, 0xec, 0xe1, 0x44} }
+
+#define UUID_FUSE_UP \
+ {{0x89, 0x46, 0xef, 0x78}, {0x11, 0xd6}, {0x8b, 0xba}, 0x24, 0x35, {0xec, 0x10, 0x75, 0x4f, 0x56, 0xa5} }
+
+#endif /* PLAT_DEF_FIP_UUID_H */
diff --git a/plat/nxp/common/fip_handler/common/plat_tbbr_img_def.h b/plat/nxp/common/fip_handler/common/plat_tbbr_img_def.h
new file mode 100644
index 0000000..9856f70
--- /dev/null
+++ b/plat/nxp/common/fip_handler/common/plat_tbbr_img_def.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef NXP_IMG_DEF_H
+#define NXP_IMG_DEF_H
+
+#include <export/common/tbbr/tbbr_img_def_exp.h>
+
+#ifdef CONFIG_DDR_FIP_IMAGE
+/* DDR FIP IMAGE ID */
+#define DDR_FIP_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS
+
+#define DDR_IMEM_UDIMM_1D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 1
+#define DDR_IMEM_UDIMM_2D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 2
+
+#define DDR_DMEM_UDIMM_1D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 3
+#define DDR_DMEM_UDIMM_2D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 4
+
+#define DDR_IMEM_RDIMM_1D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 5
+#define DDR_IMEM_RDIMM_2D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 6
+
+#define DDR_DMEM_RDIMM_1D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 7
+#define DDR_DMEM_RDIMM_2D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 8
+
+#define DDR_FW_KEY_CERT_ID MAX_IMG_IDS_WITH_SPMDS + 9
+#define DDR_UDIMM_FW_CONTENT_CERT_ID MAX_IMG_IDS_WITH_SPMDS + 10
+#define DDR_RDIMM_FW_CONTENT_CERT_ID MAX_IMG_IDS_WITH_SPMDS + 11
+/* Max Images */
+#define MAX_IMG_WITH_DDR_IDS MAX_IMG_IDS_WITH_SPMDS + 12
+#else
+#define MAX_IMG_WITH_DDR_IDS MAX_IMG_IDS_WITH_SPMDS
+#endif
+
+#ifdef POLICY_FUSE_PROVISION
+/* FUSE FIP IMAGE ID */
+#define FUSE_FIP_IMAGE_ID MAX_IMG_WITH_DDR_IDS
+
+#define FUSE_PROV_IMAGE_ID MAX_IMG_WITH_DDR_IDS + 1
+
+#define FUSE_UP_IMAGE_ID MAX_IMG_WITH_DDR_IDS + 2
+
+#define MAX_IMG_WITH_FIMG_IDS MAX_IMG_WITH_DDR_IDS + 3
+#else
+#define MAX_IMG_WITH_FIMG_IDS MAX_IMG_WITH_DDR_IDS
+#endif
+
+#define MAX_NUMBER_IDS MAX_IMG_WITH_FIMG_IDS
+
+#endif /* NXP_IMG_DEF_H */
diff --git a/plat/nxp/common/fip_handler/common/platform_oid.h b/plat/nxp/common/fip_handler/common/platform_oid.h
new file mode 100644
index 0000000..bbd6041
--- /dev/null
+++ b/plat/nxp/common/fip_handler/common/platform_oid.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#define DDR_FW_CONTENT_CERT_PK_OID "1.3.6.1.4.1.4128.2200.1"
+#define DDR_IMEM_UDIMM_1D_HASH_OID "1.3.6.1.4.1.4128.2200.2"
+#define DDR_IMEM_UDIMM_2D_HASH_OID "1.3.6.1.4.1.4128.2200.3"
+#define DDR_DMEM_UDIMM_1D_HASH_OID "1.3.6.1.4.1.4128.2200.4"
+#define DDR_DMEM_UDIMM_2D_HASH_OID "1.3.6.1.4.1.4128.2200.5"
+#define DDR_IMEM_RDIMM_1D_HASH_OID "1.3.6.1.4.1.4128.2200.6"
+#define DDR_IMEM_RDIMM_2D_HASH_OID "1.3.6.1.4.1.4128.2200.7"
+#define DDR_DMEM_RDIMM_1D_HASH_OID "1.3.6.1.4.1.4128.2200.8"
+#define DDR_DMEM_RDIMM_2D_HASH_OID "1.3.6.1.4.1.4128.2200.9"
diff --git a/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk b/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk
new file mode 100644
index 0000000..36c07b7
--- /dev/null
+++ b/plat/nxp/common/fip_handler/ddr_fip/ddr_fip_io.mk
@@ -0,0 +1,37 @@
+#
+# Copyright 2020 NXP
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-----------------------------------------------------------------------------
+ifeq (${DDR_FIP_IO_STORAGE_ADDED},)
+
+$(eval $(call add_define, PLAT_DEF_FIP_UUID))
+$(eval $(call add_define, PLAT_TBBR_IMG_DEF))
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+
+DDR_FIP_IO_STORAGE_ADDED := 1
+$(eval $(call add_define,CONFIG_DDR_FIP_IMAGE))
+
+FIP_HANDLER_PATH := ${PLAT_COMMON_PATH}/fip_handler
+FIP_HANDLER_COMMON_PATH := ${FIP_HANDLER_PATH}/common
+DDR_FIP_IO_STORAGE_PATH := ${FIP_HANDLER_PATH}/ddr_fip
+
+PLAT_INCLUDES += -I${FIP_HANDLER_COMMON_PATH}\
+ -I$(DDR_FIP_IO_STORAGE_PATH)
+
+DDR_FIP_IO_SOURCES += $(DDR_FIP_IO_STORAGE_PATH)/ddr_io_storage.c
+
+ifeq (${BL_COMM_DDR_FIP_IO_NEEDED},yes)
+BL_COMMON_SOURCES += ${DDR_FIP_IO_SOURCES}
+else
+ifeq (${BL2_DDR_FIP_IO_NEEDED},yes)
+BL2_SOURCES += ${DDR_FIP_IO_SOURCES}
+endif
+ifeq (${BL31_DDR_FIP_IO_NEEDED},yes)
+BL31_SOURCES += ${DDR_FIP_IO_SOURCES}
+endif
+endif
+endif
+#------------------------------------------------
diff --git a/plat/nxp/common/fip_handler/ddr_fip/ddr_io_storage.c b/plat/nxp/common/fip_handler/ddr_fip/ddr_io_storage.c
new file mode 100644
index 0000000..fc3c4a4
--- /dev/null
+++ b/plat/nxp/common/fip_handler/ddr_fip/ddr_io_storage.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <io_block.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <lib/utils.h>
+#include <tools_share/firmware_image_package.h>
+#include "ddr_io_storage.h"
+#include "plat_common.h"
+#include "platform_def.h"
+
+
+/* TBD - Move these defined to the platform_def.h file.
+ * Keeping them for reference here
+ */
+extern uintptr_t backend_dev_handle;
+
+static uint32_t ddr_fip;
+
+static uintptr_t ddr_fip_dev_handle;
+
+static io_block_spec_t ddr_fip_block_spec = {
+ .offset = PLAT_DDR_FIP_OFFSET,
+ .length = PLAT_DDR_FIP_MAX_SIZE
+};
+
+static const io_uuid_spec_t ddr_imem_udimm_1d_uuid_spec = {
+ .uuid = UUID_DDR_IMEM_UDIMM_1D,
+};
+
+static const io_uuid_spec_t ddr_imem_udimm_2d_uuid_spec = {
+ .uuid = UUID_DDR_IMEM_UDIMM_2D,
+};
+
+static const io_uuid_spec_t ddr_dmem_udimm_1d_uuid_spec = {
+ .uuid = UUID_DDR_DMEM_UDIMM_1D,
+};
+
+static const io_uuid_spec_t ddr_dmem_udimm_2d_uuid_spec = {
+ .uuid = UUID_DDR_DMEM_UDIMM_2D,
+};
+
+static const io_uuid_spec_t ddr_imem_rdimm_1d_uuid_spec = {
+ .uuid = UUID_DDR_IMEM_RDIMM_1D,
+};
+
+static const io_uuid_spec_t ddr_imem_rdimm_2d_uuid_spec = {
+ .uuid = UUID_DDR_IMEM_RDIMM_2D,
+};
+
+static const io_uuid_spec_t ddr_dmem_rdimm_1d_uuid_spec = {
+ .uuid = UUID_DDR_DMEM_RDIMM_1D,
+};
+
+static const io_uuid_spec_t ddr_dmem_rdimm_2d_uuid_spec = {
+ .uuid = UUID_DDR_DMEM_RDIMM_2D,
+};
+
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t ddr_fw_key_cert_uuid_spec = {
+ .uuid = UUID_DDR_FW_KEY_CERT,
+};
+static const io_uuid_spec_t ddr_udimm_fw_cert_uuid_spec = {
+ .uuid = UUID_DDR_UDIMM_FW_CONTENT_CERT,
+};
+static const io_uuid_spec_t ddr_rdimm_fw_cert_uuid_spec = {
+ .uuid = UUID_DDR_RDIMM_FW_CONTENT_CERT,
+};
+#endif
+
+static int open_ddr_fip(const uintptr_t spec);
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+/* By default, ARM platforms load images from the FIP */
+static const struct plat_io_policy ddr_policies[] = {
+ [DDR_FIP_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
+ &backend_dev_handle,
+ (uintptr_t)&ddr_fip_block_spec,
+ NULL
+ },
+ [DDR_IMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_imem_udimm_1d_uuid_spec,
+ open_ddr_fip
+ },
+ [DDR_IMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_imem_udimm_2d_uuid_spec,
+ open_ddr_fip
+ },
+ [DDR_DMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_dmem_udimm_1d_uuid_spec,
+ open_ddr_fip
+ },
+ [DDR_DMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_dmem_udimm_2d_uuid_spec,
+ open_ddr_fip
+ },
+ [DDR_IMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_imem_rdimm_1d_uuid_spec,
+ open_ddr_fip
+ },
+ [DDR_IMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_imem_rdimm_2d_uuid_spec,
+ open_ddr_fip
+ },
+ [DDR_DMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_dmem_rdimm_1d_uuid_spec,
+ open_ddr_fip
+ },
+ [DDR_DMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_dmem_rdimm_2d_uuid_spec,
+ open_ddr_fip
+ },
+#if TRUSTED_BOARD_BOOT
+ [DDR_FW_KEY_CERT_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_fw_key_cert_uuid_spec,
+ open_ddr_fip
+ },
+ [DDR_UDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_udimm_fw_cert_uuid_spec,
+ open_ddr_fip
+ },
+ [DDR_RDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = {
+ &ddr_fip_dev_handle,
+ (uintptr_t)&ddr_rdimm_fw_cert_uuid_spec,
+ open_ddr_fip
+ },
+#endif
+};
+
+static int open_ddr_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if a Firmware Image Package is available */
+ result = io_dev_init(ddr_fip_dev_handle, (uintptr_t)DDR_FIP_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(ddr_fip_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+/* The image can be one of the DDR PHY images, which can be sleected via DDR
+ * policies
+ */
+int plat_get_ddr_fip_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec,
+ int (*check)(const uintptr_t spec))
+{
+ int result = -1;
+ const struct plat_io_policy *policy;
+
+ if (image_id >= (DDR_FIP_IMAGE_ID + ARRAY_SIZE(ddr_policies))) {
+ return result;
+ }
+
+ policy = &ddr_policies[image_id - DDR_FIP_IMAGE_ID];
+ if (image_id == DDR_FIP_IMAGE_ID) {
+ result = check(policy->image_spec);
+ } else {
+ result = policy->check(policy->image_spec);
+ }
+ if (result == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ }
+ return result;
+}
+
+int ddr_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev)
+{
+ int io_result;
+ size_t ddr_fip_offset = PLAT_DDR_FIP_OFFSET;
+
+ /* Open connections to ddr fip and cache the handles */
+ io_result = io_dev_open(fip_dev_con, (uintptr_t)&ddr_fip,
+ &ddr_fip_dev_handle);
+ assert(io_result == 0);
+
+ switch (boot_dev) {
+#if QSPI_BOOT
+ case BOOT_DEVICE_QSPI:
+ ddr_fip_offset += NXP_QSPI_FLASH_ADDR;
+ break;
+#endif
+#if NOR_BOOT
+ case BOOT_DEVICE_IFC_NOR:
+ ddr_fip_offset += NXP_NOR_FLASH_ADDR;
+ break;
+#endif
+#if FLEXSPI_NOR_BOOT
+ case BOOT_DEVICE_FLEXSPI_NOR:
+ ddr_fip_offset += NXP_FLEXSPI_FLASH_ADDR;
+ break;
+#endif
+ default:
+ break;
+ }
+
+ ddr_fip_block_spec.offset = ddr_fip_offset;
+
+ return io_result;
+}
diff --git a/plat/nxp/common/fip_handler/ddr_fip/ddr_io_storage.h b/plat/nxp/common/fip_handler/ddr_fip/ddr_io_storage.h
new file mode 100644
index 0000000..6df3902
--- /dev/null
+++ b/plat/nxp/common/fip_handler/ddr_fip/ddr_io_storage.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef DDR_IO_STORAGE_H
+#define DDR_IO_STORAGE_H
+
+#include <drivers/io/io_driver.h>
+
+#ifndef PLAT_DDR_FIP_OFFSET
+#define PLAT_DDR_FIP_OFFSET 0x800000
+#endif
+
+#ifndef PLAT_DDR_FIP_MAX_SIZE
+#define PLAT_DDR_FIP_MAX_SIZE 0x32000
+#endif
+
+int ddr_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev);
+int plat_get_ddr_fip_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec,
+ int (*check)(const uintptr_t spec));
+
+#endif /* DDR_IO_STORAGE_H */
diff --git a/plat/nxp/common/fip_handler/fuse_fip/fuse.mk b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
new file mode 100644
index 0000000..4e84d02
--- /dev/null
+++ b/plat/nxp/common/fip_handler/fuse_fip/fuse.mk
@@ -0,0 +1,99 @@
+#
+# Copyright 2018-2020 NXP
+# Copyright (c) 2023, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+NEED_FUSE := yes
+
+$(eval $(call add_define, PLAT_DEF_FIP_UUID))
+$(eval $(call add_define, POLICY_FUSE_PROVISION))
+$(eval $(call add_define, PLAT_TBBR_IMG_DEF))
+
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,GPIO_NEEDED,BL2))
+
+FIP_HANDLER_PATH := ${PLAT_COMMON_PATH}/fip_handler
+FIP_HANDLER_COMMON_PATH := ${FIP_HANDLER_PATH}/common
+
+FUSE_SOURCES := ${FIP_HANDLER_PATH}/fuse_fip/fuse_io_storage.c
+
+PLAT_INCLUDES += -I${FIP_HANDLER_COMMON_PATH}\
+ -I${FIP_HANDLER_PATH}/fuse_fip
+
+FUSE_FIP_NAME := fuse_fip.bin
+
+fip_fuse: ${BUILD_PLAT}/${FUSE_FIP_NAME}
+
+ifeq (${FUSE_PROV_FILE},)
+
+else
+ifeq (${TRUSTED_BOARD_BOOT},1)
+FUSE_PROV_FILE_SB = $(notdir ${FUSE_PROV_FILE})_prov.sb
+FUSE_FIP_ARGS += --fuse-prov ${BUILD_PLAT}/${FUSE_PROV_FILE_SB}
+FUSE_FIP_DEPS += ${BUILD_PLAT}/${FUSE_PROV_FILE_SB}
+else
+FUSE_FIP_ARGS += --fuse-prov ${FUSE_PROV_FILE}
+FUSE_FIP_DEPS += ${FUSE_PROV_FILE}
+endif
+endif
+
+ifeq (${FUSE_UP_FILE},)
+else
+ifeq (${TRUSTED_BOARD_BOOT},1)
+FUSE_UP_FILE_SB = $(notdir ${FUSE_UP_FILE})_up.sb
+FUSE_FIP_ARGS += --fuse-up ${BUILD_PLAT}/${FUSE_UP_FILE_SB}
+FUSE_FIP_DEPS += ${BUILD_PLAT}/${FUSE_UP_FILE_SB}
+else
+FUSE_FIP_ARGS += --fuse-up ${FUSE_UP_FILE}
+FUSE_FIP_DEPS += ${FUSE_UP_FILE}
+endif
+endif
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+
+ifeq (${MBEDTLS_DIR},)
+else
+ $(error Error: Trusted Board Boot with X509 certificates not supported with FUSE_PROG build option)
+endif
+
+# Path to CST directory is required to generate the CSF header
+# and prepend it to image before fip image gets generated
+ifeq (${CST_DIR},)
+ $(error Error: CST_DIR not set)
+endif
+
+ifeq (${FUSE_INPUT_FILE},)
+FUSE_INPUT_FILE := $(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/${CSF_FILE}
+endif
+
+ifeq (${FUSE_PROV_FILE},)
+else
+${BUILD_PLAT}/${FUSE_PROV_FILE_SB}: ${FUSE_PROV_FILE}
+ @echo " Generating CSF Header for $@ $<"
+ $(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
+ --app $< ${FUSE_INPUT_FILE}
+endif
+
+ifeq (${FUSE_UP_FILE},)
+else
+${BUILD_PLAT}/${FUSE_UP_FILE_SB}: ${FUSE_UP_FILE}
+ @echo " Generating CSF Header for $@ $<"
+ $(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
+ --app $< ${FUSE_INPUT_FILE}
+endif
+
+endif
+
+${BUILD_PLAT}/${FUSE_FIP_NAME}: fiptool ${FUSE_FIP_DEPS}
+ifeq (${FUSE_FIP_DEPS},)
+ $(error "Error: FUSE_PROV_FILE or/and FUSE_UP_FILE needs to point to the right file")
+endif
+ ${FIPTOOL} create ${FUSE_FIP_ARGS} $@
+ ${FIPTOOL} info $@
+ @${ECHO_BLANK_LINE}
+ @echo "Built $@ successfully"
+ @${ECHO_BLANK_LINE}
diff --git a/plat/nxp/common/fip_handler/fuse_fip/fuse_io.h b/plat/nxp/common/fip_handler/fuse_fip/fuse_io.h
new file mode 100644
index 0000000..e8775d0
--- /dev/null
+++ b/plat/nxp/common/fip_handler/fuse_fip/fuse_io.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef FUSE_IO_H
+#define FUSE_IO_H
+
+#include <drivers/io/io_driver.h>
+
+/* Can be overridden from platform_def.h file.
+ */
+#ifndef PLAT_FUSE_FIP_OFFSET
+#define PLAT_FUSE_FIP_OFFSET 0x880000
+#endif
+#ifndef PLAT_FUSE_FIP_MAX_SIZE
+#define PLAT_FUSE_FIP_MAX_SIZE 0x80000
+#endif
+
+int fip_fuse_provisioning(uintptr_t image_buf, uint32_t size);
+int fuse_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev);
+int plat_get_fuse_image_source(unsigned int image_id,
+ uintptr_t *dev_handle,
+ uintptr_t *image_spec,
+ int (*check)(const uintptr_t spec));
+#endif /* FUSE_IO_H */
diff --git a/plat/nxp/common/fip_handler/fuse_fip/fuse_io_storage.c b/plat/nxp/common/fip_handler/fuse_fip/fuse_io_storage.c
new file mode 100644
index 0000000..017ffcf
--- /dev/null
+++ b/plat/nxp/common/fip_handler/fuse_fip/fuse_io_storage.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <dcfg.h>
+#include <drivers/delay_timer.h>
+#include <fuse_prov.h>
+#include <io_block.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <lib/utils.h>
+#include <nxp_gpio.h>
+#include <sfp.h>
+#include <sfp_error_codes.h>
+#include <tools_share/firmware_image_package.h>
+
+#include "fuse_io.h"
+#include <load_img.h>
+#include <plat/common/platform.h>
+#include "plat_common.h"
+#include "platform_def.h"
+
+extern uintptr_t backend_dev_handle;
+
+static uint32_t fuse_fip;
+
+static uintptr_t fuse_fip_dev_handle;
+
+static io_block_spec_t fuse_fip_block_spec = {
+ .offset = PLAT_FUSE_FIP_OFFSET,
+ .length = PLAT_FUSE_FIP_MAX_SIZE
+};
+
+static const io_uuid_spec_t fuse_prov_uuid_spec = {
+ .uuid = UUID_FUSE_PROV,
+};
+
+static const io_uuid_spec_t fuse_up_uuid_spec = {
+ .uuid = UUID_FUSE_UP,
+};
+
+static int open_fuse_fip(const uintptr_t spec);
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+/* By default, ARM platforms load images from the FIP */
+static const struct plat_io_policy fuse_policies[] = {
+ [FUSE_FIP_IMAGE_ID - FUSE_FIP_IMAGE_ID] = {
+ &backend_dev_handle,
+ (uintptr_t)&fuse_fip_block_spec,
+ NULL
+ },
+ [FUSE_PROV_IMAGE_ID - FUSE_FIP_IMAGE_ID] = {
+ &fuse_fip_dev_handle,
+ (uintptr_t)&fuse_prov_uuid_spec,
+ open_fuse_fip
+ },
+ [FUSE_UP_IMAGE_ID - FUSE_FIP_IMAGE_ID] = {
+ &fuse_fip_dev_handle,
+ (uintptr_t)&fuse_up_uuid_spec,
+ open_fuse_fip
+ }
+};
+
+static int open_fuse_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if a Firmware Image Package is available */
+ result = io_dev_init(fuse_fip_dev_handle, (uintptr_t)FUSE_FIP_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(fuse_fip_dev_handle,
+ spec,
+ &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+/* The image can be one of the DDR PHY images, which can be sleected via DDR
+ * policies
+ */
+int plat_get_fuse_image_source(unsigned int image_id,
+ uintptr_t *dev_handle,
+ uintptr_t *image_spec,
+ int (*check)(const uintptr_t spec))
+{
+ int result;
+ const struct plat_io_policy *policy;
+
+ assert(image_id < (FUSE_FIP_IMAGE_ID + ARRAY_SIZE(fuse_policies)));
+
+ policy = &fuse_policies[image_id - FUSE_FIP_IMAGE_ID];
+
+ if (image_id == FUSE_FIP_IMAGE_ID) {
+ result = check(policy->image_spec);
+ } else {
+ result = policy->check(policy->image_spec);
+ }
+
+ if (result == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ }
+ return result;
+}
+
+int fuse_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev)
+{
+ int io_result;
+ size_t fuse_fip_offset = PLAT_FUSE_FIP_OFFSET;
+
+ /* Open connections to fuse fip and cache the handles */
+ io_result = io_dev_open(fip_dev_con, (uintptr_t)&fuse_fip,
+ &fuse_fip_dev_handle);
+
+ assert(io_result == 0);
+
+ switch (boot_dev) {
+#if QSPI_BOOT
+ case BOOT_DEVICE_QSPI:
+ fuse_fip_offset += NXP_QSPI_FLASH_ADDR;
+ break;
+#endif
+#if NOR_BOOT
+ case BOOT_DEVICE_IFC_NOR:
+ fuse_fip_offset += NXP_NOR_FLASH_ADDR;
+ break;
+#endif
+#if FLEXSPI_NOR_BOOT
+ case BOOT_DEVICE_FLEXSPI_NOR:
+ fuse_fip_offset += NXP_FLEXSPI_FLASH_ADDR;
+ break;
+#endif
+ default:
+ break;
+ }
+
+ fuse_fip_block_spec.offset = fuse_fip_offset;
+
+ return io_result;
+}
+
+int fip_fuse_provisioning(uintptr_t image_buf, uint32_t size)
+{
+ uint32_t bit_num;
+ uint32_t *gpio_base_addr = NULL;
+ struct fuse_hdr_t *fuse_hdr = NULL;
+ uint8_t barker[] = {0x68U, 0x39U, 0x27U, 0x81U};
+ int ret = -1;
+
+ if (sfp_check_oem_wp() == 0) {
+ ret = load_img(FUSE_PROV_IMAGE_ID, &image_buf, &size);
+ if (ret != 0) {
+ ERROR("Failed to load FUSE PRIV image\n");
+ assert(ret == 0);
+ }
+ fuse_hdr = (struct fuse_hdr_t *)image_buf;
+
+ /* Check barker code */
+ if (memcmp(fuse_hdr->barker, barker, sizeof(barker)) != 0) {
+ ERROR("FUSE Barker code mismatch.\n");
+ error_handler(ERROR_FUSE_BARKER);
+ return 1;
+ }
+
+ /* Check if GPIO pin to be set for POVDD */
+ if (((fuse_hdr->flags >> FLAG_POVDD_SHIFT) & 0x1) != 0) {
+ gpio_base_addr =
+ select_gpio_n_bitnum(fuse_hdr->povdd_gpio,
+ &bit_num);
+ /*
+ * Add delay so that Efuse gets the power
+ * when GPIO is enabled.
+ */
+ ret = set_gpio_bit(gpio_base_addr, bit_num);
+ mdelay(EFUSE_POWERUP_DELAY_mSec);
+ } else {
+ ret = (board_enable_povdd() == true) ? 0 : PLAT_ERROR_ENABLE_POVDD;
+ }
+ if (ret != 0) {
+ ERROR("Error enabling board POVDD: %d\n", ret);
+ ERROR("Only SFP mirror register will be set.\n");
+ }
+
+ provision_fuses(image_buf, ret == 0);
+
+ /* Check if GPIO pin to be reset for POVDD */
+ if (((fuse_hdr->flags >> FLAG_POVDD_SHIFT) & 0x1) != 0) {
+ if (gpio_base_addr == NULL) {
+ gpio_base_addr =
+ select_gpio_n_bitnum(
+ fuse_hdr->povdd_gpio,
+ &bit_num);
+ }
+ ret = clr_gpio_bit(gpio_base_addr, bit_num);
+ } else {
+ ret = board_disable_povdd() ? 0 : PLAT_ERROR_DISABLE_POVDD;
+ }
+
+ if (ret != 0) {
+ ERROR("Error disabling board POVDD: %d\n", ret);
+ }
+ }
+ return 0;
+}
diff --git a/plat/nxp/common/img_loadr/img_loadr.mk b/plat/nxp/common/img_loadr/img_loadr.mk
new file mode 100644
index 0000000..f64b1fa
--- /dev/null
+++ b/plat/nxp/common/img_loadr/img_loadr.mk
@@ -0,0 +1,21 @@
+#
+# Copyright 2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+IMG_LOADR_DRIVERS_PATH := ${PLAT_COMMON_PATH}/img_loadr
+
+IMG_LOADR_SOURCES := $(IMG_LOADR_DRIVERS_PATH)/load_img.c
+PLAT_INCLUDES += -I$(IMG_LOADR_DRIVERS_PATH)
+
+ifeq (${BL_COMM_IMG_LOADR_NEEDED},yes)
+BL_COMMON_SOURCES += ${IMG_LOADR_SOURCES}
+else
+ifeq (${BL2_IMG_LOADR_NEEDED},yes)
+BL2_SOURCES += ${IMG_LOADR_SOURCES}
+endif
+ifeq (${BL31_IMG_LOADR_NEEDED},yes)
+BL31_SOURCES += ${IMG_LOADR_SOURCES}
+endif
+endif
diff --git a/plat/nxp/common/img_loadr/load_img.c b/plat/nxp/common/img_loadr/load_img.c
new file mode 100644
index 0000000..51011e4
--- /dev/null
+++ b/plat/nxp/common/img_loadr/load_img.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include "load_img.h"
+
+/******************************************************************************
+ * This function can be used to load DDR PHY/FUSE Images
+ *
+ * @param [in] image_id Image ID to be loaded
+ *
+ * @param [in,out] image_base Location at which the image should be loaded
+ * In case image is prepended by a CSF header,
+ * image_base is pointer to actual image after
+ * the header
+ *
+ * @param [in,out] image_size User should pass the maximum size of the image
+ * possible.(Buffer size starting from image_base)
+ * Actual size of the image loaded is returned
+ * back.
+ *****************************************************************************/
+int load_img(unsigned int image_id, uintptr_t *image_base,
+ uint32_t *image_size)
+{
+ int err = 0;
+
+ image_desc_t img_info = {
+ .image_id = image_id,
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t, 0),
+#ifdef CSF_HEADER_PREPENDED
+ .image_info.image_base = *image_base - CSF_HDR_SZ,
+ .image_info.image_max_size = *image_size + CSF_HDR_SZ,
+#else
+ .image_info.image_base = *image_base,
+ .image_info.image_max_size = *image_size,
+#endif
+ };
+
+ /* Create MMU entry for the CSF header */
+#if PLAT_XLAT_TABLES_DYNAMIC
+#ifdef CSF_HEADER_PREPENDED
+ err = mmap_add_dynamic_region(img_info.image_info.image_base,
+ img_info.image_info.image_base,
+ CSF_HDR_SZ,
+ MT_MEMORY | MT_RW | MT_SECURE);
+ if (err != 0) {
+ ERROR("Failed to add dynamic memory region.\n");
+ return err;
+ }
+#endif
+#endif
+
+ VERBOSE("BL2: Loading IMG %d\n", image_id);
+ err = load_auth_image(image_id, &img_info.image_info);
+ if (err != 0) {
+ VERBOSE("Failed to load IMG %d\n", image_id);
+ return err;
+ }
+
+#ifdef CSF_HEADER_PREPENDED
+ *image_base = img_info.image_info.image_base + CSF_HDR_SZ;
+ *image_size = img_info.image_info.image_size - CSF_HDR_SZ;
+#if PLAT_XLAT_TABLES_DYNAMIC
+ mmap_remove_dynamic_region(img_info.image_info.image_base,
+ CSF_HDR_SZ);
+#endif
+#else
+ *image_base = img_info.image_info.image_base;
+ *image_size = img_info.image_info.image_size;
+#endif
+
+ return err;
+}
diff --git a/plat/nxp/common/img_loadr/load_img.h b/plat/nxp/common/img_loadr/load_img.h
new file mode 100644
index 0000000..6f9de32
--- /dev/null
+++ b/plat/nxp/common/img_loadr/load_img.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef LOAD_IMAGE_H
+#define LOAD_IMAGE_H
+
+int load_img(unsigned int image_id, uintptr_t *image_base,
+ uint32_t *image_size);
+
+#endif /* LOAD_IMAGE_H */
diff --git a/plat/nxp/common/include/default/ch_2/soc_default_base_addr.h b/plat/nxp/common/include/default/ch_2/soc_default_base_addr.h
new file mode 100644
index 0000000..6296aef
--- /dev/null
+++ b/plat/nxp/common/include/default/ch_2/soc_default_base_addr.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SOC_DEFAULT_BASE_ADDR_H
+#define SOC_DEFAULT_BASE_ADDR_H
+
+/* CCSR mmu_def.h */
+#define NXP_CCSR_ADDR 0x01000000
+#define NXP_CCSR_SIZE 0x0F000000
+
+#define NXP_DCSR_ADDR 0x20000000
+#define NXP_DCSR_SIZE 0x4000000
+
+/* Flex-SPI controller address */
+#define NXP_FLEXSPI_ADDR 0x020C0000
+/* QSPI Flash Start address */
+#define NXP_QSPI_FLASH_ADDR 0x40000000
+/* NOR Flash Start address */
+#define NXP_IFC_REGION_ADDR 0x60000000
+#define NXP_NOR_FLASH_ADDR NXP_IFC_REGION_ADDR
+
+/* MMU 500 soc.c*/
+#define NXP_SMMU_ADDR 0x09000000
+
+#define NXP_SNVS_ADDR 0x01E90000
+
+#define NXP_DCFG_ADDR 0x01EE0000
+#define NXP_SFP_ADDR 0x01E80000
+#define NXP_RCPM_ADDR 0x01EE2000
+#define NXP_CSU_ADDR 0x01510000
+#define NXP_IFC_ADDR 0x01530000
+#define NXP_SCFG_ADDR 0x01570000
+#define NXP_DCSR_ADDR 0x20000000
+#define NXP_DCSR_DCFG_ADDR (NXP_DCSR_ADDR + 0x00140000)
+#define NXP_I2C_ADDR 0x02180000
+#define NXP_ESDHC_ADDR 0x01560000
+#define NXP_UART_ADDR 0x021C0500
+#define NXP_UART1_ADDR 0x021C0600
+
+#define NXP_GPIO1_ADDR 0x02300000
+#define NXP_GPIO2_ADDR 0x02310000
+#define NXP_GPIO3_ADDR 0x02320000
+#define NXP_GPIO4_ADDR 0x02330000
+
+#define NXP_WDOG1_NS_ADDR 0x02390000
+#define NXP_WDOG2_NS_ADDR 0x023A0000
+#define NXP_WDOG1_TZ_ADDR 0x023B0000
+#define NXP_WDOG2_TZ_ADDR 0x023C0000
+
+#define NXP_TIMER_STATUS_ADDR 0x023F0000
+
+#define NXP_GICD_4K_ADDR 0x01401000
+#define NXP_GICC_4K_ADDR 0x01402000
+#define NXP_GICD_64K_ADDR 0x01410000
+#define NXP_GICC_64K_ADDR 0x01420000
+
+#define NXP_CAAM_ADDR 0x01700000
+
+#define NXP_TZC_ADDR 0x01500000
+#define NXP_DDR_ADDR 0x01080000
+
+#define NXP_TIMER_ADDR 0x02B00000
+#define NXP_CCI_ADDR 0x01180000
+#define NXP_RESET_ADDR 0x01E60000
+#define NXP_SEC_REGFILE_ADDR 0x01E88000
+#endif /* SOC_DEFAULT_BASE_ADDR_H */
diff --git a/plat/nxp/common/include/default/ch_2/soc_default_helper_macros.h b/plat/nxp/common/include/default/ch_2/soc_default_helper_macros.h
new file mode 100644
index 0000000..928ac05
--- /dev/null
+++ b/plat/nxp/common/include/default/ch_2/soc_default_helper_macros.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SOC_DEFAULT_HELPER_MACROS_H
+#define SOC_DEFAULT_HELPER_MACROS_H
+
+#ifdef NXP_OCRAM_TZPC_ADDR
+
+/* 0x1: means 4 KB
+ * 0x2: means 8 KB
+ */
+#define TZPC_BLOCK_SIZE 0x1000
+#endif
+
+/* DDR controller offsets and defines */
+#ifdef NXP_DDR_ADDR
+
+#define DDR_CFG_2_OFFSET 0x114
+#define CFG_2_FORCE_REFRESH 0x80000000
+
+#endif /* NXP_DDR_ADDR */
+
+ /* Reset block register offsets */
+#ifdef NXP_RESET_ADDR
+
+/* Register Offset */
+#define RST_RSTCR_OFFSET 0x0
+#define RST_RSTRQMR1_OFFSET 0x10
+#define RST_RSTRQSR1_OFFSET 0x18
+#define BRR_OFFSET 0x60
+
+/* helper macros */
+#define RSTRQSR1_SWRR 0x800
+#define RSTRQMR_RPTOE_MASK (1 << 19)
+
+#endif /* NXP_RESET_ADDR */
+
+/* Secure-Register-File register offsets and bit masks */
+#ifdef NXP_RST_ADDR
+/* Register Offset */
+#define CORE_HOLD_OFFSET 0x140
+#define RSTCNTL_OFFSET 0x180
+
+/* Helper macros */
+#define SW_RST_REQ_INIT 0x1
+#endif
+
+#ifdef NXP_RCPM_ADDR
+/* RCPM Register Offsets */
+#define RCPM_PCPH20SETR_OFFSET 0x0D4
+#define RCPM_PCPH20CLRR_OFFSET 0x0D8
+#define RCPM_POWMGTCSR_OFFSET 0x130
+#define RCPM_IPPDEXPCR0_OFFSET 0x140
+#define RCPM_POWMGTCSR_LPM20_REQ 0x00100000
+
+#define RCPM2_IPSTPCR0_OFFSET 0x8
+#define RCPM2_IPSTPCR1_OFFSET 0xC
+#define RCPM2_IPSTPCR2_OFFSET 0x10
+#define RCPM2_IPSTPCR3_OFFSET 0x14
+#define RCPM2_IPSTPCR4_OFFSET 0x28
+
+#define RCPM2_IPSTPACKR0_OFFSET 0x18
+#define RCPM2_IPSTPACKR1_OFFSET 0x1C
+#define RCPM2_IPSTPACKR2_OFFSET 0x20
+#define RCPM2_IPSTPACKR3_OFFSET 0x24
+#define RCPM2_IPSTPACKR4_OFFSET 0x2C
+#define RCPM2_POWMGTDCR_OFFSET 0x0
+
+/* bitfield masks */
+#define POWMGTDCR_OVRD_EN 0x80000000
+
+#endif /* NXP_RCPM_ADDR */
+
+#define DCFG_SBEESR2_ADDR 0x20140534
+#define DCFG_MBEESR2_ADDR 0x20140544
+/* SBEESR and MBEESR bit mask */
+#define OCRAM_EESR_MASK 0x00000060
+
+#endif /* SOC_DEFAULT_HELPER_MACROS_H */
diff --git a/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h b/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h
new file mode 100644
index 0000000..8d64f04
--- /dev/null
+++ b/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2021-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SOC_DEFAULT_BASE_ADDR_H
+#define SOC_DEFAULT_BASE_ADDR_H
+
+/* CCSR mmu_def.h */
+#define NXP_CCSR_ADDR 0x1000000
+#define NXP_CCSR_SIZE 0xF000000
+
+#define NXP_DCSR_ADDR 0x700000000
+#define NXP_DCSR_SIZE 0x40000000
+
+/* Quad SPI Region #1 base address */
+#define NXP_QSPI_FLASH_ADDR 0x20000000
+
+/* IFC Region #1 base address */
+#define NXP_NOR_FLASH_ADDR 0x30000000
+
+/* MMU 500 */
+#define NXP_SMMU_ADDR 0x05000000
+
+#define NXP_SNVS_ADDR 0x01E90000
+
+#define NXP_DCFG_ADDR 0x01E00000
+#define NXP_PMU_CCSR_ADDR 0x01E30000
+#define NXP_PMU_DCSR_ADDR 0x700123000
+#define NXP_PMU_ADDR NXP_PMU_CCSR_ADDR
+#define NXP_SFP_ADDR 0x01E80000
+#define NXP_SCFG_ADDR 0x01FC0000
+#define NXP_I2C_ADDR 0x02000000
+#define NXP_ESDHC_ADDR 0x02140000
+#define NXP_ESDHC2_ADDR 0x02150000
+#ifndef NXP_UART_ADDR
+#define NXP_UART_ADDR 0x021C0500
+#endif
+#ifndef NXP_UART1_ADDR
+#define NXP_UART1_ADDR 0x021C0600
+#endif
+
+#define NXP_GPIO1_ADDR 0x02300000
+#define NXP_GPIO2_ADDR 0x02310000
+#define NXP_GPIO3_ADDR 0x02320000
+#define NXP_GPIO4_ADDR 0x02330000
+
+#define NXP_WDOG1_NS_ADDR 0x02390000
+#define NXP_WDOG2_NS_ADDR 0x023A0000
+#define NXP_WDOG1_TZ_ADDR 0x023B0000
+#define NXP_WDOG2_TZ_ADDR 0x023C0000
+
+#define NXP_TIMER_STATUS_ADDR 0x023F0000
+
+#define NXP_GICD_ADDR 0x06000000
+#define NXP_GICR_ADDR 0x06100000
+#define NXP_GICR_SGI_ADDR 0x06110000
+
+#define NXP_CAAM_ADDR 0x08000000
+
+#define NXP_TZC_ADDR 0x01100000
+#define NXP_TZC2_ADDR 0x01110000
+#define NXP_TZC3_ADDR 0x01120000
+
+#define NXP_RESET_ADDR 0x01E60000
+#define NXP_SEC_REGFILE_ADDR 0x01E88000
+
+#define NXP_RST_ADDR 0x01E88000
+
+/* DDR memory Map */
+#define NXP_DDR_ADDR 0x01080000
+#define NXP_DDR2_ADDR 0x01090000
+#define NXP_DDR3_ADDR 0x08210000
+
+/* QuadSPI base address */
+#define NXP_QSPI_ADDR 0x020C0000
+/* IFC base address */
+#define NXP_IFC_ADDR 0x02240000
+
+/* CCI400 base address */
+#define NXP_CCI_ADDR 0x04090000
+
+/* Global Generic Reference Timer base address */
+#define NXP_TIMER_ADDR 0x023E0000
+
+/* OCRAM TZPC base address */
+#define NXP_OCRAM_TZPC_ADDR 0x02200000
+
+#define NXP_EPU_ADDR 0x700060000
+
+#define NXP_CCN_ADDR 0x04000000
+#define NXP_CCN_HNI_ADDR 0x04080000
+#define NXP_CCN_HN_F_0_ADDR 0x04200000
+#define NXP_CCN_HN_F_1_ADDR 0x04210000
+
+#define TPMWAKEMR0_ADDR 0x700123c50
+
+#endif /* SOC_DEFAULT_BASE_ADDR_H */
diff --git a/plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h b/plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h
new file mode 100644
index 0000000..8e68367
--- /dev/null
+++ b/plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef SOC_DEFAULT_HELPER_MACROS_H
+#define SOC_DEFAULT_HELPER_MACROS_H
+
+#ifdef NXP_OCRAM_TZPC_ADDR
+#define TZPC_BLOCK_SIZE 0x1000
+#endif
+
+/* Reset block register offsets */
+#ifdef NXP_RESET_ADDR
+
+/* Register Offset */
+#define RST_RSTCR_OFFSET 0x0
+#define RST_RSTRQMR1_OFFSET 0x10
+#define RST_RSTRQSR1_OFFSET 0x18
+#define BRR_OFFSET 0x60
+
+/* helper macros */
+#define RSTRQMR_RPTOE_MASK (1 << 19)
+#endif /* NXP_RESET_ADDR */
+
+#define PCIeRC_RN_I_NODE_ID_OFFSET 0x8
+#define PoS_CONTROL_REG_OFFSET 0x0
+#define POS_EARLY_WR_COMP_EN 0x20
+#define HNI_POS_EN 0x01
+#define POS_TERMINATE_BARRIERS 0x10
+#define SERIALIZE_DEV_nGnRnE_WRITES 0x200
+#define ENABLE_ERR_SIGNAL_TO_MN 0x4
+#define ENABLE_RESERVE_BIT53 0x400
+#define ENABLE_WUO 0x10
+
+#define PORT_S0_CTRL_REG_RNI 0x010
+#define PORT_S1_CTRL_REG_RNI 0x110
+#define PORT_S2_CTRL_REG_RNI 0x210
+#define ENABLE_FORCE_RD_QUO 0x20
+#define QOS_SETTING 0x00FF000C
+
+/* epu register offsets and values */
+#define EPU_EPGCR_OFFSET 0x0
+#define EPU_EPIMCR10_OFFSET 0x128
+#define EPU_EPCTR10_OFFSET 0xa28
+#define EPU_EPCCR10_OFFSET 0x828
+#ifndef EPU_EPCCR10_VAL
+#define EPU_EPCCR10_VAL 0xb2800000
+#endif
+#define EPU_EPIMCR10_VAL 0xba000000
+#define EPU_EPCTR10_VAL 0x0
+#define EPU_EPGCR_VAL (1 << 31)
+
+#ifdef NXP_CCN_ADDR
+#define NXP_CCN_HN_F_1_ADDR 0x04210000
+
+#define CCN_HN_F_SAM_NODEID_MASK 0x7f
+#define CCN_HN_F_SNP_DMN_CTL_OFFSET 0x200
+#define CCN_HN_F_SNP_DMN_CTL_SET_OFFSET 0x210
+#define CCN_HN_F_SNP_DMN_CTL_CLR_OFFSET 0x220
+#define CCN_HN_F_SNP_DMN_CTL_MASK 0x80a00
+#define CCN_HNF_NODE_COUNT 8
+#define CCN_HNF_OFFSET 0x10000
+
+#define SA_AUX_CTRL_REG_OFFSET 0x500
+#define NUM_HNI_NODE 2
+#define CCN_HNI_MEMORY_MAP_SIZE 0x10000
+
+#define PCIeRC_RN_I_NODE_ID_OFFSET 0x8
+#define PoS_CONTROL_REG_OFFSET 0x0
+#define POS_EARLY_WR_COMP_EN 0x20
+#define HNI_POS_EN 0x01
+#define POS_TERMINATE_BARRIERS 0x10
+#define SERIALIZE_DEV_nGnRnE_WRITES 0x200
+#define ENABLE_ERR_SIGNAL_TO_MN 0x4
+#define ENABLE_RESERVE_BIT53 0x400
+#define ENABLE_WUO 0x10
+#endif
+
+/* reset register bit */
+#define RSTRQMR_RPTOE_MASK (1 << 19)
+
+/* secmon register offsets and bitfields */
+#define SECMON_HPCOMR_OFFSET 0x4
+#define SECMON_HPCOMR_NPSWAEN 0x80000000
+
+/* Secure-Register-File register offsets and bit masks */
+#ifdef NXP_RST_ADDR
+/* Register Offset */
+#define CORE_HOLD_OFFSET 0x140
+#endif
+
+#define DCFG_SBEESR2_ADDR 0x00100534
+#define DCFG_MBEESR2_ADDR 0x00100544
+/* SBEESR and MBEESR bit mask */
+#define OCRAM_EESR_MASK 0x00000008
+
+#endif /* SOC_DEFAULT_HELPER_MACROS_H */
diff --git a/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h b/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h
new file mode 100644
index 0000000..0a4228b
--- /dev/null
+++ b/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SOC_DEFAULT_BASE_ADDR_H
+#define SOC_DEFAULT_BASE_ADDR_H
+
+/* CCSR mmu_def.h */
+#define NXP_CCSR_ADDR 0x1000000
+#define NXP_CCSR_SIZE 0xF000000
+
+#define NXP_DCSR_ADDR 0x700000000
+#define NXP_DCSR_SIZE 0x40000000
+
+/* Flex-SPI controller address */
+#define NXP_FLEXSPI_ADDR 0x020C0000
+/* Flex-SPI Flash Start address */
+#define NXP_FLEXSPI_FLASH_ADDR 0x20000000
+
+/* MMU 500 soc.c*/
+#define NXP_SMMU_ADDR 0x05000000
+
+/* CCI400 base address */
+#define NXP_CCI_ADDR 0x04090000
+
+#define NXP_SNVS_ADDR 0x01E90000
+
+#define NXP_DCFG_ADDR 0x01E00000
+#define NXP_PMU_CCSR_ADDR 0x01E30000
+#define NXP_PMU_DCSR_ADDR 0x700123000
+#define NXP_PMU_ADDR NXP_PMU_CCSR_ADDR
+#define NXP_SFP_ADDR 0x01E80000
+#define NXP_SCFG_ADDR 0x01FC0000
+#define NXP_I2C_ADDR 0x02000000
+#define NXP_ESDHC_ADDR 0x02140000
+#define NXP_ESDHC2_ADDR 0x02150000
+#define NXP_UART_ADDR 0x021C0000
+#define NXP_UART1_ADDR 0x021D0000
+
+#define NXP_GPIO1_ADDR 0x02300000
+#define NXP_GPIO2_ADDR 0x02310000
+#define NXP_GPIO3_ADDR 0x02320000
+#define NXP_GPIO4_ADDR 0x02330000
+
+#define NXP_WDOG1_NS_ADDR 0x02390000
+#define NXP_WDOG2_NS_ADDR 0x023A0000
+#define NXP_WDOG1_TZ_ADDR 0x023B0000
+#define NXP_WDOG2_TZ_ADDR 0x023C0000
+
+#define NXP_TIMER_STATUS_ADDR 0x023F0000
+
+#define NXP_GICD_ADDR 0x06000000
+#define NXP_GICR_ADDR 0x06200000
+#define NXP_GICR_SGI_ADDR 0x06210000
+
+#define NXP_CAAM_ADDR 0x08000000
+
+#define NXP_TZC_ADDR 0x01100000
+#define NXP_TZC2_ADDR 0x01110000
+#define NXP_TZC3_ADDR 0x01120000
+
+#define NXP_TIMER_ADDR 0x023E0000
+
+#define NXP_RESET_ADDR 0x01E60000
+#define NXP_SEC_REGFILE_ADDR 0x01E88000
+#define NXP_RST_ADDR 0x01E88000
+
+#define TPMWAKEMR0_ADDR 0x700123c50
+#define TZPC_BLOCK_SIZE 0x1000
+
+#define NXP_TZC_ADDR 0x01100000
+#define NXP_TZC2_ADDR 0x01110000
+#define NXP_TZC3_ADDR 0x01120000
+#define NXP_TZC4_ADDR 0x01130000
+#define NXP_DDR_ADDR 0x01080000
+#define NXP_DDR2_ADDR 0x01090000
+
+#define NXP_OCRAM_TZPC_ADDR 0x02200000
+
+#define NXP_CCN_ADDR 0x04000000
+#define NXP_CCN_HNI_ADDR 0x04080000
+#define NXP_CCN_HN_F_0_ADDR 0x04200000
+
+#define NXP_EPU_ADDR 0x700060000
+#endif /* SOC_DEFAULT_BASE_ADDR_H */
diff --git a/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h b/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h
new file mode 100644
index 0000000..1edd28d
--- /dev/null
+++ b/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SOC_DEFAULT_HELPER_MACROS_H
+#define SOC_DEFAULT_HELPER_MACROS_H
+
+#ifdef NXP_OCRAM_TZPC_ADDR
+
+/* 0x1: means 4 KB
+ * 0x2: means 8 KB
+ */
+#define TZPC_BLOCK_SIZE 0x1000
+#endif
+
+/* DDR controller offsets and defines */
+#ifdef NXP_DDR_ADDR
+
+#define DDR_CFG_2_OFFSET 0x114
+#define CFG_2_FORCE_REFRESH 0x80000000
+
+#endif /* NXP_DDR_ADDR */
+
+ /* Reset block register offsets */
+#ifdef NXP_RESET_ADDR
+
+/* Register Offset */
+#define RST_RSTCR_OFFSET 0x0
+#define RST_RSTRQMR1_OFFSET 0x10
+#define RST_RSTRQSR1_OFFSET 0x18
+#define BRR_OFFSET 0x60
+
+/* helper macros */
+#define RSTRQSR1_SWRR 0x800
+#define RSTRQMR_RPTOE_MASK (1 << 19)
+
+#endif /* NXP_RESET_ADDR */
+
+/* secmon register offsets and bitfields */
+#define SECMON_HPCOMR_OFFSET 0x4
+#define SECMON_HPCOMR_NPSWAEN 0x80000000
+
+/* Secure-Register-File register offsets and bit masks */
+#ifdef NXP_RST_ADDR
+/* Register Offset */
+#define CORE_HOLD_OFFSET 0x140
+#define RSTCNTL_OFFSET 0x180
+
+/* Helper macros */
+#define SW_RST_REQ_INIT 0x1
+#endif
+
+#ifdef NXP_CCN_ADDR
+#define NXP_CCN_HN_F_1_ADDR 0x04210000
+
+#define CCN_HN_F_SAM_NODEID_MASK 0x7f
+#define CCN_HN_F_SNP_DMN_CTL_OFFSET 0x200
+#define CCN_HN_F_SNP_DMN_CTL_SET_OFFSET 0x210
+#define CCN_HN_F_SNP_DMN_CTL_CLR_OFFSET 0x220
+#define CCN_HN_F_SNP_DMN_CTL_MASK 0x80a00
+#define CCN_HNF_NODE_COUNT 8
+#define CCN_HNF_OFFSET 0x10000
+
+#define SA_AUX_CTRL_REG_OFFSET 0x500
+#define NUM_HNI_NODE 2
+#define CCN_HNI_MEMORY_MAP_SIZE 0x10000
+
+#define PCIeRC_RN_I_NODE_ID_OFFSET 0x8
+#define PoS_CONTROL_REG_OFFSET 0x0
+#define POS_EARLY_WR_COMP_EN 0x20
+#define HNI_POS_EN 0x01
+#define POS_TERMINATE_BARRIERS 0x10
+#define SERIALIZE_DEV_nGnRnE_WRITES 0x200
+#define ENABLE_ERR_SIGNAL_TO_MN 0x4
+#define ENABLE_RESERVE_BIT53 0x400
+#define ENABLE_WUO 0x10
+#endif /* NXP_CCN_ADDR */
+
+#define DCFG_SBEESR2_ADDR 0x00100534
+#define DCFG_MBEESR2_ADDR 0x00100544
+/* SBEESR and MBEESR bit mask */
+#define OCRAM_EESR_MASK 0x00000008
+
+#endif /* SOC_DEFAULT_HELPER_MACROS_H */
diff --git a/plat/nxp/common/include/default/plat_default_def.h b/plat/nxp/common/include/default/plat_default_def.h
new file mode 100644
index 0000000..43320bb
--- /dev/null
+++ b/plat/nxp/common/include/default/plat_default_def.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_DEFAULT_DEF_H
+#define PLAT_DEFAULT_DEF_H
+
+/*
+ * Platform binary types for linking
+ */
+#ifdef __aarch64__
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+#else
+#define PLATFORM_LINKER_FORMAT "elf32-littlearm"
+#define PLATFORM_LINKER_ARCH arm
+#endif /* __aarch64__ */
+
+#define LS_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
+
+/* NXP Platforms have DRAM divided into banks.
+ * DRAM0 Bank: Maximum size of this bank is fixed to 2GB
+ * DRAM1 Bank: Greater than 2GB belongs to bank1 and size of bank1 varies from
+ * one platform to other platform.
+ * DRAMn Bank:
+ *
+ * Except a few, all the platforms have 2GB size as DRAM0 BANK.
+ * Hence common for all the platforms.
+ * For platforms where DRAM0 Size is < 2GB, it is defined in platform_def.h
+ */
+#ifndef PLAT_DEF_DRAM0_SIZE
+#define PLAT_DEF_DRAM0_SIZE 0x80000000 /* 2G */
+#endif
+
+/* This is common for all platforms where: */
+#ifndef NXP_NS_DRAM_ADDR
+#define NXP_NS_DRAM_ADDR NXP_DRAM0_ADDR
+#endif
+
+/* 1 MB is reserved for dma of sd */
+#ifndef NXP_SD_BLOCK_BUF_SIZE
+#define NXP_SD_BLOCK_BUF_SIZE (1 * 1024 * 1024)
+#endif
+
+/* 64MB is reserved for Secure memory */
+#ifndef NXP_SECURE_DRAM_SIZE
+#define NXP_SECURE_DRAM_SIZE (64 * 1024 * 1024)
+#endif
+
+/* 2M Secure EL1 Payload Shared Memory */
+#ifndef NXP_SP_SHRD_DRAM_SIZE
+#define NXP_SP_SHRD_DRAM_SIZE (2 * 1024 * 1024)
+#endif
+
+#ifndef NXP_NS_DRAM_SIZE
+/* Non secure memory */
+#define NXP_NS_DRAM_SIZE (PLAT_DEF_DRAM0_SIZE - \
+ (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE))
+#endif
+
+#ifndef NXP_SD_BLOCK_BUF_ADDR
+#define NXP_SD_BLOCK_BUF_ADDR (NXP_NS_DRAM_ADDR)
+#endif
+
+#ifndef NXP_SECURE_DRAM_ADDR
+#ifdef TEST_BL31
+#define NXP_SECURE_DRAM_ADDR 0
+#else
+#define NXP_SECURE_DRAM_ADDR (NXP_NS_DRAM_ADDR + PLAT_DEF_DRAM0_SIZE - \
+ (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE))
+#endif
+#endif
+
+#ifndef NXP_SP_SHRD_DRAM_ADDR
+#define NXP_SP_SHRD_DRAM_ADDR (NXP_NS_DRAM_ADDR + PLAT_DEF_DRAM0_SIZE - \
+ NXP_SP_SHRD_DRAM_SIZE)
+#endif
+
+#ifndef BL31_BASE
+/* 2 MB reserved in secure memory for DDR */
+#define BL31_BASE NXP_SECURE_DRAM_ADDR
+#endif
+
+#ifndef BL31_SIZE
+#define BL31_SIZE (0x200000)
+#endif
+
+#ifndef BL31_LIMIT
+#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
+#endif
+
+/* Put BL32 in secure memory */
+#ifndef BL32_BASE
+#define BL32_BASE (NXP_SECURE_DRAM_ADDR + BL31_SIZE)
+#endif
+
+#ifndef BL32_LIMIT
+#define BL32_LIMIT (NXP_SECURE_DRAM_ADDR + \
+ NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE)
+#endif
+
+/* BL33 memory region */
+/* Hardcoded based on current address in u-boot */
+#ifndef BL33_BASE
+#define BL33_BASE 0x82000000
+#endif
+
+#ifndef BL33_LIMIT
+#define BL33_LIMIT (NXP_NS_DRAM_ADDR + NXP_NS_DRAM_SIZE)
+#endif
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#ifndef FUSE_BUF
+#define FUSE_BUF ULL(0x81000000)
+#endif
+
+#ifndef FUSE_SZ
+#define FUSE_SZ 0x80000
+#endif
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES 2
+#endif
+
+#ifndef PLAT_FIP_OFFSET
+#define PLAT_FIP_OFFSET 0x100000
+#endif
+
+#ifndef PLAT_FIP_MAX_SIZE
+#define PLAT_FIP_MAX_SIZE 0x400000
+#endif
+
+/* Check if this size can be determined from array size */
+#if defined(IMAGE_BL2)
+#ifndef MAX_MMAP_REGIONS
+#define MAX_MMAP_REGIONS 8
+#endif
+#ifndef MAX_XLAT_TABLES
+#define MAX_XLAT_TABLES 6
+#endif
+#elif defined(IMAGE_BL31)
+#ifndef MAX_MMAP_REGIONS
+#define MAX_MMAP_REGIONS 9
+#endif
+#ifndef MAX_XLAT_TABLES
+#define MAX_XLAT_TABLES 9
+#endif
+#elif defined(IMAGE_BL32)
+#ifndef MAX_MMAP_REGIONS
+#define MAX_MMAP_REGIONS 8
+#endif
+#ifndef MAX_XLAT_TABLES
+#define MAX_XLAT_TABLES 9
+#endif
+#endif
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#ifndef BL32_IRQ_SEC_PHY_TIMER
+#define BL32_IRQ_SEC_PHY_TIMER 29
+#endif
+
+#endif /* PLAT_DEFAULT_DEF_H */
diff --git a/plat/nxp/common/nv_storage/nv_storage.mk b/plat/nxp/common/nv_storage/nv_storage.mk
new file mode 100644
index 0000000..dddba5f
--- /dev/null
+++ b/plat/nxp/common/nv_storage/nv_storage.mk
@@ -0,0 +1,29 @@
+#
+# Copyright 2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# NXP Non-Volatile data flag storage used and then cleared by SW on boot-up
+
+$(eval $(call add_define,NXP_NV_SW_MAINT_LAST_EXEC_DATA))
+
+ifeq ($(NXP_COINED_BB),yes)
+$(eval $(call add_define,NXP_COINED_BB))
+# BL2 : To read the reset cause from LP SECMON GPR register
+# BL31: To write the reset cause to LP SECMON GPR register
+$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL_COMM))
+
+# BL2: DDR training data is stored on Flexspi NOR.
+ifneq (${BOOT_MODE},flexspi_nor)
+$(eval $(call SET_NXP_MAKE_FLAG,XSPI_NEEDED,BL2))
+endif
+
+else
+$(eval $(call add_define_val,DEFAULT_NV_STORAGE_BASE_ADDR,'${BL2_BIN_XSPI_NOR_END_ADDRESS} - 2 * ${NXP_XSPI_NOR_UNIT_SIZE}'))
+$(eval $(call SET_NXP_MAKE_FLAG,XSPI_NEEDED,BL_COMM))
+endif
+
+NV_STORAGE_INCLUDES += -I${PLAT_COMMON_PATH}/nv_storage
+
+NV_STORAGE_SOURCES += ${PLAT_COMMON_PATH}/nv_storage/plat_nv_storage.c
diff --git a/plat/nxp/common/nv_storage/plat_nv_storage.c b/plat/nxp/common/nv_storage/plat_nv_storage.c
new file mode 100644
index 0000000..97d777e
--- /dev/null
+++ b/plat/nxp/common/nv_storage/plat_nv_storage.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <platform_def.h>
+#include <common/debug.h>
+#ifndef NXP_COINED_BB
+#include <flash_info.h>
+#include <fspi.h>
+#include <fspi_api.h>
+#endif
+#include <lib/mmio.h>
+#ifdef NXP_COINED_BB
+#include <snvs.h>
+#else
+#include <xspi_error_codes.h>
+#endif
+
+#include <plat_nv_storage.h>
+
+/*This structure will be a static structure and
+ * will be populated as first step of BL2 booting-up.
+ * fspi_strorage.c . To be located in the fspi driver folder.
+ */
+
+static nv_app_data_t nv_app_data;
+
+int read_nv_app_data(void)
+{
+ int ret = 0;
+
+#ifdef NXP_COINED_BB
+ uint8_t *nv_app_data_array = (uint8_t *) &nv_app_data;
+ uint8_t offset = 0U;
+
+ ret = snvs_read_app_data();
+ do {
+ nv_app_data_array[offset] = snvs_read_app_data_bit(offset);
+ offset++;
+
+ } while (offset < APP_DATA_MAX_OFFSET);
+ snvs_clear_app_data();
+#else
+ uintptr_t nv_base_addr = NV_STORAGE_BASE_ADDR;
+
+ ret = fspi_init(NXP_FLEXSPI_ADDR, NXP_FLEXSPI_FLASH_ADDR);
+
+ if (ret != XSPI_SUCCESS) {
+ ERROR("Failed to initialized driver flexspi-nor.\n");
+ ERROR("exiting warm-reset request.\n");
+ return -ENODEV;
+ }
+
+ xspi_read(nv_base_addr,
+ (uint32_t *)&nv_app_data, sizeof(nv_app_data_t));
+ xspi_sector_erase((uint32_t) nv_base_addr,
+ F_SECTOR_ERASE_SZ);
+#endif
+ return ret;
+}
+
+int wr_nv_app_data(int data_offset,
+ uint8_t *data,
+ int data_size)
+{
+ int ret = 0;
+#ifdef NXP_COINED_BB
+#if !TRUSTED_BOARD_BOOT
+ snvs_disable_zeroize_lp_gpr();
+#endif
+ /* In case LP SecMon General purpose register,
+ * only 1 bit flags can be saved.
+ */
+ if ((data_size > 1) || (*data != DEFAULT_SET_VALUE)) {
+ ERROR("Only binary value is allowed to be written.\n");
+ ERROR("Use flash instead of SNVS GPR as NV location.\n");
+ return -ENODEV;
+ }
+ snvs_write_app_data_bit(data_offset);
+#else
+ uint8_t read_val[sizeof(nv_app_data_t)];
+ uint8_t ready_to_write_val[sizeof(nv_app_data_t)];
+ uintptr_t nv_base_addr = NV_STORAGE_BASE_ADDR;
+
+ assert((nv_base_addr + data_offset + data_size) <= (nv_base_addr + F_SECTOR_ERASE_SZ));
+
+ ret = fspi_init(NXP_FLEXSPI_ADDR, NXP_FLEXSPI_FLASH_ADDR);
+
+ if (ret != XSPI_SUCCESS) {
+ ERROR("Failed to initialized driver flexspi-nor.\n");
+ ERROR("exiting warm-reset request.\n");
+ return -ENODEV;
+ }
+
+ ret = xspi_read(nv_base_addr + data_offset, (uint32_t *)read_val, data_size);
+
+ memset(ready_to_write_val, READY_TO_WRITE_VALUE, ARRAY_SIZE(ready_to_write_val));
+
+ if (memcmp(read_val, ready_to_write_val, data_size) == 0) {
+ xspi_write(nv_base_addr + data_offset, data, data_size);
+ }
+#endif
+
+ return ret;
+}
+
+const nv_app_data_t *get_nv_data(void)
+{
+ return (const nv_app_data_t *) &nv_app_data;
+}
diff --git a/plat/nxp/common/nv_storage/plat_nv_storage.h b/plat/nxp/common/nv_storage/plat_nv_storage.h
new file mode 100644
index 0000000..1f5264a
--- /dev/null
+++ b/plat/nxp/common/nv_storage/plat_nv_storage.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_NV_STRG_H
+#define PLAT_NV_STRG_H
+
+#define DEFAULT_SET_VALUE 0xA1
+#define READY_TO_WRITE_VALUE 0xFF
+
+#ifndef NV_STORAGE_BASE_ADDR
+#define NV_STORAGE_BASE_ADDR DEFAULT_NV_STORAGE_BASE_ADDR
+#endif
+
+typedef struct {
+uint8_t warm_rst_flag;
+uint8_t wdt_rst_flag;
+uint8_t dummy[2];
+} nv_app_data_t;
+
+
+/*below enum and above structure should be in-sync. */
+enum app_data_offset {
+ WARM_RESET_FLAG_OFFSET,
+ WDT_RESET_FLAG_OFFSET,
+ APP_DATA_MAX_OFFSET,
+};
+
+int read_nv_app_data(void);
+
+int wr_nv_app_data(int data_offset,
+ uint8_t *data,
+ int data_size);
+
+const nv_app_data_t *get_nv_data(void);
+
+#endif /* PLAT_NV_STRG_H */
diff --git a/plat/nxp/common/ocram/aarch64/ocram.S b/plat/nxp/common/ocram/aarch64/ocram.S
new file mode 100644
index 0000000..ec53341
--- /dev/null
+++ b/plat/nxp/common/ocram/aarch64/ocram.S
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+#include <soc_default_base_addr.h>
+#include <soc_default_helper_macros.h>
+
+.global ocram_init
+
+/*
+ * void ocram_init(uintptr_t start_addr, size_t size)
+ *
+ * This function will do OCRAM ECC.
+ * OCRAM is initialized with 64-bit writes and then a write
+ * performed to address 0x0010_0534 with the value 0x0000_0008.
+ *
+ * x0: start_addr
+ * x1: size in bytes
+ * Called from C
+ */
+
+func ocram_init
+ /* save the aarch32/64 non-volatile registers */
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ /* convert bytes to 64-byte chunks */
+ lsr x1, x1, #6
+1:
+ /* for each location, read and write-back */
+ dc ivac, x0
+ dsb sy
+ ldp x4, x5, [x0]
+ ldp x6, x7, [x0, #16]
+ ldp x8, x9, [x0, #32]
+ ldp x10, x11, [x0, #48]
+ stp x4, x5, [x0]
+ stp x6, x7, [x0, #16]
+ stp x8, x9, [x0, #32]
+ stp x10, x11, [x0, #48]
+ dc cvac, x0
+
+ sub x1, x1, #1
+ cbz x1, 2f
+ add x0, x0, #64
+ b 1b
+2:
+ /* Clear OCRAM ECC status bit in SBEESR2 and MBEESR2 */
+ ldr w1, =OCRAM_EESR_MASK
+ ldr x0, =DCFG_SBEESR2_ADDR
+ str w1, [x0]
+ ldr x0, =DCFG_MBEESR2_ADDR
+ str w1, [x0]
+
+ /* restore the aarch32/64 non-volatile registers */
+ ldp x18, x30, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ ret
+endfunc ocram_init
diff --git a/plat/nxp/common/ocram/ocram.h b/plat/nxp/common/ocram/ocram.h
new file mode 100644
index 0000000..479de61
--- /dev/null
+++ b/plat/nxp/common/ocram/ocram.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef OCRAM_H
+#define OCRAM_H
+
+void ocram_init(uintptr_t start_addr, size_t size);
+
+#endif /* OCRAM_H */
diff --git a/plat/nxp/common/ocram/ocram.mk b/plat/nxp/common/ocram/ocram.mk
new file mode 100644
index 0000000..c77bd4a
--- /dev/null
+++ b/plat/nxp/common/ocram/ocram.mk
@@ -0,0 +1,14 @@
+#
+# Copyright 2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+PLAT_OCRAM_PATH := $(PLAT_COMMON_PATH)/ocram
+
+OCRAM_SOURCES := ${PLAT_OCRAM_PATH}/$(ARCH)/ocram.S
+
+BL2_SOURCES += ${OCRAM_SOURCES}
+
+PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/ocram
diff --git a/plat/nxp/common/plat_make_helper/plat_build_macros.mk b/plat/nxp/common/plat_make_helper/plat_build_macros.mk
new file mode 100644
index 0000000..bba5e36
--- /dev/null
+++ b/plat/nxp/common/plat_make_helper/plat_build_macros.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2020, NXP.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+define SET_NXP_MAKE_FLAG
+$1 := yes
+$2_$1 := yes
+endef
diff --git a/plat/nxp/common/plat_make_helper/plat_common_def.mk b/plat/nxp/common/plat_make_helper/plat_common_def.mk
new file mode 100644
index 0000000..86dacf8
--- /dev/null
+++ b/plat/nxp/common/plat_make_helper/plat_common_def.mk
@@ -0,0 +1,103 @@
+# Copyright 2020-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Include build macros, for example: SET_NXP_MAKE_FLAG
+include plat/nxp/common/plat_make_helper/plat_build_macros.mk
+
+# Adding platform specific defines
+
+$(eval $(call add_define_val,BOARD,'"${BOARD}"'))
+
+ifeq (${POVDD_ENABLE},yes)
+$(eval $(call add_define,CONFIG_POVDD_ENABLE))
+endif
+
+ifneq (${FLASH_TYPE},)
+$(eval $(call add_define,CONFIG_${FLASH_TYPE}))
+endif
+
+ifneq (${XSPI_FLASH_SZ},)
+$(eval $(call add_define_val,NXP_FLEXSPI_FLASH_SIZE,${XSPI_FLASH_SZ}))
+endif
+
+ifneq (${QSPI_FLASH_SZ},)
+$(eval $(call add_define_val,NXP_QSPI_FLASH_SIZE,${QSPI_FLASH_SZ}))
+endif
+
+ifneq (${NOR_FLASH_SZ},)
+$(eval $(call add_define_val,NXP_NOR_FLASH_SIZE,${NOR_FLASH_SZ}))
+endif
+
+
+ifneq (${FSPI_ERASE_4K},)
+$(eval $(call add_define_val,CONFIG_FSPI_ERASE_4K,${FSPI_ERASE_4K}))
+endif
+
+ifneq (${NUM_OF_DDRC},)
+$(eval $(call add_define_val,NUM_OF_DDRC,${NUM_OF_DDRC}))
+endif
+
+ifeq (${CONFIG_DDR_NODIMM},1)
+$(eval $(call add_define,CONFIG_DDR_NODIMM))
+DDRC_NUM_DIMM := 1
+endif
+
+ifneq (${DDRC_NUM_DIMM},)
+$(eval $(call add_define_val,DDRC_NUM_DIMM,${DDRC_NUM_DIMM}))
+endif
+
+ifneq (${DDRC_NUM_CS},)
+$(eval $(call add_define_val,DDRC_NUM_CS,${DDRC_NUM_CS}))
+endif
+
+ifeq (${DDR_ADDR_DEC},yes)
+$(eval $(call add_define,CONFIG_DDR_ADDR_DEC))
+endif
+
+ifeq (${DDR_ECC_EN},yes)
+$(eval $(call add_define,CONFIG_DDR_ECC_EN))
+endif
+
+ifeq (${CONFIG_STATIC_DDR},1)
+$(eval $(call add_define,CONFIG_STATIC_DDR))
+endif
+
+# Platform can control the base address for non-volatile storage.
+#$(eval $(call add_define_val,NV_STORAGE_BASE_ADDR,'${BL2_BIN_XSPI_NOR_END_ADDRESS} - 2 * ${NXP_XSPI_NOR_UNIT_SIZE}'))
+
+ifeq (${WARM_BOOT},yes)
+$(eval $(call add_define_val,PHY_TRAINING_REGS_ON_FLASH,'${BL2_BIN_XSPI_NOR_END_ADDRESS} - ${NXP_XSPI_NOR_UNIT_SIZE}'))
+endif
+
+# Selecting Boot Source for the TFA images.
+define add_boot_mode_define
+ ifeq ($(1),qspi)
+ $$(eval $$(call SET_NXP_MAKE_FLAG,QSPI_NEEDED,BL2))
+ $$(eval $$(call add_define,QSPI_BOOT))
+ else ifeq ($(1),sd)
+ $$(eval $$(call SET_NXP_MAKE_FLAG,SD_MMC_NEEDED,BL2))
+ $$(eval $$(call add_define,SD_BOOT))
+ else ifeq ($(1),emmc)
+ $$(eval $$(call SET_NXP_MAKE_FLAG,SD_MMC_NEEDED,BL2))
+ $$(eval $$(call add_define,EMMC_BOOT))
+ else ifeq ($(1),nor)
+ $$(eval $$(call SET_NXP_MAKE_FLAG,IFC_NOR_NEEDED,BL2))
+ $$(eval $$(call add_define,NOR_BOOT))
+ else ifeq ($(1),nand)
+ $$(eval $$(call SET_NXP_MAKE_FLAG,IFC_NAND_NEEDED,BL2))
+ $$(eval $$(call add_define,NAND_BOOT))
+ else ifeq ($(1),flexspi_nor)
+ $$(eval $$(call SET_NXP_MAKE_FLAG,XSPI_NEEDED,BL2))
+ $$(eval $$(call add_define,FLEXSPI_NOR_BOOT))
+ else
+ $$(error $(PLAT) Cannot Support Boot Mode: $(BOOT_MODE))
+ endif
+endef
+
+ifneq (,$(findstring $(BOOT_MODE),$(SUPPORTED_BOOT_MODE)))
+ $(eval $(call add_boot_mode_define,$(strip $(BOOT_MODE))))
+else
+ $(error $(PLAT) Un-supported Boot Mode = $(BOOT_MODE))
+endif
diff --git a/plat/nxp/common/plat_make_helper/soc_common_def.mk b/plat/nxp/common/plat_make_helper/soc_common_def.mk
new file mode 100644
index 0000000..52f2867
--- /dev/null
+++ b/plat/nxp/common/plat_make_helper/soc_common_def.mk
@@ -0,0 +1,117 @@
+# Copyright 2020-2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Adding SoC specific defines
+
+ifneq (${CACHE_LINE},)
+$(eval $(call add_define_val,PLATFORM_CACHE_LINE_SHIFT,${CACHE_LINE}))
+$(eval CACHE_WRITEBACK_GRANULE=$(shell echo $$((1 << $(CACHE_LINE)))))
+$(eval $(call add_define_val,CACHE_WRITEBACK_GRANULE,$(CACHE_WRITEBACK_GRANULE)))
+endif
+
+ifneq (${INTERCONNECT},)
+$(eval $(call add_define,NXP_HAS_${INTERCONNECT}))
+ifeq (${INTERCONNECT}, CCI400)
+ICNNCT_ID := 0x420
+$(eval $(call add_define,ICNNCT_ID))
+endif
+endif
+
+ifneq (${CHASSIS},)
+$(eval $(call add_define,CONFIG_CHASSIS_${CHASSIS}))
+endif
+
+ifneq (${PLAT_DDR_PHY},)
+$(eval $(call add_define,NXP_DDR_${PLAT_DDR_PHY}))
+endif
+
+ifneq (${PHYS_SYS},)
+$(eval $(call add_define,CONFIG_PHYS_64BIT))
+endif
+
+ifneq (${CSF_HDR_SZ},)
+$(eval $(call add_define_val,CSF_HDR_SZ,${CSF_HDR_SZ}))
+endif
+
+ifneq (${OCRAM_START_ADDR},)
+$(eval $(call add_define_val,NXP_OCRAM_ADDR,${OCRAM_START_ADDR}))
+endif
+
+ifneq (${OCRAM_SIZE},)
+$(eval $(call add_define_val,NXP_OCRAM_SIZE,${OCRAM_SIZE}))
+endif
+
+ifneq (${NXP_ROM_RSVD},)
+$(eval $(call add_define_val,NXP_ROM_RSVD,${NXP_ROM_RSVD}))
+endif
+
+ifneq (${BL2_BASE},)
+$(eval $(call add_define_val,BL2_BASE,${BL2_BASE}))
+endif
+
+ifeq (${SEC_MEM_NON_COHERENT},yes)
+$(eval $(call add_define,SEC_MEM_NON_COHERENT))
+endif
+
+ifneq (${NXP_ESDHC_ENDIANNESS},)
+$(eval $(call add_define,NXP_ESDHC_${NXP_ESDHC_ENDIANNESS}))
+endif
+
+ifneq (${NXP_SFP_VER},)
+$(eval $(call add_define,NXP_SFP_VER_${NXP_SFP_VER}))
+endif
+
+ifneq (${NXP_SFP_ENDIANNESS},)
+$(eval $(call add_define,NXP_SFP_${NXP_SFP_ENDIANNESS}))
+endif
+
+ifneq (${NXP_GPIO_ENDIANNESS},)
+$(eval $(call add_define,NXP_GPIO_${NXP_GPIO_ENDIANNESS}))
+endif
+
+ifneq (${NXP_SNVS_ENDIANNESS},)
+$(eval $(call add_define,NXP_SNVS_${NXP_SNVS_ENDIANNESS}))
+endif
+
+ifneq (${NXP_GUR_ENDIANNESS},)
+$(eval $(call add_define,NXP_GUR_${NXP_GUR_ENDIANNESS}))
+endif
+
+ifneq (${NXP_FSPI_ENDIANNESS},)
+$(eval $(call add_define,NXP_FSPI_${NXP_FSPI_ENDIANNESS}))
+endif
+
+ifneq (${NXP_SEC_ENDIANNESS},)
+$(eval $(call add_define,NXP_SEC_${NXP_SEC_ENDIANNESS}))
+endif
+
+ifneq (${NXP_DDR_ENDIANNESS},)
+$(eval $(call add_define,NXP_DDR_${NXP_DDR_ENDIANNESS}))
+endif
+
+ifneq (${NXP_QSPI_ENDIANNESS},)
+$(eval $(call add_define,NXP_QSPI_${NXP_QSPI_ENDIANNESS}))
+endif
+
+ifneq (${NXP_SCFG_ENDIANNESS},)
+$(eval $(call add_define,NXP_SCFG_${NXP_SCFG_ENDIANNESS}))
+endif
+
+ifneq (${NXP_IFC_ENDIANNESS},)
+$(eval $(call add_define,NXP_IFC_${NXP_IFC_ENDIANNESS}))
+endif
+
+ifneq (${NXP_DDR_INTLV_256B},)
+$(eval $(call add_define,NXP_DDR_INTLV_256B))
+endif
+
+ifneq (${PLAT_XLAT_TABLES_DYNAMIC},)
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+endif
+
+ifeq (${OCRAM_ECC_EN},yes)
+$(eval $(call add_define,CONFIG_OCRAM_ECC_EN))
+include ${PLAT_COMMON_PATH}/ocram/ocram.mk
+endif
diff --git a/plat/nxp/common/psci/aarch64/psci_utils.S b/plat/nxp/common/psci/aarch64/psci_utils.S
new file mode 100644
index 0000000..ec69aea
--- /dev/null
+++ b/plat/nxp/common/psci/aarch64/psci_utils.S
@@ -0,0 +1,1155 @@
+
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <asm_macros.S>
+#include <assert_macros.S>
+
+#include <lib/psci/psci.h>
+
+#include <bl31_data.h>
+#include <plat_psci.h>
+
+
+#define RESET_RETRY_CNT 800
+#define PSCI_ABORT_CNT 100
+
+#if (SOC_CORE_RELEASE)
+
+.global _psci_cpu_on
+
+/*
+ * int _psci_cpu_on(u_register_t core_mask)
+ * x0 = target cpu core mask
+ *
+ * Called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ *
+ */
+
+func _psci_cpu_on
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ mov x6, x0
+
+ /* x0 = core mask (lsb)
+ * x6 = core mask (lsb)
+ */
+
+ /* check if core disabled */
+ bl _soc_ck_disabled /* 0-2 */
+ cbnz w0, psci_disabled
+
+ /* check core data area to see if core cannot be turned on
+ * read the core state
+ */
+ mov x0, x6
+ bl _getCoreState /* 0-5 */
+ mov x9, x0
+
+ /* x6 = core mask (lsb)
+ * x9 = core state (from data area)
+ */
+
+ cmp x9, #CORE_DISABLED
+ mov x0, #PSCI_E_DISABLED
+ b.eq cpu_on_done
+
+ cmp x9, #CORE_PENDING
+ mov x0, #PSCI_E_ON_PENDING
+ b.eq cpu_on_done
+
+ cmp x9, #CORE_RELEASED
+ mov x0, #PSCI_E_ALREADY_ON
+ b.eq cpu_on_done
+
+8:
+ /* x6 = core mask (lsb)
+ * x9 = core state (from data area)
+ */
+
+ cmp x9, #CORE_WFE
+ b.eq core_in_wfe
+ cmp x9, #CORE_IN_RESET
+ b.eq core_in_reset
+ cmp x9, #CORE_OFF
+ b.eq core_is_off
+ cmp x9, #CORE_OFF_PENDING
+
+ /* if state == CORE_OFF_PENDING, set abort */
+ mov x0, x6
+ mov x1, #ABORT_FLAG_DATA
+ mov x2, #CORE_ABORT_OP
+ bl _setCoreData /* 0-3, [13-15] */
+
+ ldr x3, =PSCI_ABORT_CNT
+7:
+ /* watch for abort to take effect */
+ mov x0, x6
+ bl _getCoreState /* 0-5 */
+ cmp x0, #CORE_OFF
+ b.eq core_is_off
+ cmp x0, #CORE_PENDING
+ mov x0, #PSCI_E_SUCCESS
+ b.eq cpu_on_done
+
+ /* loop til finished */
+ sub x3, x3, #1
+ cbnz x3, 7b
+
+ /* if we didn't see either CORE_OFF or CORE_PENDING, then this
+ * core is in CORE_OFF_PENDING - exit with success, as the core will
+ * respond to the abort request
+ */
+ mov x0, #PSCI_E_SUCCESS
+ b cpu_on_done
+
+/* this is where we start up a core out of reset */
+core_in_reset:
+ /* see if the soc-specific module supports this op */
+ ldr x7, =SOC_CORE_RELEASE
+ cbnz x7, 3f
+
+ mov x0, #PSCI_E_NOT_SUPPORTED
+ b cpu_on_done
+
+ /* x6 = core mask (lsb) */
+3:
+ /* set core state in data area */
+ mov x0, x6
+ mov x1, #CORE_PENDING
+ bl _setCoreState /* 0-3, [13-15] */
+
+ /* release the core from reset */
+ mov x0, x6
+ bl _soc_core_release /* 0-3 */
+ mov x0, #PSCI_E_SUCCESS
+ b cpu_on_done
+
+ /* Start up the core that has been powered-down via CPU_OFF
+ */
+core_is_off:
+ /* see if the soc-specific module supports this op
+ */
+ ldr x7, =SOC_CORE_RESTART
+ cbnz x7, 2f
+
+ mov x0, #PSCI_E_NOT_SUPPORTED
+ b cpu_on_done
+
+ /* x6 = core mask (lsb) */
+2:
+ /* set core state in data area */
+ mov x0, x6
+ mov x1, #CORE_WAKEUP
+ bl _setCoreState /* 0-3, [13-15] */
+
+ /* put the core back into service */
+ mov x0, x6
+#if (SOC_CORE_RESTART)
+ bl _soc_core_restart /* 0-5 */
+#endif
+ mov x0, #PSCI_E_SUCCESS
+ b cpu_on_done
+
+/* this is where we release a core that is being held in wfe */
+core_in_wfe:
+ /* x6 = core mask (lsb) */
+
+ /* set core state in data area */
+ mov x0, x6
+ mov x1, #CORE_PENDING
+ bl _setCoreState /* 0-3, [13-15] */
+ dsb sy
+ isb
+
+ /* put the core back into service */
+ sev
+ sev
+ isb
+ mov x0, #PSCI_E_SUCCESS
+
+cpu_on_done:
+ /* restore the aarch32/64 non-volatile registers */
+ ldp x18, x30, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ b psci_completed
+endfunc _psci_cpu_on
+
+#endif
+
+
+#if (SOC_CORE_OFF)
+
+.global _psci_cpu_prep_off
+.global _psci_cpu_off_wfi
+
+/*
+ * void _psci_cpu_prep_off(u_register_t core_mask)
+ * this function performs the SoC-specific programming prior
+ * to shutting the core down
+ * x0 = core_mask
+ *
+ * called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+
+func _psci_cpu_prep_off
+
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ mov x10, x0 /* x10 = core_mask */
+
+ /* the core does not return from cpu_off, so no need
+ * to save/restore non-volatile registers
+ */
+
+ /* mask interrupts by setting DAIF[7:4] to 'b1111 */
+ msr DAIFSet, #0xF
+
+ /* read cpuectlr and save current value */
+ mrs x4, CPUECTLR_EL1
+ mov x1, #CPUECTLR_DATA
+ mov x2, x4
+ mov x0, x10
+ bl _setCoreData
+
+ /* remove the core from coherency */
+ bic x4, x4, #CPUECTLR_SMPEN_MASK
+ msr CPUECTLR_EL1, x4
+
+ /* save scr_el3 */
+ mov x0, x10
+ mrs x4, SCR_EL3
+ mov x2, x4
+ mov x1, #SCR_EL3_DATA
+ bl _setCoreData
+
+ /* x4 = scr_el3 */
+
+ /* secure SGI (FIQ) taken to EL3, set SCR_EL3[FIQ] */
+ orr x4, x4, #SCR_FIQ_MASK
+ msr scr_el3, x4
+
+ /* x10 = core_mask */
+
+ /* prep the core for shutdown */
+ mov x0, x10
+ bl _soc_core_prep_off
+
+ /* restore the aarch32/64 non-volatile registers */
+ ldp x18, x30, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ b psci_completed
+endfunc _psci_cpu_prep_off
+
+/*
+ * void _psci_cpu_off_wfi(u_register_t core_mask, u_register_t resume_addr)
+ * - this function shuts down the core
+ * - this function does not return!!
+ */
+
+func _psci_cpu_off_wfi
+ /* save the wakeup address */
+ mov x29, x1
+
+ /* x0 = core_mask */
+
+ /* shutdown the core */
+ bl _soc_core_entr_off
+
+ /* branch to resume execution */
+ br x29
+endfunc _psci_cpu_off_wfi
+
+#endif
+
+
+#if (SOC_CORE_RESTART)
+
+.global _psci_wakeup
+
+/*
+ * void _psci_wakeup(u_register_t core_mask)
+ * this function performs the SoC-specific programming
+ * after a core wakes up from OFF
+ * x0 = core mask
+ *
+ * called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+
+func _psci_wakeup
+
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ mov x4, x0 /* x4 = core mask */
+
+ /* restore scr_el3 */
+ mov x0, x4
+ mov x1, #SCR_EL3_DATA
+ bl _getCoreData
+ /* x0 = saved scr_el3 */
+ msr SCR_EL3, x0
+
+ /* x4 = core mask */
+
+ /* restore CPUECTLR */
+ mov x0, x4
+ mov x1, #CPUECTLR_DATA
+ bl _getCoreData
+ orr x0, x0, #CPUECTLR_SMPEN_MASK
+ msr CPUECTLR_EL1, x0
+
+ /* x4 = core mask */
+
+ /* start the core back up */
+ mov x0, x4
+ bl _soc_core_exit_off
+
+ /* restore the aarch32/64 non-volatile registers
+ */
+ ldp x18, x30, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ b psci_completed
+endfunc _psci_wakeup
+
+#endif
+
+
+#if (SOC_SYSTEM_RESET)
+
+.global _psci_system_reset
+
+func _psci_system_reset
+
+ /* system reset is mandatory
+ * system reset is soc-specific
+ * Note: under no circumstances do we return from this call
+ */
+ bl _soc_sys_reset
+endfunc _psci_system_reset
+
+#endif
+
+
+#if (SOC_SYSTEM_OFF)
+
+.global _psci_system_off
+
+func _psci_system_off
+
+ /* system off is mandatory
+ * system off is soc-specific
+ * Note: under no circumstances do we return from this call */
+ b _soc_sys_off
+endfunc _psci_system_off
+
+#endif
+
+
+#if (SOC_CORE_STANDBY)
+
+.global _psci_core_entr_stdby
+.global _psci_core_prep_stdby
+.global _psci_core_exit_stdby
+
+/*
+ * void _psci_core_entr_stdby(u_register_t core_mask) - this
+ * is the fast-path for simple core standby
+ */
+
+func _psci_core_entr_stdby
+ stp x4, x5, [sp, #-16]!
+ stp x6, x30, [sp, #-16]!
+
+ mov x5, x0 /* x5 = core mask */
+
+ /* save scr_el3 */
+ mov x0, x5
+ mrs x4, SCR_EL3
+ mov x2, x4
+ mov x1, #SCR_EL3_DATA
+ bl _setCoreData
+
+ /* x4 = SCR_EL3
+ * x5 = core mask
+ */
+
+ /* allow interrupts @ EL3 */
+ orr x4, x4, #(SCR_IRQ_MASK | SCR_FIQ_MASK)
+ msr SCR_EL3, x4
+
+ /* x5 = core mask */
+
+ /* put the core into standby */
+ mov x0, x5
+ bl _soc_core_entr_stdby
+
+ /* restore scr_el3 */
+ mov x0, x5
+ mov x1, #SCR_EL3_DATA
+ bl _getCoreData
+ /* x0 = saved scr_el3 */
+ msr SCR_EL3, x0
+
+ ldp x6, x30, [sp], #16
+ ldp x4, x5, [sp], #16
+ isb
+ ret
+endfunc _psci_core_entr_stdby
+
+/*
+ * void _psci_core_prep_stdby(u_register_t core_mask) - this
+ * sets up the core to enter standby state thru the normal path
+ */
+
+func _psci_core_prep_stdby
+ stp x4, x5, [sp, #-16]!
+ stp x6, x30, [sp, #-16]!
+
+ mov x5, x0
+
+ /* x5 = core mask */
+
+ /* save scr_el3 */
+ mov x0, x5
+ mrs x4, SCR_EL3
+ mov x2, x4
+ mov x1, #SCR_EL3_DATA
+ bl _setCoreData
+
+ /* allow interrupts @ EL3 */
+ orr x4, x4, #(SCR_IRQ_MASK | SCR_FIQ_MASK)
+ msr SCR_EL3, x4
+
+ /* x5 = core mask */
+
+ /* call for any SoC-specific programming */
+ mov x0, x5
+ bl _soc_core_prep_stdby
+
+ ldp x6, x30, [sp], #16
+ ldp x4, x5, [sp], #16
+ isb
+ ret
+endfunc _psci_core_prep_stdby
+
+/*
+ * void _psci_core_exit_stdby(u_register_t core_mask) - this
+ * exits the core from standby state thru the normal path
+ */
+
+func _psci_core_exit_stdby
+ stp x4, x5, [sp, #-16]!
+ stp x6, x30, [sp, #-16]!
+
+ mov x5, x0
+
+ /* x5 = core mask */
+
+ /* restore scr_el3 */
+ mov x0, x5
+ mov x1, #SCR_EL3_DATA
+ bl _getCoreData
+ /* x0 = saved scr_el3 */
+ msr SCR_EL3, x0
+
+ /* x5 = core mask */
+
+ /* perform any SoC-specific programming after standby state */
+ mov x0, x5
+ bl _soc_core_exit_stdby
+
+ ldp x6, x30, [sp], #16
+ ldp x4, x5, [sp], #16
+ isb
+ ret
+endfunc _psci_core_exit_stdby
+
+#endif
+
+
+#if (SOC_CORE_PWR_DWN)
+
+.global _psci_core_prep_pwrdn
+.global _psci_cpu_pwrdn_wfi
+.global _psci_core_exit_pwrdn
+
+/*
+ * void _psci_core_prep_pwrdn_(u_register_t core_mask)
+ * this function prepares the core for power-down
+ * x0 = core mask
+ *
+ * called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+
+func _psci_core_prep_pwrdn
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ mov x6, x0
+
+ /* x6 = core mask */
+
+ /* mask interrupts by setting DAIF[7:4] to 'b1111 */
+ msr DAIFSet, #0xF
+
+ /* save scr_el3 */
+ mov x0, x6
+ mrs x4, SCR_EL3
+ mov x2, x4
+ mov x1, #SCR_EL3_DATA
+ bl _setCoreData
+
+ /* allow interrupts @ EL3 */
+ orr x4, x4, #(SCR_IRQ_MASK | SCR_FIQ_MASK)
+ msr SCR_EL3, x4
+
+ /* save cpuectlr */
+ mov x0, x6
+ mov x1, #CPUECTLR_DATA
+ mrs x2, CPUECTLR_EL1
+ bl _setCoreData
+
+ /* x6 = core mask */
+
+ /* SoC-specific programming for power-down */
+ mov x0, x6
+ bl _soc_core_prep_pwrdn
+
+ /* restore the aarch32/64 non-volatile registers
+ */
+ ldp x18, x30, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ b psci_completed
+endfunc _psci_core_prep_pwrdn
+
+/*
+ * void _psci_cpu_pwrdn_wfi(u_register_t core_mask, u_register_t resume_addr)
+ * this function powers down the core
+ */
+
+func _psci_cpu_pwrdn_wfi
+ /* save the wakeup address */
+ mov x29, x1
+
+ /* x0 = core mask */
+
+ /* shutdown the core */
+ bl _soc_core_entr_pwrdn
+
+ /* branch to resume execution */
+ br x29
+endfunc _psci_cpu_pwrdn_wfi
+
+/*
+ * void _psci_core_exit_pwrdn_(u_register_t core_mask)
+ * this function cleans up after a core power-down
+ * x0 = core mask
+ *
+ * called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+
+func _psci_core_exit_pwrdn
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ mov x5, x0 /* x5 = core mask */
+
+ /* restore scr_el3 */
+ mov x0, x5
+ mov x1, #SCR_EL3_DATA
+ bl _getCoreData
+ /* x0 = saved scr_el3 */
+ msr SCR_EL3, x0
+
+ /* x5 = core mask */
+
+ /* restore cpuectlr */
+ mov x0, x5
+ mov x1, #CPUECTLR_DATA
+ bl _getCoreData
+ /* make sure smp is set */
+ orr x0, x0, #CPUECTLR_SMPEN_MASK
+ msr CPUECTLR_EL1, x0
+
+ /* x5 = core mask */
+
+ /* SoC-specific cleanup */
+ mov x0, x5
+ bl _soc_core_exit_pwrdn
+
+ /* restore the aarch32/64 non-volatile registers
+ */
+ ldp x18, x30, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ b psci_completed
+endfunc _psci_core_exit_pwrdn
+
+#endif
+
+#if (SOC_CLUSTER_STANDBY)
+
+.global _psci_clstr_prep_stdby
+.global _psci_clstr_exit_stdby
+
+/*
+ * void _psci_clstr_prep_stdby(u_register_t core_mask) - this
+ * sets up the clstr to enter standby state thru the normal path
+ */
+
+func _psci_clstr_prep_stdby
+ stp x4, x5, [sp, #-16]!
+ stp x6, x30, [sp, #-16]!
+
+ mov x5, x0
+
+ /* x5 = core mask */
+
+ /* save scr_el3 */
+ mov x0, x5
+ mrs x4, SCR_EL3
+ mov x2, x4
+ mov x1, #SCR_EL3_DATA
+ bl _setCoreData
+
+ /* allow interrupts @ EL3 */
+ orr x4, x4, #(SCR_IRQ_MASK | SCR_FIQ_MASK)
+ msr SCR_EL3, x4
+
+ /* x5 = core mask */
+
+ /* call for any SoC-specific programming */
+ mov x0, x5
+ bl _soc_clstr_prep_stdby
+
+ ldp x6, x30, [sp], #16
+ ldp x4, x5, [sp], #16
+ isb
+ ret
+endfunc _psci_clstr_prep_stdby
+
+/*
+ * void _psci_clstr_exit_stdby(u_register_t core_mask) - this
+ * exits the clstr from standby state thru the normal path
+ */
+
+func _psci_clstr_exit_stdby
+ stp x4, x5, [sp, #-16]!
+ stp x6, x30, [sp, #-16]!
+
+ mov x5, x0 /* x5 = core mask */
+
+ /* restore scr_el3 */
+ mov x0, x5
+ mov x1, #SCR_EL3_DATA
+ bl _getCoreData
+ /* x0 = saved scr_el3 */
+ msr SCR_EL3, x0
+
+ /* x5 = core mask */
+
+ /* perform any SoC-specific programming after standby state */
+ mov x0, x5
+ bl _soc_clstr_exit_stdby
+
+ ldp x6, x30, [sp], #16
+ ldp x4, x5, [sp], #16
+ isb
+ ret
+endfunc _psci_clstr_exit_stdby
+
+#endif
+
+#if (SOC_CLUSTER_PWR_DWN)
+
+.global _psci_clstr_prep_pwrdn
+.global _psci_clstr_exit_pwrdn
+
+/*
+ * void _psci_clstr_prep_pwrdn_(u_register_t core_mask)
+ * this function prepares the cluster+core for power-down
+ * x0 = core mask
+ *
+ * called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+
+func _psci_clstr_prep_pwrdn
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ mov x6, x0 /* x6 = core mask */
+
+ /* mask interrupts by setting DAIF[7:4] to 'b1111 */
+ msr DAIFSet, #0xF
+
+ /* save scr_el3 */
+ mov x0, x6
+ mrs x4, SCR_EL3
+ mov x2, x4
+ mov x1, #SCR_EL3_DATA
+ bl _setCoreData
+
+ /* allow interrupts @ EL3 */
+ orr x4, x4, #(SCR_IRQ_MASK | SCR_FIQ_MASK)
+ msr SCR_EL3, x4
+
+ /* save cpuectlr */
+ mov x0, x6
+ mov x1, #CPUECTLR_DATA
+ mrs x2, CPUECTLR_EL1
+ mov x4, x2
+ bl _setCoreData
+
+ /* remove core from coherency */
+ bic x4, x4, #CPUECTLR_SMPEN_MASK
+ msr CPUECTLR_EL1, x4
+
+ /* x6 = core mask */
+
+ /* SoC-specific programming for power-down */
+ mov x0, x6
+ bl _soc_clstr_prep_pwrdn
+
+ /* restore the aarch32/64 non-volatile registers
+ */
+ ldp x18, x30, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ b psci_completed
+endfunc _psci_clstr_prep_pwrdn
+
+/*
+ * void _psci_clstr_exit_pwrdn_(u_register_t core_mask)
+ * this function cleans up after a cluster power-down
+ * x0 = core mask
+ *
+ * called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+
+func _psci_clstr_exit_pwrdn
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ mov x4, x0 /* x4 = core mask */
+
+ /* restore scr_el3 */
+ mov x0, x4
+ mov x1, #SCR_EL3_DATA
+ bl _getCoreData
+ /* x0 = saved scr_el3 */
+ msr SCR_EL3, x0
+
+ /* x4 = core mask */
+
+ /* restore cpuectlr */
+ mov x0, x4
+ mov x1, #CPUECTLR_DATA
+ bl _getCoreData
+ /* make sure smp is set */
+ orr x0, x0, #CPUECTLR_SMPEN_MASK
+ msr CPUECTLR_EL1, x0
+
+ /* x4 = core mask */
+
+ /* SoC-specific cleanup */
+ mov x0, x4
+ bl _soc_clstr_exit_pwrdn
+
+ /* restore the aarch32/64 non-volatile registers
+ */
+ ldp x18, x30, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ b psci_completed
+endfunc _psci_clstr_exit_pwrdn
+
+#endif
+
+#if (SOC_SYSTEM_STANDBY)
+
+.global _psci_sys_prep_stdby
+.global _psci_sys_exit_stdby
+
+/*
+ * void _psci_sys_prep_stdby(u_register_t core_mask) - this
+ * sets up the system to enter standby state thru the normal path
+ */
+
+func _psci_sys_prep_stdby
+ stp x4, x5, [sp, #-16]!
+ stp x6, x30, [sp, #-16]!
+
+ mov x5, x0 /* x5 = core mask */
+
+ /* save scr_el3 */
+ mov x0, x5
+ mrs x4, SCR_EL3
+ mov x2, x4
+ mov x1, #SCR_EL3_DATA
+ bl _setCoreData
+
+ /* allow interrupts @ EL3 */
+ orr x4, x4, #(SCR_IRQ_MASK | SCR_FIQ_MASK)
+ msr SCR_EL3, x4
+
+ /* x5 = core mask */
+
+ /* call for any SoC-specific programming */
+ mov x0, x5
+ bl _soc_sys_prep_stdby
+
+ ldp x6, x30, [sp], #16
+ ldp x4, x5, [sp], #16
+ isb
+ ret
+endfunc _psci_sys_prep_stdby
+
+/*
+ * void _psci_sys_exit_stdby(u_register_t core_mask) - this
+ * exits the system from standby state thru the normal path
+ */
+
+func _psci_sys_exit_stdby
+ stp x4, x5, [sp, #-16]!
+ stp x6, x30, [sp, #-16]!
+
+ mov x5, x0
+
+ /* x5 = core mask */
+
+ /* restore scr_el3 */
+ mov x0, x5
+ mov x1, #SCR_EL3_DATA
+ bl _getCoreData
+ /* x0 = saved scr_el3 */
+ msr SCR_EL3, x0
+
+ /* x5 = core mask */
+
+ /* perform any SoC-specific programming after standby state */
+ mov x0, x5
+ bl _soc_sys_exit_stdby
+
+ ldp x6, x30, [sp], #16
+ ldp x4, x5, [sp], #16
+ isb
+ ret
+endfunc _psci_sys_exit_stdby
+
+#endif
+
+#if (SOC_SYSTEM_PWR_DWN)
+
+.global _psci_sys_prep_pwrdn
+.global _psci_sys_pwrdn_wfi
+.global _psci_sys_exit_pwrdn
+
+/*
+ * void _psci_sys_prep_pwrdn_(u_register_t core_mask)
+ * this function prepares the system+core for power-down
+ * x0 = core mask
+ *
+ * called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+
+func _psci_sys_prep_pwrdn
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ mov x6, x0 /* x6 = core mask */
+
+ /* mask interrupts by setting DAIF[7:4] to 'b1111 */
+ msr DAIFSet, #0xF
+
+ /* save scr_el3 */
+ mov x0, x6
+ mrs x4, SCR_EL3
+ mov x2, x4
+ mov x1, #SCR_EL3_DATA
+ bl _setCoreData
+
+ /* allow interrupts @ EL3 */
+ orr x4, x4, #(SCR_IRQ_MASK | SCR_FIQ_MASK)
+ msr SCR_EL3, x4
+
+ /* save cpuectlr */
+ mov x0, x6
+ mov x1, #CPUECTLR_DATA
+ mrs x2, CPUECTLR_EL1
+ mov x4, x2
+ bl _setCoreData
+
+ /* remove core from coherency */
+ bic x4, x4, #CPUECTLR_SMPEN_MASK
+ msr CPUECTLR_EL1, x4
+
+ /* x6 = core mask */
+
+ /* SoC-specific programming for power-down */
+ mov x0, x6
+ bl _soc_sys_prep_pwrdn
+
+ /* restore the aarch32/64 non-volatile registers
+ */
+ ldp x18, x30, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ b psci_completed
+endfunc _psci_sys_prep_pwrdn
+
+
+/*
+ * void _psci_sys_pwrdn_wfi(u_register_t core_mask, u_register_t resume_addr)
+ * this function powers down the system
+ */
+
+func _psci_sys_pwrdn_wfi
+ /* save the wakeup address */
+ mov x29, x1
+
+ /* x0 = core mask */
+
+ /* shutdown the system */
+ bl _soc_sys_pwrdn_wfi
+
+ /* branch to resume execution */
+ br x29
+endfunc _psci_sys_pwrdn_wfi
+
+/*
+ * void _psci_sys_exit_pwrdn_(u_register_t core_mask)
+ * this function cleans up after a system power-down
+ * x0 = core mask
+ *
+ * Called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+
+func _psci_sys_exit_pwrdn
+
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ mov x4, x0 /* x4 = core mask */
+
+ /* restore scr_el3 */
+ mov x0, x4
+ mov x1, #SCR_EL3_DATA
+ bl _getCoreData
+
+ /* x0 = saved scr_el3 */
+ msr SCR_EL3, x0
+
+ /* x4 = core mask */
+
+ /* restore cpuectlr */
+ mov x0, x4
+ mov x1, #CPUECTLR_DATA
+ bl _getCoreData
+
+ /* make sure smp is set */
+ orr x0, x0, #CPUECTLR_SMPEN_MASK
+ msr CPUECTLR_EL1, x0
+
+ /* x4 = core mask */
+
+ /* SoC-specific cleanup */
+ mov x0, x4
+ bl _soc_sys_exit_pwrdn
+
+ /* restore the aarch32/64 non-volatile registers
+ */
+ ldp x18, x30, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ b psci_completed
+endfunc _psci_sys_exit_pwrdn
+
+#endif
+
+
+/* psci std returns */
+func psci_disabled
+ ldr w0, =PSCI_E_DISABLED
+ b psci_completed
+endfunc psci_disabled
+
+
+func psci_not_present
+ ldr w0, =PSCI_E_NOT_PRESENT
+ b psci_completed
+endfunc psci_not_present
+
+
+func psci_on_pending
+ ldr w0, =PSCI_E_ON_PENDING
+ b psci_completed
+endfunc psci_on_pending
+
+
+func psci_already_on
+ ldr w0, =PSCI_E_ALREADY_ON
+ b psci_completed
+endfunc psci_already_on
+
+
+func psci_failure
+ ldr w0, =PSCI_E_INTERN_FAIL
+ b psci_completed
+endfunc psci_failure
+
+
+func psci_unimplemented
+ ldr w0, =PSCI_E_NOT_SUPPORTED
+ b psci_completed
+endfunc psci_unimplemented
+
+
+func psci_denied
+ ldr w0, =PSCI_E_DENIED
+ b psci_completed
+endfunc psci_denied
+
+
+func psci_invalid
+ ldr w0, =PSCI_E_INVALID_PARAMS
+ b psci_completed
+endfunc psci_invalid
+
+
+func psci_success
+ mov x0, #PSCI_E_SUCCESS
+endfunc psci_success
+
+
+func psci_completed
+ /* x0 = status code */
+ ret
+endfunc psci_completed
diff --git a/plat/nxp/common/psci/include/plat_psci.h b/plat/nxp/common/psci/include/plat_psci.h
new file mode 100644
index 0000000..7fc48fb
--- /dev/null
+++ b/plat/nxp/common/psci/include/plat_psci.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_PSCI_H
+#define PLAT_PSCI_H
+#include <cortex_a53.h>
+#include <cortex_a72.h>
+
+ /* core abort current op */
+#define CORE_ABORT_OP 0x1
+
+ /* psci power levels - these are actually affinity levels
+ * in the psci_power_state_t array
+ */
+#define PLAT_CORE_LVL PSCI_CPU_PWR_LVL
+#define PLAT_CLSTR_LVL U(1)
+#define PLAT_SYS_LVL U(2)
+#define PLAT_MAX_LVL PLAT_SYS_LVL
+
+ /* core state */
+ /* OFF states 0x0 - 0xF */
+#define CORE_IN_RESET 0x0
+#define CORE_DISABLED 0x1
+#define CORE_OFF 0x2
+#define CORE_STANDBY 0x3
+#define CORE_PWR_DOWN 0x4
+#define CORE_WFE 0x6
+#define CORE_WFI 0x7
+#define CORE_LAST 0x8
+#define CORE_OFF_PENDING 0x9
+#define CORE_WORKING_INIT 0xA
+#define SYS_OFF_PENDING 0xB
+#define SYS_OFF 0xC
+
+ /* ON states 0x10 - 0x1F */
+#define CORE_PENDING 0x10
+#define CORE_RELEASED 0x11
+#define CORE_WAKEUP 0x12
+ /* highest off state */
+#define CORE_OFF_MAX 0xF
+ /* lowest on state */
+#define CORE_ON_MIN CORE_PENDING
+
+#define DAIF_SET_MASK 0x3C0
+#define SCTLR_I_C_M_MASK 0x00001005
+#define SCTLR_C_MASK 0x00000004
+#define SCTLR_I_MASK 0x00001000
+#define CPUACTLR_L1PCTL_MASK 0x0000E000
+#define DCSR_RCPM2_BASE 0x20170000
+#define CPUECTLR_SMPEN_MASK 0x40
+#define CPUECTLR_SMPEN_EN 0x40
+#define CPUECTLR_RET_MASK 0x7
+#define CPUECTLR_RET_SET 0x2
+#define CPUECTLR_TIMER_MASK 0x7
+#define CPUECTLR_TIMER_8TICKS 0x2
+#define CPUECTLR_TIMER_2TICKS 0x1
+#define SCR_IRQ_MASK 0x2
+#define SCR_FIQ_MASK 0x4
+
+/* pwr mgmt features supported in the soc-specific code:
+ * value == 0x0, the soc code does not support this feature
+ * value != 0x0, the soc code supports this feature
+ */
+#ifndef SOC_CORE_RELEASE
+#define SOC_CORE_RELEASE 0x1
+#endif
+
+#ifndef SOC_CORE_RESTART
+#define SOC_CORE_RESTART 0x1
+#endif
+
+#ifndef SOC_CORE_OFF
+#define SOC_CORE_OFF 0x1
+#endif
+
+#ifndef SOC_CORE_STANDBY
+#define SOC_CORE_STANDBY 0x1
+#endif
+
+#ifndef SOC_CORE_PWR_DWN
+#define SOC_CORE_PWR_DWN 0x1
+#endif
+
+#ifndef SOC_CLUSTER_STANDBY
+#define SOC_CLUSTER_STANDBY 0x1
+#endif
+
+#ifndef SOC_CLUSTER_PWR_DWN
+#define SOC_CLUSTER_PWR_DWN 0x1
+#endif
+
+#ifndef SOC_SYSTEM_STANDBY
+#define SOC_SYSTEM_STANDBY 0x1
+#endif
+
+#ifndef SOC_SYSTEM_PWR_DWN
+#define SOC_SYSTEM_PWR_DWN 0x1
+#endif
+
+#ifndef SOC_SYSTEM_OFF
+#define SOC_SYSTEM_OFF 0x1
+#endif
+
+#ifndef SOC_SYSTEM_RESET
+#define SOC_SYSTEM_RESET 0x1
+#endif
+
+#ifndef SOC_SYSTEM_RESET2
+#define SOC_SYSTEM_RESET2 0x1
+#endif
+
+#ifndef __ASSEMBLER__
+
+void __dead2 _psci_system_reset(void);
+void __dead2 _psci_system_off(void);
+int _psci_cpu_on(u_register_t core_mask);
+void _psci_cpu_prep_off(u_register_t core_mask);
+void __dead2 _psci_cpu_off_wfi(u_register_t core_mask,
+ u_register_t wakeup_address);
+void __dead2 _psci_cpu_pwrdn_wfi(u_register_t core_mask,
+ u_register_t wakeup_address);
+void __dead2 _psci_sys_pwrdn_wfi(u_register_t core_mask,
+ u_register_t wakeup_address);
+void _psci_wakeup(u_register_t core_mask);
+void _psci_core_entr_stdby(u_register_t core_mask);
+void _psci_core_prep_stdby(u_register_t core_mask);
+void _psci_core_exit_stdby(u_register_t core_mask);
+void _psci_core_prep_pwrdn(u_register_t core_mask);
+void _psci_core_exit_pwrdn(u_register_t core_mask);
+void _psci_clstr_prep_stdby(u_register_t core_mask);
+void _psci_clstr_exit_stdby(u_register_t core_mask);
+void _psci_clstr_prep_pwrdn(u_register_t core_mask);
+void _psci_clstr_exit_pwrdn(u_register_t core_mask);
+void _psci_sys_prep_stdby(u_register_t core_mask);
+void _psci_sys_exit_stdby(u_register_t core_mask);
+void _psci_sys_prep_pwrdn(u_register_t core_mask);
+void _psci_sys_exit_pwrdn(u_register_t core_mask);
+
+#endif
+
+#endif /* __PLAT_PSCI_H__ */
diff --git a/plat/nxp/common/psci/plat_psci.c b/plat/nxp/common/psci/plat_psci.c
new file mode 100644
index 0000000..f6dd7b3
--- /dev/null
+++ b/plat/nxp/common/psci/plat_psci.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <common/debug.h>
+
+#include <plat_gic.h>
+#include <plat_common.h>
+#include <plat_psci.h>
+#ifdef NXP_WARM_BOOT
+#include <plat_warm_rst.h>
+#endif
+
+#include <platform_def.h>
+
+#if (SOC_CORE_OFF || SOC_CORE_PWR_DWN)
+static void __dead2 _no_return_wfi(void)
+{
+_bl31_dead_wfi:
+ wfi();
+ goto _bl31_dead_wfi;
+}
+#endif
+
+#if (SOC_CORE_RELEASE || SOC_CORE_PWR_DWN)
+ /* the entry for core warm boot */
+static uintptr_t warmboot_entry = (uintptr_t) NULL;
+#endif
+
+#if (SOC_CORE_RELEASE)
+static int _pwr_domain_on(u_register_t mpidr)
+{
+ int core_pos = plat_core_pos(mpidr);
+ int rc = PSCI_E_INVALID_PARAMS;
+ u_register_t core_mask;
+
+ if (core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT) {
+
+ _soc_set_start_addr(warmboot_entry);
+
+ dsb();
+ isb();
+
+ core_mask = (1 << core_pos);
+ rc = _psci_cpu_on(core_mask);
+ }
+
+ return (rc);
+}
+#endif
+
+#if (SOC_CORE_OFF)
+static void _pwr_domain_off(const psci_power_state_t *target_state)
+{
+ u_register_t core_mask = plat_my_core_mask();
+ u_register_t core_state = _getCoreState(core_mask);
+
+ /* set core state in internal data */
+ core_state = CORE_OFF_PENDING;
+ _setCoreState(core_mask, core_state);
+
+ _psci_cpu_prep_off(core_mask);
+}
+#endif
+
+#if (SOC_CORE_OFF || SOC_CORE_PWR_DWN)
+static void __dead2 _pwr_down_wfi(const psci_power_state_t *target_state)
+{
+ u_register_t core_mask = plat_my_core_mask();
+ u_register_t core_state = _getCoreState(core_mask);
+
+ switch (core_state) {
+#if (SOC_CORE_OFF)
+ case CORE_OFF_PENDING:
+ /* set core state in internal data */
+ core_state = CORE_OFF;
+ _setCoreState(core_mask, core_state);
+
+ /* turn the core off */
+ _psci_cpu_off_wfi(core_mask, warmboot_entry);
+ break;
+#endif
+#if (SOC_CORE_PWR_DWN)
+ case CORE_PWR_DOWN:
+ /* power-down the core */
+ _psci_cpu_pwrdn_wfi(core_mask, warmboot_entry);
+ break;
+#endif
+#if (SOC_SYSTEM_PWR_DWN)
+ case SYS_OFF_PENDING:
+ /* set core state in internal data */
+ core_state = SYS_OFF;
+ _setCoreState(core_mask, core_state);
+
+ /* power-down the system */
+ _psci_sys_pwrdn_wfi(core_mask, warmboot_entry);
+ break;
+#endif
+ default:
+ _no_return_wfi();
+ break;
+ }
+}
+#endif
+
+#if (SOC_CORE_RELEASE || SOC_CORE_RESTART)
+static void _pwr_domain_wakeup(const psci_power_state_t *target_state)
+{
+ u_register_t core_mask = plat_my_core_mask();
+ u_register_t core_state = _getCoreState(core_mask);
+
+ switch (core_state) {
+ case CORE_PENDING: /* this core is coming out of reset */
+
+ /* soc per cpu setup */
+ soc_init_percpu();
+
+ /* gic per cpu setup */
+ plat_gic_pcpu_init();
+
+ /* set core state in internal data */
+ core_state = CORE_RELEASED;
+ _setCoreState(core_mask, core_state);
+ break;
+
+#if (SOC_CORE_RESTART)
+ case CORE_WAKEUP:
+
+ /* this core is waking up from OFF */
+ _psci_wakeup(core_mask);
+
+ /* set core state in internal data */
+ core_state = CORE_RELEASED;
+ _setCoreState(core_mask, core_state);
+
+ break;
+#endif
+ }
+}
+#endif
+
+#if (SOC_CORE_STANDBY)
+static void _pwr_cpu_standby(plat_local_state_t cpu_state)
+{
+ u_register_t core_mask = plat_my_core_mask();
+ u_register_t core_state;
+
+ if (cpu_state == PLAT_MAX_RET_STATE) {
+
+ /* set core state to standby */
+ core_state = CORE_STANDBY;
+ _setCoreState(core_mask, core_state);
+
+ _psci_core_entr_stdby(core_mask);
+
+ /* when we are here, the core is waking up
+ * set core state to released
+ */
+ core_state = CORE_RELEASED;
+ _setCoreState(core_mask, core_state);
+ }
+}
+#endif
+
+#if (SOC_CORE_PWR_DWN)
+static void _pwr_suspend(const psci_power_state_t *state)
+{
+
+ u_register_t core_mask = plat_my_core_mask();
+ u_register_t core_state;
+
+ if (state->pwr_domain_state[PLAT_MAX_LVL] == PLAT_MAX_OFF_STATE) {
+#if (SOC_SYSTEM_PWR_DWN)
+ _psci_sys_prep_pwrdn(core_mask);
+
+ /* set core state */
+ core_state = SYS_OFF_PENDING;
+ _setCoreState(core_mask, core_state);
+#endif
+ } else if (state->pwr_domain_state[PLAT_MAX_LVL]
+ == PLAT_MAX_RET_STATE) {
+#if (SOC_SYSTEM_STANDBY)
+ _psci_sys_prep_stdby(core_mask);
+
+ /* set core state */
+ core_state = CORE_STANDBY;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+ else if (state->pwr_domain_state[PLAT_CLSTR_LVL] ==
+ PLAT_MAX_OFF_STATE) {
+#if (SOC_CLUSTER_PWR_DWN)
+ _psci_clstr_prep_pwrdn(core_mask);
+
+ /* set core state */
+ core_state = CORE_PWR_DOWN;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+ else if (state->pwr_domain_state[PLAT_CLSTR_LVL] ==
+ PLAT_MAX_RET_STATE) {
+#if (SOC_CLUSTER_STANDBY)
+ _psci_clstr_prep_stdby(core_mask);
+
+ /* set core state */
+ core_state = CORE_STANDBY;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+ else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_OFF_STATE) {
+#if (SOC_CORE_PWR_DWN)
+ /* prep the core for power-down */
+ _psci_core_prep_pwrdn(core_mask);
+
+ /* set core state */
+ core_state = CORE_PWR_DOWN;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+ else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_RET_STATE) {
+#if (SOC_CORE_STANDBY)
+ _psci_core_prep_stdby(core_mask);
+
+ /* set core state */
+ core_state = CORE_STANDBY;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+}
+#endif
+
+#if (SOC_CORE_PWR_DWN)
+static void _pwr_suspend_finish(const psci_power_state_t *state)
+{
+
+ u_register_t core_mask = plat_my_core_mask();
+ u_register_t core_state;
+
+
+ if (state->pwr_domain_state[PLAT_MAX_LVL] == PLAT_MAX_OFF_STATE) {
+#if (SOC_SYSTEM_PWR_DWN)
+ _psci_sys_exit_pwrdn(core_mask);
+
+ /* when we are here, the core is back up
+ * set core state to released
+ */
+ core_state = CORE_RELEASED;
+ _setCoreState(core_mask, core_state);
+#endif
+ } else if (state->pwr_domain_state[PLAT_MAX_LVL]
+ == PLAT_MAX_RET_STATE) {
+#if (SOC_SYSTEM_STANDBY)
+ _psci_sys_exit_stdby(core_mask);
+
+ /* when we are here, the core is waking up
+ * set core state to released
+ */
+ core_state = CORE_RELEASED;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+ else if (state->pwr_domain_state[PLAT_CLSTR_LVL] ==
+ PLAT_MAX_OFF_STATE) {
+#if (SOC_CLUSTER_PWR_DWN)
+ _psci_clstr_exit_pwrdn(core_mask);
+
+ /* when we are here, the core is waking up
+ * set core state to released
+ */
+ core_state = CORE_RELEASED;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+ else if (state->pwr_domain_state[PLAT_CLSTR_LVL] ==
+ PLAT_MAX_RET_STATE) {
+#if (SOC_CLUSTER_STANDBY)
+ _psci_clstr_exit_stdby(core_mask);
+
+ /* when we are here, the core is waking up
+ * set core state to released
+ */
+ core_state = CORE_RELEASED;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+ else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_OFF_STATE) {
+#if (SOC_CORE_PWR_DWN)
+ _psci_core_exit_pwrdn(core_mask);
+
+ /* when we are here, the core is back up
+ * set core state to released
+ */
+ core_state = CORE_RELEASED;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+ else if (state->pwr_domain_state[PLAT_CORE_LVL] == PLAT_MAX_RET_STATE) {
+#if (SOC_CORE_STANDBY)
+ _psci_core_exit_stdby(core_mask);
+
+ /* when we are here, the core is waking up
+ * set core state to released
+ */
+ core_state = CORE_RELEASED;
+ _setCoreState(core_mask, core_state);
+#endif
+ }
+
+}
+#endif
+
+#if (SOC_CORE_STANDBY || SOC_CORE_PWR_DWN)
+
+#define PWR_STATE_TYPE_MASK 0x00010000
+#define PWR_STATE_TYPE_STNDBY 0x0
+#define PWR_STATE_TYPE_PWRDWN 0x00010000
+#define PWR_STATE_LVL_MASK 0x03000000
+#define PWR_STATE_LVL_CORE 0x0
+#define PWR_STATE_LVL_CLSTR 0x01000000
+#define PWR_STATE_LVL_SYS 0x02000000
+#define PWR_STATE_LVL_MAX 0x03000000
+
+ /* turns a requested power state into a target power state
+ * based on SoC capabilities
+ */
+static int _pwr_state_validate(uint32_t pwr_state,
+ psci_power_state_t *state)
+{
+ int stat = PSCI_E_INVALID_PARAMS;
+ int pwrdn = (pwr_state & PWR_STATE_TYPE_MASK);
+ int lvl = (pwr_state & PWR_STATE_LVL_MASK);
+
+ switch (lvl) {
+ case PWR_STATE_LVL_MAX:
+ if (pwrdn && SOC_SYSTEM_PWR_DWN)
+ state->pwr_domain_state[PLAT_MAX_LVL] =
+ PLAT_MAX_OFF_STATE;
+ else if (SOC_SYSTEM_STANDBY)
+ state->pwr_domain_state[PLAT_MAX_LVL] =
+ PLAT_MAX_RET_STATE;
+ /* fallthrough */
+ case PWR_STATE_LVL_SYS:
+ if (pwrdn && SOC_SYSTEM_PWR_DWN)
+ state->pwr_domain_state[PLAT_SYS_LVL] =
+ PLAT_MAX_OFF_STATE;
+ else if (SOC_SYSTEM_STANDBY)
+ state->pwr_domain_state[PLAT_SYS_LVL] =
+ PLAT_MAX_RET_STATE;
+ /* fallthrough */
+ case PWR_STATE_LVL_CLSTR:
+ if (pwrdn && SOC_CLUSTER_PWR_DWN)
+ state->pwr_domain_state[PLAT_CLSTR_LVL] =
+ PLAT_MAX_OFF_STATE;
+ else if (SOC_CLUSTER_STANDBY)
+ state->pwr_domain_state[PLAT_CLSTR_LVL] =
+ PLAT_MAX_RET_STATE;
+ /* fallthrough */
+ case PWR_STATE_LVL_CORE:
+ stat = PSCI_E_SUCCESS;
+
+ if (pwrdn && SOC_CORE_PWR_DWN)
+ state->pwr_domain_state[PLAT_CORE_LVL] =
+ PLAT_MAX_OFF_STATE;
+ else if (SOC_CORE_STANDBY)
+ state->pwr_domain_state[PLAT_CORE_LVL] =
+ PLAT_MAX_RET_STATE;
+ break;
+ }
+ return (stat);
+}
+
+#endif
+
+#if (SOC_SYSTEM_PWR_DWN)
+static void _pwr_state_sys_suspend(psci_power_state_t *req_state)
+{
+
+ /* if we need to have per-SoC settings, then we need to
+ * extend this by calling into psci_utils.S and from there
+ * on down to the SoC.S files
+ */
+
+ req_state->pwr_domain_state[PLAT_MAX_LVL] = PLAT_MAX_OFF_STATE;
+ req_state->pwr_domain_state[PLAT_SYS_LVL] = PLAT_MAX_OFF_STATE;
+ req_state->pwr_domain_state[PLAT_CLSTR_LVL] = PLAT_MAX_OFF_STATE;
+ req_state->pwr_domain_state[PLAT_CORE_LVL] = PLAT_MAX_OFF_STATE;
+
+}
+#endif
+
+#if defined(NXP_WARM_BOOT) && (SOC_SYSTEM_RESET2)
+static int psci_system_reset2(int is_vendor,
+ int reset_type,
+ u_register_t cookie)
+{
+ int ret = 0;
+
+ INFO("Executing the sequence of warm reset.\n");
+ ret = prep_n_execute_warm_reset();
+
+ return ret;
+}
+#endif
+
+static plat_psci_ops_t _psci_pm_ops = {
+#if (SOC_SYSTEM_OFF)
+ .system_off = _psci_system_off,
+#endif
+#if (SOC_SYSTEM_RESET)
+ .system_reset = _psci_system_reset,
+#endif
+#if defined(NXP_WARM_BOOT) && (SOC_SYSTEM_RESET2)
+ .system_reset2 = psci_system_reset2,
+#endif
+#if (SOC_CORE_RELEASE || SOC_CORE_RESTART)
+ /* core released or restarted */
+ .pwr_domain_on_finish = _pwr_domain_wakeup,
+#endif
+#if (SOC_CORE_OFF)
+ /* core shutting down */
+ .pwr_domain_off = _pwr_domain_off,
+#endif
+#if (SOC_CORE_OFF || SOC_CORE_PWR_DWN)
+ .pwr_domain_pwr_down_wfi = _pwr_down_wfi,
+#endif
+#if (SOC_CORE_STANDBY || SOC_CORE_PWR_DWN)
+ /* cpu_suspend */
+ .validate_power_state = _pwr_state_validate,
+#if (SOC_CORE_STANDBY)
+ .cpu_standby = _pwr_cpu_standby,
+#endif
+#if (SOC_CORE_PWR_DWN)
+ .pwr_domain_suspend = _pwr_suspend,
+ .pwr_domain_suspend_finish = _pwr_suspend_finish,
+#endif
+#endif
+#if (SOC_SYSTEM_PWR_DWN)
+ .get_sys_suspend_power_state = _pwr_state_sys_suspend,
+#endif
+#if (SOC_CORE_RELEASE)
+ /* core executing psci_cpu_on */
+ .pwr_domain_on = _pwr_domain_on
+#endif
+};
+
+#if (SOC_CORE_RELEASE || SOC_CORE_PWR_DWN)
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ warmboot_entry = sec_entrypoint;
+ *psci_ops = &_psci_pm_ops;
+ return 0;
+}
+
+#else
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ *psci_ops = &_psci_pm_ops;
+ return 0;
+}
+#endif
diff --git a/plat/nxp/common/psci/psci.mk b/plat/nxp/common/psci/psci.mk
new file mode 100644
index 0000000..a2791c2
--- /dev/null
+++ b/plat/nxp/common/psci/psci.mk
@@ -0,0 +1,35 @@
+#
+# Copyright 2018-2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# Select the PSCI files
+#
+# -----------------------------------------------------------------------------
+
+ifeq (${ADD_PSCI},)
+
+ADD_PSCI := 1
+PLAT_PSCI_PATH := $(PLAT_COMMON_PATH)/psci
+
+PSCI_SOURCES := ${PLAT_PSCI_PATH}/plat_psci.c \
+ ${PLAT_PSCI_PATH}/$(ARCH)/psci_utils.S \
+ plat/common/plat_psci_common.c
+
+PLAT_INCLUDES += -I${PLAT_PSCI_PATH}/include
+
+ifeq (${BL_COMM_PSCI_NEEDED},yes)
+BL_COMMON_SOURCES += ${PSCI_SOURCES}
+else
+ifeq (${BL2_PSCI_NEEDED},yes)
+BL2_SOURCES += ${PSCI_SOURCES}
+endif
+ifeq (${BL31_PSCI_NEEDED},yes)
+BL31_SOURCES += ${PSCI_SOURCES}
+endif
+endif
+endif
+# -----------------------------------------------------------------------------
diff --git a/plat/nxp/common/setup/aarch64/ls_bl2_mem_params_desc.c b/plat/nxp/common/setup/aarch64/ls_bl2_mem_params_desc.c
new file mode 100644
index 0000000..7463d47
--- /dev/null
+++ b/plat/nxp/common/setup/aarch64/ls_bl2_mem_params_desc.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <common/bl_common.h>
+#include <common/desc_image_load.h>
+#ifdef CSF_HEADER_PREPENDED
+#include <csf_hdr.h>
+#endif
+#include <plat/common/platform.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.arg1 = LS_BL31_PLAT_PARAM_VAL,
+#endif
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP),
+#ifdef CSF_HEADER_PREPENDED
+ .image_info.image_base = BL31_BASE - CSF_HDR_SZ,
+ .image_info.image_max_size = (BL31_LIMIT - BL31_BASE) +
+ CSF_HDR_SZ,
+#else
+ .image_info.image_base = BL31_BASE,
+ .image_info.image_max_size = (BL31_LIMIT - BL31_BASE),
+#endif
+
+# ifdef NXP_LOAD_BL32
+ .next_handoff_image_id = BL32_IMAGE_ID,
+# else
+ .next_handoff_image_id = BL33_IMAGE_ID,
+# endif
+ },
+# ifdef NXP_LOAD_BL32
+ /* 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),
+ .ep_info.pc = BL32_BASE,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+#ifdef CSF_HEADER_PREPENDED
+ .image_info.image_base = BL32_BASE - CSF_HDR_SZ,
+ .image_info.image_max_size = (BL32_LIMIT - BL32_BASE) +
+ CSF_HDR_SZ,
+#else
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = (BL32_LIMIT - BL32_BASE),
+#endif
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+# endif /* BL32_BASE */
+
+ /* 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,
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+#ifdef CSF_HEADER_PREPENDED
+ .image_info.image_base = BL33_BASE - CSF_HDR_SZ,
+ .image_info.image_max_size = (BL33_LIMIT - BL33_BASE) +
+ CSF_HDR_SZ,
+#else
+ .image_info.image_base = BL33_BASE,
+ .image_info.image_max_size = BL33_LIMIT - BL33_BASE,
+#endif
+ .ep_info.spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/nxp/common/setup/common.mk b/plat/nxp/common/setup/common.mk
new file mode 100644
index 0000000..b7e16ae
--- /dev/null
+++ b/plat/nxp/common/setup/common.mk
@@ -0,0 +1,105 @@
+#
+# Copyright 2018-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+###############################################################################
+# Flow begins in BL2 at EL3 mode
+RESET_TO_BL2 := 1
+
+# Though one core is powered up by default, there are
+# platform specific ways to release more than one core
+COLD_BOOT_SINGLE_CPU := 0
+
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+USE_COHERENT_MEM := 0
+
+# Use generic OID definition (tbbr_oid.h)
+USE_TBBR_DEFS := 1
+
+PLAT_XLAT_TABLES_DYNAMIC := 0
+
+ENABLE_SVE_FOR_NS := 0
+
+ENABLE_STACK_PROTECTOR := 0
+
+ERROR_DEPRECATED := 0
+
+LS_DISABLE_TRUSTED_WDOG := 1
+
+# On ARM platforms, separate the code and read-only data sections to allow
+# mapping the former as executable and the latter as execute-never.
+SEPARATE_CODE_AND_RODATA := 1
+
+# Enable new version of image loading on ARM platforms
+LOAD_IMAGE_V2 := 1
+
+RCW := ""
+
+ifneq (${SPD},none)
+$(eval $(call add_define, NXP_LOAD_BL32))
+endif
+
+###############################################################################
+
+PLAT_TOOL_PATH := tools/nxp
+CREATE_PBL_TOOL_PATH := ${PLAT_TOOL_PATH}/create_pbl
+PLAT_SETUP_PATH := ${PLAT_PATH}/common/setup
+
+PLAT_INCLUDES += -I${PLAT_SETUP_PATH}/include \
+ -Iinclude/plat/arm/common \
+ -Iinclude/drivers/arm \
+ -Iinclude/lib \
+ -Iinclude/drivers/io \
+ -Ilib/psci
+
+# Required without TBBR.
+# To include the defines for DDR PHY Images.
+PLAT_INCLUDES += -Iinclude/common/tbbr
+
+include ${PLAT_SETUP_PATH}/core.mk
+PLAT_BL_COMMON_SOURCES += ${CPU_LIBS} \
+ plat/nxp/common/setup/ls_err.c \
+ plat/nxp/common/setup/ls_common.c
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += ${PLAT_SETUP_PATH}/ls_stack_protector.c
+endif
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
+
+BL2_SOURCES += drivers/io/io_fip.c \
+ drivers/io/io_memmap.c \
+ drivers/io/io_storage.c \
+ common/desc_image_load.c \
+ plat/nxp/common/setup/ls_image_load.c \
+ plat/nxp/common/setup/ls_io_storage.c \
+ plat/nxp/common/setup/ls_bl2_el3_setup.c \
+ plat/nxp/common/setup/${ARCH}/ls_bl2_mem_params_desc.c
+
+BL31_SOURCES += plat/nxp/common/setup/ls_bl31_setup.c \
+
+ifeq (${LS_EL3_INTERRUPT_HANDLER}, yes)
+$(eval $(call add_define, LS_EL3_INTERRUPT_HANDLER))
+BL31_SOURCES += plat/nxp/common/setup/ls_interrupt_mgmt.c
+endif
+
+ifeq (${TEST_BL31}, 1)
+BL31_SOURCES += ${TEST_SOURCES}
+endif
+
+# Verify build config
+# -------------------
+
+ifneq (${LOAD_IMAGE_V2}, 1)
+ $(error Error: Layerscape needs LOAD_IMAGE_V2=1)
+else
+$(eval $(call add_define,LOAD_IMAGE_V2))
+endif
+
+include $(CREATE_PBL_TOOL_PATH)/create_pbl.mk
diff --git a/plat/nxp/common/setup/core.mk b/plat/nxp/common/setup/core.mk
new file mode 100644
index 0000000..82ce30e
--- /dev/null
+++ b/plat/nxp/common/setup/core.mk
@@ -0,0 +1,22 @@
+# Copyright 2018-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# Select the CORE files
+#
+# -----------------------------------------------------------------------------
+
+CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S
+
+ifeq (,$(filter $(CORE_TYPE),a53 a72))
+$(error "CORE_TYPE not specified or incorrect")
+else
+UPPER_CORE_TYPE=$(shell echo $(CORE_TYPE) | tr a-z A-Z)
+$(eval $(call add_define_val,CPUECTLR_EL1,CORTEX_$(UPPER_CORE_TYPE)_ECTLR_EL1))
+CPU_LIBS += lib/cpus/${ARCH}/cortex_$(CORE_TYPE).S
+endif
+
+# -----------------------------------------------------------------------------
diff --git a/plat/nxp/common/setup/include/bl31_data.h b/plat/nxp/common/setup/include/bl31_data.h
new file mode 100644
index 0000000..dd20d43
--- /dev/null
+++ b/plat/nxp/common/setup/include/bl31_data.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef BL31_DATA_H
+#define BL31_DATA_H
+
+#define SECURE_DATA_BASE NXP_OCRAM_ADDR
+#define SECURE_DATA_SIZE NXP_OCRAM_SIZE
+#define SECURE_DATA_TOP (SECURE_DATA_BASE + SECURE_DATA_SIZE)
+#define SMC_REGION_SIZE 0x80
+#define SMC_GLBL_BASE (SECURE_DATA_TOP - SMC_REGION_SIZE)
+#define BC_PSCI_DATA_SIZE 0xC0
+#define BC_PSCI_BASE (SMC_GLBL_BASE - BC_PSCI_DATA_SIZE)
+#define SECONDARY_TOP BC_PSCI_BASE
+
+#define SEC_PSCI_DATA_SIZE 0xC0
+#define SEC_REGION_SIZE SEC_PSCI_DATA_SIZE
+
+/* SMC global data */
+#define BOOTLOC_OFFSET 0x0
+#define BOOT_SVCS_OSET 0x8
+
+/* offset to prefetch disable mask */
+#define PREFETCH_DIS_OFFSET 0x10
+/* must reference last smc global entry */
+#define LAST_SMC_GLBL_OFFSET 0x18
+
+#define SMC_TASK_OFFSET 0xC
+#define TSK_START_OFFSET 0x0
+#define TSK_DONE_OFFSET 0x4
+#define TSK_CORE_OFFSET 0x8
+#define SMC_TASK1_BASE (SMC_GLBL_BASE + 32)
+#define SMC_TASK2_BASE (SMC_TASK1_BASE + SMC_TASK_OFFSET)
+#define SMC_TASK3_BASE (SMC_TASK2_BASE + SMC_TASK_OFFSET)
+#define SMC_TASK4_BASE (SMC_TASK3_BASE + SMC_TASK_OFFSET)
+
+/* psci data area offsets */
+#define CORE_STATE_DATA 0x0
+#define SPSR_EL3_DATA 0x8
+#define CNTXT_ID_DATA 0x10
+#define START_ADDR_DATA 0x18
+#define LINK_REG_DATA 0x20
+#define GICC_CTLR_DATA 0x28
+#define ABORT_FLAG_DATA 0x30
+#define SCTLR_DATA 0x38
+#define CPUECTLR_DATA 0x40
+#define AUX_01_DATA 0x48 /* usage defined per SoC */
+#define AUX_02_DATA 0x50 /* usage defined per SoC */
+#define AUX_03_DATA 0x58 /* usage defined per SoC */
+#define AUX_04_DATA 0x60 /* usage defined per SoC */
+#define AUX_05_DATA 0x68 /* usage defined per SoC */
+#define AUX_06_DATA 0x70 /* usage defined per SoC */
+#define AUX_07_DATA 0x78 /* usage defined per SoC */
+#define SCR_EL3_DATA 0x80
+#define HCR_EL2_DATA 0x88
+
+#endif /* BL31_DATA_H */
diff --git a/plat/nxp/common/setup/include/ls_interrupt_mgmt.h b/plat/nxp/common/setup/include/ls_interrupt_mgmt.h
new file mode 100644
index 0000000..7dbddfb
--- /dev/null
+++ b/plat/nxp/common/setup/include/ls_interrupt_mgmt.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef LS_EL3_INTRPT_MGMT_H
+#define LS_EL3_INTRPT_MGMT_H
+
+#include <bl31/interrupt_mgmt.h>
+
+#define MAX_INTR_EL3 128
+
+/*
+ * Register handler to specific GIC entrance
+ * for INTR_TYPE_EL3 type of interrupt
+ */
+int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler);
+
+void ls_el3_interrupt_config(void);
+
+#endif /* LS_EL3_INTRPT_MGMT_H */
diff --git a/plat/nxp/common/setup/include/mmu_def.h b/plat/nxp/common/setup/include/mmu_def.h
new file mode 100644
index 0000000..2a7771b
--- /dev/null
+++ b/plat/nxp/common/setup/include/mmu_def.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef MMU_MAP_DEF_H
+#define MMU_MAP_DEF_H
+
+#include <lib/xlat_tables/xlat_tables_defs.h>
+
+#include <platform_def.h>
+
+
+#define LS_MAP_CCSR MAP_REGION_FLAT(NXP_CCSR_ADDR, \
+ NXP_CCSR_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#ifdef NXP_DCSR_ADDR
+#define LS_MAP_DCSR MAP_REGION_FLAT(NXP_DCSR_ADDR, \
+ NXP_DCSR_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+#endif
+
+#define LS_MAP_CONSOLE MAP_REGION_FLAT(NXP_DUART1_ADDR, \
+ NXP_DUART_SIZE, \
+ MT_DEVICE | MT_RW | MT_NS)
+
+#define LS_MAP_OCRAM MAP_REGION_FLAT(NXP_OCRAM_ADDR, \
+ NXP_OCRAM_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#endif /* MMU_MAP_DEF_H */
diff --git a/plat/nxp/common/setup/include/plat_common.h b/plat/nxp/common/setup/include/plat_common.h
new file mode 100644
index 0000000..e13f45c
--- /dev/null
+++ b/plat/nxp/common/setup/include/plat_common.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_COMMON_H
+#define PLAT_COMMON_H
+
+#include <stdbool.h>
+
+#include <dcfg.h>
+#include <lib/el3_runtime/cpu_data.h>
+
+#include <platform_def.h>
+
+#ifdef IMAGE_BL31
+
+#define BL31_END (uintptr_t)(&__BL31_END__)
+
+/*******************************************************************************
+ * This structure represents the superset of information that can be passed to
+ * BL31 e.g. while passing control to it from BL2. The BL32 parameters will be
+ * populated only if BL2 detects its presence. A pointer to a structure of this
+ * type should be passed in X0 to BL31's cold boot entrypoint.
+ *
+ * Use of this structure and the X0 parameter is not mandatory: the BL31
+ * platform code can use other mechanisms to provide the necessary information
+ * about BL32 and BL33 to the common and SPD code.
+ *
+ * BL31 image information is mandatory if this structure is used. If either of
+ * the optional BL32 and BL33 image information is not provided, this is
+ * indicated by the respective image_info pointers being zero.
+ ******************************************************************************/
+typedef struct bl31_params {
+ param_header_t h;
+ image_info_t *bl31_image_info;
+ entry_point_info_t *bl32_ep_info;
+ image_info_t *bl32_image_info;
+ entry_point_info_t *bl33_ep_info;
+ image_info_t *bl33_image_info;
+} bl31_params_t;
+
+/* BL3 utility functions */
+void ls_bl31_early_platform_setup(void *from_bl2,
+ void *plat_params_from_bl2);
+/* LS Helper functions */
+unsigned int plat_my_core_mask(void);
+unsigned int plat_core_mask(u_register_t mpidr);
+unsigned int plat_core_pos(u_register_t mpidr);
+//unsigned int plat_my_core_pos(void);
+
+/* BL31 Data API(s) */
+void _init_global_data(void);
+void _initialize_psci(void);
+uint32_t _getCoreState(u_register_t core_mask);
+void _setCoreState(u_register_t core_mask, u_register_t core_state);
+
+/* SoC defined structure and API(s) */
+void soc_runtime_setup(void);
+void soc_init(void);
+void soc_platform_setup(void);
+void soc_early_platform_setup2(void);
+#endif /* IMAGE_BL31 */
+
+#ifdef IMAGE_BL2
+void soc_early_init(void);
+void soc_mem_access(void);
+void soc_preload_setup(void);
+void soc_bl2_prepare_exit(void);
+
+/* IO storage utility functions */
+int plat_io_setup(void);
+int open_backend(const uintptr_t spec);
+
+void ls_bl2_plat_arch_setup(void);
+void ls_bl2_el3_plat_arch_setup(void);
+
+enum boot_device {
+ BOOT_DEVICE_IFC_NOR,
+ BOOT_DEVICE_IFC_NAND,
+ BOOT_DEVICE_QSPI,
+ BOOT_DEVICE_EMMC,
+ BOOT_DEVICE_SDHC2_EMMC,
+ BOOT_DEVICE_FLEXSPI_NOR,
+ BOOT_DEVICE_FLEXSPI_NAND,
+ BOOT_DEVICE_NONE
+};
+
+enum boot_device get_boot_dev(void);
+
+/* DDR Related functions */
+#if DDR_INIT
+#ifdef NXP_WARM_BOOT
+long long init_ddr(uint32_t wrm_bt_flg);
+#else
+long long init_ddr(void);
+#endif
+#endif
+
+/* Board specific weak functions */
+bool board_enable_povdd(void);
+bool board_disable_povdd(void);
+
+void mmap_add_ddr_region_dynamically(void);
+#endif /* IMAGE_BL2 */
+
+typedef struct {
+ uint64_t addr;
+ uint64_t size;
+} region_info_t;
+
+typedef struct {
+ uint64_t num_dram_regions;
+ int64_t total_dram_size;
+ region_info_t region[NUM_DRAM_REGIONS];
+} dram_regions_info_t;
+
+dram_regions_info_t *get_dram_regions_info(void);
+
+void ls_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
+#if USE_COHERENT_MEM
+ , uintptr_t coh_start,
+ uintptr_t coh_limit
+#endif
+);
+
+#define SOC_NAME_MAX_LEN (20)
+
+/* Structure to define SoC personality */
+struct soc_type {
+ char name[SOC_NAME_MAX_LEN];
+ uint32_t version;
+ uint8_t num_clusters;
+ uint8_t cores_per_cluster;
+};
+void get_cluster_info(const struct soc_type *soc_list, uint8_t ps_count,
+ uint8_t *num_clusters, uint8_t *cores_per_cluster);
+
+#define SOC_ENTRY(n, v, ncl, nc) { \
+ .name = #n, \
+ .version = SVR_##v, \
+ .num_clusters = (ncl), \
+ .cores_per_cluster = (nc)}
+
+#endif /* PLAT_COMMON_H */
diff --git a/plat/nxp/common/setup/include/plat_macros.S b/plat/nxp/common/setup/include/plat_macros.S
new file mode 100644
index 0000000..69a3b08
--- /dev/null
+++ b/plat/nxp/common/setup/include/plat_macros.S
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2018-2020 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/common/setup/ls_bl2_el3_setup.c b/plat/nxp/common/setup/ls_bl2_el3_setup.c
new file mode 100644
index 0000000..a4cbaef
--- /dev/null
+++ b/plat/nxp/common/setup/ls_bl2_el3_setup.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+
+#include <common/desc_image_load.h>
+#include <dcfg.h>
+#ifdef POLICY_FUSE_PROVISION
+#include <fuse_io.h>
+#endif
+#include <mmu_def.h>
+#include <plat_common.h>
+#ifdef NXP_NV_SW_MAINT_LAST_EXEC_DATA
+#include <plat_nv_storage.h>
+#endif
+
+#pragma weak bl2_el3_early_platform_setup
+#pragma weak bl2_el3_plat_arch_setup
+#pragma weak bl2_el3_plat_prepare_exit
+
+static dram_regions_info_t dram_regions_info = {0};
+
+/*******************************************************************************
+ * Return the pointer to the 'dram_regions_info structure of the DRAM.
+ * This structure is populated after init_ddr().
+ ******************************************************************************/
+dram_regions_info_t *get_dram_regions_info(void)
+{
+ return &dram_regions_info;
+}
+
+#ifdef DDR_INIT
+static void populate_dram_regions_info(void)
+{
+ long long dram_remain_size = dram_regions_info.total_dram_size;
+ uint8_t reg_id = 0U;
+
+ dram_regions_info.region[reg_id].addr = NXP_DRAM0_ADDR;
+ dram_regions_info.region[reg_id].size =
+ dram_remain_size > NXP_DRAM0_MAX_SIZE ?
+ NXP_DRAM0_MAX_SIZE : dram_remain_size;
+
+ if (dram_regions_info.region[reg_id].size != NXP_DRAM0_SIZE) {
+ ERROR("Incorrect DRAM0 size is defined in platform_def.h\n");
+ }
+
+ dram_remain_size -= dram_regions_info.region[reg_id].size;
+ dram_regions_info.region[reg_id].size -= (NXP_SECURE_DRAM_SIZE
+ + NXP_SP_SHRD_DRAM_SIZE);
+
+ assert(dram_regions_info.region[reg_id].size > 0);
+
+ /* Reducing total dram size by 66MB */
+ dram_regions_info.total_dram_size -= (NXP_SECURE_DRAM_SIZE
+ + NXP_SP_SHRD_DRAM_SIZE);
+
+#if defined(NXP_DRAM1_ADDR) && defined(NXP_DRAM1_MAX_SIZE)
+ if (dram_remain_size > 0) {
+ reg_id++;
+ dram_regions_info.region[reg_id].addr = NXP_DRAM1_ADDR;
+ dram_regions_info.region[reg_id].size =
+ dram_remain_size > NXP_DRAM1_MAX_SIZE ?
+ NXP_DRAM1_MAX_SIZE : dram_remain_size;
+ dram_remain_size -= dram_regions_info.region[reg_id].size;
+ }
+#endif
+#if defined(NXP_DRAM2_ADDR) && defined(NXP_DRAM2_MAX_SIZE)
+ if (dram_remain_size > 0) {
+ reg_id++;
+ dram_regions_info.region[reg_id].addr = NXP_DRAM1_ADDR;
+ dram_regions_info.region[reg_id].size =
+ dram_remain_size > NXP_DRAM1_MAX_SIZE ?
+ NXP_DRAM1_MAX_SIZE : dram_remain_size;
+ dram_remain_size -= dram_regions_info.region[reg_id].size;
+ }
+#endif
+ reg_id++;
+ dram_regions_info.num_dram_regions = reg_id;
+}
+#endif
+
+#ifdef IMAGE_BL32
+/*******************************************************************************
+ * Gets SPSR for BL32 entry
+ ******************************************************************************/
+static uint32_t ls_get_spsr_for_bl32_entry(void)
+{
+ /*
+ * The Secure Payload Dispatcher service is responsible for
+ * setting the SPSR prior to entry into the BL32 image.
+ */
+ return 0U;
+}
+#endif
+
+/*******************************************************************************
+ * Gets SPSR for BL33 entry
+ ******************************************************************************/
+#ifndef AARCH32
+static uint32_t ls_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(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+#else
+/*******************************************************************************
+ * Gets SPSR for BL33 entry
+ ******************************************************************************/
+static uint32_t ls_get_spsr_for_bl33_entry(void)
+{
+ unsigned int hyp_status, mode, spsr;
+
+ hyp_status = GET_VIRT_EXT(read_id_pfr1());
+
+ mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
+
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+ spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
+ SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+#endif /* AARCH32 */
+
+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)
+{
+ /*
+ * SoC specific early init
+ * Any errata handling or SoC specific early initialization can
+ * be done here
+ * Set Counter Base Frequency in CNTFID0 and in cntfrq_el0.
+ * Initialize the interconnect.
+ * Enable coherency for primary CPU cluster
+ */
+ soc_early_init();
+
+ /* Initialise the IO layer and register platform IO devices */
+ plat_io_setup();
+
+ if (dram_regions_info.total_dram_size > 0) {
+ populate_dram_regions_info();
+ }
+
+#ifdef NXP_NV_SW_MAINT_LAST_EXEC_DATA
+ read_nv_app_data();
+#if DEBUG
+ const nv_app_data_t *nv_app_data = get_nv_data();
+
+ INFO("Value of warm_reset flag = 0x%x\n", nv_app_data->warm_rst_flag);
+ INFO("Value of WDT flag = 0x%x\n", nv_app_data->wdt_rst_flag);
+#endif
+#endif
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only initializes the mmu in a quick and dirty way.
+ ******************************************************************************/
+void ls_bl2_el3_plat_arch_setup(void)
+{
+ unsigned int flags = 0U;
+ /* Initialise the IO layer and register platform IO devices */
+ ls_setup_page_tables(
+#if SEPARATE_BL2_NOLOAD_REGION
+ BL2_START,
+ BL2_LIMIT - BL2_START,
+#else
+ BL2_BASE,
+ (unsigned long)(&__BL2_END__) - BL2_BASE,
+#endif
+ BL_CODE_BASE,
+ BL_CODE_END,
+ BL_RO_DATA_BASE,
+ BL_RO_DATA_END
+#if USE_COHERENT_MEM
+ , BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END
+#endif
+ );
+
+ if ((dram_regions_info.region[0].addr == 0)
+ && (dram_regions_info.total_dram_size == 0)) {
+ flags = XLAT_TABLE_NC;
+ }
+
+#ifdef AARCH32
+ enable_mmu_secure(0);
+#else
+ enable_mmu_el3(flags);
+#endif
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+ ls_bl2_el3_plat_arch_setup();
+}
+
+void bl2_platform_setup(void)
+{
+ /*
+ * Perform platform setup before loading the image.
+ */
+}
+
+/* Handling image information by platform. */
+int ls_bl2_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);
+
+ assert(bl_mem_params);
+
+ switch (image_id) {
+ case BL31_IMAGE_ID:
+ bl_mem_params->ep_info.args.arg3 =
+ (u_register_t) &dram_regions_info;
+
+ /* Pass the value of PORSR1 register in Argument 4 */
+ bl_mem_params->ep_info.args.arg4 =
+ (u_register_t)read_reg_porsr1();
+ flush_dcache_range((uintptr_t)&dram_regions_info,
+ sizeof(dram_regions_info));
+ break;
+#if defined(AARCH64) && defined(IMAGE_BL32)
+ case BL32_IMAGE_ID:
+ bl_mem_params->ep_info.spsr = ls_get_spsr_for_bl32_entry();
+ break;
+#endif
+ case BL33_IMAGE_ID:
+ /* BL33 expects to receive the primary CPU MPID (through r0) */
+ bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
+ bl_mem_params->ep_info.spsr = ls_get_spsr_for_bl33_entry();
+ break;
+ }
+
+ return err;
+}
+
+/*******************************************************************************
+ * 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)
+{
+ return ls_bl2_handle_post_image_load(image_id);
+}
+
+void bl2_el3_plat_prepare_exit(void)
+{
+ return soc_bl2_prepare_exit();
+}
+
+/* Called to do the dynamic initialization required
+ * before loading the next image.
+ */
+void bl2_plat_preload_setup(void)
+{
+
+ soc_preload_setup();
+
+#ifdef DDR_INIT
+ if (dram_regions_info.total_dram_size <= 0) {
+ ERROR("Asserting as the DDR is not initialized yet.");
+ assert(false);
+ }
+#endif
+
+ if ((dram_regions_info.region[0].addr == 0)
+ && (dram_regions_info.total_dram_size > 0)) {
+ populate_dram_regions_info();
+#ifdef PLAT_XLAT_TABLES_DYNAMIC
+ mmap_add_ddr_region_dynamically();
+#endif
+ }
+
+ /* setup the memory region access permissions */
+ soc_mem_access();
+
+#ifdef POLICY_FUSE_PROVISION
+ fip_fuse_provisioning((uintptr_t)FUSE_BUF, FUSE_SZ);
+#endif
+}
diff --git a/plat/nxp/common/setup/ls_bl31_setup.c b/plat/nxp/common/setup/ls_bl31_setup.c
new file mode 100644
index 0000000..3d0d804
--- /dev/null
+++ b/plat/nxp/common/setup/ls_bl31_setup.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
+
+#ifdef LS_EL3_INTERRUPT_HANDLER
+#include <ls_interrupt_mgmt.h>
+#endif
+#include <mmu_def.h>
+#include <plat_common.h>
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+#ifdef TEST_BL31
+#define SPSR_FOR_EL2H 0x3C9
+#define SPSR_FOR_EL1H 0x3C5
+#else
+static entry_point_info_t bl31_image_ep_info;
+#endif
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+static dram_regions_info_t dram_regions_info = {0};
+static uint64_t rcw_porsr1;
+
+/* Return the pointer to the 'dram_regions_info structure of the DRAM.
+ * This structure is populated after init_ddr().
+ */
+dram_regions_info_t *get_dram_regions_info(void)
+{
+ return &dram_regions_info;
+}
+
+/* Return the RCW.PORSR1 value which was passed in from BL2
+ */
+uint64_t bl31_get_porsr1(void)
+{
+ return rcw_porsr1;
+}
+
+/*
+ * Return pointer to the 'entry_point_info' structure of the next image for the
+ * security state specified:
+ * - BL33 corresponds to the non-secure image type; while
+ * - BL32 corresponds to the secure image type.
+ * - A NULL pointer is returned, if the image does not exist.
+ */
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ assert(sec_state_is_valid(type));
+ next_image_info = (type == NON_SECURE)
+ ? &bl33_image_ep_info : &bl32_image_ep_info;
+
+#ifdef TEST_BL31
+ next_image_info->pc = _get_test_entry();
+ next_image_info->spsr = SPSR_FOR_EL2H;
+ next_image_info->h.attr = NON_SECURE;
+#endif
+
+ if (next_image_info->pc != 0U) {
+ return next_image_info;
+ } else {
+ return NULL;
+ }
+}
+
+/*
+ * Perform any BL31 early platform setup common to NXP platforms.
+ * - 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.
+ * - BL2 has flushed this information to memory, in order to fetch latest data.
+ */
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+#ifndef TEST_BL31
+ int i = 0;
+ void *from_bl2 = (void *)arg0;
+#endif
+ soc_early_platform_setup2();
+
+#ifdef TEST_BL31
+ dram_regions_info.num_dram_regions = 2;
+ dram_regions_info.total_dram_size = 0x100000000;
+ dram_regions_info.region[0].addr = 0x80000000;
+ dram_regions_info.region[0].size = 0x80000000;
+ dram_regions_info.region[1].addr = 0x880000000;
+ dram_regions_info.region[1].size = 0x80000000;
+
+ bl33_image_ep_info.pc = _get_test_entry();
+#else
+ /*
+ * Check params passed from BL2 should not be NULL,
+ */
+ bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+
+ 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;
+
+ /*
+ * Copy BL33 and BL32 (if present), entry point information.
+ * They are stored in Secure RAM, in BL2's address space.
+ */
+ while (bl_params != NULL) {
+ if (bl_params->image_id == BL31_IMAGE_ID) {
+ bl31_image_ep_info = *bl_params->ep_info;
+ dram_regions_info_t *loc_dram_regions_info =
+ (dram_regions_info_t *) bl31_image_ep_info.args.arg3;
+
+ dram_regions_info.num_dram_regions =
+ loc_dram_regions_info->num_dram_regions;
+ dram_regions_info.total_dram_size =
+ loc_dram_regions_info->total_dram_size;
+ VERBOSE("Number of DRAM Regions = %" PRIx64 "\n",
+ dram_regions_info.num_dram_regions);
+
+ for (i = 0; i < dram_regions_info.num_dram_regions;
+ i++) {
+ dram_regions_info.region[i].addr =
+ loc_dram_regions_info->region[i].addr;
+ dram_regions_info.region[i].size =
+ loc_dram_regions_info->region[i].size;
+ VERBOSE("DRAM%d Size = %" PRIx64 "\n", i,
+ dram_regions_info.region[i].size);
+ }
+ rcw_porsr1 = bl31_image_ep_info.args.arg4;
+ }
+
+ if (bl_params->image_id == BL32_IMAGE_ID) {
+ bl32_image_ep_info = *bl_params->ep_info;
+ }
+
+ if (bl_params->image_id == BL33_IMAGE_ID) {
+ bl33_image_ep_info = *bl_params->ep_info;
+ }
+
+ bl_params = bl_params->next_params_info;
+ }
+#endif /* TEST_BL31 */
+
+ if (bl33_image_ep_info.pc == 0) {
+ panic();
+ }
+
+ /*
+ * perform basic initialization on the soc
+ */
+ soc_init();
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform setup common to ARM standard platforms
+ ******************************************************************************/
+void bl31_platform_setup(void)
+{
+ NOTICE("Welcome to %s BL31 Phase\n", BOARD);
+ soc_platform_setup();
+
+ /* Console logs gone missing as part going to
+ * EL1 for initializing Bl32 if present.
+ * console flush is necessary to avoid it.
+ */
+ (void)console_flush();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+#ifdef LS_EL3_INTERRUPT_HANDLER
+ ls_el3_interrupt_config();
+#endif
+ soc_runtime_setup();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup shared between
+ * ARM standard platforms. This only does basic initialization. Later
+ * architectural setup (bl31_arch_setup()) does not do anything platform
+ * specific.
+ ******************************************************************************/
+void bl31_plat_arch_setup(void)
+{
+
+ ls_setup_page_tables(BL31_BASE,
+ BL31_END - BL31_BASE,
+ BL_CODE_BASE,
+ BL_CODE_END,
+ BL_RO_DATA_BASE,
+ BL_RO_DATA_END
+#if USE_COHERENT_MEM
+ , BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END
+#endif
+ );
+ enable_mmu_el3(0);
+}
diff --git a/plat/nxp/common/setup/ls_common.c b/plat/nxp/common/setup/ls_common.c
new file mode 100644
index 0000000..28d6b72
--- /dev/null
+++ b/plat/nxp/common/setup/ls_common.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <mmu_def.h>
+#include <plat/common/platform.h>
+
+#include "plat_common.h"
+#include "platform_def.h"
+
+const mmap_region_t *plat_ls_get_mmap(void);
+
+/*
+ * Table of memory regions for various BL stages to map using the MMU.
+ * This doesn't include Trusted SRAM as arm_setup_page_tables() already
+ * takes care of mapping it.
+ *
+ * The flash needs to be mapped as writable in order to erase the FIP's Table of
+ * Contents in case of unrecoverable error (see plat_error_handler()).
+ */
+#ifdef IMAGE_BL2
+const mmap_region_t plat_ls_mmap[] = {
+ LS_MAP_CCSR,
+ {0}
+};
+#endif
+
+#ifdef IMAGE_BL31
+const mmap_region_t plat_ls_mmap[] = {
+ LS_MAP_CCSR,
+#ifdef NXP_DCSR_ADDR
+ LS_MAP_DCSR,
+#endif
+ LS_MAP_OCRAM,
+ {0}
+};
+#endif
+#ifdef IMAGE_BL32
+const mmap_region_t plat_ls_mmap[] = {
+ LS_MAP_CCSR,
+ LS_MAP_BL32_SEC_MEM,
+ {0}
+};
+#endif
+
+/* Weak definitions may be overridden in specific NXP SoC */
+#pragma weak plat_get_ns_image_entrypoint
+#pragma weak plat_ls_get_mmap
+
+#if defined(IMAGE_BL31) || !defined(CONFIG_DDR_FIP_IMAGE)
+static void mmap_add_ddr_regions_statically(void)
+{
+ int i = 0;
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+ /* MMU map for Non-Secure DRAM Regions */
+ VERBOSE("DRAM Region %d: %p - %p\n", i,
+ (void *) info_dram_regions->region[i].addr,
+ (void *) (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size
+ - 1));
+ mmap_add_region(info_dram_regions->region[i].addr,
+ info_dram_regions->region[i].addr,
+ info_dram_regions->region[i].size,
+ MT_MEMORY | MT_RW | MT_NS);
+
+ /* MMU map for Secure DDR Region on DRAM-0 */
+ if (info_dram_regions->region[i].size >
+ (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE)) {
+ VERBOSE("Secure DRAM Region %d: %p - %p\n", i,
+ (void *) (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size),
+ (void *) (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size
+ + NXP_SECURE_DRAM_SIZE
+ + NXP_SP_SHRD_DRAM_SIZE
+ - 1));
+ mmap_add_region((info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size),
+ (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size),
+ (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE),
+ MT_MEMORY | MT_RW | MT_SECURE);
+ }
+
+#ifdef IMAGE_BL31
+ for (i = 1; i < info_dram_regions->num_dram_regions; i++) {
+ if (info_dram_regions->region[i].size == 0)
+ break;
+ VERBOSE("DRAM Region %d: %p - %p\n", i,
+ (void *) info_dram_regions->region[i].addr,
+ (void *) (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size
+ - 1));
+ mmap_add_region(info_dram_regions->region[i].addr,
+ info_dram_regions->region[i].addr,
+ info_dram_regions->region[i].size,
+ MT_MEMORY | MT_RW | MT_NS);
+ }
+#endif
+}
+#endif
+
+#if defined(PLAT_XLAT_TABLES_DYNAMIC)
+void mmap_add_ddr_region_dynamically(void)
+{
+ int ret, i = 0;
+
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+ /* MMU map for Non-Secure DRAM Regions */
+ VERBOSE("DRAM Region %d: %p - %p\n", i,
+ (void *) info_dram_regions->region[i].addr,
+ (void *) (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size
+ - 1));
+ ret = mmap_add_dynamic_region(info_dram_regions->region[i].addr,
+ info_dram_regions->region[i].addr,
+ info_dram_regions->region[i].size,
+ MT_MEMORY | MT_RW | MT_NS);
+ if (ret != 0) {
+ ERROR("Failed to add dynamic memory region\n");
+ panic();
+ }
+
+ /* MMU map for Secure DDR Region on DRAM-0 */
+ if (info_dram_regions->region[i].size >
+ (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE)) {
+ VERBOSE("Secure DRAM Region %d: %p - %p\n", i,
+ (void *) (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size),
+ (void *) (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size
+ + NXP_SECURE_DRAM_SIZE
+ + NXP_SP_SHRD_DRAM_SIZE
+ - 1));
+ ret = mmap_add_dynamic_region((info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size),
+ (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size),
+ (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE),
+ MT_MEMORY | MT_RW | MT_SECURE);
+ if (ret != 0) {
+ ERROR("Failed to add dynamic memory region\n");
+ panic();
+ }
+ }
+
+#ifdef IMAGE_BL31
+ for (i = 1; i < info_dram_regions->num_dram_regions; i++) {
+ if (info_dram_regions->region[i].size == 0) {
+ break;
+ }
+ VERBOSE("DRAM Region %d: %p - %p\n", i,
+ (void *) info_dram_regions->region[i].addr,
+ (void *) (info_dram_regions->region[i].addr
+ + info_dram_regions->region[i].size
+ - 1));
+ ret = mmap_add_dynamic_region(info_dram_regions->region[i].addr,
+ info_dram_regions->region[i].addr,
+ info_dram_regions->region[i].size,
+ MT_MEMORY | MT_RW | MT_NS);
+ if (ret != 0) {
+ ERROR("Failed to add dynamic memory region\n");
+ panic();
+ }
+ }
+#endif
+}
+#endif
+
+/*
+ * Set up the page tables for the generic and platform-specific memory regions.
+ * The extents of the generic memory regions are specified by the function
+ * arguments and consist of:
+ * - Trusted SRAM seen by the BL image;
+ * - Code section;
+ * - Read-only data section;
+ * - Coherent memory region, if applicable.
+ */
+void ls_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
+#if USE_COHERENT_MEM
+ ,
+ uintptr_t coh_start,
+ uintptr_t coh_limit
+#endif
+ )
+{
+ /*
+ * Map the Trusted SRAM with appropriate memory attributes.
+ * Subsequent mappings will adjust the attributes for specific regions.
+ */
+ VERBOSE("Memory seen by this BL image: %p - %p\n",
+ (void *) total_base, (void *) (total_base + total_size));
+ mmap_add_region(total_base, total_base,
+ total_size,
+ MT_MEMORY | MT_RW | MT_SECURE);
+
+ /* Re-map the code section */
+ VERBOSE("Code region: %p - %p\n",
+ (void *) code_start, (void *) code_limit);
+ mmap_add_region(code_start, code_start,
+ code_limit - code_start,
+ MT_CODE | MT_SECURE);
+
+ /* Re-map the read-only data section */
+ VERBOSE("Read-only data region: %p - %p\n",
+ (void *) rodata_start, (void *) rodata_limit);
+ mmap_add_region(rodata_start, rodata_start,
+ rodata_limit - rodata_start,
+ MT_RO_DATA | MT_SECURE);
+
+#if USE_COHERENT_MEM
+ /* Re-map the coherent memory region */
+ VERBOSE("Coherent region: %p - %p\n",
+ (void *) coh_start, (void *) coh_limit);
+ mmap_add_region(coh_start, coh_start,
+ coh_limit - coh_start,
+ MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
+ /* Now (re-)map the platform-specific memory regions */
+ mmap_add(plat_ls_get_mmap());
+
+
+#if defined(IMAGE_BL31) || !defined(CONFIG_DDR_FIP_IMAGE)
+ mmap_add_ddr_regions_statically();
+#endif
+
+ /* Create the page tables to reflect the above mappings */
+ init_xlat_tables();
+}
+
+/*******************************************************************************
+ * Returns NXP platform specific memory map regions.
+ ******************************************************************************/
+const mmap_region_t *plat_ls_get_mmap(void)
+{
+ return plat_ls_mmap;
+}
+
+/*
+ * This function get the number of clusters and cores count per cluster
+ * in the SoC.
+ */
+void get_cluster_info(const struct soc_type *soc_list, uint8_t ps_count,
+ uint8_t *num_clusters, uint8_t *cores_per_cluster)
+{
+ const soc_info_t *soc_info = get_soc_info();
+ *num_clusters = NUMBER_OF_CLUSTERS;
+ *cores_per_cluster = CORES_PER_CLUSTER;
+ unsigned int i;
+
+ for (i = 0U; i < ps_count; i++) {
+ if (soc_list[i].version == soc_info->svr_reg.bf_ver.version) {
+ *num_clusters = soc_list[i].num_clusters;
+ *cores_per_cluster = soc_list[i].cores_per_cluster;
+ break;
+ }
+ }
+
+ VERBOSE("NUM of cluster = 0x%x, Cores per cluster = 0x%x\n",
+ *num_clusters, *cores_per_cluster);
+}
diff --git a/plat/nxp/common/setup/ls_err.c b/plat/nxp/common/setup/ls_err.c
new file mode 100644
index 0000000..845cd15
--- /dev/null
+++ b/plat/nxp/common/setup/ls_err.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+
+#if TRUSTED_BOARD_BOOT
+#include <dcfg.h>
+#include <snvs.h>
+#endif
+
+#include "plat_common.h"
+
+/*
+ * Error handler
+ */
+void plat_error_handler(int err)
+{
+#if TRUSTED_BOARD_BOOT
+ uint32_t mode;
+ bool sb = check_boot_mode_secure(&mode);
+#endif
+
+ switch (err) {
+ case -ENOENT:
+ case -EAUTH:
+ printf("Authentication failure\n");
+#if TRUSTED_BOARD_BOOT
+ /* For SB production mode i.e ITS = 1 */
+ if (sb == true) {
+ if (mode == 1U) {
+ transition_snvs_soft_fail();
+ } else {
+ transition_snvs_non_secure();
+ }
+ }
+#endif
+ break;
+ default:
+ /* Unexpected error */
+ break;
+ }
+
+ /* Loop until the watchdog resets the system */
+ for (;;)
+ wfi();
+}
diff --git a/plat/nxp/common/setup/ls_image_load.c b/plat/nxp/common/setup/ls_image_load.c
new file mode 100644
index 0000000..259ab31
--- /dev/null
+++ b/plat/nxp/common/setup/ls_image_load.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <common/desc_image_load.h>
+
+/*******************************************************************************
+ * This function flushes the data structures so that they are visible
+ * in memory for the next BL image.
+ ******************************************************************************/
+void plat_flush_next_bl_params(void)
+{
+ flush_bl_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of loadable images.
+ ******************************************************************************/
+bl_load_info_t *plat_get_bl_image_load_info(void)
+{
+ return get_bl_load_info_from_mem_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images.
+ ******************************************************************************/
+bl_params_t *plat_get_next_bl_params(void)
+{
+ return get_next_bl_params_from_mem_params_desc();
+}
diff --git a/plat/nxp/common/setup/ls_interrupt_mgmt.c b/plat/nxp/common/setup/ls_interrupt_mgmt.c
new file mode 100644
index 0000000..a81cb2b
--- /dev/null
+++ b/plat/nxp/common/setup/ls_interrupt_mgmt.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <bl31/interrupt_mgmt.h>
+#include <common/debug.h>
+#include <ls_interrupt_mgmt.h>
+#include <plat/common/platform.h>
+
+static interrupt_type_handler_t type_el3_interrupt_table[MAX_INTR_EL3];
+
+int request_intr_type_el3(uint32_t id, interrupt_type_handler_t handler)
+{
+ /* Validate 'handler' and 'id' parameters */
+ if (!handler || id >= MAX_INTR_EL3) {
+ return -EINVAL;
+ }
+
+ /* Check if a handler has already been registered */
+ if (type_el3_interrupt_table[id] != NULL) {
+ return -EALREADY;
+ }
+
+ type_el3_interrupt_table[id] = handler;
+
+ return 0;
+}
+
+static uint64_t ls_el3_interrupt_handler(uint32_t id, uint32_t flags,
+ void *handle, void *cookie)
+{
+ uint32_t intr_id;
+ interrupt_type_handler_t handler;
+
+ intr_id = plat_ic_get_pending_interrupt_id();
+
+ INFO("Interrupt recvd is %d\n", intr_id);
+
+ handler = type_el3_interrupt_table[intr_id];
+ if (handler != NULL) {
+ handler(intr_id, flags, handle, cookie);
+ }
+
+ /*
+ * Mark this interrupt as complete to avoid a interrupt storm.
+ */
+ plat_ic_end_of_interrupt(intr_id);
+
+ return 0U;
+}
+
+void ls_el3_interrupt_config(void)
+{
+ uint64_t flags = 0U;
+ uint64_t rc;
+
+ set_interrupt_rm_flag(flags, NON_SECURE);
+ rc = register_interrupt_type_handler(INTR_TYPE_EL3,
+ ls_el3_interrupt_handler, flags);
+ if (rc != 0U) {
+ panic();
+ }
+}
diff --git a/plat/nxp/common/setup/ls_io_storage.c b/plat/nxp/common/setup/ls_io_storage.c
new file mode 100644
index 0000000..7f01e72
--- /dev/null
+++ b/plat/nxp/common/setup/ls_io_storage.c
@@ -0,0 +1,556 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/io/io_block.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_fip.h>
+#include <drivers/io/io_memmap.h>
+#include <drivers/io/io_storage.h>
+#ifdef FLEXSPI_NOR_BOOT
+#include <flexspi_nor.h>
+#endif
+#if defined(NAND_BOOT)
+#include <ifc_nand.h>
+#endif
+#if defined(NOR_BOOT)
+#include <ifc_nor.h>
+#endif
+#if defined(QSPI_BOOT)
+#include <qspi.h>
+#endif
+#if defined(SD_BOOT) || defined(EMMC_BOOT)
+#include <sd_mmc.h>
+#endif
+#include <tools_share/firmware_image_package.h>
+
+#ifdef CONFIG_DDR_FIP_IMAGE
+#include <ddr_io_storage.h>
+#endif
+#ifdef POLICY_FUSE_PROVISION
+#include <fuse_io.h>
+#endif
+#include "plat_common.h"
+#include "platform_def.h"
+
+uint32_t fip_device;
+/* IO devices */
+uintptr_t backend_dev_handle;
+
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *backend_dev_con;
+
+static io_block_spec_t fip_block_spec = {
+ .offset = PLAT_FIP_OFFSET,
+ .length = PLAT_FIP_MAX_SIZE
+};
+
+static const io_uuid_spec_t bl2_uuid_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+};
+
+static const io_uuid_spec_t fuse_bl2_uuid_spec = {
+ .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
+};
+
+static const io_uuid_spec_t bl31_uuid_spec = {
+ .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+};
+
+static const io_uuid_spec_t bl32_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32,
+};
+
+static const io_uuid_spec_t bl33_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+static const io_uuid_spec_t tb_fw_config_uuid_spec = {
+ .uuid = UUID_TB_FW_CONFIG,
+};
+
+static const io_uuid_spec_t hw_config_uuid_spec = {
+ .uuid = UUID_HW_CONFIG,
+};
+
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FW_CERT,
+};
+
+static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t fuse_key_cert_uuid_spec = {
+ .uuid = UUID_SCP_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
+ .uuid = UUID_SOC_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t fuse_cert_uuid_spec = {
+ .uuid = UUID_SCP_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
+ .uuid = UUID_SOC_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
+static int open_fip(const uintptr_t spec);
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+/* By default, ARM platforms load images from the FIP */
+static const struct plat_io_policy policies[] = {
+ [FIP_IMAGE_ID] = {
+ &backend_dev_handle,
+ (uintptr_t)&fip_block_spec,
+ open_backend
+ },
+ [BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl2_uuid_spec,
+ open_fip
+ },
+ [SCP_BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&fuse_bl2_uuid_spec,
+ open_fip
+ },
+ [BL31_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl31_uuid_spec,
+ open_fip
+ },
+ [BL32_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_uuid_spec,
+ open_fip
+ },
+ [BL33_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl33_uuid_spec,
+ open_fip
+ },
+ [TB_FW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tb_fw_config_uuid_spec,
+ open_fip
+ },
+ [HW_CONFIG_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&hw_config_uuid_spec,
+ open_fip
+ },
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tb_fw_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&trusted_key_cert_uuid_spec,
+ open_fip
+ },
+ [SCP_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&fuse_key_cert_uuid_spec,
+ open_fip
+ },
+ [SOC_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&soc_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_OS_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [NON_TRUSTED_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [SCP_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&fuse_cert_uuid_spec,
+ open_fip
+ },
+ [SOC_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&soc_fw_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_cert_uuid_spec,
+ open_fip
+ },
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_cert_uuid_spec,
+ open_fip
+ },
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+
+/* Weak definitions may be overridden in specific ARM standard platform */
+#pragma weak plat_io_setup
+
+/*
+ * Return an IO device handle and specification which can be used to access
+ */
+static int open_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if a Firmware Image Package is available */
+ result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(fip_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+
+int open_backend(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ result = io_dev_init(backend_dev_handle, (uintptr_t)NULL);
+ if (result == 0) {
+ result = io_open(backend_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+#if defined(SD_BOOT) || defined(EMMC_BOOT) || defined(NAND_BOOT)
+static int plat_io_block_setup(size_t fip_offset, uintptr_t block_dev_spec)
+{
+ int io_result;
+
+ fip_block_spec.offset = fip_offset;
+
+ io_result = register_io_dev_block(&backend_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(backend_dev_con, block_dev_spec,
+ &backend_dev_handle);
+ assert(io_result == 0);
+
+ return io_result;
+}
+#endif
+
+#if defined(FLEXSPI_NOR_BOOT) || defined(QSPI_BOOT) || defined(NOR_BOOT)
+static int plat_io_memmap_setup(size_t fip_offset)
+{
+ int io_result;
+
+ fip_block_spec.offset = fip_offset;
+
+ io_result = register_io_dev_memmap(&backend_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(backend_dev_con, (uintptr_t)NULL,
+ &backend_dev_handle);
+ assert(io_result == 0);
+
+ return io_result;
+}
+#endif
+
+static int ls_io_fip_setup(unsigned int boot_dev)
+{
+ int io_result;
+
+ io_result = register_io_dev_fip(&fip_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(fip_dev_con, (uintptr_t)&fip_device,
+ &fip_dev_handle);
+ assert(io_result == 0);
+
+#ifdef CONFIG_DDR_FIP_IMAGE
+ /* Open connection to DDR FIP image if available */
+ io_result = ddr_fip_setup(fip_dev_con, boot_dev);
+
+ assert(io_result == 0);
+#endif
+
+#ifdef POLICY_FUSE_PROVISION
+ /* Open connection to FUSE FIP image if available */
+ io_result = fuse_fip_setup(fip_dev_con, boot_dev);
+
+ assert(io_result == 0);
+#endif
+
+ return io_result;
+}
+
+int ls_qspi_io_setup(void)
+{
+#ifdef QSPI_BOOT
+ qspi_io_setup(NXP_QSPI_FLASH_ADDR,
+ NXP_QSPI_FLASH_SIZE,
+ PLAT_FIP_OFFSET);
+ return plat_io_memmap_setup(NXP_QSPI_FLASH_ADDR + PLAT_FIP_OFFSET);
+#else
+ ERROR("QSPI driver not present. Check your BUILD\n");
+
+ /* Should never reach here */
+ assert(false);
+ return -1;
+#endif
+}
+
+int emmc_sdhc2_io_setup(void)
+{
+#if defined(EMMC_BOOT) && defined(NXP_ESDHC2_ADDR)
+ uintptr_t block_dev_spec;
+ int ret;
+
+ ret = sd_emmc_init(&block_dev_spec,
+ NXP_ESDHC2_ADDR,
+ NXP_SD_BLOCK_BUF_ADDR,
+ NXP_SD_BLOCK_BUF_SIZE,
+ false);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return plat_io_block_setup(PLAT_FIP_OFFSET, block_dev_spec);
+#else
+ ERROR("EMMC driver not present. Check your BUILD\n");
+
+ /* Should never reach here */
+ assert(false);
+ return -1;
+#endif
+}
+
+int emmc_io_setup(void)
+{
+/* On the platforms which only has one ESDHC controller,
+ * eMMC-boot will use the first ESDHC controller.
+ */
+#if defined(SD_BOOT) || defined(EMMC_BOOT)
+ uintptr_t block_dev_spec;
+ int ret;
+
+ ret = sd_emmc_init(&block_dev_spec,
+ NXP_ESDHC_ADDR,
+ NXP_SD_BLOCK_BUF_ADDR,
+ NXP_SD_BLOCK_BUF_SIZE,
+ true);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return plat_io_block_setup(PLAT_FIP_OFFSET, block_dev_spec);
+#else
+ ERROR("SD driver not present. Check your BUILD\n");
+
+ /* Should never reach here */
+ assert(false);
+ return -1;
+#endif
+}
+
+int ifc_nor_io_setup(void)
+{
+#if defined(NOR_BOOT)
+ int ret;
+
+ ret = ifc_nor_init(NXP_NOR_FLASH_ADDR,
+ NXP_NOR_FLASH_SIZE);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ return plat_io_memmap_setup(NXP_NOR_FLASH_ADDR + PLAT_FIP_OFFSET);
+#else
+ ERROR("NOR driver not present. Check your BUILD\n");
+
+ /* Should never reach here */
+ assert(false);
+ return -1;
+#endif
+}
+
+int ifc_nand_io_setup(void)
+{
+#if defined(NAND_BOOT)
+ uintptr_t block_dev_spec;
+ int ret;
+
+ ret = ifc_nand_init(&block_dev_spec,
+ NXP_IFC_REGION_ADDR,
+ NXP_IFC_ADDR,
+ NXP_IFC_SRAM_BUFFER_SIZE,
+ NXP_SD_BLOCK_BUF_ADDR,
+ NXP_SD_BLOCK_BUF_SIZE);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return plat_io_block_setup(PLAT_FIP_OFFSET, block_dev_spec);
+#else
+
+ ERROR("NAND driver not present. Check your BUILD\n");
+
+ /* Should never reach here */
+ assert(false);
+ return -1;
+#endif
+}
+
+int ls_flexspi_nor_io_setup(void)
+{
+#ifdef FLEXSPI_NOR_BOOT
+ int ret = 0;
+
+ ret = flexspi_nor_io_setup(NXP_FLEXSPI_FLASH_ADDR,
+ NXP_FLEXSPI_FLASH_SIZE,
+ NXP_FLEXSPI_ADDR);
+
+ if (ret != 0) {
+ ERROR("FlexSPI NOR driver initialization error.\n");
+ /* Should never reach here */
+ assert(0);
+ panic();
+ return -1;
+ }
+
+ return plat_io_memmap_setup(NXP_FLEXSPI_FLASH_ADDR + PLAT_FIP_OFFSET);
+#else
+ ERROR("FlexSPI NOR driver not present. Check your BUILD\n");
+
+ /* Should never reach here */
+ assert(false);
+ return -1;
+#endif
+}
+
+static int (* const ls_io_setup_table[])(void) = {
+ [BOOT_DEVICE_IFC_NOR] = ifc_nor_io_setup,
+ [BOOT_DEVICE_IFC_NAND] = ifc_nand_io_setup,
+ [BOOT_DEVICE_QSPI] = ls_qspi_io_setup,
+ [BOOT_DEVICE_EMMC] = emmc_io_setup,
+ [BOOT_DEVICE_SDHC2_EMMC] = emmc_sdhc2_io_setup,
+ [BOOT_DEVICE_FLEXSPI_NOR] = ls_flexspi_nor_io_setup,
+ [BOOT_DEVICE_FLEXSPI_NAND] = ls_flexspi_nor_io_setup,
+};
+
+
+int plat_io_setup(void)
+{
+ int (*io_setup)(void);
+ unsigned int boot_dev = BOOT_DEVICE_NONE;
+ int ret;
+
+ boot_dev = get_boot_dev();
+ if (boot_dev == BOOT_DEVICE_NONE) {
+ ERROR("Boot Device detection failed, Check RCW_SRC\n");
+ return -EINVAL;
+ }
+
+ io_setup = ls_io_setup_table[boot_dev];
+ ret = io_setup();
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = ls_io_fip_setup(boot_dev);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+/* Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy
+ */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ int result = -1;
+ const struct plat_io_policy *policy;
+
+ if (image_id < ARRAY_SIZE(policies)) {
+
+ policy = &policies[image_id];
+ result = policy->check(policy->image_spec);
+ if (result == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ }
+ }
+#ifdef CONFIG_DDR_FIP_IMAGE
+ else {
+ VERBOSE("Trying alternative IO\n");
+ result = plat_get_ddr_fip_image_source(image_id, dev_handle,
+ image_spec, open_backend);
+ }
+#endif
+#ifdef POLICY_FUSE_PROVISION
+ if (result != 0) {
+ VERBOSE("Trying FUSE IO\n");
+ result = plat_get_fuse_image_source(image_id, dev_handle,
+ image_spec, open_backend);
+ }
+#endif
+
+ return result;
+}
diff --git a/plat/nxp/common/setup/ls_stack_protector.c b/plat/nxp/common/setup/ls_stack_protector.c
new file mode 100644
index 0000000..ab78f88
--- /dev/null
+++ b/plat/nxp/common/setup/ls_stack_protector.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+#include <arch_helpers.h>
+
+#include <plat/common/platform.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ /*
+ * TBD: Generate Random Number from NXP CAAM Block.
+ */
+ return RANDOM_CANARY_VALUE ^ read_cntpct_el0();
+}
diff --git a/plat/nxp/common/sip_svc/aarch64/sipsvc.S b/plat/nxp/common/sip_svc/aarch64/sipsvc.S
new file mode 100644
index 0000000..6a47cbf
--- /dev/null
+++ b/plat/nxp/common/sip_svc/aarch64/sipsvc.S
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <asm_macros.S>
+#include <bl31_data.h>
+
+.global el2_2_aarch32
+.global prefetch_disable
+
+#define SPSR_EL3_M4 0x10
+#define SPSR_EL_MASK 0xC
+#define SPSR_EL2 0x8
+#define SCR_EL3_4_EL2_AARCH32 0x131
+#define SPSR32_EL2_LE 0x1DA
+
+#define MIDR_PARTNUM_START 4
+#define MIDR_PARTNUM_WIDTH 12
+#define MIDR_PARTNUM_A53 0xD03
+#define MIDR_PARTNUM_A57 0xD07
+#define MIDR_PARTNUM_A72 0xD08
+
+/*
+ * uint64_t el2_2_aarch32(u_register_t smc_id,
+ * u_register_t start_addr,
+ * u_register_t parm1,
+ * u_register_t parm2)
+ * this function allows changing the execution width of EL2 from Aarch64
+ * to Aarch32
+ * Note: MUST be called from EL2 @ Aarch64
+ * in: x0 = smc function id
+ * x1 = start address for EL2 @ Aarch32
+ * x2 = first parameter to pass to EL2 @ Aarch32
+ * x3 = second parameter to pass to EL2 @ Aarch32
+ * out: x0 = 0, on success
+ * x0 = -1, on failure
+ * uses x0, x1, x2, x3
+ */
+func el2_2_aarch32
+
+ /* check that caller is EL2 @ Aarch64 - err return if not */
+ mrs x0, spsr_el3
+ /* see if we were called from Aarch32 */
+ tst x0, #SPSR_EL3_M4
+ b.ne 2f
+
+ /* see if we were called from EL2 */
+ and x0, x0, SPSR_EL_MASK
+ cmp x0, SPSR_EL2
+ b.ne 2f
+
+ /* set ELR_EL3 */
+ msr elr_el3, x1
+
+ /* set scr_el3 */
+ mov x0, #SCR_EL3_4_EL2_AARCH32
+ msr scr_el3, x0
+
+ /* set sctlr_el2 */
+ ldr x1, =SCTLR_EL2_RES1
+ msr sctlr_el2, x1
+
+ /* set spsr_el3 */
+ ldr x0, =SPSR32_EL2_LE
+ msr spsr_el3, x0
+
+ /* x2 = parm 1
+ * x3 = parm2
+ */
+
+ /* set the parameters to be passed-thru to EL2 @ Aarch32 */
+ mov x1, x2
+ mov x2, x3
+
+ /* x1 = parm 1
+ * x2 = parm2
+ */
+
+ mov x0, xzr
+ /* invalidate the icache */
+ ic iallu
+ dsb sy
+ isb
+ b 1f
+2:
+ /* error return */
+ mvn x0, xzr
+ ret
+1:
+ eret
+endfunc el2_2_aarch32
+
+/*
+ * int prefetch_disable(u_register_t smc_id, u_register_t mask)
+ * this function marks cores which need to have the prefetch disabled -
+ * secondary cores have prefetch disabled when they are released from reset -
+ * the bootcore has prefetch disabled when this call is made
+ * in: x0 = function id
+ * x1 = core mask, where bit[0]=core0, bit[1]=core1, etc
+ * if a bit in the mask is set, then prefetch is disabled for that
+ * core
+ * out: x0 = SMC_SUCCESS
+ */
+func prefetch_disable
+ stp x4, x30, [sp, #-16]!
+
+ mov x3, x1
+
+ /* x1 = core prefetch disable mask */
+ /* x3 = core prefetch disable mask */
+
+ /* store the mask */
+ mov x0, #PREFETCH_DIS_OFFSET
+ bl _set_global_data
+
+ /* x3 = core prefetch disable mask */
+
+ /* see if we need to disable prefetch on THIS core */
+ bl plat_my_core_mask
+
+ /* x0 = core mask lsb */
+ /* x3 = core prefetch disable mask */
+
+ tst x3, x0
+ b.eq 1f
+
+ /* read midr_el1 */
+ mrs x1, midr_el1
+
+ /* x1 = midr_el1 */
+
+ mov x0, xzr
+ bfxil x0, x1, #MIDR_PARTNUM_START, #MIDR_PARTNUM_WIDTH
+
+ /* x0 = part number (a53, a57, a72, etc) */
+
+ /* branch on cpu-specific */
+ cmp x0, #MIDR_PARTNUM_A57
+ b.eq 1f
+ cmp x0, #MIDR_PARTNUM_A72
+ b.ne 1f
+
+ bl _disable_ldstr_pfetch_A72
+ b 1f
+1:
+ ldp x4, x30, [sp], #16
+ mov x0, xzr
+ ret
+endfunc prefetch_disable
diff --git a/plat/nxp/common/sip_svc/include/sipsvc.h b/plat/nxp/common/sip_svc/include/sipsvc.h
new file mode 100644
index 0000000..d9e61e9
--- /dev/null
+++ b/plat/nxp/common/sip_svc/include/sipsvc.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SIPSVC_H
+#define SIPSVC_H
+
+#include <stdint.h>
+
+#define SMC_FUNC_MASK 0x0000ffff
+#define SMC32_PARAM_MASK 0xffffffff
+
+/* SMC function IDs for SiP Service queries */
+#define SIP_SVC_CALL_COUNT 0xff00
+#define SIP_SVC_UID 0xff01
+#define SIP_SVC_VERSION 0xff03
+#define SIP_SVC_PRNG 0xff10
+#define SIP_SVC_RNG 0xff11
+#define SIP_SVC_MEM_BANK 0xff12
+#define SIP_SVC_PREFETCH_DIS 0xff13
+#define SIP_SVC_HUK 0xff14
+#define SIP_SVC_ALLOW_L1L2_ERR 0xff15
+#define SIP_SVC_ALLOW_L2_CLR 0xff16
+#define SIP_SVC_2_AARCH32 0xff17
+#define SIP_SVC_PORSR1 0xff18
+
+/* Layerscape SiP Service Calls version numbers */
+#define LS_SIP_SVC_VERSION_MAJOR 0x0
+#define LS_SIP_SVC_VERSION_MINOR 0x1
+
+/* Number of Layerscape SiP Calls implemented */
+#define LS_COMMON_SIP_NUM_CALLS 10
+
+/* Parameter Type Constants */
+#define SIP_PARAM_TYPE_NONE 0x0
+#define SIP_PARAM_TYPE_VALUE_INPUT 0x1
+#define SIP_PARAM_TYPE_VALUE_OUTPUT 0x2
+#define SIP_PARAM_TYPE_VALUE_INOUT 0x3
+#define SIP_PARAM_TYPE_MEMREF_INPUT 0x5
+#define SIP_PARAM_TYPE_MEMREF_OUTPUT 0x6
+#define SIP_PARAM_TYPE_MEMREF_INOUT 0x7
+
+#define SIP_PARAM_TYPE_MASK 0xF
+
+/*
+ * The macro SIP_PARAM_TYPES can be used to construct a value that you can
+ * compare against an incoming paramTypes to check the type of all the
+ * parameters in one comparison.
+ */
+#define SIP_PARAM_TYPES(t0, t1, t2, t3) \
+ ((t0) | ((t1) << 4) | ((t2) << 8) | ((t3) << 12))
+
+/*
+ * The macro SIP_PARAM_TYPE_GET can be used to extract the type of a given
+ * parameter from paramTypes if you need more fine-grained type checking.
+ */
+#define SIP_PARAM_TYPE_GET(t, i) ((((uint32_t)(t)) >> ((i) * 4)) & 0xF)
+
+/*
+ * The macro SIP_PARAM_TYPE_SET can be used to load the type of a given
+ * parameter from paramTypes without specifying all types (SIP_PARAM_TYPES)
+ */
+#define SIP_PARAM_TYPE_SET(t, i) (((uint32_t)(t) & 0xF) << ((i) * 4))
+
+#define SIP_SVC_RNG_PARAMS (SIP_PARAM_TYPE_VALUE_INPUT, \
+ SIP_PARAM_TYPE_MEMREF_OUTPUT, \
+ SIP_PARAM_TYPE_NONE, \
+ SIP_PARAM_TYPE_NONE)
+
+/* Layerscape SiP Calls error code */
+enum {
+ LS_SIP_SUCCESS = 0,
+ LS_SIP_INVALID_PARAM = -1,
+ LS_SIP_NOT_SUPPORTED = -2,
+};
+
+#endif /* SIPSVC_H */
diff --git a/plat/nxp/common/sip_svc/sip_svc.c b/plat/nxp/common/sip_svc/sip_svc.c
new file mode 100644
index 0000000..1c8668e
--- /dev/null
+++ b/plat/nxp/common/sip_svc/sip_svc.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <caam.h>
+#include <common/runtime_svc.h>
+#include <dcfg.h>
+#include <lib/mmio.h>
+#include <tools_share/uuid.h>
+
+#include <plat_common.h>
+#include <sipsvc.h>
+
+/* Layerscape SiP Service UUID */
+DEFINE_SVC_UUID2(nxp_sip_svc_uid,
+ 0x871de4ef, 0xedfc, 0x4209, 0xa4, 0x23,
+ 0x8d, 0x23, 0x75, 0x9d, 0x3b, 0x9f);
+
+#pragma weak nxp_plat_sip_handler
+static uintptr_t nxp_plat_sip_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)
+{
+ ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+}
+
+uint64_t el2_2_aarch32(u_register_t smc_id, u_register_t start_addr,
+ u_register_t parm1, u_register_t parm2);
+
+uint64_t prefetch_disable(u_register_t smc_id, u_register_t mask);
+uint64_t bl31_get_porsr1(void);
+
+static void clean_top_32b_of_param(uint32_t smc_fid,
+ u_register_t *px1,
+ u_register_t *px2,
+ u_register_t *px3,
+ u_register_t *px4)
+{
+ /* if parameters from SMC32. Clean top 32 bits */
+ if (GET_SMC_CC(smc_fid) == SMC_32) {
+ *px1 = *px1 & SMC32_PARAM_MASK;
+ *px2 = *px2 & SMC32_PARAM_MASK;
+ *px3 = *px3 & SMC32_PARAM_MASK;
+ *px4 = *px4 & SMC32_PARAM_MASK;
+ }
+}
+
+/* This function handles Layerscape defined SiP Calls */
+static uintptr_t nxp_sip_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)
+{
+ uint32_t ns;
+ uint64_t ret;
+ dram_regions_info_t *info_dram_regions;
+
+ /* if parameter is sent from SMC32. Clean top 32 bits */
+ clean_top_32b_of_param(smc_fid, &x1, &x2, &x3, &x4);
+
+ /* Determine which security state this SMC originated from */
+ ns = is_caller_non_secure(flags);
+ if (ns == 0) {
+ /* SiP SMC service secure world's call */
+ ;
+ } else {
+ /* SiP SMC service normal world's call */
+ ;
+ }
+
+ switch (smc_fid & SMC_FUNC_MASK) {
+ case SIP_SVC_RNG:
+ if (is_sec_enabled() == false) {
+ NOTICE("SEC is disabled.\n");
+ SMC_RET1(handle, SMC_UNK);
+ }
+
+ /* Return zero on failure */
+ ret = get_random((int)x1);
+ if (ret != 0) {
+ SMC_RET2(handle, SMC_OK, ret);
+ } else {
+ SMC_RET1(handle, SMC_UNK);
+ }
+ /* break is not required as SMC_RETx return */
+ case SIP_SVC_HUK:
+ if (is_sec_enabled() == false) {
+ NOTICE("SEC is disabled.\n");
+ SMC_RET1(handle, SMC_UNK);
+ }
+ ret = get_hw_unq_key_blob_hw((uint8_t *) x1, (uint32_t) x2);
+
+ if (ret == SMC_OK) {
+ SMC_RET1(handle, SMC_OK);
+ } else {
+ SMC_RET1(handle, SMC_UNK);
+ }
+ /* break is not required as SMC_RETx return */
+ case SIP_SVC_MEM_BANK:
+ VERBOSE("Handling SMC SIP_SVC_MEM_BANK.\n");
+ info_dram_regions = get_dram_regions_info();
+
+ if (x1 == -1) {
+ SMC_RET2(handle, SMC_OK,
+ info_dram_regions->total_dram_size);
+ } else if (x1 >= info_dram_regions->num_dram_regions) {
+ SMC_RET1(handle, SMC_UNK);
+ } else {
+ SMC_RET3(handle, SMC_OK,
+ info_dram_regions->region[x1].addr,
+ info_dram_regions->region[x1].size);
+ }
+ /* break is not required as SMC_RETx return */
+ case SIP_SVC_PREFETCH_DIS:
+ VERBOSE("In SIP_SVC_PREFETCH_DIS call\n");
+ ret = prefetch_disable(smc_fid, x1);
+ if (ret == SMC_OK) {
+ SMC_RET1(handle, SMC_OK);
+ } else {
+ SMC_RET1(handle, SMC_UNK);
+ }
+ /* break is not required as SMC_RETx return */
+ case SIP_SVC_2_AARCH32:
+ ret = el2_2_aarch32(smc_fid, x1, x2, x3);
+
+ /* In success case, control should not reach here. */
+ NOTICE("SMC: SIP_SVC_2_AARCH32 Failed.\n");
+ SMC_RET1(handle, SMC_UNK);
+ /* break is not required as SMC_RETx return */
+ case SIP_SVC_PORSR1:
+ ret = bl31_get_porsr1();
+ SMC_RET2(handle, SMC_OK, ret);
+ /* break is not required as SMC_RETx return */
+ default:
+ return nxp_plat_sip_handler(smc_fid, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+}
+
+/* This function is responsible for handling all SiP calls */
+static uintptr_t sip_smc_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)
+{
+ switch (smc_fid & SMC_FUNC_MASK) {
+ case SIP_SVC_CALL_COUNT:
+ /* Return the number of Layerscape SiP Service Calls. */
+ SMC_RET1(handle, LS_COMMON_SIP_NUM_CALLS);
+ break;
+ case SIP_SVC_UID:
+ /* Return UID to the caller */
+ SMC_UUID_RET(handle, nxp_sip_svc_uid);
+ break;
+ case SIP_SVC_VERSION:
+ /* Return the version of current implementation */
+ SMC_RET2(handle, LS_SIP_SVC_VERSION_MAJOR,
+ LS_SIP_SVC_VERSION_MINOR);
+ break;
+ default:
+ return nxp_sip_handler(smc_fid, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+}
+
+/* Define a runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+ nxp_sip_svc,
+ OEN_SIP_START,
+ OEN_SIP_END,
+ SMC_TYPE_FAST,
+ NULL,
+ sip_smc_handler
+);
diff --git a/plat/nxp/common/sip_svc/sipsvc.mk b/plat/nxp/common/sip_svc/sipsvc.mk
new file mode 100644
index 0000000..c3a57de
--- /dev/null
+++ b/plat/nxp/common/sip_svc/sipsvc.mk
@@ -0,0 +1,35 @@
+#
+# Copyright 2018-2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# Select the SIP SVC files
+#
+# -----------------------------------------------------------------------------
+
+ifeq (${ADD_SIPSVC},)
+
+ADD_SIPSVC := 1
+
+PLAT_SIPSVC_PATH := $(PLAT_COMMON_PATH)/sip_svc
+
+SIPSVC_SOURCES := ${PLAT_SIPSVC_PATH}/sip_svc.c \
+ ${PLAT_SIPSVC_PATH}/$(ARCH)/sipsvc.S
+
+PLAT_INCLUDES += -I${PLAT_SIPSVC_PATH}/include
+
+ifeq (${BL_COMM_SIPSVC_NEEDED},yes)
+BL_COMMON_SOURCES += ${SIPSVC_SOURCES}
+else
+ifeq (${BL2_SIPSVC_NEEDED},yes)
+BL2_SOURCES += ${SIPSVC_SOURCES}
+endif
+ifeq (${BL31_SIPSVC_NEEDED},yes)
+BL31_SOURCES += ${SIPSVC_SOURCES}
+endif
+endif
+endif
+# -----------------------------------------------------------------------------
diff --git a/plat/nxp/common/soc_errata/errata.c b/plat/nxp/common/soc_errata/errata.c
new file mode 100644
index 0000000..55ef604
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <common/debug.h>
+
+#include "errata_list.h"
+
+void soc_errata(void)
+{
+#ifdef ERRATA_SOC_A050426
+ INFO("SoC workaround for Errata A050426 was applied\n");
+ erratum_a050426();
+#endif
+#ifdef ERRATA_SOC_A008850
+ INFO("SoC workaround for Errata A008850 Early-Phase was applied\n");
+ erratum_a008850_early();
+#endif
+#if ERRATA_SOC_A009660
+ INFO("SoC workaround for Errata A009660 was applied\n");
+ erratum_a009660();
+#endif
+#if ERRATA_SOC_A010539
+ INFO("SoC workaround for Errata A010539 was applied\n");
+ erratum_a010539();
+#endif
+
+ /*
+ * The following DDR Erratas workaround are implemented in DDR driver,
+ * but print information here.
+ */
+#if ERRATA_DDR_A011396
+ INFO("SoC workaround for DDR Errata A011396 was applied\n");
+#endif
+#if ERRATA_DDR_A050450
+ INFO("SoC workaround for DDR Errata A050450 was applied\n");
+#endif
+#if ERRATA_DDR_A050958
+ INFO("SoC workaround for DDR Errata A050958 was applied\n");
+#endif
+#if ERRATA_DDR_A008511
+ INFO("SoC workaround for DDR Errata A008511 was applied\n");
+#endif
+#if ERRATA_DDR_A009803
+ INFO("SoC workaround for DDR Errata A009803 was applied\n");
+#endif
+#if ERRATA_DDR_A009942
+ INFO("SoC workaround for DDR Errata A009942 was applied\n");
+#endif
+#if ERRATA_DDR_A010165
+ INFO("SoC workaround for DDR Errata A010165 was applied\n");
+#endif
+#if ERRATA_DDR_A009663
+ INFO("SoC workaround for DDR Errata A009663 was applied\n");
+#endif
+}
diff --git a/plat/nxp/common/soc_errata/errata.h b/plat/nxp/common/soc_errata/errata.h
new file mode 100644
index 0000000..ab67995
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2020-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef ERRATA_H
+#define ERRATA_H
+
+#include "errata_list.h"
+
+void soc_errata(void);
+
+#endif /* ERRATA_H */
diff --git a/plat/nxp/common/soc_errata/errata.mk b/plat/nxp/common/soc_errata/errata.mk
new file mode 100644
index 0000000..3deef3d
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata.mk
@@ -0,0 +1,26 @@
+#
+# Copyright 2021-2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform Errata Build flags.
+# These should be enabled by the platform if the erratum workaround needs to be
+# applied.
+
+ERRATA := \
+ ERRATA_SOC_A050426 \
+ ERRATA_SOC_A008850 \
+ ERRATA_SOC_A009660 \
+ ERRATA_SOC_A010539
+
+define enable_errata
+ $(1) ?= 0
+ ifeq ($$($(1)),1)
+ $$(eval $$(call add_define,$(1)))
+ BL2_SOURCES += $(PLAT_COMMON_PATH)/soc_errata/errata_a$(shell echo $(1)|awk -F '_A' '{print $$NF}').c
+ endif
+endef
+
+$(foreach e,$(ERRATA),$(eval $(call enable_errata,$(strip $(e)))))
+
+BL2_SOURCES += $(PLAT_COMMON_PATH)/soc_errata/errata.c
diff --git a/plat/nxp/common/soc_errata/errata_a008850.c b/plat/nxp/common/soc_errata/errata_a008850.c
new file mode 100644
index 0000000..e8c0f64
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_a008850.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <cci.h>
+#include <common/debug.h>
+#include <ls_interconnect.h>
+#include <mmio.h>
+
+#include <platform_def.h>
+
+void erratum_a008850_early(void)
+{
+ /* part 1 of 2 */
+ uintptr_t cci_base = NXP_CCI_ADDR;
+ uint32_t val = mmio_read_32(cci_base + CTRL_OVERRIDE_REG);
+
+ /* enabling forced barrier termination on CCI400 */
+ mmio_write_32(cci_base + CTRL_OVERRIDE_REG,
+ (val | CCI_TERMINATE_BARRIER_TX));
+
+}
+
+void erratum_a008850_post(void)
+{
+ /* part 2 of 2 */
+ uintptr_t cci_base = NXP_CCI_ADDR;
+ uint32_t val = mmio_read_32(cci_base + CTRL_OVERRIDE_REG);
+
+ /* Clear the BARRIER_TX bit */
+ val = val & ~(CCI_TERMINATE_BARRIER_TX);
+
+ /*
+ * Disable barrier termination on CCI400, allowing
+ * barriers to propagate across CCI
+ */
+ mmio_write_32(cci_base + CTRL_OVERRIDE_REG, val);
+
+ INFO("SoC workaround for Errata A008850 Post-Phase was applied\n");
+}
diff --git a/plat/nxp/common/soc_errata/errata_a009660.c b/plat/nxp/common/soc_errata/errata_a009660.c
new file mode 100644
index 0000000..d31a4d7
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_a009660.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <mmio.h>
+#include <soc_default_base_addr.h>
+
+void erratum_a009660(void)
+{
+ mmio_write_32(NXP_SCFG_ADDR + 0x20c, 0x63b20042);
+}
diff --git a/plat/nxp/common/soc_errata/errata_a010539.c b/plat/nxp/common/soc_errata/errata_a010539.c
new file mode 100644
index 0000000..3dcbdc8
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_a010539.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <mmio.h>
+
+#include <plat_common.h>
+
+void erratum_a010539(void)
+{
+ if (get_boot_dev() == BOOT_DEVICE_QSPI) {
+ unsigned int *porsr1 = (void *)(NXP_DCFG_ADDR +
+ DCFG_PORSR1_OFFSET);
+ uint32_t val;
+
+ val = (gur_in32(porsr1) & ~PORSR1_RCW_MASK);
+ mmio_write_32((uint32_t)(NXP_DCSR_DCFG_ADDR +
+ DCFG_DCSR_PORCR1_OFFSET), htobe32(val));
+ /* Erratum need to set '1' to all bits for reserved SCFG register 0x1a8 */
+ mmio_write_32((uint32_t)(NXP_SCFG_ADDR + 0x1a8),
+ htobe32(0xffffffff));
+ }
+}
diff --git a/plat/nxp/common/soc_errata/errata_a050426.c b/plat/nxp/common/soc_errata/errata_a050426.c
new file mode 100644
index 0000000..ba4f71f
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_a050426.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2021-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <common/debug.h>
+#include <mmio.h>
+
+void erratum_a050426(void)
+{
+ uint32_t i, val3, val4;
+
+ /*
+ * Part of this Errata is implemented in RCW and SCRATCHRW5
+ * register is updated to hold Errata number.
+ * Validate whether RCW has already included required changes
+ */
+ if (mmio_read_32(0x01e00210) != 0x00050426) {
+ ERROR("%s: Invalid RCW : ERR050426 not implemented\n", __func__);
+ }
+
+ /* Enable BIST to access Internal memory locations */
+ val3 = mmio_read_32(0x700117E60);
+ mmio_write_32(0x700117E60, (val3 | 0x80000001));
+ val4 = mmio_read_32(0x700117E90);
+ mmio_write_32(0x700117E90, (val4 & 0xFFDFFFFF));
+
+ /* wriop Internal Memory.*/
+ for (i = 0U; i < 4U; i++) {
+ mmio_write_32(0x706312000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706312400 + (i * 4), 0x55555555);
+ mmio_write_32(0x706312800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706314000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706314400 + (i * 4), 0x55555555);
+ mmio_write_32(0x706314800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706314c00 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 3U; i++) {
+ mmio_write_32(0x706316000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706320000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706320400 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 2U; i++) {
+ mmio_write_32(0x70640a000 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 3U; i++) {
+ mmio_write_32(0x706518000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706519000 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 4U; i++) {
+ mmio_write_32(0x706522000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706522800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706523000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706523800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706524000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706524800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706608000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706608800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706609000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706609800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70660a000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70660a800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70660b000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70660b800 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 3U; i++) {
+ mmio_write_32(0x70660c000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70660c800 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 2U; i++) {
+ mmio_write_32(0x706718000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706718800 + (i * 4), 0x55555555);
+ }
+ mmio_write_32(0x706b0a000, 0x55555555);
+
+ for (i = 0U; i < 4U; i++) {
+ mmio_write_32(0x706b0e000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706b0e800 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 2U; i++) {
+ mmio_write_32(0x706b10000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706b10400 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 4U; i++) {
+ mmio_write_32(0x706b14000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706b14800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706b15000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706b15800 + (i * 4), 0x55555555);
+ }
+ mmio_write_32(0x706e12000, 0x55555555);
+
+ for (i = 0U; i < 4U; i++) {
+ mmio_write_32(0x706e14000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e14800 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 2U; i++) {
+ mmio_write_32(0x706e16000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e16400 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 3U; i++) {
+ mmio_write_32(0x706e1a000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e1a800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e1b000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e1b800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e1c000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e1c800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e1e000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e1e800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e1f000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e1f800 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e20000 + (i * 4), 0x55555555);
+ mmio_write_32(0x706e20800 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 4U; i++) {
+ mmio_write_32(0x707108000 + (i * 4), 0x55555555);
+ mmio_write_32(0x707109000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70710a000 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 2U; i++) {
+ mmio_write_32(0x70711c000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70711c800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70711d000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70711d800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70711e000 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 4U; i++) {
+ mmio_write_32(0x707120000 + (i * 4), 0x55555555);
+ mmio_write_32(0x707121000 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 3U; i++) {
+ mmio_write_32(0x707122000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70725a000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70725b000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70725c000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70725e000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70725e400 + (i * 4), 0x55555555);
+ mmio_write_32(0x70725e800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70725ec00 + (i * 4), 0x55555555);
+ mmio_write_32(0x70725f000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70725f400 + (i * 4), 0x55555555);
+ mmio_write_32(0x707340000 + (i * 4), 0x55555555);
+ mmio_write_32(0x707346000 + (i * 4), 0x55555555);
+ mmio_write_32(0x707484000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70748a000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70748b000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70748c000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70748d000 + (i * 4), 0x55555555);
+ }
+
+ /* EDMA Internal Memory.*/
+ for (i = 0U; i < 5U; i++) {
+ mmio_write_32(0x70a208000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70a208800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70a209000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70a209800 + (i * 4), 0x55555555);
+ }
+
+ /* QDMA Internal Memory.*/
+ for (i = 0U; i < 5U; i++) {
+ mmio_write_32(0x70b008000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b00c000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b010000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b014000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b018000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b018400 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b01a000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b01a400 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b01c000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b01d000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b01e000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b01e800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b01f000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b01f800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b020000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b020400 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b020800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b020c00 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b022000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b022400 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b024000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b024800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b025000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b025800 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 4U; i++) {
+ mmio_write_32(0x70b026000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b026200 + (i * 4), 0x55555555);
+ }
+ for (i = 0U; i < 5U; i++) {
+ mmio_write_32(0x70b028000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b028800 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b029000 + (i * 4), 0x55555555);
+ mmio_write_32(0x70b029800 + (i * 4), 0x55555555);
+ }
+
+ /* Disable BIST */
+ mmio_write_32(0x700117E60, val3);
+ mmio_write_32(0x700117E90, val4);
+}
diff --git a/plat/nxp/common/soc_errata/errata_list.h b/plat/nxp/common/soc_errata/errata_list.h
new file mode 100644
index 0000000..f6741e2
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_list.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2021-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef ERRATA_LIST_H
+#define ERRATA_LIST_H
+
+#ifdef ERRATA_SOC_A050426
+void erratum_a050426(void);
+#endif
+
+#ifdef ERRATA_SOC_A008850
+void erratum_a008850_early(void);
+void erratum_a008850_post(void);
+#endif
+
+#ifdef ERRATA_SOC_A009660
+void erratum_a009660(void);
+#endif
+
+#ifdef ERRATA_SOC_A010539
+void erratum_a010539(void);
+#endif
+
+#endif /* ERRATA_LIST_H */
diff --git a/plat/nxp/common/tbbr/csf_tbbr.c b/plat/nxp/common/tbbr/csf_tbbr.c
new file mode 100644
index 0000000..8f38f3e
--- /dev/null
+++ b/plat/nxp/common/tbbr/csf_tbbr.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ *
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <csf_hdr.h>
+#include <dcfg.h>
+#include <drivers/auth/crypto_mod.h>
+#include <snvs.h>
+
+#include <plat/common/platform.h>
+#include "plat_common.h"
+
+extern bool rotpk_not_dpld;
+extern uint8_t rotpk_hash_table[MAX_KEY_ENTRIES][SHA256_BYTES];
+extern uint32_t num_rotpk_hash_entries;
+
+/*
+ * In case of secure boot, return ptr of rotpk_hash table in key_ptr and
+ * number of hashes in key_len
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ uint32_t mode = 0U;
+ *flags = ROTPK_NOT_DEPLOYED;
+
+ /* ROTPK hash table must be available for secure boot */
+ if (rotpk_not_dpld == true) {
+ if (check_boot_mode_secure(&mode) == true) {
+ /* Production mode, don;t continue further */
+ if (mode == 1U) {
+ return -EAUTH;
+ }
+
+ /* For development mode, rotpk flag false
+ * indicates that SRK hash comparison might
+ * have failed. This is not fatal error.
+ * Continue in this case but transition SNVS
+ * to non-secure state
+ */
+ transition_snvs_non_secure();
+ return 0;
+ } else {
+ return 0;
+ }
+ }
+
+ /*
+ * We return the complete hash table and number of entries in
+ * table for NXP platform specific implementation.
+ * Here hash is always assume as SHA-256
+ */
+ *key_ptr = rotpk_hash_table;
+ *key_len = num_rotpk_hash_entries;
+ *flags = ROTPK_IS_HASH;
+
+ return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ /*
+ * No support for non-volatile counter. Update the ROT key to protect
+ * the system against rollback.
+ */
+ *nv_ctr = 0U;
+
+ return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ return 0;
+}
diff --git a/plat/nxp/common/tbbr/nxp_rotpk.S b/plat/nxp/common/tbbr/nxp_rotpk.S
new file mode 100644
index 0000000..8e084d1
--- /dev/null
+++ b/plat/nxp/common/tbbr/nxp_rotpk.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ *
+ */
+
+#ifndef _CSF_HDR_H_
+
+ .global nxp_rotpk_hash
+ .global nxp_rotpk_hash_end
+ .section .rodata.nxp_rotpk_hash, "a"
+nxp_rotpk_hash:
+ /* DER header */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* SHA256 */
+ .incbin ROTPK_HASH
+nxp_rotpk_hash_end:
+#endif
diff --git a/plat/nxp/common/tbbr/tbbr.mk b/plat/nxp/common/tbbr/tbbr.mk
new file mode 100644
index 0000000..4aac9d6
--- /dev/null
+++ b/plat/nxp/common/tbbr/tbbr.mk
@@ -0,0 +1,162 @@
+#
+# Copyright 2020-2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# For TRUSTED_BOARD_BOOT platforms need to include this makefile
+# Following definations are to be provided by platform.mk file or
+# by user - BL33_INPUT_FILE, BL32_INPUT_FILE, BL31_INPUT_FILE
+
+ifeq ($(CHASSIS), 2)
+include $(PLAT_DRIVERS_PATH)/csu/csu.mk
+CSF_FILE := input_blx_ch${CHASSIS}
+BL2_CSF_FILE := input_bl2_ch${CHASSIS}
+else
+ifeq ($(CHASSIS), 3)
+CSF_FILE := input_blx_ch${CHASSIS}
+BL2_CSF_FILE := input_bl2_ch${CHASSIS}
+PBI_CSF_FILE := input_pbi_ch${CHASSIS}
+$(eval $(call add_define, CSF_HDR_CH3))
+else
+ifeq ($(CHASSIS), 3_2)
+CSF_FILE := input_blx_ch3
+BL2_CSF_FILE := input_bl2_ch${CHASSIS}
+PBI_CSF_FILE := input_pbi_ch${CHASSIS}
+$(eval $(call add_define, CSF_HDR_CH3))
+else
+ $(error -> CHASSIS not set!)
+endif
+endif
+endif
+
+PLAT_AUTH_PATH := $(PLAT_DRIVERS_PATH)/auth
+
+
+ifeq (${BL2_INPUT_FILE},)
+ BL2_INPUT_FILE := $(PLAT_AUTH_PATH)/csf_hdr_parser/${BL2_CSF_FILE}
+endif
+
+ifeq (${PBI_INPUT_FILE},)
+ PBI_INPUT_FILE := $(PLAT_AUTH_PATH)/csf_hdr_parser/${PBI_CSF_FILE}
+endif
+
+# If MBEDTLS_DIR is not specified, use CSF Header option
+ifeq (${MBEDTLS_DIR},)
+ # Generic image processing filters to prepend CSF header
+ ifeq (${BL33_INPUT_FILE},)
+ BL33_INPUT_FILE := $(PLAT_AUTH_PATH)/csf_hdr_parser/${CSF_FILE}
+ endif
+
+ ifeq (${BL31_INPUT_FILE},)
+ BL31_INPUT_FILE := $(PLAT_AUTH_PATH)/csf_hdr_parser/${CSF_FILE}
+ endif
+
+ ifeq (${BL32_INPUT_FILE},)
+ BL32_INPUT_FILE := $(PLAT_AUTH_PATH)/csf_hdr_parser/${CSF_FILE}
+ endif
+
+ ifeq (${FUSE_INPUT_FILE},)
+ FUSE_INPUT_FILE := $(PLAT_AUTH_PATH)/csf_hdr_parser/${CSF_FILE}
+ endif
+
+ PLAT_INCLUDES += -I$(PLAT_DRIVERS_PATH)/sfp
+ PLAT_TBBR_SOURCES += $(PLAT_AUTH_PATH)/csf_hdr_parser/cot.c \
+ $(PLAT_COMMON_PATH)/tbbr/csf_tbbr.c
+ # IMG PARSER here is CSF header parser
+ include $(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/csf_hdr.mk
+ PLAT_TBBR_SOURCES += $(CSF_HDR_SOURCES)
+
+ SCP_BL2_PRE_TOOL_FILTER := CST_SCP_BL2
+ BL31_PRE_TOOL_FILTER := CST_BL31
+ BL32_PRE_TOOL_FILTER := CST_BL32
+ BL33_PRE_TOOL_FILTER := CST_BL33
+else
+
+ ifeq (${DISABLE_FUSE_WRITE}, 1)
+ $(eval $(call add_define,DISABLE_FUSE_WRITE))
+ endif
+
+ # For Mbedtls currently crypto is not supported via CAAM
+ # enable it when that support is there
+ CAAM_INTEG := 0
+ KEY_ALG := rsa
+ KEY_SIZE := 2048
+
+ $(eval $(call add_define,MBEDTLS_X509))
+ ifeq (${PLAT_DDR_PHY},PHY_GEN2)
+ $(eval $(call add_define,PLAT_DEF_OID))
+ endif
+ include drivers/auth/mbedtls/mbedtls_x509.mk
+
+
+ PLAT_TBBR_SOURCES += $(PLAT_AUTH_PATH)/tbbr/tbbr_cot.c \
+ $(PLAT_COMMON_PATH)/tbbr/nxp_rotpk.S \
+ $(PLAT_COMMON_PATH)/tbbr/x509_tbbr.c
+
+ #ROTPK key is embedded in BL2 image
+ ifeq (${ROT_KEY},)
+ ROT_KEY = $(BUILD_PLAT)/rot_key.pem
+ endif
+
+ ifeq (${SAVE_KEYS},1)
+
+ ifeq (${TRUSTED_WORLD_KEY},)
+ TRUSTED_WORLD_KEY = ${BUILD_PLAT}/trusted.pem
+ endif
+
+ ifeq (${NON_TRUSTED_WORLD_KEY},)
+ NON_TRUSTED_WORLD_KEY = ${BUILD_PLAT}/non-trusted.pem
+ endif
+
+ ifeq (${BL31_KEY},)
+ BL31_KEY = ${BUILD_PLAT}/soc.pem
+ endif
+
+ ifeq (${BL32_KEY},)
+ BL32_KEY = ${BUILD_PLAT}/trusted_os.pem
+ endif
+
+ ifeq (${BL33_KEY},)
+ BL33_KEY = ${BUILD_PLAT}/non-trusted_os.pem
+ endif
+
+ endif
+
+ ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
+
+ $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+
+ $(BUILD_PLAT)/bl2/nxp_rotpk.o: $(ROTPK_HASH)
+
+ certificates: $(ROT_KEY)
+ $(ROT_KEY): | $(BUILD_PLAT)
+ @echo " OPENSSL $@"
+ @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 |\
+ ${OPENSSL_BIN_PATH}/openssl dgst -sha256 -binary > $@ 2>/dev/null
+
+endif #MBEDTLS_DIR
+
+PLAT_INCLUDES += -Iinclude/common/tbbr
+
+# Generic files for authentication framework
+TBBR_SOURCES += drivers/auth/auth_mod.c \
+ drivers/auth/crypto_mod.c \
+ drivers/auth/img_parser_mod.c \
+ plat/common/tbbr/plat_tbbr.c \
+ ${PLAT_TBBR_SOURCES}
+
+# If CAAM_INTEG is not defined (would be scenario with MBED TLS)
+# include mbedtls_crypto
+ifeq (${CAAM_INTEG},0)
+ include drivers/auth/mbedtls/mbedtls_crypto.mk
+else
+ include $(PLAT_DRIVERS_PATH)/crypto/caam/src/auth/auth.mk
+ TBBR_SOURCES += ${AUTH_SOURCES}
+endif
diff --git a/plat/nxp/common/tbbr/x509_tbbr.c b/plat/nxp/common/tbbr/x509_tbbr.c
new file mode 100644
index 0000000..ec87674
--- /dev/null
+++ b/plat/nxp/common/tbbr/x509_tbbr.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <lib/cassert.h>
+#include <sfp.h>
+#include <tools_share/tbbr_oid.h>
+
+#include <plat/common/platform.h>
+#include "plat_common.h"
+
+extern char nxp_rotpk_hash[], nxp_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = nxp_rotpk_hash;
+ *key_len = nxp_rotpk_hash_end - nxp_rotpk_hash;
+ *flags = ROTPK_IS_HASH;
+
+ return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ const char *oid;
+ uint32_t uid_num;
+ uint32_t val = 0U;
+
+ assert(cookie != NULL);
+ assert(nv_ctr != NULL);
+
+ oid = (const char *)cookie;
+ if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ uid_num = 3U;
+ } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ uid_num = 4U;
+ } else {
+ return 1;
+ }
+
+ val = sfp_read_oem_uid(uid_num);
+
+ INFO("SFP Value read is %x from UID %d\n", val, uid_num);
+ if (val == 0U) {
+ *nv_ctr = 0U;
+ } else {
+ *nv_ctr = (32U - __builtin_clz(val));
+ }
+
+ INFO("NV Counter value for UID %d is %d\n", uid_num, *nv_ctr);
+ return 0;
+
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ const char *oid;
+ uint32_t uid_num, sfp_val;
+
+ assert(cookie != NULL);
+
+ /* Counter values upto 32 are supported */
+ if (nv_ctr > 32U) {
+ return 1;
+ }
+
+ oid = (const char *)cookie;
+ if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ uid_num = 3U;
+ } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ uid_num = 4U;
+ } else {
+ return 1;
+ }
+ sfp_val = (1U << (nv_ctr - 1));
+
+ if (sfp_write_oem_uid(uid_num, sfp_val) == 1) {
+ /* Enable POVDD on board */
+ if (board_enable_povdd()) {
+ sfp_program_fuses();
+ }
+
+ /* Disable POVDD on board */
+ board_disable_povdd();
+ } else {
+ ERROR("Invalid OEM UID sent.\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
+{
+ return get_mbedtls_heap_helper(heap_addr, heap_size);
+}
diff --git a/plat/nxp/common/warm_reset/plat_warm_reset.c b/plat/nxp/common/warm_reset/plat_warm_reset.c
new file mode 100644
index 0000000..966a73c
--- /dev/null
+++ b/plat/nxp/common/warm_reset/plat_warm_reset.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#ifndef NXP_COINED_BB
+#include <flash_info.h>
+#include <fspi.h>
+#include <fspi_api.h>
+#endif
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#ifdef NXP_COINED_BB
+#include <snvs.h>
+#endif
+
+#include <plat_nv_storage.h>
+#include "plat_warm_rst.h"
+#include "platform_def.h"
+
+#if defined(IMAGE_BL2)
+
+uint32_t is_warm_boot(void)
+{
+ uint32_t ret = mmio_read_32(NXP_RESET_ADDR + RST_RSTRQSR1_OFFSET)
+ & ~(RSTRQSR1_SWRR);
+
+ const nv_app_data_t *nv_app_data = get_nv_data();
+
+ if (ret == 0U) {
+ INFO("Not a SW(Warm) triggered reset.\n");
+ return 0U;
+ }
+
+ ret = (nv_app_data->warm_rst_flag == WARM_BOOT_SUCCESS) ? 1 : 0;
+
+ if (ret != 0U) {
+ INFO("Warm Reset was triggered..\n");
+ } else {
+ INFO("Warm Reset was not triggered..\n");
+ }
+
+ return ret;
+}
+
+#endif
+
+#if defined(IMAGE_BL31)
+int prep_n_execute_warm_reset(void)
+{
+#ifdef NXP_COINED_BB
+#if !TRUSTED_BOARD_BOOT
+ snvs_disable_zeroize_lp_gpr();
+#endif
+#else
+ int ret;
+ uint8_t warm_reset = WARM_BOOT_SUCCESS;
+
+ ret = fspi_init(NXP_FLEXSPI_ADDR, NXP_FLEXSPI_FLASH_ADDR);
+
+ if (ret != 0) {
+ ERROR("Failed to initialized driver flexspi-nor.\n");
+ ERROR("exiting warm-reset request.\n");
+ return PSCI_E_INTERN_FAIL;
+ }
+
+ /* Sector starting from NV_STORAGE_BASE_ADDR is already
+ * erased for writing.
+ */
+
+#if (ERLY_WRM_RST_FLG_FLSH_UPDT)
+ ret = xspi_write((uint32_t)NV_STORAGE_BASE_ADDR,
+ &warm_reset,
+ sizeof(warm_reset));
+#else
+ /* Preparation for writing the Warm reset flag. */
+ ret = xspi_wren((uint32_t)NV_STORAGE_BASE_ADDR);
+
+ /* IP Control Register0 - SF Address to be read */
+ fspi_out32((NXP_FLEXSPI_ADDR + FSPI_IPCR0),
+ (uint32_t) NV_STORAGE_BASE_ADDR);
+
+ while ((fspi_in32(NXP_FLEXSPI_ADDR + FSPI_INTR) &
+ FSPI_INTR_IPTXWE_MASK) == 0) {
+ ;
+ }
+ /* Write TX FIFO Data Register */
+ fspi_out32(NXP_FLEXSPI_ADDR + FSPI_TFDR, (uint32_t) warm_reset);
+
+ fspi_out32(NXP_FLEXSPI_ADDR + FSPI_INTR, FSPI_INTR_IPTXWE);
+
+ /* IP Control Register1 - SEQID_WRITE operation, Size = 1 Byte */
+ fspi_out32(NXP_FLEXSPI_ADDR + FSPI_IPCR1,
+ (uint32_t)(FSPI_WRITE_SEQ_ID << FSPI_IPCR1_ISEQID_SHIFT) |
+ (uint16_t) sizeof(warm_reset));
+
+ /* Trigger XSPI-IP-Write cmd only if:
+ * - Putting DDR in-self refresh mode is successfully.
+ * to complete the writing of the warm-reset flag
+ * to flash.
+ *
+ * This code is as part of assembly.
+ */
+#endif
+#endif
+ INFO("Doing DDR Self refresh.\n");
+ _soc_sys_warm_reset();
+
+ /* Expected behaviour is to do the power cycle */
+ while (1 != 0)
+ ;
+
+ return -1;
+}
+#endif
diff --git a/plat/nxp/common/warm_reset/plat_warm_rst.h b/plat/nxp/common/warm_reset/plat_warm_rst.h
new file mode 100644
index 0000000..e0c39c5
--- /dev/null
+++ b/plat/nxp/common/warm_reset/plat_warm_rst.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_WARM_RST_H
+#define PLAT_WARM_RST_H
+
+#ifndef NXP_COINED_BB
+#define ERLY_WRM_RST_FLG_FLSH_UPDT 0
+#endif
+
+#ifndef __ASSEMBLER__
+
+#if defined(IMAGE_BL2)
+uint32_t is_warm_boot(void);
+#endif
+
+#if defined(IMAGE_BL31)
+int prep_n_execute_warm_reset(void);
+int _soc_sys_warm_reset(void);
+#endif
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* PLAT_WARM_RST_H */
diff --git a/plat/nxp/common/warm_reset/warm_reset.mk b/plat/nxp/common/warm_reset/warm_reset.mk
new file mode 100644
index 0000000..236004f
--- /dev/null
+++ b/plat/nxp/common/warm_reset/warm_reset.mk
@@ -0,0 +1,20 @@
+#
+# Copyright 2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-----------------------------------------------------------------------------
+ifeq (${WARM_RST_ADDED},)
+
+WARM_RST_ADDED := 1
+NXP_NV_SW_MAINT_LAST_EXEC_DATA := yes
+
+$(eval $(call add_define,NXP_WARM_BOOT))
+
+
+WARM_RST_INCLUDES += -I${PLAT_COMMON_PATH}/warm_reset
+WARM_RST_BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}_warm_rst.S
+
+WARM_RST_BL_COMM_SOURCES += ${PLAT_COMMON_PATH}/warm_reset/plat_warm_reset.c
+
+endif
diff --git a/plat/nxp/soc-ls1028a/aarch64/ls1028a.S b/plat/nxp/soc-ls1028a/aarch64/ls1028a.S
new file mode 100644
index 0000000..404c39e
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/aarch64/ls1028a.S
@@ -0,0 +1,1387 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .section .text, "ax"
+
+#include <asm_macros.S>
+
+#include <lib/psci/psci.h>
+#include <nxp_timer.h>
+#include <plat_gic.h>
+#include <pmu.h>
+
+#include <bl31_data.h>
+#include <plat_psci.h>
+#include <platform_def.h>
+
+ .global soc_init_lowlevel
+ .global soc_init_percpu
+ .global _set_platform_security
+ .global _soc_set_start_addr
+
+ .global _soc_core_release
+ .global _soc_ck_disabled
+ .global _soc_core_restart
+ .global _soc_core_prep_off
+ .global _soc_core_entr_off
+ .global _soc_core_exit_off
+ .global _soc_sys_reset
+ .global _soc_sys_off
+ .global _soc_core_prep_stdby
+ .global _soc_core_entr_stdby
+ .global _soc_core_exit_stdby
+ .global _soc_core_prep_pwrdn
+ .global _soc_core_entr_pwrdn
+ .global _soc_core_exit_pwrdn
+ .global _soc_clstr_prep_stdby
+ .global _soc_clstr_exit_stdby
+ .global _soc_clstr_prep_pwrdn
+ .global _soc_clstr_exit_pwrdn
+ .global _soc_sys_prep_stdby
+ .global _soc_sys_exit_stdby
+ .global _soc_sys_prep_pwrdn
+ .global _soc_sys_pwrdn_wfi
+ .global _soc_sys_exit_pwrdn
+
+ .equ TZPCDECPROT_0_SET_BASE, 0x02200804
+ .equ TZPCDECPROT_1_SET_BASE, 0x02200810
+ .equ TZPCDECPROT_2_SET_BASE, 0x0220081C
+
+ .equ TZASC_REGION_ATTRIBUTES_0_0, 0x01100110
+
+/*
+ * This function initialize the soc.
+ * in: void
+ * out: void
+ * uses x0 - x11
+ */
+func soc_init_lowlevel
+ /*
+ * Called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ /*
+ * Make sure the personality has been established by releasing cores
+ * that are marked "to-be-disabled" from reset
+ */
+ bl release_disabled /* 0-8 */
+
+ /* Set SCRATCHRW7 to 0x0 */
+ ldr x0, =DCFG_SCRATCHRW7_OFFSET
+ mov x1, xzr
+ bl _write_reg_dcfg
+
+ /* Restore the aarch32/64 non-volatile registers */
+ ldp x18, x30, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ ret
+endfunc soc_init_lowlevel
+
+/*
+ * void soc_init_percpu(void)
+ *
+ * This function performs any soc-specific initialization that is needed on
+ * a per-core basis
+ * in: none
+ * out: none
+ * uses x0 - x3
+ */
+func soc_init_percpu
+ stp x4, x30, [sp, #-16]!
+
+ bl plat_my_core_mask
+ mov x2, x0
+
+ /* x2 = core mask */
+
+ /* see if this core is marked for prefetch disable */
+ mov x0, #PREFETCH_DIS_OFFSET
+ bl _get_global_data /* 0-1 */
+ tst x0, x2
+ b.eq 1f
+ bl _disable_ldstr_pfetch_A72 /* 0 */
+1:
+ mov x0, #NXP_PMU_ADDR
+ bl enable_timer_base_to_cluster
+
+ ldp x4, x30, [sp], #16
+ ret
+endfunc soc_init_percpu
+
+/*
+ * This function determines if a core is disabled via COREDISABLEDSR
+ * in: w0 = core_mask_lsb
+ * out: w0 = 0, core not disabled
+ * w0 != 0, core disabled
+ * uses x0, x1
+ */
+func _soc_ck_disabled
+ /* get base addr of dcfg block */
+ ldr x1, =NXP_DCFG_ADDR
+
+ /* read COREDISABLEDSR */
+ ldr w1, [x1, #DCFG_COREDISABLEDSR_OFFSET]
+
+ /* test core bit */
+ and w0, w1, w0
+
+ ret
+endfunc _soc_ck_disabled
+
+/*
+ * This function sets the security mechanisms in the SoC to implement the
+ * Platform Security Policy
+ */
+func _set_platform_security
+ mov x3, x30
+
+#if (!SUPPRESS_TZC)
+ /* initialize the tzpc */
+ bl init_tzpc
+#endif
+
+#if (!SUPPRESS_SEC)
+ /* initialize secmon */
+ bl initSecMon
+#endif
+
+ mov x30, x3
+ ret
+endfunc _set_platform_security
+
+/*
+ * Part of CPU_ON
+ *
+ * This function releases a secondary core from reset
+ * in: x0 = core_mask_lsb
+ * out: none
+ * uses: x0 - x3
+ */
+_soc_core_release:
+ mov x3, x30
+
+ /*
+ * Write to CORE_HOLD to tell the bootrom that we want this core
+ * to run
+ */
+ ldr x1, =NXP_SEC_REGFILE_ADDR
+ str w0, [x1, #CORE_HOLD_OFFSET]
+
+ /* Read-modify-write BRRL to release core */
+ mov x1, #NXP_RESET_ADDR
+ ldr w2, [x1, #BRR_OFFSET]
+ orr w2, w2, w0
+ str w2, [x1, #BRR_OFFSET]
+ dsb sy
+ isb
+
+ /* Send event */
+ sev
+ isb
+
+ mov x30, x3
+ ret
+
+/*
+ * This function writes a 64-bit address to bootlocptrh/l
+ * in: x0, 64-bit address to write to BOOTLOCPTRL/H
+ * uses x0, x1, x2
+ */
+func _soc_set_start_addr
+ /* Get the 64-bit base address of the dcfg block */
+ ldr x2, =NXP_DCFG_ADDR
+
+ /* Write the 32-bit BOOTLOCPTRL register */
+ mov x1, x0
+ str w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET]
+
+ /* Write the 32-bit BOOTLOCPTRH register */
+ lsr x1, x0, #32
+ str w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET]
+ ret
+endfunc _soc_set_start_addr
+
+/*
+ * Part of CPU_ON
+ *
+ * This function restarts a core shutdown via _soc_core_entr_off
+ * in: x0 = core mask lsb (of the target cpu)
+ * out: x0 == 0, on success
+ * x0 != 0, on failure
+ * uses x0 - x6
+ */
+_soc_core_restart:
+ mov x6, x30
+ mov x4, x0
+
+ /* pgm GICD_CTLR - enable secure grp0 */
+ mov x5, #NXP_GICD_ADDR
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ orr w2, w2, #GICD_CTLR_EN_GRP_0
+ str w2, [x5, #GICD_CTLR_OFFSET]
+ dsb sy
+ isb
+
+ /* Poll on RWP til write completes */
+4:
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ tst w2, #GICD_CTLR_RWP
+ b.ne 4b
+
+ /*
+ * x4 = core mask lsb
+ * x5 = gicd base addr
+ */
+
+ mov x0, x4
+ bl get_mpidr_value
+
+ /* Generate target list bit */
+ and x1, x0, #MPIDR_AFFINITY0_MASK
+ mov x2, #1
+ lsl x2, x2, x1
+
+ /* Get the affinity1 field */
+ and x1, x0, #MPIDR_AFFINITY1_MASK
+ lsl x1, x1, #8
+ orr x2, x2, x1
+
+ /* Insert the INTID for SGI15 */
+ orr x2, x2, #ICC_SGI0R_EL1_INTID
+
+ /* Fire the SGI */
+ msr ICC_SGI0R_EL1, x2
+ dsb sy
+ isb
+
+ /* Load '0' on success */
+ mov x0, xzr
+
+ mov x30, x6
+ ret
+
+/*
+ * Part of CPU_OFF
+ *
+ * This function programs SoC & GIC registers in preparation for shutting down
+ * the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0 - x7
+ */
+_soc_core_prep_off:
+ mov x8, x30
+ mov x7, x0
+
+ /* x7 = core mask lsb */
+
+ mrs x1, CPUECTLR_EL1
+
+ /* Set smp and disable L2 snoops in cpuectlr */
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH
+ bic x1, x1, #CPUECTLR_INS_PREFETCH_MASK
+ bic x1, x1, #CPUECTLR_DAT_PREFETCH_MASK
+
+ /* Set retention control in cpuectlr */
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ orr x1, x1, #CPUECTLR_TIMER_2TICKS
+ msr CPUECTLR_EL1, x1
+
+ /* Get redistributor rd base addr for this core */
+ mov x0, x7
+ bl get_gic_rd_base
+ mov x6, x0
+
+ /* Get redistributor sgi base addr for this core */
+ mov x0, x7
+ bl get_gic_sgi_base
+ mov x5, x0
+
+ /*
+ * x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* Disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w3, #GICR_ICENABLER0_SGI15
+ str w3, [x5, #GICR_ICENABLER0_OFFSET]
+2:
+ /* Poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* Disable GRP1 interrupts at cpu interface */
+ msr ICC_IGRPEN1_EL3, xzr
+
+ /* Disable GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* Program the redistributor - poll on GICR_CTLR.RWP as needed */
+
+ /* Define SGI 15 as Grp0 - GICR_IGROUPR0 */
+ ldr w4, [x5, #GICR_IGROUPR0_OFFSET]
+ bic w4, w4, #GICR_IGROUPR0_SGI15
+ str w4, [x5, #GICR_IGROUPR0_OFFSET]
+
+ /* Define SGI 15 as Grp0 - GICR_IGRPMODR0 */
+ ldr w3, [x5, #GICR_IGRPMODR0_OFFSET]
+ bic w3, w3, #GICR_IGRPMODR0_SGI15
+ str w3, [x5, #GICR_IGRPMODR0_OFFSET]
+
+ /* Set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */
+ ldr w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+ bic w4, w4, #GICR_IPRIORITYR3_SGI15_MASK
+ str w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+
+ /* Enable SGI 15 at redistributor - GICR_ISENABLER0 */
+ mov w3, #GICR_ISENABLER0_SGI15
+ str w3, [x5, #GICR_ISENABLER0_OFFSET]
+ dsb sy
+ isb
+3:
+ /* Poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 3b
+
+ /* Quiesce the debug interfaces */
+ mrs x3, osdlr_el1
+ orr x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ /* Enable grp0 ints */
+ mov x3, #ICC_IGRPEN0_EL1_EN
+ msr ICC_IGRPEN0_EL1, x3
+
+ /*
+ * x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* Clear any pending interrupts */
+ mvn w1, wzr
+ str w1, [x5, #GICR_ICPENDR0_OFFSET]
+
+ /* Make sure system counter is enabled */
+ ldr x3, =NXP_TIMER_ADDR
+ ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 4f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+4:
+ /* Enable the core timer and mask timer interrupt */
+ mov x1, #CNTP_CTL_EL0_EN
+ orr x1, x1, #CNTP_CTL_EL0_IMASK
+ msr cntp_ctl_el0, x1
+
+ isb
+ mov x30, x8
+ ret
+
+/*
+ * Part of CPU_OFF
+ *
+ * This function performs the final steps to shutdown the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0 - x5
+ */
+_soc_core_entr_off:
+ mov x5, x30
+ mov x4, x0
+
+ /* x4 = core mask */
+1:
+ /* Enter low-power state by executing wfi */
+ wfi
+
+ /* See if SGI15 woke us up */
+ mrs x2, ICC_IAR0_EL1
+ mov x3, #ICC_IAR0_EL1_SGI15
+ cmp x2, x3
+ b.ne 1b
+
+ /* Deactivate the int */
+ msr ICC_EOIR0_EL1, x2
+
+ /* x4 = core mask */
+2:
+ /* Check if core has been turned on */
+ mov x0, x4
+ bl _getCoreState
+
+ /* x0 = core state */
+
+ cmp x0, #CORE_WAKEUP
+ b.ne 1b
+
+ /* If we get here, then we have exited the wfi */
+ mov x30, x5
+ ret
+
+/*
+ * Part of CPU_OFF
+ *
+ * This function starts the process of starting a core back up
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_core_exit_off:
+ mov x6, x30
+ mov x5, x0
+
+ /* Disable forwarding of GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* Get redistributor sgi base addr for this core */
+ mov x0, x5
+ bl get_gic_sgi_base
+ mov x4, x0
+
+ /* x4 = gicr sgi base addr */
+ /* x5 = core mask */
+
+ /* Disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w1, #GICR_ICENABLER0_SGI15
+ str w1, [x4, #GICR_ICENABLER0_OFFSET]
+
+ /* Get redistributor rd base addr for this core */
+ mov x0, x5
+ bl get_gic_rd_base
+ mov x4, x0
+
+ /* x4 = gicr rd base addr */
+2:
+ /* Poll on rwp bit in GICR_CTLR */
+ ldr w2, [x4, #GICR_CTLR_OFFSET]
+ tst w2, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* x4 = gicr rd base addr */
+
+ /* Unlock the debug interfaces */
+ mrs x3, osdlr_el1
+ bic x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ dsb sy
+ isb
+ mov x30, x6
+ ret
+
+/*
+ * This function requests a reset of the entire SOC
+ * in: none
+ * out: none
+ * uses: x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_sys_reset:
+ mov x3, x30
+
+ /* Make sure the mask is cleared in the reset request mask register */
+ mov x0, #RST_RSTRQMR1_OFFSET
+ mov w1, wzr
+ bl _write_reg_reset
+
+ /* Set the reset request */
+ mov x4, #RST_RSTCR_OFFSET
+ mov x0, x4
+ mov w1, #RSTCR_RESET_REQ
+ bl _write_reg_reset
+
+ /* x4 = RST_RSTCR_OFFSET */
+
+ /*
+ * Just in case this address range is mapped as cacheable,
+ * flush the write out of the dcaches
+ */
+ mov x2, #NXP_RESET_ADDR
+ add x2, x2, x4
+ dc cvac, x2
+ dsb st
+ isb
+
+ /* This function does not return */
+1:
+ wfi
+ b 1b
+
+/*
+ * Part of SYSTEM_OFF
+ *
+ * This function turns off the SoC clocks
+ * Note: this function is not intended to return, and the only allowable
+ * recovery is POR
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_sys_off:
+ /*
+ * Disable sec, spi and flexspi
+ * TBD - Check if eNETC needs to be disabled
+ */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, =DCFG_DEVDISR1_SEC
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, =DCFG_DEVDISR4_SPI_QSPI
+ str w1, [x2, x0]
+
+ /* Set TPMWAKEMR0 */
+ ldr x0, =TPMWAKEMR0_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ /* Disable icache, dcache, mmu @ EL1 */
+ mov x1, #SCTLR_I_C_M_MASK
+ mrs x0, sctlr_el1
+ bic x0, x0, x1
+ msr sctlr_el1, x0
+
+ /* Disable L2 prefetches */
+ mrs x0, CPUECTLR_EL1
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ bic x0, x0, #CPUECTLR_TIMER_MASK
+ orr x0, x0, #CPUECTLR_TIMER_2TICKS
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+
+ /* Disable CCI snoop domain */
+ ldr x0, =NXP_CCI_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ bl get_pmu_idle_core_mask
+
+ /* x3 = pmu base addr */
+ mov x3, #NXP_PMU_ADDR
+4:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w0
+ b.ne 4b
+
+ bl get_pmu_idle_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+ str w0, [x3, #PMU_CLAINACTSETR_OFFSET]
+
+ bl get_pmu_idle_core_mask
+ mov x3, #NXP_PMU_ADDR
+1:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w0
+ b.ne 1b
+
+ bl get_pmu_flush_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+ str w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET]
+2:
+ ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET]
+ cmp w1, w0
+ b.ne 2b
+
+ str w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET]
+
+ str w0, [x3, #PMU_CLSINACTSETR_OFFSET]
+
+ mov x2, #DAIF_SET_MASK
+ mrs x1, spsr_el1
+ orr x1, x1, x2
+ msr spsr_el1, x1
+
+ mrs x1, spsr_el2
+ orr x1, x1, x2
+ msr spsr_el2, x1
+
+ /* Force the debug interface to be quiescent */
+ mrs x0, osdlr_el1
+ orr x0, x0, #0x1
+ msr osdlr_el1, x0
+
+ /* Invalidate all TLB entries at all 3 exception levels */
+ tlbi alle1
+ tlbi alle2
+ tlbi alle3
+
+ /* x3 = pmu base addr */
+
+ /* Request lpm20 */
+ ldr x0, =PMU_POWMGTCSR_OFFSET
+ ldr w1, =PMU_POWMGTCSR_VAL
+ str w1, [x3, x0]
+ isb
+ dsb sy
+5:
+ wfe
+ b.eq 5b
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_core_prep_stdby:
+ /* Clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function puts the calling core into standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_stdby:
+ /* X0 = core mask lsb */
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_core_exit_stdby:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2
+ */
+_soc_core_prep_pwrdn:
+ /* Make sure system counter is enabled */
+ ldr x2, =NXP_TIMER_ADDR
+ ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+ /*
+ * Enable dynamic retention control (CPUECTLR[2:0])
+ * Set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_2TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x1
+
+ isb
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function puts the calling core into a power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_pwrdn:
+ /* X0 = core mask lsb */
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_core_exit_pwrdn:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_clstr_prep_stdby:
+ /* Clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_clstr_exit_stdby:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2
+ */
+_soc_clstr_prep_pwrdn:
+ /* Make sure system counter is enabled */
+ ldr x2, =NXP_TIMER_ADDR
+ ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+ /*
+ * Enable dynamic retention control (CPUECTLR[2:0])
+ * Set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_2TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x1
+
+ isb
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_clstr_exit_pwrdn:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_prep_stdby:
+ /* Clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_sys_exit_stdby:
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs SoC-specific programming prior to
+ * suspend-to-power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4
+ */
+_soc_sys_prep_pwrdn:
+ /* Set retention control */
+ mrs x0, CPUECTLR_EL1
+ bic x0, x0, #CPUECTLR_TIMER_MASK
+ orr x0, x0, #CPUECTLR_TIMER_2TICKS
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function puts the calling core, and potentially the soc, into a
+ * low-power state
+ * in: x0 = core mask lsb
+ * out: x0 = 0, success
+ * x0 < 0, failure
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x13, x14, x15,
+ * x16, x17, x18
+ */
+_soc_sys_pwrdn_wfi:
+ mov x18, x30
+
+ mov x3, #NXP_PMU_ADDR
+
+ /* x3 = pmu base addr */
+
+ /* Backup epu registers to stack */
+ ldr x2, =NXP_EPU_ADDR
+ ldr w4, [x2, #EPU_EPIMCR10_OFFSET]
+ ldr w5, [x2, #EPU_EPCCR10_OFFSET]
+ ldr w6, [x2, #EPU_EPCTR10_OFFSET]
+ ldr w7, [x2, #EPU_EPGCR_OFFSET]
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+
+ /*
+ * x2 = epu base addr
+ * x3 = pmu base addr
+ */
+
+ /* Set up EPU event to receive the wake signal from PMU */
+ mov w4, #EPU_EPIMCR10_VAL
+ mov w5, #EPU_EPCCR10_VAL
+ mov w6, #EPU_EPCTR10_VAL
+ mov w7, #EPU_EPGCR_VAL
+ str w4, [x2, #EPU_EPIMCR10_OFFSET]
+ str w5, [x2, #EPU_EPCCR10_OFFSET]
+ str w6, [x2, #EPU_EPCTR10_OFFSET]
+ str w7, [x2, #EPU_EPGCR_OFFSET]
+
+ ldr x2, =NXP_GICD_ADDR
+
+ /*
+ * x2 = gicd base addr
+ * x3 = pmu base addr
+ */
+
+ /* Backup flextimer/mmc/usb interrupt router */
+ ldr x0, =GICD_IROUTER60_OFFSET
+ ldr x1, =GICD_IROUTER76_OFFSET
+ ldr w4, [x2, x0]
+ ldr w5, [x2, x1]
+ ldr x0, =GICD_IROUTER112_OFFSET
+ ldr x1, =GICD_IROUTER113_OFFSET
+ ldr w6, [x2, x0]
+ ldr w7, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+
+ /*
+ * x2 = gicd base addr
+ * x3 = pmu base addr
+ * x0 = GICD_IROUTER112_OFFSET
+ * x1 = GICD_IROUTER113_OFFSET
+ */
+
+ /* Re-route interrupt to cluster 1 */
+ ldr w4, =GICD_IROUTER_VALUE
+ str w4, [x2, x0]
+ str w4, [x2, x1]
+ ldr x0, =GICD_IROUTER60_OFFSET
+ ldr x1, =GICD_IROUTER76_OFFSET
+ str w4, [x2, x0]
+ str w4, [x2, x1]
+ dsb sy
+ isb
+
+ /* x3 = pmu base addr */
+
+ /* Disable sec, Check for eNETC, spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, =DCFG_DEVDISR1_SEC
+ str w1, [x2, x0]
+
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, =DCFG_DEVDISR4_SPI_QSPI
+ str w1, [x2, x0]
+
+ /* x3 = pmu base addr */
+
+ /* Set TPMWAKEMR0 */
+ ldr x0, =TPMWAKEMR0_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ /* Disable CCI snoop domain */
+ ldr x0, =NXP_CCI_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ /* Setup retention control */
+ mrs x0, CPUECTLR_EL1
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ orr x0, x0, #CPUECTLR_TIMER_2TICKS
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+
+ bl get_pmu_idle_core_mask
+ mov x3, #NXP_PMU_ADDR
+8:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w0
+ b.ne 8b
+
+ /* x3 = NXP_PMU_ADDR */
+ /* 1 cluster SoC */
+
+ bl get_pmu_idle_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+
+ str w0, [x3, #PMU_CLAINACTSETR_OFFSET]
+
+ bl get_pmu_idle_core_mask
+ /* x3 = NXP_PMU_ADDR */
+ mov x3, #NXP_PMU_ADDR
+1:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w0
+ b.ne 1b
+
+ /* x3 = NXP_PMU_ADDR */
+ bl get_pmu_flush_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+
+ str w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET]
+
+ /* x3 = NXP_PMU_ADDR */
+2:
+ ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET]
+ cmp w1, w0
+ b.ne 2b
+
+ /* x3 = NXP_PMU_ADDR */
+
+ str w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET]
+
+ str w0, [x3, #PMU_CLSINACTSETR_OFFSET]
+
+ /* Force the debug interface to be quiescent */
+ mrs x0, osdlr_el1
+ orr x0, x0, #0x1
+ msr osdlr_el1, x0
+
+ /*
+ * Enable the WakeRequest signal
+ * x3 is cpu mask starting from cpu1 to cpu0
+ */
+ bl get_tot_num_cores
+ sub x0, x0, #1
+ mov x3, #0x1
+ lsl x3, x3, x0
+2:
+ mov x0, x3
+ bl get_gic_rd_base // 0-2
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ orr w1, w1, #GICR_WAKER_SLEEP_BIT
+ str w1, [x0, #GICR_WAKER_OFFSET]
+1:
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ cmp w1, #GICR_WAKER_ASLEEP
+ b.ne 1b
+
+ lsr x3, x3, #1
+ cbnz x3, 2b
+
+ /* Invalidate all TLB entries at all 3 exception levels */
+ tlbi alle1
+ tlbi alle2
+ tlbi alle3
+
+ /* Request lpm20 */
+ mov x3, #NXP_PMU_ADDR
+ ldr x0, =PMU_POWMGTCSR_OFFSET
+ ldr w1, =PMU_POWMGTCSR_VAL
+ str w1, [x3, x0]
+
+ ldr x5, =NXP_EPU_ADDR
+4:
+ wfe
+ ldr w1, [x5, #EPU_EPCTR10_OFFSET]
+ cmp w1, #0
+ b.eq 4b
+
+ /* x3 = NXP_PMU_ADDR */
+
+ bl get_pmu_idle_cluster_mask
+ mov x3, NXP_PMU_ADDR
+
+ /* Re-enable the GPP ACP */
+ str w0, [x3, #PMU_CLAINACTCLRR_OFFSET]
+ str w0, [x3, #PMU_CLSINACTCLRR_OFFSET]
+
+ /* x3 = NXP_PMU_ADDR */
+3:
+ ldr w1, [x3, #PMU_CLAINACTSETR_OFFSET]
+ cbnz w1, 3b
+4:
+ ldr w1, [x3, #PMU_CLSINACTSETR_OFFSET]
+ cbnz w1, 4b
+
+ /*
+ * Enable the WakeRequest signal on cpu 0-1
+ * x3 is cpu mask starting from cpu1
+ */
+ bl get_tot_num_cores
+ sub x0, x0, #1
+ mov x3, #0x1
+ lsl x3, x3, x0
+2:
+ mov x0, x3
+ bl get_gic_rd_base // 0-2
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ bic w1, w1, #GICR_WAKER_SLEEP_BIT
+ str w1, [x0, #GICR_WAKER_OFFSET]
+1:
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ cbnz w1, 1b
+
+ lsr x3, x3, #1
+ cbnz x3, 2b
+
+ /* Enable CCI snoop domain */
+ ldr x0, =NXP_CCI_ADDR
+ str wzr, [x0]
+ dsb sy
+ isb
+
+ ldr x3, =NXP_EPU_ADDR
+
+ /* x3 = epu base addr */
+
+ /* Enable sec, enetc, spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ str wzr, [x2, #DCFG_DEVDISR1_OFFSET]
+ str wzr, [x2, #DCFG_DEVDISR2_OFFSET]
+ str wzr, [x2, #DCFG_DEVDISR4_OFFSET]
+
+ /* Restore flextimer/mmc/usb interrupt router */
+ ldr x3, =NXP_GICD_ADDR
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_IROUTER113_OFFSET
+ str w2, [x3, x1]
+ ldr x1, =GICD_IROUTER112_OFFSET
+ str w0, [x3, x1]
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_IROUTER76_OFFSET
+ str w2, [x3, x1]
+ ldr x1, =GICD_IROUTER60_OFFSET
+ str w0, [x3, x1]
+
+ /* Restore EPU registers */
+ ldr x3, =NXP_EPU_ADDR
+ ldp x0, x2, [sp], #16
+ str w2, [x3, #EPU_EPGCR_OFFSET]
+ str w0, [x3, #EPU_EPCTR10_OFFSET]
+ ldp x2, x1, [sp], #16
+ str w1, [x3, #EPU_EPCCR10_OFFSET]
+ str w2, [x3, #EPU_EPIMCR10_OFFSET]
+
+ dsb sy
+ isb
+ mov x30, x18
+ ret
+
+/*
+ * Part of CPU_SUSPEND
+ *
+ * This function performs any SoC-specific cleanup after power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_exit_pwrdn:
+ /* Enable stack alignment checking */
+ mrs x1, SCTLR_EL1
+ orr x1, x1, #0x4
+ msr SCTLR_EL1, x1
+
+ /* Enable debug interface */
+ mrs x1, osdlr_el1
+ bic x1, x1, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x1
+
+ /* Enable i-cache */
+ mrs x1, SCTLR_EL3
+ orr x1, x1, #SCTLR_I_MASK
+ msr SCTLR_EL3, x1
+
+ isb
+ ret
+
+/*
+ * This function setc up the TrustZone Address Space Controller (TZASC)
+ * in: none
+ * out: none
+ * uses x0, x1
+ */
+init_tzpc:
+ /* Set Non Secure access for all devices protected via TZPC */
+ ldr x1, =TZPCDECPROT_0_SET_BASE /* decode Protection-0 Set Reg */
+ mov w0, #0xFF /* set decode region to NS, Bits[7:0] */
+ str w0, [x1]
+
+ ldr x1, =TZPCDECPROT_1_SET_BASE /* decode Protection-1 Set Reg */
+ mov w0, #0xFF /* set decode region to NS, Bits[7:0] */
+ str w0, [x1]
+
+ ldr x1, =TZPCDECPROT_2_SET_BASE /* decode Protection-2 Set Reg */
+ mov w0, #0xFF /* set decode region to NS, Bits[7:0] */
+ str w0, [x1]
+
+ /* entire SRAM as NS */
+ ldr x1, =NXP_OCRAM_TZPC_ADDR /* secure RAM region size Reg */
+ mov w0, #0x00000000 /* 0x00000000 = no secure region */
+ str w0, [x1]
+
+ ret
+
+/*
+ * This function performs any needed initialization on SecMon for
+ * boot services
+ */
+initSecMon:
+ /* Read the register hpcomr */
+ ldr x1, =NXP_SNVS_ADDR
+ ldr w0, [x1, #SECMON_HPCOMR_OFFSET]
+ /* Turn off secure access for the privileged registers */
+ orr w0, w0, #SECMON_HPCOMR_NPSWAEN
+ /* Write back */
+ str w0, [x1, #SECMON_HPCOMR_OFFSET]
+
+ ret
+
+/*
+ * This function checks to see if cores which are to be disabled have been
+ * released from reset - if not, it releases them
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
+ */
+release_disabled:
+ stp x18, x30, [sp, #-16]!
+
+ /*
+ * Get the number of cpus on this device
+ * Calling the below c function.
+ * No need to Callee saved registers x9-x15,
+ * as these registers are not used by the callee
+ * prior to calling the below C-routine.
+ */
+ bl get_tot_num_cores
+ mov x6, x0
+
+ /* Read COREDISABLESR */
+ mov x0, #NXP_DCFG_ADDR
+ ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET]
+
+ mov x0, #NXP_RESET_ADDR
+ ldr w5, [x0, #BRR_OFFSET]
+
+ /* Load the core mask for the first core */
+ mov x7, #1
+
+ /*
+ * x4 = COREDISABLESR
+ * x5 = BRR
+ * x6 = loop count
+ * x7 = core mask bit
+ */
+2:
+ /* Check if the core is to be disabled */
+ tst x4, x7
+ b.eq 1f
+
+ /* See if disabled cores have already been released from reset */
+ tst x5, x7
+ b.ne 1f
+
+ /* If core has not been released, then release it (0-3) */
+ mov x0, x7
+ bl _soc_core_release
+
+ /* Record the core state in the data area (0-3) */
+ mov x0, x7
+ mov x1, #CORE_DISABLED
+ bl _setCoreState
+1:
+ /* Decrement the counter */
+ subs x6, x6, #1
+ b.le 3f
+ /* Shift the core mask to the next core */
+ lsl x7, x7, #1
+ /* Continue */
+ b 2b
+3:
+ ldp x18, x30, [sp], #16
+ ret
+
+/*
+ * Write a register in the DCFG block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_dcfg:
+ ldr x2, =NXP_DCFG_ADDR
+ str w1, [x2, x0]
+ ret
+
+/*
+ * Read a register in the DCFG block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1, x2
+ */
+_read_reg_dcfg:
+ ldr x2, =NXP_DCFG_ADDR
+ ldr w1, [x2, x0]
+ mov w0, w1
+ ret
+
+/*
+ * This function returns an mpidr value for a core, given a core_mask_lsb
+ * in: x0 = core mask lsb
+ * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits
+ * uses x0, x1
+ */
+get_mpidr_value:
+ /* Convert a core mask to an SoC core number */
+ clz w0, w0
+ mov w1, #31
+ sub w0, w1, w0
+
+ /* Get the mpidr core number from the SoC core number */
+ mov w1, wzr
+ tst x0, #1
+ b.eq 1f
+ orr w1, w1, #1
+1:
+ /* Extract the cluster number */
+ lsr w0, w0, #1
+ orr w0, w1, w0, lsl #8
+
+ ret
+
+/*
+ * This function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor rd base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_rd_base:
+ /* Get the 0-based core number */
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ /* x2 = core number / loop counter */
+ ldr x0, =NXP_GICR_ADDR
+ mov x1, #GIC_RD_OFFSET
+2:
+ cbz x2, 1f
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+
+/*
+ * This function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor sgi base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_sgi_base:
+ /* Get the 0-based core number */
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ /* x2 = core number / loop counter */
+ ldr x0, =NXP_GICR_SGI_ADDR
+ mov x1, #GIC_SGI_OFFSET
+2:
+ cbz x2, 1f
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+
+/*
+ * Write a register in the RESET block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_reset:
+ ldr x2, =NXP_RESET_ADDR
+ str w1, [x2, x0]
+ ret
+
+/*
+ * Read a register in the RESET block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1
+ */
+_read_reg_reset:
+ ldr x1, =NXP_RESET_ADDR
+ ldr w0, [x1, x0]
+ ret
diff --git a/plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S b/plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S
new file mode 100644
index 0000000..ec67529
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+.globl plat_secondary_cold_boot_setup
+.globl plat_is_my_cpu_primary
+.globl plat_reset_handler
+.globl platform_mem_init
+
+func platform_mem1_init
+ ret
+endfunc platform_mem1_init
+
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+func apply_platform_errata
+ ret
+endfunc apply_platform_errata
+
+func plat_reset_handler
+ mov x29, x30
+ bl apply_platform_errata
+
+#if defined(IMAGE_BL31)
+ ldr x0, =POLICY_SMMU_PAGESZ_64K
+ cbz x0, 1f
+ /* Set the SMMU page size in the sACR register */
+ bl _set_smmu_pagesz_64
+#endif
+1:
+ mov x30, x29
+ ret
+endfunc plat_reset_handler
+
+/*
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ */
+func plat_secondary_cold_boot_setup
+ /* ls1028a does not do cold boot for secondary CPU */
+cb_panic:
+ b cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+/*
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu.
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, 0x0
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
diff --git a/plat/nxp/soc-ls1028a/include/soc.h b/plat/nxp/soc-ls1028a/include/soc.h
new file mode 100644
index 0000000..b1d044a
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/include/soc.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOC_H
+#define SOC_H
+
+/* Chassis specific defines - common across SoC's of a particular platform */
+#include <dcfg_lsch3.h>
+#include <soc_default_base_addr.h>
+#include <soc_default_helper_macros.h>
+
+/*
+ * SVR Definition of LS1028A
+ * (not include major and minor rev)
+ * These info is listed in Table B-6. DCFG differences
+ * between LS1028A and LS1027A of LS1028ARM(Reference Manual)
+ */
+#define SVR_LS1017AN 0x870B25
+#define SVR_LS1017AE 0x870B24
+#define SVR_LS1018AN 0x870B21
+#define SVR_LS1018AE 0x870B20
+#define SVR_LS1027AN 0x870B05
+#define SVR_LS1027AE 0x870B04
+#define SVR_LS1028AN 0x870B01
+#define SVR_LS1028AE 0x870B00
+
+/* Number of cores in platform */
+#define PLATFORM_CORE_COUNT 2
+#define NUMBER_OF_CLUSTERS 1
+#define CORES_PER_CLUSTER 2
+
+/* Set to 0 if the clusters are not symmetrical */
+#define SYMMETRICAL_CLUSTERS 1
+
+#define NUM_DRAM_REGIONS 3
+
+#define NXP_DRAM0_ADDR 0x80000000
+#define NXP_DRAM0_MAX_SIZE 0x80000000 /* 2GB */
+
+#define NXP_DRAM1_ADDR 0x2080000000
+#define NXP_DRAM1_MAX_SIZE 0x1F80000000 /* 126G */
+
+#define NXP_DRAM2_ADDR 0x6000000000
+#define NXP_DRAM2_MAX_SIZE 0x2000000000 /* 128G */
+
+/* DRAM0 Size defined in platform_def.h */
+#define NXP_DRAM0_SIZE PLAT_DEF_DRAM0_SIZE
+
+/* CCSR space memory Map */
+#undef NXP_UART_ADDR
+#define NXP_UART_ADDR 0x021C0500
+
+#undef NXP_UART1_ADDR
+#define NXP_UART1_ADDR 0x021C0600
+
+#undef NXP_WDOG1_TZ_ADDR
+#define NXP_WDOG1_TZ_ADDR 0x023C0000
+
+#undef NXP_GICR_ADDR
+#define NXP_GICR_ADDR 0x06040000
+
+#undef NXP_GICR_SGI_ADDR
+#define NXP_GICR_SGI_ADDR 0x06050000
+
+/* EPU register offsets and values */
+#define EPU_EPGCR_OFFSET 0x0
+#define EPU_EPIMCR10_OFFSET 0x128
+#define EPU_EPCTR10_OFFSET 0xa28
+#define EPU_EPCCR10_OFFSET 0x828
+#define EPU_EPCCR10_VAL 0xb2800000
+#define EPU_EPIMCR10_VAL 0xba000000
+#define EPU_EPCTR10_VAL 0x0
+#define EPU_EPGCR_VAL (1 << 31)
+
+/* PORSR1 */
+#define PORSR1_RCW_MASK 0x07800000
+#define PORSR1_RCW_SHIFT 23
+
+#define SDHC1_VAL 0x8
+#define SDHC2_VAL 0x9
+#define I2C1_VAL 0xa
+#define FLEXSPI_NAND2K_VAL 0xc
+#define FLEXSPI_NAND4K_VAL 0xd
+#define FLEXSPI_NOR 0xf
+
+/*
+ * Required LS standard platform porting definitions
+ * for CCI-400
+ */
+#define NXP_CCI_CLUSTER0_SL_IFACE_IX 4
+
+/* Defines required for using XLAT tables from ARM common code */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 40)
+
+/* Clock Divisors */
+#define NXP_PLATFORM_CLK_DIVIDER 1
+#define NXP_UART_CLK_DIVIDER 2
+
+/* dcfg register offsets and values */
+#define DCFG_DEVDISR2_ENETC (1 << 31)
+
+#define MPIDR_AFFINITY0_MASK 0x00FF
+#define MPIDR_AFFINITY1_MASK 0xFF00
+#define CPUECTLR_DISABLE_TWALK_PREFETCH 0x4000000000
+#define CPUECTLR_INS_PREFETCH_MASK 0x1800000000
+#define CPUECTLR_DAT_PREFETCH_MASK 0x0300000000
+#define OSDLR_EL1_DLK_LOCK 0x1
+#define CNTP_CTL_EL0_EN 0x1
+#define CNTP_CTL_EL0_IMASK 0x2
+
+#define SYSTEM_PWR_DOMAINS 1
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
+ NUMBER_OF_CLUSTERS + \
+ SYSTEM_PWR_DOMAINS)
+
+/* Power state coordination occurs at the system level */
+#define PLAT_PD_COORD_LVL MPIDR_AFFLVL2
+#define PLAT_MAX_PWR_LVL PLAT_PD_COORD_LVL
+
+/* Local power state for power domains in Run state */
+#define LS_LOCAL_STATE_RUN PSCI_LOCAL_STATE_RUN
+
+/* define retention state */
+#define PLAT_MAX_RET_STATE (PSCI_LOCAL_STATE_RUN + 1)
+#define LS_LOCAL_STATE_RET PLAT_MAX_RET_STATE
+
+/* define power-down state */
+#define PLAT_MAX_OFF_STATE (PLAT_MAX_RET_STATE + 1)
+#define LS_LOCAL_STATE_OFF PLAT_MAX_OFF_STATE
+
+/* One cache line needed for bakery locks on ARM platforms */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
+
+#ifndef __ASSEMBLER__
+/* CCI slave interfaces */
+static const int cci_map[] = {
+ NXP_CCI_CLUSTER0_SL_IFACE_IX,
+};
+void soc_init_lowlevel(void);
+void soc_init_percpu(void);
+void _soc_set_start_addr(unsigned long addr);
+void _set_platform_security(void);
+#endif
+
+#endif /* SOC_H */
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c b/plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c
new file mode 100644
index 0000000..d82be51
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <string.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <lib/utils.h>
+
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+const struct ddr_cfg_regs static_1600 = {
+ .cs[0].config = U(0x80040422),
+ .cs[0].bnds = U(0xFF),
+ .sdram_cfg[0] = U(0xE50C0004),
+ .sdram_cfg[1] = U(0x401100),
+ .timing_cfg[0] = U(0x91550018),
+ .timing_cfg[1] = U(0xBAB40C42),
+ .timing_cfg[2] = U(0x48C111),
+ .timing_cfg[3] = U(0x1111000),
+ .timing_cfg[4] = U(0x2),
+ .timing_cfg[5] = U(0x3401400),
+ .timing_cfg[7] = U(0x23300000),
+ .timing_cfg[8] = U(0x2114600),
+ .sdram_mode[0] = U(0x3010210),
+ .sdram_mode[9] = U(0x4000000),
+ .sdram_mode[8] = U(0x500),
+ .sdram_mode[2] = U(0x10210),
+ .sdram_mode[10] = U(0x400),
+ .sdram_mode[11] = U(0x4000000),
+ .sdram_mode[4] = U(0x10210),
+ .sdram_mode[12] = U(0x400),
+ .sdram_mode[13] = U(0x4000000),
+ .sdram_mode[6] = U(0x10210),
+ .sdram_mode[14] = U(0x400),
+ .sdram_mode[15] = U(0x4000000),
+ .interval = U(0x18600618),
+ .data_init = U(0xdeadbeef),
+ .zq_cntl = U(0x8A090705),
+ .clk_cntl = U(0x2000000),
+ .cdr[0] = U(0x80040000),
+ .cdr[1] = U(0xA181),
+ .wrlvl_cntl[0] = U(0x8675F605),
+ .wrlvl_cntl[1] = U(0x6070700),
+ .wrlvl_cntl[2] = U(0x0000008),
+ .dq_map[0] = U(0x5b65b658),
+ .dq_map[1] = U(0xd96d8000),
+ .dq_map[2] = U(0),
+ .dq_map[3] = U(0x1600000),
+ .debug[28] = U(0x00700046),
+};
+
+unsigned long long board_static_ddr(struct ddr_info *priv)
+{
+ memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600));
+ return ULL(0x100000000);
+}
+
+#else
+
+static const struct rc_timing rcz[] = {
+ {1600, 8, 5},
+ {}
+};
+
+static const struct board_timing ram[] = {
+ {0x1f, rcz, 0x1020200, 0x00000003},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ ret = cal_board_params(priv, ram, ARRAY_SIZE(ram));
+ if (ret != 0) {
+ return ret;
+ }
+
+ popts->bstopre = U(0x40); /* precharge value */
+ popts->half_strength_drive_en = 1;
+ popts->cpo_sample = U(0x46);
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
+ DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */
+
+ popts->addr_hash = 1; /* address hashing */
+ return 0;
+}
+
+/* DDR model number: MT40A1G8SA-075:E */
+struct dimm_params ddr_raw_timing = {
+ .n_ranks = U(1),
+ .rank_density = ULL(4294967296),
+ .capacity = ULL(4294967296),
+ .primary_sdram_width = U(32),
+ .ec_sdram_width = U(4),
+ .rdimm = U(0),
+ .mirrored_dimm = U(0),
+ .n_row_addr = U(16),
+ .n_col_addr = U(10),
+ .bank_group_bits = U(2),
+ .edc_config = U(2),
+ .burst_lengths_bitmask = U(0x0c),
+ .tckmin_x_ps = 750,
+ .tckmax_ps = 1900,
+ .caslat_x = U(0x0001FFE00),
+ .taa_ps = 13500,
+ .trcd_ps = 13500,
+ .trp_ps = 13500,
+ .tras_ps = 32000,
+ .trc_ps = 45500,
+ .twr_ps = 15000,
+ .trfc1_ps = 350000,
+ .trfc2_ps = 260000,
+ .trfc4_ps = 160000,
+ .tfaw_ps = 21000,
+ .trrds_ps = 3000,
+ .trrdl_ps = 4900,
+ .tccdl_ps = 5000,
+ .refresh_rate_ps = U(7800000),
+ .dq_mapping[0] = U(0x16),
+ .dq_mapping[1] = U(0x36),
+ .dq_mapping[2] = U(0x16),
+ .dq_mapping[3] = U(0x36),
+ .dq_mapping[4] = U(0x16),
+ .dq_mapping[5] = U(0x36),
+ .dq_mapping[6] = U(0x16),
+ .dq_mapping[7] = U(0x36),
+ .dq_mapping[8] = U(0x16),
+ .dq_mapping[9] = U(0x0),
+ .dq_mapping[10] = U(0x0),
+ .dq_mapping[11] = U(0x0),
+ .dq_mapping[12] = U(0x0),
+ .dq_mapping[13] = U(0x0),
+ .dq_mapping[14] = U(0x0),
+ .dq_mapping[15] = U(0x0),
+ .dq_mapping[16] = U(0x0),
+ .dq_mapping[17] = U(0x0),
+ .dq_mapping_ors = U(0),
+ .rc = U(0x1f),
+};
+
+int ddr_get_ddr_params(struct dimm_params *pdimm,
+ struct ddr_conf *conf)
+{
+ static const char dimm_model[] = "Fixed DDR on board";
+
+ conf->dimm_in_use[0] = 1;
+ memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params));
+ memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
+
+ return 1;
+}
+#endif
+
+int64_t init_ddr(void)
+{
+ struct ddr_info info;
+ struct sysinfo sys;
+ int64_t dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ get_clocks(&sys);
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = 1;
+ info.dimm_on_ctlr = 1;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h b/plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h
new file mode 100644
index 0000000..63c0219
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+#include <cortex_a72.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+#define NXP_SPD_EEPROM0 0x51
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+/* SD block buffer */
+#define NXP_SD_BLOCK_BUF_SIZE (0xC000)
+
+#ifdef SD_BOOT
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
+ - NXP_SD_BLOCK_BUF_SIZE)
+#else
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#endif
+#define BL2_TEXT_LIMIT (BL2_LIMIT)
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 4
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+#define BL31_WDOG_SEC 89
+
+/*
+ * Define properties 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_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define PLAT_LS_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(15, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/platform.c b/plat/nxp/soc-ls1028a/ls1028ardb/platform.c
new file mode 100644
index 0000000..65d508c
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/platform.mk b/plat/nxp/soc-ls1028a/ls1028ardb/platform.mk
new file mode 100644
index 0000000..c455000
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/platform.mk
@@ -0,0 +1,33 @@
+#
+# Copyright 2020-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Board-specific build parameters
+BOOT_MODE ?= flexspi_nor
+BOARD := ls1028ardb
+POVDD_ENABLE := no
+WARM_BOOT := no
+
+# DDR build parameters
+NUM_OF_DDRC := 1
+CONFIG_DDR_NODIMM := 1
+DDR_ECC_EN := yes
+
+# On-board flash
+FLASH_TYPE := MT35XU02G
+XSPI_FLASH_SZ := 0x10000000
+
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c \
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := flexspi_nor \
+ sd \
+ emmc
+
+# Add platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Add SoC build info
+include plat/nxp/soc-ls1028a/soc.mk
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h b/plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h
new file mode 100644
index 0000000..bbad293
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/policy.h b/plat/nxp/soc-ls1028a/ls1028ardb/policy.h
new file mode 100644
index 0000000..67a8b45
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/ls1028ardb/policy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2020-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/*
+ * Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1028a/soc.c b/plat/nxp/soc-ls1028a/soc.c
new file mode 100644
index 0000000..2fb353f
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/soc.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <endian.h>
+
+#include <arch.h>
+#include <caam.h>
+#include <cassert.h>
+#include <cci.h>
+#include <common/debug.h>
+#include <dcfg.h>
+#include <i2c.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <ls_interconnect.h>
+#include <mmio.h>
+#ifdef POLICY_FUSE_PROVISION
+#include <nxp_gpio.h>
+#endif
+#if TRUSTED_BOARD_BOOT
+#include <nxp_smmu.h>
+#endif
+#include <nxp_timer.h>
+#include <plat_console.h>
+#include <plat_gic.h>
+#include <plat_tzc400.h>
+#include <pmu.h>
+#include <scfg.h>
+#if defined(NXP_SFP_ENABLED)
+#include <sfp.h>
+#endif
+
+#include <errata.h>
+#ifdef CONFIG_OCRAM_ECC_EN
+#include <ocram.h>
+#endif
+#include "plat_common.h"
+#include "platform_def.h"
+#include "soc.h"
+
+static dcfg_init_info_t dcfg_init_data = {
+ .g_nxp_dcfg_addr = NXP_DCFG_ADDR,
+ .nxp_sysclk_freq = NXP_SYSCLK_FREQ,
+ .nxp_ddrclk_freq = NXP_DDRCLK_FREQ,
+ .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER,
+};
+
+static struct soc_type soc_list[] = {
+ SOC_ENTRY(LS1017AN, LS1017AN, 1, 1),
+ SOC_ENTRY(LS1017AE, LS1017AE, 1, 1),
+ SOC_ENTRY(LS1018AN, LS1018AN, 1, 1),
+ SOC_ENTRY(LS1018AE, LS1018AE, 1, 1),
+ SOC_ENTRY(LS1027AN, LS1027AN, 1, 2),
+ SOC_ENTRY(LS1027AE, LS1027AE, 1, 2),
+ SOC_ENTRY(LS1028AN, LS1028AN, 1, 2),
+ SOC_ENTRY(LS1028AE, LS1028AE, 1, 2),
+};
+
+CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256,
+ assert_invalid_ls1028a_cluster_count);
+
+/*
+ * Function returns the base counter frequency
+ * after reading the first entry at CNTFID0 (0x20 offset).
+ *
+ * Function is used by:
+ * 1. ARM common code for PSCI management.
+ * 2. ARM Generic Timer init.
+ *
+ */
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+ /*
+ * Below register specifies the base frequency of the system counter.
+ * As per NXP Board Manuals:
+ * The system counter always works with SYS_REF_CLK/4 frequency clock.
+ */
+ counter_base_frequency = mmio_read_32(NXP_TIMER_ADDR + CNTFID_OFF);
+
+ return counter_base_frequency;
+}
+
+#ifdef IMAGE_BL2
+
+#ifdef POLICY_FUSE_PROVISION
+static gpio_init_info_t gpio_init_data = {
+ .gpio1_base_addr = NXP_GPIO1_ADDR,
+ .gpio2_base_addr = NXP_GPIO2_ADDR,
+ .gpio3_base_addr = NXP_GPIO3_ADDR,
+};
+#endif
+
+void soc_preload_setup(void)
+{
+}
+
+void soc_early_init(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+#ifdef CONFIG_OCRAM_ECC_EN
+ ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
+#endif
+ dcfg_init(&dcfg_init_data);
+ enable_timer_base_to_cluster(NXP_PMU_ADDR);
+ enable_core_tb(NXP_PMU_ADDR);
+ dram_regions_info_t *dram_regions_info = get_dram_regions_info();
+
+#ifdef POLICY_FUSE_PROVISION
+ gpio_init(&gpio_init_data);
+ sec_init(NXP_CAAM_ADDR);
+#endif
+
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+ enum boot_device dev = get_boot_dev();
+ /*
+ * Mark the buffer for SD in OCRAM as non secure.
+ * The buffer is assumed to be at end of OCRAM for
+ * the logic below to calculate TZPC programming
+ */
+ if (dev == BOOT_DEVICE_EMMC || dev == BOOT_DEVICE_SDHC2_EMMC) {
+ /*
+ * Calculate the region in OCRAM which is secure
+ * The buffer for SD needs to be marked non-secure
+ * to allow SD to do DMA operations on it
+ */
+ uint32_t secure_region = (NXP_OCRAM_SIZE - NXP_SD_BLOCK_BUF_SIZE);
+ uint32_t mask = secure_region/TZPC_BLOCK_SIZE;
+
+ mmio_write_32(NXP_OCRAM_TZPC_ADDR, mask);
+
+ /* Add the entry for buffer in MMU Table */
+ mmap_add_region(NXP_SD_BLOCK_BUF_ADDR, NXP_SD_BLOCK_BUF_ADDR,
+ NXP_SD_BLOCK_BUF_SIZE, MT_DEVICE | MT_RW | MT_NS);
+ }
+
+#if TRUSTED_BOARD_BOOT
+ uint32_t mode;
+
+ sfp_init(NXP_SFP_ADDR);
+
+ /*
+ * For secure boot disable SMMU.
+ * Later when platform security policy comes in picture,
+ * this might get modified based on the policy
+ */
+ if (check_boot_mode_secure(&mode) == true) {
+ bypass_smmu(NXP_SMMU_ADDR);
+ }
+
+ /*
+ * For Mbedtls currently crypto is not supported via CAAM
+ * enable it when that support is there. In tbbr.mk
+ * the CAAM_INTEG is set as 0.
+ */
+#ifndef MBEDTLS_X509
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled()) {
+ sec_init(NXP_CAAM_ADDR);
+ } else {
+ INFO("SEC is disabled.\n");
+ }
+#endif
+#endif
+
+ /* Set eDDRTQ for DDR performance */
+ scfg_setbits32((void *)(NXP_SCFG_ADDR + 0x210), 0x1f1f1f1f);
+
+ soc_errata();
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ */
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ delay_timer_init(NXP_TIMER_ADDR);
+ i2c_init(NXP_I2C_ADDR);
+ dram_regions_info->total_dram_size = init_ddr();
+}
+
+void soc_bl2_prepare_exit(void)
+{
+#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE)
+ set_sfp_wr_disable();
+#endif
+}
+
+/*
+ * This function returns the boot device based on RCW_SRC
+ */
+enum boot_device get_boot_dev(void)
+{
+ enum boot_device src = BOOT_DEVICE_NONE;
+ uint32_t porsr1;
+ uint32_t rcw_src;
+
+ porsr1 = read_reg_porsr1();
+
+ rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT;
+ switch (rcw_src) {
+ case FLEXSPI_NOR:
+ src = BOOT_DEVICE_FLEXSPI_NOR;
+ INFO("RCW BOOT SRC is FLEXSPI NOR\n");
+ break;
+ case FLEXSPI_NAND2K_VAL:
+ case FLEXSPI_NAND4K_VAL:
+ INFO("RCW BOOT SRC is FLEXSPI NAND\n");
+ src = BOOT_DEVICE_FLEXSPI_NAND;
+ break;
+ case SDHC1_VAL:
+ src = BOOT_DEVICE_EMMC;
+ INFO("RCW BOOT SRC is SD\n");
+ break;
+ case SDHC2_VAL:
+ src = BOOT_DEVICE_SDHC2_EMMC;
+ INFO("RCW BOOT SRC is EMMC\n");
+ break;
+ default:
+ break;
+ }
+
+ return src;
+}
+
+/*
+ * This function sets up access permissions on memory regions
+ ****************************************************************************/
+void soc_mem_access(void)
+{
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+ struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION];
+ int dram_idx = 0;
+ /* index 0 is reserved for region-0 */
+ int index = 1;
+
+ for (dram_idx = 0; dram_idx < info_dram_regions->num_dram_regions;
+ dram_idx++) {
+ if (info_dram_regions->region[dram_idx].size == 0) {
+ ERROR("DDR init failure, or");
+ ERROR("DRAM regions not populated correctly.\n");
+ break;
+ }
+
+ index = populate_tzc400_reg_list(tzc400_reg_list,
+ dram_idx, index,
+ info_dram_regions->region[dram_idx].addr,
+ info_dram_regions->region[dram_idx].size,
+ NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE);
+ }
+
+ mem_access_setup(NXP_TZC_ADDR, index, tzc400_reg_list);
+}
+
+#else
+
+static unsigned char _power_domain_tree_desc[NUMBER_OF_CLUSTERS + 2];
+/*
+ * This function dynamically constructs the topology according to
+ * SoC Flavor and returns it.
+ */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+ unsigned int i;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ /*
+ * The highest level is the system level. The next level is constituted
+ * by clusters and then cores in clusters.
+ */
+ _power_domain_tree_desc[0] = 1;
+ _power_domain_tree_desc[1] = num_clusters;
+
+ for (i = 0; i < _power_domain_tree_desc[1]; i++)
+ _power_domain_tree_desc[i + 2] = cores_per_cluster;
+
+ return _power_domain_tree_desc;
+}
+
+/*
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ */
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ return num_clusters;
+}
+
+void soc_early_platform_setup2(void)
+{
+ dcfg_init(&dcfg_init_data);
+ /* Initialize system level generic timer for Socs */
+ delay_timer_init(NXP_TIMER_ADDR);
+
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+}
+
+void soc_platform_setup(void)
+{
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ static uintptr_t target_mask_array[PLATFORM_CORE_COUNT];
+ static interrupt_prop_t ls_interrupt_props[] = {
+ PLAT_LS_G1S_IRQ_PROPS(INTR_GROUP1S),
+ PLAT_LS_G0_IRQ_PROPS(INTR_GROUP0)
+ };
+
+ plat_ls_gic_driver_init(NXP_GICD_ADDR, NXP_GICR_ADDR,
+ PLATFORM_CORE_COUNT,
+ ls_interrupt_props,
+ ARRAY_SIZE(ls_interrupt_props),
+ target_mask_array,
+ plat_core_pos);
+
+ plat_ls_gic_init();
+ enable_init_timer();
+}
+
+/* This function initializes the soc from the BL31 module */
+void soc_init(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ /* Low-level init of the soc */
+ soc_init_lowlevel();
+ _init_global_data();
+ soc_init_percpu();
+ _initialize_psci();
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /* Enable Interconnect coherency for the primary CPU's cluster. */
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ /* Set platform security policies */
+ _set_platform_security();
+
+ /* Init SEC Engine which will be used by SiP */
+ if (is_sec_enabled()) {
+ sec_init(NXP_CAAM_ADDR);
+ } else {
+ INFO("SEC is disabled.\n");
+ }
+}
+
+#ifdef NXP_WDOG_RESTART
+static uint64_t wdog_interrupt_handler(uint32_t id, uint32_t flags,
+ void *handle, void *cookie)
+{
+ uint8_t data = WDOG_RESET_FLAG;
+
+ wr_nv_app_data(WDT_RESET_FLAG_OFFSET,
+ (uint8_t *)&data, sizeof(data));
+
+ mmio_write_32(NXP_RST_ADDR + RSTCNTL_OFFSET, SW_RST_REQ_INIT);
+
+ return 0;
+}
+#endif
+
+void soc_runtime_setup(void)
+{
+#ifdef NXP_WDOG_RESTART
+ request_intr_type_el3(BL31_NS_WDOG_WS1, wdog_interrupt_handler);
+#endif
+}
+
+/* This function returns the total number of cores in the SoC. */
+unsigned int get_tot_num_cores(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ return (num_clusters * cores_per_cluster);
+}
+
+/* This function returns the PMU IDLE Cluster mask. */
+unsigned int get_pmu_idle_cluster_mask(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ return ((1 << num_clusters) - 2);
+}
+
+/* This function returns the PMU Flush Cluster mask. */
+unsigned int get_pmu_flush_cluster_mask(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ return ((1 << num_clusters) - 2);
+}
+
+/* This function returns the PMU idle core mask. */
+unsigned int get_pmu_idle_core_mask(void)
+{
+ return ((1 << get_tot_num_cores()) - 2);
+}
+
+/* Function to return the SoC SYS CLK */
+unsigned int get_sys_clk(void)
+{
+ return NXP_SYSCLK_FREQ;
+}
+#endif
diff --git a/plat/nxp/soc-ls1028a/soc.def b/plat/nxp/soc-ls1028a/soc.def
new file mode 100644
index 0000000..93275b3
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/soc.def
@@ -0,0 +1,97 @@
+#
+# Copyright 2018-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# This file contains the basic architecture definitions that drive the build
+#
+# -----------------------------------------------------------------------------
+
+CORE_TYPE := a72
+
+CACHE_LINE := 6
+
+# Set to GIC400 or GIC500
+GIC := GIC500
+
+# Set to CCI400 or CCN504 or CCN508
+INTERCONNECT := CCI400
+
+# Layerscape chassis level - set to 3=LSCH3 or 2=LSCH2
+CHASSIS := 3_2
+
+# TZC used is TZC380 or TZC400
+TZC_ID := TZC400
+
+# CONSOLE is NS16550 or PL011
+CONSOLE := NS16550
+
+# DDR PHY generation to be used
+PLAT_DDR_PHY := PHY_GEN1
+
+PHYS_SYS := 64
+
+# Max Size of CSF header. Required to define BL2 TEXT LIMIT in soc.def
+# Input to CST create_hdr_esbc tool
+CSF_HDR_SZ := 0x3000
+
+# In IMAGE_BL2, compile time flag for handling Cache coherency
+# with CAAM for BL2 running from OCRAM
+SEC_MEM_NON_COHERENT := yes
+
+# OCRAM MAP for BL2
+# Before BL2
+# 0x18000000 - 0x18009fff -> Used by ROM code
+# 0x1800a000 - 0x1800dfff -> CSF header for BL2
+# For FlexSFlexSPI boot
+# 0x1800e000 - 0x18040000 -> Reserved for BL2 binary
+# For SD boot
+# 0x1800e000 - 0x18030000 -> Reserved for BL2 binary
+# 0x18030000 - 0x18040000 -> Reserved for SD buffer
+OCRAM_START_ADDR := 0x18000000
+OCRAM_SIZE := 0x40000
+
+# Area of OCRAM reserved by ROM code
+NXP_ROM_RSVD := 0xa000
+
+# Location of BL2 on OCRAM
+BL2_BASE_ADDR := $(shell echo $$(( $(OCRAM_START_ADDR) + $(NXP_ROM_RSVD) + $(CSF_HDR_SZ) )))
+
+# Covert to HEX to be used by create_pbl.mk
+BL2_BASE := $(shell echo "0x"$$(echo "obase=16; ${BL2_BASE_ADDR}" | bc))
+
+# BL2_HDR_LOC is at (BL2_BASE + NXP_ROM_RSVD)
+# This value BL2_HDR_LOC + CSF_HDR_SZ should not
+# overalp with BL2_BASE
+# Input to CST create_hdr_isbc tool
+BL2_HDR_LOC := 0x1800A000
+
+# SoC ERRATAS to be enabled
+
+# DDR ERRATA
+ERRATA_DDR_A009803 := 1
+ERRATA_DDR_A009942 := 1
+ERRATA_DDR_A010165 := 1
+
+# Enable dynamic memory mapping
+PLAT_XLAT_TABLES_DYNAMIC := 1
+
+# Define Endianness of each module
+NXP_GUR_ENDIANNESS := LE
+NXP_DDR_ENDIANNESS := LE
+NXP_SEC_ENDIANNESS := LE
+NXP_SFP_ENDIANNESS := LE
+NXP_SNVS_ENDIANNESS := LE
+NXP_ESDHC_ENDIANNESS := LE
+NXP_QSPI_ENDIANNESS := LE
+NXP_FSPI_ENDIANNESS := LE
+NXP_SCFG_ENDIANNESS := LE
+NXP_GPIO_ENDIANNESS := LE
+
+NXP_SFP_VER := 3_4
+
+# OCRAM ECC Enabled
+OCRAM_ECC_EN := yes
diff --git a/plat/nxp/soc-ls1028a/soc.mk b/plat/nxp/soc-ls1028a/soc.mk
new file mode 100644
index 0000000..92d8e98
--- /dev/null
+++ b/plat/nxp/soc-ls1028a/soc.mk
@@ -0,0 +1,113 @@
+#
+# Copyright 2020-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# SoC-specific build parameters
+SOC := ls1028a
+PLAT_PATH := plat/nxp
+PLAT_COMMON_PATH := plat/nxp/common
+PLAT_DRIVERS_PATH := drivers/nxp
+PLAT_SOC_PATH := ${PLAT_PATH}/soc-${SOC}
+BOARD_PATH := ${PLAT_SOC_PATH}/${BOARD}
+
+# Get SoC-specific definitions
+include ${PLAT_SOC_PATH}/soc.def
+include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
+SECURE_BOOT := yes
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM))
+
+$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+
+# Selecting PSCI & SIP_SVC support
+$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31))
+
+PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\
+ -I${BOARD_PATH}\
+ -I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
+ -I${PLAT_SOC_PATH}/include\
+ -I${PLAT_COMMON_PATH}/soc_errata
+
+ifeq (${SECURE_BOOT},yes)
+include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
+endif
+
+ifeq ($(WARM_BOOT),yes)
+include ${PLAT_COMMON_PATH}/warm_reset/warm_reset.mk
+endif
+
+ifeq (${NXP_NV_SW_MAINT_LAST_EXEC_DATA}, yes)
+include ${PLAT_COMMON_PATH}/nv_storage/nv_storage.mk
+endif
+
+ifeq (${PSCI_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/psci/psci.mk
+endif
+
+ifeq (${SIPSVC_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk
+endif
+
+ifeq (${DDR_FIP_IO_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/fip_handler/ddr_fip/ddr_fip_io.mk
+endif
+
+# For fuse-fip & fuse-programming
+ifeq (${FUSE_PROG}, 1)
+include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk
+endif
+
+ifeq (${IMG_LOADR_NEEDED},yes)
+include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk
+endif
+
+# Adding source files for the above selected drivers.
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+# Adding SoC specific files
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
+
+PLAT_INCLUDES += ${NV_STORAGE_INCLUDES}\
+ ${WARM_RST_INCLUDES}
+
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\
+ ${WARM_RST_BL31_SOURCES}\
+ ${PSCI_SOURCES}\
+ ${SIPSVC_SOURCES}\
+ ${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S
+
+PLAT_BL_COMMON_SOURCES += ${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\
+ ${PLAT_SOC_PATH}/aarch64/${SOC}_helpers.S\
+ ${NV_STORAGE_SOURCES}\
+ ${WARM_RST_BL_COMM_SOURCES}\
+ ${PLAT_SOC_PATH}/soc.c
+
+ifeq (${TEST_BL31}, 1)
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S \
+ ${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S
+endif
+
+BL2_SOURCES += ${DDR_CNTLR_SOURCES}\
+ ${TBBR_SOURCES}\
+ ${FUSE_SOURCES}
+
+# Adding TFA setup files
+include ${PLAT_PATH}/common/setup/common.mk
diff --git a/plat/nxp/soc-ls1043a/aarch64/ls1043a.S b/plat/nxp/soc-ls1043a/aarch64/ls1043a.S
new file mode 100644
index 0000000..a1baf79
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/aarch64/ls1043a.S
@@ -0,0 +1,1637 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <cortex_a53.h>
+#include <dcfg_lsch2.h>
+#include <plat_gic.h>
+#include <scfg.h>
+
+#include <bl31_data.h>
+#include <plat_psci.h>
+#include <platform_def.h>
+
+/* the BASE address for these offsets is AUX_01_DATA in the */
+/* bootcore's psci data region */
+#define DEVDISR2_MASK_OFFSET 0x0 /* references AUX_01_DATA */
+#define DEVDISR5_MASK_OFFSET 0x8 /* references AUX_02_DATA */
+#define CPUACTLR_DATA_OFFSET 0x10 /* references AUX_03_DATA */
+/* the BASE address for these offsets is AUX_04_DATA in the */
+/* bootcore's psci data region */
+#define GICD_BASE_ADDR_OFFSET 0x0 /* references AUX_04_DATA */
+#define GICC_BASE_ADDR_OFFSET 0x8 /* references AUX_05_DATA */
+
+#define DAIF_DATA AUX_06_DATA /* references AUX_06_DATA */
+
+#define IPSTPACK_RETRY_CNT 0x10000
+#define DDR_SLEEP_RETRY_CNT 0x10000
+#define CPUACTLR_EL1 S3_1_C15_C2_0
+#define DDR_SDRAM_CFG_2_FRCSR 0x80000000
+#define DDR_SDRAM_CFG_2_OFFSET 0x114
+#define DDR_TIMING_CFG_4_OFFSET 0x160
+#define DDR_CNTRL_BASE_ADDR 0x01080000
+
+#define DLL_LOCK_MASK 0x3
+#define DLL_LOCK_VALUE 0x2
+
+#define ERROR_DDR_SLEEP -1
+#define ERROR_DDR_WAKE -2
+#define ERROR_NO_QUIESCE -3
+
+#define CORE_RESTARTABLE 0
+#define CORE_NOT_RESTARTABLE 1
+
+#define RESET_RETRY_CNT 800
+
+.global soc_init_lowlevel
+.global soc_init_percpu
+.global _soc_core_release
+.global _soc_core_restart
+.global _soc_ck_disabled
+.global _soc_sys_reset
+.global _soc_sys_off
+.global _getGICD_BaseAddr
+.global _getGICC_BaseAddr
+.global _soc_set_start_addr
+.global _soc_core_prep_off
+.global _soc_core_entr_off
+.global _soc_core_exit_off
+.global _soc_core_prep_stdby
+.global _soc_core_entr_stdby
+.global _soc_core_exit_stdby
+.global _soc_core_prep_pwrdn
+.global _soc_core_entr_pwrdn
+.global _soc_core_exit_pwrdn
+.global _soc_clstr_prep_stdby
+.global _soc_clstr_exit_stdby
+.global _soc_clstr_prep_pwrdn
+.global _soc_clstr_exit_pwrdn
+.global _soc_sys_prep_stdby
+.global _soc_sys_exit_stdby
+.global _soc_sys_prep_pwrdn
+.global _soc_sys_pwrdn_wfi
+.global _soc_sys_exit_pwrdn
+
+/*
+ * This function initialize the soc.
+ * in: void
+ * out: void
+ */
+func soc_init_lowlevel
+ ret
+endfunc soc_init_lowlevel
+
+/*
+ * void soc_init_percpu(void)
+ * this function performs any soc-specific initialization that is needed on
+ * a per-core basis
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+func soc_init_percpu
+ mov x3, x30
+
+ bl plat_my_core_mask
+ mov x2, x0
+
+ /* see if this core is marked for prefetch disable */
+ mov x0, #PREFETCH_DIS_OFFSET
+ bl _get_global_data /* 0-1 */
+ tst x0, x2
+ b.eq 1f
+ bl _disable_ldstr_pfetch_A53 /* 0 */
+1:
+ mov x30, x3
+ ret
+endfunc soc_init_percpu
+
+/*
+ * part of CPU_ON
+ * this function releases a secondary core from reset
+ * in: x0 = core_mask_lsb
+ * out: none
+ * uses: x0, x1, x2, x3
+ */
+_soc_core_release:
+
+#if (TEST_BL31)
+ mov w2, w0
+ CoreMaskMsb w2, w3
+ /* x2 = core mask msb */
+#else
+ mov x2, x0
+#endif
+ /* write COREBCR */
+ ldr x1, =NXP_SCFG_ADDR
+ rev w3, w2
+ str w3, [x1, #SCFG_COREBCR_OFFSET]
+ isb
+
+ /* read-modify-write BRR */
+ mov x1, #NXP_DCFG_ADDR
+ ldr w2, [x1, #DCFG_BRR_OFFSET]
+ rev w3, w2
+ orr w3, w3, w0
+ rev w2, w3
+ str w2, [x1, #DCFG_BRR_OFFSET]
+ isb
+
+ /* send event */
+ sev
+ isb
+ ret
+
+
+/*
+ * part of CPU_ON
+ * this function restarts a core shutdown via _soc_core_entr_off
+ * in: x0 = core mask lsb (of the target cpu)
+ * out: x0 == 0, on success
+ * x0 != 0, on failure
+ * uses x0 ~ x5
+ */
+_soc_core_restart:
+ mov x5, x30
+ mov x3, x0
+
+ /* x3 = core mask lsb */
+ bl _getGICD_BaseAddr
+ mov x4, x0
+
+ /* x4 = GICD_BASE_ADDR */
+ /* enable forwarding of group 0 interrupts by setting GICD_CTLR[0] = 1 */
+ ldr w1, [x4, #GICD_CTLR_OFFSET]
+ orr w1, w1, #GICD_CTLR_EN_GRP0
+ str w1, [x4, #GICD_CTLR_OFFSET]
+ dsb sy
+ isb
+
+ /*
+ * fire SGI by writing to GICD_SGIR the following values:
+ * [25:24] = 0x0 (forward interrupt to the CPU interfaces specified in CPUTargetList field)
+ * [23:16] = core mask lsb[7:0] (forward interrupt to target cpu)
+ * [15] = 0 (forward SGI only if it is configured as group 0 interrupt)
+ * [3:0] = 0xF (interrupt ID = 15)
+ */
+ lsl w1, w3, #16
+ orr w1, w1, #0xF
+ str w1, [x4, #GICD_SGIR_OFFSET]
+ dsb sy
+ isb
+
+ /* load '0' on success */
+ mov x0, xzr
+
+ mov x30, x5
+ ret
+
+/*
+ * this function determines if a core is disabled via COREDISR
+ * in: w0 = core_mask_lsb
+ * out: w0 = 0, core not disabled
+ * w0 != 0, core disabled
+ * uses x0, x1, x2
+ */
+_soc_ck_disabled:
+
+ /* get base addr of dcfg block */
+ ldr x1, =NXP_DCFG_ADDR
+
+ /* read COREDISR */
+ ldr w1, [x1, #DCFG_COREDISR_OFFSET]
+ rev w2, w1
+
+ /* test core bit */
+ and w0, w2, w0
+ ret
+
+/*
+ * this function resets the system via SoC-specific methods
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_sys_reset:
+
+ ldr x2, =NXP_DCFG_ADDR
+
+ /* make sure the mask is cleared in the reset request mask register */
+ mov w1, wzr
+ str w1, [x2, #DCFG_RSTRQMR1_OFFSET]
+
+ /* x2 = NXP_DCFG_ADDR */
+
+ /* set the reset request */
+ ldr w1, =RSTCR_RESET_REQ
+ ldr x3, =DCFG_RSTCR_OFFSET
+ rev w0, w1
+ str w0, [x2, x3]
+
+ /* x2 = NXP_DCFG_ADDR */
+ /* x3 = DCFG_RSTCR_OFFSET */
+
+ /* just in case this address range is mapped as cacheable,
+ * flush the write out of the dcaches */
+ add x3, x2, x3
+ dc cvac, x3
+ dsb st
+ isb
+
+ /* Note: this function does not return */
+1:
+ wfi
+ b 1b
+
+
+/*
+ * part of SYSTEM_OFF
+ * this function turns off the SoC clocks
+ * Note: this function is not intended to return, and the only allowable
+ * recovery is POR
+ * in: none
+ * out: none
+ * uses x0 ~ x8
+ */
+_soc_sys_off:
+
+ /* mask interrupts at the core */
+ mrs x1, DAIF
+ mov x0, #DAIF_SET_MASK
+ orr x0, x1, x0
+ msr DAIF, x0
+
+ /* disable icache, dcache, mmu @ EL1 */
+ mov x1, #SCTLR_I_C_M_MASK
+ mrs x0, sctlr_el1
+ bic x0, x0, x1
+ msr sctlr_el1, x0
+
+ /* disable dcache for EL3 */
+ mrs x1, SCTLR_EL3
+ bic x1, x1, #SCTLR_C_MASK
+ /* make sure icache is enabled */
+ orr x1, x1, #SCTLR_I_MASK
+ msr SCTLR_EL3, x1
+ isb
+
+ /* set WFIL2_EN in SCFG_COREPMCR */
+ ldr x0, =SCFG_COREPMCR_OFFSET
+ ldr x1, =COREPMCR_WFIL2
+ bl write_reg_scfg
+
+ /* set OVRD_EN in RCPM2_POWMGTDCR */
+ ldr x0, =RCPM2_POWMGTDCR_OFFSET
+ ldr x1, =POWMGTDCR_OVRD_EN
+ bl write_reg_rcpm2
+
+ /* read IPPDEXPCR0 @ RCPM_IPPDEXPCR0 */
+ ldr x0, =RCPM_IPPDEXPCR0_OFFSET
+ bl read_reg_rcpm
+ mov x7, x0
+
+ /* build an override mask for IPSTPCR4/IPSTPACK4/DEVDISR5 */
+ mov x5, xzr
+ ldr x6, =IPPDEXPCR_MASK2
+ and x6, x6, x7
+ cbz x6, 1f
+
+ /* x5 = override mask
+ * x6 = IPPDEXPCR bits for DEVDISR5
+ * x7 = IPPDEXPCR */
+
+ /* get the overrides */
+ orr x4, x5, #DEVDISR5_I2C_1
+ tst x6, #IPPDEXPCR_I2C1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR5_LPUART1
+ tst x6, #IPPDEXPCR_LPUART1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR5_FLX_TMR
+ tst x6, #IPPDEXPCR_FLX_TMR1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR5_OCRAM1
+ tst x6, #IPPDEXPCR_OCRAM1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR5_GPIO
+ tst x6, #IPPDEXPCR_GPIO1
+ csel x5, x5, x4, EQ
+1:
+ /* store the DEVDISR5 override mask */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ str w5, [x2, #DEVDISR5_MASK_OFFSET]
+
+ /* build an override mask for IPSTPCR1/IPSTPACK1/DEVDISR2 */
+ mov x5, xzr
+ ldr x6, =IPPDEXPCR_MASK1
+ and x6, x6, x7
+ cbz x6, 2f
+
+ /* x5 = override mask */
+ /* x6 = IPPDEXPCR bits for DEVDISR2 */
+
+ /* get the overrides */
+ orr x4, x5, #DEVDISR2_FMAN1_MAC1
+ tst x6, #IPPDEXPCR_MAC1_1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC2
+ tst x6, #IPPDEXPCR_MAC1_2
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC3
+ tst x6, #IPPDEXPCR_MAC1_3
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC4
+ tst x6, #IPPDEXPCR_MAC1_4
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC5
+ tst x6, #IPPDEXPCR_MAC1_5
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC6
+ tst x6, #IPPDEXPCR_MAC1_6
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC9
+ tst x6, #IPPDEXPCR_MAC1_9
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1
+ tst x6, #IPPDEXPCR_FM1
+ csel x5, x5, x4, EQ
+
+2:
+ /* store the DEVDISR2 override mask */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ str w5, [x2, #DEVDISR2_MASK_OFFSET]
+
+ /* x5 = DEVDISR2 override mask */
+
+ /* write IPSTPCR0 - no overrides */
+ ldr x0, =RCPM2_IPSTPCR0_OFFSET
+ ldr x1, =IPSTPCR0_VALUE
+ bl write_reg_rcpm2
+
+ /* x5 = DEVDISR2 override mask */
+
+ /* write IPSTPCR1 - overrides possible */
+ ldr x0, =RCPM2_IPSTPCR1_OFFSET
+ ldr x1, =IPSTPCR1_VALUE
+ bic x1, x1, x5
+ bl write_reg_rcpm2
+
+ /* write IPSTPCR2 - no overrides */
+ ldr x0, =RCPM2_IPSTPCR2_OFFSET
+ ldr x1, =IPSTPCR2_VALUE
+ bl write_reg_rcpm2
+
+ /* write IPSTPCR3 - no overrides */
+ ldr x0, =RCPM2_IPSTPCR3_OFFSET
+ ldr x1, =IPSTPCR3_VALUE
+ bl write_reg_rcpm2
+
+ /* write IPSTPCR4 - overrides possible */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ ldr w6, [x2, #DEVDISR5_MASK_OFFSET]
+ ldr x0, =RCPM2_IPSTPCR4_OFFSET
+ ldr x1, =IPSTPCR4_VALUE
+ bic x1, x1, x6
+ bl write_reg_rcpm2
+
+ /* x5 = DEVDISR2 override mask */
+ /* x6 = DEVDISR5 override mask */
+
+ /* poll on IPSTPACK0 */
+ ldr x3, =RCPM2_IPSTPACKR0_OFFSET
+ ldr x4, =IPSTPCR0_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+3:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 14f
+ sub x7, x7, #1
+ cbnz x7, 3b
+
+14:
+ /* poll on IPSTPACK1 */
+ ldr x3, =IPSTPCR1_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+ bic x4, x3, x5
+ ldr x3, =RCPM2_IPSTPACKR1_OFFSET
+4:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 15f
+ sub x7, x7, #1
+ cbnz x7, 4b
+
+15:
+ /* poll on IPSTPACK2 */
+ ldr x3, =RCPM2_IPSTPACKR2_OFFSET
+ ldr x4, =IPSTPCR2_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+5:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 16f
+ sub x7, x7, #1
+ cbnz x7, 5b
+
+16:
+ /* poll on IPSTPACK3 */
+ ldr x3, =RCPM2_IPSTPACKR3_OFFSET
+ ldr x4, =IPSTPCR3_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+6:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 17f
+ sub x7, x7, #1
+ cbnz x7, 6b
+
+17:
+ /* poll on IPSTPACK4 */
+ ldr x3, =IPSTPCR4_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+ bic x4, x3, x6
+ ldr x3, =RCPM2_IPSTPACKR4_OFFSET
+7:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 18f
+ sub x7, x7, #1
+ cbnz x7, 7b
+
+18:
+ ldr x7, =BC_PSCI_BASE
+ add x7, x7, #AUX_01_DATA
+
+ /* x5 = DEVDISR2 override mask
+ * x6 = DEVDISR5 override mask
+ * x7 = [soc_data_area] */
+
+ /* DEVDISR1 - load new value */
+ mov x0, #DCFG_DEVDISR1_OFFSET
+ bl read_reg_dcfg
+ mov x0, #DCFG_DEVDISR1_OFFSET
+ ldr x1, =DEVDISR1_VALUE
+ bl write_reg_dcfg
+
+ /* DEVDISR2 - load new value */
+ mov x0, #DCFG_DEVDISR2_OFFSET
+ bl read_reg_dcfg
+ mov x0, #DCFG_DEVDISR2_OFFSET
+ ldr x1, =DEVDISR2_VALUE
+ bic x1, x1, x5
+ bl write_reg_dcfg
+
+ /* x6 = DEVDISR5 override mask */
+ /* x7 = [soc_data_area] */
+
+ /* DEVDISR3 - load new value */
+ mov x0, #DCFG_DEVDISR3_OFFSET
+ bl read_reg_dcfg
+ mov x0, #DCFG_DEVDISR3_OFFSET
+ ldr x1, =DEVDISR3_VALUE
+ bl write_reg_dcfg
+
+ /* DEVDISR4 - load new value */
+ mov x0, #DCFG_DEVDISR4_OFFSET
+ bl read_reg_dcfg
+ mov x0, #DCFG_DEVDISR4_OFFSET
+ ldr x1, =DEVDISR4_VALUE
+ bl write_reg_dcfg
+
+ /* DEVDISR5 - load new value */
+ mov x0, #DCFG_DEVDISR5_OFFSET
+ bl read_reg_dcfg
+ mov x0, #DCFG_DEVDISR5_OFFSET
+ ldr x1, =DEVDISR5_VALUE
+ bic x1, x1, x6
+ bl write_reg_dcfg
+
+ /* x7 = [soc_data_area] */
+
+ /* disable data prefetch */
+ mrs x0, CPUACTLR_EL1
+ bic x0, x0, #CPUACTLR_L1PCTL_MASK
+ msr CPUACTLR_EL1, x0
+
+ /* x6 = DEVDISR5 override mask */
+
+ /* setup registers for cache-only execution */
+ ldr x5, =IPSTPCR4_VALUE
+ bic x5, x5, x6
+ mov x6, #DDR_CNTRL_BASE_ADDR
+ mov x7, #DCSR_RCPM2_BASE
+ mov x8, #NXP_DCFG_ADDR
+ dsb sy
+ isb
+
+ /* set the DLL_LOCK cycle count */
+ ldr w1, [x6, #DDR_TIMING_CFG_4_OFFSET]
+ rev w2, w1
+ bic w2, w2, #DLL_LOCK_MASK
+ orr w2, w2, #DLL_LOCK_VALUE
+ rev w1, w2
+ str w1, [x6, #DDR_TIMING_CFG_4_OFFSET]
+
+ /* x5 = ipstpcr4 (IPSTPCR4_VALUE bic DEVDISR5_MASK)
+ * x6 = DDR_CNTRL_BASE_ADDR
+ * x7 = DCSR_RCPM2_BASE
+ * x8 = NXP_DCFG_ADDR */
+
+ /* enter the cache-only sequence - there is no return */
+ b final_shutdown
+
+
+/*
+ * part of CPU_OFF
+ * this function programs SoC & GIC registers in preparation for shutting down
+ * the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0 ~ x7
+ */
+_soc_core_prep_off:
+ mov x7, x30
+ mov x6, x0
+
+ /* make sure the smpen bit is set */
+ mrs x2, CORTEX_A53_ECTLR_EL1
+ orr x2, x2, #CPUECTLR_SMPEN_MASK
+ msr CORTEX_A53_ECTLR_EL1, x2
+ isb
+
+ /* configure the cpu interface */
+
+ /* disable signaling of ints */
+ bl _getGICC_BaseAddr // 0-1
+ mov x4, x0
+
+ ldr w3, [x4, #GICC_CTLR_OFFSET]
+ bic w3, w3, #GICC_CTLR_EN_GRP0
+ bic w3, w3, #GICC_CTLR_EN_GRP1
+ str w3, [x4, #GICC_CTLR_OFFSET]
+ dsb sy
+ isb
+
+ /*
+ * x3 = GICC_CTRL
+ * x4 = GICC_BASE_ADDR
+ * x6 = core mask
+ */
+
+ /* set the priority filter */
+ ldr w2, [x4, #GICC_PMR_OFFSET]
+ orr w2, w2, #GICC_PMR_FILTER
+ str w2, [x4, #GICC_PMR_OFFSET]
+
+ /* setup GICC_CTLR */
+ bic w3, w3, #GICC_CTLR_ACKCTL_MASK
+ orr w3, w3, #GICC_CTLR_FIQ_EN_MASK
+ orr w3, w3, #GICC_CTLR_EOImodeS_MASK
+ orr w3, w3, #GICC_CTLR_CBPR_MASK
+ str w3, [x4, #GICC_CTLR_OFFSET]
+
+ /* x3 = GICC_CTRL */
+ /* x4 = GICC_BASE_ADDR */
+
+ /* setup the banked-per-core GICD registers */
+ bl _getGICD_BaseAddr
+
+ /*
+ * x0 = GICD_BASE_ADDR
+ * x3 = GICC_CTRL
+ * x4 = GICC_BASE_ADDR
+ * x6 = core mask
+ */
+
+ /* define SGI15 as Grp0 */
+ ldr w2, [x0, #GICD_IGROUPR0_OFFSET]
+ bic w2, w2, #GICD_IGROUP0_SGI15
+ str w2, [x0, #GICD_IGROUPR0_OFFSET]
+
+ /* set priority of SGI 15 to highest... */
+ ldr w2, [x0, #GICD_IPRIORITYR3_OFFSET]
+ bic w2, w2, #GICD_IPRIORITY_SGI15_MASK
+ str w2, [x0, #GICD_IPRIORITYR3_OFFSET]
+
+ /* enable SGI 15 */
+ ldr w2, [x0, #GICD_ISENABLER0_OFFSET]
+ orr w2, w2, #GICD_ISENABLE0_SGI15
+ str w2, [x0, #GICD_ISENABLER0_OFFSET]
+
+ /* enable the cpu interface */
+ orr w3, w3, #GICC_CTLR_EN_GRP0
+ str w3, [x4, #GICC_CTLR_OFFSET]
+
+ /* x0 = GICD_BASE_ADDR
+ * x6 = core mask */
+
+ /* clear any pending SGIs */
+ add x0, x0, #GICD_CPENDSGIR3_OFFSET
+ ldr x2, =GICD_CPENDSGIR_CLR_MASK
+ str w2, [x0]
+
+ dsb sy
+ isb
+ mov x30, x7
+ ret
+
+/*
+ * part of CPU_OFF
+ * this function performs the final steps to shutdown the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0 ~ x5
+ */
+_soc_core_entr_off:
+ mov x5, x30
+ mov x4, x0
+
+ bl _getGICD_BaseAddr
+ mov x3, x0
+
+ /* x3 = GICD_BASE_ADDR */
+ /* x4 = core mask (lsb) */
+
+3:
+ /* enter low-power state by executing wfi */
+ wfi
+
+ /* x3 = GICD_BASE_ADDR */
+ /* x4 = core mask (lsb) */
+
+ /* see if we got hit by SGI 15 */
+ add x0, x3, #GICD_SPENDSGIR3_OFFSET
+ ldr w2, [x0]
+ and w2, w2, #GICD_SPENDSGIR3_SGI15_MASK
+ cbz w2, 4f
+
+ /* clear the pending SGI */
+ ldr x2, =GICD_CPENDSGIR_CLR_MASK
+ add x0, x3, #GICD_CPENDSGIR3_OFFSET
+ str w2, [x0]
+4:
+ /* check if core has been turned on */
+ mov x0, x4
+ bl _getCoreState
+
+ /* x0 = core state */
+ cmp x0, #CORE_WAKEUP
+ b.ne 3b
+
+ /* if we get here, then we have exited the wfi */
+ dsb sy
+ isb
+ mov x30, x5
+ ret
+
+/*
+ * part of CPU_OFF
+ * this function starts the process of starting a core back up
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0 ~ x5
+ */
+_soc_core_exit_off:
+ mov x5, x30
+ mov x4, x0
+
+ /* x4 = core mask */
+
+ bl _getGICC_BaseAddr
+ mov x2, x0
+
+ /* read GICC_IAR */
+ ldr w0, [x2, #GICC_IAR_OFFSET]
+
+ /* write GICC_EIOR - signal end-of-interrupt */
+ str w0, [x2, #GICC_EOIR_OFFSET]
+
+ /* write GICC_DIR - disable interrupt */
+ str w0, [x2, #GICC_DIR_OFFSET]
+
+ /* x2 = GICC_BASE_ADDR */
+
+ /* disable signaling of grp0 ints */
+ ldr w1, [x2, #GICC_CTLR_OFFSET]
+ bic w1, w1, #GICC_CTLR_EN_GRP0
+ str w1, [x2, #GICC_CTLR_OFFSET]
+
+ dsb sy
+ isb
+ mov x30, x5
+ ret
+
+/*
+ * this function loads a 64-bit execution address of the core in the soc registers
+ * BOOTLOCPTRL/H
+ * in: x0, 64-bit address to write to BOOTLOCPTRL/H
+ * uses x0, x1, x2, x3
+ */
+_soc_set_start_addr:
+ /* get the 64-bit base address of the scfg block */
+ ldr x2, =NXP_SCFG_ADDR
+
+ /* write the 32-bit BOOTLOCPTRL register (offset 0x604 in the scfg block) */
+ mov x1, x0
+ rev w3, w1
+ str w3, [x2, #SCFG_BOOTLOCPTRL_OFFSET]
+
+ /* write the 32-bit BOOTLOCPTRH register (offset 0x600 in the scfg block) */
+ lsr x1, x0, #32
+ rev w3, w1
+ str w3, [x2, #SCFG_BOOTLOCPTRH_OFFSET]
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core into standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_stdby:
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_core_prep_stdby:
+ /* clear CORTEX_A53_ECTLR_EL1[2:0] */
+ mrs x1, CORTEX_A53_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CORTEX_A53_ECTLR_EL1, x1
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_core_exit_stdby:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_core_prep_pwrdn:
+ /* make sure the smp bit is set */
+ mrs x1, CORTEX_A53_ECTLR_EL1
+ orr x1, x1, #CPUECTLR_SMPEN_MASK
+ msr CORTEX_A53_ECTLR_EL1, x1
+ isb
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core into a power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_pwrdn:
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_core_exit_pwrdn:
+ ret
+
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_clstr_prep_stdby:
+ /* clear CORTEX_A53_ECTLR_EL1[2:0] */
+ mrs x1, CORTEX_A53_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CORTEX_A53_ECTLR_EL1, x1
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_clstr_exit_stdby:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_clstr_prep_pwrdn:
+ /* make sure the smp bit is set */
+ mrs x1, CORTEX_A53_ECTLR_EL1
+ orr x1, x1, #CPUECTLR_SMPEN_MASK
+ msr CORTEX_A53_ECTLR_EL1, x1
+ isb
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_clstr_exit_pwrdn:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_prep_stdby:
+ /* clear CORTEX_A53_ECTLR_EL1[2:0] */
+ mrs x1, CORTEX_A53_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CORTEX_A53_ECTLR_EL1, x1
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_sys_exit_stdby:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to
+ * suspend-to-power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4
+ */
+_soc_sys_prep_pwrdn:
+ mov x4, x30
+ /* make sure the smp bit is set */
+ mrs x1, CORTEX_A53_ECTLR_EL1
+ orr x1, x1, #CPUECTLR_SMPEN_MASK
+ msr CORTEX_A53_ECTLR_EL1, x1
+ isb
+
+ /* set WFIL2_EN in SCFG_COREPMCR */
+ ldr x0, =SCFG_COREPMCR_OFFSET
+ ldr x1, =COREPMCR_WFIL2
+ bl write_reg_scfg // 0-3
+
+ /* set OVRD_EN in RCPM2_POWMGTDCR */
+ ldr x0, =RCPM2_POWMGTDCR_OFFSET
+ ldr x1, =POWMGTDCR_OVRD_EN
+ bl write_reg_rcpm2 // 0-3
+
+ mov x30, x4
+ ret
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core, and potentially the soc, into a
+ * low-power state
+ * in: x0 = core mask lsb
+ * out: x0 = 0, success
+ * x0 < 0, failure
+ * uses x0 ~ x9
+ */
+_soc_sys_pwrdn_wfi:
+ mov x18, x30
+
+ /* read IPPDEXPCR0 @ RCPM_IPPDEXPCR0 */
+ ldr x0, =RCPM_IPPDEXPCR0_OFFSET
+ bl read_reg_rcpm
+ mov x7, x0
+
+ /* build an override mask for IPSTPCR4/IPSTPACK4/DEVDISR5 */
+ mov x5, xzr
+ ldr x6, =IPPDEXPCR_MASK2
+ and x6, x6, x7
+ cbz x6, 1f
+
+ /* x5 = override mask
+ * x6 = IPPDEXPCR bits for DEVDISR5
+ * x7 = IPPDEXPCR */
+
+ /* get the overrides */
+ orr x4, x5, #DEVDISR5_I2C_1
+ tst x6, #IPPDEXPCR_I2C1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR5_LPUART1
+ tst x6, #IPPDEXPCR_LPUART1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR5_FLX_TMR
+ tst x6, #IPPDEXPCR_FLX_TMR1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR5_OCRAM1
+ tst x6, #IPPDEXPCR_OCRAM1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR5_GPIO
+ tst x6, #IPPDEXPCR_GPIO1
+ csel x5, x5, x4, EQ
+1:
+ /* store the DEVDISR5 override mask */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ str w5, [x2, #DEVDISR5_MASK_OFFSET]
+
+ /* build an override mask for IPSTPCR1/IPSTPACK1/DEVDISR2 */
+ mov x5, xzr
+ ldr x6, =IPPDEXPCR_MASK1
+ and x6, x6, x7
+ cbz x6, 2f
+
+ /* x5 = override mask */
+ /* x6 = IPPDEXPCR bits for DEVDISR2 */
+
+ /* get the overrides */
+ orr x4, x5, #DEVDISR2_FMAN1_MAC1
+ tst x6, #IPPDEXPCR_MAC1_1
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC2
+ tst x6, #IPPDEXPCR_MAC1_2
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC3
+ tst x6, #IPPDEXPCR_MAC1_3
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC4
+ tst x6, #IPPDEXPCR_MAC1_4
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC5
+ tst x6, #IPPDEXPCR_MAC1_5
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC6
+ tst x6, #IPPDEXPCR_MAC1_6
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1_MAC9
+ tst x6, #IPPDEXPCR_MAC1_9
+ csel x5, x5, x4, EQ
+
+ orr x4, x5, #DEVDISR2_FMAN1
+ tst x6, #IPPDEXPCR_FM1
+ csel x5, x5, x4, EQ
+
+2:
+ /* store the DEVDISR2 override mask */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ str w5, [x2, #DEVDISR2_MASK_OFFSET]
+
+ /* x5 = DEVDISR2 override mask */
+
+ /* write IPSTPCR0 - no overrides */
+ ldr x0, =RCPM2_IPSTPCR0_OFFSET
+ ldr x1, =IPSTPCR0_VALUE
+ bl write_reg_rcpm2
+
+ /* x5 = DEVDISR2 override mask */
+
+ /* write IPSTPCR1 - overrides possible */
+ ldr x0, =RCPM2_IPSTPCR1_OFFSET
+ ldr x1, =IPSTPCR1_VALUE
+ bic x1, x1, x5
+ bl write_reg_rcpm2
+
+ /* write IPSTPCR2 - no overrides */
+ ldr x0, =RCPM2_IPSTPCR2_OFFSET
+ ldr x1, =IPSTPCR2_VALUE
+ bl write_reg_rcpm2
+
+ /* write IPSTPCR3 - no overrides */
+ ldr x0, =RCPM2_IPSTPCR3_OFFSET
+ ldr x1, =IPSTPCR3_VALUE
+ bl write_reg_rcpm2
+
+ /* write IPSTPCR4 - overrides possible */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ ldr w6, [x2, #DEVDISR5_MASK_OFFSET]
+ ldr x0, =RCPM2_IPSTPCR4_OFFSET
+ ldr x1, =IPSTPCR4_VALUE
+ bic x1, x1, x6
+ bl write_reg_rcpm2
+
+ /* x5 = DEVDISR2 override mask */
+ /* x6 = DEVDISR5 override mask */
+
+ /* poll on IPSTPACK0 */
+ ldr x3, =RCPM2_IPSTPACKR0_OFFSET
+ ldr x4, =IPSTPCR0_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+3:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 14f
+ sub x7, x7, #1
+ cbnz x7, 3b
+
+14:
+ /* poll on IPSTPACK1 */
+ ldr x3, =IPSTPCR1_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+ bic x4, x3, x5
+ ldr x3, =RCPM2_IPSTPACKR1_OFFSET
+4:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 15f
+ sub x7, x7, #1
+ cbnz x7, 4b
+
+15:
+ /* poll on IPSTPACK2 */
+ ldr x3, =RCPM2_IPSTPACKR2_OFFSET
+ ldr x4, =IPSTPCR2_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+5:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 16f
+ sub x7, x7, #1
+ cbnz x7, 5b
+
+16:
+ /* poll on IPSTPACK3 */
+ ldr x3, =RCPM2_IPSTPACKR3_OFFSET
+ ldr x4, =IPSTPCR3_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+6:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 17f
+ sub x7, x7, #1
+ cbnz x7, 6b
+
+17:
+ /* poll on IPSTPACK4 */
+ ldr x3, =IPSTPCR4_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+ bic x4, x3, x6
+ ldr x3, =RCPM2_IPSTPACKR4_OFFSET
+7:
+ mov x0, x3
+ bl read_reg_rcpm2
+ cmp x0, x4
+ b.eq 18f
+ sub x7, x7, #1
+ cbnz x7, 7b
+
+18:
+ ldr x7, =BC_PSCI_BASE
+ add x7, x7, #AUX_01_DATA
+
+ /* x5 = DEVDISR2 override mask
+ * x6 = DEVDISR5 override mask
+ * x7 = [soc_data_area] */
+
+ /* save DEVDISR1 and load new value */
+ mov x0, #DCFG_DEVDISR1_OFFSET
+ bl read_reg_dcfg
+ mov w13, w0
+ mov x0, #DCFG_DEVDISR1_OFFSET
+ ldr x1, =DEVDISR1_VALUE
+ bl write_reg_dcfg
+
+ /* save DEVDISR2 and load new value */
+ mov x0, #DCFG_DEVDISR2_OFFSET
+ bl read_reg_dcfg
+ mov w14, w0
+ mov x0, #DCFG_DEVDISR2_OFFSET
+ ldr x1, =DEVDISR2_VALUE
+ bic x1, x1, x5
+ bl write_reg_dcfg
+
+ /* x6 = DEVDISR5 override mask */
+ /* x7 = [soc_data_area] */
+
+ /* save DEVDISR3 and load new value */
+ mov x0, #DCFG_DEVDISR3_OFFSET
+ bl read_reg_dcfg
+ mov w15, w0
+ mov x0, #DCFG_DEVDISR3_OFFSET
+ ldr x1, =DEVDISR3_VALUE
+ bl write_reg_dcfg
+
+ /* save DEVDISR4 and load new value */
+ mov x0, #DCFG_DEVDISR4_OFFSET
+ bl read_reg_dcfg
+ mov w16, w0
+ mov x0, #DCFG_DEVDISR4_OFFSET
+ ldr x1, =DEVDISR4_VALUE
+ bl write_reg_dcfg
+
+ /* save DEVDISR5 and load new value */
+ mov x0, #DCFG_DEVDISR5_OFFSET
+ bl read_reg_dcfg
+ mov w17, w0
+ mov x0, #DCFG_DEVDISR5_OFFSET
+ ldr x1, =DEVDISR5_VALUE
+ bic x1, x1, x6
+ bl write_reg_dcfg
+
+ /* x7 = [soc_data_area] */
+
+ /* save cpuactlr and disable data prefetch */
+ mrs x0, CPUACTLR_EL1
+ str w0, [x7, #CPUACTLR_DATA_OFFSET]
+ bic x0, x0, #CPUACTLR_L1PCTL_MASK
+ msr CPUACTLR_EL1, x0
+
+ /* x6 = DEVDISR5 override mask */
+
+ /* setup registers for cache-only execution */
+ ldr x5, =IPSTPCR4_VALUE
+ bic x5, x5, x6
+ mov x6, #DDR_CNTRL_BASE_ADDR
+ mov x7, #DCSR_RCPM2_BASE
+ mov x8, #NXP_DCFG_ADDR
+ dsb sy
+ isb
+
+ /* set the DLL_LOCK cycle count */
+ ldr w1, [x6, #DDR_TIMING_CFG_4_OFFSET]
+ rev w2, w1
+ bic w2, w2, #DLL_LOCK_MASK
+ orr w2, w2, #DLL_LOCK_VALUE
+ rev w1, w2
+ str w1, [x6, #DDR_TIMING_CFG_4_OFFSET]
+
+ /*
+ * x5 = ipstpcr4 (IPSTPCR4_VALUE bic DEVDISR5_MASK)
+ * x6 = DDR_CNTRL_BASE_ADDR
+ * x7 = DCSR_RCPM2_BASE
+ * x8 = NXP_DCFG_ADDR
+ * w13 = DEVDISR1 saved value
+ * w14 = DEVDISR2 saved value
+ * w15 = DEVDISR3 saved value
+ * w16 = DEVDISR4 saved value
+ * w17 = DEVDISR5 saved value
+ */
+
+ /* enter the cache-only sequence */
+ mov x9, #CORE_RESTARTABLE
+ bl final_pwrdown
+
+ /* when we are here, the core has come out of wfi and the SoC is back up */
+
+ mov x30, x18
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_exit_pwrdn:
+ /* clear POWMGTDCR */
+ mov x1, #DCSR_RCPM2_BASE
+ str wzr, [x1, #RCPM2_POWMGTDCR_OFFSET]
+
+ /* clear WFIL2_EN in SCFG_COREPMCR */
+ mov x1, #NXP_SCFG_ADDR
+ str wzr, [x1, #SCFG_COREPMCR_OFFSET]
+
+ ret
+
+/*
+ * write a register in the SCFG block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2, x3
+ */
+write_reg_scfg:
+ ldr x2, =NXP_SCFG_ADDR
+ /* swap for BE */
+ rev w3, w1
+ str w3, [x2, x0]
+ ret
+/*
+ * read a register in the SCFG block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1, x2
+ */
+read_reg_scfg:
+ ldr x2, =NXP_SCFG_ADDR
+ ldr w1, [x2, x0]
+ /* swap for BE */
+ rev w0, w1
+ ret
+
+/*
+ * write a register in the DCFG block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2, x3
+ */
+write_reg_dcfg:
+ ldr x2, =NXP_DCFG_ADDR
+ /* swap for BE */
+ rev w3, w1
+ str w3, [x2, x0]
+ ret
+
+/*
+ * read a register in the DCFG block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1, x2
+ */
+read_reg_dcfg:
+ ldr x2, =NXP_DCFG_ADDR
+ ldr w1, [x2, x0]
+ /* swap for BE */
+ rev w0, w1
+ ret
+
+/*
+ * write a register in the RCPM block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2, x3
+ */
+write_reg_rcpm:
+ ldr x2, =NXP_RCPM_ADDR
+ /* swap for BE */
+ rev w3, w1
+ str w3, [x2, x0]
+ ret
+
+/*
+ * read a register in the RCPM block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1, x2
+ */
+read_reg_rcpm:
+ ldr x2, =NXP_RCPM_ADDR
+ ldr w1, [x2, x0]
+ /* swap for BE */
+ rev w0, w1
+ ret
+
+/*
+ * write a register in the DCSR-RCPM2 block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2, x3
+ */
+write_reg_rcpm2:
+ ldr x2, =DCSR_RCPM2_BASE
+ /* swap for BE */
+ rev w3, w1
+ str w3, [x2, x0]
+ ret
+
+/*
+ * read a register in the DCSR-RCPM2 block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1, x2
+ */
+read_reg_rcpm2:
+ ldr x2, =DCSR_RCPM2_BASE
+ ldr w1, [x2, x0]
+ /* swap for BE */
+ rev w0, w1
+ ret
+
+/*
+ * this function returns the base address of the gic distributor
+ * in: none
+ * out: x0 = base address of gic distributor
+ * uses x0, x1
+ */
+_getGICD_BaseAddr:
+ /* read SVR and get the SoC version */
+ mov x0, #NXP_DCFG_ADDR
+ ldr w1, [x0, #DCFG_SVR_OFFSET]
+ rev w0, w1
+
+ /* x0 = svr */
+ and w0, w0, #SVR_MIN_VER_MASK
+ cmp w0, #SVR_MINOR_VER_0
+ b.ne 8f
+
+ /* load the gic base addresses for rev 1.0 parts */
+ ldr x0, =NXP_GICD_4K_ADDR
+ b 10f
+8:
+ /* for rev 1.1 and later parts, the GIC base addresses */
+ /* can be at 4k or 64k offsets */
+
+ /* read the scfg reg GIC400_ADDR_ALIGN */
+ mov x0, #NXP_SCFG_ADDR
+ ldr w1, [x0, #SCFG_GIC400_ADDR_ALIGN_OFFSET]
+ rev w0, w1
+
+ /* x0 = GIC400_ADDR_ALIGN value */
+ and x0, x0, #SCFG_GIC400_ADDR_ALIGN_4KMODE_MASK
+ mov x1, #SCFG_GIC400_ADDR_ALIGN_4KMODE_EN
+ cmp x0, x1
+ b.ne 9f
+
+ /* load the base addresses for 4k offsets */
+ ldr x0, =NXP_GICD_4K_ADDR
+ b 10f
+9:
+ /* load the base address for 64k offsets */
+ ldr x0, =NXP_GICD_64K_ADDR
+10:
+ ret
+
+/*
+ * this function returns the base address of the gic distributor
+ * in: none
+ * out: x0 = base address of gic controller
+ * uses x0, x1
+ */
+_getGICC_BaseAddr:
+ /* read SVR and get the SoC version */
+ mov x0, #NXP_DCFG_ADDR
+ ldr w1, [x0, #DCFG_SVR_OFFSET]
+ rev w0, w1
+
+ /* x0 = svr */
+ and w0, w0, #SVR_MIN_VER_MASK
+ cmp w0, #SVR_MINOR_VER_0
+ b.ne 8f
+
+ /* load the gic base addresses for rev 1.0 parts */
+ ldr x0, =NXP_GICC_4K_ADDR
+ b 10f
+8:
+ /* for rev 1.1 and later parts, the GIC base addresses */
+ /* can be at 4k or 64k offsets */
+
+ /* read the scfg reg GIC400_ADDR_ALIGN */
+ mov x0, #NXP_SCFG_ADDR
+ ldr w1, [x0, #SCFG_GIC400_ADDR_ALIGN_OFFSET]
+ rev w0, w1
+
+ /* x0 = GIC400_ADDR_ALIGN value */
+ and x0, x0, #SCFG_GIC400_ADDR_ALIGN_4KMODE_MASK
+ mov x1, #SCFG_GIC400_ADDR_ALIGN_4KMODE_EN
+ cmp x0, x1
+ b.ne 9f
+
+ /* load the base addresses for 4k offsets */
+ ldr x0, =NXP_GICC_4K_ADDR
+ b 10f
+9:
+ /* load the base address for 64k offsets */
+ ldr x0, =NXP_GICC_64K_ADDR
+10:
+ ret
+
+/*
+ * this function will pwrdown ddr and the final core - it will do this
+ * by loading itself into the icache and then executing from there
+ * in: x5 = ipstpcr4 (IPSTPCR4_VALUE bic DEVDISR5_MASK)
+ * x6 = DDR_CNTRL_BASE_ADDR
+ * x7 = DCSR_RCPM2_BASE
+ * x8 = NXP_DCFG_ADDR
+ * x9 = 0, restartable
+ * = 1, non-restartable
+ * w13 = DEVDISR1 saved value
+ * w14 = DEVDISR2 saved value
+ * w15 = DEVDISR3 saved value
+ * w16 = DEVDISR4 saved value
+ * w17 = DEVDISR5 saved value
+ * out: none
+ * uses x0 ~ x9
+ */
+
+/* 4Kb aligned */
+.align 12
+final_pwrdown:
+ mov x0, xzr
+ b touch_line_0
+start_line_0:
+ mov x0, #1
+ mov x2, #DDR_SDRAM_CFG_2_FRCSR /* put ddr in self refresh - start */
+ ldr w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ rev w4, w3
+ orr w4, w4, w2
+ rev w3, w4
+ str w3, [x6, #DDR_SDRAM_CFG_2_OFFSET] /* put ddr in self refresh - end */
+ orr w3, w5, #DEVDISR5_MEM /* quiesce ddr clocks - start */
+ rev w4, w3
+ str w4, [x7, #RCPM2_IPSTPCR4_OFFSET] /* quiesce ddr clocks - end */
+
+ mov w3, #DEVDISR5_MEM
+ rev w3, w3 /* polling mask */
+ mov x2, #DDR_SLEEP_RETRY_CNT /* poll on ipstpack4 - start */
+touch_line_0:
+ cbz x0, touch_line_1
+
+start_line_1:
+ ldr w1, [x7, #RCPM2_IPSTPACKR4_OFFSET]
+ tst w1, w3
+ b.ne 1f
+ subs x2, x2, #1
+ b.gt start_line_1 /* poll on ipstpack4 - end */
+
+ /* if we get here, we have a timeout err */
+ rev w4, w5
+ str w4, [x7, #RCPM2_IPSTPCR4_OFFSET] /* re-enable ddr clks interface */
+ mov x0, #ERROR_DDR_SLEEP /* load error code */
+ b 2f
+1:
+ str w4, [x8, #DCFG_DEVDISR5_OFFSET] /* disable ddr cntrlr clk in devdisr5 */
+5:
+ wfi /* stop the final core */
+
+ cbnz x9, 5b /* if non-restartable, keep in wfi */
+ rev w4, w5
+ str w4, [x8, #DCFG_DEVDISR5_OFFSET] /* re-enable ddr in devdisr5 */
+ str w4, [x7, #RCPM2_IPSTPCR4_OFFSET] /* re-enable ddr clk in ipstpcr4 */
+touch_line_1:
+ cbz x0, touch_line_2
+
+start_line_2:
+ ldr w1, [x7, #RCPM2_IPSTPACKR4_OFFSET] /* poll on ipstpack4 - start */
+ tst w1, w3
+ b.eq 2f
+ nop
+ b start_line_2 /* poll on ipstpack4 - end */
+2:
+ mov x2, #DDR_SDRAM_CFG_2_FRCSR /* take ddr out-of self refresh - start */
+ ldr w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ rev w4, w3
+ bic w4, w4, w2
+ rev w3, w4
+ mov x1, #DDR_SLEEP_RETRY_CNT /* wait for ddr cntrlr clock - start */
+3:
+ subs x1, x1, #1
+ b.gt 3b /* wait for ddr cntrlr clock - end */
+ str w3, [x6, #DDR_SDRAM_CFG_2_OFFSET] /* take ddr out-of self refresh - end */
+ rev w1, w17
+touch_line_2:
+ cbz x0, touch_line_3
+
+start_line_3:
+ str w1, [x8, #DCFG_DEVDISR5_OFFSET] /* reset devdisr5 */
+ rev w1, w16
+ str w1, [x8, #DCFG_DEVDISR4_OFFSET] /* reset devdisr4 */
+ rev w1, w15
+ str w1, [x8, #DCFG_DEVDISR3_OFFSET] /* reset devdisr3 */
+ rev w1, w14
+ str w1, [x8, #DCFG_DEVDISR2_OFFSET] /* reset devdisr2 */
+ rev w1, w13
+ str w1, [x8, #DCFG_DEVDISR1_OFFSET] /* reset devdisr1 */
+ str wzr, [x7, #RCPM2_IPSTPCR4_OFFSET] /* reset ipstpcr4 */
+ str wzr, [x7, #RCPM2_IPSTPCR3_OFFSET] /* reset ipstpcr3 */
+ str wzr, [x7, #RCPM2_IPSTPCR2_OFFSET] /* reset ipstpcr2 */
+ str wzr, [x7, #RCPM2_IPSTPCR1_OFFSET] /* reset ipstpcr1 */
+ str wzr, [x7, #RCPM2_IPSTPCR0_OFFSET] /* reset ipstpcr0 */
+ b continue_restart
+touch_line_3:
+ cbz x0, start_line_0
+
+/* execute here after ddr is back up */
+continue_restart:
+ /*
+ * if x0 = 1, all is well
+ * if x0 < 1, we had an error
+ */
+ cmp x0, #1
+ b.ne 4f
+ mov x0, #0
+4:
+ ret
+
+/*
+ * Note: there is no return from this function
+ * this function will shutdown ddr and the final core - it will do this
+ * by loading itself into the icache and then executing from there
+ * in: x5 = ipstpcr4 (IPSTPCR4_VALUE bic DEVDISR5_MASK)
+ * x6 = DDR_CNTRL_BASE_ADDR
+ * x7 = DCSR_RCPM2_BASE
+ * x8 = NXP_DCFG_ADDR
+ * out: none
+ * uses x0 ~ x8
+ */
+
+/* 4Kb aligned */
+.align 12
+final_shutdown:
+
+ mov x0, xzr
+ b touch_line0
+start_line0:
+ mov x0, #1
+ mov x2, #DDR_SDRAM_CFG_2_FRCSR /* put ddr in self refresh - start */
+ ldr w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ rev w4, w3
+ orr w4, w4, w2
+ rev w3, w4
+ str w3, [x6, #DDR_SDRAM_CFG_2_OFFSET] /* put ddr in self refresh - end */
+ orr w3, w5, #DEVDISR5_MEM /* quiesce ddr clocks - start */
+ rev w4, w3
+ str w4, [x7, #RCPM2_IPSTPCR4_OFFSET] /* quiesce ddr clocks - end */
+
+ mov w3, #DEVDISR5_MEM
+ rev w3, w3 /* polling mask */
+ mov x2, #DDR_SLEEP_RETRY_CNT /* poll on ipstpack4 - start */
+touch_line0:
+ cbz x0, touch_line1
+
+start_line1:
+ ldr w1, [x7, #RCPM2_IPSTPACKR4_OFFSET]
+ tst w1, w3
+ b.ne 1f
+ subs x2, x2, #1
+ b.gt start_line1 /* poll on ipstpack4 - end */
+ nop
+ nop
+ nop
+ nop
+1:
+ str w4, [x8, #DCFG_DEVDISR5_OFFSET] /* disable ddr cntrlr clk in devdisr5 */
+5:
+ wfi /* stop the final core */
+ b 5b /* stay here until POR */
+ nop
+ nop
+ nop
+touch_line1:
+ cbz x0, start_line0
diff --git a/plat/nxp/soc-ls1043a/aarch64/ls1043a_helpers.S b/plat/nxp/soc-ls1043a/aarch64/ls1043a_helpers.S
new file mode 100644
index 0000000..bc88886
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/aarch64/ls1043a_helpers.S
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+ .globl plat_secondary_cold_boot_setup
+ .globl plat_is_my_cpu_primary
+ .globl plat_reset_handler
+ .globl platform_mem_init
+
+func platform_mem1_init
+ ret
+endfunc platform_mem1_init
+
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+func apply_platform_errata
+ ret
+endfunc apply_platform_errata
+
+func plat_reset_handler
+ mov x29, x30
+ bl apply_platform_errata
+
+#if defined(IMAGE_BL31)
+ ldr x0, =POLICY_SMMU_PAGESZ_64K
+ cbz x0, 1f
+ /* Set the SMMU page size in the sACR register */
+ bl _set_smmu_pagesz_64
+#endif
+1:
+ mov x30, x29
+ ret
+endfunc plat_reset_handler
+
+/*
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ */
+func plat_secondary_cold_boot_setup
+ /* ls1043a does not do cold boot for secondary CPU */
+cb_panic:
+ b cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+/*
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu.
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, 0x0
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
diff --git a/plat/nxp/soc-ls1043a/include/ns_access.h b/plat/nxp/soc-ls1043a/include/ns_access.h
new file mode 100644
index 0000000..423c454
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/include/ns_access.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2015, 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018, 2020-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NS_ACCESS_H
+#define NS_ACCESS_H
+
+#include <csu.h>
+
+enum csu_cslx_ind {
+ CSU_CSLX_PCIE2_IO = 0,
+ CSU_CSLX_PCIE1_IO,
+ CSU_CSLX_MG2TPR_IP,
+ CSU_CSLX_IFC_MEM,
+ CSU_CSLX_OCRAM,
+ CSU_CSLX_GIC,
+ CSU_CSLX_PCIE1,
+ CSU_CSLX_OCRAM2,
+ CSU_CSLX_QSPI_MEM,
+ CSU_CSLX_PCIE2,
+ CSU_CSLX_SATA,
+ CSU_CSLX_USB1,
+ CSU_CSLX_QM_BM_SWPORTAL,
+ CSU_CSLX_PCIE3 = 16,
+ CSU_CSLX_PCIE3_IO,
+ CSU_CSLX_USB3 = 20,
+ CSU_CSLX_USB2,
+ CSU_CSLX_PFE = 23,
+ CSU_CSLX_SERDES = 32,
+ CSU_CSLX_QDMA,
+ CSU_CSLX_LPUART2,
+ CSU_CSLX_LPUART1,
+ CSU_CSLX_LPUART4,
+ CSU_CSLX_LPUART3,
+ CSU_CSLX_LPUART6,
+ CSU_CSLX_LPUART5,
+ CSU_CSLX_DSPI1 = 41,
+ CSU_CSLX_QSPI,
+ CSU_CSLX_ESDHC,
+ CSU_CSLX_IFC = 45,
+ CSU_CSLX_I2C1,
+ CSU_CSLX_USB_2,
+ CSU_CSLX_I2C3 = 48,
+ CSU_CSLX_I2C2,
+ CSU_CSLX_DUART2 = 50,
+ CSU_CSLX_DUART1,
+ CSU_CSLX_WDT2,
+ CSU_CSLX_WDT1,
+ CSU_CSLX_EDMA,
+ CSU_CSLX_SYS_CNT,
+ CSU_CSLX_DMA_MUX2,
+ CSU_CSLX_DMA_MUX1,
+ CSU_CSLX_DDR,
+ CSU_CSLX_QUICC,
+ CSU_CSLX_DCFG_CCU_RCPM = 60,
+ CSU_CSLX_SECURE_BOOTROM,
+ CSU_CSLX_SFP,
+ CSU_CSLX_TMU,
+ CSU_CSLX_SECURE_MONITOR,
+ CSU_CSLX_SCFG,
+ CSU_CSLX_FM = 66,
+ CSU_CSLX_SEC5_5,
+ CSU_CSLX_BM,
+ CSU_CSLX_QM,
+ CSU_CSLX_GPIO2 = 70,
+ CSU_CSLX_GPIO1,
+ CSU_CSLX_GPIO4,
+ CSU_CSLX_GPIO3,
+ CSU_CSLX_PLATFORM_CONT,
+ CSU_CSLX_CSU,
+ CSU_CSLX_IIC4 = 77,
+ CSU_CSLX_WDT4,
+ CSU_CSLX_WDT3,
+ CSU_CSLX_ESDHC2 = 80,
+ CSU_CSLX_WDT5 = 81,
+ CSU_CSLX_SAI2,
+ CSU_CSLX_SAI1,
+ CSU_CSLX_SAI4,
+ CSU_CSLX_SAI3,
+ CSU_CSLX_FTM2 = 86,
+ CSU_CSLX_FTM1,
+ CSU_CSLX_FTM4,
+ CSU_CSLX_FTM3,
+ CSU_CSLX_FTM6 = 90,
+ CSU_CSLX_FTM5,
+ CSU_CSLX_FTM8,
+ CSU_CSLX_FTM7,
+ CSU_CSLX_DSCR = 121,
+};
+
+struct csu_ns_dev_st ns_dev[] = {
+ {CSU_CSLX_PCIE2_IO, CSU_ALL_RW},
+ {CSU_CSLX_PCIE1_IO, CSU_ALL_RW},
+ {CSU_CSLX_MG2TPR_IP, CSU_ALL_RW},
+ {CSU_CSLX_IFC_MEM, CSU_ALL_RW},
+ {CSU_CSLX_OCRAM, CSU_S_SUP_RW},
+ {CSU_CSLX_GIC, CSU_ALL_RW},
+ {CSU_CSLX_PCIE1, CSU_ALL_RW},
+ {CSU_CSLX_OCRAM2, CSU_S_SUP_RW},
+ {CSU_CSLX_QSPI_MEM, CSU_ALL_RW},
+ {CSU_CSLX_PCIE2, CSU_ALL_RW},
+ {CSU_CSLX_SATA, CSU_ALL_RW},
+ {CSU_CSLX_USB1, CSU_ALL_RW},
+ {CSU_CSLX_QM_BM_SWPORTAL, CSU_ALL_RW},
+ {CSU_CSLX_PCIE3, CSU_ALL_RW},
+ {CSU_CSLX_PCIE3_IO, CSU_ALL_RW},
+ {CSU_CSLX_USB3, CSU_ALL_RW},
+ {CSU_CSLX_USB2, CSU_ALL_RW},
+ {CSU_CSLX_PFE, CSU_ALL_RW},
+ {CSU_CSLX_SERDES, CSU_ALL_RW},
+ {CSU_CSLX_QDMA, CSU_ALL_RW},
+ {CSU_CSLX_LPUART2, CSU_ALL_RW},
+ {CSU_CSLX_LPUART1, CSU_ALL_RW},
+ {CSU_CSLX_LPUART4, CSU_ALL_RW},
+ {CSU_CSLX_LPUART3, CSU_ALL_RW},
+ {CSU_CSLX_LPUART6, CSU_ALL_RW},
+ {CSU_CSLX_LPUART5, CSU_ALL_RW},
+ {CSU_CSLX_DSPI1, CSU_ALL_RW},
+ {CSU_CSLX_QSPI, CSU_ALL_RW},
+ {CSU_CSLX_ESDHC, CSU_ALL_RW},
+ {CSU_CSLX_IFC, CSU_ALL_RW},
+ {CSU_CSLX_I2C1, CSU_ALL_RW},
+ {CSU_CSLX_USB_2, CSU_ALL_RW},
+ {CSU_CSLX_I2C3, CSU_ALL_RW},
+ {CSU_CSLX_I2C2, CSU_ALL_RW},
+ {CSU_CSLX_DUART2, CSU_ALL_RW},
+ {CSU_CSLX_DUART1, CSU_ALL_RW},
+ {CSU_CSLX_WDT2, CSU_ALL_RW},
+ {CSU_CSLX_WDT1, CSU_ALL_RW},
+ {CSU_CSLX_EDMA, CSU_ALL_RW},
+ {CSU_CSLX_SYS_CNT, CSU_ALL_RW},
+ {CSU_CSLX_DMA_MUX2, CSU_ALL_RW},
+ {CSU_CSLX_DMA_MUX1, CSU_ALL_RW},
+ {CSU_CSLX_DDR, CSU_ALL_RW},
+ {CSU_CSLX_QUICC, CSU_ALL_RW},
+ {CSU_CSLX_DCFG_CCU_RCPM, CSU_ALL_RW},
+ {CSU_CSLX_SECURE_BOOTROM, CSU_ALL_RW},
+ {CSU_CSLX_SFP, CSU_ALL_RW},
+ {CSU_CSLX_TMU, CSU_ALL_RW},
+ {CSU_CSLX_SECURE_MONITOR, CSU_ALL_RW},
+ {CSU_CSLX_SCFG, CSU_ALL_RW},
+ {CSU_CSLX_FM, CSU_ALL_RW},
+ {CSU_CSLX_SEC5_5, CSU_ALL_RW},
+ {CSU_CSLX_BM, CSU_ALL_RW},
+ {CSU_CSLX_QM, CSU_ALL_RW},
+ {CSU_CSLX_GPIO2, CSU_ALL_RW},
+ {CSU_CSLX_GPIO1, CSU_ALL_RW},
+ {CSU_CSLX_GPIO4, CSU_ALL_RW},
+ {CSU_CSLX_GPIO3, CSU_ALL_RW},
+ {CSU_CSLX_PLATFORM_CONT, CSU_ALL_RW},
+ {CSU_CSLX_CSU, CSU_ALL_RW},
+ {CSU_CSLX_IIC4, CSU_ALL_RW},
+ {CSU_CSLX_WDT4, CSU_ALL_RW},
+ {CSU_CSLX_WDT3, CSU_ALL_RW},
+ {CSU_CSLX_ESDHC2, CSU_ALL_RW},
+ {CSU_CSLX_WDT5, CSU_ALL_RW},
+ {CSU_CSLX_SAI2, CSU_ALL_RW},
+ {CSU_CSLX_SAI1, CSU_ALL_RW},
+ {CSU_CSLX_SAI4, CSU_ALL_RW},
+ {CSU_CSLX_SAI3, CSU_ALL_RW},
+ {CSU_CSLX_FTM2, CSU_ALL_RW},
+ {CSU_CSLX_FTM1, CSU_ALL_RW},
+ {CSU_CSLX_FTM4, CSU_ALL_RW},
+ {CSU_CSLX_FTM3, CSU_ALL_RW},
+ {CSU_CSLX_FTM6, CSU_ALL_RW},
+ {CSU_CSLX_FTM5, CSU_ALL_RW},
+ {CSU_CSLX_FTM8, CSU_ALL_RW},
+ {CSU_CSLX_FTM7, CSU_ALL_RW},
+ {CSU_CSLX_DSCR, CSU_ALL_RW},
+};
+
+#endif /* NS_ACCESS_H */
diff --git a/plat/nxp/soc-ls1043a/include/soc.h b/plat/nxp/soc-ls1043a/include/soc.h
new file mode 100644
index 0000000..e018102
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/include/soc.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2017-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOC_H
+#define SOC_H
+
+/* Chassis specific defines - common across SoC's of a particular platform */
+#include "dcfg_lsch2.h"
+#include "soc_default_base_addr.h"
+#include "soc_default_helper_macros.h"
+
+/* DDR Regions Info */
+#define NUM_DRAM_REGIONS 3
+#define NXP_DRAM0_ADDR 0x80000000
+#define NXP_DRAM0_MAX_SIZE 0x80000000 /* 2 GB */
+
+#define NXP_DRAM1_ADDR 0x880000000
+#define NXP_DRAM1_MAX_SIZE 0x780000000 /* 30 GB */
+
+#define NXP_DRAM2_ADDR 0x8800000000
+#define NXP_DRAM2_MAX_SIZE 0x7800000000 /* 480 GB */
+/* DRAM0 Size defined in platform_def.h */
+#define NXP_DRAM0_SIZE PLAT_DEF_DRAM0_SIZE
+
+/*
+ * P23: 23 x 23 package
+ * A: without security
+ * AE: with security
+ * SVR Definition (not include major and minor rev)
+ */
+#define SVR_LS1023A 0x879209
+#define SVR_LS1023AE 0x879208
+#define SVR_LS1023A_P23 0x87920B
+#define SVR_LS1023AE_P23 0x87920A
+#define SVR_LS1043A 0x879201
+#define SVR_LS1043AE 0x879200
+#define SVR_LS1043A_P23 0x879203
+#define SVR_LS1043AE_P23 0x879202
+
+/* Number of cores in platform */
+#define PLATFORM_CORE_COUNT 4
+#define NUMBER_OF_CLUSTERS 1
+#define CORES_PER_CLUSTER 4
+
+/* set to 0 if the clusters are not symmetrical */
+#define SYMMETRICAL_CLUSTERS 1
+
+/*
+ * Required LS standard platform porting definitions
+ * for CCI-400
+ */
+#define NXP_CCI_CLUSTER0_SL_IFACE_IX 4
+
+/* ls1043 version info for GIC configuration */
+#define REV1_0 0x10
+#define REV1_1 0x11
+#define GIC_ADDR_BIT 31
+
+/* Errata */
+#define NXP_ERRATUM_A009663
+#define NXP_ERRATUM_A009942
+
+#define NUM_OF_DDRC 1
+
+/* Defines required for using XLAT tables from ARM common code */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 40)
+
+/* Clock Divisors */
+#define NXP_PLATFORM_CLK_DIVIDER 1
+#define NXP_UART_CLK_DIVIDER 1
+
+/*
+ * Set this switch to 1 if you need to keep the debug block
+ * clocked during system power-down.
+ */
+#define DEBUG_ACTIVE 0
+
+#define IPPDEXPCR_MAC1_1 0x80000000 // DEVDISR2_FMAN1_MAC1
+#define IPPDEXPCR_MAC1_2 0x40000000 // DEVDISR2_FMAN1_MAC2
+#define IPPDEXPCR_MAC1_3 0x20000000 // DEVDISR2_FMAN1_MAC3
+#define IPPDEXPCR_MAC1_4 0x10000000 // DEVDISR2_FMAN1_MAC4
+#define IPPDEXPCR_MAC1_5 0x08000000 // DEVDISR2_FMAN1_MAC5
+#define IPPDEXPCR_MAC1_6 0x04000000 // DEVDISR2_FMAN1_MAC6
+#define IPPDEXPCR_MAC1_9 0x00800000 // DEVDISR2_FMAN1_MAC9
+#define IPPDEXPCR_I2C1 0x00080000 // DEVDISR5_I2C_1
+#define IPPDEXPCR_LPUART1 0x00040000 // DEVDISR5_LPUART1
+#define IPPDEXPCR_FLX_TMR1 0x00020000 // DEVDISR5_FLX_TMR
+#define IPPDEXPCR_OCRAM1 0x00010000 // DEVDISR5_OCRAM1
+#define IPPDEXPCR_GPIO1 0x00000040 // DEVDISR5_GPIO
+#define IPPDEXPCR_FM1 0x00000008 // DEVDISR2_FMAN1
+
+#define IPPDEXPCR_MASK1 0xFC800008 // overrides for DEVDISR2
+#define IPPDEXPCR_MASK2 0x000F0040 // overriddes for DEVDISR5
+
+#define IPSTPCR0_VALUE 0xA000C201
+#define IPSTPCR1_VALUE 0x00000080
+#define IPSTPCR2_VALUE 0x000C0000
+#define IPSTPCR3_VALUE 0x38000000
+#if (DEBUG_ACTIVE)
+ #define IPSTPCR4_VALUE 0x10833BFC
+#else
+ #define IPSTPCR4_VALUE 0x10A33BFC
+#endif
+
+#define DEVDISR1_QE 0x00000001
+#define DEVDISR1_SEC 0x00000200
+#define DEVDISR1_USB1 0x00004000
+#define DEVDISR1_SATA 0x00008000
+#define DEVDISR1_USB2 0x00010000
+#define DEVDISR1_USB3 0x00020000
+#define DEVDISR1_DMA2 0x00400000
+#define DEVDISR1_DMA1 0x00800000
+#define DEVDISR1_ESDHC 0x20000000
+#define DEVDISR1_PBL 0x80000000
+
+#define DEVDISR2_FMAN1 0x00000080
+#define DEVDISR2_FMAN1_MAC9 0x00800000
+#define DEVDISR2_FMAN1_MAC6 0x04000000
+#define DEVDISR2_FMAN1_MAC5 0x08000000
+#define DEVDISR2_FMAN1_MAC4 0x10000000
+#define DEVDISR2_FMAN1_MAC3 0x20000000
+#define DEVDISR2_FMAN1_MAC2 0x40000000
+#define DEVDISR2_FMAN1_MAC1 0x80000000
+
+#define DEVDISR3_BMAN 0x00040000
+#define DEVDISR3_QMAN 0x00080000
+#define DEVDISR3_PEX3 0x20000000
+#define DEVDISR3_PEX2 0x40000000
+#define DEVDISR3_PEX1 0x80000000
+
+#define DEVDISR4_QSPI 0x08000000
+#define DEVDISR4_DUART2 0x10000000
+#define DEVDISR4_DUART1 0x20000000
+
+#define DEVDISR5_ICMMU 0x00000001
+#define DEVDISR5_I2C_1 0x00000002
+#define DEVDISR5_I2C_2 0x00000004
+#define DEVDISR5_I2C_3 0x00000008
+#define DEVDISR5_I2C_4 0x00000010
+#define DEVDISR5_WDG_5 0x00000020
+#define DEVDISR5_WDG_4 0x00000040
+#define DEVDISR5_WDG_3 0x00000080
+#define DEVDISR5_DSPI1 0x00000100
+#define DEVDISR5_WDG_2 0x00000200
+#define DEVDISR5_FLX_TMR 0x00000400
+#define DEVDISR5_WDG_1 0x00000800
+#define DEVDISR5_LPUART6 0x00001000
+#define DEVDISR5_LPUART5 0x00002000
+#define DEVDISR5_LPUART3 0x00008000
+#define DEVDISR5_LPUART2 0x00010000
+#define DEVDISR5_LPUART1 0x00020000
+#define DEVDISR5_DBG 0x00200000
+#define DEVDISR5_GPIO 0x00400000
+#define DEVDISR5_IFC 0x00800000
+#define DEVDISR5_OCRAM2 0x01000000
+#define DEVDISR5_OCRAM1 0x02000000
+#define DEVDISR5_LPUART4 0x10000000
+#define DEVDISR5_DDR 0x80000000
+#define DEVDISR5_MEM 0x80000000
+
+#define DEVDISR1_VALUE 0xA0C3C201
+#define DEVDISR2_VALUE 0xCC0C0080
+#define DEVDISR3_VALUE 0xE00C0000
+#define DEVDISR4_VALUE 0x38000000
+#if (DEBUG_ACTIVE)
+ #define DEVDISR5_VALUE 0x10833BFC
+#else
+ #define DEVDISR5_VALUE 0x10A33BFC
+#endif
+
+/*
+ * PWR mgmt features supported in the soc-specific code:
+ * value == 0x0 the soc code does not support this feature
+ * value != 0x0 the soc code supports this feature
+ */
+#define SOC_CORE_RELEASE 0x1
+#define SOC_CORE_RESTART 0x1
+#define SOC_CORE_OFF 0x1
+#define SOC_CORE_STANDBY 0x1
+#define SOC_CORE_PWR_DWN 0x1
+#define SOC_CLUSTER_STANDBY 0x1
+#define SOC_CLUSTER_PWR_DWN 0x1
+#define SOC_SYSTEM_STANDBY 0x1
+#define SOC_SYSTEM_PWR_DWN 0x1
+#define SOC_SYSTEM_OFF 0x1
+#define SOC_SYSTEM_RESET 0x1
+
+/* PSCI-specific defines */
+#define SYSTEM_PWR_DOMAINS 1
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
+ NUMBER_OF_CLUSTERS + \
+ SYSTEM_PWR_DOMAINS)
+
+/* Power state coordination occurs at the system level */
+#define PLAT_PD_COORD_LVL MPIDR_AFFLVL2
+#define PLAT_MAX_PWR_LVL PLAT_PD_COORD_LVL
+
+/* Local power state for power domains in Run state */
+#define LS_LOCAL_STATE_RUN PSCI_LOCAL_STATE_RUN
+
+/* define retention state */
+#define PLAT_MAX_RET_STATE (PSCI_LOCAL_STATE_RUN + 1)
+#define LS_LOCAL_STATE_RET PLAT_MAX_RET_STATE
+
+/* define power-down state */
+#define PLAT_MAX_OFF_STATE (PLAT_MAX_RET_STATE + 1)
+#define LS_LOCAL_STATE_OFF PLAT_MAX_OFF_STATE
+
+/*
+ * 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.
+ * CACHE_WRITEBACK_GRANULE is defined in soc.def
+ */
+
+/* One cache line needed for bakery locks on ARM platforms */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
+
+#ifndef __ASSEMBLER__
+/* CCI slave interfaces */
+static const int cci_map[] = {
+ NXP_CCI_CLUSTER0_SL_IFACE_IX,
+};
+void soc_init_lowlevel(void);
+void soc_init_percpu(void);
+void _soc_set_start_addr(unsigned long addr);
+
+#endif
+
+#endif /* SOC_H */
diff --git a/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c b/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c
new file mode 100644
index 0000000..28e2dab
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/ls1043ardb/ddr_init.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <lib/utils.h>
+
+#include <errata.h>
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+const struct ddr_cfg_regs static_1600 = {
+ .cs[0].config = U(0x80040322),
+ .cs[0].bnds = U(0x7F),
+ .sdram_cfg[0] = U(0xC50C0000),
+ .sdram_cfg[1] = U(0x401100),
+ .timing_cfg[0] = U(0x91550018),
+ .timing_cfg[1] = U(0xBBB48C42),
+ .timing_cfg[2] = U(0x48C111),
+ .timing_cfg[3] = U(0x10C1000),
+ .timing_cfg[4] = U(0x2),
+ .timing_cfg[5] = U(0x3401400),
+ .timing_cfg[7] = U(0x13300000),
+ .timing_cfg[8] = U(0x2115600),
+ .sdram_mode[0] = U(0x3010210),
+ .sdram_mode[9] = U(0x4000000),
+ .sdram_mode[8] = U(0x500),
+ .sdram_mode[2] = U(0x10210),
+ .sdram_mode[10] = U(0x400),
+ .sdram_mode[11] = U(0x4000000),
+ .sdram_mode[4] = U(0x10210),
+ .sdram_mode[12] = U(0x400),
+ .sdram_mode[13] = U(0x4000000),
+ .sdram_mode[6] = U(0x10210),
+ .sdram_mode[14] = U(0x400),
+ .sdram_mode[15] = U(0x4000000),
+ .interval = U(0x18600618),
+ .zq_cntl = U(0x8A090705),
+ .clk_cntl = U(0x3000000),
+ .cdr[0] = U(0x80040000),
+ .cdr[1] = U(0xA181),
+ .wrlvl_cntl[0] = U(0x8675F607),
+ .wrlvl_cntl[1] = U(0x7090807,
+ .wrlvl_cntl[2] = U(0x7070707),
+ .debug[28] = U(0x00700046),
+};
+
+uint64_t board_static_ddr(struct ddr_info *priv)
+{
+ memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600));
+
+ return ULL(0x80000000);
+}
+
+#else
+static const struct rc_timing rcz[] = {
+ {1600, 12, 7},
+ {}
+};
+
+static const struct board_timing ram[] = {
+ {0x1f, rcz, 0x00020100, 0},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ ret = cal_board_params(priv, ram, ARRAY_SIZE(ram));
+ if (ret)
+ return ret;
+
+ popts->cpo_sample = U(0x46);
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
+ DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */
+
+ return 0;
+}
+
+/* DDR model number: MT40A1G8SA-062E:R */
+struct dimm_params ddr_raw_timing = {
+ .n_ranks = U(1),
+ .rank_density = ULL(2147483648),
+ .capacity = ULL(2147483648),
+ .primary_sdram_width = U(32),
+ .ec_sdram_width = U(4),
+ .rdimm = U(0),
+ .mirrored_dimm = U(0),
+ .n_row_addr = U(16),
+ .n_col_addr = U(10),
+ .bank_group_bits = U(2),
+ .edc_config = U(2),
+ .burst_lengths_bitmask = U(0x0c),
+ .tckmin_x_ps = 625,
+ .tckmax_ps = 2200,
+ .caslat_x = U(0x0001FFE00),
+ .taa_ps = 13500,
+ .trcd_ps = 13500,
+ .trp_ps = 13500,
+ .tras_ps = 32000,
+ .trc_ps = 45500,
+ .twr_ps = 15000,
+ .trfc1_ps = 350000,
+ .trfc2_ps = 260000,
+ .trfc4_ps = 160000,
+ .tfaw_ps = 21000,
+ .trrds_ps = 3000,
+ .trrdl_ps = 4900,
+ .tccdl_ps = 5000,
+ .refresh_rate_ps = U(7800000),
+ .rc = U(0x1f),
+};
+
+int ddr_get_ddr_params(struct dimm_params *pdimm,
+ struct ddr_conf *conf)
+{
+ static const char dimm_model[] = "Fixed DDR on board";
+
+ conf->dimm_in_use[0] = 1;
+ memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params));
+ memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
+
+ return 1;
+}
+#endif
+
+int64_t init_ddr(void)
+{
+ struct ddr_info info;
+ struct sysinfo sys;
+ int64_t dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ get_clocks(&sys);
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
+ debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = 1;
+ info.dimm_on_ctlr = 1;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed\n");
+ }
+
+#ifdef ERRATA_SOC_A008850
+ erratum_a008850_post();
+#endif
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1043a/ls1043ardb/plat_def.h b/plat/nxp/soc-ls1043a/ls1043ardb/plat_def.h
new file mode 100644
index 0000000..249f457
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/ls1043ardb/plat_def.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY Images.
+ */
+#include <tbbr_img_def.h>
+
+#include "policy.h"
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0 0x51
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+/* SD block buffer */
+#define NXP_SD_BLOCK_BUF_SIZE (0x00100000)
+#define NXP_SD_BLOCK_BUF_ADDR ULL(0x80000000)
+
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 3
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES 2
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES 1
+#endif
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define BL32_IRQ_SEC_PHY_TIMER 29
+
+/*
+ * Define properties 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_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+#define PLAT_LS_G0_IRQ_PROPS(grp)
+
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1043a/ls1043ardb/platform.c b/plat/nxp/soc-ls1043a/ls1043ardb/platform.c
new file mode 100644
index 0000000..65d508c
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/ls1043ardb/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1043a/ls1043ardb/platform.mk b/plat/nxp/soc-ls1043a/ls1043ardb/platform.mk
new file mode 100644
index 0000000..5d23356
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/ls1043ardb/platform.mk
@@ -0,0 +1,40 @@
+#
+# Copyright 2018-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+
+BOOT_MODE ?= nor
+BOARD := ls1043ardb
+POVDD_ENABLE := no
+
+# DDR Compilation Configs
+CONFIG_DDR_NODIMM := 1
+NUM_OF_DDRC := 1
+DDRC_NUM_DIMM := 0
+DDRC_NUM_CS := 4
+DDR_ECC_EN := no
+CONFIG_STATIC_DDR := 0
+
+# On-Board Flash Details
+# 128MB IFC NOR Flash
+NOR_FLASH_SZ := 0x8000000
+
+# Platform specific features.
+WARM_BOOT := no
+
+# Adding Platform files build files
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := nor \
+ sd \
+ nand
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1043a/soc.mk
diff --git a/plat/nxp/soc-ls1043a/ls1043ardb/platform_def.h b/plat/nxp/soc-ls1043a/ls1043ardb/platform_def.h
new file mode 100644
index 0000000..4721a32
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/ls1043ardb/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1043a/ls1043ardb/policy.h b/plat/nxp/soc-ls1043a/ls1043ardb/policy.h
new file mode 100644
index 0000000..843b5e2
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/ls1043ardb/policy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/*
+ * Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1043a/soc.c b/plat/nxp/soc-ls1043a/soc.c
new file mode 100644
index 0000000..3e821d0
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/soc.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <caam.h>
+#include <cassert.h>
+#include <cci.h>
+#include <common/debug.h>
+#include <dcfg.h>
+#ifdef I2C_INIT
+#include <i2c.h>
+#endif
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <ls_interconnect.h>
+#ifdef POLICY_FUSE_PROVISION
+#include <nxp_gpio.h>
+#endif
+#include <nxp_smmu.h>
+#include <nxp_timer.h>
+#include <plat_console.h>
+#include <plat_gic.h>
+#include <plat_tzc380.h>
+#include <scfg.h>
+#if defined(NXP_SFP_ENABLED)
+#include <sfp.h>
+#endif
+
+#include <errata.h>
+#include <ns_access.h>
+#ifdef CONFIG_OCRAM_ECC_EN
+#include <ocram.h>
+#endif
+#include <plat_common.h>
+#include <platform_def.h>
+#include <soc.h>
+
+static dcfg_init_info_t dcfg_init_data = {
+ .g_nxp_dcfg_addr = NXP_DCFG_ADDR,
+ .nxp_sysclk_freq = NXP_SYSCLK_FREQ,
+ .nxp_ddrclk_freq = NXP_DDRCLK_FREQ,
+ .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER,
+ };
+
+
+/* Function to return the SoC SYS CLK */
+unsigned int get_sys_clk(void)
+{
+ return NXP_SYSCLK_FREQ;
+}
+
+/*
+ * Function returns the base counter frequency
+ * after reading the first entry at CNTFID0 (0x20 offset).
+ *
+ * Function is used by:
+ * 1. ARM common code for PSCI management.
+ * 2. ARM Generic Timer init.
+ *
+ */
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+
+ counter_base_frequency = get_sys_clk()/4;
+
+ return counter_base_frequency;
+}
+
+#ifdef IMAGE_BL2
+
+static struct soc_type soc_list[] = {
+ SOC_ENTRY(LS1023A, LS1023A, 1, 2),
+ SOC_ENTRY(LS1023AE, LS1023AE, 1, 2),
+ SOC_ENTRY(LS1023A_P23, LS1023A_P23, 1, 2),
+ SOC_ENTRY(LS1023AE_P23, LS1023AE_P23, 1, 2),
+ SOC_ENTRY(LS1043A, LS1043A, 1, 4),
+ SOC_ENTRY(LS1043AE, LS1043AE, 1, 4),
+ SOC_ENTRY(LS1043A_P23, LS1043A_P23, 1, 4),
+ SOC_ENTRY(LS1043AE_P23, LS1043AE_P23, 1, 4),
+};
+
+#ifdef POLICY_FUSE_PROVISION
+static gpio_init_info_t gpio_init_data = {
+ .gpio1_base_addr = NXP_GPIO1_ADDR,
+ .gpio2_base_addr = NXP_GPIO2_ADDR,
+ .gpio3_base_addr = NXP_GPIO3_ADDR,
+ .gpio4_base_addr = NXP_GPIO4_ADDR,
+};
+#endif
+
+/*
+ * Function to set the base counter frequency at
+ * the first entry of the Frequency Mode Table,
+ * at CNTFID0 (0x20 offset).
+ *
+ * Set the value of the pirmary core register cntfrq_el0.
+ */
+static void set_base_freq_CNTFID0(void)
+{
+ /*
+ * Below register specifies the base frequency of the system counter.
+ * As per NXP Board Manuals:
+ * The system counter always works with SYS_REF_CLK/4 frequency clock.
+ *
+ */
+ unsigned int counter_base_frequency = get_sys_clk()/4;
+
+ /*
+ * Setting the frequency in the Frequency modes table.
+ *
+ * Note: The value for ls1046ardb board at this offset
+ * is not RW as stated. This offset have the
+ * fixed value of 100000400 Hz.
+ *
+ * The below code line has no effect.
+ * Keeping it for other platforms where it has effect.
+ */
+ mmio_write_32(NXP_TIMER_ADDR + CNTFID_OFF, counter_base_frequency);
+
+ write_cntfrq_el0(counter_base_frequency);
+}
+
+void soc_preload_setup(void)
+{
+
+}
+
+/*******************************************************************************
+ * This function implements soc specific erratas
+ * This is called before DDR is initialized or MMU is enabled
+ ******************************************************************************/
+void soc_early_init(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+ dram_regions_info_t *dram_regions_info = get_dram_regions_info();
+
+#ifdef CONFIG_OCRAM_ECC_EN
+ ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
+#endif
+ dcfg_init(&dcfg_init_data);
+#ifdef POLICY_FUSE_PROVISION
+ gpio_init(&gpio_init_data);
+ sec_init(NXP_CAAM_ADDR);
+#endif
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+ set_base_freq_CNTFID0();
+
+ /* Enable snooping on SEC read and write transactions */
+ scfg_setbits32((void *)(NXP_SCFG_ADDR + SCFG_SNPCNFGCR_OFFSET),
+ SCFG_SNPCNFGCR_SECRDSNP | SCFG_SNPCNFGCR_SECWRSNP);
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ */
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ /*
+ * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts.
+ */
+ smmu_cache_unlock(NXP_SMMU_ADDR);
+ INFO("SMMU Cache Unlocking is Configured.\n");
+
+#if TRUSTED_BOARD_BOOT
+ uint32_t mode;
+
+ sfp_init(NXP_SFP_ADDR);
+ /*
+ * For secure boot disable SMMU.
+ * Later when platform security policy comes in picture,
+ * this might get modified based on the policy
+ */
+ if (check_boot_mode_secure(&mode) == true) {
+ bypass_smmu(NXP_SMMU_ADDR);
+ }
+
+ /*
+ * For Mbedtls currently crypto is not supported via CAAM
+ * enable it when that support is there. In tbbr.mk
+ * the CAAM_INTEG is set as 0.
+ */
+
+#ifndef MBEDTLS_X509
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false) {
+ INFO("SEC is disabled.\n");
+ } else {
+ sec_init(NXP_CAAM_ADDR);
+ }
+#endif
+#elif defined(POLICY_FUSE_PROVISION)
+ gpio_init(&gpio_init_data);
+ sfp_init(NXP_SFP_ADDR);
+ sec_init(NXP_CAAM_ADDR);
+#endif
+
+ soc_errata();
+
+ /*
+ * Initialize system level generic timer for Layerscape Socs.
+ */
+ delay_timer_init(NXP_TIMER_ADDR);
+
+#ifdef DDR_INIT
+ i2c_init(NXP_I2C_ADDR);
+ dram_regions_info->total_dram_size = init_ddr();
+#endif
+}
+
+void soc_bl2_prepare_exit(void)
+{
+#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE)
+ set_sfp_wr_disable();
+#endif
+}
+
+/*****************************************************************************
+ * This function returns the boot device based on RCW_SRC
+ ****************************************************************************/
+enum boot_device get_boot_dev(void)
+{
+ enum boot_device src = BOOT_DEVICE_NONE;
+ uint32_t porsr1;
+ uint32_t rcw_src, val;
+
+ porsr1 = read_reg_porsr1();
+
+ rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT;
+
+ val = rcw_src & RCW_SRC_NAND_MASK;
+
+ if (val == RCW_SRC_NAND_VAL) {
+ val = rcw_src & NAND_RESERVED_MASK;
+ if ((val != NAND_RESERVED_1) && (val != NAND_RESERVED_2)) {
+ src = BOOT_DEVICE_IFC_NAND;
+ INFO("RCW BOOT SRC is IFC NAND\n");
+ }
+ } else {
+ /* RCW SRC NOR */
+ val = rcw_src & RCW_SRC_NOR_MASK;
+ if (val == NOR_8B_VAL || val == NOR_16B_VAL) {
+ src = BOOT_DEVICE_IFC_NOR;
+ INFO("RCW BOOT SRC is IFC NOR\n");
+ } else {
+ switch (rcw_src) {
+ case QSPI_VAL1:
+ case QSPI_VAL2:
+ src = BOOT_DEVICE_QSPI;
+ INFO("RCW BOOT SRC is QSPI\n");
+ break;
+ case SD_VAL:
+ src = BOOT_DEVICE_EMMC;
+ INFO("RCW BOOT SRC is SD/EMMC\n");
+ break;
+ default:
+ src = BOOT_DEVICE_NONE;
+ }
+ }
+ }
+
+ return src;
+}
+
+/* This function sets up access permissions on memory regions */
+void soc_mem_access(void)
+{
+ struct tzc380_reg tzc380_reg_list[MAX_NUM_TZC_REGION];
+ int dram_idx, index = 0U;
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+
+ for (dram_idx = 0U; dram_idx < info_dram_regions->num_dram_regions;
+ dram_idx++) {
+ if (info_dram_regions->region[dram_idx].size == 0) {
+ ERROR("DDR init failure, or");
+ ERROR("DRAM regions not populated correctly.\n");
+ break;
+ }
+
+ index = populate_tzc380_reg_list(tzc380_reg_list,
+ dram_idx, index,
+ info_dram_regions->region[dram_idx].addr,
+ info_dram_regions->region[dram_idx].size,
+ NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE);
+ }
+
+ mem_access_setup(NXP_TZC_ADDR, index, tzc380_reg_list);
+
+ /* Configure CSU secure access register to disable TZASC bypass mux */
+ mmio_write_32((uintptr_t)(NXP_CSU_ADDR +
+ CSU_SEC_ACCESS_REG_OFFSET),
+ bswap32(TZASC_BYPASS_MUX_DISABLE));
+}
+
+
+#else
+const unsigned char _power_domain_tree_desc[] = {1, 1, 4};
+
+CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256,
+ assert_invalid_ls1043_cluster_count);
+
+/* This function returns the SoC topology */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+
+ return _power_domain_tree_desc;
+}
+
+/*
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ */
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
+{
+ return CORES_PER_CLUSTER;
+}
+
+void soc_early_platform_setup2(void)
+{
+ dcfg_init(&dcfg_init_data);
+ /* Initialize system level generic timer for Socs */
+ delay_timer_init(NXP_TIMER_ADDR);
+
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+}
+
+/*
+ * For LS1043a rev1.0, GIC base address align with 4k.
+ * For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT]
+ * is set, GIC base address align with 4K, or else align
+ * with 64k.
+ */
+void get_gic_offset(uint32_t *gicc_base, uint32_t *gicd_base)
+{
+ uint32_t *ccsr_svr = (uint32_t *)(NXP_DCFG_ADDR + DCFG_SVR_OFFSET);
+ uint32_t *gic_align = (uint32_t *)(NXP_SCFG_ADDR +
+ SCFG_GIC400_ADDR_ALIGN_OFFSET);
+ uint32_t val;
+
+ val = be32toh(mmio_read_32((uintptr_t)ccsr_svr));
+
+ if ((val & 0xff) == REV1_1) {
+ val = be32toh(mmio_read_32((uintptr_t)gic_align));
+ if (val & (1L << GIC_ADDR_BIT)) {
+ *gicc_base = NXP_GICC_4K_ADDR;
+ *gicd_base = NXP_GICD_4K_ADDR;
+ } else {
+ *gicc_base = NXP_GICC_64K_ADDR;
+ *gicd_base = NXP_GICD_64K_ADDR;
+ }
+ } else {
+ *gicc_base = NXP_GICC_4K_ADDR;
+ *gicd_base = NXP_GICD_4K_ADDR;
+ }
+}
+
+void soc_platform_setup(void)
+{
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ static uint32_t target_mask_array[PLATFORM_CORE_COUNT];
+ /*
+ * On a GICv2 system, the Group 1 secure interrupts are treated
+ * as Group 0 interrupts.
+ */
+ static interrupt_prop_t ls_interrupt_props[] = {
+ PLAT_LS_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
+ PLAT_LS_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
+ };
+ static uint32_t gicc_base, gicd_base;
+
+ get_gic_offset(&gicc_base, &gicd_base);
+ plat_ls_gic_driver_init(gicd_base, gicc_base,
+ PLATFORM_CORE_COUNT,
+ ls_interrupt_props,
+ ARRAY_SIZE(ls_interrupt_props),
+ target_mask_array);
+
+ plat_ls_gic_init();
+ enable_init_timer();
+}
+
+/* This function initializes the soc from the BL31 module */
+void soc_init(void)
+{
+ /* low-level init of the soc */
+ soc_init_lowlevel();
+ _init_global_data();
+ soc_init_percpu();
+ _initialize_psci();
+
+ /*
+ * Initialize the interconnect during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable coherency in interconnect for the primary CPU's cluster.
+ * Earlier bootloader stages might already do this but we can't
+ * assume so. No harm in executing this code twice.
+ */
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
+
+ /* Init CSU to enable non-secure access to peripherals */
+ enable_layerscape_ns_access(ns_dev, ARRAY_SIZE(ns_dev), NXP_CSU_ADDR);
+
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false) {
+ INFO("SEC is disabled.\n");
+ } else {
+ sec_init(NXP_CAAM_ADDR);
+ }
+}
+
+void soc_runtime_setup(void)
+{
+
+}
+#endif
diff --git a/plat/nxp/soc-ls1043a/soc.def b/plat/nxp/soc-ls1043a/soc.def
new file mode 100644
index 0000000..b174bd6
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/soc.def
@@ -0,0 +1,107 @@
+#
+# Copyright 2017-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# This file contains the basic architecture definitions that drive the build
+#
+# -----------------------------------------------------------------------------
+
+CORE_TYPE := a53
+
+CACHE_LINE := 6
+
+# set to GIC400 or GIC500
+GIC := GIC400
+
+# set to CCI400 or CCN504 or CCN508
+INTERCONNECT := CCI400
+
+# indicate layerscape chassis level - set to 3=LSCH3 or 2=LSCH2
+CHASSIS := 2
+
+# TZC IP Details TZC used is TZC380 or TZC400
+TZC_ID := TZC380
+
+# CONSOLE Details available is NS16550 or PL011
+CONSOLE := NS16550
+
+# Select the DDR PHY generation to be used
+PLAT_DDR_PHY := PHY_GEN1
+
+PHYS_SYS := 64
+
+# ddr controller - set to MMDC or NXP
+DDRCNTLR := NXP
+
+# ddr phy - set to NXP or SNPS
+DDRPHY := NXP
+
+# Area of OCRAM reserved by ROM code
+NXP_ROM_RSVD := 0x5900
+
+# Max Size of CSF header. Required to define BL2 TEXT LIMIT in soc.def
+# Input to CST create_hdr_esbc tool
+CSF_HDR_SZ := 0x3000
+
+# In IMAGE_BL2, compile time flag for handling Cache coherency
+# with CAAM for BL2 running from OCRAM
+SEC_MEM_NON_COHERENT := yes
+
+# OCRAM MAP
+OCRAM_START_ADDR := 0x10000000
+OCRAM_SIZE := 0x20000
+
+# BL2 binary is placed at start of OCRAM.
+# Also used by create_pbl.mk.
+BL2_BASE := 0x10000000
+
+# After BL2 bin, OCRAM is used by ROM Code:
+# (OCRAM_START_ADDR + BL2_BIN_SIZE) -> (NXP_ROM_RSVD - 1)
+
+# After ROM Code, OCRAM is used by CSF header.
+# (OCRAM_START_ADDR + BL2_TEXT_LIMIT + NXP_ROM_RSVD) -> (CSF_HDR_SZ - 1)
+
+# BL2_HDR_LOC has to be (OCRAM_START_ADDR + OCRAM_SIZE - NXP_ROM_RSVD - CSF_HDR_SZ)
+# This value should be greater than BL2_TEXT_LIMIT
+# Input to CST create_hdr_isbc tool
+BL2_HDR_LOC_HDR ?= $(shell echo $$(( $(OCRAM_START_ADDR) + $(OCRAM_SIZE) - $(NXP_ROM_RSVD) - $(CSF_HDR_SZ))))
+# Covert to HEX to be used by create_pbl.mk
+BL2_HDR_LOC := $$(echo "obase=16; ${BL2_HDR_LOC_HDR}" | bc)
+
+# Core Errata
+ERRATA_A53_855873 := 1
+ERRATA_A53_1530924 := 1
+
+# SoC ERRATAS to be enabled
+ERRATA_SOC_A008850 := 1
+ERRATA_SOC_A010539 := 1
+ERRATA_SOC_A009660 := 1
+
+# DDR Errata
+ERRATA_DDR_A009663 := 1
+ERRATA_DDR_A009942 := 1
+
+# enable dynamic memory mapping
+PLAT_XLAT_TABLES_DYNAMIC := 1
+
+# Define Endianness of each module
+NXP_GUR_ENDIANNESS := BE
+NXP_DDR_ENDIANNESS := BE
+NXP_SEC_ENDIANNESS := BE
+NXP_SFP_ENDIANNESS := BE
+NXP_SNVS_ENDIANNESS := BE
+NXP_ESDHC_ENDIANNESS := BE
+NXP_QSPI_ENDIANNESS := BE
+NXP_FSPI_ENDIANNESS := BE
+NXP_SCFG_ENDIANNESS := BE
+NXP_GPIO_ENDIANNESS := BE
+NXP_IFC_ENDIANNESS := BE
+
+NXP_SFP_VER := 3_2
+
+# OCRAM ECC Enabled
+OCRAM_ECC_EN := yes
diff --git a/plat/nxp/soc-ls1043a/soc.mk b/plat/nxp/soc-ls1043a/soc.mk
new file mode 100644
index 0000000..0ebb377
--- /dev/null
+++ b/plat/nxp/soc-ls1043a/soc.mk
@@ -0,0 +1,114 @@
+#
+# Copyright 2018-2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# SoC-specific build parameters
+SOC := ls1043a
+PLAT_PATH := plat/nxp
+PLAT_COMMON_PATH := plat/nxp/common
+PLAT_DRIVERS_PATH := drivers/nxp
+PLAT_SOC_PATH := ${PLAT_PATH}/soc-${SOC}
+BOARD_PATH := ${PLAT_SOC_PATH}/${BOARD}
+
+# get SoC-specific defnitions
+include ${PLAT_SOC_PATH}/soc.def
+include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+# For Security Features
+DISABLE_FUSE_WRITE := 1
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
+SECURE_BOOT := yes
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM))
+
+# Selecting Drivers for SoC
+$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,CSU_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+
+# Selecting PSCI & SIP_SVC support
+$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31))
+
+# Source File Addition
+PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\
+ -I${BOARD_PATH}\
+ -I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
+ -I${PLAT_SOC_PATH}/include\
+ -I${PLAT_COMMON_PATH}/soc_errata
+
+ifeq (${SECURE_BOOT},yes)
+include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
+endif
+
+ifeq ($(WARM_BOOT),yes)
+include ${PLAT_COMMON_PATH}/warm_reset/warm_reset.mk
+endif
+
+ifeq (${NXP_NV_SW_MAINT_LAST_EXEC_DATA}, yes)
+include ${PLAT_COMMON_PATH}/nv_storage/nv_storage.mk
+endif
+
+ifeq (${PSCI_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/psci/psci.mk
+endif
+
+ifeq (${SIPSVC_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk
+endif
+
+# for fuse-fip & fuse-programming
+ifeq (${FUSE_PROG}, 1)
+include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk
+endif
+
+ifeq (${IMG_LOADR_NEEDED},yes)
+include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk
+endif
+
+# Adding source files for the above selected drivers.
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+# Adding SoC specific files
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
+
+PLAT_INCLUDES += ${NV_STORAGE_INCLUDES}\
+ ${WARM_RST_INCLUDES}
+
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\
+ ${WARM_RST_BL31_SOURCES}\
+ ${PSCI_SOURCES}\
+ ${SIPSVC_SOURCES}\
+ ${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S
+
+PLAT_BL_COMMON_SOURCES += ${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\
+ ${PLAT_SOC_PATH}/aarch64/${SOC}_helpers.S\
+ ${NV_STORAGE_SOURCES}\
+ ${WARM_RST_BL_COMM_SOURCES}\
+ ${PLAT_SOC_PATH}/soc.c
+
+ifeq (${TEST_BL31}, 1)
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S\
+ ${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S
+endif
+
+BL2_SOURCES += ${DDR_CNTLR_SOURCES}\
+ ${TBBR_SOURCES}\
+ ${FUSE_SOURCES}
+
+# Adding TFA setup files
+include ${PLAT_PATH}/common/setup/common.mk
diff --git a/plat/nxp/soc-ls1046a/aarch64/ls1046a.S b/plat/nxp/soc-ls1046a/aarch64/ls1046a.S
new file mode 100644
index 0000000..daa0542
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/aarch64/ls1046a.S
@@ -0,0 +1,937 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <asm_macros.S>
+#include <dcfg_lsch2.h>
+#include <nxp_timer.h>
+#include <plat_gic.h>
+#include <scfg.h>
+
+#include <bl31_data.h>
+#include <plat_psci.h>
+#include <platform_def.h>
+
+#define DAIF_DATA AUX_01_DATA
+#define TIMER_CNTRL_DATA AUX_02_DATA
+
+.global soc_init_lowlevel
+.global soc_init_percpu
+.global _soc_core_release
+.global _soc_core_restart
+.global _soc_ck_disabled
+.global _soc_sys_reset
+.global _soc_sys_off
+.global _soc_set_start_addr
+.global _getGICC_BaseAddr
+.global _getGICD_BaseAddr
+.global _soc_core_prep_off
+.global _soc_core_entr_off
+.global _soc_core_exit_off
+.global _soc_core_prep_stdby
+.global _soc_core_entr_stdby
+.global _soc_core_exit_stdby
+.global _soc_core_prep_pwrdn
+.global _soc_core_entr_pwrdn
+.global _soc_core_exit_pwrdn
+.global _soc_clstr_prep_stdby
+.global _soc_clstr_exit_stdby
+.global _soc_clstr_prep_pwrdn
+.global _soc_clstr_exit_pwrdn
+.global _soc_sys_prep_stdby
+.global _soc_sys_exit_stdby
+.global _soc_sys_prep_pwrdn
+.global _soc_sys_pwrdn_wfi
+.global _soc_sys_exit_pwrdn
+
+
+/* This function initialize the soc
+ * in: void
+ * out: void
+ */
+func soc_init_lowlevel
+ ret
+endfunc soc_init_lowlevel
+
+
+/* void soc_init_percpu(void)
+ * this function performs any soc-specific initialization that is needed on
+ * a per-core basis
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+func soc_init_percpu
+ mov x3, x30
+
+ bl plat_my_core_mask
+ mov x2, x0
+
+ /* see if this core is marked for prefetch disable */
+ mov x0, #PREFETCH_DIS_OFFSET
+ bl _get_global_data /* 0-1 */
+ tst x0, x2
+ b.eq 1f
+ bl _disable_ldstr_pfetch_A72 /* 0 */
+1:
+ mov x30, x3
+ ret
+endfunc soc_init_percpu
+
+/* part of CPU_ON
+ * this function releases a secondary core from reset
+ * in: x0 = core_mask_lsb
+ * out: none
+ * uses: x0, x1, x2, x3
+ */
+func _soc_core_release
+
+#if (TEST_BL31)
+ rbit w2, w0
+ /* x2 = core mask msb */
+#else
+ mov x2, x0
+#endif
+ /* write COREBCR */
+ mov x1, #NXP_SCFG_ADDR
+ rev w3, w2
+ str w3, [x1, #SCFG_COREBCR_OFFSET]
+ isb
+
+ /* read-modify-write BRR */
+ mov x1, #NXP_DCFG_ADDR
+ ldr w2, [x1, #DCFG_BRR_OFFSET]
+ rev w3, w2
+ orr w3, w3, w0
+ rev w2, w3
+ str w2, [x1, #DCFG_BRR_OFFSET]
+ isb
+
+ /* send event */
+ sev
+ isb
+ ret
+endfunc _soc_core_release
+
+
+/* part of CPU_ON
+ * this function restarts a core shutdown via _soc_core_entr_off
+ * in: x0 = core mask lsb (of the target cpu)
+ * out: x0 == 0, on success
+ * x0 != 0, on failure
+ * uses x0, x1, x2, x3, x4, x5
+ */
+func _soc_core_restart
+ mov x5, x30
+ mov x3, x0
+
+ /*
+ * unset ph20 request in RCPM_PCPH20CLEARR
+ * this is an lsb-0 register
+ */
+ ldr x1, =NXP_RCPM_ADDR
+ rev w2, w3
+ str w2, [x1, #RCPM_PCPH20CLRR_OFFSET]
+ dsb sy
+ isb
+
+ bl _getGICD_BaseAddr
+ mov x4, x0
+
+ /* enable forwarding of group 0 interrupts by setting GICD_CTLR[0] = 1 */
+ ldr w1, [x4, #GICD_CTLR_OFFSET]
+ orr w1, w1, #GICD_CTLR_EN_GRP0
+ str w1, [x4, #GICD_CTLR_OFFSET]
+ dsb sy
+ isb
+
+
+ /*
+ * fire SGI by writing to GICD_SGIR the following values:
+ * [25:24] = 0x0 (forward interrupt to the CPU interfaces
+ * specified in CPUTargetList field)
+ * [23:16] = core mask lsb[7:0] (forward interrupt to target cpu)
+ * [15] = 0 (forward SGI only if it is configured as group 0 interrupt)
+ * [3:0] = 0xF (interrupt ID = 15)
+ */
+ lsl w1, w3, #16
+ orr w1, w1, #0xF
+ str w1, [x4, #GICD_SGIR_OFFSET]
+ dsb sy
+ isb
+
+ /* load '0' on success */
+ mov x0, xzr
+
+ mov x30, x5
+ ret
+endfunc _soc_core_restart
+
+/*
+ * This function determines if a core is disabled via COREDISR
+ * in: w0 = core_mask_lsb
+ * out: w0 = 0, core not disabled
+ * w0 != 0, core disabled
+ * uses x0, x1, x2
+ */
+func _soc_ck_disabled
+ /* get base addr of dcfg block */
+ mov x1, #NXP_DCFG_ADDR
+
+ /* read COREDISR */
+ ldr w1, [x1, #DCFG_COREDISR_OFFSET]
+ rev w2, w1
+
+ /* test core bit */
+ and w0, w2, w0
+ ret
+endfunc _soc_ck_disabled
+
+/*
+ *This function resets the system via SoC-specific methods
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+func _soc_sys_reset
+ ldr x2, =NXP_DCFG_ADDR
+
+ /* make sure the mask is cleared in the reset request mask register */
+ mov w1, wzr
+ str w1, [x2, #DCFG_RSTRQMR1_OFFSET]
+
+ /* set the reset request */
+ ldr w1, =RSTCR_RESET_REQ
+ ldr x3, =DCFG_RSTCR_OFFSET
+ rev w0, w1
+ str w0, [x2, x3]
+
+ /*
+ * just in case this address range is mapped as cacheable,
+ * flush the write out of the dcaches
+ */
+ add x3, x2, x3
+ dc cvac, x3
+ dsb st
+ isb
+
+ /* Note: this function does not return */
+1:
+ wfi
+ b 1b
+endfunc _soc_sys_reset
+
+/*
+ * Part of SYSTEM_OFF
+ * this function turns off the SoC clocks
+ * Note: this function is not intended to return, and the only allowable
+ * recovery is POR
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9
+ */
+func _soc_sys_off
+
+ /* mask interrupts at the core */
+ mrs x1, DAIF
+ mov x0, #DAIF_SET_MASK
+ orr x0, x1, x0
+ msr DAIF, x0
+
+ /* disable icache, dcache, mmu @ EL1 */
+ mov x1, #SCTLR_I_C_M_MASK
+ mrs x0, sctlr_el1
+ bic x0, x0, x1
+ msr sctlr_el1, x0
+
+ /* disable dcache for EL3 */
+ mrs x1, SCTLR_EL3
+ bic x1, x1, #SCTLR_C_MASK
+ /* make sure icache is enabled */
+ orr x1, x1, #SCTLR_I_MASK
+ msr SCTLR_EL3, x1
+ isb
+
+ /* Enable dynamic retention ctrl (CPUECTLR[2:0]) and SMP (CPUECTLR[6]) */
+ mrs x0, CORTEX_A72_ECTLR_EL1
+ orr x0, x0, #CPUECTLR_TIMER_8TICKS
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ msr CORTEX_A72_ECTLR_EL1, x0
+
+ /* set WFIL2EN in SCFG_CLUSTERPMCR */
+ ldr x0, =SCFG_COREPMCR_OFFSET
+ ldr x1, =COREPMCR_WFIL2
+ bl write_reg_scfg
+
+ /* request LPM20 */
+ mov x0, #RCPM_POWMGTCSR_OFFSET
+ bl read_reg_rcpm
+ orr x1, x0, #RCPM_POWMGTCSR_LPM20_REQ
+ mov x0, #RCPM_POWMGTCSR_OFFSET
+ bl write_reg_rcpm
+
+ dsb sy
+ isb
+1:
+ wfi
+ b 1b
+endfunc _soc_sys_off
+
+/*
+ * Write a register in the RCPM block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2, x3
+ */
+func write_reg_rcpm
+ ldr x2, =NXP_RCPM_ADDR
+ /* swap for BE */
+ rev w3, w1
+ str w3, [x2, x0]
+ ret
+endfunc write_reg_rcpm
+
+/*
+ * Read a register in the RCPM block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1, x2
+ */
+func read_reg_rcpm
+ ldr x2, =NXP_RCPM_ADDR
+ ldr w1, [x2, x0]
+ /* swap for BE */
+ rev w0, w1
+ ret
+endfunc read_reg_rcpm
+
+/*
+ * Write a register in the SCFG block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2, x3
+ */
+func write_reg_scfg
+ mov x2, #NXP_SCFG_ADDR
+ /* swap for BE */
+ rev w3, w1
+ str w3, [x2, x0]
+ ret
+endfunc write_reg_scfg
+
+/*
+ * Read a register in the SCFG block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1, x2
+ */
+func read_reg_scfg
+ mov x2, #NXP_SCFG_ADDR
+ ldr w1, [x2, x0]
+ /* swap for BE */
+ rev w0, w1
+ ret
+endfunc read_reg_scfg
+
+/*
+ * Part of CPU_OFF
+ * this function programs SoC & GIC registers in preparation for shutting down
+ * the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7
+ */
+func _soc_core_prep_off
+ mov x7, x30
+ mov x6, x0
+
+ /* Set retention control in CPUECTLR make sure smpen bit is set */
+ mrs x4, CORTEX_A72_ECTLR_EL1
+ bic x4, x4, #CPUECTLR_RET_MASK
+ orr x4, x4, #CPUECTLR_TIMER_8TICKS
+ orr x4, x4, #CPUECTLR_SMPEN_EN
+ msr CORTEX_A72_ECTLR_EL1, x4
+
+ /* save timer control current value */
+ mov x5, #NXP_TIMER_ADDR
+ ldr w4, [x5, #SYS_COUNTER_CNTCR_OFFSET]
+ mov w2, w4
+ mov x0, x6
+ mov x1, #TIMER_CNTRL_DATA
+ bl _setCoreData
+
+ /* enable the timer */
+ orr w4, w4, #CNTCR_EN_MASK
+ str w4, [x5, #SYS_COUNTER_CNTCR_OFFSET]
+
+ bl _getGICC_BaseAddr
+ mov x5, x0
+
+ /* disable signaling of ints */
+ ldr w3, [x5, #GICC_CTLR_OFFSET]
+ bic w3, w3, #GICC_CTLR_EN_GRP0
+ bic w3, w3, #GICC_CTLR_EN_GRP1
+ str w3, [x5, #GICC_CTLR_OFFSET]
+ dsb sy
+ isb
+
+
+ /*
+ * set retention control in SCFG_RETREQCR
+ * Note: this register is msb 0
+ */
+ ldr x4, =SCFG_RETREQCR_OFFSET
+ mov x0, x4
+ bl read_reg_scfg
+ rbit w1, w6
+ orr w1, w0, w1
+ mov x0, x4
+ bl write_reg_scfg
+
+ /* set the priority filter */
+ ldr w2, [x5, #GICC_PMR_OFFSET]
+ orr w2, w2, #GICC_PMR_FILTER
+ str w2, [x5, #GICC_PMR_OFFSET]
+
+ /* setup GICC_CTLR */
+ bic w3, w3, #GICC_CTLR_ACKCTL_MASK
+ orr w3, w3, #GICC_CTLR_FIQ_EN_MASK
+ orr w3, w3, #GICC_CTLR_EOImodeS_MASK
+ orr w3, w3, #GICC_CTLR_CBPR_MASK
+ str w3, [x5, #GICC_CTLR_OFFSET]
+
+ /* setup the banked-per-core GICD registers */
+ bl _getGICD_BaseAddr
+ mov x5, x0
+
+ /* define SGI15 as Grp0 */
+ ldr w2, [x5, #GICD_IGROUPR0_OFFSET]
+ bic w2, w2, #GICD_IGROUP0_SGI15
+ str w2, [x5, #GICD_IGROUPR0_OFFSET]
+
+ /* set priority of SGI 15 to highest... */
+ ldr w2, [x5, #GICD_IPRIORITYR3_OFFSET]
+ bic w2, w2, #GICD_IPRIORITY_SGI15_MASK
+ str w2, [x5, #GICD_IPRIORITYR3_OFFSET]
+
+ /* enable SGI 15 */
+ ldr w2, [x5, #GICD_ISENABLER0_OFFSET]
+ orr w2, w2, #GICD_ISENABLE0_SGI15
+ str w2, [x5, #GICD_ISENABLER0_OFFSET]
+
+ /* enable the cpu interface */
+ bl _getGICC_BaseAddr
+ mov x2, x0
+ orr w3, w3, #GICC_CTLR_EN_GRP0
+ str w3, [x2, #GICC_CTLR_OFFSET]
+
+
+ /* clear any pending SGIs */
+ ldr x2, =GICD_CPENDSGIR_CLR_MASK
+ add x0, x5, #GICD_CPENDSGIR3_OFFSET
+ str w2, [x0]
+
+ /*
+ * Set the PC_PH20_REQ bit in RCPM_PCPH20SETR
+ * this is an lsb-0 register
+ */
+ mov x1, x6
+ mov x0, #RCPM_PCPH20SETR_OFFSET
+ bl write_reg_rcpm
+
+ dsb sy
+ isb
+ mov x30, x7
+ ret
+endfunc _soc_core_prep_off
+
+/*
+ * Part of CPU_OFF
+ * this function performs the final steps to shutdown the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5
+ */
+func _soc_core_entr_off
+ mov x5, x30
+ mov x4, x0
+
+ bl _getGICD_BaseAddr
+ mov x3, x0
+
+3:
+ /* enter low-power state by executing wfi */
+ wfi
+
+ /* see if we got hit by SGI 15 */
+ add x0, x3, #GICD_SPENDSGIR3_OFFSET
+ ldr w2, [x0]
+ and w2, w2, #GICD_SPENDSGIR3_SGI15_MASK
+ cbz w2, 4f
+
+ /* clear the pending SGI */
+ ldr x2, =GICD_CPENDSGIR_CLR_MASK
+ add x0, x3, #GICD_CPENDSGIR3_OFFSET
+ str w2, [x0]
+4:
+ /* check if core has been turned on */
+ mov x0, x4
+ bl _getCoreState
+
+ cmp x0, #CORE_WAKEUP
+ b.ne 3b
+
+ /* if we get here, then we have exited the wfi */
+ dsb sy
+ isb
+ mov x30, x5
+ ret
+endfunc _soc_core_entr_off
+
+/*
+ * Part of CPU_OFF
+ * this function starts the process of starting a core back up
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+func _soc_core_exit_off
+ mov x6, x30
+ mov x5, x0
+
+ /*
+ * Clear ph20 request in RCPM_PCPH20CLRR - no need
+ * to do that here, it has been done in _soc_core_restart
+ */
+ bl _getGICC_BaseAddr
+ mov x1, x0
+
+ /* read GICC_IAR */
+ ldr w0, [x1, #GICC_IAR_OFFSET]
+
+ /* write GICC_EIOR - signal end-of-interrupt */
+ str w0, [x1, #GICC_EOIR_OFFSET]
+
+ /* write GICC_DIR - disable interrupt */
+ str w0, [x1, #GICC_DIR_OFFSET]
+
+ /* disable signaling of grp0 ints */
+ ldr w3, [x1, #GICC_CTLR_OFFSET]
+ bic w3, w3, #GICC_CTLR_EN_GRP0
+ str w3, [x1, #GICC_CTLR_OFFSET]
+
+ /*
+ * Unset retention request in SCFG_RETREQCR
+ * Note: this register is msb-0
+ */
+ ldr x4, =SCFG_RETREQCR_OFFSET
+ mov x0, x4
+ bl read_reg_scfg
+ rbit w1, w5
+ bic w1, w0, w1
+ mov x0, x4
+ bl write_reg_scfg
+
+ /* restore timer ctrl */
+ mov x0, x5
+ mov x1, #TIMER_CNTRL_DATA
+ bl _getCoreData
+ /* w0 = timer ctrl saved value */
+ mov x2, #NXP_TIMER_ADDR
+ str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+
+ dsb sy
+ isb
+ mov x30, x6
+ ret
+endfunc _soc_core_exit_off
+
+/*
+ * Function loads a 64-bit execution address of the core in the soc registers
+ * BOOTLOCPTRL/H
+ * in: x0, 64-bit address to write to BOOTLOCPTRL/H
+ * uses x0, x1, x2, x3
+ */
+func _soc_set_start_addr
+ /* get the 64-bit base address of the scfg block */
+ ldr x2, =NXP_SCFG_ADDR
+
+ /* write the 32-bit BOOTLOCPTRL register */
+ mov x1, x0
+ rev w3, w1
+ str w3, [x2, #SCFG_BOOTLOCPTRL_OFFSET]
+
+ /* write the 32-bit BOOTLOCPTRH register */
+ lsr x1, x0, #32
+ rev w3, w1
+ str w3, [x2, #SCFG_BOOTLOCPTRH_OFFSET]
+ ret
+endfunc _soc_set_start_addr
+
+/*
+ * This function returns the base address of the gic distributor
+ * in: none
+ * out: x0 = base address of gic distributor
+ * uses x0
+ */
+func _getGICD_BaseAddr
+#if (TEST_BL31)
+ /* defect in simulator - gic base addresses are on 4Kb boundary */
+ ldr x0, =NXP_GICD_4K_ADDR
+#else
+ ldr x0, =NXP_GICD_64K_ADDR
+#endif
+ ret
+endfunc _getGICD_BaseAddr
+
+/*
+ * This function returns the base address of the gic controller
+ * in: none
+ * out: x0 = base address of gic controller
+ * uses x0
+ */
+func _getGICC_BaseAddr
+#if (TEST_BL31)
+ /* defect in simulator - gic base addresses are on 4Kb boundary */
+ ldr x0, =NXP_GICC_4K_ADDR
+#else
+ ldr x0, =NXP_GICC_64K_ADDR
+#endif
+ ret
+endfunc _getGICC_BaseAddr
+
+/*
+ * Part of CPU_SUSPEND
+ * this function puts the calling core into standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+func _soc_core_entr_stdby
+ dsb sy
+ isb
+ wfi
+
+ ret
+endfunc _soc_core_entr_stdby
+
+
+/*
+ * Part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+func _soc_core_prep_stdby
+ /* clear CORTEX_A72_ECTLR_EL1[2:0] */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ ret
+endfunc _soc_core_prep_stdby
+
+/*
+ * Part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_core_exit_stdby
+ ret
+endfunc _soc_core_exit_stdby
+
+/*
+ * Part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5
+ */
+func _soc_core_prep_pwrdn
+ mov x5, x30
+ mov x4, x0
+
+ /* enable CPU retention + set smp */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ orr x1, x1, #0x1
+ orr x1, x1, #CPUECTLR_SMPEN_MASK
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ /*
+ * set the retention request in SCFG_RETREQCR
+ * this is an msb-0 register
+ */
+ ldr x3, =SCFG_RETREQCR_OFFSET
+ mov x0, x3
+ bl read_reg_scfg
+ rbit w1, w4
+ orr w1, w0, w1
+ mov x0, x3
+ bl write_reg_scfg
+
+ /*
+ * Set the PC_PH20_REQ bit in RCPM_PCPH20SETR
+ * this is an lsb-0 register
+ */
+ mov x1, x4
+ mov x0, #RCPM_PCPH20SETR_OFFSET
+ bl write_reg_rcpm
+
+ mov x30, x5
+ ret
+endfunc _soc_core_prep_pwrdn
+
+/*
+ * Part of CPU_SUSPEND
+ * this function puts the calling core into a power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+func _soc_core_entr_pwrdn
+ dsb sy
+ isb
+ wfi
+
+ ret
+endfunc _soc_core_entr_pwrdn
+
+/*
+ * Part of CPU_SUSPEND
+ * this function cleans up after a core exits power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5
+ */
+func _soc_core_exit_pwrdn
+ mov x5, x30
+ mov x4, x0
+
+ /*
+ * Set the PC_PH20_REQ bit in RCPM_PCPH20CLRR
+ * this is an lsb-0 register
+ */
+ mov x1, x4
+ mov x0, #RCPM_PCPH20CLRR_OFFSET
+ bl write_reg_rcpm
+
+ /*
+ * Unset the retention request in SCFG_RETREQCR
+ * this is an msb-0 register
+ */
+ ldr x3, =SCFG_RETREQCR_OFFSET
+ mov x0, x3
+ bl read_reg_scfg
+ rbit w1, w4
+ bic w1, w0, w1
+ mov x0, x3
+ bl write_reg_scfg
+
+ mov x30, x5
+ ret
+endfunc _soc_core_exit_pwrdn
+
+/*
+ * Part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_clstr_prep_stdby
+ /* clear CORTEX_A72_ECTLR_EL1[2:0] */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ ret
+endfunc _soc_clstr_prep_stdby
+
+/*
+ * Part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_clstr_exit_stdby
+ ret
+endfunc _soc_clstr_exit_stdby
+
+/*
+ * Part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5
+ */
+func _soc_clstr_prep_pwrdn
+ mov x5, x30
+ mov x4, x0
+
+ /* enable CPU retention + set smp */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ orr x1, x1, #0x1
+ orr x1, x1, #CPUECTLR_SMPEN_MASK
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ /*
+ * Set the retention request in SCFG_RETREQCR
+ * this is an msb-0 register.
+ */
+ ldr x3, =SCFG_RETREQCR_OFFSET
+ mov x0, x3
+ bl read_reg_scfg
+ rbit w1, w4
+ orr w1, w0, w1
+ mov x0, x3
+ bl write_reg_scfg
+
+ /*
+ * Set the PC_PH20_REQ bit in RCPM_PCPH20SETR
+ * this is an lsb-0 register.
+ */
+ mov x1, x4
+ mov x0, #RCPM_PCPH20SETR_OFFSET
+ bl write_reg_rcpm
+
+ mov x30, x5
+ ret
+endfunc _soc_clstr_prep_pwrdn
+
+/*
+ * Part of CPU_SUSPEND
+ * this function cleans up after a core exits power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5
+ */
+func _soc_clstr_exit_pwrdn
+ mov x5, x30
+ mov x4, x0
+
+ /*
+ * Set the PC_PH20_REQ bit in RCPM_PCPH20CLRR
+ * this is an lsb-0 register.
+ */
+ mov x1, x4
+ mov x0, #RCPM_PCPH20CLRR_OFFSET
+ bl write_reg_rcpm
+
+ /*
+ * Unset the retention request in SCFG_RETREQCR
+ * this is an msb-0 register.
+ */
+ ldr x3, =SCFG_RETREQCR_OFFSET
+ mov x0, x3
+ bl read_reg_scfg
+ rbit w1, w4
+ bic w1, w0, w1
+ mov x0, x3
+ bl write_reg_scfg
+
+ mov x30, x5
+ ret
+endfunc _soc_clstr_exit_pwrdn
+
+/*
+ * Part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_sys_prep_stdby
+ /* clear CORTEX_A72_ECTLR_EL1[2:0] */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ ret
+endfunc _soc_sys_prep_stdby
+
+/* Part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_sys_exit_stdby
+ ret
+endfunc _soc_sys_exit_stdby
+
+/*
+ * Part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to
+ * suspend-to-power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4
+ */
+func _soc_sys_prep_pwrdn
+ mov x4, x30
+
+ /* Enable dynamic retention contrl (CPUECTLR[2:0]) and SMP (CPUECTLR[6]) */
+ mrs x0, CORTEX_A72_ECTLR_EL1
+ bic x0, x0, #CPUECTLR_TIMER_MASK
+ orr x0, x0, #CPUECTLR_TIMER_8TICKS
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ msr CORTEX_A72_ECTLR_EL1, x0
+
+ /* Set WFIL2EN in SCFG_CLUSTERPMCR */
+ ldr x0, =SCFG_COREPMCR_OFFSET
+ ldr x1, =COREPMCR_WFIL2
+ bl write_reg_scfg
+
+ isb
+ mov x30, x4
+ ret
+endfunc _soc_sys_prep_pwrdn
+
+/*
+ * Part of CPU_SUSPEND
+ * this function puts the calling core, and potentially the soc, into a
+ * low-power state
+ * in: x0 = core mask lsb
+ * out: x0 = 0, success
+ * x0 < 0, failure
+ * uses x0, x1, x2, x3, x4
+ */
+func _soc_sys_pwrdn_wfi
+ mov x4, x30
+
+ /* request LPM20 */
+ mov x0, #RCPM_POWMGTCSR_OFFSET
+ bl read_reg_rcpm
+ orr x1, x0, #RCPM_POWMGTCSR_LPM20_REQ
+ mov x0, #RCPM_POWMGTCSR_OFFSET
+ bl write_reg_rcpm
+
+ dsb sy
+ isb
+ wfi
+
+ mov x30, x4
+ ret
+endfunc _soc_sys_pwrdn_wfi
+
+/*
+ * Part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+func _soc_sys_exit_pwrdn
+ /* clear WFIL2_EN in SCFG_COREPMCR */
+ mov x1, #NXP_SCFG_ADDR
+ str wzr, [x1, #SCFG_COREPMCR_OFFSET]
+
+ ret
+endfunc _soc_sys_exit_pwrdn
diff --git a/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S b/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S
new file mode 100644
index 0000000..a213594
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+ .globl plat_secondary_cold_boot_setup
+ .globl plat_is_my_cpu_primary
+ .globl plat_reset_handler
+ .globl platform_mem_init
+
+func platform_mem1_init
+ ret
+endfunc platform_mem1_init
+
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+func l2_mem_init
+ /* Initialize the L2 RAM latency */
+ mrs x1, S3_1_c11_c0_2
+ mov x0, #0x1C7
+ /* Clear L2 Tag RAM latency and L2 Data RAM latency */
+ bic x1, x1, x0
+ /* Set L2 data ram latency bits [2:0] */
+ orr x1, x1, #0x2
+ /* set L2 tag ram latency bits [8:6] */
+ orr x1, x1, #0x80
+ msr S3_1_c11_c0_2, x1
+ isb
+ ret
+endfunc l2_mem_init
+
+func apply_platform_errata
+ ret
+endfunc apply_platform_errata
+
+func plat_reset_handler
+ mov x29, x30
+#if (defined(IMAGE_BL2) && RESET_TO_BL2)
+ bl l2_mem_init
+#endif
+ bl apply_platform_errata
+
+#if defined(IMAGE_BL31)
+ ldr x0, =POLICY_SMMU_PAGESZ_64K
+ cbz x0, 1f
+ /* Set the SMMU page size in the SACR register */
+ bl _set_smmu_pagesz_64
+#endif
+1:
+ /*
+ * May be cntfrq_el0 needs to be assigned
+ * the value COUNTER_FREQUENCY
+ */
+ mov x30, x29
+ ret
+endfunc plat_reset_handler
+
+/*
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ */
+func plat_secondary_cold_boot_setup
+ /* ls1046a does not do cold boot for secondary CPU */
+cb_panic:
+ b cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+/*
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary cpu.
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, 0x0
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
diff --git a/plat/nxp/soc-ls1046a/include/ns_access.h b/plat/nxp/soc-ls1046a/include/ns_access.h
new file mode 100644
index 0000000..25c1964
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/include/ns_access.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2017-2018, 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NS_ACCESS_H
+#define NS_ACCESS_H
+
+#include <csu.h>
+
+enum csu_cslx_ind {
+ CSU_CSLX_PCIE2_IO = 0,
+ CSU_CSLX_PCIE1_IO,
+ CSU_CSLX_MG2TPR_IP,
+ CSU_CSLX_IFC_MEM,
+ CSU_CSLX_OCRAM,
+ CSU_CSLX_GIC,
+ CSU_CSLX_PCIE1,
+ CSU_CSLX_OCRAM2,
+ CSU_CSLX_QSPI_MEM,
+ CSU_CSLX_PCIE2,
+ CSU_CSLX_SATA,
+ CSU_CSLX_USB1,
+ CSU_CSLX_QM_BM_SWPORTAL,
+ CSU_CSLX_PCIE3 = 16,
+ CSU_CSLX_PCIE3_IO,
+ CSU_CSLX_USB3 = 20,
+ CSU_CSLX_USB2,
+ CSU_CSLX_PFE = 23,
+ CSU_CSLX_SERDES = 32,
+ CSU_CSLX_QDMA,
+ CSU_CSLX_LPUART2,
+ CSU_CSLX_LPUART1,
+ CSU_CSLX_LPUART4,
+ CSU_CSLX_LPUART3,
+ CSU_CSLX_LPUART6,
+ CSU_CSLX_LPUART5,
+ CSU_CSLX_DSPI1 = 41,
+ CSU_CSLX_QSPI,
+ CSU_CSLX_ESDHC,
+ CSU_CSLX_IFC = 45,
+ CSU_CSLX_I2C1,
+ CSU_CSLX_USB_2,
+ CSU_CSLX_I2C3 = 48,
+ CSU_CSLX_I2C2,
+ CSU_CSLX_DUART2 = 50,
+ CSU_CSLX_DUART1,
+ CSU_CSLX_WDT2,
+ CSU_CSLX_WDT1,
+ CSU_CSLX_EDMA,
+ CSU_CSLX_SYS_CNT,
+ CSU_CSLX_DMA_MUX2,
+ CSU_CSLX_DMA_MUX1,
+ CSU_CSLX_DDR,
+ CSU_CSLX_QUICC,
+ CSU_CSLX_DCFG_CCU_RCPM = 60,
+ CSU_CSLX_SECURE_BOOTROM,
+ CSU_CSLX_SFP,
+ CSU_CSLX_TMU,
+ CSU_CSLX_SECURE_MONITOR,
+ CSU_CSLX_SCFG,
+ CSU_CSLX_FM = 66,
+ CSU_CSLX_SEC5_5,
+ CSU_CSLX_BM,
+ CSU_CSLX_QM,
+ CSU_CSLX_GPIO2 = 70,
+ CSU_CSLX_GPIO1,
+ CSU_CSLX_GPIO4,
+ CSU_CSLX_GPIO3,
+ CSU_CSLX_PLATFORM_CONT,
+ CSU_CSLX_CSU,
+ CSU_CSLX_IIC4 = 77,
+ CSU_CSLX_WDT4,
+ CSU_CSLX_WDT3,
+ CSU_CSLX_ESDHC2 = 80,
+ CSU_CSLX_WDT5 = 81,
+ CSU_CSLX_SAI2,
+ CSU_CSLX_SAI1,
+ CSU_CSLX_SAI4,
+ CSU_CSLX_SAI3,
+ CSU_CSLX_FTM2 = 86,
+ CSU_CSLX_FTM1,
+ CSU_CSLX_FTM4,
+ CSU_CSLX_FTM3,
+ CSU_CSLX_FTM6 = 90,
+ CSU_CSLX_FTM5,
+ CSU_CSLX_FTM8,
+ CSU_CSLX_FTM7,
+ CSU_CSLX_DSCR = 121,
+};
+
+struct csu_ns_dev_st ns_dev[] = {
+ {CSU_CSLX_PCIE2_IO, CSU_ALL_RW},
+ {CSU_CSLX_PCIE1_IO, CSU_ALL_RW},
+ {CSU_CSLX_MG2TPR_IP, CSU_ALL_RW},
+ {CSU_CSLX_IFC_MEM, CSU_ALL_RW},
+ {CSU_CSLX_OCRAM, CSU_S_SUP_RW},
+ {CSU_CSLX_GIC, CSU_ALL_RW},
+ {CSU_CSLX_PCIE1, CSU_ALL_RW},
+ {CSU_CSLX_OCRAM2, CSU_S_SUP_RW},
+ {CSU_CSLX_QSPI_MEM, CSU_ALL_RW},
+ {CSU_CSLX_PCIE2, CSU_ALL_RW},
+ {CSU_CSLX_SATA, CSU_ALL_RW},
+ {CSU_CSLX_USB1, CSU_ALL_RW},
+ {CSU_CSLX_QM_BM_SWPORTAL, CSU_ALL_RW},
+ {CSU_CSLX_PCIE3, CSU_ALL_RW},
+ {CSU_CSLX_PCIE3_IO, CSU_ALL_RW},
+ {CSU_CSLX_USB3, CSU_ALL_RW},
+ {CSU_CSLX_USB2, CSU_ALL_RW},
+ {CSU_CSLX_PFE, CSU_ALL_RW},
+ {CSU_CSLX_SERDES, CSU_ALL_RW},
+ {CSU_CSLX_QDMA, CSU_ALL_RW},
+ {CSU_CSLX_LPUART2, CSU_ALL_RW},
+ {CSU_CSLX_LPUART1, CSU_ALL_RW},
+ {CSU_CSLX_LPUART4, CSU_ALL_RW},
+ {CSU_CSLX_LPUART3, CSU_ALL_RW},
+ {CSU_CSLX_LPUART6, CSU_ALL_RW},
+ {CSU_CSLX_LPUART5, CSU_ALL_RW},
+ {CSU_CSLX_DSPI1, CSU_ALL_RW},
+ {CSU_CSLX_QSPI, CSU_ALL_RW},
+ {CSU_CSLX_ESDHC, CSU_ALL_RW},
+ {CSU_CSLX_IFC, CSU_ALL_RW},
+ {CSU_CSLX_I2C1, CSU_ALL_RW},
+ {CSU_CSLX_USB_2, CSU_ALL_RW},
+ {CSU_CSLX_I2C3, CSU_ALL_RW},
+ {CSU_CSLX_I2C2, CSU_ALL_RW},
+ {CSU_CSLX_DUART2, CSU_ALL_RW},
+ {CSU_CSLX_DUART1, CSU_ALL_RW},
+ {CSU_CSLX_WDT2, CSU_ALL_RW},
+ {CSU_CSLX_WDT1, CSU_ALL_RW},
+ {CSU_CSLX_EDMA, CSU_ALL_RW},
+ {CSU_CSLX_SYS_CNT, CSU_ALL_RW},
+ {CSU_CSLX_DMA_MUX2, CSU_ALL_RW},
+ {CSU_CSLX_DMA_MUX1, CSU_ALL_RW},
+ {CSU_CSLX_DDR, CSU_ALL_RW},
+ {CSU_CSLX_QUICC, CSU_ALL_RW},
+ {CSU_CSLX_DCFG_CCU_RCPM, CSU_ALL_RW},
+ {CSU_CSLX_SECURE_BOOTROM, CSU_ALL_RW},
+ {CSU_CSLX_SFP, CSU_ALL_RW},
+ {CSU_CSLX_TMU, CSU_ALL_RW},
+ {CSU_CSLX_SECURE_MONITOR, CSU_ALL_RW},
+ {CSU_CSLX_SCFG, CSU_ALL_RW},
+ {CSU_CSLX_FM, CSU_ALL_RW},
+ {CSU_CSLX_SEC5_5, CSU_ALL_RW},
+ {CSU_CSLX_BM, CSU_ALL_RW},
+ {CSU_CSLX_QM, CSU_ALL_RW},
+ {CSU_CSLX_GPIO2, CSU_ALL_RW},
+ {CSU_CSLX_GPIO1, CSU_ALL_RW},
+ {CSU_CSLX_GPIO4, CSU_ALL_RW},
+ {CSU_CSLX_GPIO3, CSU_ALL_RW},
+ {CSU_CSLX_PLATFORM_CONT, CSU_ALL_RW},
+ {CSU_CSLX_CSU, CSU_ALL_RW},
+ {CSU_CSLX_IIC4, CSU_ALL_RW},
+ {CSU_CSLX_WDT4, CSU_ALL_RW},
+ {CSU_CSLX_WDT3, CSU_ALL_RW},
+ {CSU_CSLX_ESDHC2, CSU_ALL_RW},
+ {CSU_CSLX_WDT5, CSU_ALL_RW},
+ {CSU_CSLX_SAI2, CSU_ALL_RW},
+ {CSU_CSLX_SAI1, CSU_ALL_RW},
+ {CSU_CSLX_SAI4, CSU_ALL_RW},
+ {CSU_CSLX_SAI3, CSU_ALL_RW},
+ {CSU_CSLX_FTM2, CSU_ALL_RW},
+ {CSU_CSLX_FTM1, CSU_ALL_RW},
+ {CSU_CSLX_FTM4, CSU_ALL_RW},
+ {CSU_CSLX_FTM3, CSU_ALL_RW},
+ {CSU_CSLX_FTM6, CSU_ALL_RW},
+ {CSU_CSLX_FTM5, CSU_ALL_RW},
+ {CSU_CSLX_FTM8, CSU_ALL_RW},
+ {CSU_CSLX_FTM7, CSU_ALL_RW},
+ {CSU_CSLX_DSCR, CSU_ALL_RW},
+};
+
+#endif /* NS_ACCESS_H */
diff --git a/plat/nxp/soc-ls1046a/include/soc.h b/plat/nxp/soc-ls1046a/include/soc.h
new file mode 100644
index 0000000..67810c3
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/include/soc.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SOC_H
+#define SOC_H
+
+/* Chassis specific defines - common across SoC's of a particular platform */
+#include <dcfg_lsch2.h>
+
+#include <soc_default_base_addr.h>
+#include <soc_default_helper_macros.h>
+
+/* DDR Regions Info */
+#define NUM_DRAM_REGIONS U(3)
+#define NXP_DRAM0_ADDR ULL(0x80000000)
+#define NXP_DRAM0_MAX_SIZE ULL(0x80000000) /* 2 GB */
+
+#define NXP_DRAM1_ADDR ULL(0x880000000)
+#define NXP_DRAM1_MAX_SIZE ULL(0x780000000) /* 30 GB */
+
+#define NXP_DRAM2_ADDR ULL(0x8800000000)
+#define NXP_DRAM2_MAX_SIZE ULL(0x7800000000) /* 480 GB */
+
+/*DRAM0 Size defined in platform_def.h */
+#define NXP_DRAM0_SIZE PLAT_DEF_DRAM0_SIZE
+
+/*
+ * SVR Definition (not include major and minor rev)
+ * A: without security
+ * AE: with security
+ */
+#define SVR_LS1026A 0x870709
+#define SVR_LS1026AE 0x870708
+#define SVR_LS1046A 0x870701
+#define SVR_LS1046AE 0x870700
+
+/* Number of cores in platform */
+/* Used by common code for array initialization */
+#define NUMBER_OF_CLUSTERS U(1)
+#define CORES_PER_CLUSTER U(4)
+#define PLATFORM_CORE_COUNT (NUMBER_OF_CLUSTERS * CORES_PER_CLUSTER)
+
+/*
+ * Required LS standard platform porting definitions
+ * for CCI-400
+ */
+#define NXP_CCI_CLUSTER0_SL_IFACE_IX 4
+
+
+/* Defines required for using XLAT tables from ARM common code */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 40)
+
+/* Clock Divisors */
+#define NXP_PLATFORM_CLK_DIVIDER U(1)
+#define NXP_UART_CLK_DIVIDER U(2)
+
+/* set to 0 if the clusters are not symmetrical */
+#define SYMMETRICAL_CLUSTERS U(1)
+
+ /*
+ * set this switch to 1 if you need to keep the debug block
+ * clocked during system power-down
+ */
+#define DEBUG_ACTIVE 0
+
+ /*
+ * pwr mgmt features supported in the soc-specific code:
+ * value == 0x0 the soc code does not support this feature
+ * value != 0x0 the soc code supports this feature
+ */
+#define SOC_CORE_RELEASE 0x1
+#define SOC_CORE_RESTART 0x1
+#define SOC_CORE_OFF 0x1
+#define SOC_CORE_STANDBY 0x1
+#define SOC_CORE_PWR_DWN 0x1
+#define SOC_CLUSTER_STANDBY 0x1
+#define SOC_CLUSTER_PWR_DWN 0x1
+#define SOC_SYSTEM_STANDBY 0x1
+#define SOC_SYSTEM_PWR_DWN 0x1
+#define SOC_SYSTEM_OFF 0x1
+#define SOC_SYSTEM_RESET 0x1
+
+/* Start: Macros used by lib/psci files */
+#define SYSTEM_PWR_DOMAINS 1
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
+ NUMBER_OF_CLUSTERS + \
+ SYSTEM_PWR_DOMAINS)
+
+/* Power state coordination occurs at the system level */
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
+
+/* define retention state */
+#define PLAT_MAX_RET_STATE (PSCI_LOCAL_STATE_RUN + 1)
+
+/* define power-down state */
+#define PLAT_MAX_OFF_STATE (PLAT_MAX_RET_STATE + 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.
+ *
+ * CACHE_WRITEBACK_GRANULE is defined in soc.def
+ */
+
+ /* One cache line needed for bakery locks on ARM platforms */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
+
+#ifndef __ASSEMBLER__
+/* CCI slave interfaces */
+static const int cci_map[] = {
+ NXP_CCI_CLUSTER0_SL_IFACE_IX,
+};
+
+void soc_init_lowlevel(void);
+void soc_init_percpu(void);
+void _soc_set_start_addr(unsigned long addr);
+#endif
+
+#endif /* SOC_H */
diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/ddr_init.c b/plat/nxp/soc-ls1046a/ls1046afrwy/ddr_init.c
new file mode 100644
index 0000000..3d561c7
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046afrwy/ddr_init.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <lib/utils.h>
+
+#include <errata.h>
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+const struct ddr_cfg_regs static_1600 = {
+ .cs[0].config = U(0x80010412),
+ .cs[0].bnds = U(0x7F),
+ .sdram_cfg[0] = U(0xE50C0008),
+ .sdram_cfg[1] = U(0x00401010),
+ .sdram_cfg[2] = U(0x1),
+ .timing_cfg[0] = U(0xFA550018),
+ .timing_cfg[1] = U(0xBAB40C52),
+ .timing_cfg[2] = U(0x0048C11C),
+ .timing_cfg[3] = U(0x01111000),
+ .timing_cfg[4] = U(0x00000002),
+ .timing_cfg[5] = U(0x03401400),
+ .timing_cfg[6] = U(0x0),
+ .timing_cfg[7] = U(0x23300000),
+ .timing_cfg[8] = U(0x02116600),
+ .timing_cfg[9] = U(0x0),
+ .dq_map[0] = U(0x0),
+ .dq_map[1] = U(0x0),
+ .dq_map[2] = U(0x0),
+ .dq_map[3] = U(0x0),
+ .sdram_mode[0] = U(0x01010210),
+ .sdram_mode[1] = U(0x0),
+ .sdram_mode[8] = U(0x00000500),
+ .sdram_mode[9] = U(0x04000000),
+ .interval = U(0x18600618),
+ .zq_cntl = U(0x8A090705),
+ .ddr_sr_cntr = U(0x0),
+ .clk_cntl = U(0x2000000),
+ .cdr[0] = U(0x80040000),
+ .cdr[1] = U(0xC1),
+ .wrlvl_cntl[0] = U(0x86550607),
+ .wrlvl_cntl[1] = U(0x07070708),
+ .wrlvl_cntl[2] = U(0x0808088),
+};
+
+long long board_static_ddr(struct ddr_info *priv)
+{
+ memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600));
+
+ return 0x80000000ULL;
+}
+#else /* ifndef CONFIG_STATIC_DDR */
+static const struct rc_timing rcz[] = {
+ {U(1600), U(8), U(7)},
+ {U(2100), U(8), U(7)},
+ {}
+};
+
+static const struct board_timing ram[] = {
+ {U(0x1f), rcz, U(0x01010101), U(0x01010101)},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ ret = cal_board_params(priv, ram, ARRAY_SIZE(ram));
+ if (ret != 0) {
+ return ret;
+ }
+
+ popts->bstopre = 0;
+ popts->half_strength_drive_en = 1;
+ popts->cpo_sample = U(0x46);
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_50ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_50ohm) |
+ DDR_CDR2_VREF_TRAIN_EN;
+ popts->output_driver_impedance = 1;
+
+ return 0;
+}
+
+/* DDR model number: MT40A512M16JY-083E:B */
+struct dimm_params ddr_raw_timing = {
+ .n_ranks = U(1),
+ .rank_density = ULL(4294967296),
+ .capacity = ULL(4294967296),
+ .primary_sdram_width = U(64),
+ .ec_sdram_width = U(8),
+ .rdimm = U(0),
+ .mirrored_dimm = U(0),
+ .n_row_addr = U(16),
+ .n_col_addr = U(10),
+ .bank_group_bits = U(1),
+ .edc_config = U(2),
+ .burst_lengths_bitmask = U(0x0c),
+ .tckmin_x_ps = 750,
+ .tckmax_ps = 1900,
+ .caslat_x = U(0x0001FFE00),
+ .taa_ps = 13500,
+ .trcd_ps = 13500,
+ .trp_ps = 13500,
+ .tras_ps = 33000,
+ .trc_ps = 46500,
+ .twr_ps = 15000,
+ .trfc1_ps = 350000,
+ .trfc2_ps = 260000,
+ .trfc4_ps = 160000,
+ .tfaw_ps = 30000,
+ .trrds_ps = 5300,
+ .trrdl_ps = 6400,
+ .tccdl_ps = 5355,
+ .refresh_rate_ps = U(7800000),
+ .dq_mapping[0] = U(0x0),
+ .dq_mapping[1] = U(0x0),
+ .dq_mapping[2] = U(0x0),
+ .dq_mapping[3] = U(0x0),
+ .dq_mapping[4] = U(0x0),
+ .dq_mapping_ors = U(0),
+ .rc = U(0x1f),
+};
+
+int ddr_get_ddr_params(struct dimm_params *pdimm, struct ddr_conf *conf)
+{
+ static const char dimm_model[] = "Fixed DDR on board";
+
+ conf->dimm_in_use[0] = 1;
+ memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params));
+ memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
+
+ return 1;
+}
+#endif /* ifdef CONFIG_STATIC_DDR */
+
+long long init_ddr(void)
+{
+ int spd_addr[] = {NXP_SPD_EEPROM0};
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ if (get_clocks(&sys)) {
+ ERROR("System clocks are not set\n");
+ assert(0);
+ }
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
+ debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = 1;
+ info.dimm_on_ctlr = 1;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+#ifdef ERRATA_SOC_A008850
+ erratum_a008850_post();
+#endif
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/plat_def.h b/plat/nxp/soc-ls1046a/ls1046afrwy/plat_def.h
new file mode 100644
index 0000000..5134a00
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046afrwy/plat_def.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY Images.
+ */
+#include <tbbr_img_def.h>
+
+#include "policy.h"
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0 0x51
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+/* SD block buffer */
+#define NXP_SD_BLOCK_BUF_SIZE (0x8000)
+#define NXP_SD_BLOCK_BUF_ADDR ULL(0x80000000)
+
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES U(3)
+#define MAX_IO_BLOCK_DEVICES U(1)
+#define MAX_IO_HANDLES U(4)
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES U(2)
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES U(1)
+#endif
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define BL32_IRQ_SEC_PHY_TIMER 29
+
+/*
+ * Define properties 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_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+#define PLAT_LS_G0_IRQ_PROPS(grp)
+
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/platform.c b/plat/nxp/soc-ls1046a/ls1046afrwy/platform.c
new file mode 100644
index 0000000..cef920f
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046afrwy/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/platform.mk b/plat/nxp/soc-ls1046a/ls1046afrwy/platform.mk
new file mode 100644
index 0000000..1f7fad6
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046afrwy/platform.mk
@@ -0,0 +1,39 @@
+#
+# Copyright 2018-2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+
+BOOT_MODE ?= qspi
+BOARD := ls1046afrwy
+POVDD_ENABLE := no
+
+# DDR Compilation Configs
+CONFIG_STATIC_DDR := 0
+CONFIG_DDR_NODIMM := 1
+DDRC_NUM_DIMM := 0
+NUM_OF_DDRC := 1
+DDRC_NUM_CS := 1
+DDR_ECC_EN := yes
+
+# On-Board Flash Details
+QSPI_FLASH_SZ := 0x20000000
+NOR_FLASH_SZ := 0x20000000
+
+# Platform specific features.
+WARM_BOOT := no
+
+# Adding Platform files build files
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := qspi \
+ sd
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1046a/soc.mk
diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/platform_def.h b/plat/nxp/soc-ls1046a/ls1046afrwy/platform_def.h
new file mode 100644
index 0000000..7f98bb1
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046afrwy/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/policy.h b/plat/nxp/soc-ls1046a/ls1046afrwy/policy.h
new file mode 100644
index 0000000..c6c325f
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046afrwy/policy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/* Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c b/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c
new file mode 100644
index 0000000..89c9c0a
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <lib/utils.h>
+
+#include <errata.h>
+#include "platform_def.h"
+
+static const struct rc_timing rce[] = {
+ {U(1600), U(8), U(7)},
+ {U(1867), U(8), U(7)},
+ {U(2134), U(8), U(9)},
+ {}
+};
+
+static const struct board_timing udimm[] = {
+ {U(0x04), rce, U(0x01020304), U(0x06070805)},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ if (popts->rdimm) {
+ debug("RDIMM parameters not set.\n");
+ return -EINVAL;
+ }
+
+ ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
+ if (ret != 0) {
+ return ret;
+ }
+
+ popts->wrlvl_override = U(1);
+ popts->wrlvl_sample = U(0x0); /* 32 clocks */
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
+ DDR_CDR2_VREF_TRAIN_EN |
+ DDR_CDR2_VREF_RANGE_2;
+
+ /* optimize cpo for erratum A-009942 */
+ popts->cpo_sample = U(0x70);
+
+ return 0;
+}
+
+long long init_ddr(void)
+{
+ int spd_addr[] = { NXP_SPD_EEPROM0 };
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ if (get_clocks(&sys)) {
+ ERROR("System clocks are not set\n");
+ assert(0);
+ }
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
+ debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = 1;
+ info.dimm_on_ctlr = 1;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+#ifdef ERRATA_SOC_A008850
+ erratum_a008850_post();
+#endif
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/plat_def.h b/plat/nxp/soc-ls1046a/ls1046aqds/plat_def.h
new file mode 100644
index 0000000..aa69a66
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046aqds/plat_def.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/* Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0 0x51
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+/* SD block buffer */
+#define NXP_SD_BLOCK_BUF_SIZE (0x00100000)
+#define NXP_SD_BLOCK_BUF_ADDR ULL(0x80000000)
+
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES U(3)
+#define MAX_IO_BLOCK_DEVICES U(1)
+#define MAX_IO_HANDLES U(4)
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES U(2)
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES U(1)
+#endif
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define BL32_IRQ_SEC_PHY_TIMER 29
+
+/*
+ * Define properties 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_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+#define PLAT_LS_G0_IRQ_PROPS(grp)
+
+#endif
diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/platform.c b/plat/nxp/soc-ls1046a/ls1046aqds/platform.c
new file mode 100644
index 0000000..cef920f
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046aqds/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/platform.mk b/plat/nxp/soc-ls1046a/ls1046aqds/platform.mk
new file mode 100644
index 0000000..9600b93
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046aqds/platform.mk
@@ -0,0 +1,39 @@
+#
+# Copyright 2018-2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+BOOT_MODE ?= qspi
+BOARD := ls1046aqds
+POVDD_ENABLE := no
+
+ # DDR Compilation Configs
+NUM_OF_DDRC := 1
+DDRC_NUM_DIMM := 1
+DDRC_NUM_CS := 4
+DDR_ECC_EN := yes
+CONFIG_STATIC_DDR := 0
+
+# On-Board Flash Details
+QSPI_FLASH_SZ := 0x20000000
+NOR_FLASH_SZ := 0x20000000
+
+# Platform specific features.
+WARM_BOOT := no
+
+# Adding Platform files build files
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := qspi \
+ sd \
+ nor \
+ nand
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1046a/soc.mk
diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/platform_def.h b/plat/nxp/soc-ls1046a/ls1046aqds/platform_def.h
new file mode 100644
index 0000000..7f98bb1
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046aqds/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/policy.h b/plat/nxp/soc-ls1046a/ls1046aqds/policy.h
new file mode 100644
index 0000000..c6c325f
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046aqds/policy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/* Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/ddr_init.c b/plat/nxp/soc-ls1046a/ls1046ardb/ddr_init.c
new file mode 100644
index 0000000..b9940cf
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046ardb/ddr_init.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <lib/utils.h>
+
+#include <errata.h>
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+const struct ddr_cfg_regs static_2100 = {
+ .cs[0].config = U(0x80040322),
+ .cs[0].bnds = U(0x1FF),
+ .cs[1].config = U(0x80000322),
+ .cs[1].bnds = U(0x1FF),
+ .sdram_cfg[0] = U(0xE5004000),
+ .sdram_cfg[1] = U(0x401151),
+ .timing_cfg[0] = U(0xD1770018),
+ .timing_cfg[1] = U(0xF2FC9245),
+ .timing_cfg[2] = U(0x594197),
+ .timing_cfg[3] = U(0x2101100),
+ .timing_cfg[4] = U(0x220002),
+ .timing_cfg[5] = U(0x5401400),
+ .timing_cfg[7] = U(0x26600000),
+ .timing_cfg[8] = U(0x5446A00),
+ .dq_map[0] = U(0x32C57554),
+ .dq_map[1] = U(0xD4BB0BD4),
+ .dq_map[2] = U(0x2EC2F554),
+ .dq_map[3] = U(0xD95D4001),
+ .sdram_mode[0] = U(0x3010631),
+ .sdram_mode[1] = U(0x100200),
+ .sdram_mode[9] = U(0x8400000),
+ .sdram_mode[8] = U(0x500),
+ .sdram_mode[2] = U(0x10631),
+ .sdram_mode[3] = U(0x100200),
+ .sdram_mode[10] = U(0x400),
+ .sdram_mode[11] = U(0x8400000),
+ .sdram_mode[4] = U(0x10631),
+ .sdram_mode[5] = U(0x100200),
+ .sdram_mode[12] = U(0x400),
+ .sdram_mode[13] = U(0x8400000),
+ .sdram_mode[6] = U(0x10631),
+ .sdram_mode[7] = U(0x100200),
+ .sdram_mode[14] = U(0x400),
+ .sdram_mode[15] = U(0x8400000),
+ .interval = U(0x1FFE07FF),
+ .zq_cntl = U(0x8A090705),
+ .clk_cntl = U(0x2000000),
+ .cdr[0] = U(0x80040000),
+ .cdr[1] = U(0xC1),
+ .wrlvl_cntl[0] = U(0x86750609),
+ .wrlvl_cntl[1] = U(0xA0B0C0D),
+ .wrlvl_cntl[2] = U(0xF10110E),
+};
+
+const struct ddr_cfg_regs static_1800 = {
+ .cs[0].config = U(0x80040322),
+ .cs[0].bnds = U(0x1FF),
+ .cs[1].config = U(0x80000322),
+ .cs[1].bnds = U(0x1FF),
+ .sdram_cfg[0] = U(0xE5004000),
+ .sdram_cfg[1] = U(0x401151),
+ .timing_cfg[0] = U(0x91660018),
+ .timing_cfg[1] = U(0xDDD82045),
+ .timing_cfg[2] = U(0x512153),
+ .timing_cfg[3] = U(0x10E1100),
+ .timing_cfg[4] = U(0x220002),
+ .timing_cfg[5] = U(0x4401400),
+ .timing_cfg[7] = U(0x14400000),
+ .timing_cfg[8] = U(0x3335900),
+ .dq_map[0] = U(0x32C57554),
+ .dq_map[1] = U(0xD4BB0BD4),
+ .dq_map[2] = U(0x2EC2F554),
+ .dq_map[3] = U(0xD95D4001),
+ .sdram_mode[0] = U(0x3010421),
+ .sdram_mode[1] = U(0x80200),
+ .sdram_mode[9] = U(0x4400000),
+ .sdram_mode[8] = U(0x500),
+ .sdram_mode[2] = U(0x10421),
+ .sdram_mode[3] = U(0x80200),
+ .sdram_mode[10] = U(0x400),
+ .sdram_mode[11] = U(0x4400000),
+ .sdram_mode[4] = U(0x10421),
+ .sdram_mode[5] = U(0x80200),
+ .sdram_mode[12] = U(0x400),
+ .sdram_mode[13] = U(0x4400000),
+ .sdram_mode[6] = U(0x10421),
+ .sdram_mode[7] = U(0x80200),
+ .sdram_mode[14] = U(0x400),
+ .sdram_mode[15] = U(0x4400000),
+ .interval = U(0x1B6C06DB),
+ .zq_cntl = U(0x8A090705),
+ .clk_cntl = U(0x2000000),
+ .cdr[0] = U(0x80040000),
+ .cdr[1] = U(0xC1),
+ .wrlvl_cntl[0] = U(0x86750607),
+ .wrlvl_cntl[1] = U(0x8090A0B),
+ .wrlvl_cntl[2] = U(0xD0E0F0C),
+};
+
+const struct ddr_cfg_regs static_1600 = {
+ .cs[0].config = U(0x80040322),
+ .cs[0].bnds = U(0x1FF),
+ .cs[1].config = U(0x80000322),
+ .cs[1].bnds = U(0x1FF),
+ .sdram_cfg[0] = U(0xE5004000),
+ .sdram_cfg[1] = U(0x401151),
+ .sdram_cfg[2] = U(0x0),
+ .timing_cfg[0] = U(0x91550018),
+ .timing_cfg[1] = U(0xBAB48E44),
+ .timing_cfg[2] = U(0x490111),
+ .timing_cfg[3] = U(0x10C1000),
+ .timing_cfg[4] = U(0x220002),
+ .timing_cfg[5] = U(0x3401400),
+ .timing_cfg[6] = U(0x0),
+ .timing_cfg[7] = U(0x13300000),
+ .timing_cfg[8] = U(0x1224800),
+ .timing_cfg[9] = U(0x0),
+ .dq_map[0] = U(0x32C57554),
+ .dq_map[1] = U(0xD4BB0BD4),
+ .dq_map[2] = U(0x2EC2F554),
+ .dq_map[3] = U(0xD95D4001),
+ .sdram_mode[0] = U(0x3010211),
+ .sdram_mode[1] = U(0x0),
+ .sdram_mode[9] = U(0x400000),
+ .sdram_mode[8] = U(0x500),
+ .sdram_mode[2] = U(0x10211),
+ .sdram_mode[3] = U(0x0),
+ .sdram_mode[10] = U(0x400),
+ .sdram_mode[11] = U(0x400000),
+ .sdram_mode[4] = U(0x10211),
+ .sdram_mode[5] = U(0x0),
+ .sdram_mode[12] = U(0x400),
+ .sdram_mode[13] = U(0x400000),
+ .sdram_mode[6] = U(0x10211),
+ .sdram_mode[7] = U(0x0),
+ .sdram_mode[14] = U(0x400),
+ .sdram_mode[15] = U(0x400000),
+ .interval = U(0x18600618),
+ .zq_cntl = U(0x8A090705),
+ .ddr_sr_cntr = U(0x0),
+ .clk_cntl = U(0x2000000),
+ .cdr[0] = U(0x80040000),
+ .cdr[1] = U(0xC1),
+ .wrlvl_cntl[0] = U(0x86750607),
+ .wrlvl_cntl[1] = U(0x8090A0B),
+ .wrlvl_cntl[2] = U(0xD0E0F0C),
+};
+
+struct static_table {
+ unsigned long rate;
+ const struct ddr_cfg_regs *regs;
+};
+
+const struct static_table table[] = {
+ {1600, &static_1600},
+ {1800, &static_1800},
+ {2100, &static_2100},
+};
+
+long long board_static_ddr(struct ddr_info *priv)
+{
+ const unsigned long clk = priv->clk / 1000000;
+ long long size = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(table); i++) {
+ if (table[i].rate >= clk) {
+ break;
+ }
+ }
+ if (i < ARRAY_SIZE(table)) {
+ VERBOSE("Found static setting for rate %ld\n", table[i].rate);
+ memcpy(&priv->ddr_reg, table[i].regs,
+ sizeof(struct ddr_cfg_regs));
+ size = 0x200000000UL;
+ } else {
+ ERROR("Not static settings for rate %ld\n", clk);
+ }
+
+ return size;
+}
+#else /* ifndef CONFIG_STATIC_DDR */
+static const struct rc_timing rce[] = {
+ {U(1600), U(8), U(7)},
+ {U(1867), U(8), U(7)},
+ {U(2134), U(8), U(9)},
+ {}
+};
+
+static const struct board_timing udimm[] = {
+ {U(0x04), rce, U(0x01020304), U(0x06070805)},
+ {U(0x1f), rce, U(0x01020304), U(0x06070805)},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ if (popts->rdimm) {
+ debug("RDIMM parameters not set.\n");
+ return -EINVAL;
+ }
+
+ ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
+ if (ret != 0) {
+ return ret;
+ }
+
+ popts->wrlvl_override = U(1);
+ popts->wrlvl_sample = U(0x0); /* 32 clocks */
+ popts->cpo_sample = U(0x61);
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
+ DDR_CDR2_VREF_TRAIN_EN |
+ DDR_CDR2_VREF_RANGE_2;
+ popts->bstopre = U(0);
+
+ return 0;
+}
+#endif /* ifdef CONFIG_STATIC_DDR */
+
+long long init_ddr(void)
+{
+ int spd_addr[] = {NXP_SPD_EEPROM0};
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ if (get_clocks(&sys)) {
+ ERROR("System clocks are not set\n");
+ assert(0);
+ }
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
+ debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = U(1);
+ info.dimm_on_ctlr = U(1);
+ info.clk = get_ddr_freq(&sys, 0);
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+#ifdef ERRATA_SOC_A008850
+ erratum_a008850_post();
+#endif
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/plat_def.h b/plat/nxp/soc-ls1046a/ls1046ardb/plat_def.h
new file mode 100644
index 0000000..b5e66ae
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046ardb/plat_def.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY Images.
+ */
+#include <tbbr_img_def.h>
+
+#include "policy.h"
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0 0x51
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+/* SD block buffer */
+#define NXP_SD_BLOCK_BUF_SIZE (0x00100000)
+#define NXP_SD_BLOCK_BUF_ADDR ULL(0x80000000)
+
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES U(3)
+#define MAX_IO_BLOCK_DEVICES U(1)
+#define MAX_IO_HANDLES U(4)
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES U(2)
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES U(1)
+#endif
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define BL32_IRQ_SEC_PHY_TIMER 29
+
+/*
+ * Define properties 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_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+#define PLAT_LS_G0_IRQ_PROPS(grp)
+
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/platform.c b/plat/nxp/soc-ls1046a/ls1046ardb/platform.c
new file mode 100644
index 0000000..cef920f
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046ardb/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/platform.mk b/plat/nxp/soc-ls1046a/ls1046ardb/platform.mk
new file mode 100644
index 0000000..32e6db5
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046ardb/platform.mk
@@ -0,0 +1,38 @@
+#
+# Copyright 2018-2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+BOOT_MODE ?= qspi
+BOARD := ls1046ardb
+POVDD_ENABLE := no
+
+# DDR Compilation Configs
+NUM_OF_DDRC := 1
+DDRC_NUM_DIMM := 1
+DDRC_NUM_CS := 4
+DDR_ECC_EN := yes
+CONFIG_STATIC_DDR := 0
+
+# On-Board Flash Details
+QSPI_FLASH_SZ := 0x20000000
+NOR_FLASH_SZ := 0x20000000
+
+# Platform specific features.
+WARM_BOOT := no
+
+# Adding Platform files build files
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := qspi \
+ sd \
+ emmc
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1046a/soc.mk
diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/platform_def.h b/plat/nxp/soc-ls1046a/ls1046ardb/platform_def.h
new file mode 100644
index 0000000..7f98bb1
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046ardb/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/policy.h b/plat/nxp/soc-ls1046a/ls1046ardb/policy.h
new file mode 100644
index 0000000..c6c325f
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/ls1046ardb/policy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/* Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1046a/soc.c b/plat/nxp/soc-ls1046a/soc.c
new file mode 100644
index 0000000..6dfea89
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/soc.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright 2018-2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <caam.h>
+#include <cassert.h>
+#include <cci.h>
+#include <common/debug.h>
+#include <dcfg.h>
+#ifdef I2C_INIT
+#include <i2c.h>
+#endif
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <ls_interconnect.h>
+#ifdef POLICY_FUSE_PROVISION
+#include <nxp_gpio.h>
+#endif
+#include <nxp_smmu.h>
+#include <nxp_timer.h>
+#include <plat_console.h>
+#include <plat_gic.h>
+#include <plat_tzc400.h>
+#include <scfg.h>
+#if defined(NXP_SFP_ENABLED)
+#include <sfp.h>
+#endif
+
+#include <errata.h>
+#include <ns_access.h>
+#ifdef CONFIG_OCRAM_ECC_EN
+#include <ocram.h>
+#endif
+#include <plat_common.h>
+#include <platform_def.h>
+#include <soc.h>
+
+static dcfg_init_info_t dcfg_init_data = {
+ .g_nxp_dcfg_addr = NXP_DCFG_ADDR,
+ .nxp_sysclk_freq = NXP_SYSCLK_FREQ,
+ .nxp_ddrclk_freq = NXP_DDRCLK_FREQ,
+ .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER,
+};
+
+/* Function to return the SoC SYS CLK */
+static unsigned int get_sys_clk(void)
+{
+ return NXP_SYSCLK_FREQ;
+}
+
+/*
+ * Function returns the base counter frequency
+ * after reading the first entry at CNTFID0 (0x20 offset).
+ *
+ * Function is used by:
+ * 1. ARM common code for PSCI management.
+ * 2. ARM Generic Timer init.
+ *
+ */
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+
+ counter_base_frequency = get_sys_clk() / 4;
+
+ return counter_base_frequency;
+}
+
+#ifdef IMAGE_BL2
+/* Functions for BL2 */
+
+static struct soc_type soc_list[] = {
+ SOC_ENTRY(LS1046A, LS1046A, 1, 4),
+ SOC_ENTRY(LS1046AE, LS1046AE, 1, 4),
+ SOC_ENTRY(LS1026A, LS1026A, 1, 2),
+ SOC_ENTRY(LS1026AE, LS1026AE, 1, 2),
+};
+
+#ifdef POLICY_FUSE_PROVISION
+static gpio_init_info_t gpio_init_data = {
+ .gpio1_base_addr = NXP_GPIO1_ADDR,
+ .gpio2_base_addr = NXP_GPIO2_ADDR,
+ .gpio3_base_addr = NXP_GPIO3_ADDR,
+ .gpio4_base_addr = NXP_GPIO4_ADDR,
+};
+#endif
+
+/*
+ * Function to set the base counter frequency at
+ * the first entry of the Frequency Mode Table,
+ * at CNTFID0 (0x20 offset).
+ *
+ * Set the value of the pirmary core register cntfrq_el0.
+ */
+static void set_base_freq_CNTFID0(void)
+{
+ /*
+ * Below register specifies the base frequency of the system counter.
+ * As per NXP Board Manuals:
+ * The system counter always works with SYS_REF_CLK/4 frequency clock.
+ */
+ unsigned int counter_base_frequency = get_sys_clk() / 4;
+
+ /* Setting the frequency in the Frequency modes table.
+ *
+ * Note: The value for ls1046ardb board at this offset
+ * is not RW as stated. This offset have the
+ * fixed value of 100000400 Hz.
+ *
+ * The below code line has no effect.
+ * Keeping it for other platforms where it has effect.
+ */
+ mmio_write_32(NXP_TIMER_ADDR + CNTFID_OFF, counter_base_frequency);
+
+ write_cntfrq_el0(counter_base_frequency);
+}
+
+void soc_preload_setup(void)
+{
+
+}
+
+/*
+ * This function implements soc specific erratas
+ * This is called before DDR is initialized or MMU is enabled
+ */
+void soc_early_init(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+ dram_regions_info_t *dram_regions_info = get_dram_regions_info();
+
+#ifdef CONFIG_OCRAM_ECC_EN
+ ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
+#endif
+ dcfg_init(&dcfg_init_data);
+#ifdef POLICY_FUSE_PROVISION
+ gpio_init(&gpio_init_data);
+ sec_init(NXP_CAAM_ADDR);
+#endif
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+ set_base_freq_CNTFID0();
+
+ /* Enable snooping on SEC read and write transactions */
+ scfg_setbits32((void *)(NXP_SCFG_ADDR + SCFG_SNPCNFGCR_OFFSET),
+ SCFG_SNPCNFGCR_SECRDSNP | SCFG_SNPCNFGCR_SECWRSNP);
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ */
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ /*
+ * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts.
+ */
+ smmu_cache_unlock(NXP_SMMU_ADDR);
+ INFO("SMMU Cache Unlocking is Configured.\n");
+
+#if TRUSTED_BOARD_BOOT
+ uint32_t mode;
+
+ sfp_init(NXP_SFP_ADDR);
+ /*
+ * For secure boot disable SMMU.
+ * Later when platform security policy comes in picture,
+ * this might get modified based on the policy
+ */
+ if (check_boot_mode_secure(&mode) == true) {
+ bypass_smmu(NXP_SMMU_ADDR);
+ }
+
+ /*
+ * For Mbedtls currently crypto is not supported via CAAM
+ * enable it when that support is there. In tbbr.mk
+ * the CAAM_INTEG is set as 0.
+ */
+#ifndef MBEDTLS_X509
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false) {
+ INFO("SEC is disabled.\n");
+ } else {
+ sec_init(NXP_CAAM_ADDR);
+ }
+#endif
+#elif defined(POLICY_FUSE_PROVISION)
+ gpio_init(&gpio_init_data);
+ sfp_init(NXP_SFP_ADDR);
+ sec_init(NXP_CAAM_ADDR);
+#endif
+
+ soc_errata();
+
+ /* Initialize system level generic timer for Layerscape Socs. */
+ delay_timer_init(NXP_TIMER_ADDR);
+
+#ifdef DDR_INIT
+ i2c_init(NXP_I2C_ADDR);
+ dram_regions_info->total_dram_size = init_ddr();
+#endif
+}
+
+void soc_bl2_prepare_exit(void)
+{
+#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE)
+ set_sfp_wr_disable();
+#endif
+}
+
+/* This function returns the boot device based on RCW_SRC */
+enum boot_device get_boot_dev(void)
+{
+ enum boot_device src = BOOT_DEVICE_NONE;
+ uint32_t porsr1;
+ uint32_t rcw_src, val;
+
+ porsr1 = read_reg_porsr1();
+
+ rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT;
+
+ val = rcw_src & RCW_SRC_NAND_MASK;
+
+ if (val == RCW_SRC_NAND_VAL) {
+ val = rcw_src & NAND_RESERVED_MASK;
+ if ((val != NAND_RESERVED_1) && (val != NAND_RESERVED_2)) {
+ src = BOOT_DEVICE_IFC_NAND;
+ INFO("RCW BOOT SRC is IFC NAND\n");
+ }
+ } else {
+ /* RCW SRC NOR */
+ val = rcw_src & RCW_SRC_NOR_MASK;
+ if (val == NOR_8B_VAL || val == NOR_16B_VAL) {
+ src = BOOT_DEVICE_IFC_NOR;
+ INFO("RCW BOOT SRC is IFC NOR\n");
+ } else {
+ switch (rcw_src) {
+ case QSPI_VAL1:
+ case QSPI_VAL2:
+ src = BOOT_DEVICE_QSPI;
+ INFO("RCW BOOT SRC is QSPI\n");
+ break;
+ case SD_VAL:
+ src = BOOT_DEVICE_EMMC;
+ INFO("RCW BOOT SRC is SD/EMMC\n");
+ break;
+ default:
+ src = BOOT_DEVICE_NONE;
+ }
+ }
+ }
+
+ return src;
+}
+
+/* This function sets up access permissions on memory regions */
+void soc_mem_access(void)
+{
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+ struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION];
+ unsigned int dram_idx, index = 0U;
+
+ for (dram_idx = 0U; dram_idx < info_dram_regions->num_dram_regions;
+ dram_idx++) {
+ if (info_dram_regions->region[dram_idx].size == 0) {
+ ERROR("DDR init failure, or");
+ ERROR("DRAM regions not populated correctly.\n");
+ break;
+ }
+
+ index = populate_tzc400_reg_list(tzc400_reg_list,
+ dram_idx, index,
+ info_dram_regions->region[dram_idx].addr,
+ info_dram_regions->region[dram_idx].size,
+ NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE);
+ }
+
+ mem_access_setup(NXP_TZC_ADDR, index, tzc400_reg_list);
+}
+
+#else /* IMAGE_BL2 */
+/* Functions for BL31 */
+
+const unsigned char _power_domain_tree_desc[] = {1, 1, 4};
+
+CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256,
+ assert_invalid_ls1046_cluster_count);
+
+/* This function returns the SoC topology */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return _power_domain_tree_desc;
+}
+
+/*
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ */
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
+{
+ return CORES_PER_CLUSTER;
+}
+
+void soc_early_platform_setup2(void)
+{
+ dcfg_init(&dcfg_init_data);
+ /* Initialize system level generic timer for SoCs */
+ delay_timer_init(NXP_TIMER_ADDR);
+
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+}
+
+void soc_platform_setup(void)
+{
+ static uint32_t target_mask_array[PLATFORM_CORE_COUNT];
+ /*
+ * On a GICv2 system, the Group 1 secure interrupts are treated
+ * as Group 0 interrupts.
+ */
+ static interrupt_prop_t ls_interrupt_props[] = {
+ PLAT_LS_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
+ PLAT_LS_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
+ };
+
+ plat_ls_gic_driver_init(
+#if (TEST_BL31)
+ /* Defect in simulator - GIC base addresses (4Kb aligned) */
+ NXP_GICD_4K_ADDR,
+ NXP_GICC_4K_ADDR,
+#else
+ NXP_GICD_64K_ADDR,
+ NXP_GICC_64K_ADDR,
+#endif
+ PLATFORM_CORE_COUNT,
+ ls_interrupt_props,
+ ARRAY_SIZE(ls_interrupt_props),
+ target_mask_array);
+
+ plat_ls_gic_init();
+ enable_init_timer();
+}
+
+/* This function initializes the soc from the BL31 module */
+void soc_init(void)
+{
+ /* low-level init of the soc */
+ soc_init_lowlevel();
+ _init_global_data();
+ soc_init_percpu();
+ _initialize_psci();
+
+ /*
+ * Initialize the interconnect during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable coherency in interconnect for the primary CPU's cluster.
+ * Earlier bootloader stages might already do this but we can't
+ * assume so. No harm in executing this code twice.
+ */
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
+
+ /* Init CSU to enable non-secure access to peripherals */
+ enable_layerscape_ns_access(ns_dev, ARRAY_SIZE(ns_dev), NXP_CSU_ADDR);
+
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false) {
+ INFO("SEC is disabled.\n");
+ } else {
+ sec_init(NXP_CAAM_ADDR);
+ }
+}
+
+void soc_runtime_setup(void)
+{
+
+}
+
+#endif /* IMAGE_BL2 */
diff --git a/plat/nxp/soc-ls1046a/soc.def b/plat/nxp/soc-ls1046a/soc.def
new file mode 100644
index 0000000..50fc9c9
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/soc.def
@@ -0,0 +1,107 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# This file contains the basic architecture definitions that drive the build
+#
+# -----------------------------------------------------------------------------
+
+CORE_TYPE := a72
+
+CACHE_LINE := 6
+
+# set to GIC400 or GIC500
+GIC := GIC400
+
+# set to CCI400 or CCN504 or CCN508
+INTERCONNECT := CCI400
+
+# indicate layerscape chassis level - set to 3=LSCH3 or 2=LSCH2
+CHASSIS := 2
+
+# TZC IP Details TZC used is TZC380 or TZC400
+TZC_ID := TZC400
+
+# CONSOLE Details available is NS16550 or PL011
+CONSOLE := NS16550
+
+ # Select the DDR PHY generation to be used
+PLAT_DDR_PHY := PHY_GEN1
+
+PHYS_SYS := 64
+
+# ddr controller - set to MMDC or NXP
+DDRCNTLR := NXP
+
+# ddr phy - set to NXP or SNPS
+DDRPHY := NXP
+
+# Area of OCRAM reserved by ROM code
+NXP_ROM_RSVD := 0x8000
+
+# Max Size of CSF header. Required to define BL2 TEXT LIMIT in soc.def
+# Input to CST create_hdr_esbc tool
+CSF_HDR_SZ := 0x4000
+
+# In IMAGE_BL2, compile time flag for handling Cache coherency
+# with CAAM for BL2 running from OCRAM
+SEC_MEM_NON_COHERENT := yes
+
+# OCRAM MAP
+OCRAM_START_ADDR := 0x10000000
+OCRAM_SIZE := 0x20000
+
+# BL2 binary is placed at start of OCRAM.
+# Also used by create_pbl.mk.
+BL2_BASE := 0x10000000
+
+# After BL2 bin, OCRAM is used by ROM Code:
+# (OCRAM_START_ADDR + BL2_BIN_SIZE) -> (NXP_ROM_RSVD - 1)
+
+# After ROM Code, OCRAM is used by CSF header.
+# (OCRAM_START_ADDR + BL2_TEXT_LIMIT + NXP_ROM_RSVD) -> (CSF_HDR_SZ - 1)
+
+# BL2_HDR_LOC has to be (OCRAM_START_ADDR + OCRAM_SIZE - NXP_ROM_RSVD - CSF_HDR_SZ)
+# This value should be greater than BL2_TEXT_LIMIT
+# Input to CST create_hdr_isbc tool
+BL2_HDR_LOC_HDR ?= $(shell echo $$(( $(OCRAM_START_ADDR) + $(OCRAM_SIZE) - $(NXP_ROM_RSVD) - $(CSF_HDR_SZ))))
+# Covert to HEX to be used by create_pbl.mk
+BL2_HDR_LOC := $$(echo "obase=16; ${BL2_HDR_LOC_HDR}" | bc)
+
+# Core Errata
+ERRATA_A72_859971 := 1
+
+# SoC ERRATAS
+ERRATA_SOC_A008850 := 1
+ERRATA_SOC_A010539 := 1
+
+# DDR Errata
+ERRATA_DDR_A008511 := 1
+ERRATA_DDR_A009803 := 1
+ERRATA_DDR_A009942 := 1
+ERRATA_DDR_A010165 := 1
+
+# enable dynamic memory mapping
+PLAT_XLAT_TABLES_DYNAMIC := 1
+
+# Define Endianness of each module
+NXP_GUR_ENDIANNESS := BE
+NXP_DDR_ENDIANNESS := BE
+NXP_SEC_ENDIANNESS := BE
+NXP_SFP_ENDIANNESS := BE
+NXP_SNVS_ENDIANNESS := BE
+NXP_ESDHC_ENDIANNESS := BE
+NXP_QSPI_ENDIANNESS := BE
+NXP_FSPI_ENDIANNESS := BE
+NXP_SCFG_ENDIANNESS := BE
+NXP_GPIO_ENDIANNESS := BE
+NXP_IFC_ENDIANNESS := BE
+
+NXP_SFP_VER := 3_2
+
+# OCRAM ECC Enabled
+OCRAM_ECC_EN := yes
diff --git a/plat/nxp/soc-ls1046a/soc.mk b/plat/nxp/soc-ls1046a/soc.mk
new file mode 100644
index 0000000..7644027
--- /dev/null
+++ b/plat/nxp/soc-ls1046a/soc.mk
@@ -0,0 +1,114 @@
+#
+# Copyright 2018-2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# SoC-specific build parameters
+SOC := ls1046a
+PLAT_PATH := plat/nxp
+PLAT_COMMON_PATH:= plat/nxp/common
+PLAT_DRIVERS_PATH:= drivers/nxp
+PLAT_SOC_PATH := ${PLAT_PATH}/soc-${SOC}
+BOARD_PATH := ${PLAT_SOC_PATH}/${BOARD}
+
+# Get SoC-specific defnitions
+include ${PLAT_SOC_PATH}/soc.def
+include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+# For Security Features
+DISABLE_FUSE_WRITE := 1
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
+SECURE_BOOT := yes
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM))
+
+# Selecting Drivers for SoC
+$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,CSU_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+
+# Selecting PSCI & SIP_SVC support
+$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31))
+
+# Source File Addition
+PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\
+ -I${BOARD_PATH}\
+ -I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
+ -I${PLAT_SOC_PATH}/include\
+ -I${PLAT_COMMON_PATH}/soc_errata
+
+ifeq (${SECURE_BOOT},yes)
+include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
+endif
+
+ifeq ($(WARM_BOOT),yes)
+include ${PLAT_COMMON_PATH}/warm_reset/warm_reset.mk
+endif
+
+ifeq (${NXP_NV_SW_MAINT_LAST_EXEC_DATA}, yes)
+include ${PLAT_COMMON_PATH}/nv_storage/nv_storage.mk
+endif
+
+ifeq (${PSCI_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/psci/psci.mk
+endif
+
+ifeq (${SIPSVC_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk
+endif
+
+# For fuse-fip & fuse-programming
+ifeq (${FUSE_PROG}, 1)
+include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk
+endif
+
+ifeq (${IMG_LOADR_NEEDED},yes)
+include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk
+endif
+
+# Adding source files for the above selected drivers.
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+# Adding SoC specific files
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
+
+PLAT_INCLUDES += ${NV_STORAGE_INCLUDES}\
+ ${WARM_RST_INCLUDES}
+
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\
+ ${WARM_RST_BL31_SOURCES}\
+ ${PSCI_SOURCES}\
+ ${SIPSVC_SOURCES}\
+ ${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S
+
+PLAT_BL_COMMON_SOURCES += ${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\
+ ${PLAT_SOC_PATH}/aarch64/${SOC}_helpers.S\
+ ${NV_STORAGE_SOURCES}\
+ ${WARM_RST_BL_COMM_SOURCES}\
+ ${PLAT_SOC_PATH}/soc.c
+
+ifeq (${TEST_BL31}, 1)
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S\
+ ${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S
+endif
+
+BL2_SOURCES += ${DDR_CNTLR_SOURCES}\
+ ${TBBR_SOURCES}\
+ ${FUSE_SOURCES}
+
+# Adding TFA setup files
+include ${PLAT_PATH}/common/setup/common.mk
diff --git a/plat/nxp/soc-ls1088a/aarch64/ls1088a.S b/plat/nxp/soc-ls1088a/aarch64/ls1088a.S
new file mode 100644
index 0000000..0c6b7ea
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/aarch64/ls1088a.S
@@ -0,0 +1,1817 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+.section .text, "ax"
+
+#include <asm_macros.S>
+#include <lib/psci/psci.h>
+#include <nxp_timer.h>
+#include <plat_gic.h>
+
+#include "bl31_data.h"
+#include "plat_psci.h"
+#include "platform_def.h"
+
+/*
+ * the BASE address for these offsets is AUX_01_DATA in the
+ * bootcore's psci data region
+ */
+#define DEVDISR2_MASK_OFFSET 0x0 /* references AUX_01_DATA */
+#define DEVDISR5_MASK_OFFSET 0x8 /* references AUX_02_DATA */
+
+/*
+ * the BASE address for these offsets is AUX_04_DATA in the
+ * bootcore's psci data region
+ */
+#define GICD_BASE_ADDR_OFFSET 0x0 /* references AUX_04_DATA */
+#define GICC_BASE_ADDR_OFFSET 0x8 /* references AUX_05_DATA */
+
+#define IPSTPACK_RETRY_CNT 0x10000
+#define DDR_SLEEP_RETRY_CNT 0x10000
+#define CPUACTLR_EL1 S3_1_C15_C2_0
+#define DDR_SDRAM_CFG_2_FRCSR 0x80000000
+#define DDR_SDRAM_CFG_2_OFFSET 0x114
+#define DDR_TIMING_CFG_4_OFFSET 0x160
+#define DDR_CNTRL_BASE_ADDR 0x01080000
+
+#define DLL_LOCK_MASK 0x3
+#define DLL_LOCK_VALUE 0x2
+
+#define ERROR_DDR_SLEEP -1
+#define ERROR_DDR_WAKE -2
+#define ERROR_NO_QUIESCE -3
+
+#define CORE_RESTARTABLE 0
+#define CORE_NOT_RESTARTABLE 1
+
+.global soc_init_lowlevel
+.global soc_init_percpu
+
+.global _soc_core_release
+.global _soc_core_restart
+.global _soc_ck_disabled
+.global _soc_sys_reset
+.global _soc_sys_off
+
+.global _soc_core_prep_off
+.global _soc_core_entr_off
+.global _soc_core_exit_off
+
+.global _soc_core_prep_stdby
+.global _soc_core_entr_stdby
+.global _soc_core_exit_stdby
+.global _soc_core_prep_pwrdn
+.global _soc_core_entr_pwrdn
+.global _soc_core_exit_pwrdn
+.global _soc_clstr_prep_stdby
+.global _soc_clstr_exit_stdby
+.global _soc_clstr_prep_pwrdn
+.global _soc_clstr_exit_pwrdn
+.global _soc_sys_prep_stdby
+.global _soc_sys_exit_stdby
+.global _soc_sys_prep_pwrdn
+.global _soc_sys_pwrdn_wfi
+.global _soc_sys_exit_pwrdn
+
+.global _set_platform_security
+.global _soc_set_start_addr
+
+.equ TZPCDECPROT_0_SET_BASE, 0x02200804
+.equ TZPCDECPROT_1_SET_BASE, 0x02200810
+.equ TZPCDECPROT_2_SET_BASE, 0x0220081C
+
+.equ TZASC_REGION_ATTRIBUTES_0_0, 0x01100110
+
+.equ MPIDR_AFFINITY0_MASK, 0x00FF
+.equ MPIDR_AFFINITY1_MASK, 0xFF00
+.equ CPUECTLR_DISABLE_TWALK_PREFETCH, 0x4000000000
+.equ CPUECTLR_INS_PREFETCH_MASK, 0x1800000000
+.equ CPUECTLR_DAT_PREFETCH_MASK, 0x0300000000
+.equ OSDLR_EL1_DLK_LOCK, 0x1
+.equ CNTP_CTL_EL0_EN, 0x1
+.equ CNTP_CTL_EL0_IMASK, 0x2
+/* shifted value for incrementing cluster count in mpidr */
+.equ MPIDR_CLUSTER, 0x100
+
+/*
+ * This function initialize the soc,
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11
+ */
+func soc_init_lowlevel
+ /*
+ * called from C, so save the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ */
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ /*
+ * make sure the personality has been established by releasing cores
+ * that are marked "to-be-disabled" from reset
+ */
+ bl release_disabled
+
+ /* set SCRATCHRW7 to 0x0 */
+ ldr x0, =DCFG_SCRATCHRW7_OFFSET
+ mov x1, xzr
+ bl _write_reg_dcfg
+
+ /* restore the aarch32/64 non-volatile registers */
+ ldp x18, x30, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ ret
+endfunc soc_init_lowlevel
+
+/*
+ * void soc_init_percpu(void)
+ * this function performs any soc-specific initialization that is needed on
+ * a per-core basis
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+func soc_init_percpu
+ stp x4, x30, [sp, #-16]!
+
+ bl plat_my_core_mask
+ mov x2, x0
+
+ /* x2 = core mask */
+
+ /* see if this core is marked for prefetch disable */
+ mov x0, #PREFETCH_DIS_OFFSET
+ bl _get_global_data
+ tst x0, x2
+ b.eq 1f
+ bl _disable_ldstr_pfetch_A53
+1:
+ mov x0, #NXP_PMU_ADDR
+ bl enable_timer_base_to_cluster
+ ldp x4, x30, [sp], #16
+ ret
+endfunc soc_init_percpu
+
+/*
+ * this function sets the security mechanisms in the SoC to implement the
+ * Platform Security Policy
+ */
+func _set_platform_security
+ mov x3, x30
+
+#if (!SUPPRESS_TZC)
+ /* initialize the tzpc */
+ bl init_tzpc
+#endif
+
+#if (!SUPPRESS_SEC)
+ /* initialize secmon */
+ bl initSecMon
+#endif
+ mov x30, x3
+ ret
+endfunc _set_platform_security
+
+/*
+ * this function writes a 64-bit address to bootlocptrh/l
+ * in: x0, 64-bit address to write to BOOTLOCPTRL/H
+ * out: none
+ * uses x0, x1, x2
+ */
+func _soc_set_start_addr
+ /* get the 64-bit base address of the dcfg block */
+ ldr x2, =NXP_DCFG_ADDR
+
+ /* write the 32-bit BOOTLOCPTRL register */
+ mov x1, x0
+ str w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET]
+
+ /* write the 32-bit BOOTLOCPTRH register */
+ lsr x1, x0, #32
+ str w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET]
+ ret
+endfunc _soc_set_start_addr
+
+/*
+ * part of CPU_ON
+ * this function releases a secondary core from reset
+ * in: x0 = core_mask_lsb
+ * out: none
+ * uses: x0, x1, x2, x3
+ */
+_soc_core_release:
+ mov x3, x30
+
+ /* x0 = core mask */
+
+ ldr x1, =NXP_SEC_REGFILE_ADDR
+ /*
+ * write to CORE_HOLD to tell the bootrom that we want this core
+ * to run
+ */
+ str w0, [x1, #CORE_HOLD_OFFSET]
+
+ /* x0 = core mask */
+
+ /* read-modify-write BRRL to release core */
+ mov x1, #NXP_RESET_ADDR
+ ldr w2, [x1, #BRR_OFFSET]
+ orr w2, w2, w0
+ str w2, [x1, #BRR_OFFSET]
+ dsb sy
+ isb
+
+ /* send event */
+ sev
+ isb
+
+ mov x30, x3
+ ret
+
+/*
+ * this function determines if a core is disabled via COREDISABLEDSR
+ * in: w0 = core_mask_lsb
+ * out: w0 = 0, core not disabled
+ * w0 != 0, core disabled
+ * uses x0, x1
+ */
+_soc_ck_disabled:
+ /* get base addr of dcfg block */
+ ldr x1, =NXP_DCFG_ADDR
+
+ /* read COREDISABLEDSR */
+ ldr w1, [x1, #DCFG_COREDISABLEDSR_OFFSET]
+
+ /* test core bit */
+ and w0, w1, w0
+
+ ret
+
+/*
+ * part of CPU_ON
+ * this function restarts a core shutdown via _soc_core_entr_off
+ * in: x0 = core mask lsb (of the target cpu)
+ * out: x0 == 0, on success
+ * x0 != 0, on failure
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_core_restart:
+ mov x6, x30
+ mov x4, x0
+
+ /* x4 = core mask lsb */
+
+ /* pgm GICD_CTLR - enable secure grp0 */
+ mov x5, #NXP_GICD_ADDR
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ orr w2, w2, #GICD_CTLR_EN_GRP_0
+ str w2, [x5, #GICD_CTLR_OFFSET]
+ dsb sy
+ isb
+ /* poll on RWP til write completes */
+4:
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ tst w2, #GICD_CTLR_RWP
+ b.ne 4b
+
+ /*
+ * x4 = core mask lsb
+ * x5 = gicd base addr
+ */
+
+ mov x0, x4
+ bl get_mpidr_value
+
+ /*
+ * x0 = mpidr of target core
+ * x4 = core mask lsb of target core
+ * x5 = gicd base addr
+ */
+
+ /* generate target list bit */
+ and x1, x0, #MPIDR_AFFINITY0_MASK
+ mov x2, #1
+ lsl x2, x2, x1
+ /* get the affinity1 field */
+ and x1, x0, #MPIDR_AFFINITY1_MASK
+ lsl x1, x1, #8
+ orr x2, x2, x1
+ /* insert the INTID for SGI15 */
+ orr x2, x2, #ICC_SGI0R_EL1_INTID
+ /* fire the SGI */
+ msr ICC_SGI0R_EL1, x2
+ dsb sy
+ isb
+
+ /* load '0' on success */
+ mov x0, xzr
+
+ mov x30, x6
+ ret
+
+/*
+ * part of CPU_OFF
+ * this function programs SoC & GIC registers in preparation for shutting down
+ * the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7
+ */
+_soc_core_prep_off:
+ mov x8, x30
+ mov x7, x0
+
+ /* x7 = core mask lsb */
+
+ mrs x1, CPUECTLR_EL1
+ /* set smp and disable L2 snoops in cpuectlr */
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH
+ bic x1, x1, #CPUECTLR_INS_PREFETCH_MASK
+ bic x1, x1, #CPUECTLR_DAT_PREFETCH_MASK
+ /* set retention control in cpuectlr */
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ orr x1, x1, #CPUECTLR_TIMER_8TICKS
+ msr CPUECTLR_EL1, x1
+
+ /* get redistributor rd base addr for this core */
+ mov x0, x7
+ bl get_gic_rd_base
+ mov x6, x0
+
+ /* get redistributor sgi base addr for this core */
+ mov x0, x7
+ bl get_gic_sgi_base
+ mov x5, x0
+
+ /* x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w3, #GICR_ICENABLER0_SGI15
+ str w3, [x5, #GICR_ICENABLER0_OFFSET]
+2:
+ /* poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* disable GRP1 interrupts at cpu interface */
+ msr ICC_IGRPEN1_EL3, xzr
+
+ /* disable GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* program the redistributor - poll on GICR_CTLR.RWP as needed */
+
+ /* define SGI 15 as Grp0 - GICR_IGROUPR0 */
+ ldr w4, [x5, #GICR_IGROUPR0_OFFSET]
+ bic w4, w4, #GICR_IGROUPR0_SGI15
+ str w4, [x5, #GICR_IGROUPR0_OFFSET]
+
+ /* define SGI 15 as Grp0 - GICR_IGRPMODR0 */
+ ldr w3, [x5, #GICR_IGRPMODR0_OFFSET]
+ bic w3, w3, #GICR_IGRPMODR0_SGI15
+ str w3, [x5, #GICR_IGRPMODR0_OFFSET]
+
+ /* set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */
+ ldr w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+ bic w4, w4, #GICR_IPRIORITYR3_SGI15_MASK
+ str w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+
+ /* enable SGI 15 at redistributor - GICR_ISENABLER0 */
+ mov w3, #GICR_ISENABLER0_SGI15
+ str w3, [x5, #GICR_ISENABLER0_OFFSET]
+ dsb sy
+ isb
+3:
+ /* poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 3b
+
+ /* quiesce the debug interfaces */
+ mrs x3, osdlr_el1
+ orr x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ /* enable grp0 ints */
+ mov x3, #ICC_IGRPEN0_EL1_EN
+ msr ICC_IGRPEN0_EL1, x3
+
+ /*
+ * x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* clear any pending interrupts */
+ mvn w1, wzr
+ str w1, [x5, #GICR_ICPENDR0_OFFSET]
+
+ /* make sure system counter is enabled */
+ ldr x3, =NXP_TIMER_ADDR
+ ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 4f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+4:
+ /* enable the core timer and mask timer interrupt */
+ mov x1, #CNTP_CTL_EL0_EN
+ orr x1, x1, #CNTP_CTL_EL0_IMASK
+ msr cntp_ctl_el0, x1
+
+ mov x30, x8
+ ret
+
+/*
+ * part of CPU_OFF
+ * this function performs the final steps to shutdown the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5
+ */
+_soc_core_entr_off:
+ mov x5, x30
+ mov x4, x0
+
+ /* x4 = core mask */
+1:
+ /* enter low-power state by executing wfi */
+ wfi
+
+ /* see if SGI15 woke us up */
+ mrs x2, ICC_IAR0_EL1
+ mov x3, #ICC_IAR0_EL1_SGI15
+ cmp x2, x3
+ b.ne 2f
+
+ /* deactivate the int */
+ msr ICC_EOIR0_EL1, x2
+
+ /* x4 = core mask */
+2:
+ /* check if core has been turned on */
+ mov x0, x4
+ bl _getCoreState
+
+ /* x0 = core state */
+
+ cmp x0, #CORE_WAKEUP
+ b.ne 1b
+
+ /* if we get here, then we have exited the wfi */
+
+ mov x30, x5
+ ret
+
+/*
+ * part of CPU_OFF
+ * this function starts the process of starting a core back up
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_core_exit_off:
+ mov x6, x30
+ mov x5, x0
+
+ /* disable forwarding of GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* get redistributor sgi base addr for this core */
+ mov x0, x5
+ bl get_gic_sgi_base
+ mov x4, x0
+
+ /*
+ * x4 = gicr sgi base addr
+ * x5 = core mask
+ */
+
+ /* disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w1, #GICR_ICENABLER0_SGI15
+ str w1, [x4, #GICR_ICENABLER0_OFFSET]
+
+ /* get redistributor rd base addr for this core */
+ mov x0, x5
+ bl get_gic_rd_base
+ mov x4, x0
+
+ /* x4 = gicr rd base addr */
+2:
+ /* poll on rwp bit in GICR_CTLR */
+ ldr w2, [x4, #GICR_CTLR_OFFSET]
+ tst w2, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* x4 = gicr rd base addr */
+
+ /* unlock the debug interfaces */
+ mrs x3, osdlr_el1
+ bic x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ dsb sy
+ isb
+ mov x30, x6
+ ret
+
+/*
+ * this function requests a reset of the entire SOC
+ * in: none
+ * out: none
+ * uses: x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_sys_reset:
+ mov x3, x30
+
+ /* make sure the mask is cleared in the reset request mask register */
+ mov x0, #RST_RSTRQMR1_OFFSET
+ mov w1, wzr
+ bl _write_reg_reset
+
+ /* set the reset request */
+ mov x4, #RST_RSTCR_OFFSET
+ mov x0, x4
+ mov w1, #RSTCR_RESET_REQ
+ bl _write_reg_reset
+
+ /* x4 = RST_RSTCR_OFFSET */
+
+ /*
+ * just in case this address range is mapped as cacheable,
+ * flush the write out of the dcaches
+ */
+ mov x2, #NXP_RESET_ADDR
+ add x2, x2, x4
+ dc cvac, x2
+ dsb st
+ isb
+
+ /* this function does not return */
+ b .
+
+/*
+ * this function turns off the SoC
+ * Note: this function is not intended to return, and the only allowable
+ * recovery is POR
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_sys_off:
+ /*
+ * A-009810: LPM20 entry sequence might cause
+ * spurious timeout reset request
+ * workaround: MASK RESET REQ RPTOE
+ */
+ ldr x0, =NXP_RESET_ADDR
+ ldr w1, [x0, #RST_RSTRQMR1_OFFSET]
+ orr w1, w1, #RSTRQMR_RPTOE_MASK
+ str w1, [x0, #RST_RSTRQMR1_OFFSET]
+
+ /* disable SEC, QBman spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, =DCFG_DEVDISR1_SEC
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR3_OFFSET
+ ldr w1, =DCFG_DEVDISR3_QBMAIN
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, =DCFG_DEVDISR4_SPI_QSPI
+ str w1, [x2, x0]
+
+ /* set TPMWAKEMR0 */
+ ldr x0, =TPMWAKEMR0_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ /* disable icache, dcache, mmu @ EL1 */
+ mov x1, #SCTLR_I_C_M_MASK
+ mrs x0, sctlr_el1
+ bic x0, x0, x1
+ msr sctlr_el1, x0
+
+ /* disable L2 prefetches */
+ mrs x0, CPUECTLR_EL1
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ orr x0, x0, #CPUECTLR_TIMER_8TICKS
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+
+ /* disable CCN snoop domain */
+ ldr x0, =NXP_CCI_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ mov x2, #DAIF_SET_MASK
+
+ mrs x1, spsr_el1
+ orr x1, x1, x2
+ msr spsr_el1, x1
+
+ mrs x1, spsr_el2
+ orr x1, x1, x2
+ msr spsr_el2, x1
+
+ bl get_pmu_idle_cluster_mask
+ mov x3, #NXP_PMU_ADDR
+
+ /* x3 = pmu base addr */
+
+ /* idle the ACP interfaces */
+ str w0, [x3, #PMU_CLAINACTSETR_OFFSET]
+
+ /* force the debug interface to be quiescent */
+ mrs x0, osdlr_el1
+ orr x0, x0, #0x1
+ msr osdlr_el1, x0
+
+ bl get_pmu_flush_cluster_mask
+ /* x3 = pmu base addr */
+ mov x3, #NXP_PMU_ADDR
+
+ /* clear flush request and status */
+ ldr x2, =PMU_CLSL2FLUSHCLRR_OFFSET
+ str w0, [x3, x2]
+
+ /* close the Skyros master port */
+ ldr x2, =PMU_CLSINACTSETR_OFFSET
+ str w0, [x3, x2]
+
+ /* request lpm20 */
+ ldr x0, =PMU_POWMGTCSR_OFFSET
+ ldr w1, =PMU_POWMGTCSR_VAL
+ str w1, [x3, x0]
+
+ /* this function does not return */
+1:
+ wfi
+ b 1b
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_core_prep_stdby:
+ /* clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core into standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_stdby:
+ /* X0 = core mask lsb */
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_core_exit_stdby:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_core_prep_pwrdn:
+ /* make sure system counter is enabled */
+ ldr x3, =NXP_TIMER_ADDR
+ ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+ /*
+ * enable dynamic retention control (CPUECTLR[2:0])
+ * set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_8TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x1
+
+ isb
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core into a power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_pwrdn:
+ /* X0 = core mask lsb */
+ dsb sy
+ isb
+ wfi
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function cleans up after a core exits power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses
+ */
+_soc_core_exit_pwrdn:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_clstr_prep_stdby:
+ /* clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_clstr_exit_stdby:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_clstr_prep_pwrdn:
+ /* make sure system counter is enabled */
+ ldr x3, =NXP_TIMER_ADDR
+ ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+ /*
+ * enable dynamic retention control (CPUECTLR[2:0])
+ * set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_8TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x1
+
+ isb
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function cleans up after a core exits power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses
+ */
+_soc_clstr_exit_pwrdn:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_prep_stdby:
+ /* clear CPUECTLR_EL1[2:0] */
+ mrs x1, CPUECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CPUECTLR_EL1, x1
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_sys_exit_stdby:
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to
+ * suspend-to-power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_sys_prep_pwrdn:
+ /* set retention control */
+ mrs x0, CPUECTLR_EL1
+ bic x0, x0, #CPUECTLR_TIMER_MASK
+ orr x0, x0, #CPUECTLR_TIMER_8TICKS
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core, and potentially the soc, into a
+ * low-power state
+ * in: x0 = core mask lsb
+ * out: x0 = 0, success
+ * x0 < 0, failure
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
+ */
+_soc_sys_pwrdn_wfi:
+ /* Save LR to stack */
+ stp x18, x30, [sp, #-16]!
+
+ /* Poll PCPW20SR for all secondary cores to be placed in PW20 */
+ bl get_tot_num_cores
+ mov x3, #0x1
+ lsl x3, x3, x0
+ sub x3, x3, #2
+1:
+ mov x0, #NXP_PMU_ADDR
+ ldr w1, [x0, #PMU_PCPW20SR_OFFSET]
+ cmp w1, w3
+ b.ne 1b
+
+ /* backup EPU registers to stack */
+ mov x3, #NXP_PMU_ADDR
+ ldr x2, =NXP_EPU_ADDR
+ ldr w4, [x2, #EPU_EPIMCR10_OFFSET]
+ ldr w5, [x2, #EPU_EPCCR10_OFFSET]
+ ldr w6, [x2, #EPU_EPCTR10_OFFSET]
+ ldr w7, [x2, #EPU_EPGCR_OFFSET]
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+
+ /*
+ * x2 = epu base addr
+ * x3 = pmu base addr
+ */
+
+ /* set up EPU event to receive the wake signal from PMU */
+ mov w4, #EPU_EPIMCR10_VAL
+ mov w5, #EPU_EPCCR10_VAL
+ mov w6, #EPU_EPCTR10_VAL
+ mov w7, #EPU_EPGCR_VAL
+ str w4, [x2, #EPU_EPIMCR10_OFFSET]
+ str w5, [x2, #EPU_EPCCR10_OFFSET]
+ str w6, [x2, #EPU_EPCTR10_OFFSET]
+ str w7, [x2, #EPU_EPGCR_OFFSET]
+
+ /*
+ * A-010194: There is logic problem
+ * in the path of GIC-to-PMU to issue
+ * wake request to core0
+ * Workaround: Re-target the wakeup interrupts
+ * to a core other than the last active core0
+ */
+ ldr x2, =NXP_GICD_ADDR
+
+ /* backup flextimer/mmc/usb interrupt router */
+ ldr x0, =GICD_IROUTER60_OFFSET
+ ldr x1, =GICD_IROUTER76_OFFSET
+ ldr w4, [x2, x0]
+ ldr w5, [x2, x1]
+ ldr x0, =GICD_IROUTER112_OFFSET
+ ldr x1, =GICD_IROUTER113_OFFSET
+ ldr w6, [x2, x0]
+ ldr w7, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+
+ /*
+ * x2 = gicd base addr
+ * x0 = GICD_IROUTER112_OFFSET
+ * x1 = GICD_IROUTER113_OFFSET
+ */
+
+ /* re-route interrupt to cluster 1 */
+ ldr w4, =GICD_IROUTER_VALUE
+ str w4, [x2, x0]
+ str w4, [x2, x1]
+ ldr x0, =GICD_IROUTER60_OFFSET
+ ldr x1, =GICD_IROUTER76_OFFSET
+ str w4, [x2, x0]
+ str w4, [x2, x1]
+ dsb sy
+ isb
+
+ /* backup flextimer/mmc/usb interrupt enabler */
+ ldr x0, =GICD_ISENABLER_1
+ ldr w4, [x2, x0]
+ ldr x1, =GICD_ISENABLER_2
+ ldr w5, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+
+ ldr x0, =GICD_ISENABLER_3
+ ldr w4, [x2, x0]
+ ldr x1, =GICD_ICENABLER_1
+ ldr w5, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+
+ ldr x0, =GICD_ICENABLER_2
+ ldr w4, [x2, x0]
+ ldr x1, =GICD_ICENABLER_3
+ ldr w5, [x2, x1]
+ stp x4, x5, [sp, #-16]!
+
+ /* enable related interrupt routing */
+ ldr w4, =GICD_ISENABLER_1_VALUE
+ ldr x0, =GICD_ISENABLER_1
+ str w4, [x2, x0]
+ dsb sy
+ isb
+
+ ldr w4, =GICD_ISENABLER_2_VALUE
+ ldr x0, =GICD_ISENABLER_2
+ str w4, [x2, x0]
+ dsb sy
+ isb
+
+ ldr w4, =GICD_ISENABLER_3_VALUE
+ ldr x0, =GICD_ISENABLER_3
+ str w4, [x2, x0]
+ dsb sy
+ isb
+
+ /* set POWMGTDCR [STP_PV_EN] = 1 */
+ ldr x2, =NXP_POWMGTDCR
+ ldr w4, =0x01
+ str w4, [x2]
+
+ /* program IPSTPCR for override stop request (except DDR) */
+ mov x3, #NXP_PMU_ADDR
+
+ /* build an override mask for IPSTPCR4/IPSTPACK4/DEVDISR5 */
+ ldr x2, =PMU_IPPDEXPCR4_OFFSET
+ ldr w7, [x3, x2]
+
+ mov x5, xzr
+ ldr x6, =IPPDEXPCR4_MASK
+ and x6, x6, x7
+ cbz x6, 1f
+
+ /*
+ * x5 = override mask
+ * x6 = IPPDEXPCR bits for DEVDISR5
+ * x7 = IPPDEXPCR
+ */
+
+ /* get the overrides */
+ orr x4, x5, #DEVDISR5_FLX_TMR
+ tst x6, #IPPDEXPCR_FLX_TMR
+ csel x5, x5, x4, EQ
+1:
+ /* store the DEVDISR5 override mask */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ str w5, [x2, #DEVDISR5_MASK_OFFSET]
+
+ mov x3, #NXP_PMU_ADDR
+
+ /* write IPSTPCR0 - no overrides */
+ ldr x2, =PMU_IPSTPCR0_OFFSET
+ ldr w5, =IPSTPCR0_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR1 - no overrides */
+ ldr x2, =PMU_IPSTPCR1_OFFSET
+ ldr w5, =IPSTPCR1_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR2 - no overrides */
+ ldr x2, =PMU_IPSTPCR2_OFFSET
+ ldr w5, =IPSTPCR2_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR3 - no overrides */
+ ldr x2, =PMU_IPSTPCR3_OFFSET
+ ldr w5, =IPSTPCR3_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR4 - overrides possible */
+ ldr x2, =BC_PSCI_BASE
+ add x2, x2, #AUX_01_DATA
+ ldr w6, [x2, #DEVDISR5_MASK_OFFSET]
+ ldr x2, =PMU_IPSTPCR4_OFFSET
+ ldr w5, =IPSTPCR4_VALUE
+ bic x5, x5, x6
+ str w5, [x3, x2]
+
+ /* write IPSTPCR5 - no overrides */
+ ldr x2, =PMU_IPSTPCR5_OFFSET
+ ldr w5, =IPSTPCR5_VALUE
+ str w5, [x3, x2]
+
+ /* write IPSTPCR6 - no overrides */
+ ldr x2, =PMU_IPSTPCR6_OFFSET
+ ldr w5, =IPSTPCR6_VALUE
+ str w5, [x3, x2]
+
+ /* poll IPSTPACK for IP stop acknowledgment (except DDR) */
+ mov x3, #NXP_PMU_ADDR
+
+ /* poll on IPSTPACK0 */
+ ldr x2, =PMU_IPSTPACK0_OFFSET
+ ldr x4, =IPSTPCR0_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+3:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 14f
+ sub x7, x7, #1
+ cbnz x7, 3b
+
+14:
+ /* poll on IPSTPACK1 */
+ ldr x2, =PMU_IPSTPACK1_OFFSET
+ ldr x4, =IPSTPCR1_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+4:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 15f
+ sub x7, x7, #1
+ cbnz x7, 4b
+
+15:
+ /* poll on IPSTPACK2 */
+ ldr x2, =PMU_IPSTPACK2_OFFSET
+ ldr x4, =IPSTPCR2_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+5:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 16f
+ sub x7, x7, #1
+ cbnz x7, 5b
+
+16:
+ /* poll on IPSTPACK3 */
+ ldr x2, =PMU_IPSTPACK3_OFFSET
+ ldr x4, =IPSTPCR3_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+6:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 17f
+ sub x7, x7, #1
+ cbnz x7, 6b
+
+17:
+ /* poll on IPSTPACK4 */
+ ldr x2, =PMU_IPSTPACK4_OFFSET
+ ldr x4, =IPSTPCR4_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+7:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 18f
+ sub x7, x7, #1
+ cbnz x7, 7b
+
+18:
+ /* poll on IPSTPACK5 */
+ ldr x2, =PMU_IPSTPACK5_OFFSET
+ ldr x4, =IPSTPCR5_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+8:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 19f
+ sub x7, x7, #1
+ cbnz x7, 8b
+
+19:
+ /* poll on IPSTPACK6 */
+ ldr x2, =PMU_IPSTPACK6_OFFSET
+ ldr x4, =IPSTPCR6_VALUE
+ ldr x7, =IPSTPACK_RETRY_CNT
+9:
+ ldr w0, [x3, x2]
+ cmp x0, x4
+ b.eq 20f
+ sub x7, x7, #1
+ cbnz x7, 9b
+
+20:
+ /* save current DEVDISR states to DDR. */
+ ldr x2, =NXP_DCFG_ADDR
+
+ /* save DEVDISR1 and load new value */
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, [x2, x0]
+ mov w13, w1
+ ldr x1, =DEVDISR1_VALUE
+ str w1, [x2, x0]
+ /* save DEVDISR2 and load new value */
+ ldr x0, =DCFG_DEVDISR2_OFFSET
+ ldr w1, [x2, x0]
+ mov w14, w1
+ ldr x1, =DEVDISR2_VALUE
+ str w1, [x2, x0]
+
+ /* x6 = DEVDISR5 override mask */
+
+ /* save DEVDISR3 and load new value */
+ ldr x0, =DCFG_DEVDISR3_OFFSET
+ ldr w1, [x2, x0]
+ mov w15, w1
+ ldr x1, =DEVDISR3_VALUE
+ str w1, [x2, x0]
+
+ /* save DEVDISR4 and load new value */
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, [x2, x0]
+ mov w16, w1
+ /* not stop uart print */
+ ldr x1, =0x0000332
+ str w1, [x2, x0]
+
+ /* save DEVDISR5 and load new value */
+ ldr x0, =DCFG_DEVDISR5_OFFSET
+ ldr w1, [x2, x0]
+ mov w17, w1
+ /* Enable this wakeup will fail, should enable OCRAM */
+ ldr x1, =0x00102300
+ str w1, [x2, x0]
+
+ /* save DEVDISR6 and load new value */
+ ldr x0, =DCFG_DEVDISR6_OFFSET
+ ldr w1, [x2, x0]
+ mov w18, w1
+ ldr x1, =DEVDISR6_VALUE
+ str w1, [x2, x0]
+
+ /*
+ * w13 = DEVDISR1 saved value
+ * w14 = DEVDISR2 saved value
+ * w15 = DEVDISR3 saved value
+ * w16 = DEVDISR4 saved value
+ * w17 = DEVDISR5 saved value
+ * w18 = DEVDISR6 saved value
+ */
+ /*
+ * A-009810: LPM20 entry sequence might cause
+ * spurious timeout reset request
+ * workaround: MASK RESET REQ RPTOE
+ */
+ ldr x0, =NXP_RESET_ADDR
+ ldr w1, =RSTRQMR_RPTOE_MASK
+ str w1, [x0, #RST_RSTRQMR1_OFFSET]
+
+ /* disable SEC, QBman spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, =DCFG_DEVDISR1_SEC
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR3_OFFSET
+ ldr w1, =DCFG_DEVDISR3_QBMAIN
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, =DCFG_DEVDISR4_SPI_QSPI
+ str w1, [x2, x0]
+
+ /*
+ * write the GICR_WAKER.ProcessorSleep bits to 1
+ * enable the WakeRequest signal
+ * x3 is cpu mask starting from cpu7
+ */
+ bl get_tot_num_cores
+ sub x0, x0, #1
+ mov x3, #0x1
+ lsl x3, x3, x0
+2:
+ mov x0, x3
+ bl get_gic_rd_base
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ orr w1, w1, #GICR_WAKER_SLEEP_BIT
+ str w1, [x0, #GICR_WAKER_OFFSET]
+1:
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ cmp w1, #GICR_WAKER_ASLEEP
+ b.ne 1b
+
+ lsr x3, x3, #1
+ cbnz x3, 2b
+
+ /* x3 = pmu base addr */
+
+ /* perform Icache Warming Sequence */
+ ldr x5, =IPSTPCR4_VALUE
+ mov x6, DDR_CNTRL_BASE_ADDR
+ mov x7, #NXP_PMU_ADDR
+ mov x8, #NXP_DCFG_ADDR
+ mov x10, #PMU_IPSTPCR4_OFFSET
+ mov x11, #PMU_IPSTPACK4_OFFSET
+ mov x12, #PMU_IPSTPCR3_OFFSET
+ mov x18, #PMU_IPSTPCR2_OFFSET
+ mov x19, #PMU_IPSTPCR1_OFFSET
+ mov x21, #PMU_IPSTPCR0_OFFSET
+ ldr x22, =DCFG_DEVDISR5_OFFSET
+ ldr x23, =NXP_EPU_ADDR
+ mov x9, #CORE_RESTARTABLE
+ bl final_pwrdown
+
+ /*
+ * disable the WakeRequest signal on cpu 0-7
+ * x3 is cpu mask starting from cpu7
+ */
+ bl get_tot_num_cores
+ sub x0, x0, #1
+ mov x3, #0x1
+ lsl x3, x3, x0
+2:
+ mov x0, x3
+ bl get_gic_rd_base
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ bic w1, w1, #GICR_WAKER_SLEEP_BIT
+ str w1, [x0, #GICR_WAKER_OFFSET]
+1:
+ ldr w1, [x0, #GICR_WAKER_OFFSET]
+ cbnz w1, 1b
+
+ lsr x3, x3, #1
+ cbnz x3, 2b
+
+ /* set SGI for secondary core wakeup */
+ ldr x0, =0x1000002
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x2000004
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x3000008
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x4010001
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x5010002
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x6010004
+ msr S3_0_C12_C11_7, x0
+ isb
+ ldr x0, =0x7010008
+ msr S3_0_C12_C11_7, x0
+
+ /* enable SEC, QBman spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ str wzr, [x2, #DCFG_DEVDISR1_OFFSET]
+ str wzr, [x2, #DCFG_DEVDISR3_OFFSET]
+ str wzr, [x2, #DCFG_DEVDISR4_OFFSET]
+
+ /* clear POWMGTDCR [STP_PV_EN] */
+ ldr x2, =NXP_POWMGTDCR
+ ldr w4, [x2]
+ bic w4, w4, #0x01
+ str w4, [x2]
+
+ /* restore flextimer/mmc/usb interrupt enabler */
+ ldr x3, =NXP_GICD_ADDR
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_ICENABLER_2
+ mvn w0, w0
+ str w0, [x3, x1]
+ ldr x1, =GICD_ICENABLER_3
+ mvn w2, w2
+ str w2, [x3, x1]
+
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_ISENABLER_3
+ str w0, [x3, x1]
+ ldr x1, =GICD_ICENABLER_1
+ mvn w2, w2
+ str w0, [x3, x1]
+
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_ISENABLER_1
+ str w0, [x3, x1]
+ ldr x1, =GICD_ISENABLER_2
+ str w0, [x3, x1]
+
+ /* restore flextimer/mmc/usb interrupt router */
+ ldr x3, =NXP_GICD_ADDR
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_IROUTER113_OFFSET
+ str w2, [x3, x1]
+ ldr x1, =GICD_IROUTER112_OFFSET
+ str w0, [x3, x1]
+ ldp x0, x2, [sp], #16
+ ldr x1, =GICD_IROUTER76_OFFSET
+ str w2, [x3, x1]
+ ldr x1, =GICD_IROUTER60_OFFSET
+ str w0, [x3, x1]
+
+ /* restore EPU registers */
+ ldr x3, =NXP_EPU_ADDR
+ ldp x0, x2, [sp], #16
+ str w2, [x3, #EPU_EPGCR_OFFSET]
+ str w0, [x3, #EPU_EPCTR10_OFFSET]
+ ldp x2, x1, [sp], #16
+ str w1, [x3, #EPU_EPCCR10_OFFSET]
+ str w2, [x3, #EPU_EPIMCR10_OFFSET]
+
+ isb
+ /* Restor LR */
+ ldp x18, x30, [sp], #16
+ ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_exit_pwrdn:
+ mrs x1, SCTLR_EL1
+ orr x1, x1, #SCTLR_I_MASK
+ msr SCTLR_EL1, x1
+ isb
+ ret
+
+/*
+ * this function checks to see if cores which are to be disabled have been
+ * released from reset - if not, it releases them
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
+ */
+release_disabled:
+ mov x8, x30
+
+ /* read COREDISABLESR */
+ mov x0, #NXP_DCFG_ADDR
+ ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET]
+
+ /* get the number of cpus on this device */
+ mov x6, #PLATFORM_CORE_COUNT
+
+ mov x0, #NXP_RESET_ADDR
+ ldr w5, [x0, #BRR_OFFSET]
+
+ /* load the core mask for the first core */
+ mov x7, #1
+
+ /*
+ * x4 = COREDISABLESR
+ * x5 = BRR
+ * x6 = loop count
+ * x7 = core mask bit
+ */
+2:
+ /* check if the core is to be disabled */
+ tst x4, x7
+ b.eq 1f
+
+ /* see if disabled cores have already been released from reset */
+ tst x5, x7
+ b.ne 1f
+
+ /* if core has not been released, then release it (0-3) */
+ mov x0, x7
+ bl _soc_core_release
+
+ /* record the core state in the data area (0-3) */
+ mov x0, x7
+ mov x1, #CORE_DISABLED
+ bl _setCoreState
+
+1:
+ /* decrement the counter */
+ subs x6, x6, #1
+ b.le 3f
+
+ /* shift the core mask to the next core */
+ lsl x7, x7, #1
+ /* continue */
+ b 2b
+3:
+ mov x30, x8
+ ret
+
+/*
+ * write a register in the DCFG block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_dcfg:
+ ldr x2, =NXP_DCFG_ADDR
+ str w1, [x2, x0]
+ ret
+
+/*
+ * read a register in the DCFG block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1
+ */
+_read_reg_dcfg:
+ ldr x1, =NXP_DCFG_ADDR
+ ldr w0, [x1, x0]
+ ret
+
+/*
+ * this function sets up the TrustZone Address Space Controller (TZASC)
+ * in: none
+ * out: none
+ * uses x0, x1
+ */
+init_tzpc:
+ /*
+ * set Non Secure access for all devices protected via TZPC
+ * decode Protection-0 Set Reg
+ */
+ ldr x1, =TZPCDECPROT_0_SET_BASE
+ /* set decode region to NS, Bits[7:0] */
+ mov w0, #0xFF
+ str w0, [x1]
+
+ /* decode Protection-1 Set Reg */
+ ldr x1, =TZPCDECPROT_1_SET_BASE
+ /* set decode region to NS, Bits[7:0] */
+ mov w0, #0xFF
+ str w0, [x1]
+
+ /* decode Protection-2 Set Reg */
+ ldr x1, =TZPCDECPROT_2_SET_BASE
+ /* set decode region to NS, Bits[7:0] */
+ mov w0, #0xFF
+ str w0, [x1]
+
+ /*
+ * entire SRAM as NS
+ * secure RAM region size Reg
+ */
+ ldr x1, =NXP_OCRAM_TZPC_ADDR
+ /* 0x00000000 = no secure region */
+ mov w0, #0x00000000
+ str w0, [x1]
+
+ ret
+
+/* this function performs initialization on SecMon for boot services */
+initSecMon:
+ /* read the register hpcomr */
+ ldr x1, =NXP_SNVS_ADDR
+ ldr w0, [x1, #SECMON_HPCOMR_OFFSET]
+ /* turn off secure access for the privileged registers */
+ orr w0, w0, #SECMON_HPCOMR_NPSWAEN
+ /* write back */
+ str w0, [x1, #SECMON_HPCOMR_OFFSET]
+
+ ret
+
+/*
+ * this function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor rd base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_rd_base:
+ /* get the 0-based core number */
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ /* x2 = core number / loop counter */
+
+ ldr x0, =NXP_GICR_ADDR
+ mov x1, #GIC_RD_OFFSET
+2:
+ cbz x2, 1f
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+
+/*
+ * this function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor sgi base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_sgi_base:
+ /* get the 0-based core number */
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ /* x2 = core number / loop counter */
+
+ ldr x0, =NXP_GICR_SGI_ADDR
+ mov x1, #GIC_SGI_OFFSET
+2:
+ cbz x2, 1f
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+
+/*
+ * this function returns an mpidr value for a core, given a core_mask_lsb
+ * in: x0 = core mask lsb
+ * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits
+ * uses x0, x1
+ */
+get_mpidr_value:
+ /* convert a core mask to an SoC core number */
+ clz w0, w0
+ mov w1, #31
+ sub w0, w1, w0
+
+ /* w0 = SoC core number */
+
+ mov w1, wzr
+2:
+ cmp w0, #CORES_PER_CLUSTER
+ b.lt 1f
+ sub w0, w0, #CORES_PER_CLUSTER
+ add w1, w1, #MPIDR_CLUSTER
+ b 2b
+
+ /* insert the mpidr core number */
+1:
+ orr w0, w1, w0
+ ret
+
+/*
+ * write a register in the RESET block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_reset:
+ ldr x2, =NXP_RESET_ADDR
+ str w1, [x2, x0]
+ ret
+
+/*
+ * read a register in the RESET block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1
+ */
+_read_reg_reset:
+ ldr x1, =NXP_RESET_ADDR
+ ldr w0, [x1, x0]
+ ret
+
+/*
+ * this function will pwrdown ddr and the final core - it will do this
+ * by loading itself into the icache and then executing from there
+ * in: x5 = ipstpcr4 (IPSTPCR4_VALUE bic DEVDISR5_MASK)
+ * x6 = DDR_CNTRL_BASE_ADDR
+ * x7 = NXP_PMU_ADDR
+ * x8 = NXP_DCFG_ADDR
+ * x9 = 0, restartable
+ * = 1, non-restartable
+ * x10 = PMU_IPSTPCR4_OFFSET
+ * x11 = PMU_IPSTPACK4_OFFSET
+ * x12 = PMU_IPSTPCR3_OFFSET
+ * x18 = PMU_IPSTPCR2_OFFSET
+ * x19 = PMU_IPSTPCR1_OFFSET
+ * x21 = PMU_IPSTPCR0_OFFSET
+ * w13 = DEVDISR1 saved value
+ * w14 = DEVDISR2 saved value
+ * w15 = DEVDISR3 saved value
+ * w16 = DEVDISR4 saved value
+ * w17 = DEVDISR5 saved value
+ * x22 = DCFG_DEVDISR5_OFFSET
+ * x23 = NXP_EPU_ADDR
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x13, x14, x15, x16, x17
+ * x10, x11, x12, x18, x19, x21, x22, x23
+ */
+
+final_pwrdown:
+ /* delay */
+ mov w4, #0xffffff
+554:
+ sub w4, w4, #1
+ cmp w4, #0
+ b.ge 554b
+
+ mov x0, xzr
+ b touch_line_0
+
+/* 4Kb aligned */
+.align 12
+start_line_0:
+ mov x0, #1
+ /* put ddr in self refresh - start */
+ mov x2, #DDR_SDRAM_CFG_2_FRCSR
+ ldr w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ orr w3, w3, w2
+ /* put ddr in self refresh - end */
+ str w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ nop
+ nop
+touch_line_0:
+ cbz x0, touch_line_1
+
+start_line_1:
+ /* quiesce ddr clocks - start */
+ orr w3, w5, #DCFG_DEVDISR5_MEM
+ mov w4, w3
+ /* quiesce ddr clocks - end */
+ str w4, [x7, x10]
+ mov w3, #DCFG_DEVDISR5_MEM
+ /* poll on ipstpack4 - start */
+ mov x2, #DDR_SLEEP_RETRY_CNT
+ nop
+ nop
+touch_line_1:
+ cbz x0, touch_line_2
+
+start_line_2:
+ /* x11 = PMU_IPSTPACK4_OFFSET */
+ ldr w1, [x7, x11]
+ tst w1, w3
+ b.ne 5f
+ subs x2, x2, #1
+ /* poll on ipstpack4 - end */
+ b.gt start_line_2
+
+ /* if we get here, we have a timeout err */
+ mov w4, w5
+ /* x10 = PMU_IPSTPCR4_OFFSET re-enable ddr clks interface */
+ str w4, [x7, x10]
+touch_line_2:
+ cbz x0, touch_line_3
+
+start_line_3:
+ /* load error code */
+ mov x0, #ERROR_DDR_SLEEP
+ b 2f
+5:
+ wfe
+ ldr w1, [x23, #EPU_EPCTR10_OFFSET]
+ cbz w1, 5b
+
+ mov w4, w5
+touch_line_3:
+ cbz x0, touch_line_4
+
+start_line_4:
+ /* re-enable ddr in devdisr5 */
+ str w4, [x8, x22]
+ /* re-enable ddr clk in ipstpcr4 */
+ str w4, [x7, x10]
+13:
+ /* poll on ipstpack4 - start */
+ ldr w1, [x7, x11]
+ tst w1, w3
+ b.eq 2f
+ nop
+ b 13b
+ /* poll on ipstpack4 - end */
+2:
+touch_line_4:
+ cbz x0, touch_line_5
+
+start_line_5:
+ /* take ddr out-of self refresh - start */
+ mov x2, #DDR_SDRAM_CFG_2_FRCSR
+ ldr w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ mov w4, w3
+ bic w4, w4, w2
+ mov w3, w4
+ /* wait for ddr cntrlr clock- start */
+ mov x1, #DDR_SLEEP_RETRY_CNT
+3:
+ subs x1, x1, #1
+touch_line_5:
+ cbz x0, touch_line_6
+
+start_line_6:
+ /* wait for ddr cntrlr clock - end */
+ b.gt 3b
+ /* take ddr out-of self refresh - end */
+ str w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+ mov w1, w17
+ /* reset devdisr5 */
+ str w1, [x8, #DCFG_DEVDISR5_OFFSET]
+ mov w1, w16
+ /* reset devdisr4 */
+ str w1, [x8, #DCFG_DEVDISR4_OFFSET]
+ mov w1, w15
+touch_line_6:
+ cbz x0, touch_line_7
+
+start_line_7:
+ /* reset devdisr3 */
+ str w1, [x8, #DCFG_DEVDISR3_OFFSET]
+ mov w1, w14
+ /* reset devdisr2 */
+ str w1, [x8, #DCFG_DEVDISR2_OFFSET]
+ mov w1, w13
+ /* reset devdisr1 */
+ str w1, [x8, #DCFG_DEVDISR1_OFFSET]
+ /* reset ipstpcr4 */
+ str wzr, [x7, x10]
+ /* reset ipstpcr3 */
+ str wzr, [x7, x12]
+touch_line_7:
+ cbz x0, touch_line_8
+
+start_line_8:
+ /* reset ipstpcr2 */
+ str wzr, [x7, x18]
+ /* reset ipstpcr1 */
+ str wzr, [x7, x19]
+ /* reset ipstpcr0 */
+ str wzr, [x7, x21]
+
+touch_line_8:
+ cbz x0, touch_line_9
+
+start_line_9:
+ b continue_restart
+touch_line_9:
+ cbz x0, start_line_0
+
+/* execute here after ddr is back up */
+continue_restart:
+ /*
+ * if x0 = 1, all is well
+ * if x0 < 1, we had an error
+ */
+ cmp x0, #1
+ b.ne 4f
+ mov x0, #0
+4:
+ ret
diff --git a/plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S b/plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S
new file mode 100644
index 0000000..890cf81
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+ .globl plat_secondary_cold_boot_setup
+ .globl plat_is_my_cpu_primary
+ .globl plat_reset_handler
+ .globl platform_mem_init
+
+func platform_mem1_init
+ ret
+endfunc platform_mem1_init
+
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+func apply_platform_errata
+ ret
+endfunc apply_platform_errata
+
+func plat_reset_handler
+ mov x29, x30
+ bl apply_platform_errata
+
+#if defined(IMAGE_BL31)
+ ldr x0, =POLICY_SMMU_PAGESZ_64K
+ cbz x0, 1f
+ /* Set the SMMU page size in the sACR register */
+ bl _set_smmu_pagesz_64
+#endif
+1:
+ mov x30, x29
+ ret
+endfunc plat_reset_handler
+
+ /*
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ */
+func plat_secondary_cold_boot_setup
+ /* ls1088a does not do cold boot for secondary CPU */
+cb_panic:
+ b cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+ /*
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu.
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, 0x0
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
diff --git a/plat/nxp/soc-ls1088a/include/soc.h b/plat/nxp/soc-ls1088a/include/soc.h
new file mode 100644
index 0000000..793feee
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/include/soc.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOC_H
+#define SOC_H
+
+/* Chassis specific defines - common across SoC's of a particular platform */
+#include "dcfg_lsch3.h"
+#include "soc_default_base_addr.h"
+#include "soc_default_helper_macros.h"
+
+/*
+ * SVR Definition of LS1088A
+ * A: without security
+ * AE: with security
+ * (not include major and minor rev)
+ */
+#define SVR_LS1044A 0x870323
+#define SVR_LS1044AE 0x870322
+#define SVR_LS1048A 0x870321
+#define SVR_LS1048AE 0x870320
+#define SVR_LS1084A 0x870303
+#define SVR_LS1084AE 0x870302
+#define SVR_LS1088A 0x870301
+#define SVR_LS1088AE 0x870300
+
+#define SVR_WO_E 0xFFFFFE
+
+/* Number of cores in platform */
+#define NUMBER_OF_CLUSTERS 2
+#define CORES_PER_CLUSTER 4
+#define PLATFORM_CORE_COUNT (NUMBER_OF_CLUSTERS * CORES_PER_CLUSTER)
+
+/* set to 0 if the clusters are not symmetrical */
+#define SYMMETRICAL_CLUSTERS 1
+
+
+#define NUM_DRAM_REGIONS 2
+#define NXP_DRAM0_ADDR 0x80000000
+#define NXP_DRAM0_MAX_SIZE 0x80000000 /* 2 GB */
+
+#define NXP_DRAM1_ADDR 0x8080000000
+#define NXP_DRAM1_MAX_SIZE 0x7F80000000 /* 510 G */
+
+/* DRAM0 Size defined in platform_def.h */
+#define NXP_DRAM0_SIZE PLAT_DEF_DRAM0_SIZE
+
+#define NXP_POWMGTDCR 0x700123C20
+
+/* epu register offsets and values */
+#define EPU_EPGCR_OFFSET 0x0
+#define EPU_EPIMCR10_OFFSET 0x128
+#define EPU_EPCTR10_OFFSET 0xa28
+#define EPU_EPCCR10_OFFSET 0x828
+
+#ifdef EPU_EPCCR10_VAL
+#undef EPU_EPCCR10_VAL
+#endif
+#define EPU_EPCCR10_VAL 0xf2800000
+
+#define EPU_EPIMCR10_VAL 0xba000000
+#define EPU_EPCTR10_VAL 0x0
+#define EPU_EPGCR_VAL (1 << 31)
+
+/* pmu register offsets and values */
+#define PMU_PCPW20SR_OFFSET 0x830
+#define PMU_CLAINACTSETR_OFFSET 0x1100
+#define PMU_CLAINACTCLRR_OFFSET 0x1104
+#define PMU_CLSINACTSETR_OFFSET 0x1108
+#define PMU_CLSINACTCLRR_OFFSET 0x110C
+#define PMU_CLL2FLUSHSETR_OFFSET 0x1110
+#define PMU_CLSL2FLUSHCLRR_OFFSET 0x1114
+#define PMU_CLL2FLUSHSR_OFFSET 0x1118
+#define PMU_POWMGTCSR_OFFSET 0x4000
+#define PMU_IPPDEXPCR0_OFFSET 0x4040
+#define PMU_IPPDEXPCR1_OFFSET 0x4044
+#define PMU_IPPDEXPCR2_OFFSET 0x4048
+#define PMU_IPPDEXPCR3_OFFSET 0x404C
+#define PMU_IPPDEXPCR4_OFFSET 0x4050
+#define PMU_IPPDEXPCR5_OFFSET 0x4054
+#define PMU_IPSTPCR0_OFFSET 0x4120
+#define PMU_IPSTPCR1_OFFSET 0x4124
+#define PMU_IPSTPCR2_OFFSET 0x4128
+#define PMU_IPSTPCR3_OFFSET 0x412C
+#define PMU_IPSTPCR4_OFFSET 0x4130
+#define PMU_IPSTPCR5_OFFSET 0x4134
+#define PMU_IPSTPCR6_OFFSET 0x4138
+#define PMU_IPSTPACK0_OFFSET 0x4140
+#define PMU_IPSTPACK1_OFFSET 0x4144
+#define PMU_IPSTPACK2_OFFSET 0x4148
+#define PMU_IPSTPACK3_OFFSET 0x414C
+#define PMU_IPSTPACK4_OFFSET 0x4150
+#define PMU_IPSTPACK5_OFFSET 0x4154
+#define PMU_IPSTPACK6_OFFSET 0x4158
+#define PMU_POWMGTCSR_VAL (1 << 20)
+
+#define IPPDEXPCR0_MASK 0xFFFFFFFF
+#define IPPDEXPCR1_MASK 0xFFFFFFFF
+#define IPPDEXPCR2_MASK 0xFFFFFFFF
+#define IPPDEXPCR3_MASK 0xFFFFFFFF
+#define IPPDEXPCR4_MASK 0xFFFFFFFF
+#define IPPDEXPCR5_MASK 0xFFFFFFFF
+
+/* DEVDISR5_FLX_TMR */
+#define IPPDEXPCR_FLX_TMR 0x00004000
+#define DEVDISR5_FLX_TMR 0x00004000
+
+#define IPSTPCR0_VALUE 0x0041310C
+#define IPSTPCR1_VALUE 0x000003FF
+#define IPSTPCR2_VALUE 0x00013006
+
+/* Don't stop UART */
+#define IPSTPCR3_VALUE 0x0000033A
+
+#define IPSTPCR4_VALUE 0x00103300
+#define IPSTPCR5_VALUE 0x00000001
+#define IPSTPCR6_VALUE 0x00000000
+
+
+#define TZPC_BLOCK_SIZE 0x1000
+
+/* PORSR1 */
+#define PORSR1_RCW_MASK 0xFF800000
+#define PORSR1_RCW_SHIFT 23
+
+/* CFG_RCW_SRC[6:0] */
+#define RCW_SRC_TYPE_MASK 0x70
+
+/* RCW SRC NOR */
+#define NOR_16B_VAL 0x20
+
+/*
+ * RCW SRC Serial Flash
+ * 1. SERAIL NOR (QSPI)
+ * 2. OTHERS (SD/MMC, SPI, I2C1)
+ */
+#define RCW_SRC_SERIAL_MASK 0x7F
+#define QSPI_VAL 0x62
+#define SDHC_VAL 0x40
+#define EMMC_VAL 0x41
+
+/*
+ * Required LS standard platform porting definitions
+ * for CCN-504 - Read from RN-F node ID register
+ */
+#define PLAT_CLUSTER_TO_CCN_ID_MAP 1, 9, 11, 19
+
+/* Defines required for using XLAT tables from ARM common code */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 40)
+
+/*
+ * Clock Divisors
+ */
+#define NXP_PLATFORM_CLK_DIVIDER 1
+#define NXP_UART_CLK_DIVIDER 2
+
+/* dcfg register offsets and values */
+#define DCFG_DEVDISR1_OFFSET 0x70
+#define DCFG_DEVDISR2_OFFSET 0x74
+#define DCFG_DEVDISR3_OFFSET 0x78
+#define DCFG_DEVDISR5_OFFSET 0x80
+#define DCFG_DEVDISR6_OFFSET 0x84
+
+#define DCFG_DEVDISR1_SEC (1 << 22)
+#define DCFG_DEVDISR3_QBMAIN (1 << 12)
+#define DCFG_DEVDISR4_SPI_QSPI (1 << 4 | 1 << 5)
+#define DCFG_DEVDISR5_MEM (1 << 0)
+
+#define DEVDISR1_VALUE 0x0041310c
+#define DEVDISR2_VALUE 0x000003ff
+#define DEVDISR3_VALUE 0x00013006
+#define DEVDISR4_VALUE 0x0000033e
+#define DEVDISR5_VALUE 0x00103300
+#define DEVDISR6_VALUE 0x00000001
+
+/*
+ * pwr mgmt features supported in the soc-specific code:
+ * value == 0x0, the soc code does not support this feature
+ * value != 0x0, the soc code supports this feature
+ */
+#define SOC_CORE_RELEASE 0x1
+#define SOC_CORE_RESTART 0x1
+#define SOC_CORE_OFF 0x1
+#define SOC_CORE_STANDBY 0x1
+#define SOC_CORE_PWR_DWN 0x1
+#define SOC_CLUSTER_STANDBY 0x1
+#define SOC_CLUSTER_PWR_DWN 0x1
+#define SOC_SYSTEM_STANDBY 0x1
+#define SOC_SYSTEM_PWR_DWN 0x1
+#define SOC_SYSTEM_OFF 0x1
+#define SOC_SYSTEM_RESET 0x1
+
+#define SYSTEM_PWR_DOMAINS 1
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
+ NUMBER_OF_CLUSTERS + \
+ SYSTEM_PWR_DOMAINS)
+
+/* Power state coordination occurs at the system level */
+#define PLAT_PD_COORD_LVL MPIDR_AFFLVL2
+#define PLAT_MAX_PWR_LVL PLAT_PD_COORD_LVL
+
+/* Local power state for power domains in Run state */
+#define LS_LOCAL_STATE_RUN PSCI_LOCAL_STATE_RUN
+
+/* define retention state */
+#define PLAT_MAX_RET_STATE (PSCI_LOCAL_STATE_RUN + 1)
+#define LS_LOCAL_STATE_RET PLAT_MAX_RET_STATE
+
+/* define power-down state */
+#define PLAT_MAX_OFF_STATE (PLAT_MAX_RET_STATE + 1)
+#define LS_LOCAL_STATE_OFF PLAT_MAX_OFF_STATE
+
+#ifndef __ASSEMBLER__
+/* CCI slave interfaces */
+static const int cci_map[] = {
+ 3,
+ 4,
+};
+void soc_init_lowlevel(void);
+void soc_init_percpu(void);
+void _soc_set_start_addr(unsigned long addr);
+void _set_platform_security(void);
+#endif
+
+#endif /* SOC_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c b/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c
new file mode 100644
index 0000000..705463b
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <utils.h>
+
+#include <errata.h>
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+#error No static value defined
+#endif
+
+static const struct rc_timing rce[] = {
+ {U(1600), U(8), U(8)},
+ {U(1867), U(8), U(8)},
+ {U(2134), U(8), U(9)},
+ {}
+};
+
+static const struct board_timing udimm[] = {
+ {U(0x04), rce, U(0x01020307), U(0x08090b06)},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ if (popts->rdimm != 0) {
+ debug("RDIMM parameters not set.\n");
+ return -EINVAL;
+ }
+
+ ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
+ if (ret != 0) {
+ return ret;
+ }
+
+ popts->addr_hash = 1;
+ popts->cpo_sample = U(0x7b);
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
+ DDR_CDR2_VREF_TRAIN_EN |
+ DDR_CDR2_VREF_RANGE_2;
+
+ return 0;
+}
+
+long long init_ddr(void)
+{
+ int spd_addr[] = { NXP_SPD_EEPROM0 };
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ get_clocks(&sys);
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL %lu\n", sys.freq_ddr_pll0);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = NUM_OF_DDRC;
+ info.dimm_on_ctlr = DDRC_NUM_DIMM;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h b/plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h
new file mode 100644
index 0000000..ebd3a26
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0 0x51
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+#define BL2_START NXP_OCRAM_ADDR
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#define BL2_NOLOAD_START NXP_OCRAM_ADDR
+#define BL2_NOLOAD_LIMIT BL2_BASE
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 4
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES 2
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES 1
+#endif
+
+#define BL32_IRQ_SEC_PHY_TIMER 29
+#define BL31_WDOG_SEC 89
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define PLAT_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define PLAT_LS_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(15, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/platform.c b/plat/nxp/soc-ls1088a/ls1088aqds/platform.c
new file mode 100644
index 0000000..8b3eada
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/platform.mk b/plat/nxp/soc-ls1088a/ls1088aqds/platform.mk
new file mode 100644
index 0000000..97ccf26
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/platform.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+BOOT_MODE ?= qspi
+BOARD := ls1088aqds
+
+# DDR Compilation Configs
+NUM_OF_DDRC := 1
+DDRC_NUM_DIMM := 1
+DDR_ECC_EN := yes
+
+# On-Board Flash Details
+QSPI_FLASH_SZ := 0x4000000
+NOR_FLASH_SZ := 0x20000000
+
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c \
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := qspi \
+ sd \
+ nor
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1088a/soc.mk
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h b/plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h
new file mode 100644
index 0000000..7daf1c0
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/policy.h b/plat/nxp/soc-ls1088a/ls1088aqds/policy.h
new file mode 100644
index 0000000..0eaafae
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/policy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/*
+ * Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c b/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c
new file mode 100644
index 0000000..107871a
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <utils.h>
+
+#include <errata.h>
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+#error No static value defined
+#endif
+
+static const struct rc_timing rce[] = {
+ {U(1600), U(8), U(8)},
+ {U(1867), U(8), U(8)},
+ {U(2134), U(8), U(9)},
+ {}
+};
+
+static const struct board_timing udimm[] = {
+ {U(0x04), rce, U(0x01030508), U(0x090b0d06)},
+ {U(0x1f), rce, U(0x01030508), U(0x090b0d06)},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ int ret;
+ struct memctl_opt *popts = &priv->opt;
+
+ if (popts->rdimm != 0) {
+ debug("RDIMM parameters not set.\n");
+ return -EINVAL;
+ }
+
+ ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
+ if (ret != 0) {
+ return ret;
+ }
+
+ popts->addr_hash = 1;
+ popts->cpo_sample = U(0x7b);
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
+ DDR_CDR2_VREF_TRAIN_EN |
+ DDR_CDR2_VREF_RANGE_2;
+
+ return 0;
+}
+
+long long init_ddr(void)
+{
+ int spd_addr[] = { NXP_SPD_EEPROM0 };
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ get_clocks(&sys);
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL %lu\n", sys.freq_ddr_pll0);
+
+ zeromem(&info, sizeof(struct ddr_info));
+ info.num_ctlrs = NUM_OF_DDRC;
+ info.dimm_on_ctlr = DDRC_NUM_DIMM;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+ dram_size = dram_init(&info);
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h b/plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h
new file mode 100644
index 0000000..a6b14fe
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0 0x51
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+#define BL2_START NXP_OCRAM_ADDR
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#define BL2_NOLOAD_START NXP_OCRAM_ADDR
+#define BL2_NOLOAD_LIMIT BL2_BASE
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 4
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES 2
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES 1
+#endif
+
+#define BL32_IRQ_SEC_PHY_TIMER 29
+#define BL31_WDOG_SEC 89
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define PLAT_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define PLAT_LS_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(15, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/platform.c b/plat/nxp/soc-ls1088a/ls1088ardb/platform.c
new file mode 100644
index 0000000..8b3eada
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/platform.mk b/plat/nxp/soc-ls1088a/ls1088ardb/platform.mk
new file mode 100644
index 0000000..6884faf
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/platform.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+BOOT_MODE ?= qspi
+BOARD := ls1088ardb
+
+# DDR Compilation Configs
+NUM_OF_DDRC := 1
+DDRC_NUM_DIMM := 1
+DDR_ECC_EN := yes
+
+# On-Board Flash Details
+QSPI_FLASH_SZ := 0x4000000
+
+# Adding Platform files build files
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c \
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := qspi \
+ sd
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1088a/soc.mk
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h b/plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h
new file mode 100644
index 0000000..7daf1c0
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/policy.h b/plat/nxp/soc-ls1088a/ls1088ardb/policy.h
new file mode 100644
index 0000000..af206f9
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/policy.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/* Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1088a/soc.c b/plat/nxp/soc-ls1088a/soc.c
new file mode 100644
index 0000000..02d62ea
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/soc.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <caam.h>
+#include <cci.h>
+#include <common/debug.h>
+#include <dcfg.h>
+#ifdef I2C_INIT
+#include <i2c.h>
+#endif
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <ls_interconnect.h>
+#include <nxp_smmu.h>
+#include <nxp_timer.h>
+#include <plat_console.h>
+#include <plat_gic.h>
+#include <plat_tzc400.h>
+#include <pmu.h>
+#if defined(NXP_SFP_ENABLED)
+#include <sfp.h>
+#endif
+
+#include <errata.h>
+#ifdef CONFIG_OCRAM_ECC_EN
+#include <ocram.h>
+#endif
+#include <plat_common.h>
+#include <platform_def.h>
+#include <soc.h>
+
+static unsigned char _power_domain_tree_desc[NUMBER_OF_CLUSTERS + 2];
+static struct soc_type soc_list[] = {
+ SOC_ENTRY(LS1044A, LS1044A, 1, 4),
+ SOC_ENTRY(LS1044AE, LS1044AE, 1, 4),
+ SOC_ENTRY(LS1048A, LS1048A, 1, 4),
+ SOC_ENTRY(LS1048AE, LS1048AE, 1, 4),
+ SOC_ENTRY(LS1084A, LS1084A, 2, 4),
+ SOC_ENTRY(LS1084AE, LS1084AE, 2, 4),
+ SOC_ENTRY(LS1088A, LS1088A, 2, 4),
+ SOC_ENTRY(LS1088AE, LS1088AE, 2, 4),
+};
+
+static dcfg_init_info_t dcfg_init_data = {
+ .g_nxp_dcfg_addr = NXP_DCFG_ADDR,
+ .nxp_sysclk_freq = NXP_SYSCLK_FREQ,
+ .nxp_ddrclk_freq = NXP_DDRCLK_FREQ,
+ .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER,
+};
+
+/*
+ * This function dynamically constructs the topology according to
+ * SoC Flavor and returns it.
+ */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ unsigned int i;
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ /*
+ * The highest level is the system level. The next level is constituted
+ * by clusters and then cores in clusters.
+ */
+ _power_domain_tree_desc[0] = 1;
+ _power_domain_tree_desc[1] = num_clusters;
+
+ for (i = 0; i < _power_domain_tree_desc[1]; i++) {
+ _power_domain_tree_desc[i + 2] = cores_per_cluster;
+ }
+
+
+ return _power_domain_tree_desc;
+}
+
+CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256,
+ assert_invalid_ls1088a_cluster_count);
+
+/*
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ */
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
+{
+ return CORES_PER_CLUSTER;
+}
+
+/*
+ * This function returns the total number of cores in the SoC
+ */
+unsigned int get_tot_num_cores(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ return (num_clusters * cores_per_cluster);
+}
+
+/*
+ * This function returns the PMU IDLE Cluster mask.
+ */
+unsigned int get_pmu_idle_cluster_mask(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ return ((1 << num_clusters) - 2);
+}
+
+/*
+ * This function returns the PMU Flush Cluster mask.
+ */
+unsigned int get_pmu_flush_cluster_mask(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+ return ((1 << num_clusters) - 2);
+}
+
+/*
+ * This function returns the PMU IDLE Core mask.
+ */
+unsigned int get_pmu_idle_core_mask(void)
+{
+ return ((1 << get_tot_num_cores()) - 2);
+}
+
+#ifdef IMAGE_BL2
+
+void soc_bl2_prepare_exit(void)
+{
+#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE)
+ set_sfp_wr_disable();
+#endif
+}
+
+void soc_preload_setup(void)
+{
+
+}
+
+/*
+ * This function returns the boot device based on RCW_SRC
+ */
+enum boot_device get_boot_dev(void)
+{
+ enum boot_device src = BOOT_DEVICE_NONE;
+ uint32_t porsr1;
+ uint32_t rcw_src, val;
+
+ porsr1 = read_reg_porsr1();
+
+ rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT;
+
+ /* RCW SRC NOR */
+ val = rcw_src & RCW_SRC_TYPE_MASK;
+ if (val == NOR_16B_VAL) {
+ src = BOOT_DEVICE_IFC_NOR;
+ INFO("RCW BOOT SRC is IFC NOR\n");
+ } else {
+ val = rcw_src & RCW_SRC_SERIAL_MASK;
+ switch (val) {
+ case QSPI_VAL:
+ src = BOOT_DEVICE_QSPI;
+ INFO("RCW BOOT SRC is QSPI\n");
+ break;
+ case SDHC_VAL:
+ src = BOOT_DEVICE_EMMC;
+ INFO("RCW BOOT SRC is SD/EMMC\n");
+ break;
+ case EMMC_VAL:
+ src = BOOT_DEVICE_EMMC;
+ INFO("RCW BOOT SRC is SD/EMMC\n");
+ break;
+ default:
+ src = BOOT_DEVICE_NONE;
+ }
+ }
+
+ return src;
+}
+
+/*
+ * This function sets up access permissions on memory regions
+ */
+void soc_mem_access(void)
+{
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+ int i = 0;
+ struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION];
+ int dram_idx, index = 1;
+
+ for (dram_idx = 0; dram_idx < info_dram_regions->num_dram_regions;
+ dram_idx++) {
+ if (info_dram_regions->region[i].size == 0) {
+ ERROR("DDR init failure, or");
+ ERROR("DRAM regions not populated correctly.\n");
+ break;
+ }
+
+ index = populate_tzc400_reg_list(tzc400_reg_list,
+ dram_idx, index,
+ info_dram_regions->region[dram_idx].addr,
+ info_dram_regions->region[dram_idx].size,
+ NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE);
+ }
+
+ mem_access_setup(NXP_TZC_ADDR, index,
+ tzc400_reg_list);
+}
+
+/*
+ * This function implements soc specific erratum
+ * This is called before DDR is initialized or MMU is enabled
+ */
+void soc_early_init(void)
+{
+ enum boot_device dev;
+ dram_regions_info_t *dram_regions_info = get_dram_regions_info();
+
+#ifdef CONFIG_OCRAM_ECC_EN
+ ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
+#endif
+ dcfg_init(&dcfg_init_data);
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+ enable_timer_base_to_cluster(NXP_PMU_ADDR);
+ enable_core_tb(NXP_PMU_ADDR);
+
+ /*
+ * Use the region(NXP_SD_BLOCK_BUF_ADDR + NXP_SD_BLOCK_BUF_SIZE)
+ * as dma of sd
+ */
+ dev = get_boot_dev();
+ if (dev == BOOT_DEVICE_EMMC) {
+ mmap_add_region(NXP_SD_BLOCK_BUF_ADDR, NXP_SD_BLOCK_BUF_ADDR,
+ NXP_SD_BLOCK_BUF_SIZE,
+ MT_DEVICE | MT_RW | MT_NS);
+ }
+
+ /*
+ * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts.
+ */
+ smmu_cache_unlock(NXP_SMMU_ADDR);
+ INFO("SMMU Cache Unlocking is Configured.\n");
+
+#if TRUSTED_BOARD_BOOT
+ uint32_t mode;
+
+ sfp_init(NXP_SFP_ADDR);
+ /*
+ * For secure boot disable SMMU.
+ * Later when platform security policy comes in picture,
+ * this might get modified based on the policy
+ */
+ if (check_boot_mode_secure(&mode) == true) {
+ bypass_smmu(NXP_SMMU_ADDR);
+ }
+
+ /*
+ * For Mbedtls currently crypto is not supported via CAAM
+ * enable it when that support is there. In tbbr.mk
+ * the CAAM_INTEG is set as 0.
+ */
+#ifndef MBEDTLS_X509
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false) {
+ INFO("SEC is disabled.\n");
+ } else {
+ sec_init(NXP_CAAM_ADDR);
+ }
+#endif
+#endif
+
+ soc_errata();
+
+ delay_timer_init(NXP_TIMER_ADDR);
+ i2c_init(NXP_I2C_ADDR);
+ dram_regions_info->total_dram_size = init_ddr();
+}
+#else /* !IMAGE_BL2 */
+
+void soc_early_platform_setup2(void)
+{
+ dcfg_init(&dcfg_init_data);
+ /*
+ * Initialize system level generic timer for Socs
+ */
+ delay_timer_init(NXP_TIMER_ADDR);
+
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+}
+
+void soc_platform_setup(void)
+{
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ static uintptr_t target_mask_array[PLATFORM_CORE_COUNT];
+ static interrupt_prop_t ls_interrupt_props[] = {
+ PLAT_LS_G1S_IRQ_PROPS(INTR_GROUP1S),
+ PLAT_LS_G0_IRQ_PROPS(INTR_GROUP0)
+ };
+
+ plat_ls_gic_driver_init(NXP_GICD_ADDR, NXP_GICR_ADDR,
+ PLATFORM_CORE_COUNT,
+ ls_interrupt_props,
+ ARRAY_SIZE(ls_interrupt_props),
+ target_mask_array,
+ plat_core_pos);
+
+ plat_ls_gic_init();
+ enable_init_timer();
+}
+
+/*
+ * This function initializes the soc from the BL31 module
+ */
+void soc_init(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ /* low-level init of the soc */
+ soc_init_lowlevel();
+ _init_global_data();
+ soc_init_percpu();
+ _initialize_psci();
+
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ */
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ /* set platform security policies */
+ _set_platform_security();
+
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false) {
+ INFO("SEC is disabled.\n");
+ } else {
+ sec_init(NXP_CAAM_ADDR);
+ }
+}
+
+void soc_runtime_setup(void)
+{
+
+}
+#endif /* IMAGE_BL2 */
+
+/*
+ * Function to return the SoC SYS CLK
+ */
+unsigned int get_sys_clk(void)
+{
+ return NXP_SYSCLK_FREQ;
+}
+
+/*
+ * Function returns the base counter frequency
+ * after reading the first entry at CNTFID0 (0x20 offset).
+ *
+ * Function is used by:
+ * 1. ARM common code for PSCI management.
+ * 2. ARM Generic Timer init.
+ */
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+ /*
+ * Below register specifies the base frequency of the system counter.
+ * As per NXP Board Manuals:
+ * The system counter always works with SYS_REF_CLK/4 frequency clock.
+ */
+ counter_base_frequency = mmio_read_32(NXP_TIMER_ADDR + CNTFID_OFF);
+
+ return counter_base_frequency;
+}
diff --git a/plat/nxp/soc-ls1088a/soc.def b/plat/nxp/soc-ls1088a/soc.def
new file mode 100644
index 0000000..17c59ff
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/soc.def
@@ -0,0 +1,86 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# This file contains the basic architecture definitions that drive the build
+#
+# -----------------------------------------------------------------------------
+
+CORE_TYPE := a53
+
+CACHE_LINE := 6
+
+# Set to GIC400 or GIC500
+GIC := GIC500
+
+# Set to CCI400 or CCN504 or CCN508
+INTERCONNECT := CCI400
+
+# Select the DDR PHY generation to be used
+PLAT_DDR_PHY := PHY_GEN1
+
+PHYS_SYS := 64
+
+# Indicate layerscape chassis level - set to 3=LSCH3 or 2=LSCH2
+CHASSIS := 3
+
+# TZC IP Details TZC used is TZC380 or TZC400
+TZC_ID := TZC400
+
+# CONSOLE Details available is NS16550 or PL011
+CONSOLE := NS16550
+
+NXP_SFP_VER := 3_4
+
+# In IMAGE_BL2, compile time flag for handling Cache coherency
+# with CAAM for BL2 running from OCRAM
+SEC_MEM_NON_COHERENT := yes
+
+
+# OCRAM MAP for BL2
+# Before BL2
+# 0x18000000 - 0x18009fff -> Used by ROM code, (TBD - can it be used for xlat tables)
+# 0x1800a000 - 0x1801Cfff -> Reserved for BL2 binary (76 KB)
+# 0x1801D000 - 0x1801ffff -> CSF header for BL2 (12 KB)
+OCRAM_START_ADDR := 0x18000000
+OCRAM_SIZE := 0x20000
+
+CSF_HDR_SZ := 0x3000
+
+# Area of OCRAM reserved by ROM code
+NXP_ROM_RSVD := 0xa000
+
+# Input to CST create_hdr_isbc tool
+BL2_HDR_LOC := 0x1801D000
+
+# Location of BL2 on OCRAM
+# BL2_BASE=OCRAM_START_ADDR+NXP_ROM_RSVD
+BL2_BASE := 0x1800a000
+
+# SoC ERRATUM to be enabled
+
+# ARM Erratum
+ERRATA_A53_855873 := 1
+
+# DDR Erratum
+ERRATA_DDR_A008511 := 1
+ERRATA_DDR_A009803 := 1
+ERRATA_DDR_A009942 := 1
+ERRATA_DDR_A010165 := 1
+
+# Define Endianness of each module
+NXP_ESDHC_ENDIANNESS := LE
+NXP_SFP_ENDIANNESS := LE
+NXP_GPIO_ENDIANNESS := LE
+NXP_SNVS_ENDIANNESS := LE
+NXP_GUR_ENDIANNESS := LE
+NXP_SEC_ENDIANNESS := LE
+NXP_DDR_ENDIANNESS := LE
+NXP_QSPI_ENDIANNESS := LE
+
+# OCRAM ECC Enabled
+OCRAM_ECC_EN := yes
diff --git a/plat/nxp/soc-ls1088a/soc.mk b/plat/nxp/soc-ls1088a/soc.mk
new file mode 100644
index 0000000..6e39461
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/soc.mk
@@ -0,0 +1,110 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# SoC-specific build parameters
+SOC := ls1088a
+PLAT_PATH := plat/nxp
+PLAT_COMMON_PATH:= plat/nxp/common
+PLAT_DRIVERS_PATH:= drivers/nxp
+PLAT_SOC_PATH := ${PLAT_PATH}/soc-${SOC}
+BOARD_PATH := ${PLAT_SOC_PATH}/${BOARD}
+
+# Separate BL2 NOLOAD region (.bss, stack, page tables). need to
+# define BL2_NOLOAD_START and BL2_NOLOAD_LIMIT
+SEPARATE_BL2_NOLOAD_REGION := 1
+
+# get SoC-specific defnitions
+include ${PLAT_SOC_PATH}/soc.def
+include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+# For Security Features
+DISABLE_FUSE_WRITE := 1
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+ifeq (${GENERATE_COT},1)
+# Save Keys to be used by DDR FIP image
+SAVE_KEYS=1
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
+# Used by create_pbl tool to
+# create bl2_<boot_mode>_sec.pbl image
+SECURE_BOOT := yes
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM))
+
+# Selecting Drivers for SoC
+$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+
+# Selecting PSCI & SIP_SVC support
+$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31))
+
+
+# Adding SoC specific files
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
+
+PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\
+ -I${BOARD_PATH}\
+ -I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
+ -I${PLAT_COMMON_PATH}/soc_errata\
+ -I${PLAT_COMMON_PATH}/include\
+ -I${PLAT_SOC_PATH}/include
+
+ifeq (${SECURE_BOOT},yes)
+include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
+endif
+
+ifeq (${PSCI_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/psci/psci.mk
+endif
+
+ifeq (${SIPSVC_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk
+endif
+
+# for fuse-fip & fuse-programming
+ifeq (${FUSE_PROG}, 1)
+include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk
+endif
+
+ifeq (${IMG_LOADR_NEEDED},yes)
+include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk
+endif
+
+# Adding source files for the above selected drivers.
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+PLAT_BL_COMMON_SOURCES += ${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\
+ ${PLAT_SOC_PATH}/${ARCH}/${SOC}_helpers.S\
+ ${PLAT_SOC_PATH}/soc.c
+
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\
+ ${PSCI_SOURCES}\
+ ${SIPSVC_SOURCES}\
+ ${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S
+
+ifeq (${TEST_BL31}, 1)
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S \
+ ${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S
+endif
+
+BL2_SOURCES += ${DDR_CNTLR_SOURCES}\
+ ${TBBR_SOURCES}\
+ ${FUSE_SOURCES}
+
+# Adding TFA setup files
+include ${PLAT_PATH}/common/setup/common.mk
diff --git a/plat/nxp/soc-lx2160a/aarch64/lx2160a.S b/plat/nxp/soc-lx2160a/aarch64/lx2160a.S
new file mode 100644
index 0000000..cc679f2
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/aarch64/lx2160a.S
@@ -0,0 +1,1816 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+.section .text, "ax"
+
+#include <asm_macros.S>
+
+#include <lib/psci/psci.h>
+#include <nxp_timer.h>
+#include <plat_gic.h>
+#include <pmu.h>
+
+#include <bl31_data.h>
+#include <plat_psci.h>
+#include <platform_def.h>
+
+.global soc_init_start
+.global soc_init_percpu
+.global soc_init_finish
+.global _set_platform_security
+.global _soc_set_start_addr
+
+.global _soc_core_release
+.global _soc_ck_disabled
+.global _soc_core_restart
+.global _soc_core_prep_off
+.global _soc_core_entr_off
+.global _soc_core_exit_off
+.global _soc_sys_reset
+.global _soc_sys_off
+.global _soc_core_prep_stdby
+.global _soc_core_entr_stdby
+.global _soc_core_exit_stdby
+.global _soc_core_prep_pwrdn
+.global _soc_core_entr_pwrdn
+.global _soc_core_exit_pwrdn
+.global _soc_clstr_prep_stdby
+.global _soc_clstr_exit_stdby
+.global _soc_clstr_prep_pwrdn
+.global _soc_clstr_exit_pwrdn
+.global _soc_sys_prep_stdby
+.global _soc_sys_exit_stdby
+.global _soc_sys_prep_pwrdn
+.global _soc_sys_pwrdn_wfi
+.global _soc_sys_exit_pwrdn
+
+.equ TZPC_BASE, 0x02200000
+.equ TZPCDECPROT_0_SET_BASE, 0x02200804
+.equ TZPCDECPROT_1_SET_BASE, 0x02200810
+.equ TZPCDECPROT_2_SET_BASE, 0x0220081C
+
+#define CLUSTER_3_CORES_MASK 0xC0
+#define CLUSTER_3_IN_RESET 1
+#define CLUSTER_3_NORMAL 0
+
+/* cluster 3 handling no longer based on frequency, but rather on RCW[850],
+ * which is bit 18 of RCWSR27
+ */
+#define CLUSTER_3_RCW_BIT 0x40000
+
+/* retry count for clock-stop acks */
+.equ CLOCK_RETRY_CNT, 800
+
+/* disable prefetching in the A72 core */
+#define CPUACTLR_DIS_LS_HW_PRE 0x100000000000000
+#define CPUACTLR_DIS_L2_TLB_PRE 0x200000
+
+/* Function starts the initialization tasks of the soc,
+ * using secondary cores if they are available
+ *
+ * Called from C, saving the non-volatile regs
+ * save these as pairs of registers to maintain the
+ * required 16-byte alignment on the stack
+ *
+ * in:
+ * out:
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11
+ */
+func soc_init_start
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x18, x30, [sp, #-16]!
+
+ /* make sure the personality has been
+ * established by releasing cores that
+ * are marked "to-be-disabled" from reset
+ */
+ bl release_disabled /* 0-9 */
+
+ /* init the task flags */
+ bl _init_task_flags /* 0-1 */
+
+ /* set SCRATCHRW7 to 0x0 */
+ ldr x0, =DCFG_SCRATCHRW7_OFFSET
+ mov x1, xzr
+ bl _write_reg_dcfg
+
+1:
+ /* restore the aarch32/64 non-volatile registers */
+ ldp x18, x30, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ ret
+endfunc soc_init_start
+
+
+/* Function performs any soc-specific initialization that is needed on
+ * a per-core basis.
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+func soc_init_percpu
+ stp x4, x30, [sp, #-16]!
+
+ bl plat_my_core_mask
+ mov x2, x0 /* x2 = core mask */
+
+ /* Check if this core is marked for prefetch disable
+ */
+ mov x0, #PREFETCH_DIS_OFFSET
+ bl _get_global_data /* 0-1 */
+ tst x0, x2
+ b.eq 1f
+ bl _disable_ldstr_pfetch_A72 /* 0 */
+1:
+ mov x0, #NXP_PMU_ADDR
+ bl enable_timer_base_to_cluster
+ ldp x4, x30, [sp], #16
+ ret
+endfunc soc_init_percpu
+
+
+/* Function completes the initialization tasks of the soc
+ * in:
+ * out:
+ * uses x0, x1, x2, x3, x4
+ */
+func soc_init_finish
+ stp x4, x30, [sp, #-16]!
+
+ ldp x4, x30, [sp], #16
+ ret
+endfunc soc_init_finish
+
+
+/* Function sets the security mechanisms in the SoC to implement the
+ * Platform Security Policy
+ */
+func _set_platform_security
+ mov x8, x30
+
+#if (!SUPPRESS_TZC)
+ /* initialize the tzpc */
+ bl init_tzpc
+#endif
+
+#if (!SUPPRESS_SEC)
+ /* initialize secmon */
+#ifdef NXP_SNVS_ENABLED
+ mov x0, #NXP_SNVS_ADDR
+ bl init_sec_mon
+#endif
+#endif
+
+ mov x30, x8
+ ret
+endfunc _set_platform_security
+
+
+/* Function writes a 64-bit address to bootlocptrh/l
+ * in: x0, 64-bit address to write to BOOTLOCPTRL/H
+ * uses x0, x1, x2
+ */
+func _soc_set_start_addr
+ /* Get the 64-bit base address of the dcfg block */
+ ldr x2, =NXP_DCFG_ADDR
+
+ /* write the 32-bit BOOTLOCPTRL register */
+ mov x1, x0
+ str w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET]
+
+ /* write the 32-bit BOOTLOCPTRH register */
+ lsr x1, x0, #32
+ str w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET]
+ ret
+endfunc _soc_set_start_addr
+
+/* Function releases a secondary core from reset
+ * in: x0 = core_mask_lsb
+ * out: none
+ * uses: x0, x1, x2, x3
+ */
+func _soc_core_release
+ mov x3, x30
+
+ ldr x1, =NXP_SEC_REGFILE_ADDR
+ /* write to CORE_HOLD to tell
+ * the bootrom that this core is
+ * expected to run.
+ */
+ str w0, [x1, #CORE_HOLD_OFFSET]
+
+ /* read-modify-write BRRL to release core */
+ mov x1, #NXP_RESET_ADDR
+ ldr w2, [x1, #BRR_OFFSET]
+
+ /* x0 = core mask */
+ orr w2, w2, w0
+ str w2, [x1, #BRR_OFFSET]
+ dsb sy
+ isb
+
+ /* send event */
+ sev
+ isb
+
+ mov x30, x3
+ ret
+endfunc _soc_core_release
+
+
+/* Function determines if a core is disabled via COREDISABLEDSR
+ * in: w0 = core_mask_lsb
+ * out: w0 = 0, core not disabled
+ * w0 != 0, core disabled
+ * uses x0, x1
+ */
+func _soc_ck_disabled
+
+ /* get base addr of dcfg block */
+ ldr x1, =NXP_DCFG_ADDR
+
+ /* read COREDISABLEDSR */
+ ldr w1, [x1, #DCFG_COREDISABLEDSR_OFFSET]
+
+ /* test core bit */
+ and w0, w1, w0
+
+ ret
+endfunc _soc_ck_disabled
+
+
+/* Part of CPU_ON
+ * Function restarts a core shutdown via _soc_core_entr_off
+ * in: x0 = core mask lsb (of the target cpu)
+ * out: x0 == 0, on success
+ * x0 != 0, on failure
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+func _soc_core_restart
+ mov x6, x30
+ mov x4, x0
+
+ /* pgm GICD_CTLR - enable secure grp0 */
+ mov x5, #NXP_GICD_ADDR
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ orr w2, w2, #GICD_CTLR_EN_GRP_0
+ str w2, [x5, #GICD_CTLR_OFFSET]
+ dsb sy
+ isb
+
+ /* poll on RWP til write completes */
+4:
+ ldr w2, [x5, #GICD_CTLR_OFFSET]
+ tst w2, #GICD_CTLR_RWP
+ b.ne 4b
+
+ /* x4 = core mask lsb
+ * x5 = gicd base addr
+ */
+ mov x0, x4
+ bl get_mpidr_value
+
+ /* x0 = mpidr of target core
+ * x4 = core mask lsb of target core
+ * x5 = gicd base addr
+ */
+
+ /* generate target list bit */
+ and x1, x0, #MPIDR_AFFINITY0_MASK
+ mov x2, #1
+ lsl x2, x2, x1
+
+ /* get the affinity1 field */
+ and x1, x0, #MPIDR_AFFINITY1_MASK
+ lsl x1, x1, #8
+ orr x2, x2, x1
+
+ /* insert the INTID for SGI15 */
+ orr x2, x2, #ICC_SGI0R_EL1_INTID
+
+ /* fire the SGI */
+ msr ICC_SGI0R_EL1, x2
+ dsb sy
+ isb
+
+ /* load '0' on success */
+ mov x0, xzr
+
+ mov x30, x6
+ ret
+endfunc _soc_core_restart
+
+
+/* Part of CPU_OFF
+ * Function programs SoC & GIC registers in preparation for shutting down
+ * the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7
+ */
+func _soc_core_prep_off
+ mov x8, x30
+ mov x7, x0 /* x7 = core mask lsb */
+
+ mrs x1, CORTEX_A72_ECTLR_EL1
+
+ /* set smp and disable L2 snoops in cpuectlr */
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH
+ bic x1, x1, #CPUECTLR_INS_PREFETCH_MASK
+ bic x1, x1, #CPUECTLR_DAT_PREFETCH_MASK
+
+ /* set retention control in cpuectlr */
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ orr x1, x1, #CPUECTLR_TIMER_8TICKS
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ /* get redistributor rd base addr for this core */
+ mov x0, x7
+ bl get_gic_rd_base
+ mov x6, x0
+
+ /* get redistributor sgi base addr for this core */
+ mov x0, x7
+ bl get_gic_sgi_base
+ mov x5, x0
+
+ /* x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w3, #GICR_ICENABLER0_SGI15
+ str w3, [x5, #GICR_ICENABLER0_OFFSET]
+2:
+ /* poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* disable GRP1 interrupts at cpu interface */
+ msr ICC_IGRPEN1_EL3, xzr
+
+ /* disable GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* program the redistributor - poll on GICR_CTLR.RWP as needed */
+
+ /* define SGI 15 as Grp0 - GICR_IGROUPR0 */
+ ldr w4, [x5, #GICR_IGROUPR0_OFFSET]
+ bic w4, w4, #GICR_IGROUPR0_SGI15
+ str w4, [x5, #GICR_IGROUPR0_OFFSET]
+
+ /* define SGI 15 as Grp0 - GICR_IGRPMODR0 */
+ ldr w3, [x5, #GICR_IGRPMODR0_OFFSET]
+ bic w3, w3, #GICR_IGRPMODR0_SGI15
+ str w3, [x5, #GICR_IGRPMODR0_OFFSET]
+
+ /* set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */
+ ldr w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+ bic w4, w4, #GICR_IPRIORITYR3_SGI15_MASK
+ str w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+
+ /* enable SGI 15 at redistributor - GICR_ISENABLER0 */
+ mov w3, #GICR_ISENABLER0_SGI15
+ str w3, [x5, #GICR_ISENABLER0_OFFSET]
+ dsb sy
+ isb
+3:
+ /* poll on rwp bit in GICR_CTLR */
+ ldr w4, [x6, #GICR_CTLR_OFFSET]
+ tst w4, #GICR_CTLR_RWP
+ b.ne 3b
+
+ /* quiesce the debug interfaces */
+ mrs x3, osdlr_el1
+ orr x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ /* enable grp0 ints */
+ mov x3, #ICC_IGRPEN0_EL1_EN
+ msr ICC_IGRPEN0_EL1, x3
+
+ /* x5 = gicr sgi base addr
+ * x6 = gicr rd base addr
+ * x7 = core mask lsb
+ */
+
+ /* clear any pending interrupts */
+ mvn w1, wzr
+ str w1, [x5, #GICR_ICPENDR0_OFFSET]
+
+ /* make sure system counter is enabled */
+ ldr x3, =NXP_TIMER_ADDR
+ ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 4f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+4:
+ /* enable the core timer and mask timer interrupt */
+ mov x1, #CNTP_CTL_EL0_EN
+ orr x1, x1, #CNTP_CTL_EL0_IMASK
+ msr cntp_ctl_el0, x1
+
+ isb
+ mov x30, x8
+ ret
+endfunc _soc_core_prep_off
+
+
+/* Part of CPU_OFF:
+ * Function performs the final steps to shutdown the core
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5
+ */
+func _soc_core_entr_off
+ mov x5, x30
+ mov x4, x0
+
+1:
+ /* enter low-power state by executing wfi */
+ wfi
+
+ /* see if SGI15 woke us up */
+ mrs x2, ICC_IAR0_EL1
+ mov x3, #ICC_IAR0_EL1_SGI15
+ cmp x2, x3
+ b.ne 2f
+
+ /* deactivate the intrrupts. */
+ msr ICC_EOIR0_EL1, x2
+
+2:
+ /* check if core is turned ON */
+ mov x0, x4
+ /* Fetched the core state in x0 */
+ bl _getCoreState
+
+ cmp x0, #CORE_WAKEUP
+ b.ne 1b
+
+ /* Reached here, exited the wfi */
+
+ mov x30, x5
+ ret
+endfunc _soc_core_entr_off
+
+
+/* Part of CPU_OFF:
+ * Function starts the process of starting a core back up
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+func _soc_core_exit_off
+ mov x6, x30
+ mov x5, x0
+
+ /* disable forwarding of GRP0 ints at cpu interface */
+ msr ICC_IGRPEN0_EL1, xzr
+
+ /* get redistributor sgi base addr for this core */
+ mov x0, x5
+ bl get_gic_sgi_base
+ mov x4, x0
+
+ /* x4 = gicr sgi base addr
+ * x5 = core mask
+ */
+
+ /* disable SGI 15 at redistributor - GICR_ICENABLER0 */
+ mov w1, #GICR_ICENABLER0_SGI15
+ str w1, [x4, #GICR_ICENABLER0_OFFSET]
+
+ /* get redistributor rd base addr for this core */
+ mov x0, x5
+ bl get_gic_rd_base
+ mov x4, x0
+
+2:
+ /* poll on rwp bit in GICR_CTLR */
+ ldr w2, [x4, #GICR_CTLR_OFFSET]
+ tst w2, #GICR_CTLR_RWP
+ b.ne 2b
+
+ /* unlock the debug interfaces */
+ mrs x3, osdlr_el1
+ bic x3, x3, #OSDLR_EL1_DLK_LOCK
+ msr osdlr_el1, x3
+ isb
+
+ dsb sy
+ isb
+ mov x30, x6
+ ret
+endfunc _soc_core_exit_off
+
+
+/* Function requests a reset of the entire SOC
+ * in: none
+ * out: none
+ * uses: x0, x1, x2, x3, x4, x5, x6
+ */
+func _soc_sys_reset
+ mov x6, x30
+
+ ldr x2, =NXP_RST_ADDR
+ /* clear the RST_REQ_MSK and SW_RST_REQ */
+
+ mov w0, #0x00000000
+ str w0, [x2, #RSTCNTL_OFFSET]
+
+ /* initiate the sw reset request */
+ mov w0, #SW_RST_REQ_INIT
+ str w0, [x2, #RSTCNTL_OFFSET]
+
+ /* In case this address range is mapped as cacheable,
+ * flush the write out of the dcaches.
+ */
+ add x2, x2, #RSTCNTL_OFFSET
+ dc cvac, x2
+ dsb st
+ isb
+
+ /* Function does not return */
+ b .
+endfunc _soc_sys_reset
+
+
+/* Part of SYSTEM_OFF:
+ * Function turns off the SoC clocks
+ * Note: Function is not intended to return, and the only allowable
+ * recovery is POR
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+func _soc_sys_off
+
+ /* disable sec, QBman, spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+ ldr w1, =DCFG_DEVDISR1_SEC
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR3_OFFSET
+ ldr w1, =DCFG_DEVDISR3_QBMAIN
+ str w1, [x2, x0]
+ ldr x0, =DCFG_DEVDISR4_OFFSET
+ ldr w1, =DCFG_DEVDISR4_SPI_QSPI
+ str w1, [x2, x0]
+
+ /* set TPMWAKEMR0 */
+ ldr x0, =TPMWAKEMR0_ADDR
+ mov w1, #0x1
+ str w1, [x0]
+
+ /* disable icache, dcache, mmu @ EL1 */
+ mov x1, #SCTLR_I_C_M_MASK
+ mrs x0, sctlr_el1
+ bic x0, x0, x1
+ msr sctlr_el1, x0
+
+ /* disable L2 prefetches */
+ mrs x0, CORTEX_A72_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ orr x0, x0, #CPUECTLR_SMPEN_EN
+ orr x0, x0, #CPUECTLR_TIMER_8TICKS
+ msr CORTEX_A72_ECTLR_EL1, x0
+ isb
+
+ /* disable CCN snoop domain */
+ mov x1, #NXP_CCN_HN_F_0_ADDR
+ ldr x0, =CCN_HN_F_SNP_DMN_CTL_MASK
+ str x0, [x1, #CCN_HN_F_SNP_DMN_CTL_CLR_OFFSET]
+3:
+ ldr w2, [x1, #CCN_HN_F_SNP_DMN_CTL_OFFSET]
+ cmp w2, #0x2
+ b.ne 3b
+
+ mov x3, #NXP_PMU_ADDR
+
+4:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, #PMU_IDLE_CORE_MASK
+ b.ne 4b
+
+ mov w1, #PMU_IDLE_CLUSTER_MASK
+ str w1, [x3, #PMU_CLAINACTSETR_OFFSET]
+
+1:
+ ldr w1, [x3, #PMU_PCPW20SR_OFFSET]
+ cmp w1, #PMU_IDLE_CORE_MASK
+ b.ne 1b
+
+ mov w1, #PMU_FLUSH_CLUSTER_MASK
+ str w1, [x3, #PMU_CLL2FLUSHSETR_OFFSET]
+
+2:
+ ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET]
+ cmp w1, #PMU_FLUSH_CLUSTER_MASK
+ b.ne 2b
+
+ mov w1, #PMU_FLUSH_CLUSTER_MASK
+ str w1, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET]
+
+ mov w1, #PMU_FLUSH_CLUSTER_MASK
+ str w1, [x3, #PMU_CLSINACTSETR_OFFSET]
+
+ mov x2, #DAIF_SET_MASK
+ mrs x1, spsr_el1
+ orr x1, x1, x2
+ msr spsr_el1, x1
+
+ mrs x1, spsr_el2
+ orr x1, x1, x2
+ msr spsr_el2, x1
+
+ /* force the debug interface to be quiescent */
+ mrs x0, osdlr_el1
+ orr x0, x0, #0x1
+ msr osdlr_el1, x0
+
+ /* invalidate all TLB entries at all 3 exception levels */
+ tlbi alle1
+ tlbi alle2
+ tlbi alle3
+
+ /* x3 = pmu base addr */
+
+ /* request lpm20 */
+ ldr x0, =PMU_POWMGTCSR_OFFSET
+ ldr w1, =PMU_POWMGTCSR_VAL
+ str w1, [x3, x0]
+
+5:
+ wfe
+ b.eq 5b
+endfunc _soc_sys_off
+
+
+/* Part of CPU_SUSPEND
+ * Function puts the calling core into standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+func _soc_core_entr_stdby
+
+ dsb sy
+ isb
+ wfi
+
+ ret
+endfunc _soc_core_entr_stdby
+
+
+/* Part of CPU_SUSPEND
+ * Function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+func _soc_core_prep_stdby
+
+ /* clear CORTEX_A72_ECTLR_EL1[2:0] */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ ret
+endfunc _soc_core_prep_stdby
+
+
+/* Part of CPU_SUSPEND
+ * Function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_core_exit_stdby
+
+ ret
+endfunc _soc_core_exit_stdby
+
+
+/* Part of CPU_SUSPEND
+ * Function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_core_prep_pwrdn
+
+ /* make sure system counter is enabled */
+ ldr x2, =NXP_TIMER_ADDR
+ ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+
+ /* enable dynamic retention control (CPUECTLR[2:0])
+ * set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_8TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ isb
+ ret
+endfunc _soc_core_prep_pwrdn
+
+
+/* Part of CPU_SUSPEND
+ * Function puts the calling core into a power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+func _soc_core_entr_pwrdn
+
+ /* X0 = core mask lsb */
+
+ dsb sy
+ isb
+ wfi
+
+ ret
+endfunc _soc_core_entr_pwrdn
+
+
+/* Part of CPU_SUSPEND
+ * Function performs any SoC-specific cleanup after power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_core_exit_pwrdn
+
+ ret
+endfunc _soc_core_exit_pwrdn
+
+
+/* Part of CPU_SUSPEND
+ * Function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+func _soc_clstr_prep_stdby
+
+ /* clear CORTEX_A72_ECTLR_EL1[2:0] */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ ret
+endfunc _soc_clstr_prep_stdby
+
+
+/* Part of CPU_SUSPEND
+ * Function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_clstr_exit_stdby
+
+ ret
+endfunc _soc_clstr_exit_stdby
+
+
+/* Part of CPU_SUSPEND
+ * Function performs SoC-specific programming prior to power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_clstr_prep_pwrdn
+
+ /* make sure system counter is enabled */
+ ldr x2, =NXP_TIMER_ADDR
+ ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+ tst w0, #SYS_COUNTER_CNTCR_EN
+ b.ne 1f
+ orr w0, w0, #SYS_COUNTER_CNTCR_EN
+ str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+
+ /* enable dynamic retention control (CPUECTLR[2:0])
+ * set the SMPEN bit (CPUECTLR[6])
+ */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_RET_MASK
+ orr x1, x1, #CPUECTLR_TIMER_8TICKS
+ orr x1, x1, #CPUECTLR_SMPEN_EN
+ msr CORTEX_A72_ECTLR_EL1, x1
+
+ isb
+ ret
+endfunc _soc_clstr_prep_pwrdn
+
+
+/* Part of CPU_SUSPEND
+ * Function performs any SoC-specific cleanup after power-down state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_clstr_exit_pwrdn
+
+ ret
+endfunc _soc_clstr_exit_pwrdn
+
+
+/* Part of CPU_SUSPEND
+ * Function performs SoC-specific programming prior to standby
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+func _soc_sys_prep_stdby
+
+ /* clear CORTEX_A72_ECTLR_EL1[2:0] */
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ bic x1, x1, #CPUECTLR_TIMER_MASK
+ msr CORTEX_A72_ECTLR_EL1, x1
+ ret
+endfunc _soc_sys_prep_stdby
+
+
+/* Part of CPU_SUSPEND
+ * Function performs any SoC-specific cleanup after standby state
+ * in: x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+func _soc_sys_exit_stdby
+
+ ret
+endfunc _soc_sys_exit_stdby
+
+
+/* Part of CPU_SUSPEND
+ * Function performs SoC-specific programming prior to
+ * suspend-to-power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+func _soc_sys_prep_pwrdn
+
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ /* make sure the smp bit is set */
+ orr x1, x1, #CPUECTLR_SMPEN_MASK
+ /* set the retention control */
+ orr x1, x1, #CPUECTLR_RET_8CLK
+ /* disable tablewalk prefetch */
+ orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH
+ msr CORTEX_A72_ECTLR_EL1, x1
+ isb
+
+ ret
+endfunc _soc_sys_prep_pwrdn
+
+
+/* Part of CPU_SUSPEND
+ * Function puts the calling core, and potentially the soc, into a
+ * low-power state
+ * in: x0 = core mask lsb
+ * out: x0 = 0, success
+ * x0 < 0, failure
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14,
+ * x15, x16, x17, x18, x19, x20, x21, x28
+ */
+func _soc_sys_pwrdn_wfi
+ mov x28, x30
+
+ /* disable cluster snooping in the CCN-508 */
+ ldr x1, =NXP_CCN_HN_F_0_ADDR
+ ldr x7, [x1, #CCN_HN_F_SNP_DMN_CTL_OFFSET]
+ mov x6, #CCN_HNF_NODE_COUNT
+1:
+ str x7, [x1, #CCN_HN_F_SNP_DMN_CTL_CLR_OFFSET]
+ sub x6, x6, #1
+ add x1, x1, #CCN_HNF_OFFSET
+ cbnz x6, 1b
+
+ /* x0 = core mask
+ * x7 = hnf sdcr
+ */
+
+ ldr x1, =NXP_PMU_CCSR_ADDR
+ ldr x2, =NXP_PMU_DCSR_ADDR
+
+ /* enable the stop-request-override */
+ mov x3, #PMU_POWMGTDCR0_OFFSET
+ mov x4, #POWMGTDCR_STP_OV_EN
+ str w4, [x2, x3]
+
+ /* x0 = core mask
+ * x1 = NXP_PMU_CCSR_ADDR
+ * x2 = NXP_PMU_DCSR_ADDR
+ * x7 = hnf sdcr
+ */
+
+ /* disable prefetching in the A72 core */
+ mrs x8, CORTEX_A72_CPUACTLR_EL1
+ tst x8, #CPUACTLR_DIS_LS_HW_PRE
+ b.ne 2f
+ dsb sy
+ isb
+ /* disable data prefetch */
+ orr x16, x8, #CPUACTLR_DIS_LS_HW_PRE
+ /* disable tlb prefetch */
+ orr x16, x16, #CPUACTLR_DIS_L2_TLB_PRE
+ msr CORTEX_A72_CPUACTLR_EL1, x16
+ isb
+
+ /* x0 = core mask
+ * x1 = NXP_PMU_CCSR_ADDR
+ * x2 = NXP_PMU_DCSR_ADDR
+ * x7 = hnf sdcr
+ * x8 = cpuactlr
+ */
+
+2:
+ /* save hnf-sdcr and cpuactlr to stack */
+ stp x7, x8, [sp, #-16]!
+
+ /* x0 = core mask
+ * x1 = NXP_PMU_CCSR_ADDR
+ * x2 = NXP_PMU_DCSR_ADDR
+ */
+
+ /* save the IPSTPCRn registers to stack */
+ mov x15, #PMU_IPSTPCR0_OFFSET
+ ldr w9, [x1, x15]
+ mov x16, #PMU_IPSTPCR1_OFFSET
+ ldr w10, [x1, x16]
+ mov x17, #PMU_IPSTPCR2_OFFSET
+ ldr w11, [x1, x17]
+ mov x18, #PMU_IPSTPCR3_OFFSET
+ ldr w12, [x1, x18]
+ mov x19, #PMU_IPSTPCR4_OFFSET
+ ldr w13, [x1, x19]
+ mov x20, #PMU_IPSTPCR5_OFFSET
+ ldr w14, [x1, x20]
+
+ stp x9, x10, [sp, #-16]!
+ stp x11, x12, [sp, #-16]!
+ stp x13, x14, [sp, #-16]!
+
+ /* x0 = core mask
+ * x1 = NXP_PMU_CCSR_ADDR
+ * x2 = NXP_PMU_DCSR_ADDR
+ * x15 = PMU_IPSTPCR0_OFFSET
+ * x16 = PMU_IPSTPCR1_OFFSET
+ * x17 = PMU_IPSTPCR2_OFFSET
+ * x18 = PMU_IPSTPCR3_OFFSET
+ * x19 = PMU_IPSTPCR4_OFFSET
+ * x20 = PMU_IPSTPCR5_OFFSET
+ */
+
+ /* load the full clock mask for IPSTPCR0 */
+ ldr x3, =DEVDISR1_MASK
+ /* get the exclusions */
+ mov x21, #PMU_IPPDEXPCR0_OFFSET
+ ldr w4, [x1, x21]
+ /* apply the exclusions to the mask */
+ bic w7, w3, w4
+ /* stop the clocks in IPSTPCR0 */
+ str w7, [x1, x15]
+
+ /* use same procedure for IPSTPCR1-IPSTPCR5 */
+
+ /* stop the clocks in IPSTPCR1 */
+ ldr x5, =DEVDISR2_MASK
+ mov x21, #PMU_IPPDEXPCR1_OFFSET
+ ldr w6, [x1, x21]
+ bic w8, w5, w6
+ str w8, [x1, x16]
+
+ /* stop the clocks in IPSTPCR2 */
+ ldr x3, =DEVDISR3_MASK
+ mov x21, #PMU_IPPDEXPCR2_OFFSET
+ ldr w4, [x1, x21]
+ bic w9, w3, w4
+ str w9, [x1, x17]
+
+ /* stop the clocks in IPSTPCR3 */
+ ldr x5, =DEVDISR4_MASK
+ mov x21, #PMU_IPPDEXPCR3_OFFSET
+ ldr w6, [x1, x21]
+ bic w10, w5, w6
+ str w10, [x1, x18]
+
+ /* stop the clocks in IPSTPCR4
+ * - exclude the ddr clocks as we are currently executing
+ * out of *some* memory, might be ddr
+ * - exclude the OCRAM clk so that we retain any code/data in
+ * OCRAM
+ * - may need to exclude the debug clock if we are testing
+ */
+ ldr x3, =DEVDISR5_MASK
+ mov w6, #DEVDISR5_MASK_ALL_MEM
+ bic w3, w3, w6
+
+ mov w5, #POLICY_DEBUG_ENABLE
+ cbz w5, 3f
+ mov w6, #DEVDISR5_MASK_DBG
+ bic w3, w3, w6
+3:
+ mov x21, #PMU_IPPDEXPCR4_OFFSET
+ ldr w4, [x1, x21]
+ bic w11, w3, w4
+ str w11, [x1, x19]
+
+ /* stop the clocks in IPSTPCR5 */
+ ldr x5, =DEVDISR6_MASK
+ mov x21, #PMU_IPPDEXPCR5_OFFSET
+ ldr w6, [x1, x21]
+ bic w12, w5, w6
+ str w12, [x1, x20]
+
+ /* x0 = core mask
+ * x1 = NXP_PMU_CCSR_ADDR
+ * x2 = NXP_PMU_DCSR_ADDR
+ * x7 = IPSTPCR0
+ * x8 = IPSTPCR1
+ * x9 = IPSTPCR2
+ * x10 = IPSTPCR3
+ * x11 = IPSTPCR4
+ * x12 = IPSTPCR5
+ */
+
+ /* poll until the clocks are stopped in IPSTPACKSR0 */
+ mov w4, #CLOCK_RETRY_CNT
+ mov x21, #PMU_IPSTPACKSR0_OFFSET
+4:
+ ldr w5, [x1, x21]
+ cmp w5, w7
+ b.eq 5f
+ sub w4, w4, #1
+ cbnz w4, 4b
+
+ /* poll until the clocks are stopped in IPSTPACKSR1 */
+5:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x21, #PMU_IPSTPACKSR1_OFFSET
+6:
+ ldr w5, [x1, x21]
+ cmp w5, w8
+ b.eq 7f
+ sub w4, w4, #1
+ cbnz w4, 6b
+
+ /* poll until the clocks are stopped in IPSTPACKSR2 */
+7:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x21, #PMU_IPSTPACKSR2_OFFSET
+8:
+ ldr w5, [x1, x21]
+ cmp w5, w9
+ b.eq 9f
+ sub w4, w4, #1
+ cbnz w4, 8b
+
+ /* poll until the clocks are stopped in IPSTPACKSR3 */
+9:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x21, #PMU_IPSTPACKSR3_OFFSET
+10:
+ ldr w5, [x1, x21]
+ cmp w5, w10
+ b.eq 11f
+ sub w4, w4, #1
+ cbnz w4, 10b
+
+ /* poll until the clocks are stopped in IPSTPACKSR4 */
+11:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x21, #PMU_IPSTPACKSR4_OFFSET
+12:
+ ldr w5, [x1, x21]
+ cmp w5, w11
+ b.eq 13f
+ sub w4, w4, #1
+ cbnz w4, 12b
+
+ /* poll until the clocks are stopped in IPSTPACKSR5 */
+13:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x21, #PMU_IPSTPACKSR5_OFFSET
+14:
+ ldr w5, [x1, x21]
+ cmp w5, w12
+ b.eq 15f
+ sub w4, w4, #1
+ cbnz w4, 14b
+
+ /* x0 = core mask
+ * x1 = NXP_PMU_CCSR_ADDR
+ * x2 = NXP_PMU_DCSR_ADDR
+ * x7 = IPSTPCR0
+ * x8 = IPSTPCR1
+ * x9 = IPSTPCR2
+ * x10 = IPSTPCR3
+ * x11 = IPSTPCR4
+ * x12 = IPSTPCR5
+ */
+
+15:
+ mov x3, #NXP_DCFG_ADDR
+
+ /* save the devdisr registers to stack */
+ ldr w13, [x3, #DCFG_DEVDISR1_OFFSET]
+ ldr w14, [x3, #DCFG_DEVDISR2_OFFSET]
+ ldr w15, [x3, #DCFG_DEVDISR3_OFFSET]
+ ldr w16, [x3, #DCFG_DEVDISR4_OFFSET]
+ ldr w17, [x3, #DCFG_DEVDISR5_OFFSET]
+ ldr w18, [x3, #DCFG_DEVDISR6_OFFSET]
+
+ stp x13, x14, [sp, #-16]!
+ stp x15, x16, [sp, #-16]!
+ stp x17, x18, [sp, #-16]!
+
+ /* power down the IP in DEVDISR1 - corresponds to IPSTPCR0 */
+ str w7, [x3, #DCFG_DEVDISR1_OFFSET]
+
+ /* power down the IP in DEVDISR2 - corresponds to IPSTPCR1 */
+ str w8, [x3, #DCFG_DEVDISR2_OFFSET]
+
+ /* power down the IP in DEVDISR3 - corresponds to IPSTPCR2 */
+ str w9, [x3, #DCFG_DEVDISR3_OFFSET]
+
+ /* power down the IP in DEVDISR4 - corresponds to IPSTPCR3 */
+ str w10, [x3, #DCFG_DEVDISR4_OFFSET]
+
+ /* power down the IP in DEVDISR5 - corresponds to IPSTPCR4 */
+ str w11, [x3, #DCFG_DEVDISR5_OFFSET]
+
+ /* power down the IP in DEVDISR6 - corresponds to IPSTPCR5 */
+ str w12, [x3, #DCFG_DEVDISR6_OFFSET]
+
+ /* setup register values for the cache-only sequence */
+ mov x4, #NXP_DDR_ADDR
+ mov x5, #NXP_DDR2_ADDR
+ mov x6, x11
+ mov x7, x17
+ ldr x12, =PMU_CLAINACTSETR_OFFSET
+ ldr x13, =PMU_CLSINACTSETR_OFFSET
+ ldr x14, =PMU_CLAINACTCLRR_OFFSET
+ ldr x15, =PMU_CLSINACTCLRR_OFFSET
+
+ /* x0 = core mask
+ * x1 = NXP_PMU_CCSR_ADDR
+ * x2 = NXP_PMU_DCSR_ADDR
+ * x3 = NXP_DCFG_ADDR
+ * x4 = NXP_DDR_ADDR
+ * x5 = NXP_DDR2_ADDR
+ * w6 = IPSTPCR4
+ * w7 = DEVDISR5
+ * x12 = PMU_CLAINACTSETR_OFFSET
+ * x13 = PMU_CLSINACTSETR_OFFSET
+ * x14 = PMU_CLAINACTCLRR_OFFSET
+ * x15 = PMU_CLSINACTCLRR_OFFSET
+ */
+
+ mov x8, #POLICY_DEBUG_ENABLE
+ cbnz x8, 29f
+ /* force the debug interface to be quiescent */
+ mrs x9, OSDLR_EL1
+ orr x9, x9, #0x1
+ msr OSDLR_EL1, x9
+
+ /* enter the cache-only sequence */
+29:
+ bl final_pwrdown
+
+ /* when we are here, the core has come out of wfi and the
+ * ddr is back up
+ */
+
+ mov x8, #POLICY_DEBUG_ENABLE
+ cbnz x8, 30f
+ /* restart the debug interface */
+ mrs x9, OSDLR_EL1
+ mov x10, #1
+ bic x9, x9, x10
+ msr OSDLR_EL1, x9
+
+ /* get saved DEVDISR regs off stack */
+30:
+ ldp x17, x18, [sp], #16
+ ldp x15, x16, [sp], #16
+ ldp x13, x14, [sp], #16
+ /* restore DEVDISR regs */
+ str w18, [x3, #DCFG_DEVDISR6_OFFSET]
+ str w17, [x3, #DCFG_DEVDISR5_OFFSET]
+ str w16, [x3, #DCFG_DEVDISR4_OFFSET]
+ str w15, [x3, #DCFG_DEVDISR3_OFFSET]
+ str w14, [x3, #DCFG_DEVDISR2_OFFSET]
+ str w13, [x3, #DCFG_DEVDISR1_OFFSET]
+ isb
+
+ /* get saved IPSTPCRn regs off stack */
+ ldp x13, x14, [sp], #16
+ ldp x11, x12, [sp], #16
+ ldp x9, x10, [sp], #16
+
+ /* restore IPSTPCRn regs */
+ mov x15, #PMU_IPSTPCR5_OFFSET
+ str w14, [x1, x15]
+ mov x16, #PMU_IPSTPCR4_OFFSET
+ str w13, [x1, x16]
+ mov x17, #PMU_IPSTPCR3_OFFSET
+ str w12, [x1, x17]
+ mov x18, #PMU_IPSTPCR2_OFFSET
+ str w11, [x1, x18]
+ mov x19, #PMU_IPSTPCR1_OFFSET
+ str w10, [x1, x19]
+ mov x20, #PMU_IPSTPCR0_OFFSET
+ str w9, [x1, x20]
+ isb
+
+ /* poll on IPSTPACKCRn regs til IP clocks are restarted */
+ mov w4, #CLOCK_RETRY_CNT
+ mov x15, #PMU_IPSTPACKSR5_OFFSET
+16:
+ ldr w5, [x1, x15]
+ and w5, w5, w14
+ cbz w5, 17f
+ sub w4, w4, #1
+ cbnz w4, 16b
+
+17:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x15, #PMU_IPSTPACKSR4_OFFSET
+18:
+ ldr w5, [x1, x15]
+ and w5, w5, w13
+ cbz w5, 19f
+ sub w4, w4, #1
+ cbnz w4, 18b
+
+19:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x15, #PMU_IPSTPACKSR3_OFFSET
+20:
+ ldr w5, [x1, x15]
+ and w5, w5, w12
+ cbz w5, 21f
+ sub w4, w4, #1
+ cbnz w4, 20b
+
+21:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x15, #PMU_IPSTPACKSR2_OFFSET
+22:
+ ldr w5, [x1, x15]
+ and w5, w5, w11
+ cbz w5, 23f
+ sub w4, w4, #1
+ cbnz w4, 22b
+
+23:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x15, #PMU_IPSTPACKSR1_OFFSET
+24:
+ ldr w5, [x1, x15]
+ and w5, w5, w10
+ cbz w5, 25f
+ sub w4, w4, #1
+ cbnz w4, 24b
+
+25:
+ mov w4, #CLOCK_RETRY_CNT
+ mov x15, #PMU_IPSTPACKSR0_OFFSET
+26:
+ ldr w5, [x1, x15]
+ and w5, w5, w9
+ cbz w5, 27f
+ sub w4, w4, #1
+ cbnz w4, 26b
+
+27:
+ /* disable the stop-request-override */
+ mov x8, #PMU_POWMGTDCR0_OFFSET
+ mov w9, #POWMGTDCR_STP_OV_EN
+ str w9, [x2, x8]
+ isb
+
+ /* get hnf-sdcr and cpuactlr off stack */
+ ldp x7, x8, [sp], #16
+
+ /* restore cpuactlr */
+ msr CORTEX_A72_CPUACTLR_EL1, x8
+ isb
+
+ /* restore snooping in the hnf nodes */
+ ldr x9, =NXP_CCN_HN_F_0_ADDR
+ mov x6, #CCN_HNF_NODE_COUNT
+28:
+ str x7, [x9, #CCN_HN_F_SNP_DMN_CTL_SET_OFFSET]
+ sub x6, x6, #1
+ add x9, x9, #CCN_HNF_OFFSET
+ cbnz x6, 28b
+ isb
+
+ mov x30, x28
+ ret
+endfunc _soc_sys_pwrdn_wfi
+
+
+/* Part of CPU_SUSPEND
+ * Function performs any SoC-specific cleanup after power-down
+ * in: x0 = core mask lsb
+ * out: none
+ * uses x0,
+ */
+func _soc_sys_exit_pwrdn
+
+ mrs x1, CORTEX_A72_ECTLR_EL1
+ /* make sure the smp bit is set */
+ orr x1, x1, #CPUECTLR_SMPEN_MASK
+ /* clr the retention control */
+ mov x2, #CPUECTLR_RET_8CLK
+ bic x1, x1, x2
+ /* enable tablewalk prefetch */
+ mov x2, #CPUECTLR_DISABLE_TWALK_PREFETCH
+ bic x1, x1, x2
+ msr CORTEX_A72_ECTLR_EL1, x1
+ isb
+
+ ret
+endfunc _soc_sys_exit_pwrdn
+
+
+/* Function will pwrdown ddr and the final core - it will do this
+ * by loading itself into the icache and then executing from there
+ * in:
+ * x0 = core mask
+ * x1 = NXP_PMU_CCSR_ADDR
+ * x2 = NXP_PMU_DCSR_ADDR
+ * x3 = NXP_DCFG_ADDR
+ * x4 = NXP_DDR_ADDR
+ * x5 = NXP_DDR2_ADDR
+ * w6 = IPSTPCR4
+ * w7 = DEVDISR5
+ * x12 = PMU_CLAINACTSETR_OFFSET
+ * x13 = PMU_CLSINACTSETR_OFFSET
+ * x14 = PMU_CLAINACTCLRR_OFFSET
+ * x15 = PMU_CLSINACTCLRR_OFFSET
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x13, x14, x15, x16,
+ * x17, x18
+ */
+
+/* 4Kb aligned */
+.align 12
+func final_pwrdown
+
+ mov x0, xzr
+ b touch_line_0
+start_line_0:
+ mov x0, #1
+ /* put ddr controller 1 into self-refresh */
+ ldr w8, [x4, #DDR_CFG_2_OFFSET]
+ orr w8, w8, #CFG_2_FORCE_REFRESH
+ str w8, [x4, #DDR_CFG_2_OFFSET]
+
+ /* put ddr controller 2 into self-refresh */
+ ldr w8, [x5, #DDR_CFG_2_OFFSET]
+ orr w8, w8, #CFG_2_FORCE_REFRESH
+ str w8, [x5, #DDR_CFG_2_OFFSET]
+
+ /* stop the clocks in both ddr controllers */
+ mov w10, #DEVDISR5_MASK_DDR
+ mov x16, #PMU_IPSTPCR4_OFFSET
+ orr w9, w6, w10
+ str w9, [x1, x16]
+ isb
+
+ mov x17, #PMU_IPSTPACKSR4_OFFSET
+touch_line_0:
+ cbz x0, touch_line_1
+
+start_line_1:
+ /* poll IPSTPACKSR4 until
+ * ddr controller clocks are stopped.
+ */
+1:
+ ldr w8, [x1, x17]
+ and w8, w8, w10
+ cmp w8, w10
+ b.ne 1b
+
+ /* shut down power to the ddr controllers */
+ orr w9, w7, #DEVDISR5_MASK_DDR
+ str w9, [x3, #DCFG_DEVDISR5_OFFSET]
+
+ /* disable cluster acp ports */
+ mov w8, #CLAINACT_DISABLE_ACP
+ str w8, [x1, x12]
+
+ /* disable skyros ports */
+ mov w9, #CLSINACT_DISABLE_SKY
+ str w9, [x1, x13]
+ isb
+
+touch_line_1:
+ cbz x0, touch_line_2
+
+start_line_2:
+ isb
+3:
+ wfi
+
+ /* if we are here then we are awake
+ * - bring this device back up
+ */
+
+ /* enable skyros ports */
+ mov w9, #CLSINACT_DISABLE_SKY
+ str w9, [x1, x15]
+
+ /* enable acp ports */
+ mov w8, #CLAINACT_DISABLE_ACP
+ str w8, [x1, x14]
+ isb
+
+ /* bring up the ddr controllers */
+ str w7, [x3, #DCFG_DEVDISR5_OFFSET]
+ isb
+ str w6, [x1, x16]
+ isb
+
+ nop
+touch_line_2:
+ cbz x0, touch_line_3
+
+start_line_3:
+ /* poll IPSTPACKSR4 until
+ * ddr controller clocks are running
+ */
+ mov w10, #DEVDISR5_MASK_DDR
+2:
+ ldr w8, [x1, x17]
+ and w8, w8, w10
+ cbnz w8, 2b
+
+ /* take ddr controller 2 out of self-refresh */
+ mov w8, #CFG_2_FORCE_REFRESH
+ ldr w9, [x5, #DDR_CFG_2_OFFSET]
+ bic w9, w9, w8
+ str w9, [x5, #DDR_CFG_2_OFFSET]
+
+ /* take ddr controller 1 out of self-refresh */
+ ldr w9, [x4, #DDR_CFG_2_OFFSET]
+ bic w9, w9, w8
+ str w9, [x4, #DDR_CFG_2_OFFSET]
+ isb
+
+ nop
+ nop
+ nop
+touch_line_3:
+ cbz x0, start_line_0
+
+ /* execute here after ddr is back up */
+
+ ret
+endfunc final_pwrdown
+
+/* Function returns CLUSTER_3_NORMAL if the cores of cluster 3 are
+ * to be handled normally, and it returns CLUSTER_3_IN_RESET if the cores
+ * are to be held in reset
+ * in: none
+ * out: x0 = #CLUSTER_3_NORMAL, cluster 3 treated normal
+ * x0 = #CLUSTER_3_IN_RESET, cluster 3 cores held in reset
+ * uses x0, x1, x2
+ */
+func cluster3InReset
+
+ /* default return is treat cores normal */
+ mov x0, #CLUSTER_3_NORMAL
+
+ /* read RCW_SR27 register */
+ mov x1, #NXP_DCFG_ADDR
+ ldr w2, [x1, #RCW_SR27_OFFSET]
+
+ /* test the cluster 3 bit */
+ tst w2, #CLUSTER_3_RCW_BIT
+ b.eq 1f
+
+ /* if we are here, then the bit was set */
+ mov x0, #CLUSTER_3_IN_RESET
+1:
+ ret
+endfunc cluster3InReset
+
+
+/* Function checks to see if cores which are to be disabled have been
+ * released from reset - if not, it releases them
+ * Note: there may be special handling of cluster 3 cores depending upon the
+ * sys clk frequency
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9
+ */
+func release_disabled
+ mov x9, x30
+
+ /* check if we need to keep cluster 3 cores in reset */
+ bl cluster3InReset /* 0-2 */
+ mov x8, x0
+
+ /* x8 = cluster 3 handling */
+
+ /* read COREDISABLESR */
+ mov x0, #NXP_DCFG_ADDR
+ ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET]
+ cmp x8, #CLUSTER_3_IN_RESET
+ b.ne 4f
+
+ /* the cluster 3 cores are to be held in reset, so remove
+ * them from the disable mask
+ */
+ bic x4, x4, #CLUSTER_3_CORES_MASK
+4:
+ /* get the number of cpus on this device */
+ mov x6, #PLATFORM_CORE_COUNT
+
+ mov x0, #NXP_RESET_ADDR
+ ldr w5, [x0, #BRR_OFFSET]
+
+ /* load the core mask for the first core */
+ mov x7, #1
+
+ /* x4 = COREDISABLESR
+ * x5 = BRR
+ * x6 = loop count
+ * x7 = core mask bit
+ */
+2:
+ /* check if the core is to be disabled */
+ tst x4, x7
+ b.eq 1f
+
+ /* see if disabled cores have already been released from reset */
+ tst x5, x7
+ b.ne 5f
+
+ /* if core has not been released, then release it (0-3) */
+ mov x0, x7
+ bl _soc_core_release
+
+ /* record the core state in the data area (0-3) */
+ mov x0, x7
+ mov x1, #CORE_STATE_DATA
+ mov x2, #CORE_DISABLED
+ bl _setCoreData
+
+1:
+ /* see if this is a cluster 3 core */
+ mov x3, #CLUSTER_3_CORES_MASK
+ tst x3, x7
+ b.eq 5f
+
+ /* this is a cluster 3 core - see if it needs to be held in reset */
+ cmp x8, #CLUSTER_3_IN_RESET
+ b.ne 5f
+
+ /* record the core state as disabled in the data area (0-3) */
+ mov x0, x7
+ mov x1, #CORE_STATE_DATA
+ mov x2, #CORE_DISABLED
+ bl _setCoreData
+
+5:
+ /* decrement the counter */
+ subs x6, x6, #1
+ b.le 3f
+
+ /* shift the core mask to the next core */
+ lsl x7, x7, #1
+ /* continue */
+ b 2b
+3:
+ cmp x8, #CLUSTER_3_IN_RESET
+ b.ne 6f
+
+ /* we need to hold the cluster 3 cores in reset,
+ * so mark them in the COREDISR and COREDISABLEDSR registers as
+ * "disabled", and the rest of the sw stack will leave them alone
+ * thinking that they have been disabled
+ */
+ mov x0, #NXP_DCFG_ADDR
+ ldr w1, [x0, #DCFG_COREDISR_OFFSET]
+ orr w1, w1, #CLUSTER_3_CORES_MASK
+ str w1, [x0, #DCFG_COREDISR_OFFSET]
+
+ ldr w2, [x0, #DCFG_COREDISABLEDSR_OFFSET]
+ orr w2, w2, #CLUSTER_3_CORES_MASK
+ str w2, [x0, #DCFG_COREDISABLEDSR_OFFSET]
+ dsb sy
+ isb
+
+#if (PSCI_TEST)
+ /* x0 = NXP_DCFG_ADDR : read COREDISABLESR */
+ ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET]
+ /* read COREDISR */
+ ldr w3, [x0, #DCFG_COREDISR_OFFSET]
+#endif
+
+6:
+ mov x30, x9
+ ret
+
+endfunc release_disabled
+
+
+/* Function setc up the TrustZone Address Space Controller (TZASC)
+ * in: none
+ * out: none
+ * uses x0, x1
+ */
+func init_tzpc
+
+ /* set Non Secure access for all devices protected via TZPC */
+
+ /* decode Protection-0 Set Reg */
+ ldr x1, =TZPCDECPROT_0_SET_BASE
+ /* set decode region to NS, Bits[7:0] */
+ mov w0, #0xFF
+ str w0, [x1]
+
+ /* decode Protection-1 Set Reg */
+ ldr x1, =TZPCDECPROT_1_SET_BASE
+ /* set decode region to NS, Bits[7:0] */
+ mov w0, #0xFF
+ str w0, [x1]
+
+ /* decode Protection-2 Set Reg */
+ ldr x1, =TZPCDECPROT_2_SET_BASE
+ /* set decode region to NS, Bits[7:0] */
+ mov w0, #0xFF
+ str w0, [x1]
+
+ /* entire SRAM as NS */
+ /* secure RAM region size Reg */
+ ldr x1, =TZPC_BASE
+ /* 0x00000000 = no secure region */
+ mov w0, #0x00000000
+ str w0, [x1]
+
+ ret
+endfunc init_tzpc
+
+/* write a register in the DCFG block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+func _write_reg_dcfg
+ ldr x2, =NXP_DCFG_ADDR
+ str w1, [x2, x0]
+ ret
+endfunc _write_reg_dcfg
+
+
+/* read a register in the DCFG block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1, x2
+ */
+func _read_reg_dcfg
+ ldr x2, =NXP_DCFG_ADDR
+ ldr w1, [x2, x0]
+ mov w0, w1
+ ret
+endfunc _read_reg_dcfg
+
+
+/* Function returns an mpidr value for a core, given a core_mask_lsb
+ * in: x0 = core mask lsb
+ * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits
+ * uses x0, x1
+ */
+func get_mpidr_value
+
+ /* convert a core mask to an SoC core number */
+ clz w0, w0
+ mov w1, #31
+ sub w0, w1, w0
+
+ /* get the mpidr core number from the SoC core number */
+ mov w1, wzr
+ tst x0, #1
+ b.eq 1f
+ orr w1, w1, #1
+
+1:
+ /* extract the cluster number */
+ lsr w0, w0, #1
+ orr w0, w1, w0, lsl #8
+
+ ret
+endfunc get_mpidr_value
+
+
+/* Function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor rd base address for specified core
+ * uses x0, x1, x2
+ */
+func get_gic_rd_base
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ ldr x0, =NXP_GICR_ADDR
+ mov x1, #GIC_RD_OFFSET
+
+ /* x2 = core number
+ * loop counter
+ */
+2:
+ cbz x2, 1f
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+endfunc get_gic_rd_base
+
+
+/* Function returns the redistributor base address for the core specified
+ * in x1
+ * in: x0 - core mask lsb of specified core
+ * out: x0 = redistributor sgi base address for specified core
+ * uses x0, x1, x2
+ */
+func get_gic_sgi_base
+ clz w1, w0
+ mov w2, #0x20
+ sub w2, w2, w1
+ sub w2, w2, #1
+
+ ldr x0, =NXP_GICR_SGI_ADDR
+ mov x1, #GIC_SGI_OFFSET
+
+ /* loop counter */
+2:
+ cbz x2, 1f /* x2 = core number */
+ add x0, x0, x1
+ sub x2, x2, #1
+ b 2b
+1:
+ ret
+endfunc get_gic_sgi_base
+
+/* Function writes a register in the RESET block
+ * in: x0 = offset
+ * in: w1 = value to write
+ * uses x0, x1, x2
+ */
+func _write_reg_reset
+ ldr x2, =NXP_RESET_ADDR
+ str w1, [x2, x0]
+ ret
+endfunc _write_reg_reset
+
+
+/* Function reads a register in the RESET block
+ * in: x0 = offset
+ * out: w0 = value read
+ * uses x0, x1
+ */
+func _read_reg_reset
+ ldr x1, =NXP_RESET_ADDR
+ ldr w0, [x1, x0]
+ ret
+endfunc _read_reg_reset
diff --git a/plat/nxp/soc-lx2160a/aarch64/lx2160a_helpers.S b/plat/nxp/soc-lx2160a/aarch64/lx2160a_helpers.S
new file mode 100644
index 0000000..c364dec
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/aarch64/lx2160a_helpers.S
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+.globl plat_secondary_cold_boot_setup
+.globl plat_is_my_cpu_primary
+.globl plat_reset_handler
+.globl platform_mem_init
+
+
+func platform_mem1_init
+ ret
+endfunc platform_mem1_init
+
+
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+
+func apply_platform_errata
+
+ ret
+endfunc apply_platform_errata
+
+
+func plat_reset_handler
+ mov x29, x30
+ bl apply_platform_errata
+
+#if defined(IMAGE_BL31)
+ ldr x0, =POLICY_SMMU_PAGESZ_64K
+ cbz x0, 1f
+ /* Set the SMMU page size in the sACR register */
+ bl _set_smmu_pagesz_64
+#endif
+1:
+ mov x30, x29
+
+ ret
+endfunc plat_reset_handler
+
+
+/* void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset e.g
+ * mark the cpu's presence, mechanism to place it in a
+ * holding pen etc.
+ */
+func plat_secondary_cold_boot_setup
+ /* lx2160a does not do cold boot for secondary CPU */
+cb_panic:
+ b cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+
+/* unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu.
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, 0x0
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
diff --git a/plat/nxp/soc-lx2160a/aarch64/lx2160a_warm_rst.S b/plat/nxp/soc-lx2160a/aarch64/lx2160a_warm_rst.S
new file mode 100644
index 0000000..9dec3f2
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/aarch64/lx2160a_warm_rst.S
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+.section .text, "ax"
+
+#include <asm_macros.S>
+
+#ifndef NXP_COINED_BB
+#include <flash_info.h>
+#include <fspi.h>
+#endif
+#include <regs.h>
+#ifdef NXP_COINED_BB
+#include <snvs.h>
+#endif
+
+#include <plat_warm_rst.h>
+#include <platform_def.h>
+
+#define SDRAM_CFG 0x110
+#define SDRAM_CFG_2 0x114
+#define SDRAM_MD_CNTL 0x120
+#define SDRAM_INTERVAL 0x124
+#define TIMING_CFG_10 0x258
+#define DEBUG_2 0xF04
+#define DEBUG_26 0xF64
+#define DDR_DSR2 0xB24
+
+#define DDR_CNTRLR_2 0x2
+#define COUNT_100 1000
+
+ .globl _soc_sys_warm_reset
+ .align 12
+
+func _soc_sys_warm_reset
+ mov x3, xzr
+ b touch_line0
+start_line0:
+ mov x3, #1
+ mov x2, #NUM_OF_DDRC
+ ldr x1, =NXP_DDR_ADDR
+1:
+ ldr w0, [x1, #SDRAM_CFG]
+ orr w0, w0, #SDRAM_CFG_MEM_HLT
+ str w0, [x1, #SDRAM_CFG]
+2:
+ ldr w0, [x1, #DEBUG_2]
+ and w0, w0, #DDR_DBG_2_MEM_IDLE
+ cbz w0, 2b
+
+ ldr w0, [x1, #DEBUG_26]
+ orr w0, w0, #DDR_DEBUG_26_BIT_12
+ orr w0, w0, #DDR_DEBUG_26_BIT_13
+ orr w0, w0, #DDR_DEBUG_26_BIT_14
+touch_line0:
+ cbz x3, touch_line1
+
+ orr w0, w0, #DDR_DEBUG_26_BIT_15
+ orr w0, w0, #DDR_DEBUG_26_BIT_16
+ str w0, [x1, #DEBUG_26]
+
+ ldr w0, [x1, #SDRAM_CFG_2]
+ orr w0, w0, #SDRAM_CFG2_FRC_SR
+ str w0, [x1, #SDRAM_CFG_2]
+
+3:
+ ldr w0, [x1, #DDR_DSR2]
+ orr w0, w0, #DDR_DSR_2_PHY_INIT_CMPLT
+ str w0, [x1, #DDR_DSR2]
+ ldr w0, [x1, #DDR_DSR2]
+ and w0, w0, #DDR_DSR_2_PHY_INIT_CMPLT
+ cbnz w0, 3b
+
+ ldr w0, [x1, #SDRAM_INTERVAL]
+ and w0, w0, #SDRAM_INTERVAL_REFINT_CLEAR
+ str w0, [x1, #SDRAM_INTERVAL]
+touch_line1:
+ cbz x3, touch_line2
+
+ ldr w0, [x1, #SDRAM_MD_CNTL]
+ orr w0, w0, #MD_CNTL_CKE(1)
+ orr w0, w0, #MD_CNTL_MD_EN
+ str w0, [x1, #SDRAM_MD_CNTL]
+
+ ldr w0, [x1, #TIMING_CFG_10]
+ orr w0, w0, #DDR_TIMING_CFG_10_T_STAB
+ str w0, [x1, #TIMING_CFG_10]
+
+ ldr w0, [x1, #SDRAM_CFG_2]
+ and w0, w0, #SDRAM_CFG2_FRC_SR_CLEAR
+ str w0, [x1, #SDRAM_CFG_2]
+
+4:
+ ldr w0, [x1, #DDR_DSR2]
+ and w0, w0, #DDR_DSR_2_PHY_INIT_CMPLT
+ cbz w0, 4b
+ nop
+touch_line2:
+ cbz x3, touch_line3
+
+ ldr w0, [x1, #DEBUG_26]
+ orr w0, w0, #DDR_DEBUG_26_BIT_25
+ and w0, w0, #DDR_DEBUG_26_BIT_24_CLEAR
+ str w0, [x1, #DEBUG_26]
+
+ cmp x2, #DDR_CNTRLR_2
+ b.ne 5f
+ ldr x1, =NXP_DDR2_ADDR
+ mov x2, xzr
+ b 1b
+
+5:
+ mov x5, xzr
+6:
+ add x5, x5, #1
+ cmp x5, #COUNT_100
+ b.ne 6b
+ nop
+touch_line3:
+ cbz x3, touch_line4
+#ifdef NXP_COINED_BB
+ ldr x1, =NXP_SNVS_ADDR
+ ldr w0, [x1, #NXP_APP_DATA_LP_GPR_OFFSET]
+
+ /* On Warm Boot is enabled, then zeroth bit
+ * of SNVS LP GPR register 0 will used
+ * to save the status of warm-reset as a cause.
+ */
+ orr w0, w0, #(1 << NXP_LPGPR_ZEROTH_BIT)
+
+ /* write back */
+ str w0, [x1, #NXP_APP_DATA_LP_GPR_OFFSET]
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+touch_line4:
+ cbz x3, touch_line6
+#elif !(ERLY_WRM_RST_FLG_FLSH_UPDT)
+ ldr x1, =NXP_FLEXSPI_ADDR
+ ldr w0, [x1, #FSPI_IPCMD]
+ orr w0, w0, #FSPI_IPCMD_TRG_MASK
+ str w0, [x1, #FSPI_IPCMD]
+7:
+ ldr w0, [x1, #FSPI_INTR]
+ and w0, w0, #FSPI_INTR_IPCMDDONE_MASK
+ cmp w0, #0
+ b.eq 7b
+
+ ldr w0, [x1, #FSPI_IPTXFCR]
+ orr w0, w0, #FSPI_IPTXFCR_CLR
+ str w0, [x1, #FSPI_IPTXFCR]
+
+ ldr w0, [x1, #FSPI_INTR]
+ orr w0, w0, #FSPI_INTR_IPCMDDONE_MASK
+ str w0, [x1, #FSPI_INTR]
+ nop
+touch_line4:
+ cbz x3, touch_line5
+ /* flexspi driver has an api
+ * is_flash_busy().
+ * Impelementation of the api will not
+ * fit-in in 1 cache line.
+ * instead a nop-cycles are introduced to
+ * simulate the wait time for flash write
+ * completion.
+ *
+ * Note: This wait time varies from flash to flash.
+ */
+
+ mov x0, #FLASH_WR_COMP_WAIT_BY_NOP_COUNT
+8:
+ sub x0, x0, #1
+ nop
+ cmp x0, #0
+ b.ne 8b
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+touch_line5:
+ cbz x3, touch_line6
+#endif
+ ldr x2, =NXP_RST_ADDR
+ /* clear the RST_REQ_MSK and SW_RST_REQ */
+ mov w0, #0x00000000
+ str w0, [x2, #RSTCNTL_OFFSET]
+
+ /* initiate the sw reset request */
+ mov w0, #SW_RST_REQ_INIT
+ str w0, [x2, #RSTCNTL_OFFSET]
+
+ /* In case this address range is mapped as cacheable,
+ * flush the write out of the dcaches.
+ */
+ add x2, x2, #RSTCNTL_OFFSET
+ dc cvac, x2
+ dsb st
+ isb
+
+ /* Function does not return */
+ b .
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+touch_line6:
+ cbz x3, start_line0
+
+endfunc _soc_sys_warm_reset
diff --git a/plat/nxp/soc-lx2160a/ddr_fip.mk b/plat/nxp/soc-lx2160a/ddr_fip.mk
new file mode 100644
index 0000000..f14a9e8
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/ddr_fip.mk
@@ -0,0 +1,97 @@
+#
+# Copyright 2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+DDR_PHY_BIN_PATH ?= ./ddr-phy-binary/lx2160a
+
+ifeq (${DDR_IMEM_UDIMM_1D},)
+ DDR_IMEM_UDIMM_1D := ${DDR_PHY_BIN_PATH}/ddr4_pmu_train_imem.bin
+endif
+
+ifeq (${DDR_IMEM_UDIMM_2D},)
+ DDR_IMEM_UDIMM_2D := ${DDR_PHY_BIN_PATH}/ddr4_2d_pmu_train_imem.bin
+endif
+
+ifeq (${DDR_DMEM_UDIMM_1D},)
+ DDR_DMEM_UDIMM_1D := ${DDR_PHY_BIN_PATH}/ddr4_pmu_train_dmem.bin
+endif
+
+ifeq (${DDR_DMEM_UDIMM_2D},)
+ DDR_DMEM_UDIMM_2D := ${DDR_PHY_BIN_PATH}/ddr4_2d_pmu_train_dmem.bin
+endif
+
+ifeq (${DDR_IMEM_RDIMM_1D},)
+ DDR_IMEM_RDIMM_1D := ${DDR_PHY_BIN_PATH}/ddr4_rdimm_pmu_train_imem.bin
+endif
+
+ifeq (${DDR_IMEM_RDIMM_2D},)
+ DDR_IMEM_RDIMM_2D := ${DDR_PHY_BIN_PATH}/ddr4_rdimm2d_pmu_train_imem.bin
+endif
+
+ifeq (${DDR_DMEM_RDIMM_1D},)
+ DDR_DMEM_RDIMM_1D := ${DDR_PHY_BIN_PATH}/ddr4_rdimm_pmu_train_dmem.bin
+endif
+
+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
+else
+ DDR_FIP_NAME := ddr_fip.bin
+endif
+endif
+
+ifneq (${TRUSTED_BOARD_BOOT},1)
+
+DDR_FIP_ARGS += --ddr-immem-udimm-1d ${DDR_IMEM_UDIMM_1D} \
+ --ddr-immem-udimm-2d ${DDR_IMEM_UDIMM_2D} \
+ --ddr-dmmem-udimm-1d ${DDR_DMEM_UDIMM_1D} \
+ --ddr-dmmem-udimm-2d ${DDR_DMEM_UDIMM_2D} \
+ --ddr-immem-rdimm-1d ${DDR_IMEM_RDIMM_1D} \
+ --ddr-immem-rdimm-2d ${DDR_IMEM_RDIMM_2D} \
+ --ddr-dmmem-rdimm-1d ${DDR_DMEM_RDIMM_1D} \
+ --ddr-dmmem-rdimm-2d ${DDR_DMEM_RDIMM_2D}
+endif
+
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+ifeq (${MBEDTLS_DIR},)
+include plat/nxp/soc-lx2160a/ddr_sb.mk
+else
+include plat/nxp/soc-lx2160a/ddr_tbbr.mk
+
+# Variables for use with Certificate Generation Tool
+CRTTOOLPATH ?= tools/cert_create
+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}
+endif
+endif
+endif
+
+# Variables for use with Firmware Image Package
+FIPTOOLPATH ?= tools/fiptool
+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}
+
+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
new file mode 100644
index 0000000..c11651e
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/ddr_sb.mk
@@ -0,0 +1,43 @@
+#
+# Copyright 2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${TRUSTED_BOARD_BOOT},0)
+
+ifeq (${GENERATE_COT},0)
+
+DDR_FIP_ARGS += --ddr-immem-udimm-1d ${DDR_IMEM_UDIMM_1D}.sb \
+ --ddr-immem-udimm-2d ${DDR_IMEM_UDIMM_2D}.sb \
+ --ddr-dmmem-udimm-1d ${DDR_DMEM_UDIMM_1D}.sb \
+ --ddr-dmmem-udimm-2d ${DDR_DMEM_UDIMM_2D}.sb \
+ --ddr-immem-rdimm-1d ${DDR_IMEM_RDIMM_1D}.sb \
+ --ddr-immem-rdimm-2d ${DDR_IMEM_RDIMM_2D}.sb \
+ --ddr-dmmem-rdimm-1d ${DDR_DMEM_RDIMM_1D}.sb \
+ --ddr-dmmem-rdimm-2d ${DDR_DMEM_RDIMM_2D}.sb
+endif
+
+UDIMM_DEPS = ${DDR_IMEM_UDIMM_1D}.sb ${DDR_IMEM_UDIMM_2D}.sb ${DDR_DMEM_UDIMM_1D}.sb ${DDR_DMEM_UDIMM_2D}.sb
+RDIMM_DEPS = ${DDR_IMEM_RDIMM_1D}.sb ${DDR_IMEM_RDIMM_2D}.sb ${DDR_DMEM_RDIMM_1D}.sb ${DDR_DMEM_RDIMM_2D}.sb
+DDR_FIP_DEPS += ${UDIMM_DEPS}
+DDR_FIP_DEPS += ${RDIMM_DEPS}
+
+# Max Size of CSF header (CSF_HDR_SZ = 0x3000).
+# Image will be appended at this offset of the header.
+# Path to CST directory is required to generate the CSF header,
+# and prepend it to image before fip image gets generated
+ifeq (${CST_DIR},)
+ $(error Error: CST_DIR not set)
+endif
+
+ifeq (${DDR_INPUT_FILE},)
+DDR_INPUT_FILE:= drivers/nxp/auth/csf_hdr_parser/${CSF_FILE}
+endif
+
+%.sb: %
+ @echo " Generating CSF Header for $@ $<"
+ $(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
+ --app $< ${DDR_INPUT_FILE}
+
+endif
diff --git a/plat/nxp/soc-lx2160a/ddr_tbbr.mk b/plat/nxp/soc-lx2160a/ddr_tbbr.mk
new file mode 100644
index 0000000..deb475b
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/ddr_tbbr.mk
@@ -0,0 +1,95 @@
+#
+# Copyright 2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This file defines the keys and certificates that must be created to establish
+# a Chain of Trust for the DDR FW. These definitions include the
+# command line options passed to the cert_create and fiptool commands for DDR FW.
+# A DDR FW key is used for signing the DDR Firmware. The DDR key is authenticated
+# by the Trusted World Key. Two content certificates are created:
+# For DDR RDIMM Images [ signed by DDR FW Key]
+# For DDR UDIMM Images [ signed by DDR FW Key]
+#
+# Expected environment:
+#
+# BUILD_PLAT: output directory
+#
+# Build options added by this file:
+#
+# KEY_ALG
+# KEY_SIZE
+# TRUSTED_WORLD_KEY
+# NON_TRUSTED_WORLD_KEY
+#
+
+# Copy the tbbr.mk from PLAT_TOOL_PATH/cert_create_helper
+# to the ${PLAT_DIR}. So that cert_create is enabled
+# to create certificates for DDR
+$(shell cp ${PLAT_TOOL_PATH}/cert_create_helper/cert_create_tbbr.mk ${PLAT_DIR})
+
+# Certificate generation tool default parameters
+DDR_FW_CERT := ${BUILD_PLAT}/ddr_fw_key_cert.crt
+
+# Default non-volatile counter values (overridable by the platform)
+TFW_NVCTR_VAL ?= 0
+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
+
+ifeq (${TRUSTED_KEY_CERT},)
+$(info Generating: Trusted key certificate as part of DDR cert creation)
+TRUSTED_KEY_CERT := ${BUILD_PLAT}/trusted_key.crt
+$(eval $(call TOOL_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert,))
+$(eval $(call TOOL_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert,,DDR_))
+else
+$(info Using: Trusted key certificate as part of DDR cert creation)
+DDR_FIP_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT}
+endif
+
+# Add the keys to the cert_create command line options (private keys are NOT
+# packed in the FIP). Developers can use their own keys by specifying the proper
+# build option in the command line when building the Trusted Firmware
+$(if ${KEY_ALG},$(eval $(call CERT_ADD_CMD_OPT,${KEY_ALG},--key-alg,DDR_)))
+$(if ${KEY_SIZE},$(eval $(call CERT_ADD_CMD_OPT,${KEY_SIZE},--key-size,DDR_)))
+$(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg,DDR_)))
+$(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,DDR_)))
+$(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key,DDR_)))
+$(if ${NON_TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${NON_TRUSTED_WORLD_KEY},--non-trusted-world-key, DDR_)))
+
+# Add the DDR CoT (key cert + img cert)
+$(if ${DDR_KEY},$(eval $(call CERT_ADD_CMD_OPT,${DDR_KEY},--ddr-fw-key,DDR_)))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/ddr_fw_key.crt,--ddr-fw-key-cert,,DDR_))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/ddr_udimm_fw_content.crt,--ddr-udimm-fw-cert,,DDR_))
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/ddr_rdimm_fw_content.crt,--ddr-rdimm-fw-cert,,DDR_))
+
+$(eval $(call TOOL_ADD_IMG,DDR_IMEM_UDIMM_1D,--ddr-immem-udimm-1d,DDR_))
+$(eval $(call TOOL_ADD_IMG,DDR_IMEM_UDIMM_2D,--ddr-immem-udimm-2d,DDR_))
+$(eval $(call TOOL_ADD_IMG,DDR_DMEM_UDIMM_1D,--ddr-dmmem-udimm-1d,DDR_))
+$(eval $(call TOOL_ADD_IMG,DDR_DMEM_UDIMM_2D,--ddr-dmmem-udimm-2d,DDR_))
+
+$(eval $(call TOOL_ADD_IMG,DDR_IMEM_RDIMM_1D,--ddr-immem-rdimm-1d,DDR_))
+$(eval $(call TOOL_ADD_IMG,DDR_IMEM_RDIMM_2D,--ddr-immem-rdimm-2d,DDR_))
+$(eval $(call TOOL_ADD_IMG,DDR_DMEM_RDIMM_1D,--ddr-dmmem-rdimm-1d,DDR_))
+$(eval $(call TOOL_ADD_IMG,DDR_DMEM_RDIMM_2D,--ddr-dmmem-rdimm-2d,DDR_))
+
+DDR_FIP_DEPS += ddr_certificates
+
+# Process TBB related flags
+ifneq (${GENERATE_COT},0)
+ # Common cert_create options
+ ifneq (${CREATE_KEYS},0)
+ $(eval DDR_CRT_ARGS += -n)
+ ifneq (${SAVE_KEYS},0)
+ $(eval DDR_CRT_ARGS += -k)
+ endif
+ endif
+endif
diff --git a/plat/nxp/soc-lx2160a/include/soc.h b/plat/nxp/soc-lx2160a/include/soc.h
new file mode 100644
index 0000000..b781ff8
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/include/soc.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _SOC_H
+#define _SOC_H
+
+/* Chassis specific defines - common across SoC's of a particular platform */
+#include <dcfg_lsch3.h>
+#include <soc_default_base_addr.h>
+#include <soc_default_helper_macros.h>
+
+
+#define NUM_DRAM_REGIONS 3
+#define NXP_DRAM0_ADDR 0x80000000
+#define NXP_DRAM0_MAX_SIZE 0x80000000 /* 2 GB */
+
+#define NXP_DRAM1_ADDR 0x2080000000
+#define NXP_DRAM1_MAX_SIZE 0x1F80000000 /* 126 G */
+
+#define NXP_DRAM2_ADDR 0x6000000000
+#define NXP_DRAM2_MAX_SIZE 0x2000000000 /* 128G */
+
+/*DRAM0 Size defined in platform_def.h */
+#define NXP_DRAM0_SIZE PLAT_DEF_DRAM0_SIZE
+
+#define DDR_PLL_FIX
+#define NXP_DDR_PHY1_ADDR 0x01400000
+#define NXP_DDR_PHY2_ADDR 0x01600000
+
+#if defined(IMAGE_BL31)
+#define LS_SYS_TIMCTL_BASE 0x2890000
+
+#ifdef LS_SYS_TIMCTL_BASE
+#define PLAT_LS_NSTIMER_FRAME_ID 0
+#define LS_CONFIG_CNTACR 1
+#endif
+#endif
+
+/* Start: Macros used by soc.c: get_boot_dev */
+#define PORSR1_RCW_MASK 0x07800000
+#define PORSR1_RCW_SHIFT 23
+
+#define SDHC1_VAL 0x8
+#define SDHC2_VAL 0x9
+#define I2C1_VAL 0xa
+#define FLEXSPI_NAND2K_VAL 0xc
+#define FLEXSPI_NAND4K_VAL 0xd
+#define FLEXSPI_NOR 0xf
+/* End: Macros used by soc.c: get_boot_dev */
+
+/* SVR Definition (not include major and minor rev) */
+#define SVR_LX2160A 0x873601
+#define SVR_LX2160E 0x873610
+#define SVR_LX2160C 0x873600
+#define SVR_LX2160N 0x873611
+#define SVR_LX2120A 0x873621
+#define SVR_LX2120E 0x873630
+#define SVR_LX2120C 0x873620
+#define SVR_LX2120N 0x873631
+#define SVR_LX2080A 0x873603
+#define SVR_LX2080E 0x873612
+#define SVR_LX2080C 0x873602
+#define SVR_LX2080N 0x873613
+
+/* SVR Definition of SoC LX2162A. */
+#define SVR_LX2162A 0x873609
+#define SVR_LX2162E 0x873618
+#define SVR_LX2162C 0x873608
+#define SVR_LX2162N 0x873619
+#define SVR_LX2122A 0x873629
+#define SVR_LX2122E 0x873638
+#define SVR_LX2122C 0x873628
+#define SVR_LX2122N 0x873639
+#define SVR_LX2082A 0x87360b
+#define SVR_LX2082E 0x87361a
+#define SVR_LX2082C 0x87360a
+#define SVR_LX2082N 0x87361b
+
+/* Number of cores in platform */
+/* Used by common code for array initialization */
+#define NUMBER_OF_CLUSTERS 8
+#define CORES_PER_CLUSTER 2
+#define PLATFORM_CORE_COUNT NUMBER_OF_CLUSTERS * CORES_PER_CLUSTER
+
+/*
+ * Required LS standard platform porting definitions
+ * for CCN-508
+ */
+#define PLAT_CLUSTER_TO_CCN_ID_MAP 11, 15, 27, 31, 12, 28, 16, 0
+#define PLAT_6CLUSTER_TO_CCN_ID_MAP 11, 15, 27, 31, 12, 28
+
+
+/* Defines required for using XLAT tables from ARM common code */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 40)
+
+/* Clock Divisors */
+#define NXP_PLATFORM_CLK_DIVIDER 2
+#define NXP_UART_CLK_DIVIDER 4
+
+/* Start: Macros used by lx2160a.S */
+#define MPIDR_AFFINITY0_MASK 0x00FF
+#define MPIDR_AFFINITY1_MASK 0xFF00
+#define CPUECTLR_DISABLE_TWALK_PREFETCH 0x4000000000
+#define CPUECTLR_INS_PREFETCH_MASK 0x1800000000
+#define CPUECTLR_DAT_PREFETCH_MASK 0x0300000000
+#define CPUECTLR_RET_8CLK 0x2
+#define OSDLR_EL1_DLK_LOCK 0x1
+#define CNTP_CTL_EL0_EN 0x1
+#define CNTP_CTL_EL0_IMASK 0x2
+/* set to 0 if the clusters are not symmetrical */
+#define SYMMETRICAL_CLUSTERS 1
+/* End: Macros used by lx2160a.S */
+
+/* Start: Macros used by lib/psci files */
+#define SYSTEM_PWR_DOMAINS 1
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
+ NUMBER_OF_CLUSTERS + \
+ SYSTEM_PWR_DOMAINS)
+
+/* Power state coordination occurs at the system level */
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
+
+/* define retention state */
+#define PLAT_MAX_RET_STATE (PSCI_LOCAL_STATE_RUN + 1)
+
+/* define power-down state */
+#define PLAT_MAX_OFF_STATE (PLAT_MAX_RET_STATE + 1)
+/* End: Macros used by lib/psci files */
+
+/* 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.
+ *
+ * CACHE_WRITEBACK_GRANULE is defined in soc.def
+ *
+ * One cache line needed for bakery locks on ARM platforms
+ */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
+
+#ifndef WDOG_RESET_FLAG
+#define WDOG_RESET_FLAG DEFAULT_SET_VALUE
+#endif
+
+#ifndef WARM_BOOT_SUCCESS
+#define WARM_BOOT_SUCCESS DEFAULT_SET_VALUE
+#endif
+
+#ifndef __ASSEMBLER__
+
+void set_base_freq_CNTFID0(void);
+void soc_init_start(void);
+void soc_init_finish(void);
+void soc_init_percpu(void);
+void _soc_set_start_addr(unsigned long addr);
+void _set_platform_security(void);
+
+#endif
+
+#endif /* _SOC_H */
diff --git a/plat/nxp/soc-lx2160a/lx2160aqds/ddr_init.c b/plat/nxp/soc-lx2160a/lx2160aqds/ddr_init.c
new file mode 100644
index 0000000..d44733c
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160aqds/ddr_init.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <lib/utils.h>
+#include <load_img.h>
+
+#include "plat_common.h"
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+
+const struct ddr_cfg_regs static_3200 = {
+ .cs[0].bnds = U(0x03FF),
+ .cs[1].bnds = U(0x03FF),
+ .cs[0].config = U(0x80050422),
+ .cs[1].config = U(0x80000422),
+ .cs[2].bnds = U(0x00),
+ .cs[3].bnds = U(0x00),
+ .cs[2].config = U(0x00),
+ .cs[3].config = U(0x00),
+ .timing_cfg[0] = U(0xFFAA0018),
+ .timing_cfg[1] = U(0x646A8844),
+ .timing_cfg[2] = U(0x00058022),
+ .timing_cfg[3] = U(0x13622100),
+ .timing_cfg[4] = U(0x02),
+ .timing_cfg[5] = U(0x07401400),
+ .timing_cfg[7] = U(0x3BB00000),
+ .timing_cfg[8] = U(0x0944AC00),
+ .sdram_cfg[0] = U(0x65044008),
+ .sdram_cfg[1] = U(0x00401011),
+ .sdram_cfg[2] = U(0x00),
+ .sdram_mode[0] = U(0x06010C50),
+ .sdram_mode[1] = U(0x00280400),
+ .sdram_mode[2] = U(0x00),
+ .sdram_mode[3] = U(0x00),
+ .sdram_mode[4] = U(0x00),
+ .sdram_mode[5] = U(0x00),
+ .sdram_mode[6] = U(0x00),
+ .sdram_mode[7] = U(0x00),
+ .sdram_mode[8] = U(0x0500),
+ .sdram_mode[9] = U(0x10240000),
+ .sdram_mode[10] = U(0x00),
+ .sdram_mode[11] = U(0x00),
+ .sdram_mode[12] = U(0x00),
+ .sdram_mode[13] = U(0x00),
+ .sdram_mode[14] = U(0x00),
+ .sdram_mode[15] = U(0x00),
+ .md_cntl = U(0x00),
+ .interval = U(0x30C00000),
+ .data_init = U(0xDEADBEEF),
+ .init_addr = U(0x00),
+ .zq_cntl = U(0x8A090705),
+ .sdram_rcw[0] = U(0x00),
+ .sdram_rcw[1] = U(0x00),
+ .sdram_rcw[2] = U(0x00),
+ .sdram_rcw[3] = U(0x00),
+ .sdram_rcw[4] = U(0x00),
+ .sdram_rcw[5] = U(0x00),
+ .err_disable = U(0x00),
+ .err_int_en = U(0x00),
+};
+
+const struct ddr_cfg_regs static_2900 = {
+ .cs[0].bnds = U(0x03FF),
+ .cs[1].bnds = U(0x03FF),
+ .cs[0].config = U(0x80050422),
+ .cs[1].config = U(0x80000422),
+ .cs[2].bnds = U(0x00),
+ .cs[3].bnds = U(0x00),
+ .cs[2].config = U(0x00),
+ .cs[3].config = U(0x00),
+ .timing_cfg[0] = U(0xFF990018),
+ .timing_cfg[1] = U(0x4F4A4844),
+ .timing_cfg[2] = U(0x0005601F),
+ .timing_cfg[3] = U(0x125F2100),
+ .timing_cfg[4] = U(0x02),
+ .timing_cfg[5] = U(0x07401400),
+ .timing_cfg[7] = U(0x3AA00000),
+ .timing_cfg[8] = U(0x09449B00),
+ .sdram_cfg[0] = U(0x65044008),
+ .sdram_cfg[1] = U(0x00401011),
+ .sdram_cfg[2] = U(0x00),
+ .sdram_mode[0] = U(0x06010C50),
+ .sdram_mode[1] = U(0x00280400),
+ .sdram_mode[2] = U(0x00),
+ .sdram_mode[3] = U(0x00),
+ .sdram_mode[4] = U(0x00),
+ .sdram_mode[5] = U(0x00),
+ .sdram_mode[6] = U(0x00),
+ .sdram_mode[7] = U(0x00),
+ .sdram_mode[8] = U(0x0500),
+ .sdram_mode[9] = U(0x10240000),
+ .sdram_mode[10] = U(0x00),
+ .sdram_mode[11] = U(0x00),
+ .sdram_mode[12] = U(0x00),
+ .sdram_mode[13] = U(0x00),
+ .sdram_mode[14] = U(0x00),
+ .sdram_mode[15] = U(0x00),
+ .md_cntl = U(0x00),
+ .interval = U(0x2C2E0000),
+ .data_init = U(0xDEADBEEF),
+ .init_addr = U(0x00),
+ .zq_cntl = U(0x8A090705),
+ .sdram_rcw[0] = U(0x00),
+ .sdram_rcw[1] = U(0x00),
+ .sdram_rcw[2] = U(0x00),
+ .sdram_rcw[3] = U(0x00),
+ .sdram_rcw[4] = U(0x00),
+ .sdram_rcw[5] = U(0x00),
+ .err_disable = U(0x00),
+ .err_int_en = U(0x00),
+};
+
+const struct ddr_cfg_regs static_2600 = {
+ .cs[0].bnds = U(0x03FF),
+ .cs[1].bnds = U(0x03FF),
+ .cs[0].config = U(0x80050422),
+ .cs[1].config = U(0x80000422),
+ .cs[2].bnds = U(0x00),
+ .cs[3].bnds = U(0x00),
+ .cs[2].config = U(0x00),
+ .cs[3].config = U(0x00),
+ .timing_cfg[0] = U(0xFF880018),
+ .timing_cfg[1] = U(0x2A24F444),
+ .timing_cfg[2] = U(0x007141DC),
+ .timing_cfg[3] = U(0x125B2100),
+ .timing_cfg[4] = U(0x02),
+ .timing_cfg[5] = U(0x06401400),
+ .timing_cfg[7] = U(0x28800000),
+ .timing_cfg[8] = U(0x07338A00),
+ .sdram_cfg[0] = U(0x65044008),
+ .sdram_cfg[1] = U(0x00401011),
+ .sdram_cfg[2] = U(0x00),
+ .sdram_mode[0] = U(0x06010A70),
+ .sdram_mode[1] = U(0x00200400),
+ .sdram_mode[2] = U(0x00),
+ .sdram_mode[3] = U(0x00),
+ .sdram_mode[4] = U(0x00),
+ .sdram_mode[5] = U(0x00),
+ .sdram_mode[6] = U(0x00),
+ .sdram_mode[7] = U(0x00),
+ .sdram_mode[8] = U(0x0500),
+ .sdram_mode[9] = U(0x0C240000),
+ .sdram_mode[10] = U(0x00),
+ .sdram_mode[11] = U(0x00),
+ .sdram_mode[12] = U(0x00),
+ .sdram_mode[13] = U(0x00),
+ .sdram_mode[14] = U(0x00),
+ .sdram_mode[15] = U(0x00),
+ .md_cntl = U(0x00),
+ .interval = U(0x279C0000),
+ .data_init = U(0xDEADBEEF),
+ .init_addr = U(0x00),
+ .zq_cntl = U(0x8A090705),
+ .sdram_rcw[0] = U(0x00),
+ .sdram_rcw[1] = U(0x00),
+ .sdram_rcw[2] = U(0x00),
+ .sdram_rcw[3] = U(0x00),
+ .sdram_rcw[4] = U(0x00),
+ .sdram_rcw[5] = U(0x00),
+ .err_disable = U(0x00),
+ .err_int_en = U(0x00),
+};
+
+const struct dimm_params static_dimm = {
+ .rdimm = U(0),
+ .primary_sdram_width = U(64),
+ .ec_sdram_width = U(8),
+ .n_ranks = U(2),
+ .device_width = U(8),
+ .mirrored_dimm = U(1),
+};
+
+/* Sample code using two UDIMM MT18ASF1G72AZ-2G6B1, on each DDR controller */
+unsigned long long board_static_ddr(struct ddr_info *priv)
+{
+ (void)memcpy(&priv->ddr_reg, &static_2900, sizeof(static_2900));
+ (void)memcpy(&priv->dimm, &static_dimm, sizeof(static_dimm));
+ priv->conf.cs_on_dimm[0] = 0x3;
+ ddr_board_options(priv);
+ compute_ddr_phy(priv);
+
+ return ULL(0x400000000);
+}
+
+#elif defined(CONFIG_DDR_NODIMM)
+/*
+ * Sample code to bypass reading SPD. This is a sample, not recommended
+ * for boards with slots. DDR model number: UDIMM MT18ASF1G72AZ-2G6B1.
+ */
+
+const struct dimm_params ddr_raw_timing = {
+ .n_ranks = U(2),
+ .rank_density = U(4294967296u),
+ .capacity = U(8589934592u),
+ .primary_sdram_width = U(64),
+ .ec_sdram_width = U(8),
+ .device_width = U(8),
+ .die_density = U(0x4),
+ .rdimm = U(0),
+ .mirrored_dimm = U(1),
+ .n_row_addr = U(15),
+ .n_col_addr = U(10),
+ .bank_addr_bits = U(0),
+ .bank_group_bits = U(2),
+ .edc_config = U(2),
+ .burst_lengths_bitmask = U(0x0c),
+ .tckmin_x_ps = 750,
+ .tckmax_ps = 1600,
+ .caslat_x = U(0x00FFFC00),
+ .taa_ps = 13750,
+ .trcd_ps = 13750,
+ .trp_ps = 13750,
+ .tras_ps = 32000,
+ .trc_ps = 457500,
+ .twr_ps = 15000,
+ .trfc1_ps = 260000,
+ .trfc2_ps = 160000,
+ .trfc4_ps = 110000,
+ .tfaw_ps = 21000,
+ .trrds_ps = 3000,
+ .trrdl_ps = 4900,
+ .tccdl_ps = 5000,
+ .refresh_rate_ps = U(7800000),
+};
+
+int ddr_get_ddr_params(struct dimm_params *pdimm,
+ struct ddr_conf *conf)
+{
+ static const char dimm_model[] = "Fixed DDR on board";
+
+ conf->dimm_in_use[0] = 1; /* Modify accordingly */
+ memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params));
+ memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
+
+ /* valid DIMM mask, change accordingly, together with dimm_on_ctlr. */
+ return 0x5;
+}
+#endif /* CONFIG_DDR_NODIMM */
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ struct memctl_opt *popts = &priv->opt;
+ const struct ddr_conf *conf = &priv->conf;
+
+ popts->vref_dimm = U(0x24); /* range 1, 83.4% */
+ popts->rtt_override = 0;
+ popts->rtt_park = U(240);
+ popts->otf_burst_chop_en = 0;
+ popts->burst_length = U(DDR_BL8);
+ popts->trwt_override = U(1);
+ popts->bstopre = U(0); /* auto precharge */
+ popts->addr_hash = 1;
+
+ /* Set ODT impedance on PHY side */
+ switch (conf->cs_on_dimm[1]) {
+ case 0xc: /* Two slots dual rank */
+ case 0x4: /* Two slots single rank, not valid for interleaving */
+ popts->trwt = U(0xf);
+ popts->twrt = U(0x7);
+ popts->trrt = U(0x7);
+ popts->twwt = U(0x7);
+ popts->vref_phy = U(0x6B); /* 83.6% */
+ popts->odt = U(60);
+ popts->phy_tx_impedance = U(28);
+ break;
+ case 0: /* One slot used */
+ default:
+ popts->trwt = U(0x3);
+ popts->twrt = U(0x3);
+ popts->trrt = U(0x3);
+ popts->twwt = U(0x3);
+ popts->vref_phy = U(0x60); /* 75% */
+ popts->odt = U(48);
+ popts->phy_tx_impedance = U(28);
+ break;
+ }
+
+ return 0;
+}
+
+#ifdef NXP_WARM_BOOT
+long long init_ddr(uint32_t wrm_bt_flg)
+#else
+long long init_ddr(void)
+#endif
+{
+ int spd_addr[] = {0x51U, 0x52U, 0x53U, 0x54U};
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ if (get_clocks(&sys) == 1) {
+ ERROR("System clocks are not set.\n");
+ panic();
+ }
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
+ debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
+
+ zeromem(&info, sizeof(info));
+
+ /* Set two DDRC. Unused DDRC will be removed automatically. */
+ info.num_ctlrs = NUM_OF_DDRC;
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+ info.ddr[1] = (void *)NXP_DDR2_ADDR;
+ info.phy[0] = (void *)NXP_DDR_PHY1_ADDR;
+ info.phy[1] = (void *)NXP_DDR_PHY2_ADDR;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.img_loadr = load_img;
+ info.phy_gen2_fw_img_buf = PHY_GEN2_FW_IMAGE_BUFFER;
+ if (info.clk == 0) {
+ info.clk = get_ddr_freq(&sys, 1);
+ }
+ info.dimm_on_ctlr = DDRC_NUM_DIMM;
+
+ info.warm_boot_flag = DDR_WRM_BOOT_NT_SUPPORTED;
+#ifdef NXP_WARM_BOOT
+ info.warm_boot_flag = DDR_COLD_BOOT;
+ if (wrm_bt_flg != 0U) {
+ info.warm_boot_flag = DDR_WARM_BOOT;
+ } else {
+ info.warm_boot_flag = DDR_COLD_BOOT;
+ }
+#endif
+
+ dram_size = dram_init(&info
+#if defined(NXP_HAS_CCN504) || defined(NXP_HAS_CCN508)
+ , NXP_CCN_HN_F_0_ADDR
+#endif
+ );
+
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-lx2160a/lx2160aqds/plat_def.h b/plat/nxp/soc-lx2160a/lx2160aqds/plat_def.h
new file mode 100644
index 0000000..f480f92
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160aqds/plat_def.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+#include <cortex_a72.h>
+/* Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#if defined(IMAGE_BL31)
+#define LS_SYS_TIMCTL_BASE 0x2890000
+#define PLAT_LS_NSTIMER_FRAME_ID 0
+#define LS_CONFIG_CNTACR 1
+#endif
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+/* SD block buffer */
+#define NXP_SD_BLOCK_BUF_SIZE (0x8000)
+#define NXP_SD_BLOCK_BUF_ADDR (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
+ - NXP_SD_BLOCK_BUF_SIZE)
+
+#ifdef SD_BOOT
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
+ - NXP_SD_BLOCK_BUF_SIZE)
+#else
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#endif
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 4
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+#define PHY_GEN2_FW_IMAGE_BUFFER (NXP_OCRAM_ADDR + CSF_HDR_SZ)
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES 3
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES 2
+#endif
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define BL32_IRQ_SEC_PHY_TIMER 29
+
+#define BL31_WDOG_SEC 89
+
+#define BL31_NS_WDOG_WS1 108
+
+/*
+ * Define properties 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_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define NXP_IRQ_SEC_SGI_7 15
+
+#define PLAT_LS_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(BL31_NS_WDOG_WS1, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(NXP_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+#endif
diff --git a/plat/nxp/soc-lx2160a/lx2160aqds/platform.c b/plat/nxp/soc-lx2160a/lx2160aqds/platform.c
new file mode 100644
index 0000000..b00adb5
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160aqds/platform.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-lx2160a/lx2160aqds/platform.mk b/plat/nxp/soc-lx2160a/lx2160aqds/platform.mk
new file mode 100644
index 0000000..226b22b
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160aqds/platform.mk
@@ -0,0 +1,51 @@
+#
+# Copyright 2018-2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+
+BOOT_MODE ?= flexspi_nor
+BOARD ?= lx2160aqds
+POVDD_ENABLE := no
+NXP_COINED_BB := no
+
+ # DDR Compilation Configs
+NUM_OF_DDRC := 1
+DDRC_NUM_DIMM := 1
+DDRC_NUM_CS := 2
+DDR_ECC_EN := yes
+ #enable address decoding feature
+DDR_ADDR_DEC := yes
+APPLY_MAX_CDD := yes
+
+# DDR Errata
+ERRATA_DDR_A011396 := 1
+ERRATA_DDR_A050450 := 1
+
+ # On-Board Flash Details
+FLASH_TYPE := MT35XU512A
+XSPI_FLASH_SZ := 0x10000000
+NXP_XSPI_NOR_UNIT_SIZE := 0x20000
+BL2_BIN_XSPI_NOR_END_ADDRESS := 0x100000
+# CONFIG_FSPI_ERASE_4K is required to erase 4K sector sizes. This
+# config is enabled for future use cases.
+FSPI_ERASE_4K := 0
+
+# Platform specific features.
+WARM_BOOT := yes
+
+# Adding Platform files build files
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := flexspi_nor \
+ sd \
+ emmc
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-lx2160a/soc.mk
diff --git a/plat/nxp/soc-lx2160a/lx2160aqds/platform_def.h b/plat/nxp/soc-lx2160a/lx2160aqds/platform_def.h
new file mode 100644
index 0000000..5fa774e
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160aqds/platform_def.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include "plat_def.h"
+#include "plat_default_def.h"
+
+#endif
diff --git a/plat/nxp/soc-lx2160a/lx2160aqds/policy.h b/plat/nxp/soc-lx2160a/lx2160aqds/policy.h
new file mode 100644
index 0000000..05d23e2
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160aqds/policy.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/* Following defines affect the PLATFORM SECURITY POLICY */
+
+/* set this to 0x0 if the platform is not using/responding to ECC errors
+ * set this to 0x1 if ECC is being used (we have to do some init)
+ */
+#define POLICY_USING_ECC 0x0
+
+/* Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+/*
+ * POLICY_PERF_WRIOP = 0 : No Performance enhancement for WRIOP RN-I
+ * POLICY_PERF_WRIOP = 1 : No Performance enhancement for WRIOP RN-I = 7
+ * POLICY_PERF_WRIOP = 2 : No Performance enhancement for WRIOP RN-I = 23
+ */
+#define POLICY_PERF_WRIOP 0
+
+/*
+ * set this to '1' if the debug clocks need to remain enabled during
+ * system entry to low-power (LPM20) - this should only be necessary
+ * for testing and NEVER set for normal production
+ */
+#define POLICY_DEBUG_ENABLE 0
+
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-lx2160a/lx2160ardb/ddr_init.c b/plat/nxp/soc-lx2160a/lx2160ardb/ddr_init.c
new file mode 100644
index 0000000..8669b1d
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160ardb/ddr_init.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <lib/utils.h>
+#include <load_img.h>
+
+#include "plat_common.h"
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+const struct ddr_cfg_regs static_1600 = {
+ .cs[0].config = U(0xA8050322),
+ .cs[1].config = U(0x80000322),
+ .cs[0].bnds = U(0x3FF),
+ .cs[1].bnds = U(0x3FF),
+ .sdram_cfg[0] = U(0xE5044000),
+ .sdram_cfg[1] = U(0x401011),
+ .timing_cfg[0] = U(0xFF550018),
+ .timing_cfg[1] = U(0xBAB48C42),
+ .timing_cfg[2] = U(0x48C111),
+ .timing_cfg[3] = U(0x10C1000),
+ .timing_cfg[4] = U(0x2),
+ .timing_cfg[5] = U(0x3401400),
+ .timing_cfg[7] = U(0x13300000),
+ .timing_cfg[8] = U(0x2114600),
+ .sdram_mode[0] = U(0x6010210),
+ .sdram_mode[8] = U(0x500),
+ .sdram_mode[9] = U(0x4240000),
+ .interval = U(0x18600000),
+ .data_init = U(0xDEADBEEF),
+ .zq_cntl = U(0x8A090705),
+};
+
+const struct dimm_params static_dimm = {
+ .rdimm = U(0),
+ .primary_sdram_width = U(64),
+ .ec_sdram_width = U(8),
+ .n_ranks = U(2),
+ .device_width = U(8),
+ .mirrored_dimm = U(1),
+};
+
+/* Sample code using two UDIMM MT18ASF1G72AZ-2G6B1, on each DDR controller */
+unsigned long long board_static_ddr(struct ddr_info *priv)
+{
+ memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600));
+ memcpy(&priv->dimm, &static_dimm, sizeof(static_dimm));
+ priv->conf.cs_on_dimm[0] = 0x3;
+ ddr_board_options(priv);
+ compute_ddr_phy(priv);
+
+ return ULL(0x400000000);
+}
+
+#elif defined(CONFIG_DDR_NODIMM)
+/*
+ * Sample code to bypass reading SPD. This is a sample, not recommended
+ * for boards with slots. DDR model number: UDIMM MT18ASF1G72AZ-2G6B1.
+ */
+
+const struct dimm_params ddr_raw_timing = {
+ .n_ranks = U(2),
+ .rank_density = U(4294967296u),
+ .capacity = U(8589934592u),
+ .primary_sdram_width = U(64),
+ .ec_sdram_width = U(8),
+ .device_width = U(8),
+ .die_density = U(0x4),
+ .rdimm = U(0),
+ .mirrored_dimm = U(1),
+ .n_row_addr = U(15),
+ .n_col_addr = U(10),
+ .bank_addr_bits = U(0),
+ .bank_group_bits = U(2),
+ .edc_config = U(2),
+ .burst_lengths_bitmask = U(0x0c),
+ .tckmin_x_ps = 750,
+ .tckmax_ps = 1600,
+ .caslat_x = U(0x00FFFC00),
+ .taa_ps = 13750,
+ .trcd_ps = 13750,
+ .trp_ps = 13750,
+ .tras_ps = 32000,
+ .trc_ps = 457500,
+ .twr_ps = 15000,
+ .trfc1_ps = 260000,
+ .trfc2_ps = 160000,
+ .trfc4_ps = 110000,
+ .tfaw_ps = 21000,
+ .trrds_ps = 3000,
+ .trrdl_ps = 4900,
+ .tccdl_ps = 5000,
+ .refresh_rate_ps = U(7800000),
+};
+
+int ddr_get_ddr_params(struct dimm_params *pdimm,
+ struct ddr_conf *conf)
+{
+ static const char dimm_model[] = "Fixed DDR on board";
+
+ conf->dimm_in_use[0] = 1; /* Modify accordingly */
+ memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params));
+ memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
+
+ /* valid DIMM mask, change accordingly, together with dimm_on_ctlr. */
+ return 0x5;
+}
+#endif /* CONFIG_DDR_NODIMM */
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ struct memctl_opt *popts = &priv->opt;
+ const struct ddr_conf *conf = &priv->conf;
+
+ popts->vref_dimm = U(0x24); /* range 1, 83.4% */
+ popts->rtt_override = 0;
+ popts->rtt_park = U(240);
+ popts->otf_burst_chop_en = 0;
+ popts->burst_length = U(DDR_BL8);
+ popts->trwt_override = U(1);
+ popts->bstopre = U(0); /* auto precharge */
+ popts->addr_hash = 1;
+
+ /* Set ODT impedance on PHY side */
+ switch (conf->cs_on_dimm[1]) {
+ case 0xc: /* Two slots dual rank */
+ case 0x4: /* Two slots single rank, not valid for interleaving */
+ popts->trwt = U(0xf);
+ popts->twrt = U(0x7);
+ popts->trrt = U(0x7);
+ popts->twwt = U(0x7);
+ popts->vref_phy = U(0x6B); /* 83.6% */
+ popts->odt = U(60);
+ popts->phy_tx_impedance = U(28);
+ break;
+ case 0: /* One slot used */
+ default:
+ popts->trwt = U(0x3);
+ popts->twrt = U(0x3);
+ popts->trrt = U(0x3);
+ popts->twwt = U(0x3);
+ popts->vref_phy = U(0x60); /* 75% */
+ popts->odt = U(48);
+ popts->phy_tx_impedance = U(28);
+ break;
+ }
+
+ return 0;
+}
+
+long long init_ddr(void)
+{
+ int spd_addr[] = { 0x51, 0x52, 0x53, 0x54 };
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ if (get_clocks(&sys) != 0) {
+ ERROR("System clocks are not set\n");
+ panic();
+ }
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
+ debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
+
+ zeromem(&info, sizeof(info));
+
+ /* Set two DDRC. Unused DDRC will be removed automatically. */
+ info.num_ctlrs = NUM_OF_DDRC;
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+ info.ddr[1] = (void *)NXP_DDR2_ADDR;
+ info.phy[0] = (void *)NXP_DDR_PHY1_ADDR;
+ info.phy[1] = (void *)NXP_DDR_PHY2_ADDR;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.img_loadr = load_img;
+ info.phy_gen2_fw_img_buf = PHY_GEN2_FW_IMAGE_BUFFER;
+ if (info.clk == 0) {
+ info.clk = get_ddr_freq(&sys, 1);
+ }
+ info.dimm_on_ctlr = DDRC_NUM_DIMM;
+
+ info.warm_boot_flag = DDR_WRM_BOOT_NT_SUPPORTED;
+
+ dram_size = dram_init(&info
+#if defined(NXP_HAS_CCN504) || defined(NXP_HAS_CCN508)
+ , NXP_CCN_HN_F_0_ADDR
+#endif
+ );
+
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-lx2160a/lx2160ardb/plat_def.h b/plat/nxp/soc-lx2160a/lx2160ardb/plat_def.h
new file mode 100644
index 0000000..02f51e7
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160ardb/plat_def.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+#include <cortex_a72.h>
+/* Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#if defined(IMAGE_BL31)
+#define LS_SYS_TIMCTL_BASE 0x2890000
+#define PLAT_LS_NSTIMER_FRAME_ID 0
+#define LS_CONFIG_CNTACR 1
+#endif
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+/* SD block buffer */
+#define NXP_SD_BLOCK_BUF_SIZE (0x8000)
+#define NXP_SD_BLOCK_BUF_ADDR (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
+ - NXP_SD_BLOCK_BUF_SIZE)
+
+#ifdef SD_BOOT
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
+ - NXP_SD_BLOCK_BUF_SIZE)
+#else
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#endif
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 4
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+#define PHY_GEN2_FW_IMAGE_BUFFER (NXP_OCRAM_ADDR + CSF_HDR_SZ)
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES 3
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES 2
+#endif
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define BL32_IRQ_SEC_PHY_TIMER 29
+
+#define BL31_WDOG_SEC 89
+
+#define BL31_NS_WDOG_WS1 108
+
+/*
+ * Define properties 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_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define NXP_IRQ_SEC_SGI_7 15
+
+#define PLAT_LS_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(BL31_NS_WDOG_WS1, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(NXP_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+#endif
diff --git a/plat/nxp/soc-lx2160a/lx2160ardb/platform.c b/plat/nxp/soc-lx2160a/lx2160ardb/platform.c
new file mode 100644
index 0000000..b00adb5
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160ardb/platform.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-lx2160a/lx2160ardb/platform.mk b/plat/nxp/soc-lx2160a/lx2160ardb/platform.mk
new file mode 100644
index 0000000..ffb5fad
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160ardb/platform.mk
@@ -0,0 +1,51 @@
+#
+# Copyright 2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+
+BOOT_MODE ?= flexspi_nor
+BOARD ?= lx2160ardb
+POVDD_ENABLE := no
+NXP_COINED_BB := no
+
+ # DDR Compilation Configs
+NUM_OF_DDRC := 2
+DDRC_NUM_DIMM := 2
+DDRC_NUM_CS := 4
+DDR_ECC_EN := yes
+ #enable address decoding feature
+DDR_ADDR_DEC := yes
+APPLY_MAX_CDD := yes
+
+# DDR Errata
+ERRATA_DDR_A011396 := 1
+ERRATA_DDR_A050450 := 1
+
+ # On-Board Flash Details
+FLASH_TYPE := MT35XU512A
+XSPI_FLASH_SZ := 0x10000000
+NXP_XSPI_NOR_UNIT_SIZE := 0x20000
+BL2_BIN_XSPI_NOR_END_ADDRESS := 0x100000
+# CONFIG_FSPI_ERASE_4K is required to erase 4K sector sizes. This
+# config is enabled for future use cases.
+FSPI_ERASE_4K := 0
+
+ # Platform specific features.
+WARM_BOOT := no
+
+ # Adding Platform files build files
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := flexspi_nor \
+ sd \
+ emmc
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+ # Adding SoC build info
+include plat/nxp/soc-lx2160a/soc.mk
diff --git a/plat/nxp/soc-lx2160a/lx2160ardb/platform_def.h b/plat/nxp/soc-lx2160a/lx2160ardb/platform_def.h
new file mode 100644
index 0000000..6660998
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160ardb/platform_def.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include "plat_def.h"
+#include "plat_default_def.h"
+
+#endif
diff --git a/plat/nxp/soc-lx2160a/lx2160ardb/policy.h b/plat/nxp/soc-lx2160a/lx2160ardb/policy.h
new file mode 100644
index 0000000..19ad6db
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2160ardb/policy.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/* Following defines affect the PLATFORM SECURITY POLICY */
+
+/* set this to 0x0 if the platform is not using/responding to ECC errors
+ * set this to 0x1 if ECC is being used (we have to do some init)
+ */
+#define POLICY_USING_ECC 0x0
+
+/* Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+/*
+ * POLICY_PERF_WRIOP = 0 : No Performance enhancement for WRIOP RN-I
+ * POLICY_PERF_WRIOP = 1 : No Performance enhancement for WRIOP RN-I = 7
+ * POLICY_PERF_WRIOP = 2 : No Performance enhancement for WRIOP RN-I = 23
+ */
+#define POLICY_PERF_WRIOP 0
+
+/*
+ * set this to '1' if the debug clocks need to remain enabled during
+ * system entry to low-power (LPM20) - this should only be necessary
+ * for testing and NEVER set for normal production
+ */
+#define POLICY_DEBUG_ENABLE 0
+
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-lx2160a/lx2162aqds/ddr_init.c b/plat/nxp/soc-lx2160a/lx2162aqds/ddr_init.c
new file mode 100644
index 0000000..73bcc93
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2162aqds/ddr_init.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <lib/utils.h>
+#include <load_img.h>
+
+#include "plat_common.h"
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+
+const struct ddr_cfg_regs static_3200 = {
+ .cs[0].bnds = U(0x03FFU),
+ .cs[1].bnds = U(0x03FF),
+ .cs[0].config = U(0x80050422),
+ .cs[1].config = U(0x80000422),
+ .cs[2].bnds = U(0x00),
+ .cs[3].bnds = U(0x00),
+ .cs[2].config = U(0x00),
+ .cs[3].config = U(0x00),
+ .timing_cfg[0] = U(0xFFAA0018),
+ .timing_cfg[1] = U(0x646A8844),
+ .timing_cfg[2] = U(0x00058022),
+ .timing_cfg[3] = U(0x13622100),
+ .timing_cfg[4] = U(0x02),
+ .timing_cfg[5] = U(0x07401400),
+ .timing_cfg[7] = U(0x3BB00000),
+ .timing_cfg[8] = U(0x0944AC00),
+ .sdram_cfg[0] = U(0x65044008),
+ .sdram_cfg[1] = U(0x00401011),
+ .sdram_cfg[2] = U(0x00),
+ .sdram_mode[0] = U(0x06010C50),
+ .sdram_mode[1] = U(0x00280400),
+ .sdram_mode[2] = U(0x00),
+ .sdram_mode[3] = U(0x00),
+ .sdram_mode[4] = U(0x00),
+ .sdram_mode[5] = U(0x00),
+ .sdram_mode[6] = U(0x00),
+ .sdram_mode[7] = U(0x00),
+ .sdram_mode[8] = U(0x0500),
+ .sdram_mode[9] = U(0x10240000),
+ .sdram_mode[10] = U(0x00),
+ .sdram_mode[11] = U(0x00),
+ .sdram_mode[12] = U(0x00),
+ .sdram_mode[13] = U(0x00),
+ .sdram_mode[14] = U(0x00),
+ .sdram_mode[15] = U(0x00),
+ .md_cntl = U(0x00),
+ .interval = U(0x30C00000),
+ .data_init = U(0xDEADBEEF),
+ .init_addr = U(0x00),
+ .zq_cntl = U(0x8A090705),
+ .sdram_rcw[0] = U(0x00),
+ .sdram_rcw[1] = U(0x00),
+ .sdram_rcw[2] = U(0x00),
+ .sdram_rcw[3] = U(0x00),
+ .sdram_rcw[4] = U(0x00),
+ .sdram_rcw[5] = U(0x00),
+ .err_disable = U(0x00),
+ .err_int_en = U(0x00),
+};
+
+const struct ddr_cfg_regs static_2900 = {
+ .cs[0].bnds = U(0x03FF),
+ .cs[1].bnds = U(0x03FF),
+ .cs[0].config = U(0x80050422),
+ .cs[1].config = U(0x80000422),
+ .cs[2].bnds = U(0x00),
+ .cs[3].bnds = U(0x00),
+ .cs[2].config = U(0x00),
+ .cs[3].config = U(0x00),
+ .timing_cfg[0] = U(0xFF990018),
+ .timing_cfg[1] = U(0x4F4A4844),
+ .timing_cfg[2] = U(0x0005601F),
+ .timing_cfg[3] = U(0x125F2100),
+ .timing_cfg[4] = U(0x02),
+ .timing_cfg[5] = U(0x07401400),
+ .timing_cfg[7] = U(0x3AA00000),
+ .timing_cfg[8] = U(0x09449B00),
+ .sdram_cfg[0] = U(0x65044008),
+ .sdram_cfg[1] = U(0x00401011),
+ .sdram_cfg[2] = U(0x00),
+ .sdram_mode[0] = U(0x06010C50),
+ .sdram_mode[1] = U(0x00280400),
+ .sdram_mode[2] = U(0x00),
+ .sdram_mode[3] = U(0x00),
+ .sdram_mode[4] = U(0x00),
+ .sdram_mode[5] = U(0x00),
+ .sdram_mode[6] = U(0x00),
+ .sdram_mode[7] = U(0x00),
+ .sdram_mode[8] = U(0x0500),
+ .sdram_mode[9] = U(0x10240000),
+ .sdram_mode[10] = U(0x00),
+ .sdram_mode[11] = U(0x00),
+ .sdram_mode[12] = U(0x00),
+ .sdram_mode[13] = U(0x00),
+ .sdram_mode[14] = U(0x00),
+ .sdram_mode[15] = U(0x00),
+ .md_cntl = U(0x00),
+ .interval = U(0x2C2E0000),
+ .data_init = U(0xDEADBEEF),
+ .init_addr = U(0x00),
+ .zq_cntl = U(0x8A090705),
+ .sdram_rcw[0] = U(0x00),
+ .sdram_rcw[1] = U(0x00),
+ .sdram_rcw[2] = U(0x00),
+ .sdram_rcw[3] = U(0x00),
+ .sdram_rcw[4] = U(0x00),
+ .sdram_rcw[5] = U(0x00),
+ .err_disable = U(0x00),
+ .err_int_en = U(0x00),
+};
+
+const struct ddr_cfg_regs static_2600 = {
+ .cs[0].bnds = U(0x03FF),
+ .cs[1].bnds = U(0x03FF),
+ .cs[0].config = U(0x80050422),
+ .cs[1].config = U(0x80000422),
+ .cs[2].bnds = U(0x00),
+ .cs[3].bnds = U(0x00),
+ .cs[2].config = U(0x00),
+ .cs[3].config = U(0x00),
+ .timing_cfg[0] = U(0xFF880018),
+ .timing_cfg[1] = U(0x2A24F444),
+ .timing_cfg[2] = U(0x007141DC),
+ .timing_cfg[3] = U(0x125B2100),
+ .timing_cfg[4] = U(0x02),
+ .timing_cfg[5] = U(0x06401400),
+ .timing_cfg[7] = U(0x28800000),
+ .timing_cfg[8] = U(0x07338A00),
+ .sdram_cfg[0] = U(0x65044008),
+ .sdram_cfg[1] = U(0x00401011),
+ .sdram_cfg[2] = U(0x00),
+ .sdram_mode[0] = U(0x06010A70),
+ .sdram_mode[1] = U(0x00200400),
+ .sdram_mode[2] = U(0x00),
+ .sdram_mode[3] = U(0x00),
+ .sdram_mode[4] = U(0x00),
+ .sdram_mode[5] = U(0x00),
+ .sdram_mode[6] = U(0x00),
+ .sdram_mode[7] = U(0x00),
+ .sdram_mode[8] = U(0x0500),
+ .sdram_mode[9] = U(0x0C240000),
+ .sdram_mode[10] = U(0x00),
+ .sdram_mode[11] = U(0x00),
+ .sdram_mode[12] = U(0x00),
+ .sdram_mode[13] = U(0x00),
+ .sdram_mode[14] = U(0x00),
+ .sdram_mode[15] = U(0x00),
+ .md_cntl = U(0x00),
+ .interval = U(0x279C0000),
+ .data_init = U(0xDEADBEEF),
+ .init_addr = U(0x00),
+ .zq_cntl = U(0x8A090705),
+ .sdram_rcw[0] = U(0x00),
+ .sdram_rcw[1] = U(0x00),
+ .sdram_rcw[2] = U(0x00),
+ .sdram_rcw[3] = U(0x00),
+ .sdram_rcw[4] = U(0x00),
+ .sdram_rcw[5] = U(0x00),
+ .err_disable = U(0x00),
+ .err_int_en = U(0x00),
+};
+
+const struct dimm_params static_dimm = {
+ .rdimm = 0U,
+ .primary_sdram_width = 64U,
+ .ec_sdram_width = 8U,
+ .n_ranks = 2U,
+ .device_width = 8U,
+ .mirrored_dimm = 1U,
+};
+
+/* Sample code using two UDIMM MT18ASF1G72AZ-2G6B1, on each DDR controller */
+unsigned long long board_static_ddr(struct ddr_info *priv)
+{
+ memcpy(&priv->ddr_reg, &static_2900, sizeof(static_2900));
+ memcpy(&priv->dimm, &static_dimm, sizeof(static_dimm));
+ priv->conf.cs_on_dimm[0] = 0x3;
+ ddr_board_options(priv);
+ compute_ddr_phy(priv);
+
+ return ULL(0x400000000);
+}
+
+#elif defined(CONFIG_DDR_NODIMM)
+/*
+ * Sample code to bypass reading SPD. This is a sample, not recommended
+ * for boards with slots. DDR model number: UDIMM MT18ASF1G72AZ-2G6B1.
+ */
+struct dimm_params ddr_raw_timing = {
+ .n_ranks = 2U,
+ .rank_density = U(0x200000000),
+ .capacity = U(0x400000000),
+ .primary_sdram_width = 64U,
+ .ec_sdram_width = 8U,
+ .device_width = 8U,
+ .die_density = U(0x5),
+ .rdimm = 0U,
+ .mirrored_dimm = 1U,
+ .n_row_addr = 16U,
+ .n_col_addr = 10U,
+ .bank_addr_bits = 0U,
+ .bank_group_bits = 2U,
+ .edc_config = 2U,
+ .burst_lengths_bitmask = U(0x0c),
+ .tckmin_x_ps = 625,
+ .tckmax_ps = 1600,
+ .caslat_x = U(0x15FFFC00),
+ .taa_ps = 13750,
+ .trcd_ps = 13750,
+ .trp_ps = 13750,
+ .tras_ps = 32000,
+ .trc_ps = 457500,
+ .twr_ps = 15000,
+ .trfc1_ps = 350000,
+ .trfc2_ps = 260000,
+ .trfc4_ps = 160000,
+ .tfaw_ps = 21000,
+ .trrds_ps = 2500,
+ .trrdl_ps = 4900,
+ .tccdl_ps = 5000,
+ .refresh_rate_ps = 7800000U,
+};
+
+int ddr_get_ddr_params(struct dimm_params *pdimm,
+ struct ddr_conf *conf)
+{
+ static const char dimm_model[] = "Fixed DDR on board";
+
+ conf->dimm_in_use[0] = 1; /* Modify accordingly */
+ memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params));
+ memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
+
+ /* valid DIMM mask, change accordingly, together with dimm_on_ctlr. */
+ return 0x5;
+}
+#endif /* CONFIG_DDR_NODIMM */
+
+int ddr_board_options(struct ddr_info *priv)
+{
+ struct memctl_opt *popts = &priv->opt;
+ const struct ddr_conf *conf = &priv->conf;
+
+ popts->vref_dimm = U(0x19); /* range 1, 83.4% */
+ popts->rtt_override = 1U;
+ popts->rtt_override_value = 0x5U; /* RTT being used as 60 ohm */
+ popts->rtt_park = 120U;
+ popts->otf_burst_chop_en = 0;
+ popts->burst_length = DDR_BL8;
+ popts->trwt_override = 1U;
+ popts->bstopre = 0U; /* auto precharge */
+ popts->addr_hash = 1;
+
+ /* Set ODT impedance on PHY side */
+ switch (conf->cs_on_dimm[1]) {
+ case 0xc: /* Two slots dual rank */
+ case 0x4: /* Two slots single rank, not valid for interleaving */
+ popts->trwt = U(0xf);
+ popts->twrt = U(0x7);
+ popts->trrt = U(0x7);
+ popts->twwt = U(0x7);
+ popts->vref_phy = U(0x6B); /* 83.6% */
+ popts->odt = 60U;
+ popts->phy_tx_impedance = 28U;
+ break;
+ case 0: /* Ont slot used */
+ default:
+ popts->trwt = U(0x3);
+ popts->twrt = U(0x3);
+ popts->trrt = U(0x3);
+ popts->twwt = U(0x3);
+ popts->vref_phy = U(0x5D); /* 72% */
+ popts->odt = 60U;
+ popts->phy_tx_impedance = 28U;
+ break;
+ }
+
+ return 0;
+}
+
+#ifdef NXP_WARM_BOOT
+long long init_ddr(uint32_t wrm_bt_flg)
+#else
+long long init_ddr(void)
+#endif
+{
+ int spd_addr[] = { 0x51, 0x52, 0x53, 0x54 };
+ struct ddr_info info;
+ struct sysinfo sys;
+ long long dram_size;
+
+ zeromem(&sys, sizeof(sys));
+ if (get_clocks(&sys) != 0) {
+ ERROR("System clocks are not set\n");
+ panic();
+ }
+ debug("platform clock %lu\n", sys.freq_platform);
+ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
+ debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
+
+ zeromem(&info, sizeof(info));
+
+ /* Set two DDRC. Unused DDRC will be removed automatically. */
+ info.num_ctlrs = NUM_OF_DDRC;
+ info.spd_addr = spd_addr;
+ info.ddr[0] = (void *)NXP_DDR_ADDR;
+ info.ddr[1] = (void *)NXP_DDR2_ADDR;
+ info.phy[0] = (void *)NXP_DDR_PHY1_ADDR;
+ info.phy[1] = (void *)NXP_DDR_PHY2_ADDR;
+ info.clk = get_ddr_freq(&sys, 0);
+ info.img_loadr = load_img;
+ info.phy_gen2_fw_img_buf = PHY_GEN2_FW_IMAGE_BUFFER;
+ if (info.clk == 0) {
+ info.clk = get_ddr_freq(&sys, 1);
+ }
+ info.dimm_on_ctlr = DDRC_NUM_DIMM;
+
+ info.warm_boot_flag = DDR_WRM_BOOT_NT_SUPPORTED;
+#ifdef NXP_WARM_BOOT
+ if (wrm_bt_flg != 0) {
+ info.warm_boot_flag = DDR_WARM_BOOT;
+ } else {
+ info.warm_boot_flag = DDR_COLD_BOOT;
+ }
+#endif
+
+ dram_size = dram_init(&info
+#if defined(NXP_HAS_CCN504) || defined(NXP_HAS_CCN508)
+ , NXP_CCN_HN_F_0_ADDR
+#endif
+ );
+
+
+ if (dram_size < 0) {
+ ERROR("DDR init failed.\n");
+ }
+
+ return dram_size;
+}
diff --git a/plat/nxp/soc-lx2160a/lx2162aqds/plat_def.h b/plat/nxp/soc-lx2160a/lx2162aqds/plat_def.h
new file mode 100644
index 0000000..de2d244
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2162aqds/plat_def.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+#include <cortex_a72.h>
+/* Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#if defined(IMAGE_BL31)
+#define LS_SYS_TIMCTL_BASE 0x2890000
+#define PLAT_LS_NSTIMER_FRAME_ID 0
+#define LS_CONFIG_CNTACR 1
+#endif
+
+#define NXP_SYSCLK_FREQ 100000000
+#define NXP_DDRCLK_FREQ 100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE 115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE 0x2000
+#else
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE 0x1000
+#endif
+
+/* SD block buffer */
+#define NXP_SD_BLOCK_BUF_SIZE (0x8000)
+#define NXP_SD_BLOCK_BUF_ADDR (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
+ - NXP_SD_BLOCK_BUF_SIZE)
+
+#ifdef SD_BOOT
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
+ - NXP_SD_BLOCK_BUF_SIZE)
+#else
+#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#endif
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES 4
+#define MAX_IO_BLOCK_DEVICES 1
+#define MAX_IO_HANDLES 4
+
+#define PHY_GEN2_FW_IMAGE_BUFFER (NXP_OCRAM_ADDR + CSF_HDR_SZ)
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES 3
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES 2
+#endif
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define BL32_IRQ_SEC_PHY_TIMER 29
+
+#define BL31_WDOG_SEC 89
+
+#define BL31_NS_WDOG_WS1 108
+
+/*
+ * Define properties 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_LS_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define NXP_IRQ_SEC_SGI_7 15
+
+#define PLAT_LS_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(BL31_NS_WDOG_WS1, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(NXP_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+#endif
diff --git a/plat/nxp/soc-lx2160a/lx2162aqds/platform.c b/plat/nxp/soc-lx2160a/lx2162aqds/platform.c
new file mode 100644
index 0000000..7622cf0
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2162aqds/platform.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/plat/nxp/soc-lx2160a/lx2162aqds/platform.mk b/plat/nxp/soc-lx2160a/lx2162aqds/platform.mk
new file mode 100644
index 0000000..2b4712c
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2162aqds/platform.mk
@@ -0,0 +1,52 @@
+#
+# Copyright 2018-2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+
+BOOT_MODE ?= flexspi_nor
+BOARD ?= lx2162aqds
+POVDD_ENABLE := no
+NXP_COINED_BB := no
+
+ # DDR Compilation Configs
+NUM_OF_DDRC := 1
+DDRC_NUM_DIMM := 1
+DDRC_NUM_CS := 2
+DDR_ECC_EN := yes
+ #enable address decoding feature
+DDR_ADDR_DEC := yes
+APPLY_MAX_CDD := yes
+
+# DDR Errata
+ERRATA_DDR_A011396 := 1
+ERRATA_DDR_A050450 := 1
+
+
+# On-Board Flash Details
+FLASH_TYPE := MT35XU512A
+XSPI_FLASH_SZ := 0x10000000
+NXP_XSPI_NOR_UNIT_SIZE := 0x20000
+BL2_BIN_XSPI_NOR_END_ADDRESS := 0x100000
+# CONFIG_FSPI_ERASE_4K is required to erase 4K sector sizes. This
+# config is enabled for future use cases.
+FSPI_ERASE_4K := 0
+
+# Platform specific features.
+WARM_BOOT := yes
+
+# Adding Platform files build files
+BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\
+ ${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE := flexspi_nor \
+ sd \
+ emmc
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-lx2160a/soc.mk
diff --git a/plat/nxp/soc-lx2160a/lx2162aqds/platform_def.h b/plat/nxp/soc-lx2160a/lx2162aqds/platform_def.h
new file mode 100644
index 0000000..5fa774e
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2162aqds/platform_def.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include "plat_def.h"
+#include "plat_default_def.h"
+
+#endif
diff --git a/plat/nxp/soc-lx2160a/lx2162aqds/policy.h b/plat/nxp/soc-lx2160a/lx2162aqds/policy.h
new file mode 100644
index 0000000..1095f38
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/lx2162aqds/policy.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018-2020 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/* Following defines affect the PLATFORM SECURITY POLICY */
+
+/* set this to 0x0 if the platform is not using/responding to ECC errors
+ * set this to 0x1 if ECC is being used (we have to do some init)
+ */
+#define POLICY_USING_ECC 0x0
+
+/* Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+/*
+ * POLICY_PERF_WRIOP = 0 : No Performance enhancement for WRIOP RN-I
+ * POLICY_PERF_WRIOP = 1 : No Performance enhancement for WRIOP RN-I = 7
+ * POLICY_PERF_WRIOP = 2 : No Performance enhancement for WRIOP RN-I = 23
+ */
+#define POLICY_PERF_WRIOP 0
+
+/*
+ * set this to '1' if the debug clocks need to remain enabled during
+ * system entry to low-power (LPM20) - this should only be necessary
+ * for testing and NEVER set for normal production
+ */
+#define POLICY_DEBUG_ENABLE 0
+
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-lx2160a/soc.c b/plat/nxp/soc-lx2160a/soc.c
new file mode 100644
index 0000000..427189d
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/soc.c
@@ -0,0 +1,542 @@
+/*
+ * Copyright 2018-2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <bl31/interrupt_mgmt.h>
+#include <caam.h>
+#include <cassert.h>
+#include <ccn.h>
+#include <common/debug.h>
+#include <dcfg.h>
+#ifdef I2C_INIT
+#include <i2c.h>
+#endif
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <ls_interconnect.h>
+#ifdef POLICY_FUSE_PROVISION
+#include <nxp_gpio.h>
+#endif
+#include <nxp_smmu.h>
+#include <nxp_timer.h>
+#include <plat_console.h>
+#include <plat_gic.h>
+#include <plat_tzc400.h>
+#include <pmu.h>
+#if defined(NXP_SFP_ENABLED)
+#include <sfp.h>
+#endif
+
+#include <errata.h>
+#include <ls_interrupt_mgmt.h>
+#ifdef CONFIG_OCRAM_ECC_EN
+#include <ocram.h>
+#endif
+#include "plat_common.h"
+#ifdef NXP_NV_SW_MAINT_LAST_EXEC_DATA
+#include <plat_nv_storage.h>
+#endif
+#ifdef NXP_WARM_BOOT
+#include <plat_warm_rst.h>
+#endif
+#include "platform_def.h"
+#include "soc.h"
+
+static struct soc_type soc_list[] = {
+ /* SoC LX2160A */
+ SOC_ENTRY(LX2160A, LX2160A, 8, 2),
+ SOC_ENTRY(LX2160E, LX2160E, 8, 2),
+ SOC_ENTRY(LX2160C, LX2160C, 8, 2),
+ SOC_ENTRY(LX2160N, LX2160N, 8, 2),
+ SOC_ENTRY(LX2080A, LX2080A, 8, 1),
+ SOC_ENTRY(LX2080E, LX2080E, 8, 1),
+ SOC_ENTRY(LX2080C, LX2080C, 8, 1),
+ SOC_ENTRY(LX2080N, LX2080N, 8, 1),
+ SOC_ENTRY(LX2120A, LX2120A, 6, 2),
+ SOC_ENTRY(LX2120E, LX2120E, 6, 2),
+ SOC_ENTRY(LX2120C, LX2120C, 6, 2),
+ SOC_ENTRY(LX2120N, LX2120N, 6, 2),
+ /* SoC LX2162A */
+ SOC_ENTRY(LX2162A, LX2162A, 8, 2),
+ SOC_ENTRY(LX2162E, LX2162E, 8, 2),
+ SOC_ENTRY(LX2162C, LX2162C, 8, 2),
+ SOC_ENTRY(LX2162N, LX2162N, 8, 2),
+ SOC_ENTRY(LX2082A, LX2082A, 8, 1),
+ SOC_ENTRY(LX2082E, LX2082E, 8, 1),
+ SOC_ENTRY(LX2082C, LX2082C, 8, 1),
+ SOC_ENTRY(LX2082N, LX2082N, 8, 1),
+ SOC_ENTRY(LX2122A, LX2122A, 6, 2),
+ SOC_ENTRY(LX2122E, LX2122E, 6, 2),
+ SOC_ENTRY(LX2122C, LX2122C, 6, 2),
+ SOC_ENTRY(LX2122N, LX2122N, 6, 2),
+};
+
+static dcfg_init_info_t dcfg_init_data = {
+ .g_nxp_dcfg_addr = NXP_DCFG_ADDR,
+ .nxp_sysclk_freq = NXP_SYSCLK_FREQ,
+ .nxp_ddrclk_freq = NXP_DDRCLK_FREQ,
+ .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER,
+ };
+static const unsigned char master_to_6rn_id_map[] = {
+ PLAT_6CLUSTER_TO_CCN_ID_MAP
+};
+
+static const unsigned char master_to_rn_id_map[] = {
+ PLAT_CLUSTER_TO_CCN_ID_MAP
+};
+
+CASSERT(ARRAY_SIZE(master_to_rn_id_map) == NUMBER_OF_CLUSTERS,
+ assert_invalid_cluster_count_for_ccn_variant);
+
+static const ccn_desc_t plat_six_cluster_ccn_desc = {
+ .periphbase = NXP_CCN_ADDR,
+ .num_masters = ARRAY_SIZE(master_to_6rn_id_map),
+ .master_to_rn_id_map = master_to_6rn_id_map
+};
+
+static const ccn_desc_t plat_ccn_desc = {
+ .periphbase = NXP_CCN_ADDR,
+ .num_masters = ARRAY_SIZE(master_to_rn_id_map),
+ .master_to_rn_id_map = master_to_rn_id_map
+};
+
+/******************************************************************************
+ * Function returns the base counter frequency
+ * after reading the first entry at CNTFID0 (0x20 offset).
+ *
+ * Function is used by:
+ * 1. ARM common code for PSCI management.
+ * 2. ARM Generic Timer init.
+ *
+ *****************************************************************************/
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+ /*
+ * Below register specifies the base frequency of the system counter.
+ * As per NXP Board Manuals:
+ * The system counter always works with SYS_REF_CLK/4 frequency clock.
+ *
+ *
+ */
+ counter_base_frequency = mmio_read_32(NXP_TIMER_ADDR + CNTFID_OFF);
+
+ return counter_base_frequency;
+}
+
+#ifdef IMAGE_BL2
+
+#ifdef POLICY_FUSE_PROVISION
+static gpio_init_info_t gpio_init_data = {
+ .gpio1_base_addr = NXP_GPIO1_ADDR,
+ .gpio2_base_addr = NXP_GPIO2_ADDR,
+ .gpio3_base_addr = NXP_GPIO3_ADDR,
+ .gpio4_base_addr = NXP_GPIO4_ADDR,
+};
+#endif
+
+static void soc_interconnect_config(void)
+{
+ unsigned long long val = 0x0U;
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list),
+ &num_clusters, &cores_per_cluster);
+
+ if (num_clusters == 6U) {
+ ccn_init(&plat_six_cluster_ccn_desc);
+ } else {
+ ccn_init(&plat_ccn_desc);
+ }
+
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ */
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ val = ccn_read_node_reg(NODE_TYPE_HNI, 13, PCIeRC_RN_I_NODE_ID_OFFSET);
+ val |= (1 << 17);
+ ccn_write_node_reg(NODE_TYPE_HNI, 13, PCIeRC_RN_I_NODE_ID_OFFSET, val);
+
+ /* PCIe is Connected to RN-I 17 which is connected to HN-I 13. */
+ val = ccn_read_node_reg(NODE_TYPE_HNI, 30, PCIeRC_RN_I_NODE_ID_OFFSET);
+ val |= (1 << 17);
+ ccn_write_node_reg(NODE_TYPE_HNI, 30, PCIeRC_RN_I_NODE_ID_OFFSET, val);
+
+ val = ccn_read_node_reg(NODE_TYPE_HNI, 13, SA_AUX_CTRL_REG_OFFSET);
+ val |= SERIALIZE_DEV_nGnRnE_WRITES;
+ ccn_write_node_reg(NODE_TYPE_HNI, 13, SA_AUX_CTRL_REG_OFFSET, val);
+
+ val = ccn_read_node_reg(NODE_TYPE_HNI, 30, SA_AUX_CTRL_REG_OFFSET);
+ val &= ~(ENABLE_RESERVE_BIT53);
+ val |= SERIALIZE_DEV_nGnRnE_WRITES;
+ ccn_write_node_reg(NODE_TYPE_HNI, 30, SA_AUX_CTRL_REG_OFFSET, val);
+
+ val = ccn_read_node_reg(NODE_TYPE_HNI, 13, PoS_CONTROL_REG_OFFSET);
+ val &= ~(HNI_POS_EN);
+ ccn_write_node_reg(NODE_TYPE_HNI, 13, PoS_CONTROL_REG_OFFSET, val);
+
+ val = ccn_read_node_reg(NODE_TYPE_HNI, 30, PoS_CONTROL_REG_OFFSET);
+ val &= ~(HNI_POS_EN);
+ ccn_write_node_reg(NODE_TYPE_HNI, 30, PoS_CONTROL_REG_OFFSET, val);
+
+ val = ccn_read_node_reg(NODE_TYPE_HNI, 13, SA_AUX_CTRL_REG_OFFSET);
+ val &= ~(POS_EARLY_WR_COMP_EN);
+ ccn_write_node_reg(NODE_TYPE_HNI, 13, SA_AUX_CTRL_REG_OFFSET, val);
+
+ val = ccn_read_node_reg(NODE_TYPE_HNI, 30, SA_AUX_CTRL_REG_OFFSET);
+ val &= ~(POS_EARLY_WR_COMP_EN);
+ ccn_write_node_reg(NODE_TYPE_HNI, 30, SA_AUX_CTRL_REG_OFFSET, val);
+
+#if POLICY_PERF_WRIOP
+ uint16_t wriop_rni = 0U;
+
+ if (POLICY_PERF_WRIOP == 1) {
+ wriop_rni = 7U;
+ } else if (POLICY_PERF_WRIOP == 2) {
+ wriop_rni = 23U;
+ } else {
+ ERROR("Incorrect WRIOP selected.\n");
+ panic();
+ }
+
+ val = ccn_read_node_reg(NODE_TYPE_RNI, wriop_rni,
+ SA_AUX_CTRL_REG_OFFSET);
+ val |= ENABLE_WUO;
+ ccn_write_node_reg(NODE_TYPE_HNI, wriop_rni, SA_AUX_CTRL_REG_OFFSET,
+ val);
+#else
+ val = ccn_read_node_reg(NODE_TYPE_RNI, 17, SA_AUX_CTRL_REG_OFFSET);
+ val |= ENABLE_WUO;
+ ccn_write_node_reg(NODE_TYPE_RNI, 17, SA_AUX_CTRL_REG_OFFSET, val);
+#endif
+}
+
+
+void soc_preload_setup(void)
+{
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+#if defined(NXP_WARM_BOOT)
+ bool warm_reset = is_warm_boot();
+#endif
+ info_dram_regions->total_dram_size =
+#if defined(NXP_WARM_BOOT)
+ init_ddr(warm_reset);
+#else
+ init_ddr();
+#endif
+}
+
+/*******************************************************************************
+ * This function implements soc specific erratas
+ * This is called before DDR is initialized or MMU is enabled
+ ******************************************************************************/
+void soc_early_init(void)
+{
+#ifdef CONFIG_OCRAM_ECC_EN
+ ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
+#endif
+ dcfg_init(&dcfg_init_data);
+#ifdef POLICY_FUSE_PROVISION
+ gpio_init(&gpio_init_data);
+ sec_init(NXP_CAAM_ADDR);
+#endif
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+
+ enable_timer_base_to_cluster(NXP_PMU_ADDR);
+ soc_interconnect_config();
+
+ enum boot_device dev = get_boot_dev();
+ /* Mark the buffer for SD in OCRAM as non secure.
+ * The buffer is assumed to be at end of OCRAM for
+ * the logic below to calculate TZPC programming
+ */
+ if (dev == BOOT_DEVICE_EMMC || dev == BOOT_DEVICE_SDHC2_EMMC) {
+ /* Calculate the region in OCRAM which is secure
+ * The buffer for SD needs to be marked non-secure
+ * to allow SD to do DMA operations on it
+ */
+ uint32_t secure_region = (NXP_OCRAM_SIZE
+ - NXP_SD_BLOCK_BUF_SIZE);
+ uint32_t mask = secure_region/TZPC_BLOCK_SIZE;
+
+ mmio_write_32(NXP_OCRAM_TZPC_ADDR, mask);
+
+ /* Add the entry for buffer in MMU Table */
+ mmap_add_region(NXP_SD_BLOCK_BUF_ADDR, NXP_SD_BLOCK_BUF_ADDR,
+ NXP_SD_BLOCK_BUF_SIZE,
+ MT_DEVICE | MT_RW | MT_NS);
+ }
+
+ soc_errata();
+
+#if (TRUSTED_BOARD_BOOT) || defined(POLICY_FUSE_PROVISION)
+ sfp_init(NXP_SFP_ADDR);
+#endif
+
+ /*
+ * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts.
+ */
+ smmu_cache_unlock(NXP_SMMU_ADDR);
+ INFO("SMMU Cache Unlocking is Configured.\n");
+
+#if TRUSTED_BOARD_BOOT
+ uint32_t mode;
+
+ /* For secure boot disable SMMU.
+ * Later when platform security policy comes in picture,
+ * this might get modified based on the policy
+ */
+ if (check_boot_mode_secure(&mode) == true) {
+ bypass_smmu(NXP_SMMU_ADDR);
+ }
+
+ /* For Mbedtls currently crypto is not supported via CAAM
+ * enable it when that support is there. In tbbr.mk
+ * the CAAM_INTEG is set as 0.
+ */
+
+#ifndef MBEDTLS_X509
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false)
+ INFO("SEC is disabled.\n");
+ else
+ sec_init(NXP_CAAM_ADDR);
+#endif
+#endif
+
+ /*
+ * Initialize system level generic timer for Layerscape Socs.
+ */
+ delay_timer_init(NXP_TIMER_ADDR);
+ i2c_init(NXP_I2C_ADDR);
+}
+
+void soc_bl2_prepare_exit(void)
+{
+#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE)
+ set_sfp_wr_disable();
+#endif
+}
+
+/*****************************************************************************
+ * This function returns the boot device based on RCW_SRC
+ ****************************************************************************/
+enum boot_device get_boot_dev(void)
+{
+ enum boot_device src = BOOT_DEVICE_NONE;
+ uint32_t porsr1;
+ uint32_t rcw_src;
+
+ porsr1 = read_reg_porsr1();
+
+ rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT;
+
+ switch (rcw_src) {
+ case FLEXSPI_NOR:
+ src = BOOT_DEVICE_FLEXSPI_NOR;
+ INFO("RCW BOOT SRC is FLEXSPI NOR\n");
+ break;
+ case FLEXSPI_NAND2K_VAL:
+ case FLEXSPI_NAND4K_VAL:
+ INFO("RCW BOOT SRC is FLEXSPI NAND\n");
+ src = BOOT_DEVICE_FLEXSPI_NAND;
+ break;
+ case SDHC1_VAL:
+ src = BOOT_DEVICE_EMMC;
+ INFO("RCW BOOT SRC is SD\n");
+ break;
+ case SDHC2_VAL:
+ src = BOOT_DEVICE_SDHC2_EMMC;
+ INFO("RCW BOOT SRC is EMMC\n");
+ break;
+ default:
+ break;
+ }
+
+ return src;
+}
+
+
+void soc_mem_access(void)
+{
+ const devdisr5_info_t *devdisr5_info = get_devdisr5_info();
+ dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+ struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION];
+ int dram_idx, index = 0U;
+
+ for (dram_idx = 0U; dram_idx < info_dram_regions->num_dram_regions;
+ dram_idx++) {
+ if (info_dram_regions->region[dram_idx].size == 0) {
+ ERROR("DDR init failure, or");
+ ERROR("DRAM regions not populated correctly.\n");
+ break;
+ }
+
+ index = populate_tzc400_reg_list(tzc400_reg_list,
+ dram_idx, index,
+ info_dram_regions->region[dram_idx].addr,
+ info_dram_regions->region[dram_idx].size,
+ NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE);
+ }
+
+ if (devdisr5_info->ddrc1_present != 0) {
+ INFO("DDR Controller 1.\n");
+ mem_access_setup(NXP_TZC_ADDR, index,
+ tzc400_reg_list);
+ mem_access_setup(NXP_TZC3_ADDR, index,
+ tzc400_reg_list);
+ }
+ if (devdisr5_info->ddrc2_present != 0) {
+ INFO("DDR Controller 2.\n");
+ mem_access_setup(NXP_TZC2_ADDR, index,
+ tzc400_reg_list);
+ mem_access_setup(NXP_TZC4_ADDR, index,
+ tzc400_reg_list);
+ }
+}
+
+#else
+const unsigned char _power_domain_tree_desc[] = {1, 8, 2, 2, 2, 2, 2, 2, 2, 2};
+
+CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256,
+ assert_invalid_lx2160a_cluster_count);
+
+/******************************************************************************
+ * This function returns the SoC topology
+ ****************************************************************************/
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+
+ return _power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
+{
+ return CORES_PER_CLUSTER;
+}
+
+
+void soc_early_platform_setup2(void)
+{
+ dcfg_init(&dcfg_init_data);
+ /*
+ * Initialize system level generic timer for Socs
+ */
+ delay_timer_init(NXP_TIMER_ADDR);
+
+#if LOG_LEVEL > 0
+ /* Initialize the console to provide early debug support */
+ plat_console_init(NXP_CONSOLE_ADDR,
+ NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+}
+
+void soc_platform_setup(void)
+{
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ static uintptr_t target_mask_array[PLATFORM_CORE_COUNT];
+ static interrupt_prop_t ls_interrupt_props[] = {
+ PLAT_LS_G1S_IRQ_PROPS(INTR_GROUP1S),
+ PLAT_LS_G0_IRQ_PROPS(INTR_GROUP0)
+ };
+
+ plat_ls_gic_driver_init(NXP_GICD_ADDR, NXP_GICR_ADDR,
+ PLATFORM_CORE_COUNT,
+ ls_interrupt_props,
+ ARRAY_SIZE(ls_interrupt_props),
+ target_mask_array,
+ plat_core_pos);
+
+ plat_ls_gic_init();
+ enable_init_timer();
+#ifdef LS_SYS_TIMCTL_BASE
+ ls_configure_sys_timer(LS_SYS_TIMCTL_BASE,
+ LS_CONFIG_CNTACR,
+ PLAT_LS_NSTIMER_FRAME_ID);
+#endif
+}
+
+/*******************************************************************************
+ * This function initializes the soc from the BL31 module
+ ******************************************************************************/
+void soc_init(void)
+{
+ uint8_t num_clusters, cores_per_cluster;
+
+ get_cluster_info(soc_list, ARRAY_SIZE(soc_list),
+ &num_clusters, &cores_per_cluster);
+
+ /* low-level init of the soc */
+ soc_init_start();
+ _init_global_data();
+ soc_init_percpu();
+ _initialize_psci();
+
+ if (ccn_get_part0_id(NXP_CCN_ADDR) != CCN_508_PART0_ID) {
+ ERROR("Unrecognized CCN variant detected.");
+ ERROR("Only CCN-508 is supported\n");
+ panic();
+ }
+
+ if (num_clusters == 6U) {
+ ccn_init(&plat_six_cluster_ccn_desc);
+ } else {
+ ccn_init(&plat_ccn_desc);
+ }
+
+ plat_ls_interconnect_enter_coherency(num_clusters);
+
+ /* Set platform security policies */
+ _set_platform_security();
+
+ /* make sure any parallel init tasks are finished */
+ soc_init_finish();
+
+ /* Initialize the crypto accelerator if enabled */
+ if (is_sec_enabled() == false) {
+ INFO("SEC is disabled.\n");
+ } else {
+ sec_init(NXP_CAAM_ADDR);
+ }
+
+}
+
+#ifdef NXP_WDOG_RESTART
+static uint64_t wdog_interrupt_handler(uint32_t id, uint32_t flags,
+ void *handle, void *cookie)
+{
+ uint8_t data = WDOG_RESET_FLAG;
+
+ wr_nv_app_data(WDT_RESET_FLAG_OFFSET,
+ (uint8_t *)&data, sizeof(data));
+
+ mmio_write_32(NXP_RST_ADDR + RSTCNTL_OFFSET, SW_RST_REQ_INIT);
+
+ return 0;
+}
+#endif
+
+void soc_runtime_setup(void)
+{
+
+#ifdef NXP_WDOG_RESTART
+ request_intr_type_el3(BL31_NS_WDOG_WS1, wdog_interrupt_handler);
+#endif
+}
+#endif
diff --git a/plat/nxp/soc-lx2160a/soc.def b/plat/nxp/soc-lx2160a/soc.def
new file mode 100644
index 0000000..0442962
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/soc.def
@@ -0,0 +1,119 @@
+#
+# Copyright (c) 2015, 2016 Freescale Semiconductor, Inc.
+# Copyright 2017-2022 NXP Semiconductors
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# This file contains the basic architecture definitions that drive the build
+#
+# -----------------------------------------------------------------------------
+
+CORE_TYPE := a72
+
+CACHE_LINE := 6
+
+# set to GIC400 or GIC500
+GIC := GIC500
+
+# set to CCI400 or CCN504 or CCN508
+INTERCONNECT := CCN508
+
+# indicate layerscape chassis level - set to 3=LSCH3 or 2=LSCH2
+CHASSIS := 3_2
+
+# TZC IP Details TZC used is TZC380 or TZC400
+TZC_ID := TZC400
+
+# CONSOLE Details available is NS16550 or PL011
+CONSOLE := PL011
+
+# Select the DDR PHY generation to be used
+PLAT_DDR_PHY := PHY_GEN2
+
+PHYS_SYS := 64
+
+# Area of OCRAM reserved by ROM code
+NXP_ROM_RSVD := 0xa000
+
+# Max Size of CSF header. Required to define BL2 TEXT LIMIT in soc.def
+# Input to CST create_hdr_esbc tool
+CSF_HDR_SZ := 0x3000
+
+NXP_SFP_VER := 3_4
+
+# In IMAGE_BL2, compile time flag for handling Cache coherency
+# with CAAM for BL2 running from OCRAM
+SEC_MEM_NON_COHERENT := yes
+
+# Defining the endianness for NXP ESDHC
+NXP_ESDHC_ENDIANNESS := LE
+
+# Defining the endianness for NXP SFP
+NXP_SFP_ENDIANNESS := LE
+
+# Defining the endianness for NXP GPIO
+NXP_GPIO_ENDIANNESS := LE
+
+# Defining the endianness for NXP SNVS
+NXP_SNVS_ENDIANNESS := LE
+
+# Defining the endianness for NXP CCSR GUR register
+NXP_GUR_ENDIANNESS := LE
+
+# Defining the endianness for NXP FSPI register
+NXP_FSPI_ENDIANNESS := LE
+
+# Defining the endianness for NXP SEC
+NXP_SEC_ENDIANNESS := LE
+
+# Defining the endianness for NXP DDR
+NXP_DDR_ENDIANNESS := LE
+
+NXP_DDR_INTLV_256B := 1
+
+# OCRAM MAP for BL2
+# Before BL2
+# 0x18000000 - 0x18009fff -> Used by ROM code
+# 0x1800a000 - 0x1800dfff -> CSF header for BL2
+# (The above area i.e 0x18000000 - 0x1800dfff is available
+# for DDR PHY images scratch pad region during BL2 run time)
+# For FlexSPI boot
+# 0x1800e000 - 0x18040000 -> Reserved for BL2 binary
+# For SD boot
+# 0x1800e000 - 0x18030000 -> Reserved for BL2 binary
+# 0x18030000 - 0x18040000 -> Reserved for SD buffer
+OCRAM_START_ADDR := 0x18000000
+OCRAM_SIZE := 0x40000
+
+# Location of BL2 on OCRAM
+BL2_BASE_ADDR := $(shell echo $$(( $(OCRAM_START_ADDR) + $(NXP_ROM_RSVD) + $(CSF_HDR_SZ) )))
+# Covert to HEX to be used by create_pbl.mk
+BL2_BASE := $(shell echo "0x"$$(echo "obase=16; ${BL2_BASE_ADDR}" | bc))
+
+# BL2_HDR_LOC is at (OCRAM_ADDR + NXP_ROM_RSVD)
+# This value BL2_HDR_LOC + CSF_HDR_SZ should not overalp with BL2_BASE
+BL2_HDR_LOC_HDR ?= $(shell echo $$(( $(OCRAM_START_ADDR) + $(NXP_ROM_RSVD) )))
+# Covert to HEX to be used by create_pbl.mk
+BL2_HDR_LOC := $$(echo "obase=16; ${BL2_HDR_LOC_HDR}" | bc)
+
+# SoC ERRATAS to be enabled
+#
+# Core Errata
+ERRATA_A72_859971 := 1
+
+# SoC Errata
+ERRATA_SOC_A050426 := 1
+
+# DDR Errata
+ERRATA_DDR_A011396 := 1
+ERRATA_DDR_A050450 := 1
+ERRATA_DDR_A050958 := 1
+
+# enable dynamic memory mapping
+PLAT_XLAT_TABLES_DYNAMIC := 1
+
+# OCRAM ECC Enabled
+OCRAM_ECC_EN := yes
diff --git a/plat/nxp/soc-lx2160a/soc.mk b/plat/nxp/soc-lx2160a/soc.mk
new file mode 100644
index 0000000..239442c
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/soc.mk
@@ -0,0 +1,174 @@
+#
+# Copyright 2018-2020 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+ # SoC-specific build parameters
+SOC := lx2160a
+PLAT_PATH := plat/nxp
+PLAT_COMMON_PATH:= plat/nxp/common
+PLAT_DRIVERS_PATH:= drivers/nxp
+PLAT_SOC_PATH := ${PLAT_PATH}/soc-${SOC}
+BOARD_PATH := ${PLAT_SOC_PATH}/${BOARD}
+
+ # get SoC-specific defnitions
+include ${PLAT_SOC_PATH}/soc.def
+include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+ # SoC-specific
+NXP_WDOG_RESTART := yes
+
+
+ # Selecting dependent module,
+ # Selecting dependent drivers, and
+ # Adding defines.
+
+ # for features enabled above.
+ifeq (${NXP_WDOG_RESTART}, yes)
+NXP_NV_SW_MAINT_LAST_EXEC_DATA := yes
+LS_EL3_INTERRUPT_HANDLER := yes
+$(eval $(call add_define, NXP_WDOG_RESTART))
+endif
+
+
+ # For Security Features
+DISABLE_FUSE_WRITE := 1
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+ifeq (${GENERATE_COT},1)
+# Save Keys to be used by DDR FIP image
+SAVE_KEYS=1
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
+# Used by create_pbl tool to
+# create bl2_<boot_mode>_sec.pbl image
+SECURE_BOOT := yes
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM))
+
+
+ # Selecting Drivers for SoC
+$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM))
+
+$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+
+
+ # Selecting PSCI & SIP_SVC support
+$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31))
+
+
+ # Selecting Boot Source for the TFA images.
+ifeq (${BOOT_MODE}, flexspi_nor)
+$(eval $(call SET_NXP_MAKE_FLAG,XSPI_NEEDED,BL2))
+$(eval $(call add_define,FLEXSPI_NOR_BOOT))
+else
+ifeq (${BOOT_MODE}, sd)
+$(eval $(call SET_NXP_MAKE_FLAG,SD_MMC_NEEDED,BL2))
+$(eval $(call add_define,SD_BOOT))
+else
+ifeq (${BOOT_MODE}, emmc)
+$(eval $(call SET_NXP_MAKE_FLAG,SD_MMC_NEEDED,BL2))
+$(eval $(call add_define,EMMC_BOOT))
+else
+$(error Un-supported Boot Mode = ${BOOT_MODE})
+endif
+endif
+endif
+
+
+ # Separate DDR-FIP image to be loaded.
+$(eval $(call SET_NXP_MAKE_FLAG,DDR_FIP_IO_NEEDED,BL2))
+
+
+# Source File Addition
+# #####################
+
+PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\
+ -I${BOARD_PATH}\
+ -I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
+ -I${PLAT_SOC_PATH}/include\
+ -I${PLAT_COMMON_PATH}/soc_errata
+
+ifeq (${SECURE_BOOT},yes)
+include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
+endif
+
+ifeq ($(WARM_BOOT),yes)
+include ${PLAT_COMMON_PATH}/warm_reset/warm_reset.mk
+endif
+
+ifeq (${NXP_NV_SW_MAINT_LAST_EXEC_DATA}, yes)
+include ${PLAT_COMMON_PATH}/nv_storage/nv_storage.mk
+endif
+
+ifeq (${PSCI_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/psci/psci.mk
+endif
+
+ifeq (${SIPSVC_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk
+endif
+
+ifeq (${DDR_FIP_IO_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/fip_handler/ddr_fip/ddr_fip_io.mk
+endif
+
+ # for fuse-fip & fuse-programming
+ifeq (${FUSE_PROG}, 1)
+include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk
+endif
+
+ifeq (${IMG_LOADR_NEEDED},yes)
+include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk
+endif
+
+ # Adding source files for the above selected drivers.
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+ # Adding SoC specific files
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
+
+PLAT_INCLUDES += ${NV_STORAGE_INCLUDES}\
+ ${WARM_RST_INCLUDES}
+
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\
+ ${WARM_RST_BL31_SOURCES}\
+ ${PSCI_SOURCES}\
+ ${SIPSVC_SOURCES}\
+ ${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S
+
+PLAT_BL_COMMON_SOURCES += ${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\
+ ${PLAT_SOC_PATH}/aarch64/${SOC}_helpers.S\
+ ${NV_STORAGE_SOURCES}\
+ ${WARM_RST_BL_COMM_SOURCES}\
+ ${PLAT_SOC_PATH}/soc.c
+
+ifeq (${TEST_BL31}, 1)
+BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S\
+ ${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S
+endif
+
+BL2_SOURCES += ${DDR_CNTLR_SOURCES}\
+ ${TBBR_SOURCES}\
+ ${FUSE_SOURCES}
+
+
+ # Adding TFA setup files
+include ${PLAT_PATH}/common/setup/common.mk
+
+
+ # Adding source files to generate separate DDR FIP image
+include ${PLAT_SOC_PATH}/ddr_fip.mk