diff options
author | Fugang Duan <B38611@freescale.com> | 2013-09-29 05:40:31 -0400 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 09:05:43 -0400 |
commit | faae41bf9ff800696c7f2e6761157d34065cef3c (patch) | |
tree | 10a653dbdec25610b9f16682ab484214b766dc34 | |
parent | 139b7a73aead3044b1542ef9fc103038f7c868ea (diff) |
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 <B38611@freescale.com>
-rw-r--r-- | arch/arm/mach-imx/common.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-imx/mach-imx6q.c | 70 | ||||
-rw-r--r-- | 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); | |||
147 | extern int imx6_set_lpm(enum mxc_cpu_pwr_mode mode); | 147 | extern int imx6_set_lpm(enum mxc_cpu_pwr_mode mode); |
148 | extern void imx6_set_cache_lpm_in_wait(bool enable); | 148 | extern void imx6_set_cache_lpm_in_wait(bool enable); |
149 | extern void imx6sl_set_wait_clk(bool enter); | 149 | extern void imx6sl_set_wait_clk(bool enter); |
150 | extern void imx6_enet_mac_init(const char *compatible); | ||
150 | 151 | ||
151 | extern void imx_cpu_die(unsigned int cpu); | 152 | extern void imx_cpu_die(unsigned int cpu); |
152 | extern int imx_cpu_kill(unsigned int cpu); | 153 | 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 @@ | |||
33 | #include <linux/micrel_phy.h> | 33 | #include <linux/micrel_phy.h> |
34 | #include <linux/mfd/syscon.h> | 34 | #include <linux/mfd/syscon.h> |
35 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | 35 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> |
36 | #include <linux/of_net.h> | ||
36 | #include <asm/mach/arch.h> | 37 | #include <asm/mach/arch.h> |
37 | #include <asm/mach/map.h> | 38 | #include <asm/mach/map.h> |
38 | #include <asm/system_misc.h> | 39 | #include <asm/system_misc.h> |
@@ -253,6 +254,72 @@ static void __init imx6q_lvds_cabc_init(void) | |||
253 | } | 254 | } |
254 | } | 255 | } |
255 | 256 | ||
257 | #define OCOTP_MACn(n) (0x00000620 + (n) * 0x10) | ||
258 | void __init imx6_enet_mac_init(const char *compatible) | ||
259 | { | ||
260 | struct device_node *ocotp_np, *enet_np; | ||
261 | void __iomem *base; | ||
262 | struct property *newmac; | ||
263 | u32 macaddr_low, macaddr_high; | ||
264 | u8 *macaddr; | ||
265 | |||
266 | enet_np = of_find_compatible_node(NULL, NULL, compatible); | ||
267 | if (!enet_np) | ||
268 | return; | ||
269 | |||
270 | if (of_get_mac_address(enet_np)) | ||
271 | goto put_enet_node; | ||
272 | |||
273 | ocotp_np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp"); | ||
274 | if (!ocotp_np) { | ||
275 | pr_warn("failed to find ocotp node\n"); | ||
276 | goto put_enet_node; | ||
277 | } | ||
278 | |||
279 | base = of_iomap(ocotp_np, 0); | ||
280 | if (!base) { | ||
281 | pr_warn("failed to map ocotp\n"); | ||
282 | goto put_ocotp_node; | ||
283 | } | ||
284 | |||
285 | macaddr_high = readl_relaxed(base + OCOTP_MACn(0)); | ||
286 | macaddr_low = readl_relaxed(base + OCOTP_MACn(1)); | ||
287 | |||
288 | newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL); | ||
289 | if (!newmac) | ||
290 | goto put_ocotp_node; | ||
291 | |||
292 | newmac->value = newmac + 1; | ||
293 | newmac->length = 6; | ||
294 | newmac->name = kstrdup("local-mac-address", GFP_KERNEL); | ||
295 | if (!newmac->name) { | ||
296 | kfree(newmac); | ||
297 | goto put_ocotp_node; | ||
298 | } | ||
299 | |||
300 | macaddr = newmac->value; | ||
301 | macaddr[5] = macaddr_high & 0xff; | ||
302 | macaddr[4] = (macaddr_high >> 8) & 0xff; | ||
303 | macaddr[3] = (macaddr_high >> 16) & 0xff; | ||
304 | macaddr[2] = (macaddr_high >> 24) & 0xff; | ||
305 | macaddr[1] = macaddr_low & 0xff; | ||
306 | macaddr[0] = (macaddr_low >> 8) & 0xff; | ||
307 | |||
308 | of_update_property(enet_np, newmac); | ||
309 | |||
310 | put_ocotp_node: | ||
311 | of_node_put(ocotp_np); | ||
312 | put_enet_node: | ||
313 | of_node_put(enet_np); | ||
314 | } | ||
315 | |||
316 | static inline void imx6q_enet_init(void) | ||
317 | { | ||
318 | imx6_enet_mac_init("fsl,imx6q-fec"); | ||
319 | imx6q_enet_phy_init(); | ||
320 | imx6q_1588_init(); | ||
321 | } | ||
322 | |||
256 | static void __init imx6q_init_machine(void) | 323 | static void __init imx6q_init_machine(void) |
257 | { | 324 | { |
258 | struct device *parent; | 325 | struct device *parent; |
@@ -261,13 +328,12 @@ static void __init imx6q_init_machine(void) | |||
261 | if (parent == NULL) | 328 | if (parent == NULL) |
262 | pr_warn("failed to initialize soc device\n"); | 329 | pr_warn("failed to initialize soc device\n"); |
263 | 330 | ||
264 | imx6q_enet_phy_init(); | 331 | imx6q_enet_init(); |
265 | 332 | ||
266 | of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); | 333 | of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); |
267 | 334 | ||
268 | imx_anatop_init(); | 335 | imx_anatop_init(); |
269 | imx6_pm_init(); | 336 | imx6_pm_init(); |
270 | imx6q_1588_init(); | ||
271 | imx6q_csi_mux_init(); | 337 | imx6q_csi_mux_init(); |
272 | imx6q_lvds_cabc_init(); | 338 | imx6q_lvds_cabc_init(); |
273 | } | 339 | } |
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: | |||
83 | soft_restart(0); | 83 | soft_restart(0); |
84 | } | 84 | } |
85 | 85 | ||
86 | static void __init imx6sl_fec_init(void) | 86 | static void __init imx6sl_fec_clk_init(void) |
87 | { | 87 | { |
88 | struct regmap *gpr; | 88 | struct regmap *gpr; |
89 | 89 | ||
@@ -96,7 +96,12 @@ static void __init imx6sl_fec_init(void) | |||
96 | IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0); | 96 | IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK, 0); |
97 | } else | 97 | } else |
98 | pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n"); | 98 | pr_err("failed to find fsl,imx6sl-iomux-gpr regmap\n"); |
99 | } | ||
99 | 100 | ||
101 | static inline void imx6sl_fec_init(void) | ||
102 | { | ||
103 | imx6sl_fec_clk_init(); | ||
104 | imx6_enet_mac_init("fsl,imx6sl-fec"); | ||
100 | } | 105 | } |
101 | 106 | ||
102 | static void __init imx6sl_init_machine(void) | 107 | static void __init imx6sl_init_machine(void) |