diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c
index fa697c7..fbee51d 100644
--- a/arch/arm/cpu/armv7/am33xx/ddr.c
+++ b/arch/arm/cpu/armv7/am33xx/ddr.c
@@ -36,6 +36,74 @@ static struct ddr_data_regs *ddr_data_reg[2] = {
 static struct ddr_cmdtctrl *ioctrl_reg = {
 			(struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
 
+static inline u32 get_mr(int nr, u32 cs, u32 mr_addr)
+{
+	u32 mr;
+
+	mr_addr |= cs << EMIF_REG_CS_SHIFT;
+	writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg);
+
+	mr = readl(&emif_reg[nr]->emif_lpddr2_mode_reg_data);
+	debug("get_mr: EMIF1 cs %d mr %08x val 0x%x\n", cs, mr_addr, mr);
+	if (((mr & 0x0000ff00) >>  8) == (mr & 0xff) &&
+	    ((mr & 0x00ff0000) >> 16) == (mr & 0xff) &&
+	    ((mr & 0xff000000) >> 24) == (mr & 0xff))
+		return mr & 0xff;
+	else
+		return mr;
+}
+
+static inline void set_mr(int nr, u32 cs, u32 mr_addr, u32 mr_val)
+{
+	mr_addr |= cs << EMIF_REG_CS_SHIFT;
+	writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg);
+	writel(mr_val, &emif_reg[nr]->emif_lpddr2_mode_reg_data);
+}
+
+static void configure_mr(int nr, u32 cs)
+{
+	u32 mr_addr;
+
+	while (get_mr(nr, cs, LPDDR2_MR0) & LPDDR2_MR0_DAI_MASK)
+		;
+	set_mr(nr, cs, LPDDR2_MR10, 0x56);
+
+	set_mr(nr, cs, LPDDR2_MR1, 0x43);
+	set_mr(nr, cs, LPDDR2_MR2, 0x2);
+
+	mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK;
+	set_mr(nr, cs, mr_addr, 0x2);
+}
+
+/*
+ * Configure EMIF4D5 registers and MR registers
+ */
+void config_sdram_emif4d5(const struct emif_regs *regs, int nr)
+{
+	writel(0x0, &emif_reg[nr]->emif_pwr_mgmt_ctrl);
+	writel(0x0, &emif_reg[nr]->emif_pwr_mgmt_ctrl_shdw);
+	writel(0x1, &emif_reg[nr]->emif_iodft_tlgc);
+	writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
+
+	writel(regs->temp_alert_config, &emif_reg[nr]->emif_temp_alert_config);
+	writel(regs->emif_rd_wr_lvl_rmp_win,
+	       &emif_reg[nr]->emif_rd_wr_lvl_rmp_win);
+	writel(regs->emif_rd_wr_lvl_rmp_ctl,
+	       &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
+	writel(regs->emif_rd_wr_lvl_ctl, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
+	writel(regs->emif_rd_wr_exec_thresh,
+	       &emif_reg[nr]->emif_rd_wr_exec_thresh);
+
+	clrbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
+		     EMIF_REG_INITREF_DIS_MASK);
+
+	writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
+	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
+
+	configure_mr(nr, 0);
+	configure_mr(nr, 1);
+}
+
 /**
  * Configure SDRAM
  */
@@ -72,15 +140,67 @@ void set_sdram_timings(const struct emif_regs *regs, int nr)
 	writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw);
 }
 
