Lines Matching +full:device +full:- +full:addr
1 // SPDX-License-Identifier: GPL-2.0-only
3 STMMAC Ethernet Driver -- MDIO bus implementation
6 Copyright (C) 2007-2009 STMicroelectronics Ltd
54 tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P); in stmmac_xgmac2_c45_format()
56 writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P); in stmmac_xgmac2_c45_format()
67 if (priv->synopsys_id < DWXGMAC_CORE_2_20) { in stmmac_xgmac2_c22_format()
68 /* Until ver 2.20 XGMAC does not support C22 addr >= 4. Those in stmmac_xgmac2_c22_format()
71 tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P); in stmmac_xgmac2_c22_format()
76 writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P); in stmmac_xgmac2_c22_format()
81 static int stmmac_xgmac2_mdio_read(struct stmmac_priv *priv, u32 addr, in stmmac_xgmac2_mdio_read() argument
84 unsigned int mii_address = priv->hw->mii.addr; in stmmac_xgmac2_mdio_read()
85 unsigned int mii_data = priv->hw->mii.data; in stmmac_xgmac2_mdio_read()
89 ret = pm_runtime_resume_and_get(priv->device); in stmmac_xgmac2_mdio_read()
94 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_read()
96 ret = -EBUSY; in stmmac_xgmac2_mdio_read()
100 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_xgmac2_mdio_read()
101 & priv->hw->mii.clk_csr_mask; in stmmac_xgmac2_mdio_read()
105 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_read()
107 ret = -EBUSY; in stmmac_xgmac2_mdio_read()
112 writel(addr, priv->ioaddr + mii_address); in stmmac_xgmac2_mdio_read()
113 writel(value, priv->ioaddr + mii_data); in stmmac_xgmac2_mdio_read()
116 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_read()
118 ret = -EBUSY; in stmmac_xgmac2_mdio_read()
123 ret = (int)readl(priv->ioaddr + mii_data) & GENMASK(15, 0); in stmmac_xgmac2_mdio_read()
126 pm_runtime_put(priv->device); in stmmac_xgmac2_mdio_read()
134 struct net_device *ndev = bus->priv; in stmmac_xgmac2_mdio_read_c22()
136 u32 addr; in stmmac_xgmac2_mdio_read_c22() local
140 /* Until ver 2.20 XGMAC does not support C22 addr >= 4 */ in stmmac_xgmac2_mdio_read_c22()
141 if (priv->synopsys_id < DWXGMAC_CORE_2_20 && in stmmac_xgmac2_mdio_read_c22()
143 return -ENODEV; in stmmac_xgmac2_mdio_read_c22()
145 stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr); in stmmac_xgmac2_mdio_read_c22()
147 return stmmac_xgmac2_mdio_read(priv, addr, MII_XGMAC_BUSY); in stmmac_xgmac2_mdio_read_c22()
153 struct net_device *ndev = bus->priv; in stmmac_xgmac2_mdio_read_c45()
155 u32 addr; in stmmac_xgmac2_mdio_read_c45() local
159 stmmac_xgmac2_c45_format(priv, phyaddr, devad, phyreg, &addr); in stmmac_xgmac2_mdio_read_c45()
161 return stmmac_xgmac2_mdio_read(priv, addr, MII_XGMAC_BUSY); in stmmac_xgmac2_mdio_read_c45()
164 static int stmmac_xgmac2_mdio_write(struct stmmac_priv *priv, u32 addr, in stmmac_xgmac2_mdio_write() argument
167 unsigned int mii_address = priv->hw->mii.addr; in stmmac_xgmac2_mdio_write()
168 unsigned int mii_data = priv->hw->mii.data; in stmmac_xgmac2_mdio_write()
172 ret = pm_runtime_resume_and_get(priv->device); in stmmac_xgmac2_mdio_write()
177 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_write()
179 ret = -EBUSY; in stmmac_xgmac2_mdio_write()
183 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_xgmac2_mdio_write()
184 & priv->hw->mii.clk_csr_mask; in stmmac_xgmac2_mdio_write()
189 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_write()
191 ret = -EBUSY; in stmmac_xgmac2_mdio_write()
196 writel(addr, priv->ioaddr + mii_address); in stmmac_xgmac2_mdio_write()
197 writel(value, priv->ioaddr + mii_data); in stmmac_xgmac2_mdio_write()
200 ret = readl_poll_timeout(priv->ioaddr + mii_data, tmp, in stmmac_xgmac2_mdio_write()
204 pm_runtime_put(priv->device); in stmmac_xgmac2_mdio_write()
212 struct net_device *ndev = bus->priv; in stmmac_xgmac2_mdio_write_c22()
214 u32 addr; in stmmac_xgmac2_mdio_write_c22() local
218 /* Until ver 2.20 XGMAC does not support C22 addr >= 4 */ in stmmac_xgmac2_mdio_write_c22()
219 if (priv->synopsys_id < DWXGMAC_CORE_2_20 && in stmmac_xgmac2_mdio_write_c22()
221 return -ENODEV; in stmmac_xgmac2_mdio_write_c22()
223 stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr); in stmmac_xgmac2_mdio_write_c22()
225 return stmmac_xgmac2_mdio_write(priv, addr, in stmmac_xgmac2_mdio_write_c22()
232 struct net_device *ndev = bus->priv; in stmmac_xgmac2_mdio_write_c45()
234 u32 addr; in stmmac_xgmac2_mdio_write_c45() local
238 stmmac_xgmac2_c45_format(priv, phyaddr, devad, phyreg, &addr); in stmmac_xgmac2_mdio_write_c45()
240 return stmmac_xgmac2_mdio_write(priv, addr, MII_XGMAC_BUSY, in stmmac_xgmac2_mdio_write_c45()
246 unsigned int mii_address = priv->hw->mii.addr; in stmmac_mdio_read()
247 unsigned int mii_data = priv->hw->mii.data; in stmmac_mdio_read()
250 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), in stmmac_mdio_read()
252 return -EBUSY; in stmmac_mdio_read()
254 writel(data, priv->ioaddr + mii_data); in stmmac_mdio_read()
255 writel(value, priv->ioaddr + mii_address); in stmmac_mdio_read()
257 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), in stmmac_mdio_read()
259 return -EBUSY; in stmmac_mdio_read()
262 return readl(priv->ioaddr + mii_data) & MII_DATA_MASK; in stmmac_mdio_read()
268 * @phyaddr: MII addr
270 * Description: it reads data from the MII register from within the phy device.
277 struct net_device *ndev = bus->priv; in stmmac_mdio_read_c22()
282 data = pm_runtime_resume_and_get(priv->device); in stmmac_mdio_read_c22()
286 value |= (phyaddr << priv->hw->mii.addr_shift) in stmmac_mdio_read_c22()
287 & priv->hw->mii.addr_mask; in stmmac_mdio_read_c22()
288 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; in stmmac_mdio_read_c22()
289 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_mdio_read_c22()
290 & priv->hw->mii.clk_csr_mask; in stmmac_mdio_read_c22()
291 if (priv->plat->has_gmac4) in stmmac_mdio_read_c22()
296 pm_runtime_put(priv->device); in stmmac_mdio_read_c22()
304 * @phyaddr: MII addr
305 * @devad: device address to read
307 * Description: it reads data from the MII register from within the phy device.
315 struct net_device *ndev = bus->priv; in stmmac_mdio_read_c45()
320 data = pm_runtime_get_sync(priv->device); in stmmac_mdio_read_c45()
322 pm_runtime_put_noidle(priv->device); in stmmac_mdio_read_c45()
326 value |= (phyaddr << priv->hw->mii.addr_shift) in stmmac_mdio_read_c45()
327 & priv->hw->mii.addr_mask; in stmmac_mdio_read_c45()
328 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; in stmmac_mdio_read_c45()
329 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_mdio_read_c45()
330 & priv->hw->mii.clk_csr_mask; in stmmac_mdio_read_c45()
333 value &= ~priv->hw->mii.reg_mask; in stmmac_mdio_read_c45()
334 value |= (devad << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; in stmmac_mdio_read_c45()
340 pm_runtime_put(priv->device); in stmmac_mdio_read_c45()
347 unsigned int mii_address = priv->hw->mii.addr; in stmmac_mdio_write()
348 unsigned int mii_data = priv->hw->mii.data; in stmmac_mdio_write()
352 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY), in stmmac_mdio_write()
354 return -EBUSY; in stmmac_mdio_write()
357 writel(data, priv->ioaddr + mii_data); in stmmac_mdio_write()
358 writel(value, priv->ioaddr + mii_address); in stmmac_mdio_write()
361 return readl_poll_timeout(priv->ioaddr + mii_address, v, in stmmac_mdio_write()
368 * @phyaddr: MII addr
371 * Description: it writes the data into the MII register from within the device.
376 struct net_device *ndev = bus->priv; in stmmac_mdio_write_c22()
381 ret = pm_runtime_resume_and_get(priv->device); in stmmac_mdio_write_c22()
385 value |= (phyaddr << priv->hw->mii.addr_shift) in stmmac_mdio_write_c22()
386 & priv->hw->mii.addr_mask; in stmmac_mdio_write_c22()
387 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; in stmmac_mdio_write_c22()
389 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_mdio_write_c22()
390 & priv->hw->mii.clk_csr_mask; in stmmac_mdio_write_c22()
391 if (priv->plat->has_gmac4) in stmmac_mdio_write_c22()
398 pm_runtime_put(priv->device); in stmmac_mdio_write_c22()
406 * @phyaddr: MII addr
408 * @devad: device address to read
410 * Description: it writes the data into the MII register from within the device.
415 struct net_device *ndev = bus->priv; in stmmac_mdio_write_c45()
420 ret = pm_runtime_get_sync(priv->device); in stmmac_mdio_write_c45()
422 pm_runtime_put_noidle(priv->device); in stmmac_mdio_write_c45()
426 value |= (phyaddr << priv->hw->mii.addr_shift) in stmmac_mdio_write_c45()
427 & priv->hw->mii.addr_mask; in stmmac_mdio_write_c45()
428 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; in stmmac_mdio_write_c45()
430 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift) in stmmac_mdio_write_c45()
431 & priv->hw->mii.clk_csr_mask; in stmmac_mdio_write_c45()
435 value &= ~priv->hw->mii.reg_mask; in stmmac_mdio_write_c45()
436 value |= (devad << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask; in stmmac_mdio_write_c45()
442 pm_runtime_put(priv->device); in stmmac_mdio_write_c45()
455 struct net_device *ndev = bus->priv; in stmmac_mdio_reset()
457 unsigned int mii_address = priv->hw->mii.addr; in stmmac_mdio_reset()
460 if (priv->device->of_node) { in stmmac_mdio_reset()
464 reset_gpio = devm_gpiod_get_optional(priv->device, in stmmac_mdio_reset()
470 device_property_read_u32_array(priv->device, in stmmac_mdio_reset()
471 "snps,reset-delays-us", in stmmac_mdio_reset()
492 if (!priv->plat->has_gmac4) in stmmac_mdio_reset()
493 writel(0, priv->ioaddr + mii_address); in stmmac_mdio_reset()
503 int addr, mode, ret; in stmmac_pcs_setup() local
506 mode = priv->plat->phy_interface; in stmmac_pcs_setup()
507 devnode = priv->plat->port_node; in stmmac_pcs_setup()
509 if (priv->plat->pcs_init) { in stmmac_pcs_setup()
510 ret = priv->plat->pcs_init(priv); in stmmac_pcs_setup()
511 } else if (fwnode_property_present(devnode, "pcs-handle")) { in stmmac_pcs_setup()
512 pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0); in stmmac_pcs_setup()
516 } else if (priv->plat->mdio_bus_data && in stmmac_pcs_setup()
517 priv->plat->mdio_bus_data->pcs_mask) { in stmmac_pcs_setup()
518 addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1; in stmmac_pcs_setup()
519 xpcs = xpcs_create_mdiodev(priv->mii, addr, mode); in stmmac_pcs_setup()
526 return dev_err_probe(priv->device, ret, "No xPCS found\n"); in stmmac_pcs_setup()
528 priv->hw->xpcs = xpcs; in stmmac_pcs_setup()
537 if (priv->plat->pcs_exit) in stmmac_pcs_clean()
538 priv->plat->pcs_exit(priv); in stmmac_pcs_clean()
540 if (!priv->hw->xpcs) in stmmac_pcs_clean()
543 xpcs_destroy(priv->hw->xpcs); in stmmac_pcs_clean()
544 priv->hw->xpcs = NULL; in stmmac_pcs_clean()
549 * @ndev: net device structure
557 struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data; in stmmac_mdio_register()
558 struct device_node *mdio_node = priv->plat->mdio_node; in stmmac_mdio_register()
559 struct device *dev = ndev->dev.parent; in stmmac_mdio_register()
562 int addr, found, max_addr; in stmmac_mdio_register() local
569 return -ENOMEM; in stmmac_mdio_register()
571 if (mdio_bus_data->irqs) in stmmac_mdio_register()
572 memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq)); in stmmac_mdio_register()
574 new_bus->name = "stmmac"; in stmmac_mdio_register()
576 if (priv->plat->has_xgmac) { in stmmac_mdio_register()
577 new_bus->read = &stmmac_xgmac2_mdio_read_c22; in stmmac_mdio_register()
578 new_bus->write = &stmmac_xgmac2_mdio_write_c22; in stmmac_mdio_register()
579 new_bus->read_c45 = &stmmac_xgmac2_mdio_read_c45; in stmmac_mdio_register()
580 new_bus->write_c45 = &stmmac_xgmac2_mdio_write_c45; in stmmac_mdio_register()
582 if (priv->synopsys_id < DWXGMAC_CORE_2_20) { in stmmac_mdio_register()
586 /* Check if DT specified an unsupported phy addr */ in stmmac_mdio_register()
587 if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR) in stmmac_mdio_register()
591 /* XGMAC version 2.20 onwards support 32 phy addr */ in stmmac_mdio_register()
595 new_bus->read = &stmmac_mdio_read_c22; in stmmac_mdio_register()
596 new_bus->write = &stmmac_mdio_write_c22; in stmmac_mdio_register()
597 if (priv->plat->has_gmac4) { in stmmac_mdio_register()
598 new_bus->read_c45 = &stmmac_mdio_read_c45; in stmmac_mdio_register()
599 new_bus->write_c45 = &stmmac_mdio_write_c45; in stmmac_mdio_register()
605 if (mdio_bus_data->needs_reset) in stmmac_mdio_register()
606 new_bus->reset = &stmmac_mdio_reset; in stmmac_mdio_register()
608 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x", in stmmac_mdio_register()
609 new_bus->name, priv->plat->bus_id); in stmmac_mdio_register()
610 new_bus->priv = ndev; in stmmac_mdio_register()
611 new_bus->phy_mask = mdio_bus_data->phy_mask | mdio_bus_data->pcs_mask; in stmmac_mdio_register()
612 new_bus->parent = priv->device; in stmmac_mdio_register()
615 if (err == -ENODEV) { in stmmac_mdio_register()
625 if (priv->plat->has_xgmac) in stmmac_mdio_register()
628 /* If fixed-link is set, skip PHY scanning */ in stmmac_mdio_register()
629 fwnode = priv->plat->port_node; in stmmac_mdio_register()
631 fwnode = dev_fwnode(priv->device); in stmmac_mdio_register()
634 fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link"); in stmmac_mdio_register()
641 if (priv->plat->phy_node || mdio_node) in stmmac_mdio_register()
645 for (addr = 0; addr < max_addr; addr++) { in stmmac_mdio_register()
646 struct phy_device *phydev = mdiobus_get_phy(new_bus, addr); in stmmac_mdio_register()
655 if (!mdio_bus_data->irqs && in stmmac_mdio_register()
656 (mdio_bus_data->probed_phy_irq > 0)) { in stmmac_mdio_register()
657 new_bus->irq[addr] = mdio_bus_data->probed_phy_irq; in stmmac_mdio_register()
658 phydev->irq = mdio_bus_data->probed_phy_irq; in stmmac_mdio_register()
666 if (priv->plat->phy_addr == -1) in stmmac_mdio_register()
667 priv->plat->phy_addr = addr; in stmmac_mdio_register()
675 err = -ENODEV; in stmmac_mdio_register()
680 priv->mii = new_bus; in stmmac_mdio_register()
693 * @ndev: net device structure
700 if (!priv->mii) in stmmac_mdio_unregister()
703 mdiobus_unregister(priv->mii); in stmmac_mdio_unregister()
704 priv->mii->priv = NULL; in stmmac_mdio_unregister()
705 mdiobus_free(priv->mii); in stmmac_mdio_unregister()
706 priv->mii = NULL; in stmmac_mdio_unregister()