diff --git a/arch/arm/dts/socfpga_cyclone5_de10_nano.dts b/arch/arm/dts/socfpga_cyclone5_de10_nano.dts
index b620dd8dda560823c9a507d652c092844a9d2409..4be4083941d14e6879f002050f3a59ac7a2f5a37 100644
--- a/arch/arm/dts/socfpga_cyclone5_de10_nano.dts
+++ b/arch/arm/dts/socfpga_cyclone5_de10_nano.dts
@@ -77,6 +77,7 @@
 };
 
 &uart0 {
+	clock-frequency = <100000000>;
 	u-boot,dm-pre-reloc;
 };
 
diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h
index 86d5d2b62b079aed4afafbb91d9d3c81f3154d4c..c3ca8cdf3babc4a241f14b7eec77a9d1fb3f57db 100644
--- a/arch/arm/mach-socfpga/include/mach/misc.h
+++ b/arch/arm/mach-socfpga/include/mach/misc.h
@@ -39,6 +39,6 @@ void socfpga_init_security_policies(void);
 void socfpga_sdram_remap_zero(void);
 #endif
 
-void do_bridge_reset(int enable);
+void do_bridge_reset(int enable, unsigned int mask);
 
 #endif /* _MISC_H_ */
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h b/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h
index dd58922cecc60dbe49e3e969d50f98313769ee09..5e490d182e39bcde20b5c1f5e600e4d0571d23dc 100644
--- a/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h
+++ b/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h
@@ -9,6 +9,7 @@
 #include <dt-bindings/reset/altr,rst-mgr.h>
 
 void reset_deassert_peripherals_handoff(void);
+void socfpga_bridges_set_handoff_regs(bool h2f, bool lwh2f, bool f2h);
 void socfpga_bridges_reset(int enable);
 
 struct socfpga_reset_manager {
diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c
index ec8339e04574462af171b97f0f35cdb9ef74d6c0..e1ea8eb73e33ecd004f8a99adfa68b7f27cff8c8 100644
--- a/arch/arm/mach-socfpga/misc.c
+++ b/arch/arm/mach-socfpga/misc.c
@@ -126,17 +126,22 @@ int arch_cpu_init(void)
 #ifndef CONFIG_SPL_BUILD
 static int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	if (argc != 2)
+	unsigned int mask = ~0;
+
+	if (argc < 2 || argc > 3)
 		return CMD_RET_USAGE;
 
 	argv++;
 
+	if (argc == 3)
+		mask = simple_strtoul(argv[1], NULL, 16);
+
 	switch (*argv[0]) {
 	case 'e':	/* Enable */
-		do_bridge_reset(1);
+		do_bridge_reset(1, mask);
 		break;
 	case 'd':	/* Disable */
-		do_bridge_reset(0);
+		do_bridge_reset(0, mask);
 		break;
 	default:
 		return CMD_RET_USAGE;
@@ -145,10 +150,10 @@ static int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	return 0;
 }
 
-U_BOOT_CMD(bridge, 2, 1, do_bridge,
+U_BOOT_CMD(bridge, 3, 1, do_bridge,
 	   "SoCFPGA HPS FPGA bridge control",
-	   "enable  - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
-	   "bridge disable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
+	   "enable [mask] - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
+	   "bridge disable [mask] - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
 	   ""
 );
 
diff --git a/arch/arm/mach-socfpga/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c
index 63b8c75d31d134053ac521c62bded724315d8485..2e2a40b65dc13dd7578150b795e630f3be9a8f16 100644
--- a/arch/arm/mach-socfpga/misc_arria10.c
+++ b/arch/arm/mach-socfpga/misc_arria10.c
@@ -115,7 +115,7 @@ int print_cpuinfo(void)
 }
 #endif
 
-void do_bridge_reset(int enable)
+void do_bridge_reset(int enable, unsigned int mask)
 {
 	if (enable)
 		socfpga_reset_deassert_bridges_handoff();
diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
index 9865f5b5b12065cf739e5669d7843ed51c6635ec..71547d81ab69a10f7c3402aa28d00ad9eea00ab4 100644
--- a/arch/arm/mach-socfpga/misc_gen5.c
+++ b/arch/arm/mach-socfpga/misc_gen5.c
@@ -210,47 +210,26 @@ static struct socfpga_reset_manager *reset_manager_base =
 static struct socfpga_sdr_ctrl *sdr_ctrl =
 	(struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS;
 
-static void socfpga_sdram_apply_static_cfg(void)
+void do_bridge_reset(int enable, unsigned int mask)
 {
-	const u32 applymask = 0x8;
-	u32 val = readl(&sdr_ctrl->static_cfg) | applymask;
-
-	/*
-	 * SDRAM staticcfg register specific:
-	 * When applying the register setting, the CPU must not access
-	 * SDRAM. Luckily for us, we can abuse i-cache here to help us
-	 * circumvent the SDRAM access issue. The idea is to make sure
-	 * that the code is in one full i-cache line by branching past
-	 * it and back. Once it is in the i-cache, we execute the core
-	 * of the code and apply the register settings.
-	 *
-	 * The code below uses 7 instructions, while the Cortex-A9 has
-	 * 32-byte cachelines, thus the limit is 8 instructions total.
-	 */
-	asm volatile(
-		".align	5			\n"
-		"	b	2f		\n"
-		"1:	str	%0,	[%1]	\n"
-		"	dsb			\n"
-		"	isb			\n"
-		"	b	3f		\n"
-		"2:	b	1b		\n"
-		"3:	nop			\n"
-	: : "r"(val), "r"(&sdr_ctrl->static_cfg) : "memory", "cc");
-}
+	int i;
 
-void do_bridge_reset(int enable)
-{
 	if (enable) {
+		socfpga_bridges_set_handoff_regs(!(mask & BIT(0)),
+						 !(mask & BIT(1)),
+						 !(mask & BIT(2)));
+		for (i = 0; i < 2; i++) {	/* Reload SW setting cache */
+			iswgrp_handoff[i] =
+				readl(&sysmgr_regs->iswgrp_handoff[i]);
+		}
+
 		writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module);
-		socfpga_sdram_apply_static_cfg();
 		writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst);
 		writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset);
 		writel(iswgrp_handoff[1], &nic301_regs->remap);
 	} else {
 		writel(0, &sysmgr_regs->fpgaintfgrp_module);
 		writel(0, &sdr_ctrl->fpgaport_rst);
-		socfpga_sdram_apply_static_cfg();
 		writel(0, &reset_manager_base->brg_mod_reset);
 		writel(1, &nic301_regs->remap);
 	}
diff --git a/arch/arm/mach-socfpga/misc_s10.c b/arch/arm/mach-socfpga/misc_s10.c
index 113eace650edcfe12f3afd2566868362d11ab8ea..60c96090ce1c47ad2151e23d1986811f3006f38b 100644
--- a/arch/arm/mach-socfpga/misc_s10.c
+++ b/arch/arm/mach-socfpga/misc_s10.c
@@ -150,7 +150,7 @@ int arch_early_init_r(void)
 	return 0;
 }
 
