Merge pull request #1357 from antonio-nino-diaz-arm/an/fix-misra

Fix some MISRA defects in SPM code
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_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/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/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/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/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/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/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/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/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/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/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,15 +304,13 @@
 	hikey_gpio_init();
 	hikey_pmussi_init();
 	hikey_hi6553_init();
+	/* Clear SRAM since it'll be used by MCU right now. */
+	memset((void *)SRAM_BASE, 0, SRAM_SIZE);
 
 	dsb();
-	hikey_ddr_init();
+	hikey_ddr_init(DDR_FREQ_800M);
 	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);
-
 	hikey_boardid_init();
 	init_acpu_dvfs();
 	hikey_rtc_init();
@@ -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,10 +510,337 @@
 		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;
+
 	mmio_write_32((0xf7032000 + 0x580), 0x3);
 	mmio_write_32((0xf7032000 + 0x5a8), 0x11111);
 	data = mmio_read_32((0xf7032000 + 0x104));
@@ -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;
 	}
+	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;
+	}
-	NOTICE("succeed to init lpddr3 rank0 dram phy\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);
+	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;
 }
 
-int lpddr3_freq_init(int freq)
+void ddr_phy_reset(void)
 {
-	unsigned int data;
+	mmio_write_32(0xf7030340, 0xa000);
+	mmio_write_32(0xf7030344, 0xa000);
+}
 
-	if (freq == DDR_FREQ_800M) {
-		set_ddrc_800mhz();
-		INFO("%s, set ddrc 800mhz\n", __func__);
-	} else {
-		set_ddrc_533mhz();
-		INFO("%s, set ddrc 533mhz\n", __func__);
+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;
 	}
+}
 
-	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);
+void lpddrx_save_ddl_para_mission(uint32_t *ddr_ddl_para, unsigned int index)
+{
+	uint32_t value;
+	uint32_t cnt = index;
+	uint32_t i;
 
-	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);
+	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;
 	}
-	mmio_write_32((0xf7128000 + 0x118), 0x44);
-	do {
-		data = mmio_read_32((0xf712c000 + 0x004));
-	} while (data & 1);
+	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;
+}
 
-	data = mmio_read_32((0xf712c000 + 0x008));
-	if (data & 0x7fe) {
-		NOTICE("fail to init ddr3 rank0\n");
-		return -EFAULT;
+int lpddr3_freq_init(int freq)
+{
+	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);
 	}
-	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);
+	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();
+		lpddrx_save_ddl_para_mission((uint32_t *)MEMORY_AXI_DDR_DDL_ADDR,
+					     16 * 3);
+	}
+	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);
+	}
 	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/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/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__ */