Merge pull request #1356 from robertovargas-arm/misra-changes

Misra changes
diff --git a/Makefile b/Makefile
index ef4e5c6..a837846 100644
--- a/Makefile
+++ b/Makefile
@@ -373,6 +373,11 @@
     endif
 endif
 
+#For now, BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is 1.
+ifeq ($(BL2_AT_EL3)-$(BL2_IN_XIP_MEM),0-1)
+$(error "BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is enabled")
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -518,6 +523,7 @@
 $(eval $(call assert_boolean,USE_TBBR_DEFS))
 $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
 $(eval $(call assert_boolean,BL2_AT_EL3))
+$(eval $(call assert_boolean,BL2_IN_XIP_MEM))
 
 $(eval $(call assert_numeric,ARM_ARCH_MAJOR))
 $(eval $(call assert_numeric,ARM_ARCH_MINOR))
@@ -564,6 +570,7 @@
 $(eval $(call add_define,USE_TBBR_DEFS))
 $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
 $(eval $(call add_define,BL2_AT_EL3))
+$(eval $(call add_define,BL2_IN_XIP_MEM))
 
 # Define the EL3_PAYLOAD_BASE flag only if it is provided.
 ifdef EL3_PAYLOAD_BASE
diff --git a/acknowledgements.rst b/acknowledgements.rst
index 59f569e..9b81b6c 100644
--- a/acknowledgements.rst
+++ b/acknowledgements.rst
@@ -12,5 +12,7 @@
 
 Xilinx, Inc.
 
+NXP Semiconductors
+
 Individuals
 -----------
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 3728643..0f91edc 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -12,15 +12,26 @@
 ENTRY(bl2_entrypoint)
 
 MEMORY {
+#if BL2_IN_XIP_MEM
+    ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
+    RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
+#else
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+#endif
 }
 
 
 SECTIONS
 {
+#if BL2_IN_XIP_MEM
+    . = BL2_RO_BASE;
+    ASSERT(. == ALIGN(PAGE_SIZE),
+           "BL2_RO_BASE address is not aligned on a page boundary.")
+#else
     . = BL2_BASE;
     ASSERT(. == ALIGN(PAGE_SIZE),
            "BL2_BASE address is not aligned on a page boundary.")
+#endif
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
@@ -33,7 +44,11 @@
         *(.vectors)
         . = NEXT(PAGE_SIZE);
         __TEXT_END__ = .;
+#if BL2_IN_XIP_MEM
+     } >ROM
+#else
      } >RAM
+#endif
 
     .rodata . : {
         __RODATA_START__ = .;
@@ -56,7 +71,11 @@
 
         . = NEXT(PAGE_SIZE);
         __RODATA_END__ = .;
+#if BL2_IN_XIP_MEM
+    } >ROM
+#else
     } >RAM
+#endif
 
     ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
           "Resident part of BL2 has exceeded its limit.")
@@ -95,12 +114,22 @@
         . = NEXT(PAGE_SIZE);
 
         __RO_END__ = .;
+#if BL2_IN_XIP_MEM
+    } >ROM
+#else
     } >RAM
 #endif
+#endif
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
           "cpu_ops not defined for this platform.")
 
+#if BL2_IN_XIP_MEM
+    . = BL2_RW_BASE;
+    ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
+           "BL2_RW_BASE address is not aligned on a page boundary.")
+#endif
+
     /*
      * Define a linker symbol to mark start of the RW memory area for this
      * image.
@@ -113,10 +142,14 @@
      * section can be placed independently of the main .data section.
      */
     .data . : {
-        __DATA_START__ = .;
+        __DATA_RAM_START__ = .;
         *(.data*)
-        __DATA_END__ = .;
+        __DATA_RAM_END__ = .;
+#if BL2_IN_XIP_MEM
+    } >RAM AT>ROM
+#else
     } >RAM
+#endif
 
     stacks (NOLOAD) : {
         __STACKS_START__ = .;
@@ -174,12 +207,32 @@
     __RW_END__ = .;
     __BL2_END__ = .;
 
+#if BL2_IN_XIP_MEM
+    __BL2_RAM_START__ = ADDR(.data);
+    __BL2_RAM_END__ = .;
+
+    __DATA_ROM_START__ = LOADADDR(.data);
+    __DATA_SIZE__ = SIZEOF(.data);
+
+    /*
+     * The .data section is the last PROGBITS section so its end marks the end
+     * of BL2's RO content in XIP memory..
+     */
+    __BL2_ROM_END__ =  __DATA_ROM_START__ + __DATA_SIZE__;
+    ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
+           "BL2's RO content has exceeded its limit.")
+#endif
     __BSS_SIZE__ = SIZEOF(.bss);
 
+
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
 #endif
 
+#if BL2_IN_XIP_MEM
+    ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
+#else
     ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
+#endif
 }
diff --git a/bl2/bl2_private.h b/bl2/bl2_private.h
index 50295d6..f93a179 100644
--- a/bl2/bl2_private.h
+++ b/bl2/bl2_private.h
@@ -7,6 +7,20 @@
 #ifndef __BL2_PRIVATE_H__
 #define __BL2_PRIVATE_H__
 
+#if BL2_IN_XIP_MEM
+/*******************************************************************************
+ * Declarations of linker defined symbols which will tell us where BL2 lives
+ * in Trusted ROM and RAM
+ ******************************************************************************/
+extern uintptr_t __BL2_ROM_END__;
+#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__)
+
+extern uintptr_t __BL2_RAM_START__;
+extern uintptr_t __BL2_RAM_END__;
+#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__)
+#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__)
+#endif
+
 /******************************************
  * Forward declarations
  *****************************************/
diff --git a/docs/cpu-specific-build-macros.rst b/docs/cpu-specific-build-macros.rst
index 9e11cdf..65f6adb 100644
--- a/docs/cpu-specific-build-macros.rst
+++ b/docs/cpu-specific-build-macros.rst
@@ -18,7 +18,11 @@
 vulnerability workarounds should be applied at runtime.
 
 -  ``WORKAROUND_CVE_2017_5715``: Enables the security workaround for
-   `CVE-2017-5715`_. Defaults to 1.
+   `CVE-2017-5715`_. This flag can be set to 0 by the platform if none
+   of the PEs in the system need the workaround. Setting this flag to 0 provides
+   no performance benefit for non-affected platforms, it just helps to comply
+   with the recommendation in the spec regarding workaround discovery.
+   Defaults to 1.
 
 CPU Errata Workarounds
 ----------------------
diff --git a/docs/plat/ls1043a.rst b/docs/plat/ls1043a.rst
new file mode 100644
index 0000000..0d604aa
--- /dev/null
+++ b/docs/plat/ls1043a.rst
@@ -0,0 +1,91 @@
+Description
+===========
+
+The QorIQ® LS1043A processor is NXP's first quad-core, 64-bit Arm®-based
+processor for embedded networking. The LS1023A (two core version) and the
+LS1043A (four core version) deliver greater than 10 Gbps of performance
+in a flexible I/O package supporting fanless designs. This SoC is a
+purpose-built solution for small-form-factor networking and industrial
+applications with BOM optimizations for economic low layer PCB, lower cost
+power supply and single clock design. The new 0.9V versions of the LS1043A
+and LS1023A deliver addition power savings for applications such as Wireless
+LAN and to Power over Ethernet systems.
+
+LS1043ARDB Specification:
+-------------------------
+Memory subsystem:
+	* 2GByte DDR4 SDRAM (32bit bus)
+	* 128 Mbyte NOR flash single-chip memory
+	* 512 Mbyte NAND flash
+	* 16 Mbyte high-speed SPI flash
+	* SD connector to interface with the SD memory card
+
+Ethernet:
+	* XFI 10G port
+	* QSGMII with 4x 1G ports
+	* Two RGMII ports
+
+PCIe:
+	* PCIe2 (Lanes C) to mini-PCIe slot
+	* PCIe3 (Lanes D) to PCIe slot
+
+USB 3.0: two super speed USB 3.0 type A ports
+
+UART: supports two UARTs up to 115200 bps for console
+
+More information are listed in `ls1043`_.
+
+Boot Sequence
+=============
+
+
+Bootrom --> TF-A BL1 --> TF-A BL2 --> TF-A BL1 --> TF-A BL31
+--> BL32(Tee OS) --> TF-A BL31 --> BL33(u-boot) --> Linux kernel
+
+
+How to build
+============
+
+Build Procedure
+---------------
+
+-  Prepare AARCH64 toolchain.
+
+-  Build u-boot and OPTee firstly, and get binary images: u-boot.bin and tee.bin
+
+-  Build TF-A for Nor boot
+
+   Build bl1:
+
+   .. code:: shell
+
+       CROSS_COMPILE=aarch64-linux-gnu- make PLAT=ls1043 bl1
+
+   Build fip:
+
+   .. code:: shell
+
+       CROSS_COMPILE=aarch64-linux-gnu- make PLAT=ls1043 fip \
+       BL33=u-boot.bin NEED_BL32=yes BL32=tee.bin SPD=opteed
+
+Deploy TF-A Images
+-----------------
+
+-  Deploy TF-A images on Nor flash Alt Bank.
+
+   .. code:: shell
+
+       => tftp 82000000  bl1.bin
+       => pro off all;era 64100000 +$filesize;cp.b 82000000 64100000 $filesize
+
+       => tftp 82000000  fip.bin
+       => pro off all;era 64120000 +$filesize;cp.b 82000000 64120000 $filesize
+
+   Then change to Alt bank and boot up TF-A:
+
+   .. code:: shell
+
+       => cpld reset altbank
+
+
+.. _ls1043: https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/qoriq-layerscape-arm-processors/qoriq-layerscape-1043a-and-1023a-multicore-communications-processors:LS1043A?lang_cd=en
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index ff5bb12..12e135f 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -217,11 +217,37 @@
 -  **#define : BL2\_BASE**
 
    Defines the base address in secure RAM where BL1 loads the BL2 binary image.
-   Must be aligned on a page-size boundary.
+   Must be aligned on a page-size boundary. This constant is not applicable
+   when BL2_IN_XIP_MEM is set to '1'.
 
 -  **#define : BL2\_LIMIT**
 
    Defines the maximum address in secure RAM that the BL2 image can occupy.
+   This constant is not applicable when BL2_IN_XIP_MEM is set to '1'.
+
+-  **#define : BL2\_RO\_BASE**
+
+   Defines the base address in secure XIP memory where BL2 RO section originally
+   lives. Must be aligned on a page-size boundary. This constant is only needed
+   when BL2_IN_XIP_MEM is set to '1'.
+
+-  **#define : BL2\_RO\_LIMIT**
+
+   Defines the maximum address in secure XIP memory that BL2's actual content
+   (i.e. excluding any data section allocated at runtime) can occupy. This
+   constant is only needed when BL2_IN_XIP_MEM is set to '1'.
+
+-  **#define : BL2\_RW\_BASE**
+
+   Defines the base address in secure RAM where BL2's read-write data will live
+   at runtime. Must be aligned on a page-size boundary. This constant is only
+   needed when BL2_IN_XIP_MEM is set to '1'.
+
+-  **#define : BL2\_RW\_LIMIT**
+
+   Defines the maximum address in secure RAM that BL2's read-write data can
+   occupy at runtime. This constant is only needed when BL2_IN_XIP_MEM is set
+   to '1'.
 
 -  **#define : BL31\_BASE**
 
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 5794855..f8bc4be 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -246,6 +246,12 @@
 - ``BL2_AT_EL3``: This is an optional build option that enables the use of
    BL2 at EL3 execution level.
 
+- ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
+   (XIP) memory, like BL1. In these use-cases, it is necessary to initialize
+   the RW sections in RAM, while leaving the RO sections in place. This option
+   enable this use-case. For now, this option is only supported when BL2_AT_EL3
+   is set to '1'.
+
 -  ``BL31``: This is an optional build option which specifies the path to
    BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
    be built.
@@ -783,6 +789,12 @@
    HW_CONFIG blob instead of the DTS file. This option is useful to override
    the default HW_CONFIG selected by the build system.
 
+ARM JUNO platform specific build options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+-  ``JUNO_TZMP1`` : Boolean option to configure Juno to be used for TrustZone
+   Media Protection (TZ-MP1). Default value of this flag is 0.
+
 Debugging options
 ~~~~~~~~~~~~~~~~~
 
diff --git a/drivers/arm/tzc/tzc_dmc500.c b/drivers/arm/tzc/tzc_dmc500.c
index 7350b2c..8b618e6 100644
--- a/drivers/arm/tzc/tzc_dmc500.c
+++ b/drivers/arm/tzc/tzc_dmc500.c
@@ -25,6 +25,7 @@
 
 /* Pointer to the tzc_dmc500_driver_data structure populated by the platform */
 static const tzc_dmc500_driver_data_t *g_driver_data;
+static unsigned int g_sys_if_count;
 
 #define verify_region_attr(region, attr)	\
 		((g_conf_regions[(region)].sec_attr ==			\
@@ -88,7 +89,7 @@
 
 	for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
 		assert(DMC_INST_BASE_ADDR(dmc_inst));
-		for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++)
+		for (sys_if = 0; sys_if < g_sys_if_count; sys_if++)
 			_tzc_dmc500_write_flush_control(
 					DMC_INST_SI_BASE(dmc_inst, sys_if));
 	}
@@ -119,7 +120,7 @@
 		for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count;
 								dmc_inst++) {
 			assert(DMC_INST_BASE_ADDR(dmc_inst));
-			for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT;
+			for (sys_if = 0; sys_if < g_sys_if_count;
 							sys_if++) {
 				attr = _tzc_dmc500_read_region_attr_0(
 					DMC_INST_SI_BASE(dmc_inst, sys_if),
@@ -154,7 +155,7 @@
 	/* Configure region_0 in all DMC instances */
 	for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
 		assert(DMC_INST_BASE_ADDR(dmc_inst));
-		for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++)
+		for (sys_if = 0; sys_if < g_sys_if_count; sys_if++)
 			_tzc_dmc500_configure_region0(
 					DMC_INST_SI_BASE(dmc_inst, sys_if),
 					sec_attr, nsaid_permissions);
@@ -195,7 +196,7 @@
 
 	for (dmc_inst = 0; dmc_inst < g_driver_data->dmc_count; dmc_inst++) {
 		assert(DMC_INST_BASE_ADDR(dmc_inst));
-		for (sys_if = 0; sys_if < MAX_SYS_IF_COUNT; sys_if++)
+		for (sys_if = 0; sys_if < g_sys_if_count; sys_if++)
 			_tzc_dmc500_configure_region(
 					DMC_INST_SI_BASE(dmc_inst, sys_if),
 					TZC_DMC500_REGION_ATTR_F_EN_MASK,
@@ -272,4 +273,13 @@
 	/* Validates the information passed by platform */
 	validate_plat_driver_data(plat_driver_data);
 	g_driver_data = plat_driver_data;
+
+	/* Check valid system interface count */
+	assert(g_driver_data->sys_if_count <= MAX_SYS_IF_COUNT);
+
+	g_sys_if_count = g_driver_data->sys_if_count;
+
+	/* If interface count is not present then assume max */
+	if (g_sys_if_count == 0U)
+		g_sys_if_count = MAX_SYS_IF_COUNT;
 }
diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S
index 4ebf77b..d5f527a 100644
--- a/include/common/aarch64/el3_common_macros.S
+++ b/include/common/aarch64/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -278,8 +278,8 @@
 		 * an earlier boot loader stage.
 		 * -------------------------------------------------------------
 		 */
-		adr	x0, __RW_START__
-		adr	x1, __RW_END__
+		ldr	x0, =__RW_START__
+		ldr	x1, =__RW_END__
 		sub	x1, x1, x0
 		bl	inv_dcache_range
 #endif
@@ -294,7 +294,7 @@
 		bl	zeromem
 #endif
 
-#ifdef IMAGE_BL1
+#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_IN_XIP_MEM)
 		ldr	x0, =__DATA_RAM_START__
 		ldr	x1, =__DATA_ROM_START__
 		ldr	x2, =__DATA_SIZE__
diff --git a/include/drivers/arm/tzc_dmc500.h b/include/drivers/arm/tzc_dmc500.h
index 2606d1b..ff58a27 100644
--- a/include/drivers/arm/tzc_dmc500.h
+++ b/include/drivers/arm/tzc_dmc500.h
@@ -130,6 +130,7 @@
 typedef struct tzc_dmc500_driver_data {
 	uintptr_t dmc_base[MAX_DMC_COUNT];
 	int dmc_count;
+	unsigned int sys_if_count;
 } tzc_dmc500_driver_data_t;
 
 void tzc_dmc500_driver_init(const tzc_dmc500_driver_data_t *plat_driver_data);
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 8f0a74f..bfe2449 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -230,6 +230,7 @@
 
 	/* Check whether errata applies */
 	mov	x0, \_rev_var
+	/* Shall clobber: x0-x7 */
 	bl	check_errata_\_id
 
 	.ifeq \_chosen
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index b0db8f0..f79450c 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -11,6 +11,7 @@
 #include <cassert.h>
 #include <cpu_data.h>
 #include <stdint.h>
+#include <tzc_common.h>
 #include <utils_def.h>
 
 /*******************************************************************************
@@ -21,6 +22,43 @@
 struct image_info;
 struct bl_params;
 
+typedef struct arm_tzc_regions_info {
+	unsigned long long base;
+	unsigned long long end;
+	tzc_region_attributes_t sec_attr;
+	unsigned int nsaid_permissions;
+} arm_tzc_regions_info_t;
+
+/*******************************************************************************
+ * Default mapping definition of the TrustZone Controller for ARM standard
+ * platforms.
+ * Configure:
+ *   - Region 0 with no access;
+ *   - Region 1 with secure access only;
+ *   - the remaining DRAM regions access from the given Non-Secure masters.
+ ******************************************************************************/
+#if ENABLE_SPM
+#define ARM_TZC_REGIONS_DEF						\
+	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END,			\
+		TZC_REGION_S_RDWR, 0},					\
+	{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+		PLAT_ARM_TZC_NS_DEV_ACCESS}, 				\
+	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
+		PLAT_ARM_TZC_NS_DEV_ACCESS},				\
+	{ARM_SP_IMAGE_NS_BUF_BASE, (ARM_SP_IMAGE_NS_BUF_BASE +		\
+		ARM_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
+		PLAT_ARM_TZC_NS_DEV_ACCESS}
+
+#else
+#define ARM_TZC_REGIONS_DEF						\
+	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END,			\
+		TZC_REGION_S_RDWR, 0},					\
+	{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
+		PLAT_ARM_TZC_NS_DEV_ACCESS},	 			\
+	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
+		PLAT_ARM_TZC_NS_DEV_ACCESS}
+#endif
+
 #define ARM_CASSERT_MMAP						\
 	CASSERT((ARRAY_SIZE(plat_arm_mmap) + ARM_BL_REGIONS)		\
 		<= MAX_MMAP_REGIONS,					\
@@ -110,9 +148,10 @@
 void arm_io_setup(void);
 
 /* Security utility functions */
-void arm_tzc400_setup(void);
+void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions);
 struct tzc_dmc500_driver_data;
-void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data);
+void arm_tzc_dmc500_setup(struct tzc_dmc500_driver_data *plat_driver_data,
+			const arm_tzc_regions_info_t *tzc_regions);
 
 /* Systimer utility function */
 void arm_configure_sys_timer(void);
diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h
index 84923b9..827d416 100644
--- a/include/plat/common/common_def.h
+++ b/include/plat/common/common_def.h
@@ -78,9 +78,19 @@
 #define BL1_CODE_END		BL_CODE_END
 #define BL1_RO_DATA_BASE	BL_RO_DATA_BASE
 #define BL1_RO_DATA_END		round_up(BL1_ROM_END, PAGE_SIZE)
+#if BL2_IN_XIP_MEM
+#define BL2_CODE_END		BL_CODE_END
+#define BL2_RO_DATA_BASE	BL_RO_DATA_BASE
+#define BL2_RO_DATA_END		round_up(BL2_ROM_END, PAGE_SIZE)
+#endif /* BL2_IN_XIP_MEM */
 #else
 #define BL_RO_DATA_BASE		0
 #define BL_RO_DATA_END		0
 #define BL1_CODE_END		round_up(BL1_ROM_END, PAGE_SIZE)
+#if BL2_IN_XIP_MEM
+#define BL2_RO_DATA_BASE	0
+#define BL2_RO_DATA_END		0
+#define BL2_CODE_END		round_up(BL2_ROM_END, PAGE_SIZE)
+#endif /* BL2_IN_XIP_MEM */
 #endif /* SEPARATE_CODE_AND_RODATA */
 #endif /* __COMMON_DEF_H__ */
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index 3e480bc..3a23e02 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <cortex_a53.h>
 #include <cpu_macros.S>
 #include <debug.h>
+#include <errata_report.h>
 #include <plat_macros.S>
 
 #if A53_DISABLE_NON_TEMPORAL_HINT
@@ -144,8 +145,23 @@
  * This workaround is statically enabled at build time.
  */
 func check_errata_835769
