Merge pull request #1345 from dbasehore/udelay

rockchip/rk3399: Fix sram_udelay
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/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index 49e4e8e..25be577 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -24,12 +24,12 @@
  * Function declarations.
  */
 static int bl1_fwu_image_copy(unsigned int image_id,
-			uintptr_t image_addr,
+			uintptr_t image_src,
 			unsigned int block_size,
 			unsigned int image_size,
 			unsigned int flags);
 static int bl1_fwu_image_auth(unsigned int image_id,
-			uintptr_t image_addr,
+			uintptr_t image_src,
 			unsigned int image_size,
 			unsigned int flags);
 static int bl1_fwu_image_execute(unsigned int image_id,
@@ -50,7 +50,7 @@
 static unsigned int sec_exec_image_id = INVALID_IMAGE_ID;
 
 /* Authentication status of each image. */
-extern unsigned int auth_img_flags[];
+extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
 
 /*******************************************************************************
  * Top level handler for servicing FWU SMCs.
diff --git a/bl1/tbbr/tbbr_img_desc.c b/bl1/tbbr/tbbr_img_desc.c
index f2ed1a1..44f58d3 100644
--- a/bl1/tbbr/tbbr_img_desc.c
+++ b/bl1/tbbr/tbbr_img_desc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #include <bl1.h>
 #include <bl_common.h>
 #include <platform_def.h>
+#include <tbbr/tbbr_img_desc.h>
 
 image_desc_t bl1_tbbr_image_descs[] = {
     {
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_image_load.c b/bl2/bl2_image_load.c
index d5d28a5..d22e9ce 100644
--- a/bl2/bl2_image_load.c
+++ b/bl2/bl2_image_load.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
  */
@@ -182,7 +182,7 @@
  * This function loads SCP_BL2/BL3x images and returns the ep_info for
  * the next executable image.
  ******************************************************************************/
-entry_point_info_t *bl2_load_images(void)
+struct entry_point_info *bl2_load_images(void)
 {
 	bl31_params_t *bl2_to_bl31_params;
 	entry_point_info_t *bl31_ep_info;
diff --git a/bl2/bl2_image_load_v2.c b/bl2/bl2_image_load_v2.c
index d95c6b2..0f40785 100644
--- a/bl2/bl2_image_load_v2.c
+++ b/bl2/bl2_image_load_v2.c
@@ -21,7 +21,7 @@
  * This function loads SCP_BL2/BL3x images and returns the ep_info for
  * the next executable image.
  ******************************************************************************/
-entry_point_info_t *bl2_load_images(void)
+struct entry_point_info *bl2_load_images(void)
 {
 	bl_params_t *bl2_to_next_bl_params;
 	bl_load_info_t *bl2_load_info;
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/bl32/tsp/tsp_private.h b/bl32/tsp/tsp_private.h
index b11570c..dd65a5f 100644
--- a/bl32/tsp/tsp_private.h
+++ b/bl32/tsp/tsp_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,7 +62,7 @@
 
 void tsp_get_magic(uint64_t args[4]);
 
-tsp_args_t *tsp_cpu_resume_main(uint64_t arg0,
+tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl,
 				uint64_t arg1,
 				uint64_t arg2,
 				uint64_t arg3,
@@ -106,7 +106,47 @@
 /* Vector table of jumps */
 extern tsp_vectors_t tsp_vector_table;
 
+/* functions */
+int32_t tsp_common_int_handler(void);
+int32_t tsp_handle_preemption(void);
 
+tsp_args_t *tsp_abort_smc_handler(uint64_t func,
+				  uint64_t arg1,
+				  uint64_t arg2,
+				  uint64_t arg3,
+				  uint64_t arg4,
+				  uint64_t arg5,
+				  uint64_t arg6,
+				  uint64_t arg7);
+
+tsp_args_t *tsp_smc_handler(uint64_t func,
+			       uint64_t arg1,
+			       uint64_t arg2,
+			       uint64_t arg3,
+			       uint64_t arg4,
+			       uint64_t arg5,
+			       uint64_t arg6,
+			       uint64_t arg7);
+
+tsp_args_t *tsp_system_reset_main(uint64_t arg0,
+				uint64_t arg1,
+				uint64_t arg2,
+				uint64_t arg3,
+				uint64_t arg4,
+				uint64_t arg5,
+				uint64_t arg6,
+				uint64_t arg7);
+
+tsp_args_t *tsp_system_off_main(uint64_t arg0,
+				uint64_t arg1,
+				uint64_t arg2,
+				uint64_t arg3,
+				uint64_t arg4,
+				uint64_t arg5,
+				uint64_t arg6,
+				uint64_t arg7);
+
+uint64_t tsp_main(void);
 #endif /* __ASSEMBLY__ */
 
 #endif /* __TSP_PRIVATE_H__ */
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/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index 1cea60b..eb537b6 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,7 +30,7 @@
 
 /* Pointer to CoT */
 extern const auth_img_desc_t *const cot_desc_ptr;
-extern unsigned int auth_img_flags[];
+extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
 
 static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
 		const auth_param_type_desc_t *b)
diff --git a/drivers/auth/crypto_mod.c b/drivers/auth/crypto_mod.c
index 3b3e3ac..4cd0550 100644
--- a/drivers/auth/crypto_mod.c
+++ b/drivers/auth/crypto_mod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,6 @@
 #include <debug.h>
 
 /* Variable exported by the crypto library through REGISTER_CRYPTO_LIB() */
-extern const crypto_lib_desc_t crypto_lib_desc;
 
 /*
  * The crypto module is responsible for verifying digital signatures and hashes.
diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c
index 205c243..c048d00 100644
--- a/drivers/auth/mbedtls/mbedtls_common.c
+++ b/drivers/auth/mbedtls/mbedtls_common.c
@@ -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
  */
@@ -10,6 +10,7 @@
 #include <mbedtls/memory_buffer_alloc.h>
 #include <mbedtls/platform.h>
 #include <mbedtls_config.h>
+#include <mbedtls_common.h>
 
 /*
  * mbed TLS heap
diff --git a/include/bl2/bl2.h b/include/bl2/bl2.h
index f2bd07e..89ff06e 100644
--- a/include/bl2/bl2.h
+++ b/include/bl2/bl2.h
@@ -7,9 +7,6 @@
 #ifndef BL2_H__
 #define BL2_H__
 
-struct entry_point_info;
-
 void bl2_main(void);
-struct entry_point_info *bl2_load_images(void);
 
 #endif /* BL2_H__ */
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/common/runtime_svc.h b/include/common/runtime_svc.h
index 5d9fa39..706c211 100644
--- a/include/common/runtime_svc.h
+++ b/include/common/runtime_svc.h
@@ -102,15 +102,15 @@
  * oen is used to access an entry in the 'rt_svc_descs_indices' array. The entry
  * contains the index of the service descriptor in the 'rt_svc_descs' array.
  */
-#define get_unique_oen(oen, call_type)	((oen & FUNCID_OEN_MASK) |	\
-					((call_type & FUNCID_TYPE_MASK) \
-					 << FUNCID_OEN_WIDTH))
+#define get_unique_oen(oen, call_type)				\
+	(((uint32_t)(oen) & FUNCID_OEN_MASK) |			\
+	(((uint32_t)(call_type) & FUNCID_TYPE_MASK) << FUNCID_OEN_WIDTH))
 
 /*
  * This macro generates the unique owning entity number from the SMC Function
- * ID.  This unique oen is used to access an entry in the
- * 'rt_svc_descs_indices' array to invoke the corresponding runtime service
- * handler during SMC handling.
+ * ID. This unique oen is used to access an entry in the 'rt_svc_descs_indices'
+ * array to invoke the corresponding runtime service handler during SMC
+ * handling.
  */
 #define get_unique_oen_from_smc_fid(fid)		\
 	get_unique_oen(((fid) >> FUNCID_OEN_SHIFT),	\
diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h
index 060198b..273abbe 100644
--- a/include/common/tbbr/tbbr_img_def.h
+++ b/include/common/tbbr/tbbr_img_def.h
@@ -75,4 +75,7 @@
 /* NT_FW_CONFIG */
 #define NT_FW_CONFIG_ID		27
 
+/* Define size of the array */
+#define MAX_NUMBER_IDS			28
+
 #endif /* __TBBR_IMG_DEF_H__ */
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/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h
index bd65098..bb3b8f9 100644
--- a/include/drivers/auth/auth_mod.h
+++ b/include/drivers/auth/auth_mod.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,7 @@
 #include <auth_common.h>
 #include <cot_def.h>
 #include <img_parser_mod.h>
+#include <tbbr_img_def.h>
 
 /*
  * Image flags
@@ -41,7 +42,10 @@
 #define REGISTER_COT(_cot) \
 	const auth_img_desc_t *const cot_desc_ptr = \
 			(const auth_img_desc_t *const)&_cot[0]; \
-	unsigned int auth_img_flags[sizeof(_cot)/sizeof(_cot[0])]
+	unsigned int auth_img_flags[MAX_NUMBER_IDS]
+
+extern const auth_img_desc_t *const cot_desc_ptr;
+extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
 
 #endif /* TRUSTED_BOARD_BOOT */
 
diff --git a/include/drivers/auth/crypto_mod.h b/include/drivers/auth/crypto_mod.h
index 08884ab..f9b44d1 100644
--- a/include/drivers/auth/crypto_mod.h
+++ b/include/drivers/auth/crypto_mod.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,7 +43,7 @@
 void crypto_mod_init(void);
 int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
 				void *sig_ptr, unsigned int sig_len,
-				void *sig_alg, unsigned int sig_alg_len,
+				void *sig_alg_ptr, unsigned int sig_alg_len,
 				void *pk_ptr, unsigned int pk_len);
 int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
 			   void *digest_info_ptr, unsigned int digest_info_len);
@@ -57,4 +57,6 @@
 		.verify_hash = _verify_hash \
 	}
 
+extern const crypto_lib_desc_t crypto_lib_desc;
+
 #endif /* __CRYPTO_MOD_H__ */
diff --git a/include/drivers/auth/img_parser_mod.h b/include/drivers/auth/img_parser_mod.h
index 347ed62..eaf3e6e 100644
--- a/include/drivers/auth/img_parser_mod.h
+++ b/include/drivers/auth/img_parser_mod.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -44,10 +44,10 @@
 /* Exported functions */
 void img_parser_init(void);
 int img_parser_check_integrity(img_type_t img_type,
-		void *img, unsigned int img_len);
+		void *img_ptr, unsigned int img_len);
 int img_parser_get_auth_param(img_type_t img_type,
 		const auth_param_type_desc_t *type_desc,
-		void *img, unsigned int img_len,
+		void *img_ptr, unsigned int img_len,
 		void **param_ptr, unsigned int *param_len);
 
 /* Macro to register an image parser library */
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 91aa484..ff3881e 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -442,10 +442,10 @@
 #define GET_M32(mode)		(((mode) >> MODE32_SHIFT) & MODE32_MASK)
 
 #define SPSR_64(el, sp, daif)				\
-	(MODE_RW_64 << MODE_RW_SHIFT |			\
-	((el) & MODE_EL_MASK) << MODE_EL_SHIFT |	\
-	((sp) & MODE_SP_MASK) << MODE_SP_SHIFT |	\
-	((daif) & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT)
+	((MODE_RW_64 << MODE_RW_SHIFT) |		\
+	(((el) & MODE_EL_MASK) << MODE_EL_SHIFT) |	\
+	(((sp) & MODE_SP_MASK) << MODE_SP_SHIFT) |	\
+	(((daif) & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT))
 
 #define SPSR_MODE32(mode, isa, endian, aif)		\
 	((MODE_RW_32 << MODE_RW_SHIFT) |		\
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/lib/smccc.h b/include/lib/smccc.h
index d683420..b1d4dea 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -76,8 +76,8 @@
 #define SMC_FROM_SECURE		(U(0) << 0)
 #define SMC_FROM_NON_SECURE	(U(1) << 0)
 
-#define is_caller_non_secure(_f)	(!!(_f & SMC_FROM_NON_SECURE))
-#define is_caller_secure(_f)		(!(is_caller_non_secure(_f)))
+#define is_caller_non_secure(_f)	(((_f) & SMC_FROM_NON_SECURE) != U(0))
+#define is_caller_secure(_f)		(!is_caller_non_secure(_f))
 
 /* The macro below is used to identify a Standard Service SMC call */
 #define is_std_svc_call(_fid)		((((_fid) >> FUNCID_OEN_SHIFT) & \
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index ba3e360..b237945 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -299,7 +299,7 @@
  * executing.
  */
 int change_mem_attributes(xlat_ctx_t *ctx, uintptr_t base_va, size_t size,
-			mmap_attr_t attr);
+			  uint32_t attr);
 
 /*
  * Query the memory attributes of a memory page in a set of translation tables.
@@ -317,7 +317,7 @@
  *   Output parameter where to store the attributes of the targeted memory page.
  */
 int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va,
-		mmap_attr_t *attributes);
+		       uint32_t *attributes);
 
 #endif /*__ASSEMBLY__*/
 #endif /* __XLAT_TABLES_V2_H__ */
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..aa13064 100644
--- a/lib/xlat_tables_v2/xlat_tables_internal.c
+++ b/lib/xlat_tables_v2/xlat_tables_internal.c
@@ -115,8 +115,8 @@
 /*
  * Returns a block/page table descriptor for the given level and attributes.
  */
-static uint64_t xlat_desc(const xlat_ctx_t *ctx, mmap_attr_t attr,
-		   unsigned long long addr_pa, int level)
+static uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
+			  unsigned long long addr_pa, int level)
 {
 	uint64_t desc;
 	int mem_type;
@@ -561,7 +561,8 @@
 		if (action == ACTION_WRITE_BLOCK_ENTRY) {
 
 			table_base[table_idx] =
-				xlat_desc(ctx, mm->attr, table_idx_pa, level);
+				xlat_desc(ctx, (uint32_t)mm->attr, table_idx_pa,
+					  level);
 
 		} else if (action == ACTION_CREATE_NEW_TABLE) {
 
@@ -735,7 +736,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 +788,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 +812,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;
 
@@ -1411,7 +1428,7 @@
 
 
 static int get_mem_attributes_internal(const xlat_ctx_t *ctx, uintptr_t base_va,
-		mmap_attr_t *attributes, uint64_t **table_entry,
+		uint32_t *attributes, uint64_t **table_entry,
 		unsigned long long *addr_pa, int *table_level)
 {
 	uint64_t *entry;
@@ -1502,7 +1519,7 @@
 
 
 int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va,
-		mmap_attr_t *attributes)
+		       uint32_t *attributes)
 {
 	return get_mem_attributes_internal(ctx, base_va, attributes,
 					   NULL, NULL, NULL);
@@ -1512,7 +1529,7 @@
 int change_mem_attributes(xlat_ctx_t *ctx,
 			uintptr_t base_va,
 			size_t size,
-			mmap_attr_t attr)
+			uint32_t attr)
 {
 	/* Note: This implementation isn't optimized. */
 
@@ -1609,7 +1626,7 @@
 
 	for (int i = 0; i < pages_count; ++i) {
 
-		mmap_attr_t old_attr, new_attr;
+		uint32_t old_attr, new_attr;
 		uint64_t *entry;
 		int level;
 		unsigned long long addr_pa;
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_private.h b/plat/arm/board/fvp/fvp_private.h
index c5cd07d..16f10a2 100644
--- a/plat/arm/board/fvp/fvp_private.h
+++ b/plat/arm/board/fvp/fvp_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +18,7 @@
 void fvp_interconnect_init(void);
 void fvp_interconnect_enable(void);
 void fvp_interconnect_disable(void);
+void tsp_early_platform_setup(void);
 
 
 #endif /* __FVP_PRIVATE_H__ */
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_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c
index 1305934..f2be477 100644
--- a/plat/arm/common/arm_bl1_fwu.c
+++ b/plat/arm/common/arm_bl1_fwu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <debug.h>
 #include <errno.h>
 #include <plat_arm.h>
+#include <platform.h>
 #include <platform_def.h>
 #include <tbbr_img_desc.h>
 #include <utils.h>
@@ -19,7 +20,7 @@
 	unsigned int mem_size;
 } bl1_mem_info_t;
 
-bl1_mem_info_t fwu_addr_map_secure[] = {
+static bl1_mem_info_t fwu_addr_map_secure[] = {
 	{
 		.mem_base = ARM_SHARED_RAM_BASE,
 		.mem_size = ARM_SHARED_RAM_SIZE
@@ -29,7 +30,7 @@
 	}
 };
 
-bl1_mem_info_t fwu_addr_map_non_secure[] = {
+static bl1_mem_info_t fwu_addr_map_non_secure[] = {
 	{
 		.mem_base = ARM_NS_DRAM1_BASE,
 		.mem_size = ARM_NS_DRAM1_SIZE
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index cfcbf2a..9ba51a3 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arm_dyn_cfg_helpers.h>
 #include <assert.h>
 #include <desc_image_load.h>
 #include <fdt_wrappers.h>
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/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index cfbb3e9..72d5527 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -28,13 +28,14 @@
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
 BL31_SOURCES		+=	plat/arm/css/drivers/scp/css_pm_scpi.c		\
-				plat/arm/css/drivers/scpi/css_mhu.c		\
+				plat/arm/css/drivers/mhu/css_mhu.c		\
 				plat/arm/css/drivers/scpi/css_scpi.c
 else
 BL31_SOURCES		+=	plat/arm/css/drivers/scp/css_pm_scmi.c		\
 				plat/arm/css/drivers/scmi/scmi_common.c		\
 				plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c	\
-				plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c
+				plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c	\
+				plat/arm/css/drivers/mhu/css_mhu_doorbell.c
 endif
 
 ifneq (${RESET_TO_BL31},0)
@@ -60,11 +61,11 @@
 				plat/arm/css/drivers/sds/sds.c
   else
     BL2U_SOURCES	+=	plat/arm/css/drivers/scp/css_bom_bootloader.c	\
-				plat/arm/css/drivers/scpi/css_mhu.c		\
+				plat/arm/css/drivers/mhu/css_mhu.c		\
 				plat/arm/css/drivers/scpi/css_scpi.c
 
     BL2_SOURCES		+=	plat/arm/css/drivers/scp/css_bom_bootloader.c	\
-				plat/arm/css/drivers/scpi/css_mhu.c		\
+				plat/arm/css/drivers/mhu/css_mhu.c		\
 				plat/arm/css/drivers/scpi/css_scpi.c
     # Enable option to detect whether the SCP ROM firmware in use predates version
     # 1.7.0 and therefore, is incompatible.
diff --git a/plat/arm/css/common/sp_min/css_sp_min.mk b/plat/arm/css/common/sp_min/css_sp_min.mk
index 28eb2db..9fb280c 100644
--- a/plat/arm/css/common/sp_min/css_sp_min.mk
+++ b/plat/arm/css/common/sp_min/css_sp_min.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -10,11 +10,12 @@
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
 BL32_SOURCES		+=	plat/arm/css/drivers/scp/css_pm_scpi.c		\
-				plat/arm/css/drivers/scpi/css_mhu.c		\
+				plat/arm/css/drivers/mhu/css_mhu.c		\
 				plat/arm/css/drivers/scpi/css_scpi.c
 else
 BL32_SOURCES		+=	plat/arm/css/drivers/scp/css_pm_scmi.c		\
 				plat/arm/css/drivers/scmi/scmi_common.c		\
 				plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c	\
-				plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c
+				plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c	\
+				plat/arm/css/drivers/mhu/css_mhu_doorbell.c
 endif
diff --git a/plat/arm/css/drivers/scpi/css_mhu.c b/plat/arm/css/drivers/mhu/css_mhu.c
similarity index 96%
rename from plat/arm/css/drivers/scpi/css_mhu.c
rename to plat/arm/css/drivers/mhu/css_mhu.c
index 500b8df..30492a6 100644
--- a/plat/arm/css/drivers/scpi/css_mhu.c
+++ b/plat/arm/css/drivers/mhu/css_mhu.c
@@ -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
  */
diff --git a/plat/arm/css/drivers/scpi/css_mhu.h b/plat/arm/css/drivers/mhu/css_mhu.h
similarity index 85%
rename from plat/arm/css/drivers/scpi/css_mhu.h
rename to plat/arm/css/drivers/mhu/css_mhu.h
index 298eee9..0fb00c7 100644
--- a/plat/arm/css/drivers/scpi/css_mhu.h
+++ b/plat/arm/css/drivers/mhu/css_mhu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
new file mode 100644
index 0000000..b9faf67
--- /dev/null
+++ b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <platform_def.h>
+#include "css_mhu_doorbell.h"
+#include "../scmi/scmi.h"
+
+void mhu_ring_doorbell(scmi_channel_plat_info_t *plat_info)
+{
+	MHU_RING_DOORBELL(plat_info->db_reg_addr,
+			plat_info->db_modify_mask,
+			plat_info->db_preserve_mask);
+	return;
+}
+
+void mhuv2_ring_doorbell(scmi_channel_plat_info_t *plat_info)
+{
+	/* wake receiver */
+	MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR);
+
+	/* wait for receiver to acknowledge its ready */
+	while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0)
+		;
+
+	MHU_RING_DOORBELL(plat_info->db_reg_addr,
+			plat_info->db_modify_mask,
+			plat_info->db_preserve_mask);
+
+	/* clear the access request for the recevier */
+	MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR);
+
+	return;
+}
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h
new file mode 100644
index 0000000..3c94536
--- /dev/null
+++ b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CSS_MHU_DOORBELL_H
+#define CSS_MHU_DOORBELL_H
+
+#include <mmio.h>
+#include <stdint.h>
+
+/* MHUv2 Base Address */
+#define MHUV2_BASE_ADDR		PLAT_CSS_MHU_BASE
+
+/* MHUv2 Control Registers Offsets */
+#define MHU_V2_MSG_NO_CAP_OFFSET		0xF80
+#define MHU_V2_ACCESS_REQ_OFFSET		0xF88
+#define MHU_V2_ACCESS_READY_OFFSET		0xF8C
+
+#define SENDER_REG_STAT(CHANNEL)	(0x20 * (CHANNEL))
+#define SENDER_REG_SET(CHANNEL)		(0x20 * (CHANNEL)) + 0xC
+
+/* Helper macro to ring doorbell */
+#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask)	do {	\
+		uint32_t db = mmio_read_32(addr) & (preserve_mask);	\
+		mmio_write_32(addr, db | (modify_mask));		\
+	} while (0)
+
+#define MHU_V2_ACCESS_REQUEST(addr)	\
+	mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1)
+
+#define MHU_V2_CLEAR_REQUEST(addr)	\
+	mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0)
+
+#define MHU_V2_IS_ACCESS_READY(addr)	\
+	(mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1)
+
+struct scmi_channel_plat_info;
+void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info);
+void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info);
+
+#endif	/* CSS_MHU_DOORBELL_H */
diff --git a/plat/arm/css/drivers/scmi/scmi.h b/plat/arm/css/drivers/scmi/scmi.h
index 850402a..cf9ef5e 100644
--- a/plat/arm/css/drivers/scmi/scmi.h
+++ b/plat/arm/css/drivers/scmi/scmi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -96,6 +96,10 @@
 	uint32_t db_preserve_mask;
 	/* The bit mask that need to be set to ring doorbell */
 	uint32_t db_modify_mask;
+	/* The handler for ringing doorbell */
+	void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info);
+	/* cookie is unused now. But added for future enhancements. */
+	void *cookie;
 } scmi_channel_plat_info_t;
 
 /*
diff --git a/plat/arm/css/drivers/scmi/scmi_common.c b/plat/arm/css/drivers/scmi/scmi_common.c
index d0051c7..8482d21 100644
--- a/plat/arm/css/drivers/scmi/scmi_common.c
+++ b/plat/arm/css/drivers/scmi/scmi_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -39,9 +39,7 @@
 	 */
 	dmbst();
 
-	SCMI_RING_DOORBELL(ch->info->db_reg_addr, ch->info->db_modify_mask,
-					ch->info->db_preserve_mask);
-
+	ch->info->ring_doorbell(ch->info);
 	/*
 	 * Ensure that the write to the doorbell register is ordered prior to
 	 * checking whether the channel is free.
@@ -150,6 +148,7 @@
 	assert(ch->info->db_reg_addr);
 	assert(ch->info->db_modify_mask);
 	assert(ch->info->db_preserve_mask);
+	assert(ch->info->ring_doorbell != NULL);
 
 	assert(ch->lock);
 
diff --git a/plat/arm/css/drivers/scmi/scmi_private.h b/plat/arm/css/drivers/scmi/scmi_private.h
index 20e1e9b..a07841e 100644
--- a/plat/arm/css/drivers/scmi/scmi_private.h
+++ b/plat/arm/css/drivers/scmi/scmi_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -113,12 +113,6 @@
 		(val3) = mmio_read_32((uintptr_t)&payld_arr[2]);	\
 	} while (0)
 
-/* Helper macro to ring doorbell */
-#define SCMI_RING_DOORBELL(addr, modify_mask, preserve_mask)	do {	\
-		uint32_t db = mmio_read_32(addr) & (preserve_mask);	\
-		mmio_write_32(addr, db | (modify_mask));		\
-	} while (0)
-
 /*
  * Private data structure for representing the mailbox memory layout. Refer
  * the SCMI specification for more details.
diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c
index 08d6fc5..42ed30d 100644
--- a/plat/arm/css/drivers/scp/css_bom_bootloader.c
+++ b/plat/arm/css/drivers/scp/css_bom_bootloader.c
@@ -10,7 +10,7 @@
 #include <debug.h>
 #include <platform.h>
 #include <stdint.h>
-#include "../scpi/css_mhu.h"
+#include "../mhu/css_mhu.h"
 #include "../scpi/css_scpi.h"
 #include "css_scp.h"
 
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c
index f8bc20c..c0ed487 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scmi.c
@@ -13,6 +13,7 @@
 #include <platform.h>
 #include <string.h>
 #include "../scmi/scmi.h"
+#include "../mhu/css_mhu_doorbell.h"
 #include "css_scp.h"
 
 /*
@@ -76,7 +77,7 @@
  * Helper function to suspend a CPU power domain and its parent power domains
  * if applicable.
  */
-void css_scp_suspend(const psci_power_state_t *target_state)
+void css_scp_suspend(const struct psci_power_state *target_state)
 {
 	int lvl, ret;
 	uint32_t scmi_pwr_state = 0;
@@ -302,6 +303,7 @@
 		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
 		.db_preserve_mask = 0xfffffffe,
 		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
 };
 
 void plat_arm_pwrc_setup(void)
diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/plat/arm/css/drivers/scp/css_pm_scpi.c
index 545c3fb..23fd80e 100644
--- a/plat/arm/css/drivers/scp/css_pm_scpi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scpi.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
  */
@@ -19,7 +19,7 @@
 /*
  * Helper function to inform power down state to SCP.
  */
