ram: rk3328: use common sdram driver

RK3328 has a similar controller and phy with PX30, so we can use the
common driver for it and remove the duplicate codes.

Signed-off-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
diff --git a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
index d99e7e0..3e88ed4 100644
--- a/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
+++ b/arch/arm/dts/rk3328-sdram-ddr3-666.dtsi
@@ -14,6 +14,8 @@
 		0x0
 		0x10
 		0x10
+		0x10
+		0x10
 		0
 
 		0x9028b189
@@ -26,6 +28,8 @@
 
 		333
 		3
+		1
+		0
 		0
 
 		0x00000000
diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
index cc0011c..d63c761 100644
--- a/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
+++ b/arch/arm/dts/rk3328-sdram-lpddr3-1600.dtsi
@@ -14,6 +14,8 @@
 		0x0
 		0x10
 		0x10
+		0x10
+		0x10
 		0
 
 		0x98899459
@@ -27,6 +29,8 @@
 		800
 		6
 		1
+		0
+		1
 
 		0x00000000
 		0x43041008
diff --git a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
index 62d809e..b9d3b3b 100644
--- a/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
+++ b/arch/arm/dts/rk3328-sdram-lpddr3-666.dtsi
@@ -14,6 +14,8 @@
 		0x0
 		0x10
 		0x10
+		0x10
+		0x10
 		0
 
 		0x0c48a18a
@@ -26,6 +28,8 @@
 
 		333
 		6
+		1
+		0
 		0
 
 		0x00000000
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
index c747b46..1092350 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3328.h
@@ -7,197 +7,13 @@
 #ifndef _ASM_ARCH_SDRAM_RK3328_H
 #define _ASM_ARCH_SDRAM_RK3328_H
 #include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_pctl_px30.h>
+#include <asm/arch-rockchip/sdram_phy_px30.h>
+#include <asm/arch-rockchip/sdram_phy_ron_rtt_px30.h>
 
 #define SR_IDLE		93
 #define PD_IDLE		13
 #define SDRAM_ADDR	0x00000000
