From b14e520517cc0f5bdababfb1cc2909f228437d53 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 11 Jan 2021 21:11:45 +0100 Subject: [PATCH 1/4] net: sun8i-emac: Always clear syscon EPHY register 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 Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec --- 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 9f91a20d1d..2344525bf5 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 || From eb5a2b6710750d5ae002e7bf3dbec2c6ce2a17d8 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 11 Jan 2021 21:11:49 +0100 Subject: [PATCH 2/4] net: sun8i-emac: Determine pinmux based on SoC, not EMAC type 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 Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec --- 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 2344525bf5..0f6b6bb537 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); From 36ff6f00fb381fa906f563b153bdf533081d7513 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Sat, 23 Jan 2021 12:46:43 +0000 Subject: [PATCH 3/4] sunxi: OrangePi Zero 2: Enable Ethernet With the fixes to the sun8i-emac driver, we can now enable Ethernet support on the OrangePi Zero2. Signed-off-by: Andre Przywara Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec --- configs/orangepi_zero2_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/orangepi_zero2_defconfig b/configs/orangepi_zero2_defconfig index 0c20b5ff28..5af964bf10 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 From a38bb0d0377dd47dfc9270fb46112bca263e8885 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 24 Jan 2021 19:13:10 +0100 Subject: [PATCH 4/4] ata: sunxi: fix debug messages It is useless and misleading to print the ret variable that is not set by the dev_read_addr routine. Also, move the '\n' character after the round bracket that contains the error code. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass Signed-off-by: Andre Przywara --- drivers/ata/ahci_sunxi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index 58e345d998..94a3379c53 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -80,18 +80,18 @@ static int sunxi_sata_probe(struct udevice *dev) base = dev_read_addr(dev); if (base == FDT_ADDR_T_NONE) { - debug("%s: Failed to find address (err=%d\n)", __func__, ret); + debug("%s: Failed to find address\n", __func__); return -EINVAL; } reg = (u8 *)base; ret = sunxi_ahci_phy_init(reg); if (ret) { - debug("%s: Failed to init phy (err=%d\n)", __func__, ret); + debug("%s: Failed to init phy (err=%d)\n", __func__, ret); return ret; } ret = ahci_probe_scsi(dev, base); if (ret) { - debug("%s: Failed to probe (err=%d\n)", __func__, ret); + debug("%s: Failed to probe (err=%d)\n", __func__, ret); return ret; } @@ -105,7 +105,7 @@ static int sunxi_sata_bind(struct udevice *dev) ret = ahci_bind_scsi(dev, &scsi_dev); if (ret) { - debug("%s: Failed to bind (err=%d\n)", __func__, ret); + debug("%s: Failed to bind (err=%d)\n", __func__, ret); return ret; }