Merge branch 'master' of git://git.denx.de/u-boot-arm
diff --git a/Makefile b/Makefile
index 6221113..8657417 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
 VERSION = 2014
 PATCHLEVEL = 10
 SUBLEVEL =
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME =
 
 # *DOCUMENTATION*
diff --git a/arch/arm/cpu/armv7/socfpga/Makefile b/arch/arm/cpu/armv7/socfpga/Makefile
index eb33f2c..8b6e108 100644
--- a/arch/arm/cpu/armv7/socfpga/Makefile
+++ b/arch/arm/cpu/armv7/socfpga/Makefile
@@ -8,5 +8,6 @@
 #
 
 obj-y	:= lowlevel_init.o
-obj-y	+= misc.o timer.o reset_manager.o system_manager.o clock_manager.o
+obj-y	+= misc.o timer.o reset_manager.o system_manager.o clock_manager.o \
+	   fpga_manager.o
 obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o scan_manager.o
diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c
index 158501a..d869f47 100644
--- a/arch/arm/cpu/armv7/socfpga/clock_manager.c
+++ b/arch/arm/cpu/armv7/socfpga/clock_manager.c
@@ -8,38 +8,28 @@
 #include <asm/io.h>
 #include <asm/arch/clock_manager.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static const struct socfpga_clock_manager *clock_manager_base =
-		(void *)SOCFPGA_CLKMGR_ADDRESS;
+	(struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
 
-#define CLKMGR_BYPASS_ENABLE	1
-#define CLKMGR_BYPASS_DISABLE	0
-#define CLKMGR_STAT_IDLE	0
-#define CLKMGR_STAT_BUSY	1
-#define CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1		0
-#define CLKMGR_BYPASS_PERPLLSRC_SELECT_INPUT_MUX	1
-#define CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1		0
-#define CLKMGR_BYPASS_SDRPLLSRC_SELECT_INPUT_MUX	1
-
-#define CLEAR_BGP_EN_PWRDN \
-	(CLKMGR_MAINPLLGRP_VCO_PWRDN_SET(0)| \
-	CLKMGR_MAINPLLGRP_VCO_EN_SET(0)| \
-	CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(0))
-
-#define VCO_EN_BASE \
-	(CLKMGR_MAINPLLGRP_VCO_PWRDN_SET(0)| \
-	CLKMGR_MAINPLLGRP_VCO_EN_SET(1)| \
-	CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(0))
-
-static inline void cm_wait_for_lock(uint32_t mask)
+static void cm_wait_for_lock(uint32_t mask)
 {
 	register uint32_t inter_val;
+	uint32_t retry = 0;
 	do {
 		inter_val = readl(&clock_manager_base->inter) & mask;
-	} while (inter_val != mask);
+		if (inter_val == mask)
+			retry++;
+		else
+			retry = 0;
+		if (retry >= 10)
+			break;
+	} while (1);
 }
 
 /* function to poll in the fsm busy bit */
-static inline void cm_wait_for_fsm(void)
+static void cm_wait_for_fsm(void)
 {
 	while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY)
 		;
@@ -49,22 +39,22 @@
  * function to write the bypass register which requires a poll of the
  * busy bit
  */
-static inline void cm_write_bypass(uint32_t val)
+static void cm_write_bypass(uint32_t val)
 {
 	writel(val, &clock_manager_base->bypass);
 	cm_wait_for_fsm();
 }
 
 /* function to write the ctrl register which requires a poll of the busy bit */
-static inline void cm_write_ctrl(uint32_t val)
+static void cm_write_ctrl(uint32_t val)
 {
 	writel(val, &clock_manager_base->ctrl);
 	cm_wait_for_fsm();
 }
 
 /* function to write a clock register that has phase information */
-static inline void cm_write_with_phase(uint32_t value,
-	uint32_t reg_address, uint32_t mask)
+static void cm_write_with_phase(uint32_t value,
+				uint32_t reg_address, uint32_t mask)
 {
 	/* poll until phase is zero */
 	while (readl(reg_address) & mask)
@@ -128,24 +118,18 @@
 	writel(0, &clock_manager_base->per_pll.en);
 
 	/* Put all plls in bypass */
-	cm_write_bypass(
-		CLKMGR_BYPASS_PERPLLSRC_SET(
-		CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) |
-		CLKMGR_BYPASS_SDRPLLSRC_SET(
-		CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) |
-		CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENABLE) |
-		CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENABLE) |
-		CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENABLE));
+	cm_write_bypass(CLKMGR_BYPASS_PERPLL | CLKMGR_BYPASS_SDRPLL |
+			CLKMGR_BYPASS_MAINPLL);
 
-	/*
-	 * Put all plls VCO registers back to reset value.
-	 * Some code might have messed with them.
-	 */
-	writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE,
+	/* Put all plls VCO registers back to reset value. */
+	writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE &
+	       ~CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK,
 	       &clock_manager_base->main_pll.vco);
-	writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE,
+	writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE &
+	       ~CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK,
 	       &clock_manager_base->per_pll.vco);
-	writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE,
+	writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE &
+	       ~CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK,
 	       &clock_manager_base->sdr_pll.vco);
 
 	/*
@@ -170,19 +154,9 @@
 	 * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN
 	 * with numerator and denominator.
 	 */
-	writel(cfg->main_vco_base | CLEAR_BGP_EN_PWRDN |
-		CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK,
-		&clock_manager_base->main_pll.vco);
-
-	writel(cfg->peri_vco_base | CLEAR_BGP_EN_PWRDN |
-		CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK,
-		&clock_manager_base->per_pll.vco);
-
-	writel(CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(0) |
-		CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) |
-		cfg->sdram_vco_base | CLEAR_BGP_EN_PWRDN |
-		CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK,
-		&clock_manager_base->sdr_pll.vco);
+	writel(cfg->main_vco_base, &clock_manager_base->main_pll.vco);
+	writel(cfg->peri_vco_base, &clock_manager_base->per_pll.vco);
+	writel(cfg->sdram_vco_base, &clock_manager_base->sdr_pll.vco);
 
 	/*
 	 * Time starts here
@@ -217,6 +191,9 @@
 	writel(cfg->perqspiclk, &clock_manager_base->per_pll.perqspiclk);
 
 	/* Peri pernandsdmmcclk */
+	writel(cfg->mainnandsdmmcclk,
+	       &clock_manager_base->main_pll.mainnandsdmmcclk);
+
 	writel(cfg->pernandsdmmcclk,
 	       &clock_manager_base->per_pll.pernandsdmmcclk);
 
@@ -232,18 +209,16 @@
 
 	/* Enable vco */
 	/* main pll vco */
-	writel(cfg->main_vco_base | VCO_EN_BASE,
+	writel(cfg->main_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
 	       &clock_manager_base->main_pll.vco);
 
 	/* periferal pll */
-	writel(cfg->peri_vco_base | VCO_EN_BASE,
+	writel(cfg->peri_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
 	       &clock_manager_base->per_pll.vco);
 
 	/* sdram pll vco */
-	writel(CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(0) |
-		CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) |
-		cfg->sdram_vco_base | VCO_EN_BASE,
-		&clock_manager_base->sdr_pll.vco);
+	writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
+	       &clock_manager_base->sdr_pll.vco);
 
 	/* L3 MP and L3 SP */
 	writel(cfg->maindiv, &clock_manager_base->main_pll.maindiv);
@@ -294,8 +269,8 @@
 	       &clock_manager_base->per_pll.vco);
 
 	/* assert sdram outresetall */
-	writel(cfg->sdram_vco_base | VCO_EN_BASE|
-		CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(1),
+	writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN|
+		CLKMGR_SDRPLLGRP_VCO_OUTRESETALL,
 		&clock_manager_base->sdr_pll.vco);
 
 	/* deassert main outresetall */
@@ -307,9 +282,8 @@
 	       &clock_manager_base->per_pll.vco);
 
 	/* deassert sdram outresetall */
-	writel(CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) |
-		cfg->sdram_vco_base | VCO_EN_BASE,
-		&clock_manager_base->sdr_pll.vco);
+	writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN,
+	       &clock_manager_base->sdr_pll.vco);
 
 	/*
 	 * now that we've toggled outreset all, all the clocks
@@ -333,18 +307,10 @@
 			    CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK);
 
 	/* Take all three PLLs out of bypass when safe mode is cleared. */
-	cm_write_bypass(
-		CLKMGR_BYPASS_PERPLLSRC_SET(
-			CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) |
-		CLKMGR_BYPASS_SDRPLLSRC_SET(
-			CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) |
-		CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_DISABLE) |
-		CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_DISABLE) |
-		CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_DISABLE));
+	cm_write_bypass(0);
 
 	/* clear safe mode */
-	cm_write_ctrl(readl(&clock_manager_base->ctrl) |
-			CLKMGR_CTRL_SAFEMODE_SET(CLKMGR_CTRL_SAFEMODE_MASK));
+	cm_write_ctrl(readl(&clock_manager_base->ctrl) | CLKMGR_CTRL_SAFEMODE);
 
 	/*
 	 * now that safe mode is clear with clocks gated
@@ -357,4 +323,224 @@
 	writel(~0, &clock_manager_base->main_pll.en);
 	writel(~0, &clock_manager_base->per_pll.en);
 	writel(~0, &clock_manager_base->sdr_pll.en);
+
+	/* Clear the loss of lock bits (write 1 to clear) */
+	writel(CLKMGR_INTER_SDRPLLLOST_MASK | CLKMGR_INTER_PERPLLLOST_MASK |
+	       CLKMGR_INTER_MAINPLLLOST_MASK,
+	       &clock_manager_base->inter);
 }
