Merge branch 'master' of git://git.denx.de/u-boot-usb
diff --git a/arch/arm/dts/rk3288-evb.dts b/arch/arm/dts/rk3288-evb.dts
index 3e1ee58..3f03e13 100644
--- a/arch/arm/dts/rk3288-evb.dts
+++ b/arch/arm/dts/rk3288-evb.dts
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
 		0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
 		0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
@@ -25,8 +24,6 @@
 		0x8 0x1f4>;
 	rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
 		0x0 0xc3 0x6 0x2>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe 0xff>;
 	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
 };
 
diff --git a/arch/arm/dts/rk3288-fennec.dts b/arch/arm/dts/rk3288-fennec.dts
index 36e9f3d..66ddf8d 100644
--- a/arch/arm/dts/rk3288-fennec.dts
+++ b/arch/arm/dts/rk3288-fennec.dts
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
 		0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
 		0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
@@ -25,8 +24,6 @@
 		0x8 0x1f4>;
 	rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
 		0x0 0xc3 0x6 0x2>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe 0xff>;
 	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
 };
 
diff --git a/arch/arm/dts/rk3288-firefly.dts b/arch/arm/dts/rk3288-firefly.dts
index 3176d50..97568a3 100644
--- a/arch/arm/dts/rk3288-firefly.dts
+++ b/arch/arm/dts/rk3288-firefly.dts
@@ -22,7 +22,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -31,7 +30,6 @@
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
 	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
diff --git a/arch/arm/dts/rk3288-miniarm.dts b/arch/arm/dts/rk3288-miniarm.dts
index c741082..9083028 100644
--- a/arch/arm/dts/rk3288-miniarm.dts
+++ b/arch/arm/dts/rk3288-miniarm.dts
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -25,8 +24,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
diff --git a/arch/arm/dts/rk3288-popmetal.dts b/arch/arm/dts/rk3288-popmetal.dts
index 3f61a61..284d5ed 100644
--- a/arch/arm/dts/rk3288-popmetal.dts
+++ b/arch/arm/dts/rk3288-popmetal.dts
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -25,8 +24,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
diff --git a/arch/arm/dts/rk3288-rock2-square.dts b/arch/arm/dts/rk3288-rock2-square.dts
index 2c30355..11c580a 100644
--- a/arch/arm/dts/rk3288-rock2-square.dts
+++ b/arch/arm/dts/rk3288-rock2-square.dts
@@ -184,7 +184,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -192,7 +191,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
diff --git a/arch/arm/dts/rk3288-veyron.dtsi b/arch/arm/dts/rk3288-veyron.dtsi
index d9d5187..2ffe39c 100644
--- a/arch/arm/dts/rk3288-veyron.dtsi
+++ b/arch/arm/dts/rk3288-veyron.dtsi
@@ -245,7 +245,6 @@
 		533000 1150000
 		666000 1200000
 	>;
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f4 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -253,7 +252,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3036.h b/arch/arm/include/asm/arch-rockchip/cru_rk3036.h
index 7ecc8ee..aaef4b9 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3036.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3036.h
@@ -24,6 +24,12 @@
 #define PERI_HCLK_HZ	148500000
 #define PERI_PCLK_HZ	74250000
 
