All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] ARM: imx: init MAC address for ocotp
@ 2016-10-21  7:18 ` Octavian Purdila
  0 siblings, 0 replies; 6+ messages in thread
From: Octavian Purdila @ 2016-10-21  7:18 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Shawn Guo, Sascha Hauer, Fabio Estevam, linux-kernel, Octavian Purdila

This patch series adds support for initializing the ethernet MAC
address for the OCOTP fuse configuration.

Fugang Duan (1):
  ARM: imx: init enet MAC address from ocotp

Octavian Purdila (1):
  ARM: imx: add ocotp support in machine code

 arch/arm/mach-imx/Kconfig       |   5 ++
 arch/arm/mach-imx/Makefile      |   1 +
 arch/arm/mach-imx/common.h      |   3 ++
 arch/arm/mach-imx/mach-imx6q.c  |  32 ++++--------
 arch/arm/mach-imx/mach-imx6sl.c |  12 +++--
 arch/arm/mach-imx/mach-imx6sx.c |   2 +
 arch/arm/mach-imx/mach-imx7d.c  |   2 +
 arch/arm/mach-imx/ocotp.c       | 113 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 146 insertions(+), 24 deletions(-)
 create mode 100644 arch/arm/mach-imx/ocotp.c

-- 
2.7.4

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 0/2] ARM: imx: init MAC address for ocotp
@ 2016-10-21  7:18 ` Octavian Purdila
  0 siblings, 0 replies; 6+ messages in thread
From: Octavian Purdila @ 2016-10-21  7:18 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series adds support for initializing the ethernet MAC
address for the OCOTP fuse configuration.

Fugang Duan (1):
  ARM: imx: init enet MAC address from ocotp

Octavian Purdila (1):
  ARM: imx: add ocotp support in machine code

 arch/arm/mach-imx/Kconfig       |   5 ++
 arch/arm/mach-imx/Makefile      |   1 +
 arch/arm/mach-imx/common.h      |   3 ++
 arch/arm/mach-imx/mach-imx6q.c  |  32 ++++--------
 arch/arm/mach-imx/mach-imx6sl.c |  12 +++--
 arch/arm/mach-imx/mach-imx6sx.c |   2 +
 arch/arm/mach-imx/mach-imx7d.c  |   2 +
 arch/arm/mach-imx/ocotp.c       | 113 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 146 insertions(+), 24 deletions(-)
 create mode 100644 arch/arm/mach-imx/ocotp.c

-- 
2.7.4

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] ARM: imx: add ocotp support in machine code
  2016-10-21  7:18 ` Octavian Purdila
@ 2016-10-21  7:18   ` Octavian Purdila
  -1 siblings, 0 replies; 6+ messages in thread
From: Octavian Purdila @ 2016-10-21  7:18 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Shawn Guo, Sascha Hauer, Fabio Estevam, linux-kernel, Octavian Purdila

Since we will have the need to access OCOTP fuse registers from
multiple places move the ocotp initialization and register access code
to a new file and provide interfaces for it.

Signed-off-by: Octavian Purdila <octavian.purdila@nxp.com>
---
 arch/arm/mach-imx/Kconfig       |  5 +++++
 arch/arm/mach-imx/Makefile      |  1 +
 arch/arm/mach-imx/common.h      |  2 ++
 arch/arm/mach-imx/mach-imx6q.c  | 20 ++------------------
 arch/arm/mach-imx/mach-imx6sl.c |  1 +
 arch/arm/mach-imx/mach-imx6sx.c |  1 +
 arch/arm/mach-imx/mach-imx7d.c  |  1 +
 arch/arm/mach-imx/ocotp.c       | 40 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 53 insertions(+), 18 deletions(-)
 create mode 100644 arch/arm/mach-imx/ocotp.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 0ac05a0..1fb36ee 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -58,6 +58,9 @@ config HAVE_IMX_SRC
 	def_bool y if SMP
 	select ARCH_HAS_RESET_CONTROLLER
 
+config HAVE_IMX_OCOTP
+	bool
+
 config IMX_HAVE_IOMUX_V1
 	bool
 
@@ -492,6 +495,7 @@ config SOC_IMX6
 	select HAVE_IMX_SRC
 	select MFD_SYSCON
 	select PL310_ERRATA_769419 if CACHE_L2X0
