diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d871a45..9a0efe4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -882,6 +882,7 @@ config ARCH_ROCKCHIP
 	select DM
 	select SPL_DM if SPL
 	select SYS_MALLOC_F
+	select SPL_SEPARATE_BSS if SPL
 	select SPL_SYS_MALLOC_SIMPLE if SPL
 	select DM_GPIO
 	select DM_I2C
diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi
index 22277ff..c57fa5bc 100644
--- a/arch/arm/dts/rk3399.dtsi
+++ b/arch/arm/dts/rk3399.dtsi
@@ -183,6 +183,7 @@
 	};
 
 	sdhci: sdhci@fe330000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1";
 		reg = <0x0 0xfe330000 0x0 0x10000>;
 		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
@@ -416,6 +417,7 @@
 	};
 
 	pmugrf: syscon@ff320000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pmugrf", "syscon", "simple-mfd";
 		reg = <0x0 0xff320000 0x0 0x1000>;
 		#address-cells = <1>;
@@ -497,7 +499,26 @@
 		status = "disabled";
 	};
 
+	dfi: dfi@ff630000 {
+		reg = <0x00 0xff630000 0x00 0x4000>;
+		compatible = "rockchip,rk3399-dfi";
+		rockchip,pmu = <&pmugrf>;
+		clocks = <&cru PCLK_DDR_MON>;
+		clock-names = "pclk_ddr_mon";
+		status = "disabled";
+	};
+
+	dmc: dmc {
+		u-boot,dm-pre-reloc;
+		compatible = "rockchip,rk3399-dmc";
+		devfreq-events = <&dfi>;
+		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru SCLK_DDRCLK>;
+		clock-names = "dmc_clk";
+	};
+
 	pmucru: pmu-clock-controller@ff750000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pmucru";
 		reg = <0x0 0xff750000 0x0 0x1000>;
 		#clock-cells = <1>;
@@ -507,6 +528,7 @@
 	};
 
 	cru: clock-controller@ff760000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-cru";
 		reg = <0x0 0xff760000 0x0 0x1000>;
 		#clock-cells = <1>;
