diff --git a/arch/arm/cpu/armv8/fsl-lsch3/README b/arch/arm/cpu/armv8/fsl-lsch3/README
index 99fc39a61f3f7f080fbfa705c6ec53076255b416..f781620b30a0b7ca82fed84e459ac5589acdb0e5 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/README
+++ b/arch/arm/cpu/armv8/fsl-lsch3/README
@@ -33,3 +33,11 @@ is shown below considering a 32MB NOR flash device:
 	------------------------- ----> 0x0000_0000
 
 	32-MB NOR flash layout
+
+Environment Variables
+=====================
+mcboottimeout:	MC boot timeout in milliseconds. If this variable is not defined
+		the value CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS will be assumed.
+
+mcmemsize:	MC DRAM block size. If this variable is not defined, the value
+		CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE will be assumed.
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index 2a2b0af53ea2c6c846e54e273854423cc94d4d68..c5c44bcab044edc20128e48396b8b6dce4383fee 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -3,7 +3,6 @@
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
-
 #include <errno.h>
 #include <asm/io.h>
 #include <fsl-mc/fsl_mc.h>
@@ -15,14 +14,64 @@
 #include <fsl-mc/fsl_dpio.h>
 #include <fsl-mc/fsl_qbman_portal.h>
 
+#define MC_RAM_BASE_ADDR_ALIGNMENT  (512UL * 1024 * 1024)
+#define MC_RAM_BASE_ADDR_ALIGNMENT_MASK	(~(MC_RAM_BASE_ADDR_ALIGNMENT - 1))
+#define MC_RAM_SIZE_ALIGNMENT	    (256UL * 1024 * 1024)
+
+#define MC_MEM_SIZE_ENV_VAR	"mcmemsize"
+#define MC_BOOT_TIMEOUT_ENV_VAR	"mcboottimeout"
+
 DECLARE_GLOBAL_DATA_PTR;
 static int mc_boot_status;
 struct fsl_mc_io *dflt_mc_io = NULL;
 uint16_t dflt_dprc_handle = 0;
 struct fsl_dpbp_obj *dflt_dpbp = NULL;
 struct fsl_dpio_obj *dflt_dpio = NULL;
-uint16_t dflt_dpio_handle = NULL;
+uint16_t dflt_dpio_handle = 0;
+
+#ifdef DEBUG
+void dump_ram_words(const char *title, void *addr)
+{
+	int i;
+	uint32_t *words = addr;
+
+	printf("Dumping beginning of %s (%p):\n", title, addr);
+	for (i = 0; i < 16; i++)
+		printf("%#x ", words[i]);
+
+	printf("\n");
+}
 
+void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs)
+{
+	printf("MC CCSR registers:\n"
+		"reg_gcr1 %#x\n"
+		"reg_gsr %#x\n"
+		"reg_sicbalr %#x\n"
+		"reg_sicbahr %#x\n"
+		"reg_sicapr %#x\n"
+		"reg_mcfbalr %#x\n"
+		"reg_mcfbahr %#x\n"
+		"reg_mcfapr %#x\n"
+		"reg_psr %#x\n",
+		mc_ccsr_regs->reg_gcr1,
+		mc_ccsr_regs->reg_gsr,
+		mc_ccsr_regs->reg_sicbalr,
+		mc_ccsr_regs->reg_sicbahr,
+		mc_ccsr_regs->reg_sicapr,
+		mc_ccsr_regs->reg_mcfbalr,
+		mc_ccsr_regs->reg_mcfbahr,
+		mc_ccsr_regs->reg_mcfapr,
+		mc_ccsr_regs->reg_psr);
+}
+#else
+
+#define dump_ram_words(title, addr)
+#define dump_mc_ccsr_regs(mc_ccsr_regs)
+
+#endif /* DEBUG */
+
+#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
 /**
  * Copying MC firmware or DPL image to DDR
  */