-void css_scp_suspend(const psci_power_state_t *target_state)
+void css_scp_suspend(const struct psci_power_state *target_state)
 {
 	uint32_t cluster_state = scpi_power_on;
 	uint32_t system_state = scpi_power_on;
diff --git a/plat/arm/css/drivers/scpi/css_scpi.c b/plat/arm/css/drivers/scpi/css_scpi.c
index 3e92c86..2ed5760 100644
--- a/plat/arm/css/drivers/scpi/css_scpi.c
+++ b/plat/arm/css/drivers/scpi/css_scpi.c
@@ -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
  */
@@ -11,7 +11,7 @@
 #include <platform.h>
 #include <string.h>
 #include <utils.h>
-#include "css_mhu.h"
+#include "../mhu/css_mhu.h"
 #include "css_scpi.h"
 
 #define SCPI_SHARED_MEM_SCP_TO_AP	PLAT_CSS_SCP_COM_SHARED_MEM_BASE
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 9c398b7..659351a 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -45,6 +45,7 @@
 override CSS_LOAD_SCP_IMAGES	:=	0
 override NEED_BL2U		:=	no
 override ARM_BL31_IN_DRAM	:=	1
+override ARM_PLAT_MT		:=	1
 
 # System coherency is managed in hardware
 HW_ASSISTED_COHERENCY	:=	1
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/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index b446235..e74b9bb 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -34,9 +34,14 @@
  * little space for growth.
  */
 #ifndef ZYNQMP_ATF_MEM_BASE
+#if !DEBUG
 # define BL31_BASE			0xfffea000
 # define BL31_LIMIT			0xffffffff
 #else
+# define BL31_BASE			0x1000
+# define BL31_LIMIT			0x7ffff
+#endif
+#else
 # define BL31_BASE			(ZYNQMP_ATF_MEM_BASE)
 # define BL31_LIMIT			(ZYNQMP_ATF_MEM_BASE + ZYNQMP_ATF_MEM_SIZE - 1)
 # ifdef ZYNQMP_ATF_MEM_PROGBITS_SIZE
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index bddf305..e49a9cd 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/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
 
@@ -77,6 +77,9 @@
 				plat/xilinx/zynqmp/zynqmp_ipi.c		\
 				plat/xilinx/zynqmp/pm_service/pm_svc_main.c	\
 				plat/xilinx/zynqmp/pm_service/pm_api_sys.c	\
+				plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c	\
+				plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c	\
+				plat/xilinx/zynqmp/pm_service/pm_api_clock.c	\
 				plat/xilinx/zynqmp/pm_service/pm_ipi.c		\
 				plat/xilinx/zynqmp/pm_service/pm_client.c	\
 				plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
new file mode 100644
index 0000000..a41eebb
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -0,0 +1,3212 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for clock control.
+ */
+
+#include <arch_helpers.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stdbool.h>
+#include <string.h>
+#include "pm_api_clock.h"
+#include "pm_api_sys.h"
+#include "pm_client.h"
+#include "pm_common.h"
+#include "pm_ipi.h"
+
+#define CLK_NODE_MAX			U(6)
+
+#define CLK_PARENTS_ID_LEN		U(16)
+#define CLK_TOPOLOGY_NODE_OFFSET	U(16)
+#define CLK_TOPOLOGY_PAYLOAD_LEN	U(12)
+#define CLK_PARENTS_PAYLOAD_LEN		U(12)
+#define CLK_INIT_ENABLE_SHIFT		U(1)
+#define CLK_TYPE_SHIFT			U(2)
+#define CLK_CLKFLAGS_SHIFT		U(8)
+#define CLK_TYPEFLAGS_SHIFT		U(24)
+
+#define CLK_EXTERNAL_PARENT	(PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
+
+#define NA_MULT					U(0)
+#define NA_DIV					U(0)
+#define NA_SHIFT				U(0)
+#define NA_WIDTH				U(0)
+#define NA_CLK_FLAGS				U(0)
+#define NA_TYPE_FLAGS				U(0)
+
+/* PLL nodes related definitions */
+#define PLL_PRESRC_MUX_SHIFT			U(20)
+#define PLL_PRESRC_MUX_WIDTH			U(3)
+#define PLL_POSTSRC_MUX_SHIFT			U(24)
+#define PLL_POSTSRC_MUX_WIDTH			U(3)
+#define PLL_DIV2_MUX_SHIFT			U(16)
+#define PLL_DIV2_MUX_WIDTH			U(1)
+#define PLL_BYPASS_MUX_SHIFT			U(3)
+#define PLL_BYPASS_MUX_WIDTH			U(1)
+
+/* Peripheral nodes related definitions */
+/* Peripheral Clocks */
+#define PERIPH_MUX_SHIFT			U(0)
+#define PERIPH_MUX_WIDTH			U(3)
+#define PERIPH_DIV1_SHIFT			U(8)
+#define PERIPH_DIV1_WIDTH			U(6)
+#define PERIPH_DIV2_SHIFT			U(16)
+#define PERIPH_DIV2_WIDTH			U(6)
+#define PERIPH_GATE_SHIFT			U(24)
+#define PERIPH_GATE_WIDTH			U(1)
+
+#define USB_GATE_SHIFT				U(25)
+
+/* External clock related definitions */
+
+#define EXT_CLK_MIO_DATA(mio)				\
+	[EXT_CLK_INDEX(EXT_CLK_MIO##mio)] = {		\
+		.name = "mio_clk_"#mio,			\
+	}
+
+#define EXT_CLK_INDEX(n)	(n - CLK_MAX_OUTPUT_CLK)
+
+/* Clock control related definitions */
+#define BIT_MASK(x, y) (((1U << (y)) - 1) << (x))
+
+#define ISPLL(id)	(id == CLK_APLL_INT ||	\
+			 id == CLK_DPLL_INT ||  \
+			 id == CLK_VPLL_INT ||  \
+			 id == CLK_IOPLL_INT || \
+			 id == CLK_RPLL_INT)
+
+
+#define PLLCTRL_BP_MASK				BIT(3)
+#define PLLCTRL_RESET_MASK			U(1)
+#define PLL_FRAC_OFFSET				U(8)
+#define PLL_FRAC_MODE				U(1)
+#define PLL_INT_MODE				U(0)
+#define PLL_FRAC_MODE_MASK			U(0x80000000)
+#define PLL_FRAC_MODE_SHIFT			U(31)
+#define PLL_FRAC_DATA_MASK			U(0xFFFF)
+#define PLL_FRAC_DATA_SHIFT			U(0)
+#define PLL_FBDIV_MASK				U(0x7F00)
+#define PLL_FBDIV_WIDTH				U(7)
+#define PLL_FBDIV_SHIFT				U(8)
+
+#define CLK_PLL_RESET_ASSERT			U(1)
+#define CLK_PLL_RESET_RELEASE			U(2)
+#define CLK_PLL_RESET_PULSE	(CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE)
+
+/* Common topology definitions */
+#define GENERIC_MUX					\
+	{						\
+		.type = TYPE_MUX,			\
+		.offset = PERIPH_MUX_SHIFT,		\
+		.width = PERIPH_MUX_WIDTH,		\
+		.clkflags = CLK_SET_RATE_NO_REPARENT |	\
+			    CLK_IS_BASIC,		\
+		.typeflags = NA_TYPE_FLAGS,		\
+		.mult = NA_MULT,			\
+		.div = NA_DIV,				\
+	}
+
+#define IGNORE_UNUSED_MUX				\
+	{						\
+		.type = TYPE_MUX,			\
+		.offset = PERIPH_MUX_SHIFT,		\
+		.width = PERIPH_MUX_WIDTH,		\
+		.clkflags = CLK_IGNORE_UNUSED |		\
+			    CLK_SET_RATE_NO_REPARENT |	\
+			    CLK_IS_BASIC,		\
+		.typeflags = NA_TYPE_FLAGS,		\
+		.mult = NA_MULT,			\
+		.div = NA_DIV,				\
+	}
+
+#define GENERIC_DIV(id)						\
+	{							\
+		.type = TYPE_DIV##id,				\
+		.offset = PERIPH_DIV##id##_SHIFT,		\
+		.width = PERIPH_DIV##id##_WIDTH,		\
+		.clkflags = CLK_SET_RATE_NO_REPARENT |		\
+			    CLK_IS_BASIC,			\
+		.typeflags = CLK_DIVIDER_ONE_BASED |		\
+			     CLK_DIVIDER_ALLOW_ZERO,		\
+		.mult = NA_MULT,				\
+		.div = NA_DIV,					\
+	}
+
+#define IGNORE_UNUSED_DIV(id)					\
+	{							\
+		.type = TYPE_DIV##id,				\
+		.offset = PERIPH_DIV##id##_SHIFT,		\
+		.width = PERIPH_DIV##id##_WIDTH,		\
+		.clkflags = CLK_IGNORE_UNUSED |			\
+			    CLK_SET_RATE_NO_REPARENT |		\
+			    CLK_IS_BASIC,			\
+		.typeflags = CLK_DIVIDER_ONE_BASED |		\
+			     CLK_DIVIDER_ALLOW_ZERO,		\
+		.mult = NA_MULT,				\
+		.div = NA_DIV,					\
+	}
+
+#define GENERIC_GATE						\
+	{							\
+		.type = TYPE_GATE,				\
+		.offset = PERIPH_GATE_SHIFT,			\
+		.width = PERIPH_GATE_WIDTH,			\
+		.clkflags = CLK_SET_RATE_PARENT |		\
+			    CLK_SET_RATE_GATE |			\
+			    CLK_IS_BASIC,			\
+		.typeflags = NA_TYPE_FLAGS,			\
+		.mult = NA_MULT,				\
+		.div = NA_DIV,					\
+	}
+
+#define IGNORE_UNUSED_GATE					\
+	{							\
+		.type = TYPE_GATE,				\
+		.offset = PERIPH_GATE_SHIFT,			\
+		.width = PERIPH_GATE_WIDTH,			\
+		.clkflags = CLK_SET_RATE_PARENT |		\
+			    CLK_IGNORE_UNUSED |			\
+			    CLK_IS_BASIC,			\
+		.typeflags = NA_TYPE_FLAGS,			\
+		.mult = NA_MULT,				\
+		.div = NA_DIV,					\
+	}
+
+/**
+ * struct pm_clock_node - Clock topology node information
+ * @type:	Topology type (mux/div1/div2/gate/pll/fixed factor)
+ * @offset:	Offset in control register
+ * @width:	Width of the specific type in control register
+ * @clkflags:	Clk specific flags
+ * @typeflags:	Type specific flags
+ * @mult:	Multiplier for fixed factor
+ * @div:	Divisor for fixed factor
+ */
+struct pm_clock_node {
+	uint16_t clkflags;
+	uint16_t typeflags;
+	uint8_t type;
+	uint8_t offset;
+	uint8_t width;
+	uint8_t mult:4;
+	uint8_t div:4;
+};
+
+/**
+ * struct pm_clock - Clock structure
+ * @name:	Clock name
+ * @control_reg:	Control register address
+ * @status_reg:	Status register address
+ * @parents:	Parents for first clock node. Lower byte indicates parent
+ *		clock id and upper byte indicate flags for that id.
+ * pm_clock_node:	Clock nodes
+ */
+struct pm_clock {
+	char name[CLK_NAME_LEN];
+	uint8_t num_nodes;
+	unsigned int control_reg;
+	unsigned int status_reg;
+	int32_t (*parents)[];
+	struct pm_clock_node(*nodes)[];
+};
+
+/**
+ * struct pm_clock - Clock structure
+ * @name:		Clock name
+ */
+struct pm_ext_clock {
+	char name[CLK_NAME_LEN];
+};
+
+/* PLL Clocks */
+static struct pm_clock_node generic_pll_nodes[] = {
+	{
+		.type = TYPE_PLL,
+		.offset = NA_SHIFT,
+		.width = NA_WIDTH,
+		.clkflags = CLK_SET_RATE_NO_REPARENT,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node ignore_unused_pll_nodes[] = {
+	{
+		.type = TYPE_PLL,
+		.offset = NA_SHIFT,
+		.width = NA_WIDTH,
+		.clkflags = CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node generic_pll_pre_src_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = PLL_PRESRC_MUX_SHIFT,
+		.width = PLL_PRESRC_MUX_WIDTH,
+		.clkflags = CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node generic_pll_half_nodes[] = {
+	{
+		.type = TYPE_FIXEDFACTOR,
+		.offset = NA_SHIFT,
+		.width = NA_WIDTH,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = 1,
+		.div = 2,
+	},
+};
+
+static struct pm_clock_node generic_pll_int_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = PLL_DIV2_MUX_SHIFT,
+		.width =  PLL_DIV2_MUX_WIDTH,
+		.clkflags = CLK_SET_RATE_NO_REPARENT |
+			    CLK_SET_RATE_PARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node generic_pll_post_src_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = PLL_POSTSRC_MUX_SHIFT,
+		.width = PLL_POSTSRC_MUX_WIDTH,
+		.clkflags = CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node generic_pll_system_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = PLL_BYPASS_MUX_SHIFT,
+		.width = PLL_BYPASS_MUX_WIDTH,
+		.clkflags = CLK_SET_RATE_NO_REPARENT |
+			    CLK_SET_RATE_PARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node acpu_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = PERIPH_MUX_SHIFT,
+		.width = PERIPH_MUX_WIDTH,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_DIV1,
+		.offset = PERIPH_DIV1_SHIFT,
+		.width = PERIPH_DIV1_WIDTH,
+		.clkflags = CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_GATE,
+		.offset = PERIPH_GATE_SHIFT,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_IGNORE_UNUSED |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node generic_mux_div_nodes[] = {
+	GENERIC_MUX,
+	GENERIC_DIV(1),
+};
+
+static struct pm_clock_node generic_mux_div_gate_nodes[] = {
+	GENERIC_MUX,
+	GENERIC_DIV(1),
+	GENERIC_GATE,
+};
+
+static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = {
+	GENERIC_MUX,
+	GENERIC_DIV(1),
+	IGNORE_UNUSED_GATE,
+};
+
+static struct pm_clock_node generic_mux_div_div_gate_nodes[] = {
+	GENERIC_MUX,
+	GENERIC_DIV(1),
+	GENERIC_DIV(2),
+	GENERIC_GATE,
+};
+
+static struct pm_clock_node dp_audio_video_ref_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = PERIPH_MUX_SHIFT,
+		.width = PERIPH_MUX_WIDTH,
+		.clkflags = CLK_SET_RATE_NO_REPARENT |
+			    CLK_SET_RATE_PARENT |
+			    CLK_FRAC | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_DIV1,
+		.offset = PERIPH_DIV1_SHIFT,
+		.width = PERIPH_DIV1_WIDTH,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
+			    CLK_FRAC | CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_DIV2,
+		.offset = PERIPH_DIV2_SHIFT,
+		.width = PERIPH_DIV2_WIDTH,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
+			    CLK_FRAC | CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_GATE,
+		.offset = PERIPH_GATE_SHIFT,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_GATE |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node usb_nodes[] = {
+	GENERIC_MUX,
+	GENERIC_DIV(1),
+	GENERIC_DIV(2),
+	{
+		.type = TYPE_GATE,
+		.offset = USB_GATE_SHIFT,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC |
+			    CLK_SET_RATE_GATE,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node generic_domain_crossing_nodes[] = {
+	{
+		.type = TYPE_DIV1,
+		.offset = 8,
+		.width = 6,
+		.clkflags = CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node rpll_to_fpd_nodes[] = {
+	{
+		.type = TYPE_DIV1,
+		.offset = 8,
+		.width = 6,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node acpu_half_nodes[] = {
+	{
+		.type = TYPE_FIXEDFACTOR,
+		.offset = 0,
+		.width = 1,
+		.clkflags = 0,
+		.typeflags = 0,
+		.mult = 1,
+		.div = 2,
+	},
+	{
+		.type = TYPE_GATE,
+		.offset = 25,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_IGNORE_UNUSED |
+			    CLK_SET_RATE_PARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node wdt_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 0,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node ddr_nodes[] = {
+	GENERIC_MUX,
+	{
+		.type = TYPE_DIV1,
+		.offset = 8,
+		.width = 6,
+		.clkflags = CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node pl_nodes[] = {
+	GENERIC_MUX,
+	{
+		.type = TYPE_DIV1,
+		.offset = PERIPH_DIV1_SHIFT,
+		.width = PERIPH_DIV1_WIDTH,
+		.clkflags = CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_DIV2,
+		.offset = PERIPH_DIV2_SHIFT,
+		.width = PERIPH_DIV2_WIDTH,
+		.clkflags = CLK_IS_BASIC | CLK_SET_RATE_PARENT,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_GATE,
+		.offset = PERIPH_GATE_SHIFT,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node gpu_pp0_nodes[] = {
+	{
+		.type = TYPE_GATE,
+		.offset = 25,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node gpu_pp1_nodes[] = {
+	{
+		.type = TYPE_GATE,
+		.offset = 26,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node gem_nodes[] = {
+	GENERIC_MUX,
+	{
+		.type = TYPE_DIV1,
+		.offset = 8,
+		.width = 6,
+		.clkflags = CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_DIV2,
+		.offset = 16,
+		.width = 6,
+		.clkflags = CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_GATE,
+		.offset = 25,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node gem0_tx_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 1,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_GATE,
+		.offset = 26,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node gem1_tx_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 6,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_GATE,
+		.offset = 26,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node gem2_tx_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 11,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_GATE,
+		.offset = 26,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node gem3_tx_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 16,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	{
+		.type = TYPE_GATE,
+		.offset = 26,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node gem_tsu_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 20,
+		.width = 2,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node can0_mio_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 0,
+		.width = 7,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node can1_mio_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 15,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node can0_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 7,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node can1_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 22,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node cpu_r5_core_nodes[] = {
+	{
+		.type = TYPE_GATE,
+		.offset = 25,
+		.width = PERIPH_GATE_WIDTH,
+		.clkflags = CLK_IGNORE_UNUSED |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node dll_ref_nodes[] = {
+	{
+		.type = TYPE_MUX,
+		.offset = 0,
+		.width = 3,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
+		.typeflags = NA_TYPE_FLAGS,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+};
+
+static struct pm_clock_node timestamp_ref_nodes[] = {
+	GENERIC_MUX,
+	{
+		.type = TYPE_DIV1,
+		.offset = 8,
+		.width = 6,
+		.clkflags = CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+		.mult = NA_MULT,
+		.div = NA_DIV,
+	},
+	IGNORE_UNUSED_GATE,
+};
+
+static int32_t can_mio_parents[] = {
+	EXT_CLK_MIO0, EXT_CLK_MIO1, EXT_CLK_MIO2, EXT_CLK_MIO3,
+	EXT_CLK_MIO4, EXT_CLK_MIO5, EXT_CLK_MIO6, EXT_CLK_MIO7,
+	EXT_CLK_MIO8, EXT_CLK_MIO9, EXT_CLK_MIO10, EXT_CLK_MIO11,
+	EXT_CLK_MIO12, EXT_CLK_MIO13, EXT_CLK_MIO14, EXT_CLK_MIO15,
+	EXT_CLK_MIO16, EXT_CLK_MIO17, EXT_CLK_MIO18, EXT_CLK_MIO19,
+	EXT_CLK_MIO20, EXT_CLK_MIO21, EXT_CLK_MIO22, EXT_CLK_MIO23,
+	EXT_CLK_MIO24, EXT_CLK_MIO25, EXT_CLK_MIO26, EXT_CLK_MIO27,
+	EXT_CLK_MIO28, EXT_CLK_MIO29, EXT_CLK_MIO30, EXT_CLK_MIO31,
+	EXT_CLK_MIO32, EXT_CLK_MIO33, EXT_CLK_MIO34, EXT_CLK_MIO35,
+	EXT_CLK_MIO36, EXT_CLK_MIO37, EXT_CLK_MIO38, EXT_CLK_MIO39,
+	EXT_CLK_MIO40, EXT_CLK_MIO41, EXT_CLK_MIO42, EXT_CLK_MIO43,
+	EXT_CLK_MIO44, EXT_CLK_MIO45, EXT_CLK_MIO46, EXT_CLK_MIO47,
+	EXT_CLK_MIO48, EXT_CLK_MIO49, EXT_CLK_MIO50, EXT_CLK_MIO51,
+	EXT_CLK_MIO52, EXT_CLK_MIO53, EXT_CLK_MIO54, EXT_CLK_MIO55,
+	EXT_CLK_MIO56, EXT_CLK_MIO57, EXT_CLK_MIO58, EXT_CLK_MIO59,
+	EXT_CLK_MIO60, EXT_CLK_MIO61, EXT_CLK_MIO62, EXT_CLK_MIO63,
+	EXT_CLK_MIO64, EXT_CLK_MIO65, EXT_CLK_MIO66, EXT_CLK_MIO67,
+	EXT_CLK_MIO68, EXT_CLK_MIO69, EXT_CLK_MIO70, EXT_CLK_MIO71,
+	EXT_CLK_MIO72, EXT_CLK_MIO73, EXT_CLK_MIO74, EXT_CLK_MIO75,
+	EXT_CLK_MIO76, EXT_CLK_MIO77, CLK_NA_PARENT
+};
+
+/* Clock array containing clock informaton */
+static struct pm_clock clocks[] = {
+	[CLK_APLL_INT] = {
+		.name = "apll_int",
+		.control_reg = CRF_APB_APLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_APLL_PRE_SRC, CLK_NA_PARENT}),
+		.nodes = &ignore_unused_pll_nodes,
+		.num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes),
+	},
+	[CLK_APLL_PRE_SRC] = {
+		.name = "apll_pre_src",
+		.control_reg = CRF_APB_APLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_pre_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+	},
+	[CLK_APLL_HALF] = {
+		.name = "apll_half",
+		.control_reg = CRF_APB_APLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_APLL_INT, CLK_NA_PARENT}),
+		.nodes = &generic_pll_half_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+	},
+	[CLK_APLL_INT_MUX] = {
+		.name = "apll_int_mux",
+		.control_reg = CRF_APB_APLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_APLL_INT,
+			CLK_APLL_HALF,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_int_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+	},
+	[CLK_APLL_POST_SRC] = {
+		.name = "apll_post_src",
+		.control_reg = CRF_APB_APLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_post_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+	},
+	[CLK_APLL] = {
+		.name = "apll",
+		.control_reg = CRF_APB_APLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_APLL_INT_MUX,
+			CLK_APLL_POST_SRC,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_system_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+	},
+	[CLK_DPLL_INT] = {
+		.name = "dpll_int",
+		.control_reg = CRF_APB_DPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_DPLL_PRE_SRC, CLK_NA_PARENT}),
+		.nodes = &generic_pll_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_nodes),
+	},
+	[CLK_DPLL_PRE_SRC] = {
+		.name = "dpll_pre_src",
+		.control_reg = CRF_APB_DPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_pre_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+	},
+	[CLK_DPLL_HALF] = {
+		.name = "dpll_half",
+		.control_reg = CRF_APB_DPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_DPLL_INT, CLK_NA_PARENT}),
+		.nodes = &generic_pll_half_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+	},
+	[CLK_DPLL_INT_MUX] = {
+		.name = "dpll_int_mux",
+		.control_reg = CRF_APB_DPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_DPLL_INT,
+			CLK_DPLL_HALF,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_int_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+	},
+	[CLK_DPLL_POST_SRC] = {
+		.name = "dpll_post_src",
+		.control_reg = CRF_APB_DPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_post_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+	},
+	[CLK_DPLL] = {
+		.name = "dpll",
+		.control_reg = CRF_APB_DPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_DPLL_INT_MUX,
+			CLK_DPLL_POST_SRC,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_system_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+	},
+	[CLK_VPLL_INT] = {
+		.name = "vpll_int",
+		.control_reg = CRF_APB_VPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_VPLL_PRE_SRC, CLK_NA_PARENT}),
+		.nodes = &ignore_unused_pll_nodes,
+		.num_nodes = ARRAY_SIZE(ignore_unused_pll_nodes),
+	},
+	[CLK_VPLL_PRE_SRC] = {
+		.name = "vpll_pre_src",
+		.control_reg = CRF_APB_VPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_pre_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+	},
+	[CLK_VPLL_HALF] = {
+		.name = "vpll_half",
+		.control_reg = CRF_APB_VPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_VPLL_INT, CLK_NA_PARENT}),
+		.nodes = &generic_pll_half_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+	},
+	[CLK_VPLL_INT_MUX] = {
+		.name = "vpll_int_mux",
+		.control_reg = CRF_APB_VPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_VPLL_INT,
+			CLK_VPLL_HALF,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_int_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+	},
+	[CLK_VPLL_POST_SRC] = {
+		.name = "vpll_post_src",
+		.control_reg = CRF_APB_VPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_post_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+	},
+	[CLK_VPLL] = {
+		.name = "vpll",
+		.control_reg = CRF_APB_VPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_VPLL_INT_MUX,
+			CLK_VPLL_POST_SRC,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_system_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+	},
+	[CLK_IOPLL_INT] = {
+		.name = "iopll_int",
+		.control_reg = CRL_APB_IOPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_IOPLL_PRE_SRC, CLK_NA_PARENT}),
+		.nodes = &generic_pll_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_nodes),
+	},
+	[CLK_IOPLL_PRE_SRC] = {
+		.name = "iopll_pre_src",
+		.control_reg = CRL_APB_IOPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_pre_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+	},
+	[CLK_IOPLL_HALF] = {
+		.name = "iopll_half",
+		.control_reg = CRL_APB_IOPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_IOPLL_INT, CLK_NA_PARENT}),
+		.nodes = &generic_pll_half_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+	},
+	[CLK_IOPLL_INT_MUX] = {
+		.name = "iopll_int_mux",
+		.control_reg = CRL_APB_IOPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_IOPLL_INT,
+			CLK_IOPLL_HALF,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_int_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+	},
+	[CLK_IOPLL_POST_SRC] = {
+		.name = "iopll_post_src",
+		.control_reg = CRL_APB_IOPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_post_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+	},
+	[CLK_IOPLL] = {
+		.name = "iopll",
+		.control_reg = CRL_APB_IOPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_IOPLL_INT_MUX,
+			CLK_IOPLL_POST_SRC,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_system_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+	},
+	[CLK_RPLL_INT] = {
+		.name = "rpll_int",
+		.control_reg = CRL_APB_RPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_RPLL_PRE_SRC, CLK_NA_PARENT}),
+		.nodes = &generic_pll_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_nodes),
+	},
+	[CLK_RPLL_PRE_SRC] = {
+		.name = "rpll_pre_src",
+		.control_reg = CRL_APB_RPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+
+		.nodes = &generic_pll_pre_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_pre_src_nodes),
+	},
+	[CLK_RPLL_HALF] = {
+		.name = "rpll_half",
+		.control_reg = CRL_APB_RPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {CLK_RPLL_INT, CLK_NA_PARENT}),
+		.nodes = &generic_pll_half_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_half_nodes),
+	},
+	[CLK_RPLL_INT_MUX] = {
+		.name = "rpll_int_mux",
+		.control_reg = CRL_APB_RPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_RPLL_INT,
+			CLK_RPLL_HALF,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_int_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_int_nodes),
+	},
+	[CLK_RPLL_POST_SRC] = {
+		.name = "rpll_post_src",
+		.control_reg = CRL_APB_RPLL_CTRL,
+		.status_reg = CRF_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_post_src_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
+	},
+	[CLK_RPLL] = {
+		.name = "rpll",
+		.control_reg = CRL_APB_RPLL_CTRL,
+		.status_reg = CRL_APB_PLL_STATUS,
+		.parents = &((int32_t []) {
+			CLK_RPLL_INT_MUX,
+			CLK_RPLL_POST_SRC,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_pll_system_nodes,
+		.num_nodes = ARRAY_SIZE(generic_pll_system_nodes),
+	},
+	/* Peripheral Clocks */
+	[CLK_ACPU] = {
+		.name = "acpu",
+		.control_reg = CRF_APB_ACPU_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_APLL,
+			CLK_DUMMY_PARENT,
+			CLK_DPLL,
+			CLK_VPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &acpu_nodes,
+		.num_nodes = ARRAY_SIZE(acpu_nodes),
+	},
+	[CLK_DBG_TRACE] = {
+		.name = "dbg_trace",
+		.control_reg = CRF_APB_DBG_TRACE_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL_TO_FPD,
+			CLK_DUMMY_PARENT,
+			CLK_DPLL,
+			CLK_APLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_DBG_FPD] = {
+		.name = "dbg_fpd",
+		.control_reg = CRF_APB_DBG_FPD_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL_TO_FPD,
+			CLK_DUMMY_PARENT,
+			CLK_DPLL,
+			CLK_APLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_DBG_TSTMP] = {
+		.name = "dbg_tstmp",
+		.control_reg = CRF_APB_DBG_TSTMP_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL_TO_FPD,
+			CLK_DUMMY_PARENT,
+			CLK_DPLL,
+			CLK_APLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_nodes),
+	},
+	[CLK_DP_VIDEO_REF] = {
+		.name = "dp_video_ref",
+		.control_reg = CRF_APB_DP_VIDEO_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_VPLL,
+			CLK_DUMMY_PARENT,
+			CLK_DPLL,
+			CLK_RPLL_TO_FPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &dp_audio_video_ref_nodes,
+		.num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
+	},
+	[CLK_DP_AUDIO_REF] = {
+		.name = "dp_audio_ref",
+		.control_reg = CRF_APB_DP_AUDIO_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_VPLL,
+			CLK_DUMMY_PARENT,
+			CLK_DPLL,
+			CLK_RPLL_TO_FPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &dp_audio_video_ref_nodes,
+		.num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
+	},
+	[CLK_DP_STC_REF] = {
+		.name = "dp_stc_ref",
+		.control_reg = CRF_APB_DP_STC_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_VPLL,
+			CLK_DUMMY_PARENT,
+			CLK_DPLL,
+			CLK_RPLL_TO_FPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_DPDMA_REF] = {
+		.name = "dpdma_ref",
+		.control_reg = CRF_APB_DPDMA_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_APLL,
+			CLK_DUMMY_PARENT,
+			CLK_VPLL,
+			CLK_DPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_DDR_REF] = {
+		.name = "ddr_ref",
+		.control_reg = CRF_APB_DDR_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_DPLL,
+			CLK_VPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &ddr_nodes,
+		.num_nodes = ARRAY_SIZE(ddr_nodes),
+	},
+	[CLK_GPU_REF] = {
+		.name = "gpu_ref",
+		.control_reg = CRF_APB_GPU_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL_TO_FPD,
+			CLK_DUMMY_PARENT,
+			CLK_VPLL,
+			CLK_DPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_SATA_REF] = {
+		.name = "sata_ref",
+		.control_reg = CRF_APB_SATA_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL_TO_FPD,
+			CLK_DUMMY_PARENT,
+			CLK_APLL,
+			CLK_DPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_PCIE_REF] = {
+		.name = "pcie_ref",
+		.control_reg = CRF_APB_PCIE_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL_TO_FPD,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL_TO_FPD,
+			CLK_DPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_GDMA_REF] = {
+		.name = "gdma_ref",
+		.control_reg = CRF_APB_GDMA_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_APLL,
+			CLK_DUMMY_PARENT,
+			CLK_VPLL,
+			CLK_DPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_GTGREF0_REF] = {
+		.name = "gtgref0_ref",
+		.control_reg = CRF_APB_GTGREF0_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL_TO_FPD,
+			CLK_DUMMY_PARENT,
+			CLK_APLL,
+			CLK_DPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_TOPSW_MAIN] = {
+		.name = "topsw_main",
+		.control_reg = CRF_APB_TOPSW_MAIN_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_APLL,
+			CLK_DUMMY_PARENT,
+			CLK_VPLL,
+			CLK_DPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_unused_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+	},
+	[CLK_TOPSW_LSBUS] = {
+		.name = "topsw_lsbus",
+		.control_reg = CRF_APB_TOPSW_LSBUS_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_APLL,
+			CLK_DUMMY_PARENT,
+			CLK_IOPLL_TO_FPD,
+			CLK_DPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_unused_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+	},
+	[CLK_IOU_SWITCH] = {
+		.name = "iou_switch",
+		.control_reg = CRL_APB_IOU_SWITCH_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_RPLL,
+			CLK_DUMMY_PARENT,
+			CLK_IOPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_unused_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+	},
+	[CLK_GEM0_REF] = {
+		.name = "gem0_ref",
+		.control_reg = CRL_APB_GEM0_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_nodes,
+		.num_nodes = ARRAY_SIZE(gem_nodes),
+	},
+	[CLK_GEM1_REF] = {
+		.name = "gem1_ref",
+		.control_reg = CRL_APB_GEM1_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_nodes,
+		.num_nodes = ARRAY_SIZE(gem_nodes),
+	},
+	[CLK_GEM2_REF] = {
+		.name = "gem2_ref",
+		.control_reg = CRL_APB_GEM2_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_nodes,
+		.num_nodes = ARRAY_SIZE(gem_nodes),
+	},
+	[CLK_GEM3_REF] = {
+		.name = "gem3_ref",
+		.control_reg = CRL_APB_GEM3_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_nodes,
+		.num_nodes = ARRAY_SIZE(gem_nodes),
+	},
+	[CLK_USB0_BUS_REF] = {
+		.name = "usb0_bus_ref",
+		.control_reg = CRL_APB_USB0_BUS_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &usb_nodes,
+		.num_nodes = ARRAY_SIZE(usb_nodes),
+	},
+	[CLK_USB1_BUS_REF] = {
+		.name = "usb1_bus_ref",
+		.control_reg = CRL_APB_USB1_BUS_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &usb_nodes,
+		.num_nodes = ARRAY_SIZE(usb_nodes),
+	},
+	[CLK_USB3_DUAL_REF] = {
+		.name = "usb3_dual_ref",
+		.control_reg = CRL_APB_USB3_DUAL_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &usb_nodes,
+		.num_nodes = ARRAY_SIZE(usb_nodes),
+	},
+	[CLK_QSPI_REF] = {
+		.name = "qspi_ref",
+		.control_reg = CRL_APB_QSPI_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_SDIO0_REF] = {
+		.name = "sdio0_ref",
+		.control_reg = CRL_APB_SDIO0_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_VPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_SDIO1_REF] = {
+		.name = "sdio1_ref",
+		.control_reg = CRL_APB_SDIO1_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_VPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_UART0_REF] = {
+		.name = "uart0_ref",
+		.control_reg = CRL_APB_UART0_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_UART1_REF] = {
+		.name = "uart1_ref",
+		.control_reg = CRL_APB_UART1_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_SPI0_REF] = {
+		.name = "spi0_ref",
+		.control_reg = CRL_APB_SPI0_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_SPI1_REF] = {
+		.name = "spi1_ref",
+		.control_reg = CRL_APB_SPI1_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_CAN0_REF] = {
+		.name = "can0_ref",
+		.control_reg = CRL_APB_CAN0_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_CAN1_REF] = {
+		.name = "can1_ref",
+		.control_reg = CRL_APB_CAN1_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_NAND_REF] = {
+		.name = "nand_ref",
+		.control_reg = CRL_APB_NAND_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_GEM_TSU_REF] = {
+		.name = "gem_tsu_ref",
+		.control_reg = CRL_APB_GEM_TSU_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_DLL_REF] = {
+		.name = "dll_ref",
+		.control_reg = CRL_APB_DLL_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_RPLL,
+			CLK_NA_PARENT
+		}),
+		.nodes = &dll_ref_nodes,
+		.num_nodes = ARRAY_SIZE(dll_ref_nodes),
+	},
+	[CLK_ADMA_REF] = {
+		.name = "adma_ref",
+		.control_reg = CRL_APB_ADMA_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_RPLL,
+			CLK_DUMMY_PARENT,
+			CLK_IOPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_DBG_LPD] = {
+		.name = "dbg_lpd",
+		.control_reg = CRL_APB_DBG_LPD_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_RPLL,
+			CLK_DUMMY_PARENT,
+			CLK_IOPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_CPU_R5] = {
+		.name = "cpu_r5",
+		.control_reg = CRL_APB_CPU_R5_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_RPLL,
+			CLK_DUMMY_PARENT,
+			CLK_IOPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_unused_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+	},
+	[CLK_CSU_PLL] = {
+		.name = "csu_pll",
+		.control_reg = CRL_APB_CSU_PLL_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_PCAP] = {
+		.name = "pcap",
+		.control_reg = CRL_APB_PCAP_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
+	},
+	[CLK_LPD_LSBUS] = {
+		.name = "lpd_lsbus",
+		.control_reg = CRL_APB_LPD_LSBUS_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_RPLL,
+			CLK_DUMMY_PARENT,
+			CLK_IOPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_unused_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+	},
+	[CLK_LPD_SWITCH] = {
+		.name = "lpd_switch",
+		.control_reg = CRL_APB_LPD_SWITCH_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_RPLL,
+			CLK_DUMMY_PARENT,
+			CLK_IOPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_unused_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
+	},
+	[CLK_I2C0_REF] = {
+		.name = "i2c0_ref",
+		.control_reg = CRL_APB_I2C0_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_I2C1_REF] = {
+		.name = "i2c1_ref",
+		.control_reg = CRL_APB_I2C1_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_TIMESTAMP_REF] = {
+		.name = "timestamp_ref",
+		.control_reg = CRL_APB_TIMESTAMP_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &timestamp_ref_nodes,
+		.num_nodes = ARRAY_SIZE(timestamp_ref_nodes),
+	},
+	[CLK_PL0_REF] = {
+		.name = "pl0_ref",
+		.control_reg = CRL_APB_PL0_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &pl_nodes,
+		.num_nodes = ARRAY_SIZE(pl_nodes),
+	},
+	[CLK_PL1_REF] = {
+		.name = "pl1_ref",
+		.control_reg = CRL_APB_PL1_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &pl_nodes,
+		.num_nodes = ARRAY_SIZE(pl_nodes),
+	},
+	[CLK_PL2_REF] = {
+		.name = "pl2_ref",
+		.control_reg = CRL_APB_PL2_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &pl_nodes,
+		.num_nodes = ARRAY_SIZE(pl_nodes),
+	},
+	[CLK_PL3_REF] = {
+		.name = "pl3_ref",
+		.control_reg = CRL_APB_PL3_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_IOPLL,
+			CLK_DUMMY_PARENT,
+			CLK_RPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &pl_nodes,
+		.num_nodes = ARRAY_SIZE(pl_nodes),
+	},
+	[CLK_AMS_REF] = {
+		.name = "ams_ref",
+		.control_reg = CRL_APB_AMS_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_RPLL,
+			CLK_DUMMY_PARENT,
+			CLK_IOPLL,
+			CLK_DPLL_TO_LPD,
+			CLK_NA_PARENT
+		}),
+		.nodes = &generic_mux_div_div_gate_nodes,
+		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
+	},
+	[CLK_IOPLL_TO_FPD] = {
+		.name = "iopll_to_fpd",
+		.control_reg = CRL_APB_IOPLL_TO_FPD_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {CLK_IOPLL, CLK_NA_PARENT}),
+		.nodes = &generic_domain_crossing_nodes,
+		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+	},
+	[CLK_RPLL_TO_FPD] = {
+		.name = "rpll_to_fpd",
+		.control_reg = CRL_APB_RPLL_TO_FPD_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {CLK_RPLL, CLK_NA_PARENT}),
+		.nodes = &rpll_to_fpd_nodes,
+		.num_nodes = ARRAY_SIZE(rpll_to_fpd_nodes),
+	},
+	[CLK_APLL_TO_LPD] = {
+		.name = "apll_to_lpd",
+		.control_reg = CRF_APB_APLL_TO_LPD_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {CLK_APLL, CLK_NA_PARENT}),
+		.nodes = &generic_domain_crossing_nodes,
+		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+	},
+	[CLK_DPLL_TO_LPD] = {
+		.name = "dpll_to_lpd",
+		.control_reg = CRF_APB_DPLL_TO_LPD_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {CLK_DPLL, CLK_NA_PARENT}),
+		.nodes = &generic_domain_crossing_nodes,
+		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+	},
+	[CLK_VPLL_TO_LPD] = {
+		.name = "vpll_to_lpd",
+		.control_reg = CRF_APB_VPLL_TO_LPD_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {CLK_VPLL, CLK_NA_PARENT}),
+		.nodes = &generic_domain_crossing_nodes,
+		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
+	},
+	/*
+	 * This clock control requires different registers for mux and gate.
+	 * Use control and status registers for the same.
+	 */
+	[CLK_GEM0_TX] = {
+		.name = "gem0_tx",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = CRL_APB_GEM0_REF_CTRL,
+		.parents = &((int32_t []) {
+			CLK_GEM0_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM0_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem0_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem0_tx_nodes),
+	},
+	/*
+	 * This clock control requires different registers for mux and gate.
+	 * Use control and status registers for the same.
+	 */
+	[CLK_GEM1_TX] = {
+		.name = "gem1_tx",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = CRL_APB_GEM1_REF_CTRL,
+		.parents = &((int32_t []) {
+			CLK_GEM1_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM1_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem1_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem1_tx_nodes),
+	},
+	/*
+	 * This clock control requires different registers for mux and gate.
+	 * Use control and status registers for the same.
+	 */
+	[CLK_GEM2_TX] = {
+		.name = "gem2_tx",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = CRL_APB_GEM2_REF_CTRL,
+		.parents = &((int32_t []) {
+			CLK_GEM2_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM2_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem2_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem2_tx_nodes),
+	},
+	/*
+	 * This clock control requires different registers for mux and gate.
+	 * Use control and status registers for the same.
+	 */
+	[CLK_GEM3_TX] = {
+		.name = "gem3_tx",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = CRL_APB_GEM3_REF_CTRL,
+		.parents = &((int32_t []) {
+			CLK_GEM3_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM3_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem3_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem3_tx_nodes),
+	},
+	[CLK_ACPU_HALF] = {
+		.name = "acpu_half",
+		.control_reg = CRF_APB_ACPU_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			CLK_NA_PARENT
+		}),
+		.nodes = &acpu_half_nodes,
+		.num_nodes = ARRAY_SIZE(acpu_half_nodes),
+	},
+	[CLK_WDT] = {
+		.name = "wdt",
+		.control_reg = IOU_SLCR_WDT_CLK_SEL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_TOPSW_LSBUS,
+			EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT,
+			EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &wdt_nodes,
+		.num_nodes = ARRAY_SIZE(wdt_nodes),
+	},
+	[CLK_GPU_PP0_REF] = {
+		.name = "gpu_pp0_ref",
+		.control_reg = CRF_APB_GPU_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gpu_pp0_nodes,
+		.num_nodes = ARRAY_SIZE(gpu_pp0_nodes),
+	},
+	[CLK_GPU_PP1_REF] = {
+		.name = "gpu_pp1_ref",
+		.control_reg = CRF_APB_GPU_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gpu_pp1_nodes,
+		.num_nodes = ARRAY_SIZE(gpu_pp1_nodes),
+	},
+	[CLK_GEM_TSU] = {
+		.name = "gem_tsu",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM_TSU_REF,
+			CLK_GEM_TSU_REF,
+			EXT_CLK_MIO26 | CLK_EXTERNAL_PARENT,
+			EXT_CLK_MIO50_OR_MIO51 | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_tsu_nodes,
+		.num_nodes = ARRAY_SIZE(gem_tsu_nodes),
+	},
+	[CLK_CPU_R5_CORE] = {
+		.name = "cpu_r5_core",
+		.control_reg = CRL_APB_CPU_R5_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
+			CLK_DUMMY_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &cpu_r5_core_nodes,
+		.num_nodes = ARRAY_SIZE(cpu_r5_core_nodes),
+	},
+	[CLK_CAN0_MIO] = {
+		.name = "can0_mio",
+		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
+		.status_reg = 0,
+		.parents = &can_mio_parents,
+		.nodes = &can0_mio_nodes,
+		.num_nodes = ARRAY_SIZE(can0_mio_nodes),
+	},
+	[CLK_CAN1_MIO] = {
+		.name = "can1_mio",
+		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
+		.status_reg = 0,
+		.parents = &can_mio_parents,
+		.nodes = &can1_mio_nodes,
+		.num_nodes = ARRAY_SIZE(can1_mio_nodes),
+	},
+	[CLK_CAN0] = {
+		.name = "can0",
+		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_CAN0_REF,
+			CLK_CAN0_MIO,
+			CLK_NA_PARENT
+		}),
+		.nodes = &can0_nodes,
+		.num_nodes = ARRAY_SIZE(can0_nodes),
+	},
+	[CLK_CAN1] = {
+		.name = "can1",
+		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_CAN1_REF,
+			CLK_CAN1_MIO,
+			CLK_NA_PARENT
+		}),
+		.nodes = &can1_nodes,
+		.num_nodes = ARRAY_SIZE(can1_nodes),
+	},
+};
+
+static struct pm_ext_clock ext_clocks[] = {
+	[EXT_CLK_INDEX(EXT_CLK_PSS_REF)] = {
+		.name = "pss_ref_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_VIDEO)] = {
+		.name = "video_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF)] = {
+		.name = "pss_alt_ref_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_AUX_REF)] = {
+		.name = "aux_ref_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF)] = {
+		.name = "video_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_SWDT0)] = {
+		.name = "swdt0_ext_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_SWDT1)] = {
+		.name = "swdt1_ext_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = {
+		.name = "gem0_emio_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = {
+		.name = "gem1_emio_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = {
+		.name = "gem2_emio_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = {
+		.name = "gem3_emio_clk",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = {
+		.name = "mio_clk_50_51",
+	},
+	EXT_CLK_MIO_DATA(0),
+	EXT_CLK_MIO_DATA(1),
+	EXT_CLK_MIO_DATA(2),
+	EXT_CLK_MIO_DATA(3),
+	EXT_CLK_MIO_DATA(4),
+	EXT_CLK_MIO_DATA(5),
+	EXT_CLK_MIO_DATA(6),
+	EXT_CLK_MIO_DATA(7),
+	EXT_CLK_MIO_DATA(8),
+	EXT_CLK_MIO_DATA(9),
+	EXT_CLK_MIO_DATA(10),
+	EXT_CLK_MIO_DATA(11),
+	EXT_CLK_MIO_DATA(12),
+	EXT_CLK_MIO_DATA(13),
+	EXT_CLK_MIO_DATA(14),
+	EXT_CLK_MIO_DATA(15),
+	EXT_CLK_MIO_DATA(16),
+	EXT_CLK_MIO_DATA(17),
+	EXT_CLK_MIO_DATA(18),
+	EXT_CLK_MIO_DATA(19),
+	EXT_CLK_MIO_DATA(20),
+	EXT_CLK_MIO_DATA(21),
+	EXT_CLK_MIO_DATA(22),
+	EXT_CLK_MIO_DATA(23),
+	EXT_CLK_MIO_DATA(24),
+	EXT_CLK_MIO_DATA(25),
+	EXT_CLK_MIO_DATA(26),
+	EXT_CLK_MIO_DATA(27),
+	EXT_CLK_MIO_DATA(28),
+	EXT_CLK_MIO_DATA(29),
+	EXT_CLK_MIO_DATA(30),
+	EXT_CLK_MIO_DATA(31),
+	EXT_CLK_MIO_DATA(32),
+	EXT_CLK_MIO_DATA(33),
+	EXT_CLK_MIO_DATA(34),
+	EXT_CLK_MIO_DATA(35),
+	EXT_CLK_MIO_DATA(36),
+	EXT_CLK_MIO_DATA(37),
+	EXT_CLK_MIO_DATA(38),
+	EXT_CLK_MIO_DATA(39),
+	EXT_CLK_MIO_DATA(40),
+	EXT_CLK_MIO_DATA(41),
+	EXT_CLK_MIO_DATA(42),
+	EXT_CLK_MIO_DATA(43),
+	EXT_CLK_MIO_DATA(44),
+	EXT_CLK_MIO_DATA(45),
+	EXT_CLK_MIO_DATA(46),
+	EXT_CLK_MIO_DATA(47),
+	EXT_CLK_MIO_DATA(48),
+	EXT_CLK_MIO_DATA(49),
+	EXT_CLK_MIO_DATA(50),
+	EXT_CLK_MIO_DATA(51),
+	EXT_CLK_MIO_DATA(52),
+	EXT_CLK_MIO_DATA(53),
+	EXT_CLK_MIO_DATA(54),
+	EXT_CLK_MIO_DATA(55),
+	EXT_CLK_MIO_DATA(56),
+	EXT_CLK_MIO_DATA(57),
+	EXT_CLK_MIO_DATA(58),
+	EXT_CLK_MIO_DATA(59),
+	EXT_CLK_MIO_DATA(60),
+	EXT_CLK_MIO_DATA(61),
+	EXT_CLK_MIO_DATA(62),
+	EXT_CLK_MIO_DATA(63),
+	EXT_CLK_MIO_DATA(64),
+	EXT_CLK_MIO_DATA(65),
+	EXT_CLK_MIO_DATA(66),
+	EXT_CLK_MIO_DATA(67),
+	EXT_CLK_MIO_DATA(68),
+	EXT_CLK_MIO_DATA(69),
+	EXT_CLK_MIO_DATA(70),
+	EXT_CLK_MIO_DATA(71),
+	EXT_CLK_MIO_DATA(72),
+	EXT_CLK_MIO_DATA(73),
+	EXT_CLK_MIO_DATA(74),
+	EXT_CLK_MIO_DATA(75),
+	EXT_CLK_MIO_DATA(76),
+	EXT_CLK_MIO_DATA(77),
+};
+
+/* Array of clock which are invalid for this variant */
+static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB};
+
+/* Array of clocks which needs to be enabled at init */
+static uint32_t pm_clk_init_enable_list[] = {
+	CLK_ACPU,
+	CLK_DDR_REF,
+};
+
+/**
+ * pm_clock_valid - Check if clock is valid or not
+ * @clock_id	Id of the clock to be queried
+ *
+ * This function is used to check if given clock is valid
+ * or not for the chip variant.
+ *
+ * List of invalid clocks are maintained in array list for
+ * different variants.
+ *
+ * Return: Returns 1 if clock is valid else 0.
+ */
+static bool pm_clock_valid(unsigned int clock_id)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(pm_clk_invalid_list); i++)
+		if (pm_clk_invalid_list[i] == clock_id)
+			return 0;
+
+	return 1;
+}
+
+/**
+ * pm_clock_init_enable - Check if clock needs to be enabled at init
+ * @clock_id	Id of the clock to be queried
+ *
+ * This function is used to check if given clock needs to be enabled
+ * at boot up or not. Some clocks needs to be enabled at init.
+ *
+ * Return: Returns 1 if clock needs to be enabled at boot up else 0.
+ */
+static unsigned int pm_clock_init_enable(unsigned int clock_id)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(pm_clk_init_enable_list); i++)
+		if (pm_clk_init_enable_list[i] == clock_id)
+			return 1;
+
+	return 0;
+}
+
+/**
+ * pm_clock_type - Get clock's type
+ * @clock_id	Id of the clock to be queried
+ *
+ * This function is used to check type of clock (OUTPUT/EXTERNAL).
+ *
+ * Return: Returns type of clock (OUTPUT/EXTERNAL).
+ */
+static unsigned int pm_clock_type(unsigned int clock_id)
+{
+	return (clock_id < CLK_MAX_OUTPUT_CLK) ?
+		CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL;
+}
+
+/**
+ * pm_api_clock_get_name() - PM call to request a clock's name
+ * @clock_id	Clock ID
+ * @name	Name of clock (max 16 bytes)
+ *
+ * This function is used by master to get nmae of clock specified
+ * by given clock ID.
+ *
+ * @return	Returns success. In case of error, name data is 0.
+ */
+enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name)
+{
+	if (clock_id == CLK_MAX)
+		memcpy(name, END_OF_CLK, CLK_NAME_LEN);
+	else if (!pm_clock_valid(clock_id))
+		memset(name, 0, CLK_NAME_LEN);
+	else if (clock_id < CLK_MAX_OUTPUT_CLK)
+		memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
+	else
+		memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
+		       CLK_NAME_LEN);
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_clock_get_topology() - PM call to request a clock's topology
+ * @clock_id	Clock ID
+ * @index	Topology index for next toplogy node
+ * @topology	Buffer to store nodes in topology and flags
+ *
+ * This function is used by master to get topology information for the
+ * clock specified by given clock ID. Each response would return 3
+ * topology nodes. To get next nodes, caller needs to call this API with
+ * index of next node. Index starts from 0.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
+					     unsigned int index,
+					     uint32_t *topology)
+{
+	struct pm_clock_node *clock_nodes;
+	uint8_t num_nodes;
+	unsigned int i;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+
+	memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
+	clock_nodes = *clocks[clock_id].nodes;
+	num_nodes = clocks[clock_id].num_nodes;
+
+	/* Skip parent till index */
+	if (index >= num_nodes)
+		return PM_RET_SUCCESS;
+
+	for (i = 0; i < 3U; i++) {
+		if ((index + i) == num_nodes)
+			break;
+		topology[i] =  clock_nodes[index + i].type;
+		topology[i] |= clock_nodes[index + i].clkflags <<
+					CLK_CLKFLAGS_SHIFT;
+		topology[i] |= clock_nodes[index + i].typeflags <<
+					CLK_TYPEFLAGS_SHIFT;
+	}
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
+ *					   factor parameters for fixed clock
+ * @clock_id	Clock ID
+ * @mul		Multiplication value
+ * @div		Divisor value
+ *
+ * This function is used by master to get fixed factor parameers for the
+ * fixed clock. This API is application only for the fixed clock.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
+						       uint32_t *mul,
+						       uint32_t *div)
+{
+	struct pm_clock_node *clock_nodes;
+	uint8_t num_nodes;
+	unsigned int type, i;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	clock_nodes = *clocks[clock_id].nodes;
+	num_nodes = clocks[clock_id].num_nodes;
+
+	for (i = 0; i < num_nodes; i++) {
+		type =  clock_nodes[i].type;
+		if (type == TYPE_FIXEDFACTOR) {
+			*mul = clock_nodes[i].mult;
+			*div = clock_nodes[i].div;
+			break;
+		}
+	}
+
+	/* Clock is not fixed clock */
+	if (i == num_nodes)
+		return PM_RET_ERROR_ARGS;
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents
+ * @clock_id	Clock ID
+ * @index	Index of next parent
+ * @parents	Parents of the given clock
+ *
+ * This function is used by master to get clock's parents information.
+ * This API will return 3 parents with a single response. To get other
+ * parents, master should call same API in loop with new parent index
+ * till error is returned.
+ *
+ * E.g First call should have index 0 which will return parents 0, 1 and
+ * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
+ * so on.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
+					    unsigned int index,
+					    uint32_t *parents)
+{
+	unsigned int i;
+	int32_t *clk_parents;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	clk_parents = *clocks[clock_id].parents;
+	if (clk_parents == NULL)
+		return PM_RET_ERROR_ARGS;
+
+	memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
+
+	/* Skip parent till index */
+	for (i = 0; i < index; i++)
+		if (clk_parents[i] == CLK_NA_PARENT)
+			return PM_RET_SUCCESS;
+
+	for (i = 0; i < 3; i++) {
+		parents[i] = clk_parents[index + i];
+		if (clk_parents[index + i] == CLK_NA_PARENT)
+			break;
+	}
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_clock_get_attributes() - PM call to request a clock's attributes
+ * @clock_id	Clock ID
+ * @attr	Clock attributes
+ *
+ * This function is used by master to get clock's attributes
+ * (e.g. valid, clock type, etc).
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
+					       uint32_t *attr)
+{
+	if (clock_id >= CLK_MAX)
+		return PM_RET_ERROR_ARGS;
+
+	/* Clock valid bit */
+	*attr = pm_clock_valid(clock_id);
+
+	/* If clock needs to be enabled during init */
+	*attr |= (pm_clock_init_enable(clock_id) << CLK_INIT_ENABLE_SHIFT);
+
+	/* Clock type (Output/External) */
+	*attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT);
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pll_get_lockbit() -  Returns lockbit index for pll id
+ * @pll_id: Id of the pll
+ *
+ * This function return the PLL_LOCKED bit index in
+ * pll status register accosiated with given pll id.
+ *
+ * Return: Returns bit index
+ */
+static int pll_get_lockbit(unsigned int pll_id)
+{
+	switch (pll_id) {
+	case CLK_APLL_INT:
+	case CLK_IOPLL_INT:
+		return 0;
+	case CLK_DPLL_INT:
+	case CLK_RPLL_INT:
+		return 1;
+	case CLK_VPLL_INT:
+		return 2;
+	default:
+		return -1;
+	}
+}
+
+/**
+ * pm_api_pll_bypass_and_reset() - Bypass and reset PLL
+ * @clock_id: Id of the PLL
+ *
+ * This function is to bypass and reset PLL.
+ */
+static inline enum pm_ret_status
+pm_api_pll_bypass_and_reset(unsigned int clock_id, unsigned int flag)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	unsigned int reg, val;
+	int lockbit;
+
+	reg = clocks[clock_id].control_reg;
+
+	if (flag & CLK_PLL_RESET_ASSERT) {
+		ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, PLLCTRL_BP_MASK);
+		if (ret != PM_RET_SUCCESS)
+			return ret;
+		ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
+				    PLLCTRL_RESET_MASK);
+		if (ret != PM_RET_SUCCESS)
+			return ret;
+	}
+	if (flag & CLK_PLL_RESET_RELEASE) {
+		ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
+				    ~PLLCTRL_RESET_MASK);
+		if (ret != PM_RET_SUCCESS)
+			return ret;
+
+		lockbit = pll_get_lockbit(clock_id);
+		do {
+			ret = pm_mmio_read(clocks[clock_id].status_reg, &val);
+			if (ret != PM_RET_SUCCESS)
+				return ret;
+		} while ((lockbit >= 0) && !(val & (1 << lockbit)));
+
+		ret = pm_mmio_write(reg, PLLCTRL_BP_MASK,
+			      ~(unsigned int)PLLCTRL_BP_MASK);
+	}
+	return ret;
+}
+
+/**
+ * pm_api_clk_enable_disable() - Enable/Disable the clock for given id
+ * @clock_id: Id of the clock to be enabled
+ * @enable: Enable(1)/Disable(0)
+ *
+ * This function is to enable/disable the clock which is not PLL.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_api_clk_enable_disable(unsigned int clock_id,
+						    unsigned int enable)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	struct pm_clock_node *nodes = *clocks[clock_id].nodes;
+	uint8_t num_nodes = clocks[clock_id].num_nodes;
+	unsigned int reg, val;
+	uint8_t i = 0;
+	uint8_t offset = NA_SHIFT, width = NA_WIDTH;
+
+	if (clock_id == CLK_GEM0_TX || clock_id == CLK_GEM1_TX ||
+	    clock_id == CLK_GEM2_TX || clock_id == CLK_GEM3_TX)
+		reg = clocks[clock_id].status_reg;
+	else
+		reg = clocks[clock_id].control_reg;
+
+	for (i = 0; i < num_nodes; i++) {
+		if (nodes->type == TYPE_GATE) {
+			offset = nodes->offset;
+			width = nodes->width;
+			break;
+		}
+		nodes++;
+	}
+	if (width == NA_WIDTH)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	ret = pm_mmio_read(reg, &val);
+	if (ret != PM_RET_SUCCESS)
+		return ret;
+	if ((val & BIT_MASK(offset, width)) == enable)
+		return PM_RET_SUCCESS;
+
+	if (enable == 0)
+		val &= ~(BIT_MASK(offset, width));
+	else
+		val |= BIT_MASK(offset, width);
+
+	ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
+
+	return ret;
+}
+
+/**
+ * pm_api_clock_enable() - Enable the clock for given id
+ * @clock_id: Id of the clock to be enabled
+ *
+ * This function is used by master to enable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_enable(unsigned int clock_id)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (ISPLL(clock_id))
+		ret = pm_api_pll_bypass_and_reset(clock_id,
+						  CLK_PLL_RESET_PULSE);
+	else
+		ret = pm_api_clk_enable_disable(clock_id, 1);
+
+	return ret;
+}
+
+/**
+ * pm_api_clock_disable - Disable the clock for given id
+ * @clock_id	Id of the clock to be disable
+ *
+ * This function is used by master to disable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+
+enum pm_ret_status pm_api_clock_disable(unsigned int clock_id)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (ISPLL(clock_id))
+		ret = pm_api_pll_bypass_and_reset(clock_id,
+						  CLK_PLL_RESET_ASSERT);
+	else
+		ret = pm_api_clk_enable_disable(clock_id, 0);
+
+	return ret;
+}
+
+/**
+ * pm_api_get_pll_state() - Get state of PLL
+ * @clock_id	Id of the PLL
+ * @state	State of PLL(1: Enable, 0: Reset)
+ *
+ * This function is to check state of PLL.
+ */
+static inline enum pm_ret_status pm_api_get_pll_state(unsigned int clock_id,
+					unsigned int *state)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	unsigned int reg, val;
+
+	reg = clocks[clock_id].control_reg;
+
+	ret = pm_mmio_read(reg, &val);
+
+	/* state:
+	 * 1 - PLL is enabled
+	 * 0 - PLL is in reset state
+	 */
+	*state = !(val & PLLCTRL_RESET_MASK);
+	return ret;
+}
+
+/**
+ * pm_api_get_clk_state() - Get the state of clock for given id
+ * @clock_id: Id of the clock to be enabled
+ * @state: Enable(1)/Disable(0)
+ *
+ * This function is to get state of the clock which is not PLL.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_api_get_clk_state(unsigned int clock_id,
+					       unsigned int *state)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	struct pm_clock_node *nodes = *clocks[clock_id].nodes;
+	uint8_t num_nodes = clocks[clock_id].num_nodes;
+	unsigned int reg, val;
+	uint8_t i = 0;
+	uint8_t offset = NA_SHIFT, width = NA_WIDTH;
+
+	reg = clocks[clock_id].control_reg;
+
+	for (i = 0; i < num_nodes; i++) {
+		if (nodes->type == TYPE_GATE) {
+			offset = nodes->offset;
+			width = nodes->width;
+		}
+		nodes++;
+	}
+	if (width == NA_WIDTH)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	ret = pm_mmio_read(reg, &val);
+	*state = (val & BIT_MASK(offset, width)) >> offset;
+
+	return ret;
+}
+
+/**
+ * pm_api_clock_getstate - Get the clock state for given id
+ * @clock_id	Id of the clock to be queried
+ * @state	1/0 (Enabled/Disabled)
+ *
+ * This function is used by master to get the state of clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id,
+					 unsigned int *state)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (ISPLL(clock_id))
+		ret = pm_api_get_pll_state(clock_id, state);
+	else
+		ret = pm_api_get_clk_state(clock_id, state);
+
+	return ret;
+}
+
+static enum pm_ret_status pm_api_clk_set_divider(unsigned int clock_id,
+						 uint32_t divider)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	struct pm_clock_node *nodes;
+	uint8_t num_nodes;
+	uint16_t div1, div2;
+	unsigned int reg, mask = 0, val = 0, i;
+	uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
+	uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
+
+	div1 = (uint16_t)(divider & 0xFFFFU);
+	div2 = (uint16_t)((divider >> 16) & 0xFFFFU);
+
+	reg = clocks[clock_id].control_reg;
+
+	nodes = *clocks[clock_id].nodes;
+	num_nodes = clocks[clock_id].num_nodes;
+	for (i = 0; i < num_nodes; i++) {
+		if (nodes->type == TYPE_DIV1) {
+			div1_offset = nodes->offset;
+			div1_width = nodes->width;
+		}
+		if (nodes->type == TYPE_DIV2) {
+			div2_offset = nodes->offset;
+			div2_width = nodes->width;
+		}
+		nodes++;
+	}
+
+	if (div1 != (uint16_t)-1) {
+		if (div1_width == NA_WIDTH)
+			return PM_RET_ERROR_NOTSUPPORTED;
+		val |= div1 << div1_offset;
+		mask |= BIT_MASK(div1_offset, div1_width);
+	}
+	if (div2 != (uint16_t)-1) {
+		if (div2_width == NA_WIDTH)
+			return PM_RET_ERROR_NOTSUPPORTED;
+		val |= div2 << div2_offset;
+		mask |= BIT_MASK(div2_offset, div2_width);
+	}
+	ret = pm_mmio_write(reg, mask, val);
+
+	return ret;
+}
+
+static enum pm_ret_status pm_api_pll_set_divider(unsigned int clock_id,
+					  unsigned int divider)
+{
+	unsigned int reg = clocks[clock_id].control_reg;
+
+	return pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT);
+}
+
+/**
+ * pm_api_clock_setdivider - Set the clock divider for given id
+ * @clock_id	Id of the clock
+ * @divider	Divider value
+ *
+ * This function is used by master to set divider for any clock
+ * to achieve desired rate.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id,
+					   unsigned int divider)
+{
+	enum pm_ret_status ret;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (ISPLL(clock_id))
+		ret = pm_api_pll_set_divider(clock_id, divider);
+	else
+		ret = pm_api_clk_set_divider(clock_id, divider);
+
+	return ret;
+}
+
+static enum pm_ret_status pm_api_clk_get_divider(unsigned int clock_id,
+						 uint32_t *divider)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	struct pm_clock_node *nodes;
+	uint8_t num_nodes;
+	unsigned int reg, val, i, div1 = 0, div2 = 0;
+	uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
+	uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
+
+	reg = clocks[clock_id].control_reg;
+
+	nodes = *clocks[clock_id].nodes;
+	num_nodes = clocks[clock_id].num_nodes;
+	for (i = 0; i < num_nodes; i++) {
+		if (nodes->type == TYPE_DIV1) {
+			div1_offset = nodes->offset;
+			div1_width = nodes->width;
+		}
+		if (nodes->type == TYPE_DIV2) {
+			div2_offset = nodes->offset;
+			div2_width = nodes->width;
+		}
+		nodes++;
+	}
+
+	ret = pm_mmio_read(reg, &val);
+
+	if (div1_width == NA_WIDTH)
+		return PM_RET_ERROR_ARGS;
+
+	div1 = (val & BIT_MASK(div1_offset, div1_width)) >> div1_offset;
+
+	if (div2_width != NA_WIDTH)
+		div2 = (val & BIT_MASK(div2_offset, div2_width)) >> div2_offset;
+
+	*divider = div1 | (div2 << 16);
+
+	return ret;
+}
+
+static enum pm_ret_status pm_api_pll_get_divider(unsigned int clock_id,
+					  unsigned int *divider)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	unsigned int reg, val;
+
+	reg = clocks[clock_id].control_reg;
+
+	ret = pm_mmio_read(reg, &val);
+	*divider = (val & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
+
+	return ret;
+}
+
+/**
+ * pm_api_clock_getdivider - Get the clock divider for given id
+ * @clock_id	Id of the clock
+ * @divider	Divider value
+ *
+ * This function is used by master to get divider values
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id,
+					   unsigned int *divider)
+{
+	enum pm_ret_status ret;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (ISPLL(clock_id))
+		ret = pm_api_pll_get_divider(clock_id, divider);
+	else
+		ret = pm_api_clk_get_divider(clock_id, divider);
+
+	return ret;
+}
+
+/**
+ * pm_api_clock_setrate - Set the clock rate for given id
+ * @clock_id	Id of the clock
+ * @rate	Rate value in hz
+ *
+ * This function is used by master to set rate for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id,
+					uint64_t rate)
+{
+	return PM_RET_ERROR_NOTSUPPORTED;
+}
+
+/**
+ * pm_api_clock_getrate - Get the clock rate for given id
+ * @clock_id	Id of the clock
+ * @rate	rate value in hz
+ *
+ * This function is used by master to get rate
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id,
+					uint64_t *rate)
+{
+	return PM_RET_ERROR_NOTSUPPORTED;
+}
+
+/**
+ * pm_api_clock_setparent - Set the clock parent for given id
+ * @clock_id	Id of the clock
+ * @parent_id	parent id
+ *
+ * This function is used by master to set parent for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id,
+					  unsigned int parent_idx)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	struct pm_clock_node *nodes;
+	uint8_t num_nodes;
+	unsigned int reg, val;
+	int32_t *clk_parents;
+	unsigned int i = 0;
+	uint8_t  offset = NA_SHIFT, width = NA_WIDTH;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	clk_parents = *clocks[clock_id].parents;
+
+	for (i = 0; i <= parent_idx; i++)
+		if (clk_parents[i] == CLK_NA_PARENT)
+			return PM_RET_ERROR_ARGS;
+
+	nodes = *clocks[clock_id].nodes;
+	num_nodes = clocks[clock_id].num_nodes;
+	for (i = 0; i < num_nodes; i++) {
+		if (nodes->type == TYPE_MUX) {
+			offset = nodes->offset;
+			width = nodes->width;
+		}
+		nodes++;
+	}
+	if (width == NA_WIDTH)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	reg = clocks[clock_id].control_reg;
+	val = parent_idx << offset;
+	ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
+
+	return ret;
+}
+
+/**
+ * pm_api_clock_getparent - Get the clock parent for given id
+ * @clock_id	Id of the clock
+ * @parent_id	parent id
+ *
+ * This function is used by master to get parent index
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id,
+					  unsigned int *parent_idx)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	struct pm_clock_node *nodes;
+	uint8_t num_nodes;
+	unsigned int reg, val;
+	uint8_t i = 0, offset = NA_SHIFT, width = NA_WIDTH;
+
+	if (!pm_clock_valid(clock_id))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	nodes = *clocks[clock_id].nodes;
+	num_nodes = clocks[clock_id].num_nodes;
+
+	for (i = 0; i < num_nodes; i++) {
+		if (nodes->type == TYPE_MUX) {
+			offset = nodes->offset;
+			width = nodes->width;
+		}
+		nodes++;
+	}
+	if (width == NA_WIDTH)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	reg = clocks[clock_id].control_reg;
+	ret = pm_mmio_read(reg, &val);
+	val >>= offset;
+	val &= ((1U << width) - 1);
+
+	*parent_idx = val;
+
+	return ret;
+}
+
+/**
+ * pm_api_clk_set_pll_mode() -  Set PLL mode
+ * @pll     PLL id
+ * @mode    Mode fraction/integar
+ *
+ * This function sets PLL mode.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll,
+					   unsigned int mode)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	unsigned int reg;
+
+	if (!pm_clock_valid(pll))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (!ISPLL(pll))
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)
+		return PM_RET_ERROR_ARGS;
+
+	reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
+
+	ret = pm_mmio_write(reg, PLL_FRAC_MODE_MASK,
+			    mode << PLL_FRAC_MODE_SHIFT);
+
+	return ret;
+}
+
+/**
+ * pm_ioctl_get_pll_mode() -  Get PLL mode
+ * @pll     PLL id
+ * @mode    Mode fraction/integar
+ *
+ * This function returns current PLL mode.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll,
+					   unsigned int *mode)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	unsigned int val, reg;
+
+	if (!pm_clock_valid(pll))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (!ISPLL(pll))
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
+
+	ret = pm_mmio_read(reg, &val);
+	val = val & PLL_FRAC_MODE_MASK;
+	if (val == 0)
+		*mode = PLL_INT_MODE;
+	else
+		*mode = PLL_FRAC_MODE;
+
+	return ret;
+}
+
+/**
+ * pm_api_clk_set_pll_frac_data() -  Set PLL fraction data
+ * @pll     PLL id
+ * @data    fraction data
+ *
+ * This function sets fraction data. It is valid for fraction
+ * mode only.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll,
+						unsigned int data)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	unsigned int val, reg, mode = 0;
+
+	if (!pm_clock_valid(pll))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (!ISPLL(pll))
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	ret = pm_api_clk_get_pll_mode(pll, &mode);
+	if (ret != PM_RET_SUCCESS)
+		return ret;
+	if (mode == PLL_FRAC_MODE) {
+		reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
+		val = data << PLL_FRAC_DATA_SHIFT;
+		ret = pm_mmio_write(reg, PLL_FRAC_DATA_MASK, val);
+	} else {
+		return PM_RET_ERROR_ARGS;
+	}
+
+	return ret;
+}
+
+/**
+ * pm_api_clk_get_pll_frac_data() - Get PLL fraction data
+ * @pll     PLL id
+ * @data    fraction data
+ *
+ * This function returns fraction data value.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll,
+						unsigned int *data)
+{
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	unsigned int val, reg;
+
+	if (!pm_clock_valid(pll))
+		return PM_RET_ERROR_ARGS;
+
+	if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (!ISPLL(pll))
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
+
+	ret = pm_mmio_read(reg, &val);
+	*data = (val & PLL_FRAC_DATA_MASK);
+
+	return ret;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
new file mode 100644
index 0000000..56f850a
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for clock control.
+ */
+
+#ifndef _PM_API_CLOCK_H_
+#define _PM_API_CLOCK_H_
+
+#include <utils_def.h>
+#include "pm_common.h"
+
+#define CLK_NAME_LEN		U(15)
+#define MAX_PARENTS		U(100)
+#define CLK_NA_PARENT		-1
+#define CLK_DUMMY_PARENT	-2
+
+/* Flags for parent id */
+#define PARENT_CLK_SELF		U(0)
+#define PARENT_CLK_NODE1	U(1)
+#define PARENT_CLK_NODE2	U(2)
+#define PARENT_CLK_NODE3	U(3)
+#define PARENT_CLK_NODE4	U(4)
+#define PARENT_CLK_EXTERNAL	U(5)
+#define PARENT_CLK_MIO0_MIO77	U(6)
+
+#define CLK_SET_RATE_GATE	BIT(0) /* must be gated across rate change */
+#define CLK_SET_PARENT_GATE	BIT(1) /* must be gated across re-parent */
+#define CLK_SET_RATE_PARENT	BIT(2) /* propagate rate change up one level */
+#define CLK_IGNORE_UNUSED	BIT(3) /* do not gate even if unused */
+/* unused */
+#define CLK_IS_BASIC		BIT(5) /* Basic clk, can't do a to_clk_foo() */
+#define CLK_GET_RATE_NOCACHE	BIT(6) /* do not use the cached clk rate */
+#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
+#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
+#define CLK_RECALC_NEW_RATES	BIT(9) /* recalc rates after notifications */
+#define CLK_SET_RATE_UNGATE	BIT(10) /* clock needs to run to set rate */
+#define CLK_IS_CRITICAL		BIT(11) /* do not gate, ever */
+/* parents need enable during gate/ungate, set rate and re-parent */
+#define CLK_OPS_PARENT_ENABLE	BIT(12)
+#define CLK_FRAC		BIT(13)
+
+#define CLK_DIVIDER_ONE_BASED		BIT(0)
+#define CLK_DIVIDER_POWER_OF_TWO	BIT(1)
+#define CLK_DIVIDER_ALLOW_ZERO		BIT(2)
+#define CLK_DIVIDER_HIWORD_MASK		BIT(3)
+#define CLK_DIVIDER_ROUND_CLOSEST	BIT(4)
+#define CLK_DIVIDER_READ_ONLY		BIT(5)
+#define CLK_DIVIDER_MAX_AT_ZERO		BIT(6)
+
+#define END_OF_CLK     "END_OF_CLK"
+
+//CLock Ids
+enum {
+	CLK_IOPLL,
+	CLK_RPLL,
+	CLK_APLL,
+	CLK_DPLL,
+	CLK_VPLL,
+	CLK_IOPLL_TO_FPD,
+	CLK_RPLL_TO_FPD,
+	CLK_APLL_TO_LPD,
+	CLK_DPLL_TO_LPD,
+	CLK_VPLL_TO_LPD,
+	CLK_ACPU,
+	CLK_ACPU_HALF,
+	CLK_DBG_FPD,
+	CLK_DBG_LPD,
+	CLK_DBG_TRACE,
+	CLK_DBG_TSTMP,
+	CLK_DP_VIDEO_REF,
+	CLK_DP_AUDIO_REF,
+	CLK_DP_STC_REF,
+	CLK_GDMA_REF,
+	CLK_DPDMA_REF,
+	CLK_DDR_REF,
+	CLK_SATA_REF,
+	CLK_PCIE_REF,
+	CLK_GPU_REF,
+	CLK_GPU_PP0_REF,
+	CLK_GPU_PP1_REF,
+	CLK_TOPSW_MAIN,
+	CLK_TOPSW_LSBUS,
+	CLK_GTGREF0_REF,
+	CLK_LPD_SWITCH,
+	CLK_LPD_LSBUS,
+	CLK_USB0_BUS_REF,
+	CLK_USB1_BUS_REF,
+	CLK_USB3_DUAL_REF,
+	CLK_USB0,
+	CLK_USB1,
+	CLK_CPU_R5,
+	CLK_CPU_R5_CORE,
+	CLK_CSU_SPB,
+	CLK_CSU_PLL,
+	CLK_PCAP,
+	CLK_IOU_SWITCH,
+	CLK_GEM_TSU_REF,
+	CLK_GEM_TSU,
+	CLK_GEM0_REF,
+	CLK_GEM1_REF,
+	CLK_GEM2_REF,
+	CLK_GEM3_REF,
+	CLK_GEM0_TX,
+	CLK_GEM1_TX,
+	CLK_GEM2_TX,
+	CLK_GEM3_TX,
+	CLK_QSPI_REF,
+	CLK_SDIO0_REF,
+	CLK_SDIO1_REF,
+	CLK_UART0_REF,
+	CLK_UART1_REF,
+	CLK_SPI0_REF,
+	CLK_SPI1_REF,
+	CLK_NAND_REF,
+	CLK_I2C0_REF,
+	CLK_I2C1_REF,
+	CLK_CAN0_REF,
+	CLK_CAN1_REF,
+	CLK_CAN0,
+	CLK_CAN1,
+	CLK_DLL_REF,
+	CLK_ADMA_REF,
+	CLK_TIMESTAMP_REF,
+	CLK_AMS_REF,
+	CLK_PL0_REF,
+	CLK_PL1_REF,
+	CLK_PL2_REF,
+	CLK_PL3_REF,
+	CLK_WDT,
+	CLK_IOPLL_INT,
+	CLK_IOPLL_PRE_SRC,
+	CLK_IOPLL_HALF,
+	CLK_IOPLL_INT_MUX,
+	CLK_IOPLL_POST_SRC,
+	CLK_RPLL_INT,
+	CLK_RPLL_PRE_SRC,
+	CLK_RPLL_HALF,
+	CLK_RPLL_INT_MUX,
+	CLK_RPLL_POST_SRC,
+	CLK_APLL_INT,
+	CLK_APLL_PRE_SRC,
+	CLK_APLL_HALF,
+	CLK_APLL_INT_MUX,
+	CLK_APLL_POST_SRC,
+	CLK_DPLL_INT,
+	CLK_DPLL_PRE_SRC,
+	CLK_DPLL_HALF,
+	CLK_DPLL_INT_MUX,
+	CLK_DPLL_POST_SRC,
+	CLK_VPLL_INT,
+	CLK_VPLL_PRE_SRC,
+	CLK_VPLL_HALF,
+	CLK_VPLL_INT_MUX,
+	CLK_VPLL_POST_SRC,
+	CLK_CAN0_MIO,
+	CLK_CAN1_MIO,
+	END_OF_OUTPUT_CLKS,
+};
+
+#define CLK_MAX_OUTPUT_CLK (unsigned int)(END_OF_OUTPUT_CLKS)
+
+//External clock ids
+enum {
+	EXT_CLK_PSS_REF = END_OF_OUTPUT_CLKS,
+	EXT_CLK_VIDEO,
+	EXT_CLK_PSS_ALT_REF,
+	EXT_CLK_AUX_REF,
+	EXT_CLK_GT_CRX_REF,
+	EXT_CLK_SWDT0,
+	EXT_CLK_SWDT1,
+	EXT_CLK_GEM0_EMIO,
+	EXT_CLK_GEM1_EMIO,
+	EXT_CLK_GEM2_EMIO,
+	EXT_CLK_GEM3_EMIO,
+	EXT_CLK_MIO50_OR_MIO51,
+	EXT_CLK_MIO0,
+	EXT_CLK_MIO1,
+	EXT_CLK_MIO2,
+	EXT_CLK_MIO3,
+	EXT_CLK_MIO4,
+	EXT_CLK_MIO5,
+	EXT_CLK_MIO6,
+	EXT_CLK_MIO7,
+	EXT_CLK_MIO8,
+	EXT_CLK_MIO9,
+	EXT_CLK_MIO10,
+	EXT_CLK_MIO11,
+	EXT_CLK_MIO12,
+	EXT_CLK_MIO13,
+	EXT_CLK_MIO14,
+	EXT_CLK_MIO15,
+	EXT_CLK_MIO16,
+	EXT_CLK_MIO17,
+	EXT_CLK_MIO18,
+	EXT_CLK_MIO19,
+	EXT_CLK_MIO20,
+	EXT_CLK_MIO21,
+	EXT_CLK_MIO22,
+	EXT_CLK_MIO23,
+	EXT_CLK_MIO24,
+	EXT_CLK_MIO25,
+	EXT_CLK_MIO26,
+	EXT_CLK_MIO27,
+	EXT_CLK_MIO28,
+	EXT_CLK_MIO29,
+	EXT_CLK_MIO30,
+	EXT_CLK_MIO31,
+	EXT_CLK_MIO32,
+	EXT_CLK_MIO33,
+	EXT_CLK_MIO34,
+	EXT_CLK_MIO35,
+	EXT_CLK_MIO36,
+	EXT_CLK_MIO37,
+	EXT_CLK_MIO38,
+	EXT_CLK_MIO39,
+	EXT_CLK_MIO40,
+	EXT_CLK_MIO41,
+	EXT_CLK_MIO42,
+	EXT_CLK_MIO43,
+	EXT_CLK_MIO44,
+	EXT_CLK_MIO45,
+	EXT_CLK_MIO46,
+	EXT_CLK_MIO47,
+	EXT_CLK_MIO48,
+	EXT_CLK_MIO49,
+	EXT_CLK_MIO50,
+	EXT_CLK_MIO51,
+	EXT_CLK_MIO52,
+	EXT_CLK_MIO53,
+	EXT_CLK_MIO54,
+	EXT_CLK_MIO55,
+	EXT_CLK_MIO56,
+	EXT_CLK_MIO57,
+	EXT_CLK_MIO58,
+	EXT_CLK_MIO59,
+	EXT_CLK_MIO60,
+	EXT_CLK_MIO61,
+	EXT_CLK_MIO62,
+	EXT_CLK_MIO63,
+	EXT_CLK_MIO64,
+	EXT_CLK_MIO65,
+	EXT_CLK_MIO66,
+	EXT_CLK_MIO67,
+	EXT_CLK_MIO68,
+	EXT_CLK_MIO69,
+	EXT_CLK_MIO70,
+	EXT_CLK_MIO71,
+	EXT_CLK_MIO72,
+	EXT_CLK_MIO73,
+	EXT_CLK_MIO74,
+	EXT_CLK_MIO75,
+	EXT_CLK_MIO76,
+	EXT_CLK_MIO77,
+	END_OF_CLKS,
+};
+
+#define CLK_MAX (unsigned int)(END_OF_CLKS)
+
+//CLock types
+#define CLK_TYPE_OUTPUT 0U
+#define	CLK_TYPE_EXTERNAL  1U
+
+//Topology types
+#define TYPE_INVALID 0U
+#define	TYPE_MUX 1U
+#define	TYPE_PLL 2U
+#define	TYPE_FIXEDFACTOR 3U
+#define	TYPE_DIV1 4U
+#define	TYPE_DIV2 5U
+#define	TYPE_GATE 6U
+
+
+enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name);
+enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
+					     unsigned int index,
+					     uint32_t *topology);
+enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
+						       uint32_t *mul,
+						       uint32_t *div);
+enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
+					    unsigned int index,
+					    uint32_t *parents);
+enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
+					       uint32_t *attr);
+enum pm_ret_status pm_api_clock_enable(unsigned int clock_id);
+enum pm_ret_status pm_api_clock_disable(unsigned int clock_id);
+enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id,
+					 unsigned int *state);
+enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id,
+					   unsigned int divider);
+enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id,
+					   unsigned int *divider);
+enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id,
+					uint64_t rate);
+enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id,
+					uint64_t *rate);
+enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id,
+					  unsigned int parent_idx);
+enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id,
+					  unsigned int *parent_idx);
+enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll,
+					   unsigned int mode);
+enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll,
+					   unsigned int *mode);
+enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll,
+						unsigned int data);
+enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll,
+						unsigned int *data);
+
+#endif /* _PM_API_CLOCK_H_ */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
new file mode 100644
index 0000000..cdbb515
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for ioctl.
+ */
+
+#include <arch_helpers.h>
+#include <delay_timer.h>
+#include <mmio.h>
+#include <platform.h>
+#include "pm_api_clock.h"
+#include "pm_api_ioctl.h"
+#include "pm_api_sys.h"
+#include "pm_client.h"
+#include "pm_common.h"
+#include "pm_ipi.h"
+#include "../zynqmp_def.h"
+
+/**
+ * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
+ * @mode	Buffer to store value of oper mode(Split/Lock-step)
+ *
+ * This function provides current configured RPU operational mode.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(unsigned int *mode)
+{
+	unsigned int val;
+
+	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
+	val &= ZYNQMP_SLSPLIT_MASK;
+	if (val == 0)
+		*mode = PM_RPU_MODE_LOCKSTEP;
+	else
+		*mode = PM_RPU_MODE_SPLIT;
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode
+ * @mode	Value to set for oper mode(Split/Lock-step)
+ *
+ * This function configures RPU operational mode(Split/Lock-step).
+ * It also sets TCM combined mode in RPU lock-step and TCM non-combined
+ * mode for RPU split mode. In case of Lock step mode, RPU1's output is
+ * clamped.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(unsigned int mode)
+{
+	unsigned int val;
+
+	if (mmio_read_32(CRL_APB_RST_LPD_TOP) && CRL_APB_RPU_AMBA_RESET)
+		return PM_RET_ERROR_ACCESS;
+
+	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
+
+	if (mode == PM_RPU_MODE_SPLIT) {
+		val |= ZYNQMP_SLSPLIT_MASK;
+		val &= ~ZYNQMP_TCM_COMB_MASK;
+		val &= ~ZYNQMP_SLCLAMP_MASK;
+	} else if (mode == PM_RPU_MODE_LOCKSTEP) {
+		val &= ~ZYNQMP_SLSPLIT_MASK;
+		val |= ZYNQMP_TCM_COMB_MASK;
+		val |= ZYNQMP_SLCLAMP_MASK;
+	} else {
+		return PM_RET_ERROR_ARGS;
+	}
+
+	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_ioctl_config_boot_addr() - Configure RPU boot address
+ * @nid		Node ID of RPU
+ * @value	Value to set for boot address (TCM/OCM)
+ *
+ * This function configures RPU boot address(memory).
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
+						    unsigned int value)
+{
+	unsigned int rpu_cfg_addr, val;
+
+	if (nid == NODE_RPU_0)
+		rpu_cfg_addr = ZYNQMP_RPU0_CFG;
+	else if (nid == NODE_RPU_1)
+		rpu_cfg_addr = ZYNQMP_RPU1_CFG;
+	else
+		return PM_RET_ERROR_ARGS;
+
+	val = mmio_read_32(rpu_cfg_addr);
+
+	if (value == PM_RPU_BOOTMEM_LOVEC)
+		val &= ~ZYNQMP_VINITHI_MASK;
+	else if (value == PM_RPU_BOOTMEM_HIVEC)
+		val |= ZYNQMP_VINITHI_MASK;
+	else
+		return PM_RET_ERROR_ARGS;
+
+	mmio_write_32(rpu_cfg_addr, val);
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_ioctl_config_tcm_comb() - Configure TCM combined mode
+ * @value	Value to set (Split/Combined)
+ *
+ * This function configures TCM to be in split mode or combined
+ * mode.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_config_tcm_comb(unsigned int value)
+{
+	unsigned int val;
+
+	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
+
+	if (value == PM_RPU_TCM_SPLIT)
+		val &= ~ZYNQMP_TCM_COMB_MASK;
+	else if (value == PM_RPU_TCM_COMB)
+		val |= ZYNQMP_TCM_COMB_MASK;
+	else
+		return PM_RET_ERROR_ARGS;
+
+	mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_ioctl_set_tapdelay_bypass() -  Enable/Disable tap delay bypass
+ * @type	Type of tap delay to enable/disable (e.g. QSPI)
+ * @value	Enable/Disable
+ *
+ * This function enable/disable tap delay bypass.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(unsigned int type,
+						       unsigned int value)
+{
+	if ((value != PM_TAPDELAY_BYPASS_ENABLE &&
+	     value != PM_TAPDELAY_BYPASS_DISABLE) || type >= PM_TAPDELAY_MAX)
+		return PM_RET_ERROR_ARGS;
+
+	return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
+}
+
+/**
+ * pm_ioctl_set_sgmii_mode() -  Set SGMII mode for the GEM device
+ * @nid		Node ID of the device
+ * @value	Enable/Disable
+ *
+ * This function enable/disable SGMII mode for the GEM device.
+ * While enabling SGMII mode, it also ties the GEM PCS Signal
+ * Detect to 1 and selects EMIO for RX clock generation.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
+						  unsigned int value)
+{
+	unsigned int val, mask, shift;
+	enum pm_ret_status ret;
+
+	if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE)
+		return PM_RET_ERROR_ARGS;
+
+	switch (nid) {
+	case NODE_ETH_0:
+		shift = 0;
+		break;
+	case NODE_ETH_1:
+		shift = 1;
+		break;
+	case NODE_ETH_2:
+		shift = 2;
+		break;
+	case NODE_ETH_3:
+		shift = 3;
+		break;
+	default:
+		return PM_RET_ERROR_ARGS;
+	}
+
+	if (value == PM_SGMII_DISABLE) {
+		mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
+		ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
+	} else {
+		/* Tie the GEM PCS Signal Detect to 1 */
+		mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
+		val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
+		ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
+		if (ret != PM_RET_SUCCESS)
+			return ret;
+
+		/* Set the GEM to SGMII mode */
+		mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
+		val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
+		val <<= GEM_CLK_CTRL_OFFSET * shift;
+		ret =  pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
+	}
+
+	return ret;
+}
+
+/**
+ * pm_ioctl_sd_dll_reset() -  Reset DLL logic
+ * @nid		Node ID of the device
+ * @type	Reset type
+ *
+ * This function resets DLL logic for the SD device.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
+						unsigned int type)
+{
+	unsigned int mask, val;
+	enum pm_ret_status ret;
+
+	if (nid == NODE_SD_0) {
+		mask = ZYNQMP_SD0_DLL_RST_MASK;
+		val = ZYNQMP_SD0_DLL_RST;
+	} else if (nid == NODE_SD_1) {
+		mask = ZYNQMP_SD1_DLL_RST_MASK;
+		val = ZYNQMP_SD1_DLL_RST;
+	} else {
+		return PM_RET_ERROR_ARGS;
+	}
+
+	switch (type) {
+	case PM_DLL_RESET_ASSERT:
+	case PM_DLL_RESET_PULSE:
+		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
+		if (ret != PM_RET_SUCCESS)
+			return ret;
+
+		if (type == PM_DLL_RESET_ASSERT)
+			break;
+		mdelay(1);
+	case PM_DLL_RESET_RELEASE:
+		ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
+		break;
+	default:
+		ret = PM_RET_ERROR_ARGS;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pm_ioctl_sd_set_tapdelay() -  Set tap delay for the SD device
+ * @nid		Node ID of the device
+ * @type	Type of tap delay to set (input/output)
+ * @value	Value to set fot the tap delay
+ *
+ * This function sets input/output tap delay for the SD device.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
+						   enum tap_delay_type type,
+						   unsigned int value)
+{
+	unsigned int shift;
+	enum pm_ret_status ret;
+
+	if (nid == NODE_SD_0)
+		shift = 0;
+	else if (nid == NODE_SD_1)
+		shift = ZYNQMP_SD_TAP_OFFSET;
+	else
+		return PM_RET_ERROR_ARGS;
+
+	ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
+	if (ret != PM_RET_SUCCESS)
+		return ret;
+
+	if (type == PM_TAPDELAY_INPUT) {
+		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
+				    (ZYNQMP_SD_ITAPCHGWIN << shift));
+		if (ret != PM_RET_SUCCESS)
+			goto reset_release;
+		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+				    (ZYNQMP_SD_ITAPDLYENA_MASK << shift),
+				    (ZYNQMP_SD_ITAPDLYENA << shift));
+		if (ret != PM_RET_SUCCESS)
+			goto reset_release;
+		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+				    (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
+				    (value << shift));
+		if (ret != PM_RET_SUCCESS)
+			goto reset_release;
+		ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
+				    (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
+	} else if (type == PM_TAPDELAY_OUTPUT) {
+		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
+				    (ZYNQMP_SD_OTAPDLYENA_MASK << shift),
+				    (ZYNQMP_SD_OTAPDLYENA << shift));
+		if (ret != PM_RET_SUCCESS)
+			goto reset_release;
+		ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
+				    (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
+				    (value << shift));
+	} else {
+		ret = PM_RET_ERROR_ARGS;
+	}
+
+reset_release:
+	pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
+	return ret;
+}
+
+/**
+ * pm_ioctl_set_pll_frac_mode() -  Ioctl function for
+ *				   setting pll mode
+ * @pll     PLL id
+ * @mode    Mode fraction/integar
+ *
+ * This function sets PLL mode
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_pll_frac_mode
+			(unsigned int pll, unsigned int mode)
+{
+	return pm_api_clk_set_pll_mode(pll, mode);
+}
+
+/**
+ * pm_ioctl_get_pll_frac_mode() -  Ioctl function for
+ *				   getting pll mode
+ * @pll     PLL id
+ * @mode    Mode fraction/integar
+ *
+ * This function return current PLL mode
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_get_pll_frac_mode
+			(unsigned int pll, unsigned int *mode)
+{
+	return pm_api_clk_get_pll_mode(pll, mode);
+}
+
+/**
+ * pm_ioctl_set_pll_frac_data() -  Ioctl function for
+ *				   setting pll fraction data
+ * @pll     PLL id
+ * @data    fraction data
+ *
+ * This function sets fraction data.
+ * It is valid for fraction mode only.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_set_pll_frac_data
+			(unsigned int pll, unsigned int data)
+{
+	return pm_api_clk_set_pll_frac_data(pll, data);
+}
+
+/**
+ * pm_ioctl_get_pll_frac_data() -  Ioctl function for
+ *				   getting pll fraction data
+ * @pll     PLL id
+ * @data    fraction data
+ *
+ * This function returns fraction data value.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_get_pll_frac_data
+			(unsigned int pll, unsigned int *data)
+{
+	return pm_api_clk_get_pll_frac_data(pll, data);
+}
+
+/**
+ * pm_ioctl_write_ggs() - Ioctl function for writing
+ *			  global general storage (ggs)
+ * @index	GGS register index
+ * @value	Register value to be written
+ *
+ * This function writes value to GGS register.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
+					     unsigned int value)
+{
+	if (index >= GGS_NUM_REGS)
+		return PM_RET_ERROR_ARGS;
+
+	return pm_mmio_write(GGS_BASEADDR + (index << 2),
+			     0xFFFFFFFFU, value);
+}
+
+/**
+ * pm_ioctl_read_ggs() - Ioctl function for reading
+ *			 global general storage (ggs)
+ * @index	GGS register index
+ * @value	Register value
+ *
+ * This function returns GGS register value.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
+					    unsigned int *value)
+{
+	if (index >= GGS_NUM_REGS)
+		return PM_RET_ERROR_ARGS;
+
+	return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
+}
+
+/**
+ * pm_ioctl_write_pggs() - Ioctl function for writing persistent
+ *			   global general storage (pggs)
+ * @index	PGGS register index
+ * @value	Register value to be written
+ *
+ * This function writes value to PGGS register.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
+					      unsigned int value)
+{
+	if (index >= PGGS_NUM_REGS)
+		return PM_RET_ERROR_ARGS;
+
+	return pm_mmio_write(PGGS_BASEADDR + (index << 2),
+			     0xFFFFFFFFU, value);
+}
+
+/**
+ * pm_ioctl_read_pggs() - Ioctl function for reading persistent
+ *			  global general storage (pggs)
+ * @index	PGGS register index
+ * @value	Register value
+ *
+ * This function returns PGGS register value.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
+					     unsigned int *value)
+{
+	if (index >= PGGS_NUM_REGS)
+		return PM_RET_ERROR_ARGS;
+
+	return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
+}
+
+/**
+ * pm_api_ioctl() -  PM IOCTL API for device control and configs
+ * @node_id	Node ID of the device
+ * @ioctl_id	ID of the requested IOCTL
+ * @arg1	Argument 1 to requested IOCTL call
+ * @arg2	Argument 2 to requested IOCTL call
+ * @value	Returned output value
+ *
+ * This function calls IOCTL to firmware for device control and configuration.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
+				unsigned int ioctl_id,
+				unsigned int arg1,
+				unsigned int arg2,
+				unsigned int *value)
+{
+	enum pm_ret_status ret;
+
+	switch (ioctl_id) {
+	case IOCTL_GET_RPU_OPER_MODE:
+		ret = pm_ioctl_get_rpu_oper_mode(value);
+		break;
+	case IOCTL_SET_RPU_OPER_MODE:
+		ret = pm_ioctl_set_rpu_oper_mode(arg1);
+		break;
+	case IOCTL_RPU_BOOT_ADDR_CONFIG:
+		ret = pm_ioctl_config_boot_addr(nid, arg1);
+		break;
+	case IOCTL_TCM_COMB_CONFIG:
+		ret = pm_ioctl_config_tcm_comb(arg1);
+		break;
+	case IOCTL_SET_TAPDELAY_BYPASS:
+		ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
+		break;
+	case IOCTL_SET_SGMII_MODE:
+		ret = pm_ioctl_set_sgmii_mode(nid, arg1);
+		break;
+	case IOCTL_SD_DLL_RESET:
+		ret = pm_ioctl_sd_dll_reset(nid, arg1);
+		break;
+	case IOCTL_SET_SD_TAPDELAY:
+		ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
+		break;
+	case IOCTL_SET_PLL_FRAC_MODE:
+		ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
+		break;
+	case IOCTL_GET_PLL_FRAC_MODE:
+		ret = pm_ioctl_get_pll_frac_mode(arg1, value);
+		break;
+	case IOCTL_SET_PLL_FRAC_DATA:
+		ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
+		break;
+	case IOCTL_GET_PLL_FRAC_DATA:
+		ret = pm_ioctl_get_pll_frac_data(arg1, value);
+		break;
+	case IOCTL_WRITE_GGS:
+		ret = pm_ioctl_write_ggs(arg1, arg2);
+		break;
+	case IOCTL_READ_GGS:
+		ret = pm_ioctl_read_ggs(arg1, value);
+		break;
+	case IOCTL_WRITE_PGGS:
+		ret = pm_ioctl_write_pggs(arg1, arg2);
+		break;
+	case IOCTL_READ_PGGS:
+		ret = pm_ioctl_read_pggs(arg1, value);
+		break;
+	default:
+		ret = PM_RET_ERROR_NOTSUPPORTED;
+		break;
+	}
+
+	return ret;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
new file mode 100644
index 0000000..081259f
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for pin control.
+ */
+
+#ifndef _PM_API_IOCTL_H_
+#define _PM_API_IOCTL_H_
+
+#include "pm_common.h"
+
+//ioctl id
+enum {
+	IOCTL_GET_RPU_OPER_MODE,
+	IOCTL_SET_RPU_OPER_MODE,
+	IOCTL_RPU_BOOT_ADDR_CONFIG,
+	IOCTL_TCM_COMB_CONFIG,
+	IOCTL_SET_TAPDELAY_BYPASS,
+	IOCTL_SET_SGMII_MODE,
+	IOCTL_SD_DLL_RESET,
+	IOCTL_SET_SD_TAPDELAY,
+	 /* Ioctl for clock driver */
+	IOCTL_SET_PLL_FRAC_MODE,
+	IOCTL_GET_PLL_FRAC_MODE,
+	IOCTL_SET_PLL_FRAC_DATA,
+	IOCTL_GET_PLL_FRAC_DATA,
+	IOCTL_WRITE_GGS,
+	IOCTL_READ_GGS,
+	IOCTL_WRITE_PGGS,
+	IOCTL_READ_PGGS,
+};
+
+//RPU operation mode
+#define	PM_RPU_MODE_LOCKSTEP 0U
+#define	PM_RPU_MODE_SPLIT 1U
+
+//RPU boot mem
+#define	PM_RPU_BOOTMEM_LOVEC 0U
+#define	PM_RPU_BOOTMEM_HIVEC 1U
+
+//RPU tcm mpde
+#define	PM_RPU_TCM_SPLIT 0U
+#define	PM_RPU_TCM_COMB 1U
+
+//tap delay signal type
+#define	PM_TAPDELAY_NAND_DQS_IN 0U
+#define	PM_TAPDELAY_NAND_DQS_OUT 1U
+#define	PM_TAPDELAY_QSPI 2U
+#define	PM_TAPDELAY_MAX 3U
+
+//tap delay bypass
+#define	PM_TAPDELAY_BYPASS_DISABLE 0U
+#define	PM_TAPDELAY_BYPASS_ENABLE 1U
+
+//sgmii mode
+#define	PM_SGMII_DISABLE 0U
+#define	PM_SGMII_ENABLE 1U
+
+enum tap_delay_type {
+	PM_TAPDELAY_INPUT,
+	PM_TAPDELAY_OUTPUT,
+};
+
+//dll reset type
+#define	PM_DLL_RESET_ASSERT 0U
+#define	PM_DLL_RESET_RELEASE 1U
+#define	PM_DLL_RESET_PULSE 2U
+
+enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
+				unsigned int ioctl_id,
+				unsigned int arg1,
+				unsigned int arg2,
+				unsigned int *value);
+#endif /* _PM_API_IOCTL_H_ */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
new file mode 100644
index 0000000..12b9c2d
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c
@@ -0,0 +1,3039 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for pin control.
+ */
+
+#include <arch_helpers.h>
+#include <platform.h>
+#include <string.h>
+#include "pm_api_pinctrl.h"
+#include "pm_api_sys.h"
+#include "pm_client.h"
+#include "pm_common.h"
+#include "pm_ipi.h"
+
+#define PINCTRL_FUNCTION_MASK			U(0xFE)
+#define PINCTRL_VOLTAGE_STATUS_MASK		U(0x01)
+#define NFUNCS_PER_PIN				U(13)
+#define PINCTRL_NUM_MIOS			U(78)
+#define MAX_PIN_PER_REG				U(26)
+#define PINCTRL_BANK_ADDR_STEP			U(28)
+
+#define PINCTRL_DRVSTRN0_REG_OFFSET		U(0)
+#define PINCTRL_DRVSTRN1_REG_OFFSET		U(4)
+#define PINCTRL_SCHCMOS_REG_OFFSET		U(8)
+#define PINCTRL_PULLCTRL_REG_OFFSET		U(12)
+#define PINCTRL_PULLSTAT_REG_OFFSET		U(16)
+#define PINCTRL_SLEWCTRL_REG_OFFSET		U(20)
+#define PINCTRL_VOLTAGE_STAT_REG_OFFSET		U(24)
+
+#define IOU_SLCR_BANK1_CTRL5			U(0XFF180164)
+
+#define PINCTRL_CFG_ADDR_OFFSET(addr, reg, miopin)			\
+	((addr) + 4 * PINCTRL_NUM_MIOS + PINCTRL_BANK_ADDR_STEP *	\
+	((miopin) / MAX_PIN_PER_REG) + (reg))
+
+#define PINCTRL_PIN_OFFSET(_miopin) \
+	((_miopin) - (MAX_PIN_PER_REG * ((_miopin) / MAX_PIN_PER_REG)))
+
+#define PINCTRL_REGVAL_TO_PIN_CONFIG(_pin, _val)			\
+	(((_val) >> PINCTRL_PIN_OFFSET(_pin)) & 0x1)
+
+static uint8_t pm_pinctrl_mux[NFUNCS_PER_PIN] = {
+	0x02, 0x04, 0x08, 0x10, 0x18,
+	0x00, 0x20, 0x40, 0x60, 0x80,
+	0xA0, 0xC0, 0xE0
+};
+
+struct pinctrl_function {
+	char name[FUNCTION_NAME_LEN];
+	uint16_t (*groups)[];
+	uint8_t regval;
+};
+
+/* Max groups for one pin */
+#define MAX_PIN_GROUPS	U(13)
+
+struct zynqmp_pin_group {
+	uint16_t (*groups)[];
+};
+
+static struct pinctrl_function pinctrl_functions[MAX_FUNCTION] =  {
+	[PINCTRL_FUNC_CAN0] = {
+		.name = "can0",
+		.regval = 0x20,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_CAN0_0,
+			PINCTRL_GRP_CAN0_1,
+			PINCTRL_GRP_CAN0_2,
+			PINCTRL_GRP_CAN0_3,
+			PINCTRL_GRP_CAN0_4,
+			PINCTRL_GRP_CAN0_5,
+			PINCTRL_GRP_CAN0_6,
+			PINCTRL_GRP_CAN0_7,
+			PINCTRL_GRP_CAN0_8,
+			PINCTRL_GRP_CAN0_9,
+			PINCTRL_GRP_CAN0_10,
+			PINCTRL_GRP_CAN0_11,
+			PINCTRL_GRP_CAN0_12,
+			PINCTRL_GRP_CAN0_13,
+			PINCTRL_GRP_CAN0_14,
+			PINCTRL_GRP_CAN0_15,
+			PINCTRL_GRP_CAN0_16,
+			PINCTRL_GRP_CAN0_17,
+			PINCTRL_GRP_CAN0_18,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_CAN1] = {
+		.name = "can1",
+		.regval = 0x20,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_CAN1_0,
+			PINCTRL_GRP_CAN1_1,
+			PINCTRL_GRP_CAN1_2,
+			PINCTRL_GRP_CAN1_3,
+			PINCTRL_GRP_CAN1_4,
+			PINCTRL_GRP_CAN1_5,
+			PINCTRL_GRP_CAN1_6,
+			PINCTRL_GRP_CAN1_7,
+			PINCTRL_GRP_CAN1_8,
+			PINCTRL_GRP_CAN1_9,
+			PINCTRL_GRP_CAN1_10,
+			PINCTRL_GRP_CAN1_11,
+			PINCTRL_GRP_CAN1_12,
+			PINCTRL_GRP_CAN1_13,
+			PINCTRL_GRP_CAN1_14,
+			PINCTRL_GRP_CAN1_15,
+			PINCTRL_GRP_CAN1_16,
+			PINCTRL_GRP_CAN1_17,
+			PINCTRL_GRP_CAN1_18,
+			PINCTRL_GRP_CAN1_19,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_ETHERNET0] = {
+		.name = "ethernet0",
+		.regval = 0x02,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_ETHERNET1] = {
+		.name = "ethernet1",
+		.regval = 0x02,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_ETHERNET2] = {
+		.name = "ethernet2",
+		.regval = 0x02,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_ETHERNET3] = {
+		.name = "ethernet3",
+		.regval = 0x02,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_GEMTSU0] = {
+		.name = "gemtsu0",
+		.regval = 0x02,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_GEMTSU0_0,
+			PINCTRL_GRP_GEMTSU0_1,
+			PINCTRL_GRP_GEMTSU0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_GPIO0] = {
+		.name = "gpio0",
+		.regval = 0x00,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_GPIO0_0,
+			PINCTRL_GRP_GPIO0_1,
+			PINCTRL_GRP_GPIO0_2,
+			PINCTRL_GRP_GPIO0_3,
+			PINCTRL_GRP_GPIO0_4,
+			PINCTRL_GRP_GPIO0_5,
+			PINCTRL_GRP_GPIO0_6,
+			PINCTRL_GRP_GPIO0_7,
+			PINCTRL_GRP_GPIO0_8,
+			PINCTRL_GRP_GPIO0_9,
+			PINCTRL_GRP_GPIO0_10,
+			PINCTRL_GRP_GPIO0_11,
+			PINCTRL_GRP_GPIO0_12,
+			PINCTRL_GRP_GPIO0_13,
+			PINCTRL_GRP_GPIO0_14,
+			PINCTRL_GRP_GPIO0_15,
+			PINCTRL_GRP_GPIO0_16,
+			PINCTRL_GRP_GPIO0_17,
+			PINCTRL_GRP_GPIO0_18,
+			PINCTRL_GRP_GPIO0_19,
+			PINCTRL_GRP_GPIO0_20,
+			PINCTRL_GRP_GPIO0_21,
+			PINCTRL_GRP_GPIO0_22,
+			PINCTRL_GRP_GPIO0_23,
+			PINCTRL_GRP_GPIO0_24,
+			PINCTRL_GRP_GPIO0_25,
+			PINCTRL_GRP_GPIO0_26,
+			PINCTRL_GRP_GPIO0_27,
+			PINCTRL_GRP_GPIO0_28,
+			PINCTRL_GRP_GPIO0_29,
+			PINCTRL_GRP_GPIO0_30,
+			PINCTRL_GRP_GPIO0_31,
+			PINCTRL_GRP_GPIO0_32,
+			PINCTRL_GRP_GPIO0_33,
+			PINCTRL_GRP_GPIO0_34,
+			PINCTRL_GRP_GPIO0_35,
+			PINCTRL_GRP_GPIO0_36,
+			PINCTRL_GRP_GPIO0_37,
+			PINCTRL_GRP_GPIO0_38,
+			PINCTRL_GRP_GPIO0_39,
+			PINCTRL_GRP_GPIO0_40,
+			PINCTRL_GRP_GPIO0_41,
+			PINCTRL_GRP_GPIO0_42,
+			PINCTRL_GRP_GPIO0_43,
+			PINCTRL_GRP_GPIO0_44,
+			PINCTRL_GRP_GPIO0_45,
+			PINCTRL_GRP_GPIO0_46,
+			PINCTRL_GRP_GPIO0_47,
+			PINCTRL_GRP_GPIO0_48,
+			PINCTRL_GRP_GPIO0_49,
+			PINCTRL_GRP_GPIO0_50,
+			PINCTRL_GRP_GPIO0_51,
+			PINCTRL_GRP_GPIO0_52,
+			PINCTRL_GRP_GPIO0_53,
+			PINCTRL_GRP_GPIO0_54,
+			PINCTRL_GRP_GPIO0_55,
+			PINCTRL_GRP_GPIO0_56,
+			PINCTRL_GRP_GPIO0_57,
+			PINCTRL_GRP_GPIO0_58,
+			PINCTRL_GRP_GPIO0_59,
+			PINCTRL_GRP_GPIO0_60,
+			PINCTRL_GRP_GPIO0_61,
+			PINCTRL_GRP_GPIO0_62,
+			PINCTRL_GRP_GPIO0_63,
+			PINCTRL_GRP_GPIO0_64,
+			PINCTRL_GRP_GPIO0_65,
+			PINCTRL_GRP_GPIO0_66,
+			PINCTRL_GRP_GPIO0_67,
+			PINCTRL_GRP_GPIO0_68,
+			PINCTRL_GRP_GPIO0_69,
+			PINCTRL_GRP_GPIO0_70,
+			PINCTRL_GRP_GPIO0_71,
+			PINCTRL_GRP_GPIO0_72,
+			PINCTRL_GRP_GPIO0_73,
+			PINCTRL_GRP_GPIO0_74,
+			PINCTRL_GRP_GPIO0_75,
+			PINCTRL_GRP_GPIO0_76,
+			PINCTRL_GRP_GPIO0_77,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_I2C0] = {
+		.name = "i2c0",
+		.regval = 0x40,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_I2C0_0,
+			PINCTRL_GRP_I2C0_1,
+			PINCTRL_GRP_I2C0_2,
+			PINCTRL_GRP_I2C0_3,
+			PINCTRL_GRP_I2C0_4,
+			PINCTRL_GRP_I2C0_5,
+			PINCTRL_GRP_I2C0_6,
+			PINCTRL_GRP_I2C0_7,
+			PINCTRL_GRP_I2C0_8,
+			PINCTRL_GRP_I2C0_9,
+			PINCTRL_GRP_I2C0_10,
+			PINCTRL_GRP_I2C0_11,
+			PINCTRL_GRP_I2C0_12,
+			PINCTRL_GRP_I2C0_13,
+			PINCTRL_GRP_I2C0_14,
+			PINCTRL_GRP_I2C0_15,
+			PINCTRL_GRP_I2C0_16,
+			PINCTRL_GRP_I2C0_17,
+			PINCTRL_GRP_I2C0_18,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_I2C1] = {
+		.name = "i2c1",
+		.regval = 0x40,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_I2C1_0,
+			PINCTRL_GRP_I2C1_1,
+			PINCTRL_GRP_I2C1_2,
+			PINCTRL_GRP_I2C1_3,
+			PINCTRL_GRP_I2C1_4,
+			PINCTRL_GRP_I2C1_5,
+			PINCTRL_GRP_I2C1_6,
+			PINCTRL_GRP_I2C1_7,
+			PINCTRL_GRP_I2C1_8,
+			PINCTRL_GRP_I2C1_9,
+			PINCTRL_GRP_I2C1_10,
+			PINCTRL_GRP_I2C1_11,
+			PINCTRL_GRP_I2C1_12,
+			PINCTRL_GRP_I2C1_13,
+			PINCTRL_GRP_I2C1_14,
+			PINCTRL_GRP_I2C1_15,
+			PINCTRL_GRP_I2C1_16,
+			PINCTRL_GRP_I2C1_17,
+			PINCTRL_GRP_I2C1_18,
+			PINCTRL_GRP_I2C1_19,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_MDIO0] = {
+		.name = "mdio0",
+		.regval = 0x60,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_MDIO0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_MDIO1] = {
+		.name = "mdio1",
+		.regval = 0x80,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_MDIO1_0,
+			PINCTRL_GRP_MDIO1_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_MDIO2] = {
+		.name = "mdio2",
+		.regval = 0xa0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_MDIO2_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_MDIO3] = {
+		.name = "mdio3",
+		.regval = 0xc0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_MDIO3_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_QSPI0] = {
+		.name = "qspi0",
+		.regval = 0x02,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_QSPI_FBCLK] = {
+		.name = "qspi_fbclk",
+		.regval = 0x02,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI_FBCLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_QSPI_SS] = {
+		.name = "qspi_ss",
+		.regval = 0x02,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI_SS,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SPI0] = {
+		.name = "spi0",
+		.regval = 0x80,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SPI0_0,
+			PINCTRL_GRP_SPI0_1,
+			PINCTRL_GRP_SPI0_2,
+			PINCTRL_GRP_SPI0_3,
+			PINCTRL_GRP_SPI0_4,
+			PINCTRL_GRP_SPI0_5,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SPI1] = {
+		.name = "spi1",
+		.regval = 0x80,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SPI1_0,
+			PINCTRL_GRP_SPI1_1,
+			PINCTRL_GRP_SPI1_2,
+			PINCTRL_GRP_SPI1_3,
+			PINCTRL_GRP_SPI1_4,
+			PINCTRL_GRP_SPI1_5,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SPI0_SS] = {
+		.name = "spi0_ss",
+		.regval = 0x80,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SPI0_0_SS0,
+			PINCTRL_GRP_SPI0_0_SS1,
+			PINCTRL_GRP_SPI0_0_SS2,
+			PINCTRL_GRP_SPI0_1_SS0,
+			PINCTRL_GRP_SPI0_1_SS1,
+			PINCTRL_GRP_SPI0_1_SS2,
+			PINCTRL_GRP_SPI0_2_SS0,
+			PINCTRL_GRP_SPI0_2_SS1,
+			PINCTRL_GRP_SPI0_2_SS2,
+			PINCTRL_GRP_SPI0_3_SS0,
+			PINCTRL_GRP_SPI0_3_SS1,
+			PINCTRL_GRP_SPI0_3_SS2,
+			PINCTRL_GRP_SPI0_4_SS0,
+			PINCTRL_GRP_SPI0_4_SS1,
+			PINCTRL_GRP_SPI0_4_SS2,
+			PINCTRL_GRP_SPI0_5_SS0,
+			PINCTRL_GRP_SPI0_5_SS1,
+			PINCTRL_GRP_SPI0_5_SS2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SPI1_SS] = {
+		.name = "spi1_ss",
+		.regval = 0x80,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SPI1_0_SS0,
+			PINCTRL_GRP_SPI1_0_SS1,
+			PINCTRL_GRP_SPI1_0_SS2,
+			PINCTRL_GRP_SPI1_1_SS0,
+			PINCTRL_GRP_SPI1_1_SS1,
+			PINCTRL_GRP_SPI1_1_SS2,
+			PINCTRL_GRP_SPI1_2_SS0,
+			PINCTRL_GRP_SPI1_2_SS1,
+			PINCTRL_GRP_SPI1_2_SS2,
+			PINCTRL_GRP_SPI1_3_SS0,
+			PINCTRL_GRP_SPI1_3_SS1,
+			PINCTRL_GRP_SPI1_3_SS2,
+			PINCTRL_GRP_SPI1_4_SS0,
+			PINCTRL_GRP_SPI1_4_SS1,
+			PINCTRL_GRP_SPI1_4_SS2,
+			PINCTRL_GRP_SPI1_5_SS0,
+			PINCTRL_GRP_SPI1_5_SS1,
+			PINCTRL_GRP_SPI1_5_SS2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SDIO0] = {
+		.name = "sdio0",
+		.regval = 0x08,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_SDIO0_4BIT_0_0,
+			PINCTRL_GRP_SDIO0_4BIT_0_1,
+			PINCTRL_GRP_SDIO0_4BIT_1_0,
+			PINCTRL_GRP_SDIO0_4BIT_1_1,
+			PINCTRL_GRP_SDIO0_4BIT_2_0,
+			PINCTRL_GRP_SDIO0_4BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_0,
+			PINCTRL_GRP_SDIO0_1BIT_0_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_2,
+			PINCTRL_GRP_SDIO0_1BIT_0_3,
+			PINCTRL_GRP_SDIO0_1BIT_0_4,
+			PINCTRL_GRP_SDIO0_1BIT_0_5,
+			PINCTRL_GRP_SDIO0_1BIT_0_6,
+			PINCTRL_GRP_SDIO0_1BIT_0_7,
+			PINCTRL_GRP_SDIO0_1BIT_1_0,
+			PINCTRL_GRP_SDIO0_1BIT_1_1,
+			PINCTRL_GRP_SDIO0_1BIT_1_2,
+			PINCTRL_GRP_SDIO0_1BIT_1_3,
+			PINCTRL_GRP_SDIO0_1BIT_1_4,
+			PINCTRL_GRP_SDIO0_1BIT_1_5,
+			PINCTRL_GRP_SDIO0_1BIT_1_6,
+			PINCTRL_GRP_SDIO0_1BIT_1_7,
+			PINCTRL_GRP_SDIO0_1BIT_2_0,
+			PINCTRL_GRP_SDIO0_1BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_2_2,
+			PINCTRL_GRP_SDIO0_1BIT_2_3,
+			PINCTRL_GRP_SDIO0_1BIT_2_4,
+			PINCTRL_GRP_SDIO0_1BIT_2_5,
+			PINCTRL_GRP_SDIO0_1BIT_2_6,
+			PINCTRL_GRP_SDIO0_1BIT_2_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SDIO0_PC] = {
+		.name = "sdio0_pc",
+		.regval = 0x08,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SDIO0_0_PC,
+			PINCTRL_GRP_SDIO0_1_PC,
+			PINCTRL_GRP_SDIO0_2_PC,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SDIO0_CD] = {
+		.name = "sdio0_cd",
+		.regval = 0x08,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SDIO0_0_CD,
+			PINCTRL_GRP_SDIO0_1_CD,
+			PINCTRL_GRP_SDIO0_2_CD,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SDIO0_WP] = {
+		.name = "sdio0_wp",
+		.regval = 0x08,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SDIO0_0_WP,
+			PINCTRL_GRP_SDIO0_1_WP,
+			PINCTRL_GRP_SDIO0_2_WP,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SDIO1] = {
+		.name = "sdio1",
+		.regval = 0x10,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_SDIO1_4BIT_0_0,
+			PINCTRL_GRP_SDIO1_4BIT_0_1,
+			PINCTRL_GRP_SDIO1_4BIT_1_0,
+			PINCTRL_GRP_SDIO1_1BIT_0_0,
+			PINCTRL_GRP_SDIO1_1BIT_0_1,
+			PINCTRL_GRP_SDIO1_1BIT_0_2,
+			PINCTRL_GRP_SDIO1_1BIT_0_3,
+			PINCTRL_GRP_SDIO1_1BIT_0_4,
+			PINCTRL_GRP_SDIO1_1BIT_0_5,
+			PINCTRL_GRP_SDIO1_1BIT_0_6,
+			PINCTRL_GRP_SDIO1_1BIT_0_7,
+			PINCTRL_GRP_SDIO1_1BIT_1_0,
+			PINCTRL_GRP_SDIO1_1BIT_1_1,
+			PINCTRL_GRP_SDIO1_1BIT_1_2,
+			PINCTRL_GRP_SDIO1_1BIT_1_3,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SDIO1_PC] = {
+		.name = "sdio1_pc",
+		.regval = 0x10,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SDIO1_0_PC,
+			PINCTRL_GRP_SDIO1_1_PC,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SDIO1_CD] = {
+		.name = "sdio1_cd",
+		.regval = 0x10,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SDIO1_0_CD,
+			PINCTRL_GRP_SDIO1_1_CD,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SDIO1_WP] = {
+		.name = "sdio1_wp",
+		.regval = 0x10,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SDIO1_0_WP,
+			PINCTRL_GRP_SDIO1_1_WP,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_NAND0] = {
+		.name = "nand0",
+		.regval = 0x04,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_NAND0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_NAND0_CE] = {
+		.name = "nand0_ce",
+		.regval = 0x04,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_NAND0_0_CE,
+			PINCTRL_GRP_NAND0_1_CE,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_NAND0_RB] = {
+		.name = "nand0_rb",
+		.regval = 0x04,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_NAND0_0_RB,
+			PINCTRL_GRP_NAND0_1_RB,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_NAND0_DQS] = {
+		.name = "nand0_dqs",
+		.regval = 0x04,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_NAND0_0_DQS,
+			PINCTRL_GRP_NAND0_1_DQS,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TTC0_CLK] = {
+		.name = "ttc0_clk",
+		.regval = 0xa0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TTC0_0_CLK,
+			PINCTRL_GRP_TTC0_1_CLK,
+			PINCTRL_GRP_TTC0_2_CLK,
+			PINCTRL_GRP_TTC0_3_CLK,
+			PINCTRL_GRP_TTC0_4_CLK,
+			PINCTRL_GRP_TTC0_5_CLK,
+			PINCTRL_GRP_TTC0_6_CLK,
+			PINCTRL_GRP_TTC0_7_CLK,
+			PINCTRL_GRP_TTC0_8_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TTC0_WAV] = {
+		.name = "ttc0_wav",
+		.regval = 0xa0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TTC0_0_WAV,
+			PINCTRL_GRP_TTC0_1_WAV,
+			PINCTRL_GRP_TTC0_2_WAV,
+			PINCTRL_GRP_TTC0_3_WAV,
+			PINCTRL_GRP_TTC0_4_WAV,
+			PINCTRL_GRP_TTC0_5_WAV,
+			PINCTRL_GRP_TTC0_6_WAV,
+			PINCTRL_GRP_TTC0_7_WAV,
+			PINCTRL_GRP_TTC0_8_WAV,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TTC1_CLK] = {
+		.name = "ttc1_clk",
+		.regval = 0xa0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TTC1_0_CLK,
+			PINCTRL_GRP_TTC1_1_CLK,
+			PINCTRL_GRP_TTC1_2_CLK,
+			PINCTRL_GRP_TTC1_3_CLK,
+			PINCTRL_GRP_TTC1_4_CLK,
+			PINCTRL_GRP_TTC1_5_CLK,
+			PINCTRL_GRP_TTC1_6_CLK,
+			PINCTRL_GRP_TTC1_7_CLK,
+			PINCTRL_GRP_TTC1_8_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TTC1_WAV] = {
+		.name = "ttc1_wav",
+		.regval = 0xa0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TTC1_0_WAV,
+			PINCTRL_GRP_TTC1_1_WAV,
+			PINCTRL_GRP_TTC1_2_WAV,
+			PINCTRL_GRP_TTC1_3_WAV,
+			PINCTRL_GRP_TTC1_4_WAV,
+			PINCTRL_GRP_TTC1_5_WAV,
+			PINCTRL_GRP_TTC1_6_WAV,
+			PINCTRL_GRP_TTC1_7_WAV,
+			PINCTRL_GRP_TTC1_8_WAV,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TTC2_CLK] = {
+		.name = "ttc2_clk",
+		.regval = 0xa0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TTC2_0_CLK,
+			PINCTRL_GRP_TTC2_1_CLK,
+			PINCTRL_GRP_TTC2_2_CLK,
+			PINCTRL_GRP_TTC2_3_CLK,
+			PINCTRL_GRP_TTC2_4_CLK,
+			PINCTRL_GRP_TTC2_5_CLK,
+			PINCTRL_GRP_TTC2_6_CLK,
+			PINCTRL_GRP_TTC2_7_CLK,
+			PINCTRL_GRP_TTC2_8_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TTC2_WAV] = {
+		.name = "ttc2_wav",
+		.regval = 0xa0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TTC2_0_WAV,
+			PINCTRL_GRP_TTC2_1_WAV,
+			PINCTRL_GRP_TTC2_2_WAV,
+			PINCTRL_GRP_TTC2_3_WAV,
+			PINCTRL_GRP_TTC2_4_WAV,
+			PINCTRL_GRP_TTC2_5_WAV,
+			PINCTRL_GRP_TTC2_6_WAV,
+			PINCTRL_GRP_TTC2_7_WAV,
+			PINCTRL_GRP_TTC2_8_WAV,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TTC3_CLK] = {
+		.name = "ttc3_clk",
+		.regval = 0xa0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TTC3_0_CLK,
+			PINCTRL_GRP_TTC3_1_CLK,
+			PINCTRL_GRP_TTC3_2_CLK,
+			PINCTRL_GRP_TTC3_3_CLK,
+			PINCTRL_GRP_TTC3_4_CLK,
+			PINCTRL_GRP_TTC3_5_CLK,
+			PINCTRL_GRP_TTC3_6_CLK,
+			PINCTRL_GRP_TTC3_7_CLK,
+			PINCTRL_GRP_TTC3_8_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TTC3_WAV] = {
+		.name = "ttc3_wav",
+		.regval = 0xa0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TTC3_0_WAV,
+			PINCTRL_GRP_TTC3_1_WAV,
+			PINCTRL_GRP_TTC3_2_WAV,
+			PINCTRL_GRP_TTC3_3_WAV,
+			PINCTRL_GRP_TTC3_4_WAV,
+			PINCTRL_GRP_TTC3_5_WAV,
+			PINCTRL_GRP_TTC3_6_WAV,
+			PINCTRL_GRP_TTC3_7_WAV,
+			PINCTRL_GRP_TTC3_8_WAV,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_UART0] = {
+		.name = "uart0",
+		.regval = 0xc0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_UART0_0,
+			PINCTRL_GRP_UART0_1,
+			PINCTRL_GRP_UART0_2,
+			PINCTRL_GRP_UART0_3,
+			PINCTRL_GRP_UART0_4,
+			PINCTRL_GRP_UART0_5,
+			PINCTRL_GRP_UART0_6,
+			PINCTRL_GRP_UART0_7,
+			PINCTRL_GRP_UART0_8,
+			PINCTRL_GRP_UART0_9,
+			PINCTRL_GRP_UART0_10,
+			PINCTRL_GRP_UART0_11,
+			PINCTRL_GRP_UART0_12,
+			PINCTRL_GRP_UART0_13,
+			PINCTRL_GRP_UART0_14,
+			PINCTRL_GRP_UART0_15,
+			PINCTRL_GRP_UART0_16,
+			PINCTRL_GRP_UART0_17,
+			PINCTRL_GRP_UART0_18,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_UART1] = {
+		.name = "uart1",
+		.regval = 0xc0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_UART1_0,
+			PINCTRL_GRP_UART1_1,
+			PINCTRL_GRP_UART1_2,
+			PINCTRL_GRP_UART1_3,
+			PINCTRL_GRP_UART1_4,
+			PINCTRL_GRP_UART1_5,
+			PINCTRL_GRP_UART1_6,
+			PINCTRL_GRP_UART1_7,
+			PINCTRL_GRP_UART1_8,
+			PINCTRL_GRP_UART1_9,
+			PINCTRL_GRP_UART1_10,
+			PINCTRL_GRP_UART1_11,
+			PINCTRL_GRP_UART1_12,
+			PINCTRL_GRP_UART1_13,
+			PINCTRL_GRP_UART1_14,
+			PINCTRL_GRP_UART1_15,
+			PINCTRL_GRP_UART1_16,
+			PINCTRL_GRP_UART1_17,
+			PINCTRL_GRP_UART1_18,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_USB0] = {
+		.name = "usb0",
+		.regval = 0x04,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_USB0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_USB1] = {
+		.name = "usb1",
+		.regval = 0x04,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_USB1_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SWDT0_CLK] = {
+		.name = "swdt0_clk",
+		.regval = 0x60,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SWDT0_0_CLK,
+			PINCTRL_GRP_SWDT0_1_CLK,
+			PINCTRL_GRP_SWDT0_2_CLK,
+			PINCTRL_GRP_SWDT0_3_CLK,
+			PINCTRL_GRP_SWDT0_4_CLK,
+			PINCTRL_GRP_SWDT0_5_CLK,
+			PINCTRL_GRP_SWDT0_6_CLK,
+			PINCTRL_GRP_SWDT0_7_CLK,
+			PINCTRL_GRP_SWDT0_8_CLK,
+			PINCTRL_GRP_SWDT0_9_CLK,
+			PINCTRL_GRP_SWDT0_10_CLK,
+			PINCTRL_GRP_SWDT0_11_CLK,
+			PINCTRL_GRP_SWDT0_12_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SWDT0_RST] = {
+		.name = "swdt0_rst",
+		.regval = 0x60,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SWDT0_0_RST,
+			PINCTRL_GRP_SWDT0_1_RST,
+			PINCTRL_GRP_SWDT0_2_RST,
+			PINCTRL_GRP_SWDT0_3_RST,
+			PINCTRL_GRP_SWDT0_4_RST,
+			PINCTRL_GRP_SWDT0_5_RST,
+			PINCTRL_GRP_SWDT0_6_RST,
+			PINCTRL_GRP_SWDT0_7_RST,
+			PINCTRL_GRP_SWDT0_8_RST,
+			PINCTRL_GRP_SWDT0_9_RST,
+			PINCTRL_GRP_SWDT0_10_RST,
+			PINCTRL_GRP_SWDT0_11_RST,
+			PINCTRL_GRP_SWDT0_12_RST,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SWDT1_CLK] = {
+		.name = "swdt1_clk",
+		.regval = 0x60,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SWDT1_0_CLK,
+			PINCTRL_GRP_SWDT1_1_CLK,
+			PINCTRL_GRP_SWDT1_2_CLK,
+			PINCTRL_GRP_SWDT1_3_CLK,
+			PINCTRL_GRP_SWDT1_4_CLK,
+			PINCTRL_GRP_SWDT1_5_CLK,
+			PINCTRL_GRP_SWDT1_6_CLK,
+			PINCTRL_GRP_SWDT1_7_CLK,
+			PINCTRL_GRP_SWDT1_8_CLK,
+			PINCTRL_GRP_SWDT1_9_CLK,
+			PINCTRL_GRP_SWDT1_10_CLK,
+			PINCTRL_GRP_SWDT1_11_CLK,
+			PINCTRL_GRP_SWDT1_12_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_SWDT1_RST] = {
+		.name = "swdt1_rst",
+		.regval = 0x60,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_SWDT1_0_RST,
+			PINCTRL_GRP_SWDT1_1_RST,
+			PINCTRL_GRP_SWDT1_2_RST,
+			PINCTRL_GRP_SWDT1_3_RST,
+			PINCTRL_GRP_SWDT1_4_RST,
+			PINCTRL_GRP_SWDT1_5_RST,
+			PINCTRL_GRP_SWDT1_6_RST,
+			PINCTRL_GRP_SWDT1_7_RST,
+			PINCTRL_GRP_SWDT1_8_RST,
+			PINCTRL_GRP_SWDT1_9_RST,
+			PINCTRL_GRP_SWDT1_10_RST,
+			PINCTRL_GRP_SWDT1_11_RST,
+			PINCTRL_GRP_SWDT1_12_RST,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_PMU0] = {
+		.name = "pmu0",
+		.regval = 0x08,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_PMU0_0,
+			PINCTRL_GRP_PMU0_1,
+			PINCTRL_GRP_PMU0_2,
+			PINCTRL_GRP_PMU0_3,
+			PINCTRL_GRP_PMU0_4,
+			PINCTRL_GRP_PMU0_5,
+			PINCTRL_GRP_PMU0_6,
+			PINCTRL_GRP_PMU0_7,
+			PINCTRL_GRP_PMU0_8,
+			PINCTRL_GRP_PMU0_9,
+			PINCTRL_GRP_PMU0_10,
+			PINCTRL_GRP_PMU0_11,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_PCIE0] = {
+		.name = "pcie0",
+		.regval = 0x04,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_PCIE0_0,
+			PINCTRL_GRP_PCIE0_1,
+			PINCTRL_GRP_PCIE0_2,
+			PINCTRL_GRP_PCIE0_3,
+			PINCTRL_GRP_PCIE0_4,
+			PINCTRL_GRP_PCIE0_5,
+			PINCTRL_GRP_PCIE0_6,
+			PINCTRL_GRP_PCIE0_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_CSU0] = {
+		.name = "csu0",
+		.regval = 0x18,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_CSU0_0,
+			PINCTRL_GRP_CSU0_1,
+			PINCTRL_GRP_CSU0_2,
+			PINCTRL_GRP_CSU0_3,
+			PINCTRL_GRP_CSU0_4,
+			PINCTRL_GRP_CSU0_5,
+			PINCTRL_GRP_CSU0_6,
+			PINCTRL_GRP_CSU0_7,
+			PINCTRL_GRP_CSU0_8,
+			PINCTRL_GRP_CSU0_9,
+			PINCTRL_GRP_CSU0_10,
+			PINCTRL_GRP_CSU0_11,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_DPAUX0] = {
+		.name = "dpaux0",
+		.regval = 0x18,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_DPAUX0_0,
+			PINCTRL_GRP_DPAUX0_1,
+			PINCTRL_GRP_DPAUX0_2,
+			PINCTRL_GRP_DPAUX0_3,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_PJTAG0] = {
+		.name = "pjtag0",
+		.regval = 0x60,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_PJTAG0_0,
+			PINCTRL_GRP_PJTAG0_1,
+			PINCTRL_GRP_PJTAG0_2,
+			PINCTRL_GRP_PJTAG0_3,
+			PINCTRL_GRP_PJTAG0_4,
+			PINCTRL_GRP_PJTAG0_5,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TRACE0] = {
+		.name = "trace0",
+		.regval = 0xe0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TRACE0_0,
+			PINCTRL_GRP_TRACE0_1,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TRACE0_CLK] = {
+		.name = "trace0_clk",
+		.regval = 0xe0,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TRACE0_0_CLK,
+			PINCTRL_GRP_TRACE0_1_CLK,
+			PINCTRL_GRP_TRACE0_2_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_FUNC_TESTSCAN0] = {
+		.name = "testscan0",
+		.regval = 0x10,
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_TESTSCAN0_0,
+			END_OF_GROUPS,
+		}),
+	},
+};
+
+static struct zynqmp_pin_group zynqmp_pin_groups[MAX_PIN] = {
+	[PINCTRL_PIN_0] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_0,
+			PINCTRL_GRP_CAN1_0,
+			PINCTRL_GRP_I2C1_0,
+			PINCTRL_GRP_PJTAG0_0,
+			PINCTRL_GRP_SPI0_0,
+			PINCTRL_GRP_TTC3_0_CLK,
+			PINCTRL_GRP_UART1_0,
+			PINCTRL_GRP_TRACE0_0_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_1] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_1,
+			PINCTRL_GRP_CAN1_0,
+			PINCTRL_GRP_I2C1_0,
+			PINCTRL_GRP_PJTAG0_0,
+			PINCTRL_GRP_SPI0_0_SS2,
+			PINCTRL_GRP_TTC3_0_WAV,
+			PINCTRL_GRP_UART1_0,
+			PINCTRL_GRP_TRACE0_0_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_2] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_2,
+			PINCTRL_GRP_CAN0_0,
+			PINCTRL_GRP_I2C0_0,
+			PINCTRL_GRP_PJTAG0_0,
+			PINCTRL_GRP_SPI0_0_SS1,
+			PINCTRL_GRP_TTC2_0_CLK,
+			PINCTRL_GRP_UART0_0,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_3] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_3,
+			PINCTRL_GRP_CAN0_0,
+			PINCTRL_GRP_I2C0_0,
+			PINCTRL_GRP_PJTAG0_0,
+			PINCTRL_GRP_SPI0_0_SS0,
+			PINCTRL_GRP_TTC2_0_WAV,
+			PINCTRL_GRP_UART0_0,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_4] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_4,
+			PINCTRL_GRP_CAN1_1,
+			PINCTRL_GRP_I2C1_1,
+			PINCTRL_GRP_SWDT1_0_CLK,
+			PINCTRL_GRP_SPI0_0,
+			PINCTRL_GRP_TTC1_0_CLK,
+			PINCTRL_GRP_UART1_1,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_5] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI_SS,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_5,
+			PINCTRL_GRP_CAN1_1,
+			PINCTRL_GRP_I2C1_1,
+			PINCTRL_GRP_SWDT1_0_RST,
+			PINCTRL_GRP_SPI0_0,
+			PINCTRL_GRP_TTC1_0_WAV,
+			PINCTRL_GRP_UART1_1,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_6] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI_FBCLK,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_6,
+			PINCTRL_GRP_CAN0_1,
+			PINCTRL_GRP_I2C0_1,
+			PINCTRL_GRP_SWDT0_0_CLK,
+			PINCTRL_GRP_SPI1_0,
+			PINCTRL_GRP_TTC0_0_CLK,
+			PINCTRL_GRP_UART0_1,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_7] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI_SS,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_7,
+			PINCTRL_GRP_CAN0_1,
+			PINCTRL_GRP_I2C0_1,
+			PINCTRL_GRP_SWDT0_0_RST,
+			PINCTRL_GRP_SPI1_0_SS2,
+			PINCTRL_GRP_TTC0_0_WAV,
+			PINCTRL_GRP_UART0_1,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_8] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_8,
+			PINCTRL_GRP_CAN1_2,
+			PINCTRL_GRP_I2C1_2,
+			PINCTRL_GRP_SWDT1_1_CLK,
+			PINCTRL_GRP_SPI1_0_SS1,
+			PINCTRL_GRP_TTC3_1_CLK,
+			PINCTRL_GRP_UART1_2,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_9] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_NAND0_0_CE,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_9,
+			PINCTRL_GRP_CAN1_2,
+			PINCTRL_GRP_I2C1_2,
+			PINCTRL_GRP_SWDT1_1_RST,
+			PINCTRL_GRP_SPI1_0_SS0,
+			PINCTRL_GRP_TTC3_1_WAV,
+			PINCTRL_GRP_UART1_2,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_10] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_NAND0_0_RB,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_10,
+			PINCTRL_GRP_CAN0_2,
+			PINCTRL_GRP_I2C0_2,
+			PINCTRL_GRP_SWDT0_1_CLK,
+			PINCTRL_GRP_SPI1_0,
+			PINCTRL_GRP_TTC2_1_CLK,
+			PINCTRL_GRP_UART0_2,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_11] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_NAND0_0_RB,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_11,
+			PINCTRL_GRP_CAN0_2,
+			PINCTRL_GRP_I2C0_2,
+			PINCTRL_GRP_SWDT0_1_RST,
+			PINCTRL_GRP_SPI1_0,
+			PINCTRL_GRP_TTC2_1_WAV,
+			PINCTRL_GRP_UART0_2,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_12] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_QSPI0_0,
+			PINCTRL_GRP_NAND0_0_DQS,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_12,
+			PINCTRL_GRP_CAN1_3,
+			PINCTRL_GRP_I2C1_3,
+			PINCTRL_GRP_PJTAG0_1,
+			PINCTRL_GRP_SPI0_1,
+			PINCTRL_GRP_TTC1_1_CLK,
+			PINCTRL_GRP_UART1_3,
+			PINCTRL_GRP_TRACE0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_13] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_13,
+			PINCTRL_GRP_CAN1_3,
+			PINCTRL_GRP_I2C1_3,
+			PINCTRL_GRP_PJTAG0_1,
+			PINCTRL_GRP_SPI0_1_SS2,
+			PINCTRL_GRP_TTC1_1_WAV,
+			PINCTRL_GRP_UART1_3,
+			PINCTRL_GRP_TRACE0_0,
+			PINCTRL_GRP_SDIO0_4BIT_0_0,
+			PINCTRL_GRP_SDIO0_1BIT_0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_14] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_14,
+			PINCTRL_GRP_CAN0_3,
+			PINCTRL_GRP_I2C0_3,
+			PINCTRL_GRP_PJTAG0_1,
+			PINCTRL_GRP_SPI0_1_SS1,
+			PINCTRL_GRP_TTC0_1_CLK,
+			PINCTRL_GRP_UART0_3,
+			PINCTRL_GRP_TRACE0_0,
+			PINCTRL_GRP_SDIO0_4BIT_0_0,
+			PINCTRL_GRP_SDIO0_1BIT_0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_15] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_15,
+			PINCTRL_GRP_CAN0_3,
+			PINCTRL_GRP_I2C0_3,
+			PINCTRL_GRP_PJTAG0_1,
+			PINCTRL_GRP_SPI0_1_SS0,
+			PINCTRL_GRP_TTC0_1_WAV,
+			PINCTRL_GRP_UART0_3,
+			PINCTRL_GRP_TRACE0_0,
+			PINCTRL_GRP_SDIO0_4BIT_0_0,
+			PINCTRL_GRP_SDIO0_1BIT_0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_16] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_16,
+			PINCTRL_GRP_CAN1_4,
+			PINCTRL_GRP_I2C1_4,
+			PINCTRL_GRP_SWDT1_2_CLK,
+			PINCTRL_GRP_SPI0_1,
+			PINCTRL_GRP_TTC3_2_CLK,
+			PINCTRL_GRP_UART1_4,
+			PINCTRL_GRP_TRACE0_0,
+			PINCTRL_GRP_SDIO0_4BIT_0_0,
+			PINCTRL_GRP_SDIO0_1BIT_0_3,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_17] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_17,
+			PINCTRL_GRP_CAN1_4,
+			PINCTRL_GRP_I2C1_4,
+			PINCTRL_GRP_SWDT1_2_RST,
+			PINCTRL_GRP_SPI0_1,
+			PINCTRL_GRP_TTC3_2_WAV,
+			PINCTRL_GRP_UART1_4,
+			PINCTRL_GRP_TRACE0_0,
+			PINCTRL_GRP_SDIO0_4BIT_0_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_4,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_18] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_0,
+			PINCTRL_GRP_GPIO0_18,
+			PINCTRL_GRP_CAN0_4,
+			PINCTRL_GRP_I2C0_4,
+			PINCTRL_GRP_SWDT0_2_CLK,
+			PINCTRL_GRP_SPI1_1,
+			PINCTRL_GRP_TTC2_2_CLK,
+			PINCTRL_GRP_UART0_4,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_0_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_5,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_19] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_1,
+			PINCTRL_GRP_GPIO0_19,
+			PINCTRL_GRP_CAN0_4,
+			PINCTRL_GRP_I2C0_4,
+			PINCTRL_GRP_SWDT0_2_RST,
+			PINCTRL_GRP_SPI1_1_SS2,
+			PINCTRL_GRP_TTC2_2_WAV,
+			PINCTRL_GRP_UART0_4,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_0_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_6,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_20] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_2,
+			PINCTRL_GRP_GPIO0_20,
+			PINCTRL_GRP_CAN1_5,
+			PINCTRL_GRP_I2C1_5,
+			PINCTRL_GRP_SWDT1_3_CLK,
+			PINCTRL_GRP_SPI1_1_SS1,
+			PINCTRL_GRP_TTC1_2_CLK,
+			PINCTRL_GRP_UART1_5,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_0_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_21] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_3,
+			PINCTRL_GRP_GPIO0_21,
+			PINCTRL_GRP_CAN1_5,
+			PINCTRL_GRP_I2C1_5,
+			PINCTRL_GRP_SWDT1_3_RST,
+			PINCTRL_GRP_SPI1_1_SS0,
+			PINCTRL_GRP_TTC1_2_WAV,
+			PINCTRL_GRP_UART1_5,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_0_0,
+			PINCTRL_GRP_SDIO0_4BIT_0_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_0,
+			PINCTRL_GRP_SDIO0_1BIT_0_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_2,
+			PINCTRL_GRP_SDIO0_1BIT_0_3,
+			PINCTRL_GRP_SDIO0_1BIT_0_4,
+			PINCTRL_GRP_SDIO0_1BIT_0_5,
+			PINCTRL_GRP_SDIO0_1BIT_0_6,
+			PINCTRL_GRP_SDIO0_1BIT_0_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_22] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_4,
+			PINCTRL_GRP_GPIO0_22,
+			PINCTRL_GRP_CAN0_5,
+			PINCTRL_GRP_I2C0_5,
+			PINCTRL_GRP_SWDT0_3_CLK,
+			PINCTRL_GRP_SPI1_1,
+			PINCTRL_GRP_TTC0_2_CLK,
+			PINCTRL_GRP_UART0_5,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_0_0,
+			PINCTRL_GRP_SDIO0_4BIT_0_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_0,
+			PINCTRL_GRP_SDIO0_1BIT_0_1,
+			PINCTRL_GRP_SDIO0_1BIT_0_2,
+			PINCTRL_GRP_SDIO0_1BIT_0_3,
+			PINCTRL_GRP_SDIO0_1BIT_0_4,
+			PINCTRL_GRP_SDIO0_1BIT_0_5,
+			PINCTRL_GRP_SDIO0_1BIT_0_6,
+			PINCTRL_GRP_SDIO0_1BIT_0_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_23] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0_PC,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_5,
+			PINCTRL_GRP_GPIO0_23,
+			PINCTRL_GRP_CAN0_5,
+			PINCTRL_GRP_I2C0_5,
+			PINCTRL_GRP_SWDT0_3_RST,
+			PINCTRL_GRP_SPI1_1,
+			PINCTRL_GRP_TTC0_2_WAV,
+			PINCTRL_GRP_UART0_5,
+			PINCTRL_GRP_RESERVED,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_24] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0_CD,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_6,
+			PINCTRL_GRP_GPIO0_24,
+			PINCTRL_GRP_CAN1_6,
+			PINCTRL_GRP_I2C1_6,
+			PINCTRL_GRP_SWDT1_4_CLK,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TTC3_3_CLK,
+			PINCTRL_GRP_UART1_6,
+			PINCTRL_GRP_RESERVED,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_25] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_NAND0_0,
+			PINCTRL_GRP_SDIO0_0_WP,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_7,
+			PINCTRL_GRP_GPIO0_25,
+			PINCTRL_GRP_CAN1_6,
+			PINCTRL_GRP_I2C1_6,
+			PINCTRL_GRP_SWDT1_4_RST,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_TTC3_3_WAV,
+			PINCTRL_GRP_UART1_6,
+			PINCTRL_GRP_RESERVED,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_26] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_GEMTSU0_0,
+			PINCTRL_GRP_NAND0_1_CE,
+			PINCTRL_GRP_PMU0_0,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_8,
+			PINCTRL_GRP_GPIO0_26,
+			PINCTRL_GRP_CAN0_6,
+			PINCTRL_GRP_I2C0_6,
+			PINCTRL_GRP_PJTAG0_2,
+			PINCTRL_GRP_SPI0_2,
+			PINCTRL_GRP_TTC2_3_CLK,
+			PINCTRL_GRP_UART0_6,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_27] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_NAND0_1_RB,
+			PINCTRL_GRP_PMU0_1,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_DPAUX0_0,
+			PINCTRL_GRP_GPIO0_27,
+			PINCTRL_GRP_CAN0_6,
+			PINCTRL_GRP_I2C0_6,
+			PINCTRL_GRP_PJTAG0_2,
+			PINCTRL_GRP_SPI0_2_SS2,
+			PINCTRL_GRP_TTC2_3_WAV,
+			PINCTRL_GRP_UART0_6,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_28] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_NAND0_1_RB,
+			PINCTRL_GRP_PMU0_2,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_DPAUX0_0,
+			PINCTRL_GRP_GPIO0_28,
+			PINCTRL_GRP_CAN1_7,
+			PINCTRL_GRP_I2C1_7,
+			PINCTRL_GRP_PJTAG0_2,
+			PINCTRL_GRP_SPI0_2_SS1,
+			PINCTRL_GRP_TTC1_3_CLK,
+			PINCTRL_GRP_UART1_7,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_29] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_PCIE0_0,
+			PINCTRL_GRP_PMU0_3,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_DPAUX0_1,
+			PINCTRL_GRP_GPIO0_29,
+			PINCTRL_GRP_CAN1_7,
+			PINCTRL_GRP_I2C1_7,
+			PINCTRL_GRP_PJTAG0_2,
+			PINCTRL_GRP_SPI0_2_SS0,
+			PINCTRL_GRP_TTC1_3_WAV,
+			PINCTRL_GRP_UART1_7,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_30] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_PCIE0_1,
+			PINCTRL_GRP_PMU0_4,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_DPAUX0_1,
+			PINCTRL_GRP_GPIO0_30,
+			PINCTRL_GRP_CAN0_7,
+			PINCTRL_GRP_I2C0_7,
+			PINCTRL_GRP_SWDT0_4_CLK,
+			PINCTRL_GRP_SPI0_2,
+			PINCTRL_GRP_TTC0_3_CLK,
+			PINCTRL_GRP_UART0_7,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_31] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_PCIE0_2,
+			PINCTRL_GRP_PMU0_5,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_9,
+			PINCTRL_GRP_GPIO0_31,
+			PINCTRL_GRP_CAN0_7,
+			PINCTRL_GRP_I2C0_7,
+			PINCTRL_GRP_SWDT0_4_RST,
+			PINCTRL_GRP_SPI0_2,
+			PINCTRL_GRP_TTC0_3_WAV,
+			PINCTRL_GRP_UART0_7,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_32] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_NAND0_1_DQS,
+			PINCTRL_GRP_PMU0_6,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_10,
+			PINCTRL_GRP_GPIO0_32,
+			PINCTRL_GRP_CAN1_8,
+			PINCTRL_GRP_I2C1_8,
+			PINCTRL_GRP_SWDT1_5_CLK,
+			PINCTRL_GRP_SPI1_2,
+			PINCTRL_GRP_TTC3_4_CLK,
+			PINCTRL_GRP_UART1_8,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_33] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_PCIE0_3,
+			PINCTRL_GRP_PMU0_7,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_CSU0_11,
+			PINCTRL_GRP_GPIO0_33,
+			PINCTRL_GRP_CAN1_8,
+			PINCTRL_GRP_I2C1_8,
+			PINCTRL_GRP_SWDT1_5_RST,
+			PINCTRL_GRP_SPI1_2_SS2,
+			PINCTRL_GRP_TTC3_4_WAV,
+			PINCTRL_GRP_UART1_8,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_34] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_PCIE0_4,
+			PINCTRL_GRP_PMU0_8,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_DPAUX0_2,
+			PINCTRL_GRP_GPIO0_34,
+			PINCTRL_GRP_CAN0_8,
+			PINCTRL_GRP_I2C0_8,
+			PINCTRL_GRP_SWDT0_5_CLK,
+			PINCTRL_GRP_SPI1_2_SS1,
+			PINCTRL_GRP_TTC2_4_CLK,
+			PINCTRL_GRP_UART0_8,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_35] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_PCIE0_5,
+			PINCTRL_GRP_PMU0_9,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_DPAUX0_2,
+			PINCTRL_GRP_GPIO0_35,
+			PINCTRL_GRP_CAN0_8,
+			PINCTRL_GRP_I2C0_8,
+			PINCTRL_GRP_SWDT0_5_RST,
+			PINCTRL_GRP_SPI1_2_SS0,
+			PINCTRL_GRP_TTC2_4_WAV,
+			PINCTRL_GRP_UART0_8,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_36] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_PCIE0_6,
+			PINCTRL_GRP_PMU0_10,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_DPAUX0_3,
+			PINCTRL_GRP_GPIO0_36,
+			PINCTRL_GRP_CAN1_9,
+			PINCTRL_GRP_I2C1_9,
+			PINCTRL_GRP_SWDT1_6_CLK,
+			PINCTRL_GRP_SPI1_2,
+			PINCTRL_GRP_TTC1_4_CLK,
+			PINCTRL_GRP_UART1_9,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_37] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET0_0,
+			PINCTRL_GRP_PCIE0_7,
+			PINCTRL_GRP_PMU0_11,
+			PINCTRL_GRP_TESTSCAN0_0,
+			PINCTRL_GRP_DPAUX0_3,
+			PINCTRL_GRP_GPIO0_37,
+			PINCTRL_GRP_CAN1_9,
+			PINCTRL_GRP_I2C1_9,
+			PINCTRL_GRP_SWDT1_6_RST,
+			PINCTRL_GRP_SPI1_2,
+			PINCTRL_GRP_TTC1_4_WAV,
+			PINCTRL_GRP_UART1_9,
+			PINCTRL_GRP_TRACE0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_38] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_38,
+			PINCTRL_GRP_CAN0_9,
+			PINCTRL_GRP_I2C0_9,
+			PINCTRL_GRP_PJTAG0_3,
+			PINCTRL_GRP_SPI0_3,
+			PINCTRL_GRP_TTC0_4_CLK,
+			PINCTRL_GRP_UART0_9,
+			PINCTRL_GRP_TRACE0_1_CLK,
+			PINCTRL_GRP_SDIO0_4BIT_1_0,
+			PINCTRL_GRP_SDIO0_4BIT_1_1,
+			PINCTRL_GRP_SDIO0_1BIT_1_0,
+			PINCTRL_GRP_SDIO0_1BIT_1_1,
+			PINCTRL_GRP_SDIO0_1BIT_1_2,
+			PINCTRL_GRP_SDIO0_1BIT_1_3,
+			PINCTRL_GRP_SDIO0_1BIT_1_4,
+			PINCTRL_GRP_SDIO0_1BIT_1_5,
+			PINCTRL_GRP_SDIO0_1BIT_1_6,
+			PINCTRL_GRP_SDIO0_1BIT_1_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_39] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1_CD,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_39,
+			PINCTRL_GRP_CAN0_9,
+			PINCTRL_GRP_I2C0_9,
+			PINCTRL_GRP_PJTAG0_3,
+			PINCTRL_GRP_SPI0_3_SS2,
+			PINCTRL_GRP_TTC0_4_WAV,
+			PINCTRL_GRP_UART0_9,
+			PINCTRL_GRP_TRACE0_1_CLK,
+			PINCTRL_GRP_SDIO1_4BIT_0_0,
+			PINCTRL_GRP_SDIO1_1BIT_0_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_40] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_40,
+			PINCTRL_GRP_CAN1_10,
+			PINCTRL_GRP_I2C1_10,
+			PINCTRL_GRP_PJTAG0_3,
+			PINCTRL_GRP_SPI0_3_SS1,
+			PINCTRL_GRP_TTC3_5_CLK,
+			PINCTRL_GRP_UART1_10,
+			PINCTRL_GRP_TRACE0_1,
+			PINCTRL_GRP_SDIO0_4BIT_1_0,
+			PINCTRL_GRP_SDIO0_4BIT_1_1,
+			PINCTRL_GRP_SDIO0_1BIT_1_0,
+			PINCTRL_GRP_SDIO0_1BIT_1_1,
+			PINCTRL_GRP_SDIO0_1BIT_1_2,
+			PINCTRL_GRP_SDIO0_1BIT_1_3,
+			PINCTRL_GRP_SDIO0_1BIT_1_4,
+			PINCTRL_GRP_SDIO0_1BIT_1_5,
+			PINCTRL_GRP_SDIO0_1BIT_1_6,
+			PINCTRL_GRP_SDIO0_1BIT_1_7,
+			PINCTRL_GRP_SDIO1_4BIT_0_0,
+			PINCTRL_GRP_SDIO1_1BIT_0_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_41] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_41,
+			PINCTRL_GRP_CAN1_10,
+			PINCTRL_GRP_I2C1_10,
+			PINCTRL_GRP_PJTAG0_3,
+			PINCTRL_GRP_SPI0_3_SS0,
+			PINCTRL_GRP_TTC3_5_WAV,
+			PINCTRL_GRP_UART1_10,
+			PINCTRL_GRP_TRACE0_1,
+			PINCTRL_GRP_SDIO0_4BIT_1_0,
+			PINCTRL_GRP_SDIO0_1BIT_1_0,
+			PINCTRL_GRP_SDIO1_4BIT_0_0,
+			PINCTRL_GRP_SDIO1_1BIT_0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_42] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_42,
+			PINCTRL_GRP_CAN0_10,
+			PINCTRL_GRP_I2C0_10,
+			PINCTRL_GRP_SWDT0_6_CLK,
+			PINCTRL_GRP_SPI0_3,
+			PINCTRL_GRP_TTC2_5_CLK,
+			PINCTRL_GRP_UART0_10,
+			PINCTRL_GRP_TRACE0_1,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO0_4BIT_1_0,
+			PINCTRL_GRP_SDIO0_1BIT_1_1,
+			PINCTRL_GRP_SDIO1_4BIT_0_0,
+			PINCTRL_GRP_SDIO1_1BIT_0_3,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_43] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO1_0_PC,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_43,
+			PINCTRL_GRP_CAN0_10,
+			PINCTRL_GRP_I2C0_10,
+			PINCTRL_GRP_SWDT0_6_RST,
+			PINCTRL_GRP_SPI0_3,
+			PINCTRL_GRP_TTC2_5_WAV,
+			PINCTRL_GRP_UART0_10,
+			PINCTRL_GRP_TRACE0_1,
+			PINCTRL_GRP_SDIO0_4BIT_1_0,
+			PINCTRL_GRP_SDIO0_1BIT_1_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_44] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO1_0_WP,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_44,
+			PINCTRL_GRP_CAN1_11,
+			PINCTRL_GRP_I2C1_11,
+			PINCTRL_GRP_SWDT1_7_CLK,
+			PINCTRL_GRP_SPI1_3,
+			PINCTRL_GRP_TTC1_5_CLK,
+			PINCTRL_GRP_UART1_11,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_1_0,
+			PINCTRL_GRP_SDIO0_1BIT_1_3,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_45] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO1_0_CD,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_45,
+			PINCTRL_GRP_CAN1_11,
+			PINCTRL_GRP_I2C1_11,
+			PINCTRL_GRP_SWDT1_7_RST,
+			PINCTRL_GRP_SPI1_3_SS2,
+			PINCTRL_GRP_TTC1_5_WAV,
+			PINCTRL_GRP_UART1_11,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_1_1,
+			PINCTRL_GRP_SDIO0_1BIT_1_4,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_46] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_46,
+			PINCTRL_GRP_CAN0_11,
+			PINCTRL_GRP_I2C0_11,
+			PINCTRL_GRP_SWDT0_7_CLK,
+			PINCTRL_GRP_SPI1_3_SS1,
+			PINCTRL_GRP_TTC0_5_CLK,
+			PINCTRL_GRP_UART0_11,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_1_1,
+			PINCTRL_GRP_SDIO0_1BIT_1_5,
+			PINCTRL_GRP_SDIO1_4BIT_0_1,
+			PINCTRL_GRP_SDIO1_1BIT_0_4,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_47] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_47,
+			PINCTRL_GRP_CAN0_11,
+			PINCTRL_GRP_I2C0_11,
+			PINCTRL_GRP_SWDT0_7_RST,
+			PINCTRL_GRP_SPI1_3_SS0,
+			PINCTRL_GRP_TTC0_5_WAV,
+			PINCTRL_GRP_UART0_11,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_1_1,
+			PINCTRL_GRP_SDIO0_1BIT_1_6,
+			PINCTRL_GRP_SDIO1_4BIT_0_1,
+			PINCTRL_GRP_SDIO1_1BIT_0_5,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_48] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_48,
+			PINCTRL_GRP_CAN1_12,
+			PINCTRL_GRP_I2C1_12,
+			PINCTRL_GRP_SWDT1_8_CLK,
+			PINCTRL_GRP_SPI1_3,
+			PINCTRL_GRP_TTC3_6_CLK,
+			PINCTRL_GRP_UART1_12,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_1_1,
+			PINCTRL_GRP_SDIO0_1BIT_1_7,
+			PINCTRL_GRP_SDIO1_4BIT_0_1,
+			PINCTRL_GRP_SDIO1_1BIT_0_6,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_49] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1_PC,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_49,
+			PINCTRL_GRP_CAN1_12,
+			PINCTRL_GRP_I2C1_12,
+			PINCTRL_GRP_SWDT1_8_RST,
+			PINCTRL_GRP_SPI1_3,
+			PINCTRL_GRP_TTC3_6_WAV,
+			PINCTRL_GRP_UART1_12,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO1_4BIT_0_1,
+			PINCTRL_GRP_SDIO1_1BIT_0_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_50] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_GEMTSU0_1,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_1_WP,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_50,
+			PINCTRL_GRP_CAN0_12,
+			PINCTRL_GRP_I2C0_12,
+			PINCTRL_GRP_SWDT0_8_CLK,
+			PINCTRL_GRP_MDIO1_0,
+			PINCTRL_GRP_TTC2_6_CLK,
+			PINCTRL_GRP_UART0_12,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO1_4BIT_0_0,
+			PINCTRL_GRP_SDIO1_4BIT_0_1,
+			PINCTRL_GRP_SDIO1_1BIT_0_0,
+			PINCTRL_GRP_SDIO1_1BIT_0_1,
+			PINCTRL_GRP_SDIO1_1BIT_0_2,
+			PINCTRL_GRP_SDIO1_1BIT_0_3,
+			PINCTRL_GRP_SDIO1_1BIT_0_4,
+			PINCTRL_GRP_SDIO1_1BIT_0_5,
+			PINCTRL_GRP_SDIO1_1BIT_0_6,
+			PINCTRL_GRP_SDIO1_1BIT_0_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_51] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_GEMTSU0_2,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_51,
+			PINCTRL_GRP_CAN0_12,
+			PINCTRL_GRP_I2C0_12,
+			PINCTRL_GRP_SWDT0_8_RST,
+			PINCTRL_GRP_MDIO1_0,
+			PINCTRL_GRP_TTC2_6_WAV,
+			PINCTRL_GRP_UART0_12,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO1_4BIT_0_0,
+			PINCTRL_GRP_SDIO1_4BIT_0_1,
+			PINCTRL_GRP_SDIO1_1BIT_0_0,
+			PINCTRL_GRP_SDIO1_1BIT_0_1,
+			PINCTRL_GRP_SDIO1_1BIT_0_2,
+			PINCTRL_GRP_SDIO1_1BIT_0_3,
+			PINCTRL_GRP_SDIO1_1BIT_0_4,
+			PINCTRL_GRP_SDIO1_1BIT_0_5,
+			PINCTRL_GRP_SDIO1_1BIT_0_6,
+			PINCTRL_GRP_SDIO1_1BIT_0_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_52] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_52,
+			PINCTRL_GRP_CAN1_13,
+			PINCTRL_GRP_I2C1_13,
+			PINCTRL_GRP_PJTAG0_4,
+			PINCTRL_GRP_SPI0_4,
+			PINCTRL_GRP_TTC1_6_CLK,
+			PINCTRL_GRP_UART1_13,
+			PINCTRL_GRP_TRACE0_2_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_53] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_53,
+			PINCTRL_GRP_CAN1_13,
+			PINCTRL_GRP_I2C1_13,
+			PINCTRL_GRP_PJTAG0_4,
+			PINCTRL_GRP_SPI0_4_SS2,
+			PINCTRL_GRP_TTC1_6_WAV,
+			PINCTRL_GRP_UART1_13,
+			PINCTRL_GRP_TRACE0_2_CLK,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_54] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_54,
+			PINCTRL_GRP_CAN0_13,
+			PINCTRL_GRP_I2C0_13,
+			PINCTRL_GRP_PJTAG0_4,
+			PINCTRL_GRP_SPI0_4_SS1,
+			PINCTRL_GRP_TTC0_6_CLK,
+			PINCTRL_GRP_UART0_13,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_55] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_55,
+			PINCTRL_GRP_CAN0_13,
+			PINCTRL_GRP_I2C0_13,
+			PINCTRL_GRP_PJTAG0_4,
+			PINCTRL_GRP_SPI0_4_SS0,
+			PINCTRL_GRP_TTC0_6_WAV,
+			PINCTRL_GRP_UART0_13,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_56] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_56,
+			PINCTRL_GRP_CAN1_14,
+			PINCTRL_GRP_I2C1_14,
+			PINCTRL_GRP_SWDT1_9_CLK,
+			PINCTRL_GRP_SPI0_4,
+			PINCTRL_GRP_TTC3_7_CLK,
+			PINCTRL_GRP_UART1_14,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_57] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_57,
+			PINCTRL_GRP_CAN1_14,
+			PINCTRL_GRP_I2C1_14,
+			PINCTRL_GRP_SWDT1_9_RST,
+			PINCTRL_GRP_SPI0_4,
+			PINCTRL_GRP_TTC3_7_WAV,
+			PINCTRL_GRP_UART1_14,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_58] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_58,
+			PINCTRL_GRP_CAN0_14,
+			PINCTRL_GRP_I2C0_14,
+			PINCTRL_GRP_PJTAG0_5,
+			PINCTRL_GRP_SPI1_4,
+			PINCTRL_GRP_TTC2_7_CLK,
+			PINCTRL_GRP_UART0_14,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_59] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_59,
+			PINCTRL_GRP_CAN0_14,
+			PINCTRL_GRP_I2C0_14,
+			PINCTRL_GRP_PJTAG0_5,
+			PINCTRL_GRP_SPI1_4_SS2,
+			PINCTRL_GRP_TTC2_7_WAV,
+			PINCTRL_GRP_UART0_14,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_60] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_60,
+			PINCTRL_GRP_CAN1_15,
+			PINCTRL_GRP_I2C1_15,
+			PINCTRL_GRP_PJTAG0_5,
+			PINCTRL_GRP_SPI1_4_SS1,
+			PINCTRL_GRP_TTC1_7_CLK,
+			PINCTRL_GRP_UART1_15,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_61] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_61,
+			PINCTRL_GRP_CAN1_15,
+			PINCTRL_GRP_I2C1_15,
+			PINCTRL_GRP_PJTAG0_5,
+			PINCTRL_GRP_SPI1_4_SS0,
+			PINCTRL_GRP_TTC1_7_WAV,
+			PINCTRL_GRP_UART1_15,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_62] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_62,
+			PINCTRL_GRP_CAN0_15,
+			PINCTRL_GRP_I2C0_15,
+			PINCTRL_GRP_SWDT0_9_CLK,
+			PINCTRL_GRP_SPI1_4,
+			PINCTRL_GRP_TTC0_7_CLK,
+			PINCTRL_GRP_UART0_15,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_63] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET2_0,
+			PINCTRL_GRP_USB0_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_63,
+			PINCTRL_GRP_CAN0_15,
+			PINCTRL_GRP_I2C0_15,
+			PINCTRL_GRP_SWDT0_9_RST,
+			PINCTRL_GRP_SPI1_4,
+			PINCTRL_GRP_TTC0_7_WAV,
+			PINCTRL_GRP_UART0_15,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_64] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_64,
+			PINCTRL_GRP_CAN1_16,
+			PINCTRL_GRP_I2C1_16,
+			PINCTRL_GRP_SWDT1_10_CLK,
+			PINCTRL_GRP_SPI0_5,
+			PINCTRL_GRP_TTC3_8_CLK,
+			PINCTRL_GRP_UART1_16,
+			PINCTRL_GRP_TRACE0_2,
+			PINCTRL_GRP_SDIO0_4BIT_2_0,
+			PINCTRL_GRP_SDIO0_4BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_2_0,
+			PINCTRL_GRP_SDIO0_1BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_2_2,
+			PINCTRL_GRP_SDIO0_1BIT_2_3,
+			PINCTRL_GRP_SDIO0_1BIT_2_4,
+			PINCTRL_GRP_SDIO0_1BIT_2_5,
+			PINCTRL_GRP_SDIO0_1BIT_2_6,
+			PINCTRL_GRP_SDIO0_1BIT_2_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_65] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2_CD,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_65,
+			PINCTRL_GRP_CAN1_16,
+			PINCTRL_GRP_I2C1_16,
+			PINCTRL_GRP_SWDT1_10_RST,
+			PINCTRL_GRP_SPI0_5_SS2,
+			PINCTRL_GRP_TTC3_8_WAV,
+			PINCTRL_GRP_UART1_16,
+			PINCTRL_GRP_TRACE0_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_66] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_66,
+			PINCTRL_GRP_CAN0_16,
+			PINCTRL_GRP_I2C0_16,
+			PINCTRL_GRP_SWDT0_10_CLK,
+			PINCTRL_GRP_SPI0_5_SS1,
+			PINCTRL_GRP_TTC2_8_CLK,
+			PINCTRL_GRP_UART0_16,
+			PINCTRL_GRP_TRACE0_2,
+			PINCTRL_GRP_SDIO0_4BIT_2_0,
+			PINCTRL_GRP_SDIO0_4BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_2_0,
+			PINCTRL_GRP_SDIO0_1BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_2_2,
+			PINCTRL_GRP_SDIO0_1BIT_2_3,
+			PINCTRL_GRP_SDIO0_1BIT_2_4,
+			PINCTRL_GRP_SDIO0_1BIT_2_5,
+			PINCTRL_GRP_SDIO0_1BIT_2_6,
+			PINCTRL_GRP_SDIO0_1BIT_2_7,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_67] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_67,
+			PINCTRL_GRP_CAN0_16,
+			PINCTRL_GRP_I2C0_16,
+			PINCTRL_GRP_SWDT0_10_RST,
+			PINCTRL_GRP_SPI0_5_SS0,
+			PINCTRL_GRP_TTC2_8_WAV,
+			PINCTRL_GRP_UART0_16,
+			PINCTRL_GRP_TRACE0_2,
+			PINCTRL_GRP_SDIO0_4BIT_2_0,
+			PINCTRL_GRP_SDIO0_1BIT_2_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_68] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_68,
+			PINCTRL_GRP_CAN1_17,
+			PINCTRL_GRP_I2C1_17,
+			PINCTRL_GRP_SWDT1_11_CLK,
+			PINCTRL_GRP_SPI0_5,
+			PINCTRL_GRP_TTC1_8_CLK,
+			PINCTRL_GRP_UART1_17,
+			PINCTRL_GRP_TRACE0_2,
+			PINCTRL_GRP_SDIO0_4BIT_2_0,
+			PINCTRL_GRP_SDIO0_1BIT_2_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_69] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_SDIO1_1_WP,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_69,
+			PINCTRL_GRP_CAN1_17,
+			PINCTRL_GRP_I2C1_17,
+			PINCTRL_GRP_SWDT1_11_RST,
+			PINCTRL_GRP_SPI0_5,
+			PINCTRL_GRP_TTC1_8_WAV,
+			PINCTRL_GRP_UART1_17,
+			PINCTRL_GRP_TRACE0_2,
+			PINCTRL_GRP_SDIO0_4BIT_2_0,
+			PINCTRL_GRP_SDIO0_1BIT_2_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_70] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_SDIO1_1_PC,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_70,
+			PINCTRL_GRP_CAN0_17,
+			PINCTRL_GRP_I2C0_17,
+			PINCTRL_GRP_SWDT0_11_CLK,
+			PINCTRL_GRP_SPI1_5,
+			PINCTRL_GRP_TTC0_8_CLK,
+			PINCTRL_GRP_UART0_17,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_2_0,
+			PINCTRL_GRP_SDIO0_1BIT_2_3,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_71] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_SDIO1_4BIT_1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_71,
+			PINCTRL_GRP_CAN0_17,
+			PINCTRL_GRP_I2C0_17,
+			PINCTRL_GRP_SWDT0_11_RST,
+			PINCTRL_GRP_SPI1_5_SS2,
+			PINCTRL_GRP_TTC0_8_WAV,
+			PINCTRL_GRP_UART0_17,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_SDIO0_4BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_2_4,
+			PINCTRL_GRP_SDIO1_1BIT_1_0,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_72] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_SDIO1_4BIT_1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_72,
+			PINCTRL_GRP_CAN1_18,
+			PINCTRL_GRP_I2C1_18,
+			PINCTRL_GRP_SWDT1_12_CLK,
+			PINCTRL_GRP_SPI1_5_SS1,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_UART1_18,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_2_5,
+			PINCTRL_GRP_SDIO1_1BIT_1_1,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_73] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_SDIO1_4BIT_1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_73,
+			PINCTRL_GRP_CAN1_18,
+			PINCTRL_GRP_I2C1_18,
+			PINCTRL_GRP_SWDT1_12_RST,
+			PINCTRL_GRP_SPI1_5_SS0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_UART1_18,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_2_6,
+			PINCTRL_GRP_SDIO1_1BIT_1_2,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_74] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2,
+			PINCTRL_GRP_SDIO1_4BIT_1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_74,
+			PINCTRL_GRP_CAN0_18,
+			PINCTRL_GRP_I2C0_18,
+			PINCTRL_GRP_SWDT0_12_CLK,
+			PINCTRL_GRP_SPI1_5,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_UART0_18,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_4BIT_2_1,
+			PINCTRL_GRP_SDIO0_1BIT_2_7,
+			PINCTRL_GRP_SDIO1_1BIT_1_3,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_75] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_ETHERNET3_0,
+			PINCTRL_GRP_USB1_0,
+			PINCTRL_GRP_SDIO0_2_PC,
+			PINCTRL_GRP_SDIO1_4BIT_1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_75,
+			PINCTRL_GRP_CAN0_18,
+			PINCTRL_GRP_I2C0_18,
+			PINCTRL_GRP_SWDT0_12_RST,
+			PINCTRL_GRP_SPI1_5,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_UART0_18,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO1_1BIT_1_0,
+			PINCTRL_GRP_SDIO1_1BIT_1_1,
+			PINCTRL_GRP_SDIO1_1BIT_1_2,
+			PINCTRL_GRP_SDIO1_1BIT_1_3,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_76] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO0_2_WP,
+			PINCTRL_GRP_SDIO1_4BIT_1_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_76,
+			PINCTRL_GRP_CAN1_19,
+			PINCTRL_GRP_I2C1_19,
+			PINCTRL_GRP_MDIO0_0,
+			PINCTRL_GRP_MDIO1_1,
+			PINCTRL_GRP_MDIO2_0,
+			PINCTRL_GRP_MDIO3_0,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO1_1BIT_1_0,
+			PINCTRL_GRP_SDIO1_1BIT_1_1,
+			PINCTRL_GRP_SDIO1_1BIT_1_2,
+			PINCTRL_GRP_SDIO1_1BIT_1_3,
+			END_OF_GROUPS,
+		}),
+	},
+	[PINCTRL_PIN_77] = {
+		.groups = &((uint16_t []) {
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_SDIO1_1_CD,
+			PINCTRL_GRP_RESERVED,
+			PINCTRL_GRP_GPIO0_77,
+			PINCTRL_GRP_CAN1_19,
+			PINCTRL_GRP_I2C1_19,
+			PINCTRL_GRP_MDIO0_0,
+			PINCTRL_GRP_MDIO1_1,
+			PINCTRL_GRP_MDIO2_0,
+			PINCTRL_GRP_MDIO3_0,
+			PINCTRL_GRP_RESERVED,
+			END_OF_GROUPS,
+		}),
+	},
+};
+
+/**
+ * pm_api_pinctrl_get_num_pins() - PM call to request number of pins
+ * @npins	Number of pins
+ *
+ * This function is used by master to get number of pins
+ *
+ * @return	Returns success.
+ */
+enum pm_ret_status pm_api_pinctrl_get_num_pins(unsigned int *npins)
+{
+	*npins = MAX_PIN;
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_num_functions() - PM call to request number of functions
+ * @nfuncs	Number of functions
+ *
+ * This function is used by master to get number of functions
+ *
+ * @return	Returns success.
+ */
+enum pm_ret_status pm_api_pinctrl_get_num_functions(unsigned int *nfuncs)
+{
+	*nfuncs = MAX_FUNCTION;
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_num_func_groups() - PM call to request number of
+ *					  function groups
+ * @fid		Function Id
+ * @ngroups	Number of function groups
+ *
+ * This function is used by master to get number of function groups
+ *
+ * @return	Returns success.
+ */
+enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid,
+						      unsigned int *ngroups)
+{
+	int i = 0;
+	uint16_t *grps;
+
+	if (fid >= MAX_FUNCTION)
+		return PM_RET_ERROR_ARGS;
+
+	*ngroups = 0;
+
+	grps = *pinctrl_functions[fid].groups;
+	if (grps == NULL)
+		return PM_RET_SUCCESS;
+
+	while (grps[i++] != (uint16_t)END_OF_GROUPS)
+		(*ngroups)++;
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_function_name() - PM call to request a function name
+ * @fid		Function ID
+ * @name	Name of function (max 16 bytes)
+ *
+ * This function is used by master to get name of function specified
+ * by given function ID.
+ *
+ * @return	Returns success. In case of error, name data is 0.
+ */
+enum pm_ret_status pm_api_pinctrl_get_function_name(unsigned int fid,
+						    char *name)
+{
+	if (fid >= MAX_FUNCTION)
+		memcpy(name, END_OF_FUNCTION, FUNCTION_NAME_LEN);
+	else
+		memcpy(name, pinctrl_functions[fid].name, FUNCTION_NAME_LEN);
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_function_groups() - PM call to request first 6 function
+ *					  groups of function Id
+ * @fid		Function ID
+ * @index	Index of next function groups
+ * @groups	Function groups
+ *
+ * This function is used by master to get function groups specified
+ * by given function Id. This API will return 6 function groups with
+ * a single response. To get other function groups, master should call
+ * same API in loop with new function groups index till error is returned.
+ *
+ * E.g First call should have index 0 which will return function groups
+ * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
+ * function groups 6, 7, 8, 9, 10 and 11 and so on.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid,
+						      unsigned int index,
+						      uint16_t *groups)
+{
+	unsigned int i;
+	uint16_t *grps;
+
+	if (fid >= MAX_FUNCTION)
+		return PM_RET_ERROR_ARGS;
+
+	memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
+
+	grps = *pinctrl_functions[fid].groups;
+	if (grps == NULL)
+		return PM_RET_SUCCESS;
+
+	/* Skip groups till index */
+	for (i = 0; i < index; i++)
+		if (grps[i] == (uint16_t)END_OF_GROUPS)
+			return PM_RET_SUCCESS;
+
+	for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
+		groups[i] = grps[index + i];
+		if (groups[i] == (uint16_t)END_OF_GROUPS)
+			break;
+	}
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_pin_groups() - PM call to request first 6 pin
+ *				     groups of pin
+ * @pin		Pin
+ * @index	Index of next pin groups
+ * @groups	pin groups
+ *
+ * This function is used by master to get pin groups specified
+ * by given pin Id. This API will return 6 pin groups with
+ * a single response. To get other pin groups, master should call
+ * same API in loop with new pin groups index till error is returned.
+ *
+ * E.g First call should have index 0 which will return pin groups
+ * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
+ * pin groups 6, 7, 8, 9, 10 and 11 and so on.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin,
+						 unsigned int index,
+						 uint16_t *groups)
+{
+	unsigned int i;
+	uint16_t *grps;
+
+	if (pin >= MAX_PIN)
+		return PM_RET_ERROR_ARGS;
+
+	memset(groups, END_OF_GROUPS, GROUPS_PAYLOAD_LEN);
+
+	grps = *zynqmp_pin_groups[pin].groups;
+	if (!grps)
+		return PM_RET_SUCCESS;
+
+	/* Skip groups till index */
+	for (i = 0; i < index; i++)
+		if (grps[i] == (uint16_t)END_OF_GROUPS)
+			return PM_RET_SUCCESS;
+
+	for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
+		groups[i] = grps[index + i];
+		if (groups[i] == (uint16_t)END_OF_GROUPS)
+			break;
+	}
+
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_api_pinctrl_get_function() - Read function id set for the given pin
+ * @pin		Pin number
+ * @nid		Node ID of function currently set for given pin
+ *
+ * This function provides the function currently set for the given pin.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_pinctrl_get_function(unsigned int pin,
+					       unsigned int *id)
+{
+	unsigned int i = 0, j = 0;
+	enum pm_ret_status ret = PM_RET_SUCCESS;
+	unsigned int ctrlreg, val, gid;
+	uint16_t *grps;
+
+	ctrlreg = IOU_SLCR_BASEADDR + 4U * pin;
+	ret = pm_mmio_read(ctrlreg, &val);
+	if (ret != PM_RET_SUCCESS)
+		return ret;
+
+	val &= PINCTRL_FUNCTION_MASK;
+
+	for (i = 0; i < NFUNCS_PER_PIN; i++)
+		if (val == pm_pinctrl_mux[i])
+			break;
+
+	if (i == NFUNCS_PER_PIN)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	gid = *(*zynqmp_pin_groups[pin].groups + i);
+
+	for (i = 0; i < MAX_FUNCTION; i++) {
+		grps = *pinctrl_functions[i].groups;
+		if (grps == NULL)
+			continue;
+		if (val != pinctrl_functions[i].regval)
+			continue;
+
+		for (j = 0; grps[j] != (uint16_t)END_OF_GROUPS; j++) {
+			if (gid == grps[j]) {
+				*id = i;
+				goto done;
+			}
+		}
+	}
+	if (i == MAX_FUNCTION)
+		ret = PM_RET_ERROR_ARGS;
+done:
+	return ret;
+}
+
+/**
+ * pm_api_pinctrl_set_function() - Set function id set for the given pin
+ * @pin		Pin number
+ * @nid		Node ID of function to set for given pin
+ *
+ * This function provides the function currently set for the given pin.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_pinctrl_set_function(unsigned int pin,
+					       unsigned int fid)
+{
+	int i, j;
+	unsigned int ctrlreg, val;
+	uint16_t *pgrps, *fgrps;
+
+	ctrlreg = IOU_SLCR_BASEADDR + 4U * pin;
+	val = pinctrl_functions[fid].regval;
+
+	for (i = 0; i < NFUNCS_PER_PIN; i++)
+		if (val == pm_pinctrl_mux[i])
+			break;
+
+	if (i == NFUNCS_PER_PIN)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	pgrps = *zynqmp_pin_groups[pin].groups;
+	if (!pgrps)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	fgrps = *pinctrl_functions[fid].groups;
+	if (!fgrps)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	for (i = 0; fgrps[i] != (uint16_t)END_OF_GROUPS; i++)
+		for (j = 0; pgrps[j] != (uint16_t)END_OF_GROUPS; j++)
+			if (fgrps[i] == pgrps[j])
+				goto match;
+
+	return PM_RET_ERROR_NOTSUPPORTED;
+
+match:
+	return pm_mmio_write(ctrlreg, PINCTRL_FUNCTION_MASK, val);
+}
+
+/**
+ * pm_api_pinctrl_set_config() - Set configuration parameter for given pin
+ * @pin: Pin for which configuration is to be set
+ * @param: Configuration parameter to be set
+ * @value: Value to be set for configuration parameter
+ *
+ * This function sets value of requested configuration parameter for given pin.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin,
+					     unsigned int param,
+					     unsigned int value)
+{
+	enum pm_ret_status ret;
+	unsigned int ctrlreg, mask, val, offset;
+
+	if (param >= PINCTRL_CONFIG_MAX)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (pin >=  PINCTRL_NUM_MIOS)
+		return PM_RET_ERROR_ARGS;
+
+	mask = 1 << PINCTRL_PIN_OFFSET(pin);
+
+	switch (param) {
+	case PINCTRL_CONFIG_SLEW_RATE:
+		if (value != PINCTRL_SLEW_RATE_FAST &&
+		    value != PINCTRL_SLEW_RATE_SLOW)
+			return PM_RET_ERROR_ARGS;
+
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_SLEWCTRL_REG_OFFSET,
+					      pin);
+		val = value << PINCTRL_PIN_OFFSET(pin);
+		ret = pm_mmio_write(ctrlreg, mask, val);
+		break;
+	case PINCTRL_CONFIG_BIAS_STATUS:
+		if (value != PINCTRL_BIAS_ENABLE &&
+		    value != PINCTRL_BIAS_DISABLE)
+			return PM_RET_ERROR_ARGS;
+
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_PULLSTAT_REG_OFFSET,
+					      pin);
+
+		offset = PINCTRL_PIN_OFFSET(pin);
+		if (ctrlreg == IOU_SLCR_BANK1_CTRL5)
+			offset = (offset < 12U) ?
+					(offset + 14U) : (offset - 12U);
+
+		val = value << offset;
+		mask = 1 << offset;
+		ret = pm_mmio_write(ctrlreg, mask, val);
+		break;
+	case PINCTRL_CONFIG_PULL_CTRL:
+
+		if (value != PINCTRL_BIAS_PULL_DOWN &&
+		    value != PINCTRL_BIAS_PULL_UP)
+			return PM_RET_ERROR_ARGS;
+
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_PULLSTAT_REG_OFFSET,
+					      pin);
+
+		offset = PINCTRL_PIN_OFFSET(pin);
+		if (ctrlreg == IOU_SLCR_BANK1_CTRL5)
+			offset = (offset < 12U) ?
+					(offset + 14U) : (offset - 12U);
+
+		val = PINCTRL_BIAS_ENABLE << offset;
+		ret = pm_mmio_write(ctrlreg, 1 << offset, val);
+		if (ret != PM_RET_SUCCESS)
+			return ret;
+
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_PULLCTRL_REG_OFFSET,
+					      pin);
+		val = value << PINCTRL_PIN_OFFSET(pin);
+		ret = pm_mmio_write(ctrlreg, mask, val);
+		break;
+	case PINCTRL_CONFIG_SCHMITT_CMOS:
+		if (value != PINCTRL_INPUT_TYPE_CMOS &&
+		    value != PINCTRL_INPUT_TYPE_SCHMITT)
+			return PM_RET_ERROR_ARGS;
+
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_SCHCMOS_REG_OFFSET,
+					      pin);
+
+		val = value << PINCTRL_PIN_OFFSET(pin);
+		ret = pm_mmio_write(ctrlreg, mask, val);
+		break;
+	case PINCTRL_CONFIG_DRIVE_STRENGTH:
+		if (value > PINCTRL_DRIVE_STRENGTH_12MA)
+			return PM_RET_ERROR_ARGS;
+
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_DRVSTRN0_REG_OFFSET,
+					      pin);
+		val = (value >> 1) << PINCTRL_PIN_OFFSET(pin);
+		ret = pm_mmio_write(ctrlreg, mask, val);
+		if (ret)
+			return ret;
+
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_DRVSTRN1_REG_OFFSET,
+					      pin);
+		val = (value & 0x01U) << PINCTRL_PIN_OFFSET(pin);
+		ret = pm_mmio_write(ctrlreg, mask, val);
+		break;
+	default:
+		ERROR("Invalid parameter %u\n", param);
+		ret = PM_RET_ERROR_NOTSUPPORTED;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * pm_api_pinctrl_get_config() - Get configuration parameter value for given pin
+ * @pin: Pin for which configuration is to be read
+ * @param: Configuration parameter to be read
+ * @value: buffer to store value of configuration parameter
+ *
+ * This function reads value of requested configuration parameter for given pin.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_api_pinctrl_get_config(unsigned int pin,
+					     unsigned int param,
+					     unsigned int *value)
+{
+	enum pm_ret_status ret;
+	unsigned int ctrlreg, val;
+
+	if (param >= PINCTRL_CONFIG_MAX)
+		return PM_RET_ERROR_NOTSUPPORTED;
+
+	if (pin >=  PINCTRL_NUM_MIOS)
+		return PM_RET_ERROR_ARGS;
+
+	switch (param) {
+	case PINCTRL_CONFIG_SLEW_RATE:
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_SLEWCTRL_REG_OFFSET,
+					      pin);
+
+		ret = pm_mmio_read(ctrlreg, &val);
+		if (ret != PM_RET_SUCCESS)
+			return ret;
+
+		*value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+		break;
+	case PINCTRL_CONFIG_BIAS_STATUS:
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_PULLSTAT_REG_OFFSET,
+					      pin);
+
+		ret = pm_mmio_read(ctrlreg, &val);
+		if (ret)
+			return ret;
+
+		if (ctrlreg == IOU_SLCR_BANK1_CTRL5)
+			val = ((val & 0x3FFF) << 12) | ((val >> 14) & 0xFFF);
+
+		*value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+		break;
+	case PINCTRL_CONFIG_PULL_CTRL:
+
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_PULLCTRL_REG_OFFSET,
+					      pin);
+
+		ret = pm_mmio_read(ctrlreg, &val);
+		if (ret)
+			return ret;
+
+		*value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+		break;
+	case PINCTRL_CONFIG_SCHMITT_CMOS:
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_SCHCMOS_REG_OFFSET,
+					      pin);
+
+		ret = pm_mmio_read(ctrlreg, &val);
+		if (ret)
+			return ret;
+
+		*value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+		break;
+	case PINCTRL_CONFIG_DRIVE_STRENGTH:
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_DRVSTRN0_REG_OFFSET,
+					      pin);
+		ret = pm_mmio_read(ctrlreg, &val);
+		if (ret)
+			return ret;
+
+		*value = PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val) << 1;
+
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_DRVSTRN1_REG_OFFSET,
+					      pin);
+		ret = pm_mmio_read(ctrlreg, &val);
+		if (ret)
+			return ret;
+
+		*value |= PINCTRL_REGVAL_TO_PIN_CONFIG(pin, val);
+		break;
+	case PINCTRL_CONFIG_VOLTAGE_STATUS:
+		ctrlreg = PINCTRL_CFG_ADDR_OFFSET(IOU_SLCR_BASEADDR,
+					      PINCTRL_VOLTAGE_STAT_REG_OFFSET,
+					      pin);
+
+		ret = pm_mmio_read(ctrlreg, &val);
+		if (ret)
+			return ret;
+
+		*value = val & PINCTRL_VOLTAGE_STATUS_MASK;
+		break;
+	default:
+		return PM_RET_ERROR_NOTSUPPORTED;
+	}
+
+	return PM_RET_SUCCESS;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
new file mode 100644
index 0000000..c70a774
--- /dev/null
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.h
@@ -0,0 +1,734 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ZynqMP system level PM-API functions for pin control.
+ */
+
+#ifndef _PM_API_PINCTRL_H_
+#define _PM_API_PINCTRL_H_
+
+#include "pm_common.h"
+
+#define FUNCTION_NAME_LEN		U(16)
+#define GROUPS_PAYLOAD_LEN		U(12)
+#define NUM_GROUPS_PER_RESP		U(6)
+#define END_OF_FUNCTION			"END_OF_FUNCTION"
+#define END_OF_GROUPS			-1
+#define PINCTRL_GRP_RESERVED		-2
+
+//pinctrl function ids
+enum {
+	PINCTRL_FUNC_CAN0,
+	PINCTRL_FUNC_CAN1,
+	PINCTRL_FUNC_ETHERNET0,
+	PINCTRL_FUNC_ETHERNET1,
+	PINCTRL_FUNC_ETHERNET2,
+	PINCTRL_FUNC_ETHERNET3,
+	PINCTRL_FUNC_GEMTSU0,
+	PINCTRL_FUNC_GPIO0,
+	PINCTRL_FUNC_I2C0,
+	PINCTRL_FUNC_I2C1,
+	PINCTRL_FUNC_MDIO0,
+	PINCTRL_FUNC_MDIO1,
+	PINCTRL_FUNC_MDIO2,
+	PINCTRL_FUNC_MDIO3,
+	PINCTRL_FUNC_QSPI0,
+	PINCTRL_FUNC_QSPI_FBCLK,
+	PINCTRL_FUNC_QSPI_SS,
+	PINCTRL_FUNC_SPI0,
+	PINCTRL_FUNC_SPI1,
+	PINCTRL_FUNC_SPI0_SS,
+	PINCTRL_FUNC_SPI1_SS,
+	PINCTRL_FUNC_SDIO0,
+	PINCTRL_FUNC_SDIO0_PC,
+	PINCTRL_FUNC_SDIO0_CD,
+	PINCTRL_FUNC_SDIO0_WP,
+	PINCTRL_FUNC_SDIO1,
+	PINCTRL_FUNC_SDIO1_PC,
+	PINCTRL_FUNC_SDIO1_CD,
+	PINCTRL_FUNC_SDIO1_WP,
+	PINCTRL_FUNC_NAND0,
+	PINCTRL_FUNC_NAND0_CE,
+	PINCTRL_FUNC_NAND0_RB,
+	PINCTRL_FUNC_NAND0_DQS,
+	PINCTRL_FUNC_TTC0_CLK,
+	PINCTRL_FUNC_TTC0_WAV,
+	PINCTRL_FUNC_TTC1_CLK,
+	PINCTRL_FUNC_TTC1_WAV,
+	PINCTRL_FUNC_TTC2_CLK,
+	PINCTRL_FUNC_TTC2_WAV,
+	PINCTRL_FUNC_TTC3_CLK,
+	PINCTRL_FUNC_TTC3_WAV,
+	PINCTRL_FUNC_UART0,
+	PINCTRL_FUNC_UART1,
+	PINCTRL_FUNC_USB0,
+	PINCTRL_FUNC_USB1,
+	PINCTRL_FUNC_SWDT0_CLK,
+	PINCTRL_FUNC_SWDT0_RST,
+	PINCTRL_FUNC_SWDT1_CLK,
+	PINCTRL_FUNC_SWDT1_RST,
+	PINCTRL_FUNC_PMU0,
+	PINCTRL_FUNC_PCIE0,
+	PINCTRL_FUNC_CSU0,
+	PINCTRL_FUNC_DPAUX0,
+	PINCTRL_FUNC_PJTAG0,
+	PINCTRL_FUNC_TRACE0,
+	PINCTRL_FUNC_TRACE0_CLK,
+	PINCTRL_FUNC_TESTSCAN0,
+	END_FUNCTION,
+};
+
+#define MAX_FUNCTION (unsigned int)(END_FUNCTION)
+
+// pinctrl pin numbers
+enum {
+	PINCTRL_PIN_0,
+	PINCTRL_PIN_1,
+	PINCTRL_PIN_2,
+	PINCTRL_PIN_3,
+	PINCTRL_PIN_4,
+	PINCTRL_PIN_5,
+	PINCTRL_PIN_6,
+	PINCTRL_PIN_7,
+	PINCTRL_PIN_8,
+	PINCTRL_PIN_9,
+	PINCTRL_PIN_10,
+	PINCTRL_PIN_11,
+	PINCTRL_PIN_12,
+	PINCTRL_PIN_13,
+	PINCTRL_PIN_14,
+	PINCTRL_PIN_15,
+	PINCTRL_PIN_16,
+	PINCTRL_PIN_17,
+	PINCTRL_PIN_18,
+	PINCTRL_PIN_19,
+	PINCTRL_PIN_20,
+	PINCTRL_PIN_21,
+	PINCTRL_PIN_22,
+	PINCTRL_PIN_23,
+	PINCTRL_PIN_24,
+	PINCTRL_PIN_25,
+	PINCTRL_PIN_26,
+	PINCTRL_PIN_27,
+	PINCTRL_PIN_28,
+	PINCTRL_PIN_29,
+	PINCTRL_PIN_30,
+	PINCTRL_PIN_31,
+	PINCTRL_PIN_32,
+	PINCTRL_PIN_33,
+	PINCTRL_PIN_34,
+	PINCTRL_PIN_35,
+	PINCTRL_PIN_36,
+	PINCTRL_PIN_37,
+	PINCTRL_PIN_38,
+	PINCTRL_PIN_39,
+	PINCTRL_PIN_40,
+	PINCTRL_PIN_41,
+	PINCTRL_PIN_42,
+	PINCTRL_PIN_43,
+	PINCTRL_PIN_44,
+	PINCTRL_PIN_45,
+	PINCTRL_PIN_46,
+	PINCTRL_PIN_47,
+	PINCTRL_PIN_48,
+	PINCTRL_PIN_49,
+	PINCTRL_PIN_50,
+	PINCTRL_PIN_51,
+	PINCTRL_PIN_52,
+	PINCTRL_PIN_53,
+	PINCTRL_PIN_54,
+	PINCTRL_PIN_55,
+	PINCTRL_PIN_56,
+	PINCTRL_PIN_57,
+	PINCTRL_PIN_58,
+	PINCTRL_PIN_59,
+	PINCTRL_PIN_60,
+	PINCTRL_PIN_61,
+	PINCTRL_PIN_62,
+	PINCTRL_PIN_63,
+	PINCTRL_PIN_64,
+	PINCTRL_PIN_65,
+	PINCTRL_PIN_66,
+	PINCTRL_PIN_67,
+	PINCTRL_PIN_68,
+	PINCTRL_PIN_69,
+	PINCTRL_PIN_70,
+	PINCTRL_PIN_71,
+	PINCTRL_PIN_72,
+	PINCTRL_PIN_73,
+	PINCTRL_PIN_74,
+	PINCTRL_PIN_75,
+	PINCTRL_PIN_76,
+	PINCTRL_PIN_77,
+	END_PINS,
+};
+
+#define MAX_PIN (unsigned int)(END_PINS)
+
+// pinctrl group ids
+enum  {
+	PINCTRL_GRP_ETHERNET0_0,
+	PINCTRL_GRP_ETHERNET1_0,
+	PINCTRL_GRP_ETHERNET2_0,
+	PINCTRL_GRP_ETHERNET3_0,
+	PINCTRL_GRP_GEMTSU0_0,
+	PINCTRL_GRP_GEMTSU0_1,
+	PINCTRL_GRP_GEMTSU0_2,
+	PINCTRL_GRP_MDIO0_0,
+	PINCTRL_GRP_MDIO1_0,
+	PINCTRL_GRP_MDIO1_1,
+	PINCTRL_GRP_MDIO2_0,
+	PINCTRL_GRP_MDIO3_0,
+	PINCTRL_GRP_QSPI0_0,
+	PINCTRL_GRP_QSPI_SS,
+	PINCTRL_GRP_QSPI_FBCLK,
+	PINCTRL_GRP_SPI0_0,
+	PINCTRL_GRP_SPI0_0_SS0,
+	PINCTRL_GRP_SPI0_0_SS1,
+	PINCTRL_GRP_SPI0_0_SS2,
+	PINCTRL_GRP_SPI0_1,
+	PINCTRL_GRP_SPI0_1_SS0,
+	PINCTRL_GRP_SPI0_1_SS1,
+	PINCTRL_GRP_SPI0_1_SS2,
+	PINCTRL_GRP_SPI0_2,
+	PINCTRL_GRP_SPI0_2_SS0,
+	PINCTRL_GRP_SPI0_2_SS1,
+	PINCTRL_GRP_SPI0_2_SS2,
+	PINCTRL_GRP_SPI0_3,
+	PINCTRL_GRP_SPI0_3_SS0,
+	PINCTRL_GRP_SPI0_3_SS1,
+	PINCTRL_GRP_SPI0_3_SS2,
+	PINCTRL_GRP_SPI0_4,
+	PINCTRL_GRP_SPI0_4_SS0,
+	PINCTRL_GRP_SPI0_4_SS1,
+	PINCTRL_GRP_SPI0_4_SS2,
+	PINCTRL_GRP_SPI0_5,
+	PINCTRL_GRP_SPI0_5_SS0,
+	PINCTRL_GRP_SPI0_5_SS1,
+	PINCTRL_GRP_SPI0_5_SS2,
+	PINCTRL_GRP_SPI1_0,
+	PINCTRL_GRP_SPI1_0_SS0,
+	PINCTRL_GRP_SPI1_0_SS1,
+	PINCTRL_GRP_SPI1_0_SS2,
+	PINCTRL_GRP_SPI1_1,
+	PINCTRL_GRP_SPI1_1_SS0,
+	PINCTRL_GRP_SPI1_1_SS1,
+	PINCTRL_GRP_SPI1_1_SS2,
+	PINCTRL_GRP_SPI1_2,
+	PINCTRL_GRP_SPI1_2_SS0,
+	PINCTRL_GRP_SPI1_2_SS1,
+	PINCTRL_GRP_SPI1_2_SS2,
+	PINCTRL_GRP_SPI1_3,
+	PINCTRL_GRP_SPI1_3_SS0,
+	PINCTRL_GRP_SPI1_3_SS1,
+	PINCTRL_GRP_SPI1_3_SS2,
+	PINCTRL_GRP_SPI1_4,
+	PINCTRL_GRP_SPI1_4_SS0,
+	PINCTRL_GRP_SPI1_4_SS1,
+	PINCTRL_GRP_SPI1_4_SS2,
+	PINCTRL_GRP_SPI1_5,
+	PINCTRL_GRP_SPI1_5_SS0,
+	PINCTRL_GRP_SPI1_5_SS1,
+	PINCTRL_GRP_SPI1_5_SS2,
+	PINCTRL_GRP_SDIO0_0,
+	PINCTRL_GRP_SDIO0_1,
+	PINCTRL_GRP_SDIO0_2,
+	PINCTRL_GRP_SDIO0_4BIT_0_0,
+	PINCTRL_GRP_SDIO0_4BIT_0_1,
+	PINCTRL_GRP_SDIO0_4BIT_1_0,
+	PINCTRL_GRP_SDIO0_4BIT_1_1,
+	PINCTRL_GRP_SDIO0_4BIT_2_0,
+	PINCTRL_GRP_SDIO0_4BIT_2_1,
+	PINCTRL_GRP_SDIO0_1BIT_0_0,
+	PINCTRL_GRP_SDIO0_1BIT_0_1,
+	PINCTRL_GRP_SDIO0_1BIT_0_2,
+	PINCTRL_GRP_SDIO0_1BIT_0_3,
+	PINCTRL_GRP_SDIO0_1BIT_0_4,
+	PINCTRL_GRP_SDIO0_1BIT_0_5,
+	PINCTRL_GRP_SDIO0_1BIT_0_6,
+	PINCTRL_GRP_SDIO0_1BIT_0_7,
+	PINCTRL_GRP_SDIO0_1BIT_1_0,
+	PINCTRL_GRP_SDIO0_1BIT_1_1,
+	PINCTRL_GRP_SDIO0_1BIT_1_2,
+	PINCTRL_GRP_SDIO0_1BIT_1_3,
+	PINCTRL_GRP_SDIO0_1BIT_1_4,
+	PINCTRL_GRP_SDIO0_1BIT_1_5,
+	PINCTRL_GRP_SDIO0_1BIT_1_6,
+	PINCTRL_GRP_SDIO0_1BIT_1_7,
+	PINCTRL_GRP_SDIO0_1BIT_2_0,
+	PINCTRL_GRP_SDIO0_1BIT_2_1,
+	PINCTRL_GRP_SDIO0_1BIT_2_2,
+	PINCTRL_GRP_SDIO0_1BIT_2_3,
+	PINCTRL_GRP_SDIO0_1BIT_2_4,
+	PINCTRL_GRP_SDIO0_1BIT_2_5,
+	PINCTRL_GRP_SDIO0_1BIT_2_6,
+	PINCTRL_GRP_SDIO0_1BIT_2_7,
+	PINCTRL_GRP_SDIO0_0_PC,
+	PINCTRL_GRP_SDIO0_0_CD,
+	PINCTRL_GRP_SDIO0_0_WP,
+	PINCTRL_GRP_SDIO0_1_PC,
+	PINCTRL_GRP_SDIO0_1_CD,
+	PINCTRL_GRP_SDIO0_1_WP,
+	PINCTRL_GRP_SDIO0_2_PC,
+	PINCTRL_GRP_SDIO0_2_CD,
+	PINCTRL_GRP_SDIO0_2_WP,
+	PINCTRL_GRP_SDIO1_0,
+	PINCTRL_GRP_SDIO1_4BIT_0_0,
+	PINCTRL_GRP_SDIO1_4BIT_0_1,
+	PINCTRL_GRP_SDIO1_4BIT_1_0,
+	PINCTRL_GRP_SDIO1_1BIT_0_0,
+	PINCTRL_GRP_SDIO1_1BIT_0_1,
+	PINCTRL_GRP_SDIO1_1BIT_0_2,
+	PINCTRL_GRP_SDIO1_1BIT_0_3,
+	PINCTRL_GRP_SDIO1_1BIT_0_4,
+	PINCTRL_GRP_SDIO1_1BIT_0_5,
+	PINCTRL_GRP_SDIO1_1BIT_0_6,
+	PINCTRL_GRP_SDIO1_1BIT_0_7,
+	PINCTRL_GRP_SDIO1_1BIT_1_0,
+	PINCTRL_GRP_SDIO1_1BIT_1_1,
+	PINCTRL_GRP_SDIO1_1BIT_1_2,
+	PINCTRL_GRP_SDIO1_1BIT_1_3,
+	PINCTRL_GRP_SDIO1_0_PC,
+	PINCTRL_GRP_SDIO1_0_CD,
+	PINCTRL_GRP_SDIO1_0_WP,
+	PINCTRL_GRP_SDIO1_1_PC,
+	PINCTRL_GRP_SDIO1_1_CD,
+	PINCTRL_GRP_SDIO1_1_WP,
+	PINCTRL_GRP_NAND0_0,
+	PINCTRL_GRP_NAND0_0_CE,
+	PINCTRL_GRP_NAND0_0_RB,
+	PINCTRL_GRP_NAND0_0_DQS,
+	PINCTRL_GRP_NAND0_1_CE,
+	PINCTRL_GRP_NAND0_1_RB,
+	PINCTRL_GRP_NAND0_1_DQS,
+	PINCTRL_GRP_CAN0_0,
+	PINCTRL_GRP_CAN0_1,
+	PINCTRL_GRP_CAN0_2,
+	PINCTRL_GRP_CAN0_3,
+	PINCTRL_GRP_CAN0_4,
+	PINCTRL_GRP_CAN0_5,
+	PINCTRL_GRP_CAN0_6,
+	PINCTRL_GRP_CAN0_7,
+	PINCTRL_GRP_CAN0_8,
+	PINCTRL_GRP_CAN0_9,
+	PINCTRL_GRP_CAN0_10,
+	PINCTRL_GRP_CAN0_11,
+	PINCTRL_GRP_CAN0_12,
+	PINCTRL_GRP_CAN0_13,
+	PINCTRL_GRP_CAN0_14,
+	PINCTRL_GRP_CAN0_15,
+	PINCTRL_GRP_CAN0_16,
+	PINCTRL_GRP_CAN0_17,
+	PINCTRL_GRP_CAN0_18,
+	PINCTRL_GRP_CAN1_0,
+	PINCTRL_GRP_CAN1_1,
+	PINCTRL_GRP_CAN1_2,
+	PINCTRL_GRP_CAN1_3,
+	PINCTRL_GRP_CAN1_4,
+	PINCTRL_GRP_CAN1_5,
+	PINCTRL_GRP_CAN1_6,
+	PINCTRL_GRP_CAN1_7,
+	PINCTRL_GRP_CAN1_8,
+	PINCTRL_GRP_CAN1_9,
+	PINCTRL_GRP_CAN1_10,
+	PINCTRL_GRP_CAN1_11,
+	PINCTRL_GRP_CAN1_12,
+	PINCTRL_GRP_CAN1_13,
+	PINCTRL_GRP_CAN1_14,
+	PINCTRL_GRP_CAN1_15,
+	PINCTRL_GRP_CAN1_16,
+	PINCTRL_GRP_CAN1_17,
+	PINCTRL_GRP_CAN1_18,
+	PINCTRL_GRP_CAN1_19,
+	PINCTRL_GRP_UART0_0,
+	PINCTRL_GRP_UART0_1,
+	PINCTRL_GRP_UART0_2,
+	PINCTRL_GRP_UART0_3,
+	PINCTRL_GRP_UART0_4,
+	PINCTRL_GRP_UART0_5,
+	PINCTRL_GRP_UART0_6,
+	PINCTRL_GRP_UART0_7,
+	PINCTRL_GRP_UART0_8,
+	PINCTRL_GRP_UART0_9,
+	PINCTRL_GRP_UART0_10,
+	PINCTRL_GRP_UART0_11,
+	PINCTRL_GRP_UART0_12,
+	PINCTRL_GRP_UART0_13,
+	PINCTRL_GRP_UART0_14,
+	PINCTRL_GRP_UART0_15,
+	PINCTRL_GRP_UART0_16,
+	PINCTRL_GRP_UART0_17,
+	PINCTRL_GRP_UART0_18,
+	PINCTRL_GRP_UART1_0,
+	PINCTRL_GRP_UART1_1,
+	PINCTRL_GRP_UART1_2,
+	PINCTRL_GRP_UART1_3,
+	PINCTRL_GRP_UART1_4,
+	PINCTRL_GRP_UART1_5,
+	PINCTRL_GRP_UART1_6,
+	PINCTRL_GRP_UART1_7,
+	PINCTRL_GRP_UART1_8,
+	PINCTRL_GRP_UART1_9,
+	PINCTRL_GRP_UART1_10,
+	PINCTRL_GRP_UART1_11,
+	PINCTRL_GRP_UART1_12,
+	PINCTRL_GRP_UART1_13,
+	PINCTRL_GRP_UART1_14,
+	PINCTRL_GRP_UART1_15,
+	PINCTRL_GRP_UART1_16,
+	PINCTRL_GRP_UART1_17,
+	PINCTRL_GRP_UART1_18,
+	PINCTRL_GRP_I2C0_0,
+	PINCTRL_GRP_I2C0_1,
+	PINCTRL_GRP_I2C0_2,
+	PINCTRL_GRP_I2C0_3,
+	PINCTRL_GRP_I2C0_4,
+	PINCTRL_GRP_I2C0_5,
+	PINCTRL_GRP_I2C0_6,
+	PINCTRL_GRP_I2C0_7,
+	PINCTRL_GRP_I2C0_8,
+	PINCTRL_GRP_I2C0_9,
+	PINCTRL_GRP_I2C0_10,
+	PINCTRL_GRP_I2C0_11,
+	PINCTRL_GRP_I2C0_12,
+	PINCTRL_GRP_I2C0_13,
+	PINCTRL_GRP_I2C0_14,
+	PINCTRL_GRP_I2C0_15,
+	PINCTRL_GRP_I2C0_16,
+	PINCTRL_GRP_I2C0_17,
+	PINCTRL_GRP_I2C0_18,
+	PINCTRL_GRP_I2C1_0,
+	PINCTRL_GRP_I2C1_1,
+	PINCTRL_GRP_I2C1_2,
+	PINCTRL_GRP_I2C1_3,
+	PINCTRL_GRP_I2C1_4,
+	PINCTRL_GRP_I2C1_5,
+	PINCTRL_GRP_I2C1_6,
+	PINCTRL_GRP_I2C1_7,
+	PINCTRL_GRP_I2C1_8,
+	PINCTRL_GRP_I2C1_9,
+	PINCTRL_GRP_I2C1_10,
+	PINCTRL_GRP_I2C1_11,
+	PINCTRL_GRP_I2C1_12,
+	PINCTRL_GRP_I2C1_13,
+	PINCTRL_GRP_I2C1_14,
+	PINCTRL_GRP_I2C1_15,
+	PINCTRL_GRP_I2C1_16,
+	PINCTRL_GRP_I2C1_17,
+	PINCTRL_GRP_I2C1_18,
+	PINCTRL_GRP_I2C1_19,
+	PINCTRL_GRP_TTC0_0_CLK,
+	PINCTRL_GRP_TTC0_0_WAV,
+	PINCTRL_GRP_TTC0_1_CLK,
+	PINCTRL_GRP_TTC0_1_WAV,
+	PINCTRL_GRP_TTC0_2_CLK,
+	PINCTRL_GRP_TTC0_2_WAV,
+	PINCTRL_GRP_TTC0_3_CLK,
+	PINCTRL_GRP_TTC0_3_WAV,
+	PINCTRL_GRP_TTC0_4_CLK,
+	PINCTRL_GRP_TTC0_4_WAV,
+	PINCTRL_GRP_TTC0_5_CLK,
+	PINCTRL_GRP_TTC0_5_WAV,
+	PINCTRL_GRP_TTC0_6_CLK,
+	PINCTRL_GRP_TTC0_6_WAV,
+	PINCTRL_GRP_TTC0_7_CLK,
+	PINCTRL_GRP_TTC0_7_WAV,
+	PINCTRL_GRP_TTC0_8_CLK,
+	PINCTRL_GRP_TTC0_8_WAV,
+	PINCTRL_GRP_TTC1_0_CLK,
+	PINCTRL_GRP_TTC1_0_WAV,
+	PINCTRL_GRP_TTC1_1_CLK,
+	PINCTRL_GRP_TTC1_1_WAV,
+	PINCTRL_GRP_TTC1_2_CLK,
+	PINCTRL_GRP_TTC1_2_WAV,
+	PINCTRL_GRP_TTC1_3_CLK,
+	PINCTRL_GRP_TTC1_3_WAV,
+	PINCTRL_GRP_TTC1_4_CLK,
+	PINCTRL_GRP_TTC1_4_WAV,
+	PINCTRL_GRP_TTC1_5_CLK,
+	PINCTRL_GRP_TTC1_5_WAV,
+	PINCTRL_GRP_TTC1_6_CLK,
+	PINCTRL_GRP_TTC1_6_WAV,
+	PINCTRL_GRP_TTC1_7_CLK,
+	PINCTRL_GRP_TTC1_7_WAV,
+	PINCTRL_GRP_TTC1_8_CLK,
+	PINCTRL_GRP_TTC1_8_WAV,
+	PINCTRL_GRP_TTC2_0_CLK,
+	PINCTRL_GRP_TTC2_0_WAV,
+	PINCTRL_GRP_TTC2_1_CLK,
+	PINCTRL_GRP_TTC2_1_WAV,
+	PINCTRL_GRP_TTC2_2_CLK,
+	PINCTRL_GRP_TTC2_2_WAV,
+	PINCTRL_GRP_TTC2_3_CLK,
+	PINCTRL_GRP_TTC2_3_WAV,
+	PINCTRL_GRP_TTC2_4_CLK,
+	PINCTRL_GRP_TTC2_4_WAV,
+	PINCTRL_GRP_TTC2_5_CLK,
+	PINCTRL_GRP_TTC2_5_WAV,
+	PINCTRL_GRP_TTC2_6_CLK,
+	PINCTRL_GRP_TTC2_6_WAV,
+	PINCTRL_GRP_TTC2_7_CLK,
+	PINCTRL_GRP_TTC2_7_WAV,
+	PINCTRL_GRP_TTC2_8_CLK,
+	PINCTRL_GRP_TTC2_8_WAV,
+	PINCTRL_GRP_TTC3_0_CLK,
+	PINCTRL_GRP_TTC3_0_WAV,
+	PINCTRL_GRP_TTC3_1_CLK,
+	PINCTRL_GRP_TTC3_1_WAV,
+	PINCTRL_GRP_TTC3_2_CLK,
+	PINCTRL_GRP_TTC3_2_WAV,
+	PINCTRL_GRP_TTC3_3_CLK,
+	PINCTRL_GRP_TTC3_3_WAV,
+	PINCTRL_GRP_TTC3_4_CLK,
+	PINCTRL_GRP_TTC3_4_WAV,
+	PINCTRL_GRP_TTC3_5_CLK,
+	PINCTRL_GRP_TTC3_5_WAV,
+	PINCTRL_GRP_TTC3_6_CLK,
+	PINCTRL_GRP_TTC3_6_WAV,
+	PINCTRL_GRP_TTC3_7_CLK,
+	PINCTRL_GRP_TTC3_7_WAV,
+	PINCTRL_GRP_TTC3_8_CLK,
+	PINCTRL_GRP_TTC3_8_WAV,
+	PINCTRL_GRP_SWDT0_0_CLK,
+	PINCTRL_GRP_SWDT0_0_RST,
+	PINCTRL_GRP_SWDT0_1_CLK,
+	PINCTRL_GRP_SWDT0_1_RST,
+	PINCTRL_GRP_SWDT0_2_CLK,
+	PINCTRL_GRP_SWDT0_2_RST,
+	PINCTRL_GRP_SWDT0_3_CLK,
+	PINCTRL_GRP_SWDT0_3_RST,
+	PINCTRL_GRP_SWDT0_4_CLK,
+	PINCTRL_GRP_SWDT0_4_RST,
+	PINCTRL_GRP_SWDT0_5_CLK,
+	PINCTRL_GRP_SWDT0_5_RST,
+	PINCTRL_GRP_SWDT0_6_CLK,
+	PINCTRL_GRP_SWDT0_6_RST,
+	PINCTRL_GRP_SWDT0_7_CLK,
+	PINCTRL_GRP_SWDT0_7_RST,
+	PINCTRL_GRP_SWDT0_8_CLK,
+	PINCTRL_GRP_SWDT0_8_RST,
+	PINCTRL_GRP_SWDT0_9_CLK,
+	PINCTRL_GRP_SWDT0_9_RST,
+	PINCTRL_GRP_SWDT0_10_CLK,
+	PINCTRL_GRP_SWDT0_10_RST,
+	PINCTRL_GRP_SWDT0_11_CLK,
+	PINCTRL_GRP_SWDT0_11_RST,
+	PINCTRL_GRP_SWDT0_12_CLK,
+	PINCTRL_GRP_SWDT0_12_RST,
+	PINCTRL_GRP_SWDT1_0_CLK,
+	PINCTRL_GRP_SWDT1_0_RST,
+	PINCTRL_GRP_SWDT1_1_CLK,
+	PINCTRL_GRP_SWDT1_1_RST,
+	PINCTRL_GRP_SWDT1_2_CLK,
+	PINCTRL_GRP_SWDT1_2_RST,
+	PINCTRL_GRP_SWDT1_3_CLK,
+	PINCTRL_GRP_SWDT1_3_RST,
+	PINCTRL_GRP_SWDT1_4_CLK,
+	PINCTRL_GRP_SWDT1_4_RST,
+	PINCTRL_GRP_SWDT1_5_CLK,
+	PINCTRL_GRP_SWDT1_5_RST,
+	PINCTRL_GRP_SWDT1_6_CLK,
+	PINCTRL_GRP_SWDT1_6_RST,
+	PINCTRL_GRP_SWDT1_7_CLK,
+	PINCTRL_GRP_SWDT1_7_RST,
+	PINCTRL_GRP_SWDT1_8_CLK,
+	PINCTRL_GRP_SWDT1_8_RST,
+	PINCTRL_GRP_SWDT1_9_CLK,
+	PINCTRL_GRP_SWDT1_9_RST,
+	PINCTRL_GRP_SWDT1_10_CLK,
+	PINCTRL_GRP_SWDT1_10_RST,
+	PINCTRL_GRP_SWDT1_11_CLK,
+	PINCTRL_GRP_SWDT1_11_RST,
+	PINCTRL_GRP_SWDT1_12_CLK,
+	PINCTRL_GRP_SWDT1_12_RST,
+	PINCTRL_GRP_GPIO0_0,
+	PINCTRL_GRP_GPIO0_1,
+	PINCTRL_GRP_GPIO0_2,
+	PINCTRL_GRP_GPIO0_3,
+	PINCTRL_GRP_GPIO0_4,
+	PINCTRL_GRP_GPIO0_5,
+	PINCTRL_GRP_GPIO0_6,
+	PINCTRL_GRP_GPIO0_7,
+	PINCTRL_GRP_GPIO0_8,
+	PINCTRL_GRP_GPIO0_9,
+	PINCTRL_GRP_GPIO0_10,
+	PINCTRL_GRP_GPIO0_11,
+	PINCTRL_GRP_GPIO0_12,
+	PINCTRL_GRP_GPIO0_13,
+	PINCTRL_GRP_GPIO0_14,
+	PINCTRL_GRP_GPIO0_15,
+	PINCTRL_GRP_GPIO0_16,
+	PINCTRL_GRP_GPIO0_17,
+	PINCTRL_GRP_GPIO0_18,
+	PINCTRL_GRP_GPIO0_19,
+	PINCTRL_GRP_GPIO0_20,
+	PINCTRL_GRP_GPIO0_21,
+	PINCTRL_GRP_GPIO0_22,
+	PINCTRL_GRP_GPIO0_23,
+	PINCTRL_GRP_GPIO0_24,
+	PINCTRL_GRP_GPIO0_25,
+	PINCTRL_GRP_GPIO0_26,
+	PINCTRL_GRP_GPIO0_27,
+	PINCTRL_GRP_GPIO0_28,
+	PINCTRL_GRP_GPIO0_29,
+	PINCTRL_GRP_GPIO0_30,
+	PINCTRL_GRP_GPIO0_31,
+	PINCTRL_GRP_GPIO0_32,
+	PINCTRL_GRP_GPIO0_33,
+	PINCTRL_GRP_GPIO0_34,
+	PINCTRL_GRP_GPIO0_35,
+	PINCTRL_GRP_GPIO0_36,
+	PINCTRL_GRP_GPIO0_37,
+	PINCTRL_GRP_GPIO0_38,
+	PINCTRL_GRP_GPIO0_39,
+	PINCTRL_GRP_GPIO0_40,
+	PINCTRL_GRP_GPIO0_41,
+	PINCTRL_GRP_GPIO0_42,
+	PINCTRL_GRP_GPIO0_43,
+	PINCTRL_GRP_GPIO0_44,
+	PINCTRL_GRP_GPIO0_45,
+	PINCTRL_GRP_GPIO0_46,
+	PINCTRL_GRP_GPIO0_47,
+	PINCTRL_GRP_GPIO0_48,
+	PINCTRL_GRP_GPIO0_49,
+	PINCTRL_GRP_GPIO0_50,
+	PINCTRL_GRP_GPIO0_51,
+	PINCTRL_GRP_GPIO0_52,
+	PINCTRL_GRP_GPIO0_53,
+	PINCTRL_GRP_GPIO0_54,
+	PINCTRL_GRP_GPIO0_55,
+	PINCTRL_GRP_GPIO0_56,
+	PINCTRL_GRP_GPIO0_57,
+	PINCTRL_GRP_GPIO0_58,
+	PINCTRL_GRP_GPIO0_59,
+	PINCTRL_GRP_GPIO0_60,
+	PINCTRL_GRP_GPIO0_61,
+	PINCTRL_GRP_GPIO0_62,
+	PINCTRL_GRP_GPIO0_63,
+	PINCTRL_GRP_GPIO0_64,
+	PINCTRL_GRP_GPIO0_65,
+	PINCTRL_GRP_GPIO0_66,
+	PINCTRL_GRP_GPIO0_67,
+	PINCTRL_GRP_GPIO0_68,
+	PINCTRL_GRP_GPIO0_69,
+	PINCTRL_GRP_GPIO0_70,
+	PINCTRL_GRP_GPIO0_71,
+	PINCTRL_GRP_GPIO0_72,
+	PINCTRL_GRP_GPIO0_73,
+	PINCTRL_GRP_GPIO0_74,
+	PINCTRL_GRP_GPIO0_75,
+	PINCTRL_GRP_GPIO0_76,
+	PINCTRL_GRP_GPIO0_77,
+	PINCTRL_GRP_USB0_0,
+	PINCTRL_GRP_USB1_0,
+	PINCTRL_GRP_PMU0_0,
+	PINCTRL_GRP_PMU0_1,
+	PINCTRL_GRP_PMU0_2,
+	PINCTRL_GRP_PMU0_3,
+	PINCTRL_GRP_PMU0_4,
+	PINCTRL_GRP_PMU0_5,
+	PINCTRL_GRP_PMU0_6,
+	PINCTRL_GRP_PMU0_7,
+	PINCTRL_GRP_PMU0_8,
+	PINCTRL_GRP_PMU0_9,
+	PINCTRL_GRP_PMU0_10,
+	PINCTRL_GRP_PMU0_11,
+	PINCTRL_GRP_PCIE0_0,
+	PINCTRL_GRP_PCIE0_1,
+	PINCTRL_GRP_PCIE0_2,
+	PINCTRL_GRP_PCIE0_3,
+	PINCTRL_GRP_PCIE0_4,
+	PINCTRL_GRP_PCIE0_5,
+	PINCTRL_GRP_PCIE0_6,
+	PINCTRL_GRP_PCIE0_7,
+	PINCTRL_GRP_CSU0_0,
+	PINCTRL_GRP_CSU0_1,
+	PINCTRL_GRP_CSU0_2,
+	PINCTRL_GRP_CSU0_3,
+	PINCTRL_GRP_CSU0_4,
+	PINCTRL_GRP_CSU0_5,
+	PINCTRL_GRP_CSU0_6,
+	PINCTRL_GRP_CSU0_7,
+	PINCTRL_GRP_CSU0_8,
+	PINCTRL_GRP_CSU0_9,
+	PINCTRL_GRP_CSU0_10,
+	PINCTRL_GRP_CSU0_11,
+	PINCTRL_GRP_DPAUX0_0,
+	PINCTRL_GRP_DPAUX0_1,
+	PINCTRL_GRP_DPAUX0_2,
+	PINCTRL_GRP_DPAUX0_3,
+	PINCTRL_GRP_PJTAG0_0,
+	PINCTRL_GRP_PJTAG0_1,
+	PINCTRL_GRP_PJTAG0_2,
+	PINCTRL_GRP_PJTAG0_3,
+	PINCTRL_GRP_PJTAG0_4,
+	PINCTRL_GRP_PJTAG0_5,
+	PINCTRL_GRP_TRACE0_0,
+	PINCTRL_GRP_TRACE0_0_CLK,
+	PINCTRL_GRP_TRACE0_1,
+	PINCTRL_GRP_TRACE0_1_CLK,
+	PINCTRL_GRP_TRACE0_2,
+	PINCTRL_GRP_TRACE0_2_CLK,
+	PINCTRL_GRP_TESTSCAN0_0,
+};
+
+// pinctrl config parameters
+enum {
+	PINCTRL_CONFIG_SLEW_RATE,
+	PINCTRL_CONFIG_BIAS_STATUS,
+	PINCTRL_CONFIG_PULL_CTRL,
+	PINCTRL_CONFIG_SCHMITT_CMOS,
+	PINCTRL_CONFIG_DRIVE_STRENGTH,
+	PINCTRL_CONFIG_VOLTAGE_STATUS,
+	PINCTRL_CONFIG_MAX,
+};
+
+// pinctrl slew rate
+#define	PINCTRL_SLEW_RATE_FAST 0U
+#define	PINCTRL_SLEW_RATE_SLOW 1U
+
+// pinctrl bias status
+#define	PINCTRL_BIAS_DISABLE 0U
+#define	PINCTRL_BIAS_ENABLE 1U
+
+// pinctrl pull control
+#define	PINCTRL_BIAS_PULL_DOWN 0U
+#define	PINCTRL_BIAS_PULL_UP 1U
+
+// pinctrl schmitt cmos type
+#define PINCTRL_INPUT_TYPE_CMOS 0U
+#define	PINCTRL_INPUT_TYPE_SCHMITT 1U
+
+//pinctrl drive strength values
+#define	PINCTRL_DRIVE_STRENGTH_2MA 0U
+#define	PINCTRL_DRIVE_STRENGTH_4MA 1U
+#define	PINCTRL_DRIVE_STRENGTH_8MA 2U
+#define	PINCTRL_DRIVE_STRENGTH_12MA 3U
+
+enum pm_ret_status pm_api_pinctrl_set_function(unsigned int pin,
+					       unsigned int fid);
+enum pm_ret_status pm_api_pinctrl_get_function(unsigned int pin,
+					       unsigned int *id);
+enum pm_ret_status pm_api_pinctrl_set_config(unsigned int pin,
+					     unsigned int param,
+					     unsigned int value);
+enum pm_ret_status pm_api_pinctrl_get_config(unsigned int pin,
+					     unsigned int param,
+					     unsigned int *value);
+enum pm_ret_status pm_api_pinctrl_get_function_name(unsigned int fid,
+						    char *name);
+enum pm_ret_status pm_api_pinctrl_get_function_groups(unsigned int fid,
+						      unsigned int index,
+						      uint16_t *groups);
+enum pm_ret_status pm_api_pinctrl_get_pin_groups(unsigned int pin,
+						 unsigned int index,
+						 uint16_t *groups);
+enum pm_ret_status pm_api_pinctrl_get_num_pins(unsigned int *npins);
+enum pm_ret_status pm_api_pinctrl_get_num_functions(unsigned int *nfuncs);
+enum pm_ret_status pm_api_pinctrl_get_num_func_groups(unsigned int fid,
+						      unsigned int *ngroups);
+#endif /* _PM_API_PINCTRL_H_ */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index 9e21067..d75f7c0 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -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
  */
@@ -11,6 +11,9 @@
 
 #include <arch_helpers.h>
 #include <platform.h>
+#include "pm_api_clock.h"
+#include "pm_api_ioctl.h"
+#include "pm_api_pinctrl.h"
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_common.h"
@@ -545,3 +548,529 @@
 	pm_ipi_buff_read_callb(data, count);
 	pm_ipi_irq_clear(primary_proc);
 }
