[U-Boot] [RFCv2] mainline u-boot on socfpga

Pavel Machek pavel at denx.de
Mon Sep 8 14:08:45 CEST 2014


Hi!

I know coding style leaves something to be desired.
 
But.. it recognizes MMC/ethernet, and can load linux kernel.

Unfortunately, 1MB of memory at 0 is not available for some reason;
but linux works ok if you avoid that area.

"fpga load 0" now seems to work.

For some reason, I had to rewrite fpgamgr_axi_write(). There's some
bug in assembly version, causing code to get confused after it is
executed.

If some ARM expert could take a look, that would be great; bug is
likely also present in rocketboards version of u-boot.

Best regards,
									Pavel

diff --git a/arch/arm/cpu/armv7/socfpga/Makefile b/arch/arm/cpu/armv7/socfpga/Makefile
index eb33f2c..c36e0d0 100644
--- a/arch/arm/cpu/armv7/socfpga/Makefile
+++ b/arch/arm/cpu/armv7/socfpga/Makefile
@@ -10,3 +10,4 @@
 obj-y	:= lowlevel_init.o
 obj-y	+= misc.o timer.o reset_manager.o system_manager.o clock_manager.o
 obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o scan_manager.o
+obj-y	+= fpga_manager.o
diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c
index 158501a..fae5724 100644
--- a/arch/arm/cpu/armv7/socfpga/clock_manager.c
+++ b/arch/arm/cpu/armv7/socfpga/clock_manager.c
@@ -30,6 +30,10 @@ static const struct socfpga_clock_manager *clock_manager_base =
 	CLKMGR_MAINPLLGRP_VCO_EN_SET(1)| \
 	CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(0))
 
+unsigned long cm_l4_sp_clock;
+unsigned long cm_sdmmc_clock;
+unsigned long cm_qspi_clock;
+
 static inline void cm_wait_for_lock(uint32_t mask)
 {
 	register uint32_t inter_val;
@@ -358,3 +362,219 @@ void cm_basic_init(const cm_config_t *cfg)
 	writel(~0, &clock_manager_base->per_pll.en);
 	writel(~0, &clock_manager_base->sdr_pll.en);
 }