-void do_bridge_reset(int enable)
+void do_bridge_reset(int enable, unsigned int mask)
 {
 	socfpga_bridges_reset(enable);
 }
diff --git a/arch/arm/mach-socfpga/reset_manager_gen5.c b/arch/arm/mach-socfpga/reset_manager_gen5.c
index 25baef79bc2660a4d7568fe0dd5ab8f09b4477b4..89a384b59c84c085f3202e4dfc2004996999009e 100644
--- a/arch/arm/mach-socfpga/reset_manager_gen5.c
+++ b/arch/arm/mach-socfpga/reset_manager_gen5.c
@@ -73,6 +73,28 @@ void reset_deassert_peripherals_handoff(void)
 #define L3REGS_REMAP_HPS2FPGA_MASK	0x08
 #define L3REGS_REMAP_OCRAM_MASK		0x01
 
+void socfpga_bridges_set_handoff_regs(bool h2f, bool lwh2f, bool f2h)
+{
+	u32 brgmask = 0x0;
+	u32 l3rmask = L3REGS_REMAP_OCRAM_MASK;
+
+	if (h2f)
+		brgmask |= BIT(0);
+	else
+		l3rmask |= L3REGS_REMAP_HPS2FPGA_MASK;
+
+	if (lwh2f)
+		brgmask |= BIT(1);
+	else
+		l3rmask |= L3REGS_REMAP_LWHPS2FPGA_MASK;
+
+	if (f2h)
+		brgmask |= BIT(2);
+
+	writel(brgmask, &sysmgr_regs->iswgrp_handoff[0]);
+	writel(l3rmask, &sysmgr_regs->iswgrp_handoff[1]);
+}
+
 void socfpga_bridges_reset(int enable)
 {
 	const u32 l3mask = L3REGS_REMAP_LWHPS2FPGA_MASK |
@@ -81,10 +103,10 @@ void socfpga_bridges_reset(int enable)
 
 	if (enable) {
 		/* brdmodrst */
-		writel(0xffffffff, &reset_manager_base->brg_mod_reset);
+		writel(0x7, &reset_manager_base->brg_mod_reset);
+		writel(L3REGS_REMAP_OCRAM_MASK, SOCFPGA_L3REGS_ADDRESS);
 	} else {
-		writel(0, &sysmgr_regs->iswgrp_handoff[0]);
-		writel(l3mask, &sysmgr_regs->iswgrp_handoff[1]);
+		socfpga_bridges_set_handoff_regs(false, false, false);
 
 		/* Check signal from FPGA. */
 		if (!fpgamgr_test_fpga_ready()) {
diff --git a/arch/arm/mach-socfpga/spl_gen5.c b/arch/arm/mach-socfpga/spl_gen5.c
index 9dd0afb4bcacd905e2287a52acdd011d09182b26..bd2a9fe5aed644ea8290375b9aa4941213a7fb2a 100644
--- a/arch/arm/mach-socfpga/spl_gen5.c
+++ b/arch/arm/mach-socfpga/spl_gen5.c
@@ -175,8 +175,9 @@ void board_init_f(ulong dummy)
 	sysmgr_pinmux_init();
 	sysmgr_config_warmrstcfgio(0);
 
-	/* De-assert reset for bridges based on handoff */
-	socfpga_bridges_reset(0);
+	/* De-assert reset for peripherals and bridges based on handoff */
+	reset_deassert_peripherals_handoff();
+	socfpga_bridges_set_handoff_regs(true, true, true);
 
 	debug("Unfreezing/Thaw all I/O banks\n");
 	/* unfreeze / thaw all IO banks */
@@ -205,7 +206,4 @@ void board_init_f(ulong dummy)
 		debug("DRAM init failed: %d\n", ret);
 		hang();
 	}
-
-	if (!socfpga_is_booting_from_fpga())
-		socfpga_bridges_reset(1);
 }
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 93a836eac3629bde23f89e62747e17c41eea3ab0..1992d611821dc833398ca921b979c153b08e3135 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -74,15 +74,15 @@ static void dwmci_prepare_data(struct dwmci_host *host,
 		dwmci_set_idma_desc(cur_idmac, flags, cnt,
 				    (ulong)bounce_buffer + (i * PAGE_SIZE));
 
+		cur_idmac++;
 		if (blk_cnt <= 8)
 			break;
 		blk_cnt -= 8;
-		cur_idmac++;
 		i++;
 	} while(1);
 
 	data_end = (ulong)cur_idmac;
-	flush_dcache_range(data_start, data_end + ARCH_DMA_MINALIGN);
+	flush_dcache_range(data_start, roundup(data_end, ARCH_DMA_MINALIGN));
 
 	ctrl = dwmci_readl(host, DWMCI_CTRL);
 	ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN;
@@ -114,22 +114,40 @@ static int dwmci_fifo_ready(struct dwmci_host *host, u32 bit, u32 *len)
 	return 0;
 }
 