-#define PATTERN		(0x5aa5f00f)
-
-/* ddr pctl registers define */
-#define DDR_PCTL2_MSTR			0x0
-#define DDR_PCTL2_STAT			0x4
-#define DDR_PCTL2_MSTR1			0x8
-#define DDR_PCTL2_MRCTRL0		0x10
-#define DDR_PCTL2_MRCTRL1		0x14
-#define DDR_PCTL2_MRSTAT		0x18
-#define DDR_PCTL2_MRCTRL2		0x1c
-#define DDR_PCTL2_DERATEEN		0x20
-#define DDR_PCTL2_DERATEINT		0x24
-#define DDR_PCTL2_PWRCTL		0x30
-#define DDR_PCTL2_PWRTMG		0x34
-#define DDR_PCTL2_HWLPCTL		0x38
-#define DDR_PCTL2_RFSHCTL0		0x50
-#define DDR_PCTL2_RFSHCTL1		0x54
-#define DDR_PCTL2_RFSHCTL2		0x58
-#define DDR_PCTL2_RFSHCTL4		0x5c
-#define DDR_PCTL2_RFSHCTL3		0x60
-#define DDR_PCTL2_RFSHTMG		0x64
-#define DDR_PCTL2_RFSHTMG1		0x68
-#define DDR_PCTL2_RFSHCTL5		0x6c
-#define DDR_PCTL2_INIT0			0xd0
-#define DDR_PCTL2_INIT1			0xd4
-#define DDR_PCTL2_INIT2			0xd8
-#define DDR_PCTL2_INIT3			0xdc
-#define DDR_PCTL2_INIT4			0xe0
-#define DDR_PCTL2_INIT5			0xe4
-#define DDR_PCTL2_INIT6			0xe8
-#define DDR_PCTL2_INIT7			0xec
-#define DDR_PCTL2_DIMMCTL		0xf0
-#define DDR_PCTL2_RANKCTL		0xf4
-#define DDR_PCTL2_CHCTL			0xfc
-#define DDR_PCTL2_DRAMTMG0		0x100
-#define DDR_PCTL2_DRAMTMG1		0x104
-#define DDR_PCTL2_DRAMTMG2		0x108
-#define DDR_PCTL2_DRAMTMG3		0x10c
-#define DDR_PCTL2_DRAMTMG4		0x110
-#define DDR_PCTL2_DRAMTMG5		0x114
-#define DDR_PCTL2_DRAMTMG6		0x118
-#define DDR_PCTL2_DRAMTMG7		0x11c
-#define DDR_PCTL2_DRAMTMG8		0x120
-#define DDR_PCTL2_DRAMTMG9		0x124
-#define DDR_PCTL2_DRAMTMG10		0x128
-#define DDR_PCTL2_DRAMTMG11		0x12c
-#define DDR_PCTL2_DRAMTMG12		0x130
-#define DDR_PCTL2_DRAMTMG13		0x134
-#define DDR_PCTL2_DRAMTMG14		0x138
-#define DDR_PCTL2_DRAMTMG15		0x13c
-#define DDR_PCTL2_DRAMTMG16		0x140
-#define DDR_PCTL2_ZQCTL0		0x180
-#define DDR_PCTL2_ZQCTL1		0x184
-#define DDR_PCTL2_ZQCTL2		0x188
-#define DDR_PCTL2_ZQSTAT		0x18c
-#define DDR_PCTL2_DFITMG0		0x190
-#define DDR_PCTL2_DFITMG1		0x194
-#define DDR_PCTL2_DFILPCFG0		0x198
-#define DDR_PCTL2_DFILPCFG1		0x19c
-#define DDR_PCTL2_DFIUPD0		0x1a0
-#define DDR_PCTL2_DFIUPD1		0x1a4
-#define DDR_PCTL2_DFIUPD2		0x1a8
-#define DDR_PCTL2_DFIMISC		0x1b0
-#define DDR_PCTL2_DFITMG2		0x1b4
-#define DDR_PCTL2_DFITMG3		0x1b8
-#define DDR_PCTL2_DFISTAT		0x1bc
-#define DDR_PCTL2_DBICTL		0x1c0
-#define DDR_PCTL2_ADDRMAP0		0x200
-#define DDR_PCTL2_ADDRMAP1		0x204
-#define DDR_PCTL2_ADDRMAP2		0x208
-#define DDR_PCTL2_ADDRMAP3		0x20c
-#define DDR_PCTL2_ADDRMAP4		0x210
-#define DDR_PCTL2_ADDRMAP5		0x214
-#define DDR_PCTL2_ADDRMAP6		0x218
-#define DDR_PCTL2_ADDRMAP7		0x21c
-#define DDR_PCTL2_ADDRMAP8		0x220
-#define DDR_PCTL2_ADDRMAP9		0x224
-#define DDR_PCTL2_ADDRMAP10		0x228
-#define DDR_PCTL2_ADDRMAP11		0x22c
-#define DDR_PCTL2_ODTCFG		0x240
-#define DDR_PCTL2_ODTMAP		0x244
-#define DDR_PCTL2_SCHED			0x250
-#define DDR_PCTL2_SCHED1		0x254
-#define DDR_PCTL2_PERFHPR1		0x25c
-#define DDR_PCTL2_PERFLPR1		0x264
-#define DDR_PCTL2_PERFWR1		0x26c
-#define DDR_PCTL2_DQMAP0		0x280
-#define DDR_PCTL2_DQMAP1		0x284
-#define DDR_PCTL2_DQMAP2		0x288
-#define DDR_PCTL2_DQMAP3		0x28c
-#define DDR_PCTL2_DQMAP4		0x290
-#define DDR_PCTL2_DQMAP5		0x294
-#define DDR_PCTL2_DBG0			0x300
-#define DDR_PCTL2_DBG1			0x304
-#define DDR_PCTL2_DBGCAM		0x308
-#define DDR_PCTL2_DBGCMD		0x30c
-#define DDR_PCTL2_DBGSTAT		0x310
-#define DDR_PCTL2_SWCTL			0x320
-#define DDR_PCTL2_SWSTAT		0x324
-#define DDR_PCTL2_POISONCFG		0x36c
-#define DDR_PCTL2_POISONSTAT		0x370
-#define DDR_PCTL2_ADVECCINDEX		0x374
-#define DDR_PCTL2_ADVECCSTAT		0x378
-#define DDR_PCTL2_PSTAT			0x3fc
-#define DDR_PCTL2_PCCFG			0x400
-#define DDR_PCTL2_PCFGR_n		0x404
-#define DDR_PCTL2_PCFGW_n		0x408
-#define DDR_PCTL2_PCTRL_n		0x490
-
-/* PCTL2_MRSTAT */
-#define MR_WR_BUSY			BIT(0)
-
-/* PHY_REG0 */
-#define DIGITAL_DERESET			BIT(3)
-#define ANALOG_DERESET			BIT(2)
-#define DIGITAL_RESET			(0 << 3)
-#define ANALOG_RESET			(0 << 2)
-
-/* PHY_REG1 */
-#define PHY_DDR2			(0)
-#define PHY_LPDDR2			(1)
-#define PHY_DDR3			(2)
-#define PHY_LPDDR3			(3)
-#define PHY_DDR4			(4)
-#define PHY_BL_4			(0 << 2)
-#define PHY_BL_8			BIT(2)
-
-/* PHY_REG2 */
-#define PHY_DTT_EN			BIT(0)
-#define PHY_DTT_DISB			(0 << 0)
-#define PHY_WRITE_LEVELING_EN		BIT(2)
-#define PHY_WRITE_LEVELING_DISB		(0 << 2)
-#define PHY_SELECT_CS0			(2)
-#define PHY_SELECT_CS1			(1)
-#define PHY_SELECT_CS0_1		(0)
-#define PHY_WRITE_LEVELING_SELECTCS(n)	(n << 6)
-#define PHY_DATA_TRAINING_SELECTCS(n)	(n << 4)
-
-#define PHY_DDR3_RON_RTT_DISABLE	(0)
-#define PHY_DDR3_RON_RTT_451ohm		(1)
-#define PHY_DDR3_RON_RTT_225ohm		(2)
-#define PHY_DDR3_RON_RTT_150ohm		(3)
-#define PHY_DDR3_RON_RTT_112ohm		(4)
-#define PHY_DDR3_RON_RTT_90ohm		(5)
-#define PHY_DDR3_RON_RTT_75ohm		(6)
-#define PHY_DDR3_RON_RTT_64ohm		(7)
-#define PHY_DDR3_RON_RTT_56ohm		(16)
-#define PHY_DDR3_RON_RTT_50ohm		(17)
-#define PHY_DDR3_RON_RTT_45ohm		(18)
-#define PHY_DDR3_RON_RTT_41ohm		(19)
-#define PHY_DDR3_RON_RTT_37ohm		(20)
-#define PHY_DDR3_RON_RTT_34ohm		(21)
-#define PHY_DDR3_RON_RTT_33ohm		(22)
-#define PHY_DDR3_RON_RTT_30ohm		(23)
-#define PHY_DDR3_RON_RTT_28ohm		(24)
-#define PHY_DDR3_RON_RTT_26ohm		(25)
-#define PHY_DDR3_RON_RTT_25ohm		(26)
-#define PHY_DDR3_RON_RTT_23ohm		(27)
-#define PHY_DDR3_RON_RTT_22ohm		(28)
-#define PHY_DDR3_RON_RTT_21ohm		(29)
-#define PHY_DDR3_RON_RTT_20ohm		(30)
-#define PHY_DDR3_RON_RTT_19ohm		(31)
-
-#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE	(0)
-#define PHY_DDR4_LPDDR3_RON_RTT_480ohm	(1)
-#define PHY_DDR4_LPDDR3_RON_RTT_240ohm	(2)
-#define PHY_DDR4_LPDDR3_RON_RTT_160ohm	(3)
-#define PHY_DDR4_LPDDR3_RON_RTT_120ohm	(4)
-#define PHY_DDR4_LPDDR3_RON_RTT_96ohm	(5)
-#define PHY_DDR4_LPDDR3_RON_RTT_80ohm	(6)
-#define PHY_DDR4_LPDDR3_RON_RTT_68ohm	(7)
-#define PHY_DDR4_LPDDR3_RON_RTT_60ohm	(16)
-#define PHY_DDR4_LPDDR3_RON_RTT_53ohm	(17)
-#define PHY_DDR4_LPDDR3_RON_RTT_48ohm	(18)
-#define PHY_DDR4_LPDDR3_RON_RTT_43ohm	(19)
-#define PHY_DDR4_LPDDR3_RON_RTT_40ohm	(20)
-#define PHY_DDR4_LPDDR3_RON_RTT_37ohm	(21)
-#define PHY_DDR4_LPDDR3_RON_RTT_34ohm	(22)
-#define PHY_DDR4_LPDDR3_RON_RTT_32ohm	(23)
-#define PHY_DDR4_LPDDR3_RON_RTT_30ohm	(24)
-#define PHY_DDR4_LPDDR3_RON_RTT_28ohm	(25)
-#define PHY_DDR4_LPDDR3_RON_RTT_26ohm	(26)
-#define PHY_DDR4_LPDDR3_RON_RTT_25ohm	(27)
-#define PHY_DDR4_LPDDR3_RON_RTT_24ohm	(28)
-#define PHY_DDR4_LPDDR3_RON_RTT_22ohm	(29)
-#define PHY_DDR4_LPDDR3_RON_RTT_21ohm	(30)
-#define PHY_DDR4_LPDDR3_RON_RTT_20ohm	(31)
 
 /* noc registers define */
 #define DDRCONF				0x8
@@ -220,16 +36,16 @@
 #define DDR_GRF_STATUS(n)	(DDR_GRF_STATUS_BASE + (n) * 4)
 
 /* CRU_SOFTRESET_CON5 */
-#define ddrphy_psrstn_req(n)    (((0x1 << 15) << 16) | (n << 15))
-#define ddrphy_srstn_req(n)     (((0x1 << 14) << 16) | (n << 14))
-#define ddrctrl_psrstn_req(n)	(((0x1 << 13) << 16) | (n << 13))
-#define ddrctrl_srstn_req(n)	(((0x1 << 12) << 16) | (n << 12))
-#define ddrmsch_srstn_req(n)	(((0x1 << 11) << 16) | (n << 11))
-#define msch_srstn_req(n)		(((0x1 << 9) << 16) | (n << 9))
-#define dfimon_srstn_req(n)		(((0x1 << 8) << 16) | (n << 8))
-#define grf_ddr_srstn_req(n)	(((0x1 << 7) << 16) | (n << 7))
+#define ddrphy_psrstn_req(n)    (((0x1 << 15) << 16) | ((n) << 15))
+#define ddrphy_srstn_req(n)     (((0x1 << 14) << 16) | ((n) << 14))
+#define ddrctrl_psrstn_req(n)	(((0x1 << 13) << 16) | ((n) << 13))
+#define ddrctrl_srstn_req(n)	(((0x1 << 12) << 16) | ((n) << 12))
+#define ddrmsch_srstn_req(n)	(((0x1 << 11) << 16) | ((n) << 11))
+#define msch_srstn_req(n)		(((0x1 << 9) << 16) | ((n) << 9))
+#define dfimon_srstn_req(n)		(((0x1 << 8) << 16) | ((n) << 8))
+#define grf_ddr_srstn_req(n)	(((0x1 << 7) << 16) | ((n) << 7))
 /* CRU_SOFTRESET_CON9 */