@@ -31,6 +80,7 @@ static int mc_copy_image(const char *title,
 {
 	debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
 	memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
+	flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size);
 	return 0;
 }
 
@@ -92,22 +142,254 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr,
 
 	return 0;
 }
+#endif
+
+/*
+ * Calculates the values to be used to specify the address range
+ * for the MC private DRAM block, in the MCFBALR/MCFBAHR registers.
+ * It returns the highest 512MB-aligned address within the given
+ * address range, in '*aligned_base_addr', and the number of 256 MiB
+ * blocks in it, in 'num_256mb_blocks'.
+ */
+static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr,
+					   size_t mc_ram_size,
+					   u64 *aligned_base_addr,
+					   u8 *num_256mb_blocks)
+{
+	u64 addr;
+	u16 num_blocks;
+
+	if (mc_ram_size % MC_RAM_SIZE_ALIGNMENT != 0) {
+		printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
+		       mc_ram_size);
+		return -EINVAL;
+	}
+
+	num_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT;
+	if (num_blocks < 1 || num_blocks > 0xff) {
+		printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
+		       mc_ram_size);
+		return -EINVAL;
+	}
+
+	addr = (mc_private_ram_start_addr + mc_ram_size - 1) &
+		MC_RAM_BASE_ADDR_ALIGNMENT_MASK;
+
+	if (addr < mc_private_ram_start_addr) {
+		printf("fsl-mc: ERROR: bad start address %#llx\n",
+		       mc_private_ram_start_addr);
+		return -EFAULT;
+	}
+
+	*aligned_base_addr = addr;
+	*num_256mb_blocks = num_blocks;
+	return 0;
+}
+
+static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
+{
+	u64 mc_dpc_offset;
+#ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR
+	int error;
+	void *dpc_fdt_hdr;
+	int dpc_size;
+#endif
+
+#ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET
+	BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 ||
+		     CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff);
+
+	mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET;
+#else
+#error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined"
+#endif
+
+	/*
+	 * Load the MC DPC blob in the MC private DRAM block:
+	 */
+#ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR
+	printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset);
+#else
+	/*
+	 * Get address and size of the DPC blob stored in flash:
+	 */
+#ifdef CONFIG_SYS_LS_MC_DPC_IN_NOR
+	dpc_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPC_ADDR;
+#else
+#error "No CONFIG_SYS_LS_MC_DPC_IN_xxx defined"
+#endif
+
+	error = fdt_check_header(dpc_fdt_hdr);
+	if (error != 0) {
+		/*
+		 * Don't return with error here, since the MC firmware can
+		 * still boot without a DPC
+		 */
+		printf("fsl-mc: WARNING: No DPC image found\n");
+		return 0;
+	}
+
+	dpc_size = fdt_totalsize(dpc_fdt_hdr);
+	if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) {
+		printf("fsl-mc: ERROR: Bad DPC image (too large: %d)\n",
+		       dpc_size);
+		return -EINVAL;
+	}
+
+	mc_copy_image("MC DPC blob",
+		      (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset);
+#endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */
+
+	dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset));
+	return 0;
+}
+
+static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size)
+{
+	u64 mc_dpl_offset;
+#ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR
+	int error;
+	void *dpl_fdt_hdr;
+	int dpl_size;
+#endif
+
+#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
+	BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
+		     CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
+
+	mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
+#else
+#error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined"
+#endif
+
+	/*
+	 * Load the MC DPL blob in the MC private DRAM block:
+	 */
+#ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR
+	printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset);
+#else
+	/*
+	 * Get address and size of the DPL blob stored in flash:
+	 */
+#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
+	dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
+#else
+#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
+#endif
+
+	error = fdt_check_header(dpl_fdt_hdr);
+	if (error != 0) {
+		printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
+		return error;
+	}
+
+	dpl_size = fdt_totalsize(dpl_fdt_hdr);
+	if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
+		printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
+		       dpl_size);
+		return -EINVAL;
+	}
+
+	mc_copy_image("MC DPL blob",
+		      (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
+#endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */
+
+	dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset));
+	return 0;
+}
+
+/**
+ * Return the MC boot timeout value in milliseconds
+ */
+static unsigned long get_mc_boot_timeout_ms(void)
+{
+	unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS;
+
+	char *timeout_ms_env_var = getenv(MC_BOOT_TIMEOUT_ENV_VAR);
+
+	if (timeout_ms_env_var) {
+		timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10);
+		if (timeout_ms == 0) {
+			printf("fsl-mc: WARNING: Invalid value for \'"
+			       MC_BOOT_TIMEOUT_ENV_VAR
+			       "\' environment variable: %lu\n",
+			       timeout_ms);
+
+			timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS;
+		}
+	}
+
+	return timeout_ms;
+}
+
+static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
+{
+	u32 reg_gsr;
+	u32 mc_fw_boot_status;
+	unsigned long timeout_ms = get_mc_boot_timeout_ms();
+	struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
+
+	dmb();
+	debug("Polling mc_ccsr_regs->reg_gsr ...\n");
+	assert(timeout_ms > 0);
+	for (;;) {
+		udelay(1000);	/* throttle polling */
+		reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr);
+		mc_fw_boot_status = (reg_gsr & GSR_FS_MASK);
+		if (mc_fw_boot_status & 0x1)
+			break;
+
+		timeout_ms--;
+		if (timeout_ms == 0)
+			break;
+	}
+
+	if (timeout_ms == 0) {
+		if (booting_mc)
+			printf("fsl-mc: timeout booting management complex firmware\n");
+		else
+			printf("fsl-mc: timeout deploying data path layout\n");
+
+		/* TODO: Get an error status from an MC CCSR register */
+		return -ETIMEDOUT;
+	}
+
+	if (mc_fw_boot_status != 0x1) {
+		/*
+		 * TODO: Identify critical errors from the GSR register's FS
+		 * field and for those errors, set error to -ENODEV or other
+		 * appropriate errno, so that the status property is set to
+		 * failure in the fsl,dprc device tree node.
+		 */
+		if (booting_mc) {
+			printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
+			       reg_gsr);
+		} else {
+			printf("fsl-mc: WARNING: Data path layout deployed with error (GSR: %#x)\n",
+			       reg_gsr);
+		}
+	}
+
+	*final_reg_gsr = reg_gsr;
+	return 0;
+}
 
 int mc_init(void)
 {
 	int error = 0;
-	int timeout = 200000;
 	int portal_id = 0;
 	struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
 	u64 mc_ram_addr;
-	u64 mc_dpl_offset;
 	u32 reg_gsr;
-	u32 mc_fw_boot_status;
-	void *dpl_fdt_hdr;
-	int dpl_size;
+	u32 reg_mcfbalr;
+#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
 	const void *raw_image_addr;
 	size_t raw_image_size = 0;
+#endif
 	struct mc_version mc_ver_info;
+	u64 mc_ram_aligned_base_addr;
+	u8 mc_ram_num_256mb_blocks;
+	size_t mc_ram_size = mc_get_dram_block_size();
 
 	/*
 	 * The MC private DRAM block was already carved at the end of DRAM
@@ -122,8 +404,19 @@ int mc_init(void)
 	}
 
 #ifdef CONFIG_FSL_DEBUG_SERVER
+	/*
+	 * FIXME: I don't think this is right. See get_dram_size_to_hide()
+	 */
 		mc_ram_addr -= debug_server_get_dram_block_size();
 #endif
+
+	error = calculate_mc_private_ram_params(mc_ram_addr,
+						mc_ram_size,
+						&mc_ram_aligned_base_addr,
+						&mc_ram_num_256mb_blocks);
+	if (error != 0)
+		goto out;
+
 	/*
 	 * Management Complex cores should be held at reset out of POR.
 	 * U-boot should be the first software to touch MC. To be safe,
@@ -139,6 +432,9 @@ int mc_init(void)
 	out_le32(&mc_ccsr_regs->reg_gcr1, 0);
 	dmb();
 
+#ifdef CONFIG_SYS_LS_MC_FW_IN_DDR
+	printf("MC firmware is preloaded to %#llx\n", mc_ram_addr);
+#else
 	error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size);
 	if (error != 0)
 		goto out;
@@ -147,83 +443,34 @@ int mc_init(void)
 	 */
 	mc_copy_image("MC Firmware",
 		      (u64)raw_image_addr, raw_image_size, mc_ram_addr);
-
-	/*
-	 * Get address and size of the DPL blob stored in flash:
-	 */
-#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
-	dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
-#else
-#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
 #endif
+	dump_ram_words("firmware", (void *)mc_ram_addr);
 
-	error = fdt_check_header(dpl_fdt_hdr);
-	if (error != 0) {
-		printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
-		goto out;
-	}
-
-	dpl_size = fdt_totalsize(dpl_fdt_hdr);
-	if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
-		printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
-		       dpl_size);
-		error = -EINVAL;
+	error = load_mc_dpc(mc_ram_addr, mc_ram_size);
+	if (error != 0)
 		goto out;
