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(®s->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(®s->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()
131 static int xgmac_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, in xgmac_mdio_write_c22() argument
134 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_write_c22()
135 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_write_c22()
136 bool endian = priv->is_little_endian; in xgmac_mdio_write_c22()
141 mdio_stat = xgmac_read32(®s->mdio_stat, endian); in xgmac_mdio_write_c22()
143 xgmac_write32(mdio_stat, ®s->mdio_stat, endian); in xgmac_mdio_write_c22()
145 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_write_c22()
151 xgmac_write32(mdio_ctl, ®s->mdio_ctl, endian); in xgmac_mdio_write_c22()
154 xgmac_write32(MDIO_DATA(value), ®s->mdio_data, endian); in xgmac_mdio_write_c22()
156 ret = xgmac_wait_until_done(&bus->dev, regs, endian); in xgmac_mdio_write_c22()
163 static int xgmac_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr, in xgmac_mdio_write_c45() argument
166 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_write_c45()
167 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_write_c45()
168 bool endian = priv->is_little_endian; in xgmac_mdio_write_c45()
172 mdio_stat = xgmac_read32(®s->mdio_stat, endian); in xgmac_mdio_write_c45()
175 xgmac_write32(mdio_stat, ®s->mdio_stat, endian); in xgmac_mdio_write_c45()
177 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_write_c45()
183 xgmac_write32(mdio_ctl, ®s->mdio_ctl, endian); in xgmac_mdio_write_c45()
186 xgmac_write32(regnum & 0xffff, ®s->mdio_addr, endian); in xgmac_mdio_write_c45()
188 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_write_c45()
193 xgmac_write32(MDIO_DATA(value), ®s->mdio_data, endian); in xgmac_mdio_write_c45()
195 ret = xgmac_wait_until_done(&bus->dev, regs, endian); in xgmac_mdio_write_c45()
206 static int xgmac_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum) in xgmac_mdio_read_c22() argument
208 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_read_c22()
209 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_read_c22()
210 bool endian = priv->is_little_endian; in xgmac_mdio_read_c22()
217 mdio_stat = xgmac_read32(®s->mdio_stat, endian); in xgmac_mdio_read_c22()
219 xgmac_write32(mdio_stat, ®s->mdio_stat, endian); in xgmac_mdio_read_c22()
221 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_read_c22()
227 xgmac_write32(mdio_ctl, ®s->mdio_ctl, endian); in xgmac_mdio_read_c22()
229 if (priv->has_a009885) in xgmac_mdio_read_c22()
236 xgmac_write32(mdio_ctl | MDIO_CTL_READ, ®s->mdio_ctl, endian); in xgmac_mdio_read_c22()
238 ret = xgmac_wait_until_done(&bus->dev, regs, endian); in xgmac_mdio_read_c22()
243 if ((xgmac_read32(®s->mdio_stat, endian) & MDIO_STAT_RD_ER) && in xgmac_mdio_read_c22()
244 !priv->has_a011043) { in xgmac_mdio_read_c22()
245 dev_dbg(&bus->dev, in xgmac_mdio_read_c22()
250 ret = xgmac_read32(®s->mdio_data, endian) & 0xffff; in xgmac_mdio_read_c22()
251 dev_dbg(&bus->dev, "read %04x\n", ret); in xgmac_mdio_read_c22()
255 if (priv->has_a009885) in xgmac_mdio_read_c22()
265 static int xgmac_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr, in xgmac_mdio_read_c45() argument
268 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_read_c45()
269 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_read_c45()
270 bool endian = priv->is_little_endian; in xgmac_mdio_read_c45()
275 mdio_stat = xgmac_read32(®s->mdio_stat, endian); in xgmac_mdio_read_c45()
278 xgmac_write32(mdio_stat, ®s->mdio_stat, endian); in xgmac_mdio_read_c45()
280 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_read_c45()
286 xgmac_write32(mdio_ctl, ®s->mdio_ctl, endian); in xgmac_mdio_read_c45()
289 xgmac_write32(regnum & 0xffff, ®s->mdio_addr, endian); in xgmac_mdio_read_c45()
291 ret = xgmac_wait_until_free(&bus->dev, regs, endian); in xgmac_mdio_read_c45()
295 if (priv->has_a009885) in xgmac_mdio_read_c45()
302 xgmac_write32(mdio_ctl | MDIO_CTL_READ, ®s->mdio_ctl, endian); in xgmac_mdio_read_c45()
304 ret = xgmac_wait_until_done(&bus->dev, regs, endian); in xgmac_mdio_read_c45()
309 if ((xgmac_read32(®s->mdio_stat, endian) & MDIO_STAT_RD_ER) && in xgmac_mdio_read_c45()
310 !priv->has_a011043) { in xgmac_mdio_read_c45()
311 dev_dbg(&bus->dev, in xgmac_mdio_read_c45()
316 ret = xgmac_read32(®s->mdio_data, endian) & 0xffff; in xgmac_mdio_read_c45()
317 dev_dbg(&bus->dev, "read %04x\n", ret); in xgmac_mdio_read_c45()
321 if (priv->has_a009885) in xgmac_mdio_read_c45()
327 static int xgmac_mdio_set_mdc_freq(struct mii_bus *bus) in xgmac_mdio_set_mdc_freq() argument
329 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_set_mdc_freq()
330 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_set_mdc_freq()
331 struct device *dev = bus->parent; in xgmac_mdio_set_mdc_freq()
334 if (device_property_read_u32(dev, "clock-frequency", &priv->mdc_freq)) in xgmac_mdio_set_mdc_freq()
337 priv->enet_clk = devm_clk_get(dev, NULL); in xgmac_mdio_set_mdc_freq()
338 if (IS_ERR(priv->enet_clk)) { in xgmac_mdio_set_mdc_freq()
340 return PTR_ERR(priv->enet_clk); in xgmac_mdio_set_mdc_freq()
343 div = ((clk_get_rate(priv->enet_clk) / priv->mdc_freq) - 1) / 2; in xgmac_mdio_set_mdc_freq()
346 return -EINVAL; in xgmac_mdio_set_mdc_freq()
349 mdio_stat = xgmac_read32(®s->mdio_stat, priv->is_little_endian); in xgmac_mdio_set_mdc_freq()
352 xgmac_write32(mdio_stat, ®s->mdio_stat, priv->is_little_endian); in xgmac_mdio_set_mdc_freq()
356 static void xgmac_mdio_set_suppress_preamble(struct mii_bus *bus) in xgmac_mdio_set_suppress_preamble() argument
358 struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; in xgmac_mdio_set_suppress_preamble()
359 struct tgec_mdio_controller __iomem *regs = priv->mdio_base; in xgmac_mdio_set_suppress_preamble()
360 struct device *dev = bus->parent; in xgmac_mdio_set_suppress_preamble()
363 if (!device_property_read_bool(dev, "suppress-preamble")) in xgmac_mdio_set_suppress_preamble()
366 mdio_stat = xgmac_read32(®s->mdio_stat, priv->is_little_endian); in xgmac_mdio_set_suppress_preamble()
368 xgmac_write32(mdio_stat, ®s->mdio_stat, priv->is_little_endian); in xgmac_mdio_set_suppress_preamble()
376 struct mii_bus *bus; in xgmac_mdio_probe() local
379 /* In DPAA-1, MDIO is one of the many FMan sub-devices. The FMan in xgmac_mdio_probe()
381 * subdevice areas. Therefore, MDIO cannot claim exclusive access to in xgmac_mdio_probe()
386 dev_err(&pdev->dev, "could not obtain address\n"); in xgmac_mdio_probe()
387 return -EINVAL; in xgmac_mdio_probe()
390 bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(struct mdio_fsl_priv)); in xgmac_mdio_probe()
391 if (!bus) in xgmac_mdio_probe()
392 return -ENOMEM; in xgmac_mdio_probe()
394 bus->name = "Freescale XGMAC MDIO Bus"; in xgmac_mdio_probe()
395 bus->read = xgmac_mdio_read_c22; in xgmac_mdio_probe()
396 bus->write = xgmac_mdio_write_c22; in xgmac_mdio_probe()
397 bus->read_c45 = xgmac_mdio_read_c45; in xgmac_mdio_probe()
398 bus->write_c45 = xgmac_mdio_write_c45; in xgmac_mdio_probe()
399 bus->parent = &pdev->dev; in xgmac_mdio_probe()
400 snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res->start); in xgmac_mdio_probe()
402 priv = bus->priv; in xgmac_mdio_probe()
403 priv->mdio_base = devm_ioremap(&pdev->dev, res->start, in xgmac_mdio_probe()
405 if (!priv->mdio_base) in xgmac_mdio_probe()
406 return -ENOMEM; in xgmac_mdio_probe()
408 /* For both ACPI and DT cases, endianness of MDIO controller in xgmac_mdio_probe()
409 * needs to be specified using "little-endian" property. in xgmac_mdio_probe()
411 priv->is_little_endian = device_property_read_bool(&pdev->dev, in xgmac_mdio_probe()
412 "little-endian"); in xgmac_mdio_probe()
414 priv->has_a009885 = device_property_read_bool(&pdev->dev, in xgmac_mdio_probe()
415 "fsl,erratum-a009885"); in xgmac_mdio_probe()
416 priv->has_a011043 = device_property_read_bool(&pdev->dev, in xgmac_mdio_probe()
417 "fsl,erratum-a011043"); in xgmac_mdio_probe()
419 xgmac_mdio_set_suppress_preamble(bus); in xgmac_mdio_probe()
421 ret = xgmac_mdio_set_mdc_freq(bus); in xgmac_mdio_probe()
425 fwnode = dev_fwnode(&pdev->dev); in xgmac_mdio_probe()
427 ret = of_mdiobus_register(bus, to_of_node(fwnode)); in xgmac_mdio_probe()
429 ret = acpi_mdiobus_register(bus, fwnode); in xgmac_mdio_probe()
431 ret = -EINVAL; in xgmac_mdio_probe()
433 dev_err(&pdev->dev, "cannot register MDIO bus\n"); in xgmac_mdio_probe()
437 platform_set_drvdata(pdev, bus); in xgmac_mdio_probe()
444 .compatible = "fsl,fman-xmdio",
447 .compatible = "fsl,fman-memac-mdio",
461 .name = "fsl-fman_xmdio",
470 MODULE_DESCRIPTION("Freescale QorIQ 10G MDIO Controller");