+
+static unsigned int cm_get_main_vco_clk_hz(void)
+{
+	uint32_t reg, clock;
+
+	/* get the main VCO clock */
+	reg = readl(&clock_manager_base->main_pll.vco);
+	clock = CONFIG_HPS_CLK_OSC1_HZ;
+	clock /= ((reg & CLKMGR_MAINPLLGRP_VCO_DENOM_MASK) >>
+		  CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) + 1;
+	clock *= ((reg & CLKMGR_MAINPLLGRP_VCO_NUMER_MASK) >>
+		  CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) + 1;
+
+	return clock;
+}
+
+static unsigned int cm_get_per_vco_clk_hz(void)
+{
+	uint32_t reg, clock = 0;
+
+	/* identify PER PLL clock source */
+	reg = readl(&clock_manager_base->per_pll.vco);
+	reg = (reg & CLKMGR_PERPLLGRP_VCO_SSRC_MASK) >>
+	      CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET;
+	if (reg == CLKMGR_VCO_SSRC_EOSC1)
+		clock = CONFIG_HPS_CLK_OSC1_HZ;
+	else if (reg == CLKMGR_VCO_SSRC_EOSC2)
+		clock = CONFIG_HPS_CLK_OSC2_HZ;
+	else if (reg == CLKMGR_VCO_SSRC_F2S)
+		clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ;
+
+	/* get the PER VCO clock */
+	reg = readl(&clock_manager_base->per_pll.vco);
+	clock /= ((reg & CLKMGR_PERPLLGRP_VCO_DENOM_MASK) >>
+		  CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) + 1;
+	clock *= ((reg & CLKMGR_PERPLLGRP_VCO_NUMER_MASK) >>
+		  CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) + 1;
+
+	return clock;
+}
+
+unsigned long cm_get_mpu_clk_hz(void)
+{
+	uint32_t reg, clock;
+
+	clock = cm_get_main_vco_clk_hz();
+
+	/* get the MPU clock */
+	reg = readl(&clock_manager_base->altera.mpuclk);
+	clock /= (reg + 1);
+	reg = readl(&clock_manager_base->main_pll.mpuclk);
+	clock /= (reg + 1);
+	return clock;
+}
+
+unsigned long cm_get_sdram_clk_hz(void)
+{
+	uint32_t reg, clock = 0;
+
+	/* identify SDRAM PLL clock source */
+	reg = readl(&clock_manager_base->sdr_pll.vco);
+	reg = (reg & CLKMGR_SDRPLLGRP_VCO_SSRC_MASK) >>
+	      CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET;
+	if (reg == CLKMGR_VCO_SSRC_EOSC1)
+		clock = CONFIG_HPS_CLK_OSC1_HZ;
+	else if (reg == CLKMGR_VCO_SSRC_EOSC2)
+		clock = CONFIG_HPS_CLK_OSC2_HZ;
+	else if (reg == CLKMGR_VCO_SSRC_F2S)
+		clock = CONFIG_HPS_CLK_F2S_SDR_REF_HZ;
+
+	/* get the SDRAM VCO clock */
+	reg = readl(&clock_manager_base->sdr_pll.vco);
+	clock /= ((reg & CLKMGR_SDRPLLGRP_VCO_DENOM_MASK) >>
+		  CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) + 1;
+	clock *= ((reg & CLKMGR_SDRPLLGRP_VCO_NUMER_MASK) >>
+		  CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) + 1;
+
+	/* get the SDRAM (DDR_DQS) clock */
+	reg = readl(&clock_manager_base->sdr_pll.ddrdqsclk);
+	reg = (reg & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK) >>
+	      CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET;
+	clock /= (reg + 1);
+
+	return clock;
+}
+
+unsigned int cm_get_l4_sp_clk_hz(void)
+{
+	uint32_t reg, clock = 0;
+
+	/* identify the source of L4 SP clock */
+	reg = readl(&clock_manager_base->main_pll.l4src);
+	reg = (reg & CLKMGR_MAINPLLGRP_L4SRC_L4SP) >>
+	      CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET;
+
+	if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) {
+		clock = cm_get_main_vco_clk_hz();
+
+		/* get the clock prior L4 SP divider (main clk) */
+		reg = readl(&clock_manager_base->altera.mainclk);
+		clock /= (reg + 1);
+		reg = readl(&clock_manager_base->main_pll.mainclk);
+		clock /= (reg + 1);
+	} else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) {
+		clock = cm_get_per_vco_clk_hz();
+
+		/* get the clock prior L4 SP divider (periph_base_clk) */
+		reg = readl(&clock_manager_base->per_pll.perbaseclk);
+		clock /= (reg + 1);
+	}
+
+	/* get the L4 SP clock which supplied to UART */
+	reg = readl(&clock_manager_base->main_pll.maindiv);
+	reg = (reg & CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK) >>
+	      CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET;
+	clock = clock / (1 << reg);
+
+	return clock;
+}
+
+unsigned int cm_get_mmc_controller_clk_hz(void)
+{
+	uint32_t reg, clock = 0;
+
+	/* identify the source of MMC clock */
+	reg = readl(&clock_manager_base->per_pll.src);
+	reg = (reg & CLKMGR_PERPLLGRP_SRC_SDMMC_MASK) >>
+	      CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET;
+
+	if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) {
+		clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ;
+	} else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) {
+		clock = cm_get_main_vco_clk_hz();
+
+		/* get the SDMMC clock */
+		reg = readl(&clock_manager_base->main_pll.mainnandsdmmcclk);
+		clock /= (reg + 1);
+	} else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) {
+		clock = cm_get_per_vco_clk_hz();
+
+		/* get the SDMMC clock */
+		reg = readl(&clock_manager_base->per_pll.pernandsdmmcclk);
+		clock /= (reg + 1);
+	}
+
+	/* further divide by 4 as we have fixed divider at wrapper */
+	clock /= 4;
+	return clock;
+}
+
+unsigned int cm_get_qspi_controller_clk_hz(void)
+{
+	uint32_t reg, clock = 0;
+
+	/* identify the source of QSPI clock */
+	reg = readl(&clock_manager_base->per_pll.src);
+	reg = (reg & CLKMGR_PERPLLGRP_SRC_QSPI_MASK) >>
+	      CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET;
+
+	if (reg == CLKMGR_QSPI_CLK_SRC_F2S) {
+		clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ;
+	} else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) {
+		clock = cm_get_main_vco_clk_hz();
+
+		/* get the qspi clock */
+		reg = readl(&clock_manager_base->main_pll.mainqspiclk);
+		clock /= (reg + 1);
+	} else if (reg == CLKMGR_QSPI_CLK_SRC_PER) {
+		clock = cm_get_per_vco_clk_hz();
+
+		/* get the qspi clock */
+		reg = readl(&clock_manager_base->per_pll.perqspiclk);
+		clock /= (reg + 1);
+	}
+
+	return clock;
+}
+
+static void cm_print_clock_quick_summary(void)
+{
+	printf("MPU       %10ld kHz\n", cm_get_mpu_clk_hz() / 1000);
+	printf("DDR       %10ld kHz\n", cm_get_sdram_clk_hz() / 1000);
+	printf("EOSC1       %8d kHz\n", CONFIG_HPS_CLK_OSC1_HZ / 1000);
+	printf("EOSC2       %8d kHz\n", CONFIG_HPS_CLK_OSC2_HZ / 1000);
+	printf("F2S_SDR_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_SDR_REF_HZ / 1000);
+	printf("F2S_PER_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_PER_REF_HZ / 1000);
+	printf("MMC         %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
+	printf("QSPI        %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000);
+	printf("UART        %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
+}
+
+int set_cpu_clk_info(void)
+{
+	/* Calculate the clock frequencies required for drivers */
+	cm_get_l4_sp_clk_hz();
+	cm_get_mmc_controller_clk_hz();
+
+	gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000;
+	gd->bd->bi_dsp_freq = 0;
+	gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000;
+
+	return 0;
+}
+
+int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cm_print_clock_quick_summary();
+	return 0;
+}
+
+U_BOOT_CMD(
+	clocks,	CONFIG_SYS_MAXARGS, 1, do_showclocks,
+	"display clocks",
+	""
+);
diff --git a/arch/arm/cpu/armv7/socfpga/fpga_manager.c b/arch/arm/cpu/armv7/socfpga/fpga_manager.c
new file mode 100644
index 0000000..43fd2fe
--- /dev/null
+++ b/arch/arm/cpu/armv7/socfpga/fpga_manager.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * All rights reserved.
+ *
+ * This file contains only support functions used also by the SoCFPGA
+ * platform code, the real meat is located in drivers/fpga/socfpga.c .
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/fpga_manager.h>
+#include <asm/arch/reset_manager.h>
+#include <asm/arch/system_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Timeout count */
+#define FPGA_TIMEOUT_CNT		0x1000000
+
+static struct socfpga_fpga_manager *fpgamgr_regs =
+	(struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS;
+
+/* Check whether FPGA Init_Done signal is high */
+static int is_fpgamgr_initdone_high(void)
+{
+	unsigned long val;
+
+	val = readl(&fpgamgr_regs->gpio_ext_porta);
+	return val & FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK;
+}
+
+/* Get the FPGA mode */
+int fpgamgr_get_mode(void)
+{
+	unsigned long val;
+
+	val = readl(&fpgamgr_regs->stat);
+	return val & FPGAMGRREGS_STAT_MODE_MASK;
+}
+
+/* Check whether FPGA is ready to be accessed */
+int fpgamgr_test_fpga_ready(void)
+{
+	/* Check for init done signal */
+	if (!is_fpgamgr_initdone_high())
+		return 0;
+
+	/* Check again to avoid false glitches */
+	if (!is_fpgamgr_initdone_high())
+		return 0;
+
+	if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_USERMODE)
+		return 0;
+
+	return 1;
+}
+
+/* Poll until FPGA is ready to be accessed or timeout occurred */
+int fpgamgr_poll_fpga_ready(void)
+{
+	unsigned long i;
+
+	/* If FPGA is blank, wait till WD invoke warm reset */
+	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+		/* check for init done signal */
+		if (!is_fpgamgr_initdone_high())
+			continue;
+		/* check again to avoid false glitches */
+		if (!is_fpgamgr_initdone_high())
+			continue;
+		return 1;
+	}
+
+	return 0;
+}
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c
index ecae393..0eab264 100644
--- a/arch/arm/cpu/armv7/socfpga/misc.c
+++ b/arch/arm/cpu/armv7/socfpga/misc.c
@@ -6,24 +6,103 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <altera.h>
 #include <miiphy.h>
 #include <netdev.h>
+#include <asm/arch/reset_manager.h>
+#include <asm/arch/system_manager.h>
+#include <asm/arch/dwmmc.h>
+#include <asm/arch/nic301.h>
+#include <asm/arch/scu.h>
+#include <asm/pl310.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static struct pl310_regs *const pl310 =
+	(struct pl310_regs *)CONFIG_SYS_PL310_BASE;
+static struct socfpga_system_manager *sysmgr_regs =
+	(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
+static struct socfpga_reset_manager *reset_manager_base =
+	(struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS;
+static struct nic301_registers *nic301_regs =
+	(struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS;
+static struct scu_registers *scu_regs =
+	(struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS;
+
 int dram_init(void)
 {
 	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
 	return 0;
 }
 
+void enable_caches(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+	icache_enable();
+#endif
+#ifndef CONFIG_SYS_DCACHE_OFF
+	dcache_enable();
+#endif
+}
+
+/*
+ * DesignWare Ethernet initialization
+ */
+#ifdef CONFIG_DESIGNWARE_ETH
+int cpu_eth_init(bd_t *bis)
+{
+#if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS
+	const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB;
+#elif CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS
+	const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB;
+#else
+#error "Incorrect CONFIG_EMAC_BASE value!"
+#endif
+
+	/* Initialize EMAC. This needs to be done at least once per boot. */
+
+	/*
+	 * Putting the EMAC controller to reset when configuring the PHY
+	 * interface select at System Manager
+	 */
+	socfpga_emac_reset(1);
+
+	/* Clearing emac0 PHY interface select to 0 */
+	clrbits_le32(&sysmgr_regs->emacgrp_ctrl,
+		     SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift);
+
+	/* configure to PHY interface select choosed */
+	setbits_le32(&sysmgr_regs->emacgrp_ctrl,
+		     SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << physhift);
+
+	/* Release the EMAC controller from reset */
+	socfpga_emac_reset(0);
+
+	/* initialize and register the emac */
+	return designware_initialize(CONFIG_EMAC_BASE,
+				     CONFIG_PHY_INTERFACE_MODE);
+}
+#endif
+
+#ifdef CONFIG_DWMMC
+/*
+ * Initializes MMC controllers.
+ * to override, implement board_mmc_init()
+ */
+int cpu_mmc_init(bd_t *bis)
+{
+	return socfpga_dwmmc_init(SOCFPGA_SDMMC_ADDRESS,
+				  CONFIG_HPS_SDMMC_BUSWIDTH, 0);
+}
+#endif
+
 #if defined(CONFIG_DISPLAY_CPUINFO)
 /*
  * Print CPU information
  */
 int print_cpuinfo(void)
 {
-	puts("CPU   : Altera SOCFPGA Platform\n");
+	puts("CPU:   Altera SoCFPGA Platform\n");
 	return 0;
 }
 #endif
@@ -36,22 +115,159 @@
 }
 #endif
 
-int misc_init_r(void)
+#ifdef CONFIG_FPGA
+/*
+ * FPGA programming support for SoC FPGA Cyclone V
+ */
+static Altera_desc altera_fpga[] = {
+	{
+		/* Family */
+		Altera_SoCFPGA,
+		/* Interface type */
+		fast_passive_parallel,
+		/* No limitation as additional data will be ignored */
+		-1,
+		/* No device function table */
+		NULL,
+		/* Base interface address specified in driver */
+		NULL,
+		/* No cookie implementation */
+		0
+	},
+};
+
+/* add device descriptor to FPGA device table */
+static void socfpga_fpga_add(void)
 {
+	int i;
+	fpga_init();
+	for (i = 0; i < ARRAY_SIZE(altera_fpga); i++)
+		fpga_add(fpga_altera, &altera_fpga[i]);
+}
+#else
+static inline void socfpga_fpga_add(void) {}
+#endif
+
+int arch_cpu_init(void)
+{
+	/*
+	 * If the HW watchdog is NOT enabled, make sure it is not running,
+	 * for example because it was enabled in the preloader. This might
+	 * trigger a watchdog-triggered reboot of Linux kernel later.
+	 */
+#ifndef CONFIG_HW_WATCHDOG
+	socfpga_watchdog_reset();
+#endif
 	return 0;
 }
 
-
 /*
- * DesignWare Ethernet initialization
+ * Convert all NIC-301 AMBA slaves from secure to non-secure
  */
-int cpu_eth_init(bd_t *bis)
+static void socfpga_nic301_slave_ns(void)
 {
-#if !defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) && !defined(CONFIG_SPL_BUILD)
-       /* initialize and register the emac */
-	return designware_initialize(CONFIG_EMAC_BASE,
-				     CONFIG_PHY_INTERFACE_MODE);
-#else
-	return 0;
-#endif
+	writel(0x1, &nic301_regs->lwhps2fpgaregs);
+	writel(0x1, &nic301_regs->hps2fpgaregs);
+	writel(0x1, &nic301_regs->acp);
+	writel(0x1, &nic301_regs->rom);
+	writel(0x1, &nic301_regs->ocram);
+	writel(0x1, &nic301_regs->sdrdata);
 }
+
+static uint32_t iswgrp_handoff[8];
+
+int misc_init_r(void)
+{
+	int i;
+	for (i = 0; i < 8; i++)	/* Cache initial SW setting regs */
+		iswgrp_handoff[i] = readl(&sysmgr_regs->iswgrp_handoff[i]);
+
+	socfpga_bridges_reset(1);
+	socfpga_nic301_slave_ns();
+
+	/*
+	 * Private components security:
+	 * U-Boot : configure private timer, global timer and cpu component
+	 * access as non secure for kernel stage (as required by Linux)
+	 */
+	setbits_le32(&scu_regs->sacr, 0xfff);
+
+	/* Configure the L2 controller to make SDRAM start at 0 */
+#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
+	writel(0x2, &nic301_regs->remap);
+#else
+	writel(0x1, &nic301_regs->remap);	/* remap.mpuzero */
+	writel(0x1, &pl310->pl310_addr_filter_start);
+#endif
+
+	/* Add device descriptor to FPGA device table */
+	socfpga_fpga_add();
+	return 0;
+}
+
+static void socfpga_sdram_apply_static_cfg(void)
+{
+	const uint32_t staticcfg = SOCFPGA_SDR_ADDRESS + 0x505c;
+	const uint32_t applymask = 0x8;
+	uint32_t val = readl(staticcfg) | 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"(staticcfg) : "memory", "cc");
+}
+
+int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	argv++;
+
+	switch (*argv[0]) {
+	case 'e':	/* Enable */
+		writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module);
+		socfpga_sdram_apply_static_cfg();
+		writel(iswgrp_handoff[3], SOCFPGA_SDR_ADDRESS + 0x5080);
+		writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset);
+		writel(iswgrp_handoff[1], &nic301_regs->remap);
+		break;
+	case 'd':	/* Disable */
+		writel(0, &sysmgr_regs->fpgaintfgrp_module);
+		writel(0, SOCFPGA_SDR_ADDRESS + 0x5080);
+		socfpga_sdram_apply_static_cfg();
+		writel(0, &reset_manager_base->brg_mod_reset);
+		writel(1, &nic301_regs->remap);
+		break;
+	default:
+		return CMD_RET_USAGE;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	bridge, 2, 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"
+	""
+);
diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c
index e320c01..1d3a95d 100644
--- a/arch/arm/cpu/armv7/socfpga/reset_manager.c
+++ b/arch/arm/cpu/armv7/socfpga/reset_manager.c
@@ -8,12 +8,25 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/reset_manager.h>
+#include <asm/arch/fpga_manager.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 static const struct socfpga_reset_manager *reset_manager_base =
 		(void *)SOCFPGA_RSTMGR_ADDRESS;
 
+/* Toggle reset signal to watchdog (WDT is disabled after this operation!) */
+void socfpga_watchdog_reset(void)
+{
+	/* assert reset for watchdog */
+	setbits_le32(&reset_manager_base->per_mod_reset,
+		     1 << RSTMGR_PERMODRST_L4WD0_LSB);
+
+	/* deassert watchdog from reset (watchdog in not running state) */
+	clrbits_le32(&reset_manager_base->per_mod_reset,
+		     1 << RSTMGR_PERMODRST_L4WD0_LSB);
+}
+
 /*
  * Write the reset manager register to cause reset
  */
@@ -37,3 +50,57 @@
 {
 	writel(0, &reset_manager_base->per_mod_reset);
 }
+
+#if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET)
+void socfpga_bridges_reset(int enable)
+{
+	/* For SoCFPGA-VT, this is NOP. */
+}
+#else
+
+#define L3REGS_REMAP_LWHPS2FPGA_MASK	0x10
+#define L3REGS_REMAP_HPS2FPGA_MASK	0x08
+#define L3REGS_REMAP_OCRAM_MASK		0x01
+
+void socfpga_bridges_reset(int enable)
+{
+	const uint32_t l3mask = L3REGS_REMAP_LWHPS2FPGA_MASK |
+				L3REGS_REMAP_HPS2FPGA_MASK |
+				L3REGS_REMAP_OCRAM_MASK;
+
+	if (enable) {
+		/* brdmodrst */
+		writel(0xffffffff, &reset_manager_base->brg_mod_reset);
+	} else {
+		/* Check signal from FPGA. */
+		if (fpgamgr_poll_fpga_ready()) {
+			/* FPGA not ready. Wait for watchdog timeout. */
+			printf("%s: fpga not ready, hanging.\n", __func__);
+			hang();
+		}
+
+		/* brdmodrst */
+		writel(0, &reset_manager_base->brg_mod_reset);
+
+		/* Remap the bridges into memory map */
+		writel(l3mask, SOCFPGA_L3REGS_ADDRESS);
+	}
+}
+#endif
+
+/* Change the reset state for EMAC 0 and EMAC 1 */
+void socfpga_emac_reset(int enable)
+{
+	const void *reset = &reset_manager_base->per_mod_reset;
+
+	if (enable) {
+		setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB);
+		setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB);
+	} else {
+#if (CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS)
+		clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB);
+#elif (CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS)
+		clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB);
+#endif
+	}
+}
diff --git a/arch/arm/cpu/armv7/socfpga/spl.c b/arch/arm/cpu/armv7/socfpga/spl.c
index 27efde6..bd9f338 100644
--- a/arch/arm/cpu/armv7/socfpga/spl.c
+++ b/arch/arm/cpu/armv7/socfpga/spl.c
@@ -19,6 +19,31 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define MAIN_VCO_BASE (					\
+	(CONFIG_HPS_MAINPLLGRP_VCO_DENOM <<		\
+		CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) |	\
+	(CONFIG_HPS_MAINPLLGRP_VCO_NUMER <<		\
+		CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET)	\
+	)
+
+#define PERI_VCO_BASE (					\
+	(CONFIG_HPS_PERPLLGRP_VCO_PSRC <<		\
+		CLKMGR_PERPLLGRP_VCO_PSRC_OFFSET) |	\
+	(CONFIG_HPS_PERPLLGRP_VCO_DENOM <<		\
+		CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) |	\
+	(CONFIG_HPS_PERPLLGRP_VCO_NUMER <<		\
+		CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET)	\
+	)
+
+#define SDR_VCO_BASE (					\
+	(CONFIG_HPS_SDRPLLGRP_VCO_SSRC <<		\
+		CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET) |	\
+	(CONFIG_HPS_SDRPLLGRP_VCO_DENOM <<		\
+		CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) |	\
+	(CONFIG_HPS_SDRPLLGRP_VCO_NUMER <<		\
+		CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET)	\
+	)
+
 u32 spl_boot_device(void)
 {
 	return BOOT_DEVICE_RAM;
@@ -33,86 +58,87 @@
 	cm_config_t cm_default_cfg = {
 		/* main group */
 		MAIN_VCO_BASE,
-		CLKMGR_MAINPLLGRP_MPUCLK_CNT_SET(
-			CONFIG_HPS_MAINPLLGRP_MPUCLK_CNT),
-		CLKMGR_MAINPLLGRP_MAINCLK_CNT_SET(
-			CONFIG_HPS_MAINPLLGRP_MAINCLK_CNT),
-		CLKMGR_MAINPLLGRP_DBGATCLK_CNT_SET(
-			CONFIG_HPS_MAINPLLGRP_DBGATCLK_CNT),
-		CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_SET(
-			CONFIG_HPS_MAINPLLGRP_MAINQSPICLK_CNT),
-		CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_SET(
-			CONFIG_HPS_MAINPLLGRP_MAINNANDSDMMCCLK_CNT),
-		CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_SET(
-			CONFIG_HPS_MAINPLLGRP_CFGS2FUSER0CLK_CNT),
-		CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_SET(
-			CONFIG_HPS_MAINPLLGRP_MAINDIV_L3MPCLK) |
-		CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_SET(
-			CONFIG_HPS_MAINPLLGRP_MAINDIV_L3SPCLK) |
-		CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_SET(
-			CONFIG_HPS_MAINPLLGRP_MAINDIV_L4MPCLK) |
-		CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_SET(
-			CONFIG_HPS_MAINPLLGRP_MAINDIV_L4SPCLK),
-		CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_SET(
-			CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGATCLK) |
-		CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_SET(
-			CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGCLK),
-		CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_SET(
-			CONFIG_HPS_MAINPLLGRP_TRACEDIV_TRACECLK),
-		CLKMGR_MAINPLLGRP_L4SRC_L4MP_SET(
-			CONFIG_HPS_MAINPLLGRP_L4SRC_L4MP) |
-		CLKMGR_MAINPLLGRP_L4SRC_L4SP_SET(
-			CONFIG_HPS_MAINPLLGRP_L4SRC_L4SP),
+		(CONFIG_HPS_MAINPLLGRP_MPUCLK_CNT <<
+			CLKMGR_MAINPLLGRP_MPUCLK_CNT_OFFSET),
+		(CONFIG_HPS_MAINPLLGRP_MAINCLK_CNT <<
+			CLKMGR_MAINPLLGRP_MAINCLK_CNT_OFFSET),
+		(CONFIG_HPS_MAINPLLGRP_DBGATCLK_CNT <<
+			CLKMGR_MAINPLLGRP_DBGATCLK_CNT_OFFSET),
+		(CONFIG_HPS_MAINPLLGRP_MAINQSPICLK_CNT <<
+			CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_OFFSET),
+		(CONFIG_HPS_MAINPLLGRP_MAINNANDSDMMCCLK_CNT <<
+			CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET),
+		(CONFIG_HPS_MAINPLLGRP_CFGS2FUSER0CLK_CNT <<
+			CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_OFFSET),
+		(CONFIG_HPS_MAINPLLGRP_MAINDIV_L3MPCLK <<
+			CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_OFFSET) |
+		(CONFIG_HPS_MAINPLLGRP_MAINDIV_L3SPCLK <<
+			CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_OFFSET) |
+		(CONFIG_HPS_MAINPLLGRP_MAINDIV_L4MPCLK <<
+			CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_OFFSET) |
+		(CONFIG_HPS_MAINPLLGRP_MAINDIV_L4SPCLK <<
+			CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET),
+		(CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGATCLK <<
+			CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_OFFSET) |
+		(CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGCLK <<
+			CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_OFFSET),
+		(CONFIG_HPS_MAINPLLGRP_TRACEDIV_TRACECLK <<
+			CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_OFFSET),
+		(CONFIG_HPS_MAINPLLGRP_L4SRC_L4MP <<
+			CLKMGR_MAINPLLGRP_L4SRC_L4MP_OFFSET) |
+		(CONFIG_HPS_MAINPLLGRP_L4SRC_L4SP <<
+			CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET),
 
 		/* peripheral group */
 		PERI_VCO_BASE,
-		CLKMGR_PERPLLGRP_EMAC0CLK_CNT_SET(
-			CONFIG_HPS_PERPLLGRP_EMAC0CLK_CNT),
-		CLKMGR_PERPLLGRP_EMAC1CLK_CNT_SET(
-			CONFIG_HPS_PERPLLGRP_EMAC1CLK_CNT),
-		CLKMGR_PERPLLGRP_PERQSPICLK_CNT_SET(
-			CONFIG_HPS_PERPLLGRP_PERQSPICLK_CNT),
-		CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_SET(
-			CONFIG_HPS_PERPLLGRP_PERNANDSDMMCCLK_CNT),
-		CLKMGR_PERPLLGRP_PERBASECLK_CNT_SET(
-			CONFIG_HPS_PERPLLGRP_PERBASECLK_CNT),
-		CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_SET(
-			CONFIG_HPS_PERPLLGRP_S2FUSER1CLK_CNT),
-		CLKMGR_PERPLLGRP_DIV_USBCLK_SET(
-			CONFIG_HPS_PERPLLGRP_DIV_USBCLK) |
-		CLKMGR_PERPLLGRP_DIV_SPIMCLK_SET(
-			CONFIG_HPS_PERPLLGRP_DIV_SPIMCLK) |
-		CLKMGR_PERPLLGRP_DIV_CAN0CLK_SET(
-			CONFIG_HPS_PERPLLGRP_DIV_CAN0CLK) |
-		CLKMGR_PERPLLGRP_DIV_CAN1CLK_SET(
-			CONFIG_HPS_PERPLLGRP_DIV_CAN1CLK),
-		CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_SET(
-			CONFIG_HPS_PERPLLGRP_GPIODIV_GPIODBCLK),
-		CLKMGR_PERPLLGRP_SRC_QSPI_SET(
-			CONFIG_HPS_PERPLLGRP_SRC_QSPI) |
-		CLKMGR_PERPLLGRP_SRC_NAND_SET(
-			CONFIG_HPS_PERPLLGRP_SRC_NAND) |
-		CLKMGR_PERPLLGRP_SRC_SDMMC_SET(
-			CONFIG_HPS_PERPLLGRP_SRC_SDMMC),
+		(CONFIG_HPS_PERPLLGRP_EMAC0CLK_CNT <<
+			CLKMGR_PERPLLGRP_EMAC0CLK_CNT_OFFSET),
+		(CONFIG_HPS_PERPLLGRP_EMAC1CLK_CNT <<
+			CLKMGR_PERPLLGRP_EMAC1CLK_CNT_OFFSET),
+		(CONFIG_HPS_PERPLLGRP_PERQSPICLK_CNT <<
+			CLKMGR_PERPLLGRP_PERQSPICLK_CNT_OFFSET),
+		(CONFIG_HPS_PERPLLGRP_PERNANDSDMMCCLK_CNT <<
+			CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET),
+		(CONFIG_HPS_PERPLLGRP_PERBASECLK_CNT <<
+			CLKMGR_PERPLLGRP_PERBASECLK_CNT_OFFSET),
+		(CONFIG_HPS_PERPLLGRP_S2FUSER1CLK_CNT <<
+			CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_OFFSET),
+		(CONFIG_HPS_PERPLLGRP_DIV_USBCLK <<
+			CLKMGR_PERPLLGRP_DIV_USBCLK_OFFSET) |
+		(CONFIG_HPS_PERPLLGRP_DIV_SPIMCLK <<
+			CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET) |
+		(CONFIG_HPS_PERPLLGRP_DIV_CAN0CLK <<
+			CLKMGR_PERPLLGRP_DIV_CAN0CLK_OFFSET) |
+		(CONFIG_HPS_PERPLLGRP_DIV_CAN1CLK <<
+			CLKMGR_PERPLLGRP_DIV_CAN1CLK_OFFSET),
+		(CONFIG_HPS_PERPLLGRP_GPIODIV_GPIODBCLK <<
+			CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_OFFSET),
+		(CONFIG_HPS_PERPLLGRP_SRC_QSPI <<
+			CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET) |
+		(CONFIG_HPS_PERPLLGRP_SRC_NAND <<
+			CLKMGR_PERPLLGRP_SRC_NAND_OFFSET) |
+		(CONFIG_HPS_PERPLLGRP_SRC_SDMMC <<
+			CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET),
 
 		/* sdram pll group */
 		SDR_VCO_BASE,
-		CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_SET(
-			CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE) |
-		CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_SET(
-			CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_CNT),
-		CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_SET(
-			CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE) |
-		CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_SET(
-			CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT),
-		CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_SET(
-			CONFIG_HPS_SDRPLLGRP_DDRDQCLK_PHASE) |
-		CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_SET(
-			CONFIG_HPS_SDRPLLGRP_DDRDQCLK_CNT),
-		CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_SET(
-			CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE) |
-		CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_SET(
-			CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT),
+		(CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE <<
+			CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_OFFSET) |
+		(CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_CNT <<
+			CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET),
+		(CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE <<
+			CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_OFFSET) |
+		(CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT <<
+			CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_OFFSET),
+		(CONFIG_HPS_SDRPLLGRP_DDRDQCLK_PHASE <<
+			CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_OFFSET) |
+		(CONFIG_HPS_SDRPLLGRP_DDRDQCLK_CNT <<
+			CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_OFFSET),
+		(CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE <<
+			CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_OFFSET) |
+		(CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT <<
+			CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_OFFSET),
+
 	};
 
 	debug("Freezing all I/O banks\n");
diff --git a/arch/arm/cpu/armv7/socfpga/system_manager.c b/arch/arm/cpu/armv7/socfpga/system_manager.c
index d96521b..11f7bad 100644
--- a/arch/arm/cpu/armv7/socfpga/system_manager.c
+++ b/arch/arm/cpu/armv7/socfpga/system_manager.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2013 Altera Corporation <www.altera.com>
+ * Copyright (C) 2013 Altera Corporation <www.altera.com>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -7,21 +7,62 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/system_manager.h>
+#include <asm/arch/fpga_manager.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static struct socfpga_system_manager *sysmgr_regs =
+	(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
+
+/*
+ * Populate the value for SYSMGR.FPGAINTF.MODULE based on pinmux setting.
+ * The value is not wrote to SYSMGR.FPGAINTF.MODULE but
+ * CONFIG_SYSMGR_ISWGRP_HANDOFF.
+ */
+static void populate_sysmgr_fpgaintf_module(void)
+{
+	uint32_t handoff_val = 0;
+
+	/* ISWGRP_HANDOFF_FPGAINTF */
+	writel(0, &sysmgr_regs->iswgrp_handoff[2]);
+
+	/* Enable the signal for those HPS peripherals that use FPGA. */
+	if (readl(&sysmgr_regs->nandusefpga) == SYSMGR_FPGAINTF_USEFPGA)
+		handoff_val |= SYSMGR_FPGAINTF_NAND;
+	if (readl(&sysmgr_regs->rgmii1usefpga) == SYSMGR_FPGAINTF_USEFPGA)
+		handoff_val |= SYSMGR_FPGAINTF_EMAC1;
+	if (readl(&sysmgr_regs->sdmmcusefpga) == SYSMGR_FPGAINTF_USEFPGA)
+		handoff_val |= SYSMGR_FPGAINTF_SDMMC;
+	if (readl(&sysmgr_regs->rgmii0usefpga) == SYSMGR_FPGAINTF_USEFPGA)
+		handoff_val |= SYSMGR_FPGAINTF_EMAC0;
+	if (readl(&sysmgr_regs->spim0usefpga) == SYSMGR_FPGAINTF_USEFPGA)
+		handoff_val |= SYSMGR_FPGAINTF_SPIM0;
+	if (readl(&sysmgr_regs->spim1usefpga) == SYSMGR_FPGAINTF_USEFPGA)
+		handoff_val |= SYSMGR_FPGAINTF_SPIM1;
+
+	/* populate (not writing) the value for SYSMGR.FPGAINTF.MODULE
+	based on pinmux setting */
+	setbits_le32(&sysmgr_regs->iswgrp_handoff[2], handoff_val);
+
+	handoff_val = readl(&sysmgr_regs->iswgrp_handoff[2]);
+	if (fpgamgr_test_fpga_ready()) {
+		/* Enable the required signals only */
+		writel(handoff_val, &sysmgr_regs->fpgaintfgrp_module);
+	}
+}
+
 /*
  * Configure all the pin muxes
  */
 void sysmgr_pinmux_init(void)
 {
-	unsigned long offset = CONFIG_SYSMGR_PINMUXGRP_OFFSET;
+	uint32_t regs = (uint32_t)&sysmgr_regs->emacio[0];
+	int i;
 
-	const unsigned long *pval = sys_mgr_init_table;
-	unsigned long i;
-
-	for (i = 0; i < ARRAY_SIZE(sys_mgr_init_table);
-		i++, offset += sizeof(unsigned long)) {
-		writel(*pval++, (SOCFPGA_SYSMGR_ADDRESS + offset));
+	for (i = 0; i < ARRAY_SIZE(sys_mgr_init_table); i++) {
+		writel(sys_mgr_init_table[i], regs);
+		regs += sizeof(regs);
 	}
+
+	populate_sysmgr_fpgaintf_module();
 }
diff --git a/arch/arm/cpu/armv7/socfpga/timer.c b/arch/arm/cpu/armv7/socfpga/timer.c
index 58fc789..253cde3 100644
--- a/arch/arm/cpu/armv7/socfpga/timer.c
+++ b/arch/arm/cpu/armv7/socfpga/timer.c
@@ -8,6 +8,8 @@
 #include <asm/io.h>
 #include <asm/arch/timer.h>
 
+#define TIMER_LOAD_VAL		0xFFFFFFFF
+
 static const struct socfpga_timer *timer_base = (void *)CONFIG_SYS_TIMERBASE;
 
 /*
diff --git a/arch/arm/include/asm/arch-socfpga/clock_manager.h b/arch/arm/include/asm/arch-socfpga/clock_manager.h
index babac0e..fa49f6a 100644
--- a/arch/arm/include/asm/arch-socfpga/clock_manager.h
+++ b/arch/arm/include/asm/arch-socfpga/clock_manager.h
@@ -7,6 +7,15 @@
 #ifndef	_CLOCK_MANAGER_H_
 #define	_CLOCK_MANAGER_H_
 
+#ifndef __ASSEMBLER__
+/* Clock speed accessors */
+unsigned long cm_get_mpu_clk_hz(void);
+unsigned long cm_get_sdram_clk_hz(void);
+unsigned int cm_get_l4_sp_clk_hz(void);
+unsigned int cm_get_mmc_controller_clk_hz(void);
+unsigned int cm_get_qspi_controller_clk_hz(void);
+#endif
+
 typedef struct {
 	/* main group */
 	uint32_t main_vco_base;
@@ -89,6 +98,11 @@
 	u32	stat;
 };
 
+struct socfpga_clock_manager_altera {
+	u32	mpuclk;
+	u32	mainclk;
+};
+
 struct socfpga_clock_manager {
 	u32	ctrl;
 	u32	bypass;
@@ -100,112 +114,194 @@
 	struct socfpga_clock_manager_main_pll main_pll;
 	struct socfpga_clock_manager_per_pll per_pll;
 	struct socfpga_clock_manager_sdr_pll sdr_pll;
-	u32	_pad_0xe0_0x200[72];
+	struct socfpga_clock_manager_altera altera;
+	u32	_pad_0xe8_0x200[70];
 };
 
-#define CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK 0x00000200
-#define CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK 0x00000080
-#define CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK 0x00000040
-#define CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK 0x00000020
-#define CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK 0x00000010
-#define CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK 0x00000004
-#define CLKMGR_MAINPLLGRP_VCO_RESET_VALUE 0x8001000d
-#define CLKMGR_PERPLLGRP_VCO_RESET_VALUE 0x8001000d
-#define CLKMGR_SDRPLLGRP_VCO_RESET_VALUE 0x8001000d
-#define CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_SET(x) (((x) << 4) & 0x00000070)
-#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_SET(x)  (((x) << 7) & 0x00000380)
-#define CLKMGR_MAINPLLGRP_L4SRC_L4MP_SET(x) (((x) << 0) & 0x00000001)
-#define CLKMGR_MAINPLLGRP_L4SRC_L4SP_SET(x) (((x) << 1) & 0x00000002)
-#define CLKMGR_PERPLLGRP_SRC_QSPI_SET(x) (((x) << 4) & 0x00000030)
-#define CLKMGR_PERPLLGRP_SRC_NAND_SET(x) (((x) << 2) & 0x0000000c)
-#define CLKMGR_PERPLLGRP_SRC_SDMMC_SET(x) (((x) << 0) & 0x00000003)
-#define CLKMGR_MAINPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000)
-#define CLKMGR_MAINPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8)
-#define CLKMGR_MAINPLLGRP_VCO_PWRDN_SET(x) (((x) << 2) & 0x00000004)
-#define CLKMGR_MAINPLLGRP_VCO_EN_SET(x) (((x) << 1) & 0x00000002)
-#define CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(x) (((x) << 0) & 0x00000001)
-#define CLKMGR_PERPLLGRP_VCO_PSRC_SET(x) (((x) << 22) & 0x00c00000)
-#define CLKMGR_PERPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000)
-#define CLKMGR_PERPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8)
-#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(x) (((x) << 25) & 0x7e000000)
-#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(x) (((x) << 24) & 0x01000000)
-#define CLKMGR_SDRPLLGRP_VCO_SSRC_SET(x) (((x) << 22) & 0x00c00000)
-#define CLKMGR_SDRPLLGRP_VCO_DENOM_SET(x) (((x) << 16) & 0x003f0000)
-#define CLKMGR_SDRPLLGRP_VCO_NUMER_SET(x) (((x) << 3) & 0x0000fff8)
-#define CLKMGR_MAINPLLGRP_MPUCLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_MAINPLLGRP_MAINCLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_MAINPLLGRP_DBGATCLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_SET(x) \
-	(((x) << 0) & 0x000001ff)
-#define CLKMGR_PERPLLGRP_EMAC0CLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_PERPLLGRP_EMAC1CLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_CNT_SET(x) \
-	(((x) << 0) & 0x000001ff)
-#define CLKMGR_PERPLLGRP_PERBASECLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_SET(x) (((x) << 9) & 0x00000e00)
-#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_SET(x) (((x) << 9) & 0x00000e00)
-#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_SET(x) (((x) << 9) & 0x00000e00)
-#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_SET(x) (((x) << 9) & 0x00000e00)
-#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_SET(x) (((x) << 2) & 0x0000000c)
-#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_SET(x) (((x) << 0) & 0x00000003)
-#define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_SET(x) (((x) << 0) & 0x00000007)
-#define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_SET(x) (((x) << 0) & 0x00000003)
-#define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_SET(x) (((x) << 2) & 0x0000000c)
-#define CLKMGR_BYPASS_PERPLL_SET(x) (((x) << 3) & 0x00000008)
-#define CLKMGR_BYPASS_SDRPLL_SET(x) (((x) << 1) & 0x00000002)
-#define CLKMGR_BYPASS_MAINPLL_SET(x) (((x) << 0) & 0x00000001)
-#define CLKMGR_PERPLLGRP_DIV_USBCLK_SET(x) (((x) << 0) & 0x00000007)
-#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_SET(x) (((x) << 3) & 0x00000038)
-#define CLKMGR_PERPLLGRP_DIV_CAN0CLK_SET(x) (((x) << 6) & 0x000001c0)
-#define CLKMGR_PERPLLGRP_DIV_CAN1CLK_SET(x) (((x) << 9) & 0x00000e00)
-#define CLKMGR_INTER_SDRPLLLOCKED_MASK 0x00000100
-#define CLKMGR_INTER_PERPLLLOCKED_MASK 0x00000080
-#define CLKMGR_INTER_MAINPLLLOCKED_MASK 0x00000040
-#define CLKMGR_CTRL_SAFEMODE_MASK 0x00000001
-#define CLKMGR_CTRL_SAFEMODE_SET(x) (((x) << 0) & 0x00000001)
-#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_MASK 0x7e000000
-#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(x) (((x) << 24) & 0x01000000)
-#define CLKMGR_PERPLLGRP_PERQSPICLK_CNT_SET(x) (((x) << 0) & 0x000001ff)
-#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_SET(x) (((x) << 3) & 0x00000038)
-#define CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x00ffffff)
-#define CLKMGR_BYPASS_PERPLLSRC_SET(x) (((x) << 4) & 0x00000010)
-#define CLKMGR_BYPASS_SDRPLLSRC_SET(x) (((x) << 2) & 0x00000004)
-#define CLKMGR_PERPLLGRP_SRC_RESET_VALUE 0x00000015
-#define CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE 0x00000000
-#define CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK 0x80000000
-#define CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK 0x80000000
-#define CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK 0x80000000
-#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK 0x001ffe00
-#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK 0x001ffe00
-#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK 0x001ffe00
-#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK 0x001ffe00
-#define CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK 0x01000000
-#define CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK 0x01000000
-#define CLKMGR_PERPLLGRP_EN_NANDCLK_MASK 0x00000400
-#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK 0x000001ff
-#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK 0x000001ff
-#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK 0x000001ff
-#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK 0x000001ff
+#define CLKMGR_CTRL_SAFEMODE				(1 << 0)
+#define CLKMGR_CTRL_SAFEMODE_OFFSET			0
 
-#define MAIN_VCO_BASE \
-	(CLKMGR_MAINPLLGRP_VCO_DENOM_SET(CONFIG_HPS_MAINPLLGRP_VCO_DENOM) | \
-	CLKMGR_MAINPLLGRP_VCO_NUMER_SET(CONFIG_HPS_MAINPLLGRP_VCO_NUMER))
+#define CLKMGR_BYPASS_PERPLLSRC				(1 << 4)
+#define CLKMGR_BYPASS_PERPLLSRC_OFFSET			4
+#define CLKMGR_BYPASS_PERPLL				(1 << 3)
+#define CLKMGR_BYPASS_PERPLL_OFFSET			3
+#define CLKMGR_BYPASS_SDRPLLSRC				(1 << 2)
+#define CLKMGR_BYPASS_SDRPLLSRC_OFFSET			2
+#define CLKMGR_BYPASS_SDRPLL				(1 << 1)
+#define CLKMGR_BYPASS_SDRPLL_OFFSET			1
+#define CLKMGR_BYPASS_MAINPLL				(1 << 0)
+#define CLKMGR_BYPASS_MAINPLL_OFFSET			0
 
-#define PERI_VCO_BASE \
-	(CLKMGR_PERPLLGRP_VCO_PSRC_SET(CONFIG_HPS_PERPLLGRP_VCO_PSRC) | \
-	CLKMGR_PERPLLGRP_VCO_DENOM_SET(CONFIG_HPS_PERPLLGRP_VCO_DENOM) | \
-	CLKMGR_PERPLLGRP_VCO_NUMER_SET(CONFIG_HPS_PERPLLGRP_VCO_NUMER))
+#define CLKMGR_INTER_SDRPLLLOCKED_MASK			0x00000100
+#define CLKMGR_INTER_PERPLLLOCKED_MASK			0x00000080
+#define CLKMGR_INTER_MAINPLLLOCKED_MASK			0x00000040
+#define CLKMGR_INTER_PERPLLLOST_MASK			0x00000010
+#define CLKMGR_INTER_SDRPLLLOST_MASK			0x00000020
+#define CLKMGR_INTER_MAINPLLLOST_MASK			0x00000008
 
-#define SDR_VCO_BASE \
-	(CLKMGR_SDRPLLGRP_VCO_SSRC_SET(CONFIG_HPS_SDRPLLGRP_VCO_SSRC) | \
-	CLKMGR_SDRPLLGRP_VCO_DENOM_SET(CONFIG_HPS_SDRPLLGRP_VCO_DENOM) | \
-	CLKMGR_SDRPLLGRP_VCO_NUMER_SET(CONFIG_HPS_SDRPLLGRP_VCO_NUMER))
+#define CLKMGR_STAT_BUSY				(1 << 0)
+
+/* Main PLL */
+#define CLKMGR_MAINPLLGRP_VCO_BGPWRDN			(1 << 0)
+#define CLKMGR_MAINPLLGRP_VCO_BGPWRDN_OFFSET		0
+#define CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET		16
+#define CLKMGR_MAINPLLGRP_VCO_DENOM_MASK		0x003f0000
+#define CLKMGR_MAINPLLGRP_VCO_EN			(1 << 1)
+#define CLKMGR_MAINPLLGRP_VCO_EN_OFFSET			1
+#define CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET		3
+#define CLKMGR_MAINPLLGRP_VCO_NUMER_MASK		0x0000fff8
+#define CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK		0x01000000
+#define CLKMGR_MAINPLLGRP_VCO_PWRDN			(1 << 2)
+#define CLKMGR_MAINPLLGRP_VCO_PWRDN_OFFSET		2
+#define CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK		0x80000000
+#define CLKMGR_MAINPLLGRP_VCO_RESET_VALUE		0x8001000d
+
+#define CLKMGR_MAINPLLGRP_MPUCLK_CNT_OFFSET		0
+#define CLKMGR_MAINPLLGRP_MPUCLK_CNT_MASK		0x000001ff
+
+#define CLKMGR_MAINPLLGRP_MAINCLK_CNT_OFFSET		0
+#define CLKMGR_MAINPLLGRP_MAINCLK_CNT_MASK		0x000001ff
+
+#define CLKMGR_MAINPLLGRP_DBGATCLK_CNT_OFFSET		0
+#define CLKMGR_MAINPLLGRP_DBGATCLK_CNT_MASK		0x000001ff
+
+#define CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_OFFSET	0
+#define CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_MASK		0x000001ff
+
+#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_CNT_OFFSET	0
+#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_CNT_MASK	0x000001ff
+
+#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_OFFSET	0
+#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_MASK	0x000001ff
+
+#define CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK		0x00000010
+#define CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK		0x00000020
+#define CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK		0x00000080
+#define CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK		0x00000040
+#define CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK		0x00000004
+#define CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK		0x00000200
+
+#define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_OFFSET	0
+#define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_MASK		0x00000003
+#define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_OFFSET	2
+#define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_MASK		0x0000000c
+#define CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_OFFSET	4
+#define CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_MASK		0x00000070
+#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET	7
+#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK		0x00000380
+
+#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_OFFSET	0
+#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_MASK		0x00000003
+#define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_OFFSET		2
+#define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_MASK		0x0000000c
+
+#define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_OFFSET	0
+#define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_MASK	0x00000007
+
+#define CLKMGR_MAINPLLGRP_L4SRC_L4MP			(1 << 0)
+#define CLKMGR_MAINPLLGRP_L4SRC_L4MP_OFFSET		0
+#define CLKMGR_MAINPLLGRP_L4SRC_L4SP			(1 << 1)
+#define CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET		1
+#define CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE		0x00000000
+#define CLKMGR_L4_SP_CLK_SRC_MAINPLL			0x0
+#define CLKMGR_L4_SP_CLK_SRC_PERPLL			0x1
+
+/* Per PLL */
+#define CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET		16
+#define CLKMGR_PERPLLGRP_VCO_DENOM_MASK			0x003f0000
+#define CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET		3
+#define CLKMGR_PERPLLGRP_VCO_NUMER_MASK			0x0000fff8
+#define CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK		0x01000000
+#define CLKMGR_PERPLLGRP_VCO_PSRC_OFFSET		22
+#define CLKMGR_PERPLLGRP_VCO_PSRC_MASK			0x00c00000
+#define CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK		0x80000000
+#define CLKMGR_PERPLLGRP_VCO_RESET_VALUE		0x8001000d
+#define CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET		22
+#define CLKMGR_PERPLLGRP_VCO_SSRC_MASK			0x00c00000
+
+#define CLKMGR_VCO_SSRC_EOSC1				0x0
+#define CLKMGR_VCO_SSRC_EOSC2				0x1
+#define CLKMGR_VCO_SSRC_F2S				0x2
+
+#define CLKMGR_PERPLLGRP_EMAC0CLK_CNT_OFFSET		0
+#define CLKMGR_PERPLLGRP_EMAC0CLK_CNT_MASK		0x000001ff
+
+#define CLKMGR_PERPLLGRP_EMAC1CLK_CNT_OFFSET		0
+#define CLKMGR_PERPLLGRP_EMAC1CLK_CNT_MASK		0x000001ff
+
+#define CLKMGR_PERPLLGRP_PERQSPICLK_CNT_OFFSET		0
+#define CLKMGR_PERPLLGRP_PERQSPICLK_CNT_MASK		0x000001ff
+
+#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET	0
+#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_MASK	0x000001ff
+
+#define CLKMGR_PERPLLGRP_PERBASECLK_CNT_OFFSET		0
+#define CLKMGR_PERPLLGRP_PERBASECLK_CNT_MASK		0x000001ff
+
+#define CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_OFFSET		0
+#define CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_MASK		0x000001ff
+
+#define CLKMGR_PERPLLGRP_EN_NANDCLK_MASK		0x00000400
+#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK		0x00000100
+
+#define CLKMGR_PERPLLGRP_DIV_CAN0CLK_OFFSET		6
+#define CLKMGR_PERPLLGRP_DIV_CAN0CLK_MASK		0x000001c0
+#define CLKMGR_PERPLLGRP_DIV_CAN1CLK_OFFSET		9
+#define CLKMGR_PERPLLGRP_DIV_CAN1CLK_MASK		0x00000e00
+#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET		3
+#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET		3
+#define CLKMGR_PERPLLGRP_DIV_USBCLK_OFFSET		0
+#define CLKMGR_PERPLLGRP_DIV_USBCLK_MASK		0x00000007
+
+#define CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_OFFSET	0
+#define CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_MASK		0x00ffffff
+
+#define CLKMGR_PERPLLGRP_SRC_NAND_OFFSET		2
+#define CLKMGR_PERPLLGRP_SRC_NAND_MASK			0x0000000c
+#define CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET		4
+#define CLKMGR_PERPLLGRP_SRC_QSPI_MASK			0x00000030
+#define CLKMGR_PERPLLGRP_SRC_RESET_VALUE		0x00000015
+#define CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET		0
+#define CLKMGR_PERPLLGRP_SRC_SDMMC_MASK			0x00000003
+#define CLKMGR_SDMMC_CLK_SRC_F2S			0x0
+#define CLKMGR_SDMMC_CLK_SRC_MAIN			0x1
+#define CLKMGR_SDMMC_CLK_SRC_PER			0x2
+#define CLKMGR_QSPI_CLK_SRC_F2S				0x0
+#define CLKMGR_QSPI_CLK_SRC_MAIN			0x1
+#define CLKMGR_QSPI_CLK_SRC_PER				0x2
+
+/* SDR PLL */
+#define CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET		16
+#define CLKMGR_SDRPLLGRP_VCO_DENOM_MASK			0x003f0000
+#define CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET		3
+#define CLKMGR_SDRPLLGRP_VCO_NUMER_MASK			0x0000fff8
+#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL		(1 << 24)
+#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_OFFSET		24
+#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_OFFSET		25
+#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_MASK		0x7e000000
+#define CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK		0x80000000
+#define CLKMGR_SDRPLLGRP_VCO_RESET_VALUE		0x8001000d
+#define CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET		22
+#define CLKMGR_SDRPLLGRP_VCO_SSRC_MASK			0x00c00000
+
+#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET		0
+#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK		0x000001ff
+#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_OFFSET		9
+#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK		0x00000e00
+
+#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_OFFSET		0
+#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK		0x000001ff
+#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_OFFSET	9
+#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK		0x00000e00
+
+#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_OFFSET		0
+#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK		0x000001ff
+#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_OFFSET		9
+#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK		0x00000e00
+
+#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_OFFSET		0
+#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK		0x000001ff
+#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_OFFSET	9
+#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK		0x00000e00
 
 #endif /* _CLOCK_MANAGER_H_ */
diff --git a/arch/arm/include/asm/arch-socfpga/fpga_manager.h b/arch/arm/include/asm/arch-socfpga/fpga_manager.h
new file mode 100644
index 0000000..a077e22
--- /dev/null
+++ b/arch/arm/include/asm/arch-socfpga/fpga_manager.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ */
+
+#ifndef	_FPGA_MANAGER_H_
+#define	_FPGA_MANAGER_H_
+
+#include <altera.h>
+
+struct socfpga_fpga_manager {
+	/* FPGA Manager Module */
+	u32	stat;			/* 0x00 */
+	u32	ctrl;
+	u32	dclkcnt;
+	u32	dclkstat;
+	u32	gpo;			/* 0x10 */
+	u32	gpi;
+	u32	misci;			/* 0x18 */
+	u32	_pad_0x1c_0x82c[517];
+
+	/* Configuration Monitor (MON) Registers */
+	u32	gpio_inten;		/* 0x830 */
+	u32	gpio_intmask;
+	u32	gpio_inttype_level;
+	u32	gpio_int_polarity;
+	u32	gpio_intstatus;		/* 0x840 */
+	u32	gpio_raw_intstatus;
+	u32	_pad_0x848;
+	u32	gpio_porta_eoi;
+	u32	gpio_ext_porta;		/* 0x850 */
+	u32	_pad_0x854_0x85c[3];
+	u32	gpio_1s_sync;		/* 0x860 */
+	u32	_pad_0x864_0x868[2];
+	u32	gpio_ver_id_code;
+	u32	gpio_config_reg2;	/* 0x870 */
+	u32	gpio_config_reg1;
+};
+
+#define FPGAMGRREGS_STAT_MODE_MASK		0x7
+#define FPGAMGRREGS_STAT_MSEL_MASK		0xf8
+#define FPGAMGRREGS_STAT_MSEL_LSB		3
+
+#define FPGAMGRREGS_CTRL_CFGWDTH_MASK		0x200
+#define FPGAMGRREGS_CTRL_AXICFGEN_MASK		0x100
+#define FPGAMGRREGS_CTRL_NCONFIGPULL_MASK	0x4
+#define FPGAMGRREGS_CTRL_NCE_MASK		0x2
+#define FPGAMGRREGS_CTRL_EN_MASK		0x1
+#define FPGAMGRREGS_CTRL_CDRATIO_LSB		6
+
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CRC_MASK	0x8
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK	0x4
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK	0x2
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK	0x1
+
+/* FPGA Mode */
+#define FPGAMGRREGS_MODE_FPGAOFF		0x0
+#define FPGAMGRREGS_MODE_RESETPHASE		0x1
+#define FPGAMGRREGS_MODE_CFGPHASE		0x2
+#define FPGAMGRREGS_MODE_INITPHASE		0x3
+#define FPGAMGRREGS_MODE_USERMODE		0x4
+#define FPGAMGRREGS_MODE_UNKNOWN		0x5
+
+/* FPGA CD Ratio Value */
+#define CDRATIO_x1				0x0
+#define CDRATIO_x2				0x1
+#define CDRATIO_x4				0x2
+#define CDRATIO_x8				0x3
+
+/* SoCFPGA support functions */
+int fpgamgr_test_fpga_ready(void);
+int fpgamgr_poll_fpga_ready(void);
+int fpgamgr_get_mode(void);
+
+#endif /* _FPGA_MANAGER_H_ */
diff --git a/arch/arm/include/asm/arch-socfpga/nic301.h b/arch/arm/include/asm/arch-socfpga/nic301.h
new file mode 100644
index 0000000..3c8ab31
--- /dev/null
+++ b/arch/arm/include/asm/arch-socfpga/nic301.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2014 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef	_NIC301_REGISTERS_H_
+#define	_NIC301_REGISTERS_H_
+
+struct nic301_registers {
+	u32	remap;				/* 0x0 */
+	/* Security Register Group */
+	u32	_pad_0x4_0x8[1];
+	u32	l4main;
+	u32	l4sp;
+	u32	l4mp;				/* 0x10 */
+	u32	l4osc1;
+	u32	l4spim;
+	u32	stm;
+	u32	lwhps2fpgaregs;			/* 0x20 */
+	u32	_pad_0x24_0x28[1];
+	u32	usb1;
+	u32	nanddata;
+	u32	_pad_0x30_0x80[20];
+	u32	usb0;				/* 0x80 */
+	u32	nandregs;
+	u32	qspidata;
+	u32	fpgamgrdata;
+	u32	hps2fpgaregs;			/* 0x90 */
+	u32	acp;
+	u32	rom;
+	u32	ocram;
+	u32	sdrdata;			/* 0xA0 */
+	u32	_pad_0xa4_0x1fd0[1995];
+	/* ID Register Group */
+	u32	periph_id_4;			/* 0x1FD0 */
+	u32	_pad_0x1fd4_0x1fe0[3];
+	u32	periph_id_0;			/* 0x1FE0 */
+	u32	periph_id_1;
+	u32	periph_id_2;
+	u32	periph_id_3;
+	u32	comp_id_0;			/* 0x1FF0 */
+	u32	comp_id_1;
+	u32	comp_id_2;
+	u32	comp_id_3;
+	u32	_pad_0x2000_0x2008[2];
+	/* L4 MAIN */
+	u32	l4main_fn_mod_bm_iss;
+	u32	_pad_0x200c_0x3008[1023];
+	/* L4 SP */
+	u32	l4sp_fn_mod_bm_iss;
+	u32	_pad_0x300c_0x4008[1023];
+	/* L4 MP */
+	u32	l4mp_fn_mod_bm_iss;
+	u32	_pad_0x400c_0x5008[1023];
+	/* L4 OSC1 */
+	u32	l4osc_fn_mod_bm_iss;
+	u32	_pad_0x500c_0x6008[1023];
+	/* L4 SPIM */
+	u32	l4spim_fn_mod_bm_iss;
+	u32	_pad_0x600c_0x7008[1023];
+	/* STM */
+	u32	stm_fn_mod_bm_iss;
+	u32	_pad_0x700c_0x7108[63];
+	u32	stm_fn_mod;
+	u32	_pad_0x710c_0x8008[959];
+	/* LWHPS2FPGA */
+	u32	lwhps2fpga_fn_mod_bm_iss;
+	u32	_pad_0x800c_0x8108[63];
+	u32	lwhps2fpga_fn_mod;
+	u32	_pad_0x810c_0xa008[1983];
+	/* USB1 */
+	u32	usb1_fn_mod_bm_iss;
+	u32	_pad_0xa00c_0xa044[14];
+	u32	usb1_ahb_cntl;
+	u32	_pad_0xa048_0xb008[1008];
+	/* NANDDATA */
+	u32	nanddata_fn_mod_bm_iss;
+	u32	_pad_0xb00c_0xb108[63];
+	u32	nanddata_fn_mod;
+	u32	_pad_0xb10c_0x20008[21439];
+	/* USB0 */
+	u32	usb0_fn_mod_bm_iss;
+	u32	_pad_0x2000c_0x20044[14];
+	u32	usb0_ahb_cntl;
+	u32	_pad_0x20048_0x21008[1008];
+	/* NANDREGS */
+	u32	nandregs_fn_mod_bm_iss;
+	u32	_pad_0x2100c_0x21108[63];
+	u32	nandregs_fn_mod;
+	u32	_pad_0x2110c_0x22008[959];
+	/* QSPIDATA */
+	u32	qspidata_fn_mod_bm_iss;
+	u32	_pad_0x2200c_0x22044[14];
+	u32	qspidata_ahb_cntl;
+	u32	_pad_0x22048_0x23008[1008];
+	/* FPGAMGRDATA */
+	u32	fpgamgrdata_fn_mod_bm_iss;
+	u32	_pad_0x2300c_0x23040[13];
+	u32	fpgamgrdata_wr_tidemark;	/* 0x23040 */
+	u32	_pad_0x23044_0x23108[49];
+	u32	fn_mod;
+	u32	_pad_0x2310c_0x24008[959];
+	/* HPS2FPGA */
+	u32	hps2fpga_fn_mod_bm_iss;
+	u32	_pad_0x2400c_0x24040[13];
+	u32	hps2fpga_wr_tidemark;		/* 0x24040 */
+	u32	_pad_0x24044_0x24108[49];
+	u32	hps2fpga_fn_mod;
+	u32	_pad_0x2410c_0x25008[959];
+	/* ACP */
+	u32	acp_fn_mod_bm_iss;
+	u32	_pad_0x2500c_0x25108[63];
+	u32	acp_fn_mod;
+	u32	_pad_0x2510c_0x26008[959];
+	/* Boot ROM */
+	u32	bootrom_fn_mod_bm_iss;
+	u32	_pad_0x2600c_0x26108[63];
+	u32	bootrom_fn_mod;
+	u32	_pad_0x2610c_0x27008[959];
+	/* On-chip RAM */
+	u32	ocram_fn_mod_bm_iss;
+	u32	_pad_0x2700c_0x27040[13];
+	u32	ocram_wr_tidemark;		/* 0x27040 */
+	u32	_pad_0x27044_0x27108[49];
+	u32	ocram_fn_mod;
+	u32	_pad_0x2710c_0x42024[27590];
+	/* DAP */
+	u32	dap_fn_mod2;
+	u32	dap_fn_mod_ahb;
+	u32	_pad_0x4202c_0x42100[53];
+	u32	dap_read_qos;			/* 0x42100 */
+	u32	dap_write_qos;
+	u32	dap_fn_mod;
+	u32	_pad_0x4210c_0x43100[1021];
+	/* MPU */
+	u32	mpu_read_qos;			/* 0x43100 */
+	u32	mpu_write_qos;
+	u32	mpu_fn_mod;
+	u32	_pad_0x4310c_0x44028[967];
+	/* SDMMC */
+	u32	sdmmc_fn_mod_ahb;
+	u32	_pad_0x4402c_0x44100[53];
+	u32	sdmmc_read_qos;			/* 0x44100 */
+	u32	sdmmc_write_qos;
+	u32	sdmmc_fn_mod;
+	u32	_pad_0x4410c_0x45100[1021];
+	/* DMA */
+	u32	dma_read_qos;			/* 0x45100 */
+	u32	dma_write_qos;
+	u32	dma_fn_mod;
+	u32	_pad_0x4510c_0x46040[973];
+	/* FPGA2HPS */
+	u32	fpga2hps_wr_tidemark;		/* 0x46040 */
+	u32	_pad_0x46044_0x46100[47];
+	u32	fpga2hps_read_qos;		/* 0x46100 */
+	u32	fpga2hps_write_qos;
+	u32	fpga2hps_fn_mod;
+	u32	_pad_0x4610c_0x47100[1021];
+	/* ETR */
+	u32	etr_read_qos;			/* 0x47100 */
+	u32	etr_write_qos;
+	u32	etr_fn_mod;
+	u32	_pad_0x4710c_0x48100[1021];
+	/* EMAC0 */
+	u32	emac0_read_qos;			/* 0x48100 */
+	u32	emac0_write_qos;
+	u32	emac0_fn_mod;
+	u32	_pad_0x4810c_0x49100[1021];
+	/* EMAC1 */
+	u32	emac1_read_qos;			/* 0x49100 */
+	u32	emac1_write_qos;
+	u32	emac1_fn_mod;
+	u32	_pad_0x4910c_0x4a028[967];
+	/* USB0 */
+	u32	usb0_fn_mod_ahb;
+	u32	_pad_0x4a02c_0x4a100[53];
+	u32	usb0_read_qos;			/* 0x4A100 */
+	u32	usb0_write_qos;
+	u32	usb0_fn_mod;
+	u32	_pad_0x4a10c_0x4b100[1021];
+	/* NAND */
+	u32	nand_read_qos;			/* 0x4B100 */
+	u32	nand_write_qos;
+	u32	nand_fn_mod;
+	u32	_pad_0x4b10c_0x4c028[967];
+	/* USB1 */
+	u32	usb1_fn_mod_ahb;
+	u32	_pad_0x4c02c_0x4c100[53];
+	u32	usb1_read_qos;			/* 0x4C100 */
+	u32	usb1_write_qos;
+	u32	usb1_fn_mod;
+};
+
+#endif	/* _NIC301_REGISTERS_H_ */
diff --git a/arch/arm/include/asm/arch-socfpga/reset_manager.h b/arch/arm/include/asm/arch-socfpga/reset_manager.h
index 3e95476..1857b80 100644
--- a/arch/arm/include/asm/arch-socfpga/reset_manager.h
+++ b/arch/arm/include/asm/arch-socfpga/reset_manager.h
@@ -10,6 +10,11 @@
 void reset_cpu(ulong addr);
 void reset_deassert_peripherals_handoff(void);
 
+void socfpga_bridges_reset(int enable);
+
+void socfpga_emac_reset(int enable);
+void socfpga_watchdog_reset(void);
+
 struct socfpga_reset_manager {
 	u32	status;
 	u32	ctrl;
@@ -27,4 +32,8 @@
 #define RSTMGR_CTRL_SWWARMRSTREQ_LSB 1
 #endif
 
+#define RSTMGR_PERMODRST_EMAC0_LSB	0
+#define RSTMGR_PERMODRST_EMAC1_LSB	1
+#define RSTMGR_PERMODRST_L4WD0_LSB	6
+
 #endif /* _RESET_MANAGER_H_ */
diff --git a/arch/arm/include/asm/arch-socfpga/scu.h b/arch/arm/include/asm/arch-socfpga/scu.h
new file mode 100644
index 0000000..7a5b074
--- /dev/null
+++ b/arch/arm/include/asm/arch-socfpga/scu.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __SOCFPGA_SCU_H__
+#define __SOCFPGA_SCU_H__
+
+struct scu_registers {
+	u32	ctrl;			/* 0x00 */
+	u32	cfg;
+	u32	cpsr;
+	u32	iassr;
+	u32	_pad_0x10_0x3c[12];	/* 0x10 */
+	u32	fsar;			/* 0x40 */
+	u32	fear;
+	u32	_pad_0x48_0x50[2];
+	u32	acr;			/* 0x54 */
+	u32	sacr;
+};
+
+#endif	/* __SOCFPGA_SCU_H__ */
diff --git a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
index 2d3152d..6534283 100644
--- a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
+++ b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
@@ -7,16 +7,56 @@
 #ifndef _SOCFPGA_BASE_ADDRS_H_
 #define _SOCFPGA_BASE_ADDRS_H_
 
-#define SOCFPGA_L3REGS_ADDRESS 0xff800000
-#define SOCFPGA_UART0_ADDRESS 0xffc02000
-#define SOCFPGA_UART1_ADDRESS 0xffc03000
-#define SOCFPGA_OSC1TIMER0_ADDRESS 0xffd00000
-#define SOCFPGA_L4WD0_ADDRESS 0xffd02000
-#define SOCFPGA_CLKMGR_ADDRESS 0xffd04000
-#define SOCFPGA_RSTMGR_ADDRESS 0xffd05000
-#define SOCFPGA_SYSMGR_ADDRESS 0xffd08000
-#define SOCFPGA_SCANMGR_ADDRESS 0xfff02000
-#define SOCFPGA_EMAC0_ADDRESS 0xff700000
-#define SOCFPGA_EMAC1_ADDRESS 0xff702000
+#define SOCFPGA_STM_ADDRESS		0xfc000000
+#define SOCFPGA_DAP_ADDRESS		0xff000000
+#define SOCFPGA_EMAC0_ADDRESS		0xff700000
+#define SOCFPGA_EMAC1_ADDRESS		0xff702000
+#define SOCFPGA_SDMMC_ADDRESS		0xff704000
+#define SOCFPGA_QSPI_ADDRESS		0xff705000
+#define SOCFPGA_GPIO0_ADDRESS		0xff708000
+#define SOCFPGA_GPIO1_ADDRESS		0xff709000
+#define SOCFPGA_GPIO2_ADDRESS		0xff70a000
+#define SOCFPGA_L3REGS_ADDRESS		0xff800000
+#define SOCFPGA_USB0_ADDRESS		0xffb00000
+#define SOCFPGA_USB1_ADDRESS		0xffb40000
+#define SOCFPGA_CAN0_ADDRESS		0xffc00000
+#define SOCFPGA_CAN1_ADDRESS		0xffc01000
+#define SOCFPGA_UART0_ADDRESS		0xffc02000
+#define SOCFPGA_UART1_ADDRESS		0xffc03000
+#define SOCFPGA_I2C0_ADDRESS		0xffc04000
+#define SOCFPGA_I2C1_ADDRESS		0xffc05000
+#define SOCFPGA_I2C2_ADDRESS		0xffc06000
+#define SOCFPGA_I2C3_ADDRESS		0xffc07000
+#define SOCFPGA_SDR_ADDRESS		0xffc20000
+#define SOCFPGA_L4WD0_ADDRESS		0xffd02000
+#define SOCFPGA_L4WD1_ADDRESS		0xffd03000
+#define SOCFPGA_CLKMGR_ADDRESS		0xffd04000
+#define SOCFPGA_RSTMGR_ADDRESS		0xffd05000
+#define SOCFPGA_SYSMGR_ADDRESS		0xffd08000
+#define SOCFPGA_SPIS0_ADDRESS		0xffe02000
+#define SOCFPGA_SPIS1_ADDRESS		0xffe03000
+#define SOCFPGA_SPIM0_ADDRESS		0xfff00000
+#define SOCFPGA_SPIM1_ADDRESS		0xfff01000
+#define SOCFPGA_SCANMGR_ADDRESS		0xfff02000
+#define SOCFPGA_ROM_ADDRESS		0xfffd0000
+#define SOCFPGA_MPUSCU_ADDRESS		0xfffec000
+#define SOCFPGA_MPUL2_ADDRESS		0xfffef000
+#define SOCFPGA_OCRAM_ADDRESS		0xffff0000
+#define SOCFPGA_LWFPGASLAVES_ADDRESS	0xff200000
+#define SOCFPGA_LWHPS2FPGAREGS_ADDRESS	0xff400000
+#define SOCFPGA_HPS2FPGAREGS_ADDRESS	0xff500000
+#define SOCFPGA_FPGA2HPSREGS_ADDRESS	0xff600000
+#define SOCFPGA_FPGAMGRREGS_ADDRESS	0xff706000
+#define SOCFPGA_ACPIDMAP_ADDRESS	0xff707000
+#define SOCFPGA_NANDDATA_ADDRESS	0xff900000
+#define SOCFPGA_QSPIDATA_ADDRESS	0xffa00000
+#define SOCFPGA_NANDREGS_ADDRESS	0xffb80000
+#define SOCFPGA_FPGAMGRDATA_ADDRESS	0xffb90000
+#define SOCFPGA_SPTIMER0_ADDRESS	0xffc08000
+#define SOCFPGA_SPTIMER1_ADDRESS	0xffc09000
+#define SOCFPGA_OSC1TIMER0_ADDRESS	0xffd00000
+#define SOCFPGA_OSC1TIMER1_ADDRESS	0xffd01000
+#define SOCFPGA_DMANONSECURE_ADDRESS	0xffe00000
+#define SOCFPGA_DMASECURE_ADDRESS	0xffe01000
 
 #endif /* _SOCFPGA_BASE_ADDRS_H_ */
diff --git a/arch/arm/include/asm/arch-socfpga/system_manager.h b/arch/arm/include/asm/arch-socfpga/system_manager.h
index 838d210..071ec4f 100644
--- a/arch/arm/include/asm/arch-socfpga/system_manager.h
+++ b/arch/arm/include/asm/arch-socfpga/system_manager.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2013 Altera Corporation <www.altera.com>
+ * Copyright (C) 2013 Altera Corporation <www.altera.com>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -16,72 +16,131 @@
 
 #endif
 
-
-#define CONFIG_SYSMGR_PINMUXGRP_OFFSET	(0x400)
-
-#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel)	\
-	((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38))
-
 struct socfpga_system_manager {
-	u32	siliconid1;
+	/* System Manager Module */
+	u32	siliconid1;			/* 0x00 */
 	u32	siliconid2;
 	u32	_pad_0x8_0xf[2];
-	u32	wddbg;
+	u32	wddbg;				/* 0x10 */
 	u32	bootinfo;
 	u32	hpsinfo;
 	u32	parityinj;
-	u32	fpgaintfgrp_gbl;
+	/* FPGA Interface Group */
+	u32	fpgaintfgrp_gbl;		/* 0x20 */
 	u32	fpgaintfgrp_indiv;
 	u32	fpgaintfgrp_module;
 	u32	_pad_0x2c_0x2f;
-	u32	scanmgrgrp_ctrl;
+	/* Scan Manager Group */
+	u32	scanmgrgrp_ctrl;		/* 0x30 */
 	u32	_pad_0x34_0x3f[3];
-	u32	frzctrl_vioctrl;
+	/* Freeze Control Group */
+	u32	frzctrl_vioctrl;		/* 0x40 */
 	u32	_pad_0x44_0x4f[3];
-	u32	frzctrl_hioctrl;
+	u32	frzctrl_hioctrl;		/* 0x50 */
 	u32	frzctrl_src;
 	u32	frzctrl_hwctrl;
 	u32	_pad_0x5c_0x5f;
-	u32	emacgrp_ctrl;
+	/* EMAC Group */
+	u32	emacgrp_ctrl;			/* 0x60 */
 	u32	emacgrp_l3master;
 	u32	_pad_0x68_0x6f[2];
-	u32	dmagrp_ctrl;
+	/* DMA Controller Group */
+	u32	dmagrp_ctrl;			/* 0x70 */
 	u32	dmagrp_persecurity;
 	u32	_pad_0x78_0x7f[2];
-	u32	iswgrp_handoff[8];
-	u32	_pad_0xa0_0xbf[8];
-	u32	romcodegrp_ctrl;
+	/* Preloader (initial software) Group */
+	u32	iswgrp_handoff[8];		/* 0x80 */
+	u32	_pad_0xa0_0xbf[8];		/* 0xa0 */
+	/* Boot ROM Code Register Group */
+	u32	romcodegrp_ctrl;		/* 0xc0 */
 	u32	romcodegrp_cpu1startaddr;
 	u32	romcodegrp_initswstate;
 	u32	romcodegrp_initswlastld;
-	u32	romcodegrp_bootromswstate;
+	u32	romcodegrp_bootromswstate;	/* 0xd0 */
 	u32	__pad_0xd4_0xdf[3];
-	u32	romcodegrp_warmramgrp_enable;
+	/* Warm Boot from On-Chip RAM Group */
+	u32	romcodegrp_warmramgrp_enable;	/* 0xe0 */
 	u32	romcodegrp_warmramgrp_datastart;
 	u32	romcodegrp_warmramgrp_length;
 	u32	romcodegrp_warmramgrp_execution;
-	u32	romcodegrp_warmramgrp_crc;
+	u32	romcodegrp_warmramgrp_crc;	/* 0xf0 */
 	u32	__pad_0xf4_0xff[3];
-	u32	romhwgrp_ctrl;
+	/* Boot ROM Hardware Register Group */
+	u32	romhwgrp_ctrl;			/* 0x100 */
 	u32	_pad_0x104_0x107;
+	/* SDMMC Controller Group */
 	u32	sdmmcgrp_ctrl;
 	u32	sdmmcgrp_l3master;
-	u32	nandgrp_bootstrap;
+	/* NAND Flash Controller Register Group */
+	u32	nandgrp_bootstrap;		/* 0x110 */
 	u32	nandgrp_l3master;
+	/* USB Controller Group */
 	u32	usbgrp_l3master;
 	u32	_pad_0x11c_0x13f[9];
-	u32	eccgrp_l2;
+	/* ECC Management Register Group */
+	u32	eccgrp_l2;			/* 0x140 */
 	u32	eccgrp_ocram;
 	u32	eccgrp_usb0;
 	u32	eccgrp_usb1;
-	u32	eccgrp_emac0;
+	u32	eccgrp_emac0;			/* 0x150 */
 	u32	eccgrp_emac1;
 	u32	eccgrp_dma;
 	u32	eccgrp_can0;
-	u32	eccgrp_can1;
+	u32	eccgrp_can1;			/* 0x160 */
 	u32	eccgrp_nand;
 	u32	eccgrp_qspi;
 	u32	eccgrp_sdmmc;
+	u32	_pad_0x170_0x3ff[164];
+	/* Pin Mux Control Group */
+	u32	emacio[20];			/* 0x400 */
+	u32	flashio[12];			/* 0x450 */
+	u32	generalio[28];			/* 0x480 */
+	u32	_pad_0x4f0_0x4ff[4];
+	u32	mixed1io[22];			/* 0x500 */
+	u32	mixed2io[8];			/* 0x558 */
+	u32	gplinmux[23];			/* 0x578 */
+	u32	gplmux[71];			/* 0x5d4 */
+	u32	nandusefpga;			/* 0x6f0 */
+	u32	_pad_0x6f4;
+	u32	rgmii1usefpga;			/* 0x6f8 */
+	u32	_pad_0x6fc_0x700[2];
+	u32	i2c0usefpga;			/* 0x704 */
+	u32	sdmmcusefpga;			/* 0x708 */
+	u32	_pad_0x70c_0x710[2];
+	u32	rgmii0usefpga;			/* 0x714 */
+	u32	_pad_0x718_0x720[3];
+	u32	i2c3usefpga;			/* 0x724 */
+	u32	i2c2usefpga;			/* 0x728 */
+	u32	i2c1usefpga;			/* 0x72c */
+	u32	spim1usefpga;			/* 0x730 */
+	u32	_pad_0x734;
+	u32	spim0usefpga;			/* 0x738 */
 };
 
+#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGPINMUX	(1 << 0)
+#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO	(1 << 1)
+#define SYSMGR_ECC_OCRAM_EN	(1 << 0)
+#define SYSMGR_ECC_OCRAM_SERR	(1 << 3)
+#define SYSMGR_ECC_OCRAM_DERR	(1 << 4)
+#define SYSMGR_FPGAINTF_USEFPGA	0x1
+#define SYSMGR_FPGAINTF_SPIM0	(1 << 0)
+#define SYSMGR_FPGAINTF_SPIM1	(1 << 1)
+#define SYSMGR_FPGAINTF_EMAC0	(1 << 2)
+#define SYSMGR_FPGAINTF_EMAC1	(1 << 3)
+#define SYSMGR_FPGAINTF_NAND	(1 << 4)
+#define SYSMGR_FPGAINTF_SDMMC	(1 << 5)
+
+/* FIXME: This is questionable macro. */
+#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel)	\
+	((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38))
+
+/* EMAC Group Bit definitions */
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII	0x0
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII		0x1
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII		0x2
+
+#define SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB			0
+#define SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB			2
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK			0x3
+
 #endif /* _SYSTEM_MANAGER_H_ */
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index d51ba66..ca2d44f 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -185,6 +185,7 @@
 	DCACHE_OFF = 0x12,
 	DCACHE_WRITETHROUGH = 0x1a,
 	DCACHE_WRITEBACK = 0x1e,
+	DCACHE_WRITEALLOC = 0x16,
 };
 
 /* Size of an MMU section */
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index 3e62d58..2155fe8 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -73,6 +73,8 @@
 	     i++) {
 #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
 		set_section_dcache(i, DCACHE_WRITETHROUGH);
+#elif defined(CONFIG_SYS_ARM_CACHE_WRITEALLOC)
+		set_section_dcache(i, DCACHE_WRITEALLOC);
 #else
 		set_section_dcache(i, DCACHE_WRITEBACK);
 #endif
diff --git a/board/altera/socfpga/pll_config.h b/board/altera/socfpga/pll_config.h
index 9bd0442..f0f59a9 100644
--- a/board/altera/socfpga/pll_config.h
+++ b/board/altera/socfpga/pll_config.h
@@ -94,6 +94,9 @@
 
 /* Info for driver */
 #define CONFIG_HPS_CLK_OSC1_HZ			(25000000)
+#define CONFIG_HPS_CLK_OSC2_HZ			0
+#define CONFIG_HPS_CLK_F2S_SDR_REF_HZ		0
+#define CONFIG_HPS_CLK_F2S_PER_REF_HZ		0
 #define CONFIG_HPS_CLK_MAINVCO_HZ		(1600000000)
 #define CONFIG_HPS_CLK_PERVCO_HZ		(1000000000)
 #ifdef CONFIG_SOCFPGA_ARRIA5
diff --git a/board/altera/socfpga/socfpga_cyclone5.c b/board/altera/socfpga/socfpga_cyclone5.c
index fb92852..0f81d89 100644
--- a/board/altera/socfpga/socfpga_cyclone5.c
+++ b/board/altera/socfpga/socfpga_cyclone5.c
@@ -17,7 +17,7 @@
  */
 int checkboard(void)
 {
-	puts("BOARD : Altera SOCFPGA Cyclone5 Board\n");
+	puts("BOARD: Altera SoCFPGA Cyclone5 Board\n");
 	return 0;
 }
 
@@ -34,6 +34,8 @@
  */
 int board_init(void)
 {
-	icache_enable();
+	/* Address of boot parameters for ATAG (if ATAG is used) */
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
 	return 0;
 }
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 1e40983..4286e26 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -602,7 +602,7 @@
 	U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
 #ifdef CONFIG_SUPPORT_EMMC_BOOT
 	U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
-	U_BOOT_CMD_MKENT(bootpart-resize, 3, 0, do_mmc_boot_resize, "", ""),
+	U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
 	U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""),
 	U_BOOT_CMD_MKENT(rst-function, 3, 0, do_mmc_rst_func, "", ""),
 #endif
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 2519497..c192498 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -430,6 +430,16 @@
 }
 #endif /* CONFIG_USB_STORAGE */
 
+static int do_usb_stop_keyboard(int force)
+{
+#ifdef CONFIG_USB_KEYBOARD
+	if (usb_kbd_deregister(force) != 0) {
+		printf("USB not stopped: usbkbd still using USB\n");
+		return 1;
+	}
+#endif
+	return 0;
+}
 
 /******************************************************************************
  * usb command intepreter
@@ -450,6 +460,8 @@
 	if ((strncmp(argv[1], "reset", 5) == 0) ||
 		 (strncmp(argv[1], "start", 5) == 0)) {
 		bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
+		if (do_usb_stop_keyboard(1) != 0)
+			return 1;
 		usb_stop();
 		printf("(Re)start USB...\n");
 		if (usb_init() >= 0) {
@@ -468,19 +480,10 @@
 		return 0;
 	}
 	if (strncmp(argv[1], "stop", 4) == 0) {
-#ifdef CONFIG_USB_KEYBOARD
-		if (argc == 2) {
-			if (usb_kbd_deregister() != 0) {
-				printf("USB not stopped: usbkbd still"
-					" using USB\n");
-				return 1;
-			}
-		} else {
-			/* forced stop, switch console in to serial */
+		if (argc != 2)
 			console_assign(stdin, "serial");
-			usb_kbd_deregister();
-		}
-#endif
+		if (do_usb_stop_keyboard(0) != 0)
+			return 1;
 		printf("stopping USB..\n");
 		usb_stop();
 		return 0;
