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 <danishan...@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