+/* Private data for the clock driver - used by rockchip_get_cru() */
+struct rk3036_clk_priv {
+	struct rk3036_cru *cru;
+	ulong rate;
+};
+
 struct rk3036_cru {
 	struct rk3036_pll {
 		unsigned int con0;
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3288.h b/arch/arm/include/asm/arch-rockchip/cru_rk3288.h
index 8a8ca9c..d575f4a 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3288.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3288.h
@@ -25,6 +25,13 @@
 #define PERI_HCLK_HZ	148500000
 #define PERI_PCLK_HZ	74250000
 
+/* Private data for the clock driver - used by rockchip_get_cru() */
+struct rk3288_clk_priv {
+	struct rk3288_grf *grf;
+	struct rk3288_cru *cru;
+	ulong rate;
+};
+
 struct rk3288_cru {
 	struct rk3288_pll {
 		u32 con0;
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
index 6776e48..98fba2b 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
@@ -9,6 +9,12 @@
 
 #include <common.h>
 
+/* Private data for the clock driver - used by rockchip_get_cru() */
+struct rk3399_clk_priv {
+	struct rk3399_cru *cru;
+	ulong rate;
+};
+
 struct rk3399_pmucru {
 	u32 ppll_con[6];
 	u32 reserved[0x1a];
diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h
index 82c3d07..d7d67ba 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram.h
@@ -16,6 +16,11 @@
 };
 
 struct rk3288_sdram_channel {
+	/*
+	 * bit width in address, eg:
+	 * 8 banks using 3 bit to address,
+	 * 2 cs using 1 bit to address.
+	 */
 	u8 rank;
 	u8 col;
 	u8 bk;
@@ -87,6 +92,16 @@
 	u32 ddrconfig;
 	u32 ddr_freq;
 	u32 dramtype;
+	/*
+	 * DDR Stride is address mapping for DRAM space
+	 * Stride	Ch 0 range	Ch1 range	Total
+	 * 0x00		0-256MB		256MB-512MB	512MB
+	 * 0x05		0-1GB		0-1GB		1GB
+	 * 0x09		0-2GB		0-2GB		2GB
+	 * 0x0d		0-4GB		0-4GB		4GB
+	 * 0x17		N/A		0-4GB		4GB
+	 * 0x1a		0-4GB		4GB-8GB		8GB
+	 */
 	u32 stride;
 	u32 odt;
 };
diff --git a/arch/arm/mach-rockchip/rk3036/Makefile b/arch/arm/mach-rockchip/rk3036/Makefile
index 916a7a4..20d28f7 100644
--- a/arch/arm/mach-rockchip/rk3036/Makefile
+++ b/arch/arm/mach-rockchip/rk3036/Makefile
@@ -4,6 +4,8 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
+obj-y += clk_rk3036.o
+
 ifndef CONFIG_SPL_BUILD
 obj-y += syscon_rk3036.o
 endif
diff --git a/arch/arm/mach-rockchip/rk3036/clk_rk3036.c b/arch/arm/mach-rockchip/rk3036/clk_rk3036.c
new file mode 100644
index 0000000..6a06afb
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3036/clk_rk3036.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3036.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(rockchip_rk3036_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+	struct rk3036_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 94863a9..c53d2e2 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -81,9 +81,6 @@
 config SPL_LIBGENERIC_SUPPORT
 	default y
 
-config SPL_MMC_SUPPORT
-	default y
-
 config SPL_SERIAL_SUPPORT
 	default y
 
diff --git a/arch/arm/mach-rockchip/rk3288/clk_rk3288.c b/arch/arm/mach-rockchip/rk3288/clk_rk3288.c
index 2099e34..a45b923 100644
--- a/arch/arm/mach-rockchip/rk3288/clk_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/clk_rk3288.c
@@ -9,9 +9,25 @@
 #include <dm.h>
 #include <syscon.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3288.h>
 
 int rockchip_get_clk(struct udevice **devp)
 {
 	return uclass_get_device_by_driver(UCLASS_CLK,
 			DM_GET_DRIVER(rockchip_rk3288_cru), devp);
 }
+
+void *rockchip_get_cru(void)
+{
+	struct rk3288_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c
index 92f34bb..acc3b79 100644
--- a/arch/arm/mach-rockchip/rk3288/rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -6,7 +6,7 @@
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 
-#define GRF_SOC_CON2 0x24c
+#define GRF_SOC_CON2 0xff77024c
 
 int arch_cpu_init(void)
 {
diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
index 8020e9c..be3d713 100644
--- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
@@ -57,6 +57,10 @@
 	struct regmap *map;
 };
 
+#define TEST_PATTEN	0x5aa5f00f
+#define DQS_GATE_TRAINING_ERROR_RANK0	(1 << 4)
+#define DQS_GATE_TRAINING_ERROR_RANK1	(2 << 4)
+
 #ifdef CONFIG_SPL_BUILD
 static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
 {
@@ -214,7 +218,7 @@
 }
 
 static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl,
-		     const struct rk3288_sdram_params *sdram_params,
+		     struct rk3288_sdram_params *sdram_params,
 		     struct rk3288_grf *grf)
 {
 	unsigned int burstlen;
@@ -264,7 +268,7 @@
 }
 
 static void phy_cfg(const struct chan_info *chan, u32 channel,
-		    const struct rk3288_sdram_params *sdram_params)
+		    struct rk3288_sdram_params *sdram_params)
 {
 	struct rk3288_ddr_publ *publ = chan->publ;
 	struct rk3288_msch *msch = chan->msch;
@@ -446,7 +450,7 @@
 }
 
 static int data_training(const struct chan_info *chan, u32 channel,
-			 const struct rk3288_sdram_params *sdram_params)
+			 struct rk3288_sdram_params *sdram_params)
 {
 	unsigned int j;
 	int ret = 0;
@@ -549,7 +553,7 @@
 }
 
 static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum,
-			 const struct rk3288_sdram_params *sdram_params)
+			 struct rk3288_sdram_params *sdram_params)
 {
 	struct rk3288_ddr_publ *publ = chan->publ;
 
@@ -563,7 +567,7 @@
 }
 
 static void dram_all_config(const struct dram_info *dram,
-			    const struct rk3288_sdram_params *sdram_params)
+			    struct rk3288_sdram_params *sdram_params)
 {
 	unsigned int chan;
 	u32 sys_reg = 0;
@@ -589,9 +593,191 @@
 	writel(sys_reg, &dram->pmu->sys_reg[2]);
 	rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride);
 }
