Skip to contentSkip to conversation

i.MX6 ethernet phy fixup

PATCH New Sascha Hauer 3 participants 6 messages Jun 20, 2013 – Jun 21, 2013

Subsystems (3)
lore
Share & tools
lore

Sascha Hauer

author maintainer
#0 lore raw

PATCH 1/1 i.MX6 ethernet phy fixup

All i.MX6 boards with gigabit phy I'm aware of have the same fixup in U-Boot for adjusting the rx/tx delay lines. In the kernel we only have a fixup for the sabrelite board. Instead of adding individual board hooks for each new boards I think we should just do register the fixups unconditionally on i.MX for each known phy type.

This makes ethernet work on the different boards even when the bootloader misses to do it (or Linux resets the phy during startup of the ethernet interface).

I suspect this series is only the tip of the iceberg as I also see other boards having to adjust the rx/tx delay lines. The proper fix would probably be some phy level callbacks to adjust these values.

Sascha

----------------------------------------------------------------
Sascha Hauer (3):
ARM: i.MX6: call ksz9021 phy fixup for all i.MX6 boards
ARM: i.MX6: add ethernet phy fixup for AR8031
ARM: i.MX6: add ethernet phy fixup for KSZ9031

 arch/arm/mach-imx/mach-imx6q.c | 60 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 56 insertions(+), 4 deletions(-)
author maintainer
#1 lore raw

PATCH 1/3 ARM: i.MX6: call ksz9021 phy fixup for all i.MX6 boards

In current U-Boot the sabrelite, nitrogen6x and titanium all need the same fixup for the ksz9021 phy. Instead of limiting the fixup to a single board apply them for all.

---
 arch/arm/mach-imx/mach-imx6q.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
arch/arm/mach-imx/mach-imx6q.c +6 -4
index 5536fd8..e5f4a5b 100644
@@ -137,12 +137,12 @@ put_clk:
 		clk_put(cko1);
 }
 
-static void __init imx6q_sabrelite_init(void)
+static void __init imx6q_enet_phy_init(void)
 {
-	if (IS_BUILTIN(CONFIG_PHYLIB))
+	if (IS_BUILTIN(CONFIG_PHYLIB)) {
 		phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
 				ksz9021rn_phy_fixup);
-	imx6q_sabrelite_cko1_setup();
+	}
 }
 
 static void __init imx6q_1588_init(void)
@@ -164,7 +164,9 @@ static void __init imx6q_usb_init(void)
 static void __init imx6q_init_machine(void)
 {
 	if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
-		imx6q_sabrelite_init();
+		imx6q_sabrelite_cko1_setup();
+
+	imx6q_enet_phy_init();
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 
Signature · 1 line
1.8.3.1
author maintainer
#2 lore raw

PATCH 2/3 ARM: i.MX6: add ethernet phy fixup for AR8031

In reply to Sascha Hauer

The AR8031 is used on the i.MX6 based sabreSD, sabreauto and wandboard. All need the same fixup, so add it for all i.MX6.

---
 arch/arm/mach-imx/mach-imx6q.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
arch/arm/mach-imx/mach-imx6q.c +27 -0
index e5f4a5b..69fae87 100644
@@ -113,6 +113,29 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
 	return 0;
 }
 
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+	u16 val;
+
+	/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
+	phy_write(dev, 0xd, 0x7);
+	phy_write(dev, 0xe, 0x8016);
+	phy_write(dev, 0xd, 0x4007);
+
+	val = phy_read(dev, 0xe);
+	val &= 0xffe3;
+	val |= 0x18;
+	phy_write(dev, 0xe, val);
+
+	/* introduce tx clock delay */
+	phy_write(dev, 0x1d, 0x5);
+	val = phy_read(dev, 0x1e);
+	val |= 0x0100;
+	phy_write(dev, 0x1e, val);
+
+	return 0;
+}
+
 static void __init imx6q_sabrelite_cko1_setup(void)
 {
 	struct clk *cko1_sel, *ahb, *cko1;
@@ -137,11 +160,15 @@ put_clk:
 		clk_put(cko1);
 }
 
+#define PHY_ID_AR8031	0x004dd074
+
 static void __init imx6q_enet_phy_init(void)
 {
 	if (IS_BUILTIN(CONFIG_PHYLIB)) {
 		phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
 				ksz9021rn_phy_fixup);
+		phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
+				ar8031_phy_fixup);
 	}
 }
 
Signature · 1 line
1.8.3.1
#3 lore raw

PATCH 2/3 ARM: i.MX6: add ethernet phy fixup for AR8031

Hi,

Am Donnerstag, 20. Juni 2013, 17:34:32 schrieb Sascha Hauer:

Quoted 13 lines

