[PATCH v3 1/1] net: designware: Add bitbang feature for designware driver

Michael Chang zhang971090220 at gmail.com
Wed Jan 15 02:42:11 CET 2025


Add bb_miiphy_bus function for designware bitbang feature.

Signed-off-by: Jim Liu <JJLIU0 at nuvoton.com>
Signed-off-by: Michael Chang <zhang971090220 at gmail.com>
---
 arch/arm/dts/nuvoton-npcm845-evb.dts |   1 +
 drivers/net/designware.c             | 111 +++++++++++++++++++++++++++
 drivers/net/designware.h             |   6 +-
 3 files changed, 117 insertions(+), 1 deletion(-)

diff --git a/arch/arm/dts/nuvoton-npcm845-evb.dts b/arch/arm/dts/nuvoton-npcm845-evb.dts
index 0d3aaa0fff..1535defe38 100644
--- a/arch/arm/dts/nuvoton-npcm845-evb.dts
+++ b/arch/arm/dts/nuvoton-npcm845-evb.dts
@@ -190,6 +190,7 @@
 	snps,mdio-gpio = <&gpio2 28 GPIO_ACTIVE_HIGH>;    /* gpio92 */
 	snps,reset-active-low;
 	snps,reset-delays-us = <0 10000 1000000>;
+	snps,bitbang-delay = <1>;
 	snps,reset-gpio = <&gpio2 29 GPIO_ACTIVE_LOW>;    /* gpio93 */
 	status = "okay";
 };
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 07b0f49ef5..4fe13777e5 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -784,6 +784,37 @@ int designware_eth_probe(struct udevice *dev)
 	priv->bus = miiphy_get_dev_by_name(dev->name);
 	priv->dev = dev;
 
+#if defined(CONFIG_BITBANGMII) && CONFIG_IS_ENABLED(DM_GPIO)
+	if (dev_read_bool(dev, "snps,bitbang-mii")) {
+		int bus_idx;
+
+		debug("\n%s: use bitbang mii..\n", dev->name);
+		ret = gpio_request_by_name(dev, "snps,mdc-gpio", 0,
+					&priv->mdc_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+		if (ret) {
+			debug("no mdc-gpio\n");
+			return ret;
+		}
+		ret = gpio_request_by_name(dev, "snps,mdio-gpio", 0,
+					&priv->mdio_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+		if (ret) {
+			debug("no mdio-gpio\n");
+			return ret;
+		}
+		priv->bb_delay = dev_read_u32_default(dev, "snps,bitbang-delay", 1);
+
+		for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; bus_idx++) {
+			if (!bb_miiphy_buses[bus_idx].priv) {
+				bb_miiphy_buses[bus_idx].priv = priv;
+				strlcpy(bb_miiphy_buses[bus_idx].name, priv->bus->name,
+						MDIO_NAME_LEN);
+				priv->bus->read = bb_miiphy_read;
+				priv->bus->write = bb_miiphy_write;
+				break;
+			}
+		}
+	}
+#endif
 	ret = dw_phy_init(priv, dev);
 	debug("%s, ret=%d\n", __func__, ret);
 	if (!ret)
@@ -894,3 +925,83 @@ static struct pci_device_id supported[] = {
 };
 
 U_BOOT_PCI_DEVICE(eth_designware, supported);
+
+#if CONFIG_IS_ENABLED(BITBANGMII) && CONFIG_IS_ENABLED(DM_GPIO)
+static int npcm_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
+{
+	struct dw_eth_dev *priv = bus->priv;
+	struct gpio_desc *desc = &priv->mdio_gpio;
+
+	desc->flags = 0;
+	dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+
+	return 0;
+}
+
+static int npcm_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
+{
+	struct dw_eth_dev *priv = bus->priv;
+	struct gpio_desc *desc = &priv->mdio_gpio;
+
+	desc->flags = 0;
+	dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_IN);
+
+	return 0;
+}
+
+static int npcm_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
+{
+	struct dw_eth_dev *priv = bus->priv;
+
+	if (v)
+		dm_gpio_set_value(&priv->mdio_gpio, 1);
+	else
+		dm_gpio_set_value(&priv->mdio_gpio, 0);
+
+	return 0;
+}
+
+static int npcm_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
+{
+	struct dw_eth_dev *priv = bus->priv;
+
+	*v = dm_gpio_get_value(&priv->mdio_gpio);
+
+	return 0;
+}
+
+static int npcm_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
+{
+	struct dw_eth_dev *priv = bus->priv;
+
+	if (v)
+		dm_gpio_set_value(&priv->mdc_gpio, 1);
+	else
+		dm_gpio_set_value(&priv->mdc_gpio, 0);
+
+	return 0;
+}
+
+static int npcm_eth_bb_delay(struct bb_miiphy_bus *bus)
+{
+	struct dw_eth_dev *priv = bus->priv;
+
+	udelay(priv->bb_delay);
+	return 0;
+}
+
+struct bb_miiphy_bus bb_miiphy_buses[] = {
+	{
+		.name		= BB_MII_DEVNAME,
+		.mdio_active	= npcm_eth_bb_mdio_active,
+		.mdio_tristate	= npcm_eth_bb_mdio_tristate,
+		.set_mdio	= npcm_eth_bb_set_mdio,
+		.get_mdio	= npcm_eth_bb_get_mdio,
+		.set_mdc	= npcm_eth_bb_set_mdc,
+		.delay		= npcm_eth_bb_delay,
+		.priv		= NULL,
+	}
+};
+
+int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
+#endif
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index e47101ccaf..6b46bafeeb 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -229,11 +229,15 @@ struct dw_eth_dev {
 	u32 max_speed;
 	u32 tx_currdescnum;
 	u32 rx_currdescnum;
-
+#if  defined(CONFIG_BITBANGMII)
+	u32 bb_delay;
+#endif
 	struct eth_mac_regs *mac_regs_p;
 	struct eth_dma_regs *dma_regs_p;
 #if CONFIG_IS_ENABLED(DM_GPIO)
 	struct gpio_desc reset_gpio;
+	struct gpio_desc mdc_gpio;
+	struct gpio_desc mdio_gpio;
 #endif
 #ifdef CONFIG_CLK
 	struct clk *clocks;	/* clock list */
-- 
2.34.1



More information about the U-Boot mailing list