[U-Boot] socfpga: time problems, get ethernet to work in recent versions

Pavel Machek pavel at denx.de
Thu Jul 10 01:23:28 CEST 2014


Hi!

After extensive debugging, I found out that recent u-boot gets time
very wrong (at least 1000 times too fast), and that was breaking all
my attempts at getting networking to work.

(Recent is 

commit 9665fa8f9e1488209d5e01d0792c243e0a220c5a
Merge: e75e73d 33144ea
Author: Tom Rini <trini at ti.com>
Date:   Sat May 24 06:34:08 2014 -0400).

I reverted

commit 23ab7ee0ffa9d5efd0b4ad830befba306d24a327
Author: Rob Herring <rob.herring at calxeda.com>
Date:   Fri Oct 4 10:22:46 2013 -0500

    ARM: socfpga: convert to common timer code
    
    Convert socfpga to use the commmon timer code.
    
    Signed-off-by: Rob Herring <rob.herring at calxeda.com>

, and applied changes from rocketboards.org that fixed another factor
of 1000, and now networking seems to work for me.

I also reverted to old version of driver for debugging and probably
broke a lot of stuff.

Anyway, below is patch you don't want to read, but that does the trick
for me. Now that ethernet started to work, I'm sure I'll be able to
strip it down to something reasonable.

In the meantime, hints how to solve the "time goes way too fast" in
clean way would be welcome. I increased 

#define CONFIG_SYS_TIMER_RATE           25000000

by factor of 1000, then by factor of 1000000, and time was still too
fast. Hmm, maybe LL is needed there?

Anyway, time to sleep now...

									Pavel


diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c
index 23d697d..1c4f224 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;
@@ -102,6 +106,7 @@ void cm_basic_init(const cm_config_t *cfg)
 {
 	uint32_t start, timeout;
 
+	printf("cm_basic_init: initializing clocks\n");
 	/* Start by being paranoid and gate all sw managed clocks */
 
 	/*
@@ -359,3 +364,167 @@ 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));
+  
+}
+
+
+
+void cm_derive_clocks_for_drivers(void)
+{
+       cm_l4_sp_clock = cm_get_l4_sp_clk_hz();
+#if 0
+       cm_sdmmc_clock = cm_get_mmc_controller_clk_hz();
+       cm_qspi_clock = cm_get_qspi_controller_clk_hz();
+#endif
+}
diff --git a/arch/arm/cpu/armv7/socfpga/timer.c b/arch/arm/cpu/armv7/socfpga/timer.c
index 58fc789..2ed341d 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>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static const struct socfpga_timer *timer_base = (void *)CONFIG_SYS_TIMERBASE;
 
 /*
@@ -20,3 +22,76 @@ int timer_init(void)
 	writel(readl(&timer_base->ctrl) | 0x3, &timer_base->ctrl);
 	return 0;
 }
+
+static u32 read_timer(void)
+{
+	return readl(&timer_base->curr_val);
+}
+
+/*
+ * Delay x useconds
+ */
+void __udelay(unsigned long usec)
+{
+	unsigned long now, last;
+	/*
+	 * get the tmo value based on timer clock speed
+	 * tmo = delay required / period of timer clock
+	 */
+	long tmo = usec * CONFIG_TIMER_CLOCK_KHZ / 1000;
+
+	last = read_timer();
+	while (tmo > 0) {
+		now = read_timer();
+		if (last >= now)
+			/* normal mode (non roll) */
+			tmo -= last - now;
+		else
+			/* we have overflow of the count down timer */
+			tmo -= TIMER_LOAD_VAL - last + now;
+		last = now;
+	}
+}
+
+/*
+ * Get the timer value
+ */
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+/*
+ * Timer : get the time difference
+ * Unit of tick is based on the CONFIG_SYS_HZ
+ */
+ulong get_timer_masked(void)
+{
+	/* current tick value */
+	ulong now = read_timer() / (CONFIG_TIMER_CLOCK_KHZ * 1000/CONFIG_SYS_HZ);
+	if (gd->arch.lastinc >= now) {
+		/* normal mode (non roll) */
+		/* move stamp forward with absolute diff ticks */
+		gd->arch.tbl += gd->arch.lastinc - now;
+	} else {
+		/* we have overflow of the count down timer */
+	  //		gd->arch.tbl += TIMER_LOAD_VAL - gd->arch.lastinc + now;
+              gd->arch.tbl += (TIMER_LOAD_VAL / (CONFIG_TIMER_CLOCK_KHZ * 1000
+                      / CONFIG_SYS_HZ)) - gd->arch.lastinc + now;
+
+	}
+	gd->arch.lastinc = now;
+	return gd->arch.tbl;
+}
+
+/*
+ * Reset the timer
+ */
+void reset_timer(void)
+{
+	/* capture current decrementer value time */
+	gd->arch.lastinc = read_timer() /
+				(CONFIG_TIMER_CLOCK_KHZ * 1000 / CONFIG_SYS_HZ);
+	/* start "advancing" time stamp from 0 */
+	gd->arch.tbl = 0;
+}
diff --git a/arch/arm/include/asm/arch-socfpga/clock_manager.h b/arch/arm/include/asm/arch-socfpga/clock_manager.h
index 966add3..52e4603 100644
--- a/arch/arm/include/asm/arch-socfpga/clock_manager.h
+++ b/arch/arm/include/asm/arch-socfpga/clock_manager.h
@@ -202,4 +202,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/socfpga_base_addrs.h b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
index f564046..c8e925a 100644
--- a/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
+++ b/arch/arm/include/asm/arch-socfpga/socfpga_base_addrs.h
@@ -14,5 +14,8 @@
 #define SOCFPGA_CLKMGR_ADDRESS 0xffd04000
 #define SOCFPGA_RSTMGR_ADDRESS 0xffd05000
 #define SOCFPGA_SYSMGR_ADDRESS 0xffd08000
+#define SOCFPGA_EMAC0_ADDRESS 0xff700000
+#define SOCFPGA_EMAC1_ADDRESS 0xff702000
+
 
 #endif /* _SOCFPGA_BASE_ADDRS_H_ */
diff --git a/board/altera/socfpga/socfpga_cyclone5.c b/board/altera/socfpga/socfpga_cyclone5.c
index a960eb6..b199847 100644
--- a/board/altera/socfpga/socfpga_cyclone5.c
+++ b/board/altera/socfpga/socfpga_cyclone5.c
@@ -7,11 +7,39 @@
 #include <common.h>
 #include <asm/arch/reset_manager.h>
 #include <asm/io.h>
+#ifndef CONFIG_SPL_BUILD
+#include <phy.h>
+#include <micrel.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include "../../../drivers/net/designware.h"
+#endif
 
 #include <netdev.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static const struct socfpga_reset_manager *reset_manager_base =
+               (void *)SOCFPGA_RSTMGR_ADDRESS;
+
+#define RSTMGR_PERMODRST_EMAC0_LSB 0
+#define RSTMGR_PERMODRST_EMAC1_LSB 1
+
+#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_EMAC_BASE               CONFIG_EMAC1_BASE
+#define CONFIG_EPHY_PHY_ADDR           CONFIG_EPHY1_PHY_ADDR
+#define CONFIG_PHY_INTERFACE_MODE      SOCFPGA_PHYSEL_ENUM_RGMII
+
 #if defined(CONFIG_DISPLAY_CPUINFO)
 /*
  * Print CPU information
@@ -28,7 +56,7 @@ int print_cpuinfo(void)
  */
 int checkboard(void)
 {
-	puts("BOARD : Altera SOCFPGA Cyclone5 Board\n");
+	puts("BOARD : " ALTERA_BOARD_NAME "\n");
 	return 0;
 }
 
@@ -37,6 +65,13 @@ int checkboard(void)
  */
 int board_early_init_f(void)
 {
+  puts("derive_clocks_for_drivers... \n");
+#ifdef CONFIG_I2C_HARD
+       /* calculate the clock frequencies required for drivers */
+        cm_derive_clocks_for_drivers();
+
+  puts("derive_clocks_for_drivers... done\n");
+#endif
 	return 0;
 }
 
@@ -61,11 +96,231 @@ int overwrite_console(void)
 }
 #endif
 