-	mov	x1, #0x04
-	b	cpu_rev_var_ls
+	cmp	x0, #0x04
+	b.hi	errata_not_applies
+	/*
+	 * Fix potentially available for revisions r0p2, r0p3 and r0p4.
+	 * If r0p2, r0p3 or r0p4; check for fix in REVIDR, else exit.
+	 */
+	cmp	x0, #0x01
+	mov	x0, #ERRATA_APPLIES
+	b.ls	exit_check_errata_835769
+	/* Load REVIDR. */
+	mrs	x1, revidr_el1
+	/* If REVIDR[7] is set (fix exists) set ERRATA_NOT_APPLIES, else exit. */
+	tbz	x1, #7, exit_check_errata_835769
+errata_not_applies:
+	mov	x0, #ERRATA_NOT_APPLIES
+exit_check_errata_835769:
+	ret
 endfunc check_errata_835769
 
 /*
@@ -154,8 +170,22 @@
  * This workaround is statically enabled at build time.
  */
 func check_errata_843419
-	mov	x1, #0x04
-	b	cpu_rev_var_ls
+	mov	x1, #ERRATA_APPLIES
+	mov	x2, #ERRATA_NOT_APPLIES
+	cmp	x0, #0x04
+	csel	x0, x1, x2, ls
+	/*
+	 * Fix potentially available for revision r0p4.
+	 * If r0p4 check for fix in REVIDR, else exit.
+	 */
+	b.ne	exit_check_errata_843419
+	/* Load REVIDR. */
+	mrs	x3, revidr_el1
+	/* If REVIDR[8] is set (fix exists) set ERRATA_NOT_APPLIES, else exit. */
+	tbz	x3, #8, exit_check_errata_843419
+	mov	x0, x2
+exit_check_errata_843419:
+	ret
 endfunc check_errata_843419
 
 	/* -------------------------------------------------
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 5a9226d..9f13ed2 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -198,6 +198,8 @@
  * Compare the CPU's revision-variant (x0) with a given value (x1), for errata
  * application purposes. If the revision-variant is less than or same as a given
  * value, indicates that errata applies; otherwise not.
+ *
+ * Shall clobber: x0-x3
  */
 	.globl	cpu_rev_var_ls
 func cpu_rev_var_ls
@@ -212,6 +214,8 @@
  * Compare the CPU's revision-variant (x0) with a given value (x1), for errata
  * application purposes. If the revision-variant is higher than or same as a
  * given value, indicates that errata applies; otherwise not.
+ *
+ * Shall clobber: x0-x3
  */
 	.globl	cpu_rev_var_hs
 func cpu_rev_var_hs
diff --git a/lib/xlat_tables_v2/xlat_tables_internal.c b/lib/xlat_tables_v2/xlat_tables_internal.c
index 653260c..522b167 100644
--- a/lib/xlat_tables_v2/xlat_tables_internal.c
+++ b/lib/xlat_tables_v2/xlat_tables_internal.c
@@ -735,7 +735,8 @@
 void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
 {
 	mmap_region_t *mm_cursor = ctx->mmap;
-	mmap_region_t *mm_last = mm_cursor + ctx->mmap_num;
+	const mmap_region_t *mm_end = ctx->mmap + ctx->mmap_num;
+	mmap_region_t *mm_last;
 	unsigned long long end_pa = mm->base_pa + mm->size - 1;
 	uintptr_t end_va = mm->base_va + mm->size - 1;
 	int ret;
@@ -786,6 +787,21 @@
 	       && (mm_cursor->size < mm->size))
 		++mm_cursor;
 
+	/*
+	 * Find the last entry marker in the mmap
+	 */
+	mm_last = ctx->mmap;
+	while ((mm_last->size != 0U) && (mm_last < mm_end)) {
+		++mm_last;
+	}
+
+	/*
+	 * Check if we have enough space in the memory mapping table.
+	 * This shouldn't happen as we have checked in mmap_add_region_check
+	 * that there is free space.
+	 */
+	assert(mm_last->size == 0U);
+
 	/* Make room for new region by moving other regions up by one place */
 	memmove(mm_cursor + 1, mm_cursor,
 		(uintptr_t)mm_last - (uintptr_t)mm_cursor);
@@ -795,7 +811,7 @@
 	 * This shouldn't happen as we have checked in mmap_add_region_check
 	 * that there is free space.
 	 */
-	assert(mm_last->size == 0);
+	assert(mm_end->size == 0U);
 
 	*mm_cursor = *mm;
 
diff --git a/maintainers.rst b/maintainers.rst
index 77b851e..2217cbe 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -83,6 +83,15 @@
 
 -  plat/mediatek/\*
 
+NXP QorIQ Layerscape platform sub-maintainer
+--------------------------------------
+Jiafei Pan (jiafei.pan@nxp.com, `qoriq-open-source`_)
+
+Files:
+
+-  docs/plat/ls1043a.rst
+-  plat/layerscape/\*
+
 Raspberry Pi 3 platform sub-maintainer
 --------------------------------------
 
@@ -141,3 +150,4 @@
 .. _sivadur: https://github.com/sivadur
 .. _rockchip-linux: https://github.com/rockchip-linux
 .. _etienne-lms: https://github.com/etienne-lms
+.. _qoriq-open-source: https://github.com/qoriq-open-source
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 751f834..77eb157 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -30,6 +30,10 @@
 # Execute BL2 at EL3
 BL2_AT_EL3			:= 0
 
+# BL2 image is stored in XIP memory, for now, this option is only supported
+# when BL2_AT_EL3 is 1.
+BL2_IN_XIP_MEM			:= 0
+
 # By default, consider that the platform may release several CPUs out of reset.
 # The platform Makefile is free to override this value.
 COLD_BOOT_SINGLE_CPU		:= 0
diff --git a/plat/arm/board/fvp/aarch32/fvp_helpers.S b/plat/arm/board/fvp/aarch32/fvp_helpers.S
index 143972d..5d88546 100644
--- a/plat/arm/board/fvp/aarch32/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch32/fvp_helpers.S
@@ -104,15 +104,20 @@
 	bx	lr
 endfunc plat_is_my_cpu_primary
 
-	/* -----------------------------------------------------
+	/* ---------------------------------------------------------------------
 	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
 	 *
 	 * Function to calculate the core position on FVP.
 	 *
-	 * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER) +
+	 * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU) +
 	 * (CPUId * FVP_MAX_PE_PER_CPU) +
 	 * ThreadId
-	 * -----------------------------------------------------
+	 *
+	 * which can be simplified as:
+	 *
+	 * ((ClusterId * FVP_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_MAX_PE_PER_CPU)
+	 * + ThreadId
+	 * ---------------------------------------------------------------------
 	 */
 func plat_arm_calc_core_pos
 	mov	r3, r0
@@ -125,14 +130,15 @@
 	lsleq	r3, r0, #MPIDR_AFFINITY_BITS
 
 	/* Extract individual affinity fields from MPIDR */
-	mov	r2, #FVP_MAX_PE_PER_CPU
 	ubfx	r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
 	ubfx	r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
-	mla	r0, r1, r2, r0
-
-	mov	r1, #FVP_MAX_CPUS_PER_CLUSTER
 	ubfx	r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
-	mla	r0, r1, r2, r0
+
+	/* Compute linear position */
+	mov	r3, #FVP_MAX_CPUS_PER_CLUSTER
+	mla	r1, r2, r3, r1
+	mov	r3, #FVP_MAX_PE_PER_CPU
+	mla	r0, r1, r3, r0
 
 	bx	lr
 endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 4559865..a6c9227 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,5 +22,5 @@
 	 */
 
 	if (get_arm_config()->flags & ARM_CONFIG_HAS_TZC)
-		arm_tzc400_setup();
+		arm_tzc400_setup(NULL);
 }
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 2e2fdd7..b422398 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -110,12 +110,14 @@
  */
 #if TRUSTED_BOARD_BOOT
 #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
-# define PLAT_ARM_MAX_BL2_SIZE		0x1F000
+# define PLAT_ARM_MAX_BL2_SIZE		0x20000
+#elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA
+# define PLAT_ARM_MAX_BL2_SIZE		0x1D000
 #else
-# define PLAT_ARM_MAX_BL2_SIZE		0x1B000
+# define PLAT_ARM_MAX_BL2_SIZE		0x1C000
 #endif
 #else
-# define PLAT_ARM_MAX_BL2_SIZE		0xD000
+# define PLAT_ARM_MAX_BL2_SIZE		0xE000
 #endif
 
 /*
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index ce4239b..b6cfe78 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.c
@@ -1,15 +1,80 @@
 /*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <debug.h>
 #include <mmio.h>
 #include <nic_400.h>
 #include <plat_arm.h>
 #include <soc_css.h>
-#include "juno_def.h"
 
+#include "juno_def.h"
+#include "juno_tzmp1_def.h"
+
+#ifdef JUNO_TZMP1
+/*
+ * Protect buffer for VPU/GPU/DPU memory usage with hardware protection
+ * enabled. Propose 224MB video output, 96 MB video input and 32MB video
+ * private.
+ *
+ * Ind	Memory Range			Caption			  S_ATTR  NS_ATTR
+ * 1	0x080000000 - 0x0E7FFFFFF	ARM_NS_DRAM1		  NONE	  RDWR | MEDIA_RW
+ * 2	0x0E8000000 - 0x0F5FFFFFF	JUNO_MEDIA_TZC_PROT_DRAM1 NONE	  MEDIA_RW | AP_WR
+ * 3	0x0F6000000 - 0x0FBFFFFFF	JUNO_VPU_TZC_PROT_DRAM1	  RDWR	  VPU_PROT_RW
+ * 4	0x0FC000000 - 0x0FDFFFFFF	JUNO_VPU_TZC_PRIV_DRAM1	  RDWR	  VPU_PRIV_RW
+ * 5	0x0FE000000 - 0x0FEFFFFFF	JUNO_AP_TZC_SHARE_DRAM1	  NONE	  RDWR | MEDIA_RW
+ * 6	0x0FF000000 - 0x0FFFFFFFF	ARM_AP_TZC_DRAM1	  RDWR	  NONE
+ * 7	0x880000000 - 0x9FFFFFFFF	ARM_DRAM2		  NONE	  RDWR | MEDIA_RW
+ *
+ * Memory regions are neighbored to save limited TZC regions. Calculation
+ * started from ARM_TZC_SHARE_DRAM1 since it is known and fixed for both
+ * protected-enabled and protected-disabled settings.
+ *
+ * Video private buffer aheads of ARM_TZC_SHARE_DRAM1
+ */
+
+static const arm_tzc_regions_info_t juno_tzmp1_tzc_regions[] = {
+	{ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END, TZC_REGION_S_RDWR, 0},
+	{JUNO_NS_DRAM1_PT1_BASE, JUNO_NS_DRAM1_PT1_END,
+			TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS},
+	{JUNO_MEDIA_TZC_PROT_DRAM1_BASE, JUNO_MEDIA_TZC_PROT_DRAM1_END,
+			TZC_REGION_S_NONE, JUNO_MEDIA_TZC_PROT_ACCESS},
+	{JUNO_VPU_TZC_PROT_DRAM1_BASE, JUNO_VPU_TZC_PROT_DRAM1_END,
+			TZC_REGION_S_RDWR, JUNO_VPU_TZC_PROT_ACCESS},
+	{JUNO_VPU_TZC_PRIV_DRAM1_BASE, JUNO_VPU_TZC_PRIV_DRAM1_END,
+			TZC_REGION_S_RDWR, JUNO_VPU_TZC_PRIV_ACCESS},
+	{JUNO_AP_TZC_SHARE_DRAM1_BASE, JUNO_AP_TZC_SHARE_DRAM1_END,
+			TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS},
+	{ARM_DRAM2_BASE, ARM_DRAM2_END,
+			TZC_REGION_S_NONE, JUNO_MEDIA_TZC_NS_DEV_ACCESS},
+	{},
+};
+
+/*******************************************************************************
+ * Program dp650 to configure NSAID value for protected mode.
+ ******************************************************************************/
+static void init_dp650(void)
+{
+	mmio_write_32(DP650_BASE + DP650_PROT_NSAID_OFFSET,
+		      DP650_PROT_NSAID_CONFIG);
+}
+
+/*******************************************************************************
+ * Program v550 to configure NSAID value for protected mode.
+ ******************************************************************************/
+static void init_v550(void)
+{
+	/*
+	 * bits[31:28] is for PRIVATE,
+	 * bits[27:24] is for OUTBUF,
+	 * bits[23:20] is for PROTECTED.
+	 */
+	mmio_write_32(V550_BASE + V550_PROTCTRL_OFFSET, V550_PROTCTRL_CONFIG);
+}
+
+#endif /* JUNO_TZMP1 */
 
 /*******************************************************************************
  * Set up the MMU-401 SSD tables. The power-on configuration has all stream IDs
@@ -59,11 +124,23 @@
 	/* Initialize debug configuration */
 	init_debug_cfg();
 	/* Initialize the TrustZone Controller */
-	arm_tzc400_setup();
+#ifdef JUNO_TZMP1
+	arm_tzc400_setup(juno_tzmp1_tzc_regions);
+	INFO("TZC protected shared memory base address for TZMP usecase: %p\n",
+	     (void *)JUNO_AP_TZC_SHARE_DRAM1_BASE);
+	INFO("TZC protected shared memory end address for TZMP usecase: %p\n",
+	     (void *)JUNO_AP_TZC_SHARE_DRAM1_END);
+#else
+	arm_tzc400_setup(NULL);
+#endif
 	/* Do ARM CSS internal NIC setup */
 	css_init_nic400();
 	/* Do ARM CSS SoC security setup */
 	soc_css_security_setup();
 	/* Initialize the SMMU SSD tables */
 	init_mmu401();
+#ifdef JUNO_TZMP1
+	init_dp650();
+	init_v550();
+#endif
 }
diff --git a/plat/arm/board/juno/juno_tzmp1_def.h b/plat/arm/board/juno/juno_tzmp1_def.h
new file mode 100644
index 0000000..7055f76
--- /dev/null
+++ b/plat/arm/board/juno/juno_tzmp1_def.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __JUNO_TZMP1_DEF_H__
+#define __JUNO_TZMP1_DEF_H__
+
+#include <plat_arm.h>
+
+/*
+ * Public memory regions for both protected and non-protected mode
+ *
+ * OPTEE shared memory 0xFEE00000 - 0xFEFFFFFF
+ */
+#define JUNO_AP_TZC_SHARE_DRAM1_SIZE		ULL(0x02000000)
+#define JUNO_AP_TZC_SHARE_DRAM1_BASE		(ARM_AP_TZC_DRAM1_BASE - \
+						 JUNO_AP_TZC_SHARE_DRAM1_SIZE)
+#define JUNO_AP_TZC_SHARE_DRAM1_END		(ARM_AP_TZC_DRAM1_BASE - 1)
+
+/* ARM_MEDIA_FEATURES for MEDIA GPU Protect Mode Test */
+#define JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE	8	/* GPU/DPU protected, VPU outbuf */
+#define JUNO_TZC400_NSAID_FPGA_VIDEO_PROTECTED	7	/* VPU protected */
+#define JUNO_TZC400_NSAID_FPGA_VIDEO_PRIVATE	10	/* VPU private (firmware) */
+
+#define JUNO_VPU_TZC_PRIV_DRAM1_SIZE	ULL(0x02000000)
+#define JUNO_VPU_TZC_PRIV_DRAM1_BASE	(JUNO_AP_TZC_SHARE_DRAM1_BASE - \
+					 JUNO_VPU_TZC_PRIV_DRAM1_SIZE)
+#define JUNO_VPU_TZC_PRIV_DRAM1_END	(JUNO_AP_TZC_SHARE_DRAM1_BASE - 1)
+
+/* Video input protected buffer follows upper item */
+#define JUNO_VPU_TZC_PROT_DRAM1_SIZE	ULL(0x06000000)
+#define JUNO_VPU_TZC_PROT_DRAM1_BASE	(JUNO_VPU_TZC_PRIV_DRAM1_BASE - \
+					 JUNO_VPU_TZC_PROT_DRAM1_SIZE)
+#define JUNO_VPU_TZC_PROT_DRAM1_END	(JUNO_VPU_TZC_PRIV_DRAM1_BASE - 1)
+
+/* Video, graphics and display shares same NSAID and same protected buffer */
+#define JUNO_MEDIA_TZC_PROT_DRAM1_SIZE	ULL(0x0e000000)
+#define JUNO_MEDIA_TZC_PROT_DRAM1_BASE	(JUNO_VPU_TZC_PROT_DRAM1_BASE - \
+					 JUNO_MEDIA_TZC_PROT_DRAM1_SIZE)
+#define JUNO_MEDIA_TZC_PROT_DRAM1_END	(JUNO_VPU_TZC_PROT_DRAM1_BASE - 1)
+
+/* Rest of DRAM1 are Non-Secure public buffer */
+#define JUNO_NS_DRAM1_PT1_BASE		ARM_DRAM1_BASE
+#define JUNO_NS_DRAM1_PT1_END		(JUNO_MEDIA_TZC_PROT_DRAM1_BASE - 1)
+#define JUNO_NS_DRAM1_PT1_SIZE		(JUNO_NS_DRAM1_PT1_END -	\
+					 JUNO_NS_DRAM1_PT1_BASE + 1)
+
+/* TZC filter flags */
+#define JUNO_MEDIA_TZC_NS_DEV_ACCESS	(PLAT_ARM_TZC_NS_DEV_ACCESS |	\
+		TZC_REGION_ACCESS_RD(JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE))
+
+/* VPU / GPU /DPU protected access */
+#define JUNO_MEDIA_TZC_PROT_ACCESS \
+		(TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_MEDIA_SECURE) | \
+		TZC_REGION_ACCESS_WR(TZC400_NSAID_AP))
+
+#define JUNO_VPU_TZC_PROT_ACCESS \
+		(TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_VIDEO_PROTECTED))
+
+#define JUNO_VPU_TZC_PRIV_ACCESS \
+		(TZC_REGION_ACCESS_RDWR(JUNO_TZC400_NSAID_FPGA_VIDEO_PRIVATE))
+
+/*******************************************************************************
+ * Mali-DP650 related constants
+ ******************************************************************************/
+/* Base address of DP650 */
+#define DP650_BASE			0x6f200000
+/* offset to PROT_NSAID register */
+#define DP650_PROT_NSAID_OFFSET		0x10004
+/* config to PROT_NSAID register */
+#define DP650_PROT_NSAID_CONFIG		0x08008888
+
+/*******************************************************************************
+ * Mali-V550 related constants
+ ******************************************************************************/
+/* Base address of V550 */
+#define V550_BASE			0x6f030000
+/* offset to PROTCTRL register */
+#define V550_PROTCTRL_OFFSET		0x0040
+/* config to PROTCTRL register */
+#define V550_PROTCTRL_CONFIG		0xa8700000
+
+#endif /* __JUNO_TZMP1_DEF_H__ */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 656fc14..3ab99ef 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -31,6 +31,13 @@
 $(eval $(call assert_boolean,JUNO_AARCH32_EL3_RUNTIME))
 $(eval $(call add_define,JUNO_AARCH32_EL3_RUNTIME))
 
+# Flag to enable support for TZMP1 on JUNO
+JUNO_TZMP1		:=	0
+$(eval $(call assert_boolean,JUNO_TZMP1))
+ifeq (${JUNO_TZMP1}, 1)
+$(eval $(call add_define,JUNO_TZMP1))
+endif
+
 ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1)
 # Include BL32 in FIP
 NEED_BL32		:= yes
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 6b706be..a32736c 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -18,16 +18,20 @@
 
 /*******************************************************************************
  * Initialize the TrustZone Controller for ARM standard platforms.
- * Configure:
- *   - Region 0 with no access;
- *   - Region 1 with secure access only;
- *   - the remaining DRAM regions access from the given Non-Secure masters.
- *
  * When booting an EL3 payload, this is simplified: we configure region 0 with
  * secure access only and do not enable any other region.
  ******************************************************************************/
-void arm_tzc400_setup(void)
+void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
 {
+#ifndef EL3_PAYLOAD_BASE
+	int region_index = 1;
+	const arm_tzc_regions_info_t *p;
+	const arm_tzc_regions_info_t init_tzc_regions[] = {
+		ARM_TZC_REGIONS_DEF,
+		{0}
+	};
+#endif
+
 	INFO("Configuring TrustZone Controller\n");
 
 	tzc400_init(PLAT_ARM_TZC_BASE);
@@ -36,42 +40,22 @@
 	tzc400_disable_filters();
 
 #ifndef EL3_PAYLOAD_BASE
+	if (tzc_regions == NULL)
+		p = init_tzc_regions;
+	else
+		p = tzc_regions;
 
 	/* Region 0 set to no access by default */
 	tzc400_configure_region0(TZC_REGION_S_NONE, 0);
 
-	/* Region 1 set to cover Secure part of DRAM */
-	tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 1,
-			ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END,
-			TZC_REGION_S_RDWR,
-			0);
+	/* Rest Regions set according to tzc_regions array */
+	for (; p->base != 0ULL; p++) {
+		tzc400_configure_region(PLAT_ARM_TZC_FILTERS, region_index,
+			p->base, p->end, p->sec_attr, p->nsaid_permissions);
+		region_index++;
+	}
 