The AR8031 is used on the i.MX6 based sabreSD, sabreauto and wandboard. All need the same fixup, so add it for all i.MX6.

---
 arch/arm/mach-imx/mach-imx6q.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
arch/arm/mach-imx/mach-imx6q.c +0 -0
index e5f4a5b..69fae87 100644

arch/arm/mach-imx/mach-imx6q.c static int ksz9021rn_phy_fixup(struct phy_device *phydev) · line 120

Quoted 8 lines
arch/arm/mach-imx/mach-imx6q.c +5 -0
@@ -113,6 +113,29 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
 	return 0;
 }
 
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+	u16 val;
+
+	/* To enable AR8031 ouput a 125MHz clk from CLK_25M */

Typo? "ouput" -> "output"

Quoted 38 lines
arch/arm/mach-imx/mach-imx6q.c +22 -0
+	phy_write(dev, 0xd, 0x7);
+	phy_write(dev, 0xe, 0x8016);
+	phy_write(dev, 0xd, 0x4007);
+
+	val = phy_read(dev, 0xe);
+	val &= 0xffe3;
+	val |= 0x18;
+	phy_write(dev, 0xe, val);
+
+	/* introduce tx clock delay */
+	phy_write(dev, 0x1d, 0x5);
+	val = phy_read(dev, 0x1e);
+	val |= 0x0100;
+	phy_write(dev, 0x1e, val);
+
+	return 0;
+}
+
 static void __init imx6q_sabrelite_cko1_setup(void)
 {
 	struct clk *cko1_sel, *ahb, *cko1;
@@ -137,11 +160,15 @@ put_clk:
 		clk_put(cko1);
 }
 
+#define PHY_ID_AR8031	0x004dd074
+
 static void __init imx6q_enet_phy_init(void)
 {
 	if (IS_BUILTIN(CONFIG_PHYLIB)) {
 		phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
 				ksz9021rn_phy_fixup);
+		phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
+				ar8031_phy_fixup);
 	}
 }
 
#4 lore raw

PATCH 2/3 ARM: i.MX6: add ethernet phy fixup for AR8031

Quoted 19 lines · Michael Heimpold

Hi,

Am Donnerstag, 20. Juni 2013, 17:34:32 schrieb Sascha Hauer:

Quoted 16 lines

The AR8031 is used on the i.MX6 based sabreSD, sabreauto and wandboard. All need the same fixup, so add it for all i.MX6.

---
 arch/arm/mach-imx/mach-imx6q.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
arch/arm/mach-imx/mach-imx6q.c +0 -0
index e5f4a5b..69fae87 100644
@@ -113,6 +113,29 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
 	return 0;
 }
 
Quoted 8 lines

arch/arm/mach-imx/mach-imx6q.c static int ksz9021rn_phy_fixup(struct phy_device *phydev) · line 120

Quoted 5 lines
arch/arm/mach-imx/mach-imx6q.c +5 -0
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+	u16 val;
+
+	/* To enable AR8031 ouput a 125MHz clk from CLK_25M */

Typo? "ouput" -> "output"

I fixed it up and applied the series.

Shawn

author maintainer
#5 lore raw

PATCH 3/3 ARM: i.MX6: add ethernet phy fixup for KSZ9031

In reply to Sascha Hauer

The KSZ9031 is used on the i.MX6 based Data Modul eDM-QMX6 board. It needs the same fixup to the rx/tx delays as other i.MX6 boards.

---
 arch/arm/mach-imx/mach-imx6q.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
arch/arm/mach-imx/mach-imx6q.c +23 -0
index 69fae87..2f02875 100644
@@ -113,6 +113,27 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
 	return 0;
 }
 
+static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val)
+{
+	phy_write(dev, 0x0d, device);
+	phy_write(dev, 0x0e, reg);
+	phy_write(dev, 0x0d, (1 << 14) | device);
+	phy_write(dev, 0x0e, val);
+}
+
+static int ksz9031rn_phy_fixup(struct phy_device *dev)
+{
+	/*
+	 * min rx data delay, max rx/tx clock delay,
+	 * min rx/tx control delay
+	 */
+	mmd_write_reg(dev, 2, 4, 0);
+	mmd_write_reg(dev, 2, 5, 0);
+	mmd_write_reg(dev, 2, 8, 0x003ff);
+
+	return 0;
+}
+
 static int ar8031_phy_fixup(struct phy_device *dev)
 {
 	u16 val;
@@ -167,6 +188,8 @@ static void __init imx6q_enet_phy_init(void)
 	if (IS_BUILTIN(CONFIG_PHYLIB)) {
 		phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
 				ksz9021rn_phy_fixup);
+		phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
+				ksz9031rn_phy_fixup);
 		phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
 				ar8031_phy_fixup);
 	}
Signature · 1 line
1.8.3.1