+#ifdef CONFIG_HARD_I2C
+static void setenv_ethaddr_eeprom(void)
+{
+       uint addr, alen;
+       int linebytes;
+       uchar chip, enetaddr[6], temp;
+
+       /* configuration based on dev kit EEPROM */
+       chip = 0x51;            /* slave ID for EEPROM */
+       alen = 2;               /* dev kit using 2 byte addressing */
+       linebytes = 6;          /* emac address stored in 6 bytes address */
+
+#if (CONFIG_EMAC_BASE == CONFIG_EMAC0_BASE)
+       addr = 0x16c;
+#elif (CONFIG_EMAC_BASE == CONFIG_EMAC1_BASE)
+       addr = 0x174;
+#endif
+
+       i2c_read(chip, addr, alen, enetaddr, linebytes);
+
+       /* swapping endian to match board implementation */
+       temp = enetaddr[0];
+       enetaddr[0] = enetaddr[5];
+       enetaddr[5] = temp;
+       temp = enetaddr[1];
+       enetaddr[1] = enetaddr[4];
+       enetaddr[4] = temp;
+       temp = enetaddr[2];
+       enetaddr[2] = enetaddr[3];
+       enetaddr[3] = temp;
+
+       /* Gives b5:34:3f:f7:47:b0 */
+       /* Ouch, hwaddr from linux is 2a:f7:80:02:49:23 */
+       /* FIXME: hack */
+       enetaddr[0] = 0x2a;
+
+       printf("%x:%x:%x:%x:%x:%x\n", enetaddr[0], enetaddr[1], enetaddr[2],
+	      enetaddr[3], enetaddr[4], enetaddr[5]);
+
+       if (is_valid_ether_addr(enetaddr)) {
+               eth_setenv_enetaddr("ethaddr", enetaddr);
+	       puts("Have valid ether addr\n");
+       } else
+               puts("Skipped ethaddr assignment due to invalid "
+                       "EMAC address in EEPROM\n");
+}
+#endif
+
+
+static int init_ethaddr(void)
+{
+       uchar enetaddr[6];
+
+#ifdef CONFIG_HARD_I2C
+       printf("Setting ethernet address\n");
+       setenv_addr("setenv_ethaddr_eeprom", (void *)setenv_ethaddr_eeprom);
+
+       /* if no ethaddr environment, get it from EEPROM */
+       if (!eth_getenv_enetaddr("ethaddr", enetaddr))
+               setenv_ethaddr_eeprom();
+#endif
+       return 0;
+}
+
+
 /*
  * DesignWare Ethernet initialization
  */
+
+int designware_board_phy_init(struct eth_device *dev, int phy_addr,
+               int (*mii_write)(struct eth_device *, u8, u8, u16),
+               int (*dw_reset_phy)(struct eth_device *))
+{
+       struct dw_eth_dev *priv = dev->priv;
+       struct phy_device *phydev;
+       struct mii_dev *bus;
+
+       printf("Back to board file\n");
+
+       if ((*dw_reset_phy)(dev) < 0)
+               return -1;
+
+       bus = mdio_get_current_dev();
+       printf("Board file: bus %lx\n", bus);
+
+	  /*
+struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
+phy_interface_t interface)
+	  */
+
+       phydev = phy_connect(bus, phy_addr, dev,
+               priv->interface);
+
+       printf("Board file: bus %lx\n", phydev);
+       /* Micrel PHY is connected to EMAC1 */
+       if (strcasecmp(phydev->drv->name, "Micrel ksz9021") == 0 &&
+               ((phydev->drv->uid & phydev->drv->mask) ==
+               (phydev->phy_id & phydev->drv->mask))) {
+
+               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;
+
+               if (phydev->drv->config)
+                       phydev->drv->config(phydev);
+       }
+       return 0;
+}
+
+/* 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));
+}
+
+
 /* We know all the init functions have been run now */
 int board_eth_init(bd_t *bis)
 {
-	return 0;
+	init_ethaddr();
+  printf("Board_eth_init\n");
+  printf("Time : %d\n", get_timer(0));
+  mdelay(1000);
+  printf("Time : %d\n", get_timer(0));
+  mdelay(1000);
+  printf("Time : %d\n", get_timer(0));
+  mdelay(1000);
+  printf("Time : %d\n", get_timer(0));
+  mdelay(1000);
+  printf("Time : %d\n", get_timer(0));
+
+#if !defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) && \
+!defined(CONFIG_SPL_BUILD)
+
+       /* Initialize EMAC */
+
+       /*
+        * Putting the EMAC controller to reset when configuring the PHY
+        * interface select at System Manager
+       */
+  printf("enabling resets...\n");
+       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 <<
+#if (CONFIG_EMAC_BASE == CONFIG_EMAC0_BASE)
+               SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB));
+#elif (CONFIG_EMAC_BASE == CONFIG_EMAC1_BASE)
+               SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB));
+#endif
+
+       /* configure to PHY interface select choosed */
+       setbits_le32(CONFIG_SYSMGR_EMAC_CTRL,
+#if (CONFIG_PHY_INTERFACE_MODE == SOCFPGA_PHYSEL_ENUM_GMII)
+               (SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII <<
+#elif (CONFIG_PHY_INTERFACE_MODE == SOCFPGA_PHYSEL_ENUM_MII)
+               (SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII <<
+#elif (CONFIG_PHY_INTERFACE_MODE == SOCFPGA_PHYSEL_ENUM_RGMII)
+               (SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII <<
+#elif (CONFIG_PHY_INTERFACE_MODE == SOCFPGA_PHYSEL_ENUM_RMII)
+               (SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII <<
+#endif
+#if (CONFIG_EMAC_BASE == CONFIG_EMAC0_BASE)
+               SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB));
+  printf("enabling emac0...\n");
+       /* Release the EMAC controller from reset */
+       emac0_reset_enable(0);
+#elif (CONFIG_EMAC_BASE == CONFIG_EMAC1_BASE)
+               SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB));
+  printf("enabling emac1...\n");
+       /* Release the EMAC controller from reset */
+       emac1_reset_enable(0);
+#endif
+
+       /* initialize and register the emac */
+       int rval = designware_initialize(0, CONFIG_EMAC_BASE,
+					CONFIG_EPHY_PHY_ADDR,
+#if (CONFIG_PHY_INTERFACE_MODE == SOCFPGA_PHYSEL_ENUM_GMII)
+               PHY_INTERFACE_MODE_GMII);
+#elif (CONFIG_PHY_INTERFACE_MODE == SOCFPGA_PHYSEL_ENUM_MII)
+               PHY_INTERFACE_MODE_MII);
+#elif (CONFIG_PHY_INTERFACE_MODE == SOCFPGA_PHYSEL_ENUM_RGMII)
+               PHY_INTERFACE_MODE_RGMII);
+#elif (CONFIG_PHY_INTERFACE_MODE == SOCFPGA_PHYSEL_ENUM_RMII)
+               PHY_INTERFACE_MODE_RMII);
+#endif
+       printf("board_eth_init %d\n", rval);
+       return rval;
+#else
+       return 0;
+#endif
 }
