Lines Matching +full:cpsw +full:- +full:mdio
1 // SPDX-License-Identifier: GPL-2.0+
3 * DaVinci MDIO Module driver
29 #include <linux/mdio-bitbang.h>
33 * This timeout definition is a worst-case ultra defensive measure against
104 * if MDIO bus is registered from DT.
115 mdio_in = clk_get_rate(data->clk); in davinci_mdio_init_clk()
116 div = (mdio_in / data->pdata.bus_freq) - 1; in davinci_mdio_init_clk()
120 data->clk_div = div; in davinci_mdio_init_clk()
122 * One mdio transaction consists of: in davinci_mdio_init_clk()
131 * In the worst case, we could be kicking off a user-access immediately in davinci_mdio_init_clk()
132 * after the mdio bus scan state-machine triggered its own read. If in davinci_mdio_init_clk()
136 data->access_time = usecs_to_jiffies(access_time * 4); in davinci_mdio_init_clk()
137 if (!data->access_time) in davinci_mdio_init_clk()
138 data->access_time = 1; in davinci_mdio_init_clk()
144 writel(data->clk_div | CONTROL_ENABLE, &data->regs->control); in davinci_mdio_enable()
151 /* Disable MDIO state machine */ in davinci_mdio_disable()
152 reg = readl(&data->regs->control); in davinci_mdio_disable()
155 reg |= data->clk_div; in davinci_mdio_disable()
158 writel(reg, &data->regs->control); in davinci_mdio_disable()
165 reg = readl(&data->regs->poll); in davinci_mdio_enable_manual_mode()
167 writel(reg, &data->regs->poll); in davinci_mdio_enable_manual_mode()
176 reg = readl(&data->regs->manualif); in davinci_set_mdc()
183 writel(reg, &data->regs->manualif); in davinci_set_mdc()
192 reg = readl(&data->regs->manualif); in davinci_set_mdio_dir()
199 writel(reg, &data->regs->manualif); in davinci_set_mdio_dir()
208 reg = readl(&data->regs->manualif); in davinci_set_mdio_data()
215 writel(reg, &data->regs->manualif); in davinci_set_mdio_data()
224 reg = readl(&data->regs->manualif); in davinci_get_mdio_data()
232 ret = pm_runtime_resume_and_get(bus->parent); in davinci_mdiobb_read()
238 pm_runtime_mark_last_busy(bus->parent); in davinci_mdiobb_read()
239 pm_runtime_put_autosuspend(bus->parent); in davinci_mdiobb_read()
249 ret = pm_runtime_resume_and_get(bus->parent); in davinci_mdiobb_write()
255 pm_runtime_mark_last_busy(bus->parent); in davinci_mdiobb_write()
256 pm_runtime_put_autosuspend(bus->parent); in davinci_mdiobb_write()
266 ret = pm_runtime_resume_and_get(data->dev); in davinci_mdio_common_reset()
270 if (data->manual_mode) { in davinci_mdio_common_reset()
276 msleep(PHY_MAX_ADDR * data->access_time); in davinci_mdio_common_reset()
279 ver = readl(&data->regs->version); in davinci_mdio_common_reset()
280 dev_info(data->dev, in davinci_mdio_common_reset()
281 "davinci mdio revision %d.%d, bus freq %ld\n", in davinci_mdio_common_reset()
283 data->pdata.bus_freq); in davinci_mdio_common_reset()
285 if (data->skip_scan) in davinci_mdio_common_reset()
289 phy_mask = readl(&data->regs->alive); in davinci_mdio_common_reset()
291 /* restrict mdio bus to live phys only */ in davinci_mdio_common_reset()
292 dev_info(data->dev, "detected phy mask %x\n", ~phy_mask); in davinci_mdio_common_reset()
296 dev_warn(data->dev, "no live phy, scanning all\n"); in davinci_mdio_common_reset()
299 data->bus->phy_mask = phy_mask; in davinci_mdio_common_reset()
302 pm_runtime_mark_last_busy(data->dev); in davinci_mdio_common_reset()
303 pm_runtime_put_autosuspend(data->dev); in davinci_mdio_common_reset()
310 struct davinci_mdio_data *data = bus->priv; in davinci_mdio_reset()
317 struct mdiobb_ctrl *ctrl = bus->priv; in davinci_mdiobb_reset()
328 struct davinci_mdio_regs __iomem *regs = data->regs; in wait_for_user_access()
333 reg = readl(®s->user[0].access); in wait_for_user_access()
337 reg = readl(®s->control); in wait_for_user_access()
344 * An emac soft_reset may have clobbered the mdio controller's in wait_for_user_access()
348 dev_warn(data->dev, "resetting idled controller\n"); in wait_for_user_access()
350 return -EAGAIN; in wait_for_user_access()
353 reg = readl(®s->user[0].access); in wait_for_user_access()
357 dev_err(data->dev, "timed out waiting for user access\n"); in wait_for_user_access()
358 return -ETIMEDOUT; in wait_for_user_access()
364 struct davinci_mdio_regs __iomem *regs = data->regs; in wait_for_idle()
367 ret = readl_poll_timeout(®s->control, val, val & CONTROL_IDLE, in wait_for_idle()
370 dev_err(data->dev, "timed out waiting for idle\n"); in wait_for_idle()
377 struct davinci_mdio_data *data = bus->priv; in davinci_mdio_read()
382 return -EINVAL; in davinci_mdio_read()
384 ret = pm_runtime_resume_and_get(data->dev); in davinci_mdio_read()
393 if (ret == -EAGAIN) in davinci_mdio_read()
398 writel(reg, &data->regs->user[0].access); in davinci_mdio_read()
401 if (ret == -EAGAIN) in davinci_mdio_read()
406 reg = readl(&data->regs->user[0].access); in davinci_mdio_read()
407 ret = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -EIO; in davinci_mdio_read()
411 pm_runtime_mark_last_busy(data->dev); in davinci_mdio_read()
412 pm_runtime_put_autosuspend(data->dev); in davinci_mdio_read()
419 struct davinci_mdio_data *data = bus->priv; in davinci_mdio_write()
424 return -EINVAL; in davinci_mdio_write()
426 ret = pm_runtime_resume_and_get(data->dev); in davinci_mdio_write()
435 if (ret == -EAGAIN) in davinci_mdio_write()
440 writel(reg, &data->regs->user[0].access); in davinci_mdio_write()
443 if (ret == -EAGAIN) in davinci_mdio_write()
448 pm_runtime_mark_last_busy(data->dev); in davinci_mdio_write()
449 pm_runtime_put_autosuspend(data->dev); in davinci_mdio_write()
457 struct device_node *node = pdev->dev.of_node; in davinci_mdio_probe_dt()
461 return -EINVAL; in davinci_mdio_probe_dt()
464 dev_err(&pdev->dev, "Missing bus_freq property in the DT.\n"); in davinci_mdio_probe_dt()
465 return -EINVAL; in davinci_mdio_probe_dt()
467 data->bus_freq = prop; in davinci_mdio_probe_dt()
501 { .compatible = "ti,cpsw-mdio", .data = &of_cpsw_mdio_data},
517 struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev); in davinci_mdio_probe()
518 struct device *dev = &pdev->dev; in davinci_mdio_probe()
523 int autosuspend_delay_ms = -1; in davinci_mdio_probe()
527 return -ENOMEM; in davinci_mdio_probe()
529 data->manual_mode = false; in davinci_mdio_probe()
530 data->bb_ctrl.ops = &davinci_mdiobb_ops; in davinci_mdio_probe()
532 if (IS_ENABLED(CONFIG_OF) && dev->of_node) { in davinci_mdio_probe()
536 if (soc_match_data && soc_match_data->data) { in davinci_mdio_probe()
538 soc_match_data->data; in davinci_mdio_probe()
540 data->manual_mode = socdata->manual_mode; in davinci_mdio_probe()
544 if (data->manual_mode) in davinci_mdio_probe()
545 data->bus = alloc_mdio_bitbang(&data->bb_ctrl); in davinci_mdio_probe()
547 data->bus = devm_mdiobus_alloc(dev); in davinci_mdio_probe()
549 if (!data->bus) { in davinci_mdio_probe()
551 return -ENOMEM; in davinci_mdio_probe()
554 if (IS_ENABLED(CONFIG_OF) && dev->of_node) { in davinci_mdio_probe()
557 ret = davinci_mdio_probe_dt(&data->pdata, pdev); in davinci_mdio_probe()
560 snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s", pdev->name); in davinci_mdio_probe()
562 of_mdio_data = of_device_get_match_data(&pdev->dev); in davinci_mdio_probe()
565 of_mdio_data->autosuspend_delay_ms; in davinci_mdio_probe()
568 data->pdata = pdata ? (*pdata) : default_pdata; in davinci_mdio_probe()
569 snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s-%x", in davinci_mdio_probe()
570 pdev->name, pdev->id); in davinci_mdio_probe()
573 data->bus->name = dev_name(dev); in davinci_mdio_probe()
575 if (data->manual_mode) { in davinci_mdio_probe()
576 data->bus->read = davinci_mdiobb_read; in davinci_mdio_probe()
577 data->bus->write = davinci_mdiobb_write; in davinci_mdio_probe()
578 data->bus->reset = davinci_mdiobb_reset; in davinci_mdio_probe()
580 dev_info(dev, "Configuring MDIO in manual mode\n"); in davinci_mdio_probe()
582 data->bus->read = davinci_mdio_read; in davinci_mdio_probe()
583 data->bus->write = davinci_mdio_write; in davinci_mdio_probe()
584 data->bus->reset = davinci_mdio_reset; in davinci_mdio_probe()
585 data->bus->priv = data; in davinci_mdio_probe()
587 data->bus->parent = dev; in davinci_mdio_probe()
589 data->clk = devm_clk_get(dev, "fck"); in davinci_mdio_probe()
590 if (IS_ERR(data->clk)) { in davinci_mdio_probe()
592 return PTR_ERR(data->clk); in davinci_mdio_probe()
596 data->dev = dev; in davinci_mdio_probe()
600 return -EINVAL; in davinci_mdio_probe()
601 data->regs = devm_ioremap(dev, res->start, resource_size(res)); in davinci_mdio_probe()
602 if (!data->regs) in davinci_mdio_probe()
603 return -ENOMEM; in davinci_mdio_probe()
607 pm_runtime_set_autosuspend_delay(&pdev->dev, autosuspend_delay_ms); in davinci_mdio_probe()
608 pm_runtime_use_autosuspend(&pdev->dev); in davinci_mdio_probe()
609 pm_runtime_enable(&pdev->dev); in davinci_mdio_probe()
614 * Davinci MDIO will always scan the bus for PHYs detection. in davinci_mdio_probe()
616 if (dev->of_node && of_get_child_count(dev->of_node)) in davinci_mdio_probe()
617 data->skip_scan = true; in davinci_mdio_probe()
619 ret = of_mdiobus_register(data->bus, dev->of_node); in davinci_mdio_probe()
625 phy = mdiobus_get_phy(data->bus, addr); in davinci_mdio_probe()
628 phy->mdio.addr, phydev_name(phy), in davinci_mdio_probe()
629 phy->drv ? phy->drv->name : "unknown"); in davinci_mdio_probe()
636 pm_runtime_dont_use_autosuspend(&pdev->dev); in davinci_mdio_probe()
637 pm_runtime_disable(&pdev->dev); in davinci_mdio_probe()
645 if (data->bus) { in davinci_mdio_remove()
646 mdiobus_unregister(data->bus); in davinci_mdio_remove()
648 if (data->manual_mode) in davinci_mdio_remove()
649 free_mdio_bitbang(data->bus); in davinci_mdio_remove()
652 pm_runtime_dont_use_autosuspend(&pdev->dev); in davinci_mdio_remove()
653 pm_runtime_disable(&pdev->dev); in davinci_mdio_remove()
665 ctrl = readl(&data->regs->control); in davinci_mdio_runtime_suspend()
667 writel(ctrl, &data->regs->control); in davinci_mdio_runtime_suspend()
669 if (!data->manual_mode) in davinci_mdio_runtime_suspend()
679 if (data->manual_mode) { in davinci_mdio_runtime_resume()
695 data->active_in_suspend = !pm_runtime_status_suspended(dev); in davinci_mdio_suspend()
696 if (data->active_in_suspend) in davinci_mdio_suspend()
714 if (data->active_in_suspend) in davinci_mdio_resume()
750 MODULE_DESCRIPTION("DaVinci MDIO driver");