diff --git a/common/env_mmc.c b/common/env_mmc.c
index a7621a8..14648e3 100644
--- a/common/env_mmc.c
+++ b/common/env_mmc.c
@@ -113,7 +113,7 @@
 #ifdef CONFIG_SPL_BUILD
 	dev = 0;
 #endif
-	if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num)
+	if (mmc_get_env_part(mmc) != mmc->part_num)
 		mmc_switch_part(dev, mmc->part_num);
 #endif
 }
diff --git a/common/image.c b/common/image.c
index 38b56e3..085771c 100644
--- a/common/image.c
+++ b/common/image.c
@@ -138,6 +138,7 @@
 	{	IH_TYPE_PBLIMAGE,   "pblimage",   "Freescale PBL Boot Image",},
 	{	IH_TYPE_RAMDISK,    "ramdisk",	  "RAMDisk Image",	},
 	{	IH_TYPE_SCRIPT,     "script",	  "Script",		},
+	{	IH_TYPE_SOCFPGAIMAGE, "socfpgaimage", "Altera SOCFPGA preloader",},
 	{	IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
 	{	IH_TYPE_UBLIMAGE,   "ublimage",   "Davinci UBL image",},
 	{	IH_TYPE_MXSIMAGE,   "mxsimage",   "Freescale MXS Boot Image",},
diff --git a/common/stdio.c b/common/stdio.c
index c878103..8232815 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -34,6 +34,9 @@
 #define	CONFIG_SYS_DEVICE_NULLDEV	1
 #endif
 
+#ifdef	CONFIG_SYS_STDIO_DEREGISTER
+#define	CONFIG_SYS_DEVICE_NULLDEV	1
+#endif
 
 #ifdef CONFIG_SYS_DEVICE_NULLDEV
 void nulldev_putc(struct stdio_dev *dev, const char c)
@@ -172,7 +175,7 @@
  * returns 0 if success, -1 if device is assigned and 1 if devname not found
  */
 #ifdef	CONFIG_SYS_STDIO_DEREGISTER
-int stdio_deregister_dev(struct stdio_dev *dev)
+int stdio_deregister_dev(struct stdio_dev *dev, int force)
 {
 	int l;
 	struct list_head *pos;
@@ -181,6 +184,10 @@
 	/* get stdio devices (ListRemoveItem changes the dev list) */
 	for (l=0 ; l< MAX_FILES; l++) {
 		if (stdio_devices[l] == dev) {
+			if (force) {
+				strcpy(temp_names[l], "nulldev");
+				continue;
+			}
 			/* Device is assigned -> report error */
 			return -1;
 		}
@@ -202,7 +209,7 @@
 	return 0;
 }
 
-int stdio_deregister(const char *devname)
+int stdio_deregister(const char *devname, int force)
 {
 	struct stdio_dev *dev;
 
@@ -211,7 +218,7 @@
 	if (!dev) /* device not found */
 		return -ENODEV;
 
-	return stdio_deregister_dev(dev);
+	return stdio_deregister_dev(dev, force);
 }
 #endif	/* CONFIG_SYS_STDIO_DEREGISTER */
 
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index c34fd5c..fdc083c 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -8,6 +8,7 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #include <common.h>
+#include <errno.h>
 #include <malloc.h>
 #include <stdio_dev.h>
 #include <asm/byteorder.h>
@@ -170,11 +171,12 @@
 {
 	struct usb_interface *iface = &dev->config.if_desc[0];
 	struct usb_kbd_pdata *data = dev->privptr;
-	uint32_t leds = data->flags & USB_KBD_LEDMASK;
+	ALLOC_ALIGN_BUFFER(uint32_t, leds, 1, USB_DMA_MINALIGN);
 
+	*leds = data->flags & USB_KBD_LEDMASK;
 	usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		0x200, iface->desc.bInterfaceNumber, (void *)&leds, 1, 0);
+		0x200, iface->desc.bInterfaceNumber, leds, 1, 0);
 }
 
 #define CAPITAL_MASK	0x20
