Lines Matching +full:mdio +full:- +full:bus

2  * QorIQ 10G MDIO Controller
20 #include <linux/mdio.h>
33 __be32 mdio_stat; /* MDIO configuration and status */
34 __be32 mdio_ctl; /* MDIO control */
35 __be32 mdio_data; /* MDIO data */
36 __be32 mdio_addr; /* MDIO address */
82 * Wait until the MDIO bus is free
90 /* Wait till the bus is free */ in xgmac_wait_until_free()
92 while ((xgmac_read32(&regs->mdio_stat, is_little_endian) & in xgmac_wait_until_free()
95 timeout--; in xgmac_wait_until_free()
99 dev_err(dev, "timeout waiting for bus to be free\n"); in xgmac_wait_until_free()
100 return -ETIMEDOUT; in xgmac_wait_until_free()
107 * Wait till the MDIO read or write operation is complete
115 /* Wait till the MDIO write is complete */ in xgmac_wait_until_done()
117 while ((xgmac_read32(&regs->mdio_stat, is_little_endian) & in xgmac_wait_until_done()
120 timeout--; in xgmac_wait_until_done()
125 return -ETIMEDOUT; in xgmac_wait_until_done()
136 static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value) in xgmac_mdio_write() argument
138 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_write()
139 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_write()
143 bool endian = priv->is_little_endian; in xgmac_mdio_write()
145 mdio_stat = xgmac_read32(&regs->mdio_stat, endian); in xgmac_mdio_write()
156 xgmac_write32(mdio_stat, &regs->mdio_stat, endian); in xgmac_mdio_write()
158 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_write()
164 xgmac_write32(mdio_ctl, &regs->mdio_ctl, endian); in xgmac_mdio_write()
168 xgmac_write32(regnum & 0xffff, &regs->mdio_addr, endian); in xgmac_mdio_write()
170 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_write()
176 xgmac_write32(MDIO_DATA(value), &regs->mdio_data, endian); in xgmac_mdio_write()
178 ret = xgmac_wait_until_done(&bus->dev, regs, endian); in xgmac_mdio_write()
190 static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum) in xgmac_mdio_read() argument
192 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_read()
193 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_read()
199 bool endian = priv->is_little_endian; in xgmac_mdio_read()
201 mdio_stat = xgmac_read32(&regs->mdio_stat, endian); in xgmac_mdio_read()
210 xgmac_write32(mdio_stat, &regs->mdio_stat, endian); in xgmac_mdio_read()
212 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_read()
218 xgmac_write32(mdio_ctl, &regs->mdio_ctl, endian); in xgmac_mdio_read()
222 xgmac_write32(regnum & 0xffff, &regs->mdio_addr, endian); in xgmac_mdio_read()
224 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_read()
229 if (priv->has_a009885) in xgmac_mdio_read()
236 xgmac_write32(mdio_ctl | MDIO_CTL_READ, &regs->mdio_ctl, endian); in xgmac_mdio_read()
238 ret = xgmac_wait_until_done(&bus->dev, regs, endian); in xgmac_mdio_read()
243 if ((xgmac_read32(&regs->mdio_stat, endian) & MDIO_STAT_RD_ER) && in xgmac_mdio_read()
244 !priv->has_a011043) { in xgmac_mdio_read()
245 dev_dbg(&bus->dev, in xgmac_mdio_read()
250 ret = xgmac_read32(&regs->mdio_data, endian) & 0xffff; in xgmac_mdio_read()
251 dev_dbg(&bus->dev, "read %04x\n", ret); in xgmac_mdio_read()
255 if (priv->has_a009885) in xgmac_mdio_read()
261 static int xgmac_mdio_set_mdc_freq(struct mii_bus *bus) in xgmac_mdio_set_mdc_freq() argument
263 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_set_mdc_freq()
264 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_set_mdc_freq()
265 struct device *dev = bus->parent; in xgmac_mdio_set_mdc_freq()
268 if (device_property_read_u32(dev, "clock-frequency", &priv->mdc_freq)) in xgmac_mdio_set_mdc_freq()
271 priv->enet_clk = devm_clk_get(dev, NULL); in xgmac_mdio_set_mdc_freq()
272 if (IS_ERR(priv->enet_clk)) { in xgmac_mdio_set_mdc_freq()
274 return PTR_ERR(priv->enet_clk); in xgmac_mdio_set_mdc_freq()
277 div = ((clk_get_rate(priv->enet_clk) / priv->mdc_freq) - 1) / 2; in xgmac_mdio_set_mdc_freq()
280 return -EINVAL; in xgmac_mdio_set_mdc_freq()
283 mdio_stat = xgmac_read32(&regs->mdio_stat, priv->is_little_endian); in xgmac_mdio_set_mdc_freq()
286 xgmac_write32(mdio_stat, &regs->mdio_stat, priv->is_little_endian); in xgmac_mdio_set_mdc_freq()
290 static void xgmac_mdio_set_suppress_preamble(struct mii_bus *bus) in xgmac_mdio_set_suppress_preamble() argument
292 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_set_suppress_preamble()
293 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_set_suppress_preamble()
294 struct device *dev = bus->parent; in xgmac_mdio_set_suppress_preamble()
297 if (!device_property_read_bool(dev, "suppress-preamble")) in xgmac_mdio_set_suppress_preamble()
300 mdio_stat = xgmac_read32(&regs->mdio_stat, priv->is_little_endian); in xgmac_mdio_set_suppress_preamble()
302 xgmac_write32(mdio_stat, &regs->mdio_stat, priv->is_little_endian); in xgmac_mdio_set_suppress_preamble()
310 struct mii_bus *bus; in xgmac_mdio_probe() local
313 /* In DPAA-1, MDIO is one of the many FMan sub-devices. The FMan in xgmac_mdio_probe()
315 * subdevice areas. Therefore, MDIO cannot claim exclusive access to in xgmac_mdio_probe()
320 dev_err(&pdev->dev, "could not obtain address\n"); in xgmac_mdio_probe()
321 return -EINVAL; in xgmac_mdio_probe()
324 bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(struct mdio_fsl_priv)); in xgmac_mdio_probe()
325 if (!bus) in xgmac_mdio_probe()
326 return -ENOMEM; in xgmac_mdio_probe()
328 bus->name = "Freescale XGMAC MDIO Bus"; in xgmac_mdio_probe()
329 bus->read = xgmac_mdio_read; in xgmac_mdio_probe()
330 bus->write = xgmac_mdio_write; in xgmac_mdio_probe()
331 bus->parent = &pdev->dev; in xgmac_mdio_probe()
332 bus->probe_capabilities = MDIOBUS_C22_C45; in xgmac_mdio_probe()
333 snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res->start); in xgmac_mdio_probe()
335 priv = bus->priv; in xgmac_mdio_probe()
336 priv->mdio_base = devm_ioremap(&pdev->dev, res->start, in xgmac_mdio_probe()
338 if (!priv->mdio_base) in xgmac_mdio_probe()
339 return -ENOMEM; in xgmac_mdio_probe()
341 /* For both ACPI and DT cases, endianness of MDIO controller in xgmac_mdio_probe()
342 * needs to be specified using "little-endian" property. in xgmac_mdio_probe()
344 priv->is_little_endian = device_property_read_bool(&pdev->dev, in xgmac_mdio_probe()
345 "little-endian"); in xgmac_mdio_probe()
347 priv->has_a009885 = device_property_read_bool(&pdev->dev, in xgmac_mdio_probe()
348 "fsl,erratum-a009885"); in xgmac_mdio_probe()
349 priv->has_a011043 = device_property_read_bool(&pdev->dev, in xgmac_mdio_probe()
350 "fsl,erratum-a011043"); in xgmac_mdio_probe()
352 xgmac_mdio_set_suppress_preamble(bus); in xgmac_mdio_probe()
354 ret = xgmac_mdio_set_mdc_freq(bus); in xgmac_mdio_probe()
358 fwnode = dev_fwnode(&pdev->dev); in xgmac_mdio_probe()
360 ret = of_mdiobus_register(bus, to_of_node(fwnode)); in xgmac_mdio_probe()
362 ret = acpi_mdiobus_register(bus, fwnode); in xgmac_mdio_probe()
364 ret = -EINVAL; in xgmac_mdio_probe()
366 dev_err(&pdev->dev, "cannot register MDIO bus\n"); in xgmac_mdio_probe()
370 platform_set_drvdata(pdev, bus); in xgmac_mdio_probe()
377 .compatible = "fsl,fman-xmdio",
380 .compatible = "fsl,fman-memac-mdio",
394 .name = "fsl-fman_xmdio",
403 MODULE_DESCRIPTION("Freescale QorIQ 10G MDIO Controller");