+	select HAVE_IMX_OCOTP
 
 config SOC_IMX6Q
 	bool "i.MX6 Quad/DualLite support"
@@ -537,6 +541,7 @@ config SOC_IMX7D
 	select HAVE_IMX_ANATOP
 	select HAVE_IMX_MMDC
 	select HAVE_IMX_SRC
+	select HAVE_IMX_OCOTP
 	help
 		This enables support for Freescale i.MX7 Dual processor.
 
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index cab1289..feef1cf 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
 obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
 obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
 obj-$(CONFIG_HAVE_IMX_SRC) += src.o
+obj-$(CONFIG_HAVE_IMX_OCOTP) += ocotp.o
 ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
 AFLAGS_headsmp.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index c4436d9..fc78d4d0 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -103,6 +103,8 @@ void imx_gpc_hwirq_unmask(unsigned int hwirq);
 void imx_anatop_init(void);
 void imx_anatop_pre_suspend(void);
 void imx_anatop_post_resume(void);
+void imx_ocotp_init(const char *ocotp_compat);
+u32 imx_ocotp_read(u32 offset);
 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);
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 97fd251..51f6c19 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -280,6 +280,7 @@ static void __init imx6q_init_machine(void)
 
 	of_platform_default_populate(NULL, NULL, parent);
 
+	imx_ocotp_init("fsl,imx6q-ocotp");
 	imx_anatop_init();
 	cpu_is_imx6q() ?  imx6q_pm_init() : imx6dl_pm_init();
 	imx6q_1588_init();
@@ -294,22 +295,8 @@ static void __init imx6q_init_machine(void)
 
 static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
 {
-	struct device_node *np;
-	void __iomem *base;
 	u32 val;
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
-	if (!np) {
-		pr_warn("failed to find ocotp node\n");
-		return;
-	}
-
-	base = of_iomap(np, 0);
-	if (!base) {
-		pr_warn("failed to map ocotp\n");
-		goto put_node;
-	}
-
 	/*
 	 * SPEED_GRADING[1:0] defines the max speed of ARM:
 	 * 2b'11: 1200000000Hz;
@@ -318,7 +305,7 @@ static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
 	 * 2b'00: 792000000Hz;
 	 * We need to set the max speed of ARM according to fuse map.
 	 */
-	val = readl_relaxed(base + OCOTP_CFG3);
+	val = imx_ocotp_read(OCOTP_CFG3);
 	val >>= OCOTP_CFG3_SPEED_SHIFT;
 	val &= 0x3;
 
@@ -333,9 +320,6 @@ static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
 			if (dev_pm_opp_disable(cpu_dev, 852000000))
 				pr_warn("failed to disable 852 MHz OPP\n");
 	}
-	iounmap(base);
-put_node:
-	of_node_put(np);
 }
 
 static void __init imx6q_opp_init(void)
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index 0408490..01558df 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -54,6 +54,7 @@ static void __init imx6sl_init_machine(void)
 
 	of_platform_default_populate(NULL, NULL, parent);
 
+	imx_ocotp_init("fsl,imx6sl-ocotp");
 	imx6sl_fec_init();
 	imx_anatop_init();
 	imx6sl_pm_init();
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c
index 7f52d9b..acb73c1 100644
--- a/arch/arm/mach-imx/mach-imx6sx.c
+++ b/arch/arm/mach-imx/mach-imx6sx.c
@@ -74,6 +74,7 @@ static void __init imx6sx_init_machine(void)
 
 	of_platform_default_populate(NULL, NULL, parent);
 
+	imx_ocotp_init("fsl,imx6sx-ocotp");
 	imx6sx_enet_init();
 	imx_anatop_init();
 	imx6sx_pm_init();
diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index 26ca744..c29c771 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -93,6 +93,7 @@ static void __init imx7d_init_machine(void)
 	if (parent == NULL)
 		pr_warn("failed to initialize soc device\n");
 
