diff --git a/board/freescale/mpc8349emds/Makefile b/board/freescale/mpc8349emds/Makefile
index 4f76eab..601c3bf 100644
--- a/board/freescale/mpc8349emds/Makefile
+++ b/board/freescale/mpc8349emds/Makefile
@@ -27,6 +27,7 @@ LIB	= $(obj)lib$(BOARD).o
 
 COBJS-y += $(BOARD).o
 COBJS-$(CONFIG_PCI) += pci.o
+COBJS-$(CONFIG_FSL_DDR2) += ddr.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/board/freescale/mpc8349emds/ddr.c b/board/freescale/mpc8349emds/ddr.c
new file mode 100644
index 0000000..b7c028c
--- /dev/null
+++ b/board/freescale/mpc8349emds/ddr.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ */
+
+#include <common.h>
+
+#include <asm/fsl_ddr_sdram.h>
+#include <asm/fsl_ddr_dimm_params.h>
+
+typedef struct {
+	u32 datarate_mhz_low;
+	u32 datarate_mhz_high;
+	u32 n_ranks;
+	u32 clk_adjust;
+	u32 cpo;
+	u32 write_data_delay;
+	u32 force_2T;
+} board_specific_parameters_t;
+
+const board_specific_parameters_t board_specific_parameters_udimm[][20] = {
+	{
+	/*
+	 *	memory controller 0
+	 *	  lo|  hi|  num|  clk| cpo|wrdata|2T
+	 *	 mhz| mhz|ranks|adjst|    | delay|
+	 */
+		{  0, 300,    2,    4,   4,    2,  0},
+		{301, 365,    2,    4,   6,    2,  0},
+		{366, 450,    2,    4,   7,    2,  0},
+		{451, 850,    2,    4,  31,    2,  0},
+		{  0, 300,    1,    4,   4,    2,  0},
+		{301, 365,    1,    4,   6,    2,  0},
+		{366, 450,    1,    4,   7,    2,  0},
+		{451, 850,    1,    4,  31,    2,  0}
+	}
+};
+
+void fsl_ddr_board_options(memctl_options_t *popts,
+				dimm_params_t *pdimm,
+				unsigned int ctrl_num)
+{
+	const board_specific_parameters_t *pbsp;
+	u32 num_params;
+	u32 i, dimm_num;
+	ulong ddr_freq;
+
+	if (ctrl_num != 0)	/* we have only one controller */
+		return;
+	for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
+		if (pdimm[i].n_ranks)
+			break;
+	}
+	if (i >= CONFIG_DIMM_SLOTS_PER_CTLR)	/* no DIMM */
+		return;
+
+	dimm_num = i;
+	pbsp = &(board_specific_parameters_udimm[ctrl_num][0]);
+	num_params = sizeof(board_specific_parameters_udimm[ctrl_num]) /
+			sizeof(board_specific_parameters_udimm[0][0]);
+
+	/* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
+	 * freqency and n_banks specified in board_specific_parameters table.
+	 */
+	ddr_freq = get_ddr_freq(0) / 1000000;
+	for (i = 0; i < num_params; i++) {
+		if (ddr_freq >= pbsp->datarate_mhz_low &&
+		    ddr_freq <= pbsp->datarate_mhz_high &&
+		    pdimm[dimm_num].n_ranks == pbsp->n_ranks) {
+			popts->clk_adjust = pbsp->clk_adjust;
+			popts->cpo_override = pbsp->cpo;
+			popts->write_data_delay = pbsp->write_data_delay;
+			popts->twoT_en = pbsp->force_2T;
+			break;
+		}
+		pbsp++;
+	}
+
+	if (i == num_params) {
+		printf("Warning: board specific timing not found "
+			"for data rate %lu MT/s!\n", ddr_freq);
+	}
+
+	/*
+	 * Factors to consider for half-strength driver enable:
+	 *	- number of DIMMs installed
+	 */
+	popts->half_strength_driver_enable = 0;
+	popts->DQS_config = 0;	/* only true DQS signal is used on board */
+}
diff --git a/board/freescale/mpc8349emds/mpc8349emds.c b/board/freescale/mpc8349emds/mpc8349emds.c
index 365ac37..620540f 100644
--- a/board/freescale/mpc8349emds/mpc8349emds.c
+++ b/board/freescale/mpc8349emds/mpc8349emds.c
@@ -29,7 +29,11 @@
 #include <i2c.h>
 #include <spi.h>
 #include <miiphy.h>
+#ifdef CONFIG_FSL_DDR2
+#include <asm/fsl_ddr_sdram.h>
+#else
 #include <spd_sdram.h>
+#endif
 
 #if defined(CONFIG_OF_LIBFDT)
 #include <libfdt.h>
@@ -62,7 +66,7 @@ int board_early_init_f (void)
 phys_size_t initdram (int board_type)
 {
 	volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
-	u32 msize = 0;
+	phys_size_t msize = 0;
 
 	if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im)
 		return -1;
@@ -70,24 +74,24 @@ phys_size_t initdram (int board_type)
 	/* DDR SDRAM - Main SODIMM */
 	im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_BASE & LAWBAR_BAR;
 #if defined(CONFIG_SPD_EEPROM)
-	msize = spd_sdram();
+#ifndef CONFIG_FSL_DDR2
+	msize = spd_sdram() * 1024 * 1024;
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+	ddr_enable_ecc(msize);
+#endif
+#else
+	msize = fsl_ddr_sdram();
+#endif
 #else
-	msize = fixed_sdram();
+	msize = fixed_sdram() * 1024 * 1024;
 #endif
 	/*
 	 * Initialize SDRAM if it is on local bus.
 	 */
 	sdram_init();
 
-#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
-	/*
-	 * Initialize and enable DDR ECC.
-	 */
-	ddr_enable_ecc(msize * 1024 * 1024);
-#endif
-
 	/* return total bus SDRAM size(bytes)  -- DDR */
-	return (msize * 1024 * 1024);
+	return msize;
 }
 
 #if !defined(CONFIG_SPD_EEPROM)
diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h
index 45b6b5f..da2b11d 100644
--- a/include/configs/MPC8349EMDS.h
+++ b/include/configs/MPC8349EMDS.h
@@ -78,6 +78,22 @@
 #define CONFIG_SPD_EEPROM		/* use SPD EEPROM for DDR setup*/
 
 /*
+ * define CONFIG_FSL_DDR2 to use unified DDR driver
+ * undefine it to use old spd_sdram.c
+ */
+#define CONFIG_FSL_DDR2
+#ifdef CONFIG_FSL_DDR2
+#define CONFIG_SYS_SPD_BUS_NUM	0
+#define SPD_EEPROM_ADDRESS1	0x52
+#define SPD_EEPROM_ADDRESS2	0x51
+#define CONFIG_NUM_DDR_CONTROLLERS	1
+#define CONFIG_DIMM_SLOTS_PER_CTLR	2
+#define CONFIG_CHIP_SELECTS_PER_CTRL	(2 * CONFIG_DIMM_SLOTS_PER_CTLR)
+#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER
+#define CONFIG_MEM_INIT_VALUE	0xDeadBeef
+#endif
+
+/*
  * 32-bit data path mode.
  *
  * Please note that using this mode for devices with the real density of 64-bit