+
+/**
+ * pm_pinctrl_request() - Request Pin from firmware
+ * @pin		Pin number to request
+ *
+ * This function requests pin from firmware.
+ *
+ * @return	Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_pinctrl_request(unsigned int pin)
+{
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_pinctrl_release() - Release Pin from firmware
+ * @pin		Pin number to release
+ *
+ * This function releases pin from firmware.
+ *
+ * @return	Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_pinctrl_release(unsigned int pin)
+{
+	return PM_RET_SUCCESS;
+}
+
+/**
+ * pm_pinctrl_get_function() - Read function id set for the given pin
+ * @pin		Pin number
+ * @nid		Node ID of function currently set for given pin
+ *
+ * This function provides the function currently set for the given pin.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
+					   enum pm_node_id *nid)
+{
+	return pm_api_pinctrl_get_function(pin, nid);
+}
+
+/**
+ * pm_pinctrl_set_function() - Set function id set for the given pin
+ * @pin		Pin number
+ * @nid		Node ID of function to set for given pin
+ *
+ * This function provides the function currently set for the given pin.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
+					   enum pm_node_id nid)
+{
+	return pm_api_pinctrl_set_function(pin, (unsigned int)nid);
+}
+
+/**
+ * pm_pinctrl_get_config() - Read value of requested config param for given pin
+ * @pin		Pin number
+ * @param	Parameter values to be read
+ * @value	Buffer for configuration Parameter value
+ *
+ * This function provides the configuration parameter value for the given pin.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
+					 unsigned int param,
+					 unsigned int *value)
+{
+	return pm_api_pinctrl_get_config(pin, param, value);
+}
+
+/**
+ * pm_pinctrl_set_config() - Read value of requested config param for given pin
+ * @pin		Pin number
+ * @param	Parameter to set
+ * @value	Parameter value to set
+ *
+ * This function provides the configuration parameter value for the given pin.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
+					 unsigned int param,
+					 unsigned int value)
+{
+	return pm_api_pinctrl_set_config(pin, param, value);
+}
+
+/**
+ * pm_ioctl() -  PM IOCTL API for device control and configs
+ * @node_id	Node ID of the device
+ * @ioctl_id	ID of the requested IOCTL
+ * @arg1	Argument 1 to requested IOCTL call
+ * @arg2	Argument 2 to requested IOCTL call
+ * @out		Returned output value
+ *
+ * This function calls IOCTL to firmware for device control and configuration.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_ioctl(enum pm_node_id nid,
+			    unsigned int ioctl_id,
+			    unsigned int arg1,
+			    unsigned int arg2,
+			    unsigned int *value)
+{
+	return pm_api_ioctl(nid, ioctl_id, arg1, arg2, value);
+}
+
+/**
+ * pm_clock_get_name() - PM call to request a clock's name
+ * @clock_id	Clock ID
+ * @name	Name of clock (max 16 bytes)
+ *
+ * This function is used by master to get nmae of clock specified
+ * by given clock ID.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_name(unsigned int clock_id, char *name)
+{
+	return pm_api_clock_get_name(clock_id, name);
+}
+
+/**
+ * pm_clock_get_topology() - PM call to request a clock's topology
+ * @clock_id	Clock ID
+ * @index	Topology index for next toplogy node
+ * @topology	Buffer to store nodes in topology and flags
+ *
+ * This function is used by master to get topology information for the
+ * clock specified by given clock ID. Each response would return 3
+ * topology nodes. To get next nodes, caller needs to call this API with
+ * index of next node. Index starts from 0.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_topology(unsigned int clock_id,
+						unsigned int index,
+						uint32_t *topology)
+{
+	return pm_api_clock_get_topology(clock_id, index, topology);
+}
+
+/**
+ * pm_clock_get_fixedfactor_params() - PM call to request a clock's fixed factor
+ *				 parameters for fixed clock
+ * @clock_id	Clock ID
+ * @mul		Multiplication value
+ * @div		Divisor value
+ *
+ * This function is used by master to get fixed factor parameers for the
+ * fixed clock. This API is application only for the fixed clock.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_fixedfactor_params(unsigned int clock_id,
+							  uint32_t *mul,
+							  uint32_t *div)
+{
+	return pm_api_clock_get_fixedfactor_params(clock_id, mul, div);
+}
+
+/**
+ * pm_clock_get_parents() - PM call to request a clock's first 3 parents
+ * @clock_id	Clock ID
+ * @index	Index of next parent
+ * @parents	Parents of the given clock
+ *
+ * This function is used by master to get clock's parents information.
+ * This API will return 3 parents with a single response. To get other
+ * parents, master should call same API in loop with new parent index
+ * till error is returned.
+ *
+ * E.g First call should have index 0 which will return parents 0, 1 and
+ * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
+ * so on.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_parents(unsigned int clock_id,
+					       unsigned int index,
+					       uint32_t *parents)
+{
+	return pm_api_clock_get_parents(clock_id, index, parents);
+}
+
+/**
+ * pm_clock_get_attributes() - PM call to request a clock's attributes
+ * @clock_id	Clock ID
+ * @attr	Clock attributes
+ *
+ * This function is used by master to get clock's attributes
+ * (e.g. valid, clock type, etc).
+ *
+ * @return	Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_clock_get_attributes(unsigned int clock_id,
+						  uint32_t *attr)
+{
+	return pm_api_clock_get_attributes(clock_id, attr);
+}
+
+/**
+ * pm_clock_enable() - Enable the clock for given id
+ * @clock_id: Id of the clock to be enabled
+ *
+ * This function is used by master to enable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+
+enum pm_ret_status pm_clock_enable(unsigned int clock_id)
+{
+	return pm_api_clock_enable(clock_id);
+}
+
+/**
+ * pm_clock_disable - Disable the clock for given id
+ * @clock_id: Id of the clock to be disable
+ *
+ * This function is used by master to disable the clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+
+enum pm_ret_status pm_clock_disable(unsigned int clock_id)
+{
+	return pm_api_clock_disable(clock_id);
+}
+
+/**
+ * pm_clock_getstate - Get the clock state for given id
+ * @clock_id: Id of the clock to be queried
+ * @state: 1/0 (Enabled/Disabled)
+ *
+ * This function is used by master to get the state of clock
+ * including peripherals and PLL clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
+				     unsigned int *state)
+{
+	return pm_api_clock_getstate(clock_id, state);
+}
+
+/**
+ * pm_clock_setdivider - Set the clock divider for given id
+ * @clock_id: Id of the clock
+ * @divider: divider value
+ *
+ * This function is used by master to set divider for any clock
+ * to achieve desired rate.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
+				       unsigned int divider)
+{
+	return pm_api_clock_setdivider(clock_id, divider);
+}
+
+/**
+ * pm_clock_getdivider - Get the clock divider for given id
+ * @clock_id: Id of the clock
+ * @divider: divider value
+ *
+ * This function is used by master to get divider values
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
+				       unsigned int *divider)
+{
+	return pm_api_clock_getdivider(clock_id, divider);
+}
+
+/**
+ * pm_clock_setrate - Set the clock rate for given id
+ * @clock_id: Id of the clock
+ * @rate: rate value in hz
+ *
+ * This function is used by master to set rate for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
+				    uint64_t rate)
+{
+	return pm_api_clock_setrate(clock_id, rate);
+}
+
+/**
+ * pm_clock_getrate - Get the clock rate for given id
+ * @clock_id: Id of the clock
+ * @rate: rate value in hz
+ *
+ * This function is used by master to get rate
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
+				    uint64_t *rate)
+{
+	return pm_api_clock_getrate(clock_id, rate);
+}
+
+/**
+ * pm_clock_setparent - Set the clock parent for given id
+ * @clock_id: Id of the clock
+ * @parent_id: parent id
+ *
+ * This function is used by master to set parent for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
+				      unsigned int parent_id)
+{
+	return pm_api_clock_setparent(clock_id, parent_id);
+}
+
+/**
+ * pm_clock_getparent - Get the clock parent for given id
+ * @clock_id: Id of the clock
+ * @parent_id: parent id
+ *
+ * This function is used by master to get parent index
+ * for any clock.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
+				      unsigned int *parent_id)
+{
+	return pm_api_clock_getparent(clock_id, parent_id);
+}
+
+/**
+ * pm_pinctrl_get_num_pins - PM call to request number of pins
+ * @npins: Number of pins
+ *
+ * This function is used by master to get number of pins
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_num_pins(uint32_t *npins)
+{
+	return pm_api_pinctrl_get_num_pins(npins);
+}
+
+/**
+ * pm_pinctrl_get_num_functions - PM call to request number of functions
+ * @nfuncs: Number of functions
+ *
+ * This function is used by master to get number of functions
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_num_functions(uint32_t *nfuncs)
+{
+	return pm_api_pinctrl_get_num_functions(nfuncs);
+}
+
+/**
+ * pm_pinctrl_get_num_function_groups - PM call to request number of
+ *					function groups
+ * @fid: Id of function
+ * @ngroups: Number of function groups
+ *
+ * This function is used by master to get number of function groups specified
+ * by given function Id
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_num_function_groups(unsigned int fid,
+							     uint32_t *ngroups)
+{
+	return pm_api_pinctrl_get_num_func_groups(fid, ngroups);
+}
+
+/**
+ * pm_pinctrl_get_function_name - PM call to request function name
+ * @fid: Id of function
+ * @name: Name of function
+ *
+ * This function is used by master to get name of function specified
+ * by given function Id
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_function_name(unsigned int fid,
+						       char *name)
+{
+	return pm_api_pinctrl_get_function_name(fid, name);
+}
+
+/**
+ * pm_pinctrl_get_function_groups - PM call to request function groups
+ * @fid: Id of function
+ * @index: Index of next function groups
+ * @groups: Function groups
+ *
+ * This function is used by master to get function groups specified
+ * by given function Id. This API will return 6 function groups with
+ * a single response. To get other function groups, master should call
+ * same API in loop with new function groups index till error is returned.
+ *
+ * E.g First call should have index 0 which will return function groups
+ * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
+ * function groups 6, 7, 8, 9, 10 and 11 and so on.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_function_groups(unsigned int fid,
+							 unsigned int index,
+							 uint16_t *groups)
+{
+	return pm_api_pinctrl_get_function_groups(fid, index, groups);
+}
+
+/**
+ * pm_pinctrl_get_pin_groups - PM call to request pin groups
+ * @pin_id: Id of pin
+ * @index: Index of next pin groups
+ * @groups: pin groups
+ *
+ * This function is used by master to get pin groups specified
+ * by given pin Id. This API will return 6 pin groups with
+ * a single response. To get other pin groups, master should call
+ * same API in loop with new pin groups index till error is returned.
+ *
+ * E.g First call should have index 0 which will return pin groups
+ * 0, 1, 2, 3, 4 and 5. Next call, index should be 6 which will return
+ * pin groups 6, 7, 8, 9, 10 and 11 and so on.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_pinctrl_get_pin_groups(unsigned int pin_id,
+						    unsigned int index,
+						    uint16_t *groups)
+{
+	return pm_api_pinctrl_get_pin_groups(pin_id, index, groups);
+}
+
+/**
+ * pm_query_data() -  PM API for querying firmware data
+ * @arg1	Argument 1 to requested IOCTL call
+ * @arg2	Argument 2 to requested IOCTL call
+ * @arg3	Argument 3 to requested IOCTL call
+ * @arg4	Argument 4 to requested IOCTL call
+ * @data	Returned output data
+ *
+ * This function returns requested data.
+ *
+ * @return	Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_query_data(enum pm_query_id qid,
+				 unsigned int arg1,
+				 unsigned int arg2,
+				 unsigned int arg3,
+				 unsigned int *data)
+{
+	enum pm_ret_status ret;
+
+	switch (qid) {
+	case PM_QID_CLOCK_GET_NAME:
+		ret = pm_clock_get_name(arg1, (char *)data);
+		break;
+	case PM_QID_CLOCK_GET_TOPOLOGY:
+		ret = pm_clock_get_topology(arg1, arg2, &data[1]);
+		data[0] = (unsigned int)ret;
+		break;
+	case PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS:
+		ret = pm_clock_get_fixedfactor_params(arg1, &data[1], &data[2]);
+		data[0] = (unsigned int)ret;
+		break;
+	case PM_QID_CLOCK_GET_PARENTS:
+		ret = pm_clock_get_parents(arg1, arg2, &data[1]);
+		data[0] = (unsigned int)ret;
+		break;
+	case PM_QID_CLOCK_GET_ATTRIBUTES:
+		ret = pm_clock_get_attributes(arg1, &data[1]);
+		data[0] = (unsigned int)ret;
+		break;
+	case PM_QID_PINCTRL_GET_NUM_PINS:
+		ret = pm_pinctrl_get_num_pins(&data[1]);
+		data[0] = (unsigned int)ret;
+		break;
+	case PM_QID_PINCTRL_GET_NUM_FUNCTIONS:
+		ret = pm_pinctrl_get_num_functions(&data[1]);
+		data[0] = (unsigned int)ret;
+		break;
+	case PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS:
+		ret = pm_pinctrl_get_num_function_groups(arg1, &data[1]);
+		data[0] = (unsigned int)ret;
+		break;
+	case PM_QID_PINCTRL_GET_FUNCTION_NAME:
+		ret = pm_pinctrl_get_function_name(arg1, (char *)data);
+		break;
+	case PM_QID_PINCTRL_GET_FUNCTION_GROUPS:
+		ret = pm_pinctrl_get_function_groups(arg1, arg2,
+						     (uint16_t *)&data[1]);
+		data[0] = (unsigned int)ret;
+		break;
+	case PM_QID_PINCTRL_GET_PIN_GROUPS:
+		ret = pm_pinctrl_get_pin_groups(arg1, arg2,
+						(uint16_t *)&data[1]);
+		data[0] = (unsigned int)ret;
+		break;
+	default:
+		ret = PM_RET_ERROR_ARGS;
+		WARN("Unimplemented query service call: 0x%x\n", qid);
+		break;
+	}
+
+	return ret;
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index af7b252..c6de560 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,21 @@
 #include <stdint.h>
 #include "pm_defs.h"
 
+enum pm_query_id {
+	PM_QID_INVALID,
+	PM_QID_CLOCK_GET_NAME,
+	PM_QID_CLOCK_GET_TOPOLOGY,
+	PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
+	PM_QID_CLOCK_GET_PARENTS,
+	PM_QID_CLOCK_GET_ATTRIBUTES,
+	PM_QID_PINCTRL_GET_NUM_PINS,
+	PM_QID_PINCTRL_GET_NUM_FUNCTIONS,
+	PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
+	PM_QID_PINCTRL_GET_FUNCTION_NAME,
+	PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
+	PM_QID_PINCTRL_GET_PIN_GROUPS,
+};
+
 /**********************************************************
  * System-level API function declarations
  **********************************************************/
