Merge pull request #949 from antonio-nino-diaz-arm/an/printf-memory

Reduce code size when building with Trusted Board Boot enabled
diff --git a/.gitignore b/.gitignore
index 2f9c89d..4ece189 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,10 +19,6 @@
 tools/cert_create/cert_create
 tools/cert_create/cert_create.exe
 
-# Ignore header files copied.
-tools/fiptool/firmware_image_package.h
-tools/fiptool/uuid.h
-
 # GNU GLOBAL files
 GPATH
 GRTAGS
diff --git a/Makefile b/Makefile
index 9c0ccc0..c5c281a 100644
--- a/Makefile
+++ b/Makefile
@@ -113,6 +113,9 @@
 # Toolchain
 ################################################################################
 
+HOSTCC			:=	gcc
+export HOSTCC
+
 CC			:=	${CROSS_COMPILE}gcc
 CPP			:=	${CROSS_COMPILE}cpp
 AS			:=	${CROSS_COMPILE}gcc
@@ -123,11 +126,21 @@
 NM			:=	${CROSS_COMPILE}nm
 PP			:=	${CROSS_COMPILE}gcc -E
 
+ifeq ($(notdir $(CC)),armclang)
+TF_CFLAGS_aarch32	=	-target arm-arm-none-eabi -march=armv8-a
+TF_CFLAGS_aarch64	=	-target aarch64-arm-none-eabi -march=armv8-a
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+TF_CFLAGS_aarch32	=	-target armv8a-none-eabi
+TF_CFLAGS_aarch64	=	-target aarch64-elf
+else
+TF_CFLAGS_aarch32	=	-march=armv8-a
+TF_CFLAGS_aarch64	=	-march=armv8-a
+endif
+
-ASFLAGS_aarch64		=	-mgeneral-regs-only
-TF_CFLAGS_aarch64	=	-mgeneral-regs-only -mstrict-align
+TF_CFLAGS_aarch64	+=	-mgeneral-regs-only -mstrict-align
 
 ASFLAGS_aarch32		=	-march=armv8-a
-TF_CFLAGS_aarch32	=	-march=armv8-a
+ASFLAGS_aarch64		=	-march=armv8-a
 
 CPPFLAGS		=	${DEFINES} ${INCLUDES} -nostdinc		\
 				-Wmissing-include-dirs -Werror
@@ -135,8 +148,8 @@
 				-D__ASSEMBLY__ -ffreestanding 			\
 				-Wa,--fatal-warnings
 TF_CFLAGS		+=	$(CPPFLAGS) $(TF_CFLAGS_$(ARCH))		\
-				-ffreestanding -fno-builtin -Wall -std=c99 -Os	\
-				-ffunction-sections -fdata-sections
+				-ffreestanding -fno-builtin -Wall -std=gnu99	\
+				-Os -ffunction-sections -fdata-sections
 
 LDFLAGS			+=	--fatal-warnings -O1
 LDFLAGS			+=	--gc-sections
@@ -180,7 +193,8 @@
 				-Iinclude/plat/common			\
 				-Iinclude/services			\
 				${PLAT_INCLUDES}			\
-				${SPD_INCLUDES}
+				${SPD_INCLUDES}				\
+				-Iinclude/tools_share
 
 
 ################################################################################
@@ -443,6 +457,7 @@
 $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
 $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
 $(eval $(call assert_boolean,USE_COHERENT_MEM))
+$(eval $(call assert_boolean,USE_TBBR_DEFS))
 $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
 
 $(eval $(call assert_numeric,ARM_ARCH_MAJOR))
@@ -481,6 +496,7 @@
 $(eval $(call add_define,SPIN_ON_BL1_EXIT))
 $(eval $(call add_define,TRUSTED_BOARD_BOOT))
 $(eval $(call add_define,USE_COHERENT_MEM))
+$(eval $(call add_define,USE_TBBR_DEFS))
 $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
 
 # Define the EL3_PAYLOAD_BASE flag only if it is provided.
@@ -604,7 +620,7 @@
 
 .PHONY: ${CRTTOOL}
 ${CRTTOOL}:
