MLK-9694 ARM: imx6: init enet MAC address
authorFugang Duan <b38611@freescale.com>
Wed, 15 Oct 2014 01:36:40 +0000 (09:36 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:46:51 +0000 (14:46 -0500)
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 MAarch/arm/mach-imx
/mach-imx6q.cC address from
pfuse. So, in the condition, update the MAC address (read from pfuse)
to device tree.

Cherry-pick & Merge patches from:
149ac988a25b8d8eb86d05679cbb7b42819ff7a1 &
3269e5c06bdb2f7ab9bd5afa9bbfe46d872197d3

Signed-off-by: Fugang Duan <B38611@freescale.com>
arch/arm/mach-imx/common.h
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mach-imx6sl.c
arch/arm/mach-imx/mach-imx6sx.c
arch/arm/mach-imx/mach-imx7d.c

index d971663..962eb48 100644 (file)
@@ -112,6 +112,7 @@ void imx_anatop_post_resume(void);
 int imx6_set_lpm(enum mxc_cpu_pwr_mode mode);
 void imx6_set_int_mem_clk_lpm(bool enable);
 void imx6sl_set_wait_clk(bool enter);
+void imx6_enet_mac_init(const char *enet_compat, const char *ocotp_compat);
 int imx_mmdc_get_ddr_type(void);
 int imx_ddrc_get_ddr_type(void);
 void imx_cpu_die(unsigned int cpu);
index 45801b2..c63e6f6 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/micrel_phy.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of_net.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/system_misc.h>
@@ -262,6 +263,91 @@ static void __init imx6q_axi_init(void)
        }
 }
 
+#define OCOTP_MACn(n)  (0x00000620 + (n) * 0x10)
+void __init imx6_enet_mac_init(const char *enet_compat, const char *ocotp_compat)
+{
+       struct device_node *ocotp_np, *enet_np, *from = NULL;
+       void __iomem *base;
+       struct property *newmac;
+       u32 macaddr_low;
+       u32 macaddr_high = 0;
+       u32 macaddr1_high = 0;
+       u8 *macaddr;
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               enet_np = of_find_compatible_node(from, NULL, enet_compat);
+               if (!enet_np)
+                       return;
+
+               from = enet_np;
+
+               if (of_get_mac_address(enet_np))
+                       goto put_enet_node;
+
+               ocotp_np = of_find_compatible_node(NULL, NULL, ocotp_compat);
+               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_low = readl_relaxed(base + OCOTP_MACn(1));
+               if (i)
+                       macaddr1_high = readl_relaxed(base + OCOTP_MACn(2));
+               else
+                       macaddr_high = readl_relaxed(base + OCOTP_MACn(0));
+
+               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;
+               if (i) {
+                       macaddr[5] = (macaddr_low >> 16) & 0xff;
+                       macaddr[4] = (macaddr_low >> 24) & 0xff;
+                       macaddr[3] = macaddr1_high & 0xff;
+                       macaddr[2] = (macaddr1_high >> 8) & 0xff;
+                       macaddr[1] = (macaddr1_high >> 16) & 0xff;
+                       macaddr[0] = (macaddr1_high >> 24) & 0xff;
+               } else {
+                       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", "fsl,imx6q-ocotp");
+       imx6q_enet_phy_init();
+       imx6q_1588_init();
+}
+
 static void __init imx6q_init_machine(void)
 {
        struct device *parent;
@@ -276,13 +362,11 @@ static void __init imx6q_init_machine(void)
        if (parent == NULL)
                pr_warn("failed to initialize soc device\n");
 
-       imx6q_enet_phy_init();
-
        of_platform_default_populate(NULL, NULL, parent);
 
+       imx6q_enet_init();
        imx_anatop_init();
        cpu_is_imx6q() ?  imx6q_pm_init() : imx6dl_pm_init();
-       imx6q_1588_init();
        imx6q_axi_init();
 }
 
index 0408490..4ed2fb8 100644 (file)
@@ -19,7 +19,7 @@
 #include "common.h"
 #include "cpuidle.h"
 
-static void __init imx6sl_fec_init(void)
+static void __init imx6sl_fec_clk_init(void)
 {
        struct regmap *gpr;
 
@@ -30,9 +30,14 @@ static void __init imx6sl_fec_init(void)
                        IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK, 0);
                regmap_update_bits(gpr, IOMUXC_GPR1,
                        IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0);
-       } else {
+       } 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", "fsl,imx6sl-ocotp");
 }
 
 static void __init imx6sl_init_late(void)
index 7f52d9b..bd264c4 100644 (file)
@@ -60,6 +60,7 @@ static void __init imx6sx_enet_clk_sel(void)
 
 static inline void imx6sx_enet_init(void)
 {
+       imx6_enet_mac_init("fsl,imx6sx-fec", "fsl,imx6sx-ocotp");
        imx6sx_enet_phy_init();
        imx6sx_enet_clk_sel();
 }
index 8b9b8cb..fd04c4a 100644 (file)
@@ -81,6 +81,7 @@ static void __init imx7d_enet_clk_sel(void)
 
 static inline void imx7d_enet_init(void)
 {
+       imx6_enet_mac_init("fsl,imx7d-fec", "fsl,imx7d-ocotp");
        imx7d_enet_phy_init();
        imx7d_enet_clk_sel();
 }