@@ -488,7 +490,7 @@
 /* Search for keyboard and register it if found. */
 int drv_usb_kbd_init(void)
 {
-	struct stdio_dev usb_kbd_dev, *old_dev;
+	struct stdio_dev usb_kbd_dev;
 	struct usb_device *dev;
 	char *stdinname = getenv("stdin");
 	int error, i;
@@ -507,16 +509,6 @@
 		if (usb_kbd_probe(dev, 0) != 1)
 			continue;
 
-		/* We found a keyboard, check if it is already registered. */
-		debug("USB KBD: found set up device.\n");
-		old_dev = stdio_get_by_name(DEVNAME);
-		if (old_dev) {
-			/* Already registered, just return ok. */
-			debug("USB KBD: is already registered.\n");
-			usb_kbd_deregister();
-			return 1;
-		}
-
 		/* Register the keyboard */
 		debug("USB KBD: register.\n");
 		memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
@@ -555,10 +547,14 @@
 }
 
 /* Deregister the keyboard. */
-int usb_kbd_deregister(void)
+int usb_kbd_deregister(int force)
 {
 #ifdef CONFIG_SYS_STDIO_DEREGISTER
-	return stdio_deregister(DEVNAME);
+	int ret = stdio_deregister(DEVNAME, force);
+	if (ret && ret != -ENODEV)
+		return ret;
+
+	return 0;
 #else
 	return 1;
 #endif
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index dfb2e7f..6aa24d4 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -17,4 +17,5 @@
 obj-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o
 obj-$(CONFIG_FPGA_CYCLON2) += cyclon2.o
 obj-$(CONFIG_FPGA_STRATIX_II) += stratixII.o
+obj-$(CONFIG_FPGA_SOCFPGA) += socfpga.o
 endif
diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c
index 6e34a8e..a5bfe5d 100644
--- a/drivers/fpga/altera.c
+++ b/drivers/fpga/altera.c
@@ -12,216 +12,162 @@
  *  Altera FPGA support
  */
 #include <common.h>
+#include <errno.h>
 #include <ACEX1K.h>
 #include <stratixII.h>
 
-/* Define FPGA_DEBUG to get debug printf's */
-/* #define FPGA_DEBUG */
+/* Define FPGA_DEBUG to 1 to get debug printf's */
+#define FPGA_DEBUG	0
 
-#ifdef	FPGA_DEBUG
-#define	PRINTF(fmt,args...)	printf (fmt ,##args)
-#else
-#define PRINTF(fmt,args...)
-#endif
-
-/* Local Static Functions */
-static int altera_validate (Altera_desc * desc, const char *fn);
-
-/* ------------------------------------------------------------------------- */
-int altera_load(Altera_desc *desc, const void *buf, size_t bsize)
-{
-	int ret_val = FPGA_FAIL;	/* assume a failure */
-
-	if (!altera_validate (desc, (char *)__FUNCTION__)) {
-		printf ("%s: Invalid device descriptor\n", __FUNCTION__);
-	} else {
-		switch (desc->family) {
-		case Altera_ACEX1K:
-		case Altera_CYC2:
+static const struct altera_fpga {
+	enum altera_family	family;
+	const char		*name;
+	int			(*load)(Altera_desc *, const void *, size_t);
+	int			(*dump)(Altera_desc *, const void *, size_t);
+	int			(*info)(Altera_desc *);
+} altera_fpga[] = {
 #if defined(CONFIG_FPGA_ACEX1K)
-			PRINTF ("%s: Launching the ACEX1K Loader...\n",
-					__FUNCTION__);
-			ret_val = ACEX1K_load (desc, buf, bsize);
+	{ Altera_ACEX1K, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info },
+	{ Altera_CYC2,   "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info },
 #elif defined(CONFIG_FPGA_CYCLON2)
-			PRINTF ("%s: Launching the CYCLONE II Loader...\n",
-					__FUNCTION__);
-			ret_val = CYC2_load (desc, buf, bsize);
-#else
-			printf ("%s: No support for ACEX1K devices.\n",
-					__FUNCTION__);
+	{ Altera_ACEX1K, "CycloneII", CYC2_load, CYC2_dump, CYC2_info },
+	{ Altera_CYC2,   "CycloneII", CYC2_load, CYC2_dump, CYC2_info },
 #endif
-			break;
-
 #if defined(CONFIG_FPGA_STRATIX_II)
-		case Altera_StratixII:
-			PRINTF ("%s: Launching the Stratix II Loader...\n",
-				__FUNCTION__);
-			ret_val = StratixII_load (desc, buf, bsize);
-			break;
+	{ Altera_StratixII, "StratixII", StratixII_load,
+	  StratixII_dump, StratixII_info },
 #endif
-		default:
-			printf ("%s: Unsupported family type, %d\n",
-					__FUNCTION__, desc->family);
-		}
+#if defined(CONFIG_FPGA_SOCFPGA)
+	{ Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL },
+#endif
+};
+
+static int altera_validate(Altera_desc *desc, const char *fn)
+{
+	if (!desc) {
+		printf("%s: NULL descriptor!\n", fn);
+		return -EINVAL;
 	}
 
-	return ret_val;
+	if ((desc->family < min_altera_type) ||
+	    (desc->family > max_altera_type)) {
+		printf("%s: Invalid family type, %d\n", fn, desc->family);
+		return -EINVAL;
+	}
+
+	if ((desc->iface < min_altera_iface_type) ||
+	    (desc->iface > max_altera_iface_type)) {
+		printf("%s: Invalid Interface type, %d\n", fn, desc->iface);
+		return -EINVAL;
+	}
+
+	if (!desc->size) {
+		printf("%s: NULL part size\n", fn);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct altera_fpga *
+altera_desc_to_fpga(Altera_desc *desc, const char *fn)
+{
+	int i;
+
+	if (altera_validate(desc, fn)) {
+		printf("%s: Invalid device descriptor\n", fn);
+		return NULL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) {
+		if (desc->family == altera_fpga[i].family)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(altera_fpga)) {
+		printf("%s: Unsupported family type, %d\n", fn, desc->family);
+		return NULL;
+	}
+
+	return &altera_fpga[i];
+}
+
+int altera_load(Altera_desc *desc, const void *buf, size_t bsize)
+{
+	const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
+
+	if (!fpga)
+		return FPGA_FAIL;
+
+	debug_cond(FPGA_DEBUG, "%s: Launching the %s Loader...\n",
+		   __func__, fpga->name);
+	if (fpga->load)
+		return fpga->load(desc, buf, bsize);
+	return 0;
 }
 
 int altera_dump(Altera_desc *desc, const void *buf, size_t bsize)
 {
-	int ret_val = FPGA_FAIL;	/* assume a failure */
+	const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
 
-	if (!altera_validate (desc, (char *)__FUNCTION__)) {
-		printf ("%s: Invalid device descriptor\n", __FUNCTION__);
-	} else {
-		switch (desc->family) {
-		case Altera_ACEX1K:
-#if defined(CONFIG_FPGA_ACEX)
-			PRINTF ("%s: Launching the ACEX1K Reader...\n",
-					__FUNCTION__);
-			ret_val = ACEX1K_dump (desc, buf, bsize);
-#else
-			printf ("%s: No support for ACEX1K devices.\n",
-					__FUNCTION__);
-#endif
-			break;
+	if (!fpga)
+		return FPGA_FAIL;
 
-#if defined(CONFIG_FPGA_STRATIX_II)
-		case Altera_StratixII:
-			PRINTF ("%s: Launching the Stratix II Reader...\n",
-				__FUNCTION__);
-			ret_val = StratixII_dump (desc, buf, bsize);
-			break;
-#endif
-		default:
-			printf ("%s: Unsupported family type, %d\n",
-					__FUNCTION__, desc->family);
-		}
-	}
-
-	return ret_val;
+	debug_cond(FPGA_DEBUG, "%s: Launching the %s Reader...\n",
+		   __func__, fpga->name);
+	if (fpga->dump)
+		return fpga->dump(desc, buf, bsize);
+	return 0;
 }
 
-int altera_info( Altera_desc *desc )
+int altera_info(Altera_desc *desc)
 {
-	int ret_val = FPGA_FAIL;
+	const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
 
-	if (altera_validate (desc, (char *)__FUNCTION__)) {
-		printf ("Family:        \t");
-		switch (desc->family) {
-		case Altera_ACEX1K:
-			printf ("ACEX1K\n");
-			break;
-		case Altera_CYC2:
-			printf ("CYCLON II\n");
-			break;
-		case Altera_StratixII:
-			printf ("Stratix II\n");
-			break;
-			/* Add new family types here */
-		default:
-			printf ("Unknown family type, %d\n", desc->family);
-		}
+	if (!fpga)
+		return FPGA_FAIL;
 
-		printf ("Interface type:\t");
-		switch (desc->iface) {
-		case passive_serial:
-			printf ("Passive Serial (PS)\n");
-			break;
-		case passive_parallel_synchronous:
-			printf ("Passive Parallel Synchronous (PPS)\n");
-			break;
-		case passive_parallel_asynchronous:
-			printf ("Passive Parallel Asynchronous (PPA)\n");
-			break;
-		case passive_serial_asynchronous:
-			printf ("Passive Serial Asynchronous (PSA)\n");
-			break;
-		case altera_jtag_mode:		/* Not used */
-			printf ("JTAG Mode\n");
-			break;
-		case fast_passive_parallel:
-			printf ("Fast Passive Parallel (FPP)\n");
-			break;
-		case fast_passive_parallel_security:
-			printf
-			    ("Fast Passive Parallel with Security (FPPS) \n");
-			break;
-			/* Add new interface types here */
-		default:
-			printf ("Unsupported interface type, %d\n", desc->iface);
-		}
+	printf("Family:        \t%s\n", fpga->name);
 
-		printf("Device Size:   \t%zd bytes\n"
-		      "Cookie:        \t0x%x (%d)\n",
-		      desc->size, desc->cookie, desc->cookie);
-
-		if (desc->iface_fns) {
-			printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
-			switch (desc->family) {
-			case Altera_ACEX1K:
-			case Altera_CYC2:
-#if defined(CONFIG_FPGA_ACEX1K)
-				ACEX1K_info (desc);
-#elif defined(CONFIG_FPGA_CYCLON2)
-				CYC2_info (desc);
-#else
-				/* just in case */
-				printf ("%s: No support for ACEX1K devices.\n",
-						__FUNCTION__);
-#endif
-				break;
-#if defined(CONFIG_FPGA_STRATIX_II)
-			case Altera_StratixII:
-				StratixII_info (desc);
-				break;
-#endif
-				/* Add new family types here */
-			default:
-				/* we don't need a message here - we give one up above */
-				break;
-			}
-		} else {
-			printf ("No Device Function Table.\n");
-		}
-
-		ret_val = FPGA_SUCCESS;
-	} else {
-		printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+	printf("Interface type:\t");
+	switch (desc->iface) {
+	case passive_serial:
+		printf("Passive Serial (PS)\n");
+		break;
+	case passive_parallel_synchronous:
+		printf("Passive Parallel Synchronous (PPS)\n");
+		break;
+	case passive_parallel_asynchronous:
+		printf("Passive Parallel Asynchronous (PPA)\n");
+		break;
+	case passive_serial_asynchronous:
+		printf("Passive Serial Asynchronous (PSA)\n");
+		break;
+	case altera_jtag_mode:		/* Not used */
+		printf("JTAG Mode\n");
+		break;
+	case fast_passive_parallel:
+		printf("Fast Passive Parallel (FPP)\n");
+		break;
+	case fast_passive_parallel_security:
+		printf("Fast Passive Parallel with Security (FPPS)\n");
+		break;
+		/* Add new interface types here */
+	default:
+		printf("Unsupported interface type, %d\n", desc->iface);
 	}
 
-	return ret_val;
-}
+	printf("Device Size:   \t%zd bytes\n"
+	       "Cookie:        \t0x%x (%d)\n",
+	       desc->size, desc->cookie, desc->cookie);
 
-/* ------------------------------------------------------------------------- */
-
-static int altera_validate (Altera_desc * desc, const char *fn)
-{
-	int ret_val = false;
-
-	if (desc) {
-		if ((desc->family > min_altera_type) &&
-			(desc->family < max_altera_type)) {
-			if ((desc->iface > min_altera_iface_type) &&
-				(desc->iface < max_altera_iface_type)) {
-				if (desc->size) {
-					ret_val = true;
-				} else {
-					printf ("%s: NULL part size\n", fn);
-				}
-			} else {
-				printf ("%s: Invalid Interface type, %d\n",
-					fn, desc->iface);
-			}
-		} else {
-			printf ("%s: Invalid family type, %d\n", fn, desc->family);
-		}
+	if (desc->iface_fns) {
+		printf("Device Function Table @ 0x%p\n", desc->iface_fns);
+		if (fpga->info)
+			fpga->info(desc);
 	} else {
-		printf ("%s: NULL descriptor!\n", fn);
+		printf("No Device Function Table.\n");
 	}
 
-	return ret_val;
+	return FPGA_SUCCESS;
 }
-
-/* ------------------------------------------------------------------------- */
diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
new file mode 100644
index 0000000..63b3566
--- /dev/null
+++ b/drivers/fpga/socfpga.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/fpga_manager.h>
+#include <asm/arch/reset_manager.h>
+#include <asm/arch/system_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Timeout count */
+#define FPGA_TIMEOUT_CNT		0x1000000
+
+static struct socfpga_fpga_manager *fpgamgr_regs =
+	(struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS;
+static struct socfpga_system_manager *sysmgr_regs =
+	(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
+
+/* Set CD ratio */
+static void fpgamgr_set_cd_ratio(unsigned long ratio)
+{
+	clrsetbits_le32(&fpgamgr_regs->ctrl,
+			0x3 << FPGAMGRREGS_CTRL_CDRATIO_LSB,
+			(ratio & 0x3) << FPGAMGRREGS_CTRL_CDRATIO_LSB);
+}
+
+static int fpgamgr_dclkcnt_set(unsigned long cnt)
+{
+	unsigned long i;
+
+	/* Clear any existing done status */
+	if (readl(&fpgamgr_regs->dclkstat))
+		writel(0x1, &fpgamgr_regs->dclkstat);
+
+	/* Write the dclkcnt */
+	writel(cnt, &fpgamgr_regs->dclkcnt);
+
+	/* Wait till the dclkcnt done */
+	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+		if (!readl(&fpgamgr_regs->dclkstat))
+			continue;
+
+		writel(0x1, &fpgamgr_regs->dclkstat);
+		return 0;
+	}
+
+	return -ETIMEDOUT;
+}
+
+/* Start the FPGA programming by initialize the FPGA Manager */
+static int fpgamgr_program_init(void)
+{
+	unsigned long msel, i;
+
+	/* Get the MSEL value */
+	msel = readl(&fpgamgr_regs->stat);
+	msel &= FPGAMGRREGS_STAT_MSEL_MASK;
+	msel >>= FPGAMGRREGS_STAT_MSEL_LSB;
+
+	/*
+	 * Set the cfg width
+	 * If MSEL[3] = 1, cfg width = 32 bit
+	 */
+	if (msel & 0x8) {
+		setbits_le32(&fpgamgr_regs->ctrl,
+			     FPGAMGRREGS_CTRL_CFGWDTH_MASK);
+
+		/* To determine the CD ratio */
+		/* MSEL[1:0] = 0, CD Ratio = 1 */
+		if ((msel & 0x3) == 0x0)
+			fpgamgr_set_cd_ratio(CDRATIO_x1);
+		/* MSEL[1:0] = 1, CD Ratio = 4 */
+		else if ((msel & 0x3) == 0x1)
+			fpgamgr_set_cd_ratio(CDRATIO_x4);
+		/* MSEL[1:0] = 2, CD Ratio = 8 */
+		else if ((msel & 0x3) == 0x2)
+			fpgamgr_set_cd_ratio(CDRATIO_x8);
+
+	} else {	/* MSEL[3] = 0 */
+		clrbits_le32(&fpgamgr_regs->ctrl,
+			     FPGAMGRREGS_CTRL_CFGWDTH_MASK);
+
+		/* To determine the CD ratio */
+		/* MSEL[1:0] = 0, CD Ratio = 1 */
+		if ((msel & 0x3) == 0x0)
+			fpgamgr_set_cd_ratio(CDRATIO_x1);
+		/* MSEL[1:0] = 1, CD Ratio = 2 */
+		else if ((msel & 0x3) == 0x1)
+			fpgamgr_set_cd_ratio(CDRATIO_x2);
+		/* MSEL[1:0] = 2, CD Ratio = 4 */
+		else if ((msel & 0x3) == 0x2)
+			fpgamgr_set_cd_ratio(CDRATIO_x4);
+	}
+
+	/* To enable FPGA Manager configuration */
+	clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCE_MASK);
+
+	/* To enable FPGA Manager drive over configuration line */
+	setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK);
+
+	/* Put FPGA into reset phase */
+	setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK);
+
+	/* (1) wait until FPGA enter reset phase */
+	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+		if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_RESETPHASE)
+			break;
+	}
+
+	/* If not in reset state, return error */
+	if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_RESETPHASE) {
+		puts("FPGA: Could not reset\n");
+		return -1;
+	}
+
+	/* Release FPGA from reset phase */
+	clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_NCONFIGPULL_MASK);
+
+	/* (2) wait until FPGA enter configuration phase */
+	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+		if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_CFGPHASE)
+			break;
+	}
+
+	/* If not in configuration state, return error */
+	if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_CFGPHASE) {
+		puts("FPGA: Could not configure\n");
+		return -2;
+	}
+
+	/* Clear all interrupts in CB Monitor */
+	writel(0xFFF, &fpgamgr_regs->gpio_porta_eoi);
+
+	/* Enable AXI configuration */
+	setbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK);
+
+	return 0;
+}
+
+/* Write the RBF data to FPGA Manager */
+static void fpgamgr_program_write(const void *rbf_data, unsigned long rbf_size)
+{
+	uint32_t src = (uint32_t)rbf_data;
+	uint32_t dst = SOCFPGA_FPGAMGRDATA_ADDRESS;
+
+	/* Number of loops for 32-byte long copying. */
+	uint32_t loops32 = rbf_size / 32;
+	/* Number of loops for 4-byte long copying + trailing bytes */
+	uint32_t loops4 = DIV_ROUND_UP(rbf_size % 32, 4);
+
+	asm volatile(
+		"1:	ldmia	%0!,	{r0-r7}\n"
+		"	stmia	%1!,	{r0-r7}\n"
+		"	sub	%1,	#32\n"
+		"	subs	%2,	#1\n"
+		"	bne	1b\n"
+		"2:	ldr	%2,	[%0],	#4\n"
+		"	str	%2,	[%1]\n"
+		"	subs	%3,	#1\n"
+		"	bne	2b\n"
+		: "+r"(src), "+r"(dst), "+r"(loops32), "+r"(loops4) :
+		: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "cc");
+}
+
+/* Ensure the FPGA entering config done */
+static int fpgamgr_program_poll_cd(void)
+{
+	const uint32_t mask = FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK |
+			      FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK;
+	unsigned long reg, i;
+
+	/* (3) wait until full config done */
+	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+		reg = readl(&fpgamgr_regs->gpio_ext_porta);
+
+		/* Config error */
+		if (!(reg & mask)) {
+			printf("FPGA: Configuration error.\n");
+			return -3;
+		}
+
+		/* Config done without error */
+		if (reg & mask)
+			break;
+	}
+
+	/* Timeout happened, return error */
+	if (i == FPGA_TIMEOUT_CNT) {
+		printf("FPGA: Timeout waiting for program.\n");
+		return -4;
+	}
+
+	/* Disable AXI configuration */
+	clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK);
+
+	return 0;
+}
+
+/* Ensure the FPGA entering init phase */
+static int fpgamgr_program_poll_initphase(void)
+{
+	unsigned long i;
+
+	/* Additional clocks for the CB to enter initialization phase */
+	if (fpgamgr_dclkcnt_set(0x4))
+		return -5;
+
+	/* (4) wait until FPGA enter init phase or user mode */
+	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+		if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_INITPHASE)
+			break;
+		if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE)
+			break;
+	}
+
+	/* If not in configuration state, return error */
+	if (i == FPGA_TIMEOUT_CNT)
+		return -6;
+
+	return 0;
+}
+
+/* Ensure the FPGA entering user mode */
+static int fpgamgr_program_poll_usermode(void)
+{
+	unsigned long i;
+
+	/* Additional clocks for the CB to exit initialization phase */
+	if (fpgamgr_dclkcnt_set(0x5000))
+		return -7;
+
+	/* (5) wait until FPGA enter user mode */
+	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+		if (fpgamgr_get_mode() == FPGAMGRREGS_MODE_USERMODE)
+			break;
+	}
+	/* If not in configuration state, return error */
+	if (i == FPGA_TIMEOUT_CNT)
+		return -8;
+
+	/* To release FPGA Manager drive over configuration line */
+	clrbits_le32(&fpgamgr_regs->ctrl, FPGAMGRREGS_CTRL_EN_MASK);
+
+	return 0;
+}
+
+/*
+ * FPGA Manager to program the FPGA. This is the interface used by FPGA driver.
+ * Return 0 for sucess, non-zero for error.
+ */
+int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
+{
+	unsigned long status;
+
+	if ((uint32_t)rbf_data & 0x3) {
+		puts("FPGA: Unaligned data, realign to 32bit boundary.\n");
+		return -EINVAL;
+	}
+
+	/* Prior programming the FPGA, all bridges need to be shut off */
+
+	/* Disable all signals from hps peripheral controller to fpga */
+	writel(0, &sysmgr_regs->fpgaintfgrp_module);
+
+	/* Disable all signals from FPGA to HPS SDRAM */
+#define SDR_CTRLGRP_FPGAPORTRST_ADDRESS	0x5080
+	writel(0, SOCFPGA_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS);
+
+	/* Disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */
+	socfpga_bridges_reset(1);
+
+	/* Unmap the bridges from NIC-301 */
+	writel(0x1, SOCFPGA_L3REGS_ADDRESS);
+
+	/* Initialize the FPGA Manager */
+	status = fpgamgr_program_init();
+	if (status)
+		return status;
+
+	/* Write the RBF data to FPGA Manager */
+	fpgamgr_program_write(rbf_data, rbf_size);
+
+	/* Ensure the FPGA entering config done */
+	status = fpgamgr_program_poll_cd();
+	if (status)
+		return status;
+
+	/* Ensure the FPGA entering init phase */
+	status = fpgamgr_program_poll_initphase();
+	if (status)
+		return status;
+
+	/* Ensure the FPGA entering user mode */
+	return fpgamgr_program_poll_usermode();
+}
diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c
index bcd6a3e..9bdfbbc 100644
--- a/drivers/mmc/bfin_sdh.c
+++ b/drivers/mmc/bfin_sdh.c
@@ -138,9 +138,9 @@
 	if (data->flags & MMC_DATA_WRITE)
 		return UNUSABLE_ERR;
 #ifndef RSI_BLKSZ
