Lines Matching +full:cpsw +full:- +full:mdio
1 // SPDX-License-Identifier: GPL-2.0+
3 * DaVinci MDIO Module driver
31 * This timeout definition is a worst-case ultra defensive measure against
89 * if MDIO bus is registered from DT.
99 mdio_in = clk_get_rate(data->clk); in davinci_mdio_init_clk()
100 div = (mdio_in / data->pdata.bus_freq) - 1; in davinci_mdio_init_clk()
104 data->clk_div = div; in davinci_mdio_init_clk()
106 * One mdio transaction consists of: in davinci_mdio_init_clk()
115 * In the worst case, we could be kicking off a user-access immediately in davinci_mdio_init_clk()
116 * after the mdio bus scan state-machine triggered its own read. If in davinci_mdio_init_clk()
120 data->access_time = usecs_to_jiffies(access_time * 4); in davinci_mdio_init_clk()
121 if (!data->access_time) in davinci_mdio_init_clk()
122 data->access_time = 1; in davinci_mdio_init_clk()
128 writel(data->clk_div | CONTROL_ENABLE, &data->regs->control); in davinci_mdio_enable()
133 struct davinci_mdio_data *data = bus->priv; in davinci_mdio_reset()
137 ret = pm_runtime_get_sync(data->dev); in davinci_mdio_reset()
139 pm_runtime_put_noidle(data->dev); in davinci_mdio_reset()
144 msleep(PHY_MAX_ADDR * data->access_time); in davinci_mdio_reset()
147 ver = readl(&data->regs->version); in davinci_mdio_reset()
148 dev_info(data->dev, in davinci_mdio_reset()
149 "davinci mdio revision %d.%d, bus freq %ld\n", in davinci_mdio_reset()
151 data->pdata.bus_freq); in davinci_mdio_reset()
153 if (data->skip_scan) in davinci_mdio_reset()
157 phy_mask = readl(&data->regs->alive); in davinci_mdio_reset()
159 /* restrict mdio bus to live phys only */ in davinci_mdio_reset()
160 dev_info(data->dev, "detected phy mask %x\n", ~phy_mask); in davinci_mdio_reset()
164 dev_warn(data->dev, "no live phy, scanning all\n"); in davinci_mdio_reset()
167 data->bus->phy_mask = phy_mask; in davinci_mdio_reset()
170 pm_runtime_mark_last_busy(data->dev); in davinci_mdio_reset()
171 pm_runtime_put_autosuspend(data->dev); in davinci_mdio_reset()
179 struct davinci_mdio_regs __iomem *regs = data->regs; in wait_for_user_access()
184 reg = readl(®s->user[0].access); in wait_for_user_access()
188 reg = readl(®s->control); in wait_for_user_access()
195 * An emac soft_reset may have clobbered the mdio controller's in wait_for_user_access()
199 dev_warn(data->dev, "resetting idled controller\n"); in wait_for_user_access()
201 return -EAGAIN; in wait_for_user_access()
204 reg = readl(®s->user[0].access); in wait_for_user_access()
208 dev_err(data->dev, "timed out waiting for user access\n"); in wait_for_user_access()
209 return -ETIMEDOUT; in wait_for_user_access()
215 struct davinci_mdio_regs __iomem *regs = data->regs; in wait_for_idle()
218 ret = readl_poll_timeout(®s->control, val, val & CONTROL_IDLE, in wait_for_idle()
221 dev_err(data->dev, "timed out waiting for idle\n"); in wait_for_idle()
228 struct davinci_mdio_data *data = bus->priv; in davinci_mdio_read()
233 return -EINVAL; in davinci_mdio_read()
235 ret = pm_runtime_get_sync(data->dev); in davinci_mdio_read()
237 pm_runtime_put_noidle(data->dev); in davinci_mdio_read()
246 if (ret == -EAGAIN) in davinci_mdio_read()
251 writel(reg, &data->regs->user[0].access); in davinci_mdio_read()
254 if (ret == -EAGAIN) in davinci_mdio_read()
259 reg = readl(&data->regs->user[0].access); in davinci_mdio_read()
260 ret = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -EIO; in davinci_mdio_read()
264 pm_runtime_mark_last_busy(data->dev); in davinci_mdio_read()
265 pm_runtime_put_autosuspend(data->dev); in davinci_mdio_read()
272 struct davinci_mdio_data *data = bus->priv; in davinci_mdio_write()
277 return -EINVAL; in davinci_mdio_write()
279 ret = pm_runtime_get_sync(data->dev); in davinci_mdio_write()
281 pm_runtime_put_noidle(data->dev); in davinci_mdio_write()
290 if (ret == -EAGAIN) in davinci_mdio_write()
295 writel(reg, &data->regs->user[0].access); in davinci_mdio_write()
298 if (ret == -EAGAIN) in davinci_mdio_write()
303 pm_runtime_mark_last_busy(data->dev); in davinci_mdio_write()
304 pm_runtime_put_autosuspend(data->dev); in davinci_mdio_write()
312 struct device_node *node = pdev->dev.of_node; in davinci_mdio_probe_dt()
316 return -EINVAL; in davinci_mdio_probe_dt()
319 dev_err(&pdev->dev, "Missing bus_freq property in the DT.\n"); in davinci_mdio_probe_dt()
320 return -EINVAL; in davinci_mdio_probe_dt()
322 data->bus_freq = prop; in davinci_mdio_probe_dt()
334 { .compatible = "ti,cpsw-mdio", .data = &of_cpsw_mdio_data},
342 struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev); in davinci_mdio_probe()
343 struct device *dev = &pdev->dev; in davinci_mdio_probe()
348 int autosuspend_delay_ms = -1; in davinci_mdio_probe()
352 return -ENOMEM; in davinci_mdio_probe()
354 data->bus = devm_mdiobus_alloc(dev); in davinci_mdio_probe()
355 if (!data->bus) { in davinci_mdio_probe()
357 return -ENOMEM; in davinci_mdio_probe()
360 if (IS_ENABLED(CONFIG_OF) && dev->of_node) { in davinci_mdio_probe()
363 ret = davinci_mdio_probe_dt(&data->pdata, pdev); in davinci_mdio_probe()
366 snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s", pdev->name); in davinci_mdio_probe()
368 of_id = of_match_device(davinci_mdio_of_mtable, &pdev->dev); in davinci_mdio_probe()
372 of_mdio_data = of_id->data; in davinci_mdio_probe()
375 of_mdio_data->autosuspend_delay_ms; in davinci_mdio_probe()
378 data->pdata = pdata ? (*pdata) : default_pdata; in davinci_mdio_probe()
379 snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s-%x", in davinci_mdio_probe()
380 pdev->name, pdev->id); in davinci_mdio_probe()
383 data->bus->name = dev_name(dev); in davinci_mdio_probe()
384 data->bus->read = davinci_mdio_read, in davinci_mdio_probe()
385 data->bus->write = davinci_mdio_write, in davinci_mdio_probe()
386 data->bus->reset = davinci_mdio_reset, in davinci_mdio_probe()
387 data->bus->parent = dev; in davinci_mdio_probe()
388 data->bus->priv = data; in davinci_mdio_probe()
390 data->clk = devm_clk_get(dev, "fck"); in davinci_mdio_probe()
391 if (IS_ERR(data->clk)) { in davinci_mdio_probe()
393 return PTR_ERR(data->clk); in davinci_mdio_probe()
397 data->dev = dev; in davinci_mdio_probe()
401 return -EINVAL; in davinci_mdio_probe()
402 data->regs = devm_ioremap(dev, res->start, resource_size(res)); in davinci_mdio_probe()
403 if (!data->regs) in davinci_mdio_probe()
404 return -ENOMEM; in davinci_mdio_probe()
408 pm_runtime_set_autosuspend_delay(&pdev->dev, autosuspend_delay_ms); in davinci_mdio_probe()
409 pm_runtime_use_autosuspend(&pdev->dev); in davinci_mdio_probe()
410 pm_runtime_enable(&pdev->dev); in davinci_mdio_probe()
415 * Davinci MDIO will always scan the bus for PHYs detection. in davinci_mdio_probe()
417 if (dev->of_node && of_get_child_count(dev->of_node)) in davinci_mdio_probe()
418 data->skip_scan = true; in davinci_mdio_probe()
420 ret = of_mdiobus_register(data->bus, dev->of_node); in davinci_mdio_probe()
426 phy = mdiobus_get_phy(data->bus, addr); in davinci_mdio_probe()
429 phy->mdio.addr, phydev_name(phy), in davinci_mdio_probe()
430 phy->drv ? phy->drv->name : "unknown"); in davinci_mdio_probe()
437 pm_runtime_dont_use_autosuspend(&pdev->dev); in davinci_mdio_probe()
438 pm_runtime_disable(&pdev->dev); in davinci_mdio_probe()
446 if (data->bus) in davinci_mdio_remove()
447 mdiobus_unregister(data->bus); in davinci_mdio_remove()
449 pm_runtime_dont_use_autosuspend(&pdev->dev); in davinci_mdio_remove()
450 pm_runtime_disable(&pdev->dev); in davinci_mdio_remove()
462 ctrl = readl(&data->regs->control); in davinci_mdio_runtime_suspend()
464 writel(ctrl, &data->regs->control); in davinci_mdio_runtime_suspend()
485 data->active_in_suspend = !pm_runtime_status_suspended(dev); in davinci_mdio_suspend()
486 if (data->active_in_suspend) in davinci_mdio_suspend()
504 if (data->active_in_suspend) in davinci_mdio_resume()
540 MODULE_DESCRIPTION("DaVinci MDIO driver");