1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2020 NXP 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <net.h> 9 #include <dm/device-internal.h> 10 #include <dm/uclass-internal.h> 11 #include <dm/lists.h> 12 13 struct eth_phy_device_priv { 14 struct mii_dev *mdio_bus; 15 }; 16 17 int eth_phy_binds_nodes(struct udevice *eth_dev) 18 { 19 ofnode mdio_node, phy_node; 20 const char *node_name; 21 int ret; 22 23 mdio_node = dev_read_subnode(eth_dev, "mdio"); 24 if (!ofnode_valid(mdio_node)) { 25 debug("%s: %s mdio subnode not found!", __func__, 26 eth_dev->name); 27 return -ENXIO; 28 } 29 30 ofnode_for_each_subnode(phy_node, mdio_node) { 31 node_name = ofnode_get_name(phy_node); 32 33 debug("* Found child node: '%s'\n", node_name); 34 35 ret = device_bind_driver_to_node(eth_dev, 36 "eth_phy_generic_drv", 37 node_name, phy_node, NULL); 38 if (ret) { 39 debug(" - Eth phy binding error: %d\n", ret); 40 continue; 41 } 42 43 debug(" - bound phy device: '%s'\n", node_name); 44 } 45 46 return 0; 47 } 48 49 int eth_phy_set_mdio_bus(struct udevice *eth_dev, struct mii_dev *mdio_bus) 50 { 51 struct udevice *dev; 52 struct eth_phy_device_priv *uc_priv; 53 54 for (uclass_first_device(UCLASS_ETH_PHY, &dev); dev; 55 uclass_next_device(&dev)) { 56 if (dev->parent == eth_dev) { 57 uc_priv = (struct eth_phy_device_priv *)(dev->uclass_priv); 58 59 if (!uc_priv->mdio_bus) 60 uc_priv->mdio_bus = mdio_bus; 61 } 62 } 63 64 return 0; 65 } 66 67 struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev) 68 { 69 int ret; 70 struct udevice *phy_dev; 71 struct eth_phy_device_priv *uc_priv; 72 73 /* Will probe the parent of phy device, then phy device */ 74 ret = uclass_get_device_by_phandle(UCLASS_ETH_PHY, eth_dev, 75 "phy-handle", &phy_dev); 76 if (!ret) { 77 if (eth_dev != phy_dev->parent) { 78 /* 79 * phy_dev is shared and controlled by 80 * other eth controller 81 */ 82 uc_priv = (struct eth_phy_device_priv *)(phy_dev->uclass_priv); 83 if (uc_priv->mdio_bus) 84 printf("Get shared mii bus on %s\n", eth_dev->name); 85 else 86 printf("Can't get shared mii bus on %s\n", eth_dev->name); 87 88 return uc_priv->mdio_bus; 89 } 90 } else { 91 printf("FEC: can't find phy-handle\n"); 92 } 93 94 return NULL; 95 } 96 97 int eth_phy_get_addr(struct udevice *dev) 98 { 99 struct ofnode_phandle_args phandle_args; 100 int reg; 101 102 if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, 103 &phandle_args)) { 104 debug("Failed to find phy-handle"); 105 return -ENODEV; 106 } 107 108 reg = ofnode_read_u32_default(phandle_args.node, "reg", 0); 109 110 return reg; 111 } 112 113 UCLASS_DRIVER(eth_phy_generic) = { 114 .id = UCLASS_ETH_PHY, 115 .name = "eth_phy_generic", 116 .per_device_auto_alloc_size = sizeof(struct eth_phy_device_priv), 117 }; 118 119 U_BOOT_DRIVER(eth_phy_generic_drv) = { 120 .name = "eth_phy_generic_drv", 121 .id = UCLASS_ETH_PHY, 122 }; 123