[RFC PATCH 07/16] net: ti: icssg: Enforce pinctrl state on the MDIO child node

MD Danish Anwar danishanwar at ti.com
Tue Dec 19 11:12:07 CET 2023


The binding represents the MDIO controller as a child device tree
node of the MAC device tree node.

The U-Boot driver mostly ignores that child device tree node and just
hardcodes the resources it uses to support both the MAC and MDIO in a
single driver.

However, some resources like pinctrl muxing states are thus ignored.
This has been a problem with some device trees that will put some
pinctrl states on the MDIO device tree node.

Let's rework the driver a bit to create a dummy MDIO driver that we will
then get during our initialization to force the core to select the right
muxing.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
 drivers/net/ti/Kconfig        |  1 +
 drivers/net/ti/icssg_prueth.c | 59 +++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/net/ti/Kconfig b/drivers/net/ti/Kconfig
index 9fead2c7ce..6935b70e12 100644
--- a/drivers/net/ti/Kconfig
+++ b/drivers/net/ti/Kconfig
@@ -53,6 +53,7 @@ config TI_AM65_CPSW_NUSS
 config TI_ICSSG_PRUETH
 	bool "TI Gigabit PRU Ethernet driver"
 	depends on ARCH_K3
+	imply DM_MDIO
 	select PHYLIB
 	help
 	  Support Gigabit Ethernet ports over the ICSSG PRU Subsystem
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 1a7445a015..40ad827e49 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -13,6 +13,7 @@
 #include <dm/device.h>
 #include <dma-uclass.h>
 #include <dm/of_access.h>
+#include <dm/pinctrl.h>
 #include <fs_loader.h>
 #include <miiphy.h>
 #include <net.h>
@@ -100,9 +101,56 @@ static int icssg_phy_init(struct udevice *dev)
 	return ret;
 }
 
+static ofnode prueth_find_mdio(ofnode parent)
+{
+	ofnode node;
+
+	ofnode_for_each_subnode(node, parent)
+		if (ofnode_device_is_compatible(node, "ti,davinci_mdio"))
+			return node;
+
+	return ofnode_null();
+}
+
+static int prueth_mdio_setup(struct udevice *dev)
+{
+	struct prueth *priv = dev_get_priv(dev);
+	struct udevice *mdio_dev;
+	ofnode mdio;
+	int ret;
+
+	mdio = prueth_find_mdio(dev_ofnode(priv->pruss));
+	if (!ofnode_valid(mdio))
+		return 0;
+
+	/*
+	 * The MDIO controller is represented in the DT binding by a
+	 * subnode of the MAC controller.
+	 *
+	 * We don't have a DM driver for the MDIO device yet, and thus any
+	 * pinctrl setting on its node will be ignored.
+	 *
+	 * However, we do need to make sure the pins states tied to the
+	 * MDIO node are configured properly. Fortunately, the core DM
+	 * does that for use when we get a device, so we can work around
+	 * that whole issue by just requesting a dummy MDIO driver to
+	 * probe, and our pins will get muxed.
+	 */
+	ret = uclass_get_device_by_ofnode(UCLASS_MDIO, mdio, &mdio_dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int icssg_mdio_init(struct udevice *dev)
 {
 	struct prueth *prueth = dev_get_priv(dev);
+	int ret;
+
+	ret = prueth_mdio_setup(dev);
+	if (ret)
+		return ret;
 
 	prueth->bus = cpsw_mdio_init(dev->name, prueth->mdio_base,
 				     prueth->mdio_freq,
@@ -593,3 +641,14 @@ U_BOOT_DRIVER(prueth) = {
 	.plat_auto = sizeof(struct eth_pdata),
 	.flags = DM_FLAG_ALLOC_PRIV_DMA,
 };
+
+static const struct udevice_id prueth_mdio_ids[] = {
+	{ .compatible = "ti,davinci_mdio" },
+	{ }
+};
+
+U_BOOT_DRIVER(prueth_mdio) = {
+	.name		= "prueth_mdio",
+	.id			= UCLASS_MDIO,
+	.of_match	= prueth_mdio_ids,
+};
-- 
2.34.1



More information about the U-Boot mailing list