+const int ddrconf_table[] = {
+	/* row	    col,bw */
+	0,
+	((1 << 4) | 1),
+	((2 << 4) | 1),
+	((3 << 4) | 1),
+	((4 << 4) | 1),
+	((1 << 4) | 2),
+	((2 << 4) | 2),
+	((3 << 4) | 2),
+	((1 << 4) | 0),
+	((2 << 4) | 0),
+	((3 << 4) | 0),
+	0,
+	0,
+	0,
+	0,
+	((4 << 4) | 2),
+};
+
+static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
+		struct rk3288_sdram_params *sdram_params)
+{
+	int reg;
+	int need_trainig = 0;
+	const struct chan_info *chan = &dram->chan[channel];
+	struct rk3288_ddr_publ *publ = chan->publ;
+
+	if (-1 == data_training(chan, channel, sdram_params)) {
+		reg = readl(&publ->datx8[0].dxgsr[0]);
+		/* Check the result for rank 0 */
+		if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
+			debug("data training fail!\n");
+				return -EIO;
+		} else if ((channel == 1) &&
+			   (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
+			sdram_params->num_channels = 1;
+		}
+
+		/* Check the result for rank 1 */
+		if (reg & DQS_GATE_TRAINING_ERROR_RANK1) {
+			sdram_params->ch[channel].rank = 1;
+			clrsetbits_le32(&publ->pgcr, 0xF << 18,
+					sdram_params->ch[channel].rank << 18);
+			need_trainig = 1;
+		}
+		reg = readl(&publ->datx8[2].dxgsr[0]);
+		if (reg & (1 << 4)) {
+			sdram_params->ch[channel].bw = 1;
+			set_bandwidth_ratio(chan, channel,
+					    sdram_params->ch[channel].bw,
+					    dram->grf);
+			need_trainig = 1;
+		}
+	}
+	/* Assume the Die bit width are the same with the chip bit width */
+	sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
+
+	if (need_trainig &&
+	    (-1 == data_training(chan, channel, sdram_params))) {
+		if (sdram_params->base.dramtype == LPDDR3) {
+			ddr_phy_ctl_reset(dram->cru, channel, 1);
+			udelay(10);
+			ddr_phy_ctl_reset(dram->cru, channel, 0);
+			udelay(10);
+		}
+		debug("2nd data training failed!");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int sdram_col_row_detect(struct dram_info *dram, int channel,
+		struct rk3288_sdram_params *sdram_params)
+{
+	int row, col;
+	unsigned int addr;
+	const struct chan_info *chan = &dram->chan[channel];
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+	struct rk3288_ddr_publ *publ = chan->publ;
+	int ret = 0;
+
+	/* Detect col */
+	for (col = 11; col >= 9; col--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		addr = CONFIG_SYS_SDRAM_BASE +
+			(1 << (col + sdram_params->ch[channel].bw - 1));
+		writel(TEST_PATTEN, addr);
+		if ((readl(addr) == TEST_PATTEN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (col == 8) {
+		printf("Col detect error\n");
+		ret = -EINVAL;
+		goto out;
+	} else {
+		sdram_params->ch[channel].col = col;
+	}
+
+	move_to_config_state(publ, pctl);
+	writel(4, &chan->msch->ddrconf);
+	move_to_access_state(chan);
+	/* Detect row*/
+	for (row = 16; row >= 12; row--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
+		writel(TEST_PATTEN, addr);
+		if ((readl(addr) == TEST_PATTEN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (row == 11) {
+		printf("Row detect error\n");
+		ret = -EINVAL;
+	} else {
+		sdram_params->ch[channel].cs1_row = row;
+		sdram_params->ch[channel].row_3_4 = 0;
+		debug("chn %d col %d, row %d\n", channel, col, row);
+		sdram_params->ch[channel].cs0_row = row;
+	}
+
+out:
+	return ret;
+}
 
+static int sdram_get_niu_config(struct rk3288_sdram_params *sdram_params)
+{
+	int i, tmp, size, ret = 0;
+
+	tmp = sdram_params->ch[0].col - 9;
+	tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
+	tmp |= ((sdram_params->ch[0].cs0_row - 12) << 4);
+	size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
+	for (i = 0; i < size; i++)
+		if (tmp == ddrconf_table[i])
+			break;
+	if (i >= size) {
+		printf("niu config not found\n");
+		ret = -EINVAL;
+	} else {
+		sdram_params->base.ddrconfig = i;
+	}
+
+	return ret;
+}
+
+static int sdram_get_stride(struct rk3288_sdram_params *sdram_params)
+{
+	int stride = -1;
+	int ret = 0;
+	long cap = sdram_params->num_channels * (1u <<
+			(sdram_params->ch[0].cs0_row +
+			 sdram_params->ch[0].col +
+			 (sdram_params->ch[0].rank - 1) +
+			 sdram_params->ch[0].bw +
+			 3 - 20));
+
+	switch (cap) {
+	case 512:
+		stride = 0;
+		break;
+	case 1024:
+		stride = 5;
+		break;
+	case 2048:
+		stride = 9;
+		break;
+	case 4096:
+		stride = 0xd;
+		break;
+	default:
+		stride = -1;
+		printf("could not find correct stride, cap error!\n");
+		ret = -EINVAL;
+		break;
+	}
+	sdram_params->base.stride = stride;
+
+	return ret;
+}
+
 static int sdram_init(struct dram_info *dram,
-		      const struct rk3288_sdram_params *sdram_params)
+		      struct rk3288_sdram_params *sdram_params)
 {
 	int channel;
 	int zqcr;
@@ -619,12 +805,14 @@
 		struct rk3288_ddr_pctl *pctl = chan->pctl;
 		struct rk3288_ddr_publ *publ = chan->publ;
 
+		/* map all the 4GB space to the current channel */
+		if (channel)
+			rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x17);
+		else
+			rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x1a);
 		phy_pctrl_reset(dram->cru, publ, channel);
 		phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
 
-		if (channel >= sdram_params->num_channels)
-			continue;
-
 		dfi_cfg(pctl, sdram_params->base.dramtype);
 
 		pctl_cfg(channel, pctl, sdram_params, dram->grf);
@@ -658,16 +846,20 @@
 			udelay(1);
 		}
 
+		/* Using 32bit bus width for detect */
+		sdram_params->ch[channel].bw = 2;
 		set_bandwidth_ratio(chan, channel,
 				    sdram_params->ch[channel].bw, dram->grf);
 		/*
-		 * set cs
+		 * set cs, using n=3 for detect
 		 * CS0, n=1
 		 * CS1, n=2
 		 * CS0 & CS1, n = 3
 		 */
+		sdram_params->ch[channel].rank = 2,
 		clrsetbits_le32(&publ->pgcr, 0xF << 18,
 				(sdram_params->ch[channel].rank | 1) << 18);
+
 		/* DS=40ohm,ODT=155ohm */
 		zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
 			2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
@@ -693,16 +885,8 @@
 			}
 		}
 
-		if (-1 == data_training(chan, channel, sdram_params)) {
-			if (sdram_params->base.dramtype == LPDDR3) {
-				ddr_phy_ctl_reset(dram->cru, channel, 1);
-				udelay(10);
-				ddr_phy_ctl_reset(dram->cru, channel, 0);
-				udelay(10);
-			}
-			debug("failed!");
-			return -EIO;
-		}
+		/* Detect the rank and bit-width with data-training */
+		sdram_rank_bw_detect(dram, channel, sdram_params);
 
 		if (sdram_params->base.dramtype == LPDDR3) {
 			u32 i;
@@ -710,12 +894,31 @@
 			for (i = 0; i < 17; i++)
 				send_command_op(pctl, 1, MRR_CMD, i, 0);
 		}
+		writel(15, &chan->msch->ddrconf);
 		move_to_access_state(chan);
+		/* DDR3 and LPDDR3 are always 8 bank, no need detect */
+		sdram_params->ch[channel].bk = 3;
+		/* Detect Col and Row number*/
+		ret = sdram_col_row_detect(dram, channel, sdram_params);
+		if (ret)
+			goto error;
 	}
+	/* Find NIU DDR configuration */
+	ret = sdram_get_niu_config(sdram_params);
+	if (ret)
+		goto error;
+	/* Find stride setting */
+	ret = sdram_get_stride(sdram_params);
+	if (ret)
+		goto error;
+
 	dram_all_config(dram, sdram_params);
 	debug("%s done\n", __func__);
 
 	return 0;
+error:
+	printf("DRAM init failed!\n");
+	hang();
 }
 #endif /* CONFIG_SPL_BUILD */
 
@@ -743,7 +946,6 @@
 			SYS_REG_BW_MASK));
 		row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
 			SYS_REG_ROW_3_4_MASK;