-	/* Region 2 set to cover Non-Secure access to 1st DRAM address range.
-	 * Apply the same configuration to given filters in the TZC. */
-	tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 2,
-			ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END,
-			ARM_TZC_NS_DRAM_S_ACCESS,
-			PLAT_ARM_TZC_NS_DEV_ACCESS);
-
-	/* Region 3 set to cover Non-Secure access to 2nd DRAM address range */
-	tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 3,
-			ARM_DRAM2_BASE, ARM_DRAM2_END,
-			ARM_TZC_NS_DRAM_S_ACCESS,
-			PLAT_ARM_TZC_NS_DEV_ACCESS);
-
-#if ENABLE_SPM
-	/*
-	 * Region 4 set to cover Non-Secure access to the communication buffer
-	 * shared with the Secure world.
-	 */
-	tzc400_configure_region(PLAT_ARM_TZC_FILTERS,
-				4,
-				ARM_SP_IMAGE_NS_BUF_BASE,
-				(ARM_SP_IMAGE_NS_BUF_BASE +
-				 ARM_SP_IMAGE_NS_BUF_SIZE) - 1,
-				TZC_REGION_S_NONE,
-				PLAT_ARM_TZC_NS_DEV_ACCESS);
-#endif
+	INFO("Total %d regions set.\n", region_index);
 
 #else /* if defined(EL3_PAYLOAD_BASE) */
 
@@ -92,5 +76,5 @@
 
 void plat_arm_security_setup(void)
 {
-	arm_tzc400_setup();
+	arm_tzc400_setup(NULL);
 }
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index 8e41391..89c502c 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,15 +12,21 @@
 
 /*******************************************************************************
  * Initialize the DMC500-TrustZone Controller for ARM standard platforms.
- * Configure both the interfaces on Region 0 with no access, Region 1 with
- * secure access only, and the remaining DRAM regions access from the
- * given Non-Secure masters.
- *
  * When booting an EL3 payload, this is simplified: we configure region 0 with
  * secure access only and do not enable any other region.
  ******************************************************************************/
-void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data)
+void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data,
+			const arm_tzc_regions_info_t *tzc_regions)
 {
+#ifndef EL3_PAYLOAD_BASE
+	int region_index = 1;
+	const arm_tzc_regions_info_t *p;
+	const arm_tzc_regions_info_t init_tzc_regions[] = {
+		ARM_TZC_REGIONS_DEF,
+		{0}
+	};
+#endif
+
 	assert(plat_driver_data);
 
 	INFO("Configuring DMC-500 TZ Settings\n");
@@ -28,28 +34,23 @@
 	tzc_dmc500_driver_init(plat_driver_data);
 
 #ifndef EL3_PAYLOAD_BASE
+	if (tzc_regions == NULL)
+		p = init_tzc_regions;
+	else
+		p = tzc_regions;
+
 	/* Region 0 set to no access by default */
 	tzc_dmc500_configure_region0(TZC_REGION_S_NONE, 0);
 
-	/* Region 1 set to cover Secure part of DRAM */
-	tzc_dmc500_configure_region(1, ARM_AP_TZC_DRAM1_BASE,
-		ARM_EL3_TZC_DRAM1_END,
-		TZC_REGION_S_RDWR,
-		0);
+	/* Rest Regions set according to tzc_regions array */
+	for (; p->base != 0ULL; p++) {
+		tzc_dmc500_configure_region(region_index, p->base, p->end,
+					    p->sec_attr, p->nsaid_permissions);
+		region_index++;
+	}
 
-	/* Region 2 set to cover Non-Secure access to 1st DRAM address range.*/
-	tzc_dmc500_configure_region(2,
-		ARM_NS_DRAM1_BASE,
-		ARM_NS_DRAM1_END,
-		ARM_TZC_NS_DRAM_S_ACCESS,
-		PLAT_ARM_TZC_NS_DEV_ACCESS);
+	INFO("Total %d regions set.\n", region_index);
 
-	/* Region 3 set to cover Non-Secure access to 2nd DRAM address range */
-	tzc_dmc500_configure_region(3,
-		ARM_DRAM2_BASE,
-		ARM_DRAM2_END,
-		ARM_TZC_NS_DRAM_S_ACCESS,
-		PLAT_ARM_TZC_NS_DEV_ACCESS);
 #else
 	/* Allow secure access only to DRAM for EL3 payloads */
 	tzc_dmc500_configure_region0(TZC_REGION_S_RDWR, 0);
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
index a78bb1e..a3fc607 100644
--- a/plat/hisilicon/hikey/hikey_bl2_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -304,14 +304,12 @@
 	hikey_gpio_init();
 	hikey_pmussi_init();
 	hikey_hi6553_init();
-
-	dsb();
-	hikey_ddr_init();
-	hikey_security_setup();
-
 	/* Clear SRAM since it'll be used by MCU right now. */
 	memset((void *)SRAM_BASE, 0, SRAM_SIZE);
-	clean_dcache_range(SRAM_BASE, SRAM_SIZE);
+
+	dsb();
+	hikey_ddr_init(DDR_FREQ_800M);
+	hikey_security_setup();
 
 	hikey_boardid_init();
 	init_acpu_dvfs();
@@ -321,6 +319,9 @@
 
 	hikey_mmc_pll_init();
 
+	/* Clean SRAM before MCU used */
+	clean_dcache_range(SRAM_BASE, SRAM_SIZE);
+
 	reset_dwmmc_clk();
 	memset(&params, 0, sizeof(dw_mmc_params_t));
 	params.reg_base = DWMMC0_BASE;
diff --git a/plat/hisilicon/hikey/hikey_ddr.c b/plat/hisilicon/hikey/hikey_ddr.c
index ab572eb..43cece0 100644
--- a/plat/hisilicon/hikey/hikey_ddr.c
+++ b/plat/hisilicon/hikey/hikey_ddr.c
@@ -5,17 +5,16 @@
  */
 
 #include <arch_helpers.h>
+#include <assert.h>
 #include <debug.h>
 #include <errno.h>
 #include <hi6220.h>
 #include <hi6553.h>
+#include <hisi_sram_map.h>
 #include <mmio.h>
 #include <sp804_delay_timer.h>
 
-enum {
-	DDR_FREQ_533M = 0,
-	DDR_FREQ_800M,
-};
+#include "hikey_private.h"
 
 static void init_pll(void)
 {
@@ -24,7 +23,6 @@
 	data = mmio_read_32((0xf7032000 + 0x000));
 	data |= 0x1;
 	mmio_write_32((0xf7032000 + 0x000), data);
-	dsb();
 	do {
 		data = mmio_read_32((0xf7032000 + 0x000));
 	} while (!(data & (1 << 28)));
@@ -33,22 +31,45 @@
 	data &= ~0x007;
 	data |= 0x004;
 	mmio_write_32((0xf7800000 + 0x000), data);
-	dsb();
 	do {
 		data = mmio_read_32((0xf7800000 + 0x014));
 		data &= 0x007;
 	} while (data != 0x004);
 
 	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
-	data = mmio_read_32(PERI_SC_PERIPH_STAT1);
+	dsb();
+	isb();
+	udelay(10);
+	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2001);
+	dsb();
+	isb();
+	udelay(10);
+	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2201);
+	dsb();
+	isb();
+	udelay(10);
 	mmio_write_32(0xf7032000 + 0x02c, 0x5110103e);
+	dsb();
+	isb();
+	udelay(10);
 	data = mmio_read_32(0xf7032000 + 0x050);
 	data |= 1 << 28;
 	mmio_write_32(0xf7032000 + 0x050, data);
+	dsb();
+	isb();
+	udelay(10);
 	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
-	mdelay(1);
-	data = mmio_read_32(PERI_SC_PERIPH_STAT1);
-	NOTICE("syspll frequency:%dHz\n", data);
+	dsb();
+	isb();
+	udelay(10);
+	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2001);
+	dsb();
+	isb();
+	udelay(10);
+	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2201);
+	dsb();
+	isb();
+	udelay(10);
 }
 
 static void init_freq(void)
@@ -215,7 +236,7 @@
 
 	data = mmio_read_32((0xf712c000 + 0x1c8));
 	data &= 0xfffff0f0;
-	data |= 0x100f0f;
+	data |= 0x100f01;
 	mmio_write_32((0xf712c000 + 0x1c8), data);
 
 	for (i = 0; i < 0x20; i++) {
@@ -244,7 +265,7 @@
 		} while (data & 1);
 
 		data = mmio_read_32((0xf712c000 + 0x008));
-		if (!(data & 0x400)) {
+		if ((data & 0x400) == 0) {
 			mdelay(10);
 			return 0;
 		}
@@ -489,7 +510,334 @@
 		INFO("wdet rbs av fail\n");
 }
 
-static void set_ddrc_533mhz(void)
+void set_ddrc_150mhz(void)
+{
+	unsigned int data;
+
+	mmio_write_32((0xf7032000 + 0x580), 0x1);
+	mmio_write_32((0xf7032000 + 0x5a8), 0x7);
+	data = mmio_read_32((0xf7032000 + 0x104));
+	data &= 0xfffffcff;
+	mmio_write_32((0xf7032000 + 0x104), data);
+
+	mmio_write_32((0xf7030000 + 0x050), 0x31);
+	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+	mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f);
+	mmio_write_32((0xf712c000 + 0x00c), 0xf0f);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x090), 0x7200000);
+	mmio_write_32((0xf712c000 + 0x258), 0x720);
+	mmio_write_32((0xf712c000 + 0x2d8), 0x720);
+	mmio_write_32((0xf712c000 + 0x358), 0x720);
+	mmio_write_32((0xf712c000 + 0x3d8), 0x720);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
+	mmio_write_32((0xf712c000 + 0x0b4), 0xf);
+	mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
+	mmio_write_32((0xf712c000 + 0x070), 0x8940000);
+
+	data = mmio_read_32((0xf712c000 + 0x078));
+	data |= 4;
+	mmio_write_32((0xf712c000 + 0x078), data);
+	mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= 0xfffffffe;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+	mmio_write_32((0xf712c000 + 0x010), 0x500000f);
+	mmio_write_32((0xf712c000 + 0x014), 0x10);
+	data = mmio_read_32((0xf712c000 + 0x1e4));
+	data &= 0xffffff00;
+	mmio_write_32((0xf712c000 + 0x1e4), data);
+	mmio_write_32((0xf712c000 + 0x030), 0x30c82355);
+	mmio_write_32((0xf712c000 + 0x034), 0x62112bb);
+	mmio_write_32((0xf712c000 + 0x038), 0x20041022);
+	mmio_write_32((0xf712c000 + 0x03c), 0x63177497);
+	mmio_write_32((0xf712c000 + 0x040), 0x3008407);
+	mmio_write_32((0xf712c000 + 0x064), 0x10483);
+	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= 0xffff0000;
+	data |= 0x184;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= 0xbfffffff;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= ~0x10;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	data = mmio_read_32((0xf712c000 + 0x080));
+	data &= ~0x2000;
+	mmio_write_32((0xf712c000 + 0x080), data);
+	mmio_write_32((0xf712c000 + 0x270), 0x3);
+	mmio_write_32((0xf712c000 + 0x2f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x370), 0x3);
+	mmio_write_32((0xf712c000 + 0x3f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x048), 0x90420880);
+
+	mmio_write_32((0xf7128000 + 0x040), 0x0);
+	mmio_write_32((0xf712c000 + 0x004), 0x146d);
+	mmio_write_32((0xf7128000 + 0x050), 0x100123);
+	mmio_write_32((0xf7128000 + 0x060), 0x133);
+	mmio_write_32((0xf7128000 + 0x064), 0x133);
+	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+	mmio_write_32((0xf7128000 + 0x100), 0xb3290d08);
+	mmio_write_32((0xf7128000 + 0x104), 0x9621821);
+	mmio_write_32((0xf7128000 + 0x108), 0x45009023);
+	mmio_write_32((0xf7128000 + 0x10c), 0xaf44c145);
+	mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+	mmio_write_32((0xf7128000 + 0x114), 0x11080806);
+	mmio_write_32((0xf7128000 + 0x118), 0x44);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 8) {
+		NOTICE("fail to init ddr3 rank0\n");
+		return;
+	}
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 1;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x21);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x8)
+		NOTICE("ddr3 rank1 init failure\n");
+	else
+		INFO("ddr3 rank1 init pass\n");
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= ~0xf;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	INFO("succeed to set ddrc 150mhz\n");
+}
+
+void set_ddrc_266mhz(void)
+{
+	unsigned int data;
+
+	mmio_write_32((0xf7032000 + 0x580), 0x3);
+	mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
+	data = mmio_read_32((0xf7032000 + 0x104));
+	data &= 0xfffffcff;
+	mmio_write_32((0xf7032000 + 0x104), data);
+
+	mmio_write_32((0xf7030000 + 0x050), 0x31);
+	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+	mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f);
+	mmio_write_32((0xf712c000 + 0x00c), 0xf0f);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x090), 0x7200000);
+	mmio_write_32((0xf712c000 + 0x258), 0x720);
+	mmio_write_32((0xf712c000 + 0x2d8), 0x720);
+	mmio_write_32((0xf712c000 + 0x358), 0x720);
+	mmio_write_32((0xf712c000 + 0x3d8), 0x720);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
+	mmio_write_32((0xf712c000 + 0x0b4), 0xf);
+	mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
+	mmio_write_32((0xf712c000 + 0x070), 0x8940000);
+
+	data = mmio_read_32((0xf712c000 + 0x078));
+	data |= 4;
+	mmio_write_32((0xf712c000 + 0x078), data);
+	mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= 0xfffffffe;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+	mmio_write_32((0xf712c000 + 0x010), 0x500000f);
+	mmio_write_32((0xf712c000 + 0x014), 0x10);
+	data = mmio_read_32((0xf712c000 + 0x1e4));
+	data &= 0xffffff00;
+	mmio_write_32((0xf712c000 + 0x1e4), data);
+	mmio_write_32((0xf712c000 + 0x030), 0x510d4455);
+	mmio_write_32((0xf712c000 + 0x034), 0x8391ebb);
+	mmio_write_32((0xf712c000 + 0x038), 0x2005103c);
+	mmio_write_32((0xf712c000 + 0x03c), 0x6329950b);
+	mmio_write_32((0xf712c000 + 0x040), 0x300858c);
+	mmio_write_32((0xf712c000 + 0x064), 0x10483);
+	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= 0xffff0000;
+	data |= 0x184;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= 0xbfffffff;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= ~0x10;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	data = mmio_read_32((0xf712c000 + 0x080));
+	data &= ~0x2000;
+	mmio_write_32((0xf712c000 + 0x080), data);
+	mmio_write_32((0xf712c000 + 0x270), 0x3);
+	mmio_write_32((0xf712c000 + 0x2f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x370), 0x3);
+	mmio_write_32((0xf712c000 + 0x3f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x048), 0x90420880);
+
+	mmio_write_32((0xf7128000 + 0x040), 0x0);
+	mmio_write_32((0xf712c000 + 0x004), 0x146d);
+	mmio_write_32((0xf7128000 + 0x050), 0x100123);
+	mmio_write_32((0xf7128000 + 0x060), 0x133);
+	mmio_write_32((0xf7128000 + 0x064), 0x133);
+	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+	mmio_write_32((0xf7128000 + 0x100), 0xb441d50d);
+	mmio_write_32((0xf7128000 + 0x104), 0xf721839);
+	mmio_write_32((0xf7128000 + 0x108), 0x5500f03f);
+	mmio_write_32((0xf7128000 + 0x10c), 0xaf486145);
+	mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+	mmio_write_32((0xf7128000 + 0x114), 0x12080d06);
+	mmio_write_32((0xf7128000 + 0x118), 0x44);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 8) {
+		NOTICE("fail to init ddr3 rank0\n");
+		return;
+	}
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 1;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x21);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x8)
+		NOTICE("ddr3 rank1 init failure\n");
+	else
+		INFO("ddr3 rank1 init pass\n");
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= ~0xf;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	INFO("succeed to set ddrc 266mhz\n");
+}
+
+void set_ddrc_400mhz(void)
+{
+	unsigned int data;
+
+	mmio_write_32((0xf7032000 + 0x580), 0x2);
+	mmio_write_32((0xf7032000 + 0x5a8), 0x1003);
+	data = mmio_read_32((0xf7032000 + 0x104));
+	data &= 0xfffffcff;
+	mmio_write_32((0xf7032000 + 0x104), data);
+
+	mmio_write_32((0xf7030000 + 0x050), 0x31);
+	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+	mmio_write_32((0xf712c000 + 0x00c), 0x80000f0f);
+	mmio_write_32((0xf712c000 + 0x00c), 0xf0f);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x090), 0x7200000);
+	mmio_write_32((0xf712c000 + 0x258), 0x720);
+	mmio_write_32((0xf712c000 + 0x2d8), 0x720);
+	mmio_write_32((0xf712c000 + 0x358), 0x720);
+	mmio_write_32((0xf712c000 + 0x3d8), 0x720);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x0b0), 0xf00000f);
+	mmio_write_32((0xf712c000 + 0x0b4), 0xf);
+	mmio_write_32((0xf712c000 + 0x088), 0x3fff801);
+	mmio_write_32((0xf712c000 + 0x070), 0x8940000);
+
+	data = mmio_read_32((0xf712c000 + 0x078));
+	data |= 4;
+	mmio_write_32((0xf712c000 + 0x078), data);
+	mmio_write_32((0xf712c000 + 0x01c), 0x8000080);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= 0xfffffffe;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+	mmio_write_32((0xf712c000 + 0x010), 0x500000f);
+	mmio_write_32((0xf712c000 + 0x014), 0x10);
+	data = mmio_read_32((0xf712c000 + 0x1e4));
+	data &= 0xffffff00;
+	mmio_write_32((0xf712c000 + 0x1e4), data);
+	mmio_write_32((0xf712c000 + 0x030), 0x75525655);
+	mmio_write_32((0xf712c000 + 0x034), 0xa552abb);
+	mmio_write_32((0xf712c000 + 0x038), 0x20071059);
+	mmio_write_32((0xf712c000 + 0x03c), 0x633e8591);
+	mmio_write_32((0xf712c000 + 0x040), 0x3008691);
+	mmio_write_32((0xf712c000 + 0x064), 0x10483);
+	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= 0xffff0000;
+	data |= 0x184;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= 0xbfffffff;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= ~0x10;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	data = mmio_read_32((0xf712c000 + 0x080));
+	data &= ~0x2000;
+	mmio_write_32((0xf712c000 + 0x080), data);
+	mmio_write_32((0xf712c000 + 0x270), 0x3);
+	mmio_write_32((0xf712c000 + 0x2f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x370), 0x3);
+	mmio_write_32((0xf712c000 + 0x3f0), 0x3);
+	mmio_write_32((0xf712c000 + 0x048), 0x90420880);
+
+	mmio_write_32((0xf7128000 + 0x040), 0x0);
+	mmio_write_32((0xf712c000 + 0x004), 0x146d);
+	mmio_write_32((0xf7128000 + 0x050), 0x100123);
+	mmio_write_32((0xf7128000 + 0x060), 0x133);
+	mmio_write_32((0xf7128000 + 0x064), 0x133);
+	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+	mmio_write_32((0xf7128000 + 0x100), 0xb55a9d12);
+	mmio_write_32((0xf7128000 + 0x104), 0x17721855);
+	mmio_write_32((0xf7128000 + 0x108), 0x7501505f);
+	mmio_write_32((0xf7128000 + 0x10c), 0xaf4ca245);
+	mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+	mmio_write_32((0xf7128000 + 0x114), 0x13081306);
+	mmio_write_32((0xf7128000 + 0x118), 0x44);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 8) {
+		NOTICE("fail to init ddr3 rank0\n");
+		return;
+	}
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 1;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x21);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x8)
+		NOTICE("ddr3 rank1 init failure\n");
+	else
+		INFO("ddr3 rank1 init pass\n");
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= ~0xf;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	INFO("succeed to set ddrc 400mhz\n");
+}
+
+void set_ddrc_533mhz(void)
 {
 	unsigned int data;
 
@@ -503,6 +851,7 @@
 	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
 	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
 	mmio_write_32((0xf712c000 + 0x00c), 0x400);
+	mmio_write_32((0xf712c000 + 0x00c), 0x400);
 	mmio_write_32((0xf712c000 + 0x018), 0x7);
 	mmio_write_32((0xf712c000 + 0x090), 0x6400000);
 	mmio_write_32((0xf712c000 + 0x258), 0x640);
@@ -564,10 +913,53 @@
 		NOTICE("failed to init lpddr3 rank0 dram phy\n");
 		return;
 	}
