[PATCH v2 0/3] sunxi: OrangePi Zero 2: Ethernet support

The first two patches prepare the sun8i-emac driver to deal with the EMAC as integrated into the H616 SoC. This IP block is compatible with the A64 version, but the current driver prevents us from using that: - The EPHY syscon register needs to have a bit cleared to select the external PHY. On the A64 it is cleared on reset, but we should not rely on that. The Linux driver does so as well. Fixed in patch 1/3. - The pinmux setting is tied to the compatible string, but the H616 requires a different value. Fixed in patch 2/3.
The final patch enables Ethernet support for the OrangePi Zero 2 board, which now works without further ado.
Cheers, Andre
Andre Przywara (3): net: sun8i-emac: Always clear syscon EPHY register net: sun8i-emac: Determine pinmux based on SoC, not EMAC type sunxi: OrangePi Zero 2: Enable Ethernet
configs/orangepi_zero2_defconfig | 2 ++ drivers/net/sun8i_emac.c | 59 ++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 26 deletions(-)

At the moment we only consider the EPHY register for those SoCs were we actually have an internal PHY to configure. However even other SoCs have this register, an expect the EPHY select bit to be cleared for proper operation with an external PHY.
Rework sun8i_emac_set_syscon_ephy() to be called regardless of the EMAC model, and clear the H3_EPHY_SELECT bit if no internal PHY is used.
We get away without it so far because SoCs like the A64 clear this bit on reset, but we need to explicitly clear it on the H616, for instance. The Linux driver does so as well.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/net/sun8i_emac.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-)
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 9f91a20d1d1..2344525bf52 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -297,30 +297,29 @@ static void sun8i_adjust_link(struct emac_eth_dev *priv, writel(v, priv->mac_reg + EMAC_CTL0); }
-static int sun8i_emac_set_syscon_ephy(struct emac_eth_dev *priv, u32 *reg) +static u32 sun8i_emac_set_syscon_ephy(struct emac_eth_dev *priv, u32 reg) { if (priv->use_internal_phy) { /* H3 based SoC's that has an Internal 100MBit PHY * needs to be configured and powered up before use */ - *reg &= ~H3_EPHY_DEFAULT_MASK; - *reg |= H3_EPHY_DEFAULT_VALUE; - *reg |= priv->phyaddr << H3_EPHY_ADDR_SHIFT; - *reg &= ~H3_EPHY_SHUTDOWN; - *reg |= H3_EPHY_SELECT; - } else - /* This is to select External Gigabit PHY on - * the boards with H3 SoC. - */ - *reg &= ~H3_EPHY_SELECT; + reg &= ~H3_EPHY_DEFAULT_MASK; + reg |= H3_EPHY_DEFAULT_VALUE; + reg |= priv->phyaddr << H3_EPHY_ADDR_SHIFT; + reg &= ~H3_EPHY_SHUTDOWN; + return reg | H3_EPHY_SELECT; + }
- return 0; + /* This is to select External Gigabit PHY on those boards with + * an internal PHY. Does not hurt on other SoCs. Linux does + * it as well. + */ + return reg & ~H3_EPHY_SELECT; }
static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata, struct emac_eth_dev *priv) { - int ret; u32 reg;
if (priv->variant == R40_GMAC) { @@ -336,11 +335,7 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
reg = readl(priv->sysctl_reg + 0x30);
- if (priv->variant == H3_EMAC || priv->variant == H6_EMAC) { - ret = sun8i_emac_set_syscon_ephy(priv, ®); - if (ret) - return ret; - } + reg = sun8i_emac_set_syscon_ephy(priv, reg);
reg &= ~(SC_ETCS_MASK | SC_EPIT); if (priv->variant == H3_EMAC ||

The pinmux choice for the RMII/RGMII pins the EMAC is connected to is not dependent on the EMAC IP, but on the SoC it is integrated in. Deriving the pinmux from the DT compatible string (as we do at the moment) will thus cause problems with certain EMAC IP / SoC combinations.
To avoid this exact issue with the H616, let's use our Kconfig MACH symbols to choose the correct pinmux setup.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- drivers/net/sun8i_emac.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 2344525bf52..0f6b6bb537e 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -85,7 +85,9 @@
/* IO mux settings */ #define SUN8I_IOMUX_H3 2 -#define SUN8I_IOMUX_R40 5 +#define SUN8I_IOMUX_R40 5 +#define SUN8I_IOMUX_H6 5 +#define SUN8I_IOMUX_H616 2 #define SUN8I_IOMUX 4
/* H3/A64 EMAC Register's offset */ @@ -517,10 +519,10 @@ static int sun8i_emac_eth_start(struct udevice *dev)
static int parse_phy_pins(struct udevice *dev) { - struct emac_eth_dev *priv = dev_get_priv(dev); int offset; const char *pin_name; int drive, pull = SUN4I_PINCTRL_NO_PULL, i; + u32 iomux;
offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev), "pinctrl-0"); @@ -547,6 +549,21 @@ static int parse_phy_pins(struct udevice *dev) else if (fdt_get_property(gd->fdt_blob, offset, "bias-pull-down", NULL)) pull = SUN4I_PINCTRL_PULL_DOWN;
+ /* + * The GPIO pinmux value is an integration choice, so depends on the + * SoC, not the EMAC variant. + */ + if (IS_ENABLED(CONFIG_MACH_SUN8I_H3)) + iomux = SUN8I_IOMUX_H3; + else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) + iomux = SUN8I_IOMUX_R40; + else if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) + iomux = SUN8I_IOMUX_H6; + else if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) + iomux = SUN8I_IOMUX_H616; + else + iomux = SUN8I_IOMUX; + for (i = 0; ; i++) { int pin;
@@ -559,12 +576,7 @@ static int parse_phy_pins(struct udevice *dev) if (pin < 0) continue;
- if (priv->variant == H3_EMAC) - sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX_H3); - else if (priv->variant == R40_GMAC || priv->variant == H6_EMAC) - sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX_R40); - else - sunxi_gpio_set_cfgpin(pin, SUN8I_IOMUX); + sunxi_gpio_set_cfgpin(pin, iomux);
if (drive != ~0) sunxi_gpio_set_drv(pin, drive);