-	}
 
-	/*
-	 * Calculate offset in the MC private DRAM block at which the MC DPL
-	 * blob is to be placed:
-	 */
-#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
-	BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
-		     CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
-
-	mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
-#else
-	mc_dpl_offset = mc_get_dram_block_size() -
-			roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096);
-
-	if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) {
-		printf("%s: Invalid MC DPL offset: %llu\n",
-		       __func__, mc_dpl_offset);
-		error = -EINVAL;
+	error = load_mc_dpl(mc_ram_addr, mc_ram_size);
+	if (error != 0)
 		goto out;
-	}
-#endif
-
-	/*
-	 * Load the MC DPL blob at the far end of the MC private DRAM block:
-	 *
-	 * TODO: Should we place the DPL at a different location to match
-	 * assumptions of MC firmware about its memory layout?
-	 */
-	mc_copy_image("MC DPL blob",
-		      (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
 
 	debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
+	dump_mc_ccsr_regs(mc_ccsr_regs);
 
 	/*
-	 * Tell MC where the MC Firmware image was loaded in DDR:
+	 * Tell MC what is the address range of the DRAM block assigned to it:
 	 */
-	out_le32(&mc_ccsr_regs->reg_mcfbalr, (u32)mc_ram_addr);
-	out_le32(&mc_ccsr_regs->reg_mcfbahr, (u32)((u64)mc_ram_addr >> 32));
+	reg_mcfbalr = (u32)mc_ram_aligned_base_addr |
+		      (mc_ram_num_256mb_blocks - 1);
+	out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr);
+	out_le32(&mc_ccsr_regs->reg_mcfbahr,
+		 (u32)(mc_ram_aligned_base_addr >> 32));
 	out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK);
 
 	/*
-	 * Tell MC where the DPL blob was loaded in DDR, by indicating
-	 * its offset relative to the beginning of the DDR block
-	 * allocated to the MC firmware. The MC firmware is responsible
-	 * for checking that there is no overlap between the DPL blob
-	 * and the runtime heap and stack of the MC firmware itself.
-	 *
-	 * NOTE: bits [31:2] of this offset need to be stored in bits [29:0] of
-	 * the GSR MC CCSR register. So, this offset is assumed to be 4-byte
-	 * aligned.
-	 * Care must be taken not to write 1s into bits 31 and 30 of the GSR in
-	 * this case as the SoC COP or PIC will be signaled.
+	 * Tell the MC that we want delayed DPL deployment.
 	 */