@@ -530,6 +552,7 @@
 	};
 
 	grf: syscon@ff770000 {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
 		reg = <0x0 0xff770000 0x0 0x10000>;
 		#address-cells = <1>;
@@ -607,6 +630,7 @@
 	};
 
 	pinctrl: pinctrl {
+		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pinctrl";
 		rockchip,grf = <&grf>;
 		rockchip,pmu = <&pmugrf>;
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
index d3d1467..62d8496 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
@@ -318,4 +318,122 @@ struct rk3399_pmusgrf_regs {
 };
 check_member(rk3399_pmusgrf_regs, slv_secure_con4, 0xe3d4);
 
+enum {
+	/* GRF_GPIO2B_IOMUX */
+	GRF_GPIO2B1_SEL_SHIFT	= 0,
+	GRF_GPIO2B1_SEL_MASK	= 3 << GRF_GPIO2B1_SEL_SHIFT,
+	GRF_SPI2TPM_RXD		= 1,
+	GRF_GPIO2B2_SEL_SHIFT	= 2,
+	GRF_GPIO2B2_SEL_MASK	= 3 << GRF_GPIO2B2_SEL_SHIFT,
+	GRF_SPI2TPM_TXD		= 1,
+	GRF_GPIO2B3_SEL_SHIFT	= 6,
+	GRF_GPIO2B3_SEL_MASK	= 3 << GRF_GPIO2B3_SEL_SHIFT,
+	GRF_SPI2TPM_CLK		= 1,
+	GRF_GPIO2B4_SEL_SHIFT	= 8,
+	GRF_GPIO2B4_SEL_MASK	= 3 << GRF_GPIO2B4_SEL_SHIFT,
+	GRF_SPI2TPM_CSN0	= 1,
+
+	/* GRF_GPIO3A_IOMUX */
+	GRF_GPIO3A4_SEL_SHIFT	= 8,
+	GRF_GPIO3A4_SEL_MASK	= 3 << GRF_GPIO3A4_SEL_SHIFT,
+	GRF_SPI0NORCODEC_RXD	= 2,
+	GRF_GPIO3A5_SEL_SHIFT	= 10,
+	GRF_GPIO3A5_SEL_MASK	= 3 << GRF_GPIO3A5_SEL_SHIFT,
+	GRF_SPI0NORCODEC_TXD	= 2,
+	GRF_GPIO3A6_SEL_SHIFT	= 12,
+	GRF_GPIO3A6_SEL_MASK	= 3 << GRF_GPIO3A6_SEL_SHIFT,
+	GRF_SPI0NORCODEC_CLK	= 2,
+	GRF_GPIO3A7_SEL_SHIFT	= 14,
+	GRF_GPIO3A7_SEL_MASK	= 3 << GRF_GPIO3A7_SEL_SHIFT,
+	GRF_SPI0NORCODEC_CSN0	= 2,
+
+	/* GRF_GPIO3B_IOMUX */
+	GRF_GPIO3B0_SEL_SHIFT	= 0,
+	GRF_GPIO3B0_SEL_MASK	= 3 << GRF_GPIO3B0_SEL_SHIFT,
+	GRF_SPI0NORCODEC_CSN1	= 2,
+
+	/* GRF_GPIO4B_IOMUX */
+	GRF_GPIO4B0_SEL_SHIFT	= 0,
+	GRF_GPIO4B0_SEL_MASK	= 3 << GRF_GPIO4B0_SEL_SHIFT,
+	GRF_SDMMC_DATA0		= 1,
+	GRF_UART2DBGA_SIN	= 2,
+	GRF_GPIO4B1_SEL_SHIFT	= 2,
+	GRF_GPIO4B1_SEL_MASK	= 3 << GRF_GPIO4B1_SEL_SHIFT,
+	GRF_SDMMC_DATA1		= 1,
+	GRF_UART2DBGA_SOUT	= 2,
+	GRF_GPIO4B2_SEL_SHIFT	= 4,
+	GRF_GPIO4B2_SEL_MASK	= 3 << GRF_GPIO4B2_SEL_SHIFT,
+	GRF_SDMMC_DATA2		= 1,
+	GRF_GPIO4B3_SEL_SHIFT	= 6,
+	GRF_GPIO4B3_SEL_MASK	= 3 << GRF_GPIO4B3_SEL_SHIFT,
+	GRF_SDMMC_DATA3		= 1,
+	GRF_GPIO4B4_SEL_SHIFT	= 8,
+	GRF_GPIO4B4_SEL_MASK    = 3 << GRF_GPIO4B4_SEL_SHIFT,
+	GRF_SDMMC_CLKOUT        = 1,
+	GRF_GPIO4B5_SEL_SHIFT   = 10,
+	GRF_GPIO4B5_SEL_MASK    = 3 << GRF_GPIO4B5_SEL_SHIFT,
+	GRF_SDMMC_CMD           = 1,
+
+	/*  GRF_GPIO4C_IOMUX */
+	GRF_GPIO4C0_SEL_SHIFT   = 0,
+	GRF_GPIO4C0_SEL_MASK    = 3 << GRF_GPIO4C0_SEL_SHIFT,
+	GRF_UART2DGBB_SIN       = 2,
+	GRF_GPIO4C1_SEL_SHIFT   = 2,
+	GRF_GPIO4C1_SEL_MASK    = 3 << GRF_GPIO4C1_SEL_SHIFT,
+	GRF_UART2DGBB_SOUT      = 2,
+	GRF_GPIO4C2_SEL_SHIFT   = 4,
+	GRF_GPIO4C2_SEL_MASK    = 3 << GRF_GPIO4C2_SEL_SHIFT,
+	GRF_PWM_0               = 1,
+	GRF_GPIO4C3_SEL_SHIFT   = 6,
+	GRF_GPIO4C3_SEL_MASK    = 3 << GRF_GPIO4C3_SEL_SHIFT,
+	GRF_UART2DGBC_SIN       = 1,
+	GRF_GPIO4C4_SEL_SHIFT   = 8,
+	GRF_GPIO4C4_SEL_MASK    = 3 << GRF_GPIO4C4_SEL_SHIFT,
+	GRF_UART2DBGC_SOUT      = 1,
+	GRF_GPIO4C6_SEL_SHIFT   = 12,
+	GRF_GPIO4C6_SEL_MASK    = 3 << GRF_GPIO4C6_SEL_SHIFT,
+	GRF_PWM_1               = 1,
+
+	/* GRF_SOC_CON7 */
+	GRF_UART_DBG_SEL_SHIFT	= 10,
+	GRF_UART_DBG_SEL_MASK	= 3 << GRF_UART_DBG_SEL_SHIFT,
+	GRF_UART_DBG_SEL_C	= 2,
+
+	/*  PMUGRF_GPIO0A_IOMUX */
+	PMUGRF_GPIO0A6_SEL_SHIFT        = 12,
+	PMUGRF_GPIO0A6_SEL_MASK = 3 << PMUGRF_GPIO0A6_SEL_SHIFT,
+	PMUGRF_PWM_3A           = 1,
+
+	/*  PMUGRF_GPIO1A_IOMUX */
+	PMUGRF_GPIO1A7_SEL_SHIFT        = 14,
+	PMUGRF_GPIO1A7_SEL_MASK = 3 << PMUGRF_GPIO1A7_SEL_SHIFT,
+	PMUGRF_SPI1EC_RXD       = 2,
+
+	/*  PMUGRF_GPIO1B_IOMUX */
+	PMUGRF_GPIO1B0_SEL_SHIFT        = 0,
+	PMUGRF_GPIO1B0_SEL_MASK = 3 << PMUGRF_GPIO1B0_SEL_SHIFT,
+	PMUGRF_SPI1EC_TXD       = 2,
+	PMUGRF_GPIO1B1_SEL_SHIFT        = 2,
+	PMUGRF_GPIO1B1_SEL_MASK = 3 << PMUGRF_GPIO1B1_SEL_SHIFT,
+	PMUGRF_SPI1EC_CLK       = 2,
+	PMUGRF_GPIO1B2_SEL_SHIFT        = 4,
+	PMUGRF_GPIO1B2_SEL_MASK = 3 << PMUGRF_GPIO1B2_SEL_SHIFT,
+	PMUGRF_SPI1EC_CSN0      = 2,
+	PMUGRF_GPIO1B6_SEL_SHIFT        = 12,
+	PMUGRF_GPIO1B6_SEL_MASK = 3 << PMUGRF_GPIO1B6_SEL_SHIFT,
+	PMUGRF_PWM_3B           = 1,
+	PMUGRF_GPIO1B7_SEL_SHIFT        = 14,
+	PMUGRF_GPIO1B7_SEL_MASK = 3 << PMUGRF_GPIO1B7_SEL_SHIFT,
+	PMUGRF_I2C0PMU_SDA      = 2,
+
+	/*  PMUGRF_GPIO1C_IOMUX */
+	PMUGRF_GPIO1C0_SEL_SHIFT        = 0,
+	PMUGRF_GPIO1C0_SEL_MASK = 3 << PMUGRF_GPIO1C0_SEL_SHIFT,
+	PMUGRF_I2C0PMU_SCL      = 2,
+	PMUGRF_GPIO1C3_SEL_SHIFT        = 6,
+	PMUGRF_GPIO1C3_SEL_MASK = 3 << PMUGRF_GPIO1C3_SEL_SHIFT,
+	PMUGRF_PWM_2            = 1,
+
+};
+
 #endif	/* __SOC_ROCKCHIP_RK3399_GRF_H__ */
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 5c4a4c2..cd8fef8 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -26,6 +26,8 @@ config ROCKCHIP_RK3288
 config ROCKCHIP_RK3399
 	bool "Support Rockchip RK3399"
 	select ARM64
+	select SUPPORT_SPL
+	select SPL
 	help
 	  The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
 	  and quad-core Cortex-A53.
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 6e79fed..b58c02d 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -7,6 +7,7 @@
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
 obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
+obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board-spl.o
 obj-$(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) += save_boot_param.o
 else
 obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c
new file mode 100644
index 0000000..504c8f9
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3399-board-spl.c
@@ -0,0 +1,157 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <led.h>
+#include <malloc.h>
+#include <ram.h>
+#include <spl.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/sdram.h>
+#include <asm/arch/timer.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <dm/test.h>
+#include <dm/util.h>
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_MMC1;
+}
+
+u32 spl_boot_mode(const u32 boot_device)
+{
+	return MMCSD_MODE_RAW;
+}
+
+#define TIMER_CHN10_BASE	0xff8680a0
+#define TIMER_END_COUNT_L	0x00
+#define TIMER_END_COUNT_H	0x04
+#define TIMER_INIT_COUNT_L	0x10
+#define TIMER_INIT_COUNT_H	0x14
+#define TIMER_CONTROL_REG	0x1c
+
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	(0 << 1)
+#define	TIMER_RMODE	(1 << 1)
+
+void secure_timer_init(void)
+{
+	writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_L);
+	writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_H);
+	writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_L);
+	writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_H);
+	writel(TIMER_EN | TIMER_FMODE, TIMER_CHN10_BASE + TIMER_CONTROL_REG);
+}
+
+#define GRF_EMMCCORE_CON11 0xff77f02c
+void board_init_f(ulong dummy)
+{
+	struct udevice *pinctrl;
+	struct udevice *dev;
+	int ret;
+
+	/* Example code showing how to enable the debug UART on RK3288 */
+#include <asm/arch/grf_rk3399.h>
+	/* Enable early UART2 channel C on the RK3399 */
+#define GRF_BASE	0xff770000
+	struct rk3399_grf_regs * const grf = (void *)GRF_BASE;
+
+	rk_clrsetreg(&grf->gpio4c_iomux,
+		     GRF_GPIO4C3_SEL_MASK,
+		     GRF_UART2DGBC_SIN << GRF_GPIO4C3_SEL_SHIFT);
+	rk_clrsetreg(&grf->gpio4c_iomux,
+		     GRF_GPIO4C4_SEL_MASK,
+		     GRF_UART2DBGC_SOUT << GRF_GPIO4C4_SEL_SHIFT);
+	/* Set channel C as UART2 input */
+	rk_clrsetreg(&grf->soc_con7,
+		     GRF_UART_DBG_SEL_MASK,
+		     GRF_UART_DBG_SEL_C << GRF_UART_DBG_SEL_SHIFT);
+#ifdef EARLY_UART
+	/*
+	 * Debug UART can be used from here if required:
+	 *
+	 * debug_uart_init();
+	 * printch('a');
+	 * printhex8(0x1234);
+	 * printascii("string");
+	 */
+	debug_uart_init();
+	printascii("U-Boot SPL board init");
+#endif
+	/*  Emmc clock generator: disable the clock multipilier */
+	rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff);
+
+	ret = spl_init();
+	if (ret) {
+		debug("spl_init() failed: %d\n", ret);
+		hang();
+	}
+
+	secure_timer_init();
+
+	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+	if (ret) {
+		debug("Pinctrl init failed: %d\n", ret);
+		return;
+	}
+
+	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+	if (ret) {
+		debug("DRAM init failed: %d\n", ret);
+		return;
+	}
+}
+
+void spl_board_init(void)
+{
+	struct udevice *pinctrl;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+	if (ret) {
+		debug("%s: Cannot find pinctrl device\n", __func__);
+		goto err;
+	}
+
+	/* Enable debug UART */
+	ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG);
+	if (ret) {
+		debug("%s: Failed to set up console UART\n", __func__);
+		goto err;
+	}
+
+	preloader_console_init();
+#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
+	back_to_bootrom();
+#endif
+	return;
+err:
+	printf("spl_board_init: Error %d\n", ret);
+
+	/* No way to report error here */
+	hang();
+}
+
+#ifdef CONFIG_SPL_LOAD_FIT
+int board_fit_config_name_match(const char *name)
+{
+	/* Just empty function now - can't decide what to choose */
+	debug("%s: %s\n", __func__, name);
+
+	return 0;
+}
+#endif
diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig
index 40a8295..78c2846 100644
--- a/configs/evb-rk3399_defconfig
+++ b/configs/evb-rk3399_defconfig
@@ -3,7 +3,16 @@ CONFIG_ARCH_ROCKCHIP=y
 CONFIG_ROCKCHIP_RK3399=y
 CONFIG_DEFAULT_DEVICE_TREE="rk3399-evb"
 CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_SPL_OF_LIBFDT=y