-	data_ctl |= ((ffs(data_size) - 1) << 4);
+	data_ctl |= ((ffs(data->blocksize) - 1) << 4);
 #else
-	bfin_write_SDH_BLK_SIZE(data_size);
+	bfin_write_SDH_BLK_SIZE(data->blocksize);
 #endif
 	data_ctl |= DTX_DIR;
 	bfin_write_SDH_DATA_CTL(data_ctl);
@@ -189,7 +189,8 @@
 		do {
 			udelay(1);
 			status = bfin_read_SDH_STATUS();
-		} while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN)));
+		} while (!(status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL |
+			 RX_OVERRUN)));
 
 		if (status & DAT_TIME_OUT) {
 			bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT);
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 0df30bc..785eed5 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -119,7 +119,7 @@
 
 	while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
 		if (get_timer(start) > timeout) {
-			printf("Timeout on data busy\n");
+			printf("%s: Timeout on data busy\n", __func__);
 			return TIMEOUT;
 		}
 	}
@@ -177,14 +177,24 @@
 		}
 	}
 
-	if (i == retry)
+	if (i == retry) {
+		printf("%s: Timeout.\n", __func__);
 		return TIMEOUT;
+	}
 
 	if (mask & DWMCI_INTMSK_RTO) {
-		debug("Response Timeout..\n");
+		/*
+		 * Timeout here is not necessarily fatal. (e)MMC cards
+		 * will splat here when they receive CMD55 as they do
+		 * not support this command and that is exactly the way
+		 * to tell them apart from SD cards. Thus, this output
+		 * below shall be debug(). eMMC cards also do not favor
+		 * CMD8, please keep that in mind.
+		 */
+		debug("%s: Response Timeout.\n", __func__);
 		return TIMEOUT;
 	} else if (mask & DWMCI_INTMSK_RE) {
-		debug("Response Error..\n");
+		printf("%s: Response Error.\n", __func__);
 		return -1;
 	}
 