-	out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2));
+	out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00);
 
 	printf("\nfsl-mc: Booting Management Complex ...\n");
 
@@ -231,38 +478,9 @@ int mc_init(void)
 	 * Deassert reset and release MC core 0 to run
 	 */
 	out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST);
-	dmb();
-	debug("Polling mc_ccsr_regs->reg_gsr ...\n");
-
-	for (;;) {
-		reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr);
-		mc_fw_boot_status = (reg_gsr & GSR_FS_MASK);
-		if (mc_fw_boot_status & 0x1)
-			break;
-
-		udelay(1000);	/* throttle polling */
-		if (timeout-- <= 0)
-			break;
-	}
-
-	if (timeout <= 0) {
-		printf("fsl-mc: timeout booting management complex firmware\n");
-
-		/* TODO: Get an error status from an MC CCSR register */
-		error = -ETIMEDOUT;
+	error = wait_for_mc(true, &reg_gsr);
+	if (error != 0)
 		goto out;
-	}
-
-	if (mc_fw_boot_status != 0x1) {
-		/*
-		 * TODO: Identify critical errors from the GSR register's FS
-		 * field and for those errors, set error to -ENODEV or other
-		 * appropriate errno, so that the status property is set to
-		 * failure in the fsl,dprc device tree node.
-		 */
-		printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
-		       reg_gsr);
-	}
 
 	/*
 	 * TODO: need to obtain the portal_id for the root container from the
@@ -301,7 +519,16 @@ int mc_init(void)
 
 	printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n",
 	       mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision,
-	       mc_fw_boot_status);
+	       reg_gsr & GSR_FS_MASK);
+
+	/*
+	 * Tell the MC to deploy the DPL:
+	 */
+	out_le32(&mc_ccsr_regs->reg_gsr, 0x0);
+	printf("\nfsl-mc: Deploying data path layout ...\n");
+	error = wait_for_mc(false, &reg_gsr);
+	if (error != 0)
+		goto out;
 out:
 	if (error != 0)
 		mc_boot_status = -error;