+	imx_ocotp_init("fsl,imx7d-ocotp");
 	imx_anatop_init();
 	imx7d_enet_init();
 }
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
new file mode 100644
index 0000000..e73f0e8
--- /dev/null
+++ b/arch/arm/mach-imx/ocotp.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+static void __iomem *ocotp_base;
+
+void __init imx_ocotp_init(const char *compat)
+{
+	struct device_node *ocotp_np;
+
+	ocotp_np = of_find_compatible_node(NULL, NULL, compat);
+	if (!ocotp_np) {
+		pr_warn("failed to find ocotp node\n");
+		return;
+	}
+
+	ocotp_base = of_iomap(ocotp_np, 0);
+	if (!ocotp_base)
+		pr_warn("failed to map ocotp\n");
+
+	of_node_put(ocotp_np);
+}
+
+u32 imx_ocotp_read(u32 offset)
+{
+	if (WARN_ON(!ocotp_base))
+		return 0;
+
+	return readl_relaxed(ocotp_base + offset);
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 1/2] ARM: imx: add ocotp support in machine code
@ 2016-10-21  7:18   ` Octavian Purdila
  0 siblings, 0 replies; 6+ messages in thread
From: Octavian Purdila @ 2016-10-21  7:18 UTC (permalink / raw)
  To: linux-arm-kernel

Since we will have the need to access OCOTP fuse registers from
multiple places move the ocotp initialization and register access code
to a new file and provide interfaces for it.

Signed-off-by: Octavian Purdila <octavian.purdila@nxp.com>
---
 arch/arm/mach-imx/Kconfig       |  5 +++++
 arch/arm/mach-imx/Makefile      |  1 +
 arch/arm/mach-imx/common.h      |  2 ++
 arch/arm/mach-imx/mach-imx6q.c  | 20 ++------------------
 arch/arm/mach-imx/mach-imx6sl.c |  1 +
 arch/arm/mach-imx/mach-imx6sx.c |  1 +
 arch/arm/mach-imx/mach-imx7d.c  |  1 +
 arch/arm/mach-imx/ocotp.c       | 40 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 53 insertions(+), 18 deletions(-)
 create mode 100644 arch/arm/mach-imx/ocotp.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 0ac05a0..1fb36ee 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -58,6 +58,9 @@ config HAVE_IMX_SRC
 	def_bool y if SMP
 	select ARCH_HAS_RESET_CONTROLLER
 
+config HAVE_IMX_OCOTP
+	bool
+
 config IMX_HAVE_IOMUX_V1
 	bool
 
@@ -492,6 +495,7 @@ config SOC_IMX6
 	select HAVE_IMX_SRC
 	select MFD_SYSCON
 	select PL310_ERRATA_769419 if CACHE_L2X0
+	select HAVE_IMX_OCOTP
 
 config SOC_IMX6Q
 	bool "i.MX6 Quad/DualLite support"
@@ -537,6 +541,7 @@ config SOC_IMX7D
 	select HAVE_IMX_ANATOP
 	select HAVE_IMX_MMDC
 	select HAVE_IMX_SRC
+	select HAVE_IMX_OCOTP
 	help
 		This enables support for Freescale i.MX7 Dual processor.
 
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index cab1289..feef1cf 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
 obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
 obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
 obj-$(CONFIG_HAVE_IMX_SRC) += src.o
+obj-$(CONFIG_HAVE_IMX_OCOTP) += ocotp.o
 ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
 AFLAGS_headsmp.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index c4436d9..fc78d4d0 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -103,6 +103,8 @@ void imx_gpc_hwirq_unmask(unsigned int hwirq);
 void imx_anatop_init(void);
 void imx_anatop_pre_suspend(void);
 void imx_anatop_post_resume(void);
+void imx_ocotp_init(const char *ocotp_compat);
+u32 imx_ocotp_read(u32 offset);
 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);
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 97fd251..51f6c19 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -280,6 +280,7 @@ static void __init imx6q_init_machine(void)
 
 	of_platform_default_populate(NULL, NULL, parent);
 
+	imx_ocotp_init("fsl,imx6q-ocotp");
 	imx_anatop_init();
 	cpu_is_imx6q() ?  imx6q_pm_init() : imx6dl_pm_init();
 	imx6q_1588_init();
@@ -294,22 +295,8 @@ static void __init imx6q_init_machine(void)
 
 static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
 {
-	struct device_node *np;
-	void __iomem *base;
 	u32 val;
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
-	if (!np) {
-		pr_warn("failed to find ocotp node\n");
-		return;
-	}
-
-	base = of_iomap(np, 0);
-	if (!base) {
-		pr_warn("failed to map ocotp\n");
-		goto put_node;
-	}
-
 	/*
 	 * SPEED_GRADING[1:0] defines the max speed of ARM:
 	 * 2b'11: 1200000000Hz;
@@ -318,7 +305,7 @@ static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
 	 * 2b'00: 792000000Hz;
 	 * We need to set the max speed of ARM according to fuse map.
 	 */
-	val = readl_relaxed(base + OCOTP_CFG3);
+	val = imx_ocotp_read(OCOTP_CFG3);
 	val >>= OCOTP_CFG3_SPEED_SHIFT;
 	val &= 0x3;
 
@@ -333,9 +320,6 @@ static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
 			if (dev_pm_opp_disable(cpu_dev, 852000000))
 				pr_warn("failed to disable 852 MHz OPP\n");
 	}
-	iounmap(base);
-put_node:
-	of_node_put(np);
 }
 
 static void __init imx6q_opp_init(void)
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index 0408490..01558df 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -54,6 +54,7 @@ static void __init imx6sl_init_machine(void)
 
 	of_platform_default_populate(NULL, NULL, parent);
 
+	imx_ocotp_init("fsl,imx6sl-ocotp");
 	imx6sl_fec_init();
 	imx_anatop_init();
 	imx6sl_pm_init();
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c
index 7f52d9b..acb73c1 100644
--- a/arch/arm/mach-imx/mach-imx6sx.c
+++ b/arch/arm/mach-imx/mach-imx6sx.c
@@ -74,6 +74,7 @@ static void __init imx6sx_init_machine(void)
 
 	of_platform_default_populate(NULL, NULL, parent);
 
+	imx_ocotp_init("fsl,imx6sx-ocotp");
 	imx6sx_enet_init();
 	imx_anatop_init();
 	imx6sx_pm_init();
diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index 26ca744..c29c771 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -93,6 +93,7 @@ static void __init imx7d_init_machine(void)
 	if (parent == NULL)
 		pr_warn("failed to initialize soc device\n");
 
+	imx_ocotp_init("fsl,imx7d-ocotp");
 	imx_anatop_init();
 	imx7d_enet_init();
 }
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
new file mode 100644
index 0000000..e73f0e8
--- /dev/null
+++ b/arch/arm/mach-imx/ocotp.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+static void __iomem *ocotp_base;
+
+void __init imx_ocotp_init(const char *compat)
+{
+	struct device_node *ocotp_np;
+
+	ocotp_np = of_find_compatible_node(NULL, NULL, compat);
+	if (!ocotp_np) {
+		pr_warn("failed to find ocotp node\n");
+		return;
+	}
+
+	ocotp_base = of_iomap(ocotp_np, 0);
+	if (!ocotp_base)
+		pr_warn("failed to map ocotp\n");
+
+	of_node_put(ocotp_np);
+}
+
+u32 imx_ocotp_read(u32 offset)
+{
+	if (WARN_ON(!ocotp_base))
+		return 0;
+
+	return readl_relaxed(ocotp_base + offset);
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] ARM: imx: init enet MAC address from ocotp
  2016-10-21  7:18 ` Octavian Purdila