@@ -204,7 +214,7 @@
 		do {
 			mask = dwmci_readl(host, DWMCI_RINTSTS);
 			if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
-				debug("DATA ERROR!\n");
+				printf("%s: DATA ERROR!\n", __func__);
 				return -1;
 			}
 		} while (!(mask & DWMCI_INTMSK_DTO));
@@ -232,16 +242,16 @@
 	if ((freq == host->clock) || (freq == 0))
 		return 0;
 	/*
-	 * If host->get_mmc_clk didn't define,
+	 * If host->get_mmc_clk isn't defined,
 	 * then assume that host->bus_hz is source clock value.
-	 * host->bus_hz should be set from user.
+	 * host->bus_hz should be set by user.
 	 */
 	if (host->get_mmc_clk)
 		sclk = host->get_mmc_clk(host);
 	else if (host->bus_hz)
 		sclk = host->bus_hz;
 	else {
-		printf("Didn't get source clock value..\n");
+		printf("%s: Didn't get source clock value.\n", __func__);
 		return -EINVAL;
 	}
 
@@ -260,7 +270,7 @@
 	do {
 		status = dwmci_readl(host, DWMCI_CMD);
 		if (timeout-- < 0) {
-			printf("TIMEOUT error!!\n");
+			printf("%s: Timeout!\n", __func__);
 			return -ETIMEDOUT;
 		}
 	} while (status & DWMCI_CMD_START);
@@ -275,7 +285,7 @@
 	do {
 		status = dwmci_readl(host, DWMCI_CMD);
 		if (timeout-- < 0) {
-			printf("TIMEOUT error!!\n");
+			printf("%s: Timeout!\n", __func__);
 			return -ETIMEDOUT;
 		}
 	} while (status & DWMCI_CMD_START);
@@ -290,7 +300,7 @@
 	struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
 	u32 ctype, regs;
 
-	debug("Buswidth = %d, clock: %d\n",mmc->bus_width, mmc->clock);
+	debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock);
 
 	dwmci_setup_bus(host, mmc->clock);
 	switch (mmc->bus_width) {
@@ -329,7 +339,7 @@
 	dwmci_writel(host, DWMCI_PWREN, 1);
 
 	if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
-		debug("%s[%d] Fail-reset!!\n",__func__,__LINE__);
+		printf("%s[%d] Fail-reset!!\n", __func__, __LINE__);
 		return -1;
 	}
 
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index a26f3ce..44a4feb 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -594,10 +594,15 @@
 	ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
 			 (mmc->part_config & ~PART_ACCESS_MASK)
 			 | (part_num & PART_ACCESS_MASK));
-	if (ret)
-		return ret;
 
-	return mmc_set_capacity(mmc, part_num);
+	/*
+	 * Set the capacity if the switch succeeded or was intended
+	 * to return to representing the raw device.
+	 */
+	if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
+		ret = mmc_set_capacity(mmc, part_num);
+
+	return ret;
 }
 
 int mmc_getcd(struct mmc *mmc)
@@ -1010,6 +1015,8 @@
 
 			if (err)
 				return err;
+			else
+				ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
 
 			/* Read out group size from ext_csd */
 			mmc->erase_grp_size =
@@ -1127,10 +1134,11 @@
 			mmc_set_bus_width(mmc, widths[idx]);
 
 			err = mmc_send_ext_csd(mmc, test_csd);
+			/* Only compare read only fields */
 			if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
 				    == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
-				 && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
-				    == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
+				 && ext_csd[EXT_CSD_HC_WP_GRP_SIZE] \
+				    == test_csd[EXT_CSD_HC_WP_GRP_SIZE] \
 				 && ext_csd[EXT_CSD_REV] \
 				    == test_csd[EXT_CSD_REV]
 				 && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
index 9759198..d34e743 100644
--- a/drivers/mmc/mvebu_mmc.c
+++ b/drivers/mmc/mvebu_mmc.c
@@ -17,8 +17,12 @@
 #include <asm/arch/kirkwood.h>
 #include <mvebu_mmc.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #define DRIVER_NAME "MVEBU_MMC"
 
+#define MVEBU_TARGET_DRAM 0
+
 static void mvebu_mmc_write(u32 offs, u32 val)
 {
 	writel(val, CONFIG_SYS_MMC_BASE + (offs));
@@ -164,6 +168,9 @@
 			return TIMEOUT;
 		}
 	}
+	if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) &
+		(SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
+		return TIMEOUT;
 
 	/* Handling response */
 	if (cmd->resp_type & MMC_RSP_136) {
@@ -271,6 +278,7 @@
 
 	/* default to maximum timeout */
 	ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
+	ctrl_reg |= SDIO_HOST_CTRL_TMOUT_EN;
 
 	ctrl_reg |= SDIO_HOST_CTRL_PUSH_PULL_EN;
 
@@ -296,6 +304,55 @@
 	mvebu_mmc_set_clk(mmc->clock);
 }
 
+/*
+ * Set window register.
+ */
+static void mvebu_window_setup(void)
+{
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		mvebu_mmc_write(WINDOW_CTRL(i), 0);
+		mvebu_mmc_write(WINDOW_BASE(i), 0);
+	}
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		u32 size, base, attrib;
+
+		/* Enable DRAM bank */
+		switch (i) {
+		case 0:
+			attrib = KWCPU_ATTR_DRAM_CS0;
+			break;
+		case 1:
+			attrib = KWCPU_ATTR_DRAM_CS1;
+			break;
+		case 2:
+			attrib = KWCPU_ATTR_DRAM_CS2;
+			break;
+		case 3:
+			attrib = KWCPU_ATTR_DRAM_CS3;
+			break;
+		default:
+			/* invalide bank, disable access */
+			attrib = 0;
+			break;
+		}
+
+		size = gd->bd->bi_dram[i].size;
+		base = gd->bd->bi_dram[i].start;
+		if (size && attrib) {
+			mvebu_mmc_write(WINDOW_CTRL(i),
+					MVCPU_WIN_CTRL_DATA(size,
+							    MVEBU_TARGET_DRAM,
+							    attrib,
+							    MVCPU_WIN_ENABLE));
+		} else {
+			mvebu_mmc_write(WINDOW_CTRL(i), MVCPU_WIN_DISABLE);
+		}
+		mvebu_mmc_write(WINDOW_BASE(i), base);
+	}
+}
+
 static int mvebu_mmc_initialize(struct mmc *mmc)
 {
 	debug("%s: mvebu_mmc_initialize", DRIVER_NAME);
@@ -322,6 +379,8 @@
 	mvebu_mmc_write(SDIO_NOR_INTR_EN, 0);
 	mvebu_mmc_write(SDIO_ERR_INTR_EN, 0);
 
+	mvebu_window_setup();
+
 	/* SW reset */
 	mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
 
@@ -342,7 +401,8 @@
 	.f_min		= MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
 	.f_max		= MVEBU_MMC_CLOCKRATE_MAX,
 	.voltages	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.host_caps	= MMC_MODE_4BIT | MMC_MODE_HS,
+	.host_caps	= MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HC |
+			  MMC_MODE_HS_52MHz,
 	.part_type	= PART_TYPE_DOS,
 	.b_max		= CONFIG_SYS_MMC_MAX_BLK_COUNT,
 };
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index 1f96382..eb69aed 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -7,6 +7,7 @@
 #include <common.h>
 #include <malloc.h>
 #include <dwmmc.h>
+#include <errno.h>
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/clock_manager.h>
 #include <asm/arch/system_manager.h>
@@ -44,12 +45,18 @@
 int socfpga_dwmmc_init(u32 regbase, int bus_width, int index)
 {
 	struct dwmci_host *host;
+	unsigned long clk = cm_get_mmc_controller_clk_hz();
+
+	if (clk == 0) {
+		printf("%s: MMC clock is zero!", __func__);
+		return -EINVAL;
+	}
 
 	/* calloc for zero init */
-	host = calloc(sizeof(struct dwmci_host), 1);
+	host = calloc(1, sizeof(struct dwmci_host));
 	if (!host) {
-		printf("dwmci_host calloc fail!\n");
-		return -1;
+		printf("%s: calloc() failed!\n", __func__);
+		return -ENOMEM;
 	}
 
 	host->name = "SOCFPGA DWMMC";
@@ -58,7 +65,7 @@
 	host->clksel = socfpga_dwmci_clksel;
 	host->dev_index = index;
 	/* fixed clock divide by 4 which due to the SDMMC wrapper */
-	host->bus_hz = CONFIG_SOCFPGA_DWMMC_BUS_HZ;
+	host->bus_hz = clk;
 	host->fifoth_val = MSIZE(0x2) |
 		RX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1) |
 		TX_WMARK(CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2);
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index c4b5bc1..9b3175d 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -593,7 +593,7 @@
 	case CFI_CMDSET_INTEL_PROG_REGIONS:
 	case CFI_CMDSET_INTEL_EXTENDED:
 	case CFI_CMDSET_INTEL_STANDARD:
-		if ((retcode != ERR_OK)
+		if ((retcode == ERR_OK)
 		    && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
 			retcode = ERR_INVAL;
 			printf ("Flash %s error at address %lx\n", prompt,
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 7186e3b..9ded895 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -279,19 +279,21 @@
 	struct eth_dma_regs *dma_p = priv->dma_regs_p;
 	u32 desc_num = priv->tx_currdescnum;
 	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
-
+	uint32_t desc_start = (uint32_t)desc_p;
+	uint32_t desc_end = desc_start +
+		roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
+	uint32_t data_start = (uint32_t)desc_p->dmamac_addr;
+	uint32_t data_end = data_start +
+		roundup(length, ARCH_DMA_MINALIGN);
 	/*
 	 * Strictly we only need to invalidate the "txrx_status" field
 	 * for the following check, but on some platforms we cannot
-	 * invalidate only 4 bytes, so roundup to
-	 * ARCH_DMA_MINALIGN. This is safe because the individual
-	 * descriptors in the array are each aligned to
-	 * ARCH_DMA_MINALIGN.
+	 * invalidate only 4 bytes, so we flush the entire descriptor,
+	 * which is 16 bytes in total. This is safe because the
+	 * individual descriptors in the array are each aligned to
+	 * ARCH_DMA_MINALIGN and padded appropriately.
 	 */
-	invalidate_dcache_range(
-		(unsigned long)desc_p,
-		(unsigned long)desc_p +
-		roundup(sizeof(desc_p->txrx_status), ARCH_DMA_MINALIGN));
+	invalidate_dcache_range(desc_start, desc_end);
 
 	/* Check if the descriptor is owned by CPU */
 	if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
@@ -299,11 +301,10 @@
 		return -1;
 	}
 
-	memcpy((void *)desc_p->dmamac_addr, packet, length);
+	memcpy(desc_p->dmamac_addr, packet, length);
 
 	/* Flush data to be sent */
-	flush_dcache_range((unsigned long)desc_p->dmamac_addr,
-			   (unsigned long)desc_p->dmamac_addr + length);
+	flush_dcache_range(data_start, data_end);
 
 #if defined(CONFIG_DW_ALTDESCRIPTOR)
 	desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
@@ -321,8 +322,7 @@
 #endif
 
 	/* Flush modified buffer descriptor */
-	flush_dcache_range((unsigned long)desc_p,
-			   (unsigned long)desc_p + sizeof(struct dmamacdescr));
+	flush_dcache_range(desc_start, desc_end);
 
 	/* Test the wrap-around condition. */
 	if (++desc_num >= CONFIG_TX_DESCR_NUM)
@@ -342,11 +342,14 @@
 	u32 status, desc_num = priv->rx_currdescnum;
 	struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
 	int length = 0;
+	uint32_t desc_start = (uint32_t)desc_p;
+	uint32_t desc_end = desc_start +
+		roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
+	uint32_t data_start = (uint32_t)desc_p->dmamac_addr;
+	uint32_t data_end;
 
 	/* Invalidate entire buffer descriptor */
-	invalidate_dcache_range((unsigned long)desc_p,
-				(unsigned long)desc_p +
-				sizeof(struct dmamacdescr));
+	invalidate_dcache_range(desc_start, desc_end);
 
 	status = desc_p->txrx_status;
 
@@ -357,9 +360,8 @@
 			 DESC_RXSTS_FRMLENSHFT;
 
 		/* Invalidate received data */
-		invalidate_dcache_range((unsigned long)desc_p->dmamac_addr,
-					(unsigned long)desc_p->dmamac_addr +
-					roundup(length, ARCH_DMA_MINALIGN));
+		data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
+		invalidate_dcache_range(data_start, data_end);
 
 		NetReceive(desc_p->dmamac_addr, length);
 
@@ -370,9 +372,7 @@
 		desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
 
 		/* Flush only status field - others weren't changed */
-		flush_dcache_range((unsigned long)&desc_p->txrx_status,
-				   (unsigned long)&desc_p->txrx_status +
-				   sizeof(desc_p->txrx_status));
+		flush_dcache_range(desc_start, desc_end);
 
 		/* Test the wrap-around condition. */
 		if (++desc_num >= CONFIG_RX_DESCR_NUM)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 5d7e3be..507b9a3 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -25,8 +25,7 @@
 #ifndef CONFIG_PHY_MICREL_KSZ9021
 /*
  * I can't believe Micrel used the exact same part number
- * for the KSZ9021
- * Shame Micrel, Shame!!!!!
+ * for the KSZ9021. Shame Micrel, Shame!
  */
 static struct phy_driver KS8721_driver = {
 	.name = "Micrel KS8721BL",
@@ -40,7 +39,7 @@
 #endif
 
 
-/**
+/*
  * KSZ9021 - KSZ9031 common
  */
 
@@ -69,8 +68,8 @@
 		phydev->speed = SPEED_10;
 	return 0;
 }
-#ifdef CONFIG_PHY_MICREL_KSZ9021
 
+#ifdef CONFIG_PHY_MICREL_KSZ9021
 /*
  * KSZ9021
  */
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 1ac943f..fd010ca 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -198,7 +198,7 @@
 #ifdef CONFIG_SYS_STDIO_DEREGISTER
 	struct serial_dev_priv *upriv = dev->uclass_priv;
 
-	if (stdio_deregister_dev(upriv->sdev))
+	if (stdio_deregister_dev(upriv->sdev), 0)
 		return -EPERM;
 #endif
 
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index 2572b34..b0ef35e 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -777,6 +777,11 @@
 		/* select DEVICE mode */
 		writel(USBMODE_DEVICE, &udc->usbmode);
 
+#if !defined(CONFIG_USB_GADGET_DUALSPEED)
+		/* Port force Full-Speed Connect */
+		setbits_le32(&udc->portsc, PFSC);
+#endif
+
 		writel(0xffffffff, &udc->epflush);
 
 		/* Turn on the USB connection by enabling the pullup resistor */
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
index 3e4f029..16fc9dd 100644
--- a/drivers/usb/gadget/f_dfu.c
+++ b/drivers/usb/gadget/f_dfu.c
@@ -81,14 +81,6 @@
 	NULL,
 };
 
-static const struct usb_qualifier_descriptor dev_qualifier = {
-	.bLength =		sizeof dev_qualifier,
-	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
-	.bcdUSB =		__constant_cpu_to_le16(0x0200),
-	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
-	.bNumConfigurations =	1,
-};
-
 static const char dfu_name[] = "Device Firmware Upgrade";
 
 /*
@@ -237,6 +229,7 @@
 {
 	f_dfu->usb_function.strings = dfu_strings;
 	f_dfu->usb_function.hs_descriptors = f_dfu->function;
+	f_dfu->usb_function.descriptors = f_dfu->function;
 	f_dfu->dfu_state = DFU_STATE_dfuIDLE;
 }
 
@@ -244,6 +237,7 @@
 {
 	f_dfu->usb_function.strings = NULL;
 	f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
+	f_dfu->usb_function.descriptors = dfu_runtime_descs;
 }
 
 static int handle_upload(struct usb_request *req, u16 len)
@@ -808,6 +802,7 @@
 		return -ENOMEM;
 	f_dfu->usb_function.name = "dfu";
 	f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
+	f_dfu->usb_function.descriptors = dfu_runtime_descs;
 	f_dfu->usb_function.bind = dfu_bind;
 	f_dfu->usb_function.unbind = dfu_unbind;
 	f_dfu->usb_function.set_alt = dfu_set_alt;
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 38c0965..71b62e5 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -351,10 +351,11 @@
 		strncat(response, FASTBOOT_VERSION, chars_left);
 	} else if (!strcmp_l1("bootloader-version", cmd)) {
 		strncat(response, U_BOOT_VERSION, chars_left);
-	} else if (!strcmp_l1("downloadsize", cmd)) {
+	} else if (!strcmp_l1("downloadsize", cmd) ||
+		!strcmp_l1("max-download-size", cmd)) {
 		char str_num[12];
 
-		sprintf(str_num, "%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
+		sprintf(str_num, "0x%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
 		strncat(response, str_num, chars_left);
 	} else if (!strcmp_l1("serialno", cmd)) {
 		s = getenv("serial#");
@@ -386,6 +387,7 @@
 	unsigned int transfer_size = download_size - download_bytes;
 	const unsigned char *buffer = req->buf;
 	unsigned int buffer_size = req->actual;
+	unsigned int pre_dot_num, now_dot_num;
 
 	if (req->status != 0) {
 		printf("Bad status: %d\n", req->status);
@@ -398,7 +400,15 @@
 	memcpy((void *)CONFIG_USB_FASTBOOT_BUF_ADDR + download_bytes,
 	       buffer, transfer_size);
 
+	pre_dot_num = download_bytes / BYTES_PER_DOT;
 	download_bytes += transfer_size;
+	now_dot_num = download_bytes / BYTES_PER_DOT;
+
+	if (pre_dot_num != now_dot_num) {
+		putc('.');
+		if (!(now_dot_num % 74))
+			putc('\n');
+	}
 
 	/* Check if transfer is done */
 	if (download_bytes >= download_size) {
@@ -420,11 +430,6 @@
 			req->length = ep->maxpacket;
 	}
 
-	if (download_bytes && !(download_bytes % BYTES_PER_DOT)) {
-		putc('.');
-		if (!(download_bytes % (74 * BYTES_PER_DOT)))
-			putc('\n');
-	}
 	req->actual = 0;
 	usb_ep_queue(ep, req, 0);
 }