@@ -93,5 +108,42 @@
 
 enum pm_ret_status pm_get_chipid(uint32_t *value);
 void pm_get_callbackdata(uint32_t *data, size_t count);
-
+enum pm_ret_status pm_pinctrl_request(unsigned int pin);
+enum pm_ret_status pm_pinctrl_release(unsigned int pin);
+enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
+					   enum pm_node_id *nid);
+enum pm_ret_status pm_pinctrl_set_function(unsigned int pin,
+					   enum pm_node_id nid);
+enum pm_ret_status pm_pinctrl_get_config(unsigned int pin,
+					 unsigned int param,
+					 unsigned int *value);
+enum pm_ret_status pm_pinctrl_set_config(unsigned int pin,
+					 unsigned int param,
+					 unsigned int value);
+enum pm_ret_status pm_ioctl(enum pm_node_id nid,
+			    unsigned int ioctl_id,
+			    unsigned int arg1,
+			    unsigned int arg2,
+			    unsigned int *value);
+enum pm_ret_status pm_clock_enable(unsigned int clock_id);
+enum pm_ret_status pm_clock_disable(unsigned int clock_id);
+enum pm_ret_status pm_clock_getstate(unsigned int clock_id,
+				     unsigned int *state);
+enum pm_ret_status pm_clock_setdivider(unsigned int clock_id,
+				       unsigned int divider);
+enum pm_ret_status pm_clock_getdivider(unsigned int clock_id,
+				       unsigned int *divider);
+enum pm_ret_status pm_clock_setrate(unsigned int clock_id,
+				    uint64_t rate);
+enum pm_ret_status pm_clock_getrate(unsigned int clock_id,
+				    uint64_t *rate);
+enum pm_ret_status pm_clock_setparent(unsigned int clock_id,
+				      unsigned int parent_id);
+enum pm_ret_status pm_clock_getparent(unsigned int clock_id,
+				      unsigned int *parent_id);
+enum pm_ret_status pm_query_data(enum pm_query_id qid,
+				 unsigned int arg1,
+				 unsigned int arg2,
+				 unsigned int arg3,
+				 unsigned int *data);
 #endif /* _PM_API_SYS_H_ */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_common.h b/plat/xilinx/zynqmp/pm_service/pm_common.h