@ 2016-10-21  7:18   ` Octavian Purdila
  -1 siblings, 0 replies; 6+ messages in thread
From: Octavian Purdila @ 2016-10-21  7:18 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Shawn Guo, Sascha Hauer, Fabio Estevam, linux-kernel,
	Fugang Duan, Fugang Duan, Octavian Purdila

From: Fugang Duan <b38611@freescale.com>

The FEC driver advertises the following order of getting it's MAC
address: module parameters or kernel command line first, then device
tree, then fuse / flash, then mac registers set by bootloader, then
random MAC address.

This patch add support for fuse MAC address for imx6/7 by updating the
device tree fec entry with a MAC address from OCOTP, if none is set.

Signed-off-by: Fugang Duan <B38611@freescale.com>
[Octavian: move to ocotp file, squash imx7d fix]
Signed-off-by: Octavian Purdila <octavian.purdila@nxp.com>
---
 arch/arm/mach-imx/common.h      |  1 +
 arch/arm/mach-imx/mach-imx6q.c  | 12 +++++--
 arch/arm/mach-imx/mach-imx6sl.c | 11 +++++--
 arch/arm/mach-imx/mach-imx6sx.c |  1 +
 arch/arm/mach-imx/mach-imx7d.c  |  1 +
 arch/arm/mach-imx/ocotp.c       | 73 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 93 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index fc78d4d0..7609dfe 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -108,6 +108,7 @@ u32 imx_ocotp_read(u32 offset);
 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 ocotp_enet_mac_init(const char *enet_compat);
 int imx_mmdc_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 51f6c19..823b5ba 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,13 @@ static void __init imx6q_axi_init(void)
 	}
 }
 
+static inline void imx6q_enet_init(void)
+{
+	ocotp_enet_mac_init("fsl,imx6q-fec");
+	imx6q_enet_phy_init();
+	imx6q_1588_init();
+}
+
 static void __init imx6q_init_machine(void)
 {
 	struct device *parent;
@@ -276,14 +284,12 @@ 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);
 
 	imx_ocotp_init("fsl,imx6q-ocotp");
+	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 01558df..1c2863f 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();
+	ocotp_enet_mac_init("fsl,imx6sl-fec");
 }
 
 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 acb73c1..e502b55 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)
 {
+	ocotp_enet_mac_init("fsl,imx6sx-fec");
 	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 c29c771..29cde14 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -81,6 +81,7 @@ static void __init imx7d_enet_clk_sel(void)
 
 static inline void imx7d_enet_init(void)
 {
+	ocotp_enet_mac_init("fsl,imx7d-fec");
 	imx7d_enet_phy_init();
 	imx7d_enet_clk_sel();
 }
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index e73f0e8..5c5806a 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -11,6 +11,10 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_net.h>
+#include <linux/slab.h>
+
+#include "hardware.h"
 
 static void __iomem *ocotp_base;
 
@@ -38,3 +42,72 @@ u32 imx_ocotp_read(u32 offset)
 
 	return readl_relaxed(ocotp_base + offset);
 }
+
+#define OCOTP_MAC_OFF	(cpu_is_imx7d() ? 0x640 : 0x620)
+#define OCOTP_MACn(n)	(OCOTP_MAC_OFF + (n) * 0x10)
+
+void __init ocotp_enet_mac_init(const char *enet_compat)
+{
+	struct device_node *enet_np, *from = NULL;
+	struct property *newmac;
+	u32 macaddr_low;
+	u32 macaddr_high = 0;
+	u32 macaddr1_high = 0;
+	u8 *macaddr;
+	int i, id;
+
+	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;
+
+		id = of_alias_get_id(enet_np, "ethernet");
+		if (id < 0)
+			id = i;
+
+		macaddr_low = imx_ocotp_read(OCOTP_MACn(1));
+		if (id)
+			macaddr1_high = imx_ocotp_read(OCOTP_MACn(2));
+		else
+			macaddr_high = imx_ocotp_read(OCOTP_MACn(0));
+
+		newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
+		if (!newmac)
+			goto put_enet_node;
+
+		newmac->value = newmac + 1;
+		newmac->length = 6;
+		newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
+		if (!newmac->name) {
+			kfree(newmac);
+			goto put_enet_node;
+		}
+
+		macaddr = newmac->value;
+		if (id) {
+			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_enet_node:
+		of_node_put(enet_np);
+	}
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] ARM: imx: init enet MAC address from ocotp
@ 2016-10-21  7:18   ` Octavian Purdila
  0 siblings, 0 replies; 6+ messages in thread