@@ -541,7 +546,14 @@
 		error("unknown command: %s\n", cmdbuf);
 		fastboot_tx_write_str("FAILunknown command");
 	} else {
-		func_cb(ep, req);
+		if (req->actual < req->length) {
+			u8 *buf = (u8 *)req->buf;
+			buf[req->actual] = 0;
+			func_cb(ep, req);
+		} else {
+			error("buffer overflow\n");
+			fastboot_tx_write_str("FAILbuffer overflow");
+		}
 	}
 
 	if (req->status == 0) {
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index f274d96..e045957 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -1110,6 +1110,7 @@
 
 	memset(buf, 0, 8);
 	buf[0] = TYPE_DISK;
+	buf[1] = curlun->removable ? 0x80 : 0;
 	buf[2] = 2;		/* ANSI SCSI level 2 */
 	buf[3] = 2;		/* SCSI-2 INQUIRY data format */
 	buf[4] = 31;		/* Additional length */
diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c
index c85b0fb..78519fa 100644
--- a/drivers/usb/gadget/f_thor.c
+++ b/drivers/usb/gadget/f_thor.c
@@ -458,16 +458,6 @@
 	.bInterval = 0x9,
 };
 
-static struct usb_qualifier_descriptor dev_qualifier = {
-	.bLength =		sizeof(dev_qualifier),
-	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
-
-	.bcdUSB =		__constant_cpu_to_le16(0x0200),
-	.bDeviceClass =	USB_CLASS_VENDOR_SPEC,
-
-	.bNumConfigurations =	2,
-};
-
 /*
  * This attribute vendor descriptor is necessary for correct operation with
  * Windows version of THOR download program
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index eaf5913..6323c50 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -273,6 +273,29 @@
 	return QH_FULL_SPEED;
 }
 
+static void ehci_update_endpt2_dev_n_port(struct usb_device *dev,
+					  struct QH *qh)
+{
+	struct usb_device *ttdev;
+
+	if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL)
+		return;
+
+	/*
+	 * For full / low speed devices we need to get the devnum and portnr of
+	 * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs
+	 * in the tree before that one!
+	 */
+	ttdev = dev;
+	while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
+		ttdev = ttdev->parent;
+	if (!ttdev->parent)
+		return;
+
+	qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
+				     QH_ENDPT2_HUBADDR(ttdev->parent->devnum));
+}
+
 static int
 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		   int length, struct devrequest *req)
@@ -390,10 +413,9 @@
 		QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) |
 		QH_ENDPT1_DEVADDR(usb_pipedevice(pipe));
 	qh->qh_endpt1 = cpu_to_hc32(endpt);
-	endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_PORTNUM(dev->portnr) |
-		QH_ENDPT2_HUBADDR(dev->parent->devnum) |
-		QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
+	endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
 	qh->qh_endpt2 = cpu_to_hc32(endpt);
+	ehci_update_endpt2_dev_n_port(dev, qh);
 	qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
 	qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
 
@@ -974,6 +996,7 @@
 	 * Set up periodic list
 	 * Step 1: Parent QH for all periodic transfers.
 	 */
+	ehcic[index].periodic_schedules = 0;
 	periodic = &ehcic[index].periodic_queue;
 	memset(periodic, 0, sizeof(*periodic));
 	periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
@@ -1132,8 +1155,6 @@
 	return 0;
 }
 
-static int periodic_schedules;
-
 struct int_queue *
 create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
 		 int elementsize, void *buffer)
@@ -1201,12 +1222,10 @@
 			(1 << 0)); /* S-mask: microframe 0 */
 		if (dev->speed == USB_SPEED_LOW ||
 				dev->speed == USB_SPEED_FULL) {
-			debug("TT: port: %d, hub address: %d\n",
-				dev->portnr, dev->parent->devnum);
-			qh->qh_endpt2 |= cpu_to_hc32((dev->portnr << 23) |
-				(dev->parent->devnum << 16) |
-				(0x1c << 8)); /* C-mask: microframes 2-4 */
+			/* C-mask: microframes 2-4 */
+			qh->qh_endpt2 |= cpu_to_hc32((0x1c << 8));
 		}
+		ehci_update_endpt2_dev_n_port(dev, qh);
 
 		td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
 		td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -1258,7 +1277,7 @@
 		debug("FATAL: periodic should never fail, but did");
 		goto fail3;
 	}
-	periodic_schedules++;
+	ctrl->periodic_schedules++;
 
 	debug("Exit create_int_queue\n");
 	return result;
@@ -1277,6 +1296,7 @@
 void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
 {
 	struct QH *cur = queue->current;
+	struct qTD *cur_td;
 
 	/* depleted queue */
 	if (cur == NULL) {
@@ -1284,20 +1304,21 @@
 		return NULL;
 	}
 	/* still active */
-	invalidate_dcache_range((uint32_t)cur,
-				ALIGN_END_ADDR(struct QH, cur, 1));
-	if (cur->qh_overlay.qt_token & cpu_to_hc32(0x80)) {
-		debug("Exit poll_int_queue with no completed intr transfer. "
-		      "token is %x\n", cur->qh_overlay.qt_token);
+	cur_td = &queue->tds[queue->current - queue->first];
+	invalidate_dcache_range((uint32_t)cur_td,
+				ALIGN_END_ADDR(struct qTD, cur_td, 1));
+	if (QT_TOKEN_GET_STATUS(hc32_to_cpu(cur_td->qt_token)) &
+			QT_TOKEN_STATUS_ACTIVE) {
+		debug("Exit poll_int_queue with no completed intr transfer. token is %x\n",
+		      hc32_to_cpu(cur_td->qt_token));
 		return NULL;
 	}
 	if (!(cur->qh_link & QH_LINK_TERMINATE))
 		queue->current++;
 	else
 		queue->current = NULL;
-	debug("Exit poll_int_queue with completed intr transfer. "
-	      "token is %x at %p (first at %p)\n", cur->qh_overlay.qt_token,
-	      &cur->qh_overlay.qt_token, queue->first);
+	debug("Exit poll_int_queue with completed intr transfer. token is %x at %p (first at %p)\n",
+	      hc32_to_cpu(cur_td->qt_token), cur, queue->first);
 	return cur->buffer;
 }
 
@@ -1313,7 +1334,7 @@
 		debug("FATAL: periodic should never fail, but did");
 		goto out;
 	}
-	periodic_schedules--;
+	ctrl->periodic_schedules--;
 
 	struct QH *cur = &ctrl->periodic_queue;
 	timeout = get_timer(0) + 500; /* abort after 500ms */
@@ -1322,6 +1343,8 @@
 		if (NEXT_QH(cur) == queue->first) {
 			debug("found candidate. removing from chain\n");
 			cur->qh_link = queue->last->qh_link;
+			flush_dcache_range((uint32_t)cur,
+					   ALIGN_END_ADDR(struct QH, cur, 1));
 			result = 0;
 			break;
 		}
@@ -1333,7 +1356,7 @@
 		}
 	}
 
-	if (periodic_schedules > 0) {
+	if (ctrl->periodic_schedules > 0) {
 		result = enable_periodic(ctrl);
 		if (result < 0)
 			debug("FATAL: periodic should never fail, but did");
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 33e5ea9..5f0a98e 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -305,11 +305,11 @@
 #if defined(CONFIG_TEGRA20)
 	if (config->periph_id == PERIPH_ID_USBD) {
 		clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK,
-				PTS_UTMI << PTS1_SHIFT);
+				pts << PTS1_SHIFT);
 		clrbits_le32(&usbctlr->port_sc1, STS1);
 	} else {
 		clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
-				PTS_UTMI << PTS_SHIFT);
+				pts << PTS_SHIFT);
 		clrbits_le32(&usbctlr->port_sc1, STS);
 	}
 #else
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 093eb4b..433e703 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -246,6 +246,7 @@
 	struct QH qh_list __aligned(USB_DMA_MINALIGN);
 	struct QH periodic_queue __aligned(USB_DMA_MINALIGN);
 	uint32_t *periodic_list;
+	int periodic_schedules;
 	int ntds;
 };
 
diff --git a/drivers/usb/musb-new/musb_core.c b/drivers/usb/musb-new/musb_core.c
index 4edd6d7..242cc30 100644
--- a/drivers/usb/musb-new/musb_core.c
+++ b/drivers/usb/musb-new/musb_core.c
@@ -942,9 +942,7 @@
 
 	/* put into basic highspeed mode and start session */
 	musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
-#ifdef CONFIG_USB_GADGET_DUALSPEED
 						| MUSB_POWER_HSENAB
-#endif
 						/* ENSUSPEND wedges tusb */
 						/* | MUSB_POWER_ENSUSPEND */
 						);
diff --git a/include/altera.h b/include/altera.h
index ae5f7ee..c2991ad 100644
--- a/include/altera.h
+++ b/include/altera.h
@@ -10,35 +10,59 @@
 #ifndef _ALTERA_H_
 #define _ALTERA_H_
 
-typedef enum {				/* typedef Altera_iface */
-	min_altera_iface_type,		/* insert all new types after this */
-	passive_serial,			/* serial data and external clock */
-	passive_parallel_synchronous,	/* parallel data */
-	passive_parallel_asynchronous,	/* parallel data */
-	passive_serial_asynchronous,	/* serial data w/ internal clock (not used)	*/
-	altera_jtag_mode,		/* jtag/tap serial (not used ) */
-	fast_passive_parallel,		/* fast passive parallel (FPP) */
-	fast_passive_parallel_security,	/* fast passive parallel with security (FPPS) */
-	max_altera_iface_type		/* insert all new types before this */
-} Altera_iface;				/* end, typedef Altera_iface */
+enum altera_iface {
+	/* insert all new types after this */
+	min_altera_iface_type,
+	/* serial data and external clock */
+	passive_serial,
+	/* parallel data */
+	passive_parallel_synchronous,
+	/* parallel data */
+	passive_parallel_asynchronous,
+	/* serial data w/ internal clock (not used) */
+	passive_serial_asynchronous,
+	/* jtag/tap serial (not used ) */
+	altera_jtag_mode,
+	/* fast passive parallel (FPP) */
+	fast_passive_parallel,
+	/* fast passive parallel with security (FPPS) */
+	fast_passive_parallel_security,
+	/* insert all new types before this */
+	max_altera_iface_type,
+};
 
-typedef enum {			/* typedef Altera_Family */
-	min_altera_type,	/* insert all new types after this */
-	Altera_ACEX1K,		/* ACEX1K Family */
-	Altera_CYC2,		/* CYCLONII Family */
-	Altera_StratixII,	/* StratixII Family */
-/* Add new models here */
-	max_altera_type		/* insert all new types before this */
-} Altera_Family;		/* end, typedef Altera_Family */
+enum altera_family {
+	/* insert all new types after this */
+	min_altera_type,
+	/* ACEX1K Family */
+	Altera_ACEX1K,
+	/* CYCLONII Family */
+	Altera_CYC2,
+	/* StratixII Family */
+	Altera_StratixII,
+	/* SoCFPGA Family */
+	Altera_SoCFPGA,
 
-typedef struct {		/* typedef Altera_desc */
-	Altera_Family	family;	/* part type */
-	Altera_iface	iface;	/* interface type */
-	size_t		size;	/* bytes of data part can accept */
-	void *		iface_fns;/* interface function table */
-	void *		base;	/* base interface address */
-	int		cookie;	/* implementation specific cookie */
-} Altera_desc;			/* end, typedef Altera_desc */
+	/* Add new models here */
+
+	/* insert all new types before this */
+	max_altera_type,
+};
+
+typedef struct {
+	/* part type */
+	enum altera_family	family;
+	/* interface type */
+	enum altera_iface	iface;
+	/* bytes of data part can accept */
+	size_t			size;
+	/* interface function table */
+	void			*iface_fns;
+	/* base interface address */
+	void			*base;
+	/* implementation specific cookie */
+	int			cookie;
+} Altera_desc;
 
 /* Generic Altera Functions
  *********************************************************************/
@@ -69,4 +93,8 @@
 	Altera_post_fn post;
 } altera_board_specific_func;
 
+#ifdef CONFIG_FPGA_SOCFPGA
+int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size);
+#endif
+
 #endif /* _ALTERA_H_ */
diff --git a/include/configs/axs101.h b/include/configs/axs101.h
index c22d6d0..1bf8390 100644
--- a/include/configs/axs101.h
+++ b/include/configs/axs101.h
@@ -125,7 +125,6 @@
  */
 #define CONFIG_DESIGNWARE_ETH
 #define CONFIG_DW_AUTONEG
-#define CONFIG_DW_SEARCH_PHY
 #define CONFIG_NET_MULTI
 
 /*
diff --git a/include/configs/siemens-am33x-common.h b/include/configs/siemens-am33x-common.h
index bf9752f..1ce0965 100644
--- a/include/configs/siemens-am33x-common.h
+++ b/include/configs/siemens-am33x-common.h
@@ -231,7 +231,7 @@
 #define CONFIG_MUSB_GADGET
 #define CONFIG_MUSB_PIO_ONLY
 #define CONFIG_MUSB_DISABLE_BULK_COMBINE_SPLIT
-#define CONFIG_USB_GADGET_DUALSPEED
+#undef CONFIG_USB_GADGET_DUALSPEED
 #define CONFIG_USB_GADGET_VBUS_DRAW	2
 #define CONFIG_MUSB_HOST
 
diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h
new file mode 100644
index 0000000..49504dc
--- /dev/null
+++ b/include/configs/socfpga_common.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef __CONFIG_SOCFPGA_CYCLONE5_COMMON_H__
+#define __CONFIG_SOCFPGA_CYCLONE5_COMMON_H__
+
+#define CONFIG_SYS_GENERIC_BOARD
+
+/* Virtual target or real hardware */
+#undef CONFIG_SOCFPGA_VIRTUAL_TARGET
+
+#define CONFIG_ARMV7
+#define CONFIG_SYS_THUMB_BUILD
+
+#define CONFIG_SOCFPGA
+
+/*
+ * High level configuration
+ */
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_MISC_INIT_R
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_CLOCKS
+
+#define CONFIG_FIT
+#define CONFIG_OF_LIBFDT
+#define CONFIG_SYS_BOOTMAPSZ		(64 * 1024 * 1024)
+
+#define CONFIG_TIMESTAMP		/* Print image info with timestamp */
+
+/*
+ * Memory configurations
+ */
+#define CONFIG_NR_DRAM_BANKS		1
+#define PHYS_SDRAM_1			0x0
+#define CONFIG_SYS_MALLOC_LEN		(10 * 1024 * 1024)
+#define CONFIG_SYS_MEMTEST_START	PHYS_SDRAM_1
+#define CONFIG_SYS_MEMTEST_END		PHYS_SDRAM_1_SIZE
+
+#define CONFIG_SYS_INIT_RAM_ADDR	0xFFFF0000
+#define CONFIG_SYS_INIT_RAM_SIZE	(0x10000 - 0x100)
+#define CONFIG_SYS_INIT_SP_ADDR					\
+	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE -	\
+	GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
+#define CONFIG_SYS_TEXT_BASE		0x08000040
+#else
+#define CONFIG_SYS_TEXT_BASE		0x01000040
+#endif
+
+/*
+ * U-Boot general configurations
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_CBSIZE	1024		/* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE	\
+	(CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+						/* Print buffer size */
+#define CONFIG_SYS_MAXARGS	32		/* Max number of command args */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+						/* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE			/* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE			/* Command auto complete */
+#define CONFIG_CMDLINE_EDITING			/* Command history etc */
+#define CONFIG_SYS_HUSH_PARSER
+
+/*
+ * Cache
+ */
+#define CONFIG_SYS_ARM_CACHE_WRITEALLOC
+#define CONFIG_SYS_CACHELINE_SIZE 32
+#define CONFIG_SYS_L2_PL310
+#define CONFIG_SYS_PL310_BASE		SOCFPGA_MPUL2_ADDRESS
+
+/*
+ * Ethernet on SoC (EMAC)
+ */
+#if defined(CONFIG_CMD_NET) && !defined(CONFIG_SOCFPGA_VIRTUAL_TARGET)
+#define CONFIG_DESIGNWARE_ETH
+#define CONFIG_NET_MULTI
+#define CONFIG_DW_ALTDESCRIPTOR
+#define CONFIG_MII
+#define CONFIG_AUTONEG_TIMEOUT		(15 * CONFIG_SYS_HZ)
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_GIGE
+#endif
+
+/*
+ * FPGA Driver
+ */
+#ifdef CONFIG_CMD_FPGA
+#define CONFIG_FPGA
+#define CONFIG_FPGA_ALTERA
+#define CONFIG_FPGA_SOCFPGA
+#define CONFIG_FPGA_COUNT		1
+#endif
+
+/*
+ * L4 OSC1 Timer 0
+ */
+/* This timer uses eosc1, whose clock frequency is fixed at any condition. */
+#define CONFIG_SYS_TIMERBASE		SOCFPGA_OSC1TIMER0_ADDRESS
+#define CONFIG_SYS_TIMER_COUNTS_DOWN
+#define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMERBASE + 0x4)
+#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
+#define CONFIG_SYS_TIMER_RATE		2400000
+#else
+#define CONFIG_SYS_TIMER_RATE		25000000
+#endif
+
+/*
+ * L4 Watchdog
+ */
+#ifdef CONFIG_HW_WATCHDOG
+#define CONFIG_DESIGNWARE_WATCHDOG
+#define CONFIG_DW_WDT_BASE		SOCFPGA_L4WD0_ADDRESS
+#define CONFIG_DW_WDT_CLOCK_KHZ		25000
+#define CONFIG_HW_WATCHDOG_TIMEOUT_MS	12000
+#endif
+
+/*
+ * MMC Driver
+ */
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_MMC
+#define CONFIG_BOUNCE_BUFFER
+#define CONFIG_GENERIC_MMC
+#define CONFIG_DWMMC
+#define CONFIG_SOCFPGA_DWMMC
+#define CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH	1024
+#define CONFIG_SOCFPGA_DWMMC_DRVSEL	3
+#define CONFIG_SOCFPGA_DWMMC_SMPSEL	0
+/* FIXME */
+/* using smaller max blk cnt to avoid flooding the limited stack we have */
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT	256	/* FIXME -- SPL only? */
+#endif
+
+/*
+ * Serial Driver
+ */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	-4
+#define CONFIG_SYS_NS16550_COM1		SOCFPGA_UART0_ADDRESS
+#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
+#define CONFIG_SYS_NS16550_CLK		1000000
+#else
+#define CONFIG_SYS_NS16550_CLK		100000000
+#endif
+#define CONFIG_CONS_INDEX		1
+#define CONFIG_BAUDRATE			115200
+
+/*
+ * U-Boot environment
+ */
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
+#define CONFIG_SYS_CONSOLE_ENV_OVERWRITE
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE			4096
+
+/*
+ * SPL
+ */
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_RAM_DEVICE
+#define CONFIG_SPL_TEXT_BASE		0xFFFF0000
+#define CONFIG_SPL_STACK		CONFIG_SYS_INIT_SP_ADDR
+#define CONFIG_SPL_STACK_SIZE		(4 * 1024)
+#define CONFIG_SPL_MALLOC_SIZE		(5 * 1024)	/* FIXME */
+#define CONFIG_SYS_SPL_MALLOC_START	((unsigned long) (&__malloc_start))
+#define CONFIG_SYS_SPL_MALLOC_SIZE	(&__malloc_end - &__malloc_start)
+
+#define CHUNKSZ_CRC32			(1 * 1024)	/* FIXME: ewww */
+#define CONFIG_CRC32_VERIFY
+
+/* Linker script for SPL */
+#define CONFIG_SPL_LDSCRIPT	"arch/arm/cpu/armv7/socfpga/u-boot-spl.lds"
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_WATCHDOG_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_PARTITIONS
+#endif
+
+#endif	/* __CONFIG_SOCFPGA_CYCLONE5_COMMON_H__ */
diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h
index 5d145cd..8d54bf8 100644
--- a/include/configs/socfpga_cyclone5.h
+++ b/include/configs/socfpga_cyclone5.h
@@ -1,287 +1,100 @@
 /*
- *  Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * Copyright (C) 2014 Marek Vasut <marex@denx.de>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
-#ifndef __CONFIG_H
-#define __CONFIG_H
+#ifndef __CONFIG_SOCFPGA_CYCLONE5_H__
+#define __CONFIG_SOCFPGA_CYCLONE5_H__
 
 #include <asm/arch/socfpga_base_addrs.h>
 #include "../../board/altera/socfpga/pinmux_config.h"
 #include "../../board/altera/socfpga/iocsr_config.h"
 #include "../../board/altera/socfpga/pll_config.h"
 
-/*
- * High level configuration
- */
-/* Virtual target or real hardware */
-#undef CONFIG_SOCFPGA_VIRTUAL_TARGET
-
-#define CONFIG_ARMV7
-#define CONFIG_SYS_DCACHE_OFF
-#undef CONFIG_USE_IRQ
-
-#define CONFIG_MISC_INIT_R
-#define CONFIG_SINGLE_BOOTLOADER
-#define CONFIG_SOCFPGA
-
-/* base address for .text section */
-#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
-#define CONFIG_SYS_TEXT_BASE		0x08000040
-#else
-#define CONFIG_SYS_TEXT_BASE		0x01000040
-#endif
-#define CONFIG_SYS_LOAD_ADDR		0x7fc0
-
-/* Console I/O Buffer Size */
-#define CONFIG_SYS_CBSIZE		256
-/* Monitor Command Prompt */
-#define CONFIG_SYS_PROMPT		"SOCFPGA_CYCLONE5 # "
-#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE + \
-					sizeof(CONFIG_SYS_PROMPT) + 16)
-
-/*
- * Display CPU and Board Info
- */
-#define CONFIG_DISPLAY_CPUINFO
-#define CONFIG_DISPLAY_BOARDINFO
-
-/*
- * Enable early stage initialization at C environment
- */
-#define CONFIG_BOARD_EARLY_INIT_F
-
-/* flat device tree */
-#define CONFIG_OF_LIBFDT
-/* skip updating the FDT blob */
-#define CONFIG_FDT_BLOB_SKIP_UPDATE
-/* Initial Memory map size for Linux, minus 4k alignment for DFT blob */
-#define CONFIG_SYS_BOOTMAPSZ		((256*1024*1024) - (4*1024))
-
-#define CONFIG_SPL_RAM_DEVICE
-#define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR
-#define CONFIG_SYS_SPL_MALLOC_START ((unsigned long) (&__malloc_start))
-#define CONFIG_SYS_SPL_MALLOC_SIZE (&__malloc_end - &__malloc_start)
-
-/*
- * Memory allocation (MALLOC)
- */
-/* Room required on the stack for the environment data */
-#define CONFIG_ENV_SIZE			1024
-/* Size of DRAM reserved for malloc() use */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 128*1024)
-
-/* SP location before relocation, must use scratch RAM */
-#define CONFIG_SYS_INIT_RAM_ADDR	0xFFFF0000
-/* Reserving 0x100 space at back of scratch RAM for debug info */
-#define CONFIG_SYS_INIT_RAM_SIZE	(0x10000 - 0x100)
-/* Stack pointer prior relocation, must situated at on-chip RAM */
-#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_INIT_RAM_ADDR + \
-					 CONFIG_SYS_INIT_RAM_SIZE - \
-					 GENERATED_GBL_DATA_SIZE)
-
-
-/*
- * Command line configuration.
- */
+/* U-Boot Commands */
 #define CONFIG_SYS_NO_FLASH
 #include <config_cmd_default.h>
