diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2013-10-07 08:00:36 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-10-07 08:00:36 +0200 |
commit | 01f37a992fa54669c01674d61ade04e0e50464b1 (patch) | |
tree | a4931b19293f2c27353ebee8b0c746f03d994108 /arch/arm/boards/animeo_ip/init.c | |
parent | 71fbdfbb1321de894f6938f5e471f86d728eab2e (diff) | |
parent | 7ccaaf71fe84f090b359d8d21e76aaff84d295f0 (diff) | |
download | barebox-01f37a992fa54669c01674d61ade04e0e50464b1.tar.gz barebox-01f37a992fa54669c01674d61ade04e0e50464b1.tar.xz |
Merge branch 'for-next/net'
Conflicts:
arch/arm/boards/animeo_ip/init.c
Diffstat (limited to 'arch/arm/boards/animeo_ip/init.c')
-rw-r--r-- | arch/arm/boards/animeo_ip/init.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/arch/arm/boards/animeo_ip/init.c b/arch/arm/boards/animeo_ip/init.c index e99acd008b..81a8cdf210 100644 --- a/arch/arm/boards/animeo_ip/init.c +++ b/arch/arm/boards/animeo_ip/init.c @@ -19,6 +19,7 @@ #include <nand.h> #include <sizes.h> #include <linux/mtd/nand.h> +#include <linux/clk.h> #include <mach/board.h> #include <mach/at91sam9_smc.h> #include <gpio.h> @@ -26,6 +27,7 @@ #include <mach/io.h> #include <mach/at91_pmc.h> #include <mach/at91_rstc.h> +#include <local_mac_address.h> static bool animeo_ip_is_buco; static bool animeo_ip_is_io; @@ -226,12 +228,79 @@ static void animeo_ip_power_control(void) animeo_export_gpio_out(AT91_PIN_PC4, "power_save"); } +static void animeo_ip_phy_reset(void) +{ + unsigned long rstc; + int i; + struct clk *clk = clk_get(NULL, "macb_clk"); + + clk_enable(clk); + + for (i = AT91_PIN_PA12; i <= AT91_PIN_PA29; i++) + at91_set_gpio_input(i, 0); + + rstc = at91_sys_read(AT91_RSTC_MR) & AT91_RSTC_ERSTL; + + /* Need to reset PHY -> 500ms reset */ + at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY | + (AT91_RSTC_ERSTL & (0x0d << 8)) | + AT91_RSTC_URSTEN); + + at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_EXTRST); + + /* Wait for end hardware reset */ + while (!(at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_NRSTL)) + ; + + /* Restore NRST value */ + at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY | (rstc) | AT91_RSTC_URSTEN); +} + +#define MACB_SA1B 0x0098 +#define MACB_SA1T 0x009c + +static int animeo_ip_get_macb_ethaddr(u8 *addr) +{ + u32 top, bottom; + void __iomem *base = IOMEM(AT91SAM9260_BASE_EMAC); + + bottom = readl(base + MACB_SA1B); + top = readl(base + MACB_SA1T); + addr[0] = bottom & 0xff; + addr[1] = (bottom >> 8) & 0xff; + addr[2] = (bottom >> 16) & 0xff; + addr[3] = (bottom >> 24) & 0xff; + addr[4] = top & 0xff; + addr[5] = (top >> 8) & 0xff; + + /* valid and not private */ + if (is_valid_ether_addr(addr) && !(addr[0] & 0x02)) + return 0; + + return -EINVAL; +} + +static void animeo_ip_add_device_eth(void) +{ + u8 enetaddr[6]; + + if (!animeo_ip_get_macb_ethaddr(enetaddr)) + eth_register_ethaddr(0, enetaddr); + else + local_mac_address_register(0, "smf"); + + /* for usb asix */ + local_mac_address_register(1, "smf"); + + animeo_ip_phy_reset(); + at91_add_device_eth(0, &macb_pdata); +} + static int animeo_ip_devices_init(void) { animeo_ip_detect_version(); animeo_ip_power_control(); animeo_ip_add_device_nand(); - at91_add_device_eth(0, &macb_pdata); animeo_ip_add_device_usb(); animeo_ip_add_device_mci(); animeo_ip_add_device_buttons(); @@ -251,6 +320,8 @@ static int animeo_ip_devices_init(void) devfs_add_partition("nand0", SZ_256K + SZ_32K, SZ_32K, DEVFS_PARTITION_FIXED, "env_raw"); dev_add_bb_dev("env_raw", "env0"); + animeo_ip_add_device_eth(); + return 0; } |