1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * GPIO based MDIO bitbang driver.
4  *
5  * Copyright 2024 Markus Gothe <markus.gothe@genexis.eu>
6  *
7  * This file is based on the Linux kernel drivers drivers/net/phy/mdio-gpio.c
8  * and drivers/net/phy/mdio-bitbang.c which have the following copyrights:
9  *
10  * Copyright (c) 2008 CSE Semaphore Belgium.
11  *  by Laurent Pinchart <laurentp@cse-semaphore.com>
12  *
13  * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
14  *
15  * Author: Scott Wood <scottwood@freescale.com>
16  * Copyright (c) 2007 Freescale Semiconductor
17  *
18  * Copyright (c) 2003 Intracom S.A.
19  *  by Pantelis Antoniou <panto@intracom.gr>
20  *
21  * 2005 (c) MontaVista Software, Inc.
22  * Vitaly Bordug <vbordug@ru.mvista.com>
23  */
24 
25 #include <dm.h>
26 #include <log.h>
27 #include <miiphy.h>
28 #include <asm/gpio.h>
29 #include <linux/bitops.h>
30 #include <linux/delay.h>
31 #include <linux/mdio.h>
32 
33 #define MDIO_READ 2
34 #define MDIO_WRITE 1
35 
36 #define MDIO_C45 BIT(15)
37 #define MDIO_C45_ADDR (MDIO_C45 | 0)
38 #define MDIO_C45_READ (MDIO_C45 | 3)
39 #define MDIO_C45_WRITE (MDIO_C45 | 1)
40 
41 /* Minimum MDC period is 400 ns, plus some margin for error.  MDIO_DELAY
42  * is done twice per period.
43  */
44 #define MDIO_DELAY 250
45 
46 /* The PHY may take up to 300 ns to produce data, plus some margin
47  * for error.
48  */
49 #define MDIO_READ_DELAY 350
50 
51 #define MDIO_GPIO_MDC	0
52 #define MDIO_GPIO_MDIO	1
53 #define MDIO_GPIO_MDO	2
54 
55 struct mdio_gpio_priv {
56 	struct gpio_desc mdc, mdio, mdo;
57 };
58 
mdio_dir(struct udevice * mdio_dev,int dir)59 static void mdio_dir(struct udevice *mdio_dev, int dir)
60 {
61 	struct mdio_gpio_priv *priv = dev_get_priv(mdio_dev);
62 
63 	if (dm_gpio_is_valid(&priv->mdo)) {
64 		/* Separate output pin. Always set its value to high
65 		 * when changing direction. If direction is input,
66 		 * assume the pin serves as pull-up. If direction is
67 		 * output, the default value is high.
68 		 */
69 		dm_gpio_set_value(&priv->mdo, 1);
70 		return;
71 	}
72 
73 	if (dir)
74 		dm_gpio_set_dir_flags(&priv->mdio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
75 	else
76 		dm_gpio_set_dir_flags(&priv->mdio, GPIOD_IS_IN);
77 }
78 
mdio_get(struct udevice * mdio_dev)79 static int mdio_get(struct udevice *mdio_dev)
80 {
81 	struct mdio_gpio_priv *priv = dev_get_priv(mdio_dev);
82 
83 	return dm_gpio_get_value(&priv->mdio);
84 }
85 
mdio_set(struct udevice * mdio_dev,int what)86 static void mdio_set(struct udevice *mdio_dev, int what)
87 {
88 	struct mdio_gpio_priv *priv = dev_get_priv(mdio_dev);
89 
90 	if (dm_gpio_is_valid(&priv->mdo))
91 		dm_gpio_set_value(&priv->mdo, what);
92 	else
93 		dm_gpio_set_value(&priv->mdio, what);
94 }
95 
mdc_set(struct udevice * mdio_dev,int what)96 static void mdc_set(struct udevice *mdio_dev, int what)
97 {
98 	struct mdio_gpio_priv *priv = dev_get_priv(mdio_dev);
99 
100 	dm_gpio_set_value(&priv->mdc, what);
101 }
102 
103 /* MDIO must already be configured as output. */
mdio_gpio_send_bit(struct udevice * mdio_dev,int val)104 static void mdio_gpio_send_bit(struct udevice *mdio_dev, int val)
105 {
106 	mdio_set(mdio_dev, val);
107 	ndelay(MDIO_DELAY);
108 	mdc_set(mdio_dev, 1);
109 	ndelay(MDIO_DELAY);
110 	mdc_set(mdio_dev, 0);
111 }
112 
113 /* MDIO must already be configured as input. */
mdio_gpio_get_bit(struct udevice * mdio_dev)114 static int mdio_gpio_get_bit(struct udevice *mdio_dev)
115 {
116 	ndelay(MDIO_DELAY);
117 	mdc_set(mdio_dev, 1);
118 	ndelay(MDIO_READ_DELAY);
119 	mdc_set(mdio_dev, 0);
120 
121 	return mdio_get(mdio_dev);
122 }
123 
124 /* MDIO must already be configured as output. */
mdio_gpio_send_num(struct udevice * mdio_dev,u16 val,int bits)125 static void mdio_gpio_send_num(struct udevice *mdio_dev, u16 val, int bits)
126 {
127 	int i;
128 
129 	for (i = bits - 1; i >= 0; i--)
130 		mdio_gpio_send_bit(mdio_dev, (val >> i) & 1);
131 }
132 
133 /* MDIO must already be configured as input. */
mdio_gpio_get_num(struct udevice * mdio_dev,int bits)134 static u16 mdio_gpio_get_num(struct udevice *mdio_dev, int bits)
135 {
136 	int i;
137 	u16 ret = 0;
138 
139 	for (i = bits - 1; i >= 0; i--) {
140 		ret <<= 1;
141 		ret |= mdio_gpio_get_bit(mdio_dev);
142 	}
143 
144 	return ret;
145 }
146 
147 /* Utility to send the preamble, address, and
148  * register (common to read and write).
149  */
mdio_gpio_cmd(struct udevice * mdio_dev,int op,u8 phy,u8 reg)150 static void mdio_gpio_cmd(struct udevice *mdio_dev, int op, u8 phy, u8 reg)
151 {
152 	int i;
153 
154 	mdio_dir(mdio_dev, 1);
155 
156 	/*
157 	 * Send a 32 bit preamble ('1's) with an extra '1' bit for good
158 	 * measure.  The IEEE spec says this is a PHY optional
159 	 * requirement.  The AMD 79C874 requires one after power up and
160 	 * one after a MII communications error.  This means that we are
161 	 * doing more preambles than we need, but it is safer and will be
162 	 * much more robust.
163 	 */
164 	for (i = 0; i < 32; i++)
165 		mdio_gpio_send_bit(mdio_dev, 1);
166 
167 	/*
168 	 * Send the start bit (01) and the read opcode (10) or write (01).
169 	 * Clause 45 operation uses 00 for the start and 11, 10 for
170 	 * read/write.
171 	 */
172 	mdio_gpio_send_bit(mdio_dev, 0);
173 	if (op & MDIO_C45)
174 		mdio_gpio_send_bit(mdio_dev, 0);
175 	else
176 		mdio_gpio_send_bit(mdio_dev, 1);
177 	mdio_gpio_send_bit(mdio_dev, (op >> 1) & 1);
178 	mdio_gpio_send_bit(mdio_dev, (op >> 0) & 1);
179 
180 	mdio_gpio_send_num(mdio_dev, phy, 5);
181 	mdio_gpio_send_num(mdio_dev, reg, 5);
182 }
183 
184 /*
185  * In clause 45 mode all commands are prefixed by MDIO_ADDR to specify the
186  * lower 16 bits of the 21 bit address. This transfer is done identically to a
187  * MDIO_WRITE except for a different code. To enable clause 45 mode or
188  * MII_ADDR_C45 into the address. Theoretically clause 45 and normal devices
189  * can exist on the same bus. Normal devices should ignore the MDIO_ADDR
190  * phase.
191  */
mdio_gpio_cmd_addr(struct udevice * mdio_dev,int phy,u32 dev_addr,u32 reg)192 static int mdio_gpio_cmd_addr(struct udevice *mdio_dev, int phy, u32 dev_addr, u32 reg)
193 {
194 	mdio_gpio_cmd(mdio_dev, MDIO_C45_ADDR, phy, dev_addr);
195 
196 	/* send the turnaround (10) */
197 	mdio_gpio_send_bit(mdio_dev, 1);
198 	mdio_gpio_send_bit(mdio_dev, 0);
199 
200 	mdio_gpio_send_num(mdio_dev, reg, 16);
201 
202 	mdio_dir(mdio_dev, 0);
203 	mdio_gpio_get_bit(mdio_dev);
204 
205 	return dev_addr;
206 }
207 
mdio_gpio_read(struct udevice * mdio_dev,int addr,int devad,int reg)208 static int mdio_gpio_read(struct udevice *mdio_dev, int addr, int devad, int reg)
209 {
210 	int ret, i;
211 
212 	if (devad != MDIO_DEVAD_NONE) {
213 		reg = mdio_gpio_cmd_addr(mdio_dev, addr, devad, reg);
214 		mdio_gpio_cmd(mdio_dev, MDIO_C45_READ, addr, reg);
215 	} else {
216 		mdio_gpio_cmd(mdio_dev, MDIO_READ, addr, reg);
217 	}
218 
219 	mdio_dir(mdio_dev, 0);
220 
221 	/* check the turnaround bit: the PHY should be driving it to zero.
222 	 */
223 	if (mdio_gpio_get_bit(mdio_dev) != 0) {
224 		/* PHY didn't drive TA low -- flush any bits it
225 		 * may be trying to send.
226 		 */
227 		for (i = 0; i < 32; i++)
228 			mdio_gpio_get_bit(mdio_dev);
229 
230 		return 0xffff;
231 	}
232 
233 	ret = mdio_gpio_get_num(mdio_dev, 16);
234 	mdio_gpio_get_bit(mdio_dev);
235 
236 	return ret;
237 }
238 
mdio_gpio_write(struct udevice * mdio_dev,int addr,int devad,int reg,u16 val)239 static int mdio_gpio_write(struct udevice *mdio_dev, int addr, int devad, int reg, u16 val)
240 {
241 	if (devad != MDIO_DEVAD_NONE) {
242 		reg = mdio_gpio_cmd_addr(mdio_dev, addr, devad, reg);
243 		mdio_gpio_cmd(mdio_dev, MDIO_C45_WRITE, addr, reg);
244 	} else {
245 		mdio_gpio_cmd(mdio_dev, MDIO_WRITE, addr, reg);
246 	}
247 
248 	/* send the turnaround (10) */
249 	mdio_gpio_send_bit(mdio_dev, 1);
250 	mdio_gpio_send_bit(mdio_dev, 0);
251 
252 	mdio_gpio_send_num(mdio_dev, val, 16);
253 
254 	mdio_dir(mdio_dev, 0);
255 	mdio_gpio_get_bit(mdio_dev);
256 
257 	return 0;
258 }
259 
260 static const struct mdio_ops mdio_gpio_ops = {
261 	.read = mdio_gpio_read,
262 	.write = mdio_gpio_write,
263 	.reset = NULL,
264 };
265 
266 /*
267  * Name the device, we use the device tree node name.
268  * This can be overwritten by MDIO class code if device-name property is
269  * present.
270  */
mdio_gpio_bind(struct udevice * mdio_dev)271 static int mdio_gpio_bind(struct udevice *mdio_dev)
272 {
273 	if (ofnode_valid(dev_ofnode(mdio_dev)))
274 		device_set_name(mdio_dev, ofnode_get_name(dev_ofnode(mdio_dev)));
275 
276 	return 0;
277 }
278 
mdio_gpio_probe(struct udevice * mdio_dev)279 static int mdio_gpio_probe(struct udevice *mdio_dev)
280 {
281 	struct mdio_gpio_priv *priv = dev_get_priv(mdio_dev);
282 	int ret = 0;
283 
284 	ret = gpio_request_by_name(mdio_dev, "gpios", MDIO_GPIO_MDC, &priv->mdc, GPIOD_IS_OUT);
285 	if (ret)
286 		return ret;
287 
288 	ret = gpio_request_by_name(mdio_dev, "gpios", MDIO_GPIO_MDIO, &priv->mdio, GPIOD_IS_IN);
289 	if (ret)
290 		return ret;
291 
292 	ret = gpio_request_by_name(mdio_dev, "gpios", MDIO_GPIO_MDO, &priv->mdo, GPIOD_IS_OUT);
293 	if (ret && ret != -ENOENT)
294 		return ret;
295 
296 	return 0;
297 }
298 
299 static const struct udevice_id mdio_gpio_ids[] = {
300 	{ .compatible = "virtual,mdio-gpio" },
301 	{ /* sentinel */ }
302 };
303 
304 U_BOOT_DRIVER(gpio_mdio) = {
305 	.name = "gpio_mdio",
306 	.id = UCLASS_MDIO,
307 	.of_match = mdio_gpio_ids,
308 	.bind = mdio_gpio_bind,
309 	.probe = mdio_gpio_probe,
310 	.ops = &mdio_gpio_ops,
311 	.plat_auto = sizeof(struct mdio_perdev_priv),
312 	.priv_auto = sizeof(struct mdio_gpio_priv),
313 };
314