+static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size)
+{
+	unsigned int timeout;
+
+	timeout = size * 8 * 1000;	/* counting in bits and msec */
+	timeout *= 2;			/* wait twice as long */
+	timeout /= mmc->clock;
+	timeout /= mmc->bus_width;
+	timeout /= mmc->ddr_mode ? 2 : 1;
+	timeout = (timeout < 1000) ? 1000 : timeout;
+
+	return timeout;
+}
+
 static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
 {
+	struct mmc *mmc = host->mmc;
 	int ret = 0;
-	u32 timeout = 240000;
-	u32 mask, size, i, len = 0;
+	u32 timeout, mask, size, i, len = 0;
 	u32 *buf = NULL;
 	ulong start = get_timer(0);
 	u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >>
 			    RX_WMARK_SHIFT) + 1) * 2;
 
-	size = data->blocksize * data->blocks / 4;
+	size = data->blocksize * data->blocks;
 	if (data->flags == MMC_DATA_READ)
 		buf = (unsigned int *)data->dest;
 	else
 		buf = (unsigned int *)data->src;
 
+	timeout = dwmci_get_timeout(mmc, size);
+
+	size /= 4;
+
 	for (;;) {
 		mask = dwmci_readl(host, DWMCI_RINTSTS);
 		/* Error during data transfer. */
@@ -252,14 +270,20 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 			dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
 		} else {
 			if (data->flags == MMC_DATA_READ) {
-				bounce_buffer_start(&bbstate, (void*)data->dest,
+				ret = bounce_buffer_start(&bbstate,
+						(void*)data->dest,
 						data->blocksize *
 						data->blocks, GEN_BB_WRITE);
 			} else {
-				bounce_buffer_start(&bbstate, (void*)data->src,
+				ret = bounce_buffer_start(&bbstate,
+						(void*)data->src,
 						data->blocksize *
 						data->blocks, GEN_BB_READ);
 			}
+
+			if (ret)
+				return ret;
+
 			dwmci_prepare_data(host, data, cur_idmac,
 					   bbstate.bounce_buffer);
 		}