2 * Driver for the MDIO interface of Marvell network interfaces.
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
11 * Copyright (C) 2012 Marvell
13 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
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.
20 #include <linux/clk.h>
21 #include <linux/delay.h>
22 #include <linux/interrupt.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/of_device.h>
27 #include <linux/of_mdio.h>
28 #include <linux/phy.h>
29 #include <linux/platform_device.h>
30 #include <linux/sched.h>
31 #include <linux/wait.h>
33 #define MVMDIO_SMI_DATA_SHIFT 0
34 #define MVMDIO_SMI_PHY_ADDR_SHIFT 16
35 #define MVMDIO_SMI_PHY_REG_SHIFT 21
36 #define MVMDIO_SMI_READ_OPERATION BIT(26)
37 #define MVMDIO_SMI_WRITE_OPERATION 0
38 #define MVMDIO_SMI_READ_VALID BIT(27)
39 #define MVMDIO_SMI_BUSY BIT(28)
40 #define MVMDIO_ERR_INT_CAUSE 0x007C
41 #define MVMDIO_ERR_INT_SMI_DONE 0x00000010
42 #define MVMDIO_ERR_INT_MASK 0x0080
44 #define MVMDIO_XSMI_MGNT_REG 0x0
45 #define MVMDIO_XSMI_PHYADDR_SHIFT 16
46 #define MVMDIO_XSMI_DEVADDR_SHIFT 21
47 #define MVMDIO_XSMI_WRITE_OPERATION (0x5 << 26)
48 #define MVMDIO_XSMI_READ_OPERATION (0x7 << 26)
49 #define MVMDIO_XSMI_READ_VALID BIT(29)
50 #define MVMDIO_XSMI_BUSY BIT(30)
51 #define MVMDIO_XSMI_ADDR_REG 0x8
54 * SMI Timeout measurements:
55 * - Kirkwood 88F6281 (Globalscale Dreamplug): 45us to 95us (Interrupt)
56 * - Armada 370 (Globalscale Mirabox): 41us to 43us (Polled)
58 #define MVMDIO_SMI_TIMEOUT 1000 /* 1000us = 1ms */
59 #define MVMDIO_SMI_POLL_INTERVAL_MIN 45
60 #define MVMDIO_SMI_POLL_INTERVAL_MAX 55
62 #define MVMDIO_XSMI_POLL_INTERVAL_MIN 150
63 #define MVMDIO_XSMI_POLL_INTERVAL_MAX 160
65 struct orion_mdio_dev
{
69 * If we have access to the error interrupt pin (which is
70 * somewhat misnamed as it not only reflects internal errors
71 * but also reflects SMI completion), use that to wait for
72 * SMI access completion instead of polling the SMI busy bit.
75 wait_queue_head_t smi_busy_wait
;
78 enum orion_mdio_bus_type
{
83 struct orion_mdio_ops
{
84 int (*is_done
)(struct orion_mdio_dev
*);
85 unsigned int poll_interval_min
;
86 unsigned int poll_interval_max
;
89 /* Wait for the SMI unit to be ready for another operation
91 static int orion_mdio_wait_ready(const struct orion_mdio_ops
*ops
,
94 struct orion_mdio_dev
*dev
= bus
->priv
;
95 unsigned long timeout
= usecs_to_jiffies(MVMDIO_SMI_TIMEOUT
);
96 unsigned long end
= jiffies
+ timeout
;
100 if (ops
->is_done(dev
))
105 if (dev
->err_interrupt
<= 0) {
106 usleep_range(ops
->poll_interval_min
,
107 ops
->poll_interval_max
);
109 if (time_is_before_jiffies(end
))
112 /* wait_event_timeout does not guarantee a delay of at
113 * least one whole jiffie, so timeout must be no less
118 wait_event_timeout(dev
->smi_busy_wait
,
119 ops
->is_done(dev
), timeout
);
125 dev_err(bus
->parent
, "Timeout: SMI busy for too long\n");
129 static int orion_mdio_smi_is_done(struct orion_mdio_dev
*dev
)
131 return !(readl(dev
->regs
) & MVMDIO_SMI_BUSY
);
134 static const struct orion_mdio_ops orion_mdio_smi_ops
= {
135 .is_done
= orion_mdio_smi_is_done
,
136 .poll_interval_min
= MVMDIO_SMI_POLL_INTERVAL_MIN
,
137 .poll_interval_max
= MVMDIO_SMI_POLL_INTERVAL_MAX
,
140 static int orion_mdio_smi_read(struct mii_bus
*bus
, int mii_id
,
143 struct orion_mdio_dev
*dev
= bus
->priv
;
147 if (regnum
& MII_ADDR_C45
)
150 ret
= orion_mdio_wait_ready(&orion_mdio_smi_ops
, bus
);
154 writel(((mii_id
<< MVMDIO_SMI_PHY_ADDR_SHIFT
) |
155 (regnum
<< MVMDIO_SMI_PHY_REG_SHIFT
) |
156 MVMDIO_SMI_READ_OPERATION
),
159 ret
= orion_mdio_wait_ready(&orion_mdio_smi_ops
, bus
);
163 val
= readl(dev
->regs
);
164 if (!(val
& MVMDIO_SMI_READ_VALID
)) {
165 dev_err(bus
->parent
, "SMI bus read not valid\n");
169 return val
& GENMASK(15, 0);
172 static int orion_mdio_smi_write(struct mii_bus
*bus
, int mii_id
,
173 int regnum
, u16 value
)
175 struct orion_mdio_dev
*dev
= bus
->priv
;
178 if (regnum
& MII_ADDR_C45
)
181 ret
= orion_mdio_wait_ready(&orion_mdio_smi_ops
, bus
);
185 writel(((mii_id
<< MVMDIO_SMI_PHY_ADDR_SHIFT
) |
186 (regnum
<< MVMDIO_SMI_PHY_REG_SHIFT
) |
187 MVMDIO_SMI_WRITE_OPERATION
|
188 (value
<< MVMDIO_SMI_DATA_SHIFT
)),
194 static int orion_mdio_xsmi_is_done(struct orion_mdio_dev
*dev
)
196 return !(readl(dev
->regs
+ MVMDIO_XSMI_MGNT_REG
) & MVMDIO_XSMI_BUSY
);
199 static const struct orion_mdio_ops orion_mdio_xsmi_ops
= {
200 .is_done
= orion_mdio_xsmi_is_done
,
201 .poll_interval_min
= MVMDIO_XSMI_POLL_INTERVAL_MIN
,
202 .poll_interval_max
= MVMDIO_XSMI_POLL_INTERVAL_MAX
,
205 static int orion_mdio_xsmi_read(struct mii_bus
*bus
, int mii_id
,
208 struct orion_mdio_dev
*dev
= bus
->priv
;
209 u16 dev_addr
= (regnum
>> 16) & GENMASK(4, 0);
212 if (!(regnum
& MII_ADDR_C45
))
215 ret
= orion_mdio_wait_ready(&orion_mdio_xsmi_ops
, bus
);
219 writel(regnum
& GENMASK(15, 0), dev
->regs
+ MVMDIO_XSMI_ADDR_REG
);
220 writel((mii_id
<< MVMDIO_XSMI_PHYADDR_SHIFT
) |
221 (dev_addr
<< MVMDIO_XSMI_DEVADDR_SHIFT
) |
222 MVMDIO_XSMI_READ_OPERATION
,
223 dev
->regs
+ MVMDIO_XSMI_MGNT_REG
);
225 ret
= orion_mdio_wait_ready(&orion_mdio_xsmi_ops
, bus
);
229 if (!(readl(dev
->regs
+ MVMDIO_XSMI_MGNT_REG
) &
230 MVMDIO_XSMI_READ_VALID
)) {
231 dev_err(bus
->parent
, "XSMI bus read not valid\n");
235 return readl(dev
->regs
+ MVMDIO_XSMI_MGNT_REG
) & GENMASK(15, 0);
238 static int orion_mdio_xsmi_write(struct mii_bus
*bus
, int mii_id
,
239 int regnum
, u16 value
)
241 struct orion_mdio_dev
*dev
= bus
->priv
;
242 u16 dev_addr
= (regnum
>> 16) & GENMASK(4, 0);
245 if (!(regnum
& MII_ADDR_C45
))
248 ret
= orion_mdio_wait_ready(&orion_mdio_xsmi_ops
, bus
);
252 writel(regnum
& GENMASK(15, 0), dev
->regs
+ MVMDIO_XSMI_ADDR_REG
);
253 writel((mii_id
<< MVMDIO_XSMI_PHYADDR_SHIFT
) |
254 (dev_addr
<< MVMDIO_XSMI_DEVADDR_SHIFT
) |
255 MVMDIO_XSMI_WRITE_OPERATION
| value
,
256 dev
->regs
+ MVMDIO_XSMI_MGNT_REG
);
261 static irqreturn_t
orion_mdio_err_irq(int irq
, void *dev_id
)
263 struct orion_mdio_dev
*dev
= dev_id
;
265 if (readl(dev
->regs
+ MVMDIO_ERR_INT_CAUSE
) &
266 MVMDIO_ERR_INT_SMI_DONE
) {
267 writel(~MVMDIO_ERR_INT_SMI_DONE
,
268 dev
->regs
+ MVMDIO_ERR_INT_CAUSE
);
269 wake_up(&dev
->smi_busy_wait
);
276 static int orion_mdio_probe(struct platform_device
*pdev
)
278 enum orion_mdio_bus_type type
;
281 struct orion_mdio_dev
*dev
;
284 type
= (enum orion_mdio_bus_type
)of_device_get_match_data(&pdev
->dev
);
286 r
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
288 dev_err(&pdev
->dev
, "No SMI register address given\n");
292 bus
= devm_mdiobus_alloc_size(&pdev
->dev
,
293 sizeof(struct orion_mdio_dev
));
299 bus
->read
= orion_mdio_smi_read
;
300 bus
->write
= orion_mdio_smi_write
;
303 bus
->read
= orion_mdio_xsmi_read
;
304 bus
->write
= orion_mdio_xsmi_write
;
308 bus
->name
= "orion_mdio_bus";
309 snprintf(bus
->id
, MII_BUS_ID_SIZE
, "%s-mii",
310 dev_name(&pdev
->dev
));
311 bus
->parent
= &pdev
->dev
;
314 dev
->regs
= devm_ioremap(&pdev
->dev
, r
->start
, resource_size(r
));
316 dev_err(&pdev
->dev
, "Unable to remap SMI register\n");
320 init_waitqueue_head(&dev
->smi_busy_wait
);
322 if (pdev
->dev
.of_node
) {
323 for (i
= 0; i
< ARRAY_SIZE(dev
->clk
); i
++) {
324 dev
->clk
[i
] = of_clk_get(pdev
->dev
.of_node
, i
);
325 if (PTR_ERR(dev
->clk
[i
]) == -EPROBE_DEFER
) {
329 if (IS_ERR(dev
->clk
[i
]))
331 clk_prepare_enable(dev
->clk
[i
]);
334 if (!IS_ERR(of_clk_get(pdev
->dev
.of_node
,
335 ARRAY_SIZE(dev
->clk
))))
337 "unsupported number of clocks, limiting to the first "
338 __stringify(ARRAY_SIZE(dev
->clk
)) "\n");
340 dev
->clk
[0] = clk_get(&pdev
->dev
, NULL
);
341 if (PTR_ERR(dev
->clk
[0]) == -EPROBE_DEFER
) {
345 if (!IS_ERR(dev
->clk
[0]))
346 clk_prepare_enable(dev
->clk
[0]);
350 dev
->err_interrupt
= platform_get_irq(pdev
, 0);
351 if (dev
->err_interrupt
> 0 &&
352 resource_size(r
) < MVMDIO_ERR_INT_MASK
+ 4) {
354 "disabling interrupt, resource size is too small\n");
355 dev
->err_interrupt
= 0;
357 if (dev
->err_interrupt
> 0) {
358 ret
= devm_request_irq(&pdev
->dev
, dev
->err_interrupt
,
360 IRQF_SHARED
, pdev
->name
, dev
);
364 writel(MVMDIO_ERR_INT_SMI_DONE
,
365 dev
->regs
+ MVMDIO_ERR_INT_MASK
);
367 } else if (dev
->err_interrupt
== -EPROBE_DEFER
) {
372 ret
= of_mdiobus_register(bus
, pdev
->dev
.of_node
);
374 dev_err(&pdev
->dev
, "Cannot register MDIO bus (%d)\n", ret
);
378 platform_set_drvdata(pdev
, bus
);
383 if (dev
->err_interrupt
> 0)
384 writel(0, dev
->regs
+ MVMDIO_ERR_INT_MASK
);
387 for (i
= 0; i
< ARRAY_SIZE(dev
->clk
); i
++) {
388 if (IS_ERR(dev
->clk
[i
]))
390 clk_disable_unprepare(dev
->clk
[i
]);
391 clk_put(dev
->clk
[i
]);
397 static int orion_mdio_remove(struct platform_device
*pdev
)
399 struct mii_bus
*bus
= platform_get_drvdata(pdev
);
400 struct orion_mdio_dev
*dev
= bus
->priv
;
403 if (dev
->err_interrupt
> 0)
404 writel(0, dev
->regs
+ MVMDIO_ERR_INT_MASK
);
405 mdiobus_unregister(bus
);
407 for (i
= 0; i
< ARRAY_SIZE(dev
->clk
); i
++) {
408 if (IS_ERR(dev
->clk
[i
]))
410 clk_disable_unprepare(dev
->clk
[i
]);
411 clk_put(dev
->clk
[i
]);
417 static const struct of_device_id orion_mdio_match
[] = {
418 { .compatible
= "marvell,orion-mdio", .data
= (void *)BUS_TYPE_SMI
},
419 { .compatible
= "marvell,xmdio", .data
= (void *)BUS_TYPE_XSMI
},
422 MODULE_DEVICE_TABLE(of
, orion_mdio_match
);
424 static struct platform_driver orion_mdio_driver
= {
425 .probe
= orion_mdio_probe
,
426 .remove
= orion_mdio_remove
,
428 .name
= "orion-mdio",
429 .of_match_table
= orion_mdio_match
,
433 module_platform_driver(orion_mdio_driver
);
435 MODULE_DESCRIPTION("Marvell MDIO interface driver");
436 MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
437 MODULE_LICENSE("GPL");
438 MODULE_ALIAS("platform:orion-mdio");