diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c
index 3f80700711de39105a63b7b6e8a92307e890706f..fc5d951e9aa562d6d64aa18a3db4abf561e48fe8 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu.c
@@ -34,6 +34,9 @@
 #include <asm/io.h>
 #include <asm/mmu.h>
 #include <asm/fsl_law.h>
+#include <post.h>
+#include <asm/processor.h>
+#include <asm/fsl_ddr_sdram.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -282,3 +285,219 @@ void mpc85xx_reginfo(void)
 	print_laws();
 	print_lbc_regs();
 }
+
+#if CONFIG_POST & CONFIG_SYS_POST_MEMORY
+
+/* Board-specific functions defined in each board's ddr.c */
+void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
+	unsigned int ctrl_num);
+void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn,
+		       phys_addr_t *rpn);
+unsigned int
+	setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg);
+
+static void dump_spd_ddr_reg(void)
+{
+	int i, j, k, m;
+	u8 *p_8;
+	u32 *p_32;
+	ccsr_ddr_t *ddr[CONFIG_NUM_DDR_CONTROLLERS];
+	generic_spd_eeprom_t
+		spd[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR];
+
+	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
+		fsl_ddr_get_spd(spd[i], i);
+
+	puts("SPD data of all dimms (zero vaule is omitted)...\n");
+	puts("Byte (hex)  ");
+	k = 1;
+	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+		for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++)
+			printf("Dimm%d ", k++);
+	}
+	puts("\n");
+	for (k = 0; k < sizeof(generic_spd_eeprom_t); k++) {
+		m = 0;
+		printf("%3d (0x%02x)  ", k, k);
+		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
+				p_8 = (u8 *) &spd[i][j];
+				if (p_8[k]) {
+					printf("0x%02x  ", p_8[k]);
+					m++;
+				} else
+					puts("      ");
+			}
+		}
+		if (m)
+			puts("\n");
+		else
+			puts("\r");
+	}
+
+	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+		switch (i) {
+		case 0:
+			ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+			break;
+#ifdef CONFIG_SYS_MPC85xx_DDR2_ADDR
+		case 1:
+			ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
+			break;
+#endif
+		default:
+			printf("%s unexpected controller number = %u\n",
+				__func__, i);
+			return;
+		}
+	}
+	printf("DDR registers dump for all controllers "
+		"(zero vaule is omitted)...\n");
+	puts("Offset (hex)   ");
+	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
+		printf("     Base + 0x%04x", (u32)ddr[i] & 0xFFFF);
+	puts("\n");
+	for (k = 0; k < sizeof(ccsr_ddr_t)/4; k++) {
+		m = 0;
+		printf("%6d (0x%04x)", k * 4, k * 4);
+		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+			p_32 = (u32 *) ddr[i];
+			if (p_32[k]) {
+				printf("        0x%08x", p_32[k]);
+				m++;
+			} else
+				puts("                  ");
+		}
+		if (m)
+			puts("\n");
+		else
+			puts("\r");
+	}
+	puts("\n");
+}
+
+/* invalid the TLBs for DDR and setup new ones to cover p_addr */
+static int reset_tlb(phys_addr_t p_addr, u32 size, phys_addr_t *phys_offset)
+{
+	u32 vstart = CONFIG_SYS_DDR_SDRAM_BASE;
+	unsigned long epn;
+	u32 tsize, valid, ptr;
+	phys_addr_t rpn = 0;
+	int ddr_esel;
+
+	ptr = vstart;
+
+	while (ptr < (vstart + size)) {
+		ddr_esel = find_tlb_idx((void *)ptr, 1);
+		if (ddr_esel != -1) {
+			read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, &rpn);
+			disable_tlb(ddr_esel);
+		}
+		ptr += TSIZE_TO_BYTES(tsize);
+	}
+
+	/* Setup new tlb to cover the physical address */
+	setup_ddr_tlbs_phys(p_addr, size>>20);
+
+	ptr = vstart;
+	ddr_esel = find_tlb_idx((void *)ptr, 1);
+	if (ddr_esel != -1) {
+		read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, phys_offset);
+	} else {
+		printf("TLB error in function %s\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * slide the testing window up to test another area
+ * for 32_bit system, the maximum testable memory is limited to
+ * CONFIG_MAX_MEM_MAPPED
+ */
+int arch_memory_test_advance(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
+{
+	phys_addr_t test_cap, p_addr;
+	phys_size_t p_size = min(gd->ram_size, CONFIG_MAX_MEM_MAPPED);
+
+#if !defined(CONFIG_PHYS_64BIT) || \
+    !defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS) || \
+	(CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull)
+		test_cap = p_size;
+#else
+		test_cap = gd->ram_size;
+#endif
+	p_addr = (*vstart) + (*size) + (*phys_offset);
+	if (p_addr < test_cap - 1) {
+		p_size = min(test_cap - p_addr, CONFIG_MAX_MEM_MAPPED);
+		if (reset_tlb(p_addr, p_size, phys_offset) == -1)
+			return -1;
+		*vstart = CONFIG_SYS_DDR_SDRAM_BASE;
+		*size = (u32) p_size;
+		printf("Testing 0x%08llx - 0x%08llx\n",
+			(u64)(*vstart) + (*phys_offset),
+			(u64)(*vstart) + (*phys_offset) + (*size) - 1);
+	} else
+		return 1;
+
+	return 0;
+}
+
+/* initialization for testing area */
+int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
+{
+	phys_size_t p_size = min(gd->ram_size, CONFIG_MAX_MEM_MAPPED);
+
+	*vstart = CONFIG_SYS_DDR_SDRAM_BASE;
+	*size = (u32) p_size;	/* CONFIG_MAX_MEM_MAPPED < 4G */
+	*phys_offset = 0;
+
+#if !defined(CONFIG_PHYS_64BIT) || \
+    !defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS) || \
+	(CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull)
+		if (gd->ram_size > CONFIG_MAX_MEM_MAPPED) {
+			puts("Cannot test more than ");
+			print_size(CONFIG_MAX_MEM_MAPPED,
+				" without proper 36BIT support.\n");
+		}
+#endif
+	printf("Testing 0x%08llx - 0x%08llx\n",
+		(u64)(*vstart) + (*phys_offset),
+		(u64)(*vstart) + (*phys_offset) + (*size) - 1);
+
+	return 0;
+}
+
+/* invalid TLBs for DDR and remap as normal after testing */
+int arch_memory_test_cleanup(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
+{
+	unsigned long epn;
+	u32 tsize, valid, ptr;
+	phys_addr_t rpn = 0;
+	int ddr_esel;
+
+	/* disable the TLBs for this testing */
+	ptr = *vstart;
+
+	while (ptr < (*vstart) + (*size)) {
+		ddr_esel = find_tlb_idx((void *)ptr, 1);
+		if (ddr_esel != -1) {
+			read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, &rpn);
+			disable_tlb(ddr_esel);
+		}
+		ptr += TSIZE_TO_BYTES(tsize);
+	}
+
+	puts("Remap DDR ");
+	setup_ddr_tlbs(gd->ram_size>>20);
+	puts("\n");
+
+	return 0;
+}
+
+void arch_memory_failure_handle(void)
+{
+	dump_spd_ddr_reg();
+}
+#endif
diff --git a/doc/README.fsl-ddr b/doc/README.fsl-ddr
index e108a0d50c94ad8867d3287859982a05f12cdac0..1657ef61702679919301536eab515d22089c9e1d 100644
--- a/doc/README.fsl-ddr
+++ b/doc/README.fsl-ddr
@@ -78,6 +78,20 @@ If the DDR controller supports address hashing, it can be enabled by hwconfig.
 Syntax is:
 hwconfig=fsl_ddr:addr_hash=true
 
+
+Memory testing options for mpc85xx
+==================================
+1. Memory test can be done once U-boot prompt comes up using mtest, or
+2. Memory test can be done with Power-On-Self-Test function, activated at
+   compile time.
+
+   In order to enable the POST memory test, CONFIG_POST needs to be
+   defined in board configuraiton header file. By default, POST memory test
+   performs a fast test. A slow test can be enabled by changing the flag at
+   compiling time. To test memory bigger than 2GB, 36BIT support is needed.
+   Memory is tested within a 2GB window. TLBs are used to map the virtual 2GB
+   window to physical address so that all physical memory can be tested.
+
 Combination of hwconfig
 =======================
 Hwconfig can be combined with multiple parameters, for example, on a supported