From: Octavian Purdila @ 2016-10-21  7:18 UTC (permalink / raw)
  To: linux-arm-kernel

From: Fugang Duan <b38611@freescale.com>

The FEC driver advertises the following order of getting it's MAC
address: module parameters or kernel command line first, then device
tree, then fuse / flash, then mac registers set by bootloader, then
random MAC address.

This patch add support for fuse MAC address for imx6/7 by updating the
device tree fec entry with a MAC address from OCOTP, if none is set.

Signed-off-by: Fugang Duan <B38611@freescale.com>
[Octavian: move to ocotp file, squash imx7d fix]
Signed-off-by: Octavian Purdila <octavian.purdila@nxp.com>
---
 arch/arm/mach-imx/common.h      |  1 +
 arch/arm/mach-imx/mach-imx6q.c  | 12 +++++--
 arch/arm/mach-imx/mach-imx6sl.c | 11 +++++--
 arch/arm/mach-imx/mach-imx6sx.c |  1 +
 arch/arm/mach-imx/mach-imx7d.c  |  1 +
 arch/arm/mach-imx/ocotp.c       | 73 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 93 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index fc78d4d0..7609dfe 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -108,6 +108,7 @@ u32 imx_ocotp_read(u32 offset);
 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 ocotp_enet_mac_init(const char *enet_compat);
 int imx_mmdc_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 51f6c19..823b5ba 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,13 @@ static void __init imx6q_axi_init(void)
 	}
 }
 