-
 		chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
 
 		if (rank > 1)
@@ -815,21 +1017,10 @@
 	struct rk3288_sdram_params *params = dev_get_platdata(dev);
 	const void *blob = gd->fdt_blob;
 	int node = dev->of_offset;
-	int i, ret;
+	int ret;
 
-	params->num_channels = fdtdec_get_int(blob, node,
-					      "rockchip,num-channels", 1);
-	for (i = 0; i < params->num_channels; i++) {
-		ret = fdtdec_get_byte_array(blob, node,
-					    "rockchip,sdram-channel",
-					    (u8 *)&params->ch[i],
-					    sizeof(params->ch[i]));
-		if (ret) {
-			debug("%s: Cannot read rockchip,sdram-channel\n",
-			      __func__);
-			return -EINVAL;
-		}
-	}
+	/* Rk3288 supports dual-channel, set default channel num to 2 */
+	params->num_channels = 2;
 	ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
 				   (u32 *)&params->pctl_timing,
 				   sizeof(params->pctl_timing) / sizeof(u32));
@@ -870,18 +1061,15 @@
 {
 	struct rk3288_sdram_params *plat = dev_get_platdata(dev);
 	struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat;
-	int i, ret;
+	int ret;
 
-	for (i = 0; i < 2; i++) {
-		memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel,
-		       sizeof(plat->ch[i]));
-	}
 	memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
 	       sizeof(plat->pctl_timing));
 	memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
 	       sizeof(plat->phy_timing));
 	memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