-#define ddrctrl_asrstn_req(n)		(((0x1 << 9) << 16) | (n << 9))
+#define ddrctrl_asrstn_req(n)		(((0x1 << 9) << 16) | ((n) << 9))
 
 /* CRU register */
 #define CRU_PLL_CON(pll_id, n)	((pll_id)  * 0x20 + (n) * 4)
@@ -256,56 +72,46 @@
 #define POSTDIV2(n)   ((0x7 << (6 + 16)) | ((n) << 6))
 #define REFDIV(n)     ((0x3F << 16) | (n))
 
-union noc_ddrtiming {
-	u32 d32;
-	struct {
-		unsigned acttoact:6;
-		unsigned rdtomiss:6;
-		unsigned wrtomiss:6;
-		unsigned burstlen:3;
-		unsigned rdtowr:5;
-		unsigned wrtord:5;
-		unsigned bwratio:1;
-	} b;
-} NOC_TIMING_T;
-
-union noc_activate {
-	u32 d32;
-	struct {
-		unsigned rrd:4;
-		unsigned faw:6;
-		unsigned fawbank:1;
-		unsigned reserved1:21;
-	} b;
-};
-
-union noc_devtodev {
-	u32 d32;
-	struct {
-		unsigned busrdtord:2;
-		unsigned busrdtowr:2;
-		unsigned buswrtord:2;
-		unsigned reserved2:26;
-	} b;
-};
-
-union noc_ddr4timing {
-	u32 d32;
-	struct {
-		unsigned ccdl:3;
-		unsigned wrtordl:5;
-		unsigned rrdl:4;
-		unsigned reserved2:20;
-	} b;
+u16 ddr_cfg_2_rbc[] = {
+	/*
+	 * [5:4]  row(13+n)
+	 * [3]    cs(0:0 cs, 1:2 cs)
+	 * [2]  bank(0:0bank,1:8bank)
+	 * [1:0]    col(11+n)
+	 */
+	/* row,        cs,       bank,   col */
+	((3 << 4) | (0 << 3) | (1 << 2) | 0),
+	((3 << 4) | (0 << 3) | (1 << 2) | 1),
+	((2 << 4) | (0 << 3) | (1 << 2) | 2),
+	((3 << 4) | (0 << 3) | (1 << 2) | 2),
+	((2 << 4) | (0 << 3) | (1 << 2) | 3),
+	((3 << 4) | (1 << 3) | (1 << 2) | 0),
+	((3 << 4) | (1 << 3) | (1 << 2) | 1),
+	((2 << 4) | (1 << 3) | (1 << 2) | 2),
+	((3 << 4) | (0 << 3) | (0 << 2) | 1),
+	((2 << 4) | (0 << 3) | (1 << 2) | 1),
 };
 
-union noc_ddrmode {
-	u32 d32;
-	struct {
-		unsigned autoprecharge:1;
-		unsigned bwratioextended:1;
-		unsigned reserved3:30;
-	} b;
+u16 ddr4_cfg_2_rbc[] = {
+	/***************************
+	 * [6]	cs 0:0cs 1:2 cs
+	 * [5:3]  row(13+n)
+	 * [2]  cs(0:0 cs, 1:2 cs)
+	 * [1]  bw    0: 16bit 1:32bit
+	 * [0]  diebw 0:8bit 1:16bit
+	 ***************************/
+	/*  cs,       row,        cs,       bw,   diebw */
+	((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
+	((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
+	((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
+	((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
+	((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
+	((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
+	((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
+	((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
+	((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
+	((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
+	((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
 };
 
 u32 addrmap[21][9] = {
@@ -356,17 +162,65 @@
 		0x07070707, 0x00000f07, 0x3f00}
 };
 
-struct rk3328_msch_timings {
-	union noc_ddrtiming ddrtiming;
-	union noc_ddrmode ddrmode;
-	u32 readlatency;
-	union noc_activate activate;
-	union noc_devtodev devtodev;
-	union noc_ddr4timing ddr4timing;
-	u32 agingx0;
+struct rk3328_ddr_grf_regs {
+	u32 ddr_grf_con[4];
+	u32 reserved[(0x100 - 0x10) / 4];
+	u32 ddr_grf_status[11];
 };
 
-struct rk3328_msch_regs {
+union noc_ddrtiming {
+	u32 d32;
+	struct {
+		unsigned acttoact:6;
+		unsigned rdtomiss:6;
+		unsigned wrtomiss:6;
+		unsigned burstlen:3;
+		unsigned rdtowr:5;
+		unsigned wrtord:5;
+		unsigned bwratio:1;
+	} b;
+};
+
+union noc_activate {
+	u32 d32;
+	struct {
+		unsigned rrd:4;
+		unsigned faw:6;
+		unsigned fawbank:1;
+		unsigned reserved1:21;
+	} b;
+};
+
+union noc_devtodev {
+	u32 d32;
+	struct {
+		unsigned busrdtord:2;
+		unsigned busrdtowr:2;
+		unsigned buswrtord:2;
+		unsigned reserved2:26;
+	} b;
+};
+
+union noc_ddr4timing {
+	u32 d32;
+	struct {
+		unsigned ccdl:3;
+		unsigned wrtordl:5;
+		unsigned rrdl:4;
+		unsigned reserved2:20;
+	} b;
+};
+
+union noc_ddrmode {
+	u32 d32;
+	struct {
+		unsigned autoprecharge:1;
+		unsigned bwratioextended:1;
+		unsigned reserved3:30;
+	} b;
+};
+
+struct msch_regs {
 	u32 coreid;
 	u32 revisionid;
 	u32 ddrconf;
@@ -385,58 +239,27 @@
 	u32 ddr4_timing;
 };
 
-struct rk3328_ddr_grf_regs {
-	u32 ddr_grf_con[4];
-	u32 reserved[(0x100 - 0x10) / 4];
-	u32 ddr_grf_status[11];
-};
-
-struct rk3328_ddr_pctl_regs {
-	u32 pctl[30][2];
-};
-
-struct rk3328_ddr_phy_regs {
-	u32 phy[5][2];
-};
-
-struct rk3328_ddr_skew {
-	u32 a0_a1_skew[15];
-	u32 cs0_dm0_skew[11];
-	u32 cs0_dm1_skew[11];
-	u32 cs0_dm2_skew[11];
-	u32 cs0_dm3_skew[11];
-	u32 cs1_dm0_skew[11];
-	u32 cs1_dm1_skew[11];
-	u32 cs1_dm2_skew[11];
-	u32 cs1_dm3_skew[11];
+struct sdram_msch_timings {
+	union noc_ddrtiming ddrtiming;
+	union noc_ddrmode ddrmode;
+	u32 readlatency;
+	union noc_activate activate;
+	union noc_devtodev devtodev;
+	union noc_ddr4timing ddr4timing;
+	u32 agingx0;
 };
 
 struct rk3328_sdram_channel {
-	unsigned int rank;
-	unsigned int col;
-	/* 3:8bank, 2:4bank */
-	unsigned int bk;
-	/* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
-	unsigned int bw;
-	/* die buswidth, 2:32bit, 1:16bit, 0:8bit */
-	unsigned int dbw;
-	unsigned int row_3_4;
-	unsigned int cs0_row;
-	unsigned int cs1_row;
-	unsigned int ddrconfig;
-	struct rk3328_msch_timings noc_timings;
+	struct sdram_cap_info cap_info;
+	struct sdram_msch_timings noc_timings;
 };
 
 struct rk3328_sdram_params {
 	struct rk3328_sdram_channel ch;
-	unsigned int ddr_freq;
-	unsigned int dramtype;
-	unsigned int odt;
-	struct rk3328_ddr_pctl_regs pctl_regs;
-	struct rk3328_ddr_phy_regs phy_regs;
-	struct rk3328_ddr_skew skew;
+	struct sdram_base_params base;
+	struct ddr_pctl_regs pctl_regs;
+	struct ddr_phy_regs phy_regs;
+	struct ddr_phy_skew skew;
 };
 
-#define PHY_REG(base, n)		(base + 4 * (n))
-
 #endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index f5a80b4..5f1ad51 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -115,6 +115,7 @@
 	select TPL_NEEDS_SEPARATE_TEXT_BASE if TPL
 	select TPL_NEEDS_SEPARATE_STACK if TPL
 	imply ROCKCHIP_COMMON_BOARD
+	imply ROCKCHIP_SDRAM_COMMON
 	imply SPL_ROCKCHIP_COMMON_BOARD
 	imply SPL_SERIAL_SUPPORT
 	imply TPL_SERIAL_SUPPORT
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index cc6164e..a59dab4 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -45,7 +45,6 @@
 CONFIG_TPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
-CONFIG_TPL_CLK=y
 CONFIG_FASTBOOT_BUF_ADDR=0x800800
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
@@ -75,6 +74,7 @@
 CONFIG_DEBUG_UART_ANNOUNCE=y
 CONFIG_DEBUG_UART_SKIP_INIT=y
 CONFIG_SYSRESET=y
+# CONFIG_TPL_SYSRESET is not set
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig
index b128635..021f982 100644
--- a/configs/rock64-rk3328_defconfig
+++ b/configs/rock64-rk3328_defconfig
@@ -47,7 +47,6 @@
 CONFIG_TPL_SYSCON=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
-CONFIG_TPL_CLK=y
 CONFIG_FASTBOOT_BUF_ADDR=0x800800
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
@@ -76,6 +75,7 @@
 CONFIG_BAUDRATE=1500000
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_SYSRESET=y
+# CONFIG_TPL_SYSRESET is not set
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index 4bfc3d9..b477f70 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -9,6 +9,6 @@
 obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
 obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
 obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
-obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o
+obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o
 obj-$(CONFIG_RAM_RK3399) += sdram_rk3399.o
 obj-$(CONFIG_ROCKCHIP_SDRAM_COMMON) += sdram_common.o
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index e791933..69521ce 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -20,11 +20,11 @@
 
 struct dram_info {
 #ifdef CONFIG_TPL_BUILD
-	struct rk3328_ddr_pctl_regs *pctl;
-	struct rk3328_ddr_phy_regs *phy;
+	struct ddr_pctl_regs *pctl;
+	struct ddr_phy_regs *phy;
 	struct clk ddr_clk;
 	struct rk3328_cru *cru;
-	struct rk3328_msch_regs *msch;
+	struct msch_regs *msch;
 	struct rk3328_ddr_grf_regs *ddr_grf;
 #endif
 	struct ram_info info;
@@ -71,10 +71,11 @@
 	writel(ddrctrl_asrstn_req(ctl_srstn), &dram->cru->softrst_con[9]);
 }
 
-static void rkclk_set_dpll(struct dram_info *dram, unsigned int mhz)
+static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
 {
 	unsigned int refdiv, postdiv1, postdiv2, fbdiv;
 	int delay = 1000;
+	u32 mhz = hz / MHZ;
 
 	refdiv = 1;
 	if (mhz <= 300) {
@@ -122,115 +123,47 @@
 	clrbits_le32(PHY_REG(phy_base, 0xef), 1 << 7);
 
 	/* for inno ddr phy need 2*freq */
-	rkclk_set_dpll(dram,  sdram_params->ddr_freq * 2);
+	rkclk_set_dpll(dram,  sdram_params->base.ddr_freq * MHZ * 2);
 }
 
-static void phy_soft_reset(struct dram_info *dram)
-{
-	void __iomem *phy_base = dram->phy;
-
-	clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
-	udelay(1);
-	setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
-	udelay(5);
-	setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
-	udelay(1);
-}
-
-static int pctl_cfg(struct dram_info *dram,
-		    struct rk3328_sdram_params *sdram_params)
-{
-	u32 i;
-	void __iomem *pctl_base = dram->pctl;
-
-	for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
-		writel(sdram_params->pctl_regs.pctl[i][1],
-		       pctl_base + sdram_params->pctl_regs.pctl[i][0]);
-	}
-	clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
-			(0xff << 16) | 0x1f,
-			((SR_IDLE & 0xff) << 16) | (PD_IDLE & 0x1f));
-	/*
-	 * dfi_lp_en_pd=1,dfi_lp_wakeup_pd=2
-	 * hw_lp_idle_x32=1
-	 */
-	if (sdram_params->dramtype == LPDDR3) {
-		setbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0, 1);
-		clrsetbits_le32(pctl_base + DDR_PCTL2_DFILPCFG0,
-				0xf << 4,
-				2 << 4);
-	}
-	clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
-			0xfff << 16,
-			1 << 16);
-	/* disable zqcs */
-	setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
-	setbits_le32(pctl_base + 0x2000 + DDR_PCTL2_ZQCTL0, 1u << 31);
-
-	return 0;
-}
-
 /* return ddrconfig value
  *       (-1), find ddrconfig fail
  *       other, the ddrconfig value
  * only support cs0_row >= cs1_row
  */
-static unsigned int calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
+static u32 calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
 {
-	static const u16 ddr_cfg_2_rbc[] = {
-		/***************************
-		 * [5:4]  row(13+n)
-		 * [3]    cs(0:0 cs, 1:2 cs)
-		 * [2]  bank(0:0bank,1:8bank)
-		 * [1:0]    col(11+n)
-		 ****************************/
-		/* row,        cs,       bank,   col */
-		((3 << 4) | (0 << 3) | (1 << 2) | 0),
-		((3 << 4) | (0 << 3) | (1 << 2) | 1),
-		((2 << 4) | (0 << 3) | (1 << 2) | 2),
-		((3 << 4) | (0 << 3) | (1 << 2) | 2),
-		((2 << 4) | (0 << 3) | (1 << 2) | 3),
-		((3 << 4) | (1 << 3) | (1 << 2) | 0),
-		((3 << 4) | (1 << 3) | (1 << 2) | 1),
-		((2 << 4) | (1 << 3) | (1 << 2) | 2),
-		((3 << 4) | (0 << 3) | (0 << 2) | 1),
-		((2 << 4) | (0 << 3) | (1 << 2) | 1),
-	};
-
-	static const u16 ddr4_cfg_2_rbc[] = {
-		/***************************
-		 * [6]	cs 0:0cs 1:2 cs
-		 * [5:3]  row(13+n)
-		 * [2]  cs(0:0 cs, 1:2 cs)
-		 * [1]  bw    0: 16bit 1:32bit
-		 * [0]  diebw 0:8bit 1:16bit
-		 ***************************/
-		/*  cs,       row,        cs,       bw,   diebw */
-		((0 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 0),
-		((1 << 6) | (2 << 3) | (0 << 2) | (1 << 1) | 0),
-		((0 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 0),
-		((1 << 6) | (3 << 3) | (0 << 2) | (0 << 1) | 0),
-		((0 << 6) | (4 << 3) | (0 << 2) | (1 << 1) | 1),
-		((1 << 6) | (3 << 3) | (0 << 2) | (1 << 1) | 1),
-		((1 << 6) | (4 << 3) | (0 << 2) | (0 << 1) | 1),
-		((0 << 6) | (2 << 3) | (1 << 2) | (1 << 1) | 0),
-		((0 << 6) | (3 << 3) | (1 << 2) | (0 << 1) | 0),
-		((0 << 6) | (3 << 3) | (1 << 2) | (1 << 1) | 1),
-		((0 << 6) | (4 << 3) | (1 << 2) | (0 << 1) | 1),
-	};
-
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
 	u32 cs, bw, die_bw, col, row, bank;
+	u32 cs1_row;
 	u32 i, tmp;
 	u32 ddrconf = -1;
 
+	cs = cap_info->rank;
+	bw = cap_info->bw;
+	die_bw = cap_info->dbw;
+	col = cap_info->col;
+	row = cap_info->cs0_row;
+	cs1_row = cap_info->cs1_row;
+	bank = cap_info->bk;
+
-	cs = sdram_ch.rank;
-	bw = sdram_ch.bw;
-	die_bw = sdram_ch.dbw;
-	col = sdram_ch.col;
-	row = sdram_ch.cs0_row;
-	bank = sdram_ch.bk;
+	if (sdram_params->base.dramtype == DDR4) {
+		/* when DDR_TEST, CS always at MSB position for easy test */
+		if (cs == 2 && row == cs1_row) {
+			/* include 2cs cap both 2^n  or both (2^n - 2^(n-2)) */
+			tmp = ((row - 13) << 3) | (1 << 2) | (bw & 0x2) |
+			      die_bw;
+			for (i = 17; i < 21; i++) {
+				if (((tmp & 0x7) ==
+				     (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
+				    ((tmp & 0x3c) <=
+				     (ddr4_cfg_2_rbc[i - 10] & 0x3c))) {
+					ddrconf = i;
+					goto out;
+				}
+			}
+		}
 
-	if (sdram_params->dramtype == DDR4) {
 		tmp = ((cs - 1) << 6) | ((row - 13) << 3) | (bw & 0x2) | die_bw;
 		for (i = 10; i < 17; i++) {
 			if (((tmp & 0x7) == (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
@@ -246,6 +179,18 @@
 			goto out;
 		}
 
+		/* when DDR_TEST, CS always at MSB position for easy test */
+		if (cs == 2 && row == cs1_row) {
+			/* include 2cs cap both 2^n  or both (2^n - 2^(n-2)) */
+			for (i = 5; i < 8; i++) {
+				if ((bw + col - 11) == (ddr_cfg_2_rbc[i] &
+							0x3)) {
+					ddrconf = i;
+					goto out;
+				}
+			}
+		}
+
 		tmp = ((row - 13) << 4) | (1 << 2) | ((bw + col - 11) << 0);
 		for (i = 0; i < 5; i++)
 			if (((tmp & 0xf) == (ddr_cfg_2_rbc[i] & 0xf)) &&
@@ -257,23 +202,11 @@
 
 out:
 	if (ddrconf > 20)
-		printf("calculate_ddrconfig error\n");
+		printf("calculate ddrconfig error\n");
 
 	return ddrconf;
 }
 
-/* n: Unit bytes */
-static void copy_to_reg(u32 *dest, u32 *src, u32 n)
-{
-	int i;
-
-	for (i = 0; i < n / sizeof(u32); i++) {
-		writel(*src, dest);
-		src++;
-		dest++;
-	}
-}
-
 /*******
  * calculate controller dram address map, and setting to register.
  * argument sdram_ch.ddrconf must be right value before
@@ -282,274 +215,43 @@
 static void set_ctl_address_map(struct dram_info *dram,
 				struct rk3328_sdram_params *sdram_params)
 {
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
 	void __iomem *pctl_base = dram->pctl;
 
-	copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
-		    &addrmap[sdram_ch.ddrconfig][0], 9 * 4);
-	if (sdram_params->dramtype == LPDDR3 && sdram_ch.row_3_4)
+	sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
+			  &addrmap[cap_info->ddrconfig][0], 9 * 4);
+	if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4)
 		setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
-	if (sdram_params->dramtype == DDR4 && sdram_ch.bw == 0x1)
+	if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1)
 		setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
 
-	if (sdram_ch.rank == 1)
+	if (cap_info->rank == 1)
 		clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f);
 }
 
-static void phy_dll_bypass_set(struct dram_info *dram, u32 freq)
-{
-	u32 tmp;
-	void __iomem *phy_base = dram->phy;
-
-	setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
-	setbits_le32(PHY_REG(phy_base, 0x26), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x27), 1 << 3);
-	setbits_le32(PHY_REG(phy_base, 0x36), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x37), 1 << 3);
-	setbits_le32(PHY_REG(phy_base, 0x46), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x47), 1 << 3);
-	setbits_le32(PHY_REG(phy_base, 0x56), 1 << 4);
-	clrbits_le32(PHY_REG(phy_base, 0x57), 1 << 3);
-
-	if (freq <= 400)
-		/* DLL bypass */
-		setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
-	else
-		clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
-	if (freq <= 680)
-		tmp = 2;
-	else
-		tmp = 1;
-	writel(tmp, PHY_REG(phy_base, 0x28));
-	writel(tmp, PHY_REG(phy_base, 0x38));
-	writel(tmp, PHY_REG(phy_base, 0x48));
-	writel(tmp, PHY_REG(phy_base, 0x58));
-}
-
-static void set_ds_odt(struct dram_info *dram,
-		       struct rk3328_sdram_params *sdram_params)
-{
-	u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
-	void __iomem *phy_base = dram->phy;
-
-	if (sdram_params->dramtype == DDR3) {
-		cmd_drv = PHY_DDR3_RON_RTT_34ohm;
-		clk_drv = PHY_DDR3_RON_RTT_45ohm;
-		dqs_drv = PHY_DDR3_RON_RTT_34ohm;
-		dqs_odt = PHY_DDR3_RON_RTT_225ohm;
-	} else {
-		cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
-		clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
-		dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
-		dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
-	}
-	/* DS */
-	writel(cmd_drv, PHY_REG(phy_base, 0x11));
-	clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
-	writel(clk_drv, PHY_REG(phy_base, 0x16));
-	writel(clk_drv, PHY_REG(phy_base, 0x18));
-	writel(dqs_drv, PHY_REG(phy_base, 0x20));
-	writel(dqs_drv, PHY_REG(phy_base, 0x2f));
-	writel(dqs_drv, PHY_REG(phy_base, 0x30));
-	writel(dqs_drv, PHY_REG(phy_base, 0x3f));
-	writel(dqs_drv, PHY_REG(phy_base, 0x40));
-	writel(dqs_drv, PHY_REG(phy_base, 0x4f));
-	writel(dqs_drv, PHY_REG(phy_base, 0x50));
-	writel(dqs_drv, PHY_REG(phy_base, 0x5f));
-	/* ODT */
-	writel(dqs_odt, PHY_REG(phy_base, 0x21));
-	writel(dqs_odt, PHY_REG(phy_base, 0x2e));
-	writel(dqs_odt, PHY_REG(phy_base, 0x31));
-	writel(dqs_odt, PHY_REG(phy_base, 0x3e));
-	writel(dqs_odt, PHY_REG(phy_base, 0x41));
-	writel(dqs_odt, PHY_REG(phy_base, 0x4e));
-	writel(dqs_odt, PHY_REG(phy_base, 0x51));
-	writel(dqs_odt, PHY_REG(phy_base, 0x5e));
-}
-
-static void phy_cfg(struct dram_info *dram,
-		    struct rk3328_sdram_params *sdram_params)
-{
-	u32 i;
-	void __iomem *phy_base = dram->phy;
-
-	phy_dll_bypass_set(dram, sdram_params->ddr_freq);
-	for (i = 0; sdram_params->phy_regs.phy[i][0] != 0xFFFFFFFF; i++) {
-		writel(sdram_params->phy_regs.phy[i][1],
-		       phy_base + sdram_params->phy_regs.phy[i][0]);
-	}
-	if (sdram_ch.bw == 2) {
-		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
-	} else {
-		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
-		/* disable DQS2,DQS3 tx dll  for saving power */
-		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
-		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
-	}
-	set_ds_odt(dram, sdram_params);
-	/* deskew */
-	setbits_le32(PHY_REG(phy_base, 2), 8);
-	copy_to_reg(PHY_REG(phy_base, 0xb0),
-		    &sdram_params->skew.a0_a1_skew[0], 15 * 4);
-	copy_to_reg(PHY_REG(phy_base, 0x70),
-		    &sdram_params->skew.cs0_dm0_skew[0], 44 * 4);
-	copy_to_reg(PHY_REG(phy_base, 0xc0),
-		    &sdram_params->skew.cs1_dm0_skew[0], 44 * 4);
-}
-
-static int update_refresh_reg(struct dram_info *dram)
-{
-	void __iomem *pctl_base = dram->pctl;
-	u32 ret;
-
-	ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
-	writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
-
-	return 0;
-}
-
 static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
 {
-	u32 ret;
-	u32 dis_auto_zq = 0;
-	void __iomem *pctl_base = dram->pctl;
-	void __iomem *phy_base = dram->phy;
-
-	/* disable zqcs */
-	if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
-		(1ul << 31))) {
-		dis_auto_zq = 1;
-		setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
-	}
-	/* disable auto refresh */
-	setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
-	update_refresh_reg(dram);
-
-	if (dramtype == DDR4) {
-		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
-		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
-		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
-		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
-	}
-	/* choose training cs */
-	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
-	/* enable gate training */
-	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
-	udelay(50);
-	ret = readl(PHY_REG(phy_base, 0xff));
-	/* disable gate training */
-	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
-	/* restore zqcs */
-	if (dis_auto_zq)
-		clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
-	/* restore auto refresh */
-	clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
-	update_refresh_reg(dram);
-
-	if (dramtype == DDR4) {
-		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
-		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
-		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
-		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
-	}
-
-	if (ret & 0x10) {
-		ret = -1;
-	} else {
-		ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
-		ret = (ret == 0) ? 0 : -1;
-	}
-	return ret;
-}
-
-/* rank = 1: cs0
- * rank = 2: cs1
- * rank = 3: cs0 & cs1
- * note: be careful of keep mr original val
- */
-static int write_mr(struct dram_info *dram, u32 rank, u32 mr_num, u32 arg,
-		    u32 dramtype)
-{
 	void __iomem *pctl_base = dram->pctl;
-
-	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
-		continue;
-	if (dramtype == DDR3 || dramtype == DDR4) {
-		writel((mr_num << 12) | (rank << 4) | (0 << 0),
-		       pctl_base + DDR_PCTL2_MRCTRL0);
-		writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
-	} else {
-		writel((rank << 4) | (0 << 0),
-		       pctl_base + DDR_PCTL2_MRCTRL0);
-		writel((mr_num << 8) | (arg & 0xff),
-		       pctl_base + DDR_PCTL2_MRCTRL1);
-	}
-
-	setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
-	while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
-		continue;
-	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
-		continue;
-
-	return 0;
-}
-
-/*
- * rank : 1:cs0, 2:cs1, 3:cs0&cs1
- * vrefrate: 4500: 45%,
- */
-static int write_vrefdq(struct dram_info *dram, u32 rank, u32 vrefrate,
-			u32 dramtype)
-{
-	u32 tccd_l, value;
 	u32 dis_auto_zq = 0;
-	void __iomem *pctl_base = dram->pctl;
-
-	if (dramtype != DDR4 || vrefrate < 4500 || vrefrate > 9200)
-		return -1;
+	u32 pwrctl;
+	u32 ret;
 
-	tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
-	tccd_l = (tccd_l - 4) << 10;
+	/* disable auto low-power */
+	pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
+	writel(0, pctl_base + DDR_PCTL2_PWRCTL);
 
-	if (vrefrate > 7500) {
-		/* range 1 */
-		value = ((vrefrate - 6000) / 65) | tccd_l;
-	} else {
-		/* range 2 */
-		value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
-	}
+	dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
 
-	/* disable zqcs */
-	if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
-		(1ul << 31))) {
-		dis_auto_zq = 1;
-		setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
-	}
-	/* disable auto refresh */
-	setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
-	update_refresh_reg(dram);
+	ret = phy_data_training(dram->phy, cs, dramtype);
 
-	/* enable vrefdq calibratin */
-	write_mr(dram, rank, 6, value | (1 << 7), dramtype);
-	udelay(1);/* tvrefdqe */
-	/* write vrefdq value */
-	write_mr(dram, rank, 6, value | (1 << 7), dramtype);
-	udelay(1);/* tvref_time */
-	write_mr(dram, rank, 6, value | (0 << 7), dramtype);
-	udelay(1);/* tvrefdqx */
+	pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
 
-	/* restore zqcs */
-	if (dis_auto_zq)
-		clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
-	/* restore auto refresh */
-	clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
-	update_refresh_reg(dram);
+	/* restore auto low-power */
+	writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
 
-	return 0;
+	return ret;
 }
 
-#define _MAX_(x, y) ((x) > (y) ? (x) : (y))
-
 static void rx_deskew_switch_adjust(struct dram_info *dram)
 {
 	u32 i, deskew_val;
@@ -557,7 +259,7 @@
 	void __iomem *phy_base = dram->phy;
 
 	for (i = 0; i < 4; i++)
-		gate_val = _MAX_(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
+		gate_val = MAX(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
 
 	deskew_val = (gate_val >> 3) + 1;
 	deskew_val = (deskew_val > 0x1f) ? 0x1f : deskew_val;
@@ -566,8 +268,6 @@
 			(deskew_val & 0x1c) << 2);
 }
 
-#undef _MAX_
-
 static void tx_deskew_switch_adjust(struct dram_info *dram)
 {
 	void __iomem *phy_base = dram->phy;
@@ -580,40 +280,39 @@
 	writel(ddrconfig, &dram->msch->ddrconf);
 }
 
-static void dram_all_config(struct dram_info *dram,
-			    struct rk3328_sdram_params *sdram_params)
+static void sdram_msch_config(struct msch_regs *msch,
+			      struct sdram_msch_timings *noc_timings)
 {
-	u32 sys_reg = 0, tmp = 0;
+	writel(noc_timings->ddrtiming.d32, &msch->ddrtiming);
 
-	set_ddrconfig(dram, sdram_ch.ddrconfig);
+	writel(noc_timings->ddrmode.d32, &msch->ddrmode);
+	writel(noc_timings->readlatency, &msch->readlatency);
 
-	sys_reg |= SYS_REG_ENC_DDRTYPE(sdram_params->dramtype);
-	sys_reg |= SYS_REG_ENC_ROW_3_4(sdram_ch.row_3_4, 0);
-	sys_reg |= SYS_REG_ENC_RANK(sdram_ch.rank, 0);
-	sys_reg |= SYS_REG_ENC_COL(sdram_ch.col, 0);
-	sys_reg |= SYS_REG_ENC_BK(sdram_ch.bk, 0);
-	SYS_REG_ENC_CS0_ROW(sdram_ch.cs0_row, sys_reg, tmp, 0);
-	if (sdram_ch.cs1_row)
-		SYS_REG_ENC_CS1_ROW(sdram_ch.cs1_row, sys_reg, tmp, 0);
-	sys_reg |= SYS_REG_ENC_BW(sdram_ch.bw, 0);
-	sys_reg |= SYS_REG_ENC_DBW(sdram_ch.dbw, 0);
-
-	writel(sys_reg, &dram->grf->os_reg[2]);
+	writel(noc_timings->activate.d32, &msch->activate);
+	writel(noc_timings->devtodev.d32, &msch->devtodev);
+	writel(noc_timings->ddr4timing.d32, &msch->ddr4_timing);
+	writel(noc_timings->agingx0, &msch->aging0);
+	writel(noc_timings->agingx0, &msch->aging1);
+	writel(noc_timings->agingx0, &msch->aging2);
+	writel(noc_timings->agingx0, &msch->aging3);
+	writel(noc_timings->agingx0, &msch->aging4);
+	writel(noc_timings->agingx0, &msch->aging5);
+}
 
-	writel(sdram_ch.noc_timings.ddrtiming.d32, &dram->msch->ddrtiming);
+static void dram_all_config(struct dram_info *dram,
+			    struct rk3328_sdram_params *sdram_params)
+{
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+	u32 sys_reg2 = 0;
+	u32 sys_reg3 = 0;
 
-	writel(sdram_ch.noc_timings.ddrmode.d32, &dram->msch->ddrmode);
-	writel(sdram_ch.noc_timings.readlatency, &dram->msch->readlatency);
+	set_ddrconfig(dram, cap_info->ddrconfig);
+	sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
+			 &sys_reg3, 0);
+	writel(sys_reg2, &dram->grf->os_reg[2]);
+	writel(sys_reg3, &dram->grf->os_reg[3]);
 
-	writel(sdram_ch.noc_timings.activate.d32, &dram->msch->activate);
-	writel(sdram_ch.noc_timings.devtodev.d32, &dram->msch->devtodev);
-	writel(sdram_ch.noc_timings.ddr4timing.d32, &dram->msch->ddr4_timing);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging0);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging1);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging2);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging3);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging4);
-	writel(sdram_ch.noc_timings.agingx0, &dram->msch->aging5);
+	sdram_msch_config(dram->msch, &sdram_ch.noc_timings);
 }
 
 static void enable_low_power(struct dram_info *dram,
@@ -641,6 +340,7 @@
 static int sdram_init(struct dram_info *dram,
 		      struct rk3328_sdram_params *sdram_params, u32 pre_init)
 {
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
 	void __iomem *pctl_base = dram->pctl;
 
 	rkclk_ddr_reset(dram, 1, 1, 1, 1);
@@ -652,30 +352,18 @@
 	 */
 	rkclk_ddr_reset(dram, 1, 1, 1, 0);
 	rkclk_configure_ddr(dram, sdram_params);
-	if (pre_init == 0) {
-		switch (sdram_params->dramtype) {
-		case DDR3:
-			printf("DDR3\n");
-			break;
-		case DDR4:
-			printf("DDR4\n");
-			break;
-		case LPDDR3:
-		default:
-			printf("LPDDR3\n");
-			break;
-		}
-	}
+
 	/* release phy srst to provide clk to ctrl */
 	rkclk_ddr_reset(dram, 1, 1, 0, 0);
 	udelay(10);
-	phy_soft_reset(dram);
+	phy_soft_reset(dram->phy);
 	/* release ctrl presetn, and config ctl registers */
 	rkclk_ddr_reset(dram, 1, 0, 0, 0);
-	pctl_cfg(dram, sdram_params);
-	sdram_ch.ddrconfig = calculate_ddrconfig(sdram_params);
+	pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
+	cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
 	set_ctl_address_map(dram, sdram_params);
-	phy_cfg(dram, sdram_params);
+	phy_cfg(dram->phy, &sdram_params->phy_regs, &sdram_params->skew,
+		&sdram_params->base, cap_info->bw);
 
 	/* enable dfi_init_start to init phy after ctl srstn deassert */
 	setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
@@ -685,13 +373,18 @@
 		continue;
 
 	/* do ddr gate training */
-	if (data_training(dram, 0, sdram_params->dramtype) != 0) {
+	if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
+		printf("data training error\n");
+		return -1;
+	}
+	if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
 		printf("data training error\n");
 		return -1;
 	}
 
-	if (sdram_params->dramtype == DDR4)
-		write_vrefdq(dram, 0x3, 5670, sdram_params->dramtype);
+	if (sdram_params->base.dramtype == DDR4)
+		pctl_write_vrefdq(dram->pctl, 0x3, 5670,
+				  sdram_params->base.dramtype);
 
 	if (pre_init == 0) {
 		rx_deskew_switch_adjust(dram);
@@ -708,7 +401,7 @@
 			   struct rk3328_sdram_params *sdram_params,
 			   unsigned char channel)
 {
-	void __iomem *pctl_base = dram->pctl;
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
 
 	/*
 	 * for ddr3: ddrconf = 3
@@ -718,14 +411,10 @@
 	 */
 	u32 bk, bktmp;
 	u32 col, coltmp;
-	u32 row, rowtmp, row_3_4;
-	void __iomem *test_addr, *test_addr1;
-	u32 dbw;
+	u32 rowtmp;
 	u32 cs;
 	u32 bw = 1;
-	u64 cap = 0;
-	u32 dram_type = sdram_params->dramtype;
-	u32 pwrctl;
+	u32 dram_type = sdram_params->base.dramtype;
 
 	if (dram_type != DDR4) {
 		/* detect col and bk for ddr3/lpddr3 */
@@ -733,33 +422,10 @@
 		bktmp = 3;
 		rowtmp = 16;
 
-		for (col = coltmp; col >= 9; col -= 1) {
-			writel(0, SDRAM_ADDR);
-			test_addr = (void __iomem *)(SDRAM_ADDR +
-					(1ul << (col + bw - 1ul)));
-			writel(PATTERN, test_addr);
-			if ((readl(test_addr) == PATTERN) &&
-			    (readl(SDRAM_ADDR) == 0))
-				break;
-		}
-		if (col == 8) {
-			printf("col error\n");
+		if (sdram_detect_col(cap_info, coltmp) != 0)
 			goto cap_err;
-		}
-
-		test_addr = (void __iomem *)(SDRAM_ADDR +
-				(1ul << (coltmp + bktmp + bw - 1ul)));
-		writel(0, SDRAM_ADDR);
-		writel(PATTERN, test_addr);
-		if ((readl(test_addr) == PATTERN) &&
-		    (readl(SDRAM_ADDR) == 0))
-			bk = 3;
-		else
-			bk = 2;
-		if (dram_type == LPDDR3)
-			dbw = 2;
-		else
-			dbw = 1;
+		sdram_detect_bank(cap_info, coltmp, bktmp);
+		sdram_detect_dbw(cap_info, dram_type);
 	} else {
 		/* detect bg for ddr4 */
 		coltmp = 10;
@@ -768,178 +434,49 @@
 
 		col = 10;
 		bk = 2;
-		test_addr = (void __iomem *)(SDRAM_ADDR +
-				(1ul << (coltmp + bw + 1ul)));
-		writel(0, SDRAM_ADDR);
-		writel(PATTERN, test_addr);
-		if ((readl(test_addr) == PATTERN) &&
-		    (readl(SDRAM_ADDR) == 0))
-			dbw = 0;
-		else
-			dbw = 1;
+		cap_info->col = col;
+		cap_info->bk = bk;
+		sdram_detect_bg(cap_info, coltmp);
 	}
+
 	/* detect row */
-	for (row = rowtmp; row > 12; row--) {
-		writel(0, SDRAM_ADDR);
-		test_addr = (void __iomem *)(SDRAM_ADDR +
-				(1ul << (row + bktmp + coltmp + bw - 1ul)));
-		writel(PATTERN, test_addr);
-		if ((readl(test_addr) == PATTERN) &&
-		    (readl(SDRAM_ADDR) == 0))
-			break;
-	}
-	if (row == 12) {
-		printf("row error");
+	if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
 		goto cap_err;
-	}
-	/* detect row_3_4 */
-	test_addr = SDRAM_ADDR;
-	test_addr1 = (void __iomem *)(SDRAM_ADDR +
-			(0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
-
-	writel(0, test_addr);
-	writel(PATTERN, test_addr1);
-	if ((readl(test_addr) == 0) &&
-	    (readl(test_addr1) == PATTERN))
-		row_3_4 = 0;
-	else
-		row_3_4 = 1;
 
-	/* disable auto low-power */
-	pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
-	writel(0, pctl_base + DDR_PCTL2_PWRCTL);
+	/* detect row_3_4 */
+	sdram_detect_row_3_4(cap_info, coltmp, bktmp);
 
-	/* bw and cs detect using phy read gate training */
+	/* bw and cs detect using data training */
 	if (data_training(dram, 1, dram_type) == 0)
 		cs = 1;
 	else
 		cs = 0;
+	cap_info->rank = cs + 1;
 
 	bw = 2;
-
-	/* restore auto low-power */
-	writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
-
-	sdram_ch.rank = cs + 1;
-	sdram_ch.col = col;
-	sdram_ch.bk = bk;
-	sdram_ch.dbw = dbw;
-	sdram_ch.bw = bw;
-	sdram_ch.cs0_row = row;
-	if (cs)
-		sdram_ch.cs1_row = row;
-	else
-		sdram_ch.cs1_row = 0;
-	sdram_ch.row_3_4 = row_3_4;
-
-	if (dram_type == DDR4)
-		cap = 1llu << (cs + row + bk + col + ((dbw == 0) ? 2 : 1) + bw);
-	else
-		cap = 1llu << (cs + row + bk + col + bw);
-
-	return cap;
-
-cap_err:
-	return 0;
-}
-
-static u32 remodify_sdram_params(struct rk3328_sdram_params *sdram_params)
-{
-	u32 tmp = 0, tmp_adr = 0, i;
-
-	for (i = 0; sdram_params->pctl_regs.pctl[i][0] != 0xFFFFFFFF; i++) {
-		if (sdram_params->pctl_regs.pctl[i][0] == 0) {
-			tmp = sdram_params->pctl_regs.pctl[i][1];/* MSTR */
-			tmp_adr = i;
-		}
-	}
-
-	tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
+	cap_info->bw = bw;
 
-	switch (sdram_ch.dbw) {
-	case 2:
-		tmp |= (3ul << 30);
-		break;
-	case 1:
-		tmp |= (2ul << 30);
-		break;
-	case 0:
-	default:
-		tmp |= (1ul << 30);
-		break;
+	cap_info->cs0_high16bit_row = cap_info->cs0_row;
+	if (cs) {
+		cap_info->cs1_row = cap_info->cs0_row;
+		cap_info->cs1_high16bit_row = cap_info->cs0_row;
+	} else {
+		cap_info->cs1_row = 0;
+		cap_info->cs1_high16bit_row = 0;
 	}
 
-	if (sdram_ch.rank == 2)
-		tmp |= 3 << 24;
-	else
-		tmp |= 1 << 24;
-
-	tmp |= (2 - sdram_ch.bw) << 12;
-
-	sdram_params->pctl_regs.pctl[tmp_adr][1] = tmp;
-
-	if (sdram_ch.bw == 2)
-		sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
-	else
-		sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
-
 	return 0;
-}
-
-static int dram_detect_cs1_row(struct rk3328_sdram_params *sdram_params,
-			       unsigned char channel)
-{
-	u32 ret = 0;
-	u32 cs1_bit;
-	void __iomem *test_addr, *cs1_addr;
-	u32 row, bktmp, coltmp, bw;
-	u32 ddrconf = sdram_ch.ddrconfig;
-
-	if (sdram_ch.rank == 2) {
-		cs1_bit = addrmap[ddrconf][0] + 8;
-
-		if (cs1_bit > 31)
-			goto out;
-
-		cs1_addr = (void __iomem *)(1ul << cs1_bit);
-		if (cs1_bit < 20)
-			cs1_bit = 1;
-		else
-			cs1_bit = 0;
-
-		if (sdram_params->dramtype == DDR4) {
-			if (sdram_ch.dbw == 0)
-				bktmp = sdram_ch.bk + 2;
-			else
-				bktmp = sdram_ch.bk + 1;
-		} else {
-			bktmp = sdram_ch.bk;
-		}
-		bw = sdram_ch.bw;
-		coltmp = sdram_ch.col;
-
-		/* detect cs1 row */
-		for (row = sdram_ch.cs0_row; row > 12; row--) {
-			test_addr = (void __iomem *)(SDRAM_ADDR + cs1_addr +
-					(1ul << (row + cs1_bit + bktmp +
-					 coltmp + bw - 1ul)));
-			writel(0, SDRAM_ADDR + cs1_addr);
-			writel(PATTERN, test_addr);
-			if ((readl(test_addr) == PATTERN) &&
-			    (readl(SDRAM_ADDR + cs1_addr) == 0)) {
-				ret = row;
-				break;
-			}
-		}
-	}
-
-out:
-	return ret;
+cap_err:
+	return -1;
 }
 
 static int sdram_init_detect(struct dram_info *dram,
 			     struct rk3328_sdram_params *sdram_params)
 {
+	u32 sys_reg = 0;
+	u32 sys_reg3 = 0;
+	struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+
 	debug("Starting SDRAM initialization...\n");
 
 	memcpy(&sdram_ch, &sdram_params->ch,
@@ -949,13 +486,29 @@
 	dram_detect_cap(dram, sdram_params, 0);
 
 	/* modify bw, cs related timing */
-	remodify_sdram_params(sdram_params);
+	pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
+				   sdram_params->base.dramtype);
+
+	if (cap_info->bw == 2)
+		sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
+	else
+		sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
+
 	/* reinit sdram by real dram cap */
 	sdram_init(dram, sdram_params, 0);
 
 	/* redetect cs1 row */
-	sdram_ch.cs1_row =
-		dram_detect_cs1_row(sdram_params, 0);
+	sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
+	if (cap_info->cs1_row) {
+		sys_reg = readl(&dram->grf->os_reg[2]);
+		sys_reg3 = readl(&dram->grf->os_reg[3]);
+		SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
+				    sys_reg, sys_reg3, 0);
+		writel(sys_reg, &dram->grf->os_reg[2]);
+		writel(sys_reg3, &dram->grf->os_reg[3]);
+	}
+
+	sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base);
 
 	return 0;
 }