Lines Matching +full:mdio +full:- +full:bus
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Freescale PowerQUICC Ethernet Driver -- MIIM bus implementation
4 * Provides Bus interface for MIIM regs
9 * Copyright 2002-2004, 2008-2009 Freescale Semiconductor, Inc.
52 u32 ieventm; /* MDIO Interrupt event register (for etsec2)*/
53 u32 imaskm; /* MDIO Interrupt mask register (for etsec2)*/
55 u32 emapm; /* MDIO Event mapping register (for etsec2)*/
72 * Per-device-type data. Each type of device tree node that we support gets
90 * Write value to the PHY at mii_id at register regnum, on the bus attached
91 * to the local interface, which may be different from the generic mdio bus
95 * mdio pins, which may not be the same as system mdio bus, used for
98 static int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, in fsl_pq_mdio_write() argument
101 struct fsl_pq_mdio_priv *priv = bus->priv; in fsl_pq_mdio_write()
102 struct fsl_pq_mii __iomem *regs = priv->regs; in fsl_pq_mdio_write()
106 iowrite32be((mii_id << 8) | regnum, ®s->miimadd); in fsl_pq_mdio_write()
109 iowrite32be(value, ®s->miimcon); in fsl_pq_mdio_write()
113 while ((ioread32be(®s->miimind) & MIIMIND_BUSY) && timeout) { in fsl_pq_mdio_write()
115 timeout--; in fsl_pq_mdio_write()
118 return timeout ? 0 : -ETIMEDOUT; in fsl_pq_mdio_write()
122 * Read the bus for PHY at addr mii_id, register regnum, and return the value.
125 * All PHY operation done on the bus attached to the local interface, which
126 * may be different from the generic mdio bus. This is helpful in programming
127 * interfaces like the TBI which, in turn, control interfaces like on-chip
128 * SERDES and are always tied to the local mdio pins, which may not be the
129 * same as system mdio bus, used for controlling the external PHYs, for eg.
131 static int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) in fsl_pq_mdio_read() argument
133 struct fsl_pq_mdio_priv *priv = bus->priv; in fsl_pq_mdio_read()
134 struct fsl_pq_mii __iomem *regs = priv->regs; in fsl_pq_mdio_read()
139 iowrite32be((mii_id << 8) | regnum, ®s->miimadd); in fsl_pq_mdio_read()
142 iowrite32be(0, ®s->miimcom); in fsl_pq_mdio_read()
143 iowrite32be(MII_READ_COMMAND, ®s->miimcom); in fsl_pq_mdio_read()
147 while ((ioread32be(®s->miimind) & in fsl_pq_mdio_read()
150 timeout--; in fsl_pq_mdio_read()
154 return -ETIMEDOUT; in fsl_pq_mdio_read()
157 value = ioread32be(®s->miimstat); in fsl_pq_mdio_read()
159 dev_dbg(&bus->dev, "read %04x from address %x/%x\n", value, mii_id, regnum); in fsl_pq_mdio_read()
163 /* Reset the MIIM registers, and wait for the bus to free */
164 static int fsl_pq_mdio_reset(struct mii_bus *bus) in fsl_pq_mdio_reset() argument
166 struct fsl_pq_mdio_priv *priv = bus->priv; in fsl_pq_mdio_reset()
167 struct fsl_pq_mii __iomem *regs = priv->regs; in fsl_pq_mdio_reset()
170 mutex_lock(&bus->mdio_lock); in fsl_pq_mdio_reset()
173 iowrite32be(MIIMCFG_RESET, ®s->miimcfg); in fsl_pq_mdio_reset()
176 iowrite32be(MIIMCFG_INIT_VALUE, ®s->miimcfg); in fsl_pq_mdio_reset()
178 /* Wait until the bus is free */ in fsl_pq_mdio_reset()
180 while ((ioread32be(®s->miimind) & MIIMIND_BUSY) && timeout) { in fsl_pq_mdio_reset()
182 timeout--; in fsl_pq_mdio_reset()
185 mutex_unlock(&bus->mdio_lock); in fsl_pq_mdio_reset()
188 dev_err(&bus->dev, "timeout waiting for MII bus\n"); in fsl_pq_mdio_reset()
189 return -EBUSY; in fsl_pq_mdio_reset()
198 * of the mapped GFAR MDIO registers (struct gfar)
207 return &enet_regs->tbipa; in get_gfar_tbipa_from_mdio()
230 * Return the TBIPAR address for a QE MDIO node, starting from the address
235 struct fsl_pq_mdio __iomem *mdio = container_of(p, struct fsl_pq_mdio, mii); in get_ucc_tbipa() local
237 return &mdio->utbipar; in get_ucc_tbipa()
241 * Find the UCC node that controls the given MDIO node
243 * For some reason, the QE MDIO nodes are not children of the UCC devices
245 * the one that encompases the given MDIO node. We do this by comparing
246 * physical addresses. The 'start' and 'end' addresses of the MDIO node are
249 * This assumes that there is only one QE MDIO node in the entire device tree.
267 pr_debug("fsl-pq-mdio: no address range in node %pOF\n", in ucc_configure()
272 /* if our mdio regs fall within this UCC regs range */ in ucc_configure()
276 iprop = of_get_property(np, "cell-index", NULL); in ucc_configure()
278 iprop = of_get_property(np, "device-id", NULL); in ucc_configure()
280 pr_debug("fsl-pq-mdio: no UCC ID in node %pOF\n", in ucc_configure()
289 * cell-index and device-id for QE nodes are in ucc_configure()
292 if (ucc_set_qe_mux_mii_mng(id - 1) < 0) { in ucc_configure()
293 pr_debug("fsl-pq-mdio: invalid UCC ID in node %pOF\n", in ucc_configure()
298 pr_debug("fsl-pq-mdio: setting node UCC%u to MII master\n", id); in ucc_configure()
308 .compatible = "fsl,gianfar-tbi",
315 .compatible = "fsl,gianfar-mdio",
322 .type = "mdio",
330 .compatible = "fsl,etsec2-tbi",
337 .compatible = "fsl,etsec2-mdio",
346 .compatible = "fsl,ucc-mdio",
354 /* Legacy UCC MDIO node */
355 .type = "mdio",
366 .compatible = "fsl,fman-mdio",
381 struct device_node *np = pdev->dev.of_node; in set_tbipa()
398 if ((void *)tbipa > reg_map + resource_size(reg_res) - 4) in set_tbipa()
399 dev_err(&pdev->dev, "invalid register map (should be at least 0x%04zx to contain TBI address)\n", in set_tbipa()
400 ((void *)tbipa - reg_map) + 4); in set_tbipa()
412 struct device_node *np = pdev->dev.of_node; in fsl_pq_mdio_probe()
419 data = device_get_match_data(&pdev->dev); in fsl_pq_mdio_probe()
421 dev_err(&pdev->dev, "Failed to match device\n"); in fsl_pq_mdio_probe()
422 return -ENODEV; in fsl_pq_mdio_probe()
427 return -ENOMEM; in fsl_pq_mdio_probe()
429 priv = new_bus->priv; in fsl_pq_mdio_probe()
430 new_bus->name = "Freescale PowerQUICC MII Bus"; in fsl_pq_mdio_probe()
431 new_bus->read = &fsl_pq_mdio_read; in fsl_pq_mdio_probe()
432 new_bus->write = &fsl_pq_mdio_write; in fsl_pq_mdio_probe()
433 new_bus->reset = &fsl_pq_mdio_reset; in fsl_pq_mdio_probe()
437 dev_err(&pdev->dev, "could not obtain address information\n"); in fsl_pq_mdio_probe()
441 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%pOFn@%llx", np, in fsl_pq_mdio_probe()
444 priv->map = of_iomap(np, 0); in fsl_pq_mdio_probe()
445 if (!priv->map) { in fsl_pq_mdio_probe()
446 err = -ENOMEM; in fsl_pq_mdio_probe()
456 if (data->mii_offset > resource_size(&res)) { in fsl_pq_mdio_probe()
457 dev_err(&pdev->dev, "invalid register map\n"); in fsl_pq_mdio_probe()
458 err = -EINVAL; in fsl_pq_mdio_probe()
461 priv->regs = priv->map + data->mii_offset; in fsl_pq_mdio_probe()
463 new_bus->parent = &pdev->dev; in fsl_pq_mdio_probe()
466 if (data->get_tbipa) { in fsl_pq_mdio_probe()
468 if (of_node_is_type(tbi, "tbi-phy")) { in fsl_pq_mdio_probe()
469 dev_dbg(&pdev->dev, "found TBI PHY node %pOFP\n", in fsl_pq_mdio_probe()
478 dev_err(&pdev->dev, in fsl_pq_mdio_probe()
481 err = -EBUSY; in fsl_pq_mdio_probe()
485 data->get_tbipa, priv->map, &res); in fsl_pq_mdio_probe()
489 if (data->ucc_configure) in fsl_pq_mdio_probe()
490 data->ucc_configure(res.start, res.end); in fsl_pq_mdio_probe()
494 dev_err(&pdev->dev, "cannot register %s as MDIO bus\n", in fsl_pq_mdio_probe()
495 new_bus->name); in fsl_pq_mdio_probe()
502 if (priv->map) in fsl_pq_mdio_probe()
503 iounmap(priv->map); in fsl_pq_mdio_probe()
513 struct device *device = &pdev->dev; in fsl_pq_mdio_remove()
514 struct mii_bus *bus = dev_get_drvdata(device); in fsl_pq_mdio_remove() local
515 struct fsl_pq_mdio_priv *priv = bus->priv; in fsl_pq_mdio_remove()
517 mdiobus_unregister(bus); in fsl_pq_mdio_remove()
519 iounmap(priv->map); in fsl_pq_mdio_remove()
520 mdiobus_free(bus); in fsl_pq_mdio_remove()
525 .name = "fsl-pq_mdio",
534 MODULE_DESCRIPTION("Freescale PQ MDIO helpers");