diff --git a/board/bf609-ezkit/bf609-ezkit.c b/board/bf609-ezkit/bf609-ezkit.c
index 43a4330..cfc64fe 100644
--- a/board/bf609-ezkit/bf609-ezkit.c
+++ b/board/bf609-ezkit/bf609-ezkit.c
@@ -41,12 +41,12 @@ int board_eth_init(bd_t *bis)
 	if (CONFIG_DW_PORTS & 1) {
 		static const unsigned short pins[] = P_RMII0;
 		if (!peripheral_request_list(pins, "emac0"))
-			ret += designware_initialize(EMAC0_MACCFG, 0);
+			ret += designware_initialize(0, EMAC0_MACCFG, 1, 0);
 	}
 	if (CONFIG_DW_PORTS & 2) {
 		static const unsigned short pins[] = P_RMII1;
 		if (!peripheral_request_list(pins, "emac1"))
-			ret += designware_initialize(EMAC1_MACCFG, 0);
+			ret += designware_initialize(1, EMAC1_MACCFG, 1, 0);
 	}
 
 	return ret;
diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c
index 6b6bd9f..e25aba2 100644
--- a/board/spear/spear300/spear300.c
+++ b/board/spear/spear300/spear300.c
@@ -53,7 +53,8 @@ int board_eth_init(bd_t *bis)
 
 #if defined(CONFIG_DESIGNWARE_ETH)
 	u32 interface = PHY_INTERFACE_MODE_MII;
-	if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0)
+	if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY,
+				interface) >= 0)
 		ret++;
 #endif
 	return ret;
diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
index a4c6a8e..70f9aa1 100644
--- a/board/spear/spear310/spear310.c
+++ b/board/spear/spear310/spear310.c
@@ -54,7 +54,8 @@ int board_eth_init(bd_t *bis)
 
 #if defined(CONFIG_DESIGNWARE_ETH)
 	u32 interface = PHY_INTERFACE_MODE_MII;
-	if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0)
+	if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY,
+				interface) >= 0)
 		ret++;
 #endif
 #if defined(CONFIG_MACB)
diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c
index ab732a7..f6b1fdd 100644
--- a/board/spear/spear320/spear320.c
+++ b/board/spear/spear320/spear320.c
@@ -65,7 +65,8 @@ int board_eth_init(bd_t *bis)
 
 #if defined(CONFIG_DESIGNWARE_ETH)
 	u32 interface = PHY_INTERFACE_MODE_MII;
-	if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0)
+	if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY,
+				interface) >= 0)
 		ret++;
 #endif
 #if defined(CONFIG_MACB)
diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c
index 8472002..e996a0e 100644
--- a/board/spear/spear600/spear600.c
+++ b/board/spear/spear600/spear600.c
@@ -51,7 +51,8 @@ int board_eth_init(bd_t *bis)
 #if defined(CONFIG_DW_AUTONEG)
 	interface = PHY_INTERFACE_MODE_GMII;
 #endif
-	if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0)
+	if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY,
+				interface) >= 0)
 		ret++;
 #endif
 	return ret;
diff --git a/board/spear/x600/x600.c b/board/spear/x600/x600.c
index b8edfcd..044d204 100644
--- a/board/spear/x600/x600.c
+++ b/board/spear/x600/x600.c
@@ -67,32 +67,31 @@ void board_nand_init(void)
 		fsmc_nand_init(nand);
 }
 
-int board_phy_config(struct phy_device *phydev)
+int designware_board_phy_init(struct eth_device *dev, int phy_addr,
+	int (*mii_write)(struct eth_device *, u8, u8, u16),
+	int dw_reset_phy(struct eth_device *))
 {
 	/* Extended PHY control 1, select GMII */
-	phy_write(phydev, MDIO_DEVAD_NONE, 23, 0x0020);
+	mii_write(dev, phy_addr, 23, 0x0020);
 
 	/* Software reset necessary after GMII mode selction */
-	phy_reset(phydev);
+	dw_reset_phy(dev);
 
 	/* Enable extended page register access */
-	phy_write(phydev, MDIO_DEVAD_NONE, 31, 0x0001);
+	mii_write(dev, phy_addr, 31, 0x0001);
 
 	/* 17e: Enhanced LED behavior, needs to be written twice */
-	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x09ff);
-	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x09ff);
+	mii_write(dev, phy_addr, 17, 0x09ff);
+	mii_write(dev, phy_addr, 17, 0x09ff);
 
 	/* 16e: Enhanced LED method select */
-	phy_write(phydev, MDIO_DEVAD_NONE, 16, 0xe0ea);
+	mii_write(dev, phy_addr, 16, 0xe0ea);
 
 	/* Disable extended page register access */
-	phy_write(phydev, MDIO_DEVAD_NONE, 31, 0x0000);
+	mii_write(dev, phy_addr, 31, 0x0000);
 
 	/* Enable clock output pin */
-	phy_write(phydev, MDIO_DEVAD_NONE, 18, 0x0049);
-
-	if (phydev->drv->config)
-		phydev->drv->config(phydev);
+	mii_write(dev, phy_addr, 18, 0x0049);
 
 	return 0;
 }