-	NOTICE("succeed to init lpddr3 rank0 dram phy\n");
+	cat_533mhz_800mhz();
+
+	mmio_write_32((0xf712c000 + 0x004), 0xf1);
+	mmio_write_32((0xf7128000 + 0x050), 0x100123);
+	mmio_write_32((0xf7128000 + 0x060), 0x133);
+	mmio_write_32((0xf7128000 + 0x064), 0x133);
+	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+	mmio_write_32((0xf7128000 + 0x100), 0xb77b6718);
+	mmio_write_32((0xf7128000 + 0x104), 0x1e82a071);
+	mmio_write_32((0xf7128000 + 0x108), 0x9501c07e);
+	mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255);
+	mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+	mmio_write_32((0xf7128000 + 0x114), 0x13181908);
+	mmio_write_32((0xf7128000 + 0x118), 0x44);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe) {
+		NOTICE("fail to init ddr3 rank0\n");
+		return;
+	}
+	ddrx_rdet();
+	ddrx_wdet();
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 1;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x21);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe)
+		NOTICE("ddr3 rank1 init failure\n");
+	else
+		INFO("ddr3 rank1 init pass\n");
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= ~0xf;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	INFO("succeed to set ddrc 533mhz\n");
 }
 
-static void set_ddrc_800mhz(void)
+void set_ddrc_800mhz(void)
 {
 	unsigned int data;
 
@@ -581,6 +973,7 @@
 	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
 	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
 	mmio_write_32((0xf712c000 + 0x00c), 0x400);
+	mmio_write_32((0xf712c000 + 0x00c), 0x400);
 	mmio_write_32((0xf712c000 + 0x018), 0x7);
 	mmio_write_32((0xf712c000 + 0x090), 0x5400000);
 	mmio_write_32((0xf712c000 + 0x258), 0x540);
@@ -642,9 +1035,53 @@
 		WARN("failed to init lpddr3 rank0 dram phy\n");
 		return;
 	}
+	cat_533mhz_800mhz();
+
+	mmio_write_32((0xf712c000 + 0x004), 0xf1);
+	mmio_write_32((0xf7128000 + 0x050), 0x100023);
+	mmio_write_32((0xf7128000 + 0x060), 0x133);
+	mmio_write_32((0xf7128000 + 0x064), 0x133);
+	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+	mmio_write_32((0xf7128000 + 0x100), 0x755a9d12);
+	mmio_write_32((0xf7128000 + 0x104), 0x1753b055);
+	mmio_write_32((0xf7128000 + 0x108), 0x7401505f);
+	mmio_write_32((0xf7128000 + 0x10c), 0x578ca244);
+	mmio_write_32((0xf7128000 + 0x110), 0x10700000);
+	mmio_write_32((0xf7128000 + 0x114), 0x13141306);
+	mmio_write_32((0xf7128000 + 0x118), 0x44);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe) {
+		NOTICE("fail to init ddr3 rank0\n");
+		return;
+	}
+	ddrx_rdet();
+	ddrx_wdet();
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 1;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x21);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe)
+		NOTICE("ddr3 rank1 init failure\n");
+	else
+		INFO("ddr3 rank1 init pass\n");
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= ~0xf;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	INFO("succeed to set ddrc 800mhz\n");
 }
 
-static void ddrc_common_init(int ddr800)
+static void ddrc_common_init(int freq)
 {
 	unsigned int data;
 
@@ -653,11 +1090,10 @@
 	mmio_write_32((0xf7120000 + 0x104), 0x71040004);
 	mmio_write_32((0xf7121400 + 0x104), 0xf);
 	mmio_write_32((0xf7121800 + 0x104), 0xf);
-	mmio_write_32((0xf7121800 + 0x104), 0xf);
 	mmio_write_32((0xf7121c00 + 0x104), 0xf);
 	mmio_write_32((0xf7122000 + 0x104), 0xf);
 	mmio_write_32((0xf7128000 + 0x02c), 0x6);
-	mmio_write_32((0xf7128000 + 0x020), 0x1);
+	mmio_write_32((0xf7128000 + 0x020), 0x30003);
 	mmio_write_32((0xf7128000 + 0x028), 0x310201);
 	mmio_write_32((0xf712c000 + 0x1e4), 0xfe007600);
 	mmio_write_32((0xf7128000 + 0x01c), 0xaf001);
@@ -668,10 +1104,10 @@
 	mmio_write_32((0xf7128000 + 0x280), data);
 	mmio_write_32((0xf7128000 + 0x244), 0x3);
 
-	if (ddr800)
-		mmio_write_32((0xf7128000 + 0x240), 167 * 400000 / 1024);
+	if (freq == DDR_FREQ_800M)
+		mmio_write_32((0xf7128000 + 0x240), 167 * (freq / 2) / 1024);
 	else
-		mmio_write_32((0xf7128000 + 0x240), 167 * 533000 / 1024);
+		mmio_write_32((0xf7128000 + 0x240), 167 * freq / 1024);
 
 	data = mmio_read_32((0xf712c000 + 0x080));
 	data &= 0xffff;
@@ -702,20 +1138,24 @@
 		mmio_write_32((0xf7128000 + 0x064), 0x132);
 		mmio_write_32((0xf7120000 + 0x100), 0x1600);
 		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+		mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x40000000);
 		break;
 	case 0x1c:
 		mmio_write_32((0xf7128000 + 0x060), 0x142);
 		mmio_write_32((0xf7128000 + 0x064), 0x142);
 		mmio_write_32((0xf7120000 + 0x100), 0x1700);
 		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+		mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000);
 		break;
 	case 0x58:
 		mmio_write_32((0xf7128000 + 0x060), 0x133);
 		mmio_write_32((0xf7128000 + 0x064), 0x133);
 		mmio_write_32((0xf7120000 + 0x100), 0x1700);
 		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+		mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000);
 		break;
 	default:
+		mmio_write_32(MEMORY_AXI_DDR_CAPACITY_ADDR, 0x80000000);
 		break;
 	}
 	if (!data)
@@ -772,73 +1212,114 @@
 	return data;
 }
 