index 5dcbb0d..4d03bc0 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_common.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_common.h
@@ -19,6 +19,11 @@
 #define PAYLOAD_ARG_CNT		6U
 #define PAYLOAD_ARG_SIZE	4U	/* size in bytes */
 
+#define ZYNQMP_TZ_VERSION_MAJOR		1
+#define ZYNQMP_TZ_VERSION_MINOR		0
+#define ZYNQMP_TZ_VERSION		((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
+					ZYNQMP_TZ_VERSION_MINOR)
+
 /**
  * pm_ipi - struct for capturing IPI-channel specific info
  * @apu_ipi_id	APU IPI agent ID
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index ba0c52a..0c46e73 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,8 +17,8 @@
  * Version number is a 32bit value, like:
  * (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR
  */
-#define PM_VERSION_MAJOR	0
-#define PM_VERSION_MINOR	2
+#define PM_VERSION_MAJOR	1
+#define PM_VERSION_MINOR	0
 
 #define PM_VERSION	((PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR)
 
@@ -66,6 +66,28 @@
 	PM_FPGA_LOAD,
 	PM_FPGA_GET_STATUS,
 	PM_GET_CHIPID,
+	PM_SECURE_RSA_AES,
+	PM_SECURE_SHA,
+	PM_SECURE_RSA,
+	PM_PINCTRL_REQUEST,
+	PM_PINCTRL_RELEASE,
+	PM_PINCTRL_GET_FUNCTION,
+	PM_PINCTRL_SET_FUNCTION,
+	PM_PINCTRL_CONFIG_PARAM_GET,
+	PM_PINCTRL_CONFIG_PARAM_SET,
+	PM_IOCTL,
+	/* API to query information from firmware */
+	PM_QUERY_DATA,
+	/* Clock control API functions */
+	PM_CLOCK_ENABLE,
+	PM_CLOCK_DISABLE,
+	PM_CLOCK_GETSTATE,
+	PM_CLOCK_SETDIVIDER,
+	PM_CLOCK_GETDIVIDER,
+	PM_CLOCK_SETRATE,
+	PM_CLOCK_GETRATE,
+	PM_CLOCK_SETPARENT,
+	PM_CLOCK_GETPARENT,
 	PM_API_MAX
 };
 