@@ -101,7 +100,7 @@ int board_eth_init(bd_t *bis)
 {
 	int ret = 0;
 
-	if (designware_initialize(CONFIG_SPEAR_ETHBASE,
+	if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_PHY_ADDR,
 				  PHY_INTERFACE_MODE_GMII) >= 0)
 		ret++;
 
diff --git a/boards.cfg b/boards.cfg
index 221b7f8..6eebbf5 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -379,6 +379,8 @@ Active  arm         armv7          rmobile     renesas         lager
 Active  arm         armv7          s5pc1xx     samsung         goni                s5p_goni                              -                                                                                                                                 Przemyslaw Marczak <p.marczak at samsung.com>
 Active  arm         armv7          s5pc1xx     samsung         smdkc100            smdkc100                              -                                                                                                                                 Minkyu Kang <mk7.kang at samsung.com>
 Active  arm         armv7          socfpga     altera          socfpga             socfpga_cyclone5                      -                                                                                                                                 -
+Active  arm         armv7          socfpga     altera          socfpga             socfpga_virtual                      -                                                                                                                                 -
+Active  arm         armv7          socfpga     altera          socfpga             socfpga_socrates                      -                                                                                                                                 -
 Active  arm         armv7          u8500       st-ericsson     snowball            snowball                              -                                                                                                                                 Mathieu Poirier <mathieu.poirier at linaro.org>
 Active  arm         armv7          u8500       st-ericsson     u8500               u8500_href                            -                                                                                                                                 -
 Active  arm         armv7          vf610       freescale       vf610twr            vf610twr                              vf610twr:IMX_CONFIG=board/freescale/vf610twr/imximage.cfg                                                                         Alison Wang <b18965 at freescale.com>
diff --git a/common/cmd_ext2.c b/common/cmd_ext2.c
index 5a4bcc1..2675ae8 100644
--- a/common/cmd_ext2.c
+++ b/common/cmd_ext2.c
@@ -45,7 +45,7 @@ U_BOOT_CMD(
 U_BOOT_CMD(
 	ext2load,	6,	0,	do_ext2load,
 	"load binary file from a Ext2 filesystem",
-	"<interface> <dev[:part]> [addr] [filename] [bytes]\n"
+	"<interface> [<dev[:part]> [addr [filename [bytes [pos]]]]]\n"
 	"    - load binary file 'filename' from 'dev' on 'interface'\n"
 	"      to address 'addr' from ext2 filesystem."
 );
diff --git a/common/cmd_fat.c b/common/cmd_fat.c
index a12d8fa..b7e743a 100644
--- a/common/cmd_fat.c
+++ b/common/cmd_fat.c
@@ -26,7 +26,7 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 U_BOOT_CMD(
 	fatload,	7,	0,	do_fat_fsload,
 	"load binary file from a dos filesystem",
-	"<interface> [<dev[:part]>]  <addr> <filename> [bytes [pos]]\n"
+	"<interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]\n"
 	"    - Load binary file 'filename' from 'dev' on 'interface'\n"
 	"      to address 'addr' from dos filesystem.\n"
 	"      'pos' gives the file position to start loading from.\n"
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index c891ebd..c07ffb8 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -9,6 +9,9 @@
 #include <asm/io.h>
 #include "designware_i2c.h"
 
+#include <asm/arch/clock_manager.h>
+
+
 #ifdef CONFIG_I2C_MULTI_BUS
 static unsigned int bus_initialized[CONFIG_SYS_I2C_BUS_MAX];
 static unsigned int current_bus = 0;
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 78751b2..046e987 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -17,75 +17,7 @@
 #include <asm/io.h>
 #include "designware.h"
 
-#if !defined(CONFIG_PHYLIB)
-# error "DesignWare Ether MAC requires PHYLIB - missing CONFIG_PHYLIB"
-#endif
-
-static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
-{
-	struct eth_mac_regs *mac_p = bus->priv;
-	ulong start;
-	u16 miiaddr;
-	int timeout = CONFIG_MDIO_TIMEOUT;
-
-	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) |
-		  ((reg << MIIREGSHIFT) & MII_REGMSK);
-
-	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
-
-	start = get_timer(0);
-	while (get_timer(start) < timeout) {
-		if (!(readl(&mac_p->miiaddr) & MII_BUSY))
-			return readl(&mac_p->miidata);
-		udelay(10);
-	};
-
-	return -1;
-}
-
-static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
-			u16 val)
-{
-	struct eth_mac_regs *mac_p = bus->priv;
-	ulong start;
-	u16 miiaddr;
-	int ret = -1, timeout = CONFIG_MDIO_TIMEOUT;
-
-	writel(val, &mac_p->miidata);
-	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) |
-		  ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;
-
-	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
-
-	start = get_timer(0);
-	while (get_timer(start) < timeout) {
-		if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
-			ret = 0;
-			break;
-		}
-		udelay(10);
-	};
-
-	return ret;
-}
-
-static int dw_mdio_init(char *name, struct eth_mac_regs *mac_regs_p)
-{
-	struct mii_dev *bus = mdio_alloc();
-
-	if (!bus) {
-		printf("Failed to allocate MDIO bus\n");
-		return -1;
-	}
-
-	bus->read = dw_mdio_read;
-	bus->write = dw_mdio_write;
-	sprintf(bus->name, name);
-
-	bus->priv = (void *)mac_regs_p;
-
-	return mdio_register(bus);
-}
+static int configure_phy(struct eth_device *dev);
 
 static void tx_descs_init(struct eth_device *dev)
 {
@@ -170,59 +102,53 @@ static void rx_descs_init(struct eth_device *dev)
 	priv->rx_currdescnum = 0;
 }
 
-static int dw_write_hwaddr(struct eth_device *dev)
+static void descs_init(struct eth_device *dev)
 {
-	struct dw_eth_dev *priv = dev->priv;
-	struct eth_mac_regs *mac_p = priv->mac_regs_p;
-	u32 macid_lo, macid_hi;
-	u8 *mac_id = &dev->enetaddr[0];
-
-	macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) +
-		   (mac_id[3] << 24);
-	macid_hi = mac_id[4] + (mac_id[5] << 8);
-
-	writel(macid_hi, &mac_p->macaddr0hi);
-	writel(macid_lo, &mac_p->macaddr0lo);
-
-	return 0;
+	tx_descs_init(dev);
+	rx_descs_init(dev);
 }
 
-static void dw_adjust_link(struct eth_mac_regs *mac_p,
-			   struct phy_device *phydev)
+static int mac_reset(struct eth_device *dev)
 {
-	u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN;
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
 
-	if (!phydev->link) {
-		printf("%s: No link.\n", phydev->dev->name);
-		return;
-	}
+	ulong start;
+	int timeout = CONFIG_MACRESET_TIMEOUT;
 
-	if (phydev->speed != 1000)
-		conf |= MII_PORTSELECT;
+	writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);
 
-	if (phydev->speed == 100)
-		conf |= FES_100;
+	if (priv->interface != PHY_INTERFACE_MODE_RGMII)
+		writel(MII_PORTSELECT, &mac_p->conf);
 
