eth-phy-uclass.c 2.6 KB

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