From faae41bf9ff800696c7f2e6761157d34065cef3c Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Sun, 29 Sep 2013 17:40:31 +0800 Subject: ENGR00281804 ARM: imx6: init enet MAC address Enet get MAC address order: From module parameters or kernel command line -> device tree -> pfuse -> mac registers set by bootloader -> random mac address. When there have no "fec.macaddr" parameters set in kernel command line, enet driver get MAC address from device tree. And then if the MAC address set in device tree and is valid, enet driver get MAC address from device tree. Otherwise,enet get MAC address from pfuse. So, in the condition, update the MAC address (read from pfuse) to device tree. Signed-off-by: Fugang Duan --- arch/arm/mach-imx/common.h | 1 + arch/arm/mach-imx/mach-imx6q.c | 70 +++++++++++++++++++++++++++++++++++++++-- arch/arm/mach-imx/mach-imx6sl.c | 7 ++++- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 36647133e3e6..ac2251da4316 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -147,6 +147,7 @@ extern void imx_anatop_pu_enable(bool enable); extern int imx6_set_lpm(enum mxc_cpu_pwr_mode mode); extern void imx6_set_cache_lpm_in_wait(bool enable); extern void imx6sl_set_wait_clk(bool enter); +extern void imx6_enet_mac_init(const char *compatible); extern void imx_cpu_die(unsigned int cpu); extern int imx_cpu_kill(unsigned int cpu); diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 72b4d9fbc5d3..74767851e74e 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -253,6 +254,72 @@ static void __init imx6q_lvds_cabc_init(void) } } +#define OCOTP_MACn(n) (0x00000620 + (n) * 0x10) +void __init imx6_enet_mac_init(const char *compatible) +{ + struct device_node *ocotp_np, *enet_np; + void __iomem *base; + struct property *newmac; + u32 macaddr_low, macaddr_high; + u8 *macaddr; + + enet_np = of_find_compatible_node(NULL, NULL, compatible); + if (!enet_np) + return; + + if (of_get_mac_address(enet_np)) + goto put_enet_node; + + ocotp_np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp"); + if (!ocotp_np) { + pr_warn("failed to find ocotp node\n"); + goto put_enet_node; + } + + base = of_iomap(ocotp_np, 0); + if (!base) { + pr_warn("failed to map ocotp\n"); + goto put_ocotp_node; + } + + macaddr_high = readl_relaxed(base + OCOTP_MACn(0)); + macaddr_low = readl_relaxed(base + OCOTP_MACn(1)); + + newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL); + if (!newmac) + goto put_ocotp_node; + + newmac->value = newmac + 1; + newmac->length = 6; + newmac->name = kstrdup("local-mac-address", GFP_KERNEL); + if (!newmac->name) { + kfree(newmac); + goto put_ocotp_node; + } + + macaddr = newmac->value; + macaddr[5] = macaddr_high & 0xff; + macaddr[4] = (macaddr_high >> 8) & 0xff; + macaddr[3] = (macaddr_high >> 16) & 0xff; + macaddr[2] = (macaddr_high >> 24) & 0xff; + macaddr[1] = macaddr_low & 0xff; + macaddr[0] = (macaddr_low >> 8) & 0xff; + + of_update_property(enet_np, newmac); + +put_ocotp_node: + of_node_put(ocotp_np); +put_enet_node: + of_node_put(enet_np); +} + +static inline void imx6q_enet_init(void) +{ + imx6_enet_mac_init("fsl,imx6q-fec"); + imx6q_enet_phy_init(); + imx6q_1588_init(); +} + static void __init imx6q_init_machine(void) { struct device *parent; @@ -261,13 +328,12 @@ static void __init imx6q_init_machine(void) if (parent == NULL) pr_warn("failed to initialize soc device\n"); - imx6q_enet_phy_init(); + imx6q_enet_init(); of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); imx_anatop_init(); imx6_pm_init(); - imx6q_1588_init(); imx6q_csi_mux_init(); imx6q_lvds_cabc_init(); } diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c index 4265f1105b51..caf3b8116bf6 100644 --- a/arch/arm/mach-imx/mach-imx6sl.c +++ b/arch/arm/mach-imx/mach-imx6sl.c @@ -83,7 +83,7 @@ soft: soft_restart(0); } -static void __init imx6sl_fec_init(void) +static void __init imx6sl_fec_clk_init(void) { struct regmap *gpr; @@ -96,7 +96,12 @@ static void __init imx6sl_fec_init(void) IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0); } else pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n"); +} +static inline void imx6sl_fec_init(void) +{ + imx6sl_fec_clk_init(); + imx6_enet_mac_init("fsl,imx6sl-fec"); } static void __init imx6sl_init_machine(void) -- cgit v1.2.2