-	if (phydev->duplex)
-		conf |= FULLDPLXMODE;
+	start = get_timer(0);
+	while (get_timer(start) < timeout) {
+		if (!(readl(&dma_p->busmode) & DMAMAC_SRST))
+			return 0;
 
-	writel(conf, &mac_p->conf);
+		/* Try again after 10usec */
+		udelay(10);
+	};
 
-	printf("Speed: %d, %s duplex%s\n", phydev->speed,
-	       (phydev->duplex) ? "full" : "half",
-	       (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
+	return -1;
 }
 
-static void dw_eth_halt(struct eth_device *dev)
+static int dw_write_hwaddr(struct eth_device *dev)
 {
 	struct dw_eth_dev *priv = dev->priv;
 	struct eth_mac_regs *mac_p = priv->mac_regs_p;
-	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+	u32 macid_lo, macid_hi;
+	u8 *mac_id = &dev->enetaddr[0];
+
+	macid_lo = mac_id[0] + (mac_id[1] << 8) + \
+		   (mac_id[2] << 16) + (mac_id[3] << 24);
+	macid_hi = mac_id[4] + (mac_id[5] << 8);
 
-	writel(readl(&mac_p->conf) & ~(RXENABLE | TXENABLE), &mac_p->conf);
-	writel(readl(&dma_p->opmode) & ~(RXSTART | TXSTART), &dma_p->opmode);
+	writel(macid_hi, &mac_p->macaddr0hi);
+	writel(macid_lo, &mac_p->macaddr0lo);
 
-	phy_shutdown(priv->phydev);
+	return 0;
 }
 
 static int dw_eth_init(struct eth_device *dev, bd_t *bis)
@@ -230,43 +156,67 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis)
 	struct dw_eth_dev *priv = dev->priv;
 	struct eth_mac_regs *mac_p = priv->mac_regs_p;
 	struct eth_dma_regs *dma_p = priv->dma_regs_p;
-	unsigned int start;
+	u32 conf;
 
-	writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);
+#if 0
+	priv->phy_configured = 1; /* HACK, use previous state */
+	priv->speed = 100;
+	priv->duplex = FULL;
+#endif
+	if (priv->phy_configured != 1) {
+		int ret = configure_phy(dev);
+		if (ret < 0) {
+			printf("failed to configure phy: %d\n", ret);
+			return ret;
+		}
+	}
 
-	start = get_timer(0);
-	while (readl(&dma_p->busmode) & DMAMAC_SRST) {
-		if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT)
-			return -1;
+	/* Print link status only once */
+	if (!priv->link_printed) {
+		printf("ENET Speed is %d Mbps - %s duplex connection\n",
+		       priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL");
+		priv->link_printed = 1;
+	}
 
-		mdelay(100);
-	};
+#if 1
+	/* Reset ethernet hardware */
+	if (mac_reset(dev) < 0)
+		return -1;
 
-	/* Soft reset above clears HW address registers.
-	 * So we have to set it here once again */
+	/* Resore the HW MAC address as it has been lost during MAC reset */
 	dw_write_hwaddr(dev);
+#endif
 
-	rx_descs_init(dev);
-	tx_descs_init(dev);
+	writel(FIXEDBURST | PRIORXTX_41 | BURST_16,
+			&dma_p->busmode);
+
+	writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD |
+		TXSECONDFRAME, &dma_p->opmode);
 
-	writel(FIXEDBURST | PRIORXTX_41 | BURST_16, &dma_p->busmode);
+	conf = FRAMEBURSTENABLE | DISABLERXOWN;
 
-	writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD,
-	       &dma_p->opmode);
+	if (priv->speed != 1000)
+		conf |= MII_PORTSELECT;
 
-	writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode);
+	if ((priv->interface != PHY_INTERFACE_MODE_MII) &&
+		(priv->interface != PHY_INTERFACE_MODE_GMII)) {
 
-	/* Start up the PHY */
-	if (phy_startup(priv->phydev)) {
-		printf("Could not initialize PHY %s\n",
-		       priv->phydev->dev->name);
-		return -1;
+		if (priv->speed == 100)
+			conf |= FES_100;
 	}
 
-	dw_adjust_link(mac_p, priv->phydev);
+	if (priv->duplex == FULL)
+		conf |= FULLDPLXMODE;
 
-	if (!priv->phydev->link)
-		return -1;
+	writel(conf, &mac_p->conf);
+
+	descs_init(dev);
+
+	/*
+	 * Start/Enable xfer at dma as well as mac level
+	 */
+	writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode);
+	writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode);
 
 	writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);
 
@@ -376,36 +326,297 @@ static int dw_eth_recv(struct eth_device *dev)
 	return length;
 }
 
-static int dw_phy_init(struct eth_device *dev)
+static void dw_eth_halt(struct eth_device *dev)
 {
 	struct dw_eth_dev *priv = dev->priv;
-	struct phy_device *phydev;
-	int mask = 0xffffffff;
 
-#ifdef CONFIG_PHY_ADDR
-	mask = 1 << CONFIG_PHY_ADDR;
+	mac_reset(dev);
+	priv->tx_currdescnum = priv->rx_currdescnum = 0;
+}
+
+static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	ulong start;
+	u32 miiaddr;
+	int timeout = CONFIG_MDIO_TIMEOUT;
+
+	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
+		  ((reg << MIIREGSHIFT) & MII_REGMSK);
+
+	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+	start = get_timer(0);
+	while (get_timer(start) < timeout) {
+		if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
+			*val = readl(&mac_p->miidata);
+			return 0;
+		}
+ 
+		/* Try again after 10usec */
+		udelay(10);
+	};
+
+	return -1;
+}
+
+static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	ulong start;
+	u32 miiaddr;
+	int ret = -1, timeout = CONFIG_MDIO_TIMEOUT;
+	u16 value;
+
+	printf("eth_mdio_write %lx\n", &mac_p->miidata);
+
+	writel(val, &mac_p->miidata);
+	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
+		  ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;
+
+	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+	start = get_timer(0);
+	while (get_timer(start) < timeout) {
+		if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
+			ret = 0;
+			break;
+		}
+
+		/* Try again after 10usec */
+		udelay(10);
+	};
+
+	/* Needed as a fix for ST-Phy */
+	eth_mdio_read(dev, addr, reg, &value);
+
+	return ret;
+}
+
+#if defined(CONFIG_DW_SEARCH_PHY)
+static int find_phy(struct eth_device *dev)
+{
+	int phy_addr = 0;
+	u16 ctrl, oldctrl;
+
+	do {
+	  printf("Searching at %d\n", phy_addr);
+		eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl);
+		oldctrl = ctrl & BMCR_ANENABLE;
+
+		ctrl ^= BMCR_ANENABLE;
+		eth_mdio_write(dev, phy_addr, MII_BMCR, ctrl);
+		eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl);
+		ctrl &= BMCR_ANENABLE;
+
+		if (ctrl == oldctrl) {
+			phy_addr++;
+		} else {
+			ctrl ^= BMCR_ANENABLE;
+			eth_mdio_write(dev, phy_addr, MII_BMCR, ctrl);
+	  printf("Found at %d\n", phy_addr);
+
+			return phy_addr;
+		}
+	} while (phy_addr < 32);
+
+	return -1;
+}
 #endif
 