-/* FAT file system support */
+#define CONFIG_DOS_PARTITION
+#define CONFIG_FAT_WRITE
+#define CONFIG_HW_WATCHDOG
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_BOOTZ
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_EXT4
+#define CONFIG_CMD_EXT4_WRITE
 #define CONFIG_CMD_FAT
+#define CONFIG_CMD_FPGA
+#define CONFIG_CMD_FS_GENERIC
+#define CONFIG_CMD_GREPENV
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SETEXPR
 
+#define CONFIG_REGEX			/* Enable regular expression support */
 
-/*
- * Misc
- */
-#define CONFIG_DOS_PARTITION            1
+/* Memory configurations */
+#define PHYS_SDRAM_1_SIZE		0x40000000	/* 1GiB on SoCDK */
 
-#ifdef CONFIG_SPL_BUILD
-#undef CONFIG_PARTITIONS
+/* Booting Linux */
+#define CONFIG_BOOTDELAY	3
+#define CONFIG_BOOTFILE		"zImage"
+#define CONFIG_BOOTARGS		"console=ttyS0" __stringify(CONFIG_BAUDRATE)
+#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
+#define CONFIG_BOOTCOMMAND	"run ramboot"
+#else
+#define CONFIG_BOOTCOMMAND	"run mmcload; run mmcboot"
+#endif
+#define CONFIG_LOADADDR		0x8000
+#define CONFIG_SYS_LOAD_ADDR	CONFIG_LOADADDR
+
+/* Ethernet on SoC (EMAC) */
+#if defined(CONFIG_CMD_NET)
+#define CONFIG_EMAC_BASE		SOCFPGA_EMAC0_ADDRESS
+#define CONFIG_PHY_INTERFACE_MODE	PHY_INTERFACE_MODE_RGMII
+#define CONFIG_EPHY0_PHY_ADDR		0
+
+/* PHY */
+#define CONFIG_EPHY1_PHY_ADDR		4
+#define CONFIG_PHY_MICREL
+#define CONFIG_PHY_MICREL_KSZ9021
+#define CONFIG_KSZ9021_CLK_SKEW_ENV	"micrel-ksz9021-clk-skew"
+#define CONFIG_KSZ9021_CLK_SKEW_VAL	0xf0f0
+#define CONFIG_KSZ9021_DATA_SKEW_ENV	"micrel-ksz9021-data-skew"
+#define CONFIG_KSZ9021_DATA_SKEW_VAL	0x0
+
 #endif
 
-/*
- * Environment setup
- */
-
-/* Delay before automatically booting the default image */
-#define CONFIG_BOOTDELAY		3
-/* Enable auto completion of commands using TAB */
-#define CONFIG_AUTO_COMPLETE
-/* use "hush" command parser */
-#define CONFIG_SYS_HUSH_PARSER
-#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
-#define CONFIG_CMD_RUN
-
-#define CONFIG_BOOTCOMMAND "run ramboot"
-
-/*
- * arguments passed to the bootm command. The value of
- * CONFIG_BOOTARGS goes into the environment value "bootargs".
- * Do note the value will overide also the chosen node in FDT blob.
- */
-#define CONFIG_BOOTARGS "console=ttyS0,57600,mem=256M@0x0"
+/* Extra Environment */
+#define CONFIG_HOSTNAME		socfpga_cyclone5
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"verify=n\0" \
 	"loadaddr= " __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
 	"ramboot=setenv bootargs " CONFIG_BOOTARGS ";" \
 		"bootm ${loadaddr} - ${fdt_addr}\0" \
-	"bootimage=uImage\0" \
+	"bootimage=zImage\0" \
 	"fdt_addr=100\0" \
-	"fsloadcmd=ext2load\0" \
-		"bootm ${loadaddr} - ${fdt_addr}\0" \
+	"fdtimage=socfpga.dtb\0" \
+		"fsloadcmd=ext2load\0" \
+	"bootm ${loadaddr} - ${fdt_addr}\0" \
+	"mmcroot=/dev/mmcblk0p2\0" \
+	"mmcboot=setenv bootargs " CONFIG_BOOTARGS \
+		" root=${mmcroot} rw rootwait;" \
+		"bootz ${loadaddr} - ${fdt_addr}\0" \
+	"mmcload=mmc rescan;" \
+		"load mmc 0:1 ${loadaddr} ${bootimage};" \
+		"load mmc 0:1 ${fdt_addr} ${fdtimage}\0" \
 	"qspiroot=/dev/mtdblock0\0" \
 	"qspirootfstype=jffs2\0" \
 	"qspiboot=setenv bootargs " CONFIG_BOOTARGS \
 		" root=${qspiroot} rw rootfstype=${qspirootfstype};"\
 		"bootm ${loadaddr} - ${fdt_addr}\0"
 
-/* using environment setting for stdin, stdout, stderr */
-#define CONFIG_SYS_CONSOLE_IS_IN_ENV
-/* Enable the call to overwrite_console() */
-#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
-/* Enable overwrite of previous console environment settings */
-#define CONFIG_SYS_CONSOLE_ENV_OVERWRITE
+/* The rest of the configuration is shared */
+#include <configs/socfpga_common.h>
 
-/* max number of command args	 */
-#define CONFIG_SYS_MAXARGS		16
-
-
-/*
- * Hardware drivers
- */
-
-/*
- * SDRAM Memory Map
- */
-/* We have 1 bank of DRAM */
-#define CONFIG_NR_DRAM_BANKS		1
-/* SDRAM Bank #1 */
-#define CONFIG_SYS_SDRAM_BASE		0x00000000
-/* SDRAM memory size */
-#define PHYS_SDRAM_1_SIZE		0x40000000
-
-#define PHYS_SDRAM_1			CONFIG_SYS_SDRAM_BASE
-#define CONFIG_SYS_MEMTEST_START	0x00000000
-#define CONFIG_SYS_MEMTEST_END		PHYS_SDRAM_1_SIZE
-
-/*
- * NS16550 Configuration
- */
-#define UART0_BASE			SOCFPGA_UART0_ADDRESS
-#define CONFIG_SYS_NS16550
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE	-4
-#define CONFIG_SYS_NS16550_CLK          V_NS16550_CLK
-#define CONFIG_CONS_INDEX               1
-#define CONFIG_SYS_NS16550_COM1		UART0_BASE
-#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, 115200}
-#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
-#define V_NS16550_CLK			1000000
-#else
-#define V_NS16550_CLK			100000000
-#endif
-#define CONFIG_BAUDRATE			115200
-
-/*
- * FLASH
- */
-#define CONFIG_SYS_NO_FLASH
-
-/*
- * L4 OSC1 Timer 0
- */
-/* This timer use eosc1 where the clock frequency is fixed
- * throughout any condition */
-#define CONFIG_SYS_TIMERBASE		SOCFPGA_OSC1TIMER0_ADDRESS
-/* reload value when timer count to zero */
-#define TIMER_LOAD_VAL			0xFFFFFFFF
-/* Timer info */
-#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
-#define CONFIG_SYS_TIMER_RATE		2400000
-#else
-#define CONFIG_SYS_TIMER_RATE		25000000
-#endif
-#define CONFIG_SYS_TIMER_COUNTS_DOWN
-#define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMERBASE + 0x4)
-
-#define CONFIG_ENV_IS_NOWHERE
-
-/*
- * network support
- */
-#ifndef CONFIG_SOCFPGA_VIRTUAL_TARGET
-#define CONFIG_DESIGNWARE_ETH          1
-#endif
-
-#ifdef CONFIG_DESIGNWARE_ETH
-#define CONFIG_EMAC0_BASE              SOCFPGA_EMAC0_ADDRESS
-#define CONFIG_EMAC1_BASE              SOCFPGA_EMAC1_ADDRESS
-/* console support for network */
-#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_MII
-#define CONFIG_CMD_NET
-#define CONFIG_CMD_PING
-/* designware */
-#define CONFIG_NET_MULTI
-#define CONFIG_DW_ALTDESCRIPTOR
-#define CONFIG_DW_SEARCH_PHY
-#define CONFIG_MII
-#define CONFIG_PHY_GIGE
-#define CONFIG_DW_AUTONEG
-#define CONFIG_AUTONEG_TIMEOUT         (15 * CONFIG_SYS_HZ)
-#define CONFIG_PHYLIB
-#define CONFIG_PHY_MICREL
-#define CONFIG_PHY_MICREL_KSZ9021
-/* EMAC controller and PHY used */
-#define CONFIG_EMAC_BASE               CONFIG_EMAC1_BASE
-#define CONFIG_EPHY_PHY_ADDR           CONFIG_EPHY1_PHY_ADDR
-#define CONFIG_PHY_INTERFACE_MODE      PHY_INTERFACE_MODE_RGMII
-#endif /* CONFIG_DESIGNWARE_ETH */
-
-/*
- * L4 Watchdog
- */
-#define CONFIG_HW_WATCHDOG
-#define CONFIG_HW_WATCHDOG_TIMEOUT_MS	2000
-#define CONFIG_DESIGNWARE_WATCHDOG
-#define CONFIG_DW_WDT_BASE		SOCFPGA_L4WD0_ADDRESS
-/* Clocks source frequency to watchdog timer */
-#define CONFIG_DW_WDT_CLOCK_KHZ		25000
-
-
-/*
- * SPL "Second Program Loader" aka Initial Software
- */
-
-/* Enable building of SPL globally */
-#define CONFIG_SPL_FRAMEWORK
-
-/* TEXT_BASE for linking the SPL binary */
-#define CONFIG_SPL_TEXT_BASE		0xFFFF0000
-
-/* Stack size for SPL */
-#define CONFIG_SPL_STACK_SIZE		(4 * 1024)
-
-/* MALLOC size for SPL */
-#define CONFIG_SPL_MALLOC_SIZE		(5 * 1024)
-
-#define CONFIG_SPL_SERIAL_SUPPORT
-#define CONFIG_SPL_BOARD_INIT
-
-#define CHUNKSZ_CRC32			(1 * 1024)
-
-#define CONFIG_CRC32_VERIFY
-
-/* Linker script for SPL */
-#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/socfpga/u-boot-spl.lds"
-
-/* Support for common/libcommon.o in SPL binary */
-#define CONFIG_SPL_LIBCOMMON_SUPPORT
-/* Support for lib/libgeneric.o in SPL binary */
-#define CONFIG_SPL_LIBGENERIC_SUPPORT
-
-/* Support for watchdog */
-#define CONFIG_SPL_WATCHDOG_SUPPORT
-
-#endif	/* __CONFIG_H */
+#endif	/* __CONFIG_SOCFPGA_CYCLONE5_H__ */
diff --git a/include/dwmmc.h b/include/dwmmc.h
index b67f11b..109f7c8 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -157,7 +157,7 @@
 	u32 cnt;
 	u32 addr;
 	u32 next_addr;
-};
+} __aligned(ARCH_DMA_MINALIGN);
 
 static inline void dwmci_writel(struct dwmci_host *host, int reg, u32 val)
 {
diff --git a/include/image.h b/include/image.h
index 3401056..4347532 100644
--- a/include/image.h
+++ b/include/image.h
@@ -232,6 +232,7 @@
 #define IH_TYPE_MXSIMAGE	16	/* Freescale MXSBoot Image	*/
 #define IH_TYPE_GPIMAGE		17	/* TI Keystone GPHeader Image	*/
 #define IH_TYPE_ATMELIMAGE	18	/* ATMEL ROM bootable Image	*/
+#define IH_TYPE_SOCFPGAIMAGE	19	/* Altera SOCFPGA Preloader	*/
 
 /*
  * Compression Types
diff --git a/include/stdio_dev.h b/include/stdio_dev.h
index 268de8e..24da23f 100644
--- a/include/stdio_dev.h
+++ b/include/stdio_dev.h
@@ -103,8 +103,8 @@
 
 void	stdio_print_current_devices(void);
 #ifdef CONFIG_SYS_STDIO_DEREGISTER
-int	stdio_deregister(const char *devname);
-int stdio_deregister_dev(struct stdio_dev *dev);
+int stdio_deregister(const char *devname, int force);
+int stdio_deregister_dev(struct stdio_dev *dev, int force);
 #endif
 struct list_head* stdio_get_list(void);
 struct stdio_dev* stdio_get_by_name(const char* name);
diff --git a/include/usb.h b/include/usb.h
index d9fedee..c355fbe 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -216,7 +216,7 @@
 #ifdef CONFIG_USB_KEYBOARD
 
 int drv_usb_kbd_init(void);
-int usb_kbd_deregister(void);
+int usb_kbd_deregister(int force);
 
 #endif
 /* routines */
diff --git a/tools/Makefile b/tools/Makefile
index 90e966d..2b05b20 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -87,6 +87,7 @@
 			os_support.o \
 			pblimage.o \
 			pbl_crc32.o \
+			socfpgaimage.o \
 			lib/sha1.o \
 			lib/sha256.o \
 			ublimage.o \
diff --git a/tools/imagetool.c b/tools/imagetool.c
index 32d6278..98717bd 100644
--- a/tools/imagetool.c
+++ b/tools/imagetool.c
@@ -47,6 +47,8 @@
 	init_ubl_image_type();
 	/* Init Davinci AIS support */
 	init_ais_image_type();
+	/* Init Altera SOCFPGA support */
+	init_socfpga_image_type();
 	/* Init TI Keystone boot image generation/list support */
 	init_gpimage_type();
 }
diff --git a/tools/imagetool.h b/tools/imagetool.h
index c8af0e8..8bce059 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -168,6 +168,7 @@
 void init_fit_image_type(void);
 void init_ubl_image_type(void);
 void init_omap_image_type(void);
+void init_socfpga_image_type(void);
 void init_gpimage_type(void);
 
 void pbl_load_uboot(int fd, struct image_tool_params *mparams);
diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c
new file mode 100644
index 0000000..396d8a5
--- /dev/null
+++ b/tools/socfpgaimage.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2014 Charles Manning <cdhmanning@gmail.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Reference doc http://www.altera.com.cn/literature/hb/cyclone-v/cv_5400A.pdf
+ * Note this doc is not entirely accurate. Of particular interest to us is the
+ * "header" length field being in U32s and not bytes.
+ *
+ * "Header" is a structure of the following format.
+ * this is positioned at 0x40.
+ *
+ * Endian is LSB.
+ *
+ * Offset   Length   Usage
+ * -----------------------
+ *   0x40        4   Validation word 0x31305341
+ *   0x44        1   Version (whatever, zero is fine)
+ *   0x45        1   Flags   (unused, zero is fine)
+ *   0x46        2   Length  (in units of u32, including the end checksum).
+ *   0x48        2   Zero
+ *   0x4A        2   Checksum over the header. NB Not CRC32
+ *
+ * At the end of the code we have a 32-bit CRC checksum over whole binary
+ * excluding the CRC.
+ *
+ * Note that the CRC used here is **not** the zlib/Adler crc32. It is the
+ * CRC-32 used in bzip2, ethernet and elsewhere.
+ *
+ * The image is padded out to 64k, because that is what is
+ * typically used to write the image to the boot medium.
+ */
+
+#include "pbl_crc32.h"
+#include "imagetool.h"
+#include <image.h>
+
+#define HEADER_OFFSET	0x40
+#define VALIDATION_WORD	0x31305341
+#define PADDED_SIZE	0x10000
+
+/* To allow for adding CRC, the max input size is a bit smaller. */
+#define MAX_INPUT_SIZE	(PADDED_SIZE - sizeof(uint32_t))
+
+static uint8_t buffer[PADDED_SIZE];
+
+static struct socfpga_header {
+	uint32_t validation;
+	uint8_t  version;
+	uint8_t  flags;
+	uint16_t length_u32;
+	uint16_t zero;
+	uint16_t checksum;
+} header;
+
+/*
+ * The header checksum is just a very simple checksum over
+ * the header area.
+ * There is still a crc32 over the whole lot.
+ */
+static uint16_t hdr_checksum(struct socfpga_header *header)
+{
+	int len = sizeof(*header) - sizeof(header->checksum);
+	uint8_t *buf = (uint8_t *)header;
+	uint16_t ret = 0;
+
+	while (--len)
+		ret += *buf++;
+
+	return ret;
+}
+
+
+static void build_header(uint8_t *buf, uint8_t version, uint8_t flags,
+			 uint16_t length_bytes)
+{
+	header.validation = htole32(VALIDATION_WORD);
+	header.version = version;
+	header.flags = flags;
+	header.length_u32 = htole16(length_bytes/4);
+	header.zero = 0;
+	header.checksum = htole16(hdr_checksum(&header));
+
+	memcpy(buf, &header, sizeof(header));
+}
+
+/*
+ * Perform a rudimentary verification of header and return
+ * size of image.
+ */
+static int verify_header(const uint8_t *buf)
+{
+	memcpy(&header, buf, sizeof(header));
+
+	if (le32toh(header.validation) != VALIDATION_WORD)
+		return -1;
+	if (le16toh(header.checksum) != hdr_checksum(&header))
+		return -1;
+
+	return le16toh(header.length_u32) * 4;
+}
+
+/* Sign the buffer and return the signed buffer size */
+static int sign_buffer(uint8_t *buf,
+			uint8_t version, uint8_t flags,
+			int len, int pad_64k)
+{
+	uint32_t calc_crc;
+
+	/* Align the length up */
+	len = (len + 3) & (~3);
+
+	/* Build header, adding 4 bytes to length to hold the CRC32. */
+	build_header(buf + HEADER_OFFSET,  version, flags, len + 4);
+
+	/* Calculate and apply the CRC */
+	calc_crc = ~pbl_crc32(0, (char *)buf, len);
+
+	*((uint32_t *)(buf + len)) = htole32(calc_crc);
+
+	if (!pad_64k)
+		return len + 4;
+
+	return PADDED_SIZE;
+}
+
+/* Verify that the buffer looks sane */
+static int verify_buffer(const uint8_t *buf)
+{
+	int len; /* Including 32bit CRC */
+	uint32_t calc_crc;
+	uint32_t buf_crc;
+
+	len = verify_header(buf + HEADER_OFFSET);
+	if (len < 0) {
+		fprintf(stderr, "Invalid header\n");
+		return -1;
+	}
+
+	if (len < HEADER_OFFSET || len > PADDED_SIZE) {
+		fprintf(stderr, "Invalid header length (%i)\n", len);
+		return -1;
+	}
+
+	/*
+	 * Adjust length to the base of the CRC.
+	 * Check the CRC.
+	*/
+	len -= 4;
+
+	calc_crc = ~pbl_crc32(0, (const char *)buf, len);
+
+	buf_crc = le32toh(*((uint32_t *)(buf + len)));
+
+	if (buf_crc != calc_crc) {
+		fprintf(stderr, "CRC32 does not match (%08x != %08x)\n",
+			buf_crc, calc_crc);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* mkimage glue functions */
+static int socfpgaimage_verify_header(unsigned char *ptr, int image_size,
+			struct image_tool_params *params)
+{
+	if (image_size != PADDED_SIZE)
+		return -1;
+
+	return verify_buffer(ptr);
+}
+
+static void socfpgaimage_print_header(const void *ptr)
+{
+	if (verify_buffer(ptr) == 0)
+		printf("Looks like a sane SOCFPGA preloader\n");
+	else
+		printf("Not a sane SOCFPGA preloader\n");
+}
+
+static int socfpgaimage_check_params(struct image_tool_params *params)
+{
+	/* Not sure if we should be accepting fflags */
+	return	(params->dflag && (params->fflag || params->lflag)) ||
+		(params->fflag && (params->dflag || params->lflag)) ||
+		(params->lflag && (params->dflag || params->fflag));
+}
+
+static int socfpgaimage_check_image_types(uint8_t type)
+{
+	if (type == IH_TYPE_SOCFPGAIMAGE)
+		return EXIT_SUCCESS;
+	return EXIT_FAILURE;
+}
+
+/*
+ * To work in with the mkimage framework, we do some ugly stuff...
+ *
+ * First, socfpgaimage_vrec_header() is called.
+ * We prepend a fake header big enough to make the file PADDED_SIZE.
+ * This gives us enough space to do what we want later.
+ *
+ * Next, socfpgaimage_set_header() is called.
+ * We fix up the buffer by moving the image to the start of the buffer.
+ * We now have some room to do what we need (add CRC and padding).
+ */
+
+static int data_size;
+#define FAKE_HEADER_SIZE (PADDED_SIZE - data_size)
+
+static int socfpgaimage_vrec_header(struct image_tool_params *params,
+				struct image_type_params *tparams)
+{
+	struct stat sbuf;
+
+	if (params->datafile &&
+	    stat(params->datafile, &sbuf) == 0 &&
+	    sbuf.st_size <= MAX_INPUT_SIZE) {
+		data_size = sbuf.st_size;
+		tparams->header_size = FAKE_HEADER_SIZE;
+	}
+	return 0;
+}
+
+static void socfpgaimage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct image_tool_params *params)
+{
+	uint8_t *buf = (uint8_t *)ptr;
+
+	/*
+	 * This function is called after vrec_header() has been called.
+	 * At this stage we have the FAKE_HEADER_SIZE dummy bytes followed by
+	 * data_size image bytes. Total = PADDED_SIZE.
+	 * We need to fix the buffer by moving the image bytes back to
+	 * the beginning of the buffer, then actually do the signing stuff...
+	 */
+	memmove(buf, buf + FAKE_HEADER_SIZE, data_size);
+	memset(buf + data_size, 0, FAKE_HEADER_SIZE);
+
+	sign_buffer(buf, 0, 0, data_size, 0);
+}
+
+static struct image_type_params socfpgaimage_params = {
+	.name		= "Altera SOCFPGA preloader support",
+	.vrec_header	= socfpgaimage_vrec_header,
+	.header_size	= 0, /* This will be modified by vrec_header() */
+	.hdr		= (void *)buffer,
+	.check_image_type = socfpgaimage_check_image_types,
+	.verify_header	= socfpgaimage_verify_header,
+	.print_header	= socfpgaimage_print_header,
+	.set_header	= socfpgaimage_set_header,
+	.check_params	= socfpgaimage_check_params,
+};
+
+void init_socfpga_image_type(void)
+{
+	register_image_type(&socfpgaimage_params);
+}