summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFugang Duan <b38611@freescale.com>2014-10-15 09:36:40 +0800
committerNitin Garg <nitin.garg@nxp.com>2016-01-14 10:55:07 -0600
commit1b7be4d68dd2e80e98412283261a2a1dba779ddf (patch)
tree2c1daab4d9827ec84726fa5ddc7c5916be8d763f
parentb74c6b9c7fdc323af7cbc7017ab6e1172bc8e53c (diff)
MLK-9694 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. Cherry-pick & Merge patches from: 149ac988a25b8d8eb86d05679cbb7b42819ff7a1 & 3269e5c06bdb2f7ab9bd5afa9bbfe46d872197d3 Signed-off-by: Fugang Duan <B38611@freescale.com>
-rw-r--r--arch/arm/mach-imx/common.h1
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c90
-rw-r--r--arch/arm/mach-imx/mach-imx6sl.c11
-rw-r--r--arch/arm/mach-imx/mach-imx6sx.c1
-rw-r--r--arch/arm/mach-imx/mach-imx7d.c1
5 files changed, 98 insertions, 6 deletions
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 624da95562e7..0575ffe86952 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -121,6 +121,7 @@ void imx_anatop_post_resume(void);
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
void imx6q_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);
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 3ab61549ce0f..fe2a8edf5bf8 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -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;
@@ -273,13 +359,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_populate(NULL, of_default_bus_match_table, NULL, parent);
+ imx6q_enet_init();
imx_anatop_init();
cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init();
- imx6q_1588_init();
imx6q_axi_init();
}
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index 12a1b098fc6a..84608229d7b1 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -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)
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c
index f17b7004c24b..a67571ea9695 100644
--- a/arch/arm/mach-imx/mach-imx6sx.c
+++ b/arch/arm/mach-imx/mach-imx6sx.c
@@ -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();
}
diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index cb8f3c6a6bad..86343893a8a9 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -83,6 +83,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();
}