[RFC PATCH 1/5] net: mediatek: move MT7531 mdio to dedicated driver
Christian Marangi
ansuelsmth at gmail.com
Sat Aug 23 01:33:22 CEST 2025
On Sat, Aug 23, 2025 at 01:29:15AM +0200, Christian Marangi wrote:
> In preparation for support of MDIO on AN7581, move the MT7531 logic to a
> dedicated driver and permit usage of the mdio read/write function to the
> mtk_eth driver.
>
> Minor changes are required to mtk_eth for this change as the dedicated
> MDIO driver only needs info of the GSW register and nothing else.
>
> This permits Airoha driver to make use of DM_MDIO to bind for the MT7531
> driver that have the same exact register.
>
> Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
> ---
> drivers/net/Kconfig | 3 +
> drivers/net/Makefile | 4 +
> drivers/net/mdio-mt7531.c | 140 +++++++++++++++++++++++++++++++++++
> drivers/net/mdio-mt7531.h | 9 +++
> drivers/net/mtk_eth/Kconfig | 1 +
> drivers/net/mtk_eth/mt753x.c | 29 +++-----
> drivers/net/mtk_eth/mt753x.h | 3 +
> 7 files changed, 169 insertions(+), 20 deletions(-)
> create mode 100644 drivers/net/mdio-mt7531.c
> create mode 100644 drivers/net/mdio-mt7531.h
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index d1cb69f85ad..9ac9bee46c9 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -966,6 +966,9 @@ config TSEC_ENET
> This driver implements support for the (Enhanced) Three-Speed
> Ethernet Controller found on Freescale SoCs.
>
> +config MDIO_MT7531
> + bool
> +
> source "drivers/net/mtk_eth/Kconfig"
>
> config HIFEMAC_ETH
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index f8f9a71f815..beb7864adc2 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -62,7 +62,11 @@ obj-$(CONFIG_LITEETH) += liteeth.o
> obj-$(CONFIG_MACB) += macb.o
> obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
> obj-$(CONFIG_MDIO_IPQ4019) += mdio-ipq4019.o
> +<<<<<<< HEAD
> obj-$(CONFIG_MDIO_GPIO_BITBANG) += mdio_gpio.o
> +=======
> +obj-$(CONFIG_MDIO_MT7531) += mdio-mt7531.o
> +>>>>>>> net: mediatek: move MT7531 mdio to dedicated driver
This merge conflict slipped in and will be fixed in the next revision.
These changes were tested locally on an AN7581 RFB board.
> obj-$(CONFIG_MDIO_MUX_I2CREG) += mdio_mux_i2creg.o
> obj-$(CONFIG_MDIO_MUX_MESON_G12A) += mdio_mux_meson_g12a.o
> obj-$(CONFIG_MDIO_MUX_MESON_GXL) += mdio_mux_meson_gxl.o
> diff --git a/drivers/net/mdio-mt7531.c b/drivers/net/mdio-mt7531.c
> new file mode 100644
> index 00000000000..4772c9b5407
> --- /dev/null
> +++ b/drivers/net/mdio-mt7531.c
> @@ -0,0 +1,140 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include <asm/io.h>
> +#include <dm.h>
> +#include <linux/bitfield.h>
> +#include <linux/iopoll.h>
> +#include <miiphy.h>
> +
> +#define MT7531_PHY_IAC 0x701c
> +#define MT7531_PHY_ACS_ST BIT(31)
> +#define MT7531_MDIO_REG_ADDR_CL22 GENMASK(29, 25)
> +#define MT7531_MDIO_DEV_ADDR MT7531_MDIO_REG_ADDR_CL22
> +#define MT7531_MDIO_PHY_ADDR GENMASK(24, 20)
> +#define MT7531_MDIO_CMD GENMASK(19, 18)
> +#define MT7531_MDIO_CMD_READ_CL45 FIELD_PREP_CONST(MT7531_MDIO_CMD, 0x3)
> +#define MT7531_MDIO_CMD_READ_CL22 FIELD_PREP_CONST(MT7531_MDIO_CMD, 0x2)
> +#define MT7531_MDIO_CMD_WRITE FIELD_PREP_CONST(MT7531_MDIO_CMD, 0x1)
> +#define MT7531_MDIO_CMD_ADDR FIELD_PREP_CONST(MT7531_MDIO_CMD, 0x0)
> +#define MT7531_MDIO_ST GENMASK(17, 16)
> +#define MT7531_MDIO_ST_CL22 FIELD_PREP_CONST(MT7531_MDIO_ST, 0x1)
> +#define MT7531_MDIO_ST_CL45 FIELD_PREP_CONST(MT7531_MDIO_ST, 0x0)
> +#define MT7531_MDIO_RW_DATA GENMASK(15, 0)
> +#define MT7531_MDIO_REG_ADDR_CL45 MT7531_MDIO_RW_DATA
> +
> +#define MT7531_MDIO_TIMEOUT 100000
> +#define MT7531_MDIO_SLEEP 20
> +
> +struct mt7531_mdio_priv {
> + phys_addr_t switch_regs;
> +};
> +
> +static int mt7531_mdio_wait_busy(struct mt7531_mdio_priv *priv)
> +{
> + unsigned int busy;
> +
> + return readl_poll_sleep_timeout(priv->switch_regs + MT7531_PHY_IAC,
> + busy, (busy & MT7531_PHY_ACS_ST) == 0,
> + MT7531_MDIO_SLEEP, MT7531_MDIO_TIMEOUT);
> +}
> +
> +int mt7531_mdio_read(struct udevice *dev, int addr, int devad, int reg)
> +{
> + struct mt7531_mdio_priv *priv = dev_get_priv(dev);
> + u32 val;
> +
> + if (devad != MDIO_DEVAD_NONE) {
> + if (mt7531_mdio_wait_busy(priv))
> + return -ETIMEDOUT;
> +
> + val = MT7531_PHY_ACS_ST |
> + MT7531_MDIO_ST_CL45 | MT7531_MDIO_CMD_ADDR |
> + FIELD_PREP(MT7531_MDIO_PHY_ADDR, addr) |
> + FIELD_PREP(MT7531_MDIO_DEV_ADDR, devad) |
> + FIELD_PREP(MT7531_MDIO_REG_ADDR_CL45, reg);
> +
> + writel(val, priv->switch_regs + MT7531_PHY_IAC);
> + }
> +
> + if (mt7531_mdio_wait_busy(priv))
> + return -ETIMEDOUT;
> +
> + val = MT7531_PHY_ACS_ST | FIELD_PREP(MT7531_MDIO_PHY_ADDR, addr);
> + if (devad != MDIO_DEVAD_NONE)
> + val |= MT7531_MDIO_ST_CL45 | MT7531_MDIO_CMD_READ_CL45 |
> + FIELD_PREP(MT7531_MDIO_DEV_ADDR, devad);
> + else
> + val |= MT7531_MDIO_ST_CL22 | MT7531_MDIO_CMD_READ_CL22 |
> + FIELD_PREP(MT7531_MDIO_REG_ADDR_CL22, reg);
> +
> + writel(val, priv->switch_regs + MT7531_PHY_IAC);
> +
> + if (mt7531_mdio_wait_busy(priv))
> + return -ETIMEDOUT;
> +
> + val = readl(priv->switch_regs + MT7531_PHY_IAC);
> + return val & MT7531_MDIO_RW_DATA;
> +}
> +
> +int mt7531_mdio_write(struct udevice *dev, int addr, int devad,
> + int reg, u16 value)
> +{
> + struct mt7531_mdio_priv *priv = dev_get_priv(dev);
> + u32 val;
> +
> + if (devad != MDIO_DEVAD_NONE) {
> + if (mt7531_mdio_wait_busy(priv))
> + return -ETIMEDOUT;
> +
> + val = MT7531_PHY_ACS_ST |
> + MT7531_MDIO_ST_CL45 | MT7531_MDIO_CMD_ADDR |
> + FIELD_PREP(MT7531_MDIO_PHY_ADDR, addr) |
> + FIELD_PREP(MT7531_MDIO_DEV_ADDR, devad) |
> + FIELD_PREP(MT7531_MDIO_REG_ADDR_CL45, reg);
> +
> + writel(val, priv->switch_regs + MT7531_PHY_IAC);
> + }
> +
> + if (mt7531_mdio_wait_busy(priv))
> + return -ETIMEDOUT;
> +
> + val = MT7531_PHY_ACS_ST | FIELD_PREP(MT7531_MDIO_PHY_ADDR, addr) |
> + MT7531_MDIO_CMD_WRITE | FIELD_PREP(MT7531_MDIO_RW_DATA, value);
> + if (devad != MDIO_DEVAD_NONE)
> + val |= MT7531_MDIO_ST_CL45 |
> + FIELD_PREP(MT7531_MDIO_DEV_ADDR, devad);
> + else
> + val |= MT7531_MDIO_ST_CL22 |
> + FIELD_PREP(MT7531_MDIO_REG_ADDR_CL22, reg);
> +
> + writel(val, priv->switch_regs + MT7531_PHY_IAC);
> +
> + if (mt7531_mdio_wait_busy(priv))
> + return -ETIMEDOUT;
> +
> + return 0;
> +}
> +
> +static const struct mdio_ops mt7531_mdio_ops = {
> + .read = mt7531_mdio_read,
> + .write = mt7531_mdio_write,
> +};
> +
> +static int mt7531_mdio_probe(struct udevice *dev)
> +{
> + struct mt7531_mdio_priv *priv = dev_get_priv(dev);
> +
> + priv->switch_regs = dev_read_addr(dev);
> + if (priv->switch_regs == FDT_ADDR_T_NONE)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +U_BOOT_DRIVER(mt7531_mdio) = {
> + .name = "mt7531-mdio",
> + .id = UCLASS_MDIO,
> + .probe = mt7531_mdio_probe,
> + .ops = &mt7531_mdio_ops,
> + .priv_auto = sizeof(struct mt7531_mdio_priv),
> +};
> diff --git a/drivers/net/mdio-mt7531.h b/drivers/net/mdio-mt7531.h
> new file mode 100644
> index 00000000000..ee096112f92
> --- /dev/null
> +++ b/drivers/net/mdio-mt7531.h
> @@ -0,0 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +struct mt7531_mdio_priv {
> + phys_addr_t switch_regs;
> +};
> +
> +int mt7531_mdio_read(struct udevice *dev, int addr, int devad, int reg);
> +int mt7531_mdio_write(struct udevice *dev, int addr, int devad,
> + int reg, u16 value);
> diff --git a/drivers/net/mtk_eth/Kconfig b/drivers/net/mtk_eth/Kconfig
> index e8cdf408237..67b2b612b1a 100644
> --- a/drivers/net/mtk_eth/Kconfig
> +++ b/drivers/net/mtk_eth/Kconfig
> @@ -4,6 +4,7 @@ config MEDIATEK_ETH
> select PHYLIB
> select DM_GPIO
> select DM_RESET
> + select MDIO_MT7531
> help
> This Driver support MediaTek Ethernet GMAC
> Say Y to enable support for the MediaTek Ethernet GMAC.
> diff --git a/drivers/net/mtk_eth/mt753x.c b/drivers/net/mtk_eth/mt753x.c
> index cdd52f3ff1b..cf643f336d6 100644
> --- a/drivers/net/mtk_eth/mt753x.c
> +++ b/drivers/net/mtk_eth/mt753x.c
> @@ -138,8 +138,8 @@ int mt7531_mii_read(struct mt753x_switch_priv *priv, u8 phy, u8 reg)
>
> phy_addr = MT753X_PHY_ADDR(priv->phy_base, phy);
>
> - return mt7531_mii_rw(priv, phy_addr, reg, 0, MDIO_CMD_READ,
> - MDIO_ST_C22);
> + return mt7531_mdio_read(&priv->mdio_priv, phy_addr, MDIO_DEVAD_NONE,
> + reg);
> }
>
> int mt7531_mii_write(struct mt753x_switch_priv *priv, u8 phy, u8 reg, u16 val)
> @@ -151,48 +151,36 @@ int mt7531_mii_write(struct mt753x_switch_priv *priv, u8 phy, u8 reg, u16 val)
>
> phy_addr = MT753X_PHY_ADDR(priv->phy_base, phy);
>
> - return mt7531_mii_rw(priv, phy_addr, reg, val, MDIO_CMD_WRITE,
> - MDIO_ST_C22);
> + return mt7531_mdio_write(&priv->mdio_priv, phy_addr, MDIO_DEVAD_NONE,
> + reg, val);
> }
>
> int mt7531_mmd_read(struct mt753x_switch_priv *priv, u8 addr, u8 devad,
> u16 reg)
> {
> u8 phy_addr;
> - int ret;
>
> if (addr >= MT753X_NUM_PHYS)
> return -EINVAL;
>
> phy_addr = MT753X_PHY_ADDR(priv->phy_base, addr);
>
> - ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR,
> - MDIO_ST_C45);
> - if (ret)
> - return ret;
> -
> - return mt7531_mii_rw(priv, phy_addr, devad, 0, MDIO_CMD_READ_C45,
> - MDIO_ST_C45);
> + return mt7531_mdio_read(&priv->mdio_priv, phy_addr, devad,
> + reg);
> }
>
> int mt7531_mmd_write(struct mt753x_switch_priv *priv, u8 addr, u8 devad,
> u16 reg, u16 val)
> {
> u8 phy_addr;
> - int ret;
>
> if (addr >= MT753X_NUM_PHYS)
> return 0;
>
> phy_addr = MT753X_PHY_ADDR(priv->phy_base, addr);
>
> - ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR,
> - MDIO_ST_C45);
> - if (ret)
> - return ret;
> -
> - return mt7531_mii_rw(priv, phy_addr, devad, val, MDIO_CMD_WRITE,
> - MDIO_ST_C45);
> + return mt7531_mdio_write(&priv->mdio_priv, phy_addr, devad,
> + reg, val);
> }
>
> static int mt7531_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
> @@ -224,6 +212,7 @@ int mt7531_mdio_register(struct mt753x_switch_priv *priv)
> if (!mdio_bus)
> return -ENOMEM;
>
> + priv->mdio_priv.switch_regs = priv->epriv.ethsys_base + GSW_BASE;
> mdio_bus->read = mt7531_mdio_read;
> mdio_bus->write = mt7531_mdio_write;
> snprintf(mdio_bus->name, sizeof(mdio_bus->name), priv->epriv.sw->name);
> diff --git a/drivers/net/mtk_eth/mt753x.h b/drivers/net/mtk_eth/mt753x.h
> index 65046a1421c..cd128ad39fe 100644
> --- a/drivers/net/mtk_eth/mt753x.h
> +++ b/drivers/net/mtk_eth/mt753x.h
> @@ -14,6 +14,8 @@
> #include <linux/bitops.h>
> #include <linux/bitfield.h>
>
> +#include "../mdio-mt7531.h"
> +
> struct mtk_eth_priv;
>
> #define MT753X_NUM_PHYS 5
> @@ -254,6 +256,7 @@ struct mtk_eth_priv;
>
> struct mt753x_switch_priv {
> struct mtk_eth_switch_priv epriv;
> + struct mt7531_mdio_priv mdio_priv;
> struct mii_dev *mdio_bus;
> u32 smi_addr;
> u32 phy_base;
> --
> 2.50.0
>
--
Ansuel
More information about the U-Boot
mailing list