+
+#define CLKMGR_CTRL_ADDRESS 0x0
+#define CLKMGR_BYPASS_ADDRESS 0x4
+#define CLKMGR_INTER_ADDRESS 0x8
+#define CLKMGR_INTREN_ADDRESS 0xc
+#define CLKMGR_DBCTRL_ADDRESS 0x10
+#define CLKMGR_STAT_ADDRESS 0x14
+#define CLKMGR_MAINPLLGRP_ADDRESS 0x40
+#define CLKMGR_MAINPLLGRP_VCO_ADDRESS 0x40
+#define CLKMGR_MAINPLLGRP_MISC_ADDRESS 0x44
+#define CLKMGR_MAINPLLGRP_MPUCLK_ADDRESS 0x48
+#define CLKMGR_MAINPLLGRP_MAINCLK_ADDRESS 0x4c
+#define CLKMGR_MAINPLLGRP_DBGATCLK_ADDRESS 0x50
+#define CLKMGR_MAINPLLGRP_MAINQSPICLK_ADDRESS 0x54
+#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_ADDRESS 0x58
+#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_ADDRESS 0x5c
+#define CLKMGR_MAINPLLGRP_EN_ADDRESS 0x60
+#define CLKMGR_MAINPLLGRP_MAINDIV_ADDRESS 0x64
+#define CLKMGR_MAINPLLGRP_DBGDIV_ADDRESS 0x68
+#define CLKMGR_MAINPLLGRP_TRACEDIV_ADDRESS 0x6c
+#define CLKMGR_MAINPLLGRP_L4SRC_ADDRESS 0x70
+#define CLKMGR_PERPLLGRP_ADDRESS 0x80
+#define CLKMGR_PERPLLGRP_VCO_ADDRESS 0x80
+#define CLKMGR_PERPLLGRP_MISC_ADDRESS 0x84
+#define CLKMGR_PERPLLGRP_EMAC0CLK_ADDRESS 0x88
+#define CLKMGR_PERPLLGRP_EMAC1CLK_ADDRESS 0x8c
+#define CLKMGR_PERPLLGRP_PERQSPICLK_ADDRESS 0x90
+#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_ADDRESS 0x94
+#define CLKMGR_PERPLLGRP_PERBASECLK_ADDRESS 0x98
+#define CLKMGR_PERPLLGRP_S2FUSER1CLK_ADDRESS 0x9c
+#define CLKMGR_PERPLLGRP_EN_ADDRESS 0xa0
+#define CLKMGR_PERPLLGRP_DIV_ADDRESS 0xa4
+#define CLKMGR_PERPLLGRP_GPIODIV_ADDRESS 0xa8
+#define CLKMGR_PERPLLGRP_SRC_ADDRESS 0xac
+#define CLKMGR_SDRPLLGRP_ADDRESS 0xc0
+#define CLKMGR_SDRPLLGRP_VCO_ADDRESS 0xc0
+#define CLKMGR_SDRPLLGRP_CTRL_ADDRESS 0xc4
+#define CLKMGR_SDRPLLGRP_DDRDQSCLK_ADDRESS 0xc8
+#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_ADDRESS 0xcc
+#define CLKMGR_SDRPLLGRP_DDRDQCLK_ADDRESS 0xd0
+#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_ADDRESS 0xd4
+#define CLKMGR_SDRPLLGRP_EN_ADDRESS 0xd8
+#define CLKMGR_ALTERAGRP_MPUCLK 0xe0
+#define CLKMGR_ALTERAGRP_MAINCLK 0xe4
+
+#define CLKMGR_MAINPLLGRP_VCO_DENOM_GET(x)     (((x) & 0x003f0000) >> 16)
+#define CLKMGR_MAINPLLGRP_VCO_NUMER_GET(x)     (((x) & 0x0000fff8) >> 3)
+#define CLKMGR_MAINPLLGRP_L4SRC_L4SP_GET(x)    (((x) & 0x00000002) >> 1)
+#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_GET(x)  (((x) & 0x00000380) >> 7)
+#define CLKMGR_SDRPLLGRP_VCO_SSRC_GET(x)       (((x) & 0x00c00000) >> 22)
+#define CLKMGR_SDRPLLGRP_VCO_DENOM_GET(x)      (((x) & 0x003f0000) >> 16)
+#define CLKMGR_SDRPLLGRP_VCO_NUMER_GET(x)      (((x) & 0x0000fff8) >> 3)
+#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_GET(x)  (((x) & 0x000001ff) >> 0)
+#define CLKMGR_PERPLLGRP_VCO_SSRC_GET(x)       (((x) & 0x00c00000) >> 22)
+#define CLKMGR_PERPLLGRP_VCO_DENOM_GET(x)      (((x) & 0x003f0000) >> 16)
+#define CLKMGR_PERPLLGRP_VCO_NUMER_GET(x)      (((x) & 0x0000fff8) >> 3)
+#define CLKMGR_PERPLLGRP_SRC_QSPI_GET(x)       (((x) & 0x00000030) >> 4)
+#define CLKMGR_PERPLLGRP_SRC_SDMMC_GET(x)      (((x) & 0x00000003) >> 0)
+
+#define CLKMGR_VCO_SSRC_EOSC1          0x0
+#define CLKMGR_VCO_SSRC_EOSC2          0x1
+#define CLKMGR_VCO_SSRC_F2S            0x2
+#define CLKMGR_L4_SP_CLK_SRC_MAINPLL   0x0
+#define CLKMGR_L4_SP_CLK_SRC_PERPLL    0x1
+#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
+
+#define CLKMGR_L4_SP_CLK_SRC_MAINPLL   0x0
+#define CLKMGR_L4_SP_CLK_SRC_PERPLL    0x1
+#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
+
+#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)
+
+unsigned long cm_get_l4_sp_clk_hz(void)
+{
+       uint32_t reg, clock = 0;
+
+       /* identify the source of L4 SP clock */
+       reg = readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_L4SRC_ADDRESS);
+       reg = CLKMGR_MAINPLLGRP_L4SRC_L4SP_GET(reg);
+
+       if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) {
+               /* get the main VCO clock */
+               reg = readl(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_MAINPLLGRP_VCO_ADDRESS);
+               clock = CONFIG_HPS_CLK_OSC1_HZ /
+                       (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1);
+               clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1);
+
+               /* get the clock prior L4 SP divider (main clk) */
+               reg = readl(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_ALTERAGRP_MAINCLK);
+               clock /= (reg + 1);
+               reg = readl(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_MAINPLLGRP_MAINCLK_ADDRESS);
+               clock /= (reg + 1);
+       } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) {
+               /* identify PER PLL clock source */
+               reg = readl(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_PERPLLGRP_VCO_ADDRESS);
+               reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg);
+               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(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_PERPLLGRP_VCO_ADDRESS);
+               clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1);
+               clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1);
+
+               /* get the clock prior L4 SP divider (periph_base_clk) */
+               reg = readl(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_PERPLLGRP_PERBASECLK_ADDRESS);
+               clock /= (reg + 1);
+       }
+
+       /* get the L4 SP clock which supplied to UART */
+       reg = readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLLGRP_MAINDIV_ADDRESS);
+       reg = CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_GET(reg);
+       clock = clock / (reg + 1);
+
+       return clock;
+}
+
+void cm_print_clock_quick_summary(void)
+{
+       printf("CLOCK: EOSC1 clock %d KHz\n",
+		                        (CONFIG_HPS_CLK_OSC1_HZ / 1000));
+       printf("CLOCK: EOSC2 clock %d KHz\n",
+		                        (CONFIG_HPS_CLK_OSC2_HZ / 1000));
+       printf("CLOCK: F2S_SDR_REF clock %d KHz\n",
+		                        (CONFIG_HPS_CLK_F2S_SDR_REF_HZ / 1000));
+       printf("CLOCK: F2S_PER_REF clock %d KHz\n",
+		                        (CONFIG_HPS_CLK_F2S_PER_REF_HZ / 1000));
+         printf("CLOCK: UART clock %ld KHz\n",
+		                        (cm_get_l4_sp_clk_hz() / 1000));
+  
+}
+
+unsigned long cm_get_mmc_controller_clk_hz(void)
+{
+       uint32_t reg, clock = 0;
+
+       /* identify the source of MMC clock */
+       reg = readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_PERPLLGRP_SRC_ADDRESS);
+       reg = CLKMGR_PERPLLGRP_SRC_SDMMC_GET(reg);
+
+       if (reg == CLKMGR_SDMMC_CLK_SRC_F2S)
+               clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ;
+       else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) {
+               /* get the main VCO clock */
+               reg = readl(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_MAINPLLGRP_VCO_ADDRESS);
+               clock = CONFIG_HPS_CLK_OSC1_HZ /
+                       (CLKMGR_MAINPLLGRP_VCO_DENOM_GET(reg) + 1);
+               clock *= (CLKMGR_MAINPLLGRP_VCO_NUMER_GET(reg) + 1);
+
+               /* get the SDMMC clock */
+               reg = readl(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_ADDRESS);
+               clock /= (reg + 1);
+       } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) {
+               /* identify PER PLL clock source */
+               reg = readl(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_PERPLLGRP_VCO_ADDRESS);
+               reg = CLKMGR_PERPLLGRP_VCO_SSRC_GET(reg);
+               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(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_PERPLLGRP_VCO_ADDRESS);
+               clock /= (CLKMGR_PERPLLGRP_VCO_DENOM_GET(reg) + 1);
+               clock *= (CLKMGR_PERPLLGRP_VCO_NUMER_GET(reg) + 1);
+
+               /* get the SDMMC clock */
+               reg = readl(SOCFPGA_CLKMGR_ADDRESS +
+                       CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_ADDRESS);
+               clock /= (reg + 1);
+       }
+
+       /* further divide by 4 as we have fixed divider at wrapper */
+       clock /= 4;
+       return clock;
+}
+
+void cm_derive_clocks_for_drivers(void)
+{
+       cm_l4_sp_clock = cm_get_l4_sp_clk_hz();
+       cm_sdmmc_clock = cm_get_mmc_controller_clk_hz();
+
+       cm_print_clock_quick_summary();
+       printf("sdmmc_clock: %d\n", cm_sdmmc_clock);
+#if 0
+       cm_qspi_clock = cm_get_qspi_controller_clk_hz();
+#endif
+}
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..19e4eea
--- /dev/null
+++ b/arch/arm/cpu/armv7/socfpga/fpga_manager.c
@@ -0,0 +1,378 @@
+/*
+ *
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of the Altera Corporation nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/fpga_manager.h>
+#include <asm/arch/reset_manager.h>
+#include <asm/arch/system_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct socfpga_fpga_manager *fpga_manager_base =
+		(void *)SOCFPGA_FPGAMGRREGS_ADDRESS;
+
+#define DEBUG_MEMORY printf("%s\n", __func__ );
+#define SDR_CTRLGRP_FPGAPORTRST_ADDRESS 0x5080
+
+/* Check whether FPGA Init_Done signal is high */
+static int is_fpgamgr_initdone_high(void)
+{
+	unsigned long val;
+	DEBUG_MEMORY
+	val = readl(SOCFPGA_FPGAMGRREGS_ADDRESS +
+		FPGAMGRREGS_MON_GPIO_EXT_PORTA_ADDRESS);
+	if (val & FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK)
+		return 1;
+	else
+		return 0;
+}
+
+/* Get the FPGA mode */
+static int fpgamgr_get_mode(void)
+{
+	unsigned long val;
+	//DEBUG_MEMORY
+	printf("get_mode ");
+	val = readl(&fpga_manager_base->stat);
+	val = val & FPGAMGRREGS_STAT_MODE_MASK;
+	return val;
+}
+
+/* Check whether FPGA is ready to be accessed */
+int is_fpgamgr_fpga_ready(void)
+{
+	/* check for init done signal */
+	if (is_fpgamgr_initdone_high() == 0)
+		return 0;
+	/* check again to avoid false glitches */
+	if (is_fpgamgr_initdone_high() == 0)
+		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 poll_fpgamgr_fpga_ready(void)
+{
+	unsigned long i;
+	DEBUG_MEMORY
+	/* 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() == 0)
+			continue;
+		/* check again to avoid false glitches */
+		if (is_fpgamgr_initdone_high() == 0)
+			continue;
+		return 1;
+	}
+	DEBUG_MEMORY
+	return 0;
+}
+
+/* set CD ratio */
+static void fpgamgr_set_cd_ratio(unsigned long ratio)
+{
+	unsigned long reg;
+	reg = readl(&fpga_manager_base->ctrl);
+	reg = (reg & ~(0x3 << FPGAMGRREGS_CTRL_CDRATIO_LSB)) |
+		((ratio & 0x3) << FPGAMGRREGS_CTRL_CDRATIO_LSB);
+	writel(reg, &fpga_manager_base->ctrl);
+}
+
+static int fpgamgr_dclkcnt_set(unsigned long cnt)
+{
+	unsigned long i;
+
+	/* clear any existing done status */
+	if (readl(&fpga_manager_base->dclkstat))
+		writel(0x1, &fpga_manager_base->dclkstat);
+	/* write the dclkcnt */
+	writel(cnt, &fpga_manager_base->dclkcnt);
+	/*
+	 * wait till the dclkcnt done
+	 */
+	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+		if (readl(&fpga_manager_base->dclkstat)) {
+			writel(0x1, &fpga_manager_base->dclkstat);
+			return 0;
+		}
+	}
+	return -1;
+}
+
+/* Start the FPGA programming by initialize the FPGA Manager */
+int fpgamgr_program_init(void)
+{
+	unsigned long reg, i;
+
+	debug("fpga: program_init\n");
+	/* get the MSEL value */
+	reg = readl(&fpga_manager_base->stat);
+	reg = ((reg & FPGAMGRREGS_STAT_MSEL_MASK) >> FPGAMGRREGS_STAT_MSEL_LSB);
+
+	/*
+	 * Set the cfg width
+	 * If MSEL[3] = 1, cfg width = 32 bit
+	 */
+	if (reg & 0x8)
+		setbits_le32(&fpga_manager_base->ctrl,
+			FPGAMGRREGS_CTRL_CFGWDTH_MASK);
+	else
+		clrbits_le32(&fpga_manager_base->ctrl,
+			FPGAMGRREGS_CTRL_CFGWDTH_MASK);
+
+	/* To determine the CD ratio */
+	/* MSEL[3] = 1 & MSEL[1:0] = 0, CD Ratio = 1 */
+	if ((reg & 0xb) == 0x8)
+		fpgamgr_set_cd_ratio(CDRATIO_x1);
+	/* MSEL[3] = 1 & MSEL[1:0] = 1, CD Ratio = 4 */
+	else if ((reg & 0xb) == 0x9)
+		fpgamgr_set_cd_ratio(CDRATIO_x4);
+	/* MSEL[3] = 1 & MSEL[1:0] = 2, CD Ratio = 8 */
+	else if ((reg & 0xb) == 0xa)
+		fpgamgr_set_cd_ratio(CDRATIO_x8);
+	/* MSEL[3] = 0 & MSEL[1:0] = 0, CD Ratio = 1 */
+	else if ((reg & 0xb) == 0x0)
+		fpgamgr_set_cd_ratio(CDRATIO_x1);
+	/* MSEL[3] = 0 & MSEL[1:0] = 1, CD Ratio = 2 */
+	else if ((reg & 0xb) == 0x1)
+		fpgamgr_set_cd_ratio(CDRATIO_x2);
+	/* MSEL[3] = 0 & MSEL[1:0] = 2, CD Ratio = 4 */
+	else if ((reg & 0xb) == 0x2)
+		fpgamgr_set_cd_ratio(CDRATIO_x4);
+
+	debug("fpga: enable config\n");
+
+	/* to enable FPGA Manager configuration */
+	clrbits_le32(&fpga_manager_base->ctrl, FPGAMGRREGS_CTRL_NCE_MASK);
+
+	/* to enable FPGA Manager drive over configuration line */
+	setbits_le32(&fpga_manager_base->ctrl, FPGAMGRREGS_CTRL_EN_MASK);
+
+	/* put FPGA into reset phase */
+	setbits_le32(&fpga_manager_base->ctrl,
+		FPGAMGRREGS_CTRL_NCONFIGPULL_MASK);
+
+	debug("fpga: wait for reset\n");
+
+	/* (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) {
+		printf("fpga: could not reset\n");
+		return -1;
+	}
+
+	/* release FPGA from reset phase */
+	clrbits_le32(&fpga_manager_base->ctrl,
+		FPGAMGRREGS_CTRL_NCONFIGPULL_MASK);
+
+	debug("fpga: wait for config\n");
+
+	/* (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)
+		return -2;
+
+	/* clear all interrupts in CB Monitor */
+	writel(0xFFF, (SOCFPGA_FPGAMGRREGS_ADDRESS +
+		FPGAMGRREGS_MON_GPIO_PORTA_EOI_ADDRESS));
+
+	/* enable AXI configuration */
+	setbits_le32(&fpga_manager_base->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK);
+
+	debug("fpga: prepare done\n");
+
+	return 0;
+}
+
+/* Write the RBF data to FPGA Manager */
+void fpgamgr_program_write(const unsigned long *rbf_data,
+	unsigned long rbf_size)
+{
+  printf("copying from %lx to %lx, %d bytes\n", rbf_data, SOCFPGA_FPGAMGRDATA_ADDRESS, rbf_size);
+
+  printf("_axi_write\n");
+  //	fpgamgr_axi_write(rbf_data, SOCFPGA_FPGAMGRDATA_ADDRESS, rbf_size);
+  {
+    long i;
+    for (i=0; i<(rbf_size/4); i++) {
+      volatile long *data = SOCFPGA_FPGAMGRDATA_ADDRESS;
+      *data = rbf_data[i];
+    }
+  }
+
+  printf("_axi_done\n");
+
+	 printf("copying done.\n");
+}
+
+/* Ensure the FPGA entering config done */
+int fpgamgr_program_poll_cd(void)
+{
+	unsigned long reg, i;
+
+	printf("poll_cd, %d\n", FPGA_TIMEOUT_CNT);
+	/* (3) wait until full config done */
+	for (i = 0; i < FPGA_TIMEOUT_CNT; i++) {
+		if (!(i % 1000))
+			printf("reading %d/%d.\n", i, FPGA_TIMEOUT_CNT);
+		reg = readl(SOCFPGA_FPGAMGRREGS_ADDRESS +
+			FPGAMGRREGS_MON_GPIO_EXT_PORTA_ADDRESS);
+		/* config error */
+		if (!(reg & FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK) &&
+			!(reg & FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK))
+			return -3;
+		/* config done without error */
+		if ((reg & FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK) &&
+			(reg & FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK))
+			break;
+	}
+
+	/* tiemout happen, return error */
+	if (i == FPGA_TIMEOUT_CNT) {
+		printf("fpga: timeout waiting for program.\n");
+		return -4;
+	}
+
+	/* disable AXI configuration */
+	clrbits_le32(&fpga_manager_base->ctrl, FPGAMGRREGS_CTRL_AXICFGEN_MASK);
+	return 0;
+}
+
+/* Ensure the FPGA entering init phase */
+int fpgamgr_program_poll_initphase(void)
+{
+	unsigned long i;
+
+	/* additional clocks for the CB to enter initialization phase */
+	if (fpgamgr_dclkcnt_set(0x4) != 0)
+		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 */
+int fpgamgr_program_poll_usermode(void)
+{
+	unsigned long i;
+
+	/* additional clocks for the CB to exit initialization phase */
+	if (fpgamgr_dclkcnt_set(0x5000) != 0)
+		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(&fpga_manager_base->ctrl, FPGAMGRREGS_CTRL_EN_MASK);
+
+	return 0;
+}
+
+/*
+ * Using FPGA Manager to program the FPGA
+ * Return 0 for sucess
+ */
+int fpgamgr_program_fpga(const unsigned long *rbf_data,
+	unsigned long rbf_size)
+{
+	unsigned long status;
+
+	printf("program: 1\n");
+	/* prior programming the FPGA, all bridges need to be shut off */
+
+	/* disable all signals from hps peripheral controller to fpga */
+	writel(0, SYSMGR_FPGAINTF_MODULE);
+
+	printf("program: 1a\n");
+	/* disable all signals from fpga to hps sdram */
+	writel(0, (SOCFPGA_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS));
+
+	printf("program: 2\n");
+	/* disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */
+	reset_assert_all_bridges();
+	/* unmap the bridges from NIC-301 */
+	writel(0x1, SOCFPGA_L3REGS_ADDRESS);
+
+	printf("program: 3\n");
+	/* initialize the FPGA Manager */
+	status = fpgamgr_program_init();
+	if (status)
+		return status;
+
+	printf("program: 4\n");
+	/* Write the RBF data to FPGA Manager */
+	fpgamgr_program_write(rbf_data, rbf_size);
+
+	printf("...here!\n");
+
+	printf("program: 5\n");
+	/* Ensure the FPGA entering config done */
+	status = fpgamgr_program_poll_cd();
+	if (status)
+		return status;
+
+	printf("program: 6\n");
+
+	/* Ensure the FPGA entering init phase */
+	status = fpgamgr_program_poll_initphase();
+	if (status)
+		return status;
+
+	printf("program: 7\n");
+	/* Ensure the FPGA entering user mode */
+	return fpgamgr_program_poll_usermode();
+}
diff --git a/arch/arm/cpu/armv7/socfpga/lowlevel_init.S b/arch/arm/cpu/armv7/socfpga/lowlevel_init.S
index 2f2e9fc..4b5865a 100644
--- a/arch/arm/cpu/armv7/socfpga/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/socfpga/lowlevel_init.S
@@ -6,6 +6,7 @@
 
 #include <config.h>
 #include <version.h>
+#include <asm/system.h>
 
 /* Save the parameter pass in by previous boot loader */
 .global save_boot_params
@@ -51,3 +52,112 @@ lowlevel_init:
 	str	r2, [r1]
 #endif	/* #ifdef CONFIG_SPL_BUILD */
 	mov	pc, lr
+
+/*
+ * Write RBF data in burst form to FPGA Manager
+ * [r0] RBF binary source address
+ * [r1] FPGA Manager data address
+ * [r2] RBF data length
+ */
+	
+
+//ENTRY(fpgamgr_axi_write)
+.globl fpgamgr_axi_write
+fpgamgr_axi_write:	
+       PUSH    {r4-r11, lr}            /* save registers per AAPCS */
+
+write_burst:
+       cmp     r2,#32
+       beq     write_burst_cont
+       bls     write_word
+write_burst_cont:
+       ldmia   r0!, {r4-r11}
+       stmia   r1, {r4-r11}
+       subs    r2, r2, #32
+       b       write_burst
+
+write_word:
+       cmp     r2,#4
+       beq     write_word_cont
+       bls     write_byte
+write_word_cont:
+       ldmia   r0!, {r4}
+       stmia   r1, {r4}
+       subs    r2, r2, #4
+       b       write_word
+
+	/* FIXME: this is wrong, right? It will copy just one byte when copy of 3
+	is requested */
+write_byte:
+       cmp     r2,#0
+       beq     write_end
+       ldr     r3, [r0]
+       str     r3, [r1]
+write_end:
+       POP     {r4-r11, pc}
+//ENDPROC(fpgamgr_axi_write)
+
+#define SDR_CTRLGRP_STATICCFG_ADDRESS 0x505c
+#define SDR_CTRLGRP_STATICCFG_APPLYCFG_MASK 0x00000008
+
+/*
+ * Configure the fpga2sdram register
+ * For U-Boot only and this code need to run on OCRAM
+ * No stack activity or function call to avoid access to SDRAM
+ *
+ * Note that sdram_applycfg_uboot copies fixed ammount of memory;
+ * be careful if you make this function longer.
+ */
+
+.global sdram_applycfg_ocram
+sdram_applycfg_ocram:
+       mrc     p15, 0, r0, c1, c0, 0   @ Read CP15 SCTRL Register
+       bic     r0, #CR_Z               @ Disable branch predictor
+       bic     r0, #CR_I               @ Disable i-cache
+       mcr     p15, 0, r0, c1, c0, 0   @ Write CP15 SCTRL Register
+       dsb
+       isb
+
+       ldr     r1, SDR_CTRL
+       ldr     r2, SDR_STATICCFG
+       add     r1, r1, r2
+       ldr     r0, [r1]
+       ldr     r3, SDR_APPLYCFG_MASK
+       orr     r0, r0, r3
+       str     r0, [r1]
+       dsb
+       isb
+
+       mrc     p15, 0, r4, c1, c0, 0   @ Read CP15 SCTRL Register
+       orr     r4, r4, #CR_Z           @ Enable back branch predictor
+       orr     r4, r4, #CR_I           @ Enable back i-cache
+       mcr     p15, 0, r4, c1, c0, 0   @ Write CP15 SCTRL Register
+
+       mov     r0, #0
+       mov     pc, lr
+	
+SDR_CTRL:              .word   SOCFPGA_SDR_ADDRESS
+SDR_STATICCFG:         .word   SDR_CTRLGRP_STATICCFG_ADDRESS
+SDR_APPLYCFG_MASK:     .word   SDR_CTRLGRP_STATICCFG_APPLYCFG_MASK
+
+/*
+ * Relocate the sdram_applycfg_ocram function to OCRAM and call it
+ */
+.globl sdram_applycfg_uboot
+sdram_applycfg_uboot:	
+       PUSH    {r4-r11, lr}            /* save registers per AAPCS */
+
+       ldr     r1, =sdram_applycfg_ocram
+       ldr     r2, =CONFIG_SYS_INIT_RAM_ADDR
+       mov     r3, r2
+       ldmia   r1!, {r4 - r11}
+       stmia   r3!, {r4 - r11}
+       ldmia   r1!, {r4 - r11}         /* copy more in case code added */
+       stmia   r3!, {r4 - r11}         /* in the future */
+       ldmia   r1!, {r4 - r11}         /* copy more in case code added */
+       stmia   r3!, {r4 - r11}         /* in the future */
+       dsb
+       isb
+       blx     r2                      /* jump to OCRAM */
+       POP     {r4-r11, pc}
+
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c
index ecae393..5842734 100644
--- a/arch/arm/cpu/armv7/socfpga/misc.c
+++ b/arch/arm/cpu/armv7/socfpga/misc.c
@@ -8,6 +8,10 @@
 #include <asm/io.h>
 #include <miiphy.h>
 #include <netdev.h>
+#include <altera.h>
+#include <asm/arch/reset_manager.h>
+#include <asm/arch/dwmmc.h>
+
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -17,6 +21,117 @@ int dram_init(void)
 	return 0;
 }
 