@@ -79,7 +101,7 @@
 	NODE_RPU,
 	NODE_RPU_0,
 	NODE_RPU_1,
-	NODE_PL,
+	NODE_PLD,
 	NODE_FPD,
 	NODE_OCM_BANK_0,
 	NODE_OCM_BANK_1,
@@ -132,7 +154,23 @@
 	NODE_PCIE,
 	NODE_PCAP,
 	NODE_RTC,
-	NODE_MAX
+	NODE_LPD,
+	NODE_VCU,
+	NODE_IPI_RPU_1,
+	NODE_IPI_PL_0,
+	NODE_IPI_PL_1,
+	NODE_IPI_PL_2,
+	NODE_IPI_PL_3,
+	NODE_PL,
+	NODE_GEM_TSU,
+	NODE_SWDT_0,
+	NODE_SWDT_1,
+	NODE_CSU,
+	NODE_PJTAG,
+	NODE_TRACE,
+	NODE_TESTSCAN,
+	NODE_PMU,
+	NODE_MAX,
 };
 
 enum pm_request_ack {
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index fb64bc5..34b3ad4 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -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
  */
@@ -19,6 +19,7 @@
 #include "pm_ipi.h"
 
 #define PM_GET_CALLBACK_DATA	0xa01
+#define PM_GET_TRUSTZONE_VERSION	0xa03
 
 /* 0 - UP, !0 - DOWN */
 static int32_t pm_down = !0;
@@ -248,6 +249,118 @@
 			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
 	}
 
