1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/gpio/consumer.h>
14#include <linux/io.h>
15#include <linux/iopoll.h>
16#include <linux/mii.h>
17#include <linux/of_mdio.h>
18#include <linux/phy.h>
19#include <linux/property.h>
20#include <linux/slab.h>
21
22#include "dwxgmac2.h"
23#include "stmmac.h"
24
25#define MII_BUSY 0x00000001
26#define MII_WRITE 0x00000002
27#define MII_DATA_MASK GENMASK(15, 0)
28
29
30#define MII_GMAC4_GOC_SHIFT 2
31#define MII_GMAC4_REG_ADDR_SHIFT 16
32#define MII_GMAC4_WRITE (1 << MII_GMAC4_GOC_SHIFT)
33#define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT)
34#define MII_GMAC4_C45E BIT(1)
35
36
37#define MII_XGMAC_SADDR BIT(18)
38#define MII_XGMAC_CMD_SHIFT 16
39#define MII_XGMAC_WRITE (1 << MII_XGMAC_CMD_SHIFT)
40#define MII_XGMAC_READ (3 << MII_XGMAC_CMD_SHIFT)
41#define MII_XGMAC_BUSY BIT(22)
42#define MII_XGMAC_MAX_C22ADDR 3
43#define MII_XGMAC_C22P_MASK GENMASK(MII_XGMAC_MAX_C22ADDR, 0)
44
45static int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
46 int phyreg, u32 *hw_addr)
47{
48 unsigned int mii_data = priv->hw->mii.data;
49 u32 tmp;
50
51
52 if (phyaddr > MII_XGMAC_MAX_C22ADDR)
53 return -ENODEV;
54
55 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
56 !(tmp & MII_XGMAC_BUSY), 100, 10000))
57 return -EBUSY;
58
59
60 tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
61 tmp &= ~MII_XGMAC_C22P_MASK;
62 tmp |= BIT(phyaddr);
63 writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
64
65 *hw_addr = (phyaddr << 16) | (phyreg & 0x1f);
66 return 0;
67}
68
69static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
70{
71 struct net_device *ndev = bus->priv;
72 struct stmmac_priv *priv = netdev_priv(ndev);
73 unsigned int mii_address = priv->hw->mii.addr;
74 unsigned int mii_data = priv->hw->mii.data;
75 u32 tmp, addr, value = MII_XGMAC_BUSY;
76 int ret;
77
78 if (phyreg & MII_ADDR_C45) {
79 return -EOPNOTSUPP;
80 } else {
81 ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
82 if (ret)
83 return ret;
84 }
85
86 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
87 & priv->hw->mii.clk_csr_mask;
88 value |= MII_XGMAC_SADDR | MII_XGMAC_READ;
89
90
91 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
92 !(tmp & MII_XGMAC_BUSY), 100, 10000))
93 return -EBUSY;
94
95
96 writel(addr, priv->ioaddr + mii_address);
97 writel(value, priv->ioaddr + mii_data);
98
99
100 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
101 !(tmp & MII_XGMAC_BUSY), 100, 10000))
102 return -EBUSY;
103
104
105 return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
106}
107
108static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
109 int phyreg, u16 phydata)
110{
111 struct net_device *ndev = bus->priv;
112 struct stmmac_priv *priv = netdev_priv(ndev);
113 unsigned int mii_address = priv->hw->mii.addr;
114 unsigned int mii_data = priv->hw->mii.data;
115 u32 addr, tmp, value = MII_XGMAC_BUSY;
116 int ret;
117
118 if (phyreg & MII_ADDR_C45) {
119 return -EOPNOTSUPP;
120 } else {
121 ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
122 if (ret)
123 return ret;
124 }
125
126 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
127 & priv->hw->mii.clk_csr_mask;
128 value |= phydata | MII_XGMAC_SADDR;
129 value |= MII_XGMAC_WRITE;
130
131
132 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
133 !(tmp & MII_XGMAC_BUSY), 100, 10000))
134 return -EBUSY;
135
136
137 writel(addr, priv->ioaddr + mii_address);
138 writel(value, priv->ioaddr + mii_data);
139
140
141 return readl_poll_timeout(priv->ioaddr + mii_data, tmp,
142 !(tmp & MII_XGMAC_BUSY), 100, 10000);
143}
144
145
146
147
148
149
150
151
152
153
154
155static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
156{
157 struct net_device *ndev = bus->priv;
158 struct stmmac_priv *priv = netdev_priv(ndev);
159 unsigned int mii_address = priv->hw->mii.addr;
160 unsigned int mii_data = priv->hw->mii.data;
161 u32 value = MII_BUSY;
162 int data = 0;
163 u32 v;
164
165 value |= (phyaddr << priv->hw->mii.addr_shift)
166 & priv->hw->mii.addr_mask;
167 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
168 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
169 & priv->hw->mii.clk_csr_mask;
170 if (priv->plat->has_gmac4) {
171 value |= MII_GMAC4_READ;
172 if (phyreg & MII_ADDR_C45) {
173 value |= MII_GMAC4_C45E;
174 value &= ~priv->hw->mii.reg_mask;
175 value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
176 priv->hw->mii.reg_shift) &
177 priv->hw->mii.reg_mask;
178
179 data |= (phyreg & MII_REGADDR_C45_MASK) <<
180 MII_GMAC4_REG_ADDR_SHIFT;
181 }
182 }
183
184 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
185 100, 10000))
186 return -EBUSY;
187
188 writel(data, priv->ioaddr + mii_data);
189 writel(value, priv->ioaddr + mii_address);
190
191 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
192 100, 10000))
193 return -EBUSY;
194
195
196 data = (int)readl(priv->ioaddr + mii_data) & MII_DATA_MASK;
197
198 return data;
199}
200
201
202
203
204
205
206
207
208
209static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
210 u16 phydata)
211{
212 struct net_device *ndev = bus->priv;
213 struct stmmac_priv *priv = netdev_priv(ndev);
214 unsigned int mii_address = priv->hw->mii.addr;
215 unsigned int mii_data = priv->hw->mii.data;
216 u32 value = MII_BUSY;
217 int data = phydata;
218 u32 v;
219
220 value |= (phyaddr << priv->hw->mii.addr_shift)
221 & priv->hw->mii.addr_mask;
222 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
223
224 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
225 & priv->hw->mii.clk_csr_mask;
226 if (priv->plat->has_gmac4) {
227 value |= MII_GMAC4_WRITE;
228 if (phyreg & MII_ADDR_C45) {
229 value |= MII_GMAC4_C45E;
230 value &= ~priv->hw->mii.reg_mask;
231 value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
232 priv->hw->mii.reg_shift) &
233 priv->hw->mii.reg_mask;
234
235 data |= (phyreg & MII_REGADDR_C45_MASK) <<
236 MII_GMAC4_REG_ADDR_SHIFT;
237 }
238 } else {
239 value |= MII_WRITE;
240 }
241
242
243 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
244 100, 10000))
245 return -EBUSY;
246
247
248 writel(data, priv->ioaddr + mii_data);
249 writel(value, priv->ioaddr + mii_address);
250
251
252 return readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
253 100, 10000);
254}
255
256
257
258
259
260
261int stmmac_mdio_reset(struct mii_bus *bus)
262{
263#if IS_ENABLED(CONFIG_STMMAC_PLATFORM)
264 struct net_device *ndev = bus->priv;
265 struct stmmac_priv *priv = netdev_priv(ndev);
266 unsigned int mii_address = priv->hw->mii.addr;
267
268#ifdef CONFIG_OF
269 if (priv->device->of_node) {
270 struct gpio_desc *reset_gpio;
271 u32 delays[3] = { 0, 0, 0 };
272
273 reset_gpio = devm_gpiod_get_optional(priv->device,
274 "snps,reset",
275 GPIOD_OUT_LOW);
276 if (IS_ERR(reset_gpio))
277 return PTR_ERR(reset_gpio);
278
279 device_property_read_u32_array(priv->device,
280 "snps,reset-delays-us",
281 delays, ARRAY_SIZE(delays));
282
283 if (delays[0])
284 msleep(DIV_ROUND_UP(delays[0], 1000));
285
286 gpiod_set_value_cansleep(reset_gpio, 1);
287 if (delays[1])
288 msleep(DIV_ROUND_UP(delays[1], 1000));
289
290 gpiod_set_value_cansleep(reset_gpio, 0);
291 if (delays[2])
292 msleep(DIV_ROUND_UP(delays[2], 1000));
293 }
294#endif
295
296
297
298
299
300
301 if (!priv->plat->has_gmac4)
302 writel(0, priv->ioaddr + mii_address);
303#endif
304 return 0;
305}
306
307
308
309
310
311
312int stmmac_mdio_register(struct net_device *ndev)
313{
314 int err = 0;
315 struct mii_bus *new_bus;
316 struct stmmac_priv *priv = netdev_priv(ndev);
317 struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
318 struct device_node *mdio_node = priv->plat->mdio_node;
319 struct device *dev = ndev->dev.parent;
320 int addr, found, max_addr;
321
322 if (!mdio_bus_data)
323 return 0;
324
325 new_bus = mdiobus_alloc();
326 if (!new_bus)
327 return -ENOMEM;
328
329 if (mdio_bus_data->irqs)
330 memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
331
332 new_bus->name = "stmmac";
333
334 if (priv->plat->has_xgmac) {
335 new_bus->read = &stmmac_xgmac2_mdio_read;
336 new_bus->write = &stmmac_xgmac2_mdio_write;
337
338
339 max_addr = MII_XGMAC_MAX_C22ADDR + 1;
340
341
342 if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR)
343 dev_err(dev, "Unsupported phy_addr (max=%d)\n",
344 MII_XGMAC_MAX_C22ADDR);
345 } else {
346 new_bus->read = &stmmac_mdio_read;
347 new_bus->write = &stmmac_mdio_write;
348 max_addr = PHY_MAX_ADDR;
349 }
350
351 if (mdio_bus_data->needs_reset)
352 new_bus->reset = &stmmac_mdio_reset;
353
354 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
355 new_bus->name, priv->plat->bus_id);
356 new_bus->priv = ndev;
357 new_bus->phy_mask = mdio_bus_data->phy_mask;
358 new_bus->parent = priv->device;
359
360 err = of_mdiobus_register(new_bus, mdio_node);
361 if (err != 0) {
362 dev_err(dev, "Cannot register the MDIO bus\n");
363 goto bus_register_fail;
364 }
365
366 if (priv->plat->phy_node || mdio_node)
367 goto bus_register_done;
368
369 found = 0;
370 for (addr = 0; addr < max_addr; addr++) {
371 struct phy_device *phydev = mdiobus_get_phy(new_bus, addr);
372
373 if (!phydev)
374 continue;
375
376
377
378
379
380 if (!mdio_bus_data->irqs &&
381 (mdio_bus_data->probed_phy_irq > 0)) {
382 new_bus->irq[addr] = mdio_bus_data->probed_phy_irq;
383 phydev->irq = mdio_bus_data->probed_phy_irq;
384 }
385
386
387
388
389
390
391 if (priv->plat->phy_addr == -1)
392 priv->plat->phy_addr = addr;
393
394 phy_attached_info(phydev);
395 found = 1;
396 }
397
398 if (!found && !mdio_node) {
399 dev_warn(dev, "No PHY found\n");
400 mdiobus_unregister(new_bus);
401 mdiobus_free(new_bus);
402 return -ENODEV;
403 }
404
405bus_register_done:
406 priv->mii = new_bus;
407
408 return 0;
409
410bus_register_fail:
411 mdiobus_free(new_bus);
412 return err;
413}
414
415
416
417
418
419
420int stmmac_mdio_unregister(struct net_device *ndev)
421{
422 struct stmmac_priv *priv = netdev_priv(ndev);
423
424 if (!priv->mii)
425 return 0;
426
427 mdiobus_unregister(priv->mii);
428 priv->mii->priv = NULL;
429 mdiobus_free(priv->mii);
430 priv->mii = NULL;
431
432 return 0;
433}
434