blob: 07aebd935e67005c742e277e928eca65790133af [file] [log] [blame]
Ye Licd5bb772020-05-03 22:41:14 +08001// 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
13struct eth_phy_device_priv {
14 struct mii_dev *mdio_bus;
15};
16
17int 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
49int 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) {
Simon Glass95588622020-12-22 19:30:28 -070057 uc_priv = (struct eth_phy_device_priv *)(dev_get_uclass_priv(dev));
Ye Licd5bb772020-05-03 22:41:14 +080058
59 if (!uc_priv->mdio_bus)
60 uc_priv->mdio_bus = mdio_bus;
61 }
62 }
63
64 return 0;
65}
66
67struct 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 */
Simon Glass95588622020-12-22 19:30:28 -070082 uc_priv = (struct eth_phy_device_priv *)(dev_get_uclass_priv(phy_dev));
Ye Licd5bb772020-05-03 22:41:14 +080083 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
97int 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
113UCLASS_DRIVER(eth_phy_generic) = {
114 .id = UCLASS_ETH_PHY,
115 .name = "eth_phy_generic",
Simon Glass8a2b47f2020-12-03 16:55:17 -0700116 .per_device_auto = sizeof(struct eth_phy_device_priv),
Ye Licd5bb772020-05-03 22:41:14 +0800117};
118
119U_BOOT_DRIVER(eth_phy_generic_drv) = {
120 .name = "eth_phy_generic_drv",
121 .id = UCLASS_ETH_PHY,
122};