+	case PM_PINCTRL_REQUEST:
+		ret = pm_pinctrl_request(pm_arg[0]);
+		SMC_RET1(handle, (uint64_t)ret);
+
+	case PM_PINCTRL_RELEASE:
+		ret = pm_pinctrl_release(pm_arg[0]);
+		SMC_RET1(handle, (uint64_t)ret);
+
+	case PM_PINCTRL_GET_FUNCTION:
+	{
+		uint32_t value = 0;
+
+		ret = pm_pinctrl_get_function(pm_arg[0], &value);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+	}
+
+	case PM_PINCTRL_SET_FUNCTION:
+		ret = pm_pinctrl_set_function(pm_arg[0], pm_arg[1]);
+		SMC_RET1(handle, (uint64_t)ret);
+
+	case PM_PINCTRL_CONFIG_PARAM_GET:
+	{
+		uint32_t value;
+
+		ret = pm_pinctrl_get_config(pm_arg[0], pm_arg[1], &value);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+	}
+
+	case PM_PINCTRL_CONFIG_PARAM_SET:
+		ret = pm_pinctrl_set_config(pm_arg[0], pm_arg[1], pm_arg[2]);
+		SMC_RET1(handle, (uint64_t)ret);
+
+	case PM_IOCTL:
+	{
+		uint32_t value;
+
+		ret = pm_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
+			       pm_arg[3], &value);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+	}
+
+	case PM_QUERY_DATA:
+	{
+		uint32_t data[4] = { 0 };
+
+		ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
+				    pm_arg[3], data);
+		SMC_RET2(handle, (uint64_t)data[0]  | ((uint64_t)data[1] << 32),
+			 (uint64_t)data[2] | ((uint64_t)data[3] << 32));
+	}
+
+	case PM_CLOCK_ENABLE:
+		ret = pm_clock_enable(pm_arg[0]);
+		SMC_RET1(handle, (uint64_t)ret);
+
+	case PM_CLOCK_DISABLE:
+		ret = pm_clock_disable(pm_arg[0]);
+		SMC_RET1(handle, (uint64_t)ret);
+
+	case PM_CLOCK_GETSTATE:
+	{
+		uint32_t value;
+
+		ret = pm_clock_getstate(pm_arg[0], &value);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+	}
+
+	case PM_CLOCK_SETDIVIDER:
+		ret = pm_clock_setdivider(pm_arg[0], pm_arg[1]);
+		SMC_RET1(handle, (uint64_t)ret);
+
+	case PM_CLOCK_GETDIVIDER:
+	{
+		uint32_t value;
+
+		ret = pm_clock_getdivider(pm_arg[0], &value);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+	}
+
+	case PM_CLOCK_SETRATE:
+		ret = pm_clock_setrate(pm_arg[0],
+		       ((uint64_t)pm_arg[2]) << 32 | pm_arg[1]);
+
+		SMC_RET1(handle, (uint64_t)ret);
+
+	case PM_CLOCK_GETRATE:
+	{
+		uint64_t value;
+
+		ret = pm_clock_getrate(pm_arg[0], &value);
+		SMC_RET2(handle, (uint64_t)ret |
+				  (((uint64_t)value & 0xFFFFFFFFU) << 32U),
+			 (value >> 32U) & 0xFFFFFFFFU);
+
+	}
+
+	case PM_CLOCK_SETPARENT:
+		ret = pm_clock_setparent(pm_arg[0], pm_arg[1]);
+		SMC_RET1(handle, (uint64_t)ret);
+
+	case PM_CLOCK_GETPARENT:
+	{
+		uint32_t value;
+
+		ret = pm_clock_getparent(pm_arg[0], &value);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
+	}
+
+	case PM_GET_TRUSTZONE_VERSION:
+		SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS |
+			 ((uint64_t)ZYNQMP_TZ_VERSION << 32));
+
 	default:
 		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