+void __weak emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size)
+{
+}
+
+/*
+ * Configure EXT PHY registers
+ */
+static void ext_phy_settings(const struct emif_regs *regs, int nr)
+{
+	u32 *ext_phy_ctrl_base = 0;
+	u32 *emif_ext_phy_ctrl_base = 0;
+	const u32 *ext_phy_ctrl_const_regs;
+	u32 i = 0;
+	u32 size;
+
+	ext_phy_ctrl_base = (u32 *)&(regs->emif_ddr_ext_phy_ctrl_1);
+	emif_ext_phy_ctrl_base =
+			(u32 *)&(emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
+
+	/* Configure external phy control timing registers */
+	for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
+		writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
+		/* Update shadow registers */
+		writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
+	}
+
+	/*
+	 * external phy 6-24 registers do not change with
+	 * ddr frequency
+	 */
+	emif_get_ext_phy_ctrl_const_regs(&ext_phy_ctrl_const_regs, &size);
+
+	if (!size)
+		return;
+
+	for (i = 0; i < size; i++) {
+		writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
+		/* Update shadow registers */
+		writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
+	}
+}
+
 /**
  * Configure DDR PHY
  */
 void config_ddr_phy(const struct emif_regs *regs, int nr)
 {
+	/*
+	 * disable initialization and refreshes for now until we
+	 * finish programming EMIF regs.
+	 */
+	setbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
+		     EMIF_REG_INITREF_DIS_MASK);
+
 	writel(regs->emif_ddr_phy_ctlr_1,
 		&emif_reg[nr]->emif_ddr_phy_ctrl_1);
 	writel(regs->emif_ddr_phy_ctlr_1,
 		&emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw);
+
+	if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5)
+		ext_phy_settings(regs, nr);
 }
 
 /**
@@ -88,6 +208,9 @@ void config_ddr_phy(const struct emif_regs *regs, int nr)
  */
 void config_cmd_ctrl(const struct cmd_control *cmd, int nr)
 {
+	if (!cmd)
+		return;
+
 	writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio);
 	writel(cmd->cmd0dldiff, &ddr_cmd_reg[nr]->cm0dldiff);
 	writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout);
@@ -108,6 +231,9 @@ void config_ddr_data(const struct ddr_data *data, int nr)
 {
 	int i;
 
+	if (!data)
+		return;
+
 	for (i = 0; i < DDR_DATA_REGS_NR; i++) {
 		writel(data->datardsratio0,
 			&(ddr_data_reg[nr]+i)->dt0rdsratio0);
@@ -128,11 +254,20 @@ void config_ddr_data(const struct ddr_data *data, int nr)
 	}
 }
 
-void config_io_ctrl(unsigned long val)
+void config_io_ctrl(const struct ctrl_ioregs *ioregs)
 {
-	writel(val, &ioctrl_reg->cm0ioctl);
-	writel(val, &ioctrl_reg->cm1ioctl);
-	writel(val, &ioctrl_reg->cm2ioctl);
-	writel(val, &ioctrl_reg->dt0ioctl);
-	writel(val, &ioctrl_reg->dt1ioctl);
+	if (!ioregs)
+		return;
+
+	writel(ioregs->cm0ioctl, &ioctrl_reg->cm0ioctl);
+	writel(ioregs->cm1ioctl, &ioctrl_reg->cm1ioctl);
+	writel(ioregs->cm2ioctl, &ioctrl_reg->cm2ioctl);
+	writel(ioregs->dt0ioctl, &ioctrl_reg->dt0ioctl);
+	writel(ioregs->dt1ioctl, &ioctrl_reg->dt1ioctl);
+#ifdef CONFIG_AM43XX
+	writel(ioregs->dt2ioctrl, &ioctrl_reg->dt2ioctrl);
+	writel(ioregs->dt3ioctrl, &ioctrl_reg->dt3ioctrl);
+	writel(ioregs->emif_sdram_config_ext,
+	       &ioctrl_reg->emif_sdram_config_ext);
+#endif
 }
