nxp: adding support of soc lx2160a

* NXP SoC is 16 A-72 core SoC.
* SoC specific defines are defined in:
  - soc.def
  - soc.h
* Called for BL2 and BL31 setup, SoC specific setup are implemented in:
  - soc.c
* platform specific helper functions implemented at:
  - aarch64/lx2160a_helpers.S
* platform specific functions used by 'plat/nxp/commpon/psci',
  etc. are implemented at:
  - aarch64/lx2160a.S
* platform specific implementation for handling PSCI_SYSTEM_RESET2:
  - aarch64/lx2160a_warm_rst.S

Signed-off-by: rocket <rod.dorris@nxp.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
Change-Id: Ib40086f9d9079ed9b22967baff518c6df9f408b8
diff --git a/plat/nxp/soc-lx2160a/aarch64/lx2160a.S b/plat/nxp/soc-lx2160a/aarch64/lx2160a.S
new file mode 100644
index 0000000..4679fc2
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/aarch64/lx2160a.S
@@ -0,0 +1,1824 @@
+/*
+ * 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
+
+	/* 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]
+
+	/* 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/include/soc.h b/plat/nxp/soc-lx2160a/include/soc.h
new file mode 100644
index 0000000..bd23620
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/include/soc.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2018-2020 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 */
+
+/* bits */
+/* SVR Definition */
+#define SVR_LX2160A		0x04
+#define SVR_LX2120A		0x14
+#define SVR_LX2080A		0x05
+
+/* 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/soc.c b/plat/nxp/soc-lx2160a/soc.c
new file mode 100644
index 0000000..e0a2fe9
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/soc.c
@@ -0,0 +1,528 @@
+/*
+ * 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
+#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>
+#if defined(NXP_SFP_ENABLED)
+#include <sfp.h>
+#endif
+
+#include <errata.h>
+#include <ls_interrupt_mgmt.h>
+#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_ENTRY(LX2160A, LX2160A, 8, 2),
+	SOC_ENTRY(LX2080A, LX2080A, 8, 1),
+	SOC_ENTRY(LX2120A, LX2120A, 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
+};
+
+/*******************************************************************************
+ * This function returns the number of clusters in the SoC
+ ******************************************************************************/
+static unsigned int get_num_cluster(void)
+{
+	const soc_info_t *soc_info = get_soc_info();
+	uint32_t num_clusters = NUMBER_OF_CLUSTERS;
+	unsigned int i;
+
+	for (i = 0U; i < ARRAY_SIZE(soc_list); i++) {
+		if (soc_list[i].personality == soc_info->personality) {
+			num_clusters = soc_list[i].num_clusters;
+			break;
+		}
+	}
+
+	VERBOSE("NUM of cluster = 0x%x\n", num_clusters);
+
+	return num_clusters;
+}
+
+
+/******************************************************************************
+ * 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;
+
+	uint32_t num_clusters = get_num_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)
+{
+	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);
+	}
+
+#ifdef ERRATA_SOC_A050426
+	erratum_a050426();
+#endif
+
+#if (TRUSTED_BOARD_BOOT) || defined(POLICY_FUSE_PROVISION)
+	sfp_init(NXP_SFP_ADDR);
+#endif
+
+#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)
+{
+	 /* low-level init of the soc */
+	soc_init_start();
+	soc_init_percpu();
+	_init_global_data();
+	_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();
+	}
+
+	uint32_t num_clusters = get_num_cluster();
+
+	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..bd0dd15
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/soc.def
@@ -0,0 +1,201 @@
+#
+# Copyright (c) 2015, 2016 Freescale Semiconductor, Inc.
+# Copyright 2017-2020 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	:=	$$(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
+
+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_CCN508))
+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_ADDR},)
+$(eval $(call add_define_val,BL2_BASE,${BL2_BASE_ADDR}))
+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
+
+# enable dynamic memory mapping
+PLAT_XLAT_TABLES_DYNAMIC :=	1
+
+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_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
diff --git a/plat/nxp/soc-lx2160a/soc.mk b/plat/nxp/soc-lx2160a/soc.mk
new file mode 100644
index 0000000..b9649b4
--- /dev/null
+++ b/plat/nxp/soc-lx2160a/soc.mk
@@ -0,0 +1,173 @@
+#
+# 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/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
+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,SMMU_NEEDED,BL2))
+$(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
+
+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_SOC_PATH}/erratas_soc.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