-	plat->num_channels = of_plat->rockchip_num_channels;
+	/* Rk3288 supports dual-channel, set default channel num to 2 */
+	plat->num_channels = 2;
 	ret = regmap_init_mem_platdata(dev, of_plat->reg,
 				       ARRAY_SIZE(of_plat->reg) / 2,
 				       &plat->map);
diff --git a/arch/arm/mach-rockchip/rk3399/Makefile b/arch/arm/mach-rockchip/rk3399/Makefile
index 607f9c9..98ebeac 100644
--- a/arch/arm/mach-rockchip/rk3399/Makefile
+++ b/arch/arm/mach-rockchip/rk3399/Makefile
@@ -4,5 +4,6 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
+obj-y += clk_rk3399.o
 obj-y += rk3399.o
 obj-y += syscon_rk3399.o
diff --git a/arch/arm/mach-rockchip/rk3399/clk_rk3399.c b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
new file mode 100644
index 0000000..7663591
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3399.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(rockchip_rk3399_pmuclk), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+	struct rk3399_clk_priv *priv;
+	struct udevice *dev;
+	int ret;
+
+	ret = rockchip_get_clk(&dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv = dev_get_priv(dev);
+
+	return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c
index b9d7629..8bb950e 100644
--- a/arch/arm/mach-rockchip/rk3399/rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/rk3399.c
@@ -6,6 +6,10 @@
 
 #include <common.h>
 #include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#define GRF_EMMCCORE_CON11 0xff77f02c
 
 static struct mm_region rk3399_mem_map[] = {
 	{
@@ -28,3 +32,13 @@
 };
 
 struct mm_region *mem_map = rk3399_mem_map;
+
+int arch_cpu_init(void)
+{
+	/* We do some SoC one time setting here. */
+
+	/* Emmc clock generator: disable the clock multipilier */
+	rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff);
+
+	return 0;
+}
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
index fd8afe7..8db9041a 100644
--- a/configs/evb-rk3288_defconfig
+++ b/configs/evb-rk3288_defconfig
@@ -64,3 +64,4 @@
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_ERRNO_STR=y
+CONFIG_ROCKCHIP_SPL_BACK_TO_BROM=y
diff --git a/configs/fennec-rk3288_defconfig b/configs/fennec-rk3288_defconfig
index 5b4d0f1..d5452004b 100644
--- a/configs/fennec-rk3288_defconfig
+++ b/configs/fennec-rk3288_defconfig
@@ -63,3 +63,4 @@
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_ERRNO_STR=y
+CONFIG_ROCKCHIP_SPL_BACK_TO_BROM=y
diff --git a/configs/miniarm-rk3288_defconfig b/configs/miniarm-rk3288_defconfig
index 394e4aa..888563b 100644
--- a/configs/miniarm-rk3288_defconfig
+++ b/configs/miniarm-rk3288_defconfig
@@ -62,3 +62,4 @@
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_ERRNO_STR=y
+CONFIG_ROCKCHIP_SPL_BACK_TO_BROM=y
diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig
index ff6a153..1e70ae0 100644
--- a/configs/popmetal-rk3288_defconfig
+++ b/configs/popmetal-rk3288_defconfig
@@ -62,3 +62,4 @@
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_CMD_DHRYSTONE=y
 CONFIG_ERRNO_STR=y
+CONFIG_ROCKCHIP_SPL_BACK_TO_BROM=y
diff --git a/doc/README.rockchip b/doc/README.rockchip
index 69b926c..06ec80e 100644
--- a/doc/README.rockchip
+++ b/doc/README.rockchip
@@ -149,7 +149,6 @@
 
 Using fastboot on rk3288
 ========================
-- Define GPT partition layout like kylin_rk3036(see include/configs/kylin_rk3036.h)
 - Write GPT partition layout to mmc device which fastboot want to use it to
 store the image
 
@@ -212,7 +211,6 @@
    Err:   serial@ff690000
    =>
 
-
 Future work
 ===========
 
@@ -298,6 +296,15 @@
 In general all Rockchip drivers should use these features, with SPL-specific
 modifications where required.
 
+GPT partition layout
+----------------------------
+
+Rockchip use a unified GPT partition layout  in open source support.
+With this GPT partition layout, uboot can be compatilbe with other components,
+like miniloader, trusted-os, arm-trust-firmware.
+
+There are some documents about partitions in the links below.
+http://rockchip.wikidot.com/partitions
 
 --
 Simon Glass <sjg@chromium.org>
diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c
index 8899b0c..7e3bf96 100644
--- a/drivers/clk/rockchip/clk_rk3036.c
+++ b/drivers/clk/rockchip/clk_rk3036.c
@@ -19,11 +19,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-struct rk3036_clk_priv {
-	struct rk3036_cru *cru;
-	ulong rate;
-};
-
 enum {
 	VCO_MAX_HZ	= 2400U * 1000000,
 	VCO_MIN_HZ	= 600 * 1000000,
@@ -49,23 +44,6 @@
 static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
 
-void *rockchip_get_cru(void)
-{
-	struct udevice *dev;
-	fdt_addr_t addr;
-	int ret;
-
-	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
-	if (ret)
-		return ERR_PTR(ret);
-
-	addr = dev_get_addr(dev);
-	if (addr == FDT_ADDR_T_NONE)
-		return ERR_PTR(-EINVAL);
-
-	return (void *)addr;
-}
-
 static int rkclk_set_pll(struct rk3036_cru *cru, enum rk_clk_id clk_id,
 			 const struct pll_div *div)
 {
@@ -371,7 +349,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(clk_rk3036) = {
+U_BOOT_DRIVER(rockchip_rk3036_cru) = {
 	.name		= "clk_rk3036",
 	.id		= UCLASS_CLK,
 	.of_match	= rk3036_clk_ids,
diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
index bd71a96..ed97e87 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -30,12 +30,6 @@
 #endif
 };
 
-struct rk3288_clk_priv {
-	struct rk3288_grf *grf;
-	struct rk3288_cru *cru;
-	ulong rate;
-};
-
 struct pll_div {
 	u32 nr;
 	u32 nf;
@@ -140,21 +134,6 @@
 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
 
-void *rockchip_get_cru(void)
-{
-	struct rk3288_clk_priv *priv;
-	struct udevice *dev;
-	int ret;
-
-	ret = rockchip_get_clk(&dev);
-	if (ret)
-		return ERR_PTR(ret);
-
-	priv = dev_get_priv(dev);
-
-	return priv->cru;
-}
-
 static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
 			 const struct pll_div *div)
 {
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index ea0ce2a..2e87e4b 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -18,11 +18,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-struct rk3399_clk_priv {
-	struct rk3399_cru *cru;
-	ulong rate;
-};
-
 struct rk3399_pmuclk_priv {
 	struct rk3399_pmucru *pmucru;
 };
@@ -780,23 +775,6 @@
 	.set_rate = rk3399_clk_set_rate,
 };
 
-void *rockchip_get_cru(void)
-{
-	struct udevice *dev;
-	fdt_addr_t *addr;
-	int ret;
-
-	ret = uclass_get_device_by_name(UCLASS_CLK, "clk_rk3399", &dev);
-	if (ret)
-		return ERR_PTR(ret);
-
-	addr = dev_get_addr_ptr(dev);
-	if ((fdt_addr_t)addr == FDT_ADDR_T_NONE)
-		return ERR_PTR(-EINVAL);
-
-	return addr;
-}
-
 static int rk3399_clk_probe(struct udevice *dev)
 {
 	struct rk3399_clk_priv *priv = dev_get_priv(dev);
@@ -990,7 +968,7 @@
 	{ }
 };
 
-U_BOOT_DRIVER(pmuclk_rk3399) = {
+U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = {
 	.name		= "pmuclk_rk3399",
 	.id		= UCLASS_CLK,
 	.of_match	= rk3399_pmuclk_ids,
diff --git a/include/configs/evb_rk3399.h b/include/configs/evb_rk3399.h
index f453640..8fdefa2 100644
--- a/include/configs/evb_rk3399.h
+++ b/include/configs/evb_rk3399.h
@@ -10,7 +10,7 @@
 #include <configs/rk3399_common.h>
 
 #define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_SYS_MMC_ENV_DEV 0
+#define CONFIG_SYS_MMC_ENV_DEV 1
 /*
  * SPL @ 32k for ~36k
  * ENV @ 96k
diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h
index 724a3f4..4eef3f8 100644
--- a/include/configs/rk3036_common.h
+++ b/include/configs/rk3036_common.h
@@ -7,6 +7,7 @@
 #define __CONFIG_RK3036_COMMON_H
 
 #include <asm/arch/hardware.h>
+#include "rockchip-common.h"
 
 #define CONFIG_SYS_NO_FLASH
 #define CONFIG_NR_DRAM_BANKS		1
@@ -78,11 +79,6 @@
 #define CONFIG_G_DNL_VENDOR_NUM		0x2207
 #define CONFIG_G_DNL_PRODUCT_NUM	0x310a
 
-/* Enable gpt partition table */
-#define CONFIG_CMD_GPT
-
-#include <config_distro_defaults.h>
-
 #define ENV_MEM_LAYOUT_SETTINGS \
 	"scriptaddr=0x60000000\0" \
 	"pxefile_addr_r=0x60100000\0" \
@@ -90,17 +86,6 @@
 	"kernel_addr_r=0x62000000\0" \
 	"ramdisk_addr_r=0x64000000\0"
 
-#define CONFIG_RANDOM_UUID
-#define PARTS_DEFAULT \
-	"uuid_disk=${uuid_gpt_disk};" \
-	"name=boot,start=8M,size=64M,bootable,uuid=${uuid_gpt_boot};" \
-	"name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \
-
-/* First try to boot from SD (index 0), then eMMC (index 1 */
-#define BOOT_TARGET_DEVICES(func) \
-	func(MMC, mmc, 0) \
-	func(MMC, mmc, 1)
-
 #include <config_distro_bootcmd.h>
 
 /* Linux fails to load the fdt if it's loaded above 512M on a evb-rk3036 board,
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index cf6f355..0868612 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -8,6 +8,7 @@
 #define __CONFIG_RK3288_COMMON_H
 
 #include <asm/arch/hardware.h>
+#include "rockchip-common.h"
 
 #define CONFIG_SKIP_LOWLEVEL_INIT_ONLY
 #define CONFIG_SYS_NO_FLASH
@@ -89,11 +90,6 @@
 #define CONFIG_G_DNL_VENDOR_NUM		0x2207
 #define CONFIG_G_DNL_PRODUCT_NUM	0x320a
 
-/* Enable gpt partition table */
-#define CONFIG_CMD_GPT
-
-#include <config_distro_defaults.h>
-
 #define ENV_MEM_LAYOUT_SETTINGS \
 	"scriptaddr=0x00000000\0" \
 	"pxefile_addr_r=0x00100000\0" \
@@ -101,24 +97,13 @@
 	"kernel_addr_r=0x02000000\0" \
 	"ramdisk_addr_r=0x04000000\0"
 
-#define CONFIG_RANDOM_UUID
-#define PARTS_DEFAULT \
-	"uuid_disk=${uuid_gpt_disk};" \
-	"name=boot,start=8M,size=64M,bootable,uuid=${uuid_gpt_boot};" \
-	"name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \
-
-/* First try to boot from SD (index 0), then eMMC (index 1 */
-#define BOOT_TARGET_DEVICES(func) \
-	func(MMC, mmc, 0) \
-	func(MMC, mmc, 1)
-
 #include <config_distro_bootcmd.h>
 
-/* Linux fails to load the fdt if it's loaded above 512M on a Rock 2 board, so
+/* Linux fails to load the fdt if it's loaded above 256M on a Rock 2 board, so
  * limit the fdt reallocation to that */
 #define CONFIG_EXTRA_ENV_SETTINGS \
-	"fdt_high=0x1fffffff\0" \
-	"initrd_high=0x1fffffff\0" \
+	"fdt_high=0x0fffffff\0" \
+	"initrd_high=0x0fffffff\0" \
 	"partitions=" PARTS_DEFAULT \
 	ENV_MEM_LAYOUT_SETTINGS \
 	ROCKCHIP_DEVICE_SETTINGS \
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index bec004a..d75fead 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -7,6 +7,8 @@
 #ifndef __CONFIG_RK3399_COMMON_H
 #define __CONFIG_RK3399_COMMON_H
 
+#include "rockchip-common.h"
+
 #define CONFIG_SYS_NO_FLASH
 #define CONFIG_NR_DRAM_BANKS		1
 #define CONFIG_ENV_SIZE			0x2000
@@ -52,7 +54,6 @@
 #define CONFIG_SF_DEFAULT_SPEED 20000000
 
 #ifndef CONFIG_SPL_BUILD
-#include <config_distro_defaults.h>
 
 #define ENV_MEM_LAYOUT_SETTINGS \
 	"scriptaddr=0x00000000\0" \
@@ -61,19 +62,6 @@
 	"kernel_addr_r=0x02000000\0" \
 	"ramdisk_addr_r=0x04000000\0"
 
-#define CONFIG_CMD_GPT
-#define CONFIG_RANDOM_UUID
-#define CONFIG_PARTITION_UUIDS
-#define PARTS_DEFAULT \
-	"uuid_disk=${uuid_gpt_disk};" \
-	"name=boot,start=16M,size=32M,bootable;" \
-	"name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \
-
-/* First try to boot from SD (index 0), then eMMC (index 1) */
-#define BOOT_TARGET_DEVICES(func) \
-	func(MMC, mmc, 0) \
-	func(MMC, mmc, 1)
-
 #include <config_distro_bootcmd.h>
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	ENV_MEM_LAYOUT_SETTINGS \
diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h
new file mode 100644
index 0000000..7ca1696
--- /dev/null
+++ b/include/configs/rockchip-common.h
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _ROCKCHIP_COMMON_H_
+#define _ROCKCHIP_COMMON_H_
+#include <linux/sizes.h>
+
+#ifndef CONFIG_SPL_BUILD
+#include <config_distro_defaults.h>
+
+/* First try to boot from SD (index 0), then eMMC (index 1 */
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0) \
+	func(MMC, mmc, 1)
+
+ /* Enable gpt partition table */
+#define CONFIG_CMD_GPT
+#define CONFIG_RANDOM_UUID
+#define CONFIG_PARTITION_UUIDS
+#define PARTS_DEFAULT \
+	"uuid_disk=${uuid_gpt_disk};" \
+	"name=loader1,start=32K,size=4000K,uuid=${uuid_gpt_loader1};" \
+	"name=reserved1,size=64K,uuid=${uuid_gpt_reserved1};" \
+	"name=reserved2,size=4M,uuid=${uuid_gpt_reserved2};" \
+	"name=loader2,size=4MB,uuid=${uuid_gpt_loader2};" \
+	"name=atf,size=4M,uuid=${uuid_gpt_atf};" \
+	"name=boot,size=128M,bootable,uuid=${uuid_gpt_boot};" \
+	"name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \
+
+#endif
+
+#endif /* _ROCKCHIP_COMMON_H_ */