• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Driver for the MDIO interface of Marvell network interfaces.
3  *
4  * Since the MDIO interface of Marvell network interfaces is shared
5  * between all network interfaces, having a single driver allows to
6  * handle concurrent accesses properly (you may have four Ethernet
7  * ports, but they in fact share the same SMI interface to access
8  * the MDIO bus). This driver is currently used by the mvneta and
9  * mv643xx_eth drivers.
10  *
11  * Copyright (C) 2012 Marvell
12  *
13  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
14  *
15  * This file is licensed under the terms of the GNU General Public
16  * License version 2. This program is licensed "as is" without any
17  * warranty of any kind, whether express or implied.
18  */
19 
20 #include <linux/acpi.h>
21 #include <linux/acpi_mdio.h>
22 #include <linux/clk.h>
23 #include <linux/delay.h>
24 #include <linux/interrupt.h>
25 #include <linux/io.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/of_device.h>
29 #include <linux/of_mdio.h>
30 #include <linux/phy.h>
31 #include <linux/platform_device.h>
32 #include <linux/sched.h>
33 #include <linux/wait.h>
34 
35 #define MVMDIO_SMI_DATA_SHIFT		0
36 #define MVMDIO_SMI_PHY_ADDR_SHIFT	16
37 #define MVMDIO_SMI_PHY_REG_SHIFT	21
38 #define MVMDIO_SMI_READ_OPERATION	BIT(26)
39 #define MVMDIO_SMI_WRITE_OPERATION	0
40 #define MVMDIO_SMI_READ_VALID		BIT(27)
41 #define MVMDIO_SMI_BUSY			BIT(28)
42 #define MVMDIO_ERR_INT_CAUSE		0x007C
43 #define  MVMDIO_ERR_INT_SMI_DONE	0x00000010
44 #define MVMDIO_ERR_INT_MASK		0x0080
45 
46 #define MVMDIO_XSMI_MGNT_REG		0x0
47 #define  MVMDIO_XSMI_PHYADDR_SHIFT	16
48 #define  MVMDIO_XSMI_DEVADDR_SHIFT	21
49 #define  MVMDIO_XSMI_WRITE_OPERATION	(0x5 << 26)
50 #define  MVMDIO_XSMI_READ_OPERATION	(0x7 << 26)
51 #define  MVMDIO_XSMI_READ_VALID		BIT(29)
52 #define  MVMDIO_XSMI_BUSY		BIT(30)
53 #define MVMDIO_XSMI_ADDR_REG		0x8
54 
55 /*
56  * SMI Timeout measurements:
57  * - Kirkwood 88F6281 (Globalscale Dreamplug): 45us to 95us (Interrupt)
58  * - Armada 370       (Globalscale Mirabox):   41us to 43us (Polled)
59  */
60 #define MVMDIO_SMI_TIMEOUT		1000 /* 1000us = 1ms */
61 #define MVMDIO_SMI_POLL_INTERVAL_MIN	45
62 #define MVMDIO_SMI_POLL_INTERVAL_MAX	55
63 
64 #define MVMDIO_XSMI_POLL_INTERVAL_MIN	150
65 #define MVMDIO_XSMI_POLL_INTERVAL_MAX	160
66 
67 struct orion_mdio_dev {
68 	void __iomem *regs;
69 	struct clk *clk[4];
70 	/*
71 	 * If we have access to the error interrupt pin (which is
72 	 * somewhat misnamed as it not only reflects internal errors
73 	 * but also reflects SMI completion), use that to wait for
74 	 * SMI access completion instead of polling the SMI busy bit.
75 	 */
76 	int err_interrupt;
77 	wait_queue_head_t smi_busy_wait;
78 };
79 
80 enum orion_mdio_bus_type {
81 	BUS_TYPE_SMI,
82 	BUS_TYPE_XSMI
83 };
84 
85 struct orion_mdio_ops {
86 	int (*is_done)(struct orion_mdio_dev *);
87 	unsigned int poll_interval_min;
88 	unsigned int poll_interval_max;
89 };
90 
91 /* Wait for the SMI unit to be ready for another operation
92  */
orion_mdio_wait_ready(const struct orion_mdio_ops * ops,struct mii_bus * bus)93 static int orion_mdio_wait_ready(const struct orion_mdio_ops *ops,
94 				 struct mii_bus *bus)
95 {
96 	struct orion_mdio_dev *dev = bus->priv;
97 	unsigned long timeout = usecs_to_jiffies(MVMDIO_SMI_TIMEOUT);
98 	unsigned long end = jiffies + timeout;
99 	int timedout = 0;
100 
101 	while (1) {
102 	        if (ops->is_done(dev))
103 			return 0;
104 	        else if (timedout)
105 			break;
106 
107 	        if (dev->err_interrupt <= 0) {
108 			usleep_range(ops->poll_interval_min,
109 				     ops->poll_interval_max);
110 
111 			if (time_is_before_jiffies(end))
112 				++timedout;
113 	        } else {
114 			/* wait_event_timeout does not guarantee a delay of at
115 			 * least one whole jiffie, so timeout must be no less
116 			 * than two.
117 			 */
118 			if (timeout < 2)
119 				timeout = 2;
120 			wait_event_timeout(dev->smi_busy_wait,
121 				           ops->is_done(dev), timeout);
122 
123 			++timedout;
124 	        }
125 	}
126 
127 	dev_err(bus->parent, "Timeout: SMI busy for too long\n");
128 	return  -ETIMEDOUT;
129 }
130 
orion_mdio_smi_is_done(struct orion_mdio_dev * dev)131 static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev)
132 {
133 	return !(readl(dev->regs) & MVMDIO_SMI_BUSY);
134 }
135 
136 static const struct orion_mdio_ops orion_mdio_smi_ops = {
137 	.is_done = orion_mdio_smi_is_done,
138 	.poll_interval_min = MVMDIO_SMI_POLL_INTERVAL_MIN,
139 	.poll_interval_max = MVMDIO_SMI_POLL_INTERVAL_MAX,
140 };
141 
orion_mdio_smi_read(struct mii_bus * bus,int mii_id,int regnum)142 static int orion_mdio_smi_read(struct mii_bus *bus, int mii_id,
143 			       int regnum)
144 {
145 	struct orion_mdio_dev *dev = bus->priv;
146 	u32 val;
147 	int ret;
148 
149 	if (regnum & MII_ADDR_C45)
150 		return -EOPNOTSUPP;
151 
152 	ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus);
153 	if (ret < 0)
154 		return ret;
155 
156 	writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) |
157 		(regnum << MVMDIO_SMI_PHY_REG_SHIFT)  |
158 		MVMDIO_SMI_READ_OPERATION),
159 	       dev->regs);
160 
161 	ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus);
162 	if (ret < 0)
163 		return ret;
164 
165 	val = readl(dev->regs);
166 	if (!(val & MVMDIO_SMI_READ_VALID)) {
167 		dev_err(bus->parent, "SMI bus read not valid\n");
168 		return -ENODEV;
169 	}
170 
171 	return val & GENMASK(15, 0);
172 }
173 
orion_mdio_smi_write(struct mii_bus * bus,int mii_id,int regnum,u16 value)174 static int orion_mdio_smi_write(struct mii_bus *bus, int mii_id,
175 				int regnum, u16 value)
176 {
177 	struct orion_mdio_dev *dev = bus->priv;
178 	int ret;
179 
180 	if (regnum & MII_ADDR_C45)
181 		return -EOPNOTSUPP;
182 
183 	ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus);
184 	if (ret < 0)
185 		return ret;
186 
187 	writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) |
188 		(regnum << MVMDIO_SMI_PHY_REG_SHIFT)  |
189 		MVMDIO_SMI_WRITE_OPERATION            |
190 		(value << MVMDIO_SMI_DATA_SHIFT)),
191 	       dev->regs);
192 
193 	return 0;
194 }
195 
orion_mdio_xsmi_is_done(struct orion_mdio_dev * dev)196 static int orion_mdio_xsmi_is_done(struct orion_mdio_dev *dev)
197 {
198 	return !(readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & MVMDIO_XSMI_BUSY);
199 }
200 
201 static const struct orion_mdio_ops orion_mdio_xsmi_ops = {
202 	.is_done = orion_mdio_xsmi_is_done,
203 	.poll_interval_min = MVMDIO_XSMI_POLL_INTERVAL_MIN,
204 	.poll_interval_max = MVMDIO_XSMI_POLL_INTERVAL_MAX,
205 };
206 
orion_mdio_xsmi_read(struct mii_bus * bus,int mii_id,int regnum)207 static int orion_mdio_xsmi_read(struct mii_bus *bus, int mii_id,
208 				int regnum)
209 {
210 	struct orion_mdio_dev *dev = bus->priv;
211 	u16 dev_addr = (regnum >> 16) & GENMASK(4, 0);
212 	int ret;
213 
214 	if (!(regnum & MII_ADDR_C45))
215 		return -EOPNOTSUPP;
216 
217 	ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus);
218 	if (ret < 0)
219 		return ret;
220 
221 	writel(regnum & GENMASK(15, 0), dev->regs + MVMDIO_XSMI_ADDR_REG);
222 	writel((mii_id << MVMDIO_XSMI_PHYADDR_SHIFT) |
223 	       (dev_addr << MVMDIO_XSMI_DEVADDR_SHIFT) |
224 	       MVMDIO_XSMI_READ_OPERATION,
225 	       dev->regs + MVMDIO_XSMI_MGNT_REG);
226 
227 	ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus);
228 	if (ret < 0)
229 		return ret;
230 
231 	if (!(readl(dev->regs + MVMDIO_XSMI_MGNT_REG) &
232 	      MVMDIO_XSMI_READ_VALID)) {
233 		dev_err(bus->parent, "XSMI bus read not valid\n");
234 		return -ENODEV;
235 	}
236 
237 	return readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & GENMASK(15, 0);
238 }
239 
orion_mdio_xsmi_write(struct mii_bus * bus,int mii_id,int regnum,u16 value)240 static int orion_mdio_xsmi_write(struct mii_bus *bus, int mii_id,
241 				int regnum, u16 value)
242 {
243 	struct orion_mdio_dev *dev = bus->priv;
244 	u16 dev_addr = (regnum >> 16) & GENMASK(4, 0);
245 	int ret;
246 
247 	if (!(regnum & MII_ADDR_C45))
248 		return -EOPNOTSUPP;
249 
250 	ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus);
251 	if (ret < 0)
252 		return ret;
253 
254 	writel(regnum & GENMASK(15, 0), dev->regs + MVMDIO_XSMI_ADDR_REG);
255 	writel((mii_id << MVMDIO_XSMI_PHYADDR_SHIFT) |
256 	       (dev_addr << MVMDIO_XSMI_DEVADDR_SHIFT) |
257 	       MVMDIO_XSMI_WRITE_OPERATION | value,
258 	       dev->regs + MVMDIO_XSMI_MGNT_REG);
259 
260 	return 0;
261 }
262 
orion_mdio_err_irq(int irq,void * dev_id)263 static irqreturn_t orion_mdio_err_irq(int irq, void *dev_id)
264 {
265 	struct orion_mdio_dev *dev = dev_id;
266 
267 	if (readl(dev->regs + MVMDIO_ERR_INT_CAUSE) &
268 			MVMDIO_ERR_INT_SMI_DONE) {
269 		writel(~MVMDIO_ERR_INT_SMI_DONE,
270 				dev->regs + MVMDIO_ERR_INT_CAUSE);
271 		wake_up(&dev->smi_busy_wait);
272 		return IRQ_HANDLED;
273 	}
274 
275 	return IRQ_NONE;
276 }
277 
orion_mdio_probe(struct platform_device * pdev)278 static int orion_mdio_probe(struct platform_device *pdev)
279 {
280 	enum orion_mdio_bus_type type;
281 	struct resource *r;
282 	struct mii_bus *bus;
283 	struct orion_mdio_dev *dev;
284 	int i, ret;
285 
286 	type = (enum orion_mdio_bus_type)device_get_match_data(&pdev->dev);
287 
288 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
289 	if (!r) {
290 		dev_err(&pdev->dev, "No SMI register address given\n");
291 		return -ENODEV;
292 	}
293 
294 	bus = devm_mdiobus_alloc_size(&pdev->dev,
295 				      sizeof(struct orion_mdio_dev));
296 	if (!bus)
297 		return -ENOMEM;
298 
299 	switch (type) {
300 	case BUS_TYPE_SMI:
301 		bus->read = orion_mdio_smi_read;
302 		bus->write = orion_mdio_smi_write;
303 		break;
304 	case BUS_TYPE_XSMI:
305 		bus->read = orion_mdio_xsmi_read;
306 		bus->write = orion_mdio_xsmi_write;
307 		break;
308 	}
309 
310 	bus->name = "orion_mdio_bus";
311 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii",
312 		 dev_name(&pdev->dev));
313 	bus->parent = &pdev->dev;
314 
315 	dev = bus->priv;
316 	dev->regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
317 	if (!dev->regs) {
318 		dev_err(&pdev->dev, "Unable to remap SMI register\n");
319 		return -ENODEV;
320 	}
321 
322 	init_waitqueue_head(&dev->smi_busy_wait);
323 
324 	if (pdev->dev.of_node) {
325 		for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
326 			dev->clk[i] = of_clk_get(pdev->dev.of_node, i);
327 			if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) {
328 				ret = -EPROBE_DEFER;
329 				goto out_clk;
330 			}
331 			if (IS_ERR(dev->clk[i]))
332 				break;
333 			clk_prepare_enable(dev->clk[i]);
334 		}
335 
336 		if (!IS_ERR(of_clk_get(pdev->dev.of_node,
337 				       ARRAY_SIZE(dev->clk))))
338 			dev_warn(&pdev->dev,
339 				 "unsupported number of clocks, limiting to the first "
340 				 __stringify(ARRAY_SIZE(dev->clk)) "\n");
341 	} else {
342 		dev->clk[0] = clk_get(&pdev->dev, NULL);
343 		if (PTR_ERR(dev->clk[0]) == -EPROBE_DEFER) {
344 			ret = -EPROBE_DEFER;
345 			goto out_clk;
346 		}
347 		if (!IS_ERR(dev->clk[0]))
348 			clk_prepare_enable(dev->clk[0]);
349 	}
350 
351 
352 	dev->err_interrupt = platform_get_irq_optional(pdev, 0);
353 	if (dev->err_interrupt > 0 &&
354 	    resource_size(r) < MVMDIO_ERR_INT_MASK + 4) {
355 		dev_err(&pdev->dev,
356 			"disabling interrupt, resource size is too small\n");
357 		dev->err_interrupt = 0;
358 	}
359 	if (dev->err_interrupt > 0) {
360 		ret = devm_request_irq(&pdev->dev, dev->err_interrupt,
361 					orion_mdio_err_irq,
362 					IRQF_SHARED, pdev->name, dev);
363 		if (ret)
364 			goto out_mdio;
365 
366 		writel(MVMDIO_ERR_INT_SMI_DONE,
367 			dev->regs + MVMDIO_ERR_INT_MASK);
368 
369 	} else if (dev->err_interrupt == -EPROBE_DEFER) {
370 		ret = -EPROBE_DEFER;
371 		goto out_mdio;
372 	}
373 
374 	/* For the platforms not supporting DT/ACPI fall-back
375 	 * to mdiobus_register via of_mdiobus_register.
376 	 */
377 	if (is_acpi_node(pdev->dev.fwnode))
378 		ret = acpi_mdiobus_register(bus, pdev->dev.fwnode);
379 	else
380 		ret = of_mdiobus_register(bus, pdev->dev.of_node);
381 	if (ret < 0) {
382 		dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
383 		goto out_mdio;
384 	}
385 
386 	platform_set_drvdata(pdev, bus);
387 
388 	return 0;
389 
390 out_mdio:
391 	if (dev->err_interrupt > 0)
392 		writel(0, dev->regs + MVMDIO_ERR_INT_MASK);
393 
394 out_clk:
395 	for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
396 		if (IS_ERR(dev->clk[i]))
397 			break;
398 		clk_disable_unprepare(dev->clk[i]);
399 		clk_put(dev->clk[i]);
400 	}
401 
402 	return ret;
403 }
404 
orion_mdio_remove(struct platform_device * pdev)405 static int orion_mdio_remove(struct platform_device *pdev)
406 {
407 	struct mii_bus *bus = platform_get_drvdata(pdev);
408 	struct orion_mdio_dev *dev = bus->priv;
409 	int i;
410 
411 	if (dev->err_interrupt > 0)
412 		writel(0, dev->regs + MVMDIO_ERR_INT_MASK);
413 	mdiobus_unregister(bus);
414 
415 	for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
416 		if (IS_ERR(dev->clk[i]))
417 			break;
418 		clk_disable_unprepare(dev->clk[i]);
419 		clk_put(dev->clk[i]);
420 	}
421 
422 	return 0;
423 }
424 
425 static const struct of_device_id orion_mdio_match[] = {
426 	{ .compatible = "marvell,orion-mdio", .data = (void *)BUS_TYPE_SMI },
427 	{ .compatible = "marvell,xmdio", .data = (void *)BUS_TYPE_XSMI },
428 	{ }
429 };
430 MODULE_DEVICE_TABLE(of, orion_mdio_match);
431 
432 #ifdef CONFIG_ACPI
433 static const struct acpi_device_id orion_mdio_acpi_match[] = {
434 	{ "MRVL0100", BUS_TYPE_SMI },
435 	{ "MRVL0101", BUS_TYPE_XSMI },
436 	{ },
437 };
438 MODULE_DEVICE_TABLE(acpi, orion_mdio_acpi_match);
439 #endif
440 
441 static struct platform_driver orion_mdio_driver = {
442 	.probe = orion_mdio_probe,
443 	.remove = orion_mdio_remove,
444 	.driver = {
445 		.name = "orion-mdio",
446 		.of_match_table = orion_mdio_match,
447 		.acpi_match_table = ACPI_PTR(orion_mdio_acpi_match),
448 	},
449 };
450 
451 module_platform_driver(orion_mdio_driver);
452 
453 MODULE_DESCRIPTION("Marvell MDIO interface driver");
454 MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
455 MODULE_LICENSE("GPL");
456 MODULE_ALIAS("platform:orion-mdio");
457