-	phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
-	if (!phydev)
+static int dw_reset_phy(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	u16 ctrl;
+	ulong start;
+	int timeout = CONFIG_PHYRESET_TIMEOUT;
+	u32 phy_addr = priv->address;
+
+	eth_mdio_write(dev, phy_addr, MII_BMCR, BMCR_RESET);
+
+	start = get_timer(0);
+	while (get_timer(start) < timeout) {
+		eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl);
+		if (!(ctrl & BMCR_RESET))
+			break;
+
+		/* Try again after 10usec */
+		udelay(10);
+	};
+
+	if (get_timer(start) >= CONFIG_PHYRESET_TIMEOUT) {
+		printf("timed out waiting for phy reset %x\n", ctrl);
 		return -1;
+	}
 
-	phy_connect_dev(phydev, dev);
+	//	phydev->supported &= PHY_GBIT_FEATURES;
+#ifdef CONFIG_PHY_RESET_DELAY
+	udelay(CONFIG_PHY_RESET_DELAY);
+#endif
+	return 0;
+}
 
-	phydev->supported &= PHY_GBIT_FEATURES;
-	phydev->advertising = phydev->supported;
+/*
+ * Add weak default function for board specific PHY configuration
+ */
+int __weak designware_board_phy_init(struct eth_device *dev, int phy_addr,
+		int (*mii_write)(struct eth_device *, u8, u8, u16),
+		int dw_reset_phy(struct eth_device *))
+{
+	return 0;
+}
+ 
+static int configure_phy(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	int phy_addr;
+	u16 bmcr;
+#if defined(CONFIG_DW_AUTONEG)
+	u16 bmsr;
+	u32 timeout;
+	ulong start;
+#endif
 
-	priv->phydev = phydev;
-	phy_config(phydev);
+	cm_print_clock_quick_summary();
 
-	return 1;
+	printf("version emac0: %x\n", readl(0xff700020));
+	printf("version emac1: %x\n", readl(0xff702020));
+	
+	/* Oops, these do not seem to work even when rest of hw works ok */
+	printf("time since boot emac0: %d\n", readl(0xff700708));
+	printf("time since boot emac1: %d\n", readl(0xff702708));
+
+	printf("emac1 clk: %d\n", readl(0xFFD0408C));
+	/* Should contain:
+
+	   CLKMGR_PERPLLGRP_EMAC1CLK_CNT_SET(
+	   	CONFIG_HPS_PERPLLGRP_EMAC1CLK_CNT),
+  ==
+	   	CONFIG_HPS_PERPLLGRP_EMAC1CLK_CNT) << 0
+
+		== 3. ok. 
+	*/
+
+
+	printf("clocks for drivers\n");
+	cm_derive_clocks_for_drivers();
+
+	printf("configure_phy\n");
+
+#if defined(CONFIG_DW_SEARCH_PHY)
+	printf("finding phy\n");
+	phy_addr = find_phy(dev);
+	if (phy_addr >= 0)
+		priv->address = phy_addr;
+	else
+		return -1;
+#else
+	phy_addr = priv->address;
+#endif
+
+	/*
+	 * Some boards need board specific PHY initialization. This is
+	 * after the main driver init code but before the auto negotiation
+	 * is run.
+	 */
+	if (designware_board_phy_init(dev, phy_addr,
+				      eth_mdio_write, dw_reset_phy) < 0)
+		return -1;
+
+#if 1 /* FIXME: maybe we don't need to configure phy, previous u-boot should have done that? */
+#if 1
+	if (dw_reset_phy(dev) < 0)
+		return -1;
+#endif
+
+#if defined(CONFIG_DW_AUTONEG)
+	/* Set Auto-Neg Advertisement capabilities to 10/100 half/full */
+	eth_mdio_write(dev, phy_addr, MII_ADVERTISE, 0x1E1);
+
+	bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
+#else
+	bmcr = BMCR_SPEED100 | BMCR_FULLDPLX;
+
+#if defined(CONFIG_DW_SPEED10M)
+	bmcr &= ~BMCR_SPEED100;
+#endif
+#if defined(CONFIG_DW_DUPLEXHALF)
+	bmcr &= ~BMCR_FULLDPLX;
+#endif
+#endif
+	if (eth_mdio_write(dev, phy_addr, MII_BMCR, bmcr) < 0)
+		return -1;
+
+	/* Read the phy status register and populate priv structure */
+#if defined(CONFIG_DW_AUTONEG)
+	timeout = CONFIG_AUTONEG_TIMEOUT;
+	start = get_timer(0);
+	puts("Waiting for PHY auto negotiation to complete");
+	while (get_timer(start) < timeout) {
+		eth_mdio_read(dev, phy_addr, MII_BMSR, &bmsr);
+		if (bmsr & BMSR_ANEGCOMPLETE) {
+			priv->phy_configured = 1;
+			break;
+		}
+
+		/* Print dot all 1s to show progress */
+		if ((get_timer(start) % 1000) == 0)
+			putc('.');
+
+		/* Try again after 1msec */
+		udelay(1000);
+	};
+
+	if (!(bmsr & BMSR_ANEGCOMPLETE))
+		puts(" TIMEOUT!\n");
+	else
+		puts(" done\n");
+#else
+	priv->phy_configured = 1;
+#endif
+#endif
+
+#ifndef CONFIG_MII
+#error Need config_phy
+#endif
+	priv->speed = miiphy_speed(dev->name, phy_addr);
+	priv->duplex = miiphy_duplex(dev->name, phy_addr);
+
+	return 0;
+}
+
+#if defined(CONFIG_MII)
+static int dw_mii_read(const char *devname, u8 addr, u8 reg, u16 *val)
+{
+	struct eth_device *dev;
+
+	dev = eth_get_dev_by_name(devname);
+	if (dev)
+		eth_mdio_read(dev, addr, reg, val);
+
+	return 0;
 }
 
-int designware_initialize(ulong base_addr, u32 interface)
+static int dw_mii_write(const char *devname, u8 addr, u8 reg, u16 val)
+{
+	struct eth_device *dev;
+
+	dev = eth_get_dev_by_name(devname);
+	if (dev)
+		eth_mdio_write(dev, addr, reg, val);
+
+	return 0;
+}
+#endif
+ 
+int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface)
 {
 	struct eth_device *dev;
 	struct dw_eth_dev *priv;
 
+	printf("dw_initalize\n");
 	dev = (struct eth_device *) malloc(sizeof(struct eth_device));
 	if (!dev)
 		return -ENOMEM;
@@ -423,14 +634,20 @@ int designware_initialize(ulong base_addr, u32 interface)
 	memset(dev, 0, sizeof(struct eth_device));
 	memset(priv, 0, sizeof(struct dw_eth_dev));
 
-	sprintf(dev->name, "dwmac.%lx", base_addr);
+	sprintf(dev->name, "mii%d", id);
 	dev->iobase = (int)base_addr;
 	dev->priv = priv;
 
+	printf("Get address\n");
+	eth_getenv_enetaddr_by_index("eth", id, &dev->enetaddr[0]);
+
 	priv->dev = dev;
 	priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
 	priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
 			DW_DMA_BASE_OFFSET);