+void ddr_phy_reset(void)
+{
+	mmio_write_32(0xf7030340, 0xa000);
+	mmio_write_32(0xf7030344, 0xa000);
+}
+
+void lpddrx_save_ddl_para_bypass(uint32_t *ddr_ddl_para, unsigned int index)
+{
+	uint32_t value;
+	uint32_t cnt = index;
+	uint32_t i;
+
+	for (i = 0; i < 4; i++) {
+		value = mmio_read_32(0xf712c000 + 0x22c + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x23c + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x240 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x640 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+	}
+}
+
+void lpddrx_save_ddl_para_mission(uint32_t *ddr_ddl_para, unsigned int index)
+{
+	uint32_t value;
+	uint32_t cnt = index;
+	uint32_t i;
+
+	value = mmio_read_32(0xf712c000 + 0x140);
+	ddr_ddl_para[cnt++] = value;
+	value = mmio_read_32(0xf712c000 + 0x144);
+	ddr_ddl_para[cnt++] = value;
+	value = mmio_read_32(0xf712c000 + 0x148);
+	ddr_ddl_para[cnt++] = value;
+	value = mmio_read_32(0xf712c000 + 0x14c);
+	ddr_ddl_para[cnt++] = value;
+	value = mmio_read_32(0xf712c000 + 0x150);
+	ddr_ddl_para[cnt++] = value;
+	value = mmio_read_32(0xf712c000 + 0x1d4);
+	ddr_ddl_para[cnt++] = value;
+	for (i = 0; i < 4; i++) {
+		value = mmio_read_32(0xf712c000 + 0x210 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x214 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x218 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x21c + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x220 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x224 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x228 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x22c + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x230 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x234 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x238 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x23c + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x240 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+		value = mmio_read_32(0xf712c000 + 0x640 + i * 0x80);
+		ddr_ddl_para[cnt++] = value;
+	}
+	value = mmio_read_32(0xf712c000 + 0x168);
+	ddr_ddl_para[cnt++] = value;
+	value = mmio_read_32(0xf712c000 + 0x24c + 0 * 0x80);
+	ddr_ddl_para[cnt++] = value;
+	value = mmio_read_32(0xf712c000 + 0x24c + 2 * 0x80);
+	ddr_ddl_para[cnt++] = value;
+}
+
 int lpddr3_freq_init(int freq)
 {
-	unsigned int data;
-
-	if (freq == DDR_FREQ_800M) {
-		set_ddrc_800mhz();
-		INFO("%s, set ddrc 800mhz\n", __func__);
-	} else {
+	set_ddrc_150mhz();
+	lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR, 0);
+	if (freq > DDR_FREQ_150M) {
+		ddr_phy_reset();
+		set_ddrc_266mhz();
+		lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
+					    16);
+	}
+	if (freq > DDR_FREQ_266M) {
+		ddr_phy_reset();
+		set_ddrc_400mhz();
+		lpddrx_save_ddl_para_bypass((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
+					    16 * 2);
+	}
+	if (freq > DDR_FREQ_400M) {
+		ddr_phy_reset();
 		set_ddrc_533mhz();
-		INFO("%s, set ddrc 533mhz\n", __func__);
+		lpddrx_save_ddl_para_mission((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
+					     16 * 3);
 	}
-
-	mmio_write_32((0xf712c000 + 0x004), 0xf1);
-	if (freq == DDR_FREQ_800M)
-		mmio_write_32((0xf7128000 + 0x050), 0x100023);
-	else
-		mmio_write_32((0xf7128000 + 0x050), 0x100123);
-	mmio_write_32((0xf7128000 + 0x060), 0x133);
-	mmio_write_32((0xf7128000 + 0x064), 0x133);
-	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
-
-	if (freq == DDR_FREQ_800M) {
-		mmio_write_32((0xf7128000 + 0x100), 0x755a9d12);
-		mmio_write_32((0xf7128000 + 0x104), 0x1753b055);
-		mmio_write_32((0xf7128000 + 0x108), 0x7401505f);
-		mmio_write_32((0xf7128000 + 0x10c), 0x578ca244);
-		mmio_write_32((0xf7128000 + 0x110), 0x10700000);
-		mmio_write_32((0xf7128000 + 0x114), 0x13141306);
-	} else {
-		mmio_write_32((0xf7128000 + 0x100), 0xb77b6718);
-		mmio_write_32((0xf7128000 + 0x104), 0x1e82a071);
-		mmio_write_32((0xf7128000 + 0x108), 0x9501c07e);
-		mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255);
-		mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
-		mmio_write_32((0xf7128000 + 0x114), 0x13181908);
+	if (freq > DDR_FREQ_533M) {
+		ddr_phy_reset();
+		set_ddrc_800mhz();
+		lpddrx_save_ddl_para_mission((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
+					     16 * 3 + 61);
 	}
-	mmio_write_32((0xf7128000 + 0x118), 0x44);
-	do {
-		data = mmio_read_32((0xf712c000 + 0x004));
-	} while (data & 1);
-
-	data = mmio_read_32((0xf712c000 + 0x008));
-	if (data & 0x7fe) {
-		NOTICE("fail to init ddr3 rank0\n");
-		return -EFAULT;
-	}
-	INFO("init ddr3 rank0\n");
-	ddrx_rdet();
-	ddrx_wdet();
-
-	data = mmio_read_32((0xf712c000 + 0x048));
-	data |= 1;
-	mmio_write_32((0xf712c000 + 0x048), data);
-	mmio_write_32((0xf712c000 + 0x004), 0x21);
-	do {
-		data = mmio_read_32((0xf712c000 + 0x004));
-	} while (data & 1);
-
-	data = mmio_read_32((0xf712c000 + 0x008));
-	if (data & 0x7fe)
-		NOTICE("ddr3 rank1 init failure\n");
-	else
-		INFO("ddr3 rank1 init pass\n");
-
-	data = mmio_read_32((0xf712c000 + 0x048));
-	data &= ~0xf;
-	mmio_write_32((0xf712c000 + 0x048), data);
 	return 0;
 }
 
@@ -855,7 +1336,7 @@
 	data |= 1;
 	mmio_write_32((0xf7032000 + 0x010), data);
 
-	udelay(100);
+	udelay(300);
 	do {
 		data = mmio_read_32((0xf7032000 + 0x030));
 		data &= 3 << 28;
@@ -923,38 +1404,40 @@
 	mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
 }
 
-static void ddr_phy_reset(void)
-{
-	mmio_write_32(0xf7030340, 0xa000);
-	mmio_write_32(0xf7030344, 0xa000);
-}
-
-void hikey_ddr_init(void)
+void hikey_ddr_init(unsigned int ddr_freq)
 {
 	uint32_t data;
 
+	assert((ddr_freq == DDR_FREQ_150M) || (ddr_freq == DDR_FREQ_266M) ||
+	       (ddr_freq == DDR_FREQ_400M) || (ddr_freq == DDR_FREQ_533M) ||
+	       (ddr_freq == DDR_FREQ_800M));
 	init_pll();
 	init_freq();
 
-	/*
-	 * Init DDR with 533MHz. Otherwise, DDR initialization
-	 * may fail on 800MHz on some boards.
-	 */
-	ddr_phy_reset();
-	init_ddr(DDR_FREQ_533M);
-	/* Init DDR with 800MHz. */
-	ddr_phy_reset();
-	init_ddr(DDR_FREQ_800M);
+	init_ddr(ddr_freq);
 
-
-	ddrc_common_init(1);
+	ddrc_common_init(ddr_freq);
 	dienum_det_and_rowcol_cfg();
 	detect_ddr_chip_info();
 
-	data = mmio_read_32(0xf7032000 + 0x010);
-	data &= ~0x1;
-	mmio_write_32(0xf7032000 + 0x010, data);
-	data = mmio_read_32(0xf7032000 + 0x010);
+	if ((ddr_freq == DDR_FREQ_400M) || (ddr_freq == DDR_FREQ_800M)) {
+		data = mmio_read_32(0xf7032000 + 0x010);
+		data &= ~0x1;
+		mmio_write_32(0xf7032000 + 0x010, data);
+	} else if ((ddr_freq == DDR_FREQ_266M) || (ddr_freq == DDR_FREQ_533M)) {
+		data = mmio_read_32(0xf7032000 + 0x030);
+		data &= ~0x1;
+		mmio_write_32(0xf7032000 + 0x030, data);
+	} else {
+		data = mmio_read_32(0xf7032000 + 0x010);
+		data &= ~0x1;
+		mmio_write_32(0xf7032000 + 0x010, data);
+		data = mmio_read_32(0xf7032000 + 0x030);
+		data &= ~0x1;
+		mmio_write_32(0xf7032000 + 0x030, data);
+	}
+	dsb();
+	isb();
 
 	/*
 	 * Test memory access. Do not use address 0x0 because the compiler
diff --git a/plat/hisilicon/hikey/hikey_private.h b/plat/hisilicon/hikey/hikey_private.h
index 7654921..e6d109a 100644
--- a/plat/hisilicon/hikey/hikey_private.h
+++ b/plat/hisilicon/hikey/hikey_private.h
@@ -12,6 +12,14 @@
 #define RANDOM_MAX		0x7fffffffffffffff
 #define RANDOM_MAGIC		0x9a4dbeaf
 
+enum {
+	DDR_FREQ_150M = 150 * 1000,
+	DDR_FREQ_266M = 266 * 1000,
+	DDR_FREQ_400M = 400 * 1000,
+	DDR_FREQ_533M = 533 * 1000,
+	DDR_FREQ_800M = 800 * 1000
+};
+
 struct random_serial_num {
 	uint64_t	magic;
 	uint64_t	data;
@@ -34,7 +42,7 @@
 			unsigned long coh_start,
 			unsigned long coh_limit);
 
-void hikey_ddr_init(void);
+void hikey_ddr_init(unsigned int ddr_freq);
 void hikey_io_setup(void);
 
 void hikey_sp804_init(void);
diff --git a/plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S b/plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S
new file mode 100644
index 0000000..80524fc
--- /dev/null
+++ b/plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+	.globl	plat_reset_handler
+	.globl  plat_my_core_pos
+	.globl  platform_mem_init
+
+func plat_my_core_pos
+	mrs x0, mpidr_el1
+	and x1, x0, #MPIDR_CPU_MASK   //reserve the last 8 bits
+	and x0, x0, #MPIDR_CLUSTER_MASK
+	add x0, x1, x0, LSR #4  //4 cores
+	ret
+endfunc plat_my_core_pos
+
+func platform_mem_init
+	mov x29, x30
+	bl  inv_dcache_range
+
+//SDRAM_CFG
+	ldr w0, =0x1080000
+	ldr w1, =0x0c000c45
+	str w1, [x0, #0x110]
+//CS0_BNDS
+	ldr w1, =0x7f000000
+	str w1, [x0, #0x000]
+//CS0_CONFIG
+	ldr w1, =0x22030480
+	str w1, [x0, #0x080]
+//TIMING_CFG_0
+	ldr w1, =0x18005591
+	str w1, [x0, #0x104]
+//TIMING_CFG_1
+	ldr w1, =0x428cb4bb
+	str w1, [x0, #0x108]
+//TIMING_CFG_2
+	ldr w1, =0x11c14800
+	str w1, [x0, #0x10C]
+//TIMING_CFG_3
+	ldr w1, =0x00100c01
+	str w1, [x0, #0x100]
+//TIMING_CFG_4
+	ldr w1, =0x02000000
+	str w1, [x0, #0x160]
+//TIMING_CFG_5
+	ldr w1, =0x00144003
+	str w1, [x0, #0x164]
+//TIMING_CFG_7
+	ldr w1, =0x00003013
+	str w1, [x0, #0x16C]
+//TIMING_CFG_8
+	ldr w1, =0x00561102
+	str w1, [x0, #0x250]
+//SDRAM_CFG_2
+	ldr w1, =0x00114000
+	str w1, [x0, #0x114]
+//SDRAM_MODE
+	ldr w1, =0x10020103
+	str w1, [x0, #0x118]
+//SDRAM_MODE_2
+	ldr w1, =0x0
+	str w1, [x0, #0x11C]
+//SDRAM_INTERVAL
+	ldr w1, =0x18066018
+	str w1, [x0, #0x124]
+//DDR_WRLVL_CNTL
+	ldr w1, =0x07f675c6
+	str w1, [x0, #0x174]
+//DDR_WRLVL_CNTL_2
+	ldr w1, =0x00080907
+	str w1, [x0, #0x190]
+//DDR_WRLVL_CNTL_3
+	ldr w1, =0x0
+	str w1, [x0, #0x194]
+//DDR_CDR1
+	ldr w1, =0x00000480
+	str w1, [x0, #0xB28]
+//DDR_CDR2
+	ldr w1, =0x81a10000
+	str w1, [x0, #0xB2C]
+//SDRAM_CLK_CNTL
+	ldr w1, =0x00000003
+	str w1, [x0, #0x130]
+//DDR_ZQ_CNTL
+	ldr w1, =0x0507098a
+	str w1, [x0, #0x170]
+//SDRAM_MODE_9
+	ldr w1, =0x00050000
+	str w1, [x0, #0x220]
+//SDRAM_MODE_10
+	ldr w1, =0x00000004
+	str w1, [x0, #0x224]
+//CS0_CONFIG_2
+	ldr w1, =0x0
+	str w1, [x0, #0x0C0]
+//SDRAM_CFG
+	ldr w1, =0x08000cc5
+	str w1, [x0, #0x110]
+
+	mov w3,#0
+	ldr w4,=0xffffff01
+z_loop:
+delay_loop1:
+	sub w4, w4, #1
+	cmp w4, #0
+	b.gt    delay_loop1
+
+	ldr w1, [x0, #0x114]
+	add w3, w3, #1
+	cmp       w1, #0 //'\n'
+	b.eq       1f
+	cmp w3, #20
+	b.gt    1f
+	b z_loop
+
+1:
+	ldr w4,=0xffffff02
+delay_loop2:
+	sub w4, w4, #1
+	cmp w4, #0
+	b.gt        delay_loop2
+
+	ldr w1, =0x00000000
+	str w1, [x0]
+
+	ret x29
+endfunc	platform_mem_init
+
+func apply_platform_errata
+	/*TODO if needed*/
+	ret
+endfunc apply_platform_errata
+
+func plat_reset_handler
+	mov x29, x30
+	bl  apply_platform_errata
+
+	mov x30, x29
+	ret
+endfunc plat_reset_handler
diff --git a/plat/layerscape/board/ls1043/include/ls_def.h b/plat/layerscape/board/ls1043/include/ls_def.h
new file mode 100644
index 0000000..1015129
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/ls_def.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __LS_DEF_H__
+#define __LS_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <platform_def.h>
+#include <tbbr_img_def.h>
+#include <utils_def.h>
+#include <xlat_tables_defs.h>
+
+
+/******************************************************************************
+ * Definitions common to all ARM standard platforms
+ *****************************************************************************/
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define LS_BL31_PLAT_PARAM_VAL		0x0f1e2d3c4b5a6978ULL
+
+#define LS_CACHE_WRITEBACK_SHIFT	6
+
+/*
+ * Macros mapping the MPIDR Affinity levels to Layerscape Platform Power levels. The
+ * power levels have a 1:1 mapping with the MPIDR affinity levels.
+ */
+#define LS_PWR_LVL0		MPIDR_AFFLVL0
+#define LS_PWR_LVL1		MPIDR_AFFLVL1
+#define LS_PWR_LVL2		MPIDR_AFFLVL2
+
+/*
+ *  Macros for local power states in Layerscape platforms encoded by State-ID field
+ *  within the power-state parameter.
+ */
+/* Local power state for power domains in Run state. */
+#define LS_LOCAL_STATE_RUN	0
+/* Local power state for retention. Valid only for CPU power domains */
+#define LS_LOCAL_STATE_RET	1
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains
+ */
+#define LS_LOCAL_STATE_OFF	2
+
+#define LS_MAP_NS_DRAM		MAP_REGION_FLAT( \
+					(LS_NS_DRAM_BASE), \
+					LS_DRAM1_SIZE, \
+					MT_DEVICE | MT_RW | MT_NS)
+
+#define LS_MAP_TSP_SEC_MEM	MAP_REGION_FLAT( \
+					TSP_SEC_MEM_BASE, \
+					TSP_SEC_MEM_SIZE, \
+				MT_DEVICE | MT_RW | MT_SECURE)
+
+
+#define LS_MAP_FLASH0_RW	MAP_REGION_FLAT(PLAT_LS_FLASH_BASE,\
+					PLAT_LS_FLASH_SIZE, \
+					MT_DEVICE | MT_RW)
+
+#define LS_MAP_CCSR		MAP_REGION_FLAT(PLAT_LS_CCSR_BASE, \
+					PLAT_LS_CCSR_SIZE, \
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+
+#define LS_MAP_CONSOLE		MAP_REGION_FLAT(PLAT_LS1043_DUART1_BASE, \
+					PLAT_LS1043_DUART_SIZE, \
+					MT_DEVICE | MT_RW | MT_NS)
+
+/*
+ * The number of regions like RO(code), coherent and data required by
+ * different BL stages which need to be mapped in the MMU.
+ */
+/******************************************************************************
+ * Required platform porting definitions common to all ARM standard platforms
+ *****************************************************************************/
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 32)
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE		LS_LOCAL_STATE_RET
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE		LS_LOCAL_STATE_OFF
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_GRANULE		(1 << LS_CACHE_WRITEBACK_SHIFT)
+
+/*
+ * One cache line needed for bakery locks on Layerscape platforms
+ */
+#define PLAT_PERCPU_BAKERY_LOCK_SIZE		(1 * CACHE_WRITEBACK_GRANULE)
+
+#endif /* __LS_DEF_H__ */
diff --git a/plat/layerscape/board/ls1043/include/ns_access.h b/plat/layerscape/board/ls1043/include/ns_access.h
new file mode 100644
index 0000000..6ed7bc0
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/ns_access.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FSL_NS_ACCESS_H_
+#define __FSL_NS_ACCESS_H_
+
+#include "fsl_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,
+};
+
+static struct csu_ns_dev 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_ALL_RW},
+	 {CSU_CSLX_GIC, CSU_ALL_RW},
+	 {CSU_CSLX_PCIE1, CSU_ALL_RW},
+	 {CSU_CSLX_OCRAM2, CSU_ALL_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
diff --git a/plat/layerscape/board/ls1043/include/plat_macros.S b/plat/layerscape/board/ls1043/include/plat_macros.S
new file mode 100644
index 0000000..8163dc1
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/plat_macros.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+	/* ---------------------------------------------
+	 * The below required platform porting macro
+	 * prints out relevant 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/layerscape/board/ls1043/include/platform_def.h b/plat/layerscape/board/ls1043/include/platform_def.h
new file mode 100644
index 0000000..0e1cae6
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/platform_def.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <common_def.h>
+#include <tzc400.h>
+#include <utils.h>
+#include "ls_def.h"
+
+#define FIRMWARE_WELCOME_STR_LS1043	"Welcome to LS1043 BL1 Phase\n"
+#define FIRMWARE_WELCOME_STR_LS1043_BL2	"Welcome to LS1043 BL2 Phase\n"
+#define FIRMWARE_WELCOME_STR_LS1043_BL31 "Welcome to LS1043 BL31 Phase\n"
+#define FIRMWARE_WELCOME_STR_LS1043_BL32 "Welcome to LS1043 BL32 Phase, TSP\n"
+
+/* Required platform porting definitions */
+#define PLAT_PRIMARY_CPU		0x0
+#define PLAT_MAX_PWR_LVL		LS_PWR_LVL1
+#define PLATFORM_CORE_COUNT		4
+#define COUNTER_FREQUENCY		25000000	/* 25MHz */
+
+/*
+ * Required LS standard platform porting definitions
+ */
+#define PLAT_LS_CLUSTER_COUNT			1
+#define PLAT_LS1043_CCI_CLUSTER0_SL_IFACE_IX	4
+#define LS1043_CLUSTER_COUNT			1
+#define LS1043_MAX_CPUS_PER_CLUSTER		4
+
+#define LS_DRAM1_BASE			0x80000000
+#define LS_DRAM2_BASE			0x880000000
+#define LS_DRAM2_SIZE			0x780000000	/* 30G */
+#define LS_DRAM1_SIZE			0x80000000	/* 2G */
+#define LS_NS_DRAM_BASE			LS_DRAM1_BASE
+/* 64M Secure Memory, in fact there a 2M non-secure hole on top of it */
+#define LS_SECURE_DRAM_SIZE		(64 * 1024 * 1024)
+#define LS_SECURE_DRAM_BASE		(LS_NS_DRAM_BASE + LS_DRAM1_SIZE - \
+						LS_SECURE_DRAM_SIZE)
+#define LS_NS_DRAM_SIZE			(LS_DRAM1_SIZE - LS_SECURE_DRAM_SIZE)
+
+/*
+ * By default, BL2 is in DDR memory.
+ * If LS_BL2_IN_OCRAM is defined, BL2 will in OCRAM
+ */
+/* #define LS_BL2_IN_OCRAM */
+
+#ifndef LS_BL2_IN_OCRAM
+/*
+ * on top of SECURE memory is 2M non-secure hole for OPTee,
+ *  1M secure memory below this hole will be used for BL2.
+ */
+#define LS_BL2_DDR_BASE			(LS_SECURE_DRAM_BASE + \
+						LS_SECURE_DRAM_SIZE \
+						- 3 * 1024 * 1024)
+#endif
+
+#define PLAT_LS_CCSR_BASE		0x1000000
+#define PLAT_LS_CCSR_SIZE		0xF000000
+
+/* Flash base address, currently ROM is not used for TF-A images on LS platforms */
+#define PLAT_LS_TRUSTED_ROM_BASE	0x60100000
+#define PLAT_LS_TRUSTED_ROM_SIZE	0x20000000	/* Flash size */
+#define PLAT_LS_FLASH_SIZE		0x20000000
+#define PLAT_LS_FLASH_BASE		0x60000000
+
+#define LS_SRAM_BASE			0x10000000
+#define LS_SRAM_LIMIT			0x10020000	/* 128K */
+#define LS_SRAM_SHARED_SIZE		0x1000		/* 4K */
+#define LS_SRAM_SIZE			(LS_SRAM_LIMIT - LS_SRAM_BASE)
+#define LS_BL_RAM_BASE			(LS_SRAM_BASE + LS_SRAM_SHARED_SIZE)
+
+#define PLAT_LS_FIP_MAX_SIZE		0x4000000
+
+/* Memory Layout */
+
+#define BL1_RO_BASE			PLAT_LS_TRUSTED_ROM_BASE
+#define BL1_RO_LIMIT			(PLAT_LS_TRUSTED_ROM_BASE	\
+					 + PLAT_LS_TRUSTED_ROM_SIZE)
+#define PLAT_LS_FIP_BASE		0x60120000
+
+#ifdef LS_BL2_IN_OCRAM
+/* BL2 is in OCRAM */
+#define PLAT_LS_MAX_BL1_RW_SIZE		(52 * 1024)		/* 52K */
+#define PLAT_LS_MAX_BL31_SIZE		(64 * 1024)		/* 64K */
+#define PLAT_LS_MAX_BL2_SIZE		(44 * 1024)		/* 44K */
+/* Reserve memory in OCRAM for BL31 Text and ROData segment */
+#define BL31_TEXT_RODATA_SIZE		(32 * 1024)		/* 32K */
+#else /* LS_BL2_IN_OCRAM */
+/* BL2 in DDR */
+#define PLAT_LS_MAX_BL1_RW_SIZE		(64 * 1024)		/* 64K */
+#define PLAT_LS_MAX_BL31_SIZE		(64 * 1024)		/* 64K */
+#define PLAT_LS_MAX_BL2_SIZE		(1 * 1024 * 1024)	/* 1M */
+#endif /* LS_BL2_IN_OCRAM */
+/*
+ * Put BL31 at the start of OCRAM.
+ */
+#define BL31_BASE			LS_SRAM_BASE
+#define BL31_LIMIT			(LS_SRAM_BASE + PLAT_LS_MAX_BL31_SIZE)
+
+#ifdef LS_BL2_IN_OCRAM
+/*
+ * BL2 follow BL31 Text and ROData region.
+ */
+#define BL2_BASE			(BL31_BASE + BL31_TEXT_RODATA_SIZE)
+#define BL2_LIMIT			(BL2_BASE + PLAT_LS_MAX_BL2_SIZE)
+
+#else
+/*
+ * BL2 in DDR memory.
+ */
+#define BL2_BASE			LS_BL2_DDR_BASE
+#define BL2_LIMIT			(BL2_BASE + PLAT_LS_MAX_BL2_SIZE)
+
+#endif
+
+/*
+ * Put BL1 RW at the top of the Trusted SRAM.
+ */
+#ifdef LS_BL2_IN_OCRAM
+#define BL1_RW_BASE			BL2_LIMIT
+#else
+#define BL1_RW_BASE			BL31_LIMIT
+#endif
+#define BL1_RW_LIMIT			LS_SRAM_LIMIT
+
+/* Put BL32 in secure memory */
+#define BL32_BASE		LS_SECURE_DRAM_BASE
+#define BL32_LIMIT		(LS_SECURE_DRAM_BASE + LS_SECURE_DRAM_SIZE)
+/* BL33 memory region */
+#define BL33_BASE		0x82000000
+#define BL33_LIMIT		(LS_NS_DRAM_BASE + LS_NS_DRAM_SIZE)
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+/*
+ * On ARM standard platforms, the TSP can execute from Trusted SRAM,
+ * Trusted DRAM (if available) or the DRAM region secured by the TrustZone
+ * controller.
+ */
+
+#define TSP_SEC_MEM_BASE		BL32_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE)
+
+/*
+ * ID of the secure physical generic timer interrupt used by the TSP.
+ */
+#define TSP_IRQ_SEC_PHY_TIMER		29
+
+
+/*
+ * GIC related constants
+ */
+#define PLAT_LS1043_CCI_BASE		0x01180000
+#define GICD_BASE			0x01401000
+#define GICC_BASE			0x01402000
+#define GICD_BASE_64K			0x01410000
+#define GICC_BASE_64K			0x01420000
+
+#define DCFG_CCSR_SVR			0x1ee00a4
+#define REV1_0				0x10
+#define REV1_1				0x11
+#define GIC_ADDR_BIT			31
+#define SCFG_GIC400_ALIGN		0x1570188
+
+/* UART related definition */
+
+#define PLAT_LS1043_DUART1_BASE		0x021c0000
+#define PLAT_LS1043_DUART2_BASE		0x021d0000
+#define PLAT_LS1043_DUART_SIZE		0x10000
+
+#define PLAT_LS1043_UART_BASE		0x21c0500
+#define PLAT_LS1043_UART2_BASE		0x21c0600
+#define PLAT_LS1043_UART_CLOCK		400000000
+#define PLAT_LS1043_UART_BAUDRATE	115200
+/* Define UART to be used by TF-A log */
+#define LS_TF_UART_BASE		PLAT_LS1043_UART_BASE
+#define LS_TF_UART_CLOCK		PLAT_LS1043_UART_CLOCK
+#define LS_TF_UART_BAUDRATE		PLAT_LS1043_UART_BAUDRATE
+
+#define LS1043_SYS_CNTCTL_BASE		0x2B00000
+
+#define CONFIG_SYS_IMMR			0x01000000
+#define CONFIG_SYS_FSL_CSU_ADDR		(CONFIG_SYS_IMMR + 0x00510000)
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL1)
+#define PLATFORM_STACK_SIZE		0x440
+#define MAX_MMAP_REGIONS		6
+#define MAX_XLAT_TABLES			4
+#elif defined(IMAGE_BL2)
+#define PLATFORM_STACK_SIZE		0x400
+#define MAX_MMAP_REGIONS		8
+#define MAX_XLAT_TABLES			6
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE		0x400
+#define MAX_MMAP_REGIONS		8
+#define MAX_XLAT_TABLES			4
+#elif defined(IMAGE_BL32)
+#define PLATFORM_STACK_SIZE		0x440
+#define MAX_MMAP_REGIONS		8
+#define MAX_XLAT_TABLES			9
+#endif
+
+#define MAX_IO_DEVICES			3
+#define MAX_IO_HANDLES			4
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/layerscape/board/ls1043/include/soc_tzasc.h b/plat/layerscape/board/ls1043/include/soc_tzasc.h
new file mode 100644
index 0000000..0039f2d
--- /dev/null
+++ b/plat/layerscape/board/ls1043/include/soc_tzasc.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SOC_TZASC_H_
+#define _SOC_TZASC_H_
+
+#include "tzc380.h"
+
+#define MAX_NUM_TZC_REGION	3
+
+/* TZASC related constants */
+#define TZASC_CONFIGURATION_REG		0x000
+#define TZASC_SECURITY_INV_REG		0x034
+#define TZASC_SECURITY_INV_EN		0x1
+#define TZASC_REGIONS_REG		0x100
+/* As region address should address atleast 32KB memory. */
+#define TZASC_REGION_LOWADDR_MASK	0xFFFF8000
+#define TZASC_REGION_LOWADDR_OFFSET	0x0
+#define TZASC_REGION_HIGHADDR_OFFSET	0x4
+#define TZASC_REGION_ATTR_OFFSET	0x8
+#define TZASC_REGION_ENABLED		1
+#define TZASC_REGION_DISABLED		0
+#define TZASC_REGION_SIZE_32KB		0xE
+#define TZASC_REGION_SIZE_64KB		0xF
+#define TZASC_REGION_SIZE_128KB		0x10
+#define TZASC_REGION_SIZE_256KB		0x11
+#define TZASC_REGION_SIZE_512KB		0x12
+#define TZASC_REGION_SIZE_1MB		0x13
+#define TZASC_REGION_SIZE_2MB		0x14
+#define TZASC_REGION_SIZE_4MB		0x15
+#define TZASC_REGION_SIZE_8MB		0x16
+#define TZASC_REGION_SIZE_16MB		0x17
+#define TZASC_REGION_SIZE_32MB		0x18
+#define TZASC_REGION_SIZE_64MB		0x19
+#define TZASC_REGION_SIZE_128MB		0x1A
+#define TZASC_REGION_SIZE_256MB		0x1B
+#define TZASC_REGION_SIZE_512MB		0x1C
+#define TZASC_REGION_SIZE_1GB		0x1D
+#define TZASC_REGION_SIZE_2GB		0x1E
+#define TZASC_REGION_SIZE_4GB		0x1F
+#define TZASC_REGION_SIZE_8GB		0x20
+#define TZASC_REGION_SIZE_16GB		0x21
+#define TZASC_REGION_SIZE_32GB		0x22
+#define TZASC_REGION_SECURITY_SR	(1 << 3)
+#define TZASC_REGION_SECURITY_SW	(1 << 2)
+#define TZASC_REGION_SECURITY_SRW	(TZASC_REGION_SECURITY_SR| \
+						TZASC_REGION_SECURITY_SW)
+#define TZASC_REGION_SECURITY_NSR	(1 << 1)
+#define TZASC_REGION_SECURITY_NSW	1
+#define TZASC_REGION_SECURITY_NSRW	(TZASC_REGION_SECURITY_NSR| \
+						TZASC_REGION_SECURITY_NSW)
+
+#define CSU_SEC_ACCESS_REG_OFFSET	0x21C
+#define TZASC_BYPASS_MUX_DISABLE	0x4
+#define CCI_TERMINATE_BARRIER_TX	0x8
+#define CONFIG_SYS_FSL_TZASC_ADDR	0x1500000
+
+/* List of MAX_NUM_TZC_REGION TZC regions' boundaries and configurations. */
+
+static const struct tzc380_reg tzc380_reg_list[] = {
+	{
+		TZASC_REGION_SECURITY_NSRW,	/* .secure attr */
+		0x0,			/* .enabled */
+		0x0,			/* .lowaddr */
+		0x0,			/* .highaddr */
+		0x0,			/* .size */
+		0x0,			/* .submask */
+	},
+	{
+		TZASC_REGION_SECURITY_SRW,
+		TZASC_REGION_ENABLED,
+		0xFC000000,
+		0x0,
+		TZASC_REGION_SIZE_64MB,
+		0x80,			/* Disable region 7 */
+	},
+	/* reserve 2M non-scure memory for OPTEE public memory */
+	{
+		TZASC_REGION_SECURITY_SRW,
+		TZASC_REGION_ENABLED,
+		0xFF800000,
+		0x0,
+		TZASC_REGION_SIZE_8MB,
+		0xC0,			/* Disable region 6 & 7 */
+	},
+
+	{}
+};
+
+#endif /* _SOC_TZASC_H_ */
diff --git a/plat/layerscape/board/ls1043/ls1043_bl1_setup.c b/plat/layerscape/board/ls1043/ls1043_bl1_setup.c
new file mode 100644
index 0000000..e82a1fb
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_bl1_setup.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cci.h>
+#include <debug.h>
+#include <mmio.h>
+#include "plat_ls.h"
+
+static const int cci_map[] = {
+	PLAT_LS1043_CCI_CLUSTER0_SL_IFACE_IX
+};
+
+void bl1_platform_setup(void)
+{
+	NOTICE(FIRMWARE_WELCOME_STR_LS1043);
+
+	ls_bl1_platform_setup();
+
+	/*
+	 * Initialize system level generic timer for Layerscape Socs.
+	 */
+	ls_delay_timer_init();
+
+	/* TODO: remove these DDR code */
+	VERBOSE("CS0_BNDS = %x\n", mmio_read_32(0x1080000 + 0x000));
+	mmio_write_32(0x1080000 + 0x000, 0x7f000000);
+	VERBOSE("CS0_BNDS = %x\n", mmio_read_32(0x1080000 + 0x000));
+}
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+	ls_bl1_early_platform_setup();
+
+	/*
+	 * Initialize Interconnect for this cluster during cold boot.
+	 * No need for locks as no other CPU is active.
+	 */
+	cci_init(PLAT_LS1043_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
+
+	/*
+	 * Enable coherency in Interconnect for the primary CPU's cluster.
+	 */
+	cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
+
+}
+
+unsigned int bl1_plat_get_next_image_id(void)
+{
+	return BL2_IMAGE_ID;
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_bl2_setup.c b/plat/layerscape/board/ls1043/ls1043_bl2_setup.c
new file mode 100644
index 0000000..b529aa5
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_bl2_setup.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <debug.h>
+#include "plat_ls.h"
+
+void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+		u_register_t arg2, u_register_t arg3)
+{
+	ls_bl2_early_platform_setup((meminfo_t *)arg1);
+
+	/*
+	 * Initialize system level generic timer for Layerscape Socs.
+	 */
+	ls_delay_timer_init();
+}
+
+void bl2_platform_setup(void)
+{
+	NOTICE(FIRMWARE_WELCOME_STR_LS1043_BL2);
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_bl31_setup.c b/plat/layerscape/board/ls1043/ls1043_bl31_setup.c
new file mode 100644
index 0000000..3473d98
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_bl31_setup.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cci.h>
+#include <debug.h>
+#include "plat_ls.h"
+#include "fsl_csu.h"
+
+/* slave interfaces according to the RM */
+static const int cci_map[] = {
+	4,
+};
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+		u_register_t arg2, u_register_t arg3)
+{
+#ifdef LS_BL2_IN_OCRAM
+	unsigned long romem_base = (unsigned long)(&__TEXT_START__);
+	unsigned long romem_size = (unsigned long)(&__RODATA_END__)
+					- romem_base;
+
+	/* Check the Text and RO-Data region size */
+	if (romem_size > BL31_TEXT_RODATA_SIZE) {
+		ERROR("BL31 Text and RO-Data region size exceed reserved memory size\n");
+		panic();
+	}
+#endif
+
+	/*
+	 * Initialize system level generic timer for Layerscape Socs.
+	 */
+	ls_delay_timer_init();
+
+	ls_bl31_early_platform_setup((void *)arg0, (void *)arg3);
+
+	/*
+	 * Initialize the correct interconnect for this cluster during cold
+	 * boot. No need for locks as no other CPU is active.
+	 */
+	cci_init(PLAT_LS1043_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
+
+	/*
+	 * Enable coherency in interconnect for the primary CPU's cluster.
+	 * Earlier bootloader stages might already do this (e.g. Trusted
+	 * Firmware's BL1 does it) but we can't assume so. There is no harm in
+	 * executing this code twice anyway.
+	 */
+	cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr()));
+
+	/* Init CSU to enable non-secure access to peripherals */
+	enable_layerscape_ns_access();
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_err.c b/plat/layerscape/board/ls1043/ls1043_err.c
new file mode 100644
index 0000000..e4a2cae
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_err.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdint.h>
+
+/*
+ * Error handler
+ */
+void plat_error_handler(int err)
+{
+	switch (err) {
+	case -ENOENT:
+	case -EAUTH:
+		/* ToDo */
+		break;
+	default:
+		/* Unexpected error */
+		break;
+	}
+
+	/* Loop until the watchdog resets the system */
+	for (;;)
+		wfi();
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_psci.c b/plat/layerscape/board/ls1043/ls1043_psci.c
new file mode 100644
index 0000000..1c83df4
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_psci.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
+#include <assert.h>
+#include <platform.h>
+#include <psci.h>
+#include <mmio.h>
+#include <sys/endian.h>
+#include <gicv2.h>
+#include <delay_timer.h>
+#include "platform_def.h"
+
+#define LS_SCFG_BASE			0x01570000
+/* register to store warm boot entry, big endian, higher 32bit */
+#define LS_SCFG_SCRATCHRW0_OFFSET	     0x600
+/* register to store warm boot entry, big endian, lower 32bit */
+#define LS_SCFG_SCRATCHRW1_OFFSET	     0x604
+#define LS_SCFG_COREBCR_OFFSET		     0x680
+
+#define LS_DCFG_BASE			0x01EE0000
+#define LS_DCFG_RSTCR_OFFSET		     0x0B0
+#define LS_DCFG_RSTRQMR1_OFFSET		     0x0C0
+#define LS_DCFG_BRR_OFFSET		     0x0E4
+
+#define LS_SCFG_CORE0_SFT_RST_OFFSET		0x130
+#define LS_SCFG_CORE1_SFT_RST_OFFSET		0x134
+#define LS_SCFG_CORE2_SFT_RST_OFFSET		0x138
+#define LS_SCFG_CORE3_SFT_RST_OFFSET		0x13C
+
+#define LS_SCFG_CORESRENCR_OFFSET		0x204
+
+#define LS_SCFG_RVBAR0_0_OFFSET			0x220
+#define LS_SCFG_RVBAR0_1_OFFSET			0x224
+
+#define LS_SCFG_RVBAR1_0_OFFSET			0x228
+#define LS_SCFG_RVBAR1_1_OFFSET			0x22C
+
+#define LS_SCFG_RVBAR2_0_OFFSET			0x230
+#define LS_SCFG_RVBAR2_1_OFFSET			0x234
+
+#define LS_SCFG_RVBAR3_0_OFFSET			0x238
+#define LS_SCFG_RVBAR3_1_OFFSET			0x23C
+
+/* the entry for core warm boot */
+static uintptr_t warmboot_entry;
+
+/* warm reset single core */
+static void ls1043_reset_core(int core_pos)
+{
+	assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+
+	/* set 0 in RVBAR, boot from bootrom at 0x0 */
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_0_OFFSET + core_pos * 8,
+		      0);
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_RVBAR0_1_OFFSET + core_pos * 8,
+		      0);
+
+	dsb();
+	/* enable core soft reset */
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORESRENCR_OFFSET,
+		      htobe32(1 << 31));
+	dsb();
+	isb();
+	/* reset core */
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_CORE0_SFT_RST_OFFSET +
+			core_pos * 4, htobe32(1 << 31));
+	mdelay(10);
+}
+
+static void __dead2 ls1043_system_reset(void)
+{
+	/* clear reset request mask bits */
+	mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTRQMR1_OFFSET, 0);
+
+	/* set reset request bit */
+	mmio_write_32(LS_DCFG_BASE + LS_DCFG_RSTCR_OFFSET,
+		      htobe32((uint32_t)0x2));
+
+	/* system will reset; if fail, enter wfi */
+	dsb();
+	isb();
+	wfi();
+
+	panic();
+}
+
+
+static int ls1043_pwr_domain_on(u_register_t mpidr)
+{
+	int core_pos = plat_core_pos_by_mpidr(mpidr);
+	uint32_t core_mask, brr;
+
+	assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+	core_mask = 1 << core_pos;
+
+	/* set warm boot entry */
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW0_OFFSET,
+		htobe32((uint32_t)(warmboot_entry >> 32)));
+
+	mmio_write_32(LS_SCFG_BASE + LS_SCFG_SCRATCHRW1_OFFSET,
+		htobe32((uint32_t)warmboot_entry));
+
+	dsb();
+
+	brr = be32toh(mmio_read_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET));
+	if (brr & core_mask) {
+		/* core has been released, must reset it to restart */
+		ls1043_reset_core(core_pos);
+
+		/* set bit in core boot control register to enable boot */
+		mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET,
+			htobe32(core_mask));
+
+	} else {
+		/* set bit in core boot control register to enable boot */
+		mmio_write_32(LS_SCFG_BASE + LS_SCFG_COREBCR_OFFSET,
+			htobe32(core_mask));
+
+		/* release core */
+		mmio_write_32(LS_DCFG_BASE + LS_DCFG_BRR_OFFSET,
+			      htobe32(brr | core_mask));
+	}
+
+	mdelay(20);
+
+	/* wake core in case it is in wfe */
+	dsb();
+	isb();
+	sev();
+
+	return PSCI_E_SUCCESS;
+}
+
+static void ls1043_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	/* Per cpu gic distributor setup */
+	gicv2_pcpu_distif_init();
+
+	/* Enable the gic CPU interface */
+	gicv2_cpuif_enable();
+}
+
+static void ls1043_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	/* Disable the gic CPU interface */
+	gicv2_cpuif_disable();
+}
+
+static plat_psci_ops_t ls1043_psci_pm_ops = {
+	.system_reset = ls1043_system_reset,
+	.pwr_domain_on = ls1043_pwr_domain_on,
+	.pwr_domain_on_finish = ls1043_pwr_domain_on_finish,
+	.pwr_domain_off = ls1043_pwr_domain_off,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	warmboot_entry = sec_entrypoint;
+	*psci_ops = &ls1043_psci_pm_ops;
+	return 0;
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_security.c b/plat/layerscape/board/ls1043/ls1043_security.c
new file mode 100644
index 0000000..18ae56e
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_security.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat_ls.h"
+
+/*
+ * We assume that all security programming is done by the primary core.
+ */
+void plat_ls_security_setup(void)
+{
+	tzc380_setup();
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_stack_protector.c b/plat/layerscape/board/ls1043/ls1043_stack_protector.c
new file mode 100644
index 0000000..50f463b
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_stack_protector.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <stdint.h>
+
+#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL)
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+	/*
+	 * Ideally, a random number should be returned instead of the
+	 * combination of a timer's value and a compile-time constant. As the
+	 * FVP does not have any random number generator, this is better than
+	 * nothing but not necessarily really secure.
+	 */
+	return RANDOM_CANARY_VALUE ^ read_cntpct_el0();
+}
diff --git a/plat/layerscape/board/ls1043/ls1043_topology.c b/plat/layerscape/board/ls1043/ls1043_topology.c
new file mode 100644
index 0000000..12d2830
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls1043_topology.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <cassert.h>
+#include "plat_ls.h"
+#include "platform_def.h"
+
+unsigned char ls1043_power_domain_tree_desc[LS1043_CLUSTER_COUNT + 1];
+
+
+CASSERT(LS1043_CLUSTER_COUNT && LS1043_CLUSTER_COUNT <= 256,
+		assert_invalid_ls1043_cluster_count);
+
+/*******************************************************************************
+ * This function dynamically constructs the topology according to
+ * LS1043_CLUSTER_COUNT and returns it.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	int i;
+
+	ls1043_power_domain_tree_desc[0] = LS1043_CLUSTER_COUNT;
+
+	for (i = 0; i < LS1043_CLUSTER_COUNT; i++)
+		ls1043_power_domain_tree_desc[i + 1] =
+						LS1043_MAX_CPUS_PER_CLUSTER;
+
+	return ls1043_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 LS1043_MAX_CPUS_PER_CLUSTER;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	if (ls_check_mpidr(mpidr) == -1)
+		return -1;
+
+	return plat_ls_calc_core_pos(mpidr);
+}
diff --git a/plat/layerscape/board/ls1043/ls_gic.c b/plat/layerscape/board/ls1043/ls_gic.c
new file mode 100644
index 0000000..3986153
--- /dev/null
+++ b/plat/layerscape/board/ls1043/ls_gic.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <debug.h>
+#include <endian.h>
+#include "platform_def.h"
+#include "soc.h"
+
+/*
+ * Get GIC offset
+ * 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 *)DCFG_CCSR_SVR;
+	uint32_t *gic_align = (uint32_t *)SCFG_GIC400_ALIGN;
+	uint32_t val;
+	uint32_t soc_dev_id;
+
+	val = be32toh(mmio_read_32((uintptr_t)ccsr_svr));
+	soc_dev_id = val & (SVR_WO_E << 8);
+
+	if ((soc_dev_id == (SVR_LS1043A << 8) ||
+			soc_dev_id == (SVR_LS1043AE << 8)) &&
+			((val & 0xff) == REV1_1)) {
+		val = be32toh(mmio_read_32((uintptr_t)gic_align));
+		if (val & (1 << GIC_ADDR_BIT)) {
+			*gicc_base = GICC_BASE;
+			*gicd_base = GICD_BASE;
+		} else {
+			*gicc_base = GICC_BASE_64K;
+			*gicd_base = GICD_BASE_64K;
+		}
+	} else {
+		*gicc_base = GICC_BASE;
+		*gicd_base = GICD_BASE;
+	}
+}
diff --git a/plat/layerscape/board/ls1043/platform.mk b/plat/layerscape/board/ls1043/platform.mk
new file mode 100644
index 0000000..163d25e
--- /dev/null
+++ b/plat/layerscape/board/ls1043/platform.mk
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# indicate the reset vector address can be programmed
+PROGRAMMABLE_RESET_ADDRESS	:=	1
+USE_COHERENT_MEM		:=	0
+RESET_TO_BL31			:=	0
+ENABLE_STACK_PROTECTOR		:=	0
+LS1043_GIC_SOURCES		:=	drivers/arm/gic/common/gic_common.c	\
+					drivers/arm/gic/v2/gicv2_main.c		\
+					drivers/arm/gic/v2/gicv2_helpers.c	\
+					plat/common/plat_gicv2.c		\
+					plat/layerscape/board/ls1043/ls_gic.c
+
+
+LS1043_INTERCONNECT_SOURCES	:= 	drivers/arm/cci/cci.c
+
+LS1043_SECURITY_SOURCES 	:=	plat/layerscape/common/ls_tzc380.c	\
+					plat/layerscape/board/ls1043/ls1043_security.c
+
+PLAT_INCLUDES			:=	-Iplat/layerscape/board/ls1043/include   \
+					-Iinclude/plat/arm/common	\
+					-Iplat/layerscape/common/include	\
+					-Iinclude/drivers/arm   \
+					-Iinclude/lib		\
+					-Iinclude/drivers/io
+
+
+PLAT_BL_COMMON_SOURCES		:=	drivers/console/aarch64/console.S	\
+					plat/layerscape/common/aarch64/ls_console.S
+
+LS1043_CPU_LIBS			:=	lib/cpus/${ARCH}/aem_generic.S
+
+LS1043_CPU_LIBS			+=	lib/cpus/aarch64/cortex_a53.S
+
+BL1_SOURCES			+= 	plat/layerscape/board/ls1043/ls1043_bl1_setup.c		\
+					plat/layerscape/board/ls1043/ls1043_err.c			\
+					drivers/delay_timer/delay_timer.c \
+
+BL1_SOURCES     		+=	plat/layerscape/board/ls1043/${ARCH}/ls1043_helpers.S \
+					${LS1043_CPU_LIBS}					\
+					${LS1043_INTERCONNECT_SOURCES}		\
+					$(LS1043_SECURITY_SOURCES)
+
+
+BL2_SOURCES			+=	drivers/delay_timer/delay_timer.c		\
+					plat/layerscape/board/ls1043/ls1043_bl2_setup.c		\
+					plat/layerscape/board/ls1043/ls1043_err.c			\
+					${LS1043_SECURITY_SOURCES}
+
+
+BL31_SOURCES			+=	plat/layerscape/board/ls1043/ls1043_bl31_setup.c		\
+					plat/layerscape/board/ls1043/ls1043_topology.c		\
+					plat/layerscape/board/ls1043/aarch64/ls1043_helpers.S	\
+					plat/layerscape/board/ls1043/ls1043_psci.c		\
+					drivers/delay_timer/delay_timer.c		\
+					${LS1043_CPU_LIBS}					\
+					${LS1043_GIC_SOURCES}				\
+					${LS1043_INTERCONNECT_SOURCES}			\
+					${LS1043_SECURITY_SOURCES}
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT		:= 	0
+MULTI_CONSOLE_API		:=	1
+
+# Enable workarounds for selected Cortex-A53 erratas.
+ERRATA_A53_855873		:=	1
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES		+=	plat/layerscape/board/ls1043/ls1043_stack_protector.c
+endif
+
+ifeq (${ARCH},aarch32)
+    NEED_BL32 := yes
+endif
+
+include plat/layerscape/common/ls_common.mk
diff --git a/plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c b/plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c
new file mode 100644
index 0000000..4fc019c
--- /dev/null
+++ b/plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat_ls.h"
+
+void tsp_early_platform_setup(void)
+{
+	ls_tsp_early_platform_setup();
+
+	/*Todo: Initialize the platform config for future decision making */
+}
diff --git a/plat/layerscape/board/ls1043/tsp/tsp-ls1043.mk b/plat/layerscape/board/ls1043/tsp/tsp-ls1043.mk
new file mode 100644
index 0000000..3941427
--- /dev/null
+++ b/plat/layerscape/board/ls1043/tsp/tsp-ls1043.mk
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# TSP source files specific to FVP platform
+BL32_SOURCES		+=	plat/layerscape/board/ls1043/ls1043_topology.c		\
+				plat/layerscape/board/ls1043/tsp/ls1043_tsp_setup.c		\
+				${LS1043_GIC_SOURCES}
+
+include plat/layerscape/common/tsp/ls_tsp.mk
diff --git a/plat/layerscape/common/aarch64/ls_bl2_mem_params_desc.c b/plat/layerscape/common/aarch64/ls_bl2_mem_params_desc.c
new file mode 100644
index 0000000..a96e390
--- /dev/null
+++ b/plat/layerscape/common/aarch64/ls_bl2_mem_params_desc.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <desc_image_load.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <debug.h>
+#include <ls_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[] = {
+#ifdef EL3_PAYLOAD_BASE
+	/* Fill EL3 payload related information (BL31 is EL3 payload)*/
+	{
+		.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 = EL3_PAYLOAD_BASE,
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+				DISABLE_ALL_EXCEPTIONS),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				VERSION_2, image_info_t,
+				IMAGE_ATTRIB_PLAT_SETUP |
+				IMAGE_ATTRIB_SKIP_LOADING),
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+#else /* EL3_PAYLOAD_BASE */
+
+	/* 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),
+		.image_info.image_base = BL31_BASE,
+		.image_info.image_max_size = (BL31_LIMIT - BL31_BASE),
+
+# ifdef BL32_BASE
+		.next_handoff_image_id = BL32_IMAGE_ID,
+# else
+		.next_handoff_image_id = BL33_IMAGE_ID,
+# endif
+	},
+# ifdef BL32_BASE
+	/* 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),
+		.image_info.image_base = BL32_BASE,
+		.image_info.image_max_size = (BL32_LIMIT - BL32_BASE),
+
+		.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),
+# ifdef PRELOADED_BL33_BASE
+		.ep_info.pc = PRELOADED_BL33_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				VERSION_2, image_info_t,
+				IMAGE_ATTRIB_SKIP_LOADING),
+# else
+		.ep_info.pc = BL33_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				VERSION_2, image_info_t, 0),
+		.image_info.image_base = BL33_BASE,
+		.image_info.image_max_size = LS_NS_DRAM_SIZE,
+# endif /* PRELOADED_BL33_BASE */
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	}
+#endif /* EL3_PAYLOAD_BASE */
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/layerscape/common/aarch64/ls_console.S b/plat/layerscape/common/aarch64/ls_console.S
new file mode 100644
index 0000000..5c87465
--- /dev/null
+++ b/plat/layerscape/common/aarch64/ls_console.S
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <console_macros.S>
+#include <assert_macros.S>
+#include "ls_16550.h"
+
+	/*
+	 * "core" functions are low-level implementations that don't require
+	 * writable memory and are thus safe to call in BL1 crash context.
+	 */
+	.globl console_ls_16550_core_init
+	.globl console_ls_16550_core_putc
+	.globl console_ls_16550_core_getc
+
+	.globl console_ls_16550_putc
+	.globl console_ls_16550_getc
+	.globl console_ls_16550_flush
+
+	/* -----------------------------------------------
+	 * int console_ls_16550_core_init(uintptr_t base_addr,
+	 * unsigned int uart_clk, unsigned int baud_rate)
+	 * Function to initialize the console without a
+	 * C Runtime to print debug information. This
+	 * function will be accessed by console_init and
+	 * crash reporting.
+	 * In: x0 - console base address
+	 *     w1 - Uart clock in Hz
+	 *     w2 - Baud rate
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : x1, x2, x3
+	 * -----------------------------------------------
+	 */
+func console_ls_16550_core_init
+	/* Check the input base address */
+	cbz	x0, init_fail
+	/* Check baud rate and uart clock for sanity */
+	cbz	w1, init_fail
+	cbz	w2, init_fail
+
+	/* Program the baudrate */
+	/* Divisor =  Uart clock / (16 * baudrate) */
+	lsl	w2, w2, #4
+	udiv	w2, w1, w2
+	and	w1, w2, #0xff		/* w1 = DLL */
+	lsr	w2, w2, #8
+	and	w2, w2, #0xff		/* w2 = DLLM */
+	ldrb	w3, [x0, #UARTLCR]
+	orr	w3, w3, #UARTLCR_DLAB
+	strb	w3, [x0, #UARTLCR]	/* enable DLL, DLLM programming */
+	strb	w1, [x0, #UARTDLL]	/* program DLL */
+	strb	w2, [x0, #UARTDLLM]	/* program DLLM */
+	mov	w2, #~UARTLCR_DLAB
+	and	w3, w3, w2
+	strb	w3, [x0, #UARTLCR]	/* disable DLL, DLLM programming */
+
+	/* 8n1 */
+	mov	w3, #3
+	strb	w3, [x0, #UARTLCR]
+	/* no interrupt */
+	mov	w3, #0
+	strb	w3, [x0, #UARTIER]
+	/* enable fifo, DMA */
+	mov	w3, #(UARTFCR_FIFOEN |UARTFCR_TXCLR | UARTFCR_RXCLR)
+	strb	w3, [x0, #UARTFCR]
+	/* DTR + RTS */
+	mov	w3, #3
+	str	w3, [x0, #UARTMCR]
+	mov	w0, #1
+	ret
+init_fail:
+	mov	w0, #0
+	ret
+endfunc console_ls_16550_core_init
+
+#if MULTI_CONSOLE_API
+	.globl console_ls_16550_register
+
+	/* -----------------------------------------------
+	 * int console_ls_16550_register(console_ls_16550_t *console,
+	 *	uintptr_t base, uint32_t clk, uint32_t baud)
+	 * Function to initialize and register a new 16550
+	 * console. Storage passed in for the console struct
+	 * *must* be persistent (i.e. not from the stack).
+	 * In: x0 - UART register base address
+	 *     w1 - UART clock in Hz
+	 *     w2 - Baud rate
+	 *     x3 - pointer to empty console_ls_16550_t struct
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : x0, x1, x2, x6, x7, x14
+	 * -----------------------------------------------
+	 */
+func console_ls_16550_register
+	mov	x7, x30
+	mov	x6, x3
+	cbz	x6, register_fail
+	str	x0, [x6, #CONSOLE_T_16550_BASE]
+
+	bl	console_ls_16550_core_init
+	cbz	x0, register_fail
+
+	mov	x0, x6
+	mov	x30, x7
+	finish_console_register ls_16550
+
+register_fail:
+	ret	x7
+endfunc console_ls_16550_register
+#else
+	.globl console_core_init
+	.globl console_core_putc
+	.globl console_core_getc
+	.globl console_core_flush
+	.equ console_core_init,console_ls_16550_core_init
+	.equ console_core_putc,console_ls_16550_core_putc
+	.equ console_core_getc,console_ls_16550_core_getc
+	.equ console_core_flush,console_ls_16550_core_flush
+#endif
+
+	/* --------------------------------------------------------
+	 * int console_ls_16550_core_putc(int c, uintptr_t base_addr)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - console base address
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_ls_16550_core_putc
+#if ENABLE_ASSERTIONS
+	cmp	x1, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+	/* Prepend '\r' to '\n' */
+	cmp	w0, #0xA //'\n'
+	b.ne	2f
+	/* Check if the transmit FIFO is full */
+1:	ldrb	w2, [x1, #UARTLSR]
+	and	w2, w2, #UARTLSR_THRE        /* #(UARTLSR_TEMT | UARTLSR_THRE)*/
+	cmp	w2, #(UARTLSR_THRE)
+	b.ne	1b
+	mov	w2, #0xD		/* '\r' */
+	strb	w2, [x1, #UARTTX]
+	ldrb	w2, [x1, #UARTFCR]
+	orr	w2, w2, #UARTFCR_TXCLR
+
+	/* Check if the transmit FIFO is full */
+2:	ldrb	w2, [x1, #UARTLSR]
+	and	w2, w2, #(UARTLSR_THRE)
+	cmp	w2, #(UARTLSR_THRE)
+	b.ne	2b
+	strb	w0, [x1, #UARTTX]
+	ret
+endfunc console_ls_16550_core_putc
+
+	/* --------------------------------------------------------
+	 * int console_16550_putc(int c, console_ls_16550_t *console)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - pointer to console_t structure
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_ls_16550_putc
+#if ENABLE_ASSERTIONS
+	cmp	x1, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	x1, [x1, #CONSOLE_T_16550_BASE]
+	b	console_ls_16550_core_putc
+endfunc console_ls_16550_putc
+
+	/* ---------------------------------------------
+	 * int console_ls_16550_core_getc(uintptr_t base_addr)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 on if no character is available.
+	 * In :  x0 - console base address
+	 * Out : w0 - character if available, else -1
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_ls_16550_core_getc
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+	/* Check if the receive FIFO is empty */
+1:	ldrb	w1, [x0, #UARTLSR]
+	tbz	w1, #UARTLSR_RDR, 1b
+	ldrb	w0, [x0, #UARTRX]
+	ret
+no_char:
+	mov	w0, #ERROR_NO_PENDING_CHAR
+	ret
+endfunc console_ls_16550_core_getc
+
+	/* ---------------------------------------------
+	 * int console_ls_16550_getc(console_ls_16550_t *console)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 on if no character is available.
+	 * In :  x0 - pointer to console_t structure
+	 * Out : w0 - character if available, else -1
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_ls_16550_getc
+#if ENABLE_ASSERTIONS
+	cmp	x1, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	x0, [x0, #CONSOLE_T_16550_BASE]
+	b	console_ls_16550_core_getc
+endfunc console_ls_16550_getc
+
+	/* ---------------------------------------------
+	 * int console_ls_16550_core_flush(uintptr_t base_addr)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : x0 - console base address
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_ls_16550_core_flush
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
+	/* Loop until the transmit FIFO is empty */
+1:	ldrb	w1, [x0, #UARTLSR]
+	and	w1, w1, #(UARTLSR_TEMT | UARTLSR_THRE)
+	cmp	w1, #(UARTLSR_TEMT | UARTLSR_THRE)
+	b.ne	1b
+
+	mov	w0, #0
+	ret
+endfunc console_ls_16550_core_flush
+
+	/* ---------------------------------------------
+	 * int console_ls_16550_flush(console_ls_16550_t *console)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : x0 - pointer to console_t structure
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_ls_16550_flush
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	x0, [x0, #CONSOLE_T_16550_BASE]
+	b	console_ls_16550_core_flush
+endfunc console_ls_16550_flush
diff --git a/plat/layerscape/common/aarch64/ls_helpers.S b/plat/layerscape/common/aarch64/ls_helpers.S
new file mode 100644
index 0000000..7d71f48
--- /dev/null
+++ b/plat/layerscape/common/aarch64/ls_helpers.S
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <console.h>
+#include <platform_def.h>
+
+	.weak	plat_my_core_pos
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_crash_console_flush
+	.weak	platform_mem_init
+	.globl	plat_ls_calc_core_pos
+
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses the plat_ls_calc_core_pos()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_ls_calc_core_pos
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_ls_calc_core_pos(u_register_t mpidr)
+	 *  Helper function to calculate the core position.
+	 *  With this function: CorePos = (ClusterId * 4) +
+	 *  				  CoreId
+	 * -----------------------------------------------------
+	 */
+func plat_ls_calc_core_pos
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+endfunc plat_ls_calc_core_pos
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize the crash console
+	 * without a C Runtime to print crash report.
+	 * Clobber list : x0 - x4
+	 * ---------------------------------------------
+	 */
+
+#if MULTI_CONSOLE_API
+	/* -----------------------------------------------------
+	 * 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
+#if defined(IMAGE_BL1)
+	/*
+	 * BL1 code can possibly crash so early that the data segment is not yet
+	 * accessible. Don't risk undefined behavior by trying to run the normal
+	 * console framework. Platforms that want to debug BL1 will need to
+	 * override this with custom functions that can run from registers only.
+	 */
+	mov	x0, #0
+	ret
+#else	/* IMAGE_BL1 */
+	mov	x3, x30
+	mov	x0, #CONSOLE_FLAG_CRASH
+	bl	console_switch_state
+	mov	x0, #1
+	ret	x3
+#endif
+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
+
+#else	/* MULTI_CONSOLE_API */
+
+	/* -----------------------------------------------------
+	 * In the old API these are all no-op stubs that need to
+	 * be overridden by the platform to be useful.
+	 * -----------------------------------------------------
+	 */
+func plat_crash_console_init
+	mov_imm	x0, PLAT_LS1043_UART_BASE
+	mov_imm	x1, PLAT_LS1043_UART_CLOCK
+	mov_imm	x2, PLAT_LS1043_UART_BAUDRATE
+	b	console_core_init
+endfunc plat_crash_console_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to print a character on the crash
+	 * console without a C Runtime.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, PLAT_LS1043_UART_BASE
+	b	console_core_putc
+endfunc plat_crash_console_putc
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_flush()
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : r0 - r1
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_flush
+	mov_imm	x1, PLAT_LS1043_UART_BASE
+	b	console_core_flush
+endfunc plat_crash_console_flush
+#endif
+	/* ---------------------------------------------------------------------
+	 * We don't need to carry out any memory initialization on LS
+	 * platforms. The Secure SRAM is accessible straight away.
+	 * ---------------------------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
diff --git a/plat/layerscape/common/include/fsl_csu.h b/plat/layerscape/common/include/fsl_csu.h
new file mode 100644
index 0000000..680911e
--- /dev/null
+++ b/plat/layerscape/common/include/fsl_csu.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FSL_CSU_H__
+#define __FSL_CSU_H__
+
+enum csu_cslx_access {
+	CSU_NS_SUP_R = 0x08,
+	CSU_NS_SUP_W = 0x80,
+	CSU_NS_SUP_RW = 0x88,
+	CSU_NS_USER_R = 0x04,
+	CSU_NS_USER_W = 0x40,
+	CSU_NS_USER_RW = 0x44,
+	CSU_S_SUP_R = 0x02,
+	CSU_S_SUP_W = 0x20,
+	CSU_S_SUP_RW = 0x22,
+	CSU_S_USER_R = 0x01,
+	CSU_S_USER_W = 0x10,
+	CSU_S_USER_RW = 0x11,
+	CSU_ALL_RW = 0xff,
+};
+
+struct csu_ns_dev {
+	uintptr_t ind;
+	uint32_t val;
+};
+
+void enable_layerscape_ns_access(void);
+
+#endif
diff --git a/plat/layerscape/common/include/ls_16550.h b/plat/layerscape/common/include/ls_16550.h
new file mode 100644
index 0000000..503a01d
--- /dev/null
+++ b/plat/layerscape/common/include/ls_16550.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __LS_16550_H__
+#define __LS_16550_H__
+
+#include <console.h>
+
+/* UART16550 Registers */
+#define UARTTX			0x0
+#define UARTRX			0x0
+#define UARTDLL			0x0
+#define UARTIER			0x1
+#define UARTDLLM		0x1
+#define UARTFCR			0x2
+#define UARTLCR			0x3
+#define UARTLSR			0x5
+#define UARTMCR                 0x4
+
+/* FIFO Control Register bits */
+#define UARTFCR_FIFOMD_16450	(0 << 6)
+#define UARTFCR_FIFOMD_16550	(1 << 6)
+#define UARTFCR_RXTRIG_1	(0 << 6)
+#define UARTFCR_RXTRIG_4	(1 << 6)
+#define UARTFCR_RXTRIG_8	(2 << 6)
+#define UARTFCR_RXTRIG_16	(3 << 6)
+#define UARTFCR_TXTRIG_1	(0 << 4)
+#define UARTFCR_TXTRIG_4	(1 << 4)
+#define UARTFCR_TXTRIG_8	(2 << 4)
+#define UARTFCR_TXTRIG_16	(3 << 4)
+#define UARTFCR_DMAEN		(1 << 3)	/* Enable DMA mode */
+#define UARTFCR_TXCLR		(1 << 2)	/* Clear contents of Tx FIFO */
+#define UARTFCR_RXCLR		(1 << 1)	/* Clear contents of Rx FIFO */
+#define UARTFCR_FIFOEN		(1 << 0)	/* Enable the Tx/Rx FIFO */
+#define UARTFCR_64FIFO          (1 << 5)
+
+/* Line Control Register bits */
+#define UARTLCR_DLAB		(1 << 7)	/* Divisor Latch Access */
+#define UARTLCR_SETB		(1 << 6)	/* Set BREAK Condition */
+#define UARTLCR_SETP		(1 << 5)	/* Set Parity to LCR[4] */
+#define UARTLCR_EVEN		(1 << 4)	/* Even Parity Format */
+#define UARTLCR_PAR		(1 << 3)	/* Parity */
+#define UARTLCR_STOP		(1 << 2)	/* Stop Bit */
+#define UARTLCR_WORDSZ_5	0		/* Word Length of 5 */
+#define UARTLCR_WORDSZ_6	1		/* Word Length of 6 */
+#define UARTLCR_WORDSZ_7	2		/* Word Length of 7 */
+#define UARTLCR_WORDSZ_8	3		/* Word Length of 8 */
+
+/* Line Status Register bits */
+#define UARTLSR_RXFIFOEMT	(1 << 9)	/* Rx Fifo Empty */
+#define UARTLSR_TXFIFOFULL	(1 << 8)	/* Tx Fifo Full */
+#define UARTLSR_RXFIFOERR	(1 << 7)	/* Rx Fifo Error */
+#define UARTLSR_TEMT		(1 << 6)	/* Tx Shift Register Empty */
+#define UARTLSR_THRE		(1 << 5)	/* Tx Holding Register Empty */
+#define UARTLSR_BRK		(1 << 4)	/* Break Condition Detected */
+#define UARTLSR_FERR		(1 << 3)	/* Framing Error */
+#define UARTLSR_PERR		(1 << 3)	/* Parity Error */
+#define UARTLSR_OVRF		(1 << 2)	/* Rx Overrun Error */
+#define UARTLSR_RDR		(1 << 2)	/* Rx Data Ready */
+
+#define CONSOLE_T_16550_BASE	CONSOLE_T_DRVDATA
+
+#ifndef __ASSEMBLY__
+
+#include <types.h>
+
+typedef struct {
+	console_t console;
+	uintptr_t base;
+} console_ls_16550_t;
+
+/*
+ * Initialize a new 16550 console instance and register it with the console
+ * framework. The |console| pointer must point to storage that will be valid
+ * for the lifetime of the console, such as a global or static local variable.
+ * Its contents will be reinitialized from scratch.
+ */
+int console_ls_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+			   console_ls_16550_t *console);
+
+#endif /*__ASSEMBLY__*/
+
+#endif	/* __LS_16550_H__ */
diff --git a/plat/layerscape/common/include/plat_ls.h b/plat/layerscape/common/include/plat_ls.h
new file mode 100644
index 0000000..9d5ec14
--- /dev/null
+++ b/plat/layerscape/common/include/plat_ls.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_LS_H__
+#define __PLAT_LS_H__
+
+#include <sys/types.h>
+#include <cpu_data.h>
+
+/* BL1 utility functions */
+void ls_bl1_platform_setup(void);
+void ls_bl1_early_platform_setup(void);
+
+/* BL2 utility functions */
+void ls_bl2_early_platform_setup(meminfo_t *mem_layout);
+uint32_t ls_get_spsr_for_bl32_entry(void);
+uint32_t ls_get_spsr_for_bl33_entry(void);
+
+/* BL3 utility functions */
+void ls_bl31_early_platform_setup(void *from_bl2,
+				void *plat_params_from_bl2);
+
+/* IO storage utility functions */
+void plat_ls_io_setup(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
+);
+
+/* PSCI utility functions */
+int ls_check_mpidr(u_register_t mpidr);
+
+/* Security utility functions */
+int tzc380_setup(void);
+
+/* Timer utility functions */
+uint64_t ls_get_timer(uint64_t start);
+void ls_delay_timer_init(void);
+
+/* TSP utility functions */
+void ls_tsp_early_platform_setup(void);
+
+/* Helper functions */
+unsigned int plat_ls_calc_core_pos(u_register_t mpidr);
+
+/* others */
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr);
+
+#endif /* __PLAT_LS_H__ */
diff --git a/plat/layerscape/common/include/soc.h b/plat/layerscape/common/include/soc.h
new file mode 100644
index 0000000..72c10cf
--- /dev/null
+++ b/plat/layerscape/common/include/soc.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __LAYERSCAPE_SOC_H__
+#define __LAYERSCAPE_SOC_H__
+
+#include <stdint.h>
+
+#define SVR_WO_E		0xFFFFFE
+#define SVR_LS1043A		0x879204
+#define SVR_LS1043AE		0x879200
+
+void get_gic_offset(uint32_t *gicc_base, uint32_t *gicd_base);
+
+#endif /* __LAYERSCAPE_SOC_H__ */
diff --git a/plat/layerscape/common/include/tzc380.h b/plat/layerscape/common/include/tzc380.h
new file mode 100644
index 0000000..788c0ed
--- /dev/null
+++ b/plat/layerscape/common/include/tzc380.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TZC380_H__
+#define __TZC380_H__
+
+struct tzc380_reg {
+	unsigned int secure;
+	unsigned int enabled;
+	unsigned int low_addr;
+	unsigned int high_addr;
+	unsigned int size;
+	unsigned int sub_mask;
+};
+
+#endif /* __TZC380_H__ */
diff --git a/plat/layerscape/common/ls_bl1_setup.c b/plat/layerscape/common/ls_bl1_setup.c
new file mode 100644
index 0000000..43f7450
--- /dev/null
+++ b/plat/layerscape/common/ls_bl1_setup.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include "ls_16550.h"
+#include "plat_ls.h"
+#include "../../../bl1/bl1_private.h"
+
+/* Data structure which holds the extents of the trusted SRAM for BL1*/
+static meminfo_t bl1_tzram_layout;
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+	return &bl1_tzram_layout;
+}
+
+/*******************************************************************************
+ * BL1 specific platform actions shared between ARM standard platforms.
+ ******************************************************************************/
+void ls_bl1_early_platform_setup(void)
+{
+	static console_ls_16550_t console;
+
+#if !LS1043_DISABLE_TRUSTED_WDOG
+	/* TODO: Enable watchdog */
+
+#endif
+
+	/* Initialize the console to provide early debug support */
+	console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
+			       LS_TF_UART_BAUDRATE, &console);
+
+	/* Allow BL1 to see the whole Trusted RAM */
+	bl1_tzram_layout.total_base = LS_SRAM_BASE;
+	bl1_tzram_layout.total_size = LS_SRAM_SIZE;
+}
+
+/******************************************************************************
+ * Perform the very early platform specific architecture setup shared between
+ * ARM standard platforms. This only does basic initialization. Later
+ * architectural setup (bl1_arch_setup()) does not do anything platform
+ * specific.
+ *****************************************************************************/
+void ls_bl1_plat_arch_setup(void)
+{
+	ls_setup_page_tables(bl1_tzram_layout.total_base,
+			      bl1_tzram_layout.total_size,
+			      BL_CODE_BASE,
+			      BL1_CODE_END,
+			      BL1_RO_DATA_BASE,
+			      BL1_RO_DATA_END
+#if USE_COHERENT_MEM
+			      , BL_COHERENT_RAM_BASE,
+			      BL_COHERENT_RAM_END
+#endif
+			     );
+	VERBOSE("After setup the page tables\n");
+#ifdef AARCH32
+	enable_mmu_secure(0);
+#else
+	enable_mmu_el3(0);
+#endif /* AARCH32 */
+	VERBOSE("After MMU enabled\n");
+}
+
+void bl1_plat_arch_setup(void)
+{
+	ls_bl1_plat_arch_setup();
+}
+
+/*
+ * Perform the platform specific architecture setup shared between
+ * ARM standard platforms.
+ */
+void ls_bl1_platform_setup(void)
+{
+	/* Initialise the IO layer and register platform IO devices */
+	plat_ls_io_setup();
+}
+
+void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
+{
+#if !LS1043_DISABLE_TRUSTED_WDOG
+	/*TODO: Disable watchdog before leaving BL1 */
+#endif
+}
diff --git a/plat/layerscape/common/ls_bl2_setup.c b/plat/layerscape/common/ls_bl2_setup.c
new file mode 100644
index 0000000..6e6ad6e
--- /dev/null
+++ b/plat/layerscape/common/ls_bl2_setup.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <desc_image_load.h>
+#include "ls_16550.h"
+#include "plat_ls.h"
+#include "ls_def.h"
+
+/* Data structure which holds the extents of the trusted SRAM for BL2 */
+static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+
+/*******************************************************************************
+ * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
+ * in x0. This memory layout is sitting at the base of the free trusted SRAM.
+ * Copy it to a safe location before its reclaimed by later BL2 functionality.
+ ******************************************************************************/
+void ls_bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+	static console_ls_16550_t console;
+
+	/* Initialize the console to provide early debug support */
+	console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
+			       LS_TF_UART_BAUDRATE, &console);
+
+	/* Setup the BL2 memory layout */
+	bl2_tzram_layout = *mem_layout;
+
+	/* Initialise the IO layer and register platform IO devices */
+	plat_ls_io_setup();
+}
+
+/*******************************************************************************
+ * 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_plat_arch_setup(void)
+{
+	ls_setup_page_tables(bl2_tzram_layout.total_base,
+			      bl2_tzram_layout.total_size,
+			      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
+			      );
+
+#ifdef AARCH32
+	enable_mmu_secure(0);
+#else
+	enable_mmu_el1(0);
+#endif
+}
+
+void bl2_plat_arch_setup(void)
+{
+	ls_bl2_plat_arch_setup();
+}
+
+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) {
+#ifdef AARCH64
+	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);
+}
diff --git a/plat/layerscape/common/ls_bl31_setup.c b/plat/layerscape/common/ls_bl31_setup.c
new file mode 100644
index 0000000..3016f58
--- /dev/null
+++ b/plat/layerscape/common/ls_bl31_setup.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <console.h>
+#include <mmio.h>
+#include <gicv2.h>
+#include "ls_16550.h"
+#include "plat_ls.h"
+#include "soc.h"
+
+#define BL31_END (uintptr_t)(&__BL31_END__)
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+const unsigned int g0_interrupt_array1[] = {
+	9
+};
+
+gicv2_driver_data_t ls_gic_data = {
+	.gicd_base = GICD_BASE,
+	.gicc_base = GICC_BASE,
+	.g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array1),
+	.g0_interrupt_array = g0_interrupt_array1,
+};
+
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for the
+ * security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	entry_point_info_t *next_image_info;
+
+	assert(sec_state_is_valid(type));
+	next_image_info = (type == NON_SECURE)
+			? &bl33_image_ep_info : &bl32_image_ep_info;
+
+	if (next_image_info->pc)
+		return next_image_info;
+	else
+		return NULL;
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup common to Layerscape 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, so
+ * we are guaranteed to pick up good data.
+ ******************************************************************************/
+void ls_bl31_early_platform_setup(void *from_bl2,
+				void *plat_params_from_bl2)
+{
+	static console_ls_16550_t console;
+
+	/* Initialize the console to provide early debug support */
+	console_ls_16550_register(LS_TF_UART_BASE, LS_TF_UART_CLOCK,
+				LS_TF_UART_BAUDRATE, &console);
+#if RESET_TO_BL31
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(from_bl2 == NULL);
+	assert(plat_params_from_bl2 == NULL);
+
+#ifdef BL32_BASE
+	/* Populate entry point information for BL32 */
+	SET_PARAM_HEAD(&bl32_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = ls_get_spsr_for_bl32_entry();
+#endif /* BL32_BASE */
+
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+
+	bl33_image_ep_info.spsr = ls_get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#else /* RESET_TO_BL31 */
+
+	/*
+	 * In debug builds, we pass a special value in 'plat_params_from_bl2'
+	 * to verify platform parameters from BL2 to BL31.
+	 * In release builds, it's not used.
+	 */
+	assert(((unsigned long long)plat_params_from_bl2) ==
+		LS_BL31_PLAT_PARAM_VAL);
+
+	/*
+	 * 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) {
+		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;
+	}
+
+	if (bl33_image_ep_info.pc == 0)
+		panic();
+
+#endif /* RESET_TO_BL31 */
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform setup common to Layerscape platforms
+ ******************************************************************************/
+void ls_bl31_platform_setup(void)
+{
+	uint32_t gicc_base, gicd_base;
+
+	NOTICE(FIRMWARE_WELCOME_STR_LS1043_BL31);
+	/* Initialize the GIC driver, cpu and distributor interfaces */
+	get_gic_offset(&gicc_base, &gicd_base);
+	ls_gic_data.gicd_base = (uintptr_t)gicd_base;
+	ls_gic_data.gicc_base = (uintptr_t)gicc_base;
+	gicv2_driver_init(&ls_gic_data);
+	gicv2_distif_init();
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+
+#if RESET_TO_BL31
+	/*
+	 * Do initial security configuration to allow DRAM/device access
+	 * (if earlier BL has not already done so).
+	 */
+	plat_ls_security_setup();
+
+#endif /* RESET_TO_BL31 */
+
+	/* Enable and initialize the System level generic timer */
+	mmio_write_32(LS1043_SYS_CNTCTL_BASE + CNTCR_OFF,
+			CNTCR_FCREQ(0) | CNTCR_EN);
+
+	VERBOSE("Leave arm_bl31_platform_setup\n");
+}
+
+/*******************************************************************************
+ * Perform any BL31 platform runtime setup prior to BL31 exit common to Layerscape
+ * platforms
+ ******************************************************************************/
+void ls_bl31_plat_runtime_setup(void)
+{
+	static console_ls_16550_t console;
+
+	/* Initialize the runtime console */
+	console_ls_16550_register(PLAT_LS1043_UART_BASE, PLAT_LS1043_UART_CLOCK,
+				PLAT_LS1043_UART_BAUDRATE, &console);
+}
+
+void bl31_platform_setup(void)
+{
+	ls_bl31_platform_setup();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	ls_bl31_plat_runtime_setup();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup shared between
+ * Layerscape platforms. This only does basic initialization. Later
+ * architectural setup (bl31_arch_setup()) does not do anything platform
+ * specific.
+ ******************************************************************************/
+void ls_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);
+}
+
+void bl31_plat_arch_setup(void)
+{
+	ls_bl31_plat_arch_setup();
+}
diff --git a/plat/layerscape/common/ls_common.c b/plat/layerscape/common/ls_common.c
new file mode 100644
index 0000000..abf6525
--- /dev/null
+++ b/plat/layerscape/common/ls_common.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+#include <arch_helpers.h>
+#include <xlat_tables_v2.h>
+#include <assert.h>
+#include <debug.h>
+#include <mmio.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 ls_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_BL1
+const mmap_region_t plat_ls_mmap[] = {
+	LS_MAP_FLASH0_RW,
+	LS_MAP_NS_DRAM,
+	LS_MAP_CCSR,
+	{0}
+};
+#endif
+#ifdef IMAGE_BL2
+const mmap_region_t plat_ls_mmap[] = {
+	LS_MAP_FLASH0_RW,
+	LS_MAP_CCSR,
+	LS_MAP_NS_DRAM,
+	LS_MAP_TSP_SEC_MEM,
+	{0}
+};
+#endif
+#ifdef IMAGE_BL31
+const mmap_region_t plat_ls_mmap[] = {
+	LS_MAP_CCSR,
+	LS_MAP_FLASH0_RW,
+	LS_MAP_NS_DRAM,
+	LS_MAP_TSP_SEC_MEM,
+	{0}
+};
+#endif
+#ifdef IMAGE_BL32
+const mmap_region_t plat_ls_mmap[] = {
+	LS_MAP_CCSR,
+	LS_MAP_FLASH0_RW,
+	LS_MAP_TSP_SEC_MEM,
+	{0}
+};
+#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
+			   )
+{
+	/* Now (re-)map the platform-specific memory regions */
+	mmap_add(plat_ls_get_mmap());
+	/*
+	 * Map the Trusted SRAM with appropriate memory attributes.
+	 * Subsequent mappings will adjust the attributes for specific regions.
+	 */
+	VERBOSE("Trusted SRAM 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
+
+	/* Create the page tables to reflect the above mappings */
+	init_xlat_tables();
+}
+
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+	return PRELOADED_BL33_BASE;
+#else
+	return LS_NS_DRAM_BASE;
+#endif
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL32 entry
+ ******************************************************************************/
+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 0;
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL33 entry
+ ******************************************************************************/
+#ifndef AARCH32
+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) ? 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
+ ******************************************************************************/
+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 */
+
+/*******************************************************************************
+ * Returns Layerscape platform specific memory map regions.
+ ******************************************************************************/
+const mmap_region_t *plat_ls_get_mmap(void)
+{
+	return plat_ls_mmap;
+}
+
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	unsigned int counter_base_frequency;
+
+	counter_base_frequency = COUNTER_FREQUENCY;
+
+	return counter_base_frequency;
+}
diff --git a/plat/layerscape/common/ls_common.mk b/plat/layerscape/common/ls_common.mk
new file mode 100644
index 0000000..1a80e9f
--- /dev/null
+++ b/plat/layerscape/common/ls_common.mk
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+# Process LS1043_DISABLE_TRUSTED_WDOG flag
+# TODO:Temparally disabled it on development phase, not implemented yet
+LS1043_DISABLE_TRUSTED_WDOG	:=	1
+
+# On Layerscape 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 Layerscape platforms
+LOAD_IMAGE_V2			:=	1
+
+# Use generic OID definition (tbbr_oid.h)
+USE_TBBR_DEFS			:=	1
+
+
+COLD_BOOT_SINGLE_CPU		:=	1
+
+PLAT_INCLUDES		+=	-Iinclude/common/tbbr
+
+PLAT_BL_COMMON_SOURCES	+=	plat/layerscape/common/${ARCH}/ls_helpers.S		\
+				plat/layerscape/common/ls_common.c
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
+
+BL1_SOURCES		+=			\
+				drivers/io/io_fip.c				\
+				drivers/io/io_memmap.c				\
+				drivers/io/io_storage.c				\
+				plat/layerscape/common/ls_timer.c			\
+				plat/layerscape/common/ls_bl1_setup.c			\
+				plat/layerscape/common/ls_io_storage.c
+
+BL2_SOURCES		+=	drivers/io/io_fip.c				\
+				drivers/io/io_memmap.c				\
+				drivers/io/io_storage.c				\
+				plat/layerscape/common/ls_timer.c			\
+				plat/layerscape/common/ls_bl2_setup.c			\
+				plat/layerscape/common/ls_io_storage.c
+BL2_SOURCES		+=	plat/layerscape/common/${ARCH}/ls_bl2_mem_params_desc.c
+BL2_SOURCES		+=	plat/layerscape/common/ls_image_load.c		\
+					common/desc_image_load.c
+
+BL31_SOURCES		+=	plat/layerscape/common/ls_bl31_setup.c		\
+				plat/layerscape/common/ls_timer.c			\
+				plat/layerscape/common/ls_topology.c			\
+				plat/layerscape/common/ns_access.c		\
+				plat/common/plat_psci_common.c
+# Verify build config
+# -------------------
+
+ifneq (${LOAD_IMAGE_V2}, 1)
+  $(error Error: Layerscape needs LOAD_IMAGE_V2=1)
+endif
diff --git a/plat/layerscape/common/ls_image_load.c b/plat/layerscape/common/ls_image_load.c
new file mode 100644
index 0000000..909bec2
--- /dev/null
+++ b/plat/layerscape/common/ls_image_load.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <desc_image_load.h>
+#include "ls_def.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/layerscape/common/ls_io_storage.c b/plat/layerscape/common/ls_io_storage.c
new file mode 100644
index 0000000..7402366
--- /dev/null
+++ b/plat/layerscape/common/ls_io_storage.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <debug.h>
+#include <firmware_image_package.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include "platform_def.h"
+
+/* IO devices */
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fip_block_spec = {
+	.offset = PLAT_LS_FIP_BASE,
+	.length = PLAT_LS_FIP_MAX_SIZE
+};
+
+static const io_uuid_spec_t bl2_uuid_spec = {
+	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_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 int open_fip(const uintptr_t spec);
+static int open_memmap(const uintptr_t spec);
+
+struct plat_io_policy {
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+	[FIP_IMAGE_ID] = {
+		&memmap_dev_handle,
+		(uintptr_t)&fip_block_spec,
+		open_memmap
+	},
+	[BL2_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&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
+	},
+};
+
+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;
+}
+
+
+static int open_memmap(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_image_handle;
+
+	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
+	if (result == 0) {
+		result = io_open(memmap_dev_handle, spec, &local_image_handle);
+		if (result == 0) {
+			VERBOSE("Using Memmap\n");
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+
+void ls_io_setup(void)
+{
+	int io_result;
+
+	io_result = register_io_dev_fip(&fip_dev_con);
+	assert(io_result == 0);
+
+	io_result = register_io_dev_memmap(&memmap_dev_con);
+	assert(io_result == 0);
+
+	/* Open connections to devices and cache the handles */
+	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+				&fip_dev_handle);
+	assert(io_result == 0);
+
+	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
+				&memmap_dev_handle);
+	assert(io_result == 0);
+
+	/* Ignore improbable errors in release builds */
+	(void)io_result;
+}
+
+void plat_ls_io_setup(void)
+{
+	ls_io_setup();
+}
+
+int plat_ls_get_alt_image_source(
+	unsigned int image_id __unused,
+	uintptr_t *dev_handle __unused,
+	uintptr_t *image_spec __unused)
+{
+	/* By default do not try an alternative */
+	return -ENOENT;
+}
+
+/*
+ * 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;
+	const struct plat_io_policy *policy;
+
+	assert(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);
+	} else {
+		VERBOSE("Trying alternative IO\n");
+		result = plat_ls_get_alt_image_source(image_id, dev_handle,
+						       image_spec);
+	}
+
+	return result;
+}
diff --git a/plat/layerscape/common/ls_timer.c b/plat/layerscape/common/ls_timer.c
new file mode 100644
index 0000000..25b5e63
--- /dev/null
+++ b/plat/layerscape/common/ls_timer.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <delay_timer.h>
+#include <arch_helpers.h>
+
+#define TIMER_BASE_ADDR 0x02B00000
+
+uint64_t ls_get_timer(uint64_t start)
+{
+	return read_cntpct_el0() * 1000 / read_cntfrq_el0() - start;
+}
+
+static uint32_t ls_timeus_get_value(void)
+{
+	/*
+	 * Generic delay timer implementation expects the timer to be a down
+	 * counter. We apply bitwise NOT operator to the tick values returned
+	 * by read_cntpct_el0() to simulate the down counter. The value is
+	 * clipped from 64 to 32 bits.
+	 */
+	return (uint32_t)(~read_cntpct_el0());
+}
+
+static const timer_ops_t ls_timer_ops = {
+	.get_timer_value	= ls_timeus_get_value,
+	.clk_mult		= 1,
+	.clk_div		= 25,
+};
+
+
+/*
+ * Initialise the nxp layerscape on-chip free rolling us counter as the delay
+ * timer.
+ */
+void ls_delay_timer_init(void)
+{
+	uintptr_t cntcr =  TIMER_BASE_ADDR;
+
+	mmio_write_32(cntcr, 0x1);
+
+	timer_init(&ls_timer_ops);
+}
diff --git a/plat/layerscape/common/ls_topology.c b/plat/layerscape/common/ls_topology.c
new file mode 100644
index 0000000..5b76087
--- /dev/null
+++ b/plat/layerscape/common/ls_topology.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat_ls.h"
+
+/*******************************************************************************
+ * This function validates an MPIDR by checking whether it falls within the
+ * acceptable bounds. An error code (-1) is returned if an incorrect mpidr
+ * is passed.
+ ******************************************************************************/
+int ls_check_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+	uint64_t valid_mask;
+
+	valid_mask = ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK);
+	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+	if (mpidr & valid_mask)
+		return -1;
+
+	if (cluster_id >= PLAT_LS_CLUSTER_COUNT)
+		return -1;
+
+	/*
+	 * Validate cpu_id by checking whether it represents a CPU in
+	 * one of the two clusters present on the platform.
+	 */
+	if (cpu_id >= plat_ls_get_cluster_core_count(mpidr))
+		return -1;
+
+
+	return 0;
+}
diff --git a/plat/layerscape/common/ls_tzc380.c b/plat/layerscape/common/ls_tzc380.c
new file mode 100644
index 0000000..b9f32ac
--- /dev/null
+++ b/plat/layerscape/common/ls_tzc380.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <endian.h>
+#include "platform_def.h"
+#include "soc_tzasc.h"
+
+int tzc380_set_region(unsigned int tzasc_base, unsigned int region_id,
+		unsigned int enabled, unsigned int low_addr,
+		unsigned int high_addr, unsigned int size,
+		unsigned int security, unsigned int subreg_disable_mask)
+{
+	unsigned int reg;
+	unsigned int reg_base;
+	unsigned int attr_value;
+
+	reg_base = (tzasc_base + TZASC_REGIONS_REG + (region_id << 4));
+
+	if (region_id == 0) {
+		reg = (reg_base + TZASC_REGION_ATTR_OFFSET);
+		mmio_write_32((uintptr_t)reg, ((security & 0xF) << 28));
+	} else {
+		reg = reg_base + TZASC_REGION_LOWADDR_OFFSET;
+		mmio_write_32((uintptr_t)reg,
+				(low_addr & TZASC_REGION_LOWADDR_MASK));
+
+		reg = reg_base + TZASC_REGION_HIGHADDR_OFFSET;
+		mmio_write_32((uintptr_t)reg, high_addr);
+
+		reg = reg_base + TZASC_REGION_ATTR_OFFSET;
+		attr_value = ((security & 0xF) << 28) |
+			((subreg_disable_mask & 0xFF) << 8) |
+			((size & 0x3F) << 1) | (enabled & 0x1);
+		mmio_write_32((uintptr_t)reg, attr_value);
+
+	}
+	return 0;
+}
+
+int tzc380_setup(void)
+{
+	int reg_id = 0;
+
+	INFO("Configuring TZASC-380\n");
+
+	/*
+	 * Configure CCI control override register to terminate all barrier
+	 * transactions
+	 */
+	mmio_write_32(PLAT_LS1043_CCI_BASE, CCI_TERMINATE_BARRIER_TX);
+
+	/* Configure CSU secure access register to disable TZASC bypass mux */
+	mmio_write_32((uintptr_t)(CONFIG_SYS_FSL_CSU_ADDR +
+				CSU_SEC_ACCESS_REG_OFFSET),
+			bswap32(TZASC_BYPASS_MUX_DISABLE));
+
+	for (reg_id = 0; reg_id < MAX_NUM_TZC_REGION; reg_id++) {
+		tzc380_set_region(CONFIG_SYS_FSL_TZASC_ADDR,
+				reg_id,
+				tzc380_reg_list[reg_id].enabled,
+				tzc380_reg_list[reg_id].low_addr,
+				tzc380_reg_list[reg_id].high_addr,
+				tzc380_reg_list[reg_id].size,
+				tzc380_reg_list[reg_id].secure,
+				tzc380_reg_list[reg_id].sub_mask);
+	}
+
+	return 0;
+}
diff --git a/plat/layerscape/common/ns_access.c b/plat/layerscape/common/ns_access.c
new file mode 100644
index 0000000..e1daaed
--- /dev/null
+++ b/plat/layerscape/common/ns_access.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <endian.h>
+#include <debug.h>
+#include "ns_access.h"
+#include "platform_def.h"
+
+static void enable_devices_ns_access(struct csu_ns_dev *ns_dev, uint32_t num)
+{
+	uint32_t *base = (uint32_t *)CONFIG_SYS_FSL_CSU_ADDR;
+	uint32_t *reg;
+	uint32_t val;
+	int i;
+
+	for (i = 0; i < num; i++) {
+		reg = base + ns_dev[i].ind / 2;
+		val = be32toh(mmio_read_32((uintptr_t)reg));
+		if (ns_dev[i].ind % 2 == 0) {
+			val &= 0x0000ffff;
+			val |= ns_dev[i].val << 16;
+		} else {
+			val &= 0xffff0000;
+			val |= ns_dev[i].val;
+		}
+		mmio_write_32((uintptr_t)reg, htobe32(val));
+	}
+}
+
+void enable_layerscape_ns_access(void)
+{
+	enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev));
+}
diff --git a/plat/layerscape/common/tsp/ls_tsp.mk b/plat/layerscape/common/tsp/ls_tsp.mk
new file mode 100644
index 0000000..7cb9781
--- /dev/null
+++ b/plat/layerscape/common/tsp/ls_tsp.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# TSP source files common to ARM standard platforms
+BL32_SOURCES		+=	plat/layerscape/common/ls_topology.c			\
+				plat/layerscape/common/tsp/ls_tsp_setup.c		\
+				plat/common/aarch64/platform_mp_stack.S
diff --git a/plat/layerscape/common/tsp/ls_tsp_setup.c b/plat/layerscape/common/tsp/ls_tsp_setup.c
new file mode 100644
index 0000000..82ac965
--- /dev/null
+++ b/plat/layerscape/common/tsp/ls_tsp_setup.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <gicv2.h>
+#include <debug.h>
+#include "ls_16550.h"
+#include "plat_ls.h"
+#include "soc.h"
+
+#define BL32_END (unsigned long)(&__BL32_END__)
+
+const unsigned int g0_interrupt_array1[] = {
+	9
+};
+
+gicv2_driver_data_t ls_gic_data = {
+	.gicd_base = GICD_BASE,
+	.gicc_base = GICC_BASE,
+	.g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array1),
+	.g0_interrupt_array = g0_interrupt_array1,
+};
+
+/*******************************************************************************
+ * Initialize the UART
+ ******************************************************************************/
+void ls_tsp_early_platform_setup(void)
+{
+	static console_ls_16550_t console;
+	/*
+	 * Initialize a different console than already in use to display
+	 * messages from TSP
+	 */
+	console_ls_16550_register(PLAT_LS1043_UART2_BASE, PLAT_LS1043_UART_CLOCK,
+			PLAT_LS1043_UART_BAUDRATE, &console);
+	NOTICE(FIRMWARE_WELCOME_STR_LS1043_BL32);
+}
+
+/*******************************************************************************
+ * Perform platform specific setup placeholder
+ ******************************************************************************/
+void tsp_platform_setup(void)
+{
+	uint32_t gicc_base, gicd_base;
+
+	/* Initialize the GIC driver, cpu and distributor interfaces */
+	get_gic_offset(&gicc_base, &gicd_base);
+	ls_gic_data.gicd_base = (uintptr_t)gicd_base;
+	ls_gic_data.gicc_base = (uintptr_t)gicc_base;
+	gicv2_driver_init(&ls_gic_data);
+	gicv2_distif_init();
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only intializes the MMU
+ ******************************************************************************/
+void tsp_plat_arch_setup(void)
+{
+	ls_setup_page_tables(BL32_BASE,
+			      (BL32_END - BL32_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_el1(0);
+}
diff --git a/plat/layerscape/common/tsp/platform_tsp.h b/plat/layerscape/common/tsp/platform_tsp.h
new file mode 100644
index 0000000..b1c96cb
--- /dev/null
+++ b/plat/layerscape/common/tsp/platform_tsp.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_TSP_H__
+#define __PLATFORM_TSP_H__
+
+/*******************************************************************************
+ * Mandatory TSP functions (only if platform contains a TSP)
+ ******************************************************************************/
+void tsp_early_platform_setup(void);
+void tsp_plat_arch_setup(void);
+void tsp_platform_setup(void);
+
+#endif /* __PLATFORM_TSP_H__ */
diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c
index 83d3625..eb736c0 100644
--- a/services/arm_arch_svc/arm_arch_svc_setup.c
+++ b/services/arm_arch_svc/arm_arch_svc_setup.c
@@ -19,19 +19,16 @@
 
 static int32_t smccc_arch_features(u_register_t arg)
 {
-	int ret;
-
 	switch (arg) {
 	case SMCCC_VERSION:
 	case SMCCC_ARCH_FEATURES:
 		return SMC_OK;
+#if WORKAROUND_CVE_2017_5715
 	case SMCCC_ARCH_WORKAROUND_1:
-		ret = check_workaround_cve_2017_5715();
-		if (ret == ERRATA_APPLIES)
-			return 0;
-		else if (ret == ERRATA_NOT_APPLIES)
+		if (check_workaround_cve_2017_5715() == ERRATA_NOT_APPLIES)
 			return 1;
-		return -1; /* ERRATA_MISSING */
+		return 0; /* ERRATA_APPLIES || ERRATA_MISSING */
+#endif
 	default:
 		return SMC_UNK;
 	}