-	${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH}
+	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} --no-print-directory -C ${CRTTOOLPATH}
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
diff --git a/docs/plat/hikey.md b/docs/plat/hikey.md
new file mode 100644
index 0000000..a5e592b
--- /dev/null
+++ b/docs/plat/hikey.md
@@ -0,0 +1,123 @@
+
+Description
+====================
+  HiKey is one of 96boards. Hisilicon Kirin6220 processor is installed on HiKey.
+
+  More information are listed in [link](https://github.com/96boards/documentation/blob/master/ConsumerEdition/HiKey/Quickstart/README.md).
+
+
+How to build
+====================
+
+1. Code Locations
+-----------------
+
+   * ARM Trusted Firmware:
+   [link](https://github.com/ARM-software/arm-trusted-firmware)
+
+   * edk2:
+   [link](https://github.com/96boards-hikey/edk2/tree/testing/hikey960_v2.5)
+
+   * OpenPlatformPkg:
+   [link](https://github.com/96boards-hikey/OpenPlatformPkg/tree/testing/hikey960_v1.3.4)
+
+   * l-loader:
+   [link](https://github.com/96boards-hikey/l-loader/tree/testing/hikey960_v1.2)
+
+   * uefi-tools:
+   [link](https://github.com/96boards-hikey/uefi-tools/tree/testing/hikey960_v1)
+
+   * atf-fastboot:
+   [link](https://github.com/96boards-hikey/atf-fastboot/tree/master)
+
+
+2. Build Procedure
+------------------
+
+   * Fetch all the above repositories into local host.
+     Make all the repositories in the same ${BUILD_PATH}.
+
+   * Create the symbol link to OpenPlatformPkg in edk2.
+     <br>`$cd ${BUILD_PATH}/edk2`</br>
+     <br>`$ln -sf ../OpenPlatformPkg`</br>
+
+   * Prepare AARCH64 && AARCH32 toolchain. Prepare python.
+
+   * If your hikey hardware is built by CircuitCo, update _uefi-tools/platform.config_ first. _(optional)_
+     <br>__Uncomment the below sentence. Otherwise, UEFI can't output messages on serial
+     console on hikey.__</br>
+     <br>`BUILDFLAGS=-DSERIAL_BASE=0xF8015000`</br>
+     <br>If your hikey hardware is built by LeMarker, nothing to do.</br>
+
+   * Build it as debug mode. Create your own build script file or you could refer to __build_uefi.sh__ in l-loader git repository.
+     <br>`BUILD_OPTION=DEBUG`</br>
+     <br>`export AARCH64_TOOLCHAIN=GCC5`</br>
+     <br>`export UEFI_TOOLS_DIR=${BUILD_PATH}/uefi-tools`<br>
+     <br>`export EDK2_DIR=${BUILD_PATH}/edk2`</br>
+     <br>`EDK2_OUTPUT_DIR=${EDK2_DIR}/Build/HiKey/${BUILD_OPTION}_${AARCH64_TOOLCHAIN}`</br>
+     <br>`# Build fastboot for ARM Trust Firmware. It's used for recovery mode.`</br>
+     <br>`cd ${BUILD_PATH}/atf-fastboot`</br>
+     <br>`CROSS_COMPILE=aarch64-linux-gnu- make PLAT=hikey DEBUG=1`</br>
+     <br>`# Convert DEBUG/RELEASE to debug/release`</br>
+     <br>`FASTBOOT_BUILD_OPTION=$(echo ${BUILD_OPTION} | tr '[A-Z]' '[a-z]')`</br>
+     <br>`cd ${EDK2_DIR}`</br>
+     <br>`# Build UEFI & ARM Trust Firmware`</br>
+     <br>`${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware hikey`</br>
+     <br>`# Generate l-loader.bin`</br>
+     <br>`cd ${BUILD_PATH}/l-loader`</br>
+     <br>`ln -sf ${EDK2_OUTPUT_DIR}/FV/bl1.bin`</br>
+     <br>`ln -sf ${EDK2_OUTPUT_DIR}/FV/fip.bin`</br>
+     <br>`ln -sf ${BUILD_PATH}/atf-fastboot/build/hikey/${FASTBOOT_BUILD_OPTION}/bl1.bin fastboot.bin`</br>
+     <br>`python gen_loader.py -o l-loader.bin --img_bl1=bl1.bin --img_ns_bl1u=BL33_AP_UEFI.fd`</br>
+     <br>`arm-linux-gnueabihf-gcc -c -o start.o start.S`</br>
+     <br>`arm-linux-gnueabihf-ld -Bstatic -Tl-loader.lds -Ttext 0xf9800800 start.o -o loader`</br>
+     <br>`arm-linux-gnueabihf-objcopy -O binary loader temp`</br>
+     <br>`python gen_loader_hikey.py -o l-loader.bin --img_loader=temp --img_bl1=bl1.bin --img_ns_bl1u=fastboot.bin`</br>
+
+   * Generate partition table for aosp. The eMMC capacity is either 4GB or 8GB. Just change "aosp-4g" to "linux-4g" for debian.
+     <br>`$PTABLE=aosp-4g SECTOR_SIZE=512 bash -x generate_ptable.sh`</br>
+
+
+3. Setup Console
+----------------
+
+   * Install ser2net. Use telnet as the console since UEFI fails to display Boot Manager GUI in minicom. __If you don't need Boot Manager GUI, just ignore this section.__
+     <br>`$sudo apt-get install ser2net`</br>
+
+   * Configure ser2net.
+     <br>`$sudo vi /etc/ser2net.conf`</br>
+     <br>Append one line for serial-over-USB in below.</br>
+     <br>_#ser2net.conf_</br>
+     <br>`2004:telnet:0:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT banner`</br>
+
+   * Open the console.
+     <br>`$telnet localhost 2004`</br>
+     <br>And you could open the console remotely, too.</br>
+
+
+4. Flush images in recovery mode
+-----------------------------
+
+   * Make sure Pin3-Pin4 on J15 are connected for recovery mode. Then power on HiKey.
+
+   * Remove the modemmanager package. This package may cause the idt tool failure.
+     <br>`$sudo apt-get purge modemmanager`</br>
+
+   * Run the command to download l-loader.bin into HiKey.
+     <br>`$sudo python hisi-idt.py -d /dev/ttyUSB1 --img1 l-loader.bin`</br>
+
+   * Update images. All aosp or debian images could be fetched from [link](https://builds.96boards.org/).
+     <br>`$sudo fastboot flash ptable prm_ptable.img`</br>
+     <br>`$sudo fastboot flash fastboot fip.bin`</br>
+     <br>`$sudo fastboot flash boot boot.img`</br>
+     <br>`$sudo fastboot flash cache cache.img`</br>
+     <br>`$sudo fastboot flash system system.img`</br>
+     <br>`$sudo fastboot flash userdata userdata.img`</br>
+
+
+5. Boot UEFI in normal mode
+-----------------------------
+
+   * Make sure Pin3-Pin4 on J15 are open for normal boot mode. Then power on HiKey.
+
+   * Reference [link](https://github.com/96boards-hikey/tools-images-hikey960/blob/master/build-from-source/README-ATF-UEFI-build-from-source.md)
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 2379298..5165000 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -74,6 +74,9 @@
 compiler to use for a given Linaro Release. Also, these
 [Linaro instructions][Linaro SW Instructions] provide further guidance.
 
+Optionally, Trusted Firmware can be built using clang or ARM Compiler 6.
+See instructions below on how to switch the default compiler.
+
 In addition, the following optional packages and tools may be needed:
 
 *   `device-tree-compiler` package if you need to rebuild the Flattened Device
@@ -104,6 +107,28 @@
 
         export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-linux-gnueabihf-
 
+    It is possible to build Trusted Firmware using clang or ARM Compiler 6.
+    To do so `CC` needs to point to the clang or armclang binary. Only the
+    compiler is switched; the assembler and linker need to be provided by
+    the GNU toolchain, thus `CROSS_COMPILE` should be set as described above.
+
+    ARM Compiler 6 will be selected when the base name of the path assigned
+    to `CC` matches the string 'armclang'.
+
+    For AArch64 using ARM Compiler 6:
+
+        export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+        make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
+
+    Clang will be selected when the base name of the path assigned to `CC`
+    contains the string 'clang'. This is to allow both clang and clang-X.Y
+    to work.
+
+    For AArch64 using clang:
+
+        export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+        make CC=<path-to-clang>/bin/clang PLAT=<platform> all
+
 *   Change to the root directory of the Trusted Firmware source tree and build.
 
     For AArch64:
@@ -914,7 +939,11 @@
 
     make PLAT=<platform> [DEBUG=1] [V=1] certtool
 
+For platforms that do not require their own IDs in certificate files,
+the generic 'cert_create' tool can be built with the following command:
+
+    make USE_TBBR_DEFS=1 [DEBUG=1] [V=1] certtool
+
-Specifying the platform is mandatory since the tool is platform specific.
 `DEBUG=1` builds the tool in debug mode. `V=1` makes the build process more
 verbose. The following command should be used to obtain help about the tool:
 
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c
index 8b6ca23..e88c7c2 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot.c
@@ -1,12 +1,16 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <auth_mod.h>
 #include <platform_def.h>
+#if USE_TBBR_DEFS
+#include <tbbr_oid.h>
+#else
 #include <platform_oid.h>
+#endif
 #include <stddef.h>
 
 /*
diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h
index af498ca..e652a59 100644
--- a/include/lib/aarch32/arch_helpers.h
+++ b/include/lib/aarch32/arch_helpers.h
@@ -36,8 +36,8 @@
  *  systems for GCC versions < 4.6. Above GCC 4.6, both Little Endian and
  *  Big Endian systems generate the right instruction encoding.
  */
-#if !(__GNUC__ > (4) || __GNUC__ == (4) && __GNUC_MINOR__ >= (6))
-#error "GCC 4.6 or above is required to build AArch32 Trusted Firmware"
+#if !(__clang__ || __GNUC__ > (4) || __GNUC__ == (4) && __GNUC_MINOR__ >= (6))
+#error "clang or GCC 4.6 or above is required to build AArch32 Trusted Firmware"
 #endif
 
 #define _DEFINE_COPROCR_WRITE_FUNC_64(_name, coproc, opc1, CRm)		\
diff --git a/include/lib/cpus/aarch64/cortex_a53.h b/include/lib/cpus/aarch64/cortex_a53.h
index 673f978..10d9ee6 100644
--- a/include/lib/cpus/aarch64/cortex_a53.h
+++ b/include/lib/cpus/aarch64/cortex_a53.h
@@ -42,8 +42,14 @@
  ******************************************************************************/
 #define CPUACTLR_EL1			S3_1_C15_C2_0	/* Instruction def. */
 
-#define CPUACTLR_DTAH			(1 << 24)
-#define CPUACTLR_ENDCCASCI		(1 << 44)
+#define CPUACTLR_ENDCCASCI_SHIFT	44
+#define CPUACTLR_ENDCCASCI		(1 << CPUACTLR_ENDCCASCI_SHIFT)
+#define CPUACTLR_RADIS_SHIFT		27
+#define CPUACTLR_RADIS			(3 << CPUACTLR_RADIS_SHIFT)
+#define CPUACTLR_L1RADIS_SHIFT		25
+#define CPUACTLR_L1RADIS		(3 << CPUACTLR_L1RADIS_SHIFT)
+#define CPUACTLR_DTAH_SHIFT		24
+#define CPUACTLR_DTAH			(1 << CPUACTLR_DTAH_SHIFT)
 
 /*******************************************************************************
  * L2 Auxiliary Control register specific definitions.
diff --git a/include/common/firmware_image_package.h b/include/tools_share/firmware_image_package.h
similarity index 100%
rename from include/common/firmware_image_package.h
rename to include/tools_share/firmware_image_package.h
diff --git a/include/plat/arm/board/common/board_arm_oid.h b/include/tools_share/tbbr_oid.h
similarity index 89%
rename from include/plat/arm/board/common/board_arm_oid.h
rename to include/tools_share/tbbr_oid.h
index fc6cd79..7a34087 100644
--- a/include/plat/arm/board/common/board_arm_oid.h
+++ b/include/tools_share/tbbr_oid.h
@@ -1,21 +1,17 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __BOARD_ARM_OID_H__
-#define __BOARD_ARM_OID_H__
+#ifndef __TBBR_OID_H__
+#define __TBBR_OID_H__
 
 /*
  * The following is a list of OID values defined and reserved by ARM, which
  * are used to define the extension fields of the certificate structure, as
  * defined in the Trusted Board Boot Requirements (TBBR) specification,
  * ARM DEN0006C-1.
- *
- * Non-ARM platform owners that wish to align with the TBBR should define
- * constants with the same name in their own platform port(s), using their
- * own OIDs obtained from the ITU-T.
  */
 
 
@@ -140,4 +136,4 @@
 /* NonTrustedWorldBootloaderHash - BL33 */
 #define NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID	"1.3.6.1.4.1.4128.2100.1201"
 
-#endif /* __BOARD_ARM_OID_H__ */
+#endif /* __TBBR_OID_H__ */
diff --git a/include/lib/stdlib/sys/uuid.h b/include/tools_share/uuid.h
similarity index 100%
rename from include/lib/stdlib/sys/uuid.h
rename to include/tools_share/uuid.h
diff --git a/lib/compiler-rt/builtins/int_lib.h b/lib/compiler-rt/builtins/int_lib.h
index eb5503f..57dfc41 100644
--- a/lib/compiler-rt/builtins/int_lib.h
+++ b/lib/compiler-rt/builtins/int_lib.h
@@ -70,9 +70,6 @@
 /* Include the commonly used internal type definitions. */
 #include "int_types.h"
 
-/* Include internal utility function declarations. */
-#include "int_util.h"
-
 COMPILER_RT_ABI si_int __paritysi2(si_int a);
 COMPILER_RT_ABI si_int __paritydi2(di_int a);
 
diff --git a/lib/compiler-rt/builtins/int_util.c b/lib/compiler-rt/builtins/int_util.c
deleted file mode 100644
index 420d1e2..0000000
--- a/lib/compiler-rt/builtins/int_util.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ===-- int_util.c - Implement internal utilities --------------------------===
- *
- *                     The LLVM Compiler Infrastructure
- *
- * This file is dual licensed under the MIT and the University of Illinois Open
- * Source Licenses. See LICENSE.TXT for details.
- *
- * ===----------------------------------------------------------------------===
- */
-
-#include "int_lib.h"
-#include "int_util.h"
-
-/* NOTE: The definitions in this file are declared weak because we clients to be
- * able to arbitrarily package individual functions into separate .a files. If
- * we did not declare these weak, some link situations might end up seeing
- * duplicate strong definitions of the same symbol.
- *
- * We can't use this solution for kernel use (which may not support weak), but
- * currently expect that when built for kernel use all the functionality is
- * packaged into a single library.
- */
-
-#ifdef KERNEL_USE
-
-NORETURN extern void panic(const char *, ...);
-#ifndef _WIN32
-__attribute__((visibility("hidden")))
-#endif
-void compilerrt_abort_impl(const char *file, int line, const char *function) {
-  panic("%s:%d: abort in %s", file, line, function);
-}
-
-#elif __APPLE__
-
-/* from libSystem.dylib */
-NORETURN extern void __assert_rtn(const char *func, const char *file, int line,
-                                  const char *message);
-
-#ifndef _WIN32
-__attribute__((weak))
-__attribute__((visibility("hidden")))
-#endif
-void compilerrt_abort_impl(const char *file, int line, const char *function) {
-  __assert_rtn(function, file, line, "libcompiler_rt abort");
-}
-
-#else
-
-/* Get the system definition of abort() */
-#include <stdlib.h>
-
-#ifndef _WIN32
-__attribute__((weak))
-__attribute__((visibility("hidden")))
-#endif
-void compilerrt_abort_impl(const char *file, int line, const char *function) {
-  abort();
-}
-
-#endif
diff --git a/lib/compiler-rt/builtins/int_util.h b/lib/compiler-rt/builtins/int_util.h
deleted file mode 100644
index a7b20ed..0000000
--- a/lib/compiler-rt/builtins/int_util.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ===-- int_util.h - internal utility functions ----------------------------===
- *
- *                     The LLVM Compiler Infrastructure
- *
- * This file is dual licensed under the MIT and the University of Illinois Open
- * Source Licenses. See LICENSE.TXT for details.
- *
- * ===-----------------------------------------------------------------------===
- *
- * This file is not part of the interface of this library.
- *
- * This file defines non-inline utilities which are available for use in the
- * library. The function definitions themselves are all contained in int_util.c
- * which will always be compiled into any compiler-rt library.
- *
- * ===-----------------------------------------------------------------------===
- */
-
-#ifndef INT_UTIL_H
-#define INT_UTIL_H
-
-/** \brief Trigger a program abort (or panic for kernel code). */
-#define compilerrt_abort() compilerrt_abort_impl(__FILE__, __LINE__, __func__)
-
-NORETURN void compilerrt_abort_impl(const char *file, int line,
-                                    const char *function);
-
-#define COMPILE_TIME_ASSERT(expr) COMPILE_TIME_ASSERT1(expr, __COUNTER__)
-#define COMPILE_TIME_ASSERT1(expr, cnt) COMPILE_TIME_ASSERT2(expr, cnt)
-#define COMPILE_TIME_ASSERT2(expr, cnt)                                        \
-  typedef char ct_assert_##cnt[(expr) ? 1 : -1] UNUSED
-
-#endif /* INT_UTIL_H */
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 7ad0bc7..2384553 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -259,8 +259,8 @@
 	/*
 	 * Printing errata status requires atomically testing the printed flag.
 	 */
-	stp	x8, x30, [sp, #-16]!
-	mov	x8, x0
+	stp	x19, x30, [sp, #-16]!
+	mov	x19, x0
 
 	/*
 	 * Load pointers to errata lock and printed flag. Call
@@ -270,8 +270,8 @@
 	ldr	x0, [x1, #CPU_ERRATA_LOCK]
 	ldr	x1, [x1, #CPU_ERRATA_PRINTED]
 	bl	errata_needs_reporting
-	mov	x1, x8
-	ldp	x8, x30, [sp], #16
+	mov	x1, x19
+	ldp	x19, x30, [sp], #16
 	cbnz	x0, .Lprint
 #endif
 .Lnoprint:
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 36f220e..34d82c9 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -54,7 +54,7 @@
 # Convenience function for verifying option has a boolean value
 # $(eval $(call assert_boolean,FOO)) will assert FOO is 0 or 1
 define assert_boolean
-    $(and $(patsubst 0,,$(value $(1))),$(patsubst 1,,$(value $(1))),$(error $(1) must be boolean))
+    $(if $(filter-out 0 1,$($1)),$(error $1 must be boolean))
 endef
 
 0-9 := 0 1 2 3 4 5 6 7 8 9
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 18c41e0..a31e59c 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -128,6 +128,9 @@
 # Build option to choose whether Trusted firmware uses Coherent memory or not.
 USE_COHERENT_MEM		:= 1
 
+# Use tbbr_oid.h instead of platform_oid.h
+USE_TBBR_DEFS			= $(ERROR_DEPRECATED)
+
 # Build verbosity
 V				:= 0
 
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index eb1dc8c..5df1cc0 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,12 +7,11 @@
 #include <arm_def.h>
 #include <assert.h>
 #include <platform.h>
-#include <platform_oid.h>
 #include <stdint.h>
 #include <string.h>
+#include <tbbr_oid.h>
 
 /* Weak definition may be overridden in specific platform */
-#pragma weak plat_match_rotpk
 #pragma weak plat_get_nv_ctr
 #pragma weak plat_set_nv_ctr
 
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 449c580..f4df658 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -296,8 +296,6 @@
 	case ARM_PWR_LVL1:
 		ret = (psysr & PSYSR_AFF_L1) ? HW_ON : HW_OFF;
 		break;
-	default:
-		assert(0);
 	}
 
 	return ret;
diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c
index 51d3083..d1e8b9f 100644
--- a/plat/arm/board/fvp/fvp_trusted_boot.c
+++ b/plat/arm/board/fvp/fvp_trusted_boot.c
@@ -1,13 +1,14 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
-#include <platform_oid.h>
 #include <stdint.h>
 #include <string.h>
+#include <tbbr_oid.h>
+
 #include "fvp_def.h"
 
 /*
diff --git a/plat/arm/board/fvp/include/platform_oid.h b/plat/arm/board/fvp/include/platform_oid.h
deleted file mode 100644
index 5ef1580..0000000
--- a/plat/arm/board/fvp/include/platform_oid.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#include "../../../../../include/plat/arm/board/common/board_arm_oid.h"
-
-/*
- * Required platform OIDs
- * (Provided by included header)
- */
diff --git a/plat/arm/board/juno/include/platform_oid.h b/plat/arm/board/juno/include/platform_oid.h
deleted file mode 100644
index 5ef1580..0000000
--- a/plat/arm/board/juno/include/platform_oid.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#include "../../../../../include/plat/arm/board/common/board_arm_oid.h"
-
-/*
- * Required platform OIDs
- * (Provided by included header)
- */
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index ffec664..e5619b7 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -13,6 +13,7 @@
 #include <desc_image_load.h>
 #include <plat_arm.h>
 #include <platform_def.h>
+#include <platform.h>
 #include <string.h>
 #include <utils.h>
 
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 38c8cf8..5cc1a0a 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -91,6 +91,9 @@
 # Enable new version of image loading on ARM platforms
 LOAD_IMAGE_V2			:=	1
 
+# Use generic OID definition (tbbr_oid.h)
+USE_TBBR_DEFS			:=	1
+
 PLAT_INCLUDES		+=	-Iinclude/common/tbbr				\
 				-Iinclude/plat/arm/common
 
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 2369e0c..cc131a9 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -122,9 +122,11 @@
 	if ((entrypoint >= ARM_NS_DRAM1_BASE) && (entrypoint <
 			(ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE)))
 		return PSCI_E_SUCCESS;
+#ifndef AARCH32
 	if ((entrypoint >= ARM_DRAM2_BASE) && (entrypoint <
 			(ARM_DRAM2_BASE + ARM_DRAM2_SIZE)))
 		return PSCI_E_SUCCESS;
+#endif
 
 	return PSCI_E_INVALID_ADDRESS;
 }
diff --git a/plat/common/tbbr/plat_tbbr.c b/plat/common/tbbr/plat_tbbr.c
index 4aa9457..f5a4f31 100644
--- a/plat/common/tbbr/plat_tbbr.c
+++ b/plat/common/tbbr/plat_tbbr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,11 @@
 #include <assert.h>
 #include <auth/auth_mod.h>
 #include <platform.h>
+#if USE_TBBR_DEFS
+#include <tbbr_oid.h>
+#else
 #include <platform_oid.h>
+#endif
 #include <string.h>
 
 /*
diff --git a/plat/hisilicon/hikey/aarch64/hikey_common.c b/plat/hisilicon/hikey/aarch64/hikey_common.c
new file mode 100644
index 0000000..d8a68cf
--- /dev/null
+++ b/plat/hisilicon/hikey/aarch64/hikey_common.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <xlat_tables.h>
+
+#include "../hikey_def.h"
+
+#define MAP_DDR		MAP_REGION_FLAT(DDR_BASE,			\
+					DDR_SIZE,			\
+					MT_DEVICE | MT_RW | MT_NS)
+
+#define MAP_DEVICE	MAP_REGION_FLAT(DEVICE_BASE,			\
+					DEVICE_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_ROM_PARAM	MAP_REGION_FLAT(XG2RAM0_BASE,			\
+					BL1_XG2RAM0_OFFSET,		\
+					MT_DEVICE | MT_RO | MT_SECURE)
+
+#define MAP_SRAM	MAP_REGION_FLAT(SRAM_BASE,			\
+					SRAM_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+/*
+ * BL1 needs to access the areas of MMC_SRAM.
+ * BL1 loads BL2 from eMMC into SRAM before DDR initialized.
+ */
+#define MAP_MMC_SRAM	MAP_REGION_FLAT(HIKEY_BL1_MMC_DESC_BASE,	\
+					HIKEY_BL1_MMC_DESC_SIZE +	\
+					HIKEY_BL1_MMC_DATA_SIZE,	\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * hikey_init_mmu_elx() will give the available subset of that,
+ */
+#if IMAGE_BL1
+static const mmap_region_t hikey_mmap[] = {
+	MAP_DEVICE,
+	MAP_ROM_PARAM,
+	MAP_MMC_SRAM,
+	{0}
+};
+#endif
+
+#if IMAGE_BL2
+static const mmap_region_t hikey_mmap[] = {
+	MAP_DDR,
+	MAP_DEVICE,
+	{0}
+};
+#endif
+
+#if IMAGE_BL31
+static const mmap_region_t hikey_mmap[] = {
+	MAP_DEVICE,
+	MAP_SRAM,
+	{0}
+};
+#endif
+
+/*
+ * Macro generating the code for the function setting up the pagetables as per
+ * the platform memory map & initialize the mmu, for the given exception level
+ */
+#define HIKEY_CONFIGURE_MMU_EL(_el)				\
+	void hikey_init_mmu_el##_el(unsigned long total_base,	\
+				  unsigned long total_size,	\
+				  unsigned long ro_start,	\
+				  unsigned long ro_limit,	\
+				  unsigned long coh_start,	\
+				  unsigned long coh_limit)	\
+	{							\
+	       mmap_add_region(total_base, total_base,		\
+			       total_size,			\
+			       MT_MEMORY | MT_RW | MT_SECURE);	\
+	       mmap_add_region(ro_start, ro_start,		\
+			       ro_limit - ro_start,		\
+			       MT_MEMORY | MT_RO | MT_SECURE);	\
+	       mmap_add_region(coh_start, coh_start,		\
+			       coh_limit - coh_start,		\
+			       MT_DEVICE | MT_RW | MT_SECURE);	\
+	       mmap_add(hikey_mmap);				\
+	       init_xlat_tables();				\
+								\
+	       enable_mmu_el##_el(0);				\
+	}
+
+/* Define EL1 and EL3 variants of the function initialising the MMU */
+HIKEY_CONFIGURE_MMU_EL(1)
+HIKEY_CONFIGURE_MMU_EL(3)
+
+unsigned long plat_get_ns_image_entrypoint(void)
+{
+	return HIKEY_NS_IMAGE_OFFSET;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return 1200000;
+}
diff --git a/plat/hisilicon/hikey/aarch64/hikey_helpers.S b/plat/hisilicon/hikey/aarch64/hikey_helpers.S
new file mode 100644
index 0000000..680c0a1
--- /dev/null
+++ b/plat/hisilicon/hikey/aarch64/hikey_helpers.S
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include "../hikey_def.h"
+
+	.globl	plat_my_core_pos
+	.globl	platform_mem_init
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_report_exception
+	.globl	plat_reset_handler
+
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 * void platform_mem_init(void);
+	 *
+	 * We don't need to carry out any memory initialization
+	 * on HIKEY. The Secure RAM is accessible straight away.
+	 * -----------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize the crash console
+	 * without a C Runtime to print crash report.
+	 * Clobber list : x0, x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+	mov_imm	x0, CRASH_CONSOLE_BASE
+	mov_imm	x1, PL011_UART_CLK_IN_HZ
+	mov_imm	x2, PL011_BAUDRATE
+	b	console_core_init
+endfunc plat_crash_console_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to print a character on the crash
+	 * console without a C Runtime.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, CRASH_CONSOLE_BASE
+	b	console_core_putc
+endfunc plat_crash_console_putc
+
+	/* ---------------------------------------------
+	 * void plat_report_exception(unsigned int type)
+	 * Function to report an unhandled exception
+	 * with platform-specific means.
+	 * On HIKEY platform, it updates the LEDs
+	 * to indicate where we are
+	 * ---------------------------------------------
+	 */
+func plat_report_exception
+	mov	x8, x30
+
+	/* Turn on LED according to x0 (0 -- f) */
+	ldr	x2, =0xf7020000
+	and	x1, x0, #1
+	str	w1, [x2, #4]
+	and	x1, x0, #2
+	str	w1, [x2, #8]
+	and	x1, x0, #4
+	str	w1, [x2, #16]
+	and	x1, x0, #8
+	str	w1, [x2, #32]
+
+	mrs	x2, currentel
+	and	x2, x2, #0xc0
+	/* Check EL1 */
+	cmp	x2, #0x04
+	beq	plat_report_el1
+
+	adr	x4, plat_err_str
+	bl	asm_print_str
+
+	adr	x4, esr_el3_str
+	bl	asm_print_str
+
+	mrs	x4, esr_el3
+	bl	asm_print_hex
+
+	adr	x4, elr_el3_str
+	bl	asm_print_str
+
+	mrs	x4, elr_el3
+	bl	asm_print_hex
+	b	plat_report_end
+
+plat_report_el1:
+	adr	x4, plat_err_str
+	bl	asm_print_str
+
+	adr	x4, esr_el1_str
+	bl	asm_print_str
+
+	mrs	x4, esr_el1
+	bl	asm_print_hex
+
+	adr	x4, elr_el1_str
+	bl	asm_print_str
+
+	mrs	x4, elr_el1
+	bl	asm_print_hex
+plat_report_end:
+	mov	x30, x8
+	ret
+endfunc plat_report_exception
+
+	/* -----------------------------------------------------
+	 * void plat_reset_handler(void);
+	 * -----------------------------------------------------
+	 */
+func plat_reset_handler
+	ret
+endfunc plat_reset_handler
+
+.section .rodata.rev_err_str, "aS"
+plat_err_str:
+	.asciz "\nPlatform exception reporting:"
+esr_el3_str:
+	.asciz "\nESR_EL3: "
+elr_el3_str:
+	.asciz "\nELR_EL3: "
+esr_el1_str:
+	.asciz "\nESR_EL1: "
+elr_el1_str:
+	.asciz "\nELR_EL1: "
diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c
new file mode 100644
index 0000000..b005874
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_bl1_setup.c
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <dw_mmc.h>
+#include <emmc.h>
+#include <errno.h>
+#include <gpio.h>
+#include <hi6220.h>
+#include <hi6553.h>
+#include <mmio.h>
+#include <pl061_gpio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <sp804_delay_timer.h>
+#include <string.h>
+#include <tbbr/tbbr_img_desc.h>
+
+#include "../../bl1/bl1_private.h"
+#include "hikey_def.h"
+#include "hikey_private.h"
+
+/*
+ * Declarations of linker defined symbols which will help us find the layout
+ * of trusted RAM
+ */
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+/* Data structure which holds the extents of the trusted RAM for BL1 */
+static meminfo_t bl1_tzram_layout;
+
+enum {
+	BOOT_NORMAL = 0,
+	BOOT_USB_DOWNLOAD,
+	BOOT_UART_DOWNLOAD,
+};
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+	return &bl1_tzram_layout;
+}
+
+/*
+ * Perform any BL1 specific platform actions.
+ */
+void bl1_early_platform_setup(void)
+{
+	const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
+
+	/* Initialize the console to provide early debug support */
+	console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Allow BL1 to see the whole Trusted RAM */
+	bl1_tzram_layout.total_base = BL1_RW_BASE;
+	bl1_tzram_layout.total_size = BL1_RW_SIZE;
+
+	/* Calculate how much RAM BL1 is using and how much remains free */
+	bl1_tzram_layout.free_base = BL1_RW_BASE;
+	bl1_tzram_layout.free_size = BL1_RW_SIZE;
+	reserve_mem(&bl1_tzram_layout.free_base,
+		    &bl1_tzram_layout.free_size,
+		    BL1_RAM_BASE,
+		    bl1_size);
+
+	INFO("BL1: 0x%lx - 0x%lx [size = %lu]\n", BL1_RAM_BASE, BL1_RAM_LIMIT,
+	     bl1_size);
+}
+
+/*
+ * Perform the very early platform specific architecture setup here. At the
+ * moment this only does basic initialization. Later architectural setup
+ * (bl1_arch_setup()) does not do anything platform specific.
+ */
+void bl1_plat_arch_setup(void)
+{
+	hikey_init_mmu_el3(bl1_tzram_layout.total_base,
+			   bl1_tzram_layout.total_size,
+			   BL1_RO_BASE,
+			   BL1_RO_LIMIT,
+			   BL1_COHERENT_RAM_BASE,
+			   BL1_COHERENT_RAM_LIMIT);
+}
+
+static void hikey_sp804_init(void)
+{
+	uint32_t data;
+
+	/* select the clock of dual timer0 */
+	data = mmio_read_32(AO_SC_TIMER_EN0);
+	while (data & 3) {
+		data &= ~3;
+		data |= 3 << 16;
+		mmio_write_32(AO_SC_TIMER_EN0, data);
+		data = mmio_read_32(AO_SC_TIMER_EN0);
+	}
+	/* enable the pclk of dual timer0 */
+	data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4);
+	while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)) {
+		mmio_write_32(AO_SC_PERIPH_CLKEN4, PCLK_TIMER1 | PCLK_TIMER0);
+		data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4);
+	}
+	/* reset dual timer0 */
+	data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
+	mmio_write_32(AO_SC_PERIPH_RSTEN4, PCLK_TIMER1 | PCLK_TIMER0);
+	do {
+		data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
+	} while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0));
+	/* unreset dual timer0 */
+	mmio_write_32(AO_SC_PERIPH_RSTDIS4, PCLK_TIMER1 | PCLK_TIMER0);
+	do {
+		data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
+	} while ((data & PCLK_TIMER1) || (data & PCLK_TIMER0));
+
+	sp804_timer_init(SP804_TIMER0_BASE, 10, 192);
+}
+
+static void hikey_gpio_init(void)
+{
+	pl061_gpio_init();
+	pl061_gpio_register(GPIO0_BASE, 0);
+	pl061_gpio_register(GPIO1_BASE, 1);
+	pl061_gpio_register(GPIO2_BASE, 2);
+	pl061_gpio_register(GPIO3_BASE, 3);
+	pl061_gpio_register(GPIO4_BASE, 4);
+	pl061_gpio_register(GPIO5_BASE, 5);
+	pl061_gpio_register(GPIO6_BASE, 6);
+	pl061_gpio_register(GPIO7_BASE, 7);
+	pl061_gpio_register(GPIO8_BASE, 8);
+	pl061_gpio_register(GPIO9_BASE, 9);
+	pl061_gpio_register(GPIO10_BASE, 10);
+	pl061_gpio_register(GPIO11_BASE, 11);
+	pl061_gpio_register(GPIO12_BASE, 12);
+	pl061_gpio_register(GPIO13_BASE, 13);
+	pl061_gpio_register(GPIO14_BASE, 14);
+	pl061_gpio_register(GPIO15_BASE, 15);
+	pl061_gpio_register(GPIO16_BASE, 16);
+	pl061_gpio_register(GPIO17_BASE, 17);
+	pl061_gpio_register(GPIO18_BASE, 18);
+	pl061_gpio_register(GPIO19_BASE, 19);
+
+	/* Power on indicator LED (USER_LED1). */
+	gpio_set_direction(32, GPIO_DIR_OUT);	/* LED1 */
+	gpio_set_value(32, GPIO_LEVEL_HIGH);
+	gpio_set_direction(33, GPIO_DIR_OUT);	/* LED2 */
+	gpio_set_value(33, GPIO_LEVEL_LOW);
+	gpio_set_direction(34, GPIO_DIR_OUT);	/* LED3 */
+	gpio_set_direction(35, GPIO_DIR_OUT);	/* LED4 */
+}
+
+static void hikey_pmussi_init(void)
+{
+	uint32_t data;
+
+	/* Initialize PWR_HOLD GPIO */
+	gpio_set_direction(0, GPIO_DIR_OUT);
+	gpio_set_value(0, GPIO_LEVEL_LOW);
+
+	/*
+	 * After reset, PMUSSI stays in reset mode.
+	 * Now make it out of reset.
+	 */
+	mmio_write_32(AO_SC_PERIPH_RSTDIS4,
+		      AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N);
+	do {
+		data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4);
+	} while (data & AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N);
+
+	/* Set PMUSSI clock latency for read operation. */
+	data = mmio_read_32(AO_SC_MCU_SUBSYS_CTRL3);
+	data &= ~AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK;
+	data |= AO_SC_MCU_SUBSYS_CTRL3_RCLK_3;
+	mmio_write_32(AO_SC_MCU_SUBSYS_CTRL3, data);
+
+	/* enable PMUSSI clock */
+	data = AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU |
+	       AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU;
+	mmio_write_32(AO_SC_PERIPH_CLKEN5, data);
+	data = AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI;
+	mmio_write_32(AO_SC_PERIPH_CLKEN4, data);
+
+	gpio_set_value(0, GPIO_LEVEL_HIGH);
+}
+
+static void hikey_hi6553_init(void)
+{
+	uint8_t data;
+
+	mmio_write_8(HI6553_PERI_EN_MARK, 0x1e);
+	mmio_write_8(HI6553_NP_REG_ADJ1, 0);
+	data = DISABLE6_XO_CLK_CONN | DISABLE6_XO_CLK_NFC |
+		DISABLE6_XO_CLK_RF1 | DISABLE6_XO_CLK_RF2;
+	mmio_write_8(HI6553_DISABLE6_XO_CLK, data);
+
+	/* configure BUCK0 & BUCK1 */
+	mmio_write_8(HI6553_BUCK01_CTRL2, 0x5e);
+	mmio_write_8(HI6553_BUCK0_CTRL7, 0x10);
+	mmio_write_8(HI6553_BUCK1_CTRL7, 0x10);
+	mmio_write_8(HI6553_BUCK0_CTRL5, 0x1e);
+	mmio_write_8(HI6553_BUCK1_CTRL5, 0x1e);
+	mmio_write_8(HI6553_BUCK0_CTRL1, 0xfc);
+	mmio_write_8(HI6553_BUCK1_CTRL1, 0xfc);
+
+	/* configure BUCK2 */
+	mmio_write_8(HI6553_BUCK2_REG1, 0x4f);
+	mmio_write_8(HI6553_BUCK2_REG5, 0x99);
+	mmio_write_8(HI6553_BUCK2_REG6, 0x45);
+	mdelay(1);
+	mmio_write_8(HI6553_VSET_BUCK2_ADJ, 0x22);
+	mdelay(1);
+
+	/* configure BUCK3 */
+	mmio_write_8(HI6553_BUCK3_REG3, 0x02);
+	mmio_write_8(HI6553_BUCK3_REG5, 0x99);
+	mmio_write_8(HI6553_BUCK3_REG6, 0x41);
+	mmio_write_8(HI6553_VSET_BUCK3_ADJ, 0x02);
+	mdelay(1);
+
+	/* configure BUCK4 */
+	mmio_write_8(HI6553_BUCK4_REG2, 0x9a);
+	mmio_write_8(HI6553_BUCK4_REG5, 0x99);
+	mmio_write_8(HI6553_BUCK4_REG6, 0x45);
+
+	/* configure LDO20 */
+	mmio_write_8(HI6553_LDO20_REG_ADJ, 0x50);
+
+	mmio_write_8(HI6553_NP_REG_CHG, 0x0f);
+	mmio_write_8(HI6553_CLK_TOP0, 0x06);
+	mmio_write_8(HI6553_CLK_TOP3, 0xc0);
+	mmio_write_8(HI6553_CLK_TOP4, 0x00);
+
+	/* configure LDO7 & LDO10 for SD slot */
+	/* enable LDO7 */
+	data = mmio_read_8(HI6553_LDO7_REG_ADJ);
+	data = (data & 0xf8) | 0x2;
+	mmio_write_8(HI6553_LDO7_REG_ADJ, data);
+	mdelay(5);
+	mmio_write_8(HI6553_ENABLE2_LDO1_8, 1 << 6);
+	mdelay(5);
+	/* enable LDO10 */
+	data = mmio_read_8(HI6553_LDO10_REG_ADJ);
+	data = (data & 0xf8) | 0x5;
+	mmio_write_8(HI6553_LDO10_REG_ADJ, data);
+	mdelay(5);
+	mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 1);
+	mdelay(5);
+	/* enable LDO15 */
+	data = mmio_read_8(HI6553_LDO15_REG_ADJ);
+	data = (data & 0xf8) | 0x4;
+	mmio_write_8(HI6553_LDO15_REG_ADJ, data);
+	mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 6);
+	mdelay(5);
+	/* enable LDO19 */
+	data = mmio_read_8(HI6553_LDO19_REG_ADJ);
+	data |= 0x7;
+	mmio_write_8(HI6553_LDO19_REG_ADJ, data);
+	mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 2);
+	mdelay(5);
+	/* enable LDO21 */
+	data = mmio_read_8(HI6553_LDO21_REG_ADJ);
+	data = (data & 0xf8) | 0x3;
+	mmio_write_8(HI6553_LDO21_REG_ADJ, data);
+	mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 4);
+	mdelay(5);
+	/* enable LDO22 */
+	data = mmio_read_8(HI6553_LDO22_REG_ADJ);
+	data = (data & 0xf8) | 0x7;
+	mmio_write_8(HI6553_LDO22_REG_ADJ, data);
+	mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 5);
+	mdelay(5);
+
+	/* select 32.764KHz */
+	mmio_write_8(HI6553_CLK19M2_600_586_EN, 0x01);
+}
+
+static void init_mmc0_pll(void)
+{
+	unsigned int data;
+
+	/* select SYSPLL as the source of MMC0 */
+	/* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */
+	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 5 | 1 << 21);
+	do {
+		data = mmio_read_32(PERI_SC_CLK_SEL0);
+	} while (!(data & (1 << 5)));
+	/* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */
+	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 29);
+	do {
+		data = mmio_read_32(PERI_SC_CLK_SEL0);
+	} while (data & (1 << 13));
+
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 0));
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (!(data & (1 << 0)));
+
+	data = mmio_read_32(PERI_SC_PERIPH_CLKEN12);
+	data |= 1 << 1;
+	mmio_write_32(PERI_SC_PERIPH_CLKEN12, data);
+
+	do {
+		mmio_write_32(PERI_SC_CLKCFG8BIT1, (1 << 7) | 0xb);
+		data = mmio_read_32(PERI_SC_CLKCFG8BIT1);
+	} while ((data & 0xb) != 0xb);
+}
+
+static void reset_mmc0_clk(void)
+{
+	unsigned int data;
+
+	/* disable mmc0 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (data & PERI_CLK0_MMC0);
+	/* enable mmc0 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (!(data & PERI_CLK0_MMC0));
+	/* reset mmc0 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0);
+
+	/* bypass mmc0 clock phase */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
+	data |= 3;
+	mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
+
+	/* disable low power */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
+	data |= 1 << 3;
+	mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (!(data & PERI_RST0_MMC0));
+
+	/* unreset mmc0 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (data & PERI_RST0_MMC0);
+}
+
+static void init_media_clk(void)
+{
+	unsigned int data, value;
+
+	data = mmio_read_32(PMCTRL_MEDPLLCTRL);
+	data |= 1;
+	mmio_write_32(PMCTRL_MEDPLLCTRL, data);
+
+	for (;;) {
+		data = mmio_read_32(PMCTRL_MEDPLLCTRL);
+		value = 1 << 28;
+		if ((data & value) == value)
+			break;
+	}
+
+	data = mmio_read_32(PERI_SC_PERIPH_CLKEN12);
+	data = 1 << 10;
+	mmio_write_32(PERI_SC_PERIPH_CLKEN12, data);
+}
+
+static void init_mmc1_pll(void)
+{
+	uint32_t data;
+
+	/* select SYSPLL as the source of MMC1 */
+	/* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */
+	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 11 | 1 << 27);
+	do {
+		data = mmio_read_32(PERI_SC_CLK_SEL0);
+	} while (!(data & (1 << 11)));
+	/* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */
+	mmio_write_32(PERI_SC_CLK_SEL0, 1 << 30);
+	do {
+		data = mmio_read_32(PERI_SC_CLK_SEL0);
+	} while (data & (1 << 14));
+
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 1));
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (!(data & (1 << 1)));
+
+	data = mmio_read_32(PERI_SC_PERIPH_CLKEN12);
+	data |= 1 << 2;
+	mmio_write_32(PERI_SC_PERIPH_CLKEN12, data);
+
+	do {
+		/* 1.2GHz / 50 = 24MHz */
+		mmio_write_32(PERI_SC_CLKCFG8BIT2, 0x31 | (1 << 7));
+		data = mmio_read_32(PERI_SC_CLKCFG8BIT2);
+	} while ((data & 0x31) != 0x31);
+}
+
+static void reset_mmc1_clk(void)
+{
+	unsigned int data;
+
+	/* disable mmc1 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC1);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (data & PERI_CLK0_MMC1);
+	/* enable mmc1 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC1);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (!(data & PERI_CLK0_MMC1));
+	/* reset mmc1 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC1);
+
+	/* bypass mmc1 clock phase */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
+	data |= 3 << 2;
+	mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
+
+	/* disable low power */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
+	data |= 1 << 4;
+	mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (!(data & PERI_RST0_MMC1));
+
+	/* unreset mmc0 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC1);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (data & PERI_RST0_MMC1);
+}
+
+/* Initialize PLL of both eMMC and SD controllers. */
+static void hikey_mmc_pll_init(void)
+{
+	init_mmc0_pll();
+	reset_mmc0_clk();
+	init_media_clk();
+
+	dsb();
+
+	init_mmc1_pll();
+	reset_mmc1_clk();
+}
+
+/*
+ * Function which will perform any remaining platform-specific setup that can
+ * occur after the MMU and data cache have been enabled.
+ */
+void bl1_platform_setup(void)
+{
+	dw_mmc_params_t params;
+
+	assert((HIKEY_BL1_MMC_DESC_BASE >= SRAM_BASE) &&
+	       ((SRAM_BASE + SRAM_SIZE) >=
+		(HIKEY_BL1_MMC_DATA_BASE + HIKEY_BL1_MMC_DATA_SIZE)));
+	hikey_sp804_init();
+	hikey_gpio_init();
+	hikey_pmussi_init();
+	hikey_hi6553_init();
+
+	hikey_mmc_pll_init();
+
+	memset(&params, 0, sizeof(dw_mmc_params_t));
+	params.reg_base = DWMMC0_BASE;
+	params.desc_base = HIKEY_BL1_MMC_DESC_BASE;
+	params.desc_size = 1 << 20;
+	params.clk_rate = 24 * 1000 * 1000;
+	params.bus_width = EMMC_BUS_WIDTH_8;
+	params.flags = EMMC_FLAG_CMD23;
+	dw_mmc_init(&params);
+
+	hikey_io_setup();
+}
+
+/*
+ * The following function checks if Firmware update is needed,
+ * by checking if TOC in FIP image is valid or not.
+ */
+unsigned int bl1_plat_get_next_image_id(void)
+{
+	int32_t boot_mode;
+	unsigned int ret;
+
+	boot_mode = mmio_read_32(ONCHIPROM_PARAM_BASE);
+	switch (boot_mode) {
+	case BOOT_NORMAL:
+		ret = BL2_IMAGE_ID;
+		break;
+	case BOOT_USB_DOWNLOAD:
+	case BOOT_UART_DOWNLOAD:
+		ret = NS_BL1U_IMAGE_ID;
+		break;
+	default:
+		WARN("Invalid boot mode is found:%d\n", boot_mode);
+		panic();
+	}
+	return ret;
+}
+
+image_desc_t *bl1_plat_get_image_desc(unsigned int image_id)
+{
+	unsigned int index = 0;
+
+	while (bl1_tbbr_image_descs[index].image_id != INVALID_IMAGE_ID) {
+		if (bl1_tbbr_image_descs[index].image_id == image_id)
+			return &bl1_tbbr_image_descs[index];
+
+		index++;
+	}
+
+	return NULL;
+}
+
+void bl1_plat_set_ep_info(unsigned int image_id,
+		entry_point_info_t *ep_info)
+{
+	unsigned int data = 0;
+
+	if (image_id == BL2_IMAGE_ID)
+		return;
+	inv_dcache_range(NS_BL1U_BASE, NS_BL1U_SIZE);
+	__asm__ volatile ("mrs	%0, cpacr_el1" : "=r"(data));
+	do {
+		data |= 3 << 20;
+		__asm__ volatile ("msr	cpacr_el1, %0" : : "r"(data));
+		__asm__ volatile ("mrs	%0, cpacr_el1" : "=r"(data));
+	} while ((data & (3 << 20)) != (3 << 20));
+	INFO("cpacr_el1:0x%x\n", data);
+
+	ep_info->args.arg0 = 0xffff & read_mpidr();
+	ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+				DISABLE_ALL_EXCEPTIONS);
+}
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
new file mode 100644
index 0000000..9e9909b
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <dw_mmc.h>
+#include <emmc.h>
+#include <errno.h>
+#include <hi6220.h>
+#include <hisi_mcu.h>
+#include <hisi_sram_map.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <sp804_delay_timer.h>
+#include <string.h>
+
+#include "hikey_def.h"
+#include "hikey_private.h"
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL2_RO_BASE (unsigned long)(&__RO_START__)
+#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+
+typedef struct bl2_to_bl31_params_mem {
+	bl31_params_t		bl31_params;
+	image_info_t		bl31_image_info;
+	image_info_t		bl32_image_info;
+	image_info_t		bl33_image_info;
+	entry_point_info_t	bl33_ep_info;
+	entry_point_info_t	bl32_ep_info;
+	entry_point_info_t	bl31_ep_info;
+} bl2_to_bl31_params_mem_t;
+
+static bl2_to_bl31_params_mem_t bl31_params_mem;
+
+meminfo_t *bl2_plat_sec_mem_layout(void)
+{
+	return &bl2_tzram_layout;
+}
+
+void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
+{
+	scp_bl2_meminfo->total_base = SCP_BL2_BASE;
+	scp_bl2_meminfo->total_size = SCP_BL2_SIZE;
+	scp_bl2_meminfo->free_base = SCP_BL2_BASE;
+	scp_bl2_meminfo->free_size = SCP_BL2_SIZE;
+}
+
+int bl2_plat_handle_scp_bl2(struct image_info *scp_bl2_image_info)
+{
+	/* Enable MCU SRAM */
+	hisi_mcu_enable_sram();
+
+	/* Load MCU binary into SRAM */
+	hisi_mcu_load_image(scp_bl2_image_info->image_base,
+			    scp_bl2_image_info->image_size);
+	/* Let MCU running */
+	hisi_mcu_start_run();
+
+	INFO("%s: MCU PC is at 0x%x\n",
+	     __func__, mmio_read_32(AO_SC_MCU_SUBSYS_STAT2));
+	INFO("%s: AO_SC_PERIPH_CLKSTAT4 is 0x%x\n",
+	     __func__, mmio_read_32(AO_SC_PERIPH_CLKSTAT4));
+	return 0;
+}
+
+bl31_params_t *bl2_plat_get_bl31_params(void)
+{
+	bl31_params_t *bl2_to_bl31_params = NULL;
+
+	/*
+	 * Initialise the memory for all the arguments that needs to
+	 * be passed to BL3-1
+	 */
+	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
+
+	/* Assign memory for TF related information */
+	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
+	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
+
+	/* Fill BL3-1 related information */
+	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
+		VERSION_1, 0);
+
+	/* Fill BL3-2 related information if it exists */
+#if BL32_BASE
+	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
+		VERSION_1, 0);
+	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
+		VERSION_1, 0);
+#endif
+
+	/* Fill BL3-3 related information */
+	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
+		PARAM_EP, VERSION_1, 0);
+
+	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
+	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
+
+	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
+		VERSION_1, 0);
+
+	return bl2_to_bl31_params;
+}
+
+struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
+{
+	return &bl31_params_mem.bl31_ep_info;
+}
+
+void bl2_plat_set_bl31_ep_info(image_info_t *image,
+			       entry_point_info_t *bl31_ep_info)
+{
+	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
+	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+				       DISABLE_ALL_EXCEPTIONS);
+}
+
+void bl2_plat_set_bl33_ep_info(image_info_t *image,
+			       entry_point_info_t *bl33_ep_info)
+{
+	unsigned long el_status;
+	unsigned int mode;
+
+	/* Figure out what mode we enter the non-secure world in */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	if (el_status)
+		mode = MODE_EL2;
+	else
+		mode = MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
+				       DISABLE_ALL_EXCEPTIONS);
+	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+}
+
+void bl2_plat_flush_bl31_params(void)
+{
+	flush_dcache_range((unsigned long)&bl31_params_mem,
+			   sizeof(bl2_to_bl31_params_mem_t));
+}
+
+void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
+{
+	bl33_meminfo->total_base = DDR_BASE;
+	bl33_meminfo->total_size = DDR_SIZE;
+	bl33_meminfo->free_base = DDR_BASE;
+	bl33_meminfo->free_size = DDR_SIZE;
+}
+
+static void reset_dwmmc_clk(void)
+{
+	unsigned int data;
+
+	/* disable mmc0 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (data & PERI_CLK0_MMC0);
+	/* enable mmc0 bus clock */
+	mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0);
+	} while (!(data & PERI_CLK0_MMC0));
+	/* reset mmc0 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0);
+
+	/* bypass mmc0 clock phase */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL2);
+	data |= 3;
+	mmio_write_32(PERI_SC_PERIPH_CTRL2, data);
+
+	/* disable low power */
+	data = mmio_read_32(PERI_SC_PERIPH_CTRL13);
+	data |= 1 << 3;
+	mmio_write_32(PERI_SC_PERIPH_CTRL13, data);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (!(data & PERI_RST0_MMC0));
+
+	/* unreset mmc0 clock domain */
+	mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0);
+	do {
+		data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0);
+	} while (data & PERI_RST0_MMC0);
+}
+
+static void hikey_boardid_init(void)
+{
+	u_register_t midr;
+
+	midr = read_midr();
+	mmio_write_32(MEMORY_AXI_CHIP_ADDR, midr);
+	INFO("[BDID] [%x] midr: 0x%x\n", MEMORY_AXI_CHIP_ADDR,
+	     (unsigned int)midr);
+
+	mmio_write_32(MEMORY_AXI_BOARD_TYPE_ADDR, 0);
+	mmio_write_32(MEMORY_AXI_BOARD_ID_ADDR, 0x2b);
+
+	mmio_write_32(ACPU_ARM64_FLAGA, 0x1234);
+	mmio_write_32(ACPU_ARM64_FLAGB, 0x5678);
+}
+
+static void hikey_sd_init(void)
+{
+	/* switch pinmux to SD */
+	mmio_write_32(IOMG_SD_CLK, IOMG_MUX_FUNC0);
+	mmio_write_32(IOMG_SD_CMD, IOMG_MUX_FUNC0);
+	mmio_write_32(IOMG_SD_DATA0, IOMG_MUX_FUNC0);
+	mmio_write_32(IOMG_SD_DATA1, IOMG_MUX_FUNC0);
+	mmio_write_32(IOMG_SD_DATA2, IOMG_MUX_FUNC0);
+	mmio_write_32(IOMG_SD_DATA3, IOMG_MUX_FUNC0);
+
+	mmio_write_32(IOCG_SD_CLK, IOCG_INPUT_16MA);
+	mmio_write_32(IOCG_SD_CMD, IOCG_INPUT_12MA);
+	mmio_write_32(IOCG_SD_DATA0, IOCG_INPUT_12MA);
+	mmio_write_32(IOCG_SD_DATA1, IOCG_INPUT_12MA);
+	mmio_write_32(IOCG_SD_DATA2, IOCG_INPUT_12MA);
+	mmio_write_32(IOCG_SD_DATA3, IOCG_INPUT_12MA);
+
+	/* set SD Card detect as nopull */
+	mmio_write_32(IOCG_GPIO8, 0);
+}
+
+static void hikey_jumper_init(void)
+{
+	/* set jumper detect as nopull */
+	mmio_write_32(IOCG_GPIO24, 0);
+	/* set jumper detect as GPIO */
+	mmio_write_32(IOMG_GPIO24, IOMG_MUX_FUNC0);
+}
+
+void bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+	dw_mmc_params_t params;
+
+	/* Initialize the console to provide early debug support */
+	console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Setup the BL2 memory layout */
+	bl2_tzram_layout = *mem_layout;
+
+	/* Clear SRAM since it'll be used by MCU right now. */
+	memset((void *)SRAM_BASE, 0, SRAM_SIZE);
+
+	sp804_timer_init(SP804_TIMER0_BASE, 10, 192);
+	dsb();
+	hikey_ddr_init();
+
+	hikey_boardid_init();
+	init_acpu_dvfs();
+	hikey_sd_init();
+	hikey_jumper_init();
+
+	reset_dwmmc_clk();
+	memset(&params, 0, sizeof(dw_mmc_params_t));
+	params.reg_base = DWMMC0_BASE;
+	params.desc_base = HIKEY_MMC_DESC_BASE;
+	params.desc_size = 1 << 20;
+	params.clk_rate = 24 * 1000 * 1000;
+	params.bus_width = EMMC_BUS_WIDTH_8;
+	params.flags = EMMC_FLAG_CMD23;
+	dw_mmc_init(&params);
+
+	hikey_io_setup();
+}
+
+void bl2_plat_arch_setup(void)
+{
+	hikey_init_mmu_el1(bl2_tzram_layout.total_base,
+			   bl2_tzram_layout.total_size,
+			   BL2_RO_BASE,
+			   BL2_RO_LIMIT,
+			   BL2_COHERENT_RAM_BASE,
+			   BL2_COHERENT_RAM_LIMIT);
+}
+
+void bl2_platform_setup(void)
+{
+}
diff --git a/plat/hisilicon/hikey/hikey_bl31_setup.c b/plat/hisilicon/hikey/hikey_bl31_setup.c
new file mode 100644
index 0000000..9a1114a
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_bl31_setup.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <cci.h>
+#include <console.h>
+#include <debug.h>
+#include <errno.h>
+#include <gicv2.h>
+#include <hi6220.h>
+#include <hisi_ipc.h>
+#include <hisi_pwrc.h>
+#include <platform_def.h>
+
+#include "hikey_def.h"
+#include "hikey_private.h"
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL31_RO_BASE (unsigned long)(&__RO_START__)
+#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
+
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+
+static entry_point_info_t bl32_ep_info;
+static entry_point_info_t bl33_ep_info;
+
+/******************************************************************************
+ * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
+ * interrupts.
+ *****************************************************************************/
+const unsigned int g0_interrupt_array[] = {
+	IRQ_SEC_PHY_TIMER,
+	IRQ_SEC_SGI_0
+};
+
+/*
+ * Ideally `arm_gic_data` structure definition should be a `const` but it is
+ * kept as modifiable for overwriting with different GICD and GICC base when
+ * running on FVP with VE memory map.
+ */
+gicv2_driver_data_t hikey_gic_data = {
+	.gicd_base = PLAT_ARM_GICD_BASE,
+	.gicc_base = PLAT_ARM_GICC_BASE,
+	.g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array),
+	.g0_interrupt_array = g0_interrupt_array,
+};
+
+static const int cci_map[] = {
+	CCI400_SL_IFACE3_CLUSTER_IX,
+	CCI400_SL_IFACE4_CLUSTER_IX
+};
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+	entry_point_info_t *next_image_info;
+
+	next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
+
+	/* None of the images on this platform can have 0x0 as the entrypoint */
+	if (next_image_info->pc)
+		return next_image_info;
+	return NULL;
+}
+
+void bl31_early_platform_setup(bl31_params_t *from_bl2,
+			       void *plat_params_from_bl2)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(CONSOLE_BASE, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Initialize CCI driver */
+	cci_init(CCI400_BASE, cci_map, ARRAY_SIZE(cci_map));
+
+	/*
+	 * Copy BL3-2 and BL3-3 entry point information.
+	 * They are stored in Secure RAM, in BL2's address space.
+	 */
+	bl32_ep_info = *from_bl2->bl32_ep_info;
+	bl33_ep_info = *from_bl2->bl33_ep_info;
+}
+
+void bl31_plat_arch_setup(void)
+{
+	hikey_init_mmu_el3(BL31_BASE,
+			   BL31_LIMIT - BL31_BASE,
+			   BL31_RO_BASE,
+			   BL31_RO_LIMIT,
+			   BL31_COHERENT_RAM_BASE,
+			   BL31_COHERENT_RAM_LIMIT);
+}
+
+void bl31_platform_setup(void)
+{
+	/* Initialize the GIC driver, cpu and distributor interfaces */
+	gicv2_driver_init(&hikey_gic_data);
+	gicv2_distif_init();
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+
+	hisi_ipc_init();
+	hisi_pwrc_setup();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+}
diff --git a/plat/hisilicon/hikey/hikey_ddr.c b/plat/hisilicon/hikey/hikey_ddr.c
new file mode 100644
index 0000000..6328eb6
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_ddr.c
@@ -0,0 +1,967 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
+#include <hi6220.h>
+#include <hi6553.h>
+#include <mmio.h>
+#include <sp804_delay_timer.h>
+
+enum {
+	DDR_FREQ_533M = 0,
+	DDR_FREQ_800M,
+};
+
+static void init_pll(void)
+{
+	unsigned int data;
+
+	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)));
+
+	data = mmio_read_32((0xf7800000 + 0x000));
+	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);
+	mmio_write_32(0xf7032000 + 0x02c, 0x5110103e);
+	data = mmio_read_32(0xf7032000 + 0x050);
+	data |= 1 << 28;
+	mmio_write_32(0xf7032000 + 0x050, data);
+	mmio_write_32(PERI_SC_PERIPH_CTRL14, 0x2101);
+	mdelay(1);
+	data = mmio_read_32(PERI_SC_PERIPH_STAT1);
+	NOTICE("syspll frequency:%dHz\n", data);
+}
+
+static void init_freq(void)
+{
+	unsigned int data, tmp;
+	unsigned int cpuext_cfg, ddr_cfg;
+
+	mmio_write_32((0xf7032000 + 0x374), 0x4a);
+	mmio_write_32((0xf7032000 + 0x368), 0xda);
+	mmio_write_32((0xf7032000 + 0x36c), 0x01);
+	mmio_write_32((0xf7032000 + 0x370), 0x01);
+	mmio_write_32((0xf7032000 + 0x360), 0x60);
+	mmio_write_32((0xf7032000 + 0x364), 0x60);
+
+	mmio_write_32((0xf7032000 + 0x114), 0x1000);
+
+	data = mmio_read_32((0xf7032000 + 0x110));
+	data |= (3 << 12);
+	mmio_write_32((0xf7032000 + 0x110), data);
+
+	data = mmio_read_32((0xf7032000 + 0x110));
+	data |= (1 << 4);
+	mmio_write_32((0xf7032000 + 0x110), data);
+
+
+	data = mmio_read_32((0xf7032000 + 0x110));
+	data &= ~0x7;
+	data |= 0x5;
+	mmio_write_32((0xf7032000 + 0x110), data);
+	dsb();
+	mdelay(10);
+
+
+	do {
+		data = mmio_read_32((0xf6504000 + 0x008));
+		data &= (3 << 20);
+	} while (data != (3 << 20));
+	dsb();
+	mdelay(10);
+
+
+	data = mmio_read_32((0xf6504000 + 0x054));
+	data &= ~((1 << 0) | (1 << 11));
+	mmio_write_32((0xf6504000 + 0x054), data);
+	mdelay(10);
+
+	data = mmio_read_32((0xf7032000 + 0x104));
+	data &= ~(3 << 8);
+	data |= (1 << 8);
+	mmio_write_32((0xf7032000 + 0x104), data);
+
+	data = mmio_read_32((0xf7032000 + 0x100));
+	data |= (1 << 0);
+	mmio_write_32((0xf7032000 + 0x100), data);
+	dsb();
+
+	do {
+		data = mmio_read_32((0xf7032000 + 0x100));
+		data &= (1 << 2);
+	} while (data != (1 << 2));
+
+	data = mmio_read_32((0xf6504000 + 0x06c));
+	data &= ~0xffff;
+	data |= 0x56;
+	mmio_write_32((0xf6504000 + 0x06c), data);
+
+	data = mmio_read_32((0xf6504000 + 0x06c));
+	data &= ~(0xffffff << 8);
+	data |= 0xc7a << 8;
+	mmio_write_32((0xf6504000 + 0x06c), data);
+
+	data = mmio_read_32((0xf6504000 + 0x058));
+	data &= ((1 << 13) - 1);
+	data |= 0xccb;
+	mmio_write_32((0xf6504000 + 0x058), data);
+
+	mmio_write_32((0xf6504000 + 0x060), 0x1fff);
+	mmio_write_32((0xf6504000 + 0x064), 0x1ffffff);
+	mmio_write_32((0xf6504000 + 0x068), 0x7fffffff);
+	mmio_write_32((0xf6504000 + 0x05c), 0x1);
+
+	data = mmio_read_32((0xf6504000 + 0x054));
+	data &= ~(0xf << 12);
+	data |= 1 << 12;
+	mmio_write_32((0xf6504000 + 0x054), data);
+	dsb();
+
+
+	data = mmio_read_32((0xf7032000 + 0x000));
+	data &= ~(1 << 0);
+	mmio_write_32((0xf7032000 + 0x000), data);
+
+	mmio_write_32((0xf7032000 + 0x004), 0x5110207d);
+	mmio_write_32((0xf7032000 + 0x134), 0x10000005);
+	data = mmio_read_32((0xf7032000 + 0x134));
+
+
+	data = mmio_read_32((0xf7032000 + 0x000));
+	data |= (1 << 0);
+	mmio_write_32((0xf7032000 + 0x000), data);
+
+	mmio_write_32((0xf7032000 + 0x368), 0x100da);
+	data = mmio_read_32((0xf7032000 + 0x378));
+	data &= ~((1 << 7) - 1);
+	data |= 0x6b;
+	mmio_write_32((0xf7032000 + 0x378), data);
+	dsb();
+	do {
+		data = mmio_read_32((0xf7032000 + 0x378));
+		tmp = data & 0x7f;
+		data = (data & (0x7f << 8)) >> 8;
+		if (data != tmp)
+			continue;
+		data = mmio_read_32((0xf7032000 + 0x37c));
+	} while (!(data & 1));
+
+	data = mmio_read_32((0xf7032000 + 0x104));
+	data &= ~((3 << 0) |
+			(3 << 8));
+	cpuext_cfg = 1;
+	ddr_cfg = 1;
+	data |= cpuext_cfg | (ddr_cfg << 8);
+	mmio_write_32((0xf7032000 + 0x104), data);
+	dsb();
+
+	do {
+		data = mmio_read_32((0xf7032000 + 0x104));
+		tmp = (data & (3 << 16)) >> 16;
+		if (cpuext_cfg != tmp)
+			continue;
+		tmp = (data & (3 << 24)) >> 24;
+		if (ddr_cfg != tmp)
+			continue;
+		data = mmio_read_32((0xf7032000 + 0x000));
+		data &= 1 << 28;
+	} while (!data);
+
+	data = mmio_read_32((0xf7032000 + 0x100));
+	data &= ~(1 << 0);
+	mmio_write_32((0xf7032000 + 0x100), data);
+	dsb();
+	do {
+		data = mmio_read_32((0xf7032000 + 0x100));
+		data &= (1 << 1);
+	} while (data != (1 << 1));
+	mdelay(1000);
+
+	data = mmio_read_32((0xf6504000 + 0x054));
+	data &= ~(1 << 28);
+	mmio_write_32((0xf6504000 + 0x054), data);
+	dsb();
+
+	data = mmio_read_32((0xf7032000 + 0x110));
+	data &= ~((1 << 4) |
+			(3 << 12));
+	mmio_write_32((0xf7032000 + 0x110), data);
+}
+
+int cat_533mhz_800mhz(void)
+{
+	unsigned int data, i;
+	unsigned int bdl[5];
+
+
+	data = mmio_read_32((0xf712c000 + 0x1c8));
+	data &= 0xfffff0f0;
+	data |= 0x100f0f;
+	mmio_write_32((0xf712c000 + 0x1c8), data);
+
+	for (i = 0; i < 0x20; i++) {
+		mmio_write_32((0xf712c000 + 0x1d4), 0xc0000);
+		data = (i << 0x10) + i;
+		mmio_write_32((0xf712c000 + 0x140), data);
+		mmio_write_32((0xf712c000 + 0x144), data);
+		mmio_write_32((0xf712c000 + 0x148), data);
+		mmio_write_32((0xf712c000 + 0x14c), data);
+		mmio_write_32((0xf712c000 + 0x150), data);
+
+
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data |= 0x80000;
+		mmio_write_32((0xf712c000 + 0x070), data);
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data &= 0xfff7ffff;
+		mmio_write_32((0xf712c000 + 0x070), data);
+
+
+		mmio_write_32((0xf712c000 + 0x004), 0x8000);
+		mmio_write_32((0xf712c000 + 0x004), 0x0);
+		mmio_write_32((0xf712c000 + 0x004), 0x801);
+		do {
+			data = mmio_read_32((0xf712c000 + 0x004));
+		} while (data & 1);
+
+		data = mmio_read_32((0xf712c000 + 0x008));
+		if (!(data & 0x400)) {
+			mdelay(10);
+			return 0;
+		}
+		WARN("lpddr3 cat fail\n");
+		data = mmio_read_32((0xf712c000 + 0x1d4));
+		if ((data & 0x1f00) && ((data & 0x1f) == 0)) {
+			bdl[0] = mmio_read_32((0xf712c000 + 0x140));
+			bdl[1] = mmio_read_32((0xf712c000 + 0x144));
+			bdl[2] = mmio_read_32((0xf712c000 + 0x148));
+			bdl[3] = mmio_read_32((0xf712c000 + 0x14c));
+			bdl[4] = mmio_read_32((0xf712c000 + 0x150));
+			if ((!(bdl[0] & 0x1f001f)) || (!(bdl[1] & 0x1f001f)) ||
+					(!(bdl[2] & 0x1f001f)) || (!(bdl[3] & 0x1f001f)) ||
+					(!(bdl[4] & 0x1f001f))) {
+				WARN("lpddr3 cat deskew error\n");
+				if (i == 0x1f) {
+					WARN("addrnbdl is max\n");
+					return -EINVAL;
+				}
+				mmio_write_32((0xf712c000 + 0x008), 0x400);
+			} else {
+				WARN("lpddr3 cat other error1\n");
+				return -EINVAL;
+			}
+		} else {
+			WARN("lpddr3 cat other error2\n");
+			return -EINVAL;
+		}
+	}
+	return -EINVAL;
+}
+
+static void ddrx_rdet(void)
+{
+	unsigned int data, rdet, bdl[4];
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= 0xf800ffff;
+	data |= 0x8f0000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+
+	data = mmio_read_32((0xf712c000 + 0x0dc));
+	data &= 0xfffffff0;
+	data |= 0xf;
+	mmio_write_32((0xf712c000 + 0x0dc), data);
+
+
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data |= 0x80000;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= 0xfff7ffff;
+	mmio_write_32((0xf712c000 + 0x070), data);
+
+	mmio_write_32((0xf712c000 + 0x004), 0x8000);
+	mmio_write_32((0xf712c000 + 0x004), 0);
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf0000000;
+	data |= 0x80000000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+
+	mmio_write_32((0xf712c000 + 0x004), 0x101);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (!(data & 1));
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x100)
+		WARN("rdet lbs fail\n");
+
+	bdl[0] = mmio_read_32((0xf712c000 + 0x22c)) & 0x7f;
+	bdl[1] = mmio_read_32((0xf712c000 + 0x2ac)) & 0x7f;
+	bdl[2] = mmio_read_32((0xf712c000 + 0x32c)) & 0x7f;
+	bdl[3] = mmio_read_32((0xf712c000 + 0x3ac)) & 0x7f;
+	do {
+		data = mmio_read_32((0xf712c000 + 0x22c));
+		data &= ~0x7f;
+		data |= bdl[0];
+		mmio_write_32((0xf712c000 + 0x22c), data);
+		data = mmio_read_32((0xf712c000 + 0x2ac));
+		data &= ~0x7f;
+		data |= bdl[1];
+		mmio_write_32((0xf712c000 + 0x2ac), data);
+		data = mmio_read_32((0xf712c000 + 0x32c));
+		data &= ~0x7f;
+		data |= bdl[2];
+		mmio_write_32((0xf712c000 + 0x32c), data);
+		data = mmio_read_32((0xf712c000 + 0x3ac));
+		data &= ~0x7f;
+		data |= bdl[3];
+		mmio_write_32((0xf712c000 + 0x3ac), data);
+
+
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data |= 0x80000;
+		mmio_write_32((0xf712c000 + 0x070), data);
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data &= 0xfff7ffff;
+		mmio_write_32((0xf712c000 + 0x070), data);
+
+		mmio_write_32((0xf712c000 + 0x004), 0x8000);
+		mmio_write_32((0xf712c000 + 0x004), 0);
+
+		data = mmio_read_32((0xf712c000 + 0x0d0));
+		data &= ~0xf0000000;
+		data |= 0x40000000;
+		mmio_write_32((0xf712c000 + 0x0d0), data);
+		mmio_write_32((0xf712c000 + 0x004), 0x101);
+		do {
+			data = mmio_read_32((0xf712c000 + 0x004));
+		} while (data & 1);
+
+		data = mmio_read_32((0xf712c000 + 0x008));
+		rdet = data & 0x100;
+		if (rdet) {
+			INFO("rdet ds fail\n");
+			mmio_write_32((0xf712c000 + 0x008), 0x100);
+		}
+		bdl[0]++;
+		bdl[1]++;
+		bdl[2]++;
+		bdl[3]++;
+	} while (rdet);
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf0000000;
+	data |= 0x30000000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+
+	mmio_write_32((0xf712c000 + 0x004), 0x101);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x100)
+		INFO("rdet rbs av fail\n");
+}
+
+static void ddrx_wdet(void)
+{
+	unsigned int data, wdet, zero_bdl, dq[4];
+	int i;
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf;
+	data |= 0xf;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data |= 0x80000;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= ~0x80000;
+	mmio_write_32((0xf712c000 + 0x070), data);
+
+	mmio_write_32((0xf712c000 + 0x004), 0x8000);
+	mmio_write_32((0xf712c000 + 0x004), 0);
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf000;
+	data |= 0x8000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x201);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x200)
+		INFO("wdet lbs fail\n");
+
+	dq[0] = mmio_read_32((0xf712c000 + 0x234)) & 0x1f00;
+	dq[1] = mmio_read_32((0xf712c000 + 0x2b4)) & 0x1f00;
+	dq[2] = mmio_read_32((0xf712c000 + 0x334)) & 0x1f00;
+	dq[3] = mmio_read_32((0xf712c000 + 0x3b4)) & 0x1f00;
+
+	do {
+		mmio_write_32((0xf712c000 + 0x234), dq[0]);
+		mmio_write_32((0xf712c000 + 0x2b4), dq[1]);
+		mmio_write_32((0xf712c000 + 0x334), dq[2]);
+		mmio_write_32((0xf712c000 + 0x3b4), dq[3]);
+
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data |= 0x80000;
+		mmio_write_32((0xf712c000 + 0x070), data);
+		data = mmio_read_32((0xf712c000 + 0x070));
+		data &= ~0x80000;
+		mmio_write_32((0xf712c000 + 0x070), data);
+		mmio_write_32((0xf712c000 + 0x004), 0x8000);
+		mmio_write_32((0xf712c000 + 0x004), 0);
+
+		data = mmio_read_32((0xf712c000 + 0x0d0));
+		data &= ~0xf000;
+		data |= 0x4000;
+		mmio_write_32((0xf712c000 + 0x0d0), data);
+		mmio_write_32((0xf712c000 + 0x004), 0x201);
+		do {
+			data = mmio_read_32((0xf712c000 + 0x004));
+		} while (data & 1);
+
+		data = mmio_read_32((0xf712c000 + 0x008));
+		wdet = data & 0x200;
+		if (wdet) {
+			INFO("wdet ds fail\n");
+			mmio_write_32((0xf712c000 + 0x008), 0x200);
+		}
+		mdelay(10);
+
+		for (i = 0; i < 4; i++) {
+			data = mmio_read_32((0xf712c000 + 0x210 + i * 0x80));
+			if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
+					(!(data & 0x1f0000)) || (!(data & 0x1f000000)))
+				zero_bdl = 1;
+			data = mmio_read_32((0xf712c000 + 0x214 + i * 0x80));
+			if ((!(data & 0x1f)) || (!(data & 0x1f00)) ||
+					(!(data & 0x1f0000)) || (!(data & 0x1f000000)))
+				zero_bdl = 1;
+			data = mmio_read_32((0xf712c000 + 0x218 + i * 0x80));
+			if (!(data & 0x1f))
+				zero_bdl = 1;
+			if (zero_bdl) {
+				if (i == 0)
+					dq[0] = dq[0] - 0x100;
+				if (i == 1)
+					dq[1] = dq[1] - 0x100;
+				if (i == 2)
+					dq[2] = dq[2] - 0x100;
+				if (i == 3)
+					dq[3] = dq[3] - 0x100;
+			}
+		}
+	} while (wdet);
+
+	data = mmio_read_32((0xf712c000 + 0x0d0));
+	data &= ~0xf000;
+	data |= 0x3000;
+	mmio_write_32((0xf712c000 + 0x0d0), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x201);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x200)
+		INFO("wdet rbs av fail\n");
+}
+
+static 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));
+	data |= 0x100;
+	mmio_write_32((0xf7032000 + 0x104), data);
+
+	mmio_write_32((0xf7030000 + 0x050), 0x30);
+	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+	mmio_write_32((0xf712c000 + 0x00c), 0x400);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x090), 0x6400000);
+	mmio_write_32((0xf712c000 + 0x258), 0x640);
+	mmio_write_32((0xf712c000 + 0x2d8), 0x640);
+	mmio_write_32((0xf712c000 + 0x358), 0x640);
+	mmio_write_32((0xf712c000 + 0x3d8), 0x640);
+	mmio_write_32((0xf712c000 + 0x018), 0x0);
+	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), 0x9dd87855);
+	mmio_write_32((0xf712c000 + 0x034), 0xa7138bb);
+	mmio_write_32((0xf712c000 + 0x038), 0x20091477);
+	mmio_write_32((0xf712c000 + 0x03c), 0x84534e16);
+	mmio_write_32((0xf712c000 + 0x040), 0x3008817);
+	mmio_write_32((0xf712c000 + 0x064), 0x106c3);
+	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= 0xffff0000;
+	data |= 0x305;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 0x40000000;
+	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), 0xd0420900);
+
+	mmio_write_32((0xf7128000 + 0x040), 0x0);
+	mmio_write_32((0xf712c000 + 0x004), 0x140f);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe) {
+		NOTICE("failed to init lpddr3 rank0 dram phy\n");
+		return;
+	}
+	NOTICE("succeed to init lpddr3 rank0 dram phy\n");
+}
+
+static void set_ddrc_800mhz(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), 0x30);
+	mmio_write_32((0xf7030000 + 0x240), 0x5ffff);
+	mmio_write_32((0xf7030000 + 0x344), 0xf5ff);
+	mmio_write_32((0xf712c000 + 0x00c), 0x400);
+	mmio_write_32((0xf712c000 + 0x018), 0x7);
+	mmio_write_32((0xf712c000 + 0x090), 0x5400000);
+	mmio_write_32((0xf712c000 + 0x258), 0x540);
+	mmio_write_32((0xf712c000 + 0x2d8), 0x540);
+	mmio_write_32((0xf712c000 + 0x358), 0x540);
+	mmio_write_32((0xf712c000 + 0x3d8), 0x540);
+	mmio_write_32((0xf712c000 + 0x018), 0x0);
+	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), 0xe663ab77);
+	mmio_write_32((0xf712c000 + 0x034), 0xea952db);
+	mmio_write_32((0xf712c000 + 0x038), 0x200d1cb1);
+	mmio_write_32((0xf712c000 + 0x03c), 0xc67d0721);
+	mmio_write_32((0xf712c000 + 0x040), 0x3008aa1);
+	mmio_write_32((0xf712c000 + 0x064), 0x11a43);
+	mmio_write_32((0xf712c000 + 0x068), 0xff0a0000);
+	data = mmio_read_32((0xf712c000 + 0x070));
+	data &= 0xffff0000;
+	data |= 0x507;
+	mmio_write_32((0xf712c000 + 0x070), data);
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 0x40000000;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	data = mmio_read_32((0xf712c000 + 0x020));
+	data &= 0xffffffef;
+	mmio_write_32((0xf712c000 + 0x020), data);
+	data = mmio_read_32((0xf712c000 + 0x080));
+	data &= 0xffffdfff;
+	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), 0xd0420900);
+
+	mmio_write_32((0xf7128000 + 0x040), 0x2001);
+	mmio_write_32((0xf712c000 + 0x004), 0x140f);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe) {
+		WARN("failed to init lpddr3 rank0 dram phy\n");
+		return;
+	}
+}
+
+static void ddrc_common_init(int ddr800)
+{
+	unsigned int data;
+
+	mmio_write_32((0xf7120000 + 0x020), 0x1);
+	mmio_write_32((0xf7120000 + 0x100), 0x1700);
+	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 + 0x028), 0x310201);
+	mmio_write_32((0xf712c000 + 0x1e4), 0xfe007600);
+	mmio_write_32((0xf7128000 + 0x01c), 0xaf001);
+
+
+	data = mmio_read_32((0xf7128000 + 0x280));
+	data |= 1 << 7;
+	mmio_write_32((0xf7128000 + 0x280), data);
+	mmio_write_32((0xf7128000 + 0x244), 0x3);
+
+	if (ddr800)
+		mmio_write_32((0xf7128000 + 0x240), 167 * 400000 / 1024);
+	else
+		mmio_write_32((0xf7128000 + 0x240), 167 * 533000 / 1024);
+
+	data = mmio_read_32((0xf712c000 + 0x080));
+	data &= 0xffff;
+	data |= 0x4002000;
+	mmio_write_32((0xf712c000 + 0x080), data);
+	mmio_write_32((0xf7128000 + 0x000), 0x0);
+	do {
+		data = mmio_read_32((0xf7128000 + 0x294));
+	} while (data & 1);
+	mmio_write_32((0xf7128000 + 0x000), 0x2);
+}
+
+
+static int dienum_det_and_rowcol_cfg(void)
+{
+	unsigned int data;
+
+	mmio_write_32((0xf7128000 + 0x210), 0x87);
+	mmio_write_32((0xf7128000 + 0x218), 0x10000);
+	mmio_write_32((0xf7128000 + 0x00c), 0x1);
+	do {
+		data = mmio_read_32((0xf7128000 + 0x00c));
+	} while (data & 1);
+	data = mmio_read_32((0xf7128000 + 0x4a8)) & 0xfc;
+	switch (data) {
+	case 0x18:
+		mmio_write_32((0xf7128000 + 0x060), 0x132);
+		mmio_write_32((0xf7128000 + 0x064), 0x132);
+		mmio_write_32((0xf7120000 + 0x100), 0x1600);
+		mmio_write_32((0xf7120000 + 0x104), 0x71040004);
+		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);
+		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);
+		break;
+	default:
+		break;
+	}
+	if (!data)
+		return -EINVAL;
+	return 0;
+}
+
+static int detect_ddr_chip_info(void)
+{
+	unsigned int data, mr5, mr6, mr7;
+
+	mmio_write_32((0xf7128000 + 0x210), 0x57);
+	mmio_write_32((0xf7128000 + 0x218), 0x10000);
+	mmio_write_32((0xf7128000 + 0x00c), 0x1);
+
+	do {
+		data = mmio_read_32((0xf7128000 + 0x00c));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf7128000 + 0x4a8));
+	mr5 = data & 0xff;
+	switch (mr5) {
+	case 1:
+		INFO("Samsung DDR\n");
+		break;
+	case 6:
+		INFO("Hynix DDR\n");
+		break;
+	case 3:
+		INFO("Elpida DDR\n");
+		break;
+	default:
+		INFO("DDR from other vendors\n");
+		break;
+	}
+
+	mmio_write_32((0xf7128000 + 0x210), 0x67);
+	mmio_write_32((0xf7128000 + 0x218), 0x10000);
+	mmio_write_32((0xf7128000 + 0x00c), 0x1);
+	do {
+		data = mmio_read_32((0xf7128000 + 0x00c));
+	} while (data & 1);
+	data = mmio_read_32((0xf7128000 + 0x4a8));
+	mr6 = data & 0xff;
+	mmio_write_32((0xf7128000 + 0x210), 0x77);
+	mmio_write_32((0xf7128000 + 0x218), 0x10000);
+	mmio_write_32((0xf7128000 + 0x00c), 0x1);
+	do {
+		data = mmio_read_32((0xf7128000 + 0x00c));
+	} while (data & 1);
+	data = mmio_read_32((0xf7128000 + 0x4a8));
+	mr7 = data & 0xff;
+	data = mr5 + (mr6 << 8) + (mr7 << 16);
+	return data;
+}
+
+int lpddr3_freq_init(int freq)
+{
+	unsigned int data;
+
+	if (freq == DDR_FREQ_800M) {
+		set_ddrc_800mhz();
+		INFO("%s, set ddrc 800mhz\n", __func__);
+	} else {
+		set_ddrc_533mhz();
+		INFO("%s, set ddrc 533mhz\n", __func__);
+	}
+
+	mmio_write_32((0xf712c000 + 0x004), 0xf1);
+	if (freq == DDR_FREQ_800M)
+		mmio_write_32((0xf7128000 + 0x050), 0x100023);
+	else
+		mmio_write_32((0xf7128000 + 0x050), 0x100123);
+	mmio_write_32((0xf7128000 + 0x060), 0x133);
+	mmio_write_32((0xf7128000 + 0x064), 0x133);
+	mmio_write_32((0xf7128000 + 0x200), 0xa1000);
+
+	if (freq == DDR_FREQ_800M) {
+		mmio_write_32((0xf7128000 + 0x100), 0x755a9d12);
+		mmio_write_32((0xf7128000 + 0x104), 0x1753b055);
+		mmio_write_32((0xf7128000 + 0x108), 0x7401505f);
+		mmio_write_32((0xf7128000 + 0x10c), 0x578ca244);
+		mmio_write_32((0xf7128000 + 0x110), 0x10700000);
+		mmio_write_32((0xf7128000 + 0x114), 0x13141306);
+	} else {
+		mmio_write_32((0xf7128000 + 0x100), 0xb77b6718);
+		mmio_write_32((0xf7128000 + 0x104), 0x1e82a071);
+		mmio_write_32((0xf7128000 + 0x108), 0x9501c07e);
+		mmio_write_32((0xf7128000 + 0x10c), 0xaf50c255);
+		mmio_write_32((0xf7128000 + 0x110), 0x10b00000);
+		mmio_write_32((0xf7128000 + 0x114), 0x13181908);
+	}
+	mmio_write_32((0xf7128000 + 0x118), 0x44);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe) {
+		NOTICE("fail to init ddr3 rank0\n");
+		return -EFAULT;
+	}
+	INFO("init ddr3 rank0\n");
+	ddrx_rdet();
+	ddrx_wdet();
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data |= 1;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	mmio_write_32((0xf712c000 + 0x004), 0x21);
+	do {
+		data = mmio_read_32((0xf712c000 + 0x004));
+	} while (data & 1);
+
+	data = mmio_read_32((0xf712c000 + 0x008));
+	if (data & 0x7fe)
+		NOTICE("ddr3 rank1 init failure\n");
+	else
+		INFO("ddr3 rank1 init pass\n");
+
+	data = mmio_read_32((0xf712c000 + 0x048));
+	data &= ~0xf;
+	mmio_write_32((0xf712c000 + 0x048), data);
+	return 0;
+}
+
+static void init_ddr(int freq)
+{
+	unsigned int data;
+	int ret;
+
+
+	data = mmio_read_32((0xf7032000 + 0x030));
+	data |= 1;
+	mmio_write_32((0xf7032000 + 0x030), data);
+	data = mmio_read_32((0xf7032000 + 0x010));
+	data |= 1;
+	mmio_write_32((0xf7032000 + 0x010), data);
+
+	udelay(100);
+	do {
+		data = mmio_read_32((0xf7032000 + 0x030));
+		data &= 3 << 28;
+	} while (data != (3 << 28));
+	do {
+		data = mmio_read_32((0xf7032000 + 0x010));
+		data &= 3 << 28;
+	} while (data != (3 << 28));
+
+	ret = lpddr3_freq_init(freq);
+	if (ret)
+		return;
+}
+
+static void init_ddrc_qos(void)
+{
+	unsigned int port, data;
+
+	mmio_write_32((0xf7124000 + 0x088), 1);
+
+	port = 0;
+	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
+	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x11111111);
+	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x11111111);
+	mmio_write_32((0xf7120000 + 0x400 + 0 * 0x10), 0x001d0007);
+
+	for (port = 3; port <= 4; port++) {
+		mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x1210);
+		mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x77777777);
+		mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x77777777);
+	}
+
+	port = 1;
+	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
+	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
+	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
+
+	mmio_write_32((0xf7124000 + 0x1f0), 0);
+	mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
+	mmio_write_32((0xf7124000 + 0x0d0), 0x3020100);
+	mmio_write_32((0xf7124000 + 0x1f4), 0x01000100);
+	mmio_write_32((0xf7124000 + 0x08c + 0 * 4), 0xd0670402);
+	mmio_write_32((0xf7124000 + 0x068 + 0 * 4), 0x31);
+	mmio_write_32((0xf7124000 + 0x000), 0x7);
+
+	data = mmio_read_32((0xf7124000 + 0x09c));
+	data &= ~0xff0000;
+	data |= 0x400000;
+	mmio_write_32((0xf7124000 + 0x09c), data);
+	data = mmio_read_32((0xf7124000 + 0x0ac));
+	data &= ~0xff0000;
+	data |= 0x400000;
+	mmio_write_32((0xf7124000 + 0x0ac), data);
+	port = 2;
+	mmio_write_32((0xf7120000 + 0x200 + port * 0x10), 0x30000);
+	mmio_write_32((0xf7120000 + 0x204 + port * 0x10), 0x1234567);
+	mmio_write_32((0xf7120000 + 0x208 + port * 0x10), 0x1234567);
+
+
+	mmio_write_32((0xf7124000 + 0x09c), 0xff7fff);
+	mmio_write_32((0xf7124000 + 0x0a0), 0xff);
+	mmio_write_32((0xf7124000 + 0x0ac), 0xff7fff);
+	mmio_write_32((0xf7124000 + 0x0b0), 0xff);
+	mmio_write_32((0xf7124000 + 0x0bc), 0x3020100);
+	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)
+{
+	uint32_t data;
+
+	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);
+
+
+	ddrc_common_init(1);
+	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);
+
+	/*
+	 * Test memory access. Do not use address 0x0 because the compiler
+	 * may assume it is not a valid address and generate incorrect code
+	 * (GCC 4.9.1 without -fno-delete-null-pointer-checks for instance).
+	 */
+	mmio_write_32(0x4, 0xa5a55a5a);
+	INFO("ddr test value:0x%x\n", mmio_read_32(0x4));
+	init_ddrc_qos();
+}
diff --git a/plat/hisilicon/hikey/hikey_def.h b/plat/hisilicon/hikey/hikey_def.h
new file mode 100644
index 0000000..28ff553
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_def.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HIKEY_DEF_H__
+#define __HIKEY_DEF_H__
+
+#include <common_def.h>
+#include <tbbr_img_def.h>
+
+/* Always assume DDR is 1GB size. */
+#define DDR_BASE			0x0
+#define DDR_SIZE			0x80000000
+
+#define DEVICE_BASE			0xF4000000
+#define DEVICE_SIZE			0x05800000
+
+#define XG2RAM0_BASE			0xF9800000
+#define XG2RAM0_SIZE			0x00400000
+
+#define SRAM_BASE			0xFFF80000
+#define SRAM_SIZE			0x00012000
+
+/*
+ * BL1 is stored in XG2RAM0_HIRQ that is 784KB large (0xF980_0000~0xF98C_4000).
+ */
+#define ONCHIPROM_PARAM_BASE		(XG2RAM0_BASE + 0x700)
+#define LOADER_RAM_BASE			(XG2RAM0_BASE + 0x800)
+#define BL1_XG2RAM0_OFFSET		0x1000
+
+/*
+ * PL011 related constants
+ */
+#define PL011_UART0_BASE		0xF8015000
+#define PL011_UART3_BASE		0xF7113000
+#define PL011_BAUDRATE			115200
+#define PL011_UART_CLK_IN_HZ		19200000
+
+#define HIKEY_USB_DESC_BASE		(DDR_BASE + 0x00800000)
+#define HIKEY_USB_DESC_SIZE		0x00100000
+#define HIKEY_USB_DATA_BASE		(DDR_BASE + 0x10000000)
+#define HIKEY_USB_DATA_SIZE		0x10000000
+#define HIKEY_FB_BUFFER_BASE		(HIKEY_USB_DATA_BASE)
+#define HIKEY_FB_BUFFER_SIZE		HIKEY_USB_DATA_SIZE
+#define HIKEY_FB_DOWNLOAD_BASE		(HIKEY_FB_BUFFER_BASE +		\
+					 HIKEY_FB_BUFFER_SIZE)
+#define HIKEY_FB_DOWNLOAD_SIZE		HIKEY_USB_DATA_SIZE
+
+#define HIKEY_USB_DESC_IN_BASE		(DDR_BASE + 0x00800000)
+#define HIKEY_USB_DESC_IN_SIZE		0x00040000
+#define HIKEY_USB_DESC_EP0_OUT_BASE	(HIKEY_USB_DESC_IN_BASE +	\
+					 HIKEY_USB_DESC_IN_SIZE)
+#define HIKEY_USB_DESC_EP0_OUT_SIZE	0x00040000
+#define HIKEY_USB_DESC_EPX_OUT_BASE	(HIKEY_USB_DESC_EP0_OUT_BASE +	\
+					 HIKEY_USB_DESC_EP0_OUT_SIZE)
+#define HIKEY_USB_DESC_EPX_OUT_SIZE	0x00080000
+
+#define HIKEY_MMC_DESC_BASE		(DDR_BASE + 0x03000000)
+#define HIKEY_MMC_DESC_SIZE		0x00100000
+
+/*
+ * HIKEY_MMC_DATA_BASE & HIKEY_MMC_DATA_SIZE are shared between fastboot
+ * and eMMC driver. Since it could avoid to memory copy.
+ * So this SRAM region is used twice. First, it's used in BL1 as temporary
+ * buffer in eMMC driver. Second, it's used by MCU in BL2. The SRAM region
+ * needs to be clear before used in BL2.
+ */
+#define HIKEY_MMC_DATA_BASE		(DDR_BASE + 0x10000000)
+#define HIKEY_MMC_DATA_SIZE		0x20000000
+#define HIKEY_NS_IMAGE_OFFSET		(DDR_BASE + 0x35000000)
+#define HIKEY_BL1_MMC_DESC_BASE		(SRAM_BASE)
+#define HIKEY_BL1_MMC_DESC_SIZE		0x00001000
+#define HIKEY_BL1_MMC_DATA_BASE		(HIKEY_BL1_MMC_DESC_BASE +	\
+					 HIKEY_BL1_MMC_DESC_SIZE)
+#define HIKEY_BL1_MMC_DATA_SIZE		0x0000B000
+
+#define EMMC_BASE			0
+#define HIKEY_FIP_BASE			(EMMC_BASE + (4 << 20))
+#define HIKEY_FIP_MAX_SIZE		(8 << 20)
+#define HIKEY_EMMC_RPMB_BASE		(EMMC_BASE + 0)
+#define HIKEY_EMMC_RPMB_MAX_SIZE	(128 << 10)
+#define HIKEY_EMMC_USERDATA_BASE	(EMMC_BASE + 0)
+#define HIKEY_EMMC_USERDATA_MAX_SIZE	(4 << 30)
+
+/*
+ * GIC400 interrupt handling related constants
+ */
+#define IRQ_SEC_PHY_TIMER			29
+#define IRQ_SEC_SGI_0				8
+#define IRQ_SEC_SGI_1				9
+#define IRQ_SEC_SGI_2				10
+#define IRQ_SEC_SGI_3				11
+#define IRQ_SEC_SGI_4				12
+#define IRQ_SEC_SGI_5				13
+#define IRQ_SEC_SGI_6				14
+#define IRQ_SEC_SGI_7				15
+#define IRQ_SEC_SGI_8				16
+
+#endif /* __HIKEY_DEF_H__ */
diff --git a/plat/hisilicon/hikey/hikey_io_storage.c b/plat/hisilicon/hikey/hikey_io_storage.c
new file mode 100644
index 0000000..4ca1846
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_io_storage.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <emmc.h>
+#include <errno.h>
+#include <firmware_image_package.h>
+#include <io_block.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <semihosting.h>	/* For FOPEN_MODE_... */
+#include <string.h>
+#include "hikey_private.h"
+
+#define EMMC_BLOCK_SHIFT			9
+
+/* Page 1024, since only a few pages before 2048 are used as partition table */
+#define SERIALNO_EMMC_OFFSET			(1024 * 512)
+
+struct plat_io_policy {
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	int (*check)(const uintptr_t spec);
+};
+
+static const io_dev_connector_t *emmc_dev_con;
+static uintptr_t emmc_dev_handle;
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_handle;
+
+static int check_emmc(const uintptr_t spec);
+static int check_fip(const uintptr_t spec);
+
+static const io_block_spec_t emmc_fip_spec = {
+	.offset		= HIKEY_FIP_BASE,
+	.length		= HIKEY_FIP_MAX_SIZE,
+};
+
+static const io_block_dev_spec_t emmc_dev_spec = {
+	/* It's used as temp buffer in block driver. */
+#if IMAGE_BL1
+	.buffer		= {
+		.offset	= HIKEY_BL1_MMC_DATA_BASE,
+		.length	= HIKEY_BL1_MMC_DATA_SIZE,
+	},
+#else
+	.buffer		= {
+		.offset	= HIKEY_MMC_DATA_BASE,
+		.length	= HIKEY_MMC_DATA_SIZE,
+	},
+#endif
+	.ops		= {
+		.read	= emmc_read_blocks,
+		.write	= emmc_write_blocks,
+	},
+	.block_size	= EMMC_BLOCK_SIZE,
+};
+
+static const io_uuid_spec_t bl2_uuid_spec = {
+	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+};
+
+static const io_uuid_spec_t bl31_uuid_spec = {
+	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+};
+
+static const io_uuid_spec_t bl33_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+static const io_uuid_spec_t scp_bl2_uuid_spec = {
+	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
+};
+
+static const struct plat_io_policy policies[] = {
+	[FIP_IMAGE_ID] = {
+		&emmc_dev_handle,
+		(uintptr_t)&emmc_fip_spec,
+		check_emmc
+	},
+	[BL2_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl2_uuid_spec,
+		check_fip
+	},
+	[SCP_BL2_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&scp_bl2_uuid_spec,
+		check_fip
+	},
+	[BL31_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl31_uuid_spec,
+		check_fip
+	},
+	[BL33_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl33_uuid_spec,
+		check_fip
+	}
+};
+
+static int check_emmc(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_handle;
+
+	result = io_dev_init(emmc_dev_handle, (uintptr_t)NULL);
+	if (result == 0) {
+		result = io_open(emmc_dev_handle, spec, &local_handle);
+		if (result == 0)
+			io_close(local_handle);
+	}
+	return result;
+}
+
+static int check_fip(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_image_handle;
+
+	/* See if a Firmware Image Package is available */
+	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+	if (result == 0) {
+		result = io_open(fip_dev_handle, spec, &local_image_handle);
+		if (result == 0) {
+			VERBOSE("Using FIP\n");
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+void hikey_io_setup(void)
+{
+	int result;
+
+	result = register_io_dev_block(&emmc_dev_con);
+	assert(result == 0);
+
+	result = register_io_dev_fip(&fip_dev_con);
+	assert(result == 0);
+
+	result = io_dev_open(emmc_dev_con, (uintptr_t)&emmc_dev_spec,
+			     &emmc_dev_handle);
+	assert(result == 0);
+
+	result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
+	assert(result == 0);
+
+	/* Ignore improbable errors in release builds */
+	(void)result;
+}
+
+/* Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy
+ */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	int result;
+	const struct plat_io_policy *policy;
+
+	assert(image_id < ARRAY_SIZE(policies));
+
+	policy = &policies[image_id];
+	result = policy->check(policy->image_spec);
+	assert(result == 0);
+
+	*image_spec = policy->image_spec;
+	*dev_handle = *(policy->dev_handle);
+
+	return result;
+}
diff --git a/plat/hisilicon/hikey/hikey_pm.c b/plat/hisilicon/hikey/hikey_pm.c
new file mode 100644
index 0000000..9b4ef5b
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_pm.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <cci.h>
+#include <debug.h>
+#include <gicv2.h>
+#include <hi6220.h>
+#include <hisi_ipc.h>
+#include <hisi_pwrc.h>
+#include <hisi_sram_map.h>
+#include <mmio.h>
+#include <psci.h>
+
+#include "hikey_def.h"
+
+#define HIKEY_CLUSTER_STATE_ON		0
+#define HIKEY_CLUSTER_STATE_OFF		1
+
+static uintptr_t hikey_sec_entrypoint;
+/* There're two clusters in HiKey. */
+static int hikey_cluster_state[] = {HIKEY_CLUSTER_STATE_OFF,
+				    HIKEY_CLUSTER_STATE_OFF};
+
+/*******************************************************************************
+ * Handler called when a power domain is about to be turned on. The
+ * level and mpidr determine the affinity instance.
+ ******************************************************************************/
+static int hikey_pwr_domain_on(u_register_t mpidr)
+{
+	int cpu, cluster;
+	int curr_cluster;
+
+	cluster = MPIDR_AFFLVL1_VAL(mpidr);
+	cpu = MPIDR_AFFLVL0_VAL(mpidr);
+	curr_cluster = MPIDR_AFFLVL1_VAL(read_mpidr());
+	if (cluster != curr_cluster)
+		hisi_ipc_cluster_on(cpu, cluster);
+
+	hisi_pwrc_set_core_bx_addr(cpu, cluster, hikey_sec_entrypoint);
+	hisi_ipc_cpu_on(cpu, cluster);
+	return 0;
+}
+
+static void hikey_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	unsigned long mpidr;
+	int cpu, cluster;
+
+	mpidr = read_mpidr();
+	cluster = MPIDR_AFFLVL1_VAL(mpidr);
+	cpu = MPIDR_AFFLVL0_VAL(mpidr);
+	if (hikey_cluster_state[cluster] == HIKEY_CLUSTER_STATE_OFF) {
+		/*
+		 * Enable CCI coherency for this cluster.
+		 * No need for locks as no other cpu is active at the moment.
+		 */
+		cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+		hikey_cluster_state[cluster] = HIKEY_CLUSTER_STATE_ON;
+	}
+
+	/* Zero the jump address in the mailbox for this cpu */
+	hisi_pwrc_set_core_bx_addr(cpu, cluster, 0);
+
+	/* Program the GIC per-cpu distributor or re-distributor interface */
+	gicv2_pcpu_distif_init();
+	/* Enable the GIC cpu interface */
+	gicv2_cpuif_enable();
+}
+
+/*******************************************************************************
+ * Handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
+ ******************************************************************************/
+void hikey_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	unsigned long mpidr;
+	int cpu, cluster;
+
+	gicv2_cpuif_disable();
+
+	mpidr = read_mpidr();
+	cluster = MPIDR_AFFLVL1_VAL(mpidr);
+	cpu = MPIDR_AFFLVL0_VAL(mpidr);
+	if (target_state->pwr_domain_state[MPIDR_AFFLVL1] ==
+	    PLAT_MAX_OFF_STATE) {
+		hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+		cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+		hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+		hisi_ipc_cluster_off(cpu, cluster);
+		hikey_cluster_state[cluster] = HIKEY_CLUSTER_STATE_OFF;
+	}
+	hisi_ipc_cpu_off(cpu, cluster);
+}
+
+/*******************************************************************************
+ * Handler to reboot the system.
+ ******************************************************************************/
+static void __dead2 hikey_system_reset(void)
+{
+	/* Send the system reset request */
+	mmio_write_32(AO_SC_SYS_STAT0, 0x48698284);
+	isb();
+	dsb();
+
+	wfi();
+	panic();
+}
+
+/*******************************************************************************
+ * Handler called to check the validity of the power state parameter.
+ ******************************************************************************/
+int hikey_validate_power_state(unsigned int power_state,
+			       psci_power_state_t *req_state)
+{
+	int pstate = psci_get_pstate_type(power_state);
+	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+	int i;
+
+	assert(req_state);
+
+	if (pwr_lvl > PLAT_MAX_PWR_LVL)
+		return PSCI_E_INVALID_PARAMS;
+
+	/* Sanity check the requested state */
+	if (pstate == PSTATE_TYPE_STANDBY) {
+		/*
+		 * It's possible to enter standby only on power level 0
+		 * Ignore any other power level.
+		 */
+		if (pwr_lvl != MPIDR_AFFLVL0)
+			return PSCI_E_INVALID_PARAMS;
+
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] =
+					PLAT_MAX_RET_STATE;
+	} else {
+		for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++)
+			req_state->pwr_domain_state[i] =
+					PLAT_MAX_OFF_STATE;
+	}
+
+	/*
+	 * We expect the 'state id' to be zero.
+	 */
+	if (psci_get_pstate_id(power_state))
+		return PSCI_E_INVALID_PARAMS;
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Handler called to check the validity of the non secure entrypoint.
+ ******************************************************************************/
+static int hikey_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/*
+	 * Check if the non secure entrypoint lies within the non
+	 * secure DRAM.
+	 */
+	if ((entrypoint > DDR_BASE) && (entrypoint < (DDR_BASE + DDR_SIZE)))
+		return PSCI_E_SUCCESS;
+
+	return PSCI_E_INVALID_ADDRESS;
+}
+
+/*******************************************************************************
+ * Export the platform handlers to enable psci to invoke them
+ ******************************************************************************/
+static const plat_psci_ops_t hikey_psci_ops = {
+	.cpu_standby			= NULL,
+	.pwr_domain_on			= hikey_pwr_domain_on,
+	.pwr_domain_on_finish		= hikey_pwr_domain_on_finish,
+	.pwr_domain_off			= hikey_pwr_domain_off,
+	.pwr_domain_suspend		= NULL,
+	.pwr_domain_suspend_finish	= NULL,
+	.system_off			= NULL,
+	.system_reset			= hikey_system_reset,
+	.validate_power_state		= hikey_validate_power_state,
+	.validate_ns_entrypoint		= hikey_validate_ns_entrypoint,
+	.get_sys_suspend_power_state	= NULL,
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops and initialize Power Controller
+ ******************************************************************************/
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	hikey_sec_entrypoint = sec_entrypoint;
+
+	/*
+	 * Initialize PSCI ops struct
+	 */
+	*psci_ops = &hikey_psci_ops;
+
+	return 0;
+}
diff --git a/plat/hisilicon/hikey/hikey_private.h b/plat/hisilicon/hikey/hikey_private.h
new file mode 100644
index 0000000..a7709b2
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_private.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HIKEY_PRIVATE_H__
+#define __HIKEY_PRIVATE_H__
+
+#include <bl_common.h>
+
+#define RANDOM_MAX		0x7fffffffffffffff
+#define RANDOM_MAGIC		0x9a4dbeaf
+
+struct random_serial_num {
+	uint64_t	magic;
+	uint64_t	data;
+	char		serialno[32];
+};
+
+/*
+ * Function and variable prototypes
+ */
+void hikey_init_mmu_el1(unsigned long total_base,
+			unsigned long total_size,
+			unsigned long ro_start,
+			unsigned long ro_limit,
+			unsigned long coh_start,
+			unsigned long coh_limit);
+void hikey_init_mmu_el3(unsigned long total_base,
+			unsigned long total_size,
+			unsigned long ro_start,
+			unsigned long ro_limit,
+			unsigned long coh_start,
+			unsigned long coh_limit);
+
+void hikey_ddr_init(void);
+void hikey_io_setup(void);
+
+int hikey_get_partition_size(const char *arg, int left, char *response);
+int hikey_get_partition_type(const char *arg, int left, char *response);
+
+int hikey_erase(const char *arg);
+int hikey_flash(const char *arg);
+int hikey_oem(const char *arg);
+int hikey_reboot(const char *arg);
+
+const char *hikey_init_serialno(void);
+int hikey_read_serialno(struct random_serial_num *serialno);
+int hikey_write_serialno(struct random_serial_num *serialno);
+
+void init_acpu_dvfs(void);
+
+#endif /* __HIKEY_PRIVATE_H__ */
diff --git a/plat/hisilicon/hikey/hikey_topology.c b/plat/hisilicon/hikey/hikey_topology.c
new file mode 100644
index 0000000..37ea20a
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_topology.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+#include <platform_def.h>
+#include <psci.h>
+
+/*
+ * The HiKey power domain tree descriptor. The cluster power domains
+ * are arranged so that when the PSCI generic code creates the power
+ * domain tree, the indices of the CPU power domain nodes it allocates
+ * match the linear indices returned by plat_core_pos_by_mpidr().
+ */
+const unsigned char hikey_power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	1,
+	/* Number of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of CPU cores */
+	PLATFORM_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the HiKey topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return hikey_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+
+	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
+		return -1;
+
+	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT)
+		return -1;
+
+	/*
+	 * Validate cpu_id by checking whether it represents a CPU in
+	 * one of the two clusters present on the platform.
+	 */
+	if (cpu_id >= PLATFORM_CORE_COUNT_PER_CLUSTER)
+		return -1;
+
+	return (cpu_id + (cluster_id * 4));
+}
diff --git a/plat/hisilicon/hikey/hisi_dvfs.c b/plat/hisilicon/hikey/hisi_dvfs.c
new file mode 100644
index 0000000..0d4f893
--- /dev/null
+++ b/plat/hisilicon/hikey/hisi_dvfs.c
@@ -0,0 +1,778 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <hi6220.h>
+#include <hi6553.h>
+#include <hisi_sram_map.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+
+#define ACPU_FREQ_MAX_NUM		5
+#define	ACPU_OPP_NUM			7
+
+#define ACPU_VALID_VOLTAGE_MAGIC	(0x5A5AC5C5)
+
+#define ACPU_WAIT_TIMEOUT		(200)
+#define ACPU_WAIT_FOR_WFI_TIMOUT	(2000)
+#define ACPU_DFS_STATE_CNT		(0x10000)
+
+struct acpu_dvfs_sram_stru {
+	unsigned int magic;
+	unsigned int support_freq_num;
+	unsigned int support_freq_max;
+	unsigned int start_prof;
+	unsigned int vol[ACPU_OPP_NUM];
+};
+
+struct acpu_volt_cal_para {
+	unsigned int freq;
+	unsigned int ul_vol;
+	unsigned int dl_vol;
+	unsigned int core_ref_hpm;
+};
+
+struct ddr_volt_cal_para {
+	unsigned int freq;
+	unsigned int ul_vol;
+	unsigned int dl_vol;
+	unsigned int ddr_ref_hpm;
+};
+
+struct acpu_dvfs_opp_para {
+	unsigned int freq;
+	unsigned int acpu_clk_profile0;
+	unsigned int acpu_clk_profile1;
+	unsigned int acpu_vol_profile;
+	unsigned int acpu_pll_freq;
+	unsigned int acpu_pll_frac;
+};
+
+unsigned int efuse_acpu_freq[] = {
+	1200000, 1250000, 1300000, 1350000,
+	1400000, 1450000, 1500000, 1550000,
+	1600000, 1650000, 1700000, 1750000,
+	1800000, 1850000, 1900000, 1950000,
+};
+
+struct acpu_dvfs_opp_para hi6220_acpu_profile[] = {
+	{ 208000,  0x61E5, 0x022, 0x3A, 0x5220102B, 0x05555555 },
+	{ 432000,  0x10A6, 0x121, 0x3A, 0x5120102D, 0x10000005 },
+	{ 729000,  0x2283, 0x100, 0x4A, 0x51101026, 0x10000005 },
+	{ 960000,  0x1211, 0x100, 0x5B, 0x51101032, 0x10000005 },
+	{ 1200000, 0x1211, 0x100, 0x6B, 0x5110207D, 0x10000005 },
+	{ 1400000, 0x1211, 0x100, 0x6B, 0x51101049, 0x10000005 },
+	{ 1500000, 0x1211, 0x100, 0x6B, 0x51101049, 0x10000005 },
+};
+
+struct acpu_dvfs_opp_para *acpu_dvfs_profile = hi6220_acpu_profile;
+struct acpu_dvfs_sram_stru *acpu_dvfs_sram_buf =
+	(struct acpu_dvfs_sram_stru *)MEMORY_AXI_ACPU_FREQ_VOL_ADDR;
+
+static inline void write_reg_mask(uintptr_t addr,
+				  uint32_t val, uint32_t mask)
+{
+	uint32_t reg;
+
+	reg = mmio_read_32(addr);
+	reg = (reg & ~(mask)) | val;
+	mmio_write_32(addr, reg);
+}
+
+static inline uint32_t read_reg_mask(uintptr_t addr,
+				     uint32_t mask, uint32_t offset)
+{
+	uint32_t reg;
+
+	reg = mmio_read_32(addr);
+	reg &= (mask << offset);
+	return (reg >> offset);
+}
+
+static int acpu_dvfs_syspll_cfg(unsigned int prof_id)
+{
+	uint32_t reg0 = 0;
+	uint32_t count = 0;
+	uint32_t clk_div_status = 0;
+
+	/*
+	 * step 1:
+	 *  - ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x3;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x1;
+	 */
+	write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x3 << 12, 0x3 << 12);
+	write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x1 << 4,  0x1 << 4);
+
+	/*
+	 * step 2:
+	 *  - ACPUSYSPLLCFG.acpu_syspll_div_cfg:
+	 *     208MHz, set to 0x5;
+	 *     500MHz, set to 0x2;
+	 *     other opps set to 0x1
+	 */
+	if (prof_id == 0)
+		write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x5 << 0, 0x7 << 0);
+	else if (prof_id == 1)
+		write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x2 << 0, 0x7 << 0);
+	else
+		write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x1 << 0, 0x7 << 0);
+
+	/*
+	 * step 3:
+	 *  - Polling ACPU_SC_CPU_STAT.clk_div_status_vd == 0x3;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0
+	 *  - PMCTRL_ACPUCLKDIV.acpu_ddr_clk_div_cfg = 0x1
+	 *  - PMCTRL_ACPUPLLSEL.acpu_pllsw_cfg = 0x1
+	 */
+	clk_div_status = 0x3;
+	do {
+		reg0 = read_reg_mask(ACPU_SC_CPU_STAT, 0x3, 20);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: clk div status timeout!\n", __func__);
+			return -1;
+		}
+	} while (clk_div_status != reg0);
+
+	write_reg_mask(ACPU_SC_VD_CTRL, 0x0, (0x1 << 0) | (0x1 << 11));
+	write_reg_mask(PMCTRL_ACPUCLKDIV, 0x1 << 8, 0x3 << 8);
+	write_reg_mask(PMCTRL_ACPUPLLSEL, 0x1 << 0, 0x1 << 0);
+
+	return 0;
+}
+
+static void acpu_dvfs_clk_div_cfg(unsigned int prof_id,
+				  unsigned int *cpuext_cfg,
+				  unsigned int *acpu_ddr_cfg)
+{
+	if (prof_id == 0) {
+		write_reg_mask(PMCTRL_ACPUCLKDIV,
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START),
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START));
+		*cpuext_cfg = 0x1;
+		*acpu_ddr_cfg = 0x1;
+	} else if (prof_id == 1) {
+		write_reg_mask(PMCTRL_ACPUCLKDIV,
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START),
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START));
+		*cpuext_cfg = 0x1;
+		*acpu_ddr_cfg = 0x1;
+	} else {
+		/* ddr has not been inited */
+		write_reg_mask(PMCTRL_ACPUCLKDIV,
+			(0x1 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x0 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START),
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START) |
+			(0x3 << SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START));
+		*cpuext_cfg = 0x1;
+		*acpu_ddr_cfg = 0x0;
+	}
+}
+
+static int acpu_dvfs_freq_ascend(unsigned int cur_prof, unsigned int tar_prof)
+{
+	unsigned int reg0 = 0;
+	unsigned int reg1 = 0;
+	unsigned int reg2 = 0;
+	unsigned int count = 0;
+	unsigned int cpuext_cfg_val = 0;
+	unsigned int acpu_ddr_cfg_val = 0;
+	int ret = 0;
+
+	/*
+	 * step 1:
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x3;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x1;
+	 *
+	 * step 2:
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_syspll_div_cfg = 0x5 (208MHz)
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_syspll_div_cfg = 0x2 (500MHz)
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_syspll_div_cfg = 0x1 (Other OPPs)
+	 *
+	 * step 3:
+	 *  - ACPU_SC_CPU_STAT.clk_div_status_vd = 0x3;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0x0;
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0x0;
+	 *  - PMCTRL_ACPUCLKDIV.acpu_ddr_clk_div_cfg = 0x1;
+	 *  - PMCTRL_ACPUPLLSEL.acpu_pllsw_cfg = 0x1
+	 */
+	ret = acpu_dvfs_syspll_cfg(cur_prof);
+	if (ret)
+		return -1;
+
+	/*
+	 * step 4:
+	 *  - Polling PMCTRL_ACPUPLLSEL.syspll_sw_stat == 0x1
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLSEL, 0x1,
+			SOC_PMCTRL_ACPUPLLSEL_syspll_sw_stat_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: syspll sw status timeout\n", __func__);
+			return -1;
+		}
+	} while (reg0 != 0x1);
+
+	/* Enable VD functionality if > 800MHz */
+	if (acpu_dvfs_profile[tar_prof].freq > 800000) {
+
+		write_reg_mask(ACPU_SC_VD_HPM_CTRL,
+			HPM_OSC_DIV_VAL, HPM_OSC_DIV_MASK);
+
+		/*
+		 * step 5:
+		 *  - ACPU_SC_VD_HPM_CTRL.hpm_dly_exp = 0xC7A;
+		 *  - ACPU_SC_VD_MASK_PATTERN_CTRL[12:0] = 0xCCB;
+		 */
+		write_reg_mask(ACPU_SC_VD_HPM_CTRL,
+			HPM_DLY_EXP_VAL, HPM_DLY_EXP_MASK);
+		write_reg_mask(ACPU_SC_VD_MASK_PATTERN_CTRL,
+			ACPU_SC_VD_MASK_PATTERN_VAL,
+			ACPU_SC_VD_MASK_PATTERN_MASK);
+
+		/*
+		 * step 6:
+		 *  - ACPU_SC_VD_DLY_TABLE0_CTRL = 0x1FFF;
+		 *  - ACPU_SC_VD_DLY_TABLE1_CTRL = 0x1FFFFFF;
+		 *  - ACPU_SC_VD_DLY_TABLE2_CTRL = 0x7FFFFFFF;
+		 *  - ACPU_SC_VD_DLY_FIXED_CTRL  = 0x1;
+		 */
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE0_CTRL, 0x1FFF);
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE1_CTRL, 0x1FFFFFF);
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE2_CTRL, 0x7FFFFFFF);
+		mmio_write_32(ACPU_SC_VD_DLY_FIXED_CTRL, 0x1);
+
+		/*
+		 * step 7:
+		 *  - ACPU_SC_VD_CTRL.shift_table0 = 0x1;
+		 *  - ACPU_SC_VD_CTRL.shift_table1 = 0x3;
+		 *  - ACPU_SC_VD_CTRL.shift_table2 = 0x5;
+		 *  - ACPU_SC_VD_CTRL.shift_table3 = 0x6;
+		 *
+		 * step 8:
+		 *  - ACPU_SC_VD_CTRL.tune = 0x7;
+		 */
+		write_reg_mask(ACPU_SC_VD_CTRL,
+			ACPU_SC_VD_SHIFT_TABLE_TUNE_VAL,
+			ACPU_SC_VD_SHIFT_TABLE_TUNE_MASK);
+	}
+
+	/* step 9: ACPUPLLCTRL.acpupll_en_cfg = 0x0 */
+	write_reg_mask(PMCTRL_ACPUPLLCTRL, 0x0,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START);
+
+	/* step 10: set PMCTRL_ACPUPLLFREQ and PMCTRL_ACPUPLLFRAC */
+	mmio_write_32(PMCTRL_ACPUPLLFREQ,
+		acpu_dvfs_profile[tar_prof].acpu_pll_freq);
+	mmio_write_32(PMCTRL_ACPUPLLFRAC,
+		acpu_dvfs_profile[tar_prof].acpu_pll_frac);
+
+	/*
+	 * step 11:
+	 *  - wait for 1us;
+	 *  - PMCTRL_ACPUPLLCTRL.acpupll_en_cfg = 0x1
+	 */
+	count = 0;
+	while (count < ACPU_WAIT_TIMEOUT)
+		count++;
+
+	write_reg_mask(PMCTRL_ACPUPLLCTRL,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START);
+
+	/* step 12: PMCTRL_ACPUVOLPMUADDR = 0x100da */
+	mmio_write_32(PMCTRL_ACPUVOLPMUADDR, 0x100da);
+
+	/*
+	 * step 13:
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x13 (208MHz);
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x13 (500MHz);
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x20 (798MHz);
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x3A (1300MHz);
+	 *  - PMCTRL_ACPUDESTVOL.acpu_dest_vol = 0x3A (1500MHz);
+	 */
+	write_reg_mask(PMCTRL_ACPUDESTVOL,
+		acpu_dvfs_profile[tar_prof].acpu_vol_profile,
+		((0x1 << (SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_END + 1)) - 1));
+
+	/*
+	 * step 14:
+	 *  - Polling PMCTRL_ACPUDESTVOL.acpu_vol_using == ACPUDESTVOL.acpu_dest_vol
+	 *  - Polling ACPUVOLTIMEOUT.acpu_vol_timeout == 0x1
+	 *  - Config PMCTRL_ACPUCLKDIV.acpu_ddr_clk_div_cfg
+	 *  - Config ACPUCLKDIV.cpuext_clk_div_cfg;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUDESTVOL, 0x7F,
+			SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_START);
+		reg1 = read_reg_mask(PMCTRL_ACPUDESTVOL, 0x7F,
+			SOC_PMCTRL_ACPUDESTVOL_acpu_vol_using_START);
+		reg2 = read_reg_mask(PMCTRL_ACPUVOLTTIMEOUT, 0x1,
+			SOC_PMCTRL_ACPUVOLTIMEOUT_acpu_vol_timeout_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu destvol cfg timeout.\n", __func__);
+			return -1;
+		}
+	} while ((reg0 != reg1) || (reg2 != 0x1));
+
+	acpu_dvfs_clk_div_cfg(tar_prof, &cpuext_cfg_val, &acpu_ddr_cfg_val);
+
+	/*
+	 * step 15:
+	 *  - Polling PMCTRL_ACPUCLKDIV.cpuext_clk_div_stat;
+	 *  - Polling ACPUCLKDIV.acpu_ddr_clk_div_stat;
+	 *  - ACPUPLLCTRL.acpupll_timeout = 0x1;
+	 *  - PMCTRL_ACPUPLLSEL.acpu_pllsw_cfg = 0x0;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUCLKDIV, 0x3,
+			SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_stat_START);
+		reg1 = read_reg_mask(PMCTRL_ACPUCLKDIV, 0x3,
+			SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_stat_START);
+		reg2 = read_reg_mask(PMCTRL_ACPUPLLCTRL, 0x1,
+			SOC_PMCTRL_ACPUPLLCTRL_acpupll_timeout_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu clk div cfg timeout.\n", __func__);
+			return -1;
+		}
+	} while ((reg1 != cpuext_cfg_val) ||
+		(reg0 != acpu_ddr_cfg_val) ||
+		(reg2 != 0x1));
+
+	write_reg_mask(PMCTRL_ACPUPLLSEL, 0x0,
+		0x1 << SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_cfg_START);
+
+	/*
+	 * step 16:
+	 *  - Polling PMCTRL_ACPUPLLSEL.acpupll_sw_stat == 0x1;
+	 *  - ACPU_SC_VD_CTRL.force_clk_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.clk_dis_cnt_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_ini = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_dif = 0x0;
+	 *  - ACPU_SC_VD_CTRL.div_en_dif = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0x1;
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x0;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x0;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLSEL, 0x1,
+			SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_stat_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu pll sw status timeout.\n", __func__);
+			return -1;
+		}
+	} while (reg0 != 0x1);
+
+	if (acpu_dvfs_profile[tar_prof].freq > 800000)
+		write_reg_mask(ACPU_SC_VD_CTRL,
+			ACPU_SC_VD_EN_ASIC_VAL, ACPU_SC_VD_EN_MASK);
+
+	write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x0,
+		(0x3 << SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_sw_START) |
+		(0x1 << SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_cfg_START));
+
+	return 0;
+}
+
+static int acpu_dvfs_freq_descend(unsigned int cur_prof, unsigned int tar_prof)
+{
+	unsigned int reg0 = 0;
+	unsigned int reg1 = 0;
+	unsigned int reg2 = 0;
+	unsigned int count = 0;
+	unsigned int cpuext_cfg_val = 0;
+	unsigned int acpu_ddr_cfg_val = 0;
+	int ret = 0;
+
+	ret = acpu_dvfs_syspll_cfg(tar_prof);
+	if (ret)
+		return -1;
+
+	/*
+	 * step 4:
+	 *  - Polling PMCTRL_ACPUPLLSEL.syspll_sw_stat == 0x1
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLSEL, 0x1, 2);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: syspll sw status timeout.\n", __func__);
+			return -1;
+		}
+	} while (reg0 != 0x1);
+
+	/*
+	 * Step 5:
+	 *  - PMCTRL_ACPUPLLCTRL.acpupll_en_cfg = 0x0
+	 */
+	write_reg_mask(PMCTRL_ACPUPLLCTRL, 0x0, 0x1 << 0);
+
+	/*
+	 * step 6
+	 *  - Config PMCTRL_ACPUPLLFREQ and ACPUPLLFRAC
+	 */
+	mmio_write_32(PMCTRL_ACPUPLLFREQ, acpu_dvfs_profile[tar_prof].acpu_pll_freq);
+	mmio_write_32(PMCTRL_ACPUPLLFRAC, acpu_dvfs_profile[tar_prof].acpu_pll_frac);
+
+	/*
+	 * step 7:
+	 *  - Wait 1us;
+	 *  - Config PMCTRL_ACPUPLLCTRL.acpupll_en_cfg = 0x1
+	 */
+	count = 0;
+	while (count < ACPU_WAIT_TIMEOUT)
+		count++;
+
+	write_reg_mask(PMCTRL_ACPUPLLCTRL,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START,
+		0x1 << SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START);
+
+	/* Enable VD functionality if > 800MHz */
+	if (acpu_dvfs_profile[tar_prof].freq > 800000) {
+
+		write_reg_mask(ACPU_SC_VD_HPM_CTRL,
+			HPM_OSC_DIV_VAL, HPM_OSC_DIV_MASK);
+
+		/*
+		 * step 9:
+		 *  - ACPU_SC_VD_HPM_CTRL.hpm_dly_exp = 0xC7A;
+		 *  - ACPU_SC_VD_MASK_PATTERN_CTRL[12:0] = 0xCCB;
+		 */
+		write_reg_mask(ACPU_SC_VD_HPM_CTRL,
+			HPM_DLY_EXP_VAL, HPM_DLY_EXP_MASK);
+		write_reg_mask(ACPU_SC_VD_MASK_PATTERN_CTRL,
+			ACPU_SC_VD_MASK_PATTERN_VAL,
+			ACPU_SC_VD_MASK_PATTERN_MASK);
+
+		/*
+		 * step 10:
+		 *  - ACPU_SC_VD_DLY_TABLE0_CTRL = 0x1FFF;
+		 *  - ACPU_SC_VD_DLY_TABLE1_CTRL = 0x1FFFFFF;
+		 *  - ACPU_SC_VD_DLY_TABLE2_CTRL = 0x7FFFFFFF;
+		 *  - ACPU_SC_VD_DLY_FIXED_CTRL  = 0x1;
+		 */
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE0_CTRL, 0x1FFF);
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE1_CTRL, 0x1FFFFFF);
+		mmio_write_32(ACPU_SC_VD_DLY_TABLE2_CTRL, 0x7FFFFFFF);
+		mmio_write_32(ACPU_SC_VD_DLY_FIXED_CTRL, 0x1);
+
+		/*
+		 * step 11:
+		 *  - ACPU_SC_VD_CTRL.shift_table0 = 0x1;
+		 *  - ACPU_SC_VD_CTRL.shift_table1 = 0x3;
+		 *  - ACPU_SC_VD_CTRL.shift_table2 = 0x5;
+		 *  - ACPU_SC_VD_CTRL.shift_table3 = 0x6;
+		 *
+		 * step 12:
+		 *  - ACPU_SC_VD_CTRL.tune = 0x7;
+		 */
+		write_reg_mask(ACPU_SC_VD_CTRL,
+			ACPU_SC_VD_SHIFT_TABLE_TUNE_VAL,
+			ACPU_SC_VD_SHIFT_TABLE_TUNE_MASK);
+	}
+
+	/*
+	 * step 13:
+	 *  - Pollig PMCTRL_ACPUPLLCTRL.acpupll_timeout == 0x1;
+	 *  - PMCTRL_ACPUPLLSEL.acpu_pllsw_cfg = 0x0;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLCTRL, 0x1,
+			SOC_PMCTRL_ACPUPLLCTRL_acpupll_timeout_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpupll timeout.\n", __func__);
+			return -1;
+		}
+	} while (reg0 != 0x1);
+
+	write_reg_mask(PMCTRL_ACPUPLLSEL, 0x0,
+		0x1 << SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_cfg_START);
+
+	/*
+	 * step 14:
+	 *  - Polling PMCTRL_ACPUPLLSEL.acpupll_sw_stat == 0x1;
+	 *  - ACPU_SC_VD_CTRL.force_clk_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.clk_dis_cnt_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_ini = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_dif = 0x0;
+	 *  - ACPU_SC_VD_CTRL.div_en_dif = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0x1;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUPLLSEL, 0x1,
+			SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_stat_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpupll sw status timeout.\n", __func__);
+			return -1;
+		}
+	} while (reg0 != 0x1);
+
+	if (acpu_dvfs_profile[tar_prof].freq > 800000)
+		write_reg_mask(ACPU_SC_VD_CTRL,
+			ACPU_SC_VD_EN_ASIC_VAL, ACPU_SC_VD_EN_MASK);
+
+	/*
+	 * step 15:
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x0;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x0;
+	 */
+	write_reg_mask(PMCTRL_ACPUSYSPLLCFG, 0x0,
+		(0x3 << SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_sw_START) |
+		(0x1 << SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_cfg_START));
+
+	/*
+	 * step 16:
+	 *  - Polling ACPU_SC_CPU_STAT.clk_div_status_vd == 0x0;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(ACPU_SC_CPU_STAT, 0x3,
+			ACPU_SC_CPU_STAT_CLK_DIV_STATUS_VD_SHIFT);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: clk div status timeout.\n", __func__);
+			return -1;
+		}
+	} while (reg0 != 0x0);
+
+	acpu_dvfs_clk_div_cfg(tar_prof, &cpuext_cfg_val, &acpu_ddr_cfg_val);
+
+	/*
+	 * step 17:
+	 *  - Polling PMCTRL_ACPUCLKDIV.cpuext_clk_div_stat;
+	 *  - Polling ACPUCLKDIV.acpu_ddr_clk_div_stat;
+	 *  - PMCTRL_ACPUVOLPMUADDR = 0x1006C;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUCLKDIV, 0x3,
+			SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_stat_START);
+		reg1 = read_reg_mask(PMCTRL_ACPUCLKDIV, 0x3,
+			SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_stat_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu clk div cfg timeout.\n", __func__);
+			return -1;
+		}
+	} while ((reg0 != cpuext_cfg_val) || (reg1 != acpu_ddr_cfg_val));
+
+	mmio_write_32(PMCTRL_ACPUVOLPMUADDR, 0x100da);
+
+	/*
+	 * step 16:
+	 *  - Polling PMCTRL_ACPUPLLSEL.acpupll_sw_stat == 0x1;
+	 *  - ACPU_SC_VD_CTRL.force_clk_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.clk_dis_cnt_en = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_ini = 0x0;
+	 *  - ACPU_SC_VD_CTRL.calibrate_en_dif = 0x0;
+	 *  - ACPU_SC_VD_CTRL.div_en_dif = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_int = 0x1;
+	 *  - ACPU_SC_VD_CTRL.tune_en_dif = 0x1;
+	 *  - PMCTRL_ACPUSYSPLLCFG.acpu_subsys_clk_div_sw = 0x0;
+	 *  - ACPUSYSPLLCFG.acpu_syspll_clken_cfg = 0x0;
+	 */
+	write_reg_mask(PMCTRL_ACPUDESTVOL,
+		acpu_dvfs_profile[tar_prof].acpu_vol_profile,
+		((0x1 << (SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_END + 1)) - 1));
+
+	/*
+	 * step 19:
+	 *  - Polling PMCTRL_ACPUDESTVOL.acpu_vol_using == ACPUDESTVOL.acpu_dest_vol
+	 *  - ACPUVOLTIMEOUT.acpu_vol_timeout = 0x1;
+	 */
+	count = 0;
+	do {
+		reg0 = read_reg_mask(PMCTRL_ACPUDESTVOL, 0x7F,
+			SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_START);
+		reg1 = read_reg_mask(PMCTRL_ACPUDESTVOL, 0x7F,
+			SOC_PMCTRL_ACPUDESTVOL_acpu_vol_using_START);
+		reg2 = read_reg_mask(PMCTRL_ACPUVOLTTIMEOUT, 0x1,
+			SOC_PMCTRL_ACPUVOLTIMEOUT_acpu_vol_timeout_START);
+		if ((count++) > ACPU_DFS_STATE_CNT) {
+			ERROR("%s: acpu destvol cfg timeout.\n", __func__);
+			return -1;
+		}
+	} while ((reg0 != reg1) || (reg2 != 0x1));
+
+	return 0;
+}
+
+int acpu_dvfs_target(unsigned int curr_prof, unsigned int target_prof)
+{
+	int ret = 0;
+
+	if (curr_prof == target_prof) {
+		INFO("%s: target_prof is equal curr_prof: is %d!\n",
+			__func__, curr_prof);
+		return 0;
+	}
+
+	if ((curr_prof >= ACPU_FREQ_MAX_NUM) ||
+	    (target_prof >= ACPU_FREQ_MAX_NUM)) {
+		INFO("%s: invalid parameter %d %d\n",
+			__func__, curr_prof, target_prof);
+		return -1;
+	}
+
+	if (target_prof > acpu_dvfs_sram_buf->support_freq_num)
+		target_prof = acpu_dvfs_sram_buf->support_freq_num;
+
+	if (target_prof < curr_prof)
+		ret = acpu_dvfs_freq_descend(curr_prof, target_prof);
+	else if (target_prof > curr_prof)
+		ret = acpu_dvfs_freq_ascend(curr_prof, target_prof);
+
+	if (ret) {
+		ERROR("%s: acpu_dvfs_target failed!\n", __func__);
+		return -1;
+	}
+
+	/* Complete acpu dvfs setting and set magic number */
+	acpu_dvfs_sram_buf->start_prof = target_prof;
+	acpu_dvfs_sram_buf->magic = ACPU_VALID_VOLTAGE_MAGIC;
+
+	mmio_write_32(DDR_DFS_FREQ_ADDR, 800000);
+	return 0;
+}
+
+static int acpu_dvfs_set_freq(void)
+{
+	unsigned int i;
+	unsigned int curr_prof;
+	unsigned int target_prof;
+	unsigned int max_freq = 0;
+
+	max_freq = acpu_dvfs_sram_buf->support_freq_max;
+
+	for (i = 0; i < acpu_dvfs_sram_buf->support_freq_num; i++) {
+
+		if (max_freq == hi6220_acpu_profile[i].freq) {
+			target_prof = i;
+			break;
+		}
+	}
+
+	if (i == acpu_dvfs_sram_buf->support_freq_num) {
+		ERROR("%s: cannot found max freq profile\n", __func__);
+		return -1;
+	}
+
+	curr_prof = 0;
+	target_prof = i;
+
+	/* if max freq is 208MHz, do nothing */
+	if (curr_prof == target_prof)
+		return 0;
+
+	if (acpu_dvfs_target(curr_prof, target_prof)) {
+		ERROR("%s: set acpu freq failed!", __func__);
+		return -1;
+	}
+
+	INFO("%s: support freq num is %d\n",
+		__func__, acpu_dvfs_sram_buf->support_freq_num);
+	INFO("%s: start prof is 0x%x\n",
+		__func__,  acpu_dvfs_sram_buf->start_prof);
+	INFO("%s: magic is 0x%x\n",
+		__func__, acpu_dvfs_sram_buf->magic);
+	INFO("%s: voltage:\n", __func__);
+	for (i = 0; i < acpu_dvfs_sram_buf->support_freq_num; i++)
+		INFO("  - %d: 0x%x\n", i, acpu_dvfs_sram_buf->vol[i]);
+
+	NOTICE("%s: set acpu freq success!", __func__);
+	return 0;
+}
+
+struct acpu_dvfs_volt_setting {
+	unsigned int magic;
+	unsigned int support_freq_num;
+	unsigned int support_freq_max;
+	unsigned int start_prof;
+	unsigned int vol[7];
+	unsigned int hmp_dly_threshold[7];
+};
+
+static void acpu_dvfs_volt_init(void)
+{
+	struct acpu_dvfs_volt_setting *volt;
+
+	/*
+	 * - set default voltage;
+	 * - set pmu address;
+	 * - set voltage up and down step;
+	 * - set voltage stable time;
+	 */
+	mmio_write_32(PMCTRL_ACPUDFTVOL, 0x4a);
+	mmio_write_32(PMCTRL_ACPUVOLPMUADDR, 0xda);
+	mmio_write_32(PMCTRL_ACPUVOLUPSTEP, 0x1);
+	mmio_write_32(PMCTRL_ACPUVOLDNSTEP, 0x1);
+	mmio_write_32(PMCTRL_ACPUPMUVOLUPTIME, 0x60);
+	mmio_write_32(PMCTRL_ACPUPMUVOLDNTIME, 0x60);
+	mmio_write_32(PMCTRL_ACPUCLKOFFCFG, 0x1000);
+
+	volt = (void *)MEMORY_AXI_ACPU_FREQ_VOL_ADDR;
+	volt->magic = 0x5a5ac5c5;
+	volt->support_freq_num = 5;
+	volt->support_freq_max = 1200000;
+	volt->start_prof = 4;
+	volt->vol[0] = 0x49;
+	volt->vol[1] = 0x49;
+	volt->vol[2] = 0x50;
+	volt->vol[3] = 0x60;
+	volt->vol[4] = 0x78;
+	volt->vol[5] = 0x78;
+	volt->vol[6] = 0x78;
+
+	volt->hmp_dly_threshold[0] = 0x0;
+	volt->hmp_dly_threshold[1] = 0x0;
+	volt->hmp_dly_threshold[2] = 0x0;
+	volt->hmp_dly_threshold[3] = 0x0e8b0e45;
+	volt->hmp_dly_threshold[4] = 0x10691023;
+	volt->hmp_dly_threshold[5] = 0x10691023;
+	volt->hmp_dly_threshold[6] = 0x10691023;
+
+	INFO("%s: success!\n", __func__);
+}
+
+void init_acpu_dvfs(void)
+{
+	unsigned int i = 0;
+
+	INFO("%s: pmic version %d\n", __func__,
+	     mmio_read_8(HI6553_VERSION_REG));
+
+	/* init parameters */
+	mmio_write_32(ACPU_CHIP_MAX_FREQ, efuse_acpu_freq[8]);
+	INFO("%s: ACPU_CHIP_MAX_FREQ=0x%x.\n",
+		__func__, mmio_read_32(ACPU_CHIP_MAX_FREQ));
+
+	/* set maximum support frequency to 1.2GHz */
+	for (i = 0; i < ACPU_FREQ_MAX_NUM; i++)
+		acpu_dvfs_sram_buf->vol[i] = hi6220_acpu_profile[i].acpu_vol_profile;
+
+	acpu_dvfs_sram_buf->support_freq_num = ACPU_FREQ_MAX_NUM;
+	acpu_dvfs_sram_buf->support_freq_max = 1200000;
+
+	/* init acpu dvfs */
+	acpu_dvfs_volt_init();
+	acpu_dvfs_set_freq();
+}
diff --git a/plat/hisilicon/hikey/hisi_ipc.c b/plat/hisilicon/hikey/hisi_ipc.c
new file mode 100644
index 0000000..0469a08
--- /dev/null
+++ b/plat/hisilicon/hikey/hisi_ipc.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <hisi_ipc.h>
+#include <hisi_sram_map.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+static int ipc_init;
+
+static unsigned int cpu_ipc_num[PLATFORM_CLUSTER_COUNT][PLATFORM_CORE_COUNT_PER_CLUSTER] = {
+	{
+		HISI_IPC_MCU_INT_SRC_ACPU0_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU1_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU2_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU3_PD,
+	},
+	{
+		HISI_IPC_MCU_INT_SRC_ACPU4_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU5_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU6_PD,
+		HISI_IPC_MCU_INT_SRC_ACPU7_PD,
+	}
+};
+
+int hisi_cpus_pd_in_cluster_besides_curr(unsigned int cpu,
+					 unsigned int cluster)
+{
+	unsigned int val = 0, cpu_val = 0;
+	int i;
+
+	val = mmio_read_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR);
+	val = val >> (cluster * 16);
+
+	for (i = 0; i < PLATFORM_CORE_COUNT_PER_CLUSTER; i++) {
+
+		if (cpu == i)
+			continue;
+
+		cpu_val = (val >> (i * 4)) & 0xF;
+		if (cpu_val == 0x8)
+			return 0;
+	}
+
+	return 1;
+}
+
+int hisi_cpus_powered_off_besides_curr(unsigned int cpu)
+{
+	unsigned int val;
+
+	val = mmio_read_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR);
+	return (val == (0x8 << (cpu * 4)));
+}
+
+static void hisi_ipc_send(unsigned int ipc_num)
+{
+	if (!ipc_init) {
+		printf("error ipc base is null!!!\n");
+		return;
+	}
+
+	mmio_write_32(HISI_IPC_CPU_RAW_INT_ADDR, 1 << ipc_num);
+}
+
+void hisi_ipc_spin_lock(unsigned int signal)
+{
+	unsigned int hs_ctrl;
+
+	if (signal >= HISI_IPC_INT_SRC_NUM)
+		return;
+
+	do {
+		hs_ctrl = mmio_read_32(HISI_IPC_ACPU_CTRL(signal));
+	} while (hs_ctrl);
+}
+
+void hisi_ipc_spin_unlock(unsigned int signal)
+{
+	if (signal >= HISI_IPC_INT_SRC_NUM)
+		return;
+
+	mmio_write_32(HISI_IPC_ACPU_CTRL(signal), 0);
+}
+
+void hisi_ipc_cpu_on_off(unsigned int cpu, unsigned int cluster,
+			 unsigned int mode)
+{
+	unsigned int val = 0;
+	unsigned int offset;
+
+	if (mode == HISI_IPC_PM_ON)
+		offset = cluster * 16 + cpu * 4;
+	else
+		offset = cluster * 16 + cpu * 4 + 1;
+
+	hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+	val = mmio_read_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR);
+	val |= (0x01 << offset);
+	mmio_write_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR, val);
+	isb();
+	dsb();
+	hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+	hisi_ipc_send(cpu_ipc_num[cluster][cpu]);
+}
+
+void hisi_ipc_cpu_on(unsigned int cpu, unsigned int cluster)
+{
+	hisi_ipc_cpu_on_off(cpu, cluster, HISI_IPC_PM_ON);
+}
+
+void hisi_ipc_cpu_off(unsigned int cpu, unsigned int cluster)
+{
+	hisi_ipc_cpu_on_off(cpu, cluster, HISI_IPC_PM_OFF);
+}
+
+void hisi_ipc_cluster_on_off(unsigned int cpu, unsigned int cluster,
+			     unsigned int mode)
+{
+	unsigned int val = 0;
+	unsigned int offset;
+
+	if (mode == HISI_IPC_PM_ON)
+		offset = cluster * 4;
+	else
+		offset = cluster * 4 + 1;
+
+	hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+	val = mmio_read_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR);
+	val |= (0x01 << offset);
+	mmio_write_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR, val);
+	isb();
+	dsb();
+	hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+	hisi_ipc_send(cpu_ipc_num[cluster][cpu]);
+}
+
+void hisi_ipc_cluster_on(unsigned int cpu, unsigned int cluster)
+{
+	hisi_ipc_cluster_on_off(cpu, cluster, HISI_IPC_PM_ON);
+}
+
+void hisi_ipc_cluster_off(unsigned int cpu, unsigned int cluster)
+{
+	hisi_ipc_cluster_on_off(cpu, cluster, HISI_IPC_PM_OFF);
+}
+
+void hisi_ipc_cpu_suspend(unsigned int cpu, unsigned int cluster)
+{
+	unsigned int val = 0;
+	unsigned int offset;
+
+	offset = cluster * 16 + cpu * 4 + 2;
+
+	hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+	val = mmio_read_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR);
+	val |= (0x01 << offset);
+	mmio_write_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR, val);
+	hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+	hisi_ipc_send(cpu_ipc_num[cluster][cpu]);
+}
+
+void hisi_ipc_cluster_suspend(unsigned int cpu, unsigned int cluster)
+{
+	unsigned int val;
+	unsigned int offset;
+
+	offset = cluster * 4 + 1;
+
+	hisi_ipc_spin_lock(HISI_IPC_SEM_CPUIDLE);
+	if (hisi_cpus_pd_in_cluster_besides_curr(cpu, cluster)) {
+		val = mmio_read_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR);
+		val |= (0x01 << offset);
+		mmio_write_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR, val);
+	}
+	hisi_ipc_spin_unlock(HISI_IPC_SEM_CPUIDLE);
+
+	hisi_ipc_send(cpu_ipc_num[cluster][cpu]);
+}
+
+void hisi_ipc_psci_system_off(void)
+{
+	hisi_ipc_send(HISI_IPC_MCU_INT_SRC_ACPU_PD);
+}
+
+int hisi_ipc_init(void)
+{
+	ipc_init = 1;
+
+	mmio_write_32(ACPU_CORE_POWERDOWN_FLAGS_ADDR, 0x8);
+	mmio_write_32(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR, 0x8);
+	return 0;
+}
diff --git a/plat/hisilicon/hikey/hisi_mcu.c b/plat/hisilicon/hikey/hisi_mcu.c
new file mode 100644
index 0000000..359b94d
--- /dev/null
+++ b/plat/hisilicon/hikey/hisi_mcu.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <hi6220.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+
+#define MCU_SECTION_MAX		30
+
+enum MCU_IMAGE_SEC_TYPE_ENUM {
+	MCU_IMAGE_SEC_TYPE_TEXT = 0,	/* text section */
+	MCU_IMAGE_SEC_TYPE_DATA,	/* data section */
+	MCU_IMAGE_SEC_TYPE_BUTT
+};
+
+enum MCU_IMAGE_SEC_LOAD_ENUM {
+	MCU_IMAGE_SEC_LOAD_STATIC = 0,
+	MCU_IMAGE_SEC_LOAD_DYNAMIC,
+	MCU_IMAGE_SEC_LOAD_BUFFER,
+	MCU_IMAGE_SEC_LOAD_MODEM_ENTRY,
+	MCU_IMAGE_SEC_LOAD_BUTT
+};
+
+struct mcu_image_sec {
+	unsigned short serial;
+	char type;
+	char load_attr;
+	uint32_t src_offset;		/* offset in image */
+	uint32_t dst_offset;		/* offset in memory */
+	uint32_t size;
+};
+
+struct mcu_image_head {
+	char time_stamp[24];
+	uint32_t image_size;
+	uint32_t secs_num;
+	struct mcu_image_sec secs[MCU_SECTION_MAX];
+};
+
+#define SOC_SRAM_M3_BASE_ADDR		(0xF6000000)
+
+#define MCU_SRAM_SIZE			(0x0000C000)
+#define MCU_CACHE_SIZE			(0x00004000)
+#define MCU_CODE_SIZE			(MCU_SRAM_SIZE - MCU_CACHE_SIZE)
+
+#define MCU_SYS_MEM_ADDR		(0x05E00000)
+#define MCU_SYS_MEM_SIZE		(0x00100000)
+
+static uint32_t mcu2ap_addr(uint32_t mcu_addr)
+{
+	if (mcu_addr < MCU_CODE_SIZE)
+		return (mcu_addr + SOC_SRAM_M3_BASE_ADDR);
+	else if ((mcu_addr >= MCU_SRAM_SIZE) &&
+		 (mcu_addr < MCU_SRAM_SIZE + MCU_SYS_MEM_SIZE))
+		return mcu_addr - MCU_SRAM_SIZE + MCU_SYS_MEM_ADDR;
+	else
+		return mcu_addr;
+}
+
+static int is_binary_header_invalid(struct mcu_image_head *head,
+				    unsigned int length)
+{
+	/* invalid cases */
+	if ((head->image_size == 0) ||
+	    (head->image_size > length) ||
+	    (head->secs_num > MCU_SECTION_MAX) ||
+	    (head->secs_num == 0))
+		return 1;
+
+	return 0;
+}
+
+static int is_binary_section_invalid(struct mcu_image_sec *sec,
+				     struct mcu_image_head *head)
+{
+	unsigned long ap_dst_offset = 0;
+
+	if ((sec->serial >= head->secs_num) ||
+	    (sec->src_offset + sec->size > head->image_size))
+		return 1;
+
+	if ((sec->type >= MCU_IMAGE_SEC_TYPE_BUTT) ||
+	    (sec->load_attr >= MCU_IMAGE_SEC_LOAD_BUTT))
+		return 1;
+
+	ap_dst_offset = mcu2ap_addr(sec->dst_offset);
+	if ((ap_dst_offset >= SOC_SRAM_M3_BASE_ADDR) &&
+	    (ap_dst_offset < SOC_SRAM_M3_BASE_ADDR + 0x20000 - sec->size))
+		return 0;
+	else if ((ap_dst_offset >= MCU_SYS_MEM_ADDR) &&
+		 (ap_dst_offset < MCU_SYS_MEM_ADDR + MCU_SYS_MEM_SIZE - sec->size))
+		return 0;
+	else if ((ap_dst_offset >= 0xfff8e000) &&
+		 (ap_dst_offset < 0xfff91c00 - sec->size))
+		return 0;
+
+	ERROR("%s: mcu destination address invalid.\n", __func__);
+	ERROR("%s: number=%d, dst offset=%d size=%d\n",
+		__func__, sec->serial, sec->dst_offset, sec->size);
+	return 1;
+}
+
+void hisi_mcu_enable_sram(void)
+{
+	mmio_write_32(AO_SC_PERIPH_CLKEN4,
+		      AO_SC_PERIPH_CLKEN4_HCLK_IPC_S |
+		      AO_SC_PERIPH_CLKEN4_HCLK_IPC_NS);
+
+	/* set register to enable dvfs which is used by mcu */
+	mmio_write_32(PERI_SC_RESERVED8_ADDR, 0x0A001022);
+
+	/* mcu mem is powered on, need de-assert reset */
+	mmio_write_32(AO_SC_PERIPH_RSTDIS4,
+		      AO_SC_PERIPH_RSTDIS4_RESET_MCU_ECTR_N);
+
+	/* enable mcu hclk */
+	mmio_write_32(AO_SC_PERIPH_CLKEN4,
+		      AO_SC_PERIPH_CLKEN4_HCLK_MCU |
+		      AO_SC_PERIPH_CLKEN4_CLK_MCU_DAP);
+}
+
+void hisi_mcu_start_run(void)
+{
+	unsigned int val;
+
+	/* set mcu ddr remap configuration */
+	mmio_write_32(AO_SC_MCU_SUBSYS_CTRL2, MCU_SYS_MEM_ADDR);
+
+	/* de-assert reset for mcu and to run */
+	mmio_write_32(AO_SC_PERIPH_RSTDIS4,
+		AO_SC_PERIPH_RSTDIS4_RESET_MCU_ECTR_N |
+		AO_SC_PERIPH_RSTDIS4_RESET_MCU_SYS_N |
+		AO_SC_PERIPH_RSTDIS4_RESET_MCU_POR_N |
+		AO_SC_PERIPH_RSTDIS4_RESET_MCU_DAP_N);
+
+	val = mmio_read_32(AO_SC_SYS_CTRL2);
+	mmio_write_32(AO_SC_SYS_CTRL2,
+		val | AO_SC_SYS_CTRL2_GLB_SRST_STAT_CLEAR);
+
+	INFO("%s: AO_SC_SYS_CTRL2=%x\n", __func__,
+		mmio_read_32(AO_SC_SYS_CTRL2));
+}
+
+int hisi_mcu_load_image(uintptr_t image_base, uint32_t image_size)
+{
+	unsigned int i;
+	struct mcu_image_head *head;
+	char *buf;
+
+	head = (struct mcu_image_head *)image_base;
+	if (is_binary_header_invalid(head, image_size)) {
+		ERROR("Invalid %s image header.\n", head->time_stamp);
+		return -1;
+	}
+
+	buf = (char *)head;
+	for (i = 0; i < head->secs_num; i++) {
+
+		int *src, *dst;
+
+		/* check the sections */
+		if (is_binary_section_invalid(&head->secs[i], head)) {
+			ERROR("Invalid mcu section.\n");
+			return -1;
+		}
+
+		/* check if the section is static-loaded */
+		if (head->secs[i].load_attr != MCU_IMAGE_SEC_LOAD_STATIC)
+			continue;
+
+		/* copy the sections */
+		src = (int *)(intptr_t)(buf + head->secs[i].src_offset);
+		dst = (int *)(intptr_t)mcu2ap_addr(head->secs[i].dst_offset);
+
+		memcpy((void *)dst, (void *)src, head->secs[i].size);
+
+		INFO("%s: mcu sections %d:\n", __func__, i);
+		INFO("%s:  src  = 0x%x\n",
+		     __func__, (unsigned int)(uintptr_t)src);
+		INFO("%s:  dst  = 0x%x\n",
+		     __func__, (unsigned int)(uintptr_t)dst);
+		INFO("%s:  size = %d\n", __func__, head->secs[i].size);
+
+		INFO("%s:  [SRC 0x%x] 0x%x 0x%x 0x%x 0x%x\n",
+		     __func__, (unsigned int)(uintptr_t)src,
+		     src[0], src[1], src[2], src[3]);
+		INFO("%s:  [DST 0x%x] 0x%x 0x%x 0x%x 0x%x\n",
+		     __func__, (unsigned int)(uintptr_t)dst,
+		     dst[0], dst[1], dst[2], dst[3]);
+	}
+
+	return 0;
+}
diff --git a/plat/hisilicon/hikey/hisi_pwrc.c b/plat/hisilicon/hikey/hisi_pwrc.c
new file mode 100644
index 0000000..fcc9bd8
--- /dev/null
+++ b/plat/hisilicon/hikey/hisi_pwrc.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <hisi_ipc.h>
+#include <hisi_pwrc.h>
+#include <hisi_sram_map.h>
+#include <hi6220_regs_acpu.h>
+#include <hi6220_regs_ao.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <platform_def.h>
+
+#define CLUSTER_CORE_COUNT		(4)
+#define CLUSTER_CORE_MASK		((1 << CLUSTER_CORE_COUNT) - 1)
+
+void hisi_pwrc_set_core_bx_addr(unsigned int core, unsigned int cluster,
+				uintptr_t entry_point)
+{
+	uintptr_t *core_entry = (uintptr_t *)PWRCTRL_ACPU_ASM_D_ARM_PARA_AD;
+	unsigned int i;
+
+	if (!core_entry) {
+		INFO("%s: core entry point is null!\n", __func__);
+		return;
+	}
+
+	i = cluster * CLUSTER_CORE_COUNT + core;
+	mmio_write_64((uintptr_t)(core_entry + i), entry_point);
+}
+
+void hisi_pwrc_set_cluster_wfi(unsigned int cluster)
+{
+	unsigned int reg = 0;
+
+	if (cluster == 0) {
+		reg = mmio_read_32(ACPU_SC_SNOOP_PWD);
+		reg |= PD_DETECT_START0;
+		mmio_write_32(ACPU_SC_SNOOP_PWD, reg);
+	} else if (cluster == 1) {
+		reg = mmio_read_32(ACPU_SC_SNOOP_PWD);
+		reg |= PD_DETECT_START1;
+		mmio_write_32(ACPU_SC_SNOOP_PWD, reg);
+	}
+}
+
+int hisi_pwrc_setup(void)
+{
+	unsigned int reg, sec_entrypoint;
+	extern char pm_asm_code[], pm_asm_code_end[];
+	extern char v7_asm[], v7_asm_end[];
+
+	sec_entrypoint = PWRCTRL_ACPU_ASM_CODE_BASE;
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(0), sec_entrypoint >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(1), sec_entrypoint >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(2), sec_entrypoint >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(3), sec_entrypoint >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(4), sec_entrypoint >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(5), sec_entrypoint >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(6), sec_entrypoint >> 2);
+	mmio_write_32(ACPU_SC_CPUx_RVBARADDR(7), sec_entrypoint >> 2);
+
+	memset((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, 0, 0x400);
+	memcpy((void *)PWRCTRL_ACPU_ASM_SPACE_ADDR, (void *)v7_asm,
+	       v7_asm_end - v7_asm);
+
+	memcpy((void *)PWRCTRL_ACPU_ASM_CODE_BASE, (void *)pm_asm_code,
+	       pm_asm_code_end - pm_asm_code);
+
+	reg = mmio_read_32(AO_SC_SYS_CTRL1);
+	reg |= AO_SC_SYS_CTRL1_REMAP_SRAM_AARM |
+	       AO_SC_SYS_CTRL1_REMAP_SRAM_AARM_MSK;
+	mmio_write_32(AO_SC_SYS_CTRL1, reg);
+
+	return 0;
+}
diff --git a/plat/hisilicon/hikey/hisi_pwrc_sram.S b/plat/hisilicon/hikey/hisi_pwrc_sram.S
new file mode 100644
index 0000000..054763b
--- /dev/null
+++ b/plat/hisilicon/hikey/hisi_pwrc_sram.S
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cortex_a53.h>
+#include <hi6220.h>
+#include <hisi_sram_map.h>
+
+	.global pm_asm_code
+	.global pm_asm_code_end
+	.global v7_asm
+	.global v7_asm_end
+
+	.align	3
+func pm_asm_code
+	mov	x0, 0
+	msr	oslar_el1, x0
+
+	mrs	x0, CPUACTLR_EL1
+	bic	x0, x0, #(CPUACTLR_RADIS | CPUACTLR_L1RADIS)
+	orr	x0, x0, #0x180000
+	orr	x0, x0, #0xe000
+	msr	CPUACTLR_EL1, x0
+
+	mrs	x3, actlr_el3
+	orr	x3, x3, #ACTLR_EL3_L2ECTLR_BIT
+	msr	actlr_el3, x3
+
+	mrs	x3, actlr_el2
+	orr	x3, x3, #ACTLR_EL2_L2ECTLR_BIT
+	msr	actlr_el2, x3
+
+	ldr	x3, =PWRCTRL_ACPU_ASM_D_ARM_PARA_AD
+	mrs	x0, mpidr_el1
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+pen:	ldr	x4, [x3, x0, LSL #3]
+	cbz	x4, pen
+
+	mov	x0, #0x0
+	mov	x1, #0x0
+	mov	x2, #0x0
+	mov	x3, #0x0
+	br	x4
+
+	.ltorg
+
+pm_asm_code_end:
+endfunc pm_asm_code
+
+	/*
+	 * By default, all cores in Hi6220 reset with aarch32 mode.
+	 * Now hardcode ARMv7 instructions to execute warm reset for
+	 * switching aarch64 mode.
+	 */
+	.align	3
+	.section .rodata.v7_asm, "aS"
+v7_asm:
+	.word	0xE1A00000	// nop
+	.word	0xE3A02003	// mov r2, #3
+	.word	0xEE0C2F50	// mcr 15, 0, r2, cr12, cr0, {2}
+	.word	0xE320F003	// wfi
+
+	.ltorg
+v7_asm_end:
diff --git a/plat/hisilicon/hikey/include/hi6220.h b/plat/hisilicon/hikey/include/hi6220.h
new file mode 100644
index 0000000..a9c408d
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hi6220.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HI6220_H__
+#define __HI6220_H__
+
+#include <hi6220_regs_acpu.h>
+#include <hi6220_regs_ao.h>
+#include <hi6220_regs_peri.h>
+#include <hi6220_regs_pin.h>
+#include <hi6220_regs_pmctrl.h>
+
+/*******************************************************************************
+ * Implementation defined ACTLR_EL2 bit definitions
+ ******************************************************************************/
+#define ACTLR_EL2_L2ACTLR_BIT		(1 << 6)
+#define ACTLR_EL2_L2ECTLR_BIT		(1 << 5)
+#define ACTLR_EL2_L2CTLR_BIT		(1 << 4)
+#define ACTLR_EL2_CPUECTLR_BIT		(1 << 1)
+#define ACTLR_EL2_CPUACTLR_BIT		(1 << 0)
+
+/*******************************************************************************
+ * Implementation defined ACTLR_EL3 bit definitions
+ ******************************************************************************/
+#define ACTLR_EL3_L2ACTLR_BIT		(1 << 6)
+#define ACTLR_EL3_L2ECTLR_BIT		(1 << 5)
+#define ACTLR_EL3_L2CTLR_BIT		(1 << 4)
+#define ACTLR_EL3_CPUECTLR_BIT		(1 << 1)
+#define ACTLR_EL3_CPUACTLR_BIT		(1 << 0)
+
+/*******************************************************************************
+ * CCI-400 related constants
+ ******************************************************************************/
+#define CCI400_BASE				0xF6E90000
+#define CCI400_SL_IFACE3_CLUSTER_IX		3
+#define CCI400_SL_IFACE4_CLUSTER_IX		4
+
+#define DWMMC0_BASE				0xF723D000
+
+#define DWUSB_BASE				0xF72C0000
+
+#define PMUSSI_BASE				0xF8000000
+
+#define SP804_TIMER0_BASE			0xF8008000
+
+#define GPIO0_BASE				0xF8011000
+#define GPIO1_BASE				0xF8012000
+#define GPIO2_BASE				0xF8013000
+#define GPIO3_BASE				0xF8014000
+#define GPIO4_BASE				0xF7020000
+#define GPIO5_BASE				0xF7021000
+#define GPIO6_BASE				0xF7022000
+#define GPIO7_BASE				0xF7023000
+#define GPIO8_BASE				0xF7024000
+#define GPIO9_BASE				0xF7025000
+#define GPIO10_BASE				0xF7026000
+#define GPIO11_BASE				0xF7027000
+#define GPIO12_BASE				0xF7028000
+#define GPIO13_BASE				0xF7029000
+#define GPIO14_BASE				0xF702A000
+#define GPIO15_BASE				0xF702B000
+#define GPIO16_BASE				0xF702C000
+#define GPIO17_BASE				0xF702D000
+#define GPIO18_BASE				0xF702E000
+#define GPIO19_BASE				0xF702F000
+
+#endif	/* __HI6220_H__ */
diff --git a/plat/hisilicon/hikey/include/hi6220_regs_acpu.h b/plat/hisilicon/hikey/include/hi6220_regs_acpu.h
new file mode 100644
index 0000000..dde9e65
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hi6220_regs_acpu.h
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HI6220_REGS_ACPU_H__
+#define __HI6220_REGS_ACPU_H__
+
+#define ACPU_CTRL_BASE				0xF6504000
+
+#define ACPU_SC_CPU_CTRL			(ACPU_CTRL_BASE + 0x000)
+#define ACPU_SC_CPU_STAT			(ACPU_CTRL_BASE + 0x008)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFIL2		(1 << 0)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFIL2_SHIFT		(0)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI0			(1 << 1)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI0_SHIFT		(1)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI1			(1 << 2)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI1_SHIFT		(2)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI2			(1 << 3)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI2_SHIFT		(3)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI3			(1 << 4)
+#define ACPU_SC_CPU_STAT_SC_STANDBYWFI3_SHIFT		(4)
+#define ACPU_SC_CPU_STAT_A53_1_STANDBYWFIL2		(1 << 8)
+#define ACPU_SC_CPU_STAT_A53_1_STANDBYWFIL2_SHIFT	(8)
+#define ACPU_SC_CPU_STAT_A53_1_STANDBYWFI		(1 << 9)
+#define ACPU_SC_CPU_STAT_A53_1_STANDBYWFI_SHIFT		(9)
+#define ACPU_SC_CPU_STAT_L2FLSHUDONE0			(1 << 16)
+#define ACPU_SC_CPU_STAT_L2FLSHUDONE0_SHIFT		(16)
+#define ACPU_SC_CPU_STAT_L2FLSHUDONE1			(1 << 17)
+#define ACPU_SC_CPU_STAT_L2FLSHUDONE1_SHIFT		(17)
+#define ACPU_SC_CPU_STAT_CCI400_ACTIVE			(1 << 18)
+#define ACPU_SC_CPU_STAT_CCI400_ACTIVE_SHIFT		(18)
+#define ACPU_SC_CPU_STAT_CLK_DIV_STATUS_VD		(1 << 20)
+#define ACPU_SC_CPU_STAT_CLK_DIV_STATUS_VD_SHIFT	(20)
+
+#define ACPU_SC_CLKEN				(ACPU_CTRL_BASE + 0x00c)
+#define HPM_L2_1_CLKEN				(1 << 9)
+#define G_CPU_1_CLKEN				(1 << 8)
+#define HPM_L2_CLKEN				(1 << 1)
+#define G_CPU_CLKEN				(1 << 0)
+
+#define ACPU_SC_CLKDIS				(ACPU_CTRL_BASE + 0x010)
+#define ACPU_SC_CLK_STAT			(ACPU_CTRL_BASE + 0x014)
+#define ACPU_SC_RSTEN				(ACPU_CTRL_BASE + 0x018)
+#define SRST_PRESET1_RSTEN			(1 << 11)
+#define SRST_PRESET0_RSTEN			(1 << 10)
+#define SRST_CLUSTER1_RSTEN			(1 << 9)
+#define SRST_CLUSTER0_RSTEN			(1 << 8)
+#define SRST_L2_HPM_1_RSTEN			(1 << 5)
+#define SRST_AARM_L2_1_RSTEN			(1 << 4)
+#define SRST_L2_HPM_0_RSTEN			(1 << 3)
+#define SRST_AARM_L2_0_RSTEN			(1 << 1)
+#define SRST_CLUSTER1				(SRST_PRESET1_RSTEN | \
+						 SRST_CLUSTER1_RSTEN | \
+						 SRST_L2_HPM_1_RSTEN | \
+						 SRST_AARM_L2_1_RSTEN)
+#define SRST_CLUSTER0				(SRST_PRESET0_RSTEN | \
+						 SRST_CLUSTER0_RSTEN | \
+						 SRST_L2_HPM_0_RSTEN | \
+						 SRST_AARM_L2_0_RSTEN)
+
+#define ACPU_SC_RSTDIS				(ACPU_CTRL_BASE + 0x01c)
+#define ACPU_SC_RST_STAT			(ACPU_CTRL_BASE + 0x020)
+#define ACPU_SC_PDBGUP_MBIST			(ACPU_CTRL_BASE + 0x02c)
+#define PDBGUP_CLUSTER1_SHIFT			8
+
+#define ACPU_SC_VD_CTRL				(ACPU_CTRL_BASE + 0x054)
+#define ACPU_SC_VD_MASK_PATTERN_CTRL		(ACPU_CTRL_BASE + 0x058)
+#define ACPU_SC_VD_MASK_PATTERN_VAL		(0xCCB << 12)
+#define ACPU_SC_VD_MASK_PATTERN_MASK		((0x1 << 13) - 1)
+
+#define ACPU_SC_VD_DLY_FIXED_CTRL		(ACPU_CTRL_BASE + 0x05c)
+#define ACPU_SC_VD_DLY_TABLE0_CTRL		(ACPU_CTRL_BASE + 0x060)
+#define ACPU_SC_VD_DLY_TABLE1_CTRL		(ACPU_CTRL_BASE + 0x064)
+#define ACPU_SC_VD_DLY_TABLE2_CTRL		(ACPU_CTRL_BASE + 0x068)
+#define ACPU_SC_VD_HPM_CTRL			(ACPU_CTRL_BASE + 0x06c)
+#define ACPU_SC_A53_CLUSTER_MTCMOS_EN		(ACPU_CTRL_BASE + 0x088)
+#define PW_MTCMOS_EN_A53_1_EN			(1 << 1)
+#define PW_MTCMOS_EN_A53_0_EN			(1 << 0)
+
+#define ACPU_SC_A53_CLUSTER_MTCMOS_STA		(ACPU_CTRL_BASE + 0x090)
+#define ACPU_SC_A53_CLUSTER_ISO_EN		(ACPU_CTRL_BASE + 0x098)
+#define PW_ISO_A53_1_EN				(1 << 1)
+#define PW_ISO_A53_0_EN				(1 << 0)
+
+#define ACPU_SC_A53_CLUSTER_ISO_DIS		(ACPU_CTRL_BASE + 0x09c)
+#define ACPU_SC_A53_CLUSTER_ISO_STA		(ACPU_CTRL_BASE + 0x0a0)
+#define ACPU_SC_A53_1_MTCMOS_TIMER		(ACPU_CTRL_BASE + 0x0b4)
+#define ACPU_SC_A53_0_MTCMOS_TIMER		(ACPU_CTRL_BASE + 0x0bc)
+#define ACPU_SC_A53_x_MTCMOS_TIMER(x)		((x) ? ACPU_SC_A53_1_MTCMOS_TIMER : ACPU_SC_A53_0_MTCMOS_TIMER)
+
+#define ACPU_SC_SNOOP_PWD			(ACPU_CTRL_BASE + 0xe4)
+#define PD_DETECT_START1			(1 << 16)
+#define PD_DETECT_START0			(1 << 0)
+
+#define ACPU_SC_CPU0_CTRL			(ACPU_CTRL_BASE + 0x100)
+#define CPU_CTRL_AARCH64_MODE			(1 << 7)
+
+#define ACPU_SC_CPU0_STAT			(ACPU_CTRL_BASE + 0x104)
+#define ACPU_SC_CPU0_CLKEN			(ACPU_CTRL_BASE + 0x108)
+#define CPU_CLKEN_HPM				(1 << 1)
+
+#define ACPU_SC_CPU0_CLK_STAT			(ACPU_CTRL_BASE + 0x110)
+
+#define ACPU_SC_CPU0_RSTEN			(ACPU_CTRL_BASE + 0x114)
+#define ACPU_SC_CPU0_RSTDIS			(ACPU_CTRL_BASE + 0x118)
+#define ACPU_SC_CPU0_MTCMOS_EN			(ACPU_CTRL_BASE + 0x120)
+#define CPU_MTCMOS_PW				(1 << 0)
+
+#define ACPU_SC_CPU0_PW_ISOEN			(ACPU_CTRL_BASE + 0x130)
+#define CPU_PW_ISO				(1 << 0)
+
+#define ACPU_SC_CPU0_PW_ISODIS			(ACPU_CTRL_BASE + 0x134)
+#define ACPU_SC_CPU0_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x138)
+#define ACPU_SC_CPU0_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x154)
+#define CPU_MTCMOS_TIMER_STA			(1 << 0)
+
+#define ACPU_SC_CPU0_RVBARADDR			(ACPU_CTRL_BASE + 0x158)
+#define ACPU_SC_CPU1_CTRL			(ACPU_CTRL_BASE + 0x200)
+#define ACPU_SC_CPU1_STAT			(ACPU_CTRL_BASE + 0x204)
+#define ACPU_SC_CPU1_CLKEN			(ACPU_CTRL_BASE + 0x208)
+#define ACPU_SC_CPU1_CLK_STAT			(ACPU_CTRL_BASE + 0x210)
+#define ACPU_SC_CPU1_RSTEN			(ACPU_CTRL_BASE + 0x214)
+#define ACPU_SC_CPU1_RSTDIS			(ACPU_CTRL_BASE + 0x218)
+#define ACPU_SC_CPU1_MTCMOS_EN			(ACPU_CTRL_BASE + 0x220)
+#define ACPU_SC_CPU1_PW_ISODIS			(ACPU_CTRL_BASE + 0x234)
+#define ACPU_SC_CPU1_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x238)
+#define ACPU_SC_CPU1_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x254)
+#define ACPU_SC_CPU1_RVBARADDR			(ACPU_CTRL_BASE + 0x258)
+#define ACPU_SC_CPU2_CTRL			(ACPU_CTRL_BASE + 0x300)
+#define ACPU_SC_CPU2_STAT			(ACPU_CTRL_BASE + 0x304)
+#define ACPU_SC_CPU2_CLKEN			(ACPU_CTRL_BASE + 0x308)
+#define ACPU_SC_CPU2_CLK_STAT			(ACPU_CTRL_BASE + 0x310)
+#define ACPU_SC_CPU2_RSTEN			(ACPU_CTRL_BASE + 0x314)
+#define ACPU_SC_CPU2_RSTDIS			(ACPU_CTRL_BASE + 0x318)
+#define ACPU_SC_CPU2_MTCMOS_EN			(ACPU_CTRL_BASE + 0x320)
+#define ACPU_SC_CPU2_PW_ISODIS			(ACPU_CTRL_BASE + 0x334)
+#define ACPU_SC_CPU2_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x338)
+#define ACPU_SC_CPU2_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x354)
+#define ACPU_SC_CPU2_RVBARADDR			(ACPU_CTRL_BASE + 0x358)
+#define ACPU_SC_CPU3_CTRL			(ACPU_CTRL_BASE + 0x400)
+#define ACPU_SC_CPU3_STAT			(ACPU_CTRL_BASE + 0x404)
+#define ACPU_SC_CPU3_CLKEN			(ACPU_CTRL_BASE + 0x408)
+#define ACPU_SC_CPU3_CLK_STAT			(ACPU_CTRL_BASE + 0x410)
+#define ACPU_SC_CPU3_RSTEN			(ACPU_CTRL_BASE + 0x414)
+#define ACPU_SC_CPU3_RSTDIS			(ACPU_CTRL_BASE + 0x418)
+#define ACPU_SC_CPU3_MTCMOS_EN			(ACPU_CTRL_BASE + 0x420)
+#define ACPU_SC_CPU3_PW_ISODIS			(ACPU_CTRL_BASE + 0x434)
+#define ACPU_SC_CPU3_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x438)
+#define ACPU_SC_CPU3_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x454)
+#define ACPU_SC_CPU3_RVBARADDR			(ACPU_CTRL_BASE + 0x458)
+#define ACPU_SC_CPU4_CTRL			(ACPU_CTRL_BASE + 0x500)
+#define ACPU_SC_CPU4_STAT			(ACPU_CTRL_BASE + 0x504)
+#define ACPU_SC_CPU4_CLKEN			(ACPU_CTRL_BASE + 0x508)
+#define ACPU_SC_CPU4_CLK_STAT			(ACPU_CTRL_BASE + 0x510)
+#define ACPU_SC_CPU4_RSTEN			(ACPU_CTRL_BASE + 0x514)
+#define ACPU_SC_CPU4_RSTDIS			(ACPU_CTRL_BASE + 0x518)
+#define ACPU_SC_CPU4_MTCMOS_EN			(ACPU_CTRL_BASE + 0x520)
+#define ACPU_SC_CPU4_PW_ISODIS			(ACPU_CTRL_BASE + 0x534)
+#define ACPU_SC_CPU4_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x538)
+#define ACPU_SC_CPU4_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x554)
+#define ACPU_SC_CPU4_RVBARADDR			(ACPU_CTRL_BASE + 0x558)
+#define ACPU_SC_CPU5_CTRL			(ACPU_CTRL_BASE + 0x600)
+#define ACPU_SC_CPU5_STAT			(ACPU_CTRL_BASE + 0x604)
+#define ACPU_SC_CPU5_CLKEN			(ACPU_CTRL_BASE + 0x608)
+#define ACPU_SC_CPU5_CLK_STAT			(ACPU_CTRL_BASE + 0x610)
+#define ACPU_SC_CPU5_RSTEN			(ACPU_CTRL_BASE + 0x614)
+#define ACPU_SC_CPU5_RSTDIS			(ACPU_CTRL_BASE + 0x618)
+#define ACPU_SC_CPU5_MTCMOS_EN			(ACPU_CTRL_BASE + 0x620)
+#define ACPU_SC_CPU5_PW_ISODIS			(ACPU_CTRL_BASE + 0x634)
+#define ACPU_SC_CPU5_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x638)
+#define ACPU_SC_CPU5_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x654)
+#define ACPU_SC_CPU5_RVBARADDR			(ACPU_CTRL_BASE + 0x658)
+#define ACPU_SC_CPU6_CTRL			(ACPU_CTRL_BASE + 0x700)
+#define ACPU_SC_CPU6_STAT			(ACPU_CTRL_BASE + 0x704)
+#define ACPU_SC_CPU6_CLKEN			(ACPU_CTRL_BASE + 0x708)
+#define ACPU_SC_CPU6_CLK_STAT			(ACPU_CTRL_BASE + 0x710)
+#define ACPU_SC_CPU6_RSTEN			(ACPU_CTRL_BASE + 0x714)
+#define ACPU_SC_CPU6_RSTDIS			(ACPU_CTRL_BASE + 0x718)
+#define ACPU_SC_CPU6_MTCMOS_EN			(ACPU_CTRL_BASE + 0x720)
+#define ACPU_SC_CPU6_PW_ISODIS			(ACPU_CTRL_BASE + 0x734)
+#define ACPU_SC_CPU6_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x738)
+#define ACPU_SC_CPU6_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x754)
+#define ACPU_SC_CPU6_RVBARADDR			(ACPU_CTRL_BASE + 0x758)
+#define ACPU_SC_CPU7_CTRL			(ACPU_CTRL_BASE + 0x800)
+#define ACPU_SC_CPU7_STAT			(ACPU_CTRL_BASE + 0x804)
+#define ACPU_SC_CPU7_CLKEN			(ACPU_CTRL_BASE + 0x808)
+#define ACPU_SC_CPU7_CLK_STAT			(ACPU_CTRL_BASE + 0x810)
+#define ACPU_SC_CPU7_RSTEN			(ACPU_CTRL_BASE + 0x814)
+#define ACPU_SC_CPU7_RSTDIS			(ACPU_CTRL_BASE + 0x818)
+#define ACPU_SC_CPU7_MTCMOS_EN			(ACPU_CTRL_BASE + 0x820)
+#define ACPU_SC_CPU7_PW_ISODIS			(ACPU_CTRL_BASE + 0x834)
+#define ACPU_SC_CPU7_PW_ISO_STAT		(ACPU_CTRL_BASE + 0x838)
+#define ACPU_SC_CPU7_MTCMOS_TIMER_STAT		(ACPU_CTRL_BASE + 0x854)
+#define ACPU_SC_CPU7_RVBARADDR			(ACPU_CTRL_BASE + 0x858)
+#define ACPU_SC_CPUx_CTRL(x)			((x < 8) ? (ACPU_SC_CPU0_CTRL + 0x100 * x) : ACPU_SC_CPU0_CTRL)
+#define ACPU_SC_CPUx_STAT(x)			((x < 8) ? (ACPU_SC_CPU0_STAT + 0x100 * x) : ACPU_SC_CPU0_STAT)
+#define ACPU_SC_CPUx_CLKEN(x)			((x < 8) ? (ACPU_SC_CPU0_CLKEN + 0x100 * x) : ACPU_SC_CPU0_CLKEN)
+#define ACPU_SC_CPUx_CLK_STAT(x)		((x < 8) ? (ACPU_SC_CPU0_CLK_STAT + 0x100 * x) : ACPU_SC_CPU0_CLK_STAT)
+#define ACPU_SC_CPUx_RSTEN(x)			((x < 8) ? (ACPU_SC_CPU0_RSTEN + 0x100 * x) : ACPU_SC_CPU0_RSTEN)
+#define ACPU_SC_CPUx_RSTDIS(x)			((x < 8) ? (ACPU_SC_CPU0_RSTDIS + 0x100 * x) : ACPU_SC_CPU0_RSTDIS)
+#define ACPU_SC_CPUx_MTCMOS_EN(x)		((x < 8) ? (ACPU_SC_CPU0_MTCMOS_EN + 0x100 * x) : ACPU_SC_CPU0_MTCMOS_EN)
+#define ACPU_SC_CPUx_PW_ISODIS(x)		((x < 8) ? (ACPU_SC_CPU0_PW_ISODIS + 0x100 * x) : ACPU_SC_CPU0_PW_ISODIS)
+#define ACPU_SC_CPUx_PW_ISO_STAT(x)		((x < 8) ? (ACPU_SC_CPU0_PW_ISO_STAT + 0x100 * x) : ACPU_SC_CPU0_PW_ISO_STAT)
+#define ACPU_SC_CPUx_MTCMOS_TIMER_STAT(x)	((x < 8) ? (ACPU_SC_CPU0_MTCMOS_TIMER_STAT + 0x100 * x) : ACPU_SC_CPU0_MTCMOS_TIMER_STAT)
+#define ACPU_SC_CPUx_RVBARADDR(x)		((x < 8) ? (ACPU_SC_CPU0_RVBARADDR + 0x100 * x) : ACPU_SC_CPU0_RVBARADDR)
+
+#define ACPU_SC_CPU_STAT_CLKDIV_VD_MASK		(3 << 20)
+
+#define ACPU_SC_VD_CTRL_TUNE_EN_DIF		(1 << 0)
+#define ACPU_SC_VD_CTRL_TUNE_EN_DIF_SHIFT	(0)
+#define ACPU_SC_VD_CTRL_TUNE			(1 << 1)
+#define ACPU_SC_VD_CTRL_TUNE_SHIFT		(1)
+#define ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF	(1 << 7)
+#define ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF_SHIFT	(7)
+#define ACPU_SC_VD_CTRL_CALIBRATE_EN_INI	(1 << 8)
+#define ACPU_SC_VD_CTRL_CALIBRATE_EN_INI_SHIFT	(8)
+#define ACPU_SC_VD_CTRL_CLK_DIS_CNT_CLR		(1 << 9)
+#define ACPU_SC_VD_CTRL_CLK_DIS_CNT_CLR_SHIFT	(9)
+#define ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN		(1 << 10)
+#define ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN_SHIFT	(10)
+#define ACPU_SC_VD_CTRL_TUNE_EN_INT		(1 << 11)
+#define ACPU_SC_VD_CTRL_TUNE_EN_INT_SHIFT	(11)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE0		(1 << 12)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE0_MASK	(0xf << 12)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE0_SHIFT	(12)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE1		(1 << 16)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE1_MASK	(0xf << 16)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE1_SHIFT	(16)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE2		(1 << 20)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE2_MASK	(0xf << 20)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE2_SHIFT	(20)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE3		(1 << 24)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE3_MASK	(0xf << 24)
+#define ACPU_SC_VD_CTRL_SHIFT_TABLE3_SHIFT	(24)
+#define ACPU_SC_VD_CTRL_FORCE_CLK_EN		(1 << 28)
+#define ACPU_SC_VD_CTRL_FORCE_CLK_EN_SHIFT	(28)
+#define ACPU_SC_VD_CTRL_DIV_EN_DIF		(1 << 29)
+#define ACPU_SC_VD_CTRL_DIV_EN_DIF_SHIFT	(29)
+
+#define ACPU_SC_VD_SHIFT_TABLE_TUNE_VAL			\
+	((0x1 << ACPU_SC_VD_CTRL_SHIFT_TABLE0_SHIFT) |	\
+	 (0x3 << ACPU_SC_VD_CTRL_SHIFT_TABLE1_SHIFT) |	\
+	 (0x5 << ACPU_SC_VD_CTRL_SHIFT_TABLE2_SHIFT) |	\
+	 (0x6 << ACPU_SC_VD_CTRL_SHIFT_TABLE3_SHIFT) |	\
+	 (0x7 << ACPU_SC_VD_CTRL_TUNE_SHIFT))
+
+#define ACPU_SC_VD_SHIFT_TABLE_TUNE_MASK		\
+	((0xF << ACPU_SC_VD_CTRL_SHIFT_TABLE0_SHIFT) |	\
+	 (0xF << ACPU_SC_VD_CTRL_SHIFT_TABLE1_SHIFT) |	\
+	 (0xF << ACPU_SC_VD_CTRL_SHIFT_TABLE2_SHIFT) |	\
+	 (0xF << ACPU_SC_VD_CTRL_SHIFT_TABLE3_SHIFT) |	\
+	 (0x3F << ACPU_SC_VD_CTRL_TUNE_SHIFT))
+
+#define ACPU_SC_VD_HPM_CTRL_OSC_DIV		(1 << 0)
+#define ACPU_SC_VD_HPM_CTRL_OSC_DIV_SHIFT	(0)
+#define ACPU_SC_VD_HPM_CTRL_OSC_DIV_MASK	(0x000000FF)
+#define ACPU_SC_VD_HPM_CTRL_DLY_EXP		(1 << 8)
+#define ACPU_SC_VD_HPM_CTRL_DLY_EXP_SHIFT	(8)
+#define ACPU_SC_VD_HPM_CTRL_DLY_EXP_MASK	(0x001FFF00)
+
+#define HPM_OSC_DIV_VAL \
+	(0x56 << ACPU_SC_VD_HPM_CTRL_OSC_DIV_SHIFT)
+#define HPM_OSC_DIV_MASK \
+	(ACPU_SC_VD_HPM_CTRL_OSC_DIV_MASK)
+
+#define HPM_DLY_EXP_VAL \
+	(0xC7A << ACPU_SC_VD_HPM_CTRL_DLY_EXP_SHIFT)
+#define HPM_DLY_EXP_MASK \
+	(ACPU_SC_VD_HPM_CTRL_DLY_EXP_MASK)
+
+#define ACPU_SC_VD_EN_ASIC_VAL					\
+	((0x0 << ACPU_SC_VD_CTRL_FORCE_CLK_EN_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_CALIBRATE_EN_INI_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF_SHIFT) |	\
+	 (0X0 << ACPU_SC_VD_CTRL_DIV_EN_DIF_SHIFT) |		\
+	 (0X0 << ACPU_SC_VD_CTRL_TUNE_EN_INT_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_TUNE_EN_DIF_SHIFT))
+
+#define ACPU_SC_VD_EN_SFT_VAL					\
+	((0x0 << ACPU_SC_VD_CTRL_FORCE_CLK_EN_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_CALIBRATE_EN_INI_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF_SHIFT) |	\
+	 (0x0 << ACPU_SC_VD_CTRL_DIV_EN_DIF_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_TUNE_EN_INT_SHIFT) |		\
+	 (0x0 << ACPU_SC_VD_CTRL_TUNE_EN_DIF_SHIFT))
+
+#define ACPU_SC_VD_EN_MASK					\
+	((0x1 << ACPU_SC_VD_CTRL_FORCE_CLK_EN_SHIFT) |		\
+	 (0x1 << ACPU_SC_VD_CTRL_CLK_DIS_CNT_EN_SHIFT) |	\
+	 (0x1 << ACPU_SC_VD_CTRL_CALIBRATE_EN_INI_SHIFT) |	\
+	 (0x1 << ACPU_SC_VD_CTRL_CALIBRATE_EN_DIF_SHIFT) |	\
+	 (0x1 << ACPU_SC_VD_CTRL_DIV_EN_DIF_SHIFT) |		\
+	 (0x1 << ACPU_SC_VD_CTRL_TUNE_EN_INT_SHIFT) |		\
+	 (0x1 << ACPU_SC_VD_CTRL_TUNE_EN_DIF_SHIFT))
+
+#endif /* __HI6220_REGS_ACPU_H__ */
diff --git a/plat/hisilicon/hikey/include/hi6220_regs_ao.h b/plat/hisilicon/hikey/include/hi6220_regs_ao.h
new file mode 100644
index 0000000..79a5404
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hi6220_regs_ao.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HI6220_AO_H__
+#define __HI6220_AO_H__
+
+#define AO_CTRL_BASE				0xF7800000
+
+#define AO_SC_SYS_CTRL0				(AO_CTRL_BASE + 0x000)
+#define AO_SC_SYS_CTRL1				(AO_CTRL_BASE + 0x004)
+#define AO_SC_SYS_CTRL2				(AO_CTRL_BASE + 0x008)
+#define AO_SC_SYS_STAT0				(AO_CTRL_BASE + 0x010)
+#define AO_SC_SYS_STAT1				(AO_CTRL_BASE + 0x014)
+#define AO_SC_MCU_IMCTRL			(AO_CTRL_BASE + 0x018)
+#define AO_SC_MCU_IMSTAT			(AO_CTRL_BASE + 0x01C)
+#define AO_SC_SECONDRY_INT_EN0			(AO_CTRL_BASE + 0x044)
+#define AO_SC_SECONDRY_INT_STATR0		(AO_CTRL_BASE + 0x048)
+#define AO_SC_SECONDRY_INT_STATM0		(AO_CTRL_BASE + 0x04C)
+#define AO_SC_MCU_WKUP_INT_EN6			(AO_CTRL_BASE + 0x054)
+#define AO_SC_MCU_WKUP_INT_STATR6		(AO_CTRL_BASE + 0x058)
+#define AO_SC_MCU_WKUP_INT_STATM6		(AO_CTRL_BASE + 0x05C)
+#define AO_SC_MCU_WKUP_INT_EN5			(AO_CTRL_BASE + 0x064)
+#define AO_SC_MCU_WKUP_INT_STATR5		(AO_CTRL_BASE + 0x068)
+#define AO_SC_MCU_WKUP_INT_STATM5		(AO_CTRL_BASE + 0x06C)
+#define AO_SC_MCU_WKUP_INT_EN4			(AO_CTRL_BASE + 0x094)
+#define AO_SC_MCU_WKUP_INT_STATR4		(AO_CTRL_BASE + 0x098)
+#define AO_SC_MCU_WKUP_INT_STATM4		(AO_CTRL_BASE + 0x09C)
+#define AO_SC_MCU_WKUP_INT_EN0			(AO_CTRL_BASE + 0x0A8)
+#define AO_SC_MCU_WKUP_INT_STATR0		(AO_CTRL_BASE + 0x0AC)
+#define AO_SC_MCU_WKUP_INT_STATM0		(AO_CTRL_BASE + 0x0B0)
+#define AO_SC_MCU_WKUP_INT_EN1			(AO_CTRL_BASE + 0x0B4)
+#define AO_SC_MCU_WKUP_INT_STATR1		(AO_CTRL_BASE + 0x0B8)
+#define AO_SC_MCU_WKUP_INT_STATM1		(AO_CTRL_BASE + 0x0BC)
+#define AO_SC_INT_STATR				(AO_CTRL_BASE + 0x0C4)
+#define AO_SC_INT_STATM				(AO_CTRL_BASE + 0x0C8)
+#define AO_SC_INT_CLEAR				(AO_CTRL_BASE + 0x0CC)
+#define AO_SC_INT_EN_SET			(AO_CTRL_BASE + 0x0D0)
+#define AO_SC_INT_EN_DIS			(AO_CTRL_BASE + 0x0D4)
+#define AO_SC_INT_EN_STAT			(AO_CTRL_BASE + 0x0D8)
+#define AO_SC_INT_STATR1			(AO_CTRL_BASE + 0x0E4)
+#define AO_SC_INT_STATM1			(AO_CTRL_BASE + 0x0E8)
+#define AO_SC_INT_CLEAR1			(AO_CTRL_BASE + 0x0EC)
+#define AO_SC_INT_EN_SET1			(AO_CTRL_BASE + 0x0F0)
+#define AO_SC_INT_EN_DIS1			(AO_CTRL_BASE + 0x0F4)
+#define AO_SC_INT_EN_STAT1			(AO_CTRL_BASE + 0x0F8)
+#define AO_SC_TIMER_EN0				(AO_CTRL_BASE + 0x1D0)
+#define AO_SC_TIMER_EN1				(AO_CTRL_BASE + 0x1D4)
+#define AO_SC_TIMER_EN4				(AO_CTRL_BASE + 0x1F0)
+#define AO_SC_TIMER_EN5				(AO_CTRL_BASE + 0x1F4)
+#define AO_SC_MCU_SUBSYS_CTRL0			(AO_CTRL_BASE + 0x400)
+#define AO_SC_MCU_SUBSYS_CTRL1			(AO_CTRL_BASE + 0x404)
+#define AO_SC_MCU_SUBSYS_CTRL2			(AO_CTRL_BASE + 0x408)
+#define AO_SC_MCU_SUBSYS_CTRL3			(AO_CTRL_BASE + 0x40C)
+#define AO_SC_MCU_SUBSYS_CTRL4			(AO_CTRL_BASE + 0x410)
+#define AO_SC_MCU_SUBSYS_CTRL5			(AO_CTRL_BASE + 0x414)
+#define AO_SC_MCU_SUBSYS_CTRL6			(AO_CTRL_BASE + 0x418)
+#define AO_SC_MCU_SUBSYS_CTRL7			(AO_CTRL_BASE + 0x41C)
+#define AO_SC_MCU_SUBSYS_STAT0			(AO_CTRL_BASE + 0x440)
+#define AO_SC_MCU_SUBSYS_STAT1			(AO_CTRL_BASE + 0x444)
+#define AO_SC_MCU_SUBSYS_STAT2			(AO_CTRL_BASE + 0x448)
+#define AO_SC_MCU_SUBSYS_STAT3			(AO_CTRL_BASE + 0x44C)
+#define AO_SC_MCU_SUBSYS_STAT4			(AO_CTRL_BASE + 0x450)
+#define AO_SC_MCU_SUBSYS_STAT5			(AO_CTRL_BASE + 0x454)
+#define AO_SC_MCU_SUBSYS_STAT6			(AO_CTRL_BASE + 0x458)
+#define AO_SC_MCU_SUBSYS_STAT7			(AO_CTRL_BASE + 0x45C)
+#define AO_SC_PERIPH_CLKEN4			(AO_CTRL_BASE + 0x630)
+#define AO_SC_PERIPH_CLKDIS4			(AO_CTRL_BASE + 0x634)
+#define AO_SC_PERIPH_CLKSTAT4			(AO_CTRL_BASE + 0x638)
+#define AO_SC_PERIPH_CLKEN5			(AO_CTRL_BASE + 0x63C)
+#define AO_SC_PERIPH_CLKDIS5			(AO_CTRL_BASE + 0x640)
+#define AO_SC_PERIPH_CLKSTAT5			(AO_CTRL_BASE + 0x644)
+#define AO_SC_PERIPH_RSTEN4			(AO_CTRL_BASE + 0x6F0)
+#define AO_SC_PERIPH_RSTDIS4			(AO_CTRL_BASE + 0x6F4)
+#define AO_SC_PERIPH_RSTSTAT4			(AO_CTRL_BASE + 0x6F8)
+#define AO_SC_PERIPH_RSTEN5			(AO_CTRL_BASE + 0x6FC)
+#define AO_SC_PERIPH_RSTDIS5			(AO_CTRL_BASE + 0x700)
+#define AO_SC_PERIPH_RSTSTAT5			(AO_CTRL_BASE + 0x704)
+#define AO_SC_PW_CLKEN0				(AO_CTRL_BASE + 0x800)
+#define AO_SC_PW_CLKDIS0			(AO_CTRL_BASE + 0x804)
+#define AO_SC_PW_CLK_STAT0			(AO_CTRL_BASE + 0x808)
+#define AO_SC_PW_RSTEN0				(AO_CTRL_BASE + 0x810)
+#define AO_SC_PW_RSTDIS0			(AO_CTRL_BASE + 0x814)
+#define AO_SC_PW_RST_STAT0			(AO_CTRL_BASE + 0x818)
+#define AO_SC_PW_ISOEN0				(AO_CTRL_BASE + 0x820)
+#define AO_SC_PW_ISODIS0			(AO_CTRL_BASE + 0x824)
+#define AO_SC_PW_ISO_STAT0			(AO_CTRL_BASE + 0x828)
+#define AO_SC_PW_MTCMOS_EN0			(AO_CTRL_BASE + 0x830)
+#define AO_SC_PW_MTCMOS_DIS0			(AO_CTRL_BASE + 0x834)
+#define AO_SC_PW_MTCMOS_STAT0			(AO_CTRL_BASE + 0x838)
+#define AO_SC_PW_MTCMOS_ACK_STAT0		(AO_CTRL_BASE + 0x83C)
+#define AO_SC_PW_MTCMOS_TIMEOUT_STAT0		(AO_CTRL_BASE + 0x840)
+#define AO_SC_PW_STAT0				(AO_CTRL_BASE + 0x850)
+#define AO_SC_PW_STAT1				(AO_CTRL_BASE + 0x854)
+#define AO_SC_SYSTEST_STAT			(AO_CTRL_BASE + 0x880)
+#define AO_SC_SYSTEST_SLICER_CNT0		(AO_CTRL_BASE + 0x890)
+#define AO_SC_SYSTEST_SLICER_CNT1		(AO_CTRL_BASE + 0x894)
+#define AO_SC_PW_CTRL1				(AO_CTRL_BASE + 0x8C8)
+#define AO_SC_PW_CTRL				(AO_CTRL_BASE + 0x8CC)
+#define AO_SC_MCPU_VOTEEN			(AO_CTRL_BASE + 0x8D0)
+#define AO_SC_MCPU_VOTEDIS			(AO_CTRL_BASE + 0x8D4)
+#define AO_SC_MCPU_VOTESTAT			(AO_CTRL_BASE + 0x8D8)
+#define AO_SC_MCPU_VOTE_MSK0			(AO_CTRL_BASE + 0x8E0)
+#define AO_SC_MCPU_VOTE_MSK1			(AO_CTRL_BASE + 0x8E4)
+#define AO_SC_MCPU_VOTESTAT0_MSK		(AO_CTRL_BASE + 0x8E8)
+#define AO_SC_MCPU_VOTESTAT1_MSK		(AO_CTRL_BASE + 0x8EC)
+#define AO_SC_PERI_VOTEEN			(AO_CTRL_BASE + 0x8F0)
+#define AO_SC_PERI_VOTEDIS			(AO_CTRL_BASE + 0x8F4)
+#define AO_SC_PERI_VOTESTAT			(AO_CTRL_BASE + 0x8F8)
+#define AO_SC_PERI_VOTE_MSK0			(AO_CTRL_BASE + 0x900)
+#define AO_SC_PERI_VOTE_MSK1			(AO_CTRL_BASE + 0x904)
+#define AO_SC_PERI_VOTESTAT0_MSK		(AO_CTRL_BASE + 0x908)
+#define AO_SC_PERI_VOTESTAT1_MSK		(AO_CTRL_BASE + 0x90C)
+#define AO_SC_ACPU_VOTEEN			(AO_CTRL_BASE + 0x910)
+#define AO_SC_ACPU_VOTEDIS			(AO_CTRL_BASE + 0x914)
+#define AO_SC_ACPU_VOTESTAT			(AO_CTRL_BASE + 0x918)
+#define AO_SC_ACPU_VOTE_MSK0			(AO_CTRL_BASE + 0x920)
+#define AO_SC_ACPU_VOTE_MSK1			(AO_CTRL_BASE + 0x924)
+#define AO_SC_ACPU_VOTESTAT0_MSK		(AO_CTRL_BASE + 0x928)
+#define AO_SC_ACPU_VOTESTAT1_MSK		(AO_CTRL_BASE + 0x92C)
+#define AO_SC_MCU_VOTEEN			(AO_CTRL_BASE + 0x930)
+#define AO_SC_MCU_VOTEDIS			(AO_CTRL_BASE + 0x934)
+#define AO_SC_MCU_VOTESTAT			(AO_CTRL_BASE + 0x938)
+#define AO_SC_MCU_VOTE_MSK0			(AO_CTRL_BASE + 0x940)
+#define AO_SC_MCU_VOTE_MSK1			(AO_CTRL_BASE + 0x944)
+#define AO_SC_MCU_VOTESTAT0_MSK			(AO_CTRL_BASE + 0x948)
+#define AO_SC_MCU_VOTESTAT1_MSK			(AO_CTRL_BASE + 0x94C)
+#define AO_SC_MCU_VOTE1EN			(AO_CTRL_BASE + 0x960)
+#define AO_SC_MCU_VOTE1DIS			(AO_CTRL_BASE + 0x964)
+#define AO_SC_MCU_VOTE1STAT			(AO_CTRL_BASE + 0x968)
+#define AO_SC_MCU_VOTE1_MSK0			(AO_CTRL_BASE + 0x970)
+#define AO_SC_MCU_VOTE1_MSK1			(AO_CTRL_BASE + 0x974)
+#define AO_SC_MCU_VOTE1STAT0_MSK		(AO_CTRL_BASE + 0x978)
+#define AO_SC_MCU_VOTE1STAT1_MSK		(AO_CTRL_BASE + 0x97C)
+#define AO_SC_MCU_VOTE2EN			(AO_CTRL_BASE + 0x980)
+#define AO_SC_MCU_VOTE2DIS			(AO_CTRL_BASE + 0x984)
+#define AO_SC_MCU_VOTE2STAT			(AO_CTRL_BASE + 0x988)
+#define AO_SC_MCU_VOTE2_MSK0			(AO_CTRL_BASE + 0x990)
+#define AO_SC_MCU_VOTE2_MSK1			(AO_CTRL_BASE + 0x994)
+#define AO_SC_MCU_VOTE2STAT0_MSK		(AO_CTRL_BASE + 0x998)
+#define AO_SC_MCU_VOTE2STAT1_MSK		(AO_CTRL_BASE + 0x99C)
+#define AO_SC_VOTE_CTRL				(AO_CTRL_BASE + 0x9A0)
+#define AO_SC_VOTE_STAT				(AO_CTRL_BASE + 0x9A4)
+#define AO_SC_ECONUM				(AO_CTRL_BASE + 0xF00)
+#define AO_SCCHIPID				(AO_CTRL_BASE + 0xF10)
+#define AO_SCSOCID				(AO_CTRL_BASE + 0xF1C)
+#define AO_SC_SOC_FPGA_RTL_DEF			(AO_CTRL_BASE + 0xFE0)
+#define AO_SC_SOC_FPGA_PR_DEF			(AO_CTRL_BASE + 0xFE4)
+#define AO_SC_SOC_FPGA_RES_DEF0			(AO_CTRL_BASE + 0xFE8)
+#define AO_SC_SOC_FPGA_RES_DEF1			(AO_CTRL_BASE + 0xFEC)
+#define AO_SC_XTAL_CTRL0			(AO_CTRL_BASE + 0x102)
+#define AO_SC_XTAL_CTRL1			(AO_CTRL_BASE + 0x102)
+#define AO_SC_XTAL_CTRL3			(AO_CTRL_BASE + 0x103)
+#define AO_SC_XTAL_CTRL5			(AO_CTRL_BASE + 0x103)
+#define AO_SC_XTAL_STAT0			(AO_CTRL_BASE + 0x106)
+#define AO_SC_XTAL_STAT1			(AO_CTRL_BASE + 0x107)
+#define AO_SC_EFUSE_CHIPID0			(AO_CTRL_BASE + 0x108)
+#define AO_SC_EFUSE_CHIPID1			(AO_CTRL_BASE + 0x108)
+#define AO_SC_EFUSE_SYS_CTRL			(AO_CTRL_BASE + 0x108)
+#define AO_SC_DEBUG_CTRL1			(AO_CTRL_BASE + 0x128)
+#define AO_SC_DBG_STAT				(AO_CTRL_BASE + 0x12B)
+#define AO_SC_ARM_DBG_KEY0			(AO_CTRL_BASE + 0x12B)
+#define AO_SC_RESERVED31			(AO_CTRL_BASE + 0x13A)
+#define AO_SC_RESERVED32			(AO_CTRL_BASE + 0x13A)
+#define AO_SC_RESERVED33			(AO_CTRL_BASE + 0x13A)
+#define AO_SC_RESERVED34			(AO_CTRL_BASE + 0x13A)
+#define AO_SC_RESERVED35			(AO_CTRL_BASE + 0x13B)
+#define AO_SC_RESERVED36			(AO_CTRL_BASE + 0x13B)
+#define AO_SC_RESERVED37			(AO_CTRL_BASE + 0x13B)
+#define AO_SC_RESERVED38			(AO_CTRL_BASE + 0x13B)
+#define AO_SC_ALWAYSON_SYS_CTRL0		(AO_CTRL_BASE + 0x148)
+#define AO_SC_ALWAYSON_SYS_CTRL1		(AO_CTRL_BASE + 0x148)
+#define AO_SC_ALWAYSON_SYS_CTRL2		(AO_CTRL_BASE + 0x148)
+#define AO_SC_ALWAYSON_SYS_CTRL3		(AO_CTRL_BASE + 0x148)
+#define AO_SC_ALWAYSON_SYS_CTRL10		(AO_CTRL_BASE + 0x14A)
+#define AO_SC_ALWAYSON_SYS_CTRL11		(AO_CTRL_BASE + 0x14A)
+#define AO_SC_ALWAYSON_SYS_STAT0		(AO_CTRL_BASE + 0x14C)
+#define AO_SC_ALWAYSON_SYS_STAT1		(AO_CTRL_BASE + 0x14C)
+#define AO_SC_ALWAYSON_SYS_STAT2		(AO_CTRL_BASE + 0x14C)
+#define AO_SC_ALWAYSON_SYS_STAT3		(AO_CTRL_BASE + 0x14C)
+#define AO_SC_PWUP_TIME0			(AO_CTRL_BASE + 0x188)
+#define AO_SC_PWUP_TIME1			(AO_CTRL_BASE + 0x188)
+#define AO_SC_PWUP_TIME2			(AO_CTRL_BASE + 0x188)
+#define AO_SC_PWUP_TIME3			(AO_CTRL_BASE + 0x188)
+#define AO_SC_PWUP_TIME4			(AO_CTRL_BASE + 0x189)
+#define AO_SC_PWUP_TIME5			(AO_CTRL_BASE + 0x189)
+#define AO_SC_PWUP_TIME6			(AO_CTRL_BASE + 0x189)
+#define AO_SC_PWUP_TIME7			(AO_CTRL_BASE + 0x189)
+#define AO_SC_SECURITY_CTRL1			(AO_CTRL_BASE + 0x1C0)
+#define AO_SC_SYSTEST_SLICER_CNT0		(AO_CTRL_BASE + 0x890)
+#define AO_SC_SYSTEST_SLICER_CNT1		(AO_CTRL_BASE + 0x894)
+
+#define AO_SC_SYS_CTRL0_MODE_NORMAL				0x004
+#define AO_SC_SYS_CTRL0_MODE_MASK				0x007
+
+#define AO_SC_SYS_CTRL1_AARM_WD_RST_CFG				(1 << 0)
+#define AO_SC_SYS_CTRL1_REMAP_SRAM_AARM				(1 << 1)
+#define AO_SC_SYS_CTRL1_EFUSEC_REMAP				(1 << 2)
+#define AO_SC_SYS_CTRL1_EXT_PLL_SEL				(1 << 3)
+#define AO_SC_SYS_CTRL1_MCU_WDG0_RSTMCU_CFG			(1 << 4)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_DE_BOUNCE_CFG			(1 << 6)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_OE_CFG			(1 << 7)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_DE_BOUNCE_CFG			(1 << 8)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_OE_CFG			(1 << 9)
+#define AO_SC_SYS_CTRL1_BUS_DFS_FORE_HD_CFG			(1 << 10)
+#define AO_SC_SYS_CTRL1_BUS_DFS_FORE_HD_CFG1			(1 << 11)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_OE_SFT			(1 << 12)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_OE_SFT			(1 << 13)
+#define AO_SC_SYS_CTRL1_MCU_CLKEN_HARDCFG			(1 << 15)
+#define AO_SC_SYS_CTRL1_AARM_WD_RST_CFG_MSK			(1 << 16)
+#define AO_SC_SYS_CTRL1_REMAP_SRAM_AARM_MSK			(1 << 17)
+#define AO_SC_SYS_CTRL1_EFUSEC_REMAP_MSK			(1 << 18)
+#define AO_SC_SYS_CTRL1_EXT_PLL_SEL_MSK				(1 << 19)
+#define AO_SC_SYS_CTRL1_MCU_WDG0_RSTMCU_CFG_MSK			(1 << 20)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_DE_BOUNCE_CFG_MSK		(1 << 22)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_OE_CFG_MSK			(1 << 23)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_DE_BOUNCE_CFG_MSK		(1 << 24)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_OE_CFG_MSK			(1 << 25)
+#define AO_SC_SYS_CTRL1_BUS_DFS_FORE_HD_CFG_MSK			(1 << 26)
+#define AO_SC_SYS_CTRL1_BUS_DFS_FORE_HD_CFG1_MSK		(1 << 27)
+#define AO_SC_SYS_CTRL1_USIM0_HPD_OE_SFT_MSK			(1 << 28)
+#define AO_SC_SYS_CTRL1_USIM1_HPD_OE_SFT_MSK			(1 << 29)
+#define AO_SC_SYS_CTRL1_MCU_CLKEN_HARDCFG_MSK			(1 << 31)
+
+#define AO_SC_SYS_CTRL2_MCU_SFT_RST_STAT_CLEAR			(1 << 26)
+#define AO_SC_SYS_CTRL2_MCU_WDG0_RST_STAT_CLEAR			(1 << 27)
+#define AO_SC_SYS_CTRL2_TSENSOR_RST_STAT_CLEAR			(1 << 28)
+#define AO_SC_SYS_CTRL2_ACPU_WDG_RST_STAT_CLEAR			(1 << 29)
+#define AO_SC_SYS_CTRL2_MCU_WDG1_RST_STAT_CLEAR			(1 << 30)
+#define AO_SC_SYS_CTRL2_GLB_SRST_STAT_CLEAR			(1 << 31)
+
+#define AO_SC_SYS_STAT0_MCU_RST_STAT				(1 << 25)
+#define AO_SC_SYS_STAT0_MCU_SOFTRST_STAT			(1 << 26)
+#define AO_SC_SYS_STAT0_MCU_WDGRST_STAT				(1 << 27)
+#define AO_SC_SYS_STAT0_TSENSOR_HARDRST_STAT			(1 << 28)
+#define AO_SC_SYS_STAT0_ACPU_WD_GLB_RST_STAT			(1 << 29)
+#define AO_SC_SYS_STAT0_CM3_WDG1_RST_STAT			(1 << 30)
+#define AO_SC_SYS_STAT0_GLB_SRST_STAT				(1 << 31)
+
+#define AO_SC_SYS_STAT1_MODE_STATUS				(1 << 0)
+#define AO_SC_SYS_STAT1_BOOT_SEL_LOCK				(1 << 16)
+#define AO_SC_SYS_STAT1_FUNC_MODE_LOCK				(1 << 17)
+#define AO_SC_SYS_STAT1_BOOT_MODE_LOCK				(1 << 19)
+#define AO_SC_SYS_STAT1_FUN_JTAG_MODE_OUT			(1 << 20)
+#define AO_SC_SYS_STAT1_SECURITY_BOOT_FLG			(1 << 27)
+#define AO_SC_SYS_STAT1_EFUSE_NANDBOOT_MSK			(1 << 28)
+#define AO_SC_SYS_STAT1_EFUSE_NAND_BITWIDE			(1 << 29)
+
+#define AO_SC_PERIPH_RSTDIS4_RESET_MCU_ECTR_N			(1 << 0)
+#define AO_SC_PERIPH_RSTDIS4_RESET_MCU_SYS_N			(1 << 1)
+#define AO_SC_PERIPH_RSTDIS4_RESET_MCU_POR_N			(1 << 2)
+#define AO_SC_PERIPH_RSTDIS4_RESET_MCU_DAP_N			(1 << 3)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_CM3_TIMER0_N		(1 << 4)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_CM3_TIMER1_N		(1 << 5)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_CM3_WDT0_N			(1 << 6)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_CM3_WDT1_N			(1 << 7)
+#define AO_SC_PERIPH_RSTDIS4_HRESET_IPC_S_N			(1 << 8)
+#define AO_SC_PERIPH_RSTDIS4_HRESET_IPC_NS_N			(1 << 9)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_EFUSEC_N			(1 << 10)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_WDT0_N			(1 << 12)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_WDT1_N			(1 << 13)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_WDT2_N			(1 << 14)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER0_N			(1 << 15)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER1_N			(1 << 16)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER2_N			(1 << 17)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER3_N			(1 << 18)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER4_N			(1 << 19)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER5_N			(1 << 20)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER6_N			(1 << 21)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER7_N			(1 << 22)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_TIMER8_N			(1 << 23)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_UART0_N			(1 << 24)
+#define AO_SC_PERIPH_RSTDIS4_RESET_RTC0_N			(1 << 25)
+#define AO_SC_PERIPH_RSTDIS4_RESET_RTC1_N			(1 << 26)
+#define AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N			(1 << 27)
+#define AO_SC_PERIPH_RSTDIS4_RESET_JTAG_AUTH_N			(1 << 28)
+#define AO_SC_PERIPH_RSTDIS4_RESET_CS_DAPB_ON_N			(1 << 29)
+#define AO_SC_PERIPH_RSTDIS4_MDM_SUBSYS_GLB			(1 << 30)
+
+#define AO_SC_PERIPH_CLKEN4_HCLK_MCU				(1 << 0)
+#define AO_SC_PERIPH_CLKEN4_CLK_MCU_DAP				(1 << 3)
+#define AO_SC_PERIPH_CLKEN4_PCLK_CM3_TIMER0			(1 << 4)
+#define AO_SC_PERIPH_CLKEN4_PCLK_CM3_TIMER1			(1 << 5)
+#define AO_SC_PERIPH_CLKEN4_PCLK_CM3_WDT0			(1 << 6)
+#define AO_SC_PERIPH_CLKEN4_PCLK_CM3_WDT1			(1 << 7)
+#define AO_SC_PERIPH_CLKEN4_HCLK_IPC_S				(1 << 8)
+#define AO_SC_PERIPH_CLKEN4_HCLK_IPC_NS				(1 << 9)
+#define AO_SC_PERIPH_CLKEN4_PCLK_EFUSEC				(1 << 10)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TZPC				(1 << 11)
+#define AO_SC_PERIPH_CLKEN4_PCLK_WDT0				(1 << 12)
+#define AO_SC_PERIPH_CLKEN4_PCLK_WDT1				(1 << 13)
+#define AO_SC_PERIPH_CLKEN4_PCLK_WDT2				(1 << 14)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER0				(1 << 15)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER1				(1 << 16)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER2				(1 << 17)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER3				(1 << 18)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER4				(1 << 19)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER5				(1 << 20)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER6				(1 << 21)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER7				(1 << 22)
+#define AO_SC_PERIPH_CLKEN4_PCLK_TIMER8				(1 << 23)
+#define AO_SC_PERIPH_CLKEN4_CLK_UART0				(1 << 24)
+#define AO_SC_PERIPH_CLKEN4_CLK_RTC0				(1 << 25)
+#define AO_SC_PERIPH_CLKEN4_CLK_RTC1				(1 << 26)
+#define AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI				(1 << 27)
+#define AO_SC_PERIPH_CLKEN4_CLK_JTAG_AUTH			(1 << 28)
+#define AO_SC_PERIPH_CLKEN4_CLK_CS_DAPB_ON			(1 << 29)
+#define AO_SC_PERIPH_CLKEN4_CLK_PDM				(1 << 30)
+#define AO_SC_PERIPH_CLKEN4_CLK_SSI_PAD				(1 << 31)
+
+#define AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU			(1 << 0)
+#define AO_SC_PERIPH_CLKEN5_PCLK_EFUSEC_CCPU			(1 << 1)
+#define AO_SC_PERIPH_CLKEN5_HCLK_IPC_CCPU			(1 << 2)
+#define AO_SC_PERIPH_CLKEN5_HCLK_IPC_NS_CCPU			(1 << 3)
+#define AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU			(1 << 16)
+#define AO_SC_PERIPH_CLKEN5_PCLK_EFUSEC_MCU			(1 << 17)
+#define AO_SC_PERIPH_CLKEN5_HCLK_IPC_MCU			(1 << 18)
+#define AO_SC_PERIPH_CLKEN5_HCLK_IPC_NS_MCU			(1 << 19)
+
+#define AO_SC_MCU_SUBSYS_CTRL3_RCLK_3				0x003
+#define AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK			0x007
+#define AO_SC_MCU_SUBSYS_CTRL3_CSSYS_CTRL_PROT			(1 << 3)
+#define AO_SC_MCU_SUBSYS_CTRL3_TCXO_AFC_OEN_CRG			(1 << 4)
+#define AO_SC_MCU_SUBSYS_CTRL3_AOB_IO_SEL18_USIM1		(1 << 8)
+#define AO_SC_MCU_SUBSYS_CTRL3_AOB_IO_SEL18_USIM0		(1 << 9)
+#define AO_SC_MCU_SUBSYS_CTRL3_AOB_IO_SEL18_SD			(1 << 10)
+#define AO_SC_MCU_SUBSYS_CTRL3_MCU_SUBSYS_CTRL3_RESERVED	(1 << 11)
+
+#define PCLK_TIMER1						(1 << 16)
+#define PCLK_TIMER0						(1 << 15)
+
+#endif /* __HI6220_AO_H__ */
diff --git a/plat/hisilicon/hikey/include/hi6220_regs_peri.h b/plat/hisilicon/hikey/include/hi6220_regs_peri.h
new file mode 100644
index 0000000..d2c0460
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hi6220_regs_peri.h
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HI6220_PERI_H__
+#define __HI6220_PERI_H__
+
+#define PERI_BASE				0xF7030000
+
+#define PERI_SC_PERIPH_CTRL1			(PERI_BASE + 0x000)
+#define PERI_SC_PERIPH_CTRL2			(PERI_BASE + 0x004)
+#define PERI_SC_PERIPH_CTRL3			(PERI_BASE + 0x008)
+#define PERI_SC_PERIPH_CTRL4			(PERI_BASE + 0x00c)
+#define PERI_SC_PERIPH_CTRL5			(PERI_BASE + 0x010)
+#define PERI_SC_PERIPH_CTRL6			(PERI_BASE + 0x014)
+#define PERI_SC_PERIPH_CTRL8			(PERI_BASE + 0x018)
+#define PERI_SC_PERIPH_CTRL9			(PERI_BASE + 0x01c)
+#define PERI_SC_PERIPH_CTRL10			(PERI_BASE + 0x020)
+#define PERI_SC_PERIPH_CTRL12			(PERI_BASE + 0x024)
+#define PERI_SC_PERIPH_CTRL13			(PERI_BASE + 0x028)
+#define PERI_SC_PERIPH_CTRL14			(PERI_BASE + 0x02c)
+
+#define PERI_SC_DDR_CTRL0			(PERI_BASE + 0x050)
+#define PERI_SC_PERIPH_STAT1			(PERI_BASE + 0x094)
+
+#define PERI_SC_PERIPH_CLKEN0			(PERI_BASE + 0x200)
+#define PERI_SC_PERIPH_CLKDIS0			(PERI_BASE + 0x204)
+#define PERI_SC_PERIPH_CLKSTAT0			(PERI_BASE + 0x208)
+#define PERI_SC_PERIPH_CLKEN1			(PERI_BASE + 0x210)
+#define PERI_SC_PERIPH_CLKDIS1			(PERI_BASE + 0x214)
+#define PERI_SC_PERIPH_CLKSTAT1			(PERI_BASE + 0x218)
+#define PERI_SC_PERIPH_CLKEN2			(PERI_BASE + 0x220)
+#define PERI_SC_PERIPH_CLKDIS2			(PERI_BASE + 0x224)
+#define PERI_SC_PERIPH_CLKSTAT2			(PERI_BASE + 0x228)
+#define PERI_SC_PERIPH_CLKEN3			(PERI_BASE + 0x230)
+#define PERI_SC_PERIPH_CLKDIS3			(PERI_BASE + 0x234)
+#define PERI_SC_PERIPH_CLKSTAT3			(PERI_BASE + 0x238)
+#define PERI_SC_PERIPH_CLKEN8			(PERI_BASE + 0x240)
+#define PERI_SC_PERIPH_CLKDIS8			(PERI_BASE + 0x244)
+#define PERI_SC_PERIPH_CLKSTAT8			(PERI_BASE + 0x248)
+#define PERI_SC_PERIPH_CLKEN9			(PERI_BASE + 0x250)
+#define PERI_SC_PERIPH_CLKDIS9			(PERI_BASE + 0x254)
+#define PERI_SC_PERIPH_CLKSTAT9			(PERI_BASE + 0x258)
+#define PERI_SC_PERIPH_CLKEN10			(PERI_BASE + 0x260)
+#define PERI_SC_PERIPH_CLKDIS10			(PERI_BASE + 0x264)
+#define PERI_SC_PERIPH_CLKSTAT10		(PERI_BASE + 0x268)
+#define PERI_SC_PERIPH_CLKEN12			(PERI_BASE + 0x270)
+#define PERI_SC_PERIPH_CLKDIS12			(PERI_BASE + 0x274)
+#define PERI_SC_PERIPH_CLKSTAT12		(PERI_BASE + 0x278)
+
+#define PERI_SC_PERIPH_RSTEN0			(PERI_BASE + 0x300)
+#define PERI_SC_PERIPH_RSTDIS0			(PERI_BASE + 0x304)
+#define PERI_SC_PERIPH_RSTSTAT0			(PERI_BASE + 0x308)
+#define PERI_SC_PERIPH_RSTEN1			(PERI_BASE + 0x310)
+#define PERI_SC_PERIPH_RSTDIS1			(PERI_BASE + 0x314)
+#define PERI_SC_PERIPH_RSTSTAT1			(PERI_BASE + 0x318)
+#define PERI_SC_PERIPH_RSTEN2			(PERI_BASE + 0x320)
+#define PERI_SC_PERIPH_RSTDIS2			(PERI_BASE + 0x324)
+#define PERI_SC_PERIPH_RSTSTAT2			(PERI_BASE + 0x328)
+#define PERI_SC_PERIPH_RSTEN3			(PERI_BASE + 0x330)
+#define PERI_SC_PERIPH_RSTDIS3			(PERI_BASE + 0x334)
+#define PERI_SC_PERIPH_RSTSTAT3			(PERI_BASE + 0x338)
+#define PERI_SC_PERIPH_RSTEN8			(PERI_BASE + 0x340)
+#define PERI_SC_PERIPH_RSTDIS8			(PERI_BASE + 0x344)
+#define PERI_SC_PERIPH_RSTSTAT8			(PERI_BASE + 0x338)
+
+#define PERI_SC_CLK_SEL0			(PERI_BASE + 0x400)
+#define PERI_SC_CLKCFG8BIT1			(PERI_BASE + 0x494)
+#define PERI_SC_CLKCFG8BIT2			(PERI_BASE + 0x498)
+#define PERI_SC_RESERVED8_ADDR			(PERI_BASE + 0xd04)
+
+/* PERI_SC_PERIPH_CTRL1 */
+#define PERI_CTRL1_ETR_AXI_CSYSREQ_N		(1 << 0)
+#define PERI_CTRL1_ETR_AXI_CSYSREQ_N		(1 << 0)
+#define PERI_CTRL1_HIFI_INT_MASK		(1 << 1)
+#define PERI_CTRL1_HIFI_ALL_INT_MASK		(1 << 2)
+#define PERI_CTRL1_ETR_AXI_CSYSREQ_N_MSK	(1 << 16)
+#define PERI_CTRL1_HIFI_INT_MASK_MSK		(1 << 17)
+#define PERI_CTRL1_HIFI_ALL_INT_MASK_MSK	(1 << 18)
+
+/* PERI_SC_PERIPH_CTRL2	*/
+#define PERI_CTRL2_MMC_CLK_PHASE_BYPASS_EN_MMC0	(1 << 0)
+#define PERI_CTRL2_MMC_CLK_PHASE_BYPASS_EN_MMC1	(1 << 2)
+#define PERI_CTRL2_NAND_SYS_MEM_SEL		(1 << 6)
+#define PERI_CTRL2_G3D_DDRT_AXI_SEL		(1 << 7)
+#define PERI_CTRL2_GU_MDM_BBP_TESTPIN_SEL	(1 << 8)
+#define PERI_CTRL2_CODEC_SSI_MASTER_CHECK	(1 << 9)
+#define PERI_CTRL2_FUNC_TEST_SOFT		(1 << 12)
+#define PERI_CTRL2_CSSYS_TS_ENABLE		(1 << 15)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_EMA		(1 << 16)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_EMAW		(1 << 20)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_EMAS		(1 << 22)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_RET1N		(1 << 26)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_RET2N		(1 << 27)
+#define PERI_CTRL2_HIFI_RAMCTRL_S_PGEN		(1 << 28)
+
+/* PERI_SC_PERIPH_CTRL3 */
+#define PERI_CTRL3_HIFI_DDR_HARQMEM_ADDR	(1 << 0)
+#define PERI_CTRL3_HIFI_HARQMEMRMP_EN		(1 << 12)
+#define PERI_CTRL3_HARQMEM_SYS_MED_SEL		(1 << 13)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP1		(1 << 14)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP2		(1 << 16)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP3		(1 << 18)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP4		(1 << 20)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP5		(1 << 22)
+#define PERI_CTRL3_SOC_AP_OCCUPY_GRP6		(1 << 24)
+
+/* PERI_SC_PERIPH_CTRL4 */
+#define PERI_CTRL4_PICO_FSELV			(1 << 0)
+#define PERI_CTRL4_FPGA_EXT_PHY_SEL		(1 << 3)
+#define PERI_CTRL4_PICO_REFCLKSEL		(1 << 4)
+#define PERI_CTRL4_PICO_SIDDQ			(1 << 6)
+#define PERI_CTRL4_PICO_SUSPENDM_SLEEPM		(1 << 7)
+#define PERI_CTRL4_PICO_OGDISABLE		(1 << 8)
+#define PERI_CTRL4_PICO_COMMONONN		(1 << 9)
+#define PERI_CTRL4_PICO_VBUSVLDEXT		(1 << 10)
+#define PERI_CTRL4_PICO_VBUSVLDEXTSEL		(1 << 11)
+#define PERI_CTRL4_PICO_VATESTENB		(1 << 12)
+#define PERI_CTRL4_PICO_SUSPENDM		(1 << 14)
+#define PERI_CTRL4_PICO_SLEEPM			(1 << 15)
+#define PERI_CTRL4_BC11_C			(1 << 16)
+#define PERI_CTRL4_BC11_B			(1 << 17)
+#define PERI_CTRL4_BC11_A			(1 << 18)
+#define PERI_CTRL4_BC11_GND			(1 << 19)
+#define PERI_CTRL4_BC11_FLOAT			(1 << 20)
+#define PERI_CTRL4_OTG_PHY_SEL			(1 << 21)
+#define PERI_CTRL4_USB_OTG_SS_SCALEDOWN_MODE	(1 << 22)
+#define PERI_CTRL4_OTG_DM_PULLDOWN		(1 << 24)
+#define PERI_CTRL4_OTG_DP_PULLDOWN		(1 << 25)
+#define PERI_CTRL4_OTG_IDPULLUP			(1 << 26)
+#define PERI_CTRL4_OTG_DRVBUS			(1 << 27)
+#define PERI_CTRL4_OTG_SESSEND			(1 << 28)
+#define PERI_CTRL4_OTG_BVALID			(1 << 29)
+#define PERI_CTRL4_OTG_AVALID			(1 << 30)
+#define PERI_CTRL4_OTG_VBUSVALID		(1 << 31)
+
+/* PERI_SC_PERIPH_CTRL5 */
+#define PERI_CTRL5_USBOTG_RES_SEL		(1 << 3)
+#define PERI_CTRL5_PICOPHY_ACAENB		(1 << 4)
+#define PERI_CTRL5_PICOPHY_BC_MODE		(1 << 5)
+#define PERI_CTRL5_PICOPHY_CHRGSEL		(1 << 6)
+#define PERI_CTRL5_PICOPHY_VDATSRCEND		(1 << 7)
+#define PERI_CTRL5_PICOPHY_VDATDETENB		(1 << 8)
+#define PERI_CTRL5_PICOPHY_DCDENB		(1 << 9)
+#define PERI_CTRL5_PICOPHY_IDDIG		(1 << 10)
+#define PERI_CTRL5_DBG_MUX			(1 << 11)
+
+/* PERI_SC_PERIPH_CTRL6 */
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_EMA	(1 << 0)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_EMAW	(1 << 4)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_EMAS	(1 << 6)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_RET1N	(1 << 10)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_RET2N	(1 << 11)
+#define PERI_CTRL6_CSSYSOFF_RAMCTRL_S_PGEN	(1 << 12)
+
+/* PERI_SC_PERIPH_CTRL8 */
+#define PERI_CTRL8_PICOPHY_TXRISETUNE0		(1 << 0)
+#define PERI_CTRL8_PICOPHY_TXPREEMPAMPTUNE0	(1 << 2)
+#define PERI_CTRL8_PICOPHY_TXRESTUNE0		(1 << 4)
+#define PERI_CTRL8_PICOPHY_TXHSSVTUNE0		(1 << 6)
+#define PERI_CTRL8_PICOPHY_COMPDISTUNE0		(1 << 8)
+#define PERI_CTRL8_PICOPHY_TXPREEMPPULSETUNE0	(1 << 11)
+#define PERI_CTRL8_PICOPHY_OTGTUNE0		(1 << 12)
+#define PERI_CTRL8_PICOPHY_SQRXTUNE0		(1 << 16)
+#define PERI_CTRL8_PICOPHY_TXVREFTUNE0		(1 << 20)
+#define PERI_CTRL8_PICOPHY_TXFSLSTUNE0		(1 << 28)
+
+/* PERI_SC_PERIPH_CTRL9	*/
+#define PERI_CTRL9_PICOPLY_TESTCLKEN		(1 << 0)
+#define PERI_CTRL9_PICOPLY_TESTDATAOUTSEL	(1 << 1)
+#define PERI_CTRL9_PICOPLY_TESTADDR		(1 << 4)
+#define PERI_CTRL9_PICOPLY_TESTDATAIN		(1 << 8)
+
+/*
+ * PERI_SC_PERIPH_CLKEN0
+ * PERI_SC_PERIPH_CLKDIS0
+ * PERI_SC_PERIPH_CLKSTAT0
+ */
+#define PERI_CLK0_MMC0				(1 << 0)
+#define PERI_CLK0_MMC1				(1 << 1)
+#define PERI_CLK0_MMC2				(1 << 2)
+#define PERI_CLK0_NANDC				(1 << 3)
+#define PERI_CLK0_USBOTG			(1 << 4)
+#define PERI_CLK0_PICOPHY			(1 << 5)
+#define PERI_CLK0_PLL				(1 << 6)
+
+/*
+ * PERI_SC_PERIPH_CLKEN1
+ * PERI_SC_PERIPH_CLKDIS1
+ * PERI_SC_PERIPH_CLKSTAT1
+ */
+#define PERI_CLK1_HIFI				(1 << 0)
+#define PERI_CLK1_DIGACODEC			(1 << 5)
+
+/*
+ * PERI_SC_PERIPH_CLKEN2
+ * PERI_SC_PERIPH_CLKDIS2
+ * PERI_SC_PERIPH_CLKSTAT2
+ */
+#define PERI_CLK2_IPF				(1 << 0)
+#define PERI_CLK2_SOCP				(1 << 1)
+#define PERI_CLK2_DMAC				(1 << 2)
+#define PERI_CLK2_SECENG			(1 << 3)
+#define PERI_CLK2_HPM0				(1 << 5)
+#define PERI_CLK2_HPM1				(1 << 6)
+#define PERI_CLK2_HPM2				(1 << 7)
+#define PERI_CLK2_HPM3				(1 << 8)
+
+/*
+ * PERI_SC_PERIPH_CLKEN3
+ * PERI_SC_PERIPH_CLKDIS3
+ * PERI_SC_PERIPH_CLKSTAT3
+ */
+#define PERI_CLK3_CSSYS				(1 << 0)
+#define PERI_CLK3_I2C0				(1 << 1)
+#define PERI_CLK3_I2C1				(1 << 2)
+#define PERI_CLK3_I2C2				(1 << 3)
+#define PERI_CLK3_I2C3				(1 << 4)
+#define PERI_CLK3_UART1				(1 << 5)
+#define PERI_CLK3_UART2				(1 << 6)
+#define PERI_CLK3_UART3				(1 << 7)
+#define PERI_CLK3_UART4				(1 << 8)
+#define PERI_CLK3_SSP				(1 << 9)
+#define PERI_CLK3_PWM				(1 << 10)
+#define PERI_CLK3_BLPWM				(1 << 11)
+#define PERI_CLK3_TSENSOR			(1 << 12)
+#define PERI_CLK3_GPS				(1 << 15)
+#define PERI_CLK3_TCXO_PAD0			(1 << 16)
+#define PERI_CLK3_TCXO_PAD1			(1 << 17)
+#define PERI_CLK3_DAPB				(1 << 18)
+#define PERI_CLK3_HKADC				(1 << 19)
+#define PERI_CLK3_CODEC_SSI			(1 << 20)
+#define PERI_CLK3_TZPC_DEP			(1 << 21)
+
+/*
+ * PERI_SC_PERIPH_CLKEN8
+ * PERI_SC_PERIPH_CLKDIS8
+ * PERI_SC_PERIPH_CLKSTAT8
+ */
+#define PERI_CLK8_RS0				(1 << 0)
+#define PERI_CLK8_RS2				(1 << 1)
+#define PERI_CLK8_RS3				(1 << 2)
+#define PERI_CLK8_MS0				(1 << 3)
+#define PERI_CLK8_MS2				(1 << 5)
+#define PERI_CLK8_XG2RAM0			(1 << 6)
+#define PERI_CLK8_X2SRAM			(1 << 7)
+#define PERI_CLK8_SRAM				(1 << 8)
+#define PERI_CLK8_ROM				(1 << 9)
+#define PERI_CLK8_HARQ				(1 << 10)
+#define PERI_CLK8_MMU				(1 << 11)
+#define PERI_CLK8_DDRC				(1 << 12)
+#define PERI_CLK8_DDRPHY			(1 << 13)
+#define PERI_CLK8_DDRPHY_REF			(1 << 14)
+#define PERI_CLK8_X2X_SYSNOC			(1 << 15)
+#define PERI_CLK8_X2X_CCPU			(1 << 16)
+#define PERI_CLK8_DDRT				(1 << 17)
+#define PERI_CLK8_DDRPACK_RS			(1 << 18)
+
+/*
+ * PERI_SC_PERIPH_CLKEN9
+ * PERI_SC_PERIPH_CLKDIS9
+ * PERI_SC_PERIPH_CLKSTAT9
+ */
+#define PERI_CLK9_CARM_DAP			(1 << 0)
+#define PERI_CLK9_CARM_ATB			(1 << 1)
+#define PERI_CLK9_CARM_LBUS			(1 << 2)
+#define PERI_CLK9_CARM_KERNEL			(1 << 3)
+
+/*
+ * PERI_SC_PERIPH_CLKEN10
+ * PERI_SC_PERIPH_CLKDIS10
+ * PERI_SC_PERIPH_CLKSTAT10
+ */
+#define PERI_CLK10_IPF_CCPU			(1 << 0)
+#define PERI_CLK10_SOCP_CCPU			(1 << 1)
+#define PERI_CLK10_SECENG_CCPU			(1 << 2)
+#define PERI_CLK10_HARQ_CCPU			(1 << 3)
+#define PERI_CLK10_IPF_MCU			(1 << 16)
+#define PERI_CLK10_SOCP_MCU			(1 << 17)
+#define PERI_CLK10_SECENG_MCU			(1 << 18)
+#define PERI_CLK10_HARQ_MCU			(1 << 19)
+
+/*
+ * PERI_SC_PERIPH_CLKEN12
+ * PERI_SC_PERIPH_CLKDIS12
+ * PERI_SC_PERIPH_CLKSTAT12
+ */
+#define PERI_CLK12_HIFI_SRC			(1 << 0)
+#define PERI_CLK12_MMC0_SRC			(1 << 1)
+#define PERI_CLK12_MMC1_SRC			(1 << 2)
+#define PERI_CLK12_MMC2_SRC			(1 << 3)
+#define PERI_CLK12_SYSPLL_DIV			(1 << 4)
+#define PERI_CLK12_TPIU_SRC			(1 << 5)
+#define PERI_CLK12_MMC0_HF			(1 << 6)
+#define PERI_CLK12_MMC1_HF			(1 << 7)
+#define PERI_CLK12_PLL_TEST_SRC			(1 << 8)
+#define PERI_CLK12_CODEC_SOC			(1 << 9)
+#define PERI_CLK12_MEDIA			(1 << 10)
+
+/*
+ * PERI_SC_PERIPH_RSTEN0
+ * PERI_SC_PERIPH_RSTDIS0
+ * PERI_SC_PERIPH_RSTSTAT0
+ */
+#define PERI_RST0_MMC0				(1 << 0)
+#define PERI_RST0_MMC1				(1 << 1)
+#define PERI_RST0_MMC2				(1 << 2)
+#define PERI_RST0_NANDC				(1 << 3)
+#define PERI_RST0_USBOTG_BUS			(1 << 4)
+#define PERI_RST0_POR_PICOPHY			(1 << 5)
+#define PERI_RST0_USBOTG			(1 << 6)
+#define PERI_RST0_USBOTG_32K			(1 << 7)
+
+/*
+ * PERI_SC_PERIPH_RSTEN1
+ * PERI_SC_PERIPH_RSTDIS1
+ * PERI_SC_PERIPH_RSTSTAT1
+ */
+#define PERI_RST1_HIFI				(1 << 0)
+#define PERI_RST1_DIGACODEC			(1 << 5)
+
+/*
+ * PERI_SC_PERIPH_RSTEN2
+ * PERI_SC_PERIPH_RSTDIS2
+ * PERI_SC_PERIPH_RSTSTAT2
+ */
+#define PERI_RST2_IPF				(1 << 0)
+#define PERI_RST2_SOCP				(1 << 1)
+#define PERI_RST2_DMAC				(1 << 2)
+#define PERI_RST2_SECENG			(1 << 3)
+#define PERI_RST2_ABB				(1 << 4)
+#define PERI_RST2_HPM0				(1 << 5)
+#define PERI_RST2_HPM1				(1 << 6)
+#define PERI_RST2_HPM2				(1 << 7)
+#define PERI_RST2_HPM3				(1 << 8)
+
+/*
+ * PERI_SC_PERIPH_RSTEN3
+ * PERI_SC_PERIPH_RSTDIS3
+ * PERI_SC_PERIPH_RSTSTAT3
+ */
+#define PERI_RST3_CSSYS				(1 << 0)
+#define PERI_RST3_I2C0				(1 << 1)
+#define PERI_RST3_I2C1				(1 << 2)
+#define PERI_RST3_I2C2				(1 << 3)
+#define PERI_RST3_I2C3				(1 << 4)
+#define PERI_RST3_UART1				(1 << 5)
+#define PERI_RST3_UART2				(1 << 6)
+#define PERI_RST3_UART3				(1 << 7)
+#define PERI_RST3_UART4				(1 << 8)
+#define PERI_RST3_SSP				(1 << 9)
+#define PERI_RST3_PWM				(1 << 10)
+#define PERI_RST3_BLPWM				(1 << 11)
+#define PERI_RST3_TSENSOR			(1 << 12)
+#define PERI_RST3_DAPB				(1 << 18)
+#define PERI_RST3_HKADC				(1 << 19)
+#define PERI_RST3_CODEC				(1 << 20)
+
+/*
+ * PERI_SC_PERIPH_RSTEN8
+ * PERI_SC_PERIPH_RSTDIS8
+ * PERI_SC_PERIPH_RSTSTAT8
+ */
+#define PERI_RST8_RS0				(1 << 0)
+#define PERI_RST8_RS2				(1 << 1)
+#define PERI_RST8_RS3				(1 << 2)
+#define PERI_RST8_MS0				(1 << 3)
+#define PERI_RST8_MS2				(1 << 5)
+#define PERI_RST8_XG2RAM0			(1 << 6)
+#define PERI_RST8_X2SRAM_TZMA			(1 << 7)
+#define PERI_RST8_SRAM				(1 << 8)
+#define PERI_RST8_HARQ				(1 << 10)
+#define PERI_RST8_DDRC				(1 << 12)
+#define PERI_RST8_DDRC_APB			(1 << 13)
+#define PERI_RST8_DDRPACK_APB			(1 << 14)
+#define PERI_RST8_DDRT				(1 << 17)
+
+#endif /* __HI6220_PERI_H__ */
diff --git a/plat/hisilicon/hikey/include/hi6220_regs_pin.h b/plat/hisilicon/hikey/include/hi6220_regs_pin.h
new file mode 100644
index 0000000..7de4c3c
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hi6220_regs_pin.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HI6220_PIN_H__
+#define __HI6220_PIN_H__
+
+#define IOMG_BASE				0xF7010000
+
+#define IOMG_SD_CLK				(IOMG_BASE + 0x0C)
+#define IOMG_SD_CMD				(IOMG_BASE + 0x10)
+#define IOMG_SD_DATA0				(IOMG_BASE + 0x14)
+#define IOMG_SD_DATA1				(IOMG_BASE + 0x18)
+#define IOMG_SD_DATA2				(IOMG_BASE + 0x1C)
+#define IOMG_SD_DATA3				(IOMG_BASE + 0x20)
+#define IOMG_GPIO24				(IOMG_BASE + 0x140)
+
+#define IOMG_MUX_FUNC0				0
+#define IOMG_MUX_FUNC1				1
+#define IOMG_MUX_FUNC2				2
+
+#define IOCG1_BASE				0xF7010800
+#define IOCG2_BASE				0xF8001800
+
+#define IOCG_SD_CLK				(IOCG1_BASE + 0x0C)
+#define IOCG_SD_CMD				(IOCG1_BASE + 0x10)
+#define IOCG_SD_DATA0				(IOCG1_BASE + 0x14)
+#define IOCG_SD_DATA1				(IOCG1_BASE + 0x18)
+#define IOCG_SD_DATA2				(IOCG1_BASE + 0x1C)
+#define IOCG_SD_DATA3				(IOCG1_BASE + 0x20)
+#define IOCG_GPIO24				(IOCG1_BASE + 0x150)
+#define IOCG_GPIO8				(IOCG2_BASE + 0x30)
+
+#define IOCG_DRIVE_8MA				(2 << 4)
+#define IOCG_DRIVE_10MA				(3 << 4)
+#define IOCG_INPUT_16MA				0x64
+#define IOCG_INPUT_12MA				0x54
+#define IOCG_PULLDOWN				(1 << 1)
+#define IOCG_PULLUP				(1 << 0)
+
+#endif	/* __HI6220_PIN_H__ */
diff --git a/plat/hisilicon/hikey/include/hi6220_regs_pmctrl.h b/plat/hisilicon/hikey/include/hi6220_regs_pmctrl.h
new file mode 100644
index 0000000..dc09b20
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hi6220_regs_pmctrl.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HI6220_REGS_PMCTRL_H__
+#define __HI6220_REGS_PMCTRL_H__
+
+#define PMCTRL_BASE				0xF7032000
+
+#define PMCTRL_ACPUPLLCTRL			(PMCTRL_BASE + 0x000)
+#define PMCTRL_ACPUPLLFREQ			(PMCTRL_BASE + 0x004)
+#define PMCTRL_DDRPLL1CTRL			(PMCTRL_BASE + 0x010)
+#define PMCTRL_DDRPLL0CTRL			(PMCTRL_BASE + 0x030)
+#define PMCTRL_MEDPLLCTRL			(PMCTRL_BASE + 0x038)
+#define PMCTRL_ACPUPLLSEL			(PMCTRL_BASE + 0x100)
+#define PMCTRL_ACPUCLKDIV			(PMCTRL_BASE + 0x104)
+#define PMCTRL_ACPUSYSPLLCFG			(PMCTRL_BASE + 0x110)
+#define PMCTRL_ACPUCLKOFFCFG			(PMCTRL_BASE + 0x114)
+#define PMCTRL_ACPUPLLFRAC			(PMCTRL_BASE + 0x134)
+#define PMCTRL_ACPUPMUVOLUPTIME			(PMCTRL_BASE + 0x360)
+#define PMCTRL_ACPUPMUVOLDNTIME			(PMCTRL_BASE + 0x364)
+#define PMCTRL_ACPUVOLPMUADDR			(PMCTRL_BASE + 0x368)
+#define PMCTRL_ACPUVOLUPSTEP			(PMCTRL_BASE + 0x36c)
+#define PMCTRL_ACPUVOLDNSTEP			(PMCTRL_BASE + 0x370)
+#define PMCTRL_ACPUDFTVOL			(PMCTRL_BASE + 0x374)
+#define PMCTRL_ACPUDESTVOL			(PMCTRL_BASE + 0x378)
+#define PMCTRL_ACPUVOLTTIMEOUT			(PMCTRL_BASE + 0x37c)
+
+#define PMCTRL_ACPUPLLCTRL_EN_CFG		(1 << 0)
+
+#define PMCTRL_ACPUCLKDIV_CPUEXT_CFG_MASK	(3 << 0)
+#define PMCTRL_ACPUCLKDIV_DDR_CFG_MASK		(3 << 8)
+#define PMCTRL_ACPUCLKDIV_CPUEXT_STAT_MASK	(3 << 16)
+#define PMCTRL_ACPUCLKDIV_DDR_STAT_MASK		(3 << 24)
+
+#define PMCTRL_ACPUPLLSEL_ACPUPLL_CFG		(1 << 0)
+#define PMCTRL_ACPUPLLSEL_ACPUPLL_STAT		(1 << 1)
+#define PMCTRL_ACPUPLLSEL_SYSPLL_STAT		(1 << 2)
+
+#define PMCTRL_ACPUSYSPLL_CLKDIV_CFG_MASK	0x7
+#define PMCTRL_ACPUSYSPLL_CLKEN_CFG		(1 << 4)
+#define PMCTRL_ACPUSYSPLL_CLKDIV_SW		(3 << 12)
+
+#define PMCTRL_ACPUSYSPLLCFG_SYSPLL_CLKEN	(1 << 4)
+#define PMCTRL_ACPUSYSPLLCFG_CLKDIV_MASK	(3 << 12)
+
+#define PMCTRL_ACPUDESTVOL_DEST_VOL_MASK	0x7f
+#define PMCTRL_ACPUDESTVOL_CURR_VOL_MASK	(0x7f << 8)
+
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_START   (0)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_en_cfg_END     (0)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_rst_START      (2)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_rst_END        (2)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_time_START     (4)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_time_END       (27)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_timeout_START  (28)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_timeout_END    (28)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_lock_START     (29)
+#define SOC_PMCTRL_ACPUPLLCTRL_acpupll_lock_END       (29)
+
+#define SOC_PMCTRL_ACPUPLLFRAC_ADDR(base)   ((base) + (0x134))
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_sw_START   (12)
+
+#define SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_cfg_START   (0)
+#define SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_cfg_END     (0)
+#define SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_stat_START  (1)
+#define SOC_PMCTRL_ACPUPLLSEL_acpu_pllsw_stat_END    (1)
+#define SOC_PMCTRL_ACPUPLLSEL_syspll_sw_stat_START   (2)
+#define SOC_PMCTRL_ACPUPLLSEL_syspll_sw_stat_END     (2)
+
+#define SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_START     (0)
+#define SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_cfg_END       (1)
+#define SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_START   (8)
+#define SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_cfg_END     (9)
+#define SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_stat_START    (16)
+#define SOC_PMCTRL_ACPUCLKDIV_cpuext_clk_div_stat_END      (17)
+#define SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_stat_START  (24)
+#define SOC_PMCTRL_ACPUCLKDIV_acpu_ddr_clk_div_stat_END    (25)
+
+#define SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_START   (0)
+#define SOC_PMCTRL_ACPUDESTVOL_acpu_dest_vol_END     (6)
+#define SOC_PMCTRL_ACPUDESTVOL_acpu_vol_using_START  (8)
+#define SOC_PMCTRL_ACPUDESTVOL_acpu_vol_using_END    (14)
+
+#define SOC_PMCTRL_ACPUVOLTIMEOUT_acpu_vol_timeout_START  (0)
+#define SOC_PMCTRL_ACPUVOLTIMEOUT_acpu_vol_timeout_END    (0)
+
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_div_cfg_START      (0)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_div_cfg_END        (2)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_cfg_START    (4)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_cfg_END      (4)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_cfg_START  (8)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_subsys_clk_div_cfg_END    (9)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_div_stat_START     (16)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_div_stat_END       (19)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_stat_START   (20)
+#define SOC_PMCTRL_ACPUSYSPLLCFG_acpu_syspll_clken_stat_END     (20)
+
+#endif /* __HI6220_REGS_PMCTRL_H__ */
diff --git a/plat/hisilicon/hikey/include/hi6553.h b/plat/hisilicon/hikey/include/hi6553.h
new file mode 100644
index 0000000..76cb8ff
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hi6553.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HI6553_H__
+#define __HI6553_H__
+
+#include <hi6220.h>
+#include <mmio.h>
+
+#define HI6553_DISABLE6_XO_CLK			(PMUSSI_BASE + (0x036 << 2))
+
+#define DISABLE6_XO_CLK_BB			(1 << 0)
+#define DISABLE6_XO_CLK_CONN			(1 << 1)
+#define DISABLE6_XO_CLK_NFC			(1 << 2)
+#define DISABLE6_XO_CLK_RF1			(1 << 3)
+#define DISABLE6_XO_CLK_RF2			(1 << 4)
+
+#define HI6553_VERSION_REG			(PMUSSI_BASE + (0x000 << 2))
+#define HI6553_ENABLE2_LDO1_8			(PMUSSI_BASE + (0x029 << 2))
+#define HI6553_DISABLE2_LDO1_8			(PMUSSI_BASE + (0x02a << 2))
+#define HI6553_ONOFF_STATUS2_LDO1_8		(PMUSSI_BASE + (0x02b << 2))
+#define HI6553_ENABLE3_LDO9_16			(PMUSSI_BASE + (0x02c << 2))
+#define HI6553_DISABLE3_LDO9_16			(PMUSSI_BASE + (0x02d << 2))
+#define HI6553_ONOFF_STATUS3_LDO9_16		(PMUSSI_BASE + (0x02e << 2))
+#define HI6553_ENABLE4_LDO17_22			(PMUSSI_BASE + (0x02f << 2))
+#define HI6553_DISABLE4_LDO17_22		(PMUSSI_BASE + (0x030 << 2))
+#define HI6553_ONOFF_STATUS4_LDO17_22		(PMUSSI_BASE + (0x031 << 2))
+#define HI6553_PERI_EN_MARK			(PMUSSI_BASE + (0x040 << 2))
+#define HI6553_BUCK2_REG1			(PMUSSI_BASE + (0x04a << 2))
+#define HI6553_BUCK2_REG5			(PMUSSI_BASE + (0x04e << 2))
+#define HI6553_BUCK2_REG6			(PMUSSI_BASE + (0x04f << 2))
+#define HI6553_BUCK3_REG3			(PMUSSI_BASE + (0x054 << 2))
+#define HI6553_BUCK3_REG5			(PMUSSI_BASE + (0x056 << 2))
+#define HI6553_BUCK3_REG6			(PMUSSI_BASE + (0x057 << 2))
+#define HI6553_BUCK4_REG2			(PMUSSI_BASE + (0x05b << 2))
+#define HI6553_BUCK4_REG5			(PMUSSI_BASE + (0x05e << 2))
+#define HI6553_BUCK4_REG6			(PMUSSI_BASE + (0x05f << 2))
+#define HI6553_CLK_TOP0				(PMUSSI_BASE + (0x063 << 2))
+#define HI6553_CLK_TOP3				(PMUSSI_BASE + (0x066 << 2))
+#define HI6553_CLK_TOP4				(PMUSSI_BASE + (0x067 << 2))
+#define HI6553_VSET_BUCK2_ADJ			(PMUSSI_BASE + (0x06d << 2))
+#define HI6553_VSET_BUCK3_ADJ			(PMUSSI_BASE + (0x06e << 2))
+#define HI6553_LDO7_REG_ADJ			(PMUSSI_BASE + (0x078 << 2))
+#define HI6553_LDO10_REG_ADJ			(PMUSSI_BASE + (0x07b << 2))
+#define HI6553_LDO15_REG_ADJ			(PMUSSI_BASE + (0x080 << 2))
+#define HI6553_LDO19_REG_ADJ			(PMUSSI_BASE + (0x084 << 2))
+#define HI6553_LDO20_REG_ADJ			(PMUSSI_BASE + (0x085 << 2))
+#define HI6553_LDO21_REG_ADJ			(PMUSSI_BASE + (0x086 << 2))
+#define HI6553_LDO22_REG_ADJ			(PMUSSI_BASE + (0x087 << 2))
+#define HI6553_DR_LED_CTRL			(PMUSSI_BASE + (0x098 << 2))
+#define HI6553_DR_OUT_CTRL			(PMUSSI_BASE + (0x099 << 2))
+#define HI6553_DR3_ISET				(PMUSSI_BASE + (0x09a << 2))
+#define HI6553_DR3_START_DEL			(PMUSSI_BASE + (0x09b << 2))
+#define HI6553_DR4_ISET				(PMUSSI_BASE + (0x09c << 2))
+#define HI6553_DR4_START_DEL			(PMUSSI_BASE + (0x09d << 2))
+#define HI6553_DR345_TIM_CONF0			(PMUSSI_BASE + (0x0a0 << 2))
+#define HI6553_NP_REG_ADJ1			(PMUSSI_BASE + (0x0be << 2))
+#define HI6553_NP_REG_CHG			(PMUSSI_BASE + (0x0c0 << 2))
+#define HI6553_BUCK01_CTRL2			(PMUSSI_BASE + (0x0d9 << 2))
+#define HI6553_BUCK0_CTRL1			(PMUSSI_BASE + (0x0dd << 2))
+#define HI6553_BUCK0_CTRL5			(PMUSSI_BASE + (0x0e1 << 2))
+#define HI6553_BUCK0_CTRL7			(PMUSSI_BASE + (0x0e3 << 2))
+#define HI6553_BUCK1_CTRL1			(PMUSSI_BASE + (0x0e8 << 2))
+#define HI6553_BUCK1_CTRL5			(PMUSSI_BASE + (0x0ec << 2))
+#define HI6553_BUCK1_CTRL7			(PMUSSI_BASE + (0x0ef << 2))
+#define HI6553_CLK19M2_600_586_EN		(PMUSSI_BASE + (0x0fe << 2))
+
+#define LED_START_DELAY_TIME			0x00
+#define LED_ELEC_VALUE				0x07
+#define LED_LIGHT_TIME				0xf0
+#define LED_GREEN_ENABLE			(1 << 1)
+#define LED_OUT_CTRL				0x00
+
+#define PMU_HI6552_V300				0x30
+#define PMU_HI6552_V310				0x31
+
+#endif	/* __HI6553_H__ */
diff --git a/plat/hisilicon/hikey/include/hisi_ipc.h b/plat/hisilicon/hikey/include/hisi_ipc.h
new file mode 100644
index 0000000..b20742f
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hisi_ipc.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HISI_IPC_H__
+#define __HISI_IPC_H__
+
+#define HISI_IPC_CORE_ACPU		0x0
+
+#define HISI_IPC_MCU_INT_SRC_ACPU0_PD	10
+#define HISI_IPC_MCU_INT_SRC_ACPU1_PD	11
+#define HISI_IPC_MCU_INT_SRC_ACPU2_PD	12
+#define HISI_IPC_MCU_INT_SRC_ACPU3_PD	13
+#define HISI_IPC_MCU_INT_SRC_ACPU_PD	16
+#define HISI_IPC_MCU_INT_SRC_ACPU4_PD	26
+#define HISI_IPC_MCU_INT_SRC_ACPU5_PD	27
+#define HISI_IPC_MCU_INT_SRC_ACPU6_PD	28
+#define HISI_IPC_MCU_INT_SRC_ACPU7_PD	29
+
+#define HISI_IPC_SEM_CPUIDLE		27
+#define HISI_IPC_INT_SRC_NUM		32
+
+#define HISI_IPC_PM_ON			0
+#define HISI_IPC_PM_OFF			1
+
+#define HISI_IPC_OK			(0)
+#define HISI_IPC_ERROR			(-1)
+
+#define HISI_IPC_BASE_ADDR		(0xF7510000)
+#define HISI_IPC_CPU_RAW_INT_ADDR	(0xF7510420)
+#define HISI_IPC_ACPU_CTRL(i)		(0xF7510800 + (i << 3))
+
+void hisi_ipc_spin_lock(unsigned int signal);
+void hisi_ipc_spin_unlock(unsigned int signal);
+void hisi_ipc_cpu_on(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cpu_off(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cpu_suspend(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cluster_on(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cluster_off(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_cluster_suspend(unsigned int cpu, unsigned int cluster);
+void hisi_ipc_psci_system_off(void);
+int hisi_ipc_init(void);
+
+#endif	/* __HISI_IPC_H__ */
diff --git a/plat/hisilicon/hikey/include/hisi_mcu.h b/plat/hisilicon/hikey/include/hisi_mcu.h
new file mode 100644
index 0000000..f5c6ed0
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hisi_mcu.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef	__HISI_MCU_H__
+#define	__HISI_MCU_H__
+
+#include <stdint.h>
+
+extern void hisi_mcu_enable_sram(void);
+extern void hisi_mcu_start_run(void);
+extern int hisi_mcu_load_image(uintptr_t image_base, uint32_t image_size);
+
+#endif	/* __HISI_MCU_H__ */
diff --git a/plat/hisilicon/hikey/include/hisi_pwrc.h b/plat/hisilicon/hikey/include/hisi_pwrc.h
new file mode 100644
index 0000000..3a87e72
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hisi_pwrc.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HISI_PWRC_H__
+#define __HISI_PWRC_H__
+
+#ifndef __ASSEMBLY__
+
+void hisi_pwrc_set_cluster_wfi(unsigned int id);
+void hisi_pwrc_set_core_bx_addr(unsigned int core,
+				unsigned int cluster,
+				uintptr_t entry_point);
+int hisi_pwrc_setup(void);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __HISI_PWRC_H__ */
diff --git a/plat/hisilicon/hikey/include/hisi_sram_map.h b/plat/hisilicon/hikey/include/hisi_sram_map.h
new file mode 100644
index 0000000..ed90c7b
--- /dev/null
+++ b/plat/hisilicon/hikey/include/hisi_sram_map.h
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HISI_SRAM_MAP_H__
+#define __HISI_SRAM_MAP_H__
+
+/*
+ * SRAM Memory Region Layout
+ *
+ *  +-----------------------+
+ *  |  Low Power Mode       | 7KB
+ *  +-----------------------+
+ *  |  Secure OS            | 64KB
+ *  +-----------------------+
+ *  |  Software Flag        | 1KB
+ *  +-----------------------+
+ *
+ */
+
+#define SOC_SRAM_OFF_BASE_ADDR		(0xFFF80000)
+
+/* PM Section: 7KB */
+#define SRAM_PM_ADDR			(SOC_SRAM_OFF_BASE_ADDR)
+#define SRAM_PM_SIZE			(0x00001C00)
+
+/* TEE OS Section: 64KB */
+#define SRAM_TEEOS_ADDR			(SRAM_PM_ADDR + SRAM_PM_SIZE)
+#define SRAM_TEEOS_SIZE			(0x00010000)
+
+/* General Use Section: 1KB */
+#define SRAM_GENERAL_ADDR		(SRAM_TEEOS_ADDR + SRAM_TEEOS_SIZE)
+#define SRAM_GENERAL_SIZE		(0x00000400)
+
+/*
+ * General Usage Section Layout:
+ *
+ *  +-----------------------+
+ *  |  AP boot flag         | 64B
+ *  +-----------------------+
+ *  |  DICC flag            | 32B
+ *  +-----------------------+
+ *  |  Soft flag            | 256B
+ *  +-----------------------+
+ *  |  Thermal flag         | 128B
+ *  +-----------------------+
+ *  |  CSHELL               | 4B
+ *  +-----------------------+
+ *  |  Uart Switching       | 4B
+ *  +-----------------------+
+ *  |  ICC                  | 1024B
+ *  +-----------------------+
+ *  |  Memory Management    | 1024B
+ *  +-----------------------+
+ *  |  IFC                  | 32B
+ *  +-----------------------+
+ *  |  HIFI                 | 32B
+ *  +-----------------------+
+ *  |  DDR capacity         | 4B
+ *  +-----------------------+
+ *  |  Reserved             |
+ *  +-----------------------+
+ *
+ */
+
+/* App Core Boot Flags */
+#define MEMORY_AXI_ACPU_START_ADDR		(SRAM_GENERAL_ADDR)
+#define MEMORY_AXI_ACPU_START_SIZE		(64)
+
+#define MEMORY_AXI_SRESET_FLAG_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0000)
+#define MEMORY_AXI_SECOND_CPU_BOOT_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0004)
+#define MEMORY_AXI_READY_FLAG_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0008)
+#define MEMORY_AXI_FASTBOOT_ENTRY_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x000C)
+#define MEMORY_AXI_PD_CHARGE_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0010)
+#define MEMORY_AXI_DBG_ALARM_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0014)
+#define MEMORY_AXI_CHIP_ADDR			(MEMORY_AXI_ACPU_START_ADDR + 0x0018)
+#define MEMORY_AXI_BOARD_TYPE_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x001C)
+#define MEMORY_AXI_BOARD_ID_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0020)
+#define MEMORY_AXI_CHARGETYPE_FLAG_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0024)
+#define MEMORY_AXI_COLD_START_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0028)
+#define MEMORY_AXI_ANDROID_REBOOT_FLAG_ADDR	(MEMORY_AXI_ACPU_START_ADDR + 0x002C)
+#define MEMORY_AXI_ACPU_WDTRST_REBOOT_FLAG_ADDR	(MEMORY_AXI_ACPU_START_ADDR + 0x0030)
+#define MEMORY_AXI_ABNRST_BITMAP_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0034)
+#define MEMORY_AXI_32K_CLK_TYPE_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x0038)
+#define AXI_MODEM_PANIC_FLAG_ADDR		(MEMORY_AXI_ACPU_START_ADDR + 0x003C)
+#define AXI_MODEM_PANIC_FLAG			(0x68697369)
+#define MEMORY_AXI_ACPU_END_ADDR		(AXI_MODEM_PANIC_FLAG_ADDR + 4)
+
+/* DICC Flags */
+#define MEMORY_AXI_DICC_ADDR			(MEMORY_AXI_ACPU_START_ADDR + MEMORY_AXI_ACPU_START_SIZE)
+#define MEMORY_AXI_DICC_SIZE			(32)
+
+#define MEMORY_AXI_SOFT_FLAG_ADDR		(MEMORY_AXI_DICC_ADDR + MEMORY_AXI_DICC_SIZE)
+#define MEMORY_AXI_SOFT_FLAG_SIZE		(256)
+
+/* Thermal Flags */
+#define MEMORY_AXI_TEMP_PROTECT_ADDR		(MEMORY_AXI_SOFT_FLAG_ADDR + MEMORY_AXI_SOFT_FLAG_SIZE)
+#define MEMORY_AXI_TEMP_PROTECT_SIZE		(128)
+
+/* CSHELL */
+#define MEMORY_AXI_USB_CSHELL_ADDR		(MEMORY_AXI_TEMP_PROTECT_ADDR + MEMORY_AXI_TEMP_PROTECT_SIZE)
+#define MEMORY_AXI_USB_CSHELL_SIZE		(4)
+
+/* Uart and A/C Shell Switch Flags */
+#define MEMORY_AXI_UART_INOUT_ADDR		(MEMORY_AXI_USB_CSHELL_ADDR + MEMORY_AXI_USB_CSHELL_SIZE)
+#define MEMORY_AXI_UART_INOUT_SIZE		(4)
+
+/* IFC Flags */
+#define MEMORY_AXI_IFC_ADDR			(MEMORY_AXI_UART_INOUT_ADDR + MEMORY_AXI_UART_INOUT_SIZE)
+#define MEMORY_AXI_IFC_SIZE			(32)
+
+/* HIFI Data */
+#define MEMORY_AXI_HIFI_ADDR			(MEMORY_AXI_IFC_ADDR + MEMORY_AXI_IFC_SIZE)
+#define MEMORY_AXI_HIFI_SIZE			(32)
+
+/* CONFIG Flags */
+#define MEMORY_AXI_CONFIG_ADDR			(MEMORY_AXI_HIFI_ADDR + MEMORY_AXI_HIFI_SIZE)
+#define MEMORY_AXI_CONFIG_SIZE			(32)
+
+/* DDR Capacity Flags */
+#define MEMORY_AXI_DDR_CAPACITY_ADDR		(MEMORY_AXI_CONFIG_ADDR + MEMORY_AXI_CONFIG_SIZE)
+#define MEMORY_AXI_DDR_CAPACITY_SIZE		(4)
+
+/* USB Shell Flags */
+#define MEMORY_AXI_USB_SHELL_FLAG_ADDR		(MEMORY_AXI_DDR_CAPACITY_ADDR + MEMORY_AXI_DDR_CAPACITY_SIZE)
+#define MEMORY_AXI_USB_SHELL_FLAG_SIZE		(4)
+
+/* MCU WDT Switch Flag */
+#define MEMORY_AXI_MCU_WDT_FLAG_ADDR		(MEMORY_AXI_USB_SHELL_FLAG_ADDR + MEMORY_AXI_USB_SHELL_FLAG_SIZE)
+#define MEMORY_AXI_MCU_WDT_FLAG_SIZE		(4)
+
+/* TLDSP Mailbox MNTN */
+#define SRAM_DSP_MNTN_INFO_ADDR			(MEMORY_AXI_MCU_WDT_FLAG_ADDR + MEMORY_AXI_MCU_WDT_FLAG_SIZE)
+#define SRAM_DSP_MNTN_SIZE			(32)
+
+/* TLDSP ARM Mailbox Protect Flag */
+#define SRAM_DSP_ARM_MAILBOX_PROTECT_FLAG_ADDR	(SRAM_DSP_MNTN_INFO_ADDR + SRAM_DSP_MNTN_SIZE)
+#define SRAM_DSP_ARM_MAILBOX_PROTECT_FLAG_SIZE	(4)
+
+/* RTT Sleep Flag */
+#define SRAM_RTT_SLEEP_FLAG_ADDR                (SRAM_DSP_ARM_MAILBOX_PROTECT_FLAG_ADDR + SRAM_DSP_ARM_MAILBOX_PROTECT_FLAG_SIZE)
+#define SRAM_RTT_SLEEP_FLAG_SIZE                (32)
+
+/* LDSP Awake Flag */
+#define MEMORY_AXI_LDSP_AWAKE_ADDR              (SRAM_RTT_SLEEP_FLAG_ADDR + SRAM_RTT_SLEEP_FLAG_SIZE)
+#define MEMORY_AXI_LDSP_AWAKE_SIZE              (4)
+
+#define NVUPDATE_SUCCESS			0x5555AAAA
+#define NVUPDATE_FAILURE			0xAAAA5555
+
+/*
+ * Low Power Mode Region
+ */
+#define PWRCTRL_ACPU_ASM_SPACE_ADDR		(SRAM_PM_ADDR)
+#define PWRCTRL_ACPU_ASM_SPACE_SIZE		(SRAM_PM_SIZE)
+
+#define PWRCTRL_ACPU_ASM_MEM_BASE		(PWRCTRL_ACPU_ASM_SPACE_ADDR)
+#define PWRCTRL_ACPU_ASM_MEM_SIZE		(PWRCTRL_ACPU_ASM_SPACE_SIZE)
+#define PWRCTRL_ACPU_ASM_CODE_BASE		(PWRCTRL_ACPU_ASM_MEM_BASE + 0x200)
+#define PWRCTRL_ACPU_ASM_DATA_BASE		(PWRCTRL_ACPU_ASM_MEM_BASE + 0xE00)
+#define PWRCTRL_ACPU_ASM_DATA_SIZE		(0xE00)
+
+#define PWRCTRL_ACPU_ASM_D_C0_ADDR		(PWRCTRL_ACPU_ASM_DATA_BASE)
+#define PWRCTRL_ACPU_ASM_D_C0_MMU_PARA_AD	(PWRCTRL_ACPU_ASM_DATA_BASE + 0)
+#define PWRCTRL_ACPU_ASM_D_ARM_PARA_AD		(PWRCTRL_ACPU_ASM_DATA_BASE + 0x20)
+
+#define PWRCTRL_ACPU_ASM_D_COMM_ADDR		(PWRCTRL_ACPU_ASM_DATA_BASE + 0x700)
+
+#define PWRCTRL_ACPU_REBOOT			(PWRCTRL_ACPU_ASM_D_COMM_ADDR)
+#define PWRCTRL_ACPU_REBOOT_SIZE		(0x200)
+#define PWRCTRL_ACPU_ASM_SLICE_BAK_ADDR		(PWRCTRL_ACPU_REBOOT + PWRCTRL_ACPU_REBOOT_SIZE)
+#define PWRCTRL_ACPU_ASM_SLICE_BAK_SIZE		(4)
+#define PWRCTRL_ACPU_ASM_DEBUG_FLAG_ADDR	(PWRCTRL_ACPU_ASM_SLICE_BAK_ADDR + PWRCTRL_ACPU_ASM_SLICE_BAK_SIZE)
+#define PWRCTRL_ACPU_ASM_DEBUG_FLAG_SIZE	(4)
+#define EXCH_A_CORE_POWRCTRL_CONV_ADDR		(PWRCTRL_ACPU_ASM_DEBUG_FLAG_ADDR + PWRCTRL_ACPU_ASM_DEBUG_FLAG_SIZE)
+#define EXCH_A_CORE_POWRCTRL_CONV_SIZE		(4)
+
+/*
+ * Below region memory mapping is:
+ * 4 + 12 + 16 + 28 + 28 + 16 + 28 + 12 + 24 + 20 + 64 +
+ * 4 + 4 + 4 + 4 + 12 + 4 + 4 + 4 + 4 + 16 + 4 + 0x2BC +
+ * 24 + 20 + 12 + 16
+ */
+
+#define MEMORY_AXI_CPU_IDLE_ADDR		(EXCH_A_CORE_POWRCTRL_CONV_ADDR + EXCH_A_CORE_POWRCTRL_CONV_SIZE)
+#define MEMORY_AXI_CPU_IDLE_SIZE		(4)
+
+#define MEMORY_AXI_CUR_FREQ_ADDR		(MEMORY_AXI_CPU_IDLE_ADDR + MEMORY_AXI_CPU_IDLE_SIZE)
+#define MEMORY_AXI_CUR_FREQ_SIZE		(12)
+
+#define MEMORY_AXI_ACPU_FREQ_VOL_ADDR		(MEMORY_AXI_CUR_FREQ_ADDR + MEMORY_AXI_CUR_FREQ_SIZE)
+#define MEMORY_AXI_ACPU_FREQ_VOL_SIZE		(16 + 28 + 28)
+
+#define MEMORY_AXI_DDR_FREQ_VOL_ADDR		(MEMORY_AXI_ACPU_FREQ_VOL_ADDR + MEMORY_AXI_ACPU_FREQ_VOL_SIZE)
+#define MEMORY_AXI_DDR_FREQ_VOL_SIZE		(16 + 28)
+
+#define MEMORY_AXI_ACPU_FIQ_TEST_ADDR		(MEMORY_AXI_DDR_FREQ_VOL_ADDR + MEMORY_AXI_DDR_FREQ_VOL_SIZE)
+#define MEMORY_AXI_ACPU_FIQ_TEST_SIZE		(12)
+
+#define MEMORY_AXI_ACPU_FIQ_CPU_INFO_ADDR	(MEMORY_AXI_ACPU_FIQ_TEST_ADDR + MEMORY_AXI_ACPU_FIQ_TEST_SIZE)
+#define MEMORY_AXI_ACPU_FIQ_CPU_INFO_SIZE	(24)
+
+#define MEMORY_AXI_ACPU_FIQ_DEBUG_INFO_ADDR	(MEMORY_AXI_ACPU_FIQ_CPU_INFO_ADDR + MEMORY_AXI_ACPU_FIQ_CPU_INFO_SIZE)
+#define MEMORY_AXI_ACPU_FIQ_DEBUG_INFO_SIZE	(20)
+
+#define MEMORY_FREQDUMP_ADDR			(MEMORY_AXI_ACPU_FIQ_DEBUG_INFO_ADDR + MEMORY_AXI_ACPU_FIQ_DEBUG_INFO_SIZE)
+#define MEMORY_FREQDUMP_SIZE			(64)
+
+#define MEMORY_AXI_CCPU_LOG_ADDR		(MEMORY_FREQDUMP_ADDR + MEMORY_FREQDUMP_SIZE)
+#define MEMORY_AXI_CCPU_LOG_SIZE		(4)
+
+#define MEMORY_AXI_MCU_LOG_ADDR			(MEMORY_AXI_CCPU_LOG_ADDR + MEMORY_AXI_CCPU_LOG_SIZE)
+#define MEMORY_AXI_MCU_LOG_SIZE			(4)
+
+#define MEMORY_AXI_SEC_CORE_BOOT_ADDR		(MEMORY_AXI_MCU_LOG_ADDR + MEMORY_AXI_MCU_LOG_SIZE)
+#define MEMORY_AXI_SEC_CORE_BOOT_SIZE		(4)
+
+#define MEMORY_AXI_BBP_PS_VOTE_FLAG_ADDR	(MEMORY_AXI_SEC_CORE_BOOT_ADDR + MEMORY_AXI_SEC_CORE_BOOT_SIZE)
+#define MEMORY_AXI_BBP_PS_VOTE_FLAG_SIZE	(0x4)
+
+#define POLICY_AREA_RESERVED			(MEMORY_AXI_BBP_PS_VOTE_FLAG_ADDR + MEMORY_AXI_BBP_PS_VOTE_FLAG_SIZE)
+#define POLICY_AREA_RESERVED_SIZE		(12)
+
+#define DDR_POLICY_VALID_MAGIC			(POLICY_AREA_RESERVED + POLICY_AREA_RESERVED_SIZE)
+#define DDR_POLICY_VALID_MAGIC_SIZE		(4)
+
+#define DDR_POLICY_MAX_NUM			(DDR_POLICY_VALID_MAGIC + DDR_POLICY_VALID_MAGIC_SIZE)
+#define DDR_POLICY_MAX_NUM_SIZE			(4)
+
+#define DDR_POLICY_SUPPORT_NUM			(DDR_POLICY_MAX_NUM + DDR_POLICY_MAX_NUM_SIZE)
+#define DDR_POLICY_SUPPORT_NUM_SIZE		(4)
+
+#define DDR_POLICY_CUR_POLICY			(DDR_POLICY_SUPPORT_NUM + DDR_POLICY_SUPPORT_NUM_SIZE)
+#define DDR_POLICY_CUR_POLICY_SIZE		(4)
+
+#define ACPU_POLICY_VALID_MAGIC			(DDR_POLICY_CUR_POLICY + DDR_POLICY_CUR_POLICY_SIZE)
+#define ACPU_POLICY_VALID_MAGIC_SIZE		(4)
+
+#define ACPU_POLICY_MAX_NUM			(ACPU_POLICY_VALID_MAGIC + ACPU_POLICY_VALID_MAGIC_SIZE)
+#define ACPU_POLICY_MAX_NUM_SIZE		(4)
+
+#define ACPU_POLICY_SUPPORT_NUM			(ACPU_POLICY_MAX_NUM + ACPU_POLICY_MAX_NUM_SIZE)
+#define ACPU_POLICY_SUPPORT_NUM_SIZE		(4)
+
+#define ACPU_POLICY_CUR_POLICY			(ACPU_POLICY_SUPPORT_NUM + ACPU_POLICY_SUPPORT_NUM_SIZE)
+#define ACPU_POLICY_CUR_POLICY_SIZE		(4)
+
+#define LPDDR_OPTION_ADDR			(ACPU_POLICY_CUR_POLICY + ACPU_POLICY_CUR_POLICY_SIZE)
+#define LPDDR_OPTION_SIZE			(4)
+
+#define MEMORY_AXI_DDR_DDL_ADDR			(LPDDR_OPTION_ADDR + LPDDR_OPTION_SIZE)
+#define MEMORY_AXI_DDR_DDL_SIZE			(0x2BC)
+
+#define DDR_TEST_DFS_ADDR			(MEMORY_AXI_DDR_DDL_ADDR + MEMORY_AXI_DDR_DDL_SIZE)
+#define DDR_TEST_DFS_ADDR_SIZE			(4)
+
+#define DDR_TEST_DFS_TIMES_ADDR			(DDR_TEST_DFS_ADDR + DDR_TEST_DFS_ADDR_SIZE)
+#define DDR_TEST_DFS_TIMES_ADDR_SIZE		(4)
+
+#define DDR_TEST_QOS_ADDR			(DDR_TEST_DFS_TIMES_ADDR + DDR_TEST_DFS_TIMES_ADDR_SIZE)
+#define DDR_TEST_QOS_ADDR_SIZE			(4)
+
+#define DDR_TEST_FUN_ADDR			(DDR_TEST_QOS_ADDR + DDR_TEST_QOS_ADDR_SIZE)
+#define DDR_TEST_FUN_ADDR_SIZE			(4)
+
+#define BOARD_TYPE_ADDR				(DDR_TEST_FUN_ADDR + DDR_TEST_FUN_ADDR_SIZE)
+#define BOARD_ADDR_SIZE				(4)
+#define DDR_DFS_FREQ_ADDR			(BOARD_TYPE_ADDR + BOARD_ADDR_SIZE)
+#define DDR_DFS_FREQ_SIZE			(4)
+
+#define DDR_PASR_ADDR				(DDR_DFS_FREQ_ADDR + DDR_DFS_FREQ_SIZE)
+#define DDR_PASR_SIZE				(20)
+
+#define ACPU_DFS_FREQ_ADDR			(DDR_PASR_ADDR + DDR_PASR_SIZE)
+#define ACPU_DFS_FREQ_ADDR_SIZE			(12)
+
+#define ACPU_CHIP_MAX_FREQ			(ACPU_DFS_FREQ_ADDR + ACPU_DFS_FREQ_ADDR_SIZE)
+#define ACPU_CHIP_MAX_FREQ_SIZE			(4)
+
+#define MEMORY_MEDPLL_STATE_ADDR		(ACPU_CHIP_MAX_FREQ + ACPU_CHIP_MAX_FREQ_SIZE)
+#define MEMORY_MEDPLL_STATE_SIZE		(8)
+
+#define MEMORY_CCPU_LOAD_FLAG_ADDR		(MEMORY_MEDPLL_STATE_ADDR + MEMORY_MEDPLL_STATE_SIZE)
+#define MEMORY_CCPU_LOAD_FLAG_SIZE		(4)
+
+
+#define ACPU_CORE_BITS_ADDR			(MEMORY_CCPU_LOAD_FLAG_ADDR + MEMORY_CCPU_LOAD_FLAG_SIZE)
+#define ACPU_CORE_BITS_SIZE			(4)
+
+#define ACPU_CLUSTER_IDLE_ADDR			(ACPU_CORE_BITS_ADDR + ACPU_CORE_BITS_SIZE)
+#define ACPU_CLUSTER_IDLE_SIZE			(4)
+
+#define ACPU_A53_FLAGS_ADDR			(ACPU_CLUSTER_IDLE_ADDR + ACPU_CLUSTER_IDLE_SIZE)
+#define ACPU_A53_FLAGS_SIZE			(4)
+
+#define ACPU_POWER_STATE_QOS_ADDR		(ACPU_A53_FLAGS_ADDR+ACPU_A53_FLAGS_SIZE)
+#define ACPU_POWER_STATE_QOS_SIZE		(4)
+
+#define ACPU_UNLOCK_CORE_FLAGS_ADDR		(ACPU_POWER_STATE_QOS_ADDR+ACPU_POWER_STATE_QOS_SIZE)
+#define ACPU_UNLOCK_CORE_FLAGS_SIZE		(8)
+
+#define ACPU_SUBSYS_POWERDOWN_FLAGS_ADDR	(ACPU_UNLOCK_CORE_FLAGS_ADDR + ACPU_UNLOCK_CORE_FLAGS_SIZE)
+#define ACPU_SUBSYS_POWERDOWN_FLAGS_SIZE	(4)
+
+#define ACPU_CORE_POWERDOWN_FLAGS_ADDR		(ACPU_SUBSYS_POWERDOWN_FLAGS_ADDR + ACPU_SUBSYS_POWERDOWN_FLAGS_SIZE)
+#define ACPU_CORE_POWERDOWN_FLAGS_SIZE		(4)
+
+#define ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR	(ACPU_CORE_POWERDOWN_FLAGS_ADDR + ACPU_CORE_POWERDOWN_FLAGS_SIZE)
+#define ACPU_CLUSTER_POWERDOWN_FLAGS_SIZE	(4)
+
+#define ACPU_ARM64_FLAGA			(ACPU_CLUSTER_POWERDOWN_FLAGS_ADDR + ACPU_CLUSTER_POWERDOWN_FLAGS_SIZE)
+#define ACPU_ARM64_FLAGA_SIZE			(4)
+
+#define ACPU_ARM64_FLAGB			(ACPU_ARM64_FLAGA + ACPU_ARM64_FLAGA_SIZE)
+#define ACPU_ARM64_FLAGB_SIZE			(4)
+
+#define MCU_EXCEPTION_FLAGS_ADDR		(ACPU_ARM64_FLAGB + ACPU_ARM64_FLAGB_SIZE)
+#define MCU_EXCEPTION_FLAGS_SIZE		(4)
+
+#define ACPU_MASTER_CORE_STATE_ADDR		(MCU_EXCEPTION_FLAGS_ADDR + MCU_EXCEPTION_FLAGS_SIZE)
+#define ACPU_MASTER_CORE_STATE_SIZE		(4)
+
+#define PWRCTRL_AXI_RESERVED_ADDR		(ACPU_MASTER_CORE_STATE_ADDR + ACPU_MASTER_CORE_STATE_SIZE)
+
+#endif /* __HISI_SRAM_MAP_H__ */
diff --git a/plat/hisilicon/hikey/include/plat_macros.S b/plat/hisilicon/hikey/include/plat_macros.S
new file mode 100644
index 0000000..1ad217a
--- /dev/null
+++ b/plat/hisilicon/hikey/include/plat_macros.S
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <cci.h>
+#include <gic_v2.h>
+#include <hi6220.h>
+#include <platform_def.h>
+
+.section .rodata.gic_reg_name, "aS"
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n"	\
+		" Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+.section .rodata.cci_reg_name, "aS"
+cci_iface_regs:
+	.asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
+
+/* ---------------------------------------------
+ * The below macro prints out relevant GIC
+ * registers whenever an unhandled exception is
+ * taken in BL31.
+ * ---------------------------------------------
+ */
+.macro plat_crash_print_regs
+	mov_imm	x16, PLAT_ARM_GICD_BASE
+	mov_imm	x17, PLAT_ARM_GICC_BASE
+
+	/* Load the gicc reg list to x6 */
+	adr	x6, gicc_regs
+	/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+	ldr	w8, [x17, #GICC_HPPIR]
+	ldr	w9, [x17, #GICC_AHPPIR]
+	ldr	w10, [x17, #GICC_CTLR]
+	/* Store to the crash buf and print to cosole */
+	bl	str_in_crash_buf_print
+
+	/* Print the GICD_ISPENDR regs */
+	add	x7, x16, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+2:
+	sub	x4, x7, x16
+	cmp	x4, #0x280
+	b.eq	1f
+	bl	asm_print_hex
+	adr	x4, spacer
+	bl	asm_print_str
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+	adr	x4, newline
+	bl	asm_print_str
+	b	2b
+1:
+	adr	x6, cci_iface_regs
+	/* Store in x7 the base address of the first interface */
+	mov_imm	x7, (CCI400_BASE + SLAVE_IFACE_OFFSET(	\
+			CCI400_SL_IFACE3_CLUSTER_IX))
+	ldr	w8, [x7, #SNOOP_CTRL_REG]
+	/* Store in x7 the base address of the second interface */
+	mov_imm	x7, (CCI400_BASE + SLAVE_IFACE_OFFSET(	\
+			CCI400_SL_IFACE4_CLUSTER_IX))
+	ldr	w9, [x7, #SNOOP_CTRL_REG]
+	/* Store to the crash buf and print to console */
+	bl	str_in_crash_buf_print
+.endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/hisilicon/hikey/include/platform_def.h b/plat/hisilicon/hikey/include/platform_def.h
new file mode 100644
index 0000000..a91a9b0
--- /dev/null
+++ b/plat/hisilicon/hikey/include/platform_def.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include "../hikey_def.h"
+
+/*
+ * Platform binary types for linking
+ */
+#define PLATFORM_LINKER_FORMAT          "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH            aarch64
+
+
+/*
+ * Generic platform constants
+ */
+
+/* Size of cacheable stacks */
+#define PLATFORM_STACK_SIZE		0x800
+
+#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+
+#define PLATFORM_CACHE_LINE_SIZE	64
+#define PLATFORM_CLUSTER_COUNT		2
+#define PLATFORM_CORE_COUNT_PER_CLUSTER	4
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT *	\
+					 PLATFORM_CORE_COUNT_PER_CLUSTER)
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
+#define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CORE_COUNT + \
+					 PLATFORM_CLUSTER_COUNT + 1)
+
+#define PLAT_MAX_RET_STATE		1
+#define PLAT_MAX_OFF_STATE		2
+
+#define MAX_IO_DEVICES			3
+#define MAX_IO_HANDLES			4
+/* eMMC RPMB and eMMC User Data */
+#define MAX_IO_BLOCK_DEVICES		2
+
+/* GIC related constants (no GICR in GIC-400) */
+#define PLAT_ARM_GICD_BASE		0xF6801000
+#define PLAT_ARM_GICC_BASE		0xF6802000
+#define PLAT_ARM_GICH_BASE		0xF6804000
+#define PLAT_ARM_GICV_BASE		0xF6806000
+
+
+/*
+ * Platform memory map related constants
+ */
+
+/*
+ * BL1 is stored in XG2RAM0_HIRQ that is 784KB large (0xF980_0000~0xF98C_4000).
+ */
+#define ONCHIPROM_PARAM_BASE		(XG2RAM0_BASE + 0x700)
+#define LOADER_RAM_BASE			(XG2RAM0_BASE + 0x800)
+#define BL1_XG2RAM0_OFFSET		0x1000
+
+/*
+ * BL1 specific defines.
+ *
+ * Both loader and BL1_RO region stay in SRAM since they are used to simulate
+ * ROM.
+ * Loader is used to switch Hi6220 SoC from 32-bit to 64-bit mode.
+ *
+ * ++++++++++  0xF980_0000
+ * + loader +
+ * ++++++++++  0xF980_1000
+ * + BL1_RO +
+ * ++++++++++  0xF981_0000
+ * + BL1_RW +
+ * ++++++++++  0xF989_8000
+ */
+#define BL1_RO_BASE			(XG2RAM0_BASE + BL1_XG2RAM0_OFFSET)
+#define BL1_RO_LIMIT			(XG2RAM0_BASE + 0x10000)
+#define BL1_RW_BASE			(BL1_RO_LIMIT)	/* 0xf981_0000 */
+#define BL1_RW_SIZE			(0x00088000)
+#define BL1_RW_LIMIT			(0xF9898000)
+
+/*
+ * BL2 specific defines.
+ */
+#define BL2_BASE			(BL1_RW_BASE + 0x8000)	/* 0xf981_8000 */
+#define BL2_LIMIT			(BL2_BASE + 0x40000)
+
+/*
+ * SCP_BL2 specific defines.
+ * In HiKey, SCP_BL2 means MCU firmware. It's loaded into the temporary buffer
+ * at 0x0100_0000. Then BL2 will parse the sections and loaded them into
+ * predefined separated buffers.
+ */
+#define SCP_BL2_BASE			(DDR_BASE + 0x01000000)
+#define SCP_BL2_LIMIT			(SCP_BL2_BASE + 0x00100000)
+#define SCP_BL2_SIZE			(SCP_BL2_LIMIT - SCP_BL2_BASE)
+
+/*
+ * BL31 specific defines.
+ */
+#define BL31_BASE			BL2_LIMIT
+#define BL31_LIMIT			0xF9898000
+
+#define NS_BL1U_BASE			(BL2_BASE)
+#define NS_BL1U_SIZE			(0x00010000)
+#define NS_BL1U_LIMIT			(NS_BL1U_BASE + NS_BL1U_SIZE)
+
+/*
+ * Platform specific page table and MMU setup constants
+ */
+#define ADDR_SPACE_SIZE			(1ull << 32)
+
+#if IMAGE_BL1 || IMAGE_BL2 || IMAGE_BL31
+#define MAX_XLAT_TABLES			3
+#endif
+
+#define MAX_MMAP_REGIONS		16
+
+#define HIKEY_NS_IMAGE_OFFSET		(DDR_BASE + 0x35000000)
+
+/*
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ */
+#define CACHE_WRITEBACK_SHIFT		6
+#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
new file mode 100644
index 0000000..ec4bb5c
--- /dev/null
+++ b/plat/hisilicon/hikey/platform.mk
@@ -0,0 +1,77 @@
+#
+# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+CONSOLE_BASE			:=	PL011_UART3_BASE
+CRASH_CONSOLE_BASE		:=	PL011_UART3_BASE
+PLAT_PARTITION_MAX_ENTRIES	:=	12
+PLAT_PL061_MAX_GPIOS		:=	160
+COLD_BOOT_SINGLE_CPU		:=	1
+PROGRAMMABLE_RESET_ADDRESS	:=	1
+
+# Process flags
+$(eval $(call add_define,CONSOLE_BASE))
+$(eval $(call add_define,CRASH_CONSOLE_BASE))
+$(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
+$(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
+$(eval $(call FIP_ADD_IMG,SCP_BL2,--scp-fw))
+
+ENABLE_PLAT_COMPAT	:=	0
+
+USE_COHERENT_MEM	:=	1
+
+PLAT_INCLUDES		:=	-Iinclude/common/tbbr			\
+				-Iinclude/drivers/synopsys		\
+				-Iplat/hisilicon/hikey/include
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/arm/pl011/pl011_console.S	\
+				lib/aarch64/xlat_tables.c		\
+				plat/hisilicon/hikey/aarch64/hikey_common.c
+
+BL1_SOURCES		+=	bl1/tbbr/tbbr_img_desc.c		\
+				drivers/arm/pl061/pl061_gpio.c		\
+				drivers/arm/sp804/sp804_delay_timer.c	\
+				drivers/delay_timer/delay_timer.c	\
+				drivers/gpio/gpio.c			\
+				drivers/io/io_block.c			\
+				drivers/io/io_fip.c			\
+				drivers/io/io_storage.c			\
+				drivers/emmc/emmc.c			\
+				drivers/synopsys/emmc/dw_mmc.c		\
+				lib/cpus/aarch64/cortex_a53.S		\
+				plat/hisilicon/hikey/aarch64/hikey_helpers.S \
+				plat/hisilicon/hikey/hikey_bl1_setup.c	\
+				plat/hisilicon/hikey/hikey_io_storage.c
+
+BL2_SOURCES		+=	drivers/arm/sp804/sp804_delay_timer.c	\
+				drivers/delay_timer/delay_timer.c	\
+				drivers/io/io_block.c			\
+				drivers/io/io_fip.c			\
+				drivers/io/io_storage.c			\
+				drivers/emmc/emmc.c			\
+				drivers/synopsys/emmc/dw_mmc.c		\
+				plat/hisilicon/hikey/aarch64/hikey_helpers.S \
+				plat/hisilicon/hikey/hikey_bl2_setup.c	\
+				plat/hisilicon/hikey/hikey_ddr.c	\
+				plat/hisilicon/hikey/hikey_io_storage.c	\
+				plat/hisilicon/hikey/hisi_dvfs.c	\
+				plat/hisilicon/hikey/hisi_mcu.c
+
+HIKEY_GIC_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
+				drivers/arm/gic/v2/gicv2_main.c		\
+				drivers/arm/gic/v2/gicv2_helpers.c	\
+				plat/common/plat_gicv2.c
+
+BL31_SOURCES		+=	drivers/arm/cci/cci.c			\
+				lib/cpus/aarch64/cortex_a53.S		\
+				plat/common/aarch64/plat_psci_common.c	\
+				plat/hisilicon/hikey/aarch64/hikey_helpers.S \
+				plat/hisilicon/hikey/hikey_bl31_setup.c	\
+				plat/hisilicon/hikey/hikey_pm.c		\
+				plat/hisilicon/hikey/hikey_topology.c	\
+				plat/hisilicon/hikey/hisi_ipc.c		\
+				plat/hisilicon/hikey/hisi_pwrc.c	\
+				plat/hisilicon/hikey/hisi_pwrc_sram.S	\
+				${HIKEY_GIC_SOURCES}
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 989a8e4..efd1f25 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -27,6 +27,13 @@
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 
+ifeq (${USE_TBBR_DEFS},1)
+# In this case, cert_tool is platform-independent
+PLAT_MSG		:=	TBBR Generic
+PLAT_INCLUDE		:=	../../include/tools_share
+else
+PLAT_MSG		:=	${PLAT}
+
 PLATFORM_ROOT		:=	../../plat/
 include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
 
@@ -35,6 +42,7 @@
 ifeq ($(PLAT_INCLUDE),)
   $(error "Error: Invalid platform '${PLAT}' has no include directory.")
 endif
+endif
 
 ifeq (${DEBUG},1)
   CFLAGS += -g -O0 -DDEBUG -DLOG_LEVEL=40
@@ -47,13 +55,16 @@
 	Q :=
 endif
 
+$(eval $(call add_define,USE_TBBR_DEFS))
+CFLAGS += ${DEFINES}
+
 # Make soft links and include from local directory otherwise wrong headers
 # could get pulled in from firmware tree.
 INC_DIR := -I ./include -I ${PLAT_INCLUDE} -I ${OPENSSL_DIR}/include
 LIB_DIR := -L ${OPENSSL_DIR}/lib
 LIB := -lssl -lcrypto
 
-CC := gcc
+HOSTCC ?= gcc
 
 .PHONY: all clean realclean
 
@@ -62,13 +73,13 @@
 ${BINARY}: ${OBJECTS} Makefile
 	@echo "  LD      $@"
 	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
-                const char platform_msg[] = "${PLAT}";' | \
+                const char platform_msg[] = "${PLAT_MSG}";' | \
                 ${CC} -c ${CFLAGS} -xc - -o src/build_msg.o
-	${Q}${CC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+	${Q}${HOSTCC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
 
 %.o: %.c
 	@echo "  CC      $<"
-	${Q}${CC} -c ${CFLAGS} ${INC_DIR} $< -o $@
+	${Q}${HOSTCC} -c ${CFLAGS} ${INC_DIR} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c
index 62ff255..80ccfe9 100644
--- a/tools/cert_create/src/cert.c
+++ b/tools/cert_create/src/cert.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,11 +14,16 @@
 #include <openssl/sha.h>
 #include <openssl/x509v3.h>
 
+#if USE_TBBR_DEFS
+#include <tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+
 #include "cert.h"
 #include "cmd_opt.h"
 #include "debug.h"
 #include "key.h"
-#include "platform_oid.h"
 #include "sha.h"
 
 #define SERIAL_RAND_BITS	64
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index a118fbb..c1bde5d 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,11 +13,16 @@
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 
+#if USE_TBBR_DEFS
+#include <tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+
 #include "cert.h"
 #include "cmd_opt.h"
 #include "debug.h"
 #include "key.h"
-#include "platform_oid.h"
 #include "sha.h"
 
 #define MAX_FILENAME_LEN		1024
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index e0f331c..9923637 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,12 +18,17 @@
 #include <openssl/sha.h>
 #include <openssl/x509v3.h>
 
+#if USE_TBBR_DEFS
+#include <tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+
 #include "cert.h"
 #include "cmd_opt.h"
 #include "debug.h"
 #include "ext.h"
 #include "key.h"
-#include "platform_oid.h"
 #include "sha.h"
 #include "tbbr/tbb_ext.h"
 #include "tbbr/tbb_cert.h"
diff --git a/tools/cert_create/src/tbbr/tbb_ext.c b/tools/cert_create/src/tbbr/tbb_ext.c
index 11d779b..d9a8ea2 100644
--- a/tools/cert_create/src/tbbr/tbb_ext.c
+++ b/tools/cert_create/src/tbbr/tbb_ext.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,8 +8,14 @@
 #include <string.h>
 #include <openssl/err.h>
 #include <openssl/x509v3.h>
+
+#if USE_TBBR_DEFS
+#include <tbbr_oid.h>
+#else
+#include <platform_oid.h>
+#endif
+
 #include "ext.h"
-#include "platform_oid.h"
 #include "tbbr/tbb_ext.h"
 #include "tbbr/tbb_key.h"
 
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 0a46ad7..ee674b7 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -11,7 +11,6 @@
 PROJECT := fiptool${BIN_EXT}
 OBJECTS := fiptool.o tbbr_config.o
 V := 0
-COPIED_H_FILES := uuid.h firmware_image_package.h
 
 override CPPFLAGS += -D_GNU_SOURCE -D_XOPEN_SOURCE=700
 CFLAGS := -Wall -Werror -pedantic -std=c99
@@ -28,10 +27,9 @@
   Q :=
 endif
 
-# Only include from local directory (see comment below).
-INCLUDE_PATHS := -I.
+INCLUDE_PATHS := -I. -I../../include/tools_share
 
-CC := gcc
+HOSTCC ?= gcc
 
 .PHONY: all clean distclean
 
@@ -39,7 +37,7 @@
 
 ${PROJECT}: ${OBJECTS} Makefile
 	@echo "  LD      $@"
-	${Q}${CC} ${OBJECTS} -o $@ ${LDLIBS}
+	${Q}${HOSTCC} ${OBJECTS} -o $@ ${LDLIBS}
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
@@ -48,24 +46,9 @@
 	${Q}mkdir -p ../fip_create
 	${Q}install -m 755 fip_create.sh ../fip_create/fip_create
 
-%.o: %.c %.h ${COPIED_H_FILES} Makefile
+%.o: %.c %.h Makefile
 	@echo "  CC      $<"
-	${Q}${CC} -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
-
-#
-# Copy required library headers to a local directory so they can be included
-# by this project without adding the library directories to the system include
-# path. This avoids conflicts with definitions in the compiler standard
-# include path.
-#
-uuid.h : ../../include/lib/stdlib/sys/uuid.h
-	$(call SHELL_COPY,$<,$@)
-
-firmware_image_package.h : ../../include/common/firmware_image_package.h
-	$(call SHELL_COPY,$<,$@)
+	${Q}${HOSTCC} -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS} fip_create)
-
-distclean: clean
-	$(call SHELL_DELETE_ALL, ${COPIED_H_FILES})
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 7bfd272..4d80f2f 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,8 +20,9 @@
 
 #include <openssl/sha.h>
 
+#include <firmware_image_package.h>
+
 #include "fiptool.h"
-#include "firmware_image_package.h"
 #include "tbbr_config.h"
 
 #define OPT_TOC_ENTRY 0
diff --git a/tools/fiptool/fiptool.h b/tools/fiptool/fiptool.h
index 81453e0..4b5cdd9 100644
--- a/tools/fiptool/fiptool.h
+++ b/tools/fiptool/fiptool.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,8 +10,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "firmware_image_package.h"
-#include "uuid.h"
+#include <firmware_image_package.h>
+#include <uuid.h>
 
 #define NELEM(x) (sizeof (x) / sizeof *(x))
 
diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c
index 4662083..7c6c24b 100644
--- a/tools/fiptool/tbbr_config.c
+++ b/tools/fiptool/tbbr_config.c
@@ -1,12 +1,13 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <stddef.h>
 
-#include "firmware_image_package.h"
+#include <firmware_image_package.h>
+
 #include "tbbr_config.h"
 
 /* The images used depends on the platform. */
diff --git a/tools/fiptool/tbbr_config.h b/tools/fiptool/tbbr_config.h
index a5155c8..bad757d 100644
--- a/tools/fiptool/tbbr_config.h
+++ b/tools/fiptool/tbbr_config.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,7 @@
 
 #include <stdint.h>
 
-#include "uuid.h"
+#include <uuid.h>
 
 /* TODO: Update this number as required */
 #define TOC_HEADER_SERIAL_NUMBER 0x12345678