With the fixes to the sun8i-emac driver, we can now enable Ethernet support on the OrangePi Zero2.
Signed-off-by: Andre Przywara andre.przywara@arm.com --- configs/orangepi_zero2_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/orangepi_zero2_defconfig b/configs/orangepi_zero2_defconfig index 0c20b5ff28f..5af964bf100 100644 --- a/configs/orangepi_zero2_defconfig +++ b/configs/orangepi_zero2_defconfig @@ -11,3 +11,5 @@ CONFIG_R_I2C_ENABLE=y CONFIG_DEFAULT_DEVICE_TREE="sun50i-h616-orangepi-zero2" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL_I2C_SUPPORT=y +CONFIG_PHY_REALTEK=y +CONFIG_SUN8I_EMAC=y

Dne sreda, 27. januar 2021 ob 02:06:35 CET je Andre Przywara napisal(a):
The first two patches prepare the sun8i-emac driver to deal with the EMAC as integrated into the H616 SoC. This IP block is compatible with the A64 version, but the current driver prevents us from using that:
- The EPHY syscon register needs to have a bit cleared to select the external PHY. On the A64 it is cleared on reset, but we should not rely on that. The Linux driver does so as well. Fixed in patch 1/3.
- The pinmux setting is tied to the compatible string, but the H616 requires a different value. Fixed in patch 2/3.
The final patch enables Ethernet support for the OrangePi Zero 2 board, which now works without further ado.
This is cleaner and works for me, so for the whole series: Tested-by: Jernej Skrabec jernej.skrabec@siol.net Reviewed-by: Jernej Skrabec jernej.skrabec@siol.net
Thanks!
Best regards, Jernej
Cheers, Andre
Andre Przywara (3): net: sun8i-emac: Always clear syscon EPHY register net: sun8i-emac: Determine pinmux based on SoC, not EMAC type sunxi: OrangePi Zero 2: Enable Ethernet
configs/orangepi_zero2_defconfig | 2 ++ drivers/net/sun8i_emac.c | 59 ++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 26 deletions(-)
-- 2.17.5
participants (2)
-
Andre Przywara
-
Jernej Škrabec