+#define L3REGS_SECGRP_LWHPS2FPGAREGS_ADDRESS 0x20
+#define L3REGS_SECGRP_HPS2FPGAREGS_ADDRESS 0x90
+#define L3REGS_SECGRP_ACP_ADDRESS 0x94
+#define L3REGS_SECGRP_ROM_ADDRESS 0x98
+#define L3REGS_SECGRP_OCRAM_ADDRESS 0x9c
+#define L3REGS_SECGRP_SDRDATA_ADDRESS 0xa0
+
+#define L3REGS_REMAP_LWHPS2FPGA_MASK 0x00000010
+#define L3REGS_REMAP_HPS2FPGA_MASK 0x00000008
+#define L3REGS_REMAP_OCRAM_MASK 0x00000001
+
+/*
+ * Convert all slave from secure to non secure
+ */
+void nic301_slave_ns(void)
+{
+       writel(0x1, (SOCFPGA_L3REGS_ADDRESS +
+               L3REGS_SECGRP_LWHPS2FPGAREGS_ADDRESS));
+       writel(0x1, (SOCFPGA_L3REGS_ADDRESS +
+               L3REGS_SECGRP_HPS2FPGAREGS_ADDRESS));
+       writel(0x1, (SOCFPGA_L3REGS_ADDRESS +
+               L3REGS_SECGRP_ACP_ADDRESS));
+       writel(0x1, (SOCFPGA_L3REGS_ADDRESS +
+               L3REGS_SECGRP_ROM_ADDRESS));
+       writel(0x1, (SOCFPGA_L3REGS_ADDRESS +
+               L3REGS_SECGRP_OCRAM_ADDRESS));
+       writel(0x1, (SOCFPGA_L3REGS_ADDRESS +
+               L3REGS_SECGRP_SDRDATA_ADDRESS));
+       return;
+}
+
+
+static const struct socfpga_reset_manager *reset_manager_base =
+               (void *)SOCFPGA_RSTMGR_ADDRESS;
+
+#define CONFIG_SYSMGR_EMAC_CTRL                (SOCFPGA_SYSMGR_ADDRESS + 0x60)
+
+/* Enumeration: sysmgr::emacgrp::ctrl::physel::enum                        */
+#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 0x00000003
+
+/* EMAC controller and PHY used */
+#define CONFIG_EPHY_PHY_ADDR           CONFIG_EPHY1_PHY_ADDR
+
+#define SYSMGR_FPGAINTF_MODULE         (SOCFPGA_SYSMGR_ADDRESS + 0x28)
+
+/* Preloader handoff to bootloader register */
+#define SYSMGR_ISWGRP_HANDOFF0         (SOCFPGA_SYSMGR_ADDRESS + 0x80)
+#define SYSMGR_ISWGRP_HANDOFF1         (SOCFPGA_SYSMGR_ADDRESS + 0x84)
+#define SYSMGR_ISWGRP_HANDOFF2         (SOCFPGA_SYSMGR_ADDRESS + 0x88)
+#define SYSMGR_ISWGRP_HANDOFF3         (SOCFPGA_SYSMGR_ADDRESS + 0x8C)
+#define SYSMGR_ISWGRP_HANDOFF4         (SOCFPGA_SYSMGR_ADDRESS + 0x90)
+#define SYSMGR_ISWGRP_HANDOFF5         (SOCFPGA_SYSMGR_ADDRESS + 0x94)
+#define SYSMGR_ISWGRP_HANDOFF6         (SOCFPGA_SYSMGR_ADDRESS + 0x98)
+#define SYSMGR_ISWGRP_HANDOFF7         (SOCFPGA_SYSMGR_ADDRESS + 0x9C)
+
+#define ISWGRP_HANDOFF_AXIBRIDGE       SYSMGR_ISWGRP_HANDOFF0
+#define ISWGRP_HANDOFF_L3REMAP         SYSMGR_ISWGRP_HANDOFF1
+#define ISWGRP_HANDOFF_FPGAINTF                SYSMGR_ISWGRP_HANDOFF2
+#define ISWGRP_HANDOFF_FPGA2SDR                SYSMGR_ISWGRP_HANDOFF3
+
+#define SDR_CTRLGRP_FPGAPORTRST_ADDRESS 0x5080
+
+/*
+ * DesignWare Ethernet initialization
+ */
+#ifdef CONFIG_DESIGNWARE_ETH
+int cpu_eth_init(bd_t *bis)
+{
+	/* 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
+	 */
+	emac0_reset_enable(1);
+	emac1_reset_enable(1);
+
+	/* Clearing emac0 PHY interface select to 0 */
+	clrbits_le32(CONFIG_SYSMGR_EMAC_CTRL,
+		     (SYSMGR_EMACGRP_CTRL_PHYSEL_MASK <<
+		      SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB));
+
+	/* configure to PHY interface select choosed */
+	setbits_le32(CONFIG_SYSMGR_EMAC_CTRL,
+		     (SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII <<
+		      SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB));
+	/* Release the EMAC controller from reset */
+	emac1_reset_enable(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, 4, 0);
+}
+#endif
+
 #if defined(CONFIG_DISPLAY_CPUINFO)
 /*
  * Print CPU information
@@ -36,22 +151,123 @@ int overwrite_console(void)
 }
 #endif
 
-int misc_init_r(void)
+#ifdef CONFIG_FPGA
+/*
+ * FPGA programming support for SoC FPGA Cyclone V
+ */
+/* currently only single FPGA device avaiable on dev kit */
+Altera_desc altera_fpga[CONFIG_FPGA_COUNT] = {
+	{Altera_SoCFPGA, /* family */
+	fast_passive_parallel, /* interface type */
+	-1,		/* no limitation as
+			additional data will be ignored */
+	NULL,		/* no device function table */
+	NULL,		/* base interface address specified in driver */
+	0}		/* no cookie implementation */
+};
+
+/* add device descriptor to FPGA device table */
+void socfpga_fpga_add(void)
 {
-	return 0;
+	int i;
+	fpga_init();
+	for (i = 0; i < CONFIG_FPGA_COUNT; i++)
+		fpga_add(fpga_altera, &altera_fpga[i]);
+}
+#endif
+
+void sdram_applycfg_uboot(void);
+
+#define SOCFPGA_MPUL2_ADDRESS 0xfffef000
+#define SOCFPGA_MPUL2_ADRFLTR_START    (0xC00)
+
+/* create environment for bridges and handoff */
+static void prepare_environment(void)
+{
+	char buf[32];
+
+	/* hps peripheral controller to fgpa */
+	setenv_addr("fpgaintf", (void *)SYSMGR_FPGAINTF_MODULE);
+	sprintf(buf, "0x%08x", readl(ISWGRP_HANDOFF_FPGAINTF));
+	setenv("fpgaintf_handoff", buf);
+
+	/* fpga2sdram port */
+	setenv_addr("fpga2sdram", (void *)(SOCFPGA_SDR_ADDRESS +
+		SDR_CTRLGRP_FPGAPORTRST_ADDRESS));
+	sprintf(buf, "0x%08x", readl(ISWGRP_HANDOFF_FPGA2SDR));
+	setenv("fpga2sdram_handoff", buf);
+	setenv_addr("fpga2sdram_apply", (void *)sdram_applycfg_uboot);
+
+	/* axi bridges (hps2fpga, lwhps2fpga and fpga2hps) */
+	setenv_addr("axibridge", (void *)&reset_manager_base->brg_mod_reset);
+	sprintf(buf, "0x%08x", readl(ISWGRP_HANDOFF_AXIBRIDGE));
+	setenv("axibridge_handoff", buf);
+
+	/* l3 remap register */
+	setenv_addr("l3remap", (void *)SOCFPGA_L3REGS_ADDRESS);
+	sprintf(buf, "0x%08x", readl(ISWGRP_HANDOFF_L3REMAP));
+	setenv("l3remap_handoff", buf);
+
+	/* add signle command to enable all bridges based on handoff */
+	setenv("bridge_enable_handoff",
+		"mw $fpgaintf ${fpgaintf_handoff}; "
+		"go $fpga2sdram_apply; "
+		"mw $fpga2sdram ${fpga2sdram_handoff}; "
+		"mw $axibridge ${axibridge_handoff}; "
+		"mw $l3remap ${l3remap_handoff} ");
+
+	/* add signle command to disable all bridges */
+	setenv("bridge_disable",
+		"mw $fpgaintf 0; "
+		"mw $fpga2sdram 0; "
+		"go $fpga2sdram_apply; "
+		"mw $axibridge 0; "
+		"mw $l3remap 0x1 ");
 }
 
