1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2020 NXP
4  */
5 
6 #define LOG_CATEGORY UCLASS_ETH_PHY
7 
8 #include <dm.h>
9 #include <log.h>
10 #include <net.h>
11 #include <asm-generic/gpio.h>
12 #include <dm/device_compat.h>
13 #include <dm/device-internal.h>
14 #include <dm/uclass-internal.h>
15 #include <dm/lists.h>
16 #include <linux/delay.h>
17 
18 struct eth_phy_device_priv {
19 	struct mii_dev *mdio_bus;
20 	struct gpio_desc reset_gpio;
21 	u32 reset_assert_delay;
22 	u32 reset_deassert_delay;
23 };
24 
eth_phy_binds_nodes(struct udevice * eth_dev)25 int eth_phy_binds_nodes(struct udevice *eth_dev)
26 {
27 	ofnode mdio_node, phy_node;
28 	const char *node_name;
29 	int ret;
30 
31 	/* search a subnode named "mdio.*" */
32 	dev_for_each_subnode(mdio_node, eth_dev) {
33 		node_name = ofnode_get_name(mdio_node);
34 		if (!strncmp(node_name, "mdio", 4))
35 			break;
36 	}
37 	if (!ofnode_valid(mdio_node)) {
38 		dev_dbg(eth_dev, "%s: %s mdio subnode not found!\n", __func__,
39 			eth_dev->name);
40 		return -ENXIO;
41 	}
42 	dev_dbg(eth_dev, "%s: %s subnode found!\n", __func__, node_name);
43 
44 	ofnode_for_each_subnode(phy_node, mdio_node) {
45 		node_name = ofnode_get_name(phy_node);
46 
47 		dev_dbg(eth_dev, "* Found child node: '%s'\n", node_name);
48 
49 		ret = device_bind_driver_to_node(eth_dev,
50 						 "eth_phy_generic_drv",
51 						 node_name, phy_node, NULL);
52 		if (ret) {
53 			dev_dbg(eth_dev, "  - Eth phy binding error: %d\n", ret);
54 			continue;
55 		}
56 
57 		dev_dbg(eth_dev, "  - bound phy device: '%s'\n", node_name);
58 	}
59 
60 	return 0;
61 }
62 
eth_phy_set_mdio_bus(struct udevice * eth_dev,struct mii_dev * mdio_bus)63 int eth_phy_set_mdio_bus(struct udevice *eth_dev, struct mii_dev *mdio_bus)
64 {
65 	struct udevice *dev;
66 	struct eth_phy_device_priv *uc_priv;
67 
68 	for (uclass_first_device(UCLASS_ETH_PHY, &dev); dev;
69 	     uclass_next_device(&dev)) {
70 		if (dev->parent == eth_dev) {
71 			uc_priv = (struct eth_phy_device_priv *)(dev_get_uclass_priv(dev));
72 
73 			if (!uc_priv->mdio_bus)
74 				uc_priv->mdio_bus = mdio_bus;
75 		}
76 	}
77 
78 	return 0;
79 }
80 
eth_phy_get_mdio_bus(struct udevice * eth_dev)81 struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev)
82 {
83 	int ret;
84 	struct udevice *phy_dev;
85 	struct eth_phy_device_priv *uc_priv;
86 
87 	/* Will probe the parent of phy device, then phy device */
88 	ret = uclass_get_device_by_phandle(UCLASS_ETH_PHY, eth_dev,
89 					   "phy-handle", &phy_dev);
90 	if (!ret) {
91 		if (eth_dev != phy_dev->parent) {
92 			/*
93 			 * phy_dev is shared and controlled by
94 			 * other eth controller
95 			 */
96 			uc_priv = (struct eth_phy_device_priv *)(dev_get_uclass_priv(phy_dev));
97 			if (uc_priv->mdio_bus)
98 				log_notice("Get shared mii bus on %s\n", eth_dev->name);
99 			else
100 				log_notice("Can't get shared mii bus on %s\n", eth_dev->name);
101 
102 			return uc_priv->mdio_bus;
103 		}
104 	} else {
105 		log_debug("Can't find phy-handle for %s\n", eth_dev->name);
106 	}
107 
108 	return NULL;
109 }
110 
eth_phy_get_addr(struct udevice * dev)111 int eth_phy_get_addr(struct udevice *dev)
112 {
113 	struct ofnode_phandle_args phandle_args;
114 	int reg;
115 
116 	if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
117 				       &phandle_args)) {
118 		dev_dbg(dev, "Failed to find phy-handle");
119 		return -ENODEV;
120 	}
121 
122 	reg = ofnode_read_u32_default(phandle_args.node, "reg", 0);
123 
124 	return reg;
125 }
126 
127 /* parsing generic properties of devicetree/bindings/net/ethernet-phy.yaml */
eth_phy_of_to_plat(struct udevice * dev)128 static int eth_phy_of_to_plat(struct udevice *dev)
129 {
130 	struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev);
131 	int ret;
132 
133 	if (!CONFIG_IS_ENABLED(DM_GPIO))
134 		return 0;
135 
136 	/* search "reset-gpios" in phy node */
137 	ret = gpio_request_by_name(dev, "reset-gpios", 0,
138 				   &uc_priv->reset_gpio,
139 				   GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
140 	if (ret && ret != -ENOENT)
141 		return ret;
142 
143 	uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0);
144 	uc_priv->reset_deassert_delay = dev_read_u32_default(dev, "reset-deassert-us", 0);
145 
146 	/* These are used by some DTs, try these as a fallback. */
147 	if (!uc_priv->reset_assert_delay && !uc_priv->reset_deassert_delay) {
148 		uc_priv->reset_assert_delay =
149 			dev_read_u32_default(dev, "reset-delay-us", 0);
150 		uc_priv->reset_deassert_delay =
151 			dev_read_u32_default(dev, "reset-post-delay-us", 0);
152 	}
153 
154 	return 0;
155 }
156 
eth_phy_reset(struct udevice * dev,int value)157 static void eth_phy_reset(struct udevice *dev, int value)
158 {
159 	struct eth_phy_device_priv *uc_priv = dev_get_uclass_priv(dev);
160 	u32 delay;
161 
162 	if (!CONFIG_IS_ENABLED(DM_GPIO))
163 		return;
164 
165 	if (!dm_gpio_is_valid(&uc_priv->reset_gpio))
166 		return;
167 
168 	dm_gpio_set_value(&uc_priv->reset_gpio, value);
169 
170 	delay = value ? uc_priv->reset_assert_delay : uc_priv->reset_deassert_delay;
171 	if (delay)
172 		udelay(delay);
173 }
174 
eth_phy_pre_probe(struct udevice * dev)175 static int eth_phy_pre_probe(struct udevice *dev)
176 {
177 	/* Assert and deassert the reset signal */
178 	eth_phy_reset(dev, 1);
179 	eth_phy_reset(dev, 0);
180 
181 	return 0;
182 }
183 
184 UCLASS_DRIVER(eth_phy_generic) = {
185 	.id		= UCLASS_ETH_PHY,
186 	.name		= "eth_phy_generic",
187 	.per_device_auto	= sizeof(struct eth_phy_device_priv),
188 	.pre_probe	= eth_phy_pre_probe,
189 };
190 
191 U_BOOT_DRIVER(eth_phy_generic_drv) = {
192 	.name		= "eth_phy_generic_drv",
193 	.id		= UCLASS_ETH_PHY,
194 	.of_to_plat	= eth_phy_of_to_plat,
195 };
196