diff --git a/plat/xilinx/zynqmp/zynqmp_def.h b/plat/xilinx/zynqmp/zynqmp_def.h
index e90ad02..60df187 100644
--- a/plat/xilinx/zynqmp/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/zynqmp_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,33 +27,36 @@
  * ZYNQMP memory map related constants
  ******************************************************************************/
 /* Aggregate of all devices in the first GB */
-#define DEVICE0_BASE		0xFF000000
-#define DEVICE0_SIZE		0x00E00000
-#define DEVICE1_BASE		0xF9000000
-#define DEVICE1_SIZE		0x00800000
+#define DEVICE0_BASE		U(0xFF000000)
+#define DEVICE0_SIZE		U(0x00E00000)
+#define DEVICE1_BASE		U(0xF9000000)
+#define DEVICE1_SIZE		U(0x00800000)
 
 /* For cpu reset APU space here too 0xFE5F1000 CRF_APB*/
-#define CRF_APB_BASE		0xFD1A0000
-#define CRF_APB_SIZE		0x00600000
+#define CRF_APB_BASE		U(0xFD1A0000)
+#define CRF_APB_SIZE		U(0x00600000)
+#define CRF_APB_CLK_BASE	U(0xFD1A0020)
 
 /* CRF registers and bitfields */
 #define CRF_APB_RST_FPD_APU	(CRF_APB_BASE + 0X00000104)
 
-#define CRF_APB_RST_FPD_APU_ACPU_RESET		(1 << 0)
-#define CRF_APB_RST_FPD_APU_ACPU_PWRON_RESET	(1 << 10)
+#define CRF_APB_RST_FPD_APU_ACPU_RESET		(U(1) << 0)
+#define CRF_APB_RST_FPD_APU_ACPU_PWRON_RESET	(U(1) << 10)
 
 /* CRL registers and bitfields */
-#define CRL_APB_BASE			0xFF5E0000
-#define CRL_APB_RPLL_CTRL		(CRL_APB_BASE + 0x30)
+#define CRL_APB_BASE			U(0xFF5E0000)
 #define CRL_APB_BOOT_MODE_USER		(CRL_APB_BASE + 0x200)
 #define CRL_APB_RESET_CTRL		(CRL_APB_BASE + 0x218)
+#define CRL_APB_RST_LPD_TOP		(CRL_APB_BASE + 0x23C)
+#define CRL_APB_CLK_BASE		U(0xFF5E0020)
 
-#define CRL_APB_RPLL_CTRL_BYPASS	(1 << 3)
+#define CRL_APB_RPU_AMBA_RESET		(U(1) << 2)
+#define CRL_APB_RPLL_CTRL_BYPASS	(U(1) << 3)
 
-#define CRL_APB_RESET_CTRL_SOFT_RESET	(1 << 4)
+#define CRL_APB_RESET_CTRL_SOFT_RESET	(U(1) << 4)
 
-#define CRL_APB_BOOT_MODE_MASK		(0xf << 0)
-#define ZYNQMP_BOOTMODE_JTAG		0
+#define CRL_APB_BOOT_MODE_MASK		(U(0xf) << 0)
+#define ZYNQMP_BOOTMODE_JTAG		U(0)
 
 /* system counter registers and bitfields */
 #define IOU_SCNTRS_BASE			0xFF260000
@@ -174,4 +177,138 @@
 #define ACTLR_EL3_L2ACTLR_BIT	(1 << 6)
 #define ACTLR_EL3_CPUACTLR_BIT	(1 << 0)
 
+#define IOU_SLCR_BASEADDR		U(0xFF180000)
+
+#define ZYNQMP_RPU_GLBL_CNTL			U(0xFF9A0000)
+#define ZYNQMP_RPU0_CFG				U(0xFF9A0100)
+#define ZYNQMP_RPU1_CFG				U(0xFF9A0200)
+#define ZYNQMP_SLSPLIT_MASK			U(0x08)
+#define ZYNQMP_TCM_COMB_MASK			U(0x40)
+#define ZYNQMP_SLCLAMP_MASK			U(0x10)
+#define ZYNQMP_VINITHI_MASK			U(0x04)
+
+/* Tap delay bypass */
+#define IOU_TAPDLY_BYPASS			U(0XFF180390)
+#define TAP_DELAY_MASK				U(0x7)
+
+/* SGMII mode */
+#define IOU_GEM_CTRL				U(0xFF180360)
+#define IOU_GEM_CLK_CTRL			U(0xFF180308)
+#define SGMII_SD_MASK				U(0x3)
+#define SGMII_SD_OFFSET				U(2)
+#define SGMII_PCS_SD_0				U(0x0)
+#define SGMII_PCS_SD_1				U(0x1)
+#define SGMII_PCS_SD_PHY			U(0x2)
+#define GEM_SGMII_MASK				U(0x4)
+#define GEM_CLK_CTRL_MASK			U(0xF)
+#define GEM_CLK_CTRL_OFFSET			U(5)
+#define GEM_RX_SRC_SEL_GTR			U(0x1)
+#define GEM_SGMII_MODE				U(0x4)
+
+/* SD DLL reset */
+#define ZYNQMP_SD_DLL_CTRL			U(0xFF180358)
+#define ZYNQMP_SD0_DLL_RST_MASK			U(0x00000004)
+#define ZYNQMP_SD0_DLL_RST			U(0x00000004)
+#define ZYNQMP_SD1_DLL_RST_MASK			U(0x00040000)
+#define ZYNQMP_SD1_DLL_RST			U(0x00040000)
+
+/* SD tap delay */
+#define ZYNQMP_SD_DLL_CTRL			U(0xFF180358)
+#define ZYNQMP_SD_ITAP_DLY			U(0xFF180314)
+#define ZYNQMP_SD_OTAP_DLY			U(0xFF180318)
+#define ZYNQMP_SD_TAP_OFFSET			U(16)
+#define ZYNQMP_SD_ITAPCHGWIN_MASK		U(0x200)
+#define ZYNQMP_SD_ITAPCHGWIN			U(0x200)
+#define ZYNQMP_SD_ITAPDLYENA_MASK		U(0x100)
+#define ZYNQMP_SD_ITAPDLYENA			U(0x100)
+#define ZYNQMP_SD_ITAPDLYSEL_MASK		U(0xFF)
+#define ZYNQMP_SD_OTAPDLYSEL_MASK		U(0x3F)
+#define ZYNQMP_SD_OTAPDLYENA_MASK		U(0x40)
+#define ZYNQMP_SD_OTAPDLYENA			U(0x40)
+
+/* Clock control registers */
+/* Full power domain clocks */
+#define CRF_APB_APLL_CTRL		(CRF_APB_CLK_BASE + 0x00)
+#define CRF_APB_DPLL_CTRL		(CRF_APB_CLK_BASE + 0x0c)
+#define CRF_APB_VPLL_CTRL		(CRF_APB_CLK_BASE + 0x18)
+#define CRF_APB_PLL_STATUS		(CRF_APB_CLK_BASE + 0x24)
+#define CRF_APB_APLL_TO_LPD_CTRL	(CRF_APB_CLK_BASE + 0x28)
+#define CRF_APB_DPLL_TO_LPD_CTRL	(CRF_APB_CLK_BASE + 0x2c)
+#define CRF_APB_VPLL_TO_LPD_CTRL	(CRF_APB_CLK_BASE + 0x30)
+/* Peripheral clocks */
+#define CRF_APB_ACPU_CTRL		(CRF_APB_CLK_BASE + 0x40)
+#define CRF_APB_DBG_TRACE_CTRL		(CRF_APB_CLK_BASE + 0x44)
+#define CRF_APB_DBG_FPD_CTRL		(CRF_APB_CLK_BASE + 0x48)
+#define CRF_APB_DP_VIDEO_REF_CTRL	(CRF_APB_CLK_BASE + 0x50)
+#define CRF_APB_DP_AUDIO_REF_CTRL	(CRF_APB_CLK_BASE + 0x54)
+#define CRF_APB_DP_STC_REF_CTRL		(CRF_APB_CLK_BASE + 0x5c)
+#define CRF_APB_DDR_CTRL		(CRF_APB_CLK_BASE + 0x60)
+#define CRF_APB_GPU_REF_CTRL		(CRF_APB_CLK_BASE + 0x64)
+#define CRF_APB_SATA_REF_CTRL		(CRF_APB_CLK_BASE + 0x80)
+#define CRF_APB_PCIE_REF_CTRL		(CRF_APB_CLK_BASE + 0x94)
+#define CRF_APB_GDMA_REF_CTRL		(CRF_APB_CLK_BASE + 0x98)
+#define CRF_APB_DPDMA_REF_CTRL		(CRF_APB_CLK_BASE + 0x9c)
+#define CRF_APB_TOPSW_MAIN_CTRL		(CRF_APB_CLK_BASE + 0xa0)
+#define CRF_APB_TOPSW_LSBUS_CTRL	(CRF_APB_CLK_BASE + 0xa4)
+#define CRF_APB_GTGREF0_REF_CTRL	(CRF_APB_CLK_BASE + 0xa8)
+#define CRF_APB_DBG_TSTMP_CTRL		(CRF_APB_CLK_BASE + 0xd8)
+
+/* Low power domain clocks */
+#define CRL_APB_IOPLL_CTRL		(CRL_APB_CLK_BASE + 0x00)
+#define CRL_APB_RPLL_CTRL		(CRL_APB_CLK_BASE + 0x10)
+#define CRL_APB_PLL_STATUS		(CRL_APB_CLK_BASE + 0x20)
+#define CRL_APB_IOPLL_TO_FPD_CTRL	(CRL_APB_CLK_BASE + 0x24)
+#define CRL_APB_RPLL_TO_FPD_CTRL	(CRL_APB_CLK_BASE + 0x28)
+/* Peripheral clocks */
+#define CRL_APB_USB3_DUAL_REF_CTRL	(CRL_APB_CLK_BASE + 0x2c)
+#define CRL_APB_GEM0_REF_CTRL		(CRL_APB_CLK_BASE + 0x30)
+#define CRL_APB_GEM1_REF_CTRL		(CRL_APB_CLK_BASE + 0x34)
+#define CRL_APB_GEM2_REF_CTRL		(CRL_APB_CLK_BASE + 0x38)
+#define CRL_APB_GEM3_REF_CTRL		(CRL_APB_CLK_BASE + 0x3c)
+#define CRL_APB_USB0_BUS_REF_CTRL	(CRL_APB_CLK_BASE + 0x40)
+#define CRL_APB_USB1_BUS_REF_CTRL	(CRL_APB_CLK_BASE + 0x44)
+#define CRL_APB_QSPI_REF_CTRL		(CRL_APB_CLK_BASE + 0x48)
+#define CRL_APB_SDIO0_REF_CTRL		(CRL_APB_CLK_BASE + 0x4c)
+#define CRL_APB_SDIO1_REF_CTRL		(CRL_APB_CLK_BASE + 0x50)
+#define CRL_APB_UART0_REF_CTRL		(CRL_APB_CLK_BASE + 0x54)
+#define CRL_APB_UART1_REF_CTRL		(CRL_APB_CLK_BASE + 0x58)
+#define CRL_APB_SPI0_REF_CTRL		(CRL_APB_CLK_BASE + 0x5c)
+#define CRL_APB_SPI1_REF_CTRL		(CRL_APB_CLK_BASE + 0x60)
+#define CRL_APB_CAN0_REF_CTRL		(CRL_APB_CLK_BASE + 0x64)
+#define CRL_APB_CAN1_REF_CTRL		(CRL_APB_CLK_BASE + 0x68)
+#define CRL_APB_CPU_R5_CTRL		(CRL_APB_CLK_BASE + 0x70)
+#define CRL_APB_IOU_SWITCH_CTRL		(CRL_APB_CLK_BASE + 0x7c)
+#define CRL_APB_CSU_PLL_CTRL		(CRL_APB_CLK_BASE + 0x80)
+#define CRL_APB_PCAP_CTRL		(CRL_APB_CLK_BASE + 0x84)
+#define CRL_APB_LPD_SWITCH_CTRL		(CRL_APB_CLK_BASE + 0x88)
+#define CRL_APB_LPD_LSBUS_CTRL		(CRL_APB_CLK_BASE + 0x8c)
+#define CRL_APB_DBG_LPD_CTRL		(CRL_APB_CLK_BASE + 0x90)
+#define CRL_APB_NAND_REF_CTRL		(CRL_APB_CLK_BASE + 0x94)
+#define CRL_APB_ADMA_REF_CTRL		(CRL_APB_CLK_BASE + 0x98)
+#define CRL_APB_PL0_REF_CTRL		(CRL_APB_CLK_BASE + 0xa0)
+#define CRL_APB_PL1_REF_CTRL		(CRL_APB_CLK_BASE + 0xa4)
+#define CRL_APB_PL2_REF_CTRL		(CRL_APB_CLK_BASE + 0xa8)
+#define CRL_APB_PL3_REF_CTRL		(CRL_APB_CLK_BASE + 0xac)
+#define CRL_APB_PL0_THR_CNT		(CRL_APB_CLK_BASE + 0xb4)
+#define CRL_APB_PL1_THR_CNT		(CRL_APB_CLK_BASE + 0xbc)
+#define CRL_APB_PL2_THR_CNT		(CRL_APB_CLK_BASE + 0xc4)
+#define CRL_APB_PL3_THR_CNT		(CRL_APB_CLK_BASE + 0xdc)
+#define CRL_APB_GEM_TSU_REF_CTRL	(CRL_APB_CLK_BASE + 0xe0)
+#define CRL_APB_DLL_REF_CTRL		(CRL_APB_CLK_BASE + 0xe4)
+#define CRL_APB_AMS_REF_CTRL		(CRL_APB_CLK_BASE + 0xe8)
+#define CRL_APB_I2C0_REF_CTRL		(CRL_APB_CLK_BASE + 0x100)
+#define CRL_APB_I2C1_REF_CTRL		(CRL_APB_CLK_BASE + 0x104)
+#define CRL_APB_TIMESTAMP_REF_CTRL	(CRL_APB_CLK_BASE + 0x108)
+#define IOU_SLCR_GEM_CLK_CTRL		(IOU_SLCR_BASEADDR + 0x308)
+#define IOU_SLCR_CAN_MIO_CTRL		(IOU_SLCR_BASEADDR + 0x304)
+#define IOU_SLCR_WDT_CLK_SEL		(IOU_SLCR_BASEADDR + 0x300)
+
+/* Global general storage register base address */
+#define GGS_BASEADDR		(0xFFD80030U)
+#define GGS_NUM_REGS		U(4)
+
+/* Persistent global general storage register base address */
+#define PGGS_BASEADDR		(0xFFD80050U)
+#define PGGS_NUM_REGS		U(4)
+
 #endif /* __ZYNQMP_DEF_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;
 	}
diff --git a/services/spd/tspd/tspd_private.h b/services/spd/tspd/tspd_private.h
index 8fadb7a..a63daff 100644
--- a/services/spd/tspd/tspd_private.h
+++ b/services/spd/tspd/tspd_private.h
@@ -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
  */
@@ -206,7 +206,7 @@
 /*******************************************************************************
  * Forward declarations
  ******************************************************************************/
-struct tsp_vectors;
+typedef struct tsp_vectors tsp_vectors_t;
 
 /*******************************************************************************
  * Function & Data prototypes
@@ -215,14 +215,26 @@
 void __dead2 tspd_exit_sp(uint64_t c_rt_ctx, uint64_t ret);
 uint64_t tspd_synchronous_sp_entry(tsp_context_t *tsp_ctx);
 void __dead2 tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret);
-void tspd_init_tsp_ep_state(struct entry_point_info *tsp_ep,
+void tspd_init_tsp_ep_state(struct entry_point_info *tsp_entry_point,
 				uint32_t rw,
 				uint64_t pc,
 				tsp_context_t *tsp_ctx);
 int tspd_abort_preempted_smc(tsp_context_t *tsp_ctx);
 
+uint64_t tspd_smc_handler(uint32_t smc_fid,
+			 uint64_t x1,
+			 uint64_t x2,
+			 uint64_t x3,
+			 uint64_t x4,
+			 void *cookie,
+			 void *handle,
+			 uint64_t flags);
+
+int32_t tspd_setup(void);
+uint64_t tspd_handle_sp_preemption(void *handle);
+
 extern tsp_context_t tspd_sp_context[TSPD_CORE_COUNT];
-extern struct tsp_vectors *tsp_vectors;
+extern tsp_vectors_t *tsp_vectors;
 #endif /*__ASSEMBLY__*/
 
 #endif /* __TSPD_PRIVATE_H__ */
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index 6c4e1f0..e0fe494 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -35,7 +35,7 @@
  * Replace the S-EL1 re-entry information with S-EL0 re-entry
  * information
  ******************************************************************************/
-void spm_setup_next_eret_into_sel0(cpu_context_t *secure_context)
+static void spm_setup_next_eret_into_sel0(const cpu_context_t *secure_context)
 {
 	assert(secure_context == cm_get_context(SECURE));
 
@@ -83,14 +83,14 @@
  *    as the generic smc entry routine should have saved those.
  ******************************************************************************/
 static void __dead2 spm_synchronous_sp_exit(
-			secure_partition_context_t *sp_ctx_ptr, uint64_t ret)
+		const secure_partition_context_t *sp_ctx_ptr, uint64_t ret)
 {
 	assert(sp_ctx_ptr != NULL);
 	/* Save the Secure EL1 system register context */
 	assert(cm_get_context(SECURE) == &sp_ctx_ptr->cpu_ctx);
 	cm_el1_sysregs_context_save(SECURE);
 
-	assert(sp_ctx_ptr->c_rt_ctx != 0);
+	assert(sp_ctx_ptr->c_rt_ctx != 0U);
 	spm_secure_partition_exit(sp_ctx_ptr->c_rt_ctx, ret);
 
 	/* Should never reach here */
@@ -104,7 +104,7 @@
  * used. This function performs a synchronous entry into the Secure partition.
  * The SP passes control back to this routine through a SMC.
  ******************************************************************************/
-int32_t spm_init(void)
+static int32_t spm_init(void)
 {
 	entry_point_info_t *secure_partition_ep_info;
 	uint64_t rc;
@@ -116,7 +116,7 @@
 	 * absence is a critical failure.
 	 */
 	secure_partition_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
-	assert(secure_partition_ep_info);
+	assert(secure_partition_ep_info != NULL);
 
 	/*
 	 * Initialise the common context and then overlay the S-EL0 specific
@@ -155,15 +155,15 @@
 {
 	uint32_t ep_attr;
 
-	assert(sp_ep_info);
-	assert(pc);
-	assert(sp_ctx_ptr);
+	assert(sp_ep_info != NULL);
+	assert(pc != 0U);
+	assert(sp_ctx_ptr != NULL);
 
 	cm_set_context(&sp_ctx_ptr->cpu_ctx, SECURE);
 
 	/* initialise an entrypoint to set up the CPU context */
 	ep_attr = SECURE | EP_ST_ENABLE;
-	if (read_sctlr_el3() & SCTLR_EE_BIT)
+	if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0U)
 		ep_attr |= EP_EE_BIG;
 	SET_PARAM_HEAD(sp_ep_info, PARAM_EP, VERSION_1, ep_attr);
 
@@ -192,7 +192,7 @@
 	 * absence is a critical failure.
 	 */
 	secure_partition_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
-	if (!secure_partition_ep_info) {
+	if (secure_partition_ep_info == NULL) {
 		WARN("No SPM provided by BL2 boot loader, Booting device"
 			" without SPM initialization. SMCs destined for SPM"
 			" will return SMC_UNK\n");
@@ -204,7 +204,7 @@
 	 * signalling failure initializing the service. We bail out without
 	 * registering any handlers
 	 */
-	if (!secure_partition_ep_info->pc) {
+	if (secure_partition_ep_info->pc == 0U) {
 		return 1;
 	}
 
@@ -231,9 +231,9 @@
  * The other fields are left as 0 because they are ignored by the function
  * change_mem_attributes().
  */
-static mmap_attr_t smc_attr_to_mmap_attr(unsigned int attributes)
+static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
 {
-	mmap_attr_t tf_attr = 0;
+	unsigned int tf_attr = 0U;
 
 	unsigned int access = (attributes & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
 			      >> SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
@@ -262,11 +262,11 @@
  * This function converts attributes from the Trusted Firmware format into the
  * SMC interface format.
  */
-static int smc_mmap_to_smc_attr(mmap_attr_t attr)
+static unsigned int smc_mmap_to_smc_attr(unsigned int attr)
 {
-	int smc_attr = 0;
+	unsigned int smc_attr = 0U;
 
-	int data_access;
+	unsigned int data_access;
 
 	if ((attr & MT_USER) == 0) {
 		/* No access from EL0. */
@@ -283,28 +283,29 @@
 	smc_attr |= (data_access & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
 		    << SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
 
-	if (attr & MT_EXECUTE_NEVER) {
+	if ((attr & MT_EXECUTE_NEVER) != 0U) {
 		smc_attr |= SP_MEMORY_ATTRIBUTES_NON_EXEC;
 	}
 
 	return smc_attr;
 }
 
-static int spm_memory_attributes_get_smc_handler(uintptr_t base_va)
+static int32_t spm_memory_attributes_get_smc_handler(uintptr_t base_va)
 {
+	uint32_t attributes;
+
 	spin_lock(&mem_attr_smc_lock);
 
-	mmap_attr_t attributes;
 	int rc = get_mem_attributes(secure_partition_xlat_ctx_handle,
 				     base_va, &attributes);
 
 	spin_unlock(&mem_attr_smc_lock);
 
 	/* Convert error codes of get_mem_attributes() into SPM ones. */
-	assert(rc == 0 || rc == -EINVAL);
+	assert((rc == 0) || (rc == -EINVAL));
 
 	if (rc == 0) {
-		return smc_mmap_to_smc_attr(attributes);
+		return (int32_t) smc_mmap_to_smc_attr(attributes);
 	} else {
 		return SPM_INVALID_PARAMETER;
 	}
@@ -316,7 +317,7 @@
 {
 	uintptr_t base_va = (uintptr_t) page_address;
 	size_t size = (size_t) (pages_count * PAGE_SIZE);
-	unsigned int attributes = (unsigned int) smc_attributes;
+	uint32_t attributes = (uint32_t) smc_attributes;
 
 	INFO("  Start address  : 0x%lx\n", base_va);
 	INFO("  Number of pages: %i (%zi bytes)\n", (int) pages_count, size);
@@ -330,7 +331,7 @@
 	spin_unlock(&mem_attr_smc_lock);
 
 	/* Convert error codes of change_mem_attributes() into SPM ones. */
-	assert(ret == 0 || ret == -EINVAL);
+	assert((ret == 0) || (ret == -EINVAL));
 
 	return (ret == 0) ? SPM_SUCCESS : SPM_INVALID_PARAMETER;
 }
@@ -389,7 +390,7 @@
 
 			/* Get a reference to the non-secure context */
 			ns_cpu_context = cm_get_context(NON_SECURE);
-			assert(ns_cpu_context);
+			assert(ns_cpu_context != NULL);
 
 			/* Restore non-secure state */
 			cm_el1_sysregs_context_restore(NON_SECURE);
@@ -435,17 +436,17 @@
 			uint64_t comm_size_address = x3;
 
 			/* Cookie. Reserved for future use. It must be zero. */
-			if (mm_cookie != 0) {
+			if (mm_cookie != 0U) {
 				ERROR("MM_COMMUNICATE: cookie is not zero\n");
 				SMC_RET1(handle, SPM_INVALID_PARAMETER);
 			}
 
-			if (comm_buffer_address == 0) {
+			if (comm_buffer_address == 0U) {
 				ERROR("MM_COMMUNICATE: comm_buffer_address is zero\n");
 				SMC_RET1(handle, SPM_INVALID_PARAMETER);
 			}
 
-			if (comm_size_address != 0) {
+			if (comm_size_address != 0U) {
 				VERBOSE("MM_COMMUNICATE: comm_size_address is not 0 as recommended.\n");
 			}