+CONFIG_SPL_ATF_SUPPORT=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
+CONFIG_SPL_ATF_TEXT_BASE=0x00010000
 # CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_ADDR=0x80000
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x4000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
@@ -16,18 +25,26 @@ CONFIG_CMD_EXT2=y
 CONFIG_CMD_EXT4=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_PXE=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
 CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
 CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
 CONFIG_CLK=y
+CONFIG_SPL_CLK=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_ROCKCHIP_DWMMC=y
 CONFIG_ROCKCHIP_SDHCI=y
 CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
 CONFIG_ROCKCHIP_RK3399_PINCTRL=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_RAM=y
+CONFIG_SPL_RAM=y
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_BASE=0xFF1A0000
 CONFIG_DEBUG_UART_CLOCK=24000000
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 2e87e4b..d259a1c 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -709,6 +709,44 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
 	return rk3399_mmc_get_clk(cru, clk_id);
 }
 
+#define PMUSGRF_DDR_RGN_CON16 0xff330040
+static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
+				ulong set_rate)
+{
+	struct pll_div dpll_cfg;
+
+	/*  IC ECO bug, need to set this register */
+	writel(0xc000c000, PMUSGRF_DDR_RGN_CON16);
+
+	/*  clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */
+	switch (set_rate) {
+	case 200*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
+		break;
+	case 300*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
+		break;
+	case 666*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
+		break;
+	case 800*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
+		break;
+	case 933*MHz:
+		dpll_cfg = (struct pll_div)
+		{.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
+		break;
+	default:
+		error("Unsupported SDRAM frequency!,%ld\n", set_rate);
+	}
+	rkclk_set_pll(&cru->dpll_con[0], &dpll_cfg);
+
+	return set_rate;
+}
 static ulong rk3399_clk_get_rate(struct clk *clk)
 {
 	struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
@@ -763,6 +801,9 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
 	case DCLK_VOP1:
 		ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
 		break;
+	case SCLK_DDRCLK:
+		ret = rk3399_ddr_set_clk(priv->cru, rate);
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -939,7 +980,6 @@ static void pmuclk_init(struct rk3399_pmucru *pmucru)
 
 	/*  configure pmu pclk */
 	pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1;
-	assert((pclk_div + 1) * PMU_PCLK_HZ == PPLL_HZ && pclk_div < 0x1f);
 	rk_clrsetreg(&pmucru->pmucru_clksel[0],
 		     PMU_PCLK_DIV_CON_MASK,
 		     pclk_div << PMU_PCLK_DIV_CON_SHIFT);
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3399.c b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
index 17ea165..2f8aa64 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3399.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3399.c
@@ -22,112 +22,6 @@ struct rk3399_pinctrl_priv {
 	struct rk3399_pmugrf_regs *pmugrf;
 };
 
-enum {
-	/* GRF_GPIO2B_IOMUX */
-	GRF_GPIO2B1_SEL_SHIFT	= 0,
-	GRF_GPIO2B1_SEL_MASK	= 3 << GRF_GPIO2B1_SEL_SHIFT,
-	GRF_SPI2TPM_RXD		= 1,
-	GRF_GPIO2B2_SEL_SHIFT	= 2,
-	GRF_GPIO2B2_SEL_MASK	= 3 << GRF_GPIO2B2_SEL_SHIFT,
-	GRF_SPI2TPM_TXD		= 1,
-	GRF_GPIO2B3_SEL_SHIFT	= 6,
-	GRF_GPIO2B3_SEL_MASK	= 3 << GRF_GPIO2B3_SEL_SHIFT,
-	GRF_SPI2TPM_CLK		= 1,
-	GRF_GPIO2B4_SEL_SHIFT	= 8,
-	GRF_GPIO2B4_SEL_MASK	= 3 << GRF_GPIO2B4_SEL_SHIFT,
-	GRF_SPI2TPM_CSN0	= 1,
-
-	/* GRF_GPIO3A_IOMUX */
-	GRF_GPIO3A4_SEL_SHIFT	= 8,
-	GRF_GPIO3A4_SEL_MASK	= 3 << GRF_GPIO3A4_SEL_SHIFT,
-	GRF_SPI0NORCODEC_RXD	= 2,
-	GRF_GPIO3A5_SEL_SHIFT	= 10,
-	GRF_GPIO3A5_SEL_MASK	= 3 << GRF_GPIO3A5_SEL_SHIFT,
-	GRF_SPI0NORCODEC_TXD	= 2,
-	GRF_GPIO3A6_SEL_SHIFT	= 12,
-	GRF_GPIO3A6_SEL_MASK	= 3 << GRF_GPIO3A6_SEL_SHIFT,
-	GRF_SPI0NORCODEC_CLK	= 2,
-	GRF_GPIO3A7_SEL_SHIFT	= 14,
-	GRF_GPIO3A7_SEL_MASK	= 3 << GRF_GPIO3A7_SEL_SHIFT,
-	GRF_SPI0NORCODEC_CSN0	= 2,
-
-	/* GRF_GPIO3B_IOMUX */
-	GRF_GPIO3B0_SEL_SHIFT	= 0,
-	GRF_GPIO3B0_SEL_MASK	= 3 << GRF_GPIO3B0_SEL_SHIFT,
-	GRF_SPI0NORCODEC_CSN1	= 2,
-
-	/* GRF_GPIO4B_IOMUX */
-	GRF_GPIO4B0_SEL_SHIFT	= 0,
-	GRF_GPIO4B0_SEL_MASK	= 3 << GRF_GPIO4B0_SEL_SHIFT,
-	GRF_SDMMC_DATA0		= 1,
-	GRF_UART2DBGA_SIN	= 2,
-	GRF_GPIO4B1_SEL_SHIFT	= 2,
-	GRF_GPIO4B1_SEL_MASK	= 3 << GRF_GPIO4B1_SEL_SHIFT,
-	GRF_SDMMC_DATA1		= 1,
-	GRF_UART2DBGA_SOUT	= 2,
-	GRF_GPIO4B2_SEL_SHIFT	= 4,
-	GRF_GPIO4B2_SEL_MASK	= 3 << GRF_GPIO4B2_SEL_SHIFT,
-	GRF_SDMMC_DATA2		= 1,
-	GRF_GPIO4B3_SEL_SHIFT	= 6,
-	GRF_GPIO4B3_SEL_MASK	= 3 << GRF_GPIO4B3_SEL_SHIFT,
-	GRF_SDMMC_DATA3		= 1,
-	GRF_GPIO4B4_SEL_SHIFT	= 8,
-	GRF_GPIO4B4_SEL_MASK	= 3 << GRF_GPIO4B4_SEL_SHIFT,
-	GRF_SDMMC_CLKOUT	= 1,
-	GRF_GPIO4B5_SEL_SHIFT	= 10,
-	GRF_GPIO4B5_SEL_MASK	= 3 << GRF_GPIO4B5_SEL_SHIFT,
-	GRF_SDMMC_CMD		= 1,
-
-	/* GRF_GPIO4C_IOMUX */
-	GRF_GPIO4C2_SEL_SHIFT	= 4,
-	GRF_GPIO4C2_SEL_MASK	= 3 << GRF_GPIO4C2_SEL_SHIFT,
-	GRF_PWM_0		= 1,
-	GRF_GPIO4C3_SEL_SHIFT	= 6,
-	GRF_GPIO4C3_SEL_MASK	= 3 << GRF_GPIO4C3_SEL_SHIFT,
-	GRF_UART2DGBC_SIN	= 1,
-	GRF_GPIO4C4_SEL_SHIFT	= 8,
-	GRF_GPIO4C4_SEL_MASK	= 3 << GRF_GPIO4C4_SEL_SHIFT,
-	GRF_UART2DBGC_SOUT	= 1,
-	GRF_GPIO4C6_SEL_SHIFT	= 12,
-	GRF_GPIO4C6_SEL_MASK	= 3 << GRF_GPIO4C6_SEL_SHIFT,
-	GRF_PWM_1		= 1,
-
-	/* PMUGRF_GPIO0A_IOMUX */
-	PMUGRF_GPIO0A6_SEL_SHIFT	= 12,
-	PMUGRF_GPIO0A6_SEL_MASK	= 3 << PMUGRF_GPIO0A6_SEL_SHIFT,
-	PMUGRF_PWM_3A		= 1,
-
-	/* PMUGRF_GPIO1A_IOMUX */
-	PMUGRF_GPIO1A7_SEL_SHIFT	= 14,
-	PMUGRF_GPIO1A7_SEL_MASK	= 3 << PMUGRF_GPIO1A7_SEL_SHIFT,
-	PMUGRF_SPI1EC_RXD	= 2,
-
-	/* PMUGRF_GPIO1B_IOMUX */
-	PMUGRF_GPIO1B0_SEL_SHIFT	= 0,
-	PMUGRF_GPIO1B0_SEL_MASK = 3 << PMUGRF_GPIO1B0_SEL_SHIFT,
-	PMUGRF_SPI1EC_TXD	= 2,
-	PMUGRF_GPIO1B1_SEL_SHIFT	= 2,
-	PMUGRF_GPIO1B1_SEL_MASK = 3 << PMUGRF_GPIO1B1_SEL_SHIFT,
-	PMUGRF_SPI1EC_CLK	= 2,
-	PMUGRF_GPIO1B2_SEL_SHIFT	= 4,
-	PMUGRF_GPIO1B2_SEL_MASK = 3 << PMUGRF_GPIO1B2_SEL_SHIFT,
-	PMUGRF_SPI1EC_CSN0	= 2,
-	PMUGRF_GPIO1B6_SEL_SHIFT	= 12,
-	PMUGRF_GPIO1B6_SEL_MASK	= 3 << PMUGRF_GPIO1B6_SEL_SHIFT,
-	PMUGRF_PWM_3B		= 1,
-	PMUGRF_GPIO1B7_SEL_SHIFT	= 14,
-	PMUGRF_GPIO1B7_SEL_MASK	= 3 << PMUGRF_GPIO1B7_SEL_SHIFT,
-	PMUGRF_I2C0PMU_SDA	= 2,
-
-	/* PMUGRF_GPIO1C_IOMUX */
-	PMUGRF_GPIO1C0_SEL_SHIFT	= 0,
-	PMUGRF_GPIO1C0_SEL_MASK	= 3 << PMUGRF_GPIO1C0_SEL_SHIFT,
-	PMUGRF_I2C0PMU_SCL	= 2,
-	PMUGRF_GPIO1C3_SEL_SHIFT	= 6,
-	PMUGRF_GPIO1C3_SEL_MASK	= 3 << PMUGRF_GPIO1C3_SEL_SHIFT,
-	PMUGRF_PWM_2		= 1,
-
-};
 static void pinctrl_rk3399_pwm_config(struct rk3399_grf_regs *grf,
 		struct rk3399_pmugrf_regs *pmugrf, int pwm_id)
 {
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index aa646c6..3699a9d 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -17,12 +17,23 @@
 #define CONFIG_SYS_MALLOC_LEN		(32 << 20)
 #define CONFIG_SYS_CBSIZE		1024
 #define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
 
 #define CONFIG_SYS_NS16550_MEM32
 
 #define CONFIG_SYS_TEXT_BASE		0x00200000
 #define CONFIG_SYS_INIT_SP_ADDR		0x00300000
 #define CONFIG_SYS_LOAD_ADDR		0x00800800
+#define CONFIG_SPL_STACK		0xff8effff
+#define CONFIG_SPL_TEXT_BASE		0xff8c2008
+#define CONFIG_SPL_MAX_SIZE		0x30000
+/*  BSS setup */
+#define CONFIG_SPL_BSS_START_ADDR       0xff8e0000
+#define CONFIG_SPL_BSS_MAX_SIZE         0x10000
 
 #define CONFIG_SYS_BOOTM_LEN	(64 << 20)	/* 64M */
 
diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
index 0a86aec..d4bdcc6 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -122,6 +122,10 @@
 #define SCLK_DPHY_RX0_CFG		165
 #define SCLK_RMII_SRC			166
 #define SCLK_PCIEPHY_REF100M		167
+#define SCLK_USBPHY0_480M_SRC		168
+#define SCLK_USBPHY1_480M_SRC		169
+#define SCLK_DDRCLK			170
+#define SCLK_TESTOUT2			171
 
 #define DCLK_VOP0			180
 #define DCLK_VOP1			181
@@ -589,13 +593,13 @@
 #define SRST_P_SPI0			214
 #define SRST_P_SPI1			215
 #define SRST_P_SPI2			216
-#define SRST_P_SPI3			217
-#define SRST_P_SPI4			218
+#define SRST_P_SPI4			217
+#define SRST_P_SPI5			218
 #define SRST_SPI0			219
 #define SRST_SPI1			220
 #define SRST_SPI2			221
-#define SRST_SPI3			222
-#define SRST_SPI4			223
+#define SRST_SPI4			222
+#define SRST_SPI5			223
 
 /* cru_softrst_con14 */
 #define SRST_I2S0_8CH			224
@@ -717,8 +721,8 @@
 #define SRST_H_CM0S_NOC			3
 #define SRST_DBG_CM0S			4
 #define SRST_PO_CM0S			5
-#define SRST_P_SPI6			6
-#define SRST_SPI6			7
+#define SRST_P_SPI3			6
+#define SRST_SPI3			7
 #define SRST_P_TIMER_0_1		8
 #define SRST_P_TIMER_0			9
 #define SRST_P_TIMER_1			10