diff --git a/arch/arm/cpu/armv7/am33xx/emif4.c b/arch/arm/cpu/armv7/am33xx/emif4.c
index 59ad25c..d28fceb 100644
--- a/arch/arm/cpu/armv7/am33xx/emif4.c
+++ b/arch/arm/cpu/armv7/am33xx/emif4.c
@@ -48,6 +48,11 @@ static struct vtp_reg *vtpreg[2] = {
 #ifdef CONFIG_AM33XX
 static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
 #endif
+#ifdef CONFIG_AM43XX
+static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+static struct cm_device_inst *cm_device =
+				(struct cm_device_inst *)CM_DEVICE_INST;
+#endif
 
 #ifdef CONFIG_TI81XX
 void config_dmm(const struct dmm_lisa_map_regs *regs)
@@ -87,7 +92,7 @@ void __weak ddr_pll_config(unsigned int ddrpll_m)
 {
 }
 
-void config_ddr(unsigned int pll, unsigned int ioctrl,
+void config_ddr(unsigned int pll, const struct ctrl_ioregs *ioregs,
 		const struct ddr_data *data, const struct cmd_control *ctrl,
 		const struct emif_regs *regs, int nr)
 {
@@ -99,7 +104,18 @@ void config_ddr(unsigned int pll, unsigned int ioctrl,
 
 	config_ddr_data(data, nr);
 #ifdef CONFIG_AM33XX
-	config_io_ctrl(ioctrl);
+	config_io_ctrl(ioregs);
+
+	/* Set CKE to be controlled by EMIF/DDR PHY */
+	writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
+#endif
+#ifdef CONFIG_AM43XX
+	writel(readl(&cm_device->cm_dll_ctrl) & ~0x1, &cm_device->cm_dll_ctrl);
+	while ((readl(&cm_device->cm_dll_ctrl) && CM_DLL_READYST) == 0)
+		;
+	writel(0x0, &ddrctrl->ddrioctrl);
+
+	config_io_ctrl(ioregs);
 
 	/* Set CKE to be controlled by EMIF/DDR PHY */
 	writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
@@ -108,6 +124,9 @@ void config_ddr(unsigned int pll, unsigned int ioctrl,
 	/* Program EMIF instance */
 	config_ddr_phy(regs, nr);
 	set_sdram_timings(regs, nr);
-	config_sdram(regs, nr);
+	if (get_emif_rev(EMIF1_BASE) == EMIF_4D5)
+		config_sdram_emif4d5(regs, nr);
+	else
+		config_sdram(regs, nr);
 }
 #endif
diff --git a/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h b/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
index 02ed595..4c9352a 100644
--- a/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
+++ b/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
@@ -28,6 +28,9 @@
 #define UART_CLK_RUNNING_MASK	0x1
 #define UART_SMART_IDLE_EN	(0x1 << 0x3)
 
+#define CM_DLL_CTRL_NO_OVERRIDE	0x0
+#define CM_DLL_READYST		0x4
+
 extern void enable_dmm_clocks(void);
 extern const struct dpll_params dpll_core_opp100;
 extern struct dpll_params dpll_mpu_opp100;
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h
index 19b8469..18d0458 100644
--- a/arch/arm/include/asm/arch-am33xx/cpu.h
+++ b/arch/arm/include/asm/arch-am33xx/cpu.h
@@ -401,6 +401,11 @@ struct cm_perpll {
 	unsigned int cpgmac0clkctrl;	/* offset 0xB20 */
 };
 
+struct cm_device_inst {
+	unsigned int cm_clkout1_ctrl;
+	unsigned int cm_dll_ctrl;
+};
+
 struct cm_dpll {
 	unsigned int resv1;
 	unsigned int clktimer2clk;	/* offset 0x04 */
diff --git a/arch/arm/include/asm/arch-am33xx/ddr_defs.h b/arch/arm/include/asm/arch-am33xx/ddr_defs.h
index fe48b5f..c98ab7f 100644
--- a/arch/arm/include/asm/arch-am33xx/ddr_defs.h
+++ b/arch/arm/include/asm/arch-am33xx/ddr_defs.h
@@ -19,7 +19,11 @@
 #define VTP_CTRL_ENABLE		(0x1 << 6)
 #define VTP_CTRL_START_EN	(0x1)
 #define PHY_DLL_LOCK_DIFF	0x0
+#ifdef CONFIG_AM43XX
+#define DDR_CKE_CTRL_NORMAL	0x3
+#else
 #define DDR_CKE_CTRL_NORMAL	0x1
+#endif
 #define PHY_EN_DYN_PWRDN	(0x1 << 20)
 
 /* Micron MT47H128M16RT-25E */
@@ -126,6 +130,14 @@
 #define K4B2G1646EBIH9_PHY_WR_DATA		0x76
 #define K4B2G1646EBIH9_IOCTRL_VALUE		0x18B
 
+#define  LPDDR2_ADDRCTRL_IOCTRL_VALUE   0x294
+#define  LPDDR2_ADDRCTRL_WD0_IOCTRL_VALUE 0x00000000
+#define  LPDDR2_ADDRCTRL_WD1_IOCTRL_VALUE 0x00000000
+#define  LPDDR2_DATA0_IOCTRL_VALUE   0x20000294
+#define  LPDDR2_DATA1_IOCTRL_VALUE   0x20000294
+#define  LPDDR2_DATA2_IOCTRL_VALUE   0x20000294
+#define  LPDDR2_DATA3_IOCTRL_VALUE   0x20000294
+
 /**
  * Configure DMM
  */
@@ -135,6 +147,7 @@ void config_dmm(const struct dmm_lisa_map_regs *regs);
  * Configure SDRAM
  */
 void config_sdram(const struct emif_regs *regs, int nr);
+void config_sdram_emif4d5(const struct emif_regs *regs, int nr);
 
 /**
  * Set SDRAM timings
@@ -291,12 +304,27 @@ struct ddr_cmdtctrl {
 	unsigned int resv2[12];
 	unsigned int dt0ioctl;
 	unsigned int dt1ioctl;
+	unsigned int dt2ioctrl;
+	unsigned int dt3ioctrl;
+	unsigned int resv3[4];
+	unsigned int emif_sdram_config_ext;
+};
+
+struct ctrl_ioregs {
+	unsigned int cm0ioctl;
+	unsigned int cm1ioctl;
+	unsigned int cm2ioctl;
+	unsigned int dt0ioctl;
+	unsigned int dt1ioctl;
+	unsigned int dt2ioctrl;
+	unsigned int dt3ioctrl;
+	unsigned int emif_sdram_config_ext;
 };
 
 /**
  * Configure DDR io control registers
  */
-void config_io_ctrl(unsigned long val);
+void config_io_ctrl(const struct ctrl_ioregs *ioregs);
 
 struct ddr_ctrl {
 	unsigned int ddrioctrl;
@@ -304,8 +332,9 @@ struct ddr_ctrl {
 	unsigned int ddrckectrl;
 };
 
-void config_ddr(unsigned int pll, unsigned int ioctrl,
+void config_ddr(unsigned int pll, const struct ctrl_ioregs *ioregs,
 		const struct ddr_data *data, const struct cmd_control *ctrl,
 		const struct emif_regs *regs, int nr);
+void emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size);
 
 #endif  /* _DDR_DEFS_H */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h b/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
index 64f9c99..efb7b0d 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
@@ -62,5 +62,6 @@
 #define PRM_PER_USBPHYOCP2SCP0_CLKCTRL (CM_PER + 0x5b8)
 #define PRM_PER_USBPHYOCP2SCP1_CLKCTRL (CM_PER + 0x5c0)
 #define USBPHYOCPSCP_MODULE_EN	(1 << 2)
+#define CM_DEVICE_INST			0x44df4100
 
 #endif /* __AM43XX_HARDWARE_AM43XX_H */
diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h
index 1b94a99..ce6b229 100644
--- a/arch/arm/include/asm/emif.h
+++ b/arch/arm/include/asm/emif.h
@@ -14,11 +14,15 @@
 #define _EMIF_H_
 #include <asm/types.h>
 #include <common.h>
+#include <asm/io.h>
 
 /* Base address */
 #define EMIF1_BASE				0x4c000000
 #define EMIF2_BASE				0x4d000000
 
+#define EMIF_4D					0x4
+#define EMIF_4D5				0x5
+
 /* Registers shifts, masks and values */
 
 /* EMIF_MOD_ID_REV */
@@ -1139,6 +1143,14 @@ struct lpddr2_mr_regs {
 	s8 mr16;
 };
 
+static inline u32 get_emif_rev(u32 base)
+{
+	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+	return (readl(&emif->emif_mod_id_rev) & EMIF_REG_MAJOR_REVISION_MASK)
+		>> EMIF_REG_MAJOR_REVISION_SHIFT;
+}
+
 /* assert macros */
 #if defined(DEBUG)
 #define emif_assert(c)	({ if (!(c)) for (;;); })
diff --git a/board/isee/igep0033/board.c b/board/isee/igep0033/board.c
index 0b8356d..2a1b75f 100644
--- a/board/isee/igep0033/board.c
+++ b/board/isee/igep0033/board.c
@@ -81,9 +81,17 @@ void set_mux_conf_regs(void)
 	enable_board_pin_mux();
 }
 
+const struct ctrl_ioregs ioregs = {
+	.cm0ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+	.cm1ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+	.cm2ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+	.dt0ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+	.dt1ioctl		= K4B2G1646EBIH9_IOCTRL_VALUE,
+};
+
 void sdram_init(void)
 {
-	config_ddr(400, K4B2G1646EBIH9_IOCTRL_VALUE, &ddr3_data,
+	config_ddr(400, &ioregs, &ddr3_data,
 		   &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
 }
 #endif
diff --git a/board/phytec/pcm051/board.c b/board/phytec/pcm051/board.c
index 034886a..f8e1951 100644
--- a/board/phytec/pcm051/board.c
+++ b/board/phytec/pcm051/board.c
@@ -96,10 +96,18 @@ void set_mux_conf_regs(void)
 	enable_board_pin_mux();
 }
 
+const struct ctrl_ioregs ioregs = {
+	.cm0ioctl		= MT41J256M8HX15E_IOCTRL_VALUE,
+	.cm1ioctl		= MT41J256M8HX15E_IOCTRL_VALUE,
+	.cm2ioctl		= MT41J256M8HX15E_IOCTRL_VALUE,
+	.dt0ioctl		= MT41J256M8HX15E_IOCTRL_VALUE,
+	.dt1ioctl		= MT41J256M8HX15E_IOCTRL_VALUE,
+};
+
 void sdram_init(void)
 {
-	config_ddr(DDR_CLK_MHZ, MT41J256M8HX15E_IOCTRL_VALUE, &ddr3_data,
-			&ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
+	config_ddr(DDR_CLK_MHZ, &ioregs, &ddr3_data, &ddr3_cmd_ctrl_data,
+		   &ddr3_emif_reg_data, 0);
 }
 #endif
 
diff --git a/board/siemens/dxr2/board.c b/board/siemens/dxr2/board.c
index af9d84f..df26340 100644
--- a/board/siemens/dxr2/board.c
+++ b/board/siemens/dxr2/board.c
@@ -147,6 +147,14 @@ struct cmd_control dxr2_ddr3_cmd_ctrl_data = {
 	.cmd1dldiff = 0,
 	.cmd2dldiff = 0,
 };
+
+const struct ctrl_ioregs ioregs = {
+	.cm0ioctl		= DXR2_IOCTRL_VAL,
+	.cm1ioctl		= DXR2_IOCTRL_VAL,
+	.cm2ioctl		= DXR2_IOCTRL_VAL,
+	.dt0ioctl		= DXR2_IOCTRL_VAL,
+	.dt1ioctl		= DXR2_IOCTRL_VAL,
+};
 	/* pass values from eeprom */
 	dxr2_ddr3_emif_reg_data.sdram_tim1 = settings.ddr3.sdram_tim1;
 	dxr2_ddr3_emif_reg_data.sdram_tim2 = settings.ddr3.sdram_tim2;
@@ -168,7 +176,7 @@ struct cmd_control dxr2_ddr3_cmd_ctrl_data = {
 	dxr2_ddr3_cmd_ctrl_data.cmd2csratio = settings.ddr3.ddr3_sratio;
 	dxr2_ddr3_cmd_ctrl_data.cmd2iclkout = settings.ddr3.iclkout;
 
-	config_ddr(DDR_PLL_FREQ, DXR2_IOCTRL_VAL, &dxr2_ddr3_data,
+	config_ddr(DDR_PLL_FREQ, &ioregs, &dxr2_ddr3_data,
 		   &dxr2_ddr3_cmd_ctrl_data, &dxr2_ddr3_emif_reg_data, 0);
 }
 
diff --git a/board/siemens/pxm2/board.c b/board/siemens/pxm2/board.c
index 2c1841f..16aec28 100644
--- a/board/siemens/pxm2/board.c
+++ b/board/siemens/pxm2/board.c
@@ -74,7 +74,15 @@ struct cmd_control pxm2_ddr3_cmd_ctrl_data = {
 	.cmd2iclkout = 0,
 };
 
-	config_ddr(DDR_PLL_FREQ, DXR2_IOCTRL_VAL, &pxm2_ddr3_data,
+const struct ctrl_ioregs ioregs = {
+	.cm0ioctl		= DXR2_IOCTRL_VAL,
+	.cm1ioctl		= DXR2_IOCTRL_VAL,
+	.cm2ioctl		= DXR2_IOCTRL_VAL,
+	.dt0ioctl		= DXR2_IOCTRL_VAL,
+	.dt1ioctl		= DXR2_IOCTRL_VAL,
+};
+
+	config_ddr(DDR_PLL_FREQ, &ioregs, &pxm2_ddr3_data,
 		   &pxm2_ddr3_cmd_ctrl_data, &pxm2_ddr3_emif_reg_data, 0);
 }
 
diff --git a/board/siemens/rut/board.c b/board/siemens/rut/board.c
index 5de8fc6..317350b 100644
--- a/board/siemens/rut/board.c
+++ b/board/siemens/rut/board.c
@@ -79,7 +79,15 @@ struct cmd_control rut_ddr3_cmd_ctrl_data = {
 	.cmd2iclkout = 1,
 };
 
-	config_ddr(DDR_PLL_FREQ, RUT_IOCTRL_VAL, &rut_ddr3_data,
+const struct ctrl_ioregs ioregs = {
+	.cm0ioctl		= RUT_IOCTRL_VAL,
+	.cm1ioctl		= RUT_IOCTRL_VAL,
+	.cm2ioctl		= RUT_IOCTRL_VAL,
+	.dt0ioctl		= RUT_IOCTRL_VAL,
+	.dt1ioctl		= RUT_IOCTRL_VAL,
+};
+
+	config_ddr(DDR_PLL_FREQ, &ioregs, &rut_ddr3_data,
 		   &rut_ddr3_cmd_ctrl_data, &rut_ddr3_emif_reg_data, 0);
 }
 
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index 8edd21b..aff2dba 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -443,6 +443,38 @@ void set_mux_conf_regs(void)
 	enable_board_pin_mux(&header);
 }
 
+const struct ctrl_ioregs ioregs_evmsk = {
+	.cm0ioctl		= MT41J128MJT125_IOCTRL_VALUE,
+	.cm1ioctl		= MT41J128MJT125_IOCTRL_VALUE,
+	.cm2ioctl		= MT41J128MJT125_IOCTRL_VALUE,
+	.dt0ioctl		= MT41J128MJT125_IOCTRL_VALUE,
+	.dt1ioctl		= MT41J128MJT125_IOCTRL_VALUE,
+};
+
+const struct ctrl_ioregs ioregs_bonelt = {
+	.cm0ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+	.cm1ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+	.cm2ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+	.dt0ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+	.dt1ioctl		= MT41K256M16HA125E_IOCTRL_VALUE,
+};
+
+const struct ctrl_ioregs ioregs_evm15 = {
+	.cm0ioctl		= MT41J512M8RH125_IOCTRL_VALUE,
+	.cm1ioctl		= MT41J512M8RH125_IOCTRL_VALUE,
+	.cm2ioctl		= MT41J512M8RH125_IOCTRL_VALUE,
+	.dt0ioctl		= MT41J512M8RH125_IOCTRL_VALUE,
+	.dt1ioctl		= MT41J512M8RH125_IOCTRL_VALUE,
+};
+
+const struct ctrl_ioregs ioregs = {
+	.cm0ioctl		= MT47H128M16RT25E_IOCTRL_VALUE,
+	.cm1ioctl		= MT47H128M16RT25E_IOCTRL_VALUE,
+	.cm2ioctl		= MT47H128M16RT25E_IOCTRL_VALUE,
+	.dt0ioctl		= MT47H128M16RT25E_IOCTRL_VALUE,
+	.dt1ioctl		= MT47H128M16RT25E_IOCTRL_VALUE,
+};
+
 void sdram_init(void)
 {
 	__maybe_unused struct am335x_baseboard_id header;
@@ -460,18 +492,18 @@ void sdram_init(void)
 	}
 
 	if (board_is_evm_sk(&header))
-		config_ddr(303, MT41J128MJT125_IOCTRL_VALUE, &ddr3_data,
+		config_ddr(303, &ioregs_evmsk, &ddr3_data,
 			   &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
 	else if (board_is_bone_lt(&header))
-		config_ddr(400, MT41K256M16HA125E_IOCTRL_VALUE,
+		config_ddr(400, &ioregs_bonelt,
 			   &ddr3_beagleblack_data,
 			   &ddr3_beagleblack_cmd_ctrl_data,
 			   &ddr3_beagleblack_emif_reg_data, 0);
 	else if (board_is_evm_15_or_later(&header))
-		config_ddr(303, MT41J512M8RH125_IOCTRL_VALUE, &ddr3_evm_data,
+		config_ddr(303, &ioregs_evm15, &ddr3_evm_data,
 			   &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data, 0);
 	else
-		config_ddr(266, MT47H128M16RT25E_IOCTRL_VALUE, &ddr2_data,
+		config_ddr(266, &ioregs, &ddr2_data,
 			   &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0);
 }
 #endif
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c
index 366bec3..10c6a2b 100644
--- a/board/ti/am43xx/board.c
+++ b/board/ti/am43xx/board.c
@@ -15,6 +15,8 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/mux.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/emif.h>
 #include "board.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -83,6 +85,69 @@ const struct dpll_params gp_evm_dpll_core = {
 const struct dpll_params gp_evm_dpll_per = {
 		960, 23, 5, -1, -1, -1, -1};
 
+const struct ctrl_ioregs ioregs_lpddr2 = {
+	.cm0ioctl		= LPDDR2_ADDRCTRL_IOCTRL_VALUE,
+	.cm1ioctl		= LPDDR2_ADDRCTRL_WD0_IOCTRL_VALUE,
+	.cm2ioctl		= LPDDR2_ADDRCTRL_WD1_IOCTRL_VALUE,
+	.dt0ioctl		= LPDDR2_DATA0_IOCTRL_VALUE,
+	.dt1ioctl		= LPDDR2_DATA0_IOCTRL_VALUE,
+	.dt2ioctrl		= LPDDR2_DATA0_IOCTRL_VALUE,
+	.dt3ioctrl		= LPDDR2_DATA0_IOCTRL_VALUE,
+	.emif_sdram_config_ext	= 0x1,
+};
+
+const struct emif_regs emif_regs_lpddr2 = {
+	.sdram_config			= 0x808012BA,
+	.ref_ctrl			= 0x0000040D,
+	.sdram_tim1			= 0xEA86B411,
+	.sdram_tim2			= 0x103A094A,
+	.sdram_tim3			= 0x0F6BA37F,
+	.read_idle_ctrl			= 0x00050000,
+	.zq_config			= 0x50074BE4,
+	.temp_alert_config		= 0x0,
+	.emif_rd_wr_lvl_rmp_win		= 0x0,
+	.emif_rd_wr_lvl_rmp_ctl		= 0x0,
+	.emif_rd_wr_lvl_ctl		= 0x0,
+	.emif_ddr_phy_ctlr_1		= 0x0E084006,
+	.emif_rd_wr_exec_thresh		= 0x00000405,
+	.emif_ddr_ext_phy_ctrl_1	= 0x04010040,
+	.emif_ddr_ext_phy_ctrl_2	= 0x00500050,
+	.emif_ddr_ext_phy_ctrl_3	= 0x00500050,
+	.emif_ddr_ext_phy_ctrl_4	= 0x00500050,
+	.emif_ddr_ext_phy_ctrl_5	= 0x00500050
+};
+
+const u32 ext_phy_ctrl_const_base_lpddr2[] = {
+	0x00500050,
+	0x00350035,
+	0x00350035,
+	0x00350035,
+	0x00350035,
+	0x00350035,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x40001000,
+	0x08102040
+};
+
+void emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size)
+{
+	*regs = ext_phy_ctrl_const_base_lpddr2;
+	*size = ARRAY_SIZE(ext_phy_ctrl_const_base_lpddr2);
+
+	return;
+}
+
 const struct dpll_params *get_dpll_ddr_params(void)
 {
 	if (board_is_eposevm())
@@ -134,6 +199,7 @@ void set_mux_conf_regs(void)
 
 void sdram_init(void)
 {
+	config_ddr(0, &ioregs_lpddr2, NULL, NULL, &emif_regs_lpddr2, 0);
 }
 #endif
 
diff --git a/board/ti/ti814x/evm.c b/board/ti/ti814x/evm.c
index e406326..56ec4b2 100644
--- a/board/ti/ti814x/evm.c
+++ b/board/ti/ti814x/evm.c
@@ -100,9 +100,9 @@ void sdram_init(void)
 {
 	config_dmm(&evm_lisa_map_regs);
 
-	config_ddr(0, 0, &evm_ddr2_data, &evm_ddr2_cctrl_data,
+	config_ddr(0, NULL, &evm_ddr2_data, &evm_ddr2_cctrl_data,
 		   &evm_ddr2_emif0_regs, 0);
-	config_ddr(0, 0, &evm_ddr2_data, &evm_ddr2_cctrl_data,
+	config_ddr(0, NULL, &evm_ddr2_data, &evm_ddr2_cctrl_data,
 		   &evm_ddr2_emif1_regs, 1);
 }
 #endif
diff --git a/board/ti/ti816x/evm.c b/board/ti/ti816x/evm.c
index 74d35e9..9e7d503 100644
--- a/board/ti/ti816x/evm.c
+++ b/board/ti/ti816x/evm.c
@@ -206,13 +206,15 @@ void sdram_init(void)
 	if (CONFIG_TI816X_USE_EMIF0) {
 		ddr2_emif0_regs.emif_ddr_phy_ctlr_1 =
 			(get_cpu_rev() == 0x1 ? 0x0000010B : 0x0000030B);
-		config_ddr(0, 0, &ddr2_data, &ddr2_ctrl, &ddr2_emif0_regs, 0);
+		config_ddr(0, NULL, &ddr2_data, &ddr2_ctrl, &ddr2_emif0_regs,
+			   0);
 	}
 
 	if (CONFIG_TI816X_USE_EMIF1) {
 		ddr2_emif1_regs.emif_ddr_phy_ctlr_1 =
 			(get_cpu_rev() == 0x1 ? 0x0000010B : 0x0000030B);
-		config_ddr(1, 0, &ddr2_data, &ddr2_ctrl, &ddr2_emif1_regs, 1);
+		config_ddr(1, NULL, &ddr2_data, &ddr2_ctrl, &ddr2_emif1_regs,
+			   1);
 	}
 #endif
 
@@ -220,10 +222,12 @@ void sdram_init(void)
 	ddr3_data.datadldiff0 = (get_cpu_rev() == 0x1 ? 0x0 : 0xF);
 
 	if (CONFIG_TI816X_USE_EMIF0)
-		config_ddr(0, 0, &ddr3_data, &ddr3_ctrl, &ddr3_emif0_regs, 0);
+		config_ddr(0, NULL, &ddr3_data, &ddr3_ctrl, &ddr3_emif0_regs,
+			   0);
 
 	if (CONFIG_TI816X_USE_EMIF1)
-		config_ddr(1, 0, &ddr3_data, &ddr3_ctrl, &ddr3_emif1_regs, 1);
+		config_ddr(1, NULL, &ddr3_data, &ddr3_ctrl, &ddr3_emif1_regs,
+			   1);
 #endif
 }
 #endif /* CONFIG_SPL_BUILD */