@@ -318,14 +545,28 @@ int get_mc_boot_status(void)
 
 /**
  * Return the actual size of the MC private DRAM block.
- *
- * NOTE: For now this function always returns the minimum required size,
- * However, in the future, the actual size may be obtained from an environment
- * variable.
  */
 unsigned long mc_get_dram_block_size(void)
 {
-	return CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
+	unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
+
+	char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR);
+
+	if (dram_block_size_env_var) {
+		dram_block_size = simple_strtoul(dram_block_size_env_var, NULL,
+						 10);
+
+		if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) {
+			printf("fsl-mc: WARNING: Invalid value for \'"
+			       MC_MEM_SIZE_ENV_VAR
+			       "\' environment variable: %lu\n",
+			       dram_block_size);
+
+			dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
+		}
+	}
+
+	return dram_block_size;
 }
 
 int dpio_init(struct dprc_obj_desc obj_desc)
@@ -464,6 +705,8 @@ int fsl_mc_ldpaa_init(bd_t *bis)
 	int num_child_objects = 0;
 
 	error = mc_init();
+	if (error < 0)
+		goto error;
 
 	error = dprc_get_container_id(dflt_mc_io, &container_id);
 	if (error < 0) {
@@ -517,24 +760,27 @@ void fsl_mc_ldpaa_exit(bd_t *bis)
 {
 	int err;
 
+	if (get_mc_boot_status() == 0) {
+		err = dpio_disable(dflt_mc_io, dflt_dpio_handle);
+		if (err < 0) {
+			printf("dpio_disable() failed: %d\n", err);
+			return;
+		}
+		err = dpio_reset(dflt_mc_io, dflt_dpio_handle);
+		if (err < 0) {
+			printf("dpio_reset() failed: %d\n", err);
+			return;
+		}
+		err = dpio_close(dflt_mc_io, dflt_dpio_handle);
+		if (err < 0) {
+			printf("dpio_close() failed: %d\n", err);
+			return;
+		}
 
-	err = dpio_disable(dflt_mc_io, dflt_dpio_handle);
-	if (err < 0) {
-		printf("dpio_disable() failed: %d\n", err);
-		return;
-	}
-	err = dpio_reset(dflt_mc_io, dflt_dpio_handle);
-	if (err < 0) {
-		printf("dpio_reset() failed: %d\n", err);
-		return;
-	}
-	err = dpio_close(dflt_mc_io, dflt_dpio_handle);
-	if (err < 0) {
-		printf("dpio_close() failed: %d\n", err);
-		return;
+		free(dflt_dpio);
+		free(dflt_dpbp);
 	}
 
-	free(dflt_dpio);
-	free(dflt_dpbp);
-	free(dflt_mc_io);
+	if (dflt_mc_io)
+		free(dflt_mc_io);
 }
diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h
index 5ce5e1c9cbd866f1a57d2601f47e000dfcb56c77..4b68106ce4594c9ef27d390d22813a697d0a24f1 100644
--- a/include/configs/ls2085a_common.h
+++ b/include/configs/ls2085a_common.h
@@ -138,8 +138,10 @@
 #define CONFIG_FSL_MC_ENET
 #define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE	(512UL * 1024 * 1024)
 /* TODO Actual DPL max length needs to be confirmed with the MC FW team */
-#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH		(256 * 1024)
-#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET	0xe00000
+#define CONFIG_SYS_LS_MC_DPC_MAX_LENGTH	    0x20000
+#define CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET    0x00F00000
+#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH	    0x20000
+#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET    0x00F20000
 
 /* Carve out a DDR region which will not be used by u-boot/Linux */
 #if defined(CONFIG_FSL_MC_ENET) || defined(CONFIG_FSL_DEBUG_SERVER)
diff --git a/include/configs/ls2085a_emu.h b/include/configs/ls2085a_emu.h
index 961dc63c8f5273fd74d89a27432d594e4a3a4fa6..2d68e1bf7e59f77af4c2127550d7a0c6d9078dc6 100644
--- a/include/configs/ls2085a_emu.h
+++ b/include/configs/ls2085a_emu.h
@@ -72,12 +72,15 @@
 #define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
 #define CONFIG_SYS_DEBUG_SERVER_FW_ADDR	0x580C00000ULL
 
-/* MC firmware */
-#define CONFIG_SYS_LS_MC_FW_IN_NOR
-#define CONFIG_SYS_LS_MC_FW_ADDR	0x580200000ULL
+/*
+ * This trick allows users to load MC images into DDR directly without
+ * copying from NOR flash. It dramatically improves speed.
+ */
+#define CONFIG_SYS_LS_MC_FW_IN_DDR
+#define CONFIG_SYS_LS_MC_DPL_IN_DDR
+#define CONFIG_SYS_LS_MC_DPC_IN_DDR
 
-#define CONFIG_SYS_LS_MC_DPL_IN_NOR
-#define CONFIG_SYS_LS_MC_DPL_ADDR	0x5806C0000ULL
+#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 200000
 
 /* Store environment at top of flash */
 #define CONFIG_ENV_IS_NOWHERE		1
diff --git a/include/configs/ls2085a_simu.h b/include/configs/ls2085a_simu.h
index e669d8d33e59e9ee220a99985a5d819349de064b..d0d2eedb6d7cc36e197e003967ed2eace543bdda 100644
--- a/include/configs/ls2085a_simu.h
+++ b/include/configs/ls2085a_simu.h
@@ -138,6 +138,11 @@
 #define CONFIG_SYS_LS_MC_DPL_IN_NOR
 #define CONFIG_SYS_LS_MC_DPL_ADDR	0x5806C0000ULL
 
+#define CONFIG_SYS_LS_MC_DPC_IN_NOR
+#define CONFIG_SYS_LS_MC_DPC_ADDR	0x5806F8000ULL
+
+#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 200000
+
 /* Store environment at top of flash */
 #define CONFIG_ENV_IS_NOWHERE		1
 #define CONFIG_ENV_SIZE			0x1000