+	priv->address = phy_addr;
+	priv->phy_configured = 0;
+	priv->interface = interface;
 
 	dev->init = dw_eth_init;
 	dev->send = dw_eth_send;
@@ -438,12 +655,13 @@ int designware_initialize(ulong base_addr, u32 interface)
 	dev->halt = dw_eth_halt;
 	dev->write_hwaddr = dw_write_hwaddr;
 
+	printf("Get eth register\n");
 	eth_register(dev);
 
-	priv->interface = interface;
+#if defined(CONFIG_MII)
+	printf("Get eth miiphy_register\n");
 
-	dw_mdio_init(dev->name, priv->mac_regs_p);
-	priv->bus = miiphy_get_dev_by_name(dev->name);
-
-	return dw_phy_init(dev);
+	miiphy_register(dev->name, dw_mii_read, dw_mii_write);
+#endif
+	return 1;
 }
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index 382b0c7..60b1103 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -16,6 +16,8 @@
 
 #define CONFIG_MACRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
 #define CONFIG_MDIO_TIMEOUT	(3 * CONFIG_SYS_HZ)
+#define CONFIG_PHYRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
+#define CONFIG_AUTONEG_TIMEOUT	(5 * CONFIG_SYS_HZ)
 
 struct eth_mac_regs {
 	u32 conf;		/* 0x00 */
@@ -215,9 +217,14 @@ struct dmamacdescr {
 #endif
 
 struct dw_eth_dev {
+	u32 address;
 	u32 interface;
+	u32 speed;
+	u32 duplex;
 	u32 tx_currdescnum;
 	u32 rx_currdescnum;
+	u32 phy_configured;
+	u32 link_printed;
 
 	struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
 	struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM];
@@ -229,8 +236,15 @@ struct dw_eth_dev {
 	struct eth_dma_regs *dma_regs_p;
 
 	struct eth_device *dev;
-	struct phy_device *phydev;
-	struct mii_dev *bus;
 };
 
+/* Speed specific definitions */
+#define SPEED_10M		1
+#define SPEED_100M		2
+#define SPEED_1000M		3
+
+/* Duplex mode specific definitions */
+#define HALF_DUPLEX		1
+#define FULL_DUPLEX		2
+
 #endif
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 5d7e3be..506efb2 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -53,6 +53,8 @@ static struct phy_driver KS8721_driver = {
 static int ksz90xx_startup(struct phy_device *phydev)
 {
 	unsigned phy_ctl;
+
+	printf("ksz90xx_startup\n");
 	genphy_update_link(phydev);
 	phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
 
@@ -215,6 +217,7 @@ static struct phy_driver ksz9031_driver = {
 
 int phy_micrel_init(void)
 {
+  printf("phy_micrel_init\n");
 	phy_register(&KSZ804_driver);
 #ifdef CONFIG_PHY_MICREL_KSZ9021
 	phy_register(&ksz9021_driver);
diff --git a/fs/fs.c b/fs/fs.c
index 79d432d..ea15c5f 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -276,6 +276,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 	unsigned long pos;
 	int len_read;
 	unsigned long time;
+	char *ep;
 
 	if (argc < 2)
 		return CMD_RET_USAGE;
@@ -286,7 +287,9 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 		return 1;
 
 	if (argc >= 4) {
-		addr = simple_strtoul(argv[3], NULL, 16);
+		addr = simple_strtoul(argv[3], &ep, 16);
+		if (ep == argv[3] || *ep != '\0')
+			return CMD_RET_USAGE;
 	} else {
 		addr_str = getenv("loadaddr");
 		if (addr_str != NULL)
diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h
index 12192ff..1a43e1b 100644
--- a/include/configs/bf609-ezkit.h
+++ b/include/configs/bf609-ezkit.h
@@ -72,13 +72,12 @@
 #define CONFIG_NET_MULTI
 #define CONFIG_HOSTNAME		"bf609-ezkit"
 #define CONFIG_DESIGNWARE_ETH
-#define CONFIG_PHY_ADDR		1
 #define CONFIG_DW_PORTS		1
+#define CONFIG_DW_AUTONEG
 #define CONFIG_DW_ALTDESCRIPTOR
 #define CONFIG_CMD_NET
 #define CONFIG_CMD_MII
 #define CONFIG_MII
-#define CONFIG_PHYLIB
 
 /* i2c Settings */
 #define CONFIG_BFIN_TWI_I2C
diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h
new file mode 100644
index 0000000..0cad725
--- /dev/null
+++ b/include/configs/socfpga_common.h
@@ -0,0 +1,301 @@
+/*
+ *  Copyright (C) 2012 Altera Corporation <www.altera.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef __CONFIG_COMMON_H
+#define __CONFIG_COMMON_H
+
+#include <asm/arch/socfpga_base_addrs.h>
+#include "../../board/altera/socfpga/pinmux_config.h"
+#include "../../board/altera/socfpga/pll_config.h"
+
+/*
+ * High level configuration
+ */
+
+#define CONFIG_SYS_GENERIC_BOARD
+
+#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.
+ */
+#define CONFIG_SYS_NO_FLASH
+#include <config_cmd_default.h>
+/* FAT file system support */
+#define CONFIG_CMD_FAT
+
+
+/*
+ * Misc
+ */
+#define CONFIG_DOS_PARTITION            1
+
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_PARTITIONS
+#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 at 0x0"
+
+#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" \
+	"fdt_addr=100\0" \
+	"fsloadcmd=ext2load\0" \
+		"bootm ${loadaddr} - ${fdt_addr}\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
+
+/* 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			57600
+
+/*
+ * 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		2400
+#else
+#define CONFIG_SYS_TIMER_RATE		25000000
+#endif
+#define CONFIG_SYS_TIMER_COUNTER	(CONFIG_SYS_TIMERBASE + 0x4)
+
+#define CONFIG_TIMER_CLOCK_KHZ         (CONFIG_HPS_CLK_OSC1_HZ / 1000)
+
+#define CONFIG_ENV_IS_NOWHERE
+
+/*
+ * I2C support
+ */
+#define SOCFPGA_I2C0_ADDRESS 0xffc04000
+
+/* FIXME */
+#define CONFIG_HARD_I2C
+#ifdef CONFIG_HARD_I2C
+#define CONFIG_DW_I2C
+#define CONFIG_SYS_I2C_BASE            SOCFPGA_I2C0_ADDRESS
+/* using standard mode which the speed up to 100Kb/s) */
+#define CONFIG_SYS_I2C_SPEED           (100000)
+/* address of device when used as slave */
+#define CONFIG_SYS_I2C_SLAVE           (0x02)
+/* clock supplied to I2C controller in unit of MHz */
+#define IC_CLK                         (cm_l4_sp_clock / 1000000)
+#define CONFIG_CMD_I2C
+#endif
+
+/*
+ * 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
+/* 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 */
+
+/*
+ * SPL "Second Program Loader" aka Initial Software
+ */
+
+/* Enable building of SPL globally */
+#define CONFIG_SPL
+#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
+
+#endif	/* __CONFIG_COMMON_H */
diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5.h
index 0254249..d5d59d2 100644
--- a/include/configs/socfpga_cyclone5.h
+++ b/include/configs/socfpga_cyclone5.h
@@ -1,240 +1,16 @@
 /*
- *  Copyright (C) 2012 Altera Corporation <www.altera.com>
+ *  Copyright (C) 2014 Pavel Machek <pavel at denx.de>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
-#include <asm/arch/socfpga_base_addrs.h>
-#include "../../board/altera/socfpga/pinmux_config.h"
-#include "../../board/altera/socfpga/pll_config.h"
-
-/*
- * High level configuration
- */
 /* Virtual target or real hardware */
-#define 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.
- */
-#define CONFIG_SYS_NO_FLASH
-#include <config_cmd_default.h>
-/* FAT file system support */
-#define CONFIG_CMD_FAT
-
-
-/*
- * Misc
- */
-#define CONFIG_DOS_PARTITION            1
-
-#ifdef CONFIG_SPL_BUILD
-#undef CONFIG_PARTITIONS
-#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 at 0x0"
-
-#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" \
-	"fdt_addr=100\0" \
-	"fsloadcmd=ext2load\0" \
-		"bootm ${loadaddr} - ${fdt_addr}\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
-
-/* 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_COUNTER	(CONFIG_SYS_TIMERBASE + 0x4)
-
-#define CONFIG_ENV_IS_NOWHERE
-
-/*
- * SPL "Second Program Loader" aka Initial Software
- */
-
-/* Enable building of SPL globally */
-#define CONFIG_SPL
-#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
+#undef CONFIG_SOCFPGA_VIRTUAL_TARGET
 
-/* Linker script for SPL */
-#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/socfpga/u-boot-spl.lds"
+#include <configs/socfpga_common.h>
 
-/* 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
+#define ALTERA_BOARD_NAME "Altera SOCFPGA Cyclone5 Board"
 
-#endif	/* __CONFIG_H */
+#endif /* __CONFIG_H */
diff --git a/include/configs/socfpga_socrates.h b/include/configs/socfpga_socrates.h
new file mode 100644
index 0000000..27e0261
--- /dev/null
+++ b/include/configs/socfpga_socrates.h
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (C) 2014 Pavel Machek <pavel at denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* Virtual target or real hardware */
+#undef CONFIG_SOCFPGA_VIRTUAL_TARGET
+
+#include <configs/socfpga_common.h>
+
+#define ALTERA_BOARD_NAME "EBV SoCrates - Cyclone V SoC FPGA Board"
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/socfpga_virtual.h b/include/configs/socfpga_virtual.h
new file mode 100644
index 0000000..cf871e2
--- /dev/null
+++ b/include/configs/socfpga_virtual.h
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (C) 2014 Pavel Machek <pavel at denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* Virtual target or real hardware */
+#define CONFIG_SOCFPGA_VIRTUAL_TARGET
+
+#include <configs/socfpga_common.h>
+
+#define ALTERA_BOARD_NAME "SOCFPGA Virtual Board"
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index c0eba37..55f100a 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
@@ -17,9 +17,11 @@
 /* Ethernet driver configuration */
 #define CONFIG_MII
 #define CONFIG_DESIGNWARE_ETH
+#define CONFIG_DW_SEARCH_PHY
+#define CONFIG_DW0_PHY				1
 #define CONFIG_NET_MULTI
-#define CONFIG_PHYLIB
 #define CONFIG_PHY_RESET_DELAY			10000		/* in usec */
+#define CONFIG_DW_AUTONEG
 #define CONFIG_PHY_GIGE			/* Include GbE speed/duplex detection */
 
 /* USBD driver configuration */
diff --git a/include/configs/spear6xx_evb.h b/include/configs/spear6xx_evb.h
index 28dddcc..7f4dc58 100644
--- a/include/configs/spear6xx_evb.h
+++ b/include/configs/spear6xx_evb.h
@@ -37,9 +37,6 @@
 #define CONFIG_SYS_FSMC_NAND_8BIT
 #define CONFIG_SYS_NAND_BASE			0xD2000000
 
-/* Ethernet PHY configuration */
-#define CONFIG_PHY_NATSEMI
-
 /* Environment Settings */
 #define CONFIG_EXTRA_ENV_SETTINGS              CONFIG_EXTRA_ENV_USBTTY
 
diff --git a/include/netdev.h b/include/netdev.h
index e211f18..72a0503 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -36,7 +36,7 @@ int calxedaxgmac_initialize(u32 id, ulong base_addr);
 int cs8900_initialize(u8 dev_num, int base_addr);
 int davinci_emac_initialize(void);
 int dc21x4x_initialize(bd_t *bis);
-int designware_initialize(ulong base_addr, u32 interface);
+int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface);
 int dm9000_initialize(bd_t *bis);
 int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr);
 int e1000_initialize(bd_t *bis);
diff --git a/mkit b/mkit
new file mode 100755
index 0000000..903b059
--- /dev/null
+++ b/mkit
@@ -0,0 +1,9 @@
+#!/bin/bash
+eval ` eldk-switch.sh -r 5.2 armv7a`
+#make mrproper socfpga_cyclone5_config
+#make mrproper socfpga_socrates_config
+make u-boot.img && \
+cp u-boot.bin /tftpboot/wagabuibui
+# u-boot SPL does not compile for wagabuibui
+# make spl/u-boot-spl.bin && \
+# scp u-boot.bin pavel at pollux.denx.de:~/mainline-altera/boot
diff --git a/net/bootp.c b/net/bootp.c
index 189a003..9d7f97c 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -623,9 +623,7 @@ BootpRequest(void)
 		rand_ms = rand() >> 19;
 
 	printf("Random delay: %ld ms...\n", rand_ms);
-	for (i = 0; i < rand_ms; i++)
-		udelay(1000); /*Wait 1ms*/
-
+	mdelay(rand_ms);
 #endif	/* CONFIG_BOOTP_RANDOM_DELAY */
 
 	printf("BOOTP broadcast %d\n", ++BootpTry);
diff --git a/run b/run
new file mode 100755
index 0000000..de28b29
--- /dev/null
+++ b/run
@@ -0,0 +1 @@
+./mkit && ../eldk/atest.py -w wagabuibui


-- 
(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