+static inline void imx6q_enet_init(void)
+{
+	ocotp_enet_mac_init("fsl,imx6q-fec");
+	imx6q_enet_phy_init();
+	imx6q_1588_init();
+}
+
 static void __init imx6q_init_machine(void)
 {
 	struct device *parent;
@@ -276,14 +284,12 @@ 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);
 
 	imx_ocotp_init("fsl,imx6q-ocotp");
+	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 01558df..1c2863f 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();
+	ocotp_enet_mac_init("fsl,imx6sl-fec");
 }
 
 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 acb73c1..e502b55 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)
 {
+	ocotp_enet_mac_init("fsl,imx6sx-fec");
 	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 c29c771..29cde14 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -81,6 +81,7 @@ static void __init imx7d_enet_clk_sel(void)
 
 static inline void imx7d_enet_init(void)
 {
+	ocotp_enet_mac_init("fsl,imx7d-fec");
 	imx7d_enet_phy_init();
 	imx7d_enet_clk_sel();
 }
diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index e73f0e8..5c5806a 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -11,6 +11,10 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_net.h>
+#include <linux/slab.h>
+
+#include "hardware.h"
 
 static void __iomem *ocotp_base;
 
@@ -38,3 +42,72 @@ u32 imx_ocotp_read(u32 offset)
 
 	return readl_relaxed(ocotp_base + offset);
 }
+
+#define OCOTP_MAC_OFF	(cpu_is_imx7d() ? 0x640 : 0x620)
+#define OCOTP_MACn(n)	(OCOTP_MAC_OFF + (n) * 0x10)
+
+void __init ocotp_enet_mac_init(const char *enet_compat)
+{
+	struct device_node *enet_np, *from = NULL;
+	struct property *newmac;
+	u32 macaddr_low;
+	u32 macaddr_high = 0;
+	u32 macaddr1_high = 0;
+	u8 *macaddr;
+	int i, id;
+
+	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;
+
+		id = of_alias_get_id(enet_np, "ethernet");
+		if (id < 0)
+			id = i;
+
+		macaddr_low = imx_ocotp_read(OCOTP_MACn(1));
+		if (id)
+			macaddr1_high = imx_ocotp_read(OCOTP_MACn(2));
+		else
+			macaddr_high = imx_ocotp_read(OCOTP_MACn(0));
+
+		newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
+		if (!newmac)
+			goto put_enet_node;
+
+		newmac->value = newmac + 1;
+		newmac->length = 6;
+		newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
+		if (!newmac->name) {
+			kfree(newmac);
+			goto put_enet_node;
+		}
+
+		macaddr = newmac->value;
+		if (id) {
+			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_enet_node:
+		of_node_put(enet_np);
+	}
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-10-21  8:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-21  7:18 [PATCH 0/2] ARM: imx: init MAC address for ocotp Octavian Purdila
2016-10-21  7:18 ` Octavian Purdila
2016-10-21  7:18 ` [PATCH 1/2] ARM: imx: add ocotp support in machine code Octavian Purdila
2016-10-21  7:18   ` Octavian Purdila
2016-10-21  7:18 ` [PATCH 2/2] ARM: imx: init enet MAC address from ocotp Octavian Purdila
2016-10-21  7:18   ` Octavian Purdila

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.