+int misc_init_r(void)
+{
+#if 1 /* FIXME */
+	printf("Turning off all the bridges\n");
+	reset_assert_all_bridges();
 
+	/* reset_deassert_all_bridges(); <- original code never does that */ 
+	printf("non-secure access to everyone\n");
+	nic301_slave_ns();
+#endif
+
+#if 1 /* FIXME */
+#define SOCFPGA_MPUSCU_ADDRESS 0xfffec000
 /*
- * DesignWare Ethernet initialization
+ * SCU Non-secure Access Control
  */
-int cpu_eth_init(bd_t *bis)
-{
-#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);
+#define SOCFPGA_SCU_SNSAC              (SOCFPGA_MPUSCU_ADDRESS + 0x54)
+
+       /*
+        * Private components security
+        * U-Boot : configure private timer, global timer and cpu
+        * component access as non secure for kernel stage (as required
+        * by kernel)
+        */
+       setbits_le32(SOCFPGA_SCU_SNSAC, 0xfff);
+#endif
+
+       /* Configure the L2 controller to make SDRAM start at 0 */
+#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
+       writel(0x2, SOCFPGA_L3REGS_ADDRESS);
 #else
-	return 0;
+       writel(0x1, (SOCFPGA_MPUL2_ADDRESS + SOCFPGA_MPUL2_ADRFLTR_START));
 #endif
+
+#ifdef CONFIG_FPGA
+	/* add device descriptor to FPGA device table */
+	socfpga_fpga_add();
+#endif
+
+	/* This is needed, otherwise kernel is rebooted by watchdog. */
+	watchdog_disable();
+
+	if (1) /* FIXME */
+		prepare_environment();
+	return 0;
 }
diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c
index e320c01..afc179b 100644
--- a/arch/arm/cpu/armv7/socfpga/reset_manager.c
+++ b/arch/arm/cpu/armv7/socfpga/reset_manager.c
@@ -14,6 +14,22 @@ DECLARE_GLOBAL_DATA_PTR;
 static const struct socfpga_reset_manager *reset_manager_base =
 		(void *)SOCFPGA_RSTMGR_ADDRESS;
 
+#define RSTMGR_PERMODRST_L4WD0_LSB 6
+
+#define RSTMGR_PERMODRST_EMAC0_LSB 0
+#define RSTMGR_PERMODRST_EMAC1_LSB 1
+
+/* Disable the watchdog (toggle reset to watchdog) */
+void watchdog_disable(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 +53,62 @@ void reset_deassert_peripherals_handoff(void)
 {
 	writel(0, &reset_manager_base->per_mod_reset);
 }
+
+/* Assert reset to all bridges through reset manager */
+void reset_assert_all_bridges(void)
+{
+#if !defined(CONFIG_SOCFPGA_VIRTUAL_TARGET)
+       writel(~0, &reset_manager_base->brg_mod_reset);
+#endif
+}
+
+/* Change the reset state for EMAC0 */
+void emac0_reset_enable(uint state)
+{
+       if (state)
+               setbits_le32(&reset_manager_base->per_mod_reset,
+                       (1 << RSTMGR_PERMODRST_EMAC0_LSB));
+       else
+               clrbits_le32(&reset_manager_base->per_mod_reset,
+                       (1 << RSTMGR_PERMODRST_EMAC0_LSB));
+}
+
+/* Change the reset state for EMAC1 */
+void emac1_reset_enable(uint state)
+{
+       if (state)
+               setbits_le32(&reset_manager_base->per_mod_reset,
+                       (1 << RSTMGR_PERMODRST_EMAC1_LSB));
+       else
+               clrbits_le32(&reset_manager_base->per_mod_reset,
+                       (1 << RSTMGR_PERMODRST_EMAC1_LSB));
+}
+
+#define L3REGS_REMAP_LWHPS2FPGA_MASK 0x00000010
+#define L3REGS_REMAP_HPS2FPGA_MASK 0x00000008
+#define L3REGS_REMAP_OCRAM_MASK 0x00000001
+
+void reset_deassert_all_bridges(void)
+{
+#if !defined(CONFIG_SOCFPGA_VIRTUAL_TARGET)
+#if 1 /* FIXME */
+	printf("wait for fpga\n");
+	/* check signal from FPGA */
+	if (poll_fpgamgr_fpga_ready() == 0) {
+		/* FPGA not ready. Not much can be done but let WD timeout */
+		printf("reset_deassert_all_bridges: fpga not ready, hanging.\n");
+		for (;;)
+			;
+	}
+
+	printf("modrst\n");
+	/* brdmodrst */
+	writel(0, &reset_manager_base->brg_mod_reset);
+#endif
+
+	printf("bridges\n");
+	/* remap the bridges into memory map */
+	writel((L3REGS_REMAP_LWHPS2FPGA_MASK | L3REGS_REMAP_HPS2FPGA_MASK |
+		L3REGS_REMAP_OCRAM_MASK), SOCFPGA_L3REGS_ADDRESS);
+#endif
+}
diff --git a/arch/arm/cpu/armv7/socfpga/system_manager.c b/arch/arm/cpu/armv7/socfpga/system_manager.c
index d96521b..0659407 100644
--- a/arch/arm/cpu/armv7/socfpga/system_manager.c
+++ b/arch/arm/cpu/armv7/socfpga/system_manager.c
@@ -7,8 +7,45 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/system_manager.h>
+#include <asm/arch/fpga_manager.h>
 
 DECLARE_GLOBAL_DATA_PTR;
+/*
+ * 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 unsigned long populate_sysmgr_fpgaintf_module(void)
+{
+	writel(0, ISWGRP_HANDOFF_FPGAINTF);
+
+	/* enable the signal for those hps peripheral use fpga */
+	if (readl(SYSMGR_PINMUXGRP_NANDUSEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+		setbits_le32(ISWGRP_HANDOFF_FPGAINTF,
+			SYSMGR_FPGAINTF_NAND);
+
+	if (readl(SYSMGR_PINMUXGRP_EMAC1USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+		setbits_le32(ISWGRP_HANDOFF_FPGAINTF,
+			SYSMGR_FPGAINTF_EMAC1);
+
+	if (readl(SYSMGR_PINMUXGRP_SDMMCUSEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+		setbits_le32(ISWGRP_HANDOFF_FPGAINTF,
+			SYSMGR_FPGAINTF_SDMMC);
+
+	if (readl(SYSMGR_PINMUXGRP_EMAC0USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+		setbits_le32(ISWGRP_HANDOFF_FPGAINTF,
+			SYSMGR_FPGAINTF_EMAC0);
+
+	if (readl(SYSMGR_PINMUXGRP_SPIM1USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+		setbits_le32(ISWGRP_HANDOFF_FPGAINTF,
+			SYSMGR_FPGAINTF_SPIM1);
+
+	if (readl(SYSMGR_PINMUXGRP_SPIM0USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+		setbits_le32(ISWGRP_HANDOFF_FPGAINTF,
+			SYSMGR_FPGAINTF_SPIM0);
+
+	return readl(ISWGRP_HANDOFF_FPGAINTF);
+}
 
 /*
  * Configure all the pin muxes
@@ -18,10 +55,19 @@ void sysmgr_pinmux_init(void)
 	unsigned long offset = CONFIG_SYSMGR_PINMUXGRP_OFFSET;
 
 	const unsigned long *pval = sys_mgr_init_table;
-	unsigned long i;
+	unsigned long i, reg_value;
 
 	for (i = 0; i < ARRAY_SIZE(sys_mgr_init_table);
 		i++, offset += sizeof(unsigned long)) {
 		writel(*pval++, (SOCFPGA_SYSMGR_ADDRESS + offset));
 	}
+
+	/* populate (not writing) the value for SYSMGR.FPGAINTF.MODULE
+	based on pinmux setting */
+	reg_value = populate_sysmgr_fpgaintf_module();
+
+	if (is_fpgamgr_fpga_ready()) {
+		/* enable the required signals only */
+		writel(reg_value, SYSMGR_FPGAINTF_MODULE);
+	}
 }
diff --git a/arch/arm/include/asm/arch-socfpga/clock_manager.h b/arch/arm/include/asm/arch-socfpga/clock_manager.h
index babac0e..d7c87199 100644
--- a/arch/arm/include/asm/arch-socfpga/clock_manager.h
+++ b/arch/arm/include/asm/arch-socfpga/clock_manager.h
@@ -208,4 +208,9 @@ struct socfpga_clock_manager {
 	CLKMGR_SDRPLLGRP_VCO_DENOM_SET(CONFIG_HPS_SDRPLLGRP_VCO_DENOM) | \
 	CLKMGR_SDRPLLGRP_VCO_NUMER_SET(CONFIG_HPS_SDRPLLGRP_VCO_NUMER))
 
+/* global variable which consume by drivers */
+extern unsigned long cm_l4_sp_clock;
+extern unsigned long cm_sdmmc_clock;
+extern unsigned long cm_qspi_clock;
+
 #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..8e410c5
--- /dev/null
+++ b/arch/arm/include/asm/arch-socfpga/fpga_manager.h
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of the Altera Corporation nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	_FPGA_MANAGER_H_
+#define	_FPGA_MANAGER_H_
+
+struct socfpga_fpga_manager {
+	u32	stat;
+	u32	ctrl;
+	u32	dclkcnt;
+	u32	dclkstat;
+	u32	gpo;
+	u32	gpi;
+	u32	misci;
+};
+
+#define FPGAMGRREGS_MON_GPIO_PORTA_EOI_ADDRESS	0x84c
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_ADDRESS	0x850
+
+#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_STAT_MODE_MASK		0x7
+#define FPGAMGRREGS_STAT_MSEL_MASK		0xf8
+#define FPGAMGRREGS_STAT_MSEL_LSB		3
+
+#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
+
+/* Timeout counter */
+#define FPGA_TIMEOUT_CNT		0x1000000
+
+/* 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
+
+/* Functions */
+int is_fpgamgr_fpga_ready(void);
+int poll_fpgamgr_fpga_ready(void);
+int fpgamgr_program_init(void);
+void fpgamgr_program_write(const unsigned long *rbf_data,
+	unsigned long rbf_size);
+int fpgamgr_program_poll_cd(void);
+int fpgamgr_program_poll_initphase(void);
+int fpgamgr_program_poll_usermode(void);
+int fpgamgr_program_fpga(const unsigned long *rbf_data,
+	unsigned long rbf_size);
+void fpgamgr_axi_write(const unsigned long *rbf_data,
+	const unsigned long fpgamgr_data_addr, unsigned long rbf_size);
+
+#endif /* _FPGA_MANAGER_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..eb95c5b 100644
--- a/arch/arm/include/asm/arch-socfpga/reset_manager.h
+++ b/arch/arm/include/asm/arch-socfpga/reset_manager.h
@@ -10,6 +10,14 @@
 void reset_cpu(ulong addr);
 void reset_deassert_peripherals_handoff(void);
 
+void reset_deassert_all_bridges(void);
+void reset_assert_all_bridges(void);
+
+void emac0_reset_enable(uint state);
+void emac1_reset_enable(uint state);
+
+void watchdog_disable(void);
+
 struct socfpga_reset_manager {
 	u32	status;
 	u32	ctrl;
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..39a7874 100644
--- a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
+++ b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
@@ -7,9 +7,15 @@
 #ifndef _SOCFPGA_BASE_ADDRS_H_
 #define _SOCFPGA_BASE_ADDRS_H_
 
+#define SOCFPGA_EMAC0_ADDRESS 0xff700000
+#define SOCFPGA_EMAC1_ADDRESS 0xff702000
+#define SOCFPGA_SDMMC_ADDRESS 0xff704000
+#define SOCFPGA_FPGAMGRREGS_ADDRESS 0xff706000
 #define SOCFPGA_L3REGS_ADDRESS 0xff800000
+#define SOCFPGA_FPGAMGRDATA_ADDRESS 0xffb90000
 #define SOCFPGA_UART0_ADDRESS 0xffc02000
 #define SOCFPGA_UART1_ADDRESS 0xffc03000
+#define SOCFPGA_SDR_ADDRESS 0xffc20000
 #define SOCFPGA_OSC1TIMER0_ADDRESS 0xffd00000
 #define SOCFPGA_L4WD0_ADDRESS 0xffd02000
 #define SOCFPGA_CLKMGR_ADDRESS 0xffd04000
diff --git a/arch/arm/include/asm/arch-socfpga/system_manager.h b/arch/arm/include/asm/arch-socfpga/system_manager.h
index 838d210..38b5598 100644
--- a/arch/arm/include/asm/arch-socfpga/system_manager.h
+++ b/arch/arm/include/asm/arch-socfpga/system_manager.h
@@ -84,4 +84,49 @@ struct socfpga_system_manager {
 	u32	eccgrp_sdmmc;
 };
 
+/* FPGA interface group */
+#define SYSMGR_FPGAINTF_MODULE         (SOCFPGA_SYSMGR_ADDRESS + 0x28)
+/* EMAC interface selection */
+#define CONFIG_SYSMGR_EMAC_CTRL                (SOCFPGA_SYSMGR_ADDRESS + 0x60)
+
+/* Preloader handoff to bootloader register */
+#define SYSMGR_ISWGRP_HANDOFF0         (SOCFPGA_SYSMGR_ADDRESS + 0x80)
+#define SYSMGR_ISWGRP_HANDOFF1         (SOCFPGA_SYSMGR_ADDRESS + 0x84)
+#define SYSMGR_ISWGRP_HANDOFF2         (SOCFPGA_SYSMGR_ADDRESS + 0x88)
+#define SYSMGR_ISWGRP_HANDOFF3         (SOCFPGA_SYSMGR_ADDRESS + 0x8C)
+#define SYSMGR_ISWGRP_HANDOFF4         (SOCFPGA_SYSMGR_ADDRESS + 0x90)
+#define SYSMGR_ISWGRP_HANDOFF5         (SOCFPGA_SYSMGR_ADDRESS + 0x94)
+#define SYSMGR_ISWGRP_HANDOFF6         (SOCFPGA_SYSMGR_ADDRESS + 0x98)
+#define SYSMGR_ISWGRP_HANDOFF7         (SOCFPGA_SYSMGR_ADDRESS + 0x9C)
+
+#define ISWGRP_HANDOFF_AXIBRIDGE       SYSMGR_ISWGRP_HANDOFF0
+#define ISWGRP_HANDOFF_L3REMAP         SYSMGR_ISWGRP_HANDOFF1
+#define ISWGRP_HANDOFF_FPGAINTF                SYSMGR_ISWGRP_HANDOFF2
+#define ISWGRP_HANDOFF_FPGA2SDR                SYSMGR_ISWGRP_HANDOFF3
+
+/* bit fields */
+#define CONFIG_SYSMGR_PINMUXGRP_OFFSET (0x400)
+#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)
+
+/* pin mux */
+#define SYSMGR_PINMUXGRP               (SOCFPGA_SYSMGR_ADDRESS + 0x400)
+#define SYSMGR_PINMUXGRP_FLASHIO1      (SYSMGR_PINMUXGRP + 0x54)
+#define SYSMGR_PINMUXGRP_NANDUSEFPGA   (SYSMGR_PINMUXGRP + 0x2F0)
+#define SYSMGR_PINMUXGRP_EMAC1USEFPGA  (SYSMGR_PINMUXGRP + 0x2F8)
+#define SYSMGR_PINMUXGRP_SDMMCUSEFPGA  (SYSMGR_PINMUXGRP + 0x308)
+#define SYSMGR_PINMUXGRP_EMAC0USEFPGA  (SYSMGR_PINMUXGRP + 0x314)
+#define SYSMGR_PINMUXGRP_SPIM1USEFPGA  (SYSMGR_PINMUXGRP + 0x330)
+#define SYSMGR_PINMUXGRP_SPIM0USEFPGA  (SYSMGR_PINMUXGRP + 0x338)
+
 #endif /* _SYSTEM_MANAGER_H_ */
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index d51ba66..f0dcbd7 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -185,6 +185,7 @@ enum dcache_option {
 	DCACHE_OFF = 0x12,
 	DCACHE_WRITETHROUGH = 0x1a,
 	DCACHE_WRITEBACK = 0x1e,
+	DCACHE_WRITEBACK_WRITEALLOCATE = 0x16,
 };
 
 /* Size of an MMU section */
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index 3e62d58..3227e5d 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -73,6 +73,8 @@ __weak void dram_bank_mmu_setup(int bank)
 	     i++) {
 #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
 		set_section_dcache(i, DCACHE_WRITETHROUGH);
+#elif defined(CONFIG_SYS_ARM_CACHE_WRITEBACK_WRITEALLOCATE)
+               set_section_dcache(i, DCACHE_WRITEBACK_WRITEALLOCATE);
 #else
 		set_section_dcache(i, DCACHE_WRITEBACK);
 #endif
diff --git a/board/altera/socfpga/socfpga_cyclone5.c b/board/altera/socfpga/socfpga_cyclone5.c
index fb92852..6b74997d 100644
--- a/board/altera/socfpga/socfpga_cyclone5.c
+++ b/board/altera/socfpga/socfpga_cyclone5.c
@@ -1,5 +1,6 @@
 /*
  *  Copyright (C) 2012 Altera Corporation <www.altera.com>
+ *  Copyright (C) 2014 Pavel Machek, pavel at denx.de
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -8,8 +9,6 @@
 #include <asm/arch/reset_manager.h>
 #include <asm/io.h>
 
-#include <netdev.h>
-
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -34,6 +33,17 @@ int board_early_init_f(void)
  */
 int board_init(void)
 {
-	icache_enable();
+	//	icache_enable();
+	puts("derive_clocks_for_drivers... \n");
+#if 1
+	/* calculate the clock frequencies required for drivers */
+	cm_derive_clocks_for_drivers();
+
+	puts("derive_clocks_for_drivers... done\n");
+#endif
+
+	/* adress of boot parameters for ATAG (if ATAG is used) */
+	gd->bd->bi_boot_params = 0x00000100;
+
 	return 0;
 }
diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c
index 8c5bf44..884c61a 100644
--- a/common/cmd_fpga.c
+++ b/common/cmd_fpga.c
@@ -43,6 +43,7 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 	void *fpga_data = NULL;
 	char *devstr = getenv("fpga");
 	char *datastr = getenv("fpgadata");
+	char *devsizestr = getenv("fpgadatasize");
 	int rc = FPGA_FAIL;
 	int wrong_parms = 0;
 #if defined(CONFIG_FIT)
@@ -57,7 +58,9 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 	if (devstr)
 		dev = (int) simple_strtoul(devstr, NULL, 16);
 	if (datastr)
-		fpga_data = (void *)simple_strtoul(datastr, NULL, 16);
+		fpga_data = (void *) simple_strtoul(datastr, NULL, 16);
+	if (devsizestr)
+		data_size = (size_t) simple_strtoul(devsizestr, NULL, 16);
 
 	switch (argc) {
 #if defined(CONFIG_CMD_FPGA_LOADFS)
diff --git a/common/memsize.c b/common/memsize.c
index 589400d..0cae738 100644
--- a/common/memsize.c
+++ b/common/memsize.c
@@ -33,6 +33,8 @@ long get_ram_size(long *base, long maxsize)
 	long           size;
 	int            i = 0;
 
+	return maxsize;
+
 	for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
 		addr = base + cnt;	/* pointer arith! */
 		sync ();
diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c
index 6e34a8e..36d8826 100644
--- a/drivers/fpga/altera.c
+++ b/drivers/fpga/altera.c
@@ -1,4 +1,7 @@
 /*
+ * (C) Copyright 2013
+ * Altera Corporation <www.altera.com>
+ *
  * (C) Copyright 2003
  * Steven Scholz, imc Measurement & Control, steven.scholz at imc-berlin.de
  *
@@ -14,6 +17,9 @@
 #include <common.h>
 #include <ACEX1K.h>
 #include <stratixII.h>
+#if defined(CONFIG_FPGA_SOCFPGA)
+#include <asm/arch/fpga_manager.h>
+#endif
 
 /* Define FPGA_DEBUG to get debug printf's */
 /* #define FPGA_DEBUG */
@@ -59,6 +65,18 @@ int altera_load(Altera_desc *desc, const void *buf, size_t bsize)
 			ret_val = StratixII_load (desc, buf, bsize);
 			break;
 #endif
+#if defined(CONFIG_FPGA_SOCFPGA)
+		case Altera_SoCFPGA:
+			PRINTF("%s: Launching the SoC FPGA Loader...\n",
+				__func__);
+			ret_val = fpgamgr_program_fpga(buf, bsize);
+			if (ret_val) {
+				printf("%s: Failed with error code %d\n",
+				__func__, ret_val);
+				ret_val = 1;
+			}
+			break;
+#endif
 		default:
 			printf ("%s: Unsupported family type, %d\n",
 					__FUNCTION__, desc->family);
@@ -94,6 +112,11 @@ int altera_dump(Altera_desc *desc, const void *buf, size_t bsize)
 			ret_val = StratixII_dump (desc, buf, bsize);
 			break;
 #endif
+		case Altera_SoCFPGA:
+			printf("%s: Unsupported due to security reason, %d\n",
+					__func__, desc->family);
+			ret_val = FPGA_SUCCESS;
+			break;
 		default:
 			printf ("%s: Unsupported family type, %d\n",
 					__FUNCTION__, desc->family);
@@ -119,6 +142,9 @@ int altera_info( Altera_desc *desc )
 		case Altera_StratixII:
 			printf ("Stratix II\n");
 			break;
+		case Altera_SoCFPGA:
+			printf("SoC FPGA\n");
+			break;
 			/* Add new family types here */
 		default:
 			printf ("Unknown family type, %d\n", desc->family);
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 0df30bc..4c16e7f 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -177,14 +177,16 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 		}
 	}
 
-	if (i == retry)
+	if (i == retry) {
+		printf("dwmci_send_cmd: timeout..\n");
 		return TIMEOUT;
+	}
 
 	if (mask & DWMCI_INTMSK_RTO) {
-		debug("Response Timeout..\n");
+		printf("dwmci_send_cmd: Response Timeout..\n");
 		return TIMEOUT;
 	} else if (mask & DWMCI_INTMSK_RE) {
-		debug("Response Error..\n");
+		printf("dwmci_send_cmd: Response Error..\n");
 		return -1;
 	}
 
@@ -204,7 +206,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 		do {
 			mask = dwmci_readl(host, DWMCI_RINTSTS);
 			if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
-				debug("DATA ERROR!\n");
+				printf("dwmci_send_cmd: DATA ERROR!\n");
 				return -1;
 			}
 		} while (!(mask & DWMCI_INTMSK_DTO));
@@ -232,16 +234,16 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
 	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("dwmci_setup_bus: Didn't get source clock value..\n");
 		return -EINVAL;
 	}
 
@@ -260,7 +262,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
 	do {
 		status = dwmci_readl(host, DWMCI_CMD);
 		if (timeout-- < 0) {
-			printf("TIMEOUT error!!\n");
+			printf("dwmci_setup_bus: timeout!\n");
 			return -ETIMEDOUT;
 		}
 	} while (status & DWMCI_CMD_START);
@@ -275,7 +277,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
 	do {
 		status = dwmci_readl(host, DWMCI_CMD);
 		if (timeout-- < 0) {
-			printf("TIMEOUT error!!\n");
+			printf("dwmci_setup_bus: timeout!\n");
 			return -ETIMEDOUT;
 		}
 	} while (status & DWMCI_CMD_START);
@@ -290,7 +292,7 @@ static void dwmci_set_ios(struct mmc *mmc)
 	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 +331,7 @@ static int dwmci_init(struct mmc *mmc)
 	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/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index 1f96382..d8da7f5 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -16,6 +16,8 @@ static const struct socfpga_clock_manager *clock_manager_base =
 static const struct socfpga_system_manager *system_manager_base =
 		(void *)SOCFPGA_SYSMGR_ADDRESS;
 
+#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK (1 << 8)
+
 static void socfpga_dwmci_clksel(struct dwmci_host *host)
 {
 	unsigned int drvsel;
@@ -58,7 +60,8 @@ int socfpga_dwmmc_init(u32 regbase, int bus_width, int index)
 	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 = cm_sdmmc_clock;
+	printf("bus_hz: %ld\n", host->bus_hz);
 	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/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 5d7e3be..06a31b0 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -25,8 +25,7 @@ static struct phy_driver KSZ804_driver = {
 #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 @@ static struct phy_driver KS8721_driver = {
 #endif
 
 
-/**
+/*
  * KSZ9021 - KSZ9031 common
  */
 
@@ -69,8 +68,8 @@ static int ksz90xx_startup(struct phy_device *phydev)
 		phydev->speed = SPEED_10;
 	return 0;
 }
-#ifdef CONFIG_PHY_MICREL_KSZ9021
 
+#ifdef CONFIG_PHY_MICREL_KSZ9021
 /*
  * KSZ9021
  */
@@ -113,17 +112,46 @@ static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr,
 	return ksz9021_phy_extended_write(phydev, regnum, val);
 }
 
+/* FIXME: disable_giga is probably what we want to do */
+
 /* Micrel ksz9021 */
 static int ksz9021_config(struct phy_device *phydev)
 {
 	unsigned ctrl1000 = 0;
 	const unsigned master = CTRL1000_PREFER_MASTER |
-			CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
+		CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
 	unsigned features = phydev->drv->features;
 
+	printf("ksz9021: configuring\n");
+
+	printf("Configuring PHY skew timing for %s\n",
+	       phydev->drv->name);
+
+	/* min rx data delay */
+	if (ksz9021_phy_extended_write(phydev,
+				       MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW,
+				       getenv_ulong(CONFIG_KSZ9021_DATA_SKEW_ENV, 16,
+						    CONFIG_KSZ9021_DATA_SKEW_VAL)) < 0)
+		return -1;
+	/* min tx data delay */
+	if (ksz9021_phy_extended_write(phydev,
+				       MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW,
+				       getenv_ulong(CONFIG_KSZ9021_DATA_SKEW_ENV, 16,
+						    CONFIG_KSZ9021_DATA_SKEW_VAL)) < 0)
+		return -1;
+	/* max rx/tx clock delay, min rx/tx control */
+	if (ksz9021_phy_extended_write(phydev,
+				       MII_KSZ9021_EXT_RGMII_CLOCK_SKEW,
+				       getenv_ulong(CONFIG_KSZ9021_CLK_SKEW_ENV, 16,
+						    CONFIG_KSZ9021_CLK_SKEW_VAL)) < 0)
+		return -1;
+
+	printf("ksz9021: skew ok\n");
+
+
 	if (getenv("disable_giga"))
 		features &= ~(SUPPORTED_1000baseT_Half |
-				SUPPORTED_1000baseT_Full);
+			      SUPPORTED_1000baseT_Full);
 	/* force master mode for 1000BaseT due to chip errata */
 	if (features & SUPPORTED_1000baseT_Half)
 		ctrl1000 |= ADVERTISE_1000HALF | master;
diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile
index 2dacba2..163672f 100644
--- a/examples/standalone/Makefile
+++ b/examples/standalone/Makefile
@@ -5,7 +5,8 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-extra-y        := hello_world
+extra-y        := 
+#extra-y        := hello_world
 extra-$(CONFIG_SMC91111)           += smc91111_eeprom
 extra-$(CONFIG_SMC911X)            += smc911x_eeprom
 extra-$(CONFIG_SPI_FLASH_ATMEL)    += atmel_df_pow2
diff --git a/include/altera.h b/include/altera.h
index ae5f7ee..c7f78fc 100644
--- a/include/altera.h
+++ b/include/altera.h
@@ -27,6 +27,7 @@ typedef enum {			/* typedef Altera_Family */
 	Altera_ACEX1K,		/* ACEX1K Family */
 	Altera_CYC2,		/* CYCLONII Family */
 	Altera_StratixII,	/* StratixII Family */
+	Altera_SoCFPGA,		/* SoCFPGA Family */
 /* Add new models here */
 	max_altera_type		/* insert all new types before this */
 } Altera_Family;		/* end, typedef Altera_Family */
diff --git a/include/configs/axs101.h b/include/configs/axs101.h
index c22d6d0..1bf83907 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/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h
index 5d145cd..d3d1e48 100644
--- a/include/configs/socfpga_cyclone5.h
+++ b/include/configs/socfpga_cyclone5.h
@@ -11,6 +11,8 @@
 #include "../../board/altera/socfpga/iocsr_config.h"
 #include "../../board/altera/socfpga/pll_config.h"
 
+#define CONFIG_SYS_GENERIC_BOARD
+
 /*
  * High level configuration
  */
@@ -23,6 +25,12 @@
 
 #define CONFIG_MISC_INIT_R
 #define CONFIG_SINGLE_BOOTLOADER
+
+/* Enable THUMB2 mode to reduce software size which yield better boot time */
+#define CONFIG_SYS_THUMB_BUILD
+
+#define CONFIG_SYS_ARM_CACHE_WRITEBACK_WRITEALLOCATE
+
 #define CONFIG_SOCFPGA
 
 /* base address for .text section */
@@ -31,7 +39,7 @@
 #else
 #define CONFIG_SYS_TEXT_BASE		0x01000040
 #endif
-#define CONFIG_SYS_LOAD_ADDR		0x7fc0
+#define CONFIG_SYS_LOAD_ADDR		0x8000
 
 /* Console I/O Buffer Size */
 #define CONFIG_SYS_CBSIZE		256
@@ -56,7 +64,8 @@
 /* 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_SYS_BOOTMAPSZ           (64 * 1024 * 1024)
+
 
 #define CONFIG_SPL_RAM_DEVICE
 #define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR
@@ -67,9 +76,9 @@
  * Memory allocation (MALLOC)
  */
 /* Room required on the stack for the environment data */
-#define CONFIG_ENV_SIZE			1024
+#define CONFIG_ENV_SIZE			4096
 /* Size of DRAM reserved for malloc() use */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 128*1024)
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 256*1024)
 
 /* SP location before relocation, must use scratch RAM */
 #define CONFIG_SYS_INIT_RAM_ADDR	0xFFFF0000
@@ -119,7 +128,7 @@
  * 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 at 0x0"
+#define CONFIG_BOOTARGS "console=ttyS0,115200,mem=256M at 0x0"
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"verify=n\0" \
@@ -134,7 +143,8 @@
 	"qspirootfstype=jffs2\0" \
 	"qspiboot=setenv bootargs " CONFIG_BOOTARGS \
 		" root=${qspiroot} rw rootfstype=${qspirootfstype};"\
-		"bootm ${loadaddr} - ${fdt_addr}\0"
+		"bootm ${loadaddr} - ${fdt_addr}\0" \
+        "ethaddr=12:23:34:46:56:60\0"
 
 /* using environment setting for stdin, stdout, stderr */
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
@@ -159,13 +169,30 @@
 /* SDRAM Bank #1 */
 #define CONFIG_SYS_SDRAM_BASE		0x00000000
 /* SDRAM memory size */
-#define PHYS_SDRAM_1_SIZE		0x40000000
+/* FIXME: rocketboards uses different version */
+#define PHYS_SDRAM_1_SIZE		0x20000000
 
 #define PHYS_SDRAM_1			CONFIG_SYS_SDRAM_BASE
 #define CONFIG_SYS_MEMTEST_START	0x00000000
 #define CONFIG_SYS_MEMTEST_END		PHYS_SDRAM_1_SIZE
 
 /*
+ * FPGA support
+ */
+/* Enables FPGA subsystem */
+#define CONFIG_FPGA
+#ifdef CONFIG_FPGA
+/* Altera FPGA */
+#define CONFIG_FPGA_ALTERA
+/* Family type */
+#define CONFIG_FPGA_SOCFPGA
+/* Only support single device */
+#define CONFIG_FPGA_COUNT              (1)
+/* Enable FPGA command at console */
+#define CONFIG_CMD_FPGA
+#endif
+
+/*
  * NS16550 Configuration
  */
 #define UART0_BASE			SOCFPGA_UART0_ADDRESS
@@ -188,6 +215,25 @@
  */
 #define CONFIG_SYS_NO_FLASH
 
+
+/*
+ * MMC support
+ */
+#define CONFIG_MMC
+#ifdef CONFIG_MMC
+#define CONFIG_CMD_MMC
+
+#define CONFIG_BOUNCE_BUFFER
+#define CONFIG_GENERIC_MMC             1
+#define CONFIG_DWMMC                   1
+#define CONFIG_SOCFPGA_DWMMC           1
+#define CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH	1024
+#define CONFIG_SOCFPGA_DWMMC_DRVSEL	3
+#define CONFIG_SOCFPGA_DWMMC_SMPSEL	0
+/* using smaller max blk cnt to avoid flooding the limited stack we have */
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT     256
+#endif /* CONFIG_MMC */
+
 /*
  * L4 OSC1 Timer 0
  */
@@ -225,31 +271,41 @@
 /* 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_EMAC_BASE               SOCFPGA_EMAC1_ADDRESS
 #define CONFIG_PHY_INTERFACE_MODE      PHY_INTERFACE_MODE_RGMII
+
+/* phy */
+#define CONFIG_EPHY0_PHY_ADDR          0
+#define CONFIG_EPHY1_PHY_ADDR          4
+#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
+/* Type of PHY available */
+#define SOCFPGA_PHYSEL_ENUM_GMII       0x0
+#define SOCFPGA_PHYSEL_ENUM_MII                0x1
+#define SOCFPGA_PHYSEL_ENUM_RGMII      0x2
+#define SOCFPGA_PHYSEL_ENUM_RMII       0x3
+
 #endif /* CONFIG_DESIGNWARE_ETH */
 
 /*
  * L4 Watchdog
  */
 #define CONFIG_HW_WATCHDOG
-#define CONFIG_HW_WATCHDOG_TIMEOUT_MS	2000
+#define CONFIG_HW_WATCHDOG_TIMEOUT_MS	12000